]> source.dussan.org Git - gitea.git/commitdiff
[Vendor] update macaron related (#13409)
author6543 <6543@obermui.de>
Tue, 3 Nov 2020 06:04:09 +0000 (07:04 +0100)
committerGitHub <noreply@github.com>
Tue, 3 Nov 2020 06:04:09 +0000 (08:04 +0200)
* Vendor: update gitea.com/macaron/session to a177a270

* make vendor

* Vendor: update gitea.com/macaron/macaron to 0db5d458

* make vendor

* Vendor: update gitea.com/macaron/cache to 905232fb

* make vendor

* Vendor: update gitea.com/macaron/i18n to 4ca3dd0c

* make vendor

* Vendor: update gitea.com/macaron/gzip to efa5e847

* make vendor

* Vendor: update gitea.com/macaron/captcha to e8597820

* make vendor

183 files changed:
go.mod
go.sum
vendor/gitea.com/lunny/log/.gitignore [new file with mode: 0644]
vendor/gitea.com/lunny/log/LICENSE [new file with mode: 0644]
vendor/gitea.com/lunny/log/README.md [new file with mode: 0644]
vendor/gitea.com/lunny/log/README_CN.md [new file with mode: 0644]
vendor/gitea.com/lunny/log/dbwriter.go [new file with mode: 0644]
vendor/gitea.com/lunny/log/filewriter.go [new file with mode: 0644]
vendor/gitea.com/lunny/log/go.mod [new file with mode: 0644]
vendor/gitea.com/lunny/log/go.sum [new file with mode: 0644]
vendor/gitea.com/lunny/log/logext.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/.gitignore [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/LICENSE [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/README.md [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/README_CN.md [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/batch.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/binlog.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/binlog_util.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/config/config.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/config/config.toml [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/const.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/doc.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/dump.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/go.mod [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/go.sum [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/info.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/multi.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/nodb.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/nodb_db.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/replication.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/scan.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/store/db.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/store/driver/batch.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/store/driver/driver.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/store/driver/store.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/store/goleveldb/batch.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/store/goleveldb/const.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/store/goleveldb/db.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/store/goleveldb/iterator.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/store/goleveldb/snapshot.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/store/iterator.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/store/snapshot.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/store/store.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/store/tx.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/store/writebatch.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/t_bit.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/t_hash.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/t_kv.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/t_list.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/t_set.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/t_ttl.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/t_zset.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/tx.go [new file with mode: 0644]
vendor/gitea.com/lunny/nodb/util.go [new file with mode: 0644]
vendor/gitea.com/macaron/cache/go.mod
vendor/gitea.com/macaron/cache/go.sum
vendor/gitea.com/macaron/captcha/captcha.go
vendor/gitea.com/macaron/i18n/.drone.yml
vendor/gitea.com/macaron/macaron/context.go
vendor/gitea.com/macaron/session/couchbase/couchbase.go
vendor/gitea.com/macaron/session/go.mod
vendor/gitea.com/macaron/session/go.sum
vendor/gitea.com/macaron/session/nodb/nodb.go
vendor/github.com/BurntSushi/toml/.gitignore [deleted file]
vendor/github.com/BurntSushi/toml/.travis.yml [deleted file]
vendor/github.com/BurntSushi/toml/COMPATIBLE [deleted file]
vendor/github.com/BurntSushi/toml/COPYING [deleted file]
vendor/github.com/BurntSushi/toml/Makefile [deleted file]
vendor/github.com/BurntSushi/toml/README.md [deleted file]
vendor/github.com/BurntSushi/toml/decode.go [deleted file]
vendor/github.com/BurntSushi/toml/decode_meta.go [deleted file]
vendor/github.com/BurntSushi/toml/doc.go [deleted file]
vendor/github.com/BurntSushi/toml/encode.go [deleted file]
vendor/github.com/BurntSushi/toml/encoding_types.go [deleted file]
vendor/github.com/BurntSushi/toml/encoding_types_1.1.go [deleted file]
vendor/github.com/BurntSushi/toml/lex.go [deleted file]
vendor/github.com/BurntSushi/toml/parse.go [deleted file]
vendor/github.com/BurntSushi/toml/session.vim [deleted file]
vendor/github.com/BurntSushi/toml/type_check.go [deleted file]
vendor/github.com/BurntSushi/toml/type_fields.go [deleted file]
vendor/github.com/couchbase/go-couchbase/.gitignore [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/.travis.yml [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/LICENSE [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/README.markdown [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/audit.go [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/client.go [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/conn_pool.go [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/ddocs.go [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/go.mod [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/observe.go [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/pools.go [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/port_map.go [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/streaming.go [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/tap.go [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/upr.go [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/users.go [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/util.go [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/vbmap.go [new file with mode: 0644]
vendor/github.com/couchbase/go-couchbase/views.go [new file with mode: 0644]
vendor/github.com/couchbase/gomemcached/client/collections_filter.go
vendor/github.com/couchbase/gomemcached/client/mc.go
vendor/github.com/couchbase/gomemcached/client/upr_event.go
vendor/github.com/couchbase/gomemcached/client/upr_feed.go
vendor/github.com/couchbase/gomemcached/mc_constants.go
vendor/github.com/couchbase/gomemcached/mc_req.go
vendor/github.com/couchbaselabs/go-couchbase/.gitignore [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/.travis.yml [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/LICENSE [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/README.markdown [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/audit.go [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/client.go [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/conn_pool.go [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/ddocs.go [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/observe.go [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/pools.go [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/port_map.go [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/streaming.go [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/tap.go [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/upr.go [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/users.go [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/util.go [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/vbmap.go [deleted file]
vendor/github.com/couchbaselabs/go-couchbase/views.go [deleted file]
vendor/github.com/klauspost/compress/zstd/README.md
vendor/github.com/lunny/log/.gitignore [deleted file]
vendor/github.com/lunny/log/LICENSE [deleted file]
vendor/github.com/lunny/log/README.md [deleted file]
vendor/github.com/lunny/log/README_CN.md [deleted file]
vendor/github.com/lunny/log/dbwriter.go [deleted file]
vendor/github.com/lunny/log/filewriter.go [deleted file]
vendor/github.com/lunny/log/logext.go [deleted file]
vendor/github.com/lunny/nodb/.gitignore [deleted file]
vendor/github.com/lunny/nodb/LICENSE [deleted file]
vendor/github.com/lunny/nodb/README.md [deleted file]
vendor/github.com/lunny/nodb/README_CN.md [deleted file]
vendor/github.com/lunny/nodb/batch.go [deleted file]
vendor/github.com/lunny/nodb/binlog.go [deleted file]
vendor/github.com/lunny/nodb/binlog_util.go [deleted file]
vendor/github.com/lunny/nodb/config/config.go [deleted file]
vendor/github.com/lunny/nodb/config/config.toml [deleted file]
vendor/github.com/lunny/nodb/const.go [deleted file]
vendor/github.com/lunny/nodb/doc.go [deleted file]
vendor/github.com/lunny/nodb/dump.go [deleted file]
vendor/github.com/lunny/nodb/info.go [deleted file]
vendor/github.com/lunny/nodb/multi.go [deleted file]
vendor/github.com/lunny/nodb/nodb.go [deleted file]
vendor/github.com/lunny/nodb/nodb_db.go [deleted file]
vendor/github.com/lunny/nodb/replication.go [deleted file]
vendor/github.com/lunny/nodb/scan.go [deleted file]
vendor/github.com/lunny/nodb/store/db.go [deleted file]
vendor/github.com/lunny/nodb/store/driver/batch.go [deleted file]
vendor/github.com/lunny/nodb/store/driver/driver.go [deleted file]
vendor/github.com/lunny/nodb/store/driver/store.go [deleted file]
vendor/github.com/lunny/nodb/store/goleveldb/batch.go [deleted file]
vendor/github.com/lunny/nodb/store/goleveldb/const.go [deleted file]
vendor/github.com/lunny/nodb/store/goleveldb/db.go [deleted file]
vendor/github.com/lunny/nodb/store/goleveldb/iterator.go [deleted file]
vendor/github.com/lunny/nodb/store/goleveldb/snapshot.go [deleted file]
vendor/github.com/lunny/nodb/store/iterator.go [deleted file]
vendor/github.com/lunny/nodb/store/snapshot.go [deleted file]
vendor/github.com/lunny/nodb/store/store.go [deleted file]
vendor/github.com/lunny/nodb/store/tx.go [deleted file]
vendor/github.com/lunny/nodb/store/writebatch.go [deleted file]
vendor/github.com/lunny/nodb/t_bit.go [deleted file]
vendor/github.com/lunny/nodb/t_hash.go [deleted file]
vendor/github.com/lunny/nodb/t_kv.go [deleted file]
vendor/github.com/lunny/nodb/t_list.go [deleted file]
vendor/github.com/lunny/nodb/t_set.go [deleted file]
vendor/github.com/lunny/nodb/t_ttl.go [deleted file]
vendor/github.com/lunny/nodb/t_zset.go [deleted file]
vendor/github.com/lunny/nodb/tx.go [deleted file]
vendor/github.com/lunny/nodb/util.go [deleted file]
vendor/golang.org/x/crypto/ssh/client_auth.go
vendor/golang.org/x/text/internal/language/compact/tables.go
vendor/golang.org/x/text/internal/language/tables.go
vendor/golang.org/x/text/language/tables.go
vendor/golang.org/x/text/unicode/bidi/tables12.0.0.go
vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go [new file with mode: 0644]
vendor/golang.org/x/text/unicode/norm/tables12.0.0.go
vendor/golang.org/x/text/unicode/norm/tables13.0.0.go [new file with mode: 0644]
vendor/golang.org/x/text/width/tables12.0.0.go
vendor/golang.org/x/text/width/tables13.0.0.go [new file with mode: 0644]
vendor/modules.txt

diff --git a/go.mod b/go.mod
index 6b05d34c586790f100d61d9161b4883edb66d77f..a0ee588dd290757c478bab00da458c6bf751b274 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -7,15 +7,15 @@ require (
        code.gitea.io/sdk/gitea v0.13.1
        gitea.com/lunny/levelqueue v0.3.0
        gitea.com/macaron/binding v0.0.0-20190822013154-a5f53841ed2b
-       gitea.com/macaron/cache v0.0.0-20190822004001-a6e7fee4ee76
-       gitea.com/macaron/captcha v0.0.0-20190822015246-daa973478bae
+       gitea.com/macaron/cache v0.0.0-20200924044943-905232fba10b
+       gitea.com/macaron/captcha v0.0.0-20200825161008-e8597820aaca
        gitea.com/macaron/cors v0.0.0-20190826180238-95aec09ea8b4
        gitea.com/macaron/csrf v0.0.0-20190822024205-3dc5a4474439
        gitea.com/macaron/gzip v0.0.0-20200827120000-efa5e8477cf5
-       gitea.com/macaron/i18n v0.0.0-20200910171939-7bbf54aa4c76
+       gitea.com/macaron/i18n v0.0.0-20200911004404-4ca3dd0cbd60
        gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a
-       gitea.com/macaron/macaron v1.5.0
-       gitea.com/macaron/session v0.0.0-20200902202411-e3a87877db6e
+       gitea.com/macaron/macaron v1.5.1-0.20201027213641-0db5d4584804
+       gitea.com/macaron/session v0.0.0-20201103015045-a177a2701dee
        gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7
        github.com/PuerkitoBio/goquery v1.5.1
        github.com/RoaringBitmap/roaring v0.5.1 // indirect
@@ -23,7 +23,6 @@ require (
        github.com/andybalholm/brotli v1.0.1 // indirect
        github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
        github.com/blevesearch/bleve v1.0.12
-       github.com/couchbase/gomemcached v0.0.0-20191004160342-7b5da2ec40b2 // indirect
        github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d // indirect
        github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect
        github.com/cznic/strutil v0.0.0-20181122101858-275e90344537 // indirect
@@ -50,7 +49,6 @@ require (
        github.com/gobwas/glob v0.2.3
        github.com/gogs/chardet v0.0.0-20191104214054-4b6791f73a28
        github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
-       github.com/golang/snappy v0.0.2 // indirect
        github.com/google/go-github/v32 v32.1.0
        github.com/google/uuid v1.1.2
        github.com/gorilla/context v1.1.1
@@ -64,7 +62,7 @@ require (
        github.com/jmhodges/levigo v1.0.0 // indirect
        github.com/kballard/go-shellquote v0.0.0-20170619183022-cd60e84ee657
        github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
-       github.com/klauspost/compress v1.11.1
+       github.com/klauspost/compress v1.11.2
        github.com/klauspost/pgzip v1.2.5 // indirect
        github.com/lafriks/xormstore v1.3.2
        github.com/lib/pq v1.8.1-0.20200908161135-083382b7e6fc
@@ -111,11 +109,11 @@ require (
        github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60
        go.jolheiser.com/hcaptcha v0.0.4
        go.jolheiser.com/pwn v0.0.3
-       golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee
+       golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
        golang.org/x/net v0.0.0-20201010224723-4f7140c49acb
        golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43
        golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211
-       golang.org/x/text v0.3.3
+       golang.org/x/text v0.3.4
        golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect
        golang.org/x/tools v0.0.0-20200929161345-d7fc70abf50f
        google.golang.org/appengine v1.6.7 // indirect
diff --git a/go.sum b/go.sum
index 5dcd2ba6c86166b7fbdf773347b4d4102a9a5bf6..287e748db59e4bd684be4b670e5daa9c7c679e11 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -43,20 +43,26 @@ code.gitea.io/sdk/gitea v0.13.1/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUr
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 gitea.com/lunny/levelqueue v0.3.0 h1:MHn1GuSZkxvVEDMyAPqlc7A3cOW+q8RcGhRgH/xtm6I=
 gitea.com/lunny/levelqueue v0.3.0/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU=
+gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e h1:r1en/D7xJmcY24VkHkjkcJFa+7ZWubVWPBrvsHkmHxk=
+gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e/go.mod h1:uJEsN4LQpeGYRCjuPXPZBClU7N5pWzGuyF4uqLpE/e0=
+gitea.com/lunny/nodb v0.0.0-20200923032308-3238c4655727 h1:ZF2Bd6rqVlwhIDhYiS0uGYcT+GaVNGjuKVJkTNqWMIs=
+gitea.com/lunny/nodb v0.0.0-20200923032308-3238c4655727/go.mod h1:h0OwsgcpJLSYtHcM5+Xciw9OEeuxi6ty4HDiO8C7aIY=
 gitea.com/macaron/binding v0.0.0-20190822013154-a5f53841ed2b h1:vXt85uYV17KURaUlhU7v4GbCShkqRZDSfo0TkC0YCjQ=
 gitea.com/macaron/binding v0.0.0-20190822013154-a5f53841ed2b/go.mod h1:Cxadig6POWpPYYSfg23E7jo35Yf0yvsdC1lifoKWmPo=
 gitea.com/macaron/cache v0.0.0-20190822004001-a6e7fee4ee76 h1:mMsMEg90c5KXQgRWsH8D6GHXfZIW1RAe5S9VYIb12lM=
 gitea.com/macaron/cache v0.0.0-20190822004001-a6e7fee4ee76/go.mod h1:NFHb9Of+LUnU86bU20CiXXg6ZlgCJ4XytP14UsHOXFs=
-gitea.com/macaron/captcha v0.0.0-20190822015246-daa973478bae h1:9C31eOCpMPbW9rDVq8M1UJ+5HZVYA38HHaKCVcRYDpI=
-gitea.com/macaron/captcha v0.0.0-20190822015246-daa973478bae/go.mod h1:J5h3N+1nKTXtU1x4GxexaQKgAz8UiWecNwi/CfX7CtQ=
+gitea.com/macaron/cache v0.0.0-20200924044943-905232fba10b h1:2ZE0JE3bKVBcP1VTrWeE1jqWwCAMIzfOQm1U9EGbBKU=
+gitea.com/macaron/cache v0.0.0-20200924044943-905232fba10b/go.mod h1:W5hKG8T1GBfypp5CRQlgoJU4figIL0jhx02y4XA/NOA=
+gitea.com/macaron/captcha v0.0.0-20200825161008-e8597820aaca h1:f5P41nXmXd/YOh8f6098Q0F1Y0QfpyRPSSIkni2XH4Q=
+gitea.com/macaron/captcha v0.0.0-20200825161008-e8597820aaca/go.mod h1:J5h3N+1nKTXtU1x4GxexaQKgAz8UiWecNwi/CfX7CtQ=
 gitea.com/macaron/cors v0.0.0-20190826180238-95aec09ea8b4 h1:e2rAFDejB0qN8OrY4xP4XSu8/yT6QmWxDZpB3J7r2GU=
 gitea.com/macaron/cors v0.0.0-20190826180238-95aec09ea8b4/go.mod h1:rtOK4J20kpMD9XcNsnO5YA843YSTe/MUMbDj/TJ/Q7A=
 gitea.com/macaron/csrf v0.0.0-20190822024205-3dc5a4474439 h1:88c34YM29a1GlWLrLBaG/GTT2htDdJz1u3n9+lmPolg=
 gitea.com/macaron/csrf v0.0.0-20190822024205-3dc5a4474439/go.mod h1:IsQPHx73HnnqFBYiVHjg87q4XBZyGXXu77xANukvZuk=
 gitea.com/macaron/gzip v0.0.0-20200827120000-efa5e8477cf5 h1:6rbhThlqfOb+sSmhrsVFz3bZoAeoloe7TZqyeiPbbWI=
 gitea.com/macaron/gzip v0.0.0-20200827120000-efa5e8477cf5/go.mod h1:z8vCjuhqDfvzPUJDowGqbsgoeYBvDbl95S5k6y43Pxo=
-gitea.com/macaron/i18n v0.0.0-20200910171939-7bbf54aa4c76 h1:r+z4ExFB3GHAXaGfWz+TMGs5q/RuOzDsTCGiXiAk5AY=
-gitea.com/macaron/i18n v0.0.0-20200910171939-7bbf54aa4c76/go.mod h1:g5ope1b+iWhBdHzAn6EJ9u9Gp3FRESxpG+CDf7HYc/A=
+gitea.com/macaron/i18n v0.0.0-20200911004404-4ca3dd0cbd60 h1:tNWNe5HBIlsfapFMtT4twTbXQmInRQWmdWNi8Di1ct0=
+gitea.com/macaron/i18n v0.0.0-20200911004404-4ca3dd0cbd60/go.mod h1:g5ope1b+iWhBdHzAn6EJ9u9Gp3FRESxpG+CDf7HYc/A=
 gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
 gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a h1:aOKEXkDTnh4euoH0so/THLXeHtQuqHmDPb1xEk6Ehok=
 gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
@@ -64,9 +70,11 @@ gitea.com/macaron/macaron v1.3.3-0.20190803174002-53e005ff4827/go.mod h1:/rvxMjI
 gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs=
 gitea.com/macaron/macaron v1.5.0 h1:TvWEcHw1/zaHlo0GTuKEukLh3A99+QsU2mjBrXLXjVQ=
 gitea.com/macaron/macaron v1.5.0/go.mod h1:P7hfDbQjcW22lkYkXlxdRIfWOXxH2+K4EogN4Q0UlLY=
+gitea.com/macaron/macaron v1.5.1-0.20201027213641-0db5d4584804 h1:yUiJVZKzdXsBe2tumTAXHBZa1qPGoGXM3fBG4RJ5fQg=
+gitea.com/macaron/macaron v1.5.1-0.20201027213641-0db5d4584804/go.mod h1:P7hfDbQjcW22lkYkXlxdRIfWOXxH2+K4EogN4Q0UlLY=
 gitea.com/macaron/session v0.0.0-20190821211443-122c47c5f705/go.mod h1:1ujH0jD6Ca4iK9NL0Q2a7fG2chvXx5hVa7hBfABwpkA=
-gitea.com/macaron/session v0.0.0-20200902202411-e3a87877db6e h1:BHoJ/xWNt6FrVsL54JennM9HPIQlnbmRvmaC5DO65pU=
-gitea.com/macaron/session v0.0.0-20200902202411-e3a87877db6e/go.mod h1:FanKy3WjWb5iw/iZBPk4ggoQT9FcM6bkBPvmDmsH6tY=
+gitea.com/macaron/session v0.0.0-20201103015045-a177a2701dee h1:8/N3a56RXRJ66nnep0z+T7oHCB0bY6lpvtjv9Y9FPhE=
+gitea.com/macaron/session v0.0.0-20201103015045-a177a2701dee/go.mod h1:5tJCkDbrwpGv+MQUSIZSOW0wFrkh0exsonJgOvBs1Dw=
 gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7 h1:N9QFoeNsUXLhl14mefLzGluqV7w2mGU3u+iZU+jCeWk=
 gitea.com/macaron/toolbox v0.0.0-20190822013122-05ff0fc766b7/go.mod h1:kgsbFPPS4P+acDYDOPDa3N4IWWOuDJt5/INKRUz7aks=
 gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
@@ -218,12 +226,14 @@ github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7
 github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 github.com/couchbase/ghistogram v0.1.0/go.mod h1:s1Jhy76zqfEecpNWJfWUiKZookAFaiGOEoyzgHt9i7k=
+github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89 h1:uNLXQ6QO1TocD8BaN/KkRki0Xw0brCM1PKl/ZA5pgfs=
+github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A=
 github.com/couchbase/gomemcached v0.0.0-20190515232915-c4b4ca0eb21d/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
-github.com/couchbase/gomemcached v0.0.0-20191004160342-7b5da2ec40b2 h1:vZryARwW4PSFXd9arwegEywvMTvPuXL3/oa+4L5NTe8=
-github.com/couchbase/gomemcached v0.0.0-20191004160342-7b5da2ec40b2/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
+github.com/couchbase/gomemcached v0.1.0 h1:whUde87n8CScx8ckMp2En5liqAlcuG3aKy/BQeBPu84=
+github.com/couchbase/gomemcached v0.1.0/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
 github.com/couchbase/goutils v0.0.0-20190315194238-f9d42b11473b/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
-github.com/couchbase/goutils v0.0.0-20191018232750-b49639060d85 h1:0WMIDtuXCKEm4wtAJgAAXa/qtM5O9MariLwgHaRlYmk=
-github.com/couchbase/goutils v0.0.0-20191018232750-b49639060d85/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
+github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67 h1:NCqJ6fwen6YP0WlV/IyibaT0kPt3JEI1rA62V/UPKT4=
+github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
 github.com/couchbase/moss v0.1.0/go.mod h1:9MaHIaRuy9pvLPUJxB8sh8OrLfyDczECVL37grCIubs=
 github.com/couchbase/vellum v1.0.2 h1:BrbP0NKiyDdndMPec8Jjhy0U47CZ0Lgx3xUC2r9rZqw=
 github.com/couchbase/vellum v1.0.2/go.mod h1:FcwrEivFpNi24R3jLOs3n+fs5RnuQnQqCLBJ1uAg1W4=
@@ -736,8 +746,8 @@ github.com/klauspost/compress v1.9.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
 github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
 github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
 github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
-github.com/klauspost/compress v1.11.1 h1:bPb7nMRdOZYDrpPMTA3EInUQrdgoBinqUuSwlGdKDdE=
-github.com/klauspost/compress v1.11.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.11.2 h1:MiK62aErc3gIiVEtyzKfeOHgW7atJb5g/KNX5m3c2nQ=
+github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
 github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
 github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
 github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s=
@@ -1240,8 +1250,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
 golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI=
-golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
+golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -1415,6 +1425,8 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
+golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
diff --git a/vendor/gitea.com/lunny/log/.gitignore b/vendor/gitea.com/lunny/log/.gitignore
new file mode 100644 (file)
index 0000000..3a11644
--- /dev/null
@@ -0,0 +1,26 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+log.db
+*.log
+logs
+.vscode
\ No newline at end of file
diff --git a/vendor/gitea.com/lunny/log/LICENSE b/vendor/gitea.com/lunny/log/LICENSE
new file mode 100644 (file)
index 0000000..c9338f8
--- /dev/null
@@ -0,0 +1,27 @@
+Copyright (c) 2014 - 2016 lunny
+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 the {organization} 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 HOLDER 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/gitea.com/lunny/log/README.md b/vendor/gitea.com/lunny/log/README.md
new file mode 100644 (file)
index 0000000..be63a4d
--- /dev/null
@@ -0,0 +1,51 @@
+## log
+
+[![](https://goreportcard.com/badge/gitea.com/lunny/log)](https://goreportcard.com/report/gitea.com/lunny/log)
+[![GoDoc](https://godoc.org/gitea.com/lunny/log?status.png)](https://godoc.org/gitea.com/lunny/log)
+
+[简体中文](https://gitea.com/lunny/log/blob/master/README_CN.md)
+
+# Installation
+
+```
+go get gitea.com/lunny/log
+```
+
+# Features
+
+* Add color support for unix console
+* Implemented dbwriter to save log to database
+* Implemented FileWriter to save log to file by date or time.
+* Location configuration
+
+# Example
+
+For Single File:
+```Go
+f, _ := os.Create("my.log")
+log.Std.SetOutput(f)
+```
+
+For Multiple Writer:
+```Go
+f, _ := os.Create("my.log")
+log.Std.SetOutput(io.MultiWriter(f, os.Stdout))
+```
+
+For log files by date or time:
+```Go
+w := log.NewFileWriter(log.FileOptions{
+    ByType:log.ByDay,
+    Dir:"./logs",
+})
+log.Std.SetOutput(w)
+```
+
+# About
+
+This repo is an extension of Golang log.
+
+# LICENSE
+
+ BSD License
+ [http://creativecommons.org/licenses/BSD/](http://creativecommons.org/licenses/BSD/)
diff --git a/vendor/gitea.com/lunny/log/README_CN.md b/vendor/gitea.com/lunny/log/README_CN.md
new file mode 100644 (file)
index 0000000..29cd6c1
--- /dev/null
@@ -0,0 +1,54 @@
+## log
+
+[![](https://goreportcard.com/badge/gitea.com/lunny/log)](https://goreportcard.com/report/gitea.com/lunny/log)
+[![GoDoc](https://godoc.org/gitea.com/lunny/log?status.png)](https://godoc.org/gitea.com/lunny/log)
+
+[English](https://gitea.com/lunny/log/blob/master/README.md)
+
+# 安装
+
+```
+go get gitea.com/lunny/log
+```
+
+# 特性
+
+* 对unix增加控制台颜色支持
+* 实现了保存log到数据库支持
+* 实现了保存log到按日期的文件支持
+* 实现了设置日期的地区
+
+# 例子
+
+保存到单个文件:
+
+```Go
+f, _ := os.Create("my.log")
+log.Std.SetOutput(f)
+```
+
+保存到数据库:
+
+```Go
+f, _ := os.Create("my.log")
+log.Std.SetOutput(io.MultiWriter(f, os.Stdout))
+```
+
+保存到按时间分隔的文件:
+
+```Go
+w := log.NewFileWriter(log.FileOptions{
+    ByType:log.ByDay,
+    Dir:"./logs",
+})
+log.Std.SetOutput(w)
+```
+
+# 关于
+
+本 Log 是在 golang 的 log 之上的扩展
+
+# LICENSE
+
+ BSD License
+ [http://creativecommons.org/licenses/BSD/](http://creativecommons.org/licenses/BSD/)
diff --git a/vendor/gitea.com/lunny/log/dbwriter.go b/vendor/gitea.com/lunny/log/dbwriter.go
new file mode 100644 (file)
index 0000000..e8ff00b
--- /dev/null
@@ -0,0 +1,36 @@
+package log
+
+import (
+       "database/sql"
+       "time"
+)
+
+type DBWriter struct {
+       db      *sql.DB
+       stmt    *sql.Stmt
+       content chan []byte
+}
+
+func NewDBWriter(db *sql.DB) (*DBWriter, error) {
+       _, err := db.Exec("CREATE TABLE IF NOT EXISTS log (id int, content text, created datetime)")
+       if err != nil {
+               return nil, err
+       }
+       stmt, err := db.Prepare("INSERT INTO log (content, created) values (?, ?)")
+       if err != nil {
+               return nil, err
+       }
+       return &DBWriter{db, stmt, make(chan []byte, 1000)}, nil
+}
+
+func (w *DBWriter) Write(p []byte) (n int, err error) {
+       _, err = w.stmt.Exec(string(p), time.Now())
+       if err == nil {
+               n = len(p)
+       }
+       return
+}
+
+func (w *DBWriter) Close() {
+       w.stmt.Close()
+}
diff --git a/vendor/gitea.com/lunny/log/filewriter.go b/vendor/gitea.com/lunny/log/filewriter.go
new file mode 100644 (file)
index 0000000..f0bb4d1
--- /dev/null
@@ -0,0 +1,112 @@
+package log
+
+import (
+       "io"
+       "os"
+       "path/filepath"
+       "sync"
+       "time"
+)
+
+var _ io.Writer = &Files{}
+
+type ByType int
+
+const (
+       ByDay ByType = iota
+       ByHour
+       ByMonth
+)
+
+var (
+       formats = map[ByType]string{
+               ByDay:   "2006-01-02",
+               ByHour:  "2006-01-02-15",
+               ByMonth: "2006-01",
+       }
+)
+
+func SetFileFormat(t ByType, format string) {
+       formats[t] = format
+}
+
+func (b ByType) Format() string {
+       return formats[b]
+}
+
+type Files struct {
+       FileOptions
+       f          *os.File
+       lastFormat string
+       lock       sync.Mutex
+}
+
+type FileOptions struct {
+       Dir    string
+       ByType ByType
+       Loc    *time.Location
+}
+
+func prepareFileOption(opts []FileOptions) FileOptions {
+       var opt FileOptions
+       if len(opts) > 0 {
+               opt = opts[0]
+       }
+       if opt.Dir == "" {
+               opt.Dir = "./"
+       }
+       err := os.MkdirAll(opt.Dir, os.ModePerm)
+       if err != nil {
+               panic(err.Error())
+       }
+
+       if opt.Loc == nil {
+               opt.Loc = time.Local
+       }
+       return opt
+}
+
+func NewFileWriter(opts ...FileOptions) *Files {
+       opt := prepareFileOption(opts)
+       return &Files{
+               FileOptions: opt,
+       }
+}
+
+func (f *Files) getFile() (*os.File, error) {
+       var err error
+       t := time.Now().In(f.Loc)
+       if f.f == nil {
+               f.lastFormat = t.Format(f.ByType.Format())
+               f.f, err = os.OpenFile(filepath.Join(f.Dir, f.lastFormat+".log"),
+                       os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
+               return f.f, err
+       }
+       if f.lastFormat != t.Format(f.ByType.Format()) {
+               f.f.Close()
+               f.lastFormat = t.Format(f.ByType.Format())
+               f.f, err = os.OpenFile(filepath.Join(f.Dir, f.lastFormat+".log"),
+                       os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
+               return f.f, err
+       }
+       return f.f, nil
+}
+
+func (f *Files) Write(bs []byte) (int, error) {
+       f.lock.Lock()
+       defer f.lock.Unlock()
+
+       w, err := f.getFile()
+       if err != nil {
+               return 0, err
+       }
+       return w.Write(bs)
+}
+
+func (f *Files) Close() {
+       if f.f != nil {
+               f.f.Close()
+               f.f = nil
+       }
+       f.lastFormat = ""
+}
diff --git a/vendor/gitea.com/lunny/log/go.mod b/vendor/gitea.com/lunny/log/go.mod
new file mode 100644 (file)
index 0000000..f756706
--- /dev/null
@@ -0,0 +1,5 @@
+module gitea.com/lunny/log
+
+go 1.12
+
+require github.com/mattn/go-sqlite3 v1.10.0
diff --git a/vendor/gitea.com/lunny/log/go.sum b/vendor/gitea.com/lunny/log/go.sum
new file mode 100644 (file)
index 0000000..263c187
--- /dev/null
@@ -0,0 +1,2 @@
+github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
+github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
diff --git a/vendor/gitea.com/lunny/log/logext.go b/vendor/gitea.com/lunny/log/logext.go
new file mode 100644 (file)
index 0000000..215c45f
--- /dev/null
@@ -0,0 +1,595 @@
+package log
+
+import (
+       "bytes"
+       "fmt"
+       "io"
+       "os"
+       "runtime"
+       "strings"
+       "sync"
+       "time"
+)
+
+// These flags define which text to prefix to each log entry generated by the Logger.
+const (
+       // Bits or'ed together to control what's printed. There is no control over the
+       // order they appear (the order listed here) or the format they present (as
+       // described in the comments).  A colon appears after these items:
+       //      2009/0123 01:23:23.123123 /a/b/c/d.go:23: message
+       Ldate         = 1 << iota     // the date: 2009/0123
+       Ltime                         // the time: 01:23:23
+       Lmicroseconds                 // microsecond resolution: 01:23:23.123123.  assumes Ltime.
+       Llongfile                     // full file name and line number: /a/b/c/d.go:23
+       Lshortfile                    // final file name element and line number: d.go:23. overrides Llongfile
+       Lmodule                       // module name
+       Llevel                        // level: 0(Debug), 1(Info), 2(Warn), 3(Error), 4(Panic), 5(Fatal)
+       Llongcolor                    // color will start [info] end of line
+       Lshortcolor                   // color only include [info]
+       LstdFlags     = Ldate | Ltime // initial values for the standard logger
+       //Ldefault      = Llevel | LstdFlags | Lshortfile | Llongcolor
+) // [prefix][time][level][module][shortfile|longfile]
+
+func Ldefault() int {
+       if runtime.GOOS == "windows" {
+               return Llevel | LstdFlags | Lshortfile
+       }
+       return Llevel | LstdFlags | Lshortfile | Llongcolor
+}
+
+func Version() string {
+       return "0.2.0.1121"
+}
+
+const (
+       Lall = iota
+)
+const (
+       Ldebug = iota
+       Linfo
+       Lwarn
+       Lerror
+       Lpanic
+       Lfatal
+       Lnone
+)
+
+const (
+       ForeBlack  = iota + 30 //30
+       ForeRed                //31
+       ForeGreen              //32
+       ForeYellow             //33
+       ForeBlue               //34
+       ForePurple             //35
+       ForeCyan               //36
+       ForeWhite              //37
+)
+
+const (
+       BackBlack  = iota + 40 //40
+       BackRed                //41
+       BackGreen              //42
+       BackYellow             //43
+       BackBlue               //44
+       BackPurple             //45
+       BackCyan               //46
+       BackWhite              //47
+)
+
+var levels = []string{
+       "[Debug]",
+       "[Info]",
+       "[Warn]",
+       "[Error]",
+       "[Panic]",
+       "[Fatal]",
+}
+
+// MUST called before all logs
+func SetLevels(lvs []string) {
+       levels = lvs
+}
+
+var colors = []int{
+       ForeCyan,
+       ForeGreen,
+       ForeYellow,
+       ForeRed,
+       ForePurple,
+       ForeBlue,
+}
+
+// MUST called before all logs
+func SetColors(cls []int) {
+       colors = cls
+}
+
+// A Logger represents an active logging object that generates lines of
+// output to an io.Writer.  Each logging operation makes a single call to
+// the Writer's Write method.  A Logger can be used simultaneously from
+// multiple goroutines; it guarantees to serialize access to the Writer.
+type Logger struct {
+       mu         sync.Mutex // ensures atomic writes; protects the following fields
+       prefix     string     // prefix to write at beginning of each line
+       flag       int        // properties
+       Level      int
+       out        io.Writer    // destination for output
+       buf        bytes.Buffer // for accumulating text to write
+       levelStats [6]int64
+       loc        *time.Location
+}
+
+// New creates a new Logger.   The out variable sets the
+// destination to which log data will be written.
+// The prefix appears at the beginning of each generated log line.
+// The flag argument defines the logging properties.
+func New(out io.Writer, prefix string, flag int) *Logger {
+       l := &Logger{out: out, prefix: prefix, Level: 1, flag: flag, loc: time.Local}
+       if out != os.Stdout {
+               l.flag = RmColorFlags(l.flag)
+       }
+       return l
+}
+
+var Std = New(os.Stderr, "", Ldefault())
+
+// Cheap integer to fixed-width decimal ASCII.  Give a negative width to avoid zero-padding.
+// Knows the buffer has capacity.
+func itoa(buf *bytes.Buffer, i int, wid int) {
+       var u uint = uint(i)
+       if u == 0 && wid <= 1 {
+               buf.WriteByte('0')
+               return
+       }
+
+       // Assemble decimal in reverse order.
+       var b [32]byte
+       bp := len(b)
+       for ; u > 0 || wid > 0; u /= 10 {
+               bp--
+               wid--
+               b[bp] = byte(u%10) + '0'
+       }
+
+       // avoid slicing b to avoid an allocation.
+       for bp < len(b) {
+               buf.WriteByte(b[bp])
+               bp++
+       }
+}
+
+func moduleOf(file string) string {
+       pos := strings.LastIndex(file, "/")
+       if pos != -1 {
+               pos1 := strings.LastIndex(file[:pos], "/src/")
+               if pos1 != -1 {
+                       return file[pos1+5 : pos]
+               }
+       }
+       return "UNKNOWN"
+}
+
+func (l *Logger) formatHeader(buf *bytes.Buffer, t time.Time,
+       file string, line int, lvl int, reqId string) {
+       if l.prefix != "" {
+               buf.WriteString(l.prefix)
+       }
+       if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 {
+               if l.flag&Ldate != 0 {
+                       year, month, day := t.Date()
+                       itoa(buf, year, 4)
+                       buf.WriteByte('/')
+                       itoa(buf, int(month), 2)
+                       buf.WriteByte('/')
+                       itoa(buf, day, 2)
+                       buf.WriteByte(' ')
+               }
+               if l.flag&(Ltime|Lmicroseconds) != 0 {
+                       hour, min, sec := t.Clock()
+                       itoa(buf, hour, 2)
+                       buf.WriteByte(':')
+                       itoa(buf, min, 2)
+                       buf.WriteByte(':')
+                       itoa(buf, sec, 2)
+                       if l.flag&Lmicroseconds != 0 {
+                               buf.WriteByte('.')
+                               itoa(buf, t.Nanosecond()/1e3, 6)
+                       }
+                       buf.WriteByte(' ')
+               }
+       }
+       if reqId != "" {
+               buf.WriteByte('[')
+               buf.WriteString(reqId)
+               buf.WriteByte(']')
+               buf.WriteByte(' ')
+       }
+
+       if l.flag&(Lshortcolor|Llongcolor) != 0 {
+               buf.WriteString(fmt.Sprintf("\033[1;%dm", colors[lvl]))
+       }
+       if l.flag&Llevel != 0 {
+               buf.WriteString(levels[lvl])
+               buf.WriteByte(' ')
+       }
+       if l.flag&Lshortcolor != 0 {
+               buf.WriteString("\033[0m")
+       }
+
+       if l.flag&Lmodule != 0 {
+               buf.WriteByte('[')
+               buf.WriteString(moduleOf(file))
+               buf.WriteByte(']')
+               buf.WriteByte(' ')
+       }
+       if l.flag&(Lshortfile|Llongfile) != 0 {
+               if l.flag&Lshortfile != 0 {
+                       short := file
+                       for i := len(file) - 1; i > 0; i-- {
+                               if file[i] == '/' {
+                                       short = file[i+1:]
+                                       break
+                               }
+                       }
+                       file = short
+               }
+               buf.WriteString(file)
+               buf.WriteByte(':')
+               itoa(buf, line, -1)
+               buf.WriteByte(' ')
+       }
+}
+
+// Output writes the output for a logging event.  The string s contains
+// the text to print after the prefix specified by the flags of the
+// Logger.  A newline is appended if the last character of s is not
+// already a newline.  Calldepth is used to recover the PC and is
+// provided for generality, although at the moment on all pre-defined
+// paths it will be 2.
+func (l *Logger) Output(reqId string, lvl int, calldepth int, s string) error {
+       if lvl < l.Level {
+               return nil
+       }
+       now := time.Now().In(l.loc) // get this early.
+       var file string
+       var line int
+       l.mu.Lock()
+       defer l.mu.Unlock()
+       if l.flag&(Lshortfile|Llongfile|Lmodule) != 0 {
+               // release lock while getting caller info - it's expensive.
+               l.mu.Unlock()
+               var ok bool
+               _, file, line, ok = runtime.Caller(calldepth)
+               if !ok {
+                       file = "???"
+                       line = 0
+               }
+               l.mu.Lock()
+       }
+       l.levelStats[lvl]++
+       l.buf.Reset()
+       l.formatHeader(&l.buf, now, file, line, lvl, reqId)
+       l.buf.WriteString(s)
+       if l.flag&Llongcolor != 0 {
+               l.buf.WriteString("\033[0m")
+       }
+       if len(s) > 0 && s[len(s)-1] != '\n' {
+               l.buf.WriteByte('\n')
+       }
+       _, err := l.out.Write(l.buf.Bytes())
+       return err
+}
+
+// -----------------------------------------
+
+// Printf calls l.Output to print to the logger.
+// Arguments are handled in the manner of fmt.Printf.
+func (l *Logger) Printf(format string, v ...interface{}) {
+       l.Output("", Linfo, 2, fmt.Sprintf(format, v...))
+}
+
+// Print calls l.Output to print to the logger.
+// Arguments are handled in the manner of fmt.Print.
+func (l *Logger) Print(v ...interface{}) {
+       l.Output("", Linfo, 2, fmt.Sprint(v...))
+}
+
+// Println calls l.Output to print to the logger.
+// Arguments are handled in the manner of fmt.Println.
+func (l *Logger) Println(v ...interface{}) {
+       l.Output("", Linfo, 2, fmt.Sprintln(v...))
+}
+
+// -----------------------------------------
+
+func (l *Logger) Debugf(format string, v ...interface{}) {
+       l.Output("", Ldebug, 2, fmt.Sprintf(format, v...))
+}
+
+func (l *Logger) Debug(v ...interface{}) {
+       l.Output("", Ldebug, 2, fmt.Sprintln(v...))
+}
+
+// -----------------------------------------
+func (l *Logger) Infof(format string, v ...interface{}) {
+       l.Output("", Linfo, 2, fmt.Sprintf(format, v...))
+}
+
+func (l *Logger) Info(v ...interface{}) {
+       l.Output("", Linfo, 2, fmt.Sprintln(v...))
+}
+
+// -----------------------------------------
+func (l *Logger) Warnf(format string, v ...interface{}) {
+       l.Output("", Lwarn, 2, fmt.Sprintf(format, v...))
+}
+
+func (l *Logger) Warn(v ...interface{}) {
+       l.Output("", Lwarn, 2, fmt.Sprintln(v...))
+}
+
+// -----------------------------------------
+
+func (l *Logger) Errorf(format string, v ...interface{}) {
+       l.Output("", Lerror, 2, fmt.Sprintf(format, v...))
+}
+
+func (l *Logger) Error(v ...interface{}) {
+       l.Output("", Lerror, 2, fmt.Sprintln(v...))
+}
+
+// -----------------------------------------
+
+func (l *Logger) Fatal(v ...interface{}) {
+       l.Output("", Lfatal, 2, fmt.Sprintln(v...))
+       os.Exit(1)
+}
+
+// Fatalf is equivalent to l.Printf() followed by a call to os.Exit(1).
+func (l *Logger) Fatalf(format string, v ...interface{}) {
+       l.Output("", Lfatal, 2, fmt.Sprintf(format, v...))
+       os.Exit(1)
+}
+
+// -----------------------------------------
+// Panic is equivalent to l.Print() followed by a call to panic().
+func (l *Logger) Panic(v ...interface{}) {
+       s := fmt.Sprintln(v...)
+       l.Output("", Lpanic, 2, s)
+       panic(s)
+}
+
+// Panicf is equivalent to l.Printf() followed by a call to panic().
+func (l *Logger) Panicf(format string, v ...interface{}) {
+       s := fmt.Sprintf(format, v...)
+       l.Output("", Lpanic, 2, s)
+       panic(s)
+}
+
+// -----------------------------------------
+func (l *Logger) Stack(v ...interface{}) {
+       s := fmt.Sprint(v...)
+       s += "\n"
+       buf := make([]byte, 1024*1024)
+       n := runtime.Stack(buf, true)
+       s += string(buf[:n])
+       s += "\n"
+       l.Output("", Lerror, 2, s)
+}
+
+// -----------------------------------------
+func (l *Logger) Stat() (stats []int64) {
+       l.mu.Lock()
+       v := l.levelStats
+       l.mu.Unlock()
+       return v[:]
+}
+
+// Flags returns the output flags for the logger.
+func (l *Logger) Flags() int {
+       l.mu.Lock()
+       defer l.mu.Unlock()
+       return l.flag
+}
+
+func RmColorFlags(flag int) int {
+       // for un std out, it should not show color since almost them don't support
+       if flag&Llongcolor != 0 {
+               flag = flag ^ Llongcolor
+       }
+       if flag&Lshortcolor != 0 {
+               flag = flag ^ Lshortcolor
+       }
+       return flag
+}
+
+func (l *Logger) Location() *time.Location {
+       return l.loc
+}
+
+func (l *Logger) SetLocation(loc *time.Location) {
+       l.loc = loc
+}
+
+// SetFlags sets the output flags for the logger.
+func (l *Logger) SetFlags(flag int) {
+       l.mu.Lock()
+       defer l.mu.Unlock()
+       if l.out != os.Stdout {
+               flag = RmColorFlags(flag)
+       }
+       l.flag = flag
+}
+
+// Prefix returns the output prefix for the logger.
+func (l *Logger) Prefix() string {
+       l.mu.Lock()
+       defer l.mu.Unlock()
+       return l.prefix
+}
+
+// SetPrefix sets the output prefix for the logger.
+func (l *Logger) SetPrefix(prefix string) {
+       l.mu.Lock()
+       defer l.mu.Unlock()
+       l.prefix = prefix
+}
+
+// SetOutputLevel sets the output level for the logger.
+func (l *Logger) SetOutputLevel(lvl int) {
+       l.mu.Lock()
+       defer l.mu.Unlock()
+       l.Level = lvl
+}
+
+func (l *Logger) OutputLevel() int {
+       return l.Level
+}
+
+func (l *Logger) SetOutput(w io.Writer) {
+       l.mu.Lock()
+       defer l.mu.Unlock()
+       l.out = w
+       if w != os.Stdout {
+               l.flag = RmColorFlags(l.flag)
+       }
+}
+
+// SetOutput sets the output destination for the standard logger.
+func SetOutput(w io.Writer) {
+       Std.SetOutput(w)
+}
+
+func SetLocation(loc *time.Location) {
+       Std.SetLocation(loc)
+}
+
+func Location() *time.Location {
+       return Std.Location()
+}
+
+// Flags returns the output flags for the standard logger.
+func Flags() int {
+       return Std.Flags()
+}
+
+// SetFlags sets the output flags for the standard logger.
+func SetFlags(flag int) {
+       Std.SetFlags(flag)
+}
+
+// Prefix returns the output prefix for the standard logger.
+func Prefix() string {
+       return Std.Prefix()
+}
+
+// SetPrefix sets the output prefix for the standard logger.
+func SetPrefix(prefix string) {
+       Std.SetPrefix(prefix)
+}
+
+func SetOutputLevel(lvl int) {
+       Std.SetOutputLevel(lvl)
+}
+
+func OutputLevel() int {
+       return Std.OutputLevel()
+}
+
+// -----------------------------------------
+
+// Print calls Output to print to the standard logger.
+// Arguments are handled in the manner of fmt.Print.
+func Print(v ...interface{}) {
+       Std.Output("", Linfo, 2, fmt.Sprintln(v...))
+}
+
+// Printf calls Output to print to the standard logger.
+// Arguments are handled in the manner of fmt.Printf.
+func Printf(format string, v ...interface{}) {
+       Std.Output("", Linfo, 2, fmt.Sprintf(format, v...))
+}
+
+// Println calls Output to print to the standard logger.
+// Arguments are handled in the manner of fmt.Println.
+func Println(v ...interface{}) {
+       Std.Output("", Linfo, 2, fmt.Sprintln(v...))
+}
+
+// -----------------------------------------
+
+func Debugf(format string, v ...interface{}) {
+       Std.Output("", Ldebug, 2, fmt.Sprintf(format, v...))
+}
+
+func Debug(v ...interface{}) {
+       Std.Output("", Ldebug, 2, fmt.Sprintln(v...))
+}
+
+// -----------------------------------------
+
+func Infof(format string, v ...interface{}) {
+       Std.Output("", Linfo, 2, fmt.Sprintf(format, v...))
+}
+
+func Info(v ...interface{}) {
+       Std.Output("", Linfo, 2, fmt.Sprintln(v...))
+}
+
+// -----------------------------------------
+
+func Warnf(format string, v ...interface{}) {
+       Std.Output("", Lwarn, 2, fmt.Sprintf(format, v...))
+}
+
+func Warn(v ...interface{}) {
+       Std.Output("", Lwarn, 2, fmt.Sprintln(v...))
+}
+
+// -----------------------------------------
+
+func Errorf(format string, v ...interface{}) {
+       Std.Output("", Lerror, 2, fmt.Sprintf(format, v...))
+}
+
+func Error(v ...interface{}) {
+       Std.Output("", Lerror, 2, fmt.Sprintln(v...))
+}
+
+// -----------------------------------------
+
+// Fatal is equivalent to Print() followed by a call to os.Exit(1).
+func Fatal(v ...interface{}) {
+       Std.Output("", Lfatal, 2, fmt.Sprintln(v...))
+}
+
+// Fatalf is equivalent to Printf() followed by a call to os.Exit(1).
+func Fatalf(format string, v ...interface{}) {
+       Std.Output("", Lfatal, 2, fmt.Sprintf(format, v...))
+}
+
+// -----------------------------------------
+
+// Panic is equivalent to Print() followed by a call to panic().
+func Panic(v ...interface{}) {
+       Std.Output("", Lpanic, 2, fmt.Sprintln(v...))
+}
+
+// Panicf is equivalent to Printf() followed by a call to panic().
+func Panicf(format string, v ...interface{}) {
+       Std.Output("", Lpanic, 2, fmt.Sprintf(format, v...))
+}
+
+// -----------------------------------------
+
+func Stack(v ...interface{}) {
+       s := fmt.Sprint(v...)
+       s += "\n"
+       buf := make([]byte, 1024*1024)
+       n := runtime.Stack(buf, true)
+       s += string(buf[:n])
+       s += "\n"
+       Std.Output("", Lerror, 2, s)
+}
+
+// -----------------------------------------
diff --git a/vendor/gitea.com/lunny/nodb/.gitignore b/vendor/gitea.com/lunny/nodb/.gitignore
new file mode 100644 (file)
index 0000000..8f40517
--- /dev/null
@@ -0,0 +1,7 @@
+build
+*.pyc
+.DS_Store
+nohup.out
+build_config.mk
+var
+.vscode
diff --git a/vendor/gitea.com/lunny/nodb/LICENSE b/vendor/gitea.com/lunny/nodb/LICENSE
new file mode 100644 (file)
index 0000000..7ece9fd
--- /dev/null
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 siddontang
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/vendor/gitea.com/lunny/nodb/README.md b/vendor/gitea.com/lunny/nodb/README.md
new file mode 100644 (file)
index 0000000..6734243
--- /dev/null
@@ -0,0 +1,83 @@
+# NoDB
+
+[中文](https://gitea.com/lunny/nodb/blob/master/README_CN.md)
+
+Nodb is a fork of [ledisdb](https://github.com/siddontang/ledisdb) and shrink version. It's get rid of all C or other language codes and only keep Go's. It aims to provide a nosql database library rather than a redis like server. So if you want a redis like server, ledisdb is the best choose.
+
+Nodb is a pure Go and high performance NoSQL database library. It supports some data structure like kv, list, hash, zset, bitmap, set.
+
+Nodb now use [goleveldb](https://github.com/syndtr/goleveldb) as backend to store data.
+
+## Features
+
++ Rich data structure: KV, List, Hash, ZSet, Bitmap, Set.
++ Stores lots of data, over the memory limit. 
++ Supports expiration and ttl.
++ Easy to embed in your own Go application.
+
+## Install
+
+    go get gitea.com/lunny/nodb
+
+## Package Example
+
+### Open And Select database
+```go
+import(
+  "gitea.com/lunny/nodb"
+  "gitea.com/lunny/nodb/config"
+)
+
+cfg := new(config.Config)
+cfg.DataDir = "./"
+dbs, err := nodb.Open(cfg)
+if err != nil {
+  fmt.Printf("nodb: error opening db: %v", err)
+}
+
+db, _ := dbs.Select(0)
+```
+### KV
+
+KV is the most basic nodb type like any other key-value database.
+```go
+err := db.Set(key, value)
+value, err := db.Get(key)
+```
+### List
+
+List is simply lists of values, sorted by insertion order.
+You can push or pop value on the list head (left) or tail (right).
+```go
+err := db.LPush(key, value1)
+err := db.RPush(key, value2)
+value1, err := db.LPop(key)
+value2, err := db.RPop(key)
+```
+### Hash
+
+Hash is a map between fields and values.
+```go
+n, err := db.HSet(key, field1, value1)
+n, err := db.HSet(key, field2, value2)
+value1, err := db.HGet(key, field1)
+value2, err := db.HGet(key, field2)
+```
+### ZSet
+
+ZSet is a sorted collections of values.
+Every member of zset is associated with score, a int64 value which used to sort, from smallest to greatest score.
+Members are unique, but score may be same.
+```go
+n, err := db.ZAdd(key, ScorePair{score1, member1}, ScorePair{score2, member2})
+ay, err := db.ZRangeByScore(key, minScore, maxScore, 0, -1)
+```
+## Links
+
++ [Ledisdb Official Website](http://ledisdb.com)
++ [GoDoc](https://godoc.org/gitea.com/lunny/nodb)
+
+
+## Thanks
+
+Gmail: siddontang@gmail.com
diff --git a/vendor/gitea.com/lunny/nodb/README_CN.md b/vendor/gitea.com/lunny/nodb/README_CN.md
new file mode 100644 (file)
index 0000000..adbf51d
--- /dev/null
@@ -0,0 +1,80 @@
+# NoDB
+
+[English](https://gitea.com/lunny/nodb/blob/master/README.md)
+
+Nodb 是 [ledisdb](https://github.com/siddontang/ledisdb) 的克隆和缩减版本。该版本去掉了所有C和其它语言的依赖,只保留Go语言的。目标是提供一个Nosql数据库的开发库而不是提供一个像Redis那样的服务器。因此如果你想要的是一个独立服务器,你可以直接选择ledisdb。
+
+Nodb 是一个纯Go的高性能 NoSQL 数据库。他支持 kv, list, hash, zset, bitmap, set 等数据结构。
+
+Nodb 当前底层使用 (goleveldb)[https://github.com/syndtr/goleveldb] 来存储数据。
+
+## 特性
+
++ 丰富的数据结构支持: KV, List, Hash, ZSet, Bitmap, Set。
++ 永久存储并且不受内存的限制。
++ 高性能那个。
++ 可以方便的嵌入到你的应用程序中。
+
+## 安装
+
+    go get gitea.com/lunny/nodb
+
+## 例子
+
+### 打开和选择数据库
+```go
+import(
+  "gitea.com/lunny/nodb"
+  "gitea.com/lunny/nodb/config"
+)
+
+cfg := new(config.Config)
+cfg.DataDir = "./"
+dbs, err := nodb.Open(cfg)
+if err != nil {
+  fmt.Printf("nodb: error opening db: %v", err)
+}
+db, _ := dbs.Select(0)
+```
+### KV
+
+KV 是最基础的功能,和其它Nosql一样。
+```go
+err := db.Set(key, value)
+value, err := db.Get(key)
+```
+### List
+
+List 是一些值的简单列表,按照插入的顺序排列。你可以从左或右push和pop值。
+```go
+err := db.LPush(key, value1)
+err := db.RPush(key, value2)
+value1, err := db.LPop(key)
+value2, err := db.RPop(key)
+```
+### Hash
+
+Hash 是一个field和value对应的map。
+```go
+n, err := db.HSet(key, field1, value1)
+n, err := db.HSet(key, field2, value2)
+value1, err := db.HGet(key, field1)
+value2, err := db.HGet(key, field2)
+```
+### ZSet
+
+ZSet 是一个排序的值集合。zset的每个成员对应一个score,这是一个int64的值用于从小到大排序。成员不可重复,但是score可以相同。
+```go
+n, err := db.ZAdd(key, ScorePair{score1, member1}, ScorePair{score2, member2})
+ay, err := db.ZRangeByScore(key, minScore, maxScore, 0, -1)
+```
+
+## 链接
+
++ [Ledisdb Official Website](http://ledisdb.com)
++ [GoDoc](https://godoc.org/gitea.com/lunny/nodb)
+
+
+## 感谢
+
+Gmail: siddontang@gmail.com
diff --git a/vendor/gitea.com/lunny/nodb/batch.go b/vendor/gitea.com/lunny/nodb/batch.go
new file mode 100644 (file)
index 0000000..e2bc289
--- /dev/null
@@ -0,0 +1,106 @@
+package nodb
+
+import (
+       "sync"
+
+       "gitea.com/lunny/nodb/store"
+)
+
+type batch struct {
+       l *Nodb
+
+       store.WriteBatch
+
+       sync.Locker
+
+       logs [][]byte
+
+       tx *Tx
+}
+
+func (b *batch) Commit() error {
+       b.l.commitLock.Lock()
+       defer b.l.commitLock.Unlock()
+
+       err := b.WriteBatch.Commit()
+
+       if b.l.binlog != nil {
+               if err == nil {
+                       if b.tx == nil {
+                               b.l.binlog.Log(b.logs...)
+                       } else {
+                               b.tx.logs = append(b.tx.logs, b.logs...)
+                       }
+               }
+               b.logs = [][]byte{}
+       }
+
+       return err
+}
+
+func (b *batch) Lock() {
+       b.Locker.Lock()
+}
+
+func (b *batch) Unlock() {
+       if b.l.binlog != nil {
+               b.logs = [][]byte{}
+       }
+       b.WriteBatch.Rollback()
+       b.Locker.Unlock()
+}
+
+func (b *batch) Put(key []byte, value []byte) {
+       if b.l.binlog != nil {
+               buf := encodeBinLogPut(key, value)
+               b.logs = append(b.logs, buf)
+       }
+       b.WriteBatch.Put(key, value)
+}
+
+func (b *batch) Delete(key []byte) {
+       if b.l.binlog != nil {
+               buf := encodeBinLogDelete(key)
+               b.logs = append(b.logs, buf)
+       }
+       b.WriteBatch.Delete(key)
+}
+
+type dbBatchLocker struct {
+       l      *sync.Mutex
+       wrLock *sync.RWMutex
+}
+
+func (l *dbBatchLocker) Lock() {
+       l.wrLock.RLock()
+       l.l.Lock()
+}
+
+func (l *dbBatchLocker) Unlock() {
+       l.l.Unlock()
+       l.wrLock.RUnlock()
+}
+
+type txBatchLocker struct {
+}
+
+func (l *txBatchLocker) Lock()   {}
+func (l *txBatchLocker) Unlock() {}
+
+type multiBatchLocker struct {
+}
+
+func (l *multiBatchLocker) Lock()   {}
+func (l *multiBatchLocker) Unlock() {}
+
+func (l *Nodb) newBatch(wb store.WriteBatch, locker sync.Locker, tx *Tx) *batch {
+       b := new(batch)
+       b.l = l
+       b.WriteBatch = wb
+
+       b.tx = tx
+       b.Locker = locker
+
+       b.logs = [][]byte{}
+       return b
+}
diff --git a/vendor/gitea.com/lunny/nodb/binlog.go b/vendor/gitea.com/lunny/nodb/binlog.go
new file mode 100644 (file)
index 0000000..50a9e9d
--- /dev/null
@@ -0,0 +1,391 @@
+package nodb
+
+import (
+       "bufio"
+       "encoding/binary"
+       "fmt"
+       "io"
+       "io/ioutil"
+       "os"
+       "path"
+       "strconv"
+       "strings"
+       "sync"
+       "time"
+
+       "gitea.com/lunny/log"
+       "gitea.com/lunny/nodb/config"
+)
+
+type BinLogHead struct {
+       CreateTime uint32
+       BatchId    uint32
+       PayloadLen uint32
+}
+
+func (h *BinLogHead) Len() int {
+       return 12
+}
+
+func (h *BinLogHead) Write(w io.Writer) error {
+       if err := binary.Write(w, binary.BigEndian, h.CreateTime); err != nil {
+               return err
+       }
+
+       if err := binary.Write(w, binary.BigEndian, h.BatchId); err != nil {
+               return err
+       }
+
+       if err := binary.Write(w, binary.BigEndian, h.PayloadLen); err != nil {
+               return err
+       }
+
+       return nil
+}
+
+func (h *BinLogHead) handleReadError(err error) error {
+       if err == io.EOF {
+               return io.ErrUnexpectedEOF
+       } else {
+               return err
+       }
+}
+
+func (h *BinLogHead) Read(r io.Reader) error {
+       var err error
+       if err = binary.Read(r, binary.BigEndian, &h.CreateTime); err != nil {
+               return err
+       }
+
+       if err = binary.Read(r, binary.BigEndian, &h.BatchId); err != nil {
+               return h.handleReadError(err)
+       }
+
+       if err = binary.Read(r, binary.BigEndian, &h.PayloadLen); err != nil {
+               return h.handleReadError(err)
+       }
+
+       return nil
+}
+
+func (h *BinLogHead) InSameBatch(ho *BinLogHead) bool {
+       if h.CreateTime == ho.CreateTime && h.BatchId == ho.BatchId {
+               return true
+       } else {
+               return false
+       }
+}
+
+/*
+index file format:
+ledis-bin.00001
+ledis-bin.00002
+ledis-bin.00003
+
+log file format
+
+Log: Head|PayloadData
+
+Head: createTime|batchId|payloadData
+
+*/
+
+type BinLog struct {
+       sync.Mutex
+
+       path string
+
+       cfg *config.BinLogConfig
+
+       logFile *os.File
+
+       logWb *bufio.Writer
+
+       indexName    string
+       logNames     []string
+       lastLogIndex int64
+
+       batchId uint32
+
+       ch chan struct{}
+}
+
+func NewBinLog(cfg *config.Config) (*BinLog, error) {
+       l := new(BinLog)
+
+       l.cfg = &cfg.BinLog
+       l.cfg.Adjust()
+
+       l.path = path.Join(cfg.DataDir, "binlog")
+
+       if err := os.MkdirAll(l.path, os.ModePerm); err != nil {
+               return nil, err
+       }
+
+       l.logNames = make([]string, 0, 16)
+
+       l.ch = make(chan struct{})
+
+       if err := l.loadIndex(); err != nil {
+               return nil, err
+       }
+
+       return l, nil
+}
+
+func (l *BinLog) flushIndex() error {
+       data := strings.Join(l.logNames, "\n")
+
+       bakName := fmt.Sprintf("%s.bak", l.indexName)
+       f, err := os.OpenFile(bakName, os.O_WRONLY|os.O_CREATE, 0666)
+       if err != nil {
+               log.Errorf("create binlog bak index error %s", err.Error())
+               return err
+       }
+
+       if _, err := f.WriteString(data); err != nil {
+               log.Errorf("write binlog index error %s", err.Error())
+               f.Close()
+               return err
+       }
+
+       f.Close()
+
+       if err := os.Rename(bakName, l.indexName); err != nil {
+               log.Errorf("rename binlog bak index error %s", err.Error())
+               return err
+       }
+
+       return nil
+}
+
+func (l *BinLog) loadIndex() error {
+       l.indexName = path.Join(l.path, fmt.Sprintf("ledis-bin.index"))
+       if _, err := os.Stat(l.indexName); os.IsNotExist(err) {
+               //no index file, nothing to do
+       } else {
+               indexData, err := ioutil.ReadFile(l.indexName)
+               if err != nil {
+                       return err
+               }
+
+               lines := strings.Split(string(indexData), "\n")
+               for _, line := range lines {
+                       line = strings.Trim(line, "\r\n ")
+                       if len(line) == 0 {
+                               continue
+                       }
+
+                       if _, err := os.Stat(path.Join(l.path, line)); err != nil {
+                               log.Errorf("load index line %s error %s", line, err.Error())
+                               return err
+                       } else {
+                               l.logNames = append(l.logNames, line)
+                       }
+               }
+       }
+       if l.cfg.MaxFileNum > 0 && len(l.logNames) > l.cfg.MaxFileNum {
+               //remove oldest logfile
+               if err := l.Purge(len(l.logNames) - l.cfg.MaxFileNum); err != nil {
+                       return err
+               }
+       }
+
+       var err error
+       if len(l.logNames) == 0 {
+               l.lastLogIndex = 1
+       } else {
+               lastName := l.logNames[len(l.logNames)-1]
+
+               if l.lastLogIndex, err = strconv.ParseInt(path.Ext(lastName)[1:], 10, 64); err != nil {
+                       log.Errorf("invalid logfile name %s", err.Error())
+                       return err
+               }
+
+               //like mysql, if server restart, a new binlog will create
+               l.lastLogIndex++
+       }
+
+       return nil
+}
+
+func (l *BinLog) getLogFile() string {
+       return l.FormatLogFileName(l.lastLogIndex)
+}
+
+func (l *BinLog) openNewLogFile() error {
+       var err error
+       lastName := l.getLogFile()
+
+       logPath := path.Join(l.path, lastName)
+       if l.logFile, err = os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY, 0666); err != nil {
+               log.Errorf("open new logfile error %s", err.Error())
+               return err
+       }
+
+       if l.cfg.MaxFileNum > 0 && len(l.logNames) == l.cfg.MaxFileNum {
+               l.purge(1)
+       }
+
+       l.logNames = append(l.logNames, lastName)
+
+       if l.logWb == nil {
+               l.logWb = bufio.NewWriterSize(l.logFile, 1024)
+       } else {
+               l.logWb.Reset(l.logFile)
+       }
+
+       if err = l.flushIndex(); err != nil {
+               return err
+       }
+
+       return nil
+}
+
+func (l *BinLog) checkLogFileSize() bool {
+       if l.logFile == nil {
+               return false
+       }
+
+       st, _ := l.logFile.Stat()
+       if st.Size() >= int64(l.cfg.MaxFileSize) {
+               l.closeLog()
+               return true
+       }
+
+       return false
+}
+
+func (l *BinLog) closeLog() {
+       l.lastLogIndex++
+
+       l.logFile.Close()
+       l.logFile = nil
+}
+
+func (l *BinLog) purge(n int) {
+       for i := 0; i < n; i++ {
+               logPath := path.Join(l.path, l.logNames[i])
+               os.Remove(logPath)
+       }
+
+       copy(l.logNames[0:], l.logNames[n:])
+       l.logNames = l.logNames[0 : len(l.logNames)-n]
+}
+
+func (l *BinLog) Close() {
+       if l.logFile != nil {
+               l.logFile.Close()
+               l.logFile = nil
+       }
+}
+
+func (l *BinLog) LogNames() []string {
+       return l.logNames
+}
+
+func (l *BinLog) LogFileName() string {
+       return l.getLogFile()
+}
+
+func (l *BinLog) LogFilePos() int64 {
+       if l.logFile == nil {
+               return 0
+       } else {
+               st, _ := l.logFile.Stat()
+               return st.Size()
+       }
+}
+
+func (l *BinLog) LogFileIndex() int64 {
+       return l.lastLogIndex
+}
+
+func (l *BinLog) FormatLogFileName(index int64) string {
+       return fmt.Sprintf("ledis-bin.%07d", index)
+}
+
+func (l *BinLog) FormatLogFilePath(index int64) string {
+       return path.Join(l.path, l.FormatLogFileName(index))
+}
+
+func (l *BinLog) LogPath() string {
+       return l.path
+}
+
+func (l *BinLog) Purge(n int) error {
+       l.Lock()
+       defer l.Unlock()
+
+       if len(l.logNames) == 0 {
+               return nil
+       }
+
+       if n >= len(l.logNames) {
+               n = len(l.logNames)
+               //can not purge current log file
+               if l.logNames[n-1] == l.getLogFile() {
+                       n = n - 1
+               }
+       }
+
+       l.purge(n)
+
+       return l.flushIndex()
+}
+
+func (l *BinLog) PurgeAll() error {
+       l.Lock()
+       defer l.Unlock()
+
+       l.closeLog()
+       return l.openNewLogFile()
+}
+
+func (l *BinLog) Log(args ...[]byte) error {
+       l.Lock()
+       defer l.Unlock()
+
+       var err error
+
+       if l.logFile == nil {
+               if err = l.openNewLogFile(); err != nil {
+                       return err
+               }
+       }
+
+       head := &BinLogHead{}
+
+       head.CreateTime = uint32(time.Now().Unix())
+       head.BatchId = l.batchId
+
+       l.batchId++
+
+       for _, data := range args {
+               head.PayloadLen = uint32(len(data))
+
+               if err := head.Write(l.logWb); err != nil {
+                       return err
+               }
+
+               if _, err := l.logWb.Write(data); err != nil {
+                       return err
+               }
+       }
+
+       if err = l.logWb.Flush(); err != nil {
+               log.Errorf("write log error %s", err.Error())
+               return err
+       }
+
+       l.checkLogFileSize()
+
+       close(l.ch)
+       l.ch = make(chan struct{})
+
+       return nil
+}
+
+func (l *BinLog) Wait() <-chan struct{} {
+       return l.ch
+}
diff --git a/vendor/gitea.com/lunny/nodb/binlog_util.go b/vendor/gitea.com/lunny/nodb/binlog_util.go
new file mode 100644 (file)
index 0000000..22124dd
--- /dev/null
@@ -0,0 +1,215 @@
+package nodb
+
+import (
+       "encoding/binary"
+       "errors"
+       "fmt"
+       "strconv"
+)
+
+var (
+       errBinLogDeleteType  = errors.New("invalid bin log delete type")
+       errBinLogPutType     = errors.New("invalid bin log put type")
+       errBinLogCommandType = errors.New("invalid bin log command type")
+)
+
+func encodeBinLogDelete(key []byte) []byte {
+       buf := make([]byte, 1+len(key))
+       buf[0] = BinLogTypeDeletion
+       copy(buf[1:], key)
+       return buf
+}
+
+func decodeBinLogDelete(sz []byte) ([]byte, error) {
+       if len(sz) < 1 || sz[0] != BinLogTypeDeletion {
+               return nil, errBinLogDeleteType
+       }
+
+       return sz[1:], nil
+}
+
+func encodeBinLogPut(key []byte, value []byte) []byte {
+       buf := make([]byte, 3+len(key)+len(value))
+       buf[0] = BinLogTypePut
+       pos := 1
+       binary.BigEndian.PutUint16(buf[pos:], uint16(len(key)))
+       pos += 2
+       copy(buf[pos:], key)
+       pos += len(key)
+       copy(buf[pos:], value)
+
+       return buf
+}
+
+func decodeBinLogPut(sz []byte) ([]byte, []byte, error) {
+       if len(sz) < 3 || sz[0] != BinLogTypePut {
+               return nil, nil, errBinLogPutType
+       }
+
+       keyLen := int(binary.BigEndian.Uint16(sz[1:]))
+       if 3+keyLen > len(sz) {
+               return nil, nil, errBinLogPutType
+       }
+
+       return sz[3 : 3+keyLen], sz[3+keyLen:], nil
+}
+
+func FormatBinLogEvent(event []byte) (string, error) {
+       logType := uint8(event[0])
+
+       var err error
+       var k []byte
+       var v []byte
+
+       var buf []byte = make([]byte, 0, 1024)
+
+       switch logType {
+       case BinLogTypePut:
+               k, v, err = decodeBinLogPut(event)
+               buf = append(buf, "PUT "...)
+       case BinLogTypeDeletion:
+               k, err = decodeBinLogDelete(event)
+               buf = append(buf, "DELETE "...)
+       default:
+               err = errInvalidBinLogEvent
+       }
+
+       if err != nil {
+               return "", err
+       }
+
+       if buf, err = formatDataKey(buf, k); err != nil {
+               return "", err
+       }
+
+       if v != nil && len(v) != 0 {
+               buf = append(buf, fmt.Sprintf(" %q", v)...)
+       }
+
+       return String(buf), nil
+}
+
+func formatDataKey(buf []byte, k []byte) ([]byte, error) {
+       if len(k) < 2 {
+               return nil, errInvalidBinLogEvent
+       }
+
+       buf = append(buf, fmt.Sprintf("DB:%2d ", k[0])...)
+       buf = append(buf, fmt.Sprintf("%s ", TypeName[k[1]])...)
+
+       db := new(DB)
+       db.index = k[0]
+
+       //to do format at respective place
+
+       switch k[1] {
+       case KVType:
+               if key, err := db.decodeKVKey(k); err != nil {
+                       return nil, err
+               } else {
+                       buf = strconv.AppendQuote(buf, String(key))
+               }
+       case HashType:
+               if key, field, err := db.hDecodeHashKey(k); err != nil {
+                       return nil, err
+               } else {
+                       buf = strconv.AppendQuote(buf, String(key))
+                       buf = append(buf, ' ')
+                       buf = strconv.AppendQuote(buf, String(field))
+               }
+       case HSizeType:
+               if key, err := db.hDecodeSizeKey(k); err != nil {
+                       return nil, err
+               } else {
+                       buf = strconv.AppendQuote(buf, String(key))
+               }
+       case ListType:
+               if key, seq, err := db.lDecodeListKey(k); err != nil {
+                       return nil, err
+               } else {
+                       buf = strconv.AppendQuote(buf, String(key))
+                       buf = append(buf, ' ')
+                       buf = strconv.AppendInt(buf, int64(seq), 10)
+               }
+       case LMetaType:
+               if key, err := db.lDecodeMetaKey(k); err != nil {
+                       return nil, err
+               } else {
+                       buf = strconv.AppendQuote(buf, String(key))
+               }
+       case ZSetType:
+               if key, m, err := db.zDecodeSetKey(k); err != nil {
+                       return nil, err
+               } else {
+                       buf = strconv.AppendQuote(buf, String(key))
+                       buf = append(buf, ' ')
+                       buf = strconv.AppendQuote(buf, String(m))
+               }
+       case ZSizeType:
+               if key, err := db.zDecodeSizeKey(k); err != nil {
+                       return nil, err
+               } else {
+                       buf = strconv.AppendQuote(buf, String(key))
+               }
+       case ZScoreType:
+               if key, m, score, err := db.zDecodeScoreKey(k); err != nil {
+                       return nil, err
+               } else {
+                       buf = strconv.AppendQuote(buf, String(key))
+                       buf = append(buf, ' ')
+                       buf = strconv.AppendQuote(buf, String(m))
+                       buf = append(buf, ' ')
+                       buf = strconv.AppendInt(buf, score, 10)
+               }
+       case BitType:
+               if key, seq, err := db.bDecodeBinKey(k); err != nil {
+                       return nil, err
+               } else {
+                       buf = strconv.AppendQuote(buf, String(key))
+                       buf = append(buf, ' ')
+                       buf = strconv.AppendUint(buf, uint64(seq), 10)
+               }
+       case BitMetaType:
+               if key, err := db.bDecodeMetaKey(k); err != nil {
+                       return nil, err
+               } else {
+                       buf = strconv.AppendQuote(buf, String(key))
+               }
+       case SetType:
+               if key, member, err := db.sDecodeSetKey(k); err != nil {
+                       return nil, err
+               } else {
+                       buf = strconv.AppendQuote(buf, String(key))
+                       buf = append(buf, ' ')
+                       buf = strconv.AppendQuote(buf, String(member))
+               }
+       case SSizeType:
+               if key, err := db.sDecodeSizeKey(k); err != nil {
+                       return nil, err
+               } else {
+                       buf = strconv.AppendQuote(buf, String(key))
+               }
+       case ExpTimeType:
+               if tp, key, t, err := db.expDecodeTimeKey(k); err != nil {
+                       return nil, err
+               } else {
+                       buf = append(buf, TypeName[tp]...)
+                       buf = append(buf, ' ')
+                       buf = strconv.AppendQuote(buf, String(key))
+                       buf = append(buf, ' ')
+                       buf = strconv.AppendInt(buf, t, 10)
+               }
+       case ExpMetaType:
+               if tp, key, err := db.expDecodeMetaKey(k); err != nil {
+                       return nil, err
+               } else {
+                       buf = append(buf, TypeName[tp]...)
+                       buf = append(buf, ' ')
+                       buf = strconv.AppendQuote(buf, String(key))
+               }
+       default:
+               return nil, errInvalidBinLogEvent
+       }
+
+       return buf, nil
+}
diff --git a/vendor/gitea.com/lunny/nodb/config/config.go b/vendor/gitea.com/lunny/nodb/config/config.go
new file mode 100644 (file)
index 0000000..01ca070
--- /dev/null
@@ -0,0 +1,135 @@
+package config
+
+import (
+       "io/ioutil"
+
+       "github.com/pelletier/go-toml"
+)
+
+type Size int
+
+const (
+       DefaultAddr     string = "127.0.0.1:6380"
+       DefaultHttpAddr string = "127.0.0.1:11181"
+
+       DefaultDBName string = "goleveldb"
+
+       DefaultDataDir string = "./data"
+)
+
+const (
+       MaxBinLogFileSize int = 1024 * 1024 * 1024
+       MaxBinLogFileNum  int = 10000
+
+       DefaultBinLogFileSize int = MaxBinLogFileSize
+       DefaultBinLogFileNum  int = 10
+)
+
+type LevelDBConfig struct {
+       Compression     bool `toml:"compression"`
+       BlockSize       int  `toml:"block_size"`
+       WriteBufferSize int  `toml:"write_buffer_size"`
+       CacheSize       int  `toml:"cache_size"`
+       MaxOpenFiles    int  `toml:"max_open_files"`
+}
+
+type LMDBConfig struct {
+       MapSize int  `toml:"map_size"`
+       NoSync  bool `toml:"nosync"`
+}
+
+type BinLogConfig struct {
+       MaxFileSize int `toml:"max_file_size"`
+       MaxFileNum  int `toml:"max_file_num"`
+}
+
+type Config struct {
+       DataDir string `toml:"data_dir"`
+
+       DBName string `toml:"db_name"`
+
+       LevelDB LevelDBConfig `toml:"leveldb"`
+
+       LMDB LMDBConfig `toml:"lmdb"`
+
+       BinLog BinLogConfig `toml:"binlog"`
+
+       SlaveOf string `toml:"slaveof"`
+
+       AccessLog string `toml:"access_log"`
+}
+
+func NewConfigWithFile(fileName string) (*Config, error) {
+       data, err := ioutil.ReadFile(fileName)
+       if err != nil {
+               return nil, err
+       }
+
+       return NewConfigWithData(data)
+}
+
+func NewConfigWithData(data []byte) (*Config, error) {
+       cfg := NewConfigDefault()
+
+       err := toml.Unmarshal(data, cfg)
+       if err != nil {
+               return nil, err
+       }
+
+       return cfg, nil
+}
+
+func NewConfigDefault() *Config {
+       cfg := new(Config)
+
+       cfg.DataDir = DefaultDataDir
+
+       cfg.DBName = DefaultDBName
+
+       // disable binlog
+       cfg.BinLog.MaxFileNum = 0
+       cfg.BinLog.MaxFileSize = 0
+
+       // disable replication
+       cfg.SlaveOf = ""
+
+       // disable access log
+       cfg.AccessLog = ""
+
+       cfg.LMDB.MapSize = 20 * 1024 * 1024
+       cfg.LMDB.NoSync = true
+
+       return cfg
+}
+
+func (cfg *LevelDBConfig) Adjust() {
+       if cfg.CacheSize <= 0 {
+               cfg.CacheSize = 4 * 1024 * 1024
+       }
+
+       if cfg.BlockSize <= 0 {
+               cfg.BlockSize = 4 * 1024
+       }
+
+       if cfg.WriteBufferSize <= 0 {
+               cfg.WriteBufferSize = 4 * 1024 * 1024
+       }
+
+       if cfg.MaxOpenFiles < 1024 {
+               cfg.MaxOpenFiles = 1024
+       }
+}
+
+func (cfg *BinLogConfig) Adjust() {
+       if cfg.MaxFileSize <= 0 {
+               cfg.MaxFileSize = DefaultBinLogFileSize
+       } else if cfg.MaxFileSize > MaxBinLogFileSize {
+               cfg.MaxFileSize = MaxBinLogFileSize
+       }
+
+       if cfg.MaxFileNum <= 0 {
+               cfg.MaxFileNum = DefaultBinLogFileNum
+       } else if cfg.MaxFileNum > MaxBinLogFileNum {
+               cfg.MaxFileNum = MaxBinLogFileNum
+       }
+}
diff --git a/vendor/gitea.com/lunny/nodb/config/config.toml b/vendor/gitea.com/lunny/nodb/config/config.toml
new file mode 100644 (file)
index 0000000..2a3a246
--- /dev/null
@@ -0,0 +1,45 @@
+# LedisDB configuration
+
+# Server listen address
+addr = "127.0.0.1:6380"
+
+# Server http listen address, set empty to disable
+http_addr = "127.0.0.1:11181"
+
+# Data store path, all ledisdb's data will be saved here
+data_dir = "/tmp/ledis_server"
+
+# Log server command, set empty to disable
+access_log = ""
+
+# Set slaveof to enable replication from master, empty, no replication
+slaveof = ""
+
+# Choose which backend storage to use, now support:
+#
+#   leveldb
+#   rocksdb
+#   goleveldb
+#   lmdb
+#   boltdb
+#   hyperleveldb
+#   memory
+#   
+db_name = "leveldb"
+
+[leveldb]
+compression = false
+block_size = 32768
+write_buffer_size = 67108864
+cache_size = 524288000
+max_open_files = 1024
+
+[lmdb]
+map_size = 524288000
+nosync = true
+
+[binlog]
+max_file_size = 0
+max_file_num = 0
+
+
diff --git a/vendor/gitea.com/lunny/nodb/const.go b/vendor/gitea.com/lunny/nodb/const.go
new file mode 100644 (file)
index 0000000..446dae6
--- /dev/null
@@ -0,0 +1,98 @@
+package nodb
+
+import (
+       "errors"
+)
+
+const (
+       NoneType    byte = 0
+       KVType      byte = 1
+       HashType    byte = 2
+       HSizeType   byte = 3
+       ListType    byte = 4
+       LMetaType   byte = 5
+       ZSetType    byte = 6
+       ZSizeType   byte = 7
+       ZScoreType  byte = 8
+       BitType     byte = 9
+       BitMetaType byte = 10
+       SetType     byte = 11
+       SSizeType   byte = 12
+
+       maxDataType byte = 100
+
+       ExpTimeType byte = 101
+       ExpMetaType byte = 102
+)
+
+var (
+       TypeName = map[byte]string{
+               KVType:      "kv",
+               HashType:    "hash",
+               HSizeType:   "hsize",
+               ListType:    "list",
+               LMetaType:   "lmeta",
+               ZSetType:    "zset",
+               ZSizeType:   "zsize",
+               ZScoreType:  "zscore",
+               BitType:     "bit",
+               BitMetaType: "bitmeta",
+               SetType:     "set",
+               SSizeType:   "ssize",
+               ExpTimeType: "exptime",
+               ExpMetaType: "expmeta",
+       }
+)
+
+const (
+       defaultScanCount int = 10
+)
+
+var (
+       errKeySize        = errors.New("invalid key size")
+       errValueSize      = errors.New("invalid value size")
+       errHashFieldSize  = errors.New("invalid hash field size")
+       errSetMemberSize  = errors.New("invalid set member size")
+       errZSetMemberSize = errors.New("invalid zset member size")
+       errExpireValue    = errors.New("invalid expire value")
+)
+
+const (
+       //we don't support too many databases
+       MaxDBNumber uint8 = 16
+
+       //max key size
+       MaxKeySize int = 1024
+
+       //max hash field size
+       MaxHashFieldSize int = 1024
+
+       //max zset member size
+       MaxZSetMemberSize int = 1024
+
+       //max set member size
+       MaxSetMemberSize int = 1024
+
+       //max value size
+       MaxValueSize int = 10 * 1024 * 1024
+)
+
+var (
+       ErrScoreMiss = errors.New("zset score miss")
+)
+
+const (
+       BinLogTypeDeletion uint8 = 0x0
+       BinLogTypePut      uint8 = 0x1
+       BinLogTypeCommand  uint8 = 0x2
+)
+
+const (
+       DBAutoCommit    uint8 = 0x0
+       DBInTransaction uint8 = 0x1
+       DBInMulti       uint8 = 0x2
+)
+
+var (
+       Version = "0.1"
+)
diff --git a/vendor/gitea.com/lunny/nodb/doc.go b/vendor/gitea.com/lunny/nodb/doc.go
new file mode 100644 (file)
index 0000000..2f7df33
--- /dev/null
@@ -0,0 +1,61 @@
+// package nodb is a high performance embedded NoSQL.
+//
+// nodb supports various data structure like kv, list, hash and zset like redis.
+//
+// Other features include binlog replication, data with a limited time-to-live.
+//
+// Usage
+//
+// First create a nodb instance before use:
+//
+//  l := nodb.Open(cfg)
+//
+// cfg is a Config instance which contains configuration for nodb use,
+// like DataDir (root directory for nodb working to store data).
+//
+// After you create a nodb instance, you can select a DB to store you data:
+//
+//  db, _ := l.Select(0)
+//
+// DB must be selected by a index, nodb supports only 16 databases, so the index range is [0-15].
+//
+// KV
+//
+// KV is the most basic nodb type like any other key-value database.
+//
+//  err := db.Set(key, value)
+//  value, err := db.Get(key)
+//
+// List
+//
+// List is simply lists of values, sorted by insertion order.
+// You can push or pop value on the list head (left) or tail (right).
+//
+//  err := db.LPush(key, value1)
+//  err := db.RPush(key, value2)
+//  value1, err := db.LPop(key)
+//  value2, err := db.RPop(key)
+//
+// Hash
+//
+// Hash is a map between fields and values.
+//
+//  n, err := db.HSet(key, field1, value1)
+//  n, err := db.HSet(key, field2, value2)
+//  value1, err := db.HGet(key, field1)
+//  value2, err := db.HGet(key, field2)
+//
+// ZSet
+//
+// ZSet is a sorted collections of values.
+// Every member of zset is associated with score, a int64 value which used to sort, from smallest to greatest score.
+// Members are unique, but score may be same.
+//
+//  n, err := db.ZAdd(key, ScorePair{score1, member1}, ScorePair{score2, member2})
+//  ay, err := db.ZRangeByScore(key, minScore, maxScore, 0, -1)
+//
+// Binlog
+//
+// nodb supports binlog, so you can sync binlog to another server for replication. If you want to open binlog support, set UseBinLog to true in config.
+//
+package nodb
diff --git a/vendor/gitea.com/lunny/nodb/dump.go b/vendor/gitea.com/lunny/nodb/dump.go
new file mode 100644 (file)
index 0000000..3c9722e
--- /dev/null
@@ -0,0 +1,200 @@
+package nodb
+
+import (
+       "bufio"
+       "bytes"
+       "encoding/binary"
+       "io"
+       "os"
+
+       "github.com/siddontang/go-snappy/snappy"
+)
+
+//dump format
+// fileIndex(bigendian int64)|filePos(bigendian int64)
+// |keylen(bigendian int32)|key|valuelen(bigendian int32)|value......
+//
+//key and value are both compressed for fast transfer dump on network using snappy
+
+type BinLogAnchor struct {
+       LogFileIndex int64
+       LogPos       int64
+}
+
+func (m *BinLogAnchor) WriteTo(w io.Writer) error {
+       if err := binary.Write(w, binary.BigEndian, m.LogFileIndex); err != nil {
+               return err
+       }
+
+       if err := binary.Write(w, binary.BigEndian, m.LogPos); err != nil {
+               return err
+       }
+       return nil
+}
+
+func (m *BinLogAnchor) ReadFrom(r io.Reader) error {
+       err := binary.Read(r, binary.BigEndian, &m.LogFileIndex)
+       if err != nil {
+               return err
+       }
+
+       err = binary.Read(r, binary.BigEndian, &m.LogPos)
+       if err != nil {
+               return err
+       }
+
+       return nil
+}
+
+func (l *Nodb) DumpFile(path string) error {
+       f, err := os.Create(path)
+       if err != nil {
+               return err
+       }
+       defer f.Close()
+
+       return l.Dump(f)
+}
+
+func (l *Nodb) Dump(w io.Writer) error {
+       m := new(BinLogAnchor)
+
+       var err error
+
+       l.wLock.Lock()
+       defer l.wLock.Unlock()
+
+       if l.binlog != nil {
+               m.LogFileIndex = l.binlog.LogFileIndex()
+               m.LogPos = l.binlog.LogFilePos()
+       }
+
+       wb := bufio.NewWriterSize(w, 4096)
+       if err = m.WriteTo(wb); err != nil {
+               return err
+       }
+
+       it := l.ldb.NewIterator()
+       it.SeekToFirst()
+
+       compressBuf := make([]byte, 4096)
+
+       var key []byte
+       var value []byte
+       for ; it.Valid(); it.Next() {
+               key = it.RawKey()
+               value = it.RawValue()
+
+               if key, err = snappy.Encode(compressBuf, key); err != nil {
+                       return err
+               }
+
+               if err = binary.Write(wb, binary.BigEndian, uint16(len(key))); err != nil {
+                       return err
+               }
+
+               if _, err = wb.Write(key); err != nil {
+                       return err
+               }
+
+               if value, err = snappy.Encode(compressBuf, value); err != nil {
+                       return err
+               }
+
+               if err = binary.Write(wb, binary.BigEndian, uint32(len(value))); err != nil {
+                       return err
+               }
+
+               if _, err = wb.Write(value); err != nil {
+                       return err
+               }
+       }
+
+       if err = wb.Flush(); err != nil {
+               return err
+       }
+
+       compressBuf = nil
+
+       return nil
+}
+
+func (l *Nodb) LoadDumpFile(path string) (*BinLogAnchor, error) {
+       f, err := os.Open(path)
+       if err != nil {
+               return nil, err
+       }
+       defer f.Close()
+
+       return l.LoadDump(f)
+}
+
+func (l *Nodb) LoadDump(r io.Reader) (*BinLogAnchor, error) {
+       l.wLock.Lock()
+       defer l.wLock.Unlock()
+
+       info := new(BinLogAnchor)
+
+       rb := bufio.NewReaderSize(r, 4096)
+
+       err := info.ReadFrom(rb)
+       if err != nil {
+               return nil, err
+       }
+
+       var keyLen uint16
+       var valueLen uint32
+
+       var keyBuf bytes.Buffer
+       var valueBuf bytes.Buffer
+
+       deKeyBuf := make([]byte, 4096)
+       deValueBuf := make([]byte, 4096)
+
+       var key, value []byte
+
+       for {
+               if err = binary.Read(rb, binary.BigEndian, &keyLen); err != nil && err != io.EOF {
+                       return nil, err
+               } else if err == io.EOF {
+                       break
+               }
+
+               if _, err = io.CopyN(&keyBuf, rb, int64(keyLen)); err != nil {
+                       return nil, err
+               }
+
+               if key, err = snappy.Decode(deKeyBuf, keyBuf.Bytes()); err != nil {
+                       return nil, err
+               }
+
+               if err = binary.Read(rb, binary.BigEndian, &valueLen); err != nil {
+                       return nil, err
+               }
+
+               if _, err = io.CopyN(&valueBuf, rb, int64(valueLen)); err != nil {
+                       return nil, err
+               }
+
+               if value, err = snappy.Decode(deValueBuf, valueBuf.Bytes()); err != nil {
+                       return nil, err
+               }
+
+               if err = l.ldb.Put(key, value); err != nil {
+                       return nil, err
+               }
+
+               keyBuf.Reset()
+               valueBuf.Reset()
+       }
+
+       deKeyBuf = nil
+       deValueBuf = nil
+
+       //if binlog enable, we will delete all binlogs and open a new one for handling simply
+       if l.binlog != nil {
+               l.binlog.PurgeAll()
+       }
+
+       return info, nil
+}
diff --git a/vendor/gitea.com/lunny/nodb/go.mod b/vendor/gitea.com/lunny/nodb/go.mod
new file mode 100644 (file)
index 0000000..ae0ed81
--- /dev/null
@@ -0,0 +1,11 @@
+module gitea.com/lunny/nodb
+
+go 1.12
+
+require (
+       gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e
+       github.com/mattn/go-sqlite3 v1.11.0 // indirect
+       github.com/pelletier/go-toml v1.8.1
+       github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d
+       github.com/syndtr/goleveldb v1.0.0
+)
diff --git a/vendor/gitea.com/lunny/nodb/go.sum b/vendor/gitea.com/lunny/nodb/go.sum
new file mode 100644 (file)
index 0000000..91ae7d1
--- /dev/null
@@ -0,0 +1,42 @@
+gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e h1:r1en/D7xJmcY24VkHkjkcJFa+7ZWubVWPBrvsHkmHxk=
+gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e/go.mod h1:uJEsN4LQpeGYRCjuPXPZBClU7N5pWzGuyF4uqLpE/e0=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
+github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
+github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
+github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d h1:qQWKKOvHN7Q9c6GdmUteCef2F9ubxMpxY1IKwpIKz68=
+github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d/go.mod h1:vq0tzqLRu6TS7Id0wMo2N5QzJoKedVeovOpHjnykSzY=
+github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
+github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/vendor/gitea.com/lunny/nodb/info.go b/vendor/gitea.com/lunny/nodb/info.go
new file mode 100644 (file)
index 0000000..3fd37e3
--- /dev/null
@@ -0,0 +1,24 @@
+package nodb
+
+// todo, add info
+
+// type Keyspace struct {
+//     Kvs       int `json:"kvs"`
+//     KvExpires int `json:"kv_expires"`
+
+//     Lists       int `json:"lists"`
+//     ListExpires int `json:"list_expires"`
+
+//     Bitmaps       int `json:"bitmaps"`
+//     BitmapExpires int `json:"bitmap_expires"`
+
+//     ZSets       int `json:"zsets"`
+//     ZSetExpires int `json:"zset_expires"`
+
+//     Hashes      int `json:"hashes"`
+//     HashExpires int `json:"hahsh_expires"`
+// }
+
+// type Info struct {
+//     KeySpaces [MaxDBNumber]Keyspace
+// }
diff --git a/vendor/gitea.com/lunny/nodb/multi.go b/vendor/gitea.com/lunny/nodb/multi.go
new file mode 100644 (file)
index 0000000..ca581ce
--- /dev/null
@@ -0,0 +1,73 @@
+package nodb
+
+import (
+       "errors"
+       "fmt"
+)
+
+var (
+       ErrNestMulti = errors.New("nest multi not supported")
+       ErrMultiDone = errors.New("multi has been closed")
+)
+
+type Multi struct {
+       *DB
+}
+
+func (db *DB) IsInMulti() bool {
+       return db.status == DBInMulti
+}
+
+// begin a mutli to execute commands,
+// it will block any other write operations before you close the multi, unlike transaction, mutli can not rollback
+func (db *DB) Multi() (*Multi, error) {
+       if db.IsInMulti() {
+               return nil, ErrNestMulti
+       }
+
+       m := new(Multi)
+
+       m.DB = new(DB)
+       m.DB.status = DBInMulti
+
+       m.DB.l = db.l
+
+       m.l.wLock.Lock()
+
+       m.DB.sdb = db.sdb
+
+       m.DB.bucket = db.sdb
+
+       m.DB.index = db.index
+
+       m.DB.kvBatch = m.newBatch()
+       m.DB.listBatch = m.newBatch()
+       m.DB.hashBatch = m.newBatch()
+       m.DB.zsetBatch = m.newBatch()
+       m.DB.binBatch = m.newBatch()
+       m.DB.setBatch = m.newBatch()
+
+       return m, nil
+}
+
+func (m *Multi) newBatch() *batch {
+       return m.l.newBatch(m.bucket.NewWriteBatch(), &multiBatchLocker{}, nil)
+}
+
+func (m *Multi) Close() error {
+       if m.bucket == nil {
+               return ErrMultiDone
+       }
+       m.l.wLock.Unlock()
+       m.bucket = nil
+       return nil
+}
+
+func (m *Multi) Select(index int) error {
+       if index < 0 || index >= int(MaxDBNumber) {
+               return fmt.Errorf("invalid db index %d", index)
+       }
+
+       m.DB.index = uint8(index)
+       return nil
+}
diff --git a/vendor/gitea.com/lunny/nodb/nodb.go b/vendor/gitea.com/lunny/nodb/nodb.go
new file mode 100644 (file)
index 0000000..b487579
--- /dev/null
@@ -0,0 +1,128 @@
+package nodb
+
+import (
+       "fmt"
+       "sync"
+       "time"
+
+       "gitea.com/lunny/nodb/config"
+       "gitea.com/lunny/nodb/store"
+       "gitea.com/lunny/log"
+)
+
+type Nodb struct {
+       cfg *config.Config
+
+       ldb *store.DB
+       dbs [MaxDBNumber]*DB
+
+       quit chan struct{}
+       jobs *sync.WaitGroup
+
+       binlog *BinLog
+
+       wLock      sync.RWMutex //allow one write at same time
+       commitLock sync.Mutex   //allow one write commit at same time
+}
+
+func Open(cfg *config.Config) (*Nodb, error) {
+       if len(cfg.DataDir) == 0 {
+               cfg.DataDir = config.DefaultDataDir
+       }
+
+       ldb, err := store.Open(cfg)
+       if err != nil {
+               return nil, err
+       }
+
+       l := new(Nodb)
+
+       l.quit = make(chan struct{})
+       l.jobs = new(sync.WaitGroup)
+
+       l.ldb = ldb
+
+       if cfg.BinLog.MaxFileNum > 0 && cfg.BinLog.MaxFileSize > 0 {
+               l.binlog, err = NewBinLog(cfg)
+               if err != nil {
+                       return nil, err
+               }
+       } else {
+               l.binlog = nil
+       }
+
+       for i := uint8(0); i < MaxDBNumber; i++ {
+               l.dbs[i] = l.newDB(i)
+       }
+
+       l.activeExpireCycle()
+
+       return l, nil
+}
+
+func (l *Nodb) Close() {
+       close(l.quit)
+       l.jobs.Wait()
+
+       l.ldb.Close()
+
+       if l.binlog != nil {
+               l.binlog.Close()
+               l.binlog = nil
+       }
+}
+
+func (l *Nodb) Select(index int) (*DB, error) {
+       if index < 0 || index >= int(MaxDBNumber) {
+               return nil, fmt.Errorf("invalid db index %d", index)
+       }
+
+       return l.dbs[index], nil
+}
+
+func (l *Nodb) FlushAll() error {
+       for index, db := range l.dbs {
+               if _, err := db.FlushAll(); err != nil {
+                       log.Errorf("flush db %d error %s", index, err.Error())
+               }
+       }
+
+       return nil
+}
+
+// very dangerous to use
+func (l *Nodb) DataDB() *store.DB {
+       return l.ldb
+}
+
+func (l *Nodb) activeExpireCycle() {
+       var executors []*elimination = make([]*elimination, len(l.dbs))
+       for i, db := range l.dbs {
+               executors[i] = db.newEliminator()
+       }
+
+       l.jobs.Add(1)
+       go func() {
+               tick := time.NewTicker(1 * time.Second)
+               end := false
+               done := make(chan struct{})
+               for !end {
+                       select {
+                       case <-tick.C:
+                               go func() {
+                                       for _, eli := range executors {
+                                               eli.active()
+                                       }
+                                       done <- struct{}{}
+                               }()
+                               <-done
+                       case <-l.quit:
+                               end = true
+                               break
+                       }
+               }
+
+               tick.Stop()
+               l.jobs.Done()
+       }()
+}
diff --git a/vendor/gitea.com/lunny/nodb/nodb_db.go b/vendor/gitea.com/lunny/nodb/nodb_db.go
new file mode 100644 (file)
index 0000000..76922be
--- /dev/null
@@ -0,0 +1,171 @@
+package nodb
+
+import (
+       "fmt"
+       "sync"
+
+       "gitea.com/lunny/nodb/store"
+)
+
+type ibucket interface {
+       Get(key []byte) ([]byte, error)
+
+       Put(key []byte, value []byte) error
+       Delete(key []byte) error
+
+       NewIterator() *store.Iterator
+
+       NewWriteBatch() store.WriteBatch
+
+       RangeIterator(min []byte, max []byte, rangeType uint8) *store.RangeLimitIterator
+       RevRangeIterator(min []byte, max []byte, rangeType uint8) *store.RangeLimitIterator
+       RangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *store.RangeLimitIterator
+       RevRangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *store.RangeLimitIterator
+}
+
+type DB struct {
+       l *Nodb
+
+       sdb *store.DB
+
+       bucket ibucket
+
+       index uint8
+
+       kvBatch   *batch
+       listBatch *batch
+       hashBatch *batch
+       zsetBatch *batch
+       binBatch  *batch
+       setBatch  *batch
+
+       status uint8
+}
+
+func (l *Nodb) newDB(index uint8) *DB {
+       d := new(DB)
+
+       d.l = l
+
+       d.sdb = l.ldb
+
+       d.bucket = d.sdb
+
+       d.status = DBAutoCommit
+       d.index = index
+
+       d.kvBatch = d.newBatch()
+       d.listBatch = d.newBatch()
+       d.hashBatch = d.newBatch()
+       d.zsetBatch = d.newBatch()
+       d.binBatch = d.newBatch()
+       d.setBatch = d.newBatch()
+
+       return d
+}
+
+func (db *DB) newBatch() *batch {
+       return db.l.newBatch(db.bucket.NewWriteBatch(), &dbBatchLocker{l: &sync.Mutex{}, wrLock: &db.l.wLock}, nil)
+}
+
+func (db *DB) Index() int {
+       return int(db.index)
+}
+
+func (db *DB) IsAutoCommit() bool {
+       return db.status == DBAutoCommit
+}
+
+func (db *DB) FlushAll() (drop int64, err error) {
+       all := [...](func() (int64, error)){
+               db.flush,
+               db.lFlush,
+               db.hFlush,
+               db.zFlush,
+               db.bFlush,
+               db.sFlush}
+
+       for _, flush := range all {
+               if n, e := flush(); e != nil {
+                       err = e
+                       return
+               } else {
+                       drop += n
+               }
+       }
+
+       return
+}
+
+func (db *DB) newEliminator() *elimination {
+       eliminator := newEliminator(db)
+
+       eliminator.regRetireContext(KVType, db.kvBatch, db.delete)
+       eliminator.regRetireContext(ListType, db.listBatch, db.lDelete)
+       eliminator.regRetireContext(HashType, db.hashBatch, db.hDelete)
+       eliminator.regRetireContext(ZSetType, db.zsetBatch, db.zDelete)
+       eliminator.regRetireContext(BitType, db.binBatch, db.bDelete)
+       eliminator.regRetireContext(SetType, db.setBatch, db.sDelete)
+
+       return eliminator
+}
+
+func (db *DB) flushRegion(t *batch, minKey []byte, maxKey []byte) (drop int64, err error) {
+       it := db.bucket.RangeIterator(minKey, maxKey, store.RangeROpen)
+       for ; it.Valid(); it.Next() {
+               t.Delete(it.RawKey())
+               drop++
+               if drop&1023 == 0 {
+                       if err = t.Commit(); err != nil {
+                               return
+                       }
+               }
+       }
+       it.Close()
+       return
+}
+
+func (db *DB) flushType(t *batch, dataType byte) (drop int64, err error) {
+       var deleteFunc func(t *batch, key []byte) int64
+       var metaDataType byte
+       switch dataType {
+       case KVType:
+               deleteFunc = db.delete
+               metaDataType = KVType
+       case ListType:
+               deleteFunc = db.lDelete
+               metaDataType = LMetaType
+       case HashType:
+               deleteFunc = db.hDelete
+               metaDataType = HSizeType
+       case ZSetType:
+               deleteFunc = db.zDelete
+               metaDataType = ZSizeType
+       case BitType:
+               deleteFunc = db.bDelete
+               metaDataType = BitMetaType
+       case SetType:
+               deleteFunc = db.sDelete
+               metaDataType = SSizeType
+       default:
+               return 0, fmt.Errorf("invalid data type: %s", TypeName[dataType])
+       }
+
+       var keys [][]byte
+       keys, err = db.scan(metaDataType, nil, 1024, false, "")
+       for len(keys) != 0 || err != nil {
+               for _, key := range keys {
+                       deleteFunc(t, key)
+                       db.rmExpire(t, dataType, key)
+
+               }
+
+               if err = t.Commit(); err != nil {
+                       return
+               } else {
+                       drop += int64(len(keys))
+               }
+               keys, err = db.scan(metaDataType, nil, 1024, false, "")
+       }
+       return
+}
diff --git a/vendor/gitea.com/lunny/nodb/replication.go b/vendor/gitea.com/lunny/nodb/replication.go
new file mode 100644 (file)
index 0000000..c2153f4
--- /dev/null
@@ -0,0 +1,312 @@
+package nodb
+
+import (
+       "bufio"
+       "bytes"
+       "errors"
+       "io"
+       "os"
+       "time"
+
+       "gitea.com/lunny/log"
+       "gitea.com/lunny/nodb/store/driver"
+)
+
+const (
+       maxReplBatchNum = 100
+       maxReplLogSize  = 1 * 1024 * 1024
+)
+
+var (
+       ErrSkipEvent = errors.New("skip to next event")
+)
+
+var (
+       errInvalidBinLogEvent = errors.New("invalid binglog event")
+       errInvalidBinLogFile  = errors.New("invalid binlog file")
+)
+
+type replBatch struct {
+       wb     driver.IWriteBatch
+       events [][]byte
+       l      *Nodb
+
+       lastHead *BinLogHead
+}
+
+func (b *replBatch) Commit() error {
+       b.l.commitLock.Lock()
+       defer b.l.commitLock.Unlock()
+
+       err := b.wb.Commit()
+       if err != nil {
+               b.Rollback()
+               return err
+       }
+
+       if b.l.binlog != nil {
+               if err = b.l.binlog.Log(b.events...); err != nil {
+                       b.Rollback()
+                       return err
+               }
+       }
+
+       b.events = [][]byte{}
+       b.lastHead = nil
+
+       return nil
+}
+
+func (b *replBatch) Rollback() error {
+       b.wb.Rollback()
+       b.events = [][]byte{}
+       b.lastHead = nil
+       return nil
+}
+
+func (l *Nodb) replicateEvent(b *replBatch, event []byte) error {
+       if len(event) == 0 {
+               return errInvalidBinLogEvent
+       }
+
+       b.events = append(b.events, event)
+
+       logType := uint8(event[0])
+       switch logType {
+       case BinLogTypePut:
+               return l.replicatePutEvent(b, event)
+       case BinLogTypeDeletion:
+               return l.replicateDeleteEvent(b, event)
+       default:
+               return errInvalidBinLogEvent
+       }
+}
+
+func (l *Nodb) replicatePutEvent(b *replBatch, event []byte) error {
+       key, value, err := decodeBinLogPut(event)
+       if err != nil {
+               return err
+       }
+
+       b.wb.Put(key, value)
+
+       return nil
+}
+
+func (l *Nodb) replicateDeleteEvent(b *replBatch, event []byte) error {
+       key, err := decodeBinLogDelete(event)
+       if err != nil {
+               return err
+       }
+
+       b.wb.Delete(key)
+
+       return nil
+}
+
+func ReadEventFromReader(rb io.Reader, f func(head *BinLogHead, event []byte) error) error {
+       head := &BinLogHead{}
+       var err error
+
+       for {
+               if err = head.Read(rb); err != nil {
+                       if err == io.EOF {
+                               break
+                       } else {
+                               return err
+                       }
+               }
+
+               var dataBuf bytes.Buffer
+
+               if _, err = io.CopyN(&dataBuf, rb, int64(head.PayloadLen)); err != nil {
+                       return err
+               }
+
+               err = f(head, dataBuf.Bytes())
+               if err != nil && err != ErrSkipEvent {
+                       return err
+               }
+       }
+
+       return nil
+}
+
+func (l *Nodb) ReplicateFromReader(rb io.Reader) error {
+       b := new(replBatch)
+
+       b.wb = l.ldb.NewWriteBatch()
+       b.l = l
+
+       f := func(head *BinLogHead, event []byte) error {
+               if b.lastHead == nil {
+                       b.lastHead = head
+               } else if !b.lastHead.InSameBatch(head) {
+                       if err := b.Commit(); err != nil {
+                               log.Fatalf("replication error %s, skip to next", err.Error())
+                               return ErrSkipEvent
+                       }
+                       b.lastHead = head
+               }
+
+               err := l.replicateEvent(b, event)
+               if err != nil {
+                       log.Fatalf("replication error %s, skip to next", err.Error())
+                       return ErrSkipEvent
+               }
+               return nil
+       }
+
+       err := ReadEventFromReader(rb, f)
+       if err != nil {
+               b.Rollback()
+               return err
+       }
+       return b.Commit()
+}
+
+func (l *Nodb) ReplicateFromData(data []byte) error {
+       rb := bytes.NewReader(data)
+
+       err := l.ReplicateFromReader(rb)
+
+       return err
+}
+
+func (l *Nodb) ReplicateFromBinLog(filePath string) error {
+       f, err := os.Open(filePath)
+       if err != nil {
+               return err
+       }
+
+       rb := bufio.NewReaderSize(f, 4096)
+
+       err = l.ReplicateFromReader(rb)
+
+       f.Close()
+
+       return err
+}
+
+// try to read events, if no events read, try to wait the new event singal until timeout seconds
+func (l *Nodb) ReadEventsToTimeout(info *BinLogAnchor, w io.Writer, timeout int) (n int, err error) {
+       lastIndex := info.LogFileIndex
+       lastPos := info.LogPos
+
+       n = 0
+       if l.binlog == nil {
+               //binlog not supported
+               info.LogFileIndex = 0
+               info.LogPos = 0
+               return
+       }
+
+       n, err = l.ReadEventsTo(info, w)
+       if err == nil && info.LogFileIndex == lastIndex && info.LogPos == lastPos {
+               //no events read
+               select {
+               case <-l.binlog.Wait():
+               case <-time.After(time.Duration(timeout) * time.Second):
+               }
+               return l.ReadEventsTo(info, w)
+       }
+       return
+}
+
+func (l *Nodb) ReadEventsTo(info *BinLogAnchor, w io.Writer) (n int, err error) {
+       n = 0
+       if l.binlog == nil {
+               //binlog not supported
+               info.LogFileIndex = 0
+               info.LogPos = 0
+               return
+       }
+
+       index := info.LogFileIndex
+       offset := info.LogPos
+
+       filePath := l.binlog.FormatLogFilePath(index)
+
+       var f *os.File
+       f, err = os.Open(filePath)
+       if os.IsNotExist(err) {
+               lastIndex := l.binlog.LogFileIndex()
+
+               if index == lastIndex {
+                       //no binlog at all
+                       info.LogPos = 0
+               } else {
+                       //slave binlog info had lost
+                       info.LogFileIndex = -1
+               }
+       }
+
+       if err != nil {
+               if os.IsNotExist(err) {
+                       err = nil
+               }
+               return
+       }
+
+       defer f.Close()
+
+       var fileSize int64
+       st, _ := f.Stat()
+       fileSize = st.Size()
+
+       if fileSize == info.LogPos {
+               return
+       }
+
+       if _, err = f.Seek(offset, os.SEEK_SET); err != nil {
+               //may be invliad seek offset
+               return
+       }
+
+       var lastHead *BinLogHead = nil
+
+       head := &BinLogHead{}
+
+       batchNum := 0
+
+       for {
+               if err = head.Read(f); err != nil {
+                       if err == io.EOF {
+                               //we will try to use next binlog
+                               if index < l.binlog.LogFileIndex() {
+                                       info.LogFileIndex += 1
+                                       info.LogPos = 0
+                               }
+                               err = nil
+                               return
+                       } else {
+                               return
+                       }
+
+               }
+
+               if lastHead == nil {
+                       lastHead = head
+                       batchNum++
+               } else if !lastHead.InSameBatch(head) {
+                       lastHead = head
+                       batchNum++
+                       if batchNum > maxReplBatchNum || n > maxReplLogSize {
+                               return
+                       }
+               }
+
+               if err = head.Write(w); err != nil {
+                       return
+               }
+
+               if _, err = io.CopyN(w, f, int64(head.PayloadLen)); err != nil {
+                       return
+               }
+
+               n += (head.Len() + int(head.PayloadLen))
+               info.LogPos = info.LogPos + int64(head.Len()) + int64(head.PayloadLen)
+       }
+
+       return
+}
diff --git a/vendor/gitea.com/lunny/nodb/scan.go b/vendor/gitea.com/lunny/nodb/scan.go
new file mode 100644 (file)
index 0000000..fc0bdfb
--- /dev/null
@@ -0,0 +1,144 @@
+package nodb
+
+import (
+       "bytes"
+       "errors"
+       "regexp"
+
+       "gitea.com/lunny/nodb/store"
+)
+
+var errDataType = errors.New("error data type")
+var errMetaKey = errors.New("error meta key")
+
+// Seek search the prefix key
+func (db *DB) Seek(key []byte) (*store.Iterator, error) {
+       return db.seek(KVType, key)
+}
+
+func (db *DB) seek(dataType byte, key []byte) (*store.Iterator, error) {
+       var minKey []byte
+       var err error
+
+       if len(key) > 0 {
+               if err = checkKeySize(key); err != nil {
+                       return nil, err
+               }
+               if minKey, err = db.encodeMetaKey(dataType, key); err != nil {
+                       return nil, err
+               }
+
+       } else {
+               if minKey, err = db.encodeMinKey(dataType); err != nil {
+                       return nil, err
+               }
+       }
+
+       it := db.bucket.NewIterator()
+       it.Seek(minKey)
+       return it, nil
+}
+
+func (db *DB) MaxKey() ([]byte, error) {
+       return db.encodeMaxKey(KVType)
+}
+
+func (db *DB) Key(it *store.Iterator) ([]byte, error) {
+       return db.decodeMetaKey(KVType, it.Key())
+}
+
+func (db *DB) scan(dataType byte, key []byte, count int, inclusive bool, match string) ([][]byte, error) {
+       var minKey, maxKey []byte
+       var err error
+       var r *regexp.Regexp
+
+       if len(match) > 0 {
+               if r, err = regexp.Compile(match); err != nil {
+                       return nil, err
+               }
+       }
+
+       if len(key) > 0 {
+               if err = checkKeySize(key); err != nil {
+                       return nil, err
+               }
+               if minKey, err = db.encodeMetaKey(dataType, key); err != nil {
+                       return nil, err
+               }
+
+       } else {
+               if minKey, err = db.encodeMinKey(dataType); err != nil {
+                       return nil, err
+               }
+       }
+
+       if maxKey, err = db.encodeMaxKey(dataType); err != nil {
+               return nil, err
+       }
+
+       if count <= 0 {
+               count = defaultScanCount
+       }
+
+       v := make([][]byte, 0, count)
+
+       it := db.bucket.NewIterator()
+       it.Seek(minKey)
+
+       if !inclusive {
+               if it.Valid() && bytes.Equal(it.RawKey(), minKey) {
+                       it.Next()
+               }
+       }
+
+       for i := 0; it.Valid() && i < count && bytes.Compare(it.RawKey(), maxKey) < 0; it.Next() {
+               if k, err := db.decodeMetaKey(dataType, it.Key()); err != nil {
+                       continue
+               } else if r != nil && !r.Match(k) {
+                       continue
+               } else {
+                       v = append(v, k)
+                       i++
+               }
+       }
+       it.Close()
+       return v, nil
+}
+
+func (db *DB) encodeMinKey(dataType byte) ([]byte, error) {
+       return db.encodeMetaKey(dataType, nil)
+}
+
+func (db *DB) encodeMaxKey(dataType byte) ([]byte, error) {
+       k, err := db.encodeMetaKey(dataType, nil)
+       if err != nil {
+               return nil, err
+       }
+       k[len(k)-1] = dataType + 1
+       return k, nil
+}
+
+func (db *DB) encodeMetaKey(dataType byte, key []byte) ([]byte, error) {
+       switch dataType {
+       case KVType:
+               return db.encodeKVKey(key), nil
+       case LMetaType:
+               return db.lEncodeMetaKey(key), nil
+       case HSizeType:
+               return db.hEncodeSizeKey(key), nil
+       case ZSizeType:
+               return db.zEncodeSizeKey(key), nil
+       case BitMetaType:
+               return db.bEncodeMetaKey(key), nil
+       case SSizeType:
+               return db.sEncodeSizeKey(key), nil
+       default:
+               return nil, errDataType
+       }
+}
+func (db *DB) decodeMetaKey(dataType byte, ek []byte) ([]byte, error) {
+       if len(ek) < 2 || ek[0] != db.index || ek[1] != dataType {
+               return nil, errMetaKey
+       }
+       return ek[2:], nil
+}
diff --git a/vendor/gitea.com/lunny/nodb/store/db.go b/vendor/gitea.com/lunny/nodb/store/db.go
new file mode 100644 (file)
index 0000000..fb0cf2d
--- /dev/null
@@ -0,0 +1,61 @@
+package store
+
+import (
+       "gitea.com/lunny/nodb/store/driver"
+)
+
+type DB struct {
+       driver.IDB
+}
+
+func (db *DB) NewIterator() *Iterator {
+       it := new(Iterator)
+       it.it = db.IDB.NewIterator()
+
+       return it
+}
+
+func (db *DB) NewWriteBatch() WriteBatch {
+       return db.IDB.NewWriteBatch()
+}
+
+func (db *DB) NewSnapshot() (*Snapshot, error) {
+       var err error
+       s := &Snapshot{}
+       if s.ISnapshot, err = db.IDB.NewSnapshot(); err != nil {
+               return nil, err
+       }
+
+       return s, nil
+}
+
+func (db *DB) RangeIterator(min []byte, max []byte, rangeType uint8) *RangeLimitIterator {
+       return NewRangeLimitIterator(db.NewIterator(), &Range{min, max, rangeType}, &Limit{0, -1})
+}
+
+func (db *DB) RevRangeIterator(min []byte, max []byte, rangeType uint8) *RangeLimitIterator {
+       return NewRevRangeLimitIterator(db.NewIterator(), &Range{min, max, rangeType}, &Limit{0, -1})
+}
+
+//count < 0, unlimit.
+//
+//offset must >= 0, if < 0, will get nothing.
+func (db *DB) RangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *RangeLimitIterator {
+       return NewRangeLimitIterator(db.NewIterator(), &Range{min, max, rangeType}, &Limit{offset, count})
+}
+
+//count < 0, unlimit.
+//
+//offset must >= 0, if < 0, will get nothing.
+func (db *DB) RevRangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *RangeLimitIterator {
+       return NewRevRangeLimitIterator(db.NewIterator(), &Range{min, max, rangeType}, &Limit{offset, count})
+}
+
+func (db *DB) Begin() (*Tx, error) {
+       tx, err := db.IDB.Begin()
+       if err != nil {
+               return nil, err
+       }
+
+       return &Tx{tx}, nil
+}
diff --git a/vendor/gitea.com/lunny/nodb/store/driver/batch.go b/vendor/gitea.com/lunny/nodb/store/driver/batch.go
new file mode 100644 (file)
index 0000000..6b79c21
--- /dev/null
@@ -0,0 +1,39 @@
+package driver
+
+type BatchPuter interface {
+       BatchPut([]Write) error
+}
+
+type Write struct {
+       Key   []byte
+       Value []byte
+}
+
+type WriteBatch struct {
+       batch BatchPuter
+       wb    []Write
+}
+
+func (w *WriteBatch) Put(key, value []byte) {
+       if value == nil {
+               value = []byte{}
+       }
+       w.wb = append(w.wb, Write{key, value})
+}
+
+func (w *WriteBatch) Delete(key []byte) {
+       w.wb = append(w.wb, Write{key, nil})
+}
+
+func (w *WriteBatch) Commit() error {
+       return w.batch.BatchPut(w.wb)
+}
+
+func (w *WriteBatch) Rollback() error {
+       w.wb = w.wb[0:0]
+       return nil
+}
+
+func NewWriteBatch(puter BatchPuter) IWriteBatch {
+       return &WriteBatch{puter, []Write{}}
+}
diff --git a/vendor/gitea.com/lunny/nodb/store/driver/driver.go b/vendor/gitea.com/lunny/nodb/store/driver/driver.go
new file mode 100644 (file)
index 0000000..6da67df
--- /dev/null
@@ -0,0 +1,67 @@
+package driver
+
+import (
+       "errors"
+)
+
+var (
+       ErrTxSupport = errors.New("transaction is not supported")
+)
+
+type IDB interface {
+       Close() error
+
+       Get(key []byte) ([]byte, error)
+
+       Put(key []byte, value []byte) error
+       Delete(key []byte) error
+
+       NewIterator() IIterator
+
+       NewWriteBatch() IWriteBatch
+
+       NewSnapshot() (ISnapshot, error)
+
+       Begin() (Tx, error)
+}
+
+type ISnapshot interface {
+       Get(key []byte) ([]byte, error)
+       NewIterator() IIterator
+       Close()
+}
+
+type IIterator interface {
+       Close() error
+
+       First()
+       Last()
+       Seek(key []byte)
+
+       Next()
+       Prev()
+
+       Valid() bool
+
+       Key() []byte
+       Value() []byte
+}
+
+type IWriteBatch interface {
+       Put(key []byte, value []byte)
+       Delete(key []byte)
+       Commit() error
+       Rollback() error
+}
+
+type Tx interface {
+       Get(key []byte) ([]byte, error)
+       Put(key []byte, value []byte) error
+       Delete(key []byte) error
+
+       NewIterator() IIterator
+       NewWriteBatch() IWriteBatch
+
+       Commit() error
+       Rollback() error
+}
diff --git a/vendor/gitea.com/lunny/nodb/store/driver/store.go b/vendor/gitea.com/lunny/nodb/store/driver/store.go
new file mode 100644 (file)
index 0000000..a64d226
--- /dev/null
@@ -0,0 +1,46 @@
+package driver
+
+import (
+       "fmt"
+
+       "gitea.com/lunny/nodb/config"
+)
+
+type Store interface {
+       String() string
+       Open(path string, cfg *config.Config) (IDB, error)
+       Repair(path string, cfg *config.Config) error
+}
+
+var dbs = map[string]Store{}
+
+func Register(s Store) {
+       name := s.String()
+       if _, ok := dbs[name]; ok {
+               panic(fmt.Errorf("store %s is registered", s))
+       }
+
+       dbs[name] = s
+}
+
+func ListStores() []string {
+       s := []string{}
+       for k, _ := range dbs {
+               s = append(s, k)
+       }
+
+       return s
+}
+
+func GetStore(cfg *config.Config) (Store, error) {
+       if len(cfg.DBName) == 0 {
+               cfg.DBName = config.DefaultDBName
+       }
+
+       s, ok := dbs[cfg.DBName]
+       if !ok {
+               return nil, fmt.Errorf("store %s is not registered", cfg.DBName)
+       }
+
+       return s, nil
+}
diff --git a/vendor/gitea.com/lunny/nodb/store/goleveldb/batch.go b/vendor/gitea.com/lunny/nodb/store/goleveldb/batch.go
new file mode 100644 (file)
index 0000000..b17e85e
--- /dev/null
@@ -0,0 +1,27 @@
+package goleveldb
+
+import (
+       "github.com/syndtr/goleveldb/leveldb"
+)
+
+type WriteBatch struct {
+       db     *DB
+       wbatch *leveldb.Batch
+}
+
+func (w *WriteBatch) Put(key, value []byte) {
+       w.wbatch.Put(key, value)
+}
+
+func (w *WriteBatch) Delete(key []byte) {
+       w.wbatch.Delete(key)
+}
+
+func (w *WriteBatch) Commit() error {
+       return w.db.db.Write(w.wbatch, nil)
+}
+
+func (w *WriteBatch) Rollback() error {
+       w.wbatch.Reset()
+       return nil
+}
diff --git a/vendor/gitea.com/lunny/nodb/store/goleveldb/const.go b/vendor/gitea.com/lunny/nodb/store/goleveldb/const.go
new file mode 100644 (file)
index 0000000..2fffa7c
--- /dev/null
@@ -0,0 +1,4 @@
+package goleveldb
+
+const DBName = "goleveldb"
+const MemDBName = "memory"
diff --git a/vendor/gitea.com/lunny/nodb/store/goleveldb/db.go b/vendor/gitea.com/lunny/nodb/store/goleveldb/db.go
new file mode 100644 (file)
index 0000000..a3c98e9
--- /dev/null
@@ -0,0 +1,187 @@
+package goleveldb
+
+import (
+       "github.com/syndtr/goleveldb/leveldb"
+       "github.com/syndtr/goleveldb/leveldb/cache"
+       "github.com/syndtr/goleveldb/leveldb/filter"
+       "github.com/syndtr/goleveldb/leveldb/opt"
+       "github.com/syndtr/goleveldb/leveldb/storage"
+
+       "gitea.com/lunny/nodb/config"
+       "gitea.com/lunny/nodb/store/driver"
+
+       "os"
+)
+
+const defaultFilterBits int = 10
+
+type Store struct {
+}
+
+func (s Store) String() string {
+       return DBName
+}
+
+type MemStore struct {
+}
+
+func (s MemStore) String() string {
+       return MemDBName
+}
+
+type DB struct {
+       path string
+
+       cfg *config.LevelDBConfig
+
+       db *leveldb.DB
+
+       opts *opt.Options
+
+       iteratorOpts *opt.ReadOptions
+
+       cache cache.Cache
+
+       filter filter.Filter
+}
+
+func (s Store) Open(path string, cfg *config.Config) (driver.IDB, error) {
+       if err := os.MkdirAll(path, os.ModePerm); err != nil {
+               return nil, err
+       }
+
+       db := new(DB)
+       db.path = path
+       db.cfg = &cfg.LevelDB
+
+       db.initOpts()
+
+       var err error
+       db.db, err = leveldb.OpenFile(db.path, db.opts)
+
+       if err != nil {
+               return nil, err
+       }
+
+       return db, nil
+}
+
+func (s Store) Repair(path string, cfg *config.Config) error {
+       db, err := leveldb.RecoverFile(path, newOptions(&cfg.LevelDB))
+       if err != nil {
+               return err
+       }
+
+       db.Close()
+       return nil
+}
+
+func (s MemStore) Open(path string, cfg *config.Config) (driver.IDB, error) {
+       db := new(DB)
+       db.path = path
+       db.cfg = &cfg.LevelDB
+
+       db.initOpts()
+
+       var err error
+       db.db, err = leveldb.Open(storage.NewMemStorage(), db.opts)
+       if err != nil {
+               return nil, err
+       }
+
+       return db, nil
+}
+
+func (s MemStore) Repair(path string, cfg *config.Config) error {
+       return nil
+}
+
+func (db *DB) initOpts() {
+       db.opts = newOptions(db.cfg)
+
+       db.iteratorOpts = &opt.ReadOptions{}
+       db.iteratorOpts.DontFillCache = true
+}
+
+func newOptions(cfg *config.LevelDBConfig) *opt.Options {
+       opts := &opt.Options{}
+       opts.ErrorIfMissing = false
+
+       cfg.Adjust()
+
+       //opts.BlockCacher = cache.NewLRU(cfg.CacheSize)
+       opts.BlockCacheCapacity = cfg.CacheSize
+
+       //we must use bloomfilter
+       opts.Filter = filter.NewBloomFilter(defaultFilterBits)
+
+       if !cfg.Compression {
+               opts.Compression = opt.NoCompression
+       } else {
+               opts.Compression = opt.SnappyCompression
+       }
+
+       opts.BlockSize = cfg.BlockSize
+       opts.WriteBuffer = cfg.WriteBufferSize
+
+       return opts
+}
+
+func (db *DB) Close() error {
+       return db.db.Close()
+}
+
+func (db *DB) Put(key, value []byte) error {
+       return db.db.Put(key, value, nil)
+}
+
+func (db *DB) Get(key []byte) ([]byte, error) {
+       v, err := db.db.Get(key, nil)
+       if err == leveldb.ErrNotFound {
+               return nil, nil
+       }
+       return v, nil
+}
+
+func (db *DB) Delete(key []byte) error {
+       return db.db.Delete(key, nil)
+}
+
+func (db *DB) NewWriteBatch() driver.IWriteBatch {
+       wb := &WriteBatch{
+               db:     db,
+               wbatch: new(leveldb.Batch),
+       }
+       return wb
+}
+
+func (db *DB) NewIterator() driver.IIterator {
+       it := &Iterator{
+               db.db.NewIterator(nil, db.iteratorOpts),
+       }
+
+       return it
+}
+
+func (db *DB) Begin() (driver.Tx, error) {
+       return nil, driver.ErrTxSupport
+}
+
+func (db *DB) NewSnapshot() (driver.ISnapshot, error) {
+       snapshot, err := db.db.GetSnapshot()
+       if err != nil {
+               return nil, err
+       }
+
+       s := &Snapshot{
+               db:  db,
+               snp: snapshot,
+       }
+
+       return s, nil
+}
+
+func init() {
+       driver.Register(Store{})
+       driver.Register(MemStore{})
+}
diff --git a/vendor/gitea.com/lunny/nodb/store/goleveldb/iterator.go b/vendor/gitea.com/lunny/nodb/store/goleveldb/iterator.go
new file mode 100644 (file)
index 0000000..c1fd8b5
--- /dev/null
@@ -0,0 +1,49 @@
+package goleveldb
+
+import (
+       "github.com/syndtr/goleveldb/leveldb/iterator"
+)
+
+type Iterator struct {
+       it iterator.Iterator
+}
+
+func (it *Iterator) Key() []byte {
+       return it.it.Key()
+}
+
+func (it *Iterator) Value() []byte {
+       return it.it.Value()
+}
+
+func (it *Iterator) Close() error {
+       if it.it != nil {
+               it.it.Release()
+               it.it = nil
+       }
+       return nil
+}
+
+func (it *Iterator) Valid() bool {
+       return it.it.Valid()
+}
+
+func (it *Iterator) Next() {
+       it.it.Next()
+}
+
+func (it *Iterator) Prev() {
+       it.it.Prev()
+}
+
+func (it *Iterator) First() {
+       it.it.First()
+}
+
+func (it *Iterator) Last() {
+       it.it.Last()
+}
+
+func (it *Iterator) Seek(key []byte) {
+       it.it.Seek(key)
+}
diff --git a/vendor/gitea.com/lunny/nodb/store/goleveldb/snapshot.go b/vendor/gitea.com/lunny/nodb/store/goleveldb/snapshot.go
new file mode 100644 (file)
index 0000000..ddf40f7
--- /dev/null
@@ -0,0 +1,26 @@
+package goleveldb
+
+import (
+       "gitea.com/lunny/nodb/store/driver"
+       "github.com/syndtr/goleveldb/leveldb"
+)
+
+type Snapshot struct {
+       db  *DB
+       snp *leveldb.Snapshot
+}
+
+func (s *Snapshot) Get(key []byte) ([]byte, error) {
+       return s.snp.Get(key, s.db.iteratorOpts)
+}
+
+func (s *Snapshot) NewIterator() driver.IIterator {
+       it := &Iterator{
+               s.snp.NewIterator(nil, s.db.iteratorOpts),
+       }
+       return it
+}
+
+func (s *Snapshot) Close() {
+       s.snp.Release()
+}
diff --git a/vendor/gitea.com/lunny/nodb/store/iterator.go b/vendor/gitea.com/lunny/nodb/store/iterator.go
new file mode 100644 (file)
index 0000000..df03118
--- /dev/null
@@ -0,0 +1,327 @@
+package store
+
+import (
+       "bytes"
+
+       "gitea.com/lunny/nodb/store/driver"
+)
+
+const (
+       IteratorForward  uint8 = 0
+       IteratorBackward uint8 = 1
+)
+
+const (
+       RangeClose uint8 = 0x00
+       RangeLOpen uint8 = 0x01
+       RangeROpen uint8 = 0x10
+       RangeOpen  uint8 = 0x11
+)
+
+// min must less or equal than max
+//
+// range type:
+//
+//  close: [min, max]
+//  open: (min, max)
+//  lopen: (min, max]
+//  ropen: [min, max)
+//
+type Range struct {
+       Min []byte
+       Max []byte
+
+       Type uint8
+}
+
+type Limit struct {
+       Offset int
+       Count  int
+}
+
+type Iterator struct {
+       it driver.IIterator
+}
+
+// Returns a copy of key.
+func (it *Iterator) Key() []byte {
+       k := it.it.Key()
+       if k == nil {
+               return nil
+       }
+
+       return append([]byte{}, k...)
+}
+
+// Returns a copy of value.
+func (it *Iterator) Value() []byte {
+       v := it.it.Value()
+       if v == nil {
+               return nil
+       }
+
+       return append([]byte{}, v...)
+}
+
+// Returns a reference of key.
+// you must be careful that it will be changed after next iterate.
+func (it *Iterator) RawKey() []byte {
+       return it.it.Key()
+}
+
+// Returns a reference of value.
+// you must be careful that it will be changed after next iterate.
+func (it *Iterator) RawValue() []byte {
+       return it.it.Value()
+}
+
+// Copy key to b, if b len is small or nil, returns a new one.
+func (it *Iterator) BufKey(b []byte) []byte {
+       k := it.RawKey()
+       if k == nil {
+               return nil
+       }
+       if b == nil {
+               b = []byte{}
+       }
+
+       b = b[0:0]
+       return append(b, k...)
+}
+
+// Copy value to b, if b len is small or nil, returns a new one.
+func (it *Iterator) BufValue(b []byte) []byte {
+       v := it.RawValue()
+       if v == nil {
+               return nil
+       }
+
+       if b == nil {
+               b = []byte{}
+       }
+
+       b = b[0:0]
+       return append(b, v...)
+}
+
+func (it *Iterator) Close() {
+       if it.it != nil {
+               it.it.Close()
+               it.it = nil
+       }
+}
+
+func (it *Iterator) Valid() bool {
+       return it.it.Valid()
+}
+
+func (it *Iterator) Next() {
+       it.it.Next()
+}
+
+func (it *Iterator) Prev() {
+       it.it.Prev()
+}
+
+func (it *Iterator) SeekToFirst() {
+       it.it.First()
+}
+
+func (it *Iterator) SeekToLast() {
+       it.it.Last()
+}
+
+func (it *Iterator) Seek(key []byte) {
+       it.it.Seek(key)
+}
+
+// Finds by key, if not found, nil returns.
+func (it *Iterator) Find(key []byte) []byte {
+       it.Seek(key)
+       if it.Valid() {
+               k := it.RawKey()
+               if k == nil {
+                       return nil
+               } else if bytes.Equal(k, key) {
+                       return it.Value()
+               }
+       }
+
+       return nil
+}
+
+// Finds by key, if not found, nil returns, else a reference of value returns.
+// you must be careful that it will be changed after next iterate.
+func (it *Iterator) RawFind(key []byte) []byte {
+       it.Seek(key)
+       if it.Valid() {
+               k := it.RawKey()
+               if k == nil {
+                       return nil
+               } else if bytes.Equal(k, key) {
+                       return it.RawValue()
+               }
+       }
+
+       return nil
+}
+
+type RangeLimitIterator struct {
+       it *Iterator
+
+       r *Range
+       l *Limit
+
+       step int
+
+       //0 for IteratorForward, 1 for IteratorBackward
+       direction uint8
+}
+
+func (it *RangeLimitIterator) Key() []byte {
+       return it.it.Key()
+}
+
+func (it *RangeLimitIterator) Value() []byte {
+       return it.it.Value()
+}
+
+func (it *RangeLimitIterator) RawKey() []byte {
+       return it.it.RawKey()
+}
+
+func (it *RangeLimitIterator) RawValue() []byte {
+       return it.it.RawValue()
+}
+
+func (it *RangeLimitIterator) BufKey(b []byte) []byte {
+       return it.it.BufKey(b)
+}
+
+func (it *RangeLimitIterator) BufValue(b []byte) []byte {
+       return it.it.BufValue(b)
+}
+
+func (it *RangeLimitIterator) Valid() bool {
+       if it.l.Offset < 0 {
+               return false
+       } else if !it.it.Valid() {
+               return false
+       } else if it.l.Count >= 0 && it.step >= it.l.Count {
+               return false
+       }
+
+       if it.direction == IteratorForward {
+               if it.r.Max != nil {
+                       r := bytes.Compare(it.it.RawKey(), it.r.Max)
+                       if it.r.Type&RangeROpen > 0 {
+                               return !(r >= 0)
+                       } else {
+                               return !(r > 0)
+                       }
+               }
+       } else {
+               if it.r.Min != nil {
+                       r := bytes.Compare(it.it.RawKey(), it.r.Min)
+                       if it.r.Type&RangeLOpen > 0 {
+                               return !(r <= 0)
+                       } else {
+                               return !(r < 0)
+                       }
+               }
+       }
+
+       return true
+}
+
+func (it *RangeLimitIterator) Next() {
+       it.step++
+
+       if it.direction == IteratorForward {
+               it.it.Next()
+       } else {
+               it.it.Prev()
+       }
+}
+
+func (it *RangeLimitIterator) Close() {
+       it.it.Close()
+}
+
+func NewRangeLimitIterator(i *Iterator, r *Range, l *Limit) *RangeLimitIterator {
+       return rangeLimitIterator(i, r, l, IteratorForward)
+}
+
+func NewRevRangeLimitIterator(i *Iterator, r *Range, l *Limit) *RangeLimitIterator {
+       return rangeLimitIterator(i, r, l, IteratorBackward)
+}
+
+func NewRangeIterator(i *Iterator, r *Range) *RangeLimitIterator {
+       return rangeLimitIterator(i, r, &Limit{0, -1}, IteratorForward)
+}
+
+func NewRevRangeIterator(i *Iterator, r *Range) *RangeLimitIterator {
+       return rangeLimitIterator(i, r, &Limit{0, -1}, IteratorBackward)
+}
+
+func rangeLimitIterator(i *Iterator, r *Range, l *Limit, direction uint8) *RangeLimitIterator {
+       it := new(RangeLimitIterator)
+
+       it.it = i
+
+       it.r = r
+       it.l = l
+       it.direction = direction
+
+       it.step = 0
+
+       if l.Offset < 0 {
+               return it
+       }
+
+       if direction == IteratorForward {
+               if r.Min == nil {
+                       it.it.SeekToFirst()
+               } else {
+                       it.it.Seek(r.Min)
+
+                       if r.Type&RangeLOpen > 0 {
+                               if it.it.Valid() && bytes.Equal(it.it.RawKey(), r.Min) {
+                                       it.it.Next()
+                               }
+                       }
+               }
+       } else {
+               if r.Max == nil {
+                       it.it.SeekToLast()
+               } else {
+                       it.it.Seek(r.Max)
+
+                       if !it.it.Valid() {
+                               it.it.SeekToLast()
+                       } else {
+                               if !bytes.Equal(it.it.RawKey(), r.Max) {
+                                       it.it.Prev()
+                               }
+                       }
+
+                       if r.Type&RangeROpen > 0 {
+                               if it.it.Valid() && bytes.Equal(it.it.RawKey(), r.Max) {
+                                       it.it.Prev()
+                               }
+                       }
+               }
+       }
+
+       for i := 0; i < l.Offset; i++ {
+               if it.it.Valid() {
+                       if it.direction == IteratorForward {
+                               it.it.Next()
+                       } else {
+                               it.it.Prev()
+                       }
+               }
+       }
+
+       return it
+}
diff --git a/vendor/gitea.com/lunny/nodb/store/snapshot.go b/vendor/gitea.com/lunny/nodb/store/snapshot.go
new file mode 100644 (file)
index 0000000..0d804e8
--- /dev/null
@@ -0,0 +1,16 @@
+package store
+
+import (
+       "gitea.com/lunny/nodb/store/driver"
+)
+
+type Snapshot struct {
+       driver.ISnapshot
+}
+
+func (s *Snapshot) NewIterator() *Iterator {
+       it := new(Iterator)
+       it.it = s.ISnapshot.NewIterator()
+
+       return it
+}
diff --git a/vendor/gitea.com/lunny/nodb/store/store.go b/vendor/gitea.com/lunny/nodb/store/store.go
new file mode 100644 (file)
index 0000000..687e40d
--- /dev/null
@@ -0,0 +1,51 @@
+package store
+
+import (
+       "fmt"
+       "os"
+       "path"
+       "gitea.com/lunny/nodb/config"
+       "gitea.com/lunny/nodb/store/driver"
+
+       _ "gitea.com/lunny/nodb/store/goleveldb"
+)
+
+func getStorePath(cfg *config.Config) string {
+       return path.Join(cfg.DataDir, fmt.Sprintf("%s_data", cfg.DBName))
+}
+
+func Open(cfg *config.Config) (*DB, error) {
+       s, err := driver.GetStore(cfg)
+       if err != nil {
+               return nil, err
+       }
+
+       path := getStorePath(cfg)
+
+       if err := os.MkdirAll(path, os.ModePerm); err != nil {
+               return nil, err
+       }
+
+       idb, err := s.Open(path, cfg)
+       if err != nil {
+               return nil, err
+       }
+
+       db := &DB{idb}
+
+       return db, nil
+}
+
+func Repair(cfg *config.Config) error {
+       s, err := driver.GetStore(cfg)
+       if err != nil {
+               return err
+       }
+
+       path := getStorePath(cfg)
+
+       return s.Repair(path, cfg)
+}
+
+func init() {
+}
diff --git a/vendor/gitea.com/lunny/nodb/store/tx.go b/vendor/gitea.com/lunny/nodb/store/tx.go
new file mode 100644 (file)
index 0000000..3bcb5a9
--- /dev/null
@@ -0,0 +1,42 @@
+package store
+
+import (
+       "gitea.com/lunny/nodb/store/driver"
+)
+
+type Tx struct {
+       driver.Tx
+}
+
+func (tx *Tx) NewIterator() *Iterator {
+       it := new(Iterator)
+       it.it = tx.Tx.NewIterator()
+
+       return it
+}
+
+func (tx *Tx) NewWriteBatch() WriteBatch {
+       return tx.Tx.NewWriteBatch()
+}
+
+func (tx *Tx) RangeIterator(min []byte, max []byte, rangeType uint8) *RangeLimitIterator {
+       return NewRangeLimitIterator(tx.NewIterator(), &Range{min, max, rangeType}, &Limit{0, -1})
+}
+
+func (tx *Tx) RevRangeIterator(min []byte, max []byte, rangeType uint8) *RangeLimitIterator {
+       return NewRevRangeLimitIterator(tx.NewIterator(), &Range{min, max, rangeType}, &Limit{0, -1})
+}
+
+//count < 0, unlimit.
+//
+//offset must >= 0, if < 0, will get nothing.
+func (tx *Tx) RangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *RangeLimitIterator {
+       return NewRangeLimitIterator(tx.NewIterator(), &Range{min, max, rangeType}, &Limit{offset, count})
+}
+
+//count < 0, unlimit.
+//
+//offset must >= 0, if < 0, will get nothing.
+func (tx *Tx) RevRangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *RangeLimitIterator {
+       return NewRevRangeLimitIterator(tx.NewIterator(), &Range{min, max, rangeType}, &Limit{offset, count})
+}
diff --git a/vendor/gitea.com/lunny/nodb/store/writebatch.go b/vendor/gitea.com/lunny/nodb/store/writebatch.go
new file mode 100644 (file)
index 0000000..9419ec5
--- /dev/null
@@ -0,0 +1,9 @@
+package store
+
+import (
+       "gitea.com/lunny/nodb/store/driver"
+)
+
+type WriteBatch interface {
+       driver.IWriteBatch
+}
diff --git a/vendor/gitea.com/lunny/nodb/t_bit.go b/vendor/gitea.com/lunny/nodb/t_bit.go
new file mode 100644 (file)
index 0000000..92ea831
--- /dev/null
@@ -0,0 +1,922 @@
+package nodb
+
+import (
+       "encoding/binary"
+       "errors"
+       "sort"
+       "time"
+
+       "gitea.com/lunny/nodb/store"
+)
+
+const (
+       OPand uint8 = iota + 1
+       OPor
+       OPxor
+       OPnot
+)
+
+type BitPair struct {
+       Pos int32
+       Val uint8
+}
+
+type segBitInfo struct {
+       Seq uint32
+       Off uint32
+       Val uint8
+}
+
+type segBitInfoArray []segBitInfo
+
+const (
+       // byte
+       segByteWidth uint32 = 9
+       segByteSize  uint32 = 1 << segByteWidth
+
+       // bit
+       segBitWidth uint32 = segByteWidth + 3
+       segBitSize  uint32 = segByteSize << 3
+
+       maxByteSize uint32 = 8 << 20
+       maxSegCount uint32 = maxByteSize / segByteSize
+
+       minSeq uint32 = 0
+       maxSeq uint32 = uint32((maxByteSize << 3) - 1)
+)
+
+var bitsInByte = [256]int32{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3,
+       4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3,
+       3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4,
+       5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4,
+       3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4,
+       5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2,
+       2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3,
+       4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+       3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4,
+       5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6,
+       6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5,
+       6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8}
+
+var fillBits = [...]uint8{1, 3, 7, 15, 31, 63, 127, 255}
+
+var emptySegment []byte = make([]byte, segByteSize, segByteSize)
+
+var fillSegment []byte = func() []byte {
+       data := make([]byte, segByteSize, segByteSize)
+       for i := uint32(0); i < segByteSize; i++ {
+               data[i] = 0xff
+       }
+       return data
+}()
+
+var errBinKey = errors.New("invalid bin key")
+var errOffset = errors.New("invalid offset")
+var errDuplicatePos = errors.New("duplicate bit pos")
+
+func getBit(sz []byte, offset uint32) uint8 {
+       index := offset >> 3
+       if index >= uint32(len(sz)) {
+               return 0 // error("overflow")
+       }
+
+       offset -= index << 3
+       return sz[index] >> offset & 1
+}
+
+func setBit(sz []byte, offset uint32, val uint8) bool {
+       if val != 1 && val != 0 {
+               return false // error("invalid val")
+       }
+
+       index := offset >> 3
+       if index >= uint32(len(sz)) {
+               return false // error("overflow")
+       }
+
+       offset -= index << 3
+       if sz[index]>>offset&1 != val {
+               sz[index] ^= (1 << offset)
+       }
+       return true
+}
+
+func (datas segBitInfoArray) Len() int {
+       return len(datas)
+}
+
+func (datas segBitInfoArray) Less(i, j int) bool {
+       res := (datas)[i].Seq < (datas)[j].Seq
+       if !res && (datas)[i].Seq == (datas)[j].Seq {
+               res = (datas)[i].Off < (datas)[j].Off
+       }
+       return res
+}
+
+func (datas segBitInfoArray) Swap(i, j int) {
+       datas[i], datas[j] = datas[j], datas[i]
+}
+
+func (db *DB) bEncodeMetaKey(key []byte) []byte {
+       mk := make([]byte, len(key)+2)
+       mk[0] = db.index
+       mk[1] = BitMetaType
+
+       copy(mk[2:], key)
+       return mk
+}
+
+func (db *DB) bDecodeMetaKey(bkey []byte) ([]byte, error) {
+       if len(bkey) < 2 || bkey[0] != db.index || bkey[1] != BitMetaType {
+               return nil, errBinKey
+       }
+
+       return bkey[2:], nil
+}
+
+func (db *DB) bEncodeBinKey(key []byte, seq uint32) []byte {
+       bk := make([]byte, len(key)+8)
+
+       pos := 0
+       bk[pos] = db.index
+       pos++
+       bk[pos] = BitType
+       pos++
+
+       binary.BigEndian.PutUint16(bk[pos:], uint16(len(key)))
+       pos += 2
+
+       copy(bk[pos:], key)
+       pos += len(key)
+
+       binary.BigEndian.PutUint32(bk[pos:], seq)
+
+       return bk
+}
+
+func (db *DB) bDecodeBinKey(bkey []byte) (key []byte, seq uint32, err error) {
+       if len(bkey) < 8 || bkey[0] != db.index {
+               err = errBinKey
+               return
+       }
+
+       keyLen := binary.BigEndian.Uint16(bkey[2:4])
+       if int(keyLen+8) != len(bkey) {
+               err = errBinKey
+               return
+       }
+
+       key = bkey[4 : 4+keyLen]
+       seq = uint32(binary.BigEndian.Uint32(bkey[4+keyLen:]))
+       return
+}
+
+func (db *DB) bCapByteSize(seq uint32, off uint32) uint32 {
+       var offByteSize uint32 = (off >> 3) + 1
+       if offByteSize > segByteSize {
+               offByteSize = segByteSize
+       }
+
+       return seq<<segByteWidth + offByteSize
+}
+
+func (db *DB) bParseOffset(key []byte, offset int32) (seq uint32, off uint32, err error) {
+       if offset < 0 {
+               if tailSeq, tailOff, e := db.bGetMeta(key); e != nil {
+                       err = e
+                       return
+               } else if tailSeq >= 0 {
+                       offset += int32((uint32(tailSeq)<<segBitWidth | uint32(tailOff)) + 1)
+                       if offset < 0 {
+                               err = errOffset
+                               return
+                       }
+               }
+       }
+
+       off = uint32(offset)
+
+       seq = off >> segBitWidth
+       off &= (segBitSize - 1)
+       return
+}
+
+func (db *DB) bGetMeta(key []byte) (tailSeq int32, tailOff int32, err error) {
+       var v []byte
+
+       mk := db.bEncodeMetaKey(key)
+       v, err = db.bucket.Get(mk)
+       if err != nil {
+               return
+       }
+
+       if v != nil {
+               tailSeq = int32(binary.LittleEndian.Uint32(v[0:4]))
+               tailOff = int32(binary.LittleEndian.Uint32(v[4:8]))
+       } else {
+               tailSeq = -1
+               tailOff = -1
+       }
+       return
+}
+
+func (db *DB) bSetMeta(t *batch, key []byte, tailSeq uint32, tailOff uint32) {
+       ek := db.bEncodeMetaKey(key)
+
+       buf := make([]byte, 8)
+       binary.LittleEndian.PutUint32(buf[0:4], tailSeq)
+       binary.LittleEndian.PutUint32(buf[4:8], tailOff)
+
+       t.Put(ek, buf)
+       return
+}
+
+func (db *DB) bUpdateMeta(t *batch, key []byte, seq uint32, off uint32) (tailSeq uint32, tailOff uint32, err error) {
+       var tseq, toff int32
+       var update bool = false
+
+       if tseq, toff, err = db.bGetMeta(key); err != nil {
+               return
+       } else if tseq < 0 {
+               update = true
+       } else {
+               tailSeq = uint32(MaxInt32(tseq, 0))
+               tailOff = uint32(MaxInt32(toff, 0))
+               update = (seq > tailSeq || (seq == tailSeq && off > tailOff))
+       }
+
+       if update {
+               db.bSetMeta(t, key, seq, off)
+               tailSeq = seq
+               tailOff = off
+       }
+       return
+}
+
+func (db *DB) bDelete(t *batch, key []byte) (drop int64) {
+       mk := db.bEncodeMetaKey(key)
+       t.Delete(mk)
+
+       minKey := db.bEncodeBinKey(key, minSeq)
+       maxKey := db.bEncodeBinKey(key, maxSeq)
+       it := db.bucket.RangeIterator(minKey, maxKey, store.RangeClose)
+       for ; it.Valid(); it.Next() {
+               t.Delete(it.RawKey())
+               drop++
+       }
+       it.Close()
+
+       return drop
+}
+
+func (db *DB) bGetSegment(key []byte, seq uint32) ([]byte, []byte, error) {
+       bk := db.bEncodeBinKey(key, seq)
+       segment, err := db.bucket.Get(bk)
+       if err != nil {
+               return bk, nil, err
+       }
+       return bk, segment, nil
+}
+
+func (db *DB) bAllocateSegment(key []byte, seq uint32) ([]byte, []byte, error) {
+       bk, segment, err := db.bGetSegment(key, seq)
+       if err == nil && segment == nil {
+               segment = make([]byte, segByteSize, segByteSize)
+       }
+       return bk, segment, err
+}
+
+func (db *DB) bIterator(key []byte) *store.RangeLimitIterator {
+       sk := db.bEncodeBinKey(key, minSeq)
+       ek := db.bEncodeBinKey(key, maxSeq)
+       return db.bucket.RangeIterator(sk, ek, store.RangeClose)
+}
+
+func (db *DB) bSegAnd(a []byte, b []byte, res *[]byte) {
+       if a == nil || b == nil {
+               *res = nil
+               return
+       }
+
+       data := *res
+       if data == nil {
+               data = make([]byte, segByteSize, segByteSize)
+               *res = data
+       }
+
+       for i := uint32(0); i < segByteSize; i++ {
+               data[i] = a[i] & b[i]
+       }
+       return
+}
+
+func (db *DB) bSegOr(a []byte, b []byte, res *[]byte) {
+       if a == nil || b == nil {
+               if a == nil && b == nil {
+                       *res = nil
+               } else if a == nil {
+                       *res = b
+               } else {
+                       *res = a
+               }
+               return
+       }
+
+       data := *res
+       if data == nil {
+               data = make([]byte, segByteSize, segByteSize)
+               *res = data
+       }
+
+       for i := uint32(0); i < segByteSize; i++ {
+               data[i] = a[i] | b[i]
+       }
+       return
+}
+
+func (db *DB) bSegXor(a []byte, b []byte, res *[]byte) {
+       if a == nil && b == nil {
+               *res = fillSegment
+               return
+       }
+
+       if a == nil {
+               a = emptySegment
+       }
+
+       if b == nil {
+               b = emptySegment
+       }
+
+       data := *res
+       if data == nil {
+               data = make([]byte, segByteSize, segByteSize)
+               *res = data
+       }
+
+       for i := uint32(0); i < segByteSize; i++ {
+               data[i] = a[i] ^ b[i]
+       }
+
+       return
+}
+
+func (db *DB) bExpireAt(key []byte, when int64) (int64, error) {
+       t := db.binBatch
+       t.Lock()
+       defer t.Unlock()
+
+       if seq, _, err := db.bGetMeta(key); err != nil || seq < 0 {
+               return 0, err
+       } else {
+               db.expireAt(t, BitType, key, when)
+               if err := t.Commit(); err != nil {
+                       return 0, err
+               }
+       }
+       return 1, nil
+}
+
+func (db *DB) bCountByte(val byte, soff uint32, eoff uint32) int32 {
+       if soff > eoff {
+               soff, eoff = eoff, soff
+       }
+
+       mask := uint8(0)
+       if soff > 0 {
+               mask |= fillBits[soff-1]
+       }
+       if eoff < 7 {
+               mask |= (fillBits[7] ^ fillBits[eoff])
+       }
+       mask = fillBits[7] ^ mask
+
+       return bitsInByte[val&mask]
+}
+
+func (db *DB) bCountSeg(key []byte, seq uint32, soff uint32, eoff uint32) (cnt int32, err error) {
+       if soff >= segBitSize || soff < 0 ||
+               eoff >= segBitSize || eoff < 0 {
+               return
+       }
+
+       var segment []byte
+       if _, segment, err = db.bGetSegment(key, seq); err != nil {
+               return
+       }
+
+       if segment == nil {
+               return
+       }
+
+       if soff > eoff {
+               soff, eoff = eoff, soff
+       }
+
+       headIdx := int(soff >> 3)
+       endIdx := int(eoff >> 3)
+       sByteOff := soff - ((soff >> 3) << 3)
+       eByteOff := eoff - ((eoff >> 3) << 3)
+
+       if headIdx == endIdx {
+               cnt = db.bCountByte(segment[headIdx], sByteOff, eByteOff)
+       } else {
+               cnt = db.bCountByte(segment[headIdx], sByteOff, 7) +
+                       db.bCountByte(segment[endIdx], 0, eByteOff)
+       }
+
+       // sum up following bytes
+       for idx, end := headIdx+1, endIdx-1; idx <= end; idx += 1 {
+               cnt += bitsInByte[segment[idx]]
+               if idx == end {
+                       break
+               }
+       }
+
+       return
+}
+
+func (db *DB) BGet(key []byte) (data []byte, err error) {
+       if err = checkKeySize(key); err != nil {
+               return
+       }
+
+       var ts, to int32
+       if ts, to, err = db.bGetMeta(key); err != nil || ts < 0 {
+               return
+       }
+
+       var tailSeq, tailOff = uint32(ts), uint32(to)
+       var capByteSize uint32 = db.bCapByteSize(tailSeq, tailOff)
+       data = make([]byte, capByteSize, capByteSize)
+
+       minKey := db.bEncodeBinKey(key, minSeq)
+       maxKey := db.bEncodeBinKey(key, tailSeq)
+       it := db.bucket.RangeIterator(minKey, maxKey, store.RangeClose)
+
+       var seq, s, e uint32
+       for ; it.Valid(); it.Next() {
+               if _, seq, err = db.bDecodeBinKey(it.RawKey()); err != nil {
+                       data = nil
+                       break
+               }
+
+               s = seq << segByteWidth
+               e = MinUInt32(s+segByteSize, capByteSize)
+               copy(data[s:e], it.RawValue())
+       }
+       it.Close()
+
+       return
+}
+
+func (db *DB) BDelete(key []byte) (drop int64, err error) {
+       if err = checkKeySize(key); err != nil {
+               return
+       }
+
+       t := db.binBatch
+       t.Lock()
+       defer t.Unlock()
+
+       drop = db.bDelete(t, key)
+       db.rmExpire(t, BitType, key)
+
+       err = t.Commit()
+       return
+}
+
+func (db *DB) BSetBit(key []byte, offset int32, val uint8) (ori uint8, err error) {
+       if err = checkKeySize(key); err != nil {
+               return
+       }
+
+       //      todo : check offset
+       var seq, off uint32
+       if seq, off, err = db.bParseOffset(key, offset); err != nil {
+               return 0, err
+       }
+
+       var bk, segment []byte
+       if bk, segment, err = db.bAllocateSegment(key, seq); err != nil {
+               return 0, err
+       }
+
+       if segment != nil {
+               ori = getBit(segment, off)
+               if setBit(segment, off, val) {
+                       t := db.binBatch
+                       t.Lock()
+                       defer t.Unlock()
+
+                       t.Put(bk, segment)
+                       if _, _, e := db.bUpdateMeta(t, key, seq, off); e != nil {
+                               err = e
+                               return
+                       }
+
+                       err = t.Commit()
+               }
+       }
+
+       return
+}
+
+func (db *DB) BMSetBit(key []byte, args ...BitPair) (place int64, err error) {
+       if err = checkKeySize(key); err != nil {
+               return
+       }
+
+       //      (ps : so as to aviod wasting memory copy while calling db.Get() and batch.Put(),
+       //                here we sequence the params by pos, so that we can merge the execution of
+       //                diff pos setting which targets on the same segment respectively. )
+
+       //      #1 : sequence request data
+       var argCnt = len(args)
+       var bitInfos segBitInfoArray = make(segBitInfoArray, argCnt)
+       var seq, off uint32
+
+       for i, info := range args {
+               if seq, off, err = db.bParseOffset(key, info.Pos); err != nil {
+                       return
+               }
+
+               bitInfos[i].Seq = seq
+               bitInfos[i].Off = off
+               bitInfos[i].Val = info.Val
+       }
+
+       sort.Sort(bitInfos)
+
+       for i := 1; i < argCnt; i++ {
+               if bitInfos[i].Seq == bitInfos[i-1].Seq && bitInfos[i].Off == bitInfos[i-1].Off {
+                       return 0, errDuplicatePos
+               }
+       }
+
+       //      #2 : execute bit set in order
+       t := db.binBatch
+       t.Lock()
+       defer t.Unlock()
+
+       var curBinKey, curSeg []byte
+       var curSeq, maxSeq, maxOff uint32
+
+       for _, info := range bitInfos {
+               if curSeg != nil && info.Seq != curSeq {
+                       t.Put(curBinKey, curSeg)
+                       curSeg = nil
+               }
+
+               if curSeg == nil {
+                       curSeq = info.Seq
+                       if curBinKey, curSeg, err = db.bAllocateSegment(key, info.Seq); err != nil {
+                               return
+                       }
+
+                       if curSeg == nil {
+                               continue
+                       }
+               }
+
+               if setBit(curSeg, info.Off, info.Val) {
+                       maxSeq = info.Seq
+                       maxOff = info.Off
+                       place++
+               }
+       }
+
+       if curSeg != nil {
+               t.Put(curBinKey, curSeg)
+       }
+
+       //      finally, update meta
+       if place > 0 {
+               if _, _, err = db.bUpdateMeta(t, key, maxSeq, maxOff); err != nil {
+                       return
+               }
+
+               err = t.Commit()
+       }
+
+       return
+}
+
+func (db *DB) BGetBit(key []byte, offset int32) (uint8, error) {
+       if seq, off, err := db.bParseOffset(key, offset); err != nil {
+               return 0, err
+       } else {
+               _, segment, err := db.bGetSegment(key, seq)
+               if err != nil {
+                       return 0, err
+               }
+
+               if segment == nil {
+                       return 0, nil
+               } else {
+                       return getBit(segment, off), nil
+               }
+       }
+}
+
+// func (db *DB) BGetRange(key []byte, start int32, end int32) ([]byte, error) {
+//     section := make([]byte)
+
+//     return
+// }
+
+func (db *DB) BCount(key []byte, start int32, end int32) (cnt int32, err error) {
+       var sseq, soff uint32
+       if sseq, soff, err = db.bParseOffset(key, start); err != nil {
+               return
+       }
+
+       var eseq, eoff uint32
+       if eseq, eoff, err = db.bParseOffset(key, end); err != nil {
+               return
+       }
+
+       if sseq > eseq || (sseq == eseq && soff > eoff) {
+               sseq, eseq = eseq, sseq
+               soff, eoff = eoff, soff
+       }
+
+       var segCnt int32
+       if eseq == sseq {
+               if segCnt, err = db.bCountSeg(key, sseq, soff, eoff); err != nil {
+                       return 0, err
+               }
+
+               cnt = segCnt
+
+       } else {
+               if segCnt, err = db.bCountSeg(key, sseq, soff, segBitSize-1); err != nil {
+                       return 0, err
+               } else {
+                       cnt += segCnt
+               }
+
+               if segCnt, err = db.bCountSeg(key, eseq, 0, eoff); err != nil {
+                       return 0, err
+               } else {
+                       cnt += segCnt
+               }
+       }
+
+       //      middle segs
+       var segment []byte
+       skey := db.bEncodeBinKey(key, sseq)
+       ekey := db.bEncodeBinKey(key, eseq)
+
+       it := db.bucket.RangeIterator(skey, ekey, store.RangeOpen)
+       for ; it.Valid(); it.Next() {
+               segment = it.RawValue()
+               for _, bt := range segment {
+                       cnt += bitsInByte[bt]
+               }
+       }
+       it.Close()
+
+       return
+}
+
+func (db *DB) BTail(key []byte) (int32, error) {
+       // effective length of data, the highest bit-pos set in history
+       tailSeq, tailOff, err := db.bGetMeta(key)
+       if err != nil {
+               return 0, err
+       }
+
+       tail := int32(-1)
+       if tailSeq >= 0 {
+               tail = int32(uint32(tailSeq)<<segBitWidth | uint32(tailOff))
+       }
+
+       return tail, nil
+}
+
+func (db *DB) BOperation(op uint8, dstkey []byte, srckeys ...[]byte) (blen int32, err error) {
+       //      blen -
+       //              the total bit size of data stored in destination key,
+       //              that is equal to the size of the longest input string.
+
+       var exeOp func([]byte, []byte, *[]byte)
+       switch op {
+       case OPand:
+               exeOp = db.bSegAnd
+       case OPor:
+               exeOp = db.bSegOr
+       case OPxor, OPnot:
+               exeOp = db.bSegXor
+       default:
+               return
+       }
+
+       if dstkey == nil || srckeys == nil {
+               return
+       }
+
+       t := db.binBatch
+       t.Lock()
+       defer t.Unlock()
+
+       var srcKseq, srcKoff int32
+       var seq, off, maxDstSeq, maxDstOff uint32
+
+       var keyNum int = len(srckeys)
+       var validKeyNum int
+       for i := 0; i < keyNum; i++ {
+               if srcKseq, srcKoff, err = db.bGetMeta(srckeys[i]); err != nil {
+                       return
+               } else if srcKseq < 0 {
+                       srckeys[i] = nil
+                       continue
+               }
+
+               validKeyNum++
+
+               seq = uint32(srcKseq)
+               off = uint32(srcKoff)
+               if seq > maxDstSeq || (seq == maxDstSeq && off > maxDstOff) {
+                       maxDstSeq = seq
+                       maxDstOff = off
+               }
+       }
+
+       if (op == OPnot && validKeyNum != 1) ||
+               (op != OPnot && validKeyNum < 2) {
+               return // with not enough existing source key
+       }
+
+       var srcIdx int
+       for srcIdx = 0; srcIdx < keyNum; srcIdx++ {
+               if srckeys[srcIdx] != nil {
+                       break
+               }
+       }
+
+       // init - data
+       var segments = make([][]byte, maxDstSeq+1)
+
+       if op == OPnot {
+               //      ps :
+               //              ( ~num == num ^ 0x11111111 )
+               //              we init the result segments with all bit set,
+               //              then we can calculate through the way of 'xor'.
+
+               //      ahead segments bin format : 1111 ... 1111
+               for i := uint32(0); i < maxDstSeq; i++ {
+                       segments[i] = fillSegment
+               }
+
+               //      last segment bin format : 1111..1100..0000
+               var tailSeg = make([]byte, segByteSize, segByteSize)
+               var fillByte = fillBits[7]
+               var tailSegLen = db.bCapByteSize(uint32(0), maxDstOff)
+               for i := uint32(0); i < tailSegLen-1; i++ {
+                       tailSeg[i] = fillByte
+               }
+               tailSeg[tailSegLen-1] = fillBits[maxDstOff-(tailSegLen-1)<<3]
+               segments[maxDstSeq] = tailSeg
+
+       } else {
+               // ps : init segments by data corresponding to the 1st valid source key
+               it := db.bIterator(srckeys[srcIdx])
+               for ; it.Valid(); it.Next() {
+                       if _, seq, err = db.bDecodeBinKey(it.RawKey()); err != nil {
+                               // to do ...
+                               it.Close()
+                               return
+                       }
+                       segments[seq] = it.Value()
+               }
+               it.Close()
+               srcIdx++
+       }
+
+       //      operation with following keys
+       var res []byte
+       for i := srcIdx; i < keyNum; i++ {
+               if srckeys[i] == nil {
+                       continue
+               }
+
+               it := db.bIterator(srckeys[i])
+               for idx, end := uint32(0), false; !end; it.Next() {
+                       end = !it.Valid()
+                       if !end {
+                               if _, seq, err = db.bDecodeBinKey(it.RawKey()); err != nil {
+                                       // to do ...
+                                       it.Close()
+                                       return
+                               }
+                       } else {
+                               seq = maxDstSeq + 1
+                       }
+
+                       // todo :
+                       //              operation 'and' can be optimize here :
+                       //              if seq > max_segments_idx, this loop can be break,
+                       //              which can avoid cost from Key() and bDecodeBinKey()
+
+                       for ; idx < seq; idx++ {
+                               res = nil
+                               exeOp(segments[idx], nil, &res)
+                               segments[idx] = res
+                       }
+
+                       if !end {
+                               res = it.Value()
+                               exeOp(segments[seq], res, &res)
+                               segments[seq] = res
+                               idx++
+                       }
+               }
+               it.Close()
+       }
+
+       // clear the old data in case
+       db.bDelete(t, dstkey)
+       db.rmExpire(t, BitType, dstkey)
+
+       //      set data
+       db.bSetMeta(t, dstkey, maxDstSeq, maxDstOff)
+
+       var bk []byte
+       for seq, segt := range segments {
+               if segt != nil {
+                       bk = db.bEncodeBinKey(dstkey, uint32(seq))
+                       t.Put(bk, segt)
+               }
+       }
+
+       err = t.Commit()
+       if err == nil {
+               // blen = int32(db.bCapByteSize(maxDstOff, maxDstOff))
+               blen = int32(maxDstSeq<<segBitWidth | maxDstOff + 1)
+       }
+
+       return
+}
+
+func (db *DB) BExpire(key []byte, duration int64) (int64, error) {
+       if duration <= 0 {
+               return 0, errExpireValue
+       }
+
+       if err := checkKeySize(key); err != nil {
+               return -1, err
+       }
+
+       return db.bExpireAt(key, time.Now().Unix()+duration)
+}
+
+func (db *DB) BExpireAt(key []byte, when int64) (int64, error) {
+       if when <= time.Now().Unix() {
+               return 0, errExpireValue
+       }
+
+       if err := checkKeySize(key); err != nil {
+               return -1, err
+       }
+
+       return db.bExpireAt(key, when)
+}
+
+func (db *DB) BTTL(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return -1, err
+       }
+
+       return db.ttl(BitType, key)
+}
+
+func (db *DB) BPersist(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+
+       t := db.binBatch
+       t.Lock()
+       defer t.Unlock()
+
+       n, err := db.rmExpire(t, BitType, key)
+       if err != nil {
+               return 0, err
+       }
+
+       err = t.Commit()
+       return n, err
+}
+
+func (db *DB) BScan(key []byte, count int, inclusive bool, match string) ([][]byte, error) {
+       return db.scan(BitMetaType, key, count, inclusive, match)
+}
+
+func (db *DB) bFlush() (drop int64, err error) {
+       t := db.binBatch
+       t.Lock()
+       defer t.Unlock()
+
+       return db.flushType(t, BitType)
+}
diff --git a/vendor/gitea.com/lunny/nodb/t_hash.go b/vendor/gitea.com/lunny/nodb/t_hash.go
new file mode 100644 (file)
index 0000000..e7ca41b
--- /dev/null
@@ -0,0 +1,509 @@
+package nodb
+
+import (
+       "encoding/binary"
+       "errors"
+       "time"
+
+       "gitea.com/lunny/nodb/store"
+)
+
+type FVPair struct {
+       Field []byte
+       Value []byte
+}
+
+var errHashKey = errors.New("invalid hash key")
+var errHSizeKey = errors.New("invalid hsize key")
+
+const (
+       hashStartSep byte = ':'
+       hashStopSep  byte = hashStartSep + 1
+)
+
+func checkHashKFSize(key []byte, field []byte) error {
+       if len(key) > MaxKeySize || len(key) == 0 {
+               return errKeySize
+       } else if len(field) > MaxHashFieldSize || len(field) == 0 {
+               return errHashFieldSize
+       }
+       return nil
+}
+
+func (db *DB) hEncodeSizeKey(key []byte) []byte {
+       buf := make([]byte, len(key)+2)
+
+       buf[0] = db.index
+       buf[1] = HSizeType
+
+       copy(buf[2:], key)
+       return buf
+}
+
+func (db *DB) hDecodeSizeKey(ek []byte) ([]byte, error) {
+       if len(ek) < 2 || ek[0] != db.index || ek[1] != HSizeType {
+               return nil, errHSizeKey
+       }
+
+       return ek[2:], nil
+}
+
+func (db *DB) hEncodeHashKey(key []byte, field []byte) []byte {
+       buf := make([]byte, len(key)+len(field)+1+1+2+1)
+
+       pos := 0
+       buf[pos] = db.index
+       pos++
+       buf[pos] = HashType
+       pos++
+
+       binary.BigEndian.PutUint16(buf[pos:], uint16(len(key)))
+       pos += 2
+
+       copy(buf[pos:], key)
+       pos += len(key)
+
+       buf[pos] = hashStartSep
+       pos++
+       copy(buf[pos:], field)
+
+       return buf
+}
+
+func (db *DB) hDecodeHashKey(ek []byte) ([]byte, []byte, error) {
+       if len(ek) < 5 || ek[0] != db.index || ek[1] != HashType {
+               return nil, nil, errHashKey
+       }
+
+       pos := 2
+       keyLen := int(binary.BigEndian.Uint16(ek[pos:]))
+       pos += 2
+
+       if keyLen+5 > len(ek) {
+               return nil, nil, errHashKey
+       }
+
+       key := ek[pos : pos+keyLen]
+       pos += keyLen
+
+       if ek[pos] != hashStartSep {
+               return nil, nil, errHashKey
+       }
+
+       pos++
+       field := ek[pos:]
+       return key, field, nil
+}
+
+func (db *DB) hEncodeStartKey(key []byte) []byte {
+       return db.hEncodeHashKey(key, nil)
+}
+
+func (db *DB) hEncodeStopKey(key []byte) []byte {
+       k := db.hEncodeHashKey(key, nil)
+
+       k[len(k)-1] = hashStopSep
+
+       return k
+}
+
+func (db *DB) hSetItem(key []byte, field []byte, value []byte) (int64, error) {
+       t := db.hashBatch
+
+       ek := db.hEncodeHashKey(key, field)
+
+       var n int64 = 1
+       if v, _ := db.bucket.Get(ek); v != nil {
+               n = 0
+       } else {
+               if _, err := db.hIncrSize(key, 1); err != nil {
+                       return 0, err
+               }
+       }
+
+       t.Put(ek, value)
+       return n, nil
+}
+
+//     ps : here just focus on deleting the hash data,
+//              any other likes expire is ignore.
+func (db *DB) hDelete(t *batch, key []byte) int64 {
+       sk := db.hEncodeSizeKey(key)
+       start := db.hEncodeStartKey(key)
+       stop := db.hEncodeStopKey(key)
+
+       var num int64 = 0
+       it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1)
+       for ; it.Valid(); it.Next() {
+               t.Delete(it.Key())
+               num++
+       }
+       it.Close()
+
+       t.Delete(sk)
+       return num
+}
+
+func (db *DB) hExpireAt(key []byte, when int64) (int64, error) {
+       t := db.hashBatch
+       t.Lock()
+       defer t.Unlock()
+
+       if hlen, err := db.HLen(key); err != nil || hlen == 0 {
+               return 0, err
+       } else {
+               db.expireAt(t, HashType, key, when)
+               if err := t.Commit(); err != nil {
+                       return 0, err
+               }
+       }
+       return 1, nil
+}
+
+func (db *DB) HLen(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+
+       return Int64(db.bucket.Get(db.hEncodeSizeKey(key)))
+}
+
+func (db *DB) HSet(key []byte, field []byte, value []byte) (int64, error) {
+       if err := checkHashKFSize(key, field); err != nil {
+               return 0, err
+       } else if err := checkValueSize(value); err != nil {
+               return 0, err
+       }
+
+       t := db.hashBatch
+       t.Lock()
+       defer t.Unlock()
+
+       n, err := db.hSetItem(key, field, value)
+       if err != nil {
+               return 0, err
+       }
+
+       //todo add binlog
+
+       err = t.Commit()
+       return n, err
+}
+
+func (db *DB) HGet(key []byte, field []byte) ([]byte, error) {
+       if err := checkHashKFSize(key, field); err != nil {
+               return nil, err
+       }
+
+       return db.bucket.Get(db.hEncodeHashKey(key, field))
+}
+
+func (db *DB) HMset(key []byte, args ...FVPair) error {
+       t := db.hashBatch
+       t.Lock()
+       defer t.Unlock()
+
+       var err error
+       var ek []byte
+       var num int64 = 0
+       for i := 0; i < len(args); i++ {
+               if err := checkHashKFSize(key, args[i].Field); err != nil {
+                       return err
+               } else if err := checkValueSize(args[i].Value); err != nil {
+                       return err
+               }
+
+               ek = db.hEncodeHashKey(key, args[i].Field)
+
+               if v, err := db.bucket.Get(ek); err != nil {
+                       return err
+               } else if v == nil {
+                       num++
+               }
+
+               t.Put(ek, args[i].Value)
+       }
+
+       if _, err = db.hIncrSize(key, num); err != nil {
+               return err
+       }
+
+       //todo add binglog
+       err = t.Commit()
+       return err
+}
+
+func (db *DB) HMget(key []byte, args ...[]byte) ([][]byte, error) {
+       var ek []byte
+
+       it := db.bucket.NewIterator()
+       defer it.Close()
+
+       r := make([][]byte, len(args))
+       for i := 0; i < len(args); i++ {
+               if err := checkHashKFSize(key, args[i]); err != nil {
+                       return nil, err
+               }
+
+               ek = db.hEncodeHashKey(key, args[i])
+
+               r[i] = it.Find(ek)
+       }
+
+       return r, nil
+}
+
+func (db *DB) HDel(key []byte, args ...[]byte) (int64, error) {
+       t := db.hashBatch
+
+       var ek []byte
+       var v []byte
+       var err error
+
+       t.Lock()
+       defer t.Unlock()
+
+       it := db.bucket.NewIterator()
+       defer it.Close()
+
+       var num int64 = 0
+       for i := 0; i < len(args); i++ {
+               if err := checkHashKFSize(key, args[i]); err != nil {
+                       return 0, err
+               }
+
+               ek = db.hEncodeHashKey(key, args[i])
+
+               v = it.RawFind(ek)
+               if v == nil {
+                       continue
+               } else {
+                       num++
+                       t.Delete(ek)
+               }
+       }
+
+       if _, err = db.hIncrSize(key, -num); err != nil {
+               return 0, err
+       }
+
+       err = t.Commit()
+
+       return num, err
+}
+
+func (db *DB) hIncrSize(key []byte, delta int64) (int64, error) {
+       t := db.hashBatch
+       sk := db.hEncodeSizeKey(key)
+
+       var err error
+       var size int64 = 0
+       if size, err = Int64(db.bucket.Get(sk)); err != nil {
+               return 0, err
+       } else {
+               size += delta
+               if size <= 0 {
+                       size = 0
+                       t.Delete(sk)
+                       db.rmExpire(t, HashType, key)
+               } else {
+                       t.Put(sk, PutInt64(size))
+               }
+       }
+
+       return size, nil
+}
+
+func (db *DB) HIncrBy(key []byte, field []byte, delta int64) (int64, error) {
+       if err := checkHashKFSize(key, field); err != nil {
+               return 0, err
+       }
+
+       t := db.hashBatch
+       var ek []byte
+       var err error
+
+       t.Lock()
+       defer t.Unlock()
+
+       ek = db.hEncodeHashKey(key, field)
+
+       var n int64 = 0
+       if n, err = StrInt64(db.bucket.Get(ek)); err != nil {
+               return 0, err
+       }
+
+       n += delta
+
+       _, err = db.hSetItem(key, field, StrPutInt64(n))
+       if err != nil {
+               return 0, err
+       }
+
+       err = t.Commit()
+
+       return n, err
+}
+
+func (db *DB) HGetAll(key []byte) ([]FVPair, error) {
+       if err := checkKeySize(key); err != nil {
+               return nil, err
+       }
+
+       start := db.hEncodeStartKey(key)
+       stop := db.hEncodeStopKey(key)
+
+       v := make([]FVPair, 0, 16)
+
+       it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1)
+       for ; it.Valid(); it.Next() {
+               _, f, err := db.hDecodeHashKey(it.Key())
+               if err != nil {
+                       return nil, err
+               }
+
+               v = append(v, FVPair{Field: f, Value: it.Value()})
+       }
+
+       it.Close()
+
+       return v, nil
+}
+
+func (db *DB) HKeys(key []byte) ([][]byte, error) {
+       if err := checkKeySize(key); err != nil {
+               return nil, err
+       }
+
+       start := db.hEncodeStartKey(key)
+       stop := db.hEncodeStopKey(key)
+
+       v := make([][]byte, 0, 16)
+
+       it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1)
+       for ; it.Valid(); it.Next() {
+               _, f, err := db.hDecodeHashKey(it.Key())
+               if err != nil {
+                       return nil, err
+               }
+               v = append(v, f)
+       }
+
+       it.Close()
+
+       return v, nil
+}
+
+func (db *DB) HValues(key []byte) ([][]byte, error) {
+       if err := checkKeySize(key); err != nil {
+               return nil, err
+       }
+
+       start := db.hEncodeStartKey(key)
+       stop := db.hEncodeStopKey(key)
+
+       v := make([][]byte, 0, 16)
+
+       it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1)
+       for ; it.Valid(); it.Next() {
+               _, _, err := db.hDecodeHashKey(it.Key())
+               if err != nil {
+                       return nil, err
+               }
+
+               v = append(v, it.Value())
+       }
+
+       it.Close()
+
+       return v, nil
+}
+
+func (db *DB) HClear(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+
+       t := db.hashBatch
+       t.Lock()
+       defer t.Unlock()
+
+       num := db.hDelete(t, key)
+       db.rmExpire(t, HashType, key)
+
+       err := t.Commit()
+       return num, err
+}
+
+func (db *DB) HMclear(keys ...[]byte) (int64, error) {
+       t := db.hashBatch
+       t.Lock()
+       defer t.Unlock()
+
+       for _, key := range keys {
+               if err := checkKeySize(key); err != nil {
+                       return 0, err
+               }
+
+               db.hDelete(t, key)
+               db.rmExpire(t, HashType, key)
+       }
+
+       err := t.Commit()
+       return int64(len(keys)), err
+}
+
+func (db *DB) hFlush() (drop int64, err error) {
+       t := db.hashBatch
+
+       t.Lock()
+       defer t.Unlock()
+
+       return db.flushType(t, HashType)
+}
+
+func (db *DB) HScan(key []byte, count int, inclusive bool, match string) ([][]byte, error) {
+       return db.scan(HSizeType, key, count, inclusive, match)
+}
+
+func (db *DB) HExpire(key []byte, duration int64) (int64, error) {
+       if duration <= 0 {
+               return 0, errExpireValue
+       }
+
+       return db.hExpireAt(key, time.Now().Unix()+duration)
+}
+
+func (db *DB) HExpireAt(key []byte, when int64) (int64, error) {
+       if when <= time.Now().Unix() {
+               return 0, errExpireValue
+       }
+
+       return db.hExpireAt(key, when)
+}
+
+func (db *DB) HTTL(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return -1, err
+       }
+
+       return db.ttl(HashType, key)
+}
+
+func (db *DB) HPersist(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+
+       t := db.hashBatch
+       t.Lock()
+       defer t.Unlock()
+
+       n, err := db.rmExpire(t, HashType, key)
+       if err != nil {
+               return 0, err
+       }
+
+       err = t.Commit()
+       return n, err
+}
diff --git a/vendor/gitea.com/lunny/nodb/t_kv.go b/vendor/gitea.com/lunny/nodb/t_kv.go
new file mode 100644 (file)
index 0000000..82a12f7
--- /dev/null
@@ -0,0 +1,387 @@
+package nodb
+
+import (
+       "errors"
+       "time"
+)
+
+type KVPair struct {
+       Key   []byte
+       Value []byte
+}
+
+var errKVKey = errors.New("invalid encode kv key")
+
+func checkKeySize(key []byte) error {
+       if len(key) > MaxKeySize || len(key) == 0 {
+               return errKeySize
+       }
+       return nil
+}
+
+func checkValueSize(value []byte) error {
+       if len(value) > MaxValueSize {
+               return errValueSize
+       }
+
+       return nil
+}
+
+func (db *DB) encodeKVKey(key []byte) []byte {
+       ek := make([]byte, len(key)+2)
+       ek[0] = db.index
+       ek[1] = KVType
+       copy(ek[2:], key)
+       return ek
+}
+
+func (db *DB) decodeKVKey(ek []byte) ([]byte, error) {
+       if len(ek) < 2 || ek[0] != db.index || ek[1] != KVType {
+               return nil, errKVKey
+       }
+
+       return ek[2:], nil
+}
+
+func (db *DB) encodeKVMinKey() []byte {
+       ek := db.encodeKVKey(nil)
+       return ek
+}
+
+func (db *DB) encodeKVMaxKey() []byte {
+       ek := db.encodeKVKey(nil)
+       ek[len(ek)-1] = KVType + 1
+       return ek
+}
+
+func (db *DB) incr(key []byte, delta int64) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+
+       var err error
+       key = db.encodeKVKey(key)
+
+       t := db.kvBatch
+
+       t.Lock()
+       defer t.Unlock()
+
+       var n int64
+       n, err = StrInt64(db.bucket.Get(key))
+       if err != nil {
+               return 0, err
+       }
+
+       n += delta
+
+       t.Put(key, StrPutInt64(n))
+
+       //todo binlog
+
+       err = t.Commit()
+       return n, err
+}
+
+//     ps : here just focus on deleting the key-value data,
+//              any other likes expire is ignore.
+func (db *DB) delete(t *batch, key []byte) int64 {
+       key = db.encodeKVKey(key)
+       t.Delete(key)
+       return 1
+}
+
+func (db *DB) setExpireAt(key []byte, when int64) (int64, error) {
+       t := db.kvBatch
+       t.Lock()
+       defer t.Unlock()
+
+       if exist, err := db.Exists(key); err != nil || exist == 0 {
+               return 0, err
+       } else {
+               db.expireAt(t, KVType, key, when)
+               if err := t.Commit(); err != nil {
+                       return 0, err
+               }
+       }
+       return 1, nil
+}
+
+func (db *DB) Decr(key []byte) (int64, error) {
+       return db.incr(key, -1)
+}
+
+func (db *DB) DecrBy(key []byte, decrement int64) (int64, error) {
+       return db.incr(key, -decrement)
+}
+
+func (db *DB) Del(keys ...[]byte) (int64, error) {
+       if len(keys) == 0 {
+               return 0, nil
+       }
+
+       codedKeys := make([][]byte, len(keys))
+       for i, k := range keys {
+               codedKeys[i] = db.encodeKVKey(k)
+       }
+
+       t := db.kvBatch
+       t.Lock()
+       defer t.Unlock()
+
+       for i, k := range keys {
+               t.Delete(codedKeys[i])
+               db.rmExpire(t, KVType, k)
+       }
+
+       err := t.Commit()
+       return int64(len(keys)), err
+}
+
+func (db *DB) Exists(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+
+       var err error
+       key = db.encodeKVKey(key)
+
+       var v []byte
+       v, err = db.bucket.Get(key)
+       if v != nil && err == nil {
+               return 1, nil
+       }
+
+       return 0, err
+}
+
+func (db *DB) Get(key []byte) ([]byte, error) {
+       if err := checkKeySize(key); err != nil {
+               return nil, err
+       }
+
+       key = db.encodeKVKey(key)
+
+       return db.bucket.Get(key)
+}
+
+func (db *DB) GetSet(key []byte, value []byte) ([]byte, error) {
+       if err := checkKeySize(key); err != nil {
+               return nil, err
+       } else if err := checkValueSize(value); err != nil {
+               return nil, err
+       }
+
+       key = db.encodeKVKey(key)
+
+       t := db.kvBatch
+
+       t.Lock()
+       defer t.Unlock()
+
+       oldValue, err := db.bucket.Get(key)
+       if err != nil {
+               return nil, err
+       }
+
+       t.Put(key, value)
+       //todo, binlog
+
+       err = t.Commit()
+
+       return oldValue, err
+}
+
+func (db *DB) Incr(key []byte) (int64, error) {
+       return db.incr(key, 1)
+}
+
+func (db *DB) IncrBy(key []byte, increment int64) (int64, error) {
+       return db.incr(key, increment)
+}
+
+func (db *DB) MGet(keys ...[]byte) ([][]byte, error) {
+       values := make([][]byte, len(keys))
+
+       it := db.bucket.NewIterator()
+       defer it.Close()
+
+       for i := range keys {
+               if err := checkKeySize(keys[i]); err != nil {
+                       return nil, err
+               }
+
+               values[i] = it.Find(db.encodeKVKey(keys[i]))
+       }
+
+       return values, nil
+}
+
+func (db *DB) MSet(args ...KVPair) error {
+       if len(args) == 0 {
+               return nil
+       }
+
+       t := db.kvBatch
+
+       var err error
+       var key []byte
+       var value []byte
+
+       t.Lock()
+       defer t.Unlock()
+
+       for i := 0; i < len(args); i++ {
+               if err := checkKeySize(args[i].Key); err != nil {
+                       return err
+               } else if err := checkValueSize(args[i].Value); err != nil {
+                       return err
+               }
+
+               key = db.encodeKVKey(args[i].Key)
+
+               value = args[i].Value
+
+               t.Put(key, value)
+
+               //todo binlog
+       }
+
+       err = t.Commit()
+       return err
+}
+
+func (db *DB) Set(key []byte, value []byte) error {
+       if err := checkKeySize(key); err != nil {
+               return err
+       } else if err := checkValueSize(value); err != nil {
+               return err
+       }
+
+       var err error
+       key = db.encodeKVKey(key)
+
+       t := db.kvBatch
+
+       t.Lock()
+       defer t.Unlock()
+
+       t.Put(key, value)
+
+       err = t.Commit()
+
+       return err
+}
+
+func (db *DB) SetNX(key []byte, value []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       } else if err := checkValueSize(value); err != nil {
+               return 0, err
+       }
+
+       var err error
+       key = db.encodeKVKey(key)
+
+       var n int64 = 1
+
+       t := db.kvBatch
+
+       t.Lock()
+       defer t.Unlock()
+
+       if v, err := db.bucket.Get(key); err != nil {
+               return 0, err
+       } else if v != nil {
+               n = 0
+       } else {
+               t.Put(key, value)
+
+               //todo binlog
+
+               err = t.Commit()
+       }
+
+       return n, err
+}
+
+func (db *DB) flush() (drop int64, err error) {
+       t := db.kvBatch
+       t.Lock()
+       defer t.Unlock()
+       return db.flushType(t, KVType)
+}
+
+//if inclusive is true, scan range [key, inf) else (key, inf)
+func (db *DB) Scan(key []byte, count int, inclusive bool, match string) ([][]byte, error) {
+       return db.scan(KVType, key, count, inclusive, match)
+}
+
+func (db *DB) Expire(key []byte, duration int64) (int64, error) {
+       if duration <= 0 {
+               return 0, errExpireValue
+       }
+
+       return db.setExpireAt(key, time.Now().Unix()+duration)
+}
+
+func (db *DB) ExpireAt(key []byte, when int64) (int64, error) {
+       if when <= time.Now().Unix() {
+               return 0, errExpireValue
+       }
+
+       return db.setExpireAt(key, when)
+}
+
+func (db *DB) TTL(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return -1, err
+       }
+
+       return db.ttl(KVType, key)
+}
+
+func (db *DB) Persist(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+
+       t := db.kvBatch
+       t.Lock()
+       defer t.Unlock()
+       n, err := db.rmExpire(t, KVType, key)
+       if err != nil {
+               return 0, err
+       }
+
+       err = t.Commit()
+       return n, err
+}
+
+func (db *DB) Lock() {
+       t := db.kvBatch
+       t.Lock()
+}
+
+func (db *DB) Remove(key []byte) bool {
+       if len(key) == 0 {
+               return false
+       }
+       t := db.kvBatch
+       t.Delete(db.encodeKVKey(key))
+       _, err := db.rmExpire(t, KVType, key)
+       if err != nil {
+               return false
+       }
+       return true
+}
+
+func (db *DB) Commit() error {
+       t := db.kvBatch
+       return t.Commit()
+}
+
+func (db *DB) Unlock() {
+       t := db.kvBatch
+       t.Unlock()
+}
diff --git a/vendor/gitea.com/lunny/nodb/t_list.go b/vendor/gitea.com/lunny/nodb/t_list.go
new file mode 100644 (file)
index 0000000..6e66604
--- /dev/null
@@ -0,0 +1,492 @@
+package nodb
+
+import (
+       "encoding/binary"
+       "errors"
+       "time"
+
+       "gitea.com/lunny/nodb/store"
+)
+
+const (
+       listHeadSeq int32 = 1
+       listTailSeq int32 = 2
+
+       listMinSeq     int32 = 1000
+       listMaxSeq     int32 = 1<<31 - 1000
+       listInitialSeq int32 = listMinSeq + (listMaxSeq-listMinSeq)/2
+)
+
+var errLMetaKey = errors.New("invalid lmeta key")
+var errListKey = errors.New("invalid list key")
+var errListSeq = errors.New("invalid list sequence, overflow")
+
+func (db *DB) lEncodeMetaKey(key []byte) []byte {
+       buf := make([]byte, len(key)+2)
+       buf[0] = db.index
+       buf[1] = LMetaType
+
+       copy(buf[2:], key)
+       return buf
+}
+
+func (db *DB) lDecodeMetaKey(ek []byte) ([]byte, error) {
+       if len(ek) < 2 || ek[0] != db.index || ek[1] != LMetaType {
+               return nil, errLMetaKey
+       }
+
+       return ek[2:], nil
+}
+
+func (db *DB) lEncodeListKey(key []byte, seq int32) []byte {
+       buf := make([]byte, len(key)+8)
+
+       pos := 0
+       buf[pos] = db.index
+       pos++
+       buf[pos] = ListType
+       pos++
+
+       binary.BigEndian.PutUint16(buf[pos:], uint16(len(key)))
+       pos += 2
+
+       copy(buf[pos:], key)
+       pos += len(key)
+
+       binary.BigEndian.PutUint32(buf[pos:], uint32(seq))
+
+       return buf
+}
+
+func (db *DB) lDecodeListKey(ek []byte) (key []byte, seq int32, err error) {
+       if len(ek) < 8 || ek[0] != db.index || ek[1] != ListType {
+               err = errListKey
+               return
+       }
+
+       keyLen := int(binary.BigEndian.Uint16(ek[2:]))
+       if keyLen+8 != len(ek) {
+               err = errListKey
+               return
+       }
+
+       key = ek[4 : 4+keyLen]
+       seq = int32(binary.BigEndian.Uint32(ek[4+keyLen:]))
+       return
+}
+
+func (db *DB) lpush(key []byte, whereSeq int32, args ...[]byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+
+       var headSeq int32
+       var tailSeq int32
+       var size int32
+       var err error
+
+       t := db.listBatch
+       t.Lock()
+       defer t.Unlock()
+
+       metaKey := db.lEncodeMetaKey(key)
+       headSeq, tailSeq, size, err = db.lGetMeta(nil, metaKey)
+       if err != nil {
+               return 0, err
+       }
+
+       var pushCnt int = len(args)
+       if pushCnt == 0 {
+               return int64(size), nil
+       }
+
+       var seq int32 = headSeq
+       var delta int32 = -1
+       if whereSeq == listTailSeq {
+               seq = tailSeq
+               delta = 1
+       }
+
+       //      append elements
+       if size > 0 {
+               seq += delta
+       }
+
+       for i := 0; i < pushCnt; i++ {
+               ek := db.lEncodeListKey(key, seq+int32(i)*delta)
+               t.Put(ek, args[i])
+       }
+
+       seq += int32(pushCnt-1) * delta
+       if seq <= listMinSeq || seq >= listMaxSeq {
+               return 0, errListSeq
+       }
+
+       //      set meta info
+       if whereSeq == listHeadSeq {
+               headSeq = seq
+       } else {
+               tailSeq = seq
+       }
+
+       db.lSetMeta(metaKey, headSeq, tailSeq)
+
+       err = t.Commit()
+       return int64(size) + int64(pushCnt), err
+}
+
+func (db *DB) lpop(key []byte, whereSeq int32) ([]byte, error) {
+       if err := checkKeySize(key); err != nil {
+               return nil, err
+       }
+
+       t := db.listBatch
+       t.Lock()
+       defer t.Unlock()
+
+       var headSeq int32
+       var tailSeq int32
+       var err error
+
+       metaKey := db.lEncodeMetaKey(key)
+       headSeq, tailSeq, _, err = db.lGetMeta(nil, metaKey)
+       if err != nil {
+               return nil, err
+       }
+
+       var value []byte
+
+       var seq int32 = headSeq
+       if whereSeq == listTailSeq {
+               seq = tailSeq
+       }
+
+       itemKey := db.lEncodeListKey(key, seq)
+       value, err = db.bucket.Get(itemKey)
+       if err != nil {
+               return nil, err
+       }
+
+       if whereSeq == listHeadSeq {
+               headSeq += 1
+       } else {
+               tailSeq -= 1
+       }
+
+       t.Delete(itemKey)
+       size := db.lSetMeta(metaKey, headSeq, tailSeq)
+       if size == 0 {
+               db.rmExpire(t, HashType, key)
+       }
+
+       err = t.Commit()
+       return value, err
+}
+
+//     ps : here just focus on deleting the list data,
+//              any other likes expire is ignore.
+func (db *DB) lDelete(t *batch, key []byte) int64 {
+       mk := db.lEncodeMetaKey(key)
+
+       var headSeq int32
+       var tailSeq int32
+       var err error
+
+       it := db.bucket.NewIterator()
+       defer it.Close()
+
+       headSeq, tailSeq, _, err = db.lGetMeta(it, mk)
+       if err != nil {
+               return 0
+       }
+
+       var num int64 = 0
+       startKey := db.lEncodeListKey(key, headSeq)
+       stopKey := db.lEncodeListKey(key, tailSeq)
+
+       rit := store.NewRangeIterator(it, &store.Range{startKey, stopKey, store.RangeClose})
+       for ; rit.Valid(); rit.Next() {
+               t.Delete(rit.RawKey())
+               num++
+       }
+
+       t.Delete(mk)
+
+       return num
+}
+
+func (db *DB) lGetMeta(it *store.Iterator, ek []byte) (headSeq int32, tailSeq int32, size int32, err error) {
+       var v []byte
+       if it != nil {
+               v = it.Find(ek)
+       } else {
+               v, err = db.bucket.Get(ek)
+       }
+       if err != nil {
+               return
+       } else if v == nil {
+               headSeq = listInitialSeq
+               tailSeq = listInitialSeq
+               size = 0
+               return
+       } else {
+               headSeq = int32(binary.LittleEndian.Uint32(v[0:4]))
+               tailSeq = int32(binary.LittleEndian.Uint32(v[4:8]))
+               size = tailSeq - headSeq + 1
+       }
+       return
+}
+
+func (db *DB) lSetMeta(ek []byte, headSeq int32, tailSeq int32) int32 {
+       t := db.listBatch
+
+       var size int32 = tailSeq - headSeq + 1
+       if size < 0 {
+               //      todo : log error + panic
+       } else if size == 0 {
+               t.Delete(ek)
+       } else {
+               buf := make([]byte, 8)
+
+               binary.LittleEndian.PutUint32(buf[0:4], uint32(headSeq))
+               binary.LittleEndian.PutUint32(buf[4:8], uint32(tailSeq))
+
+               t.Put(ek, buf)
+       }
+
+       return size
+}
+
+func (db *DB) lExpireAt(key []byte, when int64) (int64, error) {
+       t := db.listBatch
+       t.Lock()
+       defer t.Unlock()
+
+       if llen, err := db.LLen(key); err != nil || llen == 0 {
+               return 0, err
+       } else {
+               db.expireAt(t, ListType, key, when)
+               if err := t.Commit(); err != nil {
+                       return 0, err
+               }
+       }
+       return 1, nil
+}
+
+func (db *DB) LIndex(key []byte, index int32) ([]byte, error) {
+       if err := checkKeySize(key); err != nil {
+               return nil, err
+       }
+
+       var seq int32
+       var headSeq int32
+       var tailSeq int32
+       var err error
+
+       metaKey := db.lEncodeMetaKey(key)
+
+       it := db.bucket.NewIterator()
+       defer it.Close()
+
+       headSeq, tailSeq, _, err = db.lGetMeta(it, metaKey)
+       if err != nil {
+               return nil, err
+       }
+
+       if index >= 0 {
+               seq = headSeq + index
+       } else {
+               seq = tailSeq + index + 1
+       }
+
+       sk := db.lEncodeListKey(key, seq)
+       v := it.Find(sk)
+
+       return v, nil
+}
+
+func (db *DB) LLen(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+
+       ek := db.lEncodeMetaKey(key)
+       _, _, size, err := db.lGetMeta(nil, ek)
+       return int64(size), err
+}
+
+func (db *DB) LPop(key []byte) ([]byte, error) {
+       return db.lpop(key, listHeadSeq)
+}
+
+func (db *DB) LPush(key []byte, arg1 []byte, args ...[]byte) (int64, error) {
+       var argss = [][]byte{arg1}
+       argss = append(argss, args...)
+       return db.lpush(key, listHeadSeq, argss...)
+}
+
+func (db *DB) LRange(key []byte, start int32, stop int32) ([][]byte, error) {
+       if err := checkKeySize(key); err != nil {
+               return nil, err
+       }
+
+       var headSeq int32
+       var llen int32
+       var err error
+
+       metaKey := db.lEncodeMetaKey(key)
+
+       it := db.bucket.NewIterator()
+       defer it.Close()
+
+       if headSeq, _, llen, err = db.lGetMeta(it, metaKey); err != nil {
+               return nil, err
+       }
+
+       if start < 0 {
+               start = llen + start
+       }
+       if stop < 0 {
+               stop = llen + stop
+       }
+       if start < 0 {
+               start = 0
+       }
+
+       if start > stop || start >= llen {
+               return [][]byte{}, nil
+       }
+
+       if stop >= llen {
+               stop = llen - 1
+       }
+
+       limit := (stop - start) + 1
+       headSeq += start
+
+       v := make([][]byte, 0, limit)
+
+       startKey := db.lEncodeListKey(key, headSeq)
+       rit := store.NewRangeLimitIterator(it,
+               &store.Range{
+                       Min:  startKey,
+                       Max:  nil,
+                       Type: store.RangeClose},
+               &store.Limit{
+                       Offset: 0,
+                       Count:  int(limit)})
+
+       for ; rit.Valid(); rit.Next() {
+               v = append(v, rit.Value())
+       }
+
+       return v, nil
+}
+
+func (db *DB) RPop(key []byte) ([]byte, error) {
+       return db.lpop(key, listTailSeq)
+}
+
+func (db *DB) RPush(key []byte, arg1 []byte, args ...[]byte) (int64, error) {
+       var argss = [][]byte{arg1}
+       argss = append(argss, args...)
+       return db.lpush(key, listTailSeq, argss...)
+}
+
+func (db *DB) LClear(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+
+       t := db.listBatch
+       t.Lock()
+       defer t.Unlock()
+
+       num := db.lDelete(t, key)
+       db.rmExpire(t, ListType, key)
+
+       err := t.Commit()
+       return num, err
+}
+
+func (db *DB) LMclear(keys ...[]byte) (int64, error) {
+       t := db.listBatch
+       t.Lock()
+       defer t.Unlock()
+
+       for _, key := range keys {
+               if err := checkKeySize(key); err != nil {
+                       return 0, err
+               }
+
+               db.lDelete(t, key)
+               db.rmExpire(t, ListType, key)
+
+       }
+
+       err := t.Commit()
+       return int64(len(keys)), err
+}
+
+func (db *DB) lFlush() (drop int64, err error) {
+       t := db.listBatch
+       t.Lock()
+       defer t.Unlock()
+       return db.flushType(t, ListType)
+}
+
+func (db *DB) LExpire(key []byte, duration int64) (int64, error) {
+       if duration <= 0 {
+               return 0, errExpireValue
+       }
+
+       return db.lExpireAt(key, time.Now().Unix()+duration)
+}
+
+func (db *DB) LExpireAt(key []byte, when int64) (int64, error) {
+       if when <= time.Now().Unix() {
+               return 0, errExpireValue
+       }
+
+       return db.lExpireAt(key, when)
+}
+
+func (db *DB) LTTL(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return -1, err
+       }
+
+       return db.ttl(ListType, key)
+}
+
+func (db *DB) LPersist(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+
+       t := db.listBatch
+       t.Lock()
+       defer t.Unlock()
+
+       n, err := db.rmExpire(t, ListType, key)
+       if err != nil {
+               return 0, err
+       }
+
+       err = t.Commit()
+       return n, err
+}
+
+func (db *DB) LScan(key []byte, count int, inclusive bool, match string) ([][]byte, error) {
+       return db.scan(LMetaType, key, count, inclusive, match)
+}
+
+func (db *DB) lEncodeMinKey() []byte {
+       return db.lEncodeMetaKey(nil)
+}
+
+func (db *DB) lEncodeMaxKey() []byte {
+       ek := db.lEncodeMetaKey(nil)
+       ek[len(ek)-1] = LMetaType + 1
+       return ek
+}
diff --git a/vendor/gitea.com/lunny/nodb/t_set.go b/vendor/gitea.com/lunny/nodb/t_set.go
new file mode 100644 (file)
index 0000000..0ff33e9
--- /dev/null
@@ -0,0 +1,601 @@
+package nodb
+
+import (
+       "encoding/binary"
+       "errors"
+       "time"
+
+       "gitea.com/lunny/nodb/store"
+)
+
+var errSetKey = errors.New("invalid set key")
+var errSSizeKey = errors.New("invalid ssize key")
+
+const (
+       setStartSep byte = ':'
+       setStopSep  byte = setStartSep + 1
+       UnionType   byte = 51
+       DiffType    byte = 52
+       InterType   byte = 53
+)
+
+func checkSetKMSize(key []byte, member []byte) error {
+       if len(key) > MaxKeySize || len(key) == 0 {
+               return errKeySize
+       } else if len(member) > MaxSetMemberSize || len(member) == 0 {
+               return errSetMemberSize
+       }
+       return nil
+}
+
+func (db *DB) sEncodeSizeKey(key []byte) []byte {
+       buf := make([]byte, len(key)+2)
+
+       buf[0] = db.index
+       buf[1] = SSizeType
+
+       copy(buf[2:], key)
+       return buf
+}
+
+func (db *DB) sDecodeSizeKey(ek []byte) ([]byte, error) {
+       if len(ek) < 2 || ek[0] != db.index || ek[1] != SSizeType {
+               return nil, errSSizeKey
+       }
+
+       return ek[2:], nil
+}
+
+func (db *DB) sEncodeSetKey(key []byte, member []byte) []byte {
+       buf := make([]byte, len(key)+len(member)+1+1+2+1)
+
+       pos := 0
+       buf[pos] = db.index
+       pos++
+       buf[pos] = SetType
+       pos++
+
+       binary.BigEndian.PutUint16(buf[pos:], uint16(len(key)))
+       pos += 2
+
+       copy(buf[pos:], key)
+       pos += len(key)
+
+       buf[pos] = setStartSep
+       pos++
+       copy(buf[pos:], member)
+
+       return buf
+}
+
+func (db *DB) sDecodeSetKey(ek []byte) ([]byte, []byte, error) {
+       if len(ek) < 5 || ek[0] != db.index || ek[1] != SetType {
+               return nil, nil, errSetKey
+       }
+
+       pos := 2
+       keyLen := int(binary.BigEndian.Uint16(ek[pos:]))
+       pos += 2
+
+       if keyLen+5 > len(ek) {
+               return nil, nil, errSetKey
+       }
+
+       key := ek[pos : pos+keyLen]
+       pos += keyLen
+
+       if ek[pos] != hashStartSep {
+               return nil, nil, errSetKey
+       }
+
+       pos++
+       member := ek[pos:]
+       return key, member, nil
+}
+
+func (db *DB) sEncodeStartKey(key []byte) []byte {
+       return db.sEncodeSetKey(key, nil)
+}
+
+func (db *DB) sEncodeStopKey(key []byte) []byte {
+       k := db.sEncodeSetKey(key, nil)
+
+       k[len(k)-1] = setStopSep
+
+       return k
+}
+
+func (db *DB) sFlush() (drop int64, err error) {
+
+       t := db.setBatch
+       t.Lock()
+       defer t.Unlock()
+
+       return db.flushType(t, SetType)
+}
+
+func (db *DB) sDelete(t *batch, key []byte) int64 {
+       sk := db.sEncodeSizeKey(key)
+       start := db.sEncodeStartKey(key)
+       stop := db.sEncodeStopKey(key)
+
+       var num int64 = 0
+       it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1)
+       for ; it.Valid(); it.Next() {
+               t.Delete(it.RawKey())
+               num++
+       }
+
+       it.Close()
+
+       t.Delete(sk)
+       return num
+}
+
+func (db *DB) sIncrSize(key []byte, delta int64) (int64, error) {
+       t := db.setBatch
+       sk := db.sEncodeSizeKey(key)
+
+       var err error
+       var size int64 = 0
+       if size, err = Int64(db.bucket.Get(sk)); err != nil {
+               return 0, err
+       } else {
+               size += delta
+               if size <= 0 {
+                       size = 0
+                       t.Delete(sk)
+                       db.rmExpire(t, SetType, key)
+               } else {
+                       t.Put(sk, PutInt64(size))
+               }
+       }
+
+       return size, nil
+}
+
+func (db *DB) sExpireAt(key []byte, when int64) (int64, error) {
+       t := db.setBatch
+       t.Lock()
+       defer t.Unlock()
+
+       if scnt, err := db.SCard(key); err != nil || scnt == 0 {
+               return 0, err
+       } else {
+               db.expireAt(t, SetType, key, when)
+               if err := t.Commit(); err != nil {
+                       return 0, err
+               }
+
+       }
+
+       return 1, nil
+}
+
+func (db *DB) sSetItem(key []byte, member []byte) (int64, error) {
+       t := db.setBatch
+       ek := db.sEncodeSetKey(key, member)
+
+       var n int64 = 1
+       if v, _ := db.bucket.Get(ek); v != nil {
+               n = 0
+       } else {
+               if _, err := db.sIncrSize(key, 1); err != nil {
+                       return 0, err
+               }
+       }
+
+       t.Put(ek, nil)
+       return n, nil
+}
+
+func (db *DB) SAdd(key []byte, args ...[]byte) (int64, error) {
+       t := db.setBatch
+       t.Lock()
+       defer t.Unlock()
+
+       var err error
+       var ek []byte
+       var num int64 = 0
+       for i := 0; i < len(args); i++ {
+               if err := checkSetKMSize(key, args[i]); err != nil {
+                       return 0, err
+               }
+
+               ek = db.sEncodeSetKey(key, args[i])
+
+               if v, err := db.bucket.Get(ek); err != nil {
+                       return 0, err
+               } else if v == nil {
+                       num++
+               }
+
+               t.Put(ek, nil)
+       }
+
+       if _, err = db.sIncrSize(key, num); err != nil {
+               return 0, err
+       }
+
+       err = t.Commit()
+       return num, err
+
+}
+
+func (db *DB) SCard(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+
+       sk := db.sEncodeSizeKey(key)
+
+       return Int64(db.bucket.Get(sk))
+}
+
+func (db *DB) sDiffGeneric(keys ...[]byte) ([][]byte, error) {
+       destMap := make(map[string]bool)
+
+       members, err := db.SMembers(keys[0])
+       if err != nil {
+               return nil, err
+       }
+
+       for _, m := range members {
+               destMap[String(m)] = true
+       }
+
+       for _, k := range keys[1:] {
+               members, err := db.SMembers(k)
+               if err != nil {
+                       return nil, err
+               }
+
+               for _, m := range members {
+                       if _, ok := destMap[String(m)]; !ok {
+                               continue
+                       } else if ok {
+                               delete(destMap, String(m))
+                       }
+               }
+               // O - A = O, O is zero set.
+               if len(destMap) == 0 {
+                       return nil, nil
+               }
+       }
+
+       slice := make([][]byte, len(destMap))
+       idx := 0
+       for k, v := range destMap {
+               if !v {
+                       continue
+               }
+               slice[idx] = []byte(k)
+               idx++
+       }
+
+       return slice, nil
+}
+
+func (db *DB) SDiff(keys ...[]byte) ([][]byte, error) {
+       v, err := db.sDiffGeneric(keys...)
+       return v, err
+}
+
+func (db *DB) SDiffStore(dstKey []byte, keys ...[]byte) (int64, error) {
+       n, err := db.sStoreGeneric(dstKey, DiffType, keys...)
+       return n, err
+}
+
+func (db *DB) sInterGeneric(keys ...[]byte) ([][]byte, error) {
+       destMap := make(map[string]bool)
+
+       members, err := db.SMembers(keys[0])
+       if err != nil {
+               return nil, err
+       }
+
+       for _, m := range members {
+               destMap[String(m)] = true
+       }
+
+       for _, key := range keys[1:] {
+               if err := checkKeySize(key); err != nil {
+                       return nil, err
+               }
+
+               members, err := db.SMembers(key)
+               if err != nil {
+                       return nil, err
+               } else if len(members) == 0 {
+                       return nil, err
+               }
+
+               tempMap := make(map[string]bool)
+               for _, member := range members {
+                       if err := checkKeySize(member); err != nil {
+                               return nil, err
+                       }
+                       if _, ok := destMap[String(member)]; ok {
+                               tempMap[String(member)] = true //mark this item as selected
+                       }
+               }
+               destMap = tempMap //reduce the size of the result set
+               if len(destMap) == 0 {
+                       return nil, nil
+               }
+       }
+
+       slice := make([][]byte, len(destMap))
+       idx := 0
+       for k, v := range destMap {
+               if !v {
+                       continue
+               }
+
+               slice[idx] = []byte(k)
+               idx++
+       }
+
+       return slice, nil
+
+}
+
+func (db *DB) SInter(keys ...[]byte) ([][]byte, error) {
+       v, err := db.sInterGeneric(keys...)
+       return v, err
+
+}
+
+func (db *DB) SInterStore(dstKey []byte, keys ...[]byte) (int64, error) {
+       n, err := db.sStoreGeneric(dstKey, InterType, keys...)
+       return n, err
+}
+
+func (db *DB) SIsMember(key []byte, member []byte) (int64, error) {
+       ek := db.sEncodeSetKey(key, member)
+
+       var n int64 = 1
+       if v, err := db.bucket.Get(ek); err != nil {
+               return 0, err
+       } else if v == nil {
+               n = 0
+       }
+       return n, nil
+}
+
+func (db *DB) SMembers(key []byte) ([][]byte, error) {
+       if err := checkKeySize(key); err != nil {
+               return nil, err
+       }
+
+       start := db.sEncodeStartKey(key)
+       stop := db.sEncodeStopKey(key)
+
+       v := make([][]byte, 0, 16)
+
+       it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1)
+       for ; it.Valid(); it.Next() {
+               _, m, err := db.sDecodeSetKey(it.Key())
+               if err != nil {
+                       return nil, err
+               }
+
+               v = append(v, m)
+       }
+
+       it.Close()
+
+       return v, nil
+}
+
+func (db *DB) SRem(key []byte, args ...[]byte) (int64, error) {
+       t := db.setBatch
+       t.Lock()
+       defer t.Unlock()
+
+       var ek []byte
+       var v []byte
+       var err error
+
+       it := db.bucket.NewIterator()
+       defer it.Close()
+
+       var num int64 = 0
+       for i := 0; i < len(args); i++ {
+               if err := checkSetKMSize(key, args[i]); err != nil {
+                       return 0, err
+               }
+
+               ek = db.sEncodeSetKey(key, args[i])
+
+               v = it.RawFind(ek)
+               if v == nil {
+                       continue
+               } else {
+                       num++
+                       t.Delete(ek)
+               }
+       }
+
+       if _, err = db.sIncrSize(key, -num); err != nil {
+               return 0, err
+       }
+
+       err = t.Commit()
+       return num, err
+
+}
+
+func (db *DB) sUnionGeneric(keys ...[]byte) ([][]byte, error) {
+       dstMap := make(map[string]bool)
+
+       for _, key := range keys {
+               if err := checkKeySize(key); err != nil {
+                       return nil, err
+               }
+
+               members, err := db.SMembers(key)
+               if err != nil {
+                       return nil, err
+               }
+
+               for _, member := range members {
+                       dstMap[String(member)] = true
+               }
+       }
+
+       slice := make([][]byte, len(dstMap))
+       idx := 0
+       for k, v := range dstMap {
+               if !v {
+                       continue
+               }
+               slice[idx] = []byte(k)
+               idx++
+       }
+
+       return slice, nil
+}
+
+func (db *DB) SUnion(keys ...[]byte) ([][]byte, error) {
+       v, err := db.sUnionGeneric(keys...)
+       return v, err
+}
+
+func (db *DB) SUnionStore(dstKey []byte, keys ...[]byte) (int64, error) {
+       n, err := db.sStoreGeneric(dstKey, UnionType, keys...)
+       return n, err
+}
+
+func (db *DB) sStoreGeneric(dstKey []byte, optType byte, keys ...[]byte) (int64, error) {
+       if err := checkKeySize(dstKey); err != nil {
+               return 0, err
+       }
+
+       t := db.setBatch
+       t.Lock()
+       defer t.Unlock()
+
+       db.sDelete(t, dstKey)
+
+       var err error
+       var ek []byte
+       var v [][]byte
+
+       switch optType {
+       case UnionType:
+               v, err = db.sUnionGeneric(keys...)
+       case DiffType:
+               v, err = db.sDiffGeneric(keys...)
+       case InterType:
+               v, err = db.sInterGeneric(keys...)
+       }
+
+       if err != nil {
+               return 0, err
+       }
+
+       for _, m := range v {
+               if err := checkSetKMSize(dstKey, m); err != nil {
+                       return 0, err
+               }
+
+               ek = db.sEncodeSetKey(dstKey, m)
+
+               if _, err := db.bucket.Get(ek); err != nil {
+                       return 0, err
+               }
+
+               t.Put(ek, nil)
+       }
+
+       var num = int64(len(v))
+       sk := db.sEncodeSizeKey(dstKey)
+       t.Put(sk, PutInt64(num))
+
+       if err = t.Commit(); err != nil {
+               return 0, err
+       }
+       return num, nil
+}
+
+func (db *DB) SClear(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+
+       t := db.setBatch
+       t.Lock()
+       defer t.Unlock()
+
+       num := db.sDelete(t, key)
+       db.rmExpire(t, SetType, key)
+
+       err := t.Commit()
+       return num, err
+}
+
+func (db *DB) SMclear(keys ...[]byte) (int64, error) {
+       t := db.setBatch
+       t.Lock()
+       defer t.Unlock()
+
+       for _, key := range keys {
+               if err := checkKeySize(key); err != nil {
+                       return 0, err
+               }
+
+               db.sDelete(t, key)
+               db.rmExpire(t, SetType, key)
+       }
+
+       err := t.Commit()
+       return int64(len(keys)), err
+}
+
+func (db *DB) SExpire(key []byte, duration int64) (int64, error) {
+       if duration <= 0 {
+               return 0, errExpireValue
+       }
+
+       return db.sExpireAt(key, time.Now().Unix()+duration)
+
+}
+
+func (db *DB) SExpireAt(key []byte, when int64) (int64, error) {
+       if when <= time.Now().Unix() {
+               return 0, errExpireValue
+       }
+
+       return db.sExpireAt(key, when)
+
+}
+
+func (db *DB) STTL(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return -1, err
+       }
+
+       return db.ttl(SetType, key)
+}
+
+func (db *DB) SPersist(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+
+       t := db.setBatch
+       t.Lock()
+       defer t.Unlock()
+
+       n, err := db.rmExpire(t, SetType, key)
+       if err != nil {
+               return 0, err
+       }
+       err = t.Commit()
+       return n, err
+}
+
+func (db *DB) SScan(key []byte, count int, inclusive bool, match string) ([][]byte, error) {
+       return db.scan(SSizeType, key, count, inclusive, match)
+}
diff --git a/vendor/gitea.com/lunny/nodb/t_ttl.go b/vendor/gitea.com/lunny/nodb/t_ttl.go
new file mode 100644 (file)
index 0000000..f0007dc
--- /dev/null
@@ -0,0 +1,195 @@
+package nodb
+
+import (
+       "encoding/binary"
+       "errors"
+       "time"
+
+       "gitea.com/lunny/nodb/store"
+)
+
+var (
+       errExpMetaKey = errors.New("invalid expire meta key")
+       errExpTimeKey = errors.New("invalid expire time key")
+)
+
+type retireCallback func(*batch, []byte) int64
+
+type elimination struct {
+       db         *DB
+       exp2Tx     []*batch
+       exp2Retire []retireCallback
+}
+
+var errExpType = errors.New("invalid expire type")
+
+func (db *DB) expEncodeTimeKey(dataType byte, key []byte, when int64) []byte {
+       buf := make([]byte, len(key)+11)
+
+       buf[0] = db.index
+       buf[1] = ExpTimeType
+       buf[2] = dataType
+       pos := 3
+
+       binary.BigEndian.PutUint64(buf[pos:], uint64(when))
+       pos += 8
+
+       copy(buf[pos:], key)
+
+       return buf
+}
+
+func (db *DB) expEncodeMetaKey(dataType byte, key []byte) []byte {
+       buf := make([]byte, len(key)+3)
+
+       buf[0] = db.index
+       buf[1] = ExpMetaType
+       buf[2] = dataType
+       pos := 3
+
+       copy(buf[pos:], key)
+
+       return buf
+}
+
+func (db *DB) expDecodeMetaKey(mk []byte) (byte, []byte, error) {
+       if len(mk) <= 3 || mk[0] != db.index || mk[1] != ExpMetaType {
+               return 0, nil, errExpMetaKey
+       }
+
+       return mk[2], mk[3:], nil
+}
+
+func (db *DB) expDecodeTimeKey(tk []byte) (byte, []byte, int64, error) {
+       if len(tk) < 11 || tk[0] != db.index || tk[1] != ExpTimeType {
+               return 0, nil, 0, errExpTimeKey
+       }
+
+       return tk[2], tk[11:], int64(binary.BigEndian.Uint64(tk[3:])), nil
+}
+
+func (db *DB) expire(t *batch, dataType byte, key []byte, duration int64) {
+       db.expireAt(t, dataType, key, time.Now().Unix()+duration)
+}
+
+func (db *DB) expireAt(t *batch, dataType byte, key []byte, when int64) {
+       mk := db.expEncodeMetaKey(dataType, key)
+       tk := db.expEncodeTimeKey(dataType, key, when)
+
+       t.Put(tk, mk)
+       t.Put(mk, PutInt64(when))
+}
+
+func (db *DB) ttl(dataType byte, key []byte) (t int64, err error) {
+       mk := db.expEncodeMetaKey(dataType, key)
+
+       if t, err = Int64(db.bucket.Get(mk)); err != nil || t == 0 {
+               t = -1
+       } else {
+               t -= time.Now().Unix()
+               if t <= 0 {
+                       t = -1
+               }
+               // if t == -1 : to remove ????
+       }
+
+       return t, err
+}
+
+func (db *DB) rmExpire(t *batch, dataType byte, key []byte) (int64, error) {
+       mk := db.expEncodeMetaKey(dataType, key)
+       if v, err := db.bucket.Get(mk); err != nil {
+               return 0, err
+       } else if v == nil {
+               return 0, nil
+       } else if when, err2 := Int64(v, nil); err2 != nil {
+               return 0, err2
+       } else {
+               tk := db.expEncodeTimeKey(dataType, key, when)
+               t.Delete(mk)
+               t.Delete(tk)
+               return 1, nil
+       }
+}
+
+func (db *DB) expFlush(t *batch, dataType byte) (err error) {
+       minKey := make([]byte, 3)
+       minKey[0] = db.index
+       minKey[1] = ExpTimeType
+       minKey[2] = dataType
+
+       maxKey := make([]byte, 3)
+       maxKey[0] = db.index
+       maxKey[1] = ExpMetaType
+       maxKey[2] = dataType + 1
+
+       _, err = db.flushRegion(t, minKey, maxKey)
+       err = t.Commit()
+       return
+}
+
+//////////////////////////////////////////////////////////
+//
+//////////////////////////////////////////////////////////
+
+func newEliminator(db *DB) *elimination {
+       eli := new(elimination)
+       eli.db = db
+       eli.exp2Tx = make([]*batch, maxDataType)
+       eli.exp2Retire = make([]retireCallback, maxDataType)
+       return eli
+}
+
+func (eli *elimination) regRetireContext(dataType byte, t *batch, onRetire retireCallback) {
+
+       //      todo .. need to ensure exist - mapExpMetaType[expType]
+
+       eli.exp2Tx[dataType] = t
+       eli.exp2Retire[dataType] = onRetire
+}
+
+//     call by outside ... (from *db to another *db)
+func (eli *elimination) active() {
+       now := time.Now().Unix()
+       db := eli.db
+       dbGet := db.bucket.Get
+
+       minKey := db.expEncodeTimeKey(NoneType, nil, 0)
+       maxKey := db.expEncodeTimeKey(maxDataType, nil, now)
+
+       it := db.bucket.RangeLimitIterator(minKey, maxKey, store.RangeROpen, 0, -1)
+       for ; it.Valid(); it.Next() {
+               tk := it.RawKey()
+               mk := it.RawValue()
+
+               dt, k, _, err := db.expDecodeTimeKey(tk)
+               if err != nil {
+                       continue
+               }
+
+               t := eli.exp2Tx[dt]
+               onRetire := eli.exp2Retire[dt]
+               if tk == nil || onRetire == nil {
+                       continue
+               }
+
+               t.Lock()
+
+               if exp, err := Int64(dbGet(mk)); err == nil {
+                       // check expire again
+                       if exp <= now {
+                               onRetire(t, k)
+                               t.Delete(tk)
+                               t.Delete(mk)
+
+                               t.Commit()
+                       }
+
+               }
+
+               t.Unlock()
+       }
+       it.Close()
+
+       return
+}
diff --git a/vendor/gitea.com/lunny/nodb/t_zset.go b/vendor/gitea.com/lunny/nodb/t_zset.go
new file mode 100644 (file)
index 0000000..91e3004
--- /dev/null
@@ -0,0 +1,943 @@
+package nodb
+
+import (
+       "bytes"
+       "encoding/binary"
+       "errors"
+       "time"
+
+       "gitea.com/lunny/nodb/store"
+)
+
+const (
+       MinScore     int64 = -1<<63 + 1
+       MaxScore     int64 = 1<<63 - 1
+       InvalidScore int64 = -1 << 63
+
+       AggregateSum byte = 0
+       AggregateMin byte = 1
+       AggregateMax byte = 2
+)
+
+type ScorePair struct {
+       Score  int64
+       Member []byte
+}
+
+var errZSizeKey = errors.New("invalid zsize key")
+var errZSetKey = errors.New("invalid zset key")
+var errZScoreKey = errors.New("invalid zscore key")
+var errScoreOverflow = errors.New("zset score overflow")
+var errInvalidAggregate = errors.New("invalid aggregate")
+var errInvalidWeightNum = errors.New("invalid weight number")
+var errInvalidSrcKeyNum = errors.New("invalid src key number")
+
+const (
+       zsetNScoreSep    byte = '<'
+       zsetPScoreSep    byte = zsetNScoreSep + 1
+       zsetStopScoreSep byte = zsetPScoreSep + 1
+
+       zsetStartMemSep byte = ':'
+       zsetStopMemSep  byte = zsetStartMemSep + 1
+)
+
+func checkZSetKMSize(key []byte, member []byte) error {
+       if len(key) > MaxKeySize || len(key) == 0 {
+               return errKeySize
+       } else if len(member) > MaxZSetMemberSize || len(member) == 0 {
+               return errZSetMemberSize
+       }
+       return nil
+}
+
+func (db *DB) zEncodeSizeKey(key []byte) []byte {
+       buf := make([]byte, len(key)+2)
+       buf[0] = db.index
+       buf[1] = ZSizeType
+
+       copy(buf[2:], key)
+       return buf
+}
+
+func (db *DB) zDecodeSizeKey(ek []byte) ([]byte, error) {
+       if len(ek) < 2 || ek[0] != db.index || ek[1] != ZSizeType {
+               return nil, errZSizeKey
+       }
+
+       return ek[2:], nil
+}
+
+func (db *DB) zEncodeSetKey(key []byte, member []byte) []byte {
+       buf := make([]byte, len(key)+len(member)+5)
+
+       pos := 0
+       buf[pos] = db.index
+       pos++
+
+       buf[pos] = ZSetType
+       pos++
+
+       binary.BigEndian.PutUint16(buf[pos:], uint16(len(key)))
+       pos += 2
+
+       copy(buf[pos:], key)
+       pos += len(key)
+
+       buf[pos] = zsetStartMemSep
+       pos++
+
+       copy(buf[pos:], member)
+
+       return buf
+}
+
+func (db *DB) zDecodeSetKey(ek []byte) ([]byte, []byte, error) {
+       if len(ek) < 5 || ek[0] != db.index || ek[1] != ZSetType {
+               return nil, nil, errZSetKey
+       }
+
+       keyLen := int(binary.BigEndian.Uint16(ek[2:]))
+       if keyLen+5 > len(ek) {
+               return nil, nil, errZSetKey
+       }
+
+       key := ek[4 : 4+keyLen]
+
+       if ek[4+keyLen] != zsetStartMemSep {
+               return nil, nil, errZSetKey
+       }
+
+       member := ek[5+keyLen:]
+       return key, member, nil
+}
+
+func (db *DB) zEncodeStartSetKey(key []byte) []byte {
+       k := db.zEncodeSetKey(key, nil)
+       return k
+}
+
+func (db *DB) zEncodeStopSetKey(key []byte) []byte {
+       k := db.zEncodeSetKey(key, nil)
+       k[len(k)-1] = zsetStartMemSep + 1
+       return k
+}
+
+func (db *DB) zEncodeScoreKey(key []byte, member []byte, score int64) []byte {
+       buf := make([]byte, len(key)+len(member)+14)
+
+       pos := 0
+       buf[pos] = db.index
+       pos++
+
+       buf[pos] = ZScoreType
+       pos++
+
+       binary.BigEndian.PutUint16(buf[pos:], uint16(len(key)))
+       pos += 2
+
+       copy(buf[pos:], key)
+       pos += len(key)
+
+       if score < 0 {
+               buf[pos] = zsetNScoreSep
+       } else {
+               buf[pos] = zsetPScoreSep
+       }
+
+       pos++
+       binary.BigEndian.PutUint64(buf[pos:], uint64(score))
+       pos += 8
+
+       buf[pos] = zsetStartMemSep
+       pos++
+
+       copy(buf[pos:], member)
+       return buf
+}
+
+func (db *DB) zEncodeStartScoreKey(key []byte, score int64) []byte {
+       return db.zEncodeScoreKey(key, nil, score)
+}
+
+func (db *DB) zEncodeStopScoreKey(key []byte, score int64) []byte {
+       k := db.zEncodeScoreKey(key, nil, score)
+       k[len(k)-1] = zsetStopMemSep
+       return k
+}
+
+func (db *DB) zDecodeScoreKey(ek []byte) (key []byte, member []byte, score int64, err error) {
+       if len(ek) < 14 || ek[0] != db.index || ek[1] != ZScoreType {
+               err = errZScoreKey
+               return
+       }
+
+       keyLen := int(binary.BigEndian.Uint16(ek[2:]))
+       if keyLen+14 > len(ek) {
+               err = errZScoreKey
+               return
+       }
+
+       key = ek[4 : 4+keyLen]
+       pos := 4 + keyLen
+
+       if (ek[pos] != zsetNScoreSep) && (ek[pos] != zsetPScoreSep) {
+               err = errZScoreKey
+               return
+       }
+       pos++
+
+       score = int64(binary.BigEndian.Uint64(ek[pos:]))
+       pos += 8
+
+       if ek[pos] != zsetStartMemSep {
+               err = errZScoreKey
+               return
+       }
+
+       pos++
+
+       member = ek[pos:]
+       return
+}
+
+func (db *DB) zSetItem(t *batch, key []byte, score int64, member []byte) (int64, error) {
+       if score <= MinScore || score >= MaxScore {
+               return 0, errScoreOverflow
+       }
+
+       var exists int64 = 0
+       ek := db.zEncodeSetKey(key, member)
+
+       if v, err := db.bucket.Get(ek); err != nil {
+               return 0, err
+       } else if v != nil {
+               exists = 1
+
+               if s, err := Int64(v, err); err != nil {
+                       return 0, err
+               } else {
+                       sk := db.zEncodeScoreKey(key, member, s)
+                       t.Delete(sk)
+               }
+       }
+
+       t.Put(ek, PutInt64(score))
+
+       sk := db.zEncodeScoreKey(key, member, score)
+       t.Put(sk, []byte{})
+
+       return exists, nil
+}
+
+func (db *DB) zDelItem(t *batch, key []byte, member []byte, skipDelScore bool) (int64, error) {
+       ek := db.zEncodeSetKey(key, member)
+       if v, err := db.bucket.Get(ek); err != nil {
+               return 0, err
+       } else if v == nil {
+               //not exists
+               return 0, nil
+       } else {
+               //exists
+               if !skipDelScore {
+                       //we must del score
+                       if s, err := Int64(v, err); err != nil {
+                               return 0, err
+                       } else {
+                               sk := db.zEncodeScoreKey(key, member, s)
+                               t.Delete(sk)
+                       }
+               }
+       }
+
+       t.Delete(ek)
+
+       return 1, nil
+}
+
+func (db *DB) zDelete(t *batch, key []byte) int64 {
+       delMembCnt, _ := db.zRemRange(t, key, MinScore, MaxScore, 0, -1)
+       //      todo : log err
+       return delMembCnt
+}
+
+func (db *DB) zExpireAt(key []byte, when int64) (int64, error) {
+       t := db.zsetBatch
+       t.Lock()
+       defer t.Unlock()
+
+       if zcnt, err := db.ZCard(key); err != nil || zcnt == 0 {
+               return 0, err
+       } else {
+               db.expireAt(t, ZSetType, key, when)
+               if err := t.Commit(); err != nil {
+                       return 0, err
+               }
+       }
+       return 1, nil
+}
+
+func (db *DB) ZAdd(key []byte, args ...ScorePair) (int64, error) {
+       if len(args) == 0 {
+               return 0, nil
+       }
+
+       t := db.zsetBatch
+       t.Lock()
+       defer t.Unlock()
+
+       var num int64 = 0
+       for i := 0; i < len(args); i++ {
+               score := args[i].Score
+               member := args[i].Member
+
+               if err := checkZSetKMSize(key, member); err != nil {
+                       return 0, err
+               }
+
+               if n, err := db.zSetItem(t, key, score, member); err != nil {
+                       return 0, err
+               } else if n == 0 {
+                       //add new
+                       num++
+               }
+       }
+
+       if _, err := db.zIncrSize(t, key, num); err != nil {
+               return 0, err
+       }
+
+       //todo add binlog
+       err := t.Commit()
+       return num, err
+}
+
+func (db *DB) zIncrSize(t *batch, key []byte, delta int64) (int64, error) {
+       sk := db.zEncodeSizeKey(key)
+
+       size, err := Int64(db.bucket.Get(sk))
+       if err != nil {
+               return 0, err
+       } else {
+               size += delta
+               if size <= 0 {
+                       size = 0
+                       t.Delete(sk)
+                       db.rmExpire(t, ZSetType, key)
+               } else {
+                       t.Put(sk, PutInt64(size))
+               }
+       }
+
+       return size, nil
+}
+
+func (db *DB) ZCard(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+
+       sk := db.zEncodeSizeKey(key)
+       return Int64(db.bucket.Get(sk))
+}
+
+func (db *DB) ZScore(key []byte, member []byte) (int64, error) {
+       if err := checkZSetKMSize(key, member); err != nil {
+               return InvalidScore, err
+       }
+
+       var score int64 = InvalidScore
+
+       k := db.zEncodeSetKey(key, member)
+       if v, err := db.bucket.Get(k); err != nil {
+               return InvalidScore, err
+       } else if v == nil {
+               return InvalidScore, ErrScoreMiss
+       } else {
+               if score, err = Int64(v, nil); err != nil {
+                       return InvalidScore, err
+               }
+       }
+
+       return score, nil
+}
+
+func (db *DB) ZRem(key []byte, members ...[]byte) (int64, error) {
+       if len(members) == 0 {
+               return 0, nil
+       }
+
+       t := db.zsetBatch
+       t.Lock()
+       defer t.Unlock()
+
+       var num int64 = 0
+       for i := 0; i < len(members); i++ {
+               if err := checkZSetKMSize(key, members[i]); err != nil {
+                       return 0, err
+               }
+
+               if n, err := db.zDelItem(t, key, members[i], false); err != nil {
+                       return 0, err
+               } else if n == 1 {
+                       num++
+               }
+       }
+
+       if _, err := db.zIncrSize(t, key, -num); err != nil {
+               return 0, err
+       }
+
+       err := t.Commit()
+       return num, err
+}
+
+func (db *DB) ZIncrBy(key []byte, delta int64, member []byte) (int64, error) {
+       if err := checkZSetKMSize(key, member); err != nil {
+               return InvalidScore, err
+       }
+
+       t := db.zsetBatch
+       t.Lock()
+       defer t.Unlock()
+
+       ek := db.zEncodeSetKey(key, member)
+
+       var oldScore int64 = 0
+       v, err := db.bucket.Get(ek)
+       if err != nil {
+               return InvalidScore, err
+       } else if v == nil {
+               db.zIncrSize(t, key, 1)
+       } else {
+               if oldScore, err = Int64(v, err); err != nil {
+                       return InvalidScore, err
+               }
+       }
+
+       newScore := oldScore + delta
+       if newScore >= MaxScore || newScore <= MinScore {
+               return InvalidScore, errScoreOverflow
+       }
+
+       sk := db.zEncodeScoreKey(key, member, newScore)
+       t.Put(sk, []byte{})
+       t.Put(ek, PutInt64(newScore))
+
+       if v != nil {
+               // so as to update score, we must delete the old one
+               oldSk := db.zEncodeScoreKey(key, member, oldScore)
+               t.Delete(oldSk)
+       }
+
+       err = t.Commit()
+       return newScore, err
+}
+
+func (db *DB) ZCount(key []byte, min int64, max int64) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+       minKey := db.zEncodeStartScoreKey(key, min)
+       maxKey := db.zEncodeStopScoreKey(key, max)
+
+       rangeType := store.RangeROpen
+
+       it := db.bucket.RangeLimitIterator(minKey, maxKey, rangeType, 0, -1)
+       var n int64 = 0
+       for ; it.Valid(); it.Next() {
+               n++
+       }
+       it.Close()
+
+       return n, nil
+}
+
+func (db *DB) zrank(key []byte, member []byte, reverse bool) (int64, error) {
+       if err := checkZSetKMSize(key, member); err != nil {
+               return 0, err
+       }
+
+       k := db.zEncodeSetKey(key, member)
+
+       it := db.bucket.NewIterator()
+       defer it.Close()
+
+       if v := it.Find(k); v == nil {
+               return -1, nil
+       } else {
+               if s, err := Int64(v, nil); err != nil {
+                       return 0, err
+               } else {
+                       var rit *store.RangeLimitIterator
+
+                       sk := db.zEncodeScoreKey(key, member, s)
+
+                       if !reverse {
+                               minKey := db.zEncodeStartScoreKey(key, MinScore)
+
+                               rit = store.NewRangeIterator(it, &store.Range{minKey, sk, store.RangeClose})
+                       } else {
+                               maxKey := db.zEncodeStopScoreKey(key, MaxScore)
+                               rit = store.NewRevRangeIterator(it, &store.Range{sk, maxKey, store.RangeClose})
+                       }
+
+                       var lastKey []byte = nil
+                       var n int64 = 0
+
+                       for ; rit.Valid(); rit.Next() {
+                               n++
+
+                               lastKey = rit.BufKey(lastKey)
+                       }
+
+                       if _, m, _, err := db.zDecodeScoreKey(lastKey); err == nil && bytes.Equal(m, member) {
+                               n--
+                               return n, nil
+                       }
+               }
+       }
+
+       return -1, nil
+}
+
+func (db *DB) zIterator(key []byte, min int64, max int64, offset int, count int, reverse bool) *store.RangeLimitIterator {
+       minKey := db.zEncodeStartScoreKey(key, min)
+       maxKey := db.zEncodeStopScoreKey(key, max)
+
+       if !reverse {
+               return db.bucket.RangeLimitIterator(minKey, maxKey, store.RangeClose, offset, count)
+       } else {
+               return db.bucket.RevRangeLimitIterator(minKey, maxKey, store.RangeClose, offset, count)
+       }
+}
+
+func (db *DB) zRemRange(t *batch, key []byte, min int64, max int64, offset int, count int) (int64, error) {
+       if len(key) > MaxKeySize {
+               return 0, errKeySize
+       }
+
+       it := db.zIterator(key, min, max, offset, count, false)
+       var num int64 = 0
+       for ; it.Valid(); it.Next() {
+               sk := it.RawKey()
+               _, m, _, err := db.zDecodeScoreKey(sk)
+               if err != nil {
+                       continue
+               }
+
+               if n, err := db.zDelItem(t, key, m, true); err != nil {
+                       return 0, err
+               } else if n == 1 {
+                       num++
+               }
+
+               t.Delete(sk)
+       }
+       it.Close()
+
+       if _, err := db.zIncrSize(t, key, -num); err != nil {
+               return 0, err
+       }
+
+       return num, nil
+}
+
+func (db *DB) zRange(key []byte, min int64, max int64, offset int, count int, reverse bool) ([]ScorePair, error) {
+       if len(key) > MaxKeySize {
+               return nil, errKeySize
+       }
+
+       if offset < 0 {
+               return []ScorePair{}, nil
+       }
+
+       nv := 64
+       if count > 0 {
+               nv = count
+       }
+
+       v := make([]ScorePair, 0, nv)
+
+       var it *store.RangeLimitIterator
+
+       //if reverse and offset is 0, count < 0, we may use forward iterator then reverse
+       //because store iterator prev is slower than next
+       if !reverse || (offset == 0 && count < 0) {
+               it = db.zIterator(key, min, max, offset, count, false)
+       } else {
+               it = db.zIterator(key, min, max, offset, count, true)
+       }
+
+       for ; it.Valid(); it.Next() {
+               _, m, s, err := db.zDecodeScoreKey(it.Key())
+               //may be we will check key equal?
+               if err != nil {
+                       continue
+               }
+
+               v = append(v, ScorePair{Member: m, Score: s})
+       }
+       it.Close()
+
+       if reverse && (offset == 0 && count < 0) {
+               for i, j := 0, len(v)-1; i < j; i, j = i+1, j-1 {
+                       v[i], v[j] = v[j], v[i]
+               }
+       }
+
+       return v, nil
+}
+
+func (db *DB) zParseLimit(key []byte, start int, stop int) (offset int, count int, err error) {
+       if start < 0 || stop < 0 {
+               //refer redis implementation
+               var size int64
+               size, err = db.ZCard(key)
+               if err != nil {
+                       return
+               }
+
+               llen := int(size)
+
+               if start < 0 {
+                       start = llen + start
+               }
+               if stop < 0 {
+                       stop = llen + stop
+               }
+
+               if start < 0 {
+                       start = 0
+               }
+
+               if start >= llen {
+                       offset = -1
+                       return
+               }
+       }
+
+       if start > stop {
+               offset = -1
+               return
+       }
+
+       offset = start
+       count = (stop - start) + 1
+       return
+}
+
+func (db *DB) ZClear(key []byte) (int64, error) {
+       t := db.zsetBatch
+       t.Lock()
+       defer t.Unlock()
+
+       rmCnt, err := db.zRemRange(t, key, MinScore, MaxScore, 0, -1)
+       if err == nil {
+               err = t.Commit()
+       }
+
+       return rmCnt, err
+}
+
+func (db *DB) ZMclear(keys ...[]byte) (int64, error) {
+       t := db.zsetBatch
+       t.Lock()
+       defer t.Unlock()
+
+       for _, key := range keys {
+               if _, err := db.zRemRange(t, key, MinScore, MaxScore, 0, -1); err != nil {
+                       return 0, err
+               }
+       }
+
+       err := t.Commit()
+
+       return int64(len(keys)), err
+}
+
+func (db *DB) ZRange(key []byte, start int, stop int) ([]ScorePair, error) {
+       return db.ZRangeGeneric(key, start, stop, false)
+}
+
+//min and max must be inclusive
+//if no limit, set offset = 0 and count = -1
+func (db *DB) ZRangeByScore(key []byte, min int64, max int64,
+       offset int, count int) ([]ScorePair, error) {
+       return db.ZRangeByScoreGeneric(key, min, max, offset, count, false)
+}
+
+func (db *DB) ZRank(key []byte, member []byte) (int64, error) {
+       return db.zrank(key, member, false)
+}
+
+func (db *DB) ZRemRangeByRank(key []byte, start int, stop int) (int64, error) {
+       offset, count, err := db.zParseLimit(key, start, stop)
+       if err != nil {
+               return 0, err
+       }
+
+       var rmCnt int64
+
+       t := db.zsetBatch
+       t.Lock()
+       defer t.Unlock()
+
+       rmCnt, err = db.zRemRange(t, key, MinScore, MaxScore, offset, count)
+       if err == nil {
+               err = t.Commit()
+       }
+
+       return rmCnt, err
+}
+
+//min and max must be inclusive
+func (db *DB) ZRemRangeByScore(key []byte, min int64, max int64) (int64, error) {
+       t := db.zsetBatch
+       t.Lock()
+       defer t.Unlock()
+
+       rmCnt, err := db.zRemRange(t, key, min, max, 0, -1)
+       if err == nil {
+               err = t.Commit()
+       }
+
+       return rmCnt, err
+}
+
+func (db *DB) ZRevRange(key []byte, start int, stop int) ([]ScorePair, error) {
+       return db.ZRangeGeneric(key, start, stop, true)
+}
+
+func (db *DB) ZRevRank(key []byte, member []byte) (int64, error) {
+       return db.zrank(key, member, true)
+}
+
+//min and max must be inclusive
+//if no limit, set offset = 0 and count = -1
+func (db *DB) ZRevRangeByScore(key []byte, min int64, max int64, offset int, count int) ([]ScorePair, error) {
+       return db.ZRangeByScoreGeneric(key, min, max, offset, count, true)
+}
+
+func (db *DB) ZRangeGeneric(key []byte, start int, stop int, reverse bool) ([]ScorePair, error) {
+       offset, count, err := db.zParseLimit(key, start, stop)
+       if err != nil {
+               return nil, err
+       }
+
+       return db.zRange(key, MinScore, MaxScore, offset, count, reverse)
+}
+
+//min and max must be inclusive
+//if no limit, set offset = 0 and count = -1
+func (db *DB) ZRangeByScoreGeneric(key []byte, min int64, max int64,
+       offset int, count int, reverse bool) ([]ScorePair, error) {
+
+       return db.zRange(key, min, max, offset, count, reverse)
+}
+
+func (db *DB) zFlush() (drop int64, err error) {
+       t := db.zsetBatch
+       t.Lock()
+       defer t.Unlock()
+       return db.flushType(t, ZSetType)
+}
+
+func (db *DB) ZExpire(key []byte, duration int64) (int64, error) {
+       if duration <= 0 {
+               return 0, errExpireValue
+       }
+
+       return db.zExpireAt(key, time.Now().Unix()+duration)
+}
+
+func (db *DB) ZExpireAt(key []byte, when int64) (int64, error) {
+       if when <= time.Now().Unix() {
+               return 0, errExpireValue
+       }
+
+       return db.zExpireAt(key, when)
+}
+
+func (db *DB) ZTTL(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return -1, err
+       }
+
+       return db.ttl(ZSetType, key)
+}
+
+func (db *DB) ZPersist(key []byte) (int64, error) {
+       if err := checkKeySize(key); err != nil {
+               return 0, err
+       }
+
+       t := db.zsetBatch
+       t.Lock()
+       defer t.Unlock()
+
+       n, err := db.rmExpire(t, ZSetType, key)
+       if err != nil {
+               return 0, err
+       }
+
+       err = t.Commit()
+       return n, err
+}
+
+func getAggregateFunc(aggregate byte) func(int64, int64) int64 {
+       switch aggregate {
+       case AggregateSum:
+               return func(a int64, b int64) int64 {
+                       return a + b
+               }
+       case AggregateMax:
+               return func(a int64, b int64) int64 {
+                       if a > b {
+                               return a
+                       }
+                       return b
+               }
+       case AggregateMin:
+               return func(a int64, b int64) int64 {
+                       if a > b {
+                               return b
+                       }
+                       return a
+               }
+       }
+       return nil
+}
+
+func (db *DB) ZUnionStore(destKey []byte, srcKeys [][]byte, weights []int64, aggregate byte) (int64, error) {
+
+       var destMap = map[string]int64{}
+       aggregateFunc := getAggregateFunc(aggregate)
+       if aggregateFunc == nil {
+               return 0, errInvalidAggregate
+       }
+       if len(srcKeys) < 1 {
+               return 0, errInvalidSrcKeyNum
+       }
+       if weights != nil {
+               if len(srcKeys) != len(weights) {
+                       return 0, errInvalidWeightNum
+               }
+       } else {
+               weights = make([]int64, len(srcKeys))
+               for i := 0; i < len(weights); i++ {
+                       weights[i] = 1
+               }
+       }
+
+       for i, key := range srcKeys {
+               scorePairs, err := db.ZRange(key, 0, -1)
+               if err != nil {
+                       return 0, err
+               }
+               for _, pair := range scorePairs {
+                       if score, ok := destMap[String(pair.Member)]; !ok {
+                               destMap[String(pair.Member)] = pair.Score * weights[i]
+                       } else {
+                               destMap[String(pair.Member)] = aggregateFunc(score, pair.Score*weights[i])
+                       }
+               }
+       }
+
+       t := db.zsetBatch
+       t.Lock()
+       defer t.Unlock()
+
+       db.zDelete(t, destKey)
+
+       for member, score := range destMap {
+               if err := checkZSetKMSize(destKey, []byte(member)); err != nil {
+                       return 0, err
+               }
+
+               if _, err := db.zSetItem(t, destKey, score, []byte(member)); err != nil {
+                       return 0, err
+               }
+       }
+
+       var num = int64(len(destMap))
+       sk := db.zEncodeSizeKey(destKey)
+       t.Put(sk, PutInt64(num))
+
+       //todo add binlog
+       if err := t.Commit(); err != nil {
+               return 0, err
+       }
+       return num, nil
+}
+
+func (db *DB) ZInterStore(destKey []byte, srcKeys [][]byte, weights []int64, aggregate byte) (int64, error) {
+
+       aggregateFunc := getAggregateFunc(aggregate)
+       if aggregateFunc == nil {
+               return 0, errInvalidAggregate
+       }
+       if len(srcKeys) < 1 {
+               return 0, errInvalidSrcKeyNum
+       }
+       if weights != nil {
+               if len(srcKeys) != len(weights) {
+                       return 0, errInvalidWeightNum
+               }
+       } else {
+               weights = make([]int64, len(srcKeys))
+               for i := 0; i < len(weights); i++ {
+                       weights[i] = 1
+               }
+       }
+
+       var destMap = map[string]int64{}
+       scorePairs, err := db.ZRange(srcKeys[0], 0, -1)
+       if err != nil {
+               return 0, err
+       }
+       for _, pair := range scorePairs {
+               destMap[String(pair.Member)] = pair.Score * weights[0]
+       }
+
+       for i, key := range srcKeys[1:] {
+               scorePairs, err := db.ZRange(key, 0, -1)
+               if err != nil {
+                       return 0, err
+               }
+               tmpMap := map[string]int64{}
+               for _, pair := range scorePairs {
+                       if score, ok := destMap[String(pair.Member)]; ok {
+                               tmpMap[String(pair.Member)] = aggregateFunc(score, pair.Score*weights[i+1])
+                       }
+               }
+               destMap = tmpMap
+       }
+
+       t := db.zsetBatch
+       t.Lock()
+       defer t.Unlock()
+
+       db.zDelete(t, destKey)
+
+       for member, score := range destMap {
+               if err := checkZSetKMSize(destKey, []byte(member)); err != nil {
+                       return 0, err
+               }
+               if _, err := db.zSetItem(t, destKey, score, []byte(member)); err != nil {
+                       return 0, err
+               }
+       }
+
+       var num int64 = int64(len(destMap))
+       sk := db.zEncodeSizeKey(destKey)
+       t.Put(sk, PutInt64(num))
+       //todo add binlog
+       if err := t.Commit(); err != nil {
+               return 0, err
+       }
+       return num, nil
+}
+
+func (db *DB) ZScan(key []byte, count int, inclusive bool, match string) ([][]byte, error) {
+       return db.scan(ZSizeType, key, count, inclusive, match)
+}
diff --git a/vendor/gitea.com/lunny/nodb/tx.go b/vendor/gitea.com/lunny/nodb/tx.go
new file mode 100644 (file)
index 0000000..e56b4c0
--- /dev/null
@@ -0,0 +1,113 @@
+package nodb
+
+import (
+       "errors"
+       "fmt"
+
+       "gitea.com/lunny/nodb/store"
+)
+
+var (
+       ErrNestTx = errors.New("nest transaction not supported")
+       ErrTxDone = errors.New("Transaction has already been committed or rolled back")
+)
+
+type Tx struct {
+       *DB
+
+       tx *store.Tx
+
+       logs [][]byte
+}
+
+func (db *DB) IsTransaction() bool {
+       return db.status == DBInTransaction
+}
+
+// Begin a transaction, it will block all other write operations before calling Commit or Rollback.
+// You must be very careful to prevent long-time transaction.
+func (db *DB) Begin() (*Tx, error) {
+       if db.IsTransaction() {
+               return nil, ErrNestTx
+       }
+
+       tx := new(Tx)
+
+       tx.DB = new(DB)
+       tx.DB.l = db.l
+
+       tx.l.wLock.Lock()
+
+       tx.DB.sdb = db.sdb
+
+       var err error
+       tx.tx, err = db.sdb.Begin()
+       if err != nil {
+               tx.l.wLock.Unlock()
+               return nil, err
+       }
+
+       tx.DB.bucket = tx.tx
+
+       tx.DB.status = DBInTransaction
+
+       tx.DB.index = db.index
+
+       tx.DB.kvBatch = tx.newBatch()
+       tx.DB.listBatch = tx.newBatch()
+       tx.DB.hashBatch = tx.newBatch()
+       tx.DB.zsetBatch = tx.newBatch()
+       tx.DB.binBatch = tx.newBatch()
+       tx.DB.setBatch = tx.newBatch()
+
+       return tx, nil
+}
+
+func (tx *Tx) Commit() error {
+       if tx.tx == nil {
+               return ErrTxDone
+       }
+
+       tx.l.commitLock.Lock()
+       err := tx.tx.Commit()
+       tx.tx = nil
+
+       if len(tx.logs) > 0 {
+               tx.l.binlog.Log(tx.logs...)
+       }
+
+       tx.l.commitLock.Unlock()
+
+       tx.l.wLock.Unlock()
+
+       tx.DB.bucket = nil
+
+       return err
+}
+
+func (tx *Tx) Rollback() error {
+       if tx.tx == nil {
+               return ErrTxDone
+       }
+
+       err := tx.tx.Rollback()
+       tx.tx = nil
+
+       tx.l.wLock.Unlock()
+       tx.DB.bucket = nil
+
+       return err
+}
+
+func (tx *Tx) newBatch() *batch {
+       return tx.l.newBatch(tx.tx.NewWriteBatch(), &txBatchLocker{}, tx)
+}
+
+func (tx *Tx) Select(index int) error {
+       if index < 0 || index >= int(MaxDBNumber) {
+               return fmt.Errorf("invalid db index %d", index)
+       }
+
+       tx.DB.index = uint8(index)
+       return nil
+}
diff --git a/vendor/gitea.com/lunny/nodb/util.go b/vendor/gitea.com/lunny/nodb/util.go
new file mode 100644 (file)
index 0000000..d5949a9
--- /dev/null
@@ -0,0 +1,113 @@
+package nodb
+
+import (
+       "encoding/binary"
+       "errors"
+       "reflect"
+       "strconv"
+       "unsafe"
+)
+
+var errIntNumber = errors.New("invalid integer")
+
+// no copy to change slice to string
+// use your own risk
+func String(b []byte) (s string) {
+       pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
+       pstring := (*reflect.StringHeader)(unsafe.Pointer(&s))
+       pstring.Data = pbytes.Data
+       pstring.Len = pbytes.Len
+       return
+}
+
+// no copy to change string to slice
+// use your own risk
+func Slice(s string) (b []byte) {
+       pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
+       pstring := (*reflect.StringHeader)(unsafe.Pointer(&s))
+       pbytes.Data = pstring.Data
+       pbytes.Len = pstring.Len
+       pbytes.Cap = pstring.Len
+       return
+}
+
+func Int64(v []byte, err error) (int64, error) {
+       if err != nil {
+               return 0, err
+       } else if v == nil || len(v) == 0 {
+               return 0, nil
+       } else if len(v) != 8 {
+               return 0, errIntNumber
+       }
+
+       return int64(binary.LittleEndian.Uint64(v)), nil
+}
+
+func PutInt64(v int64) []byte {
+       var b []byte
+       pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
+       pbytes.Data = uintptr(unsafe.Pointer(&v))
+       pbytes.Len = 8
+       pbytes.Cap = 8
+       return b
+}
+
+func StrInt64(v []byte, err error) (int64, error) {
+       if err != nil {
+               return 0, err
+       } else if v == nil {
+               return 0, nil
+       } else {
+               return strconv.ParseInt(String(v), 10, 64)
+       }
+}
+
+func StrInt32(v []byte, err error) (int32, error) {
+       if err != nil {
+               return 0, err
+       } else if v == nil {
+               return 0, nil
+       } else {
+               res, err := strconv.ParseInt(String(v), 10, 32)
+               return int32(res), err
+       }
+}
+
+func StrInt8(v []byte, err error) (int8, error) {
+       if err != nil {
+               return 0, err
+       } else if v == nil {
+               return 0, nil
+       } else {
+               res, err := strconv.ParseInt(String(v), 10, 8)
+               return int8(res), err
+       }
+}
+
+func StrPutInt64(v int64) []byte {
+       return strconv.AppendInt(nil, v, 10)
+}
+
+func MinUInt32(a uint32, b uint32) uint32 {
+       if a > b {
+               return b
+       } else {
+               return a
+       }
+}
+
+func MaxUInt32(a uint32, b uint32) uint32 {
+       if a > b {
+               return a
+       } else {
+               return b
+       }
+}
+
+func MaxInt32(a int32, b int32) int32 {
+       if a > b {
+               return a
+       } else {
+               return b
+       }
+}
index b00811dc2aa7ce978f897e041fa09518000033d8..d214f0c34db497c082c3e89b8ad9beedce62ec81 100644 (file)
@@ -4,18 +4,20 @@ go 1.11
 
 require (
        gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb
+       github.com/BurntSushi/toml v0.3.1 // indirect
        github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668
        github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 // indirect
        github.com/edsrzf/mmap-go v1.0.0 // indirect
        github.com/go-redis/redis v6.15.2+incompatible
        github.com/go-sql-driver/mysql v1.4.1
+       github.com/golang/snappy v0.0.2 // indirect
        github.com/lib/pq v1.2.0
        github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de // indirect
        github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af
        github.com/mattn/go-sqlite3 v1.11.0 // indirect
        github.com/onsi/ginkgo v1.8.0 // indirect
        github.com/onsi/gomega v1.5.0 // indirect
-       github.com/pelletier/go-toml v1.4.0 // indirect
+       github.com/pelletier/go-toml v1.8.1 // indirect
        github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 // indirect
        github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d // indirect
        github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92
@@ -27,4 +29,5 @@ require (
        golang.org/x/sys v0.0.0-20190730183949-1393eb018365 // indirect
        google.golang.org/appengine v1.6.1 // indirect
        gopkg.in/ini.v1 v1.44.2
+       gopkg.in/yaml.v2 v2.2.2 // indirect
 )
index 3f311ad14bbb446f8ce4d98ef20211972f296221..ceec0162af2028a6d974a151da1fb30355fa8798 100644 (file)
@@ -23,6 +23,8 @@ github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw=
+github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
 github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@@ -46,8 +48,8 @@ github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
 github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg=
-github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
+github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
+github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
 github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 h1:xT+JlYxNGqyT+XcU8iUrN18JYed2TvG9yN5ULG2jATM=
 github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
 github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d h1:qQWKKOvHN7Q9c6GdmUteCef2F9ubxMpxY1IKwpIKz68=
index b6e51f2a2652a854e82eaaafa841df4793f54c75..283db3b43f6a6f5e843612b8e45aa8fb81591114 100644 (file)
@@ -240,10 +240,10 @@ func Captchaer(options ...Options) macaron.Handler {
                                }
                        }
 
+                       ctx.Status(200)
                        if _, err := NewImage([]byte(chars), cpt.StdWidth, cpt.StdHeight, cpt.ColorPalette).WriteTo(ctx.Resp); err != nil {
                                panic(fmt.Errorf("write captcha: %v", err))
                        }
-                       ctx.Status(200)
                        return
                }
 
index 3f2a43489205fd3177242cc0e3d775871127509b..72eebbb496c94e81bad49e5c7316f6839462ad19 100644 (file)
@@ -1,9 +1,9 @@
 kind: pipeline
-name: golang-1-1
+name: golang-1-14
 
 steps:
 - name: test
-  image: golang:1.11
+  image: golang:1.14
   environment:
       GOPROXY: https://goproxy.cn
   commands:
@@ -12,11 +12,11 @@ steps:
 
 ---
 kind: pipeline
-name: golang-1-2
+name: golang-1-15
 
 steps:
 - name: test
-  image: golang:1.12
+  image: golang:1.15
   environment:
       GOPROXY: https://goproxy.cn
   commands:
index 35a7e7017cce358f321dff93fbbe8b98d438820a..cf545eb46218be6c574ac34ec4827c68ce0335b1 100644 (file)
@@ -1,4 +1,5 @@
 // Copyright 2014 The Macaron Authors
+// Copyright 2020 The Gitea Authors
 //
 // Licensed under the Apache License, Version 2.0 (the "License"): you may
 // not use this file except in compliance with the License. You may obtain
@@ -68,6 +69,7 @@ type Request struct {
        *http.Request
 }
 
+// Body returns a RequestBody for the request
 func (r *Request) Body() *RequestBody {
        return &RequestBody{r.Request.Body}
 }
@@ -75,6 +77,7 @@ func (r *Request) Body() *RequestBody {
 // ContextInvoker is an inject.FastInvoker wrapper of func(ctx *Context).
 type ContextInvoker func(ctx *Context)
 
+// Invoke implements inject.FastInvoker - in the context of a func(ctx *Context) this simply calls the function
 func (invoke ContextInvoker) Invoke(params []interface{}) ([]reflect.Value, error) {
        invoke(params[0].(*Context))
        return nil, nil
@@ -97,41 +100,43 @@ type Context struct {
        Data map[string]interface{}
 }
 
-func (c *Context) handler() Handler {
-       if c.index < len(c.handlers) {
-               return c.handlers[c.index]
+func (ctx *Context) handler() Handler {
+       if ctx.index < len(ctx.handlers) {
+               return ctx.handlers[ctx.index]
        }
-       if c.index == len(c.handlers) {
-               return c.action
+       if ctx.index == len(ctx.handlers) {
+               return ctx.action
        }
        panic("invalid index for context handler")
 }
 
-func (c *Context) Next() {
-       c.index += 1
-       c.run()
+// Next runs the next handler in the context chain
+func (ctx *Context) Next() {
+       ctx.index++
+       ctx.run()
 }
 
-func (c *Context) Written() bool {
-       return c.Resp.Written()
+// Written returns whether the context response has been written to
+func (ctx *Context) Written() bool {
+       return ctx.Resp.Written()
 }
 
-func (c *Context) run() {
-       for c.index <= len(c.handlers) {
-               vals, err := c.Invoke(c.handler())
+func (ctx *Context) run() {
+       for ctx.index <= len(ctx.handlers) {
+               vals, err := ctx.Invoke(ctx.handler())
                if err != nil {
                        panic(err)
                }
-               c.index += 1
+               ctx.index++
 
                // if the handler returned something, write it to the http response
                if len(vals) > 0 {
-                       ev := c.GetVal(reflect.TypeOf(ReturnHandler(nil)))
+                       ev := ctx.GetVal(reflect.TypeOf(ReturnHandler(nil)))
                        handleReturn := ev.Interface().(ReturnHandler)
-                       handleReturn(c, vals)
+                       handleReturn(ctx, vals)
                }
 
-               if c.Written() {
+               if ctx.Written() {
                        return
                }
        }
@@ -172,6 +177,7 @@ func (ctx *Context) HTMLSet(status int, setName, tplName string, data ...interfa
        ctx.renderHTML(status, setName, tplName, data...)
 }
 
+// Redirect sends a redirect response
 func (ctx *Context) Redirect(location string, status ...int) {
        code := http.StatusFound
        if len(status) == 1 {
@@ -181,7 +187,7 @@ func (ctx *Context) Redirect(location string, status ...int) {
        http.Redirect(ctx.Resp, ctx.Req.Request, location, code)
 }
 
-// Maximum amount of memory to use when parsing a multipart form.
+// MaxMemory is the maximum amount of memory to use when parsing a multipart form.
 // Set this to whatever value you prefer; default is 10 MB.
 var MaxMemory = int64(1024 * 1024 * 10)
 
@@ -341,6 +347,8 @@ func (ctx *Context) SetCookie(name string, value string, others ...interface{})
                        cookie.MaxAge = int(v)
                case int32:
                        cookie.MaxAge = int(v)
+               case func(*http.Cookie):
+                       v(&cookie)
                }
        }
 
@@ -348,12 +356,16 @@ func (ctx *Context) SetCookie(name string, value string, others ...interface{})
        if len(others) > 1 {
                if v, ok := others[1].(string); ok && len(v) > 0 {
                        cookie.Path = v
+               } else if v, ok := others[1].(func(*http.Cookie)); ok {
+                       v(&cookie)
                }
        }
 
        if len(others) > 2 {
                if v, ok := others[2].(string); ok && len(v) > 0 {
                        cookie.Domain = v
+               } else if v, ok := others[1].(func(*http.Cookie)); ok {
+                       v(&cookie)
                }
        }
 
@@ -361,6 +373,8 @@ func (ctx *Context) SetCookie(name string, value string, others ...interface{})
                switch v := others[3].(type) {
                case bool:
                        cookie.Secure = v
+               case func(*http.Cookie):
+                       v(&cookie)
                default:
                        if others[3] != nil {
                                cookie.Secure = true
@@ -371,6 +385,8 @@ func (ctx *Context) SetCookie(name string, value string, others ...interface{})
        if len(others) > 4 {
                if v, ok := others[4].(bool); ok && v {
                        cookie.HttpOnly = true
+               } else if v, ok := others[1].(func(*http.Cookie)); ok {
+                       v(&cookie)
                }
        }
 
@@ -378,6 +394,16 @@ func (ctx *Context) SetCookie(name string, value string, others ...interface{})
                if v, ok := others[5].(time.Time); ok {
                        cookie.Expires = v
                        cookie.RawExpires = v.Format(time.UnixDate)
+               } else if v, ok := others[1].(func(*http.Cookie)); ok {
+                       v(&cookie)
+               }
+       }
+
+       if len(others) > 6 {
+               for _, other := range others[6:] {
+                       if v, ok := other.(func(*http.Cookie)); ok {
+                               v(&cookie)
+                       }
                }
        }
 
index 8f5a32f96918fae820b83d1c77300c787e78ac35..25a278d34ce9ea71f00b3e2211eb017f1f2bd762 100644 (file)
@@ -20,7 +20,7 @@ import (
        "sync"
 
        "gitea.com/macaron/session"
-       "github.com/couchbaselabs/go-couchbase"
+       "github.com/couchbase/go-couchbase"
 )
 
 // CouchbaseSessionStore represents a couchbase session store implementation.
index e161b8e1655d8ffefcd737d4ac0430994c882496..f44315f827751940567e787bd14e78b739ffe846 100644 (file)
@@ -3,30 +3,28 @@ module gitea.com/macaron/session
 go 1.11
 
 require (
-       gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb
+       gitea.com/lunny/nodb v0.0.0-20200923032308-3238c4655727
+       gitea.com/macaron/macaron v1.5.0
        github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668
-       github.com/couchbase/gomemcached v0.0.0-20190515232915-c4b4ca0eb21d // indirect
-       github.com/couchbase/goutils v0.0.0-20191018232750-b49639060d85 // indirect
-       github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7
+       github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89
+       github.com/couchbase/gomemcached v0.1.0 // indirect
+       github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67 // indirect
        github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 // indirect
        github.com/edsrzf/mmap-go v1.0.0 // indirect
        github.com/go-redis/redis v6.15.2+incompatible
        github.com/go-sql-driver/mysql v1.4.1
+       github.com/golang/snappy v0.0.2 // indirect
        github.com/lib/pq v1.2.0
-       github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de // indirect
-       github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af
-       github.com/mattn/go-sqlite3 v1.11.0 // indirect
-       github.com/pelletier/go-toml v1.4.0 // indirect
        github.com/pkg/errors v0.8.1 // indirect
        github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 // indirect
-       github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d // indirect
        github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92
        github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d // indirect
        github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337
        github.com/stretchr/testify v1.3.0 // indirect
-       github.com/syndtr/goleveldb v1.0.0 // indirect
-       github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e
+       github.com/unknwon/com v1.0.1
+       golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 // indirect
        golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 // indirect
        google.golang.org/appengine v1.6.1 // indirect
-       gopkg.in/ini.v1 v1.44.0
+       gopkg.in/ini.v1 v1.62.0
+       gopkg.in/yaml.v2 v2.2.2 // indirect
 )
index 38d5f5f226bac298e15a100630d72a0a0629b0b9..cf76c4e87474cdc6a80423eb6dd2fddeaa0aa946 100644 (file)
@@ -1,17 +1,17 @@
-gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591 h1:UbCTjPcLrNxR9LzKDjQBMT2zoxZuEnca1pZCpgeMuhQ=
-gitea.com/macaron/inject v0.0.0-20190803172902-8375ba841591/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
-gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb h1:amL0md6orTj1tXY16ANzVU9FmzQB+W7aJwp8pVDbrmA=
-gitea.com/macaron/macaron v1.3.3-0.20190821202302-9646c0587edb/go.mod h1:0coI+mSPSwbsyAbOuFllVS38awuk9mevhLD52l50Gjs=
-github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e h1:r1en/D7xJmcY24VkHkjkcJFa+7ZWubVWPBrvsHkmHxk=
+gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e/go.mod h1:uJEsN4LQpeGYRCjuPXPZBClU7N5pWzGuyF4uqLpE/e0=
+gitea.com/lunny/nodb v0.0.0-20200923032308-3238c4655727 h1:ZF2Bd6rqVlwhIDhYiS0uGYcT+GaVNGjuKVJkTNqWMIs=
+gitea.com/lunny/nodb v0.0.0-20200923032308-3238c4655727/go.mod h1:h0OwsgcpJLSYtHcM5+Xciw9OEeuxi6ty4HDiO8C7aIY=
+gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a/go.mod h1:h6E4kLao1Yko6DOU6QDnQPcuoNzvbZqzj2mtPcEn1aM=
+gitea.com/macaron/macaron v1.5.0/go.mod h1:P7hfDbQjcW22lkYkXlxdRIfWOXxH2+K4EogN4Q0UlLY=
 github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 h1:U/lr3Dgy4WK+hNk4tyD+nuGjpVLPEHuJSFXMw11/HPA=
 github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
-github.com/couchbase/gomemcached v0.0.0-20190515232915-c4b4ca0eb21d h1:XMf4E1U+b9E3ElF0mjvfXZdflBRZz4gLp16nQ/QSHQM=
-github.com/couchbase/gomemcached v0.0.0-20190515232915-c4b4ca0eb21d/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
-github.com/couchbase/goutils v0.0.0-20191018232750-b49639060d85 h1:0WMIDtuXCKEm4wtAJgAAXa/qtM5O9MariLwgHaRlYmk=
-github.com/couchbase/goutils v0.0.0-20191018232750-b49639060d85/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
-github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7 h1:1XjEY/gnjQ+AfXef2U6dxCquhiRzkEpxZuWqs+QxTL8=
-github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7/go.mod h1:mby/05p8HE5yHEAKiIH/555NoblMs7PtW6NrYshDruc=
+github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89 h1:uNLXQ6QO1TocD8BaN/KkRki0Xw0brCM1PKl/ZA5pgfs=
+github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A=
+github.com/couchbase/gomemcached v0.1.0 h1:whUde87n8CScx8ckMp2En5liqAlcuG3aKy/BQeBPu84=
+github.com/couchbase/gomemcached v0.1.0/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
+github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67 h1:NCqJ6fwen6YP0WlV/IyibaT0kPt3JEI1rA62V/UPKT4=
+github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
 github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 h1:Lgdd/Qp96Qj8jqLpq2cI1I1X7BJnu06efS+XkhRoLUQ=
 github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -30,6 +30,8 @@ github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw=
+github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
 github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@@ -40,10 +42,7 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
 github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de h1:nyxwRdWHAVxpFcDThedEgQ07DbcRc5xgNObtbTp76fk=
-github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ=
-github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af h1:UaWHNBdukWrSG3DRvHFR/hyfg681fceqQDYVTBncKfQ=
-github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VObJ7peltM+2n3PWOz7yTrfUuGbVFkzN0=
+github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
 github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -51,8 +50,8 @@ github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
 github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg=
-github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
+github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
+github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
 github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -68,6 +67,7 @@ github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
 github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY=
 github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
 github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
 github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
 github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
@@ -76,12 +76,13 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
 github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
-github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM=
-github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
+github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
+golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -109,6 +110,7 @@ gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0=
 gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
index db174e7ed19f02b0ed033e7ea69c6260397a086f..08a73c54909064778729ae981e571da27080d8ed 100644 (file)
@@ -19,8 +19,8 @@ import (
        "sync"
 
        "gitea.com/macaron/session"
-       "github.com/lunny/nodb"
-       "github.com/lunny/nodb/config"
+       "gitea.com/lunny/nodb"
+       "gitea.com/lunny/nodb/config"
 )
 
 // NodbStore represents a nodb session store implementation.
diff --git a/vendor/github.com/BurntSushi/toml/.gitignore b/vendor/github.com/BurntSushi/toml/.gitignore
deleted file mode 100644 (file)
index 0cd3800..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-TAGS
-tags
-.*.swp
-tomlcheck/tomlcheck
-toml.test
diff --git a/vendor/github.com/BurntSushi/toml/.travis.yml b/vendor/github.com/BurntSushi/toml/.travis.yml
deleted file mode 100644 (file)
index 8b8afc4..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-language: go
-go:
-  - 1.1
-  - 1.2
-  - 1.3
-  - 1.4
-  - 1.5
-  - 1.6
-  - tip
-install:
-  - go install ./...
-  - go get github.com/BurntSushi/toml-test
-script:
-  - export PATH="$PATH:$HOME/gopath/bin"
-  - make test
diff --git a/vendor/github.com/BurntSushi/toml/COMPATIBLE b/vendor/github.com/BurntSushi/toml/COMPATIBLE
deleted file mode 100644 (file)
index 6efcfd0..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Compatible with TOML version
-[v0.4.0](https://github.com/toml-lang/toml/blob/v0.4.0/versions/en/toml-v0.4.0.md)
-
diff --git a/vendor/github.com/BurntSushi/toml/COPYING b/vendor/github.com/BurntSushi/toml/COPYING
deleted file mode 100644 (file)
index 01b5743..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 TOML authors
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/vendor/github.com/BurntSushi/toml/Makefile b/vendor/github.com/BurntSushi/toml/Makefile
deleted file mode 100644 (file)
index 3600848..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-install:
-       go install ./...
-
-test: install
-       go test -v
-       toml-test toml-test-decoder
-       toml-test -encoder toml-test-encoder
-
-fmt:
-       gofmt -w *.go */*.go
-       colcheck *.go */*.go
-
-tags:
-       find ./ -name '*.go' -print0 | xargs -0 gotags > TAGS
-
-push:
-       git push origin master
-       git push github master
-
diff --git a/vendor/github.com/BurntSushi/toml/README.md b/vendor/github.com/BurntSushi/toml/README.md
deleted file mode 100644 (file)
index 7c1b37e..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-## TOML parser and encoder for Go with reflection
-
-TOML stands for Tom's Obvious, Minimal Language. This Go package provides a
-reflection interface similar to Go's standard library `json` and `xml`
-packages. This package also supports the `encoding.TextUnmarshaler` and
-`encoding.TextMarshaler` interfaces so that you can define custom data
-representations. (There is an example of this below.)
-
-Spec: https://github.com/toml-lang/toml
-
-Compatible with TOML version
-[v0.4.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md)
-
-Documentation: https://godoc.org/github.com/BurntSushi/toml
-
-Installation:
-
-```bash
-go get github.com/BurntSushi/toml
-```
-
-Try the toml validator:
-
-```bash
-go get github.com/BurntSushi/toml/cmd/tomlv
-tomlv some-toml-file.toml
-```
-
-[![Build Status](https://travis-ci.org/BurntSushi/toml.svg?branch=master)](https://travis-ci.org/BurntSushi/toml) [![GoDoc](https://godoc.org/github.com/BurntSushi/toml?status.svg)](https://godoc.org/github.com/BurntSushi/toml)
-
-### Testing
-
-This package passes all tests in
-[toml-test](https://github.com/BurntSushi/toml-test) for both the decoder
-and the encoder.
-
-### Examples
-
-This package works similarly to how the Go standard library handles `XML`
-and `JSON`. Namely, data is loaded into Go values via reflection.
-
-For the simplest example, consider some TOML file as just a list of keys
-and values:
-
-```toml
-Age = 25
-Cats = [ "Cauchy", "Plato" ]
-Pi = 3.14
-Perfection = [ 6, 28, 496, 8128 ]
-DOB = 1987-07-05T05:45:00Z
-```
-
-Which could be defined in Go as:
-
-```go
-type Config struct {
-  Age int
-  Cats []string
-  Pi float64
-  Perfection []int
-  DOB time.Time // requires `import time`
-}
-```
-
-And then decoded with:
-
-```go
-var conf Config
-if _, err := toml.Decode(tomlData, &conf); err != nil {
-  // handle error
-}
-```
-
-You can also use struct tags if your struct field name doesn't map to a TOML
-key value directly:
-
-```toml
-some_key_NAME = "wat"
-```
-
-```go
-type TOML struct {
-  ObscureKey string `toml:"some_key_NAME"`
-}
-```
-
-### Using the `encoding.TextUnmarshaler` interface
-
-Here's an example that automatically parses duration strings into
-`time.Duration` values:
-
-```toml
-[[song]]
-name = "Thunder Road"
-duration = "4m49s"
-
-[[song]]
-name = "Stairway to Heaven"
-duration = "8m03s"
-```
-
-Which can be decoded with:
-
-```go
-type song struct {
-  Name     string
-  Duration duration
-}
-type songs struct {
-  Song []song
-}
-var favorites songs
-if _, err := toml.Decode(blob, &favorites); err != nil {
-  log.Fatal(err)
-}
-
-for _, s := range favorites.Song {
-  fmt.Printf("%s (%s)\n", s.Name, s.Duration)
-}
-```
-
-And you'll also need a `duration` type that satisfies the
-`encoding.TextUnmarshaler` interface:
-
-```go
-type duration struct {
-       time.Duration
-}
-
-func (d *duration) UnmarshalText(text []byte) error {
-       var err error
-       d.Duration, err = time.ParseDuration(string(text))
-       return err
-}
-```
-
-### More complex usage
-
-Here's an example of how to load the example from the official spec page:
-
-```toml
-# This is a TOML document. Boom.
-
-title = "TOML Example"
-
-[owner]
-name = "Tom Preston-Werner"
-organization = "GitHub"
-bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
-dob = 1979-05-27T07:32:00Z # First class dates? Why not?
-
-[database]
-server = "192.168.1.1"
-ports = [ 8001, 8001, 8002 ]
-connection_max = 5000
-enabled = true
-
-[servers]
-
-  # You can indent as you please. Tabs or spaces. TOML don't care.
-  [servers.alpha]
-  ip = "10.0.0.1"
-  dc = "eqdc10"
-
-  [servers.beta]
-  ip = "10.0.0.2"
-  dc = "eqdc10"
-
-[clients]
-data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it
-
-# Line breaks are OK when inside arrays
-hosts = [
-  "alpha",
-  "omega"
-]
-```
-
-And the corresponding Go types are:
-
-```go
-type tomlConfig struct {
-       Title string
-       Owner ownerInfo
-       DB database `toml:"database"`
-       Servers map[string]server
-       Clients clients
-}
-
-type ownerInfo struct {
-       Name string
-       Org string `toml:"organization"`
-       Bio string
-       DOB time.Time
-}
-
-type database struct {
-       Server string
-       Ports []int
-       ConnMax int `toml:"connection_max"`
-       Enabled bool
-}
-
-type server struct {
-       IP string
-       DC string
-}
-
-type clients struct {
-       Data [][]interface{}
-       Hosts []string
-}
-```
-
-Note that a case insensitive match will be tried if an exact match can't be
-found.
-
-A working example of the above can be found in `_examples/example.{go,toml}`.
diff --git a/vendor/github.com/BurntSushi/toml/decode.go b/vendor/github.com/BurntSushi/toml/decode.go
deleted file mode 100644 (file)
index b0fd51d..0000000
+++ /dev/null
@@ -1,509 +0,0 @@
-package toml
-
-import (
-       "fmt"
-       "io"
-       "io/ioutil"
-       "math"
-       "reflect"
-       "strings"
-       "time"
-)
-
-func e(format string, args ...interface{}) error {
-       return fmt.Errorf("toml: "+format, args...)
-}
-
-// Unmarshaler is the interface implemented by objects that can unmarshal a
-// TOML description of themselves.
-type Unmarshaler interface {
-       UnmarshalTOML(interface{}) error
-}
-
-// Unmarshal decodes the contents of `p` in TOML format into a pointer `v`.
-func Unmarshal(p []byte, v interface{}) error {
-       _, err := Decode(string(p), v)
-       return err
-}
-
-// Primitive is a TOML value that hasn't been decoded into a Go value.
-// When using the various `Decode*` functions, the type `Primitive` may
-// be given to any value, and its decoding will be delayed.
-//
-// A `Primitive` value can be decoded using the `PrimitiveDecode` function.
-//
-// The underlying representation of a `Primitive` value is subject to change.
-// Do not rely on it.
-//
-// N.B. Primitive values are still parsed, so using them will only avoid
-// the overhead of reflection. They can be useful when you don't know the
-// exact type of TOML data until run time.
-type Primitive struct {
-       undecoded interface{}
-       context   Key
-}
-
-// DEPRECATED!
-//
-// Use MetaData.PrimitiveDecode instead.
-func PrimitiveDecode(primValue Primitive, v interface{}) error {
-       md := MetaData{decoded: make(map[string]bool)}
-       return md.unify(primValue.undecoded, rvalue(v))
-}
-
-// PrimitiveDecode is just like the other `Decode*` functions, except it
-// decodes a TOML value that has already been parsed. Valid primitive values
-// can *only* be obtained from values filled by the decoder functions,
-// including this method. (i.e., `v` may contain more `Primitive`
-// values.)
-//
-// Meta data for primitive values is included in the meta data returned by
-// the `Decode*` functions with one exception: keys returned by the Undecoded
-// method will only reflect keys that were decoded. Namely, any keys hidden
-// behind a Primitive will be considered undecoded. Executing this method will
-// update the undecoded keys in the meta data. (See the example.)
-func (md *MetaData) PrimitiveDecode(primValue Primitive, v interface{}) error {
-       md.context = primValue.context
-       defer func() { md.context = nil }()
-       return md.unify(primValue.undecoded, rvalue(v))
-}
-
-// Decode will decode the contents of `data` in TOML format into a pointer
-// `v`.
-//
-// TOML hashes correspond to Go structs or maps. (Dealer's choice. They can be
-// used interchangeably.)
-//
-// TOML arrays of tables correspond to either a slice of structs or a slice
-// of maps.
-//
-// TOML datetimes correspond to Go `time.Time` values.
-//
-// All other TOML types (float, string, int, bool and array) correspond
-// to the obvious Go types.
-//
-// An exception to the above rules is if a type implements the
-// encoding.TextUnmarshaler interface. In this case, any primitive TOML value
-// (floats, strings, integers, booleans and datetimes) will be converted to
-// a byte string and given to the value's UnmarshalText method. See the
-// Unmarshaler example for a demonstration with time duration strings.
-//
-// Key mapping
-//
-// TOML keys can map to either keys in a Go map or field names in a Go
-// struct. The special `toml` struct tag may be used to map TOML keys to
-// struct fields that don't match the key name exactly. (See the example.)
-// A case insensitive match to struct names will be tried if an exact match
-// can't be found.
-//
-// The mapping between TOML values and Go values is loose. That is, there
-// may exist TOML values that cannot be placed into your representation, and
-// there may be parts of your representation that do not correspond to
-// TOML values. This loose mapping can be made stricter by using the IsDefined
-// and/or Undecoded methods on the MetaData returned.
-//
-// This decoder will not handle cyclic types. If a cyclic type is passed,
-// `Decode` will not terminate.
-func Decode(data string, v interface{}) (MetaData, error) {
-       rv := reflect.ValueOf(v)
-       if rv.Kind() != reflect.Ptr {
-               return MetaData{}, e("Decode of non-pointer %s", reflect.TypeOf(v))
-       }
-       if rv.IsNil() {
-               return MetaData{}, e("Decode of nil %s", reflect.TypeOf(v))
-       }
-       p, err := parse(data)
-       if err != nil {
-               return MetaData{}, err
-       }
-       md := MetaData{
-               p.mapping, p.types, p.ordered,
-               make(map[string]bool, len(p.ordered)), nil,
-       }
-       return md, md.unify(p.mapping, indirect(rv))
-}
-
-// DecodeFile is just like Decode, except it will automatically read the
-// contents of the file at `fpath` and decode it for you.
-func DecodeFile(fpath string, v interface{}) (MetaData, error) {
-       bs, err := ioutil.ReadFile(fpath)
-       if err != nil {
-               return MetaData{}, err
-       }
-       return Decode(string(bs), v)
-}
-
-// DecodeReader is just like Decode, except it will consume all bytes
-// from the reader and decode it for you.
-func DecodeReader(r io.Reader, v interface{}) (MetaData, error) {
-       bs, err := ioutil.ReadAll(r)
-       if err != nil {
-               return MetaData{}, err
-       }
-       return Decode(string(bs), v)
-}
-
-// unify performs a sort of type unification based on the structure of `rv`,
-// which is the client representation.
-//
-// Any type mismatch produces an error. Finding a type that we don't know
-// how to handle produces an unsupported type error.
-func (md *MetaData) unify(data interface{}, rv reflect.Value) error {
-
-       // Special case. Look for a `Primitive` value.
-       if rv.Type() == reflect.TypeOf((*Primitive)(nil)).Elem() {
-               // Save the undecoded data and the key context into the primitive
-               // value.
-               context := make(Key, len(md.context))
-               copy(context, md.context)
-               rv.Set(reflect.ValueOf(Primitive{
-                       undecoded: data,
-                       context:   context,
-               }))
-               return nil
-       }
-
-       // Special case. Unmarshaler Interface support.
-       if rv.CanAddr() {
-               if v, ok := rv.Addr().Interface().(Unmarshaler); ok {
-                       return v.UnmarshalTOML(data)
-               }
-       }
-
-       // Special case. Handle time.Time values specifically.
-       // TODO: Remove this code when we decide to drop support for Go 1.1.
-       // This isn't necessary in Go 1.2 because time.Time satisfies the encoding
-       // interfaces.
-       if rv.Type().AssignableTo(rvalue(time.Time{}).Type()) {
-               return md.unifyDatetime(data, rv)
-       }
-
-       // Special case. Look for a value satisfying the TextUnmarshaler interface.
-       if v, ok := rv.Interface().(TextUnmarshaler); ok {
-               return md.unifyText(data, v)
-       }
-       // BUG(burntsushi)
-       // The behavior here is incorrect whenever a Go type satisfies the
-       // encoding.TextUnmarshaler interface but also corresponds to a TOML
-       // hash or array. In particular, the unmarshaler should only be applied
-       // to primitive TOML values. But at this point, it will be applied to
-       // all kinds of values and produce an incorrect error whenever those values
-       // are hashes or arrays (including arrays of tables).
-
-       k := rv.Kind()
-
-       // laziness
-       if k >= reflect.Int && k <= reflect.Uint64 {
-               return md.unifyInt(data, rv)
-       }
-       switch k {
-       case reflect.Ptr:
-               elem := reflect.New(rv.Type().Elem())
-               err := md.unify(data, reflect.Indirect(elem))
-               if err != nil {
-                       return err
-               }
-               rv.Set(elem)
-               return nil
-       case reflect.Struct:
-               return md.unifyStruct(data, rv)
-       case reflect.Map:
-               return md.unifyMap(data, rv)
-       case reflect.Array:
-               return md.unifyArray(data, rv)
-       case reflect.Slice:
-               return md.unifySlice(data, rv)
-       case reflect.String:
-               return md.unifyString(data, rv)
-       case reflect.Bool:
-               return md.unifyBool(data, rv)
-       case reflect.Interface:
-               // we only support empty interfaces.
-               if rv.NumMethod() > 0 {
-                       return e("unsupported type %s", rv.Type())
-               }
-               return md.unifyAnything(data, rv)
-       case reflect.Float32:
-               fallthrough
-       case reflect.Float64:
-               return md.unifyFloat64(data, rv)
-       }
-       return e("unsupported type %s", rv.Kind())
-}
-
-func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error {
-       tmap, ok := mapping.(map[string]interface{})
-       if !ok {
-               if mapping == nil {
-                       return nil
-               }
-               return e("type mismatch for %s: expected table but found %T",
-                       rv.Type().String(), mapping)
-       }
-
-       for key, datum := range tmap {
-               var f *field
-               fields := cachedTypeFields(rv.Type())
-               for i := range fields {
-                       ff := &fields[i]
-                       if ff.name == key {
-                               f = ff
-                               break
-                       }
-                       if f == nil && strings.EqualFold(ff.name, key) {
-                               f = ff
-                       }
-               }
-               if f != nil {
-                       subv := rv
-                       for _, i := range f.index {
-                               subv = indirect(subv.Field(i))
-                       }
-                       if isUnifiable(subv) {
-                               md.decoded[md.context.add(key).String()] = true
-                               md.context = append(md.context, key)
-                               if err := md.unify(datum, subv); err != nil {
-                                       return err
-                               }
-                               md.context = md.context[0 : len(md.context)-1]
-                       } else if f.name != "" {
-                               // Bad user! No soup for you!
-                               return e("cannot write unexported field %s.%s",
-                                       rv.Type().String(), f.name)
-                       }
-               }
-       }
-       return nil
-}
-
-func (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error {
-       tmap, ok := mapping.(map[string]interface{})
-       if !ok {
-               if tmap == nil {
-                       return nil
-               }
-               return badtype("map", mapping)
-       }
-       if rv.IsNil() {
-               rv.Set(reflect.MakeMap(rv.Type()))
-       }
-       for k, v := range tmap {
-               md.decoded[md.context.add(k).String()] = true
-               md.context = append(md.context, k)
-
-               rvkey := indirect(reflect.New(rv.Type().Key()))
-               rvval := reflect.Indirect(reflect.New(rv.Type().Elem()))
-               if err := md.unify(v, rvval); err != nil {
-                       return err
-               }
-               md.context = md.context[0 : len(md.context)-1]
-
-               rvkey.SetString(k)
-               rv.SetMapIndex(rvkey, rvval)
-       }
-       return nil
-}
-
-func (md *MetaData) unifyArray(data interface{}, rv reflect.Value) error {
-       datav := reflect.ValueOf(data)
-       if datav.Kind() != reflect.Slice {
-               if !datav.IsValid() {
-                       return nil
-               }
-               return badtype("slice", data)
-       }
-       sliceLen := datav.Len()
-       if sliceLen != rv.Len() {
-               return e("expected array length %d; got TOML array of length %d",
-                       rv.Len(), sliceLen)
-       }
-       return md.unifySliceArray(datav, rv)
-}
-
-func (md *MetaData) unifySlice(data interface{}, rv reflect.Value) error {
-       datav := reflect.ValueOf(data)
-       if datav.Kind() != reflect.Slice {
-               if !datav.IsValid() {
-                       return nil
-               }
-               return badtype("slice", data)
-       }
-       n := datav.Len()
-       if rv.IsNil() || rv.Cap() < n {
-               rv.Set(reflect.MakeSlice(rv.Type(), n, n))
-       }
-       rv.SetLen(n)
-       return md.unifySliceArray(datav, rv)
-}
-
-func (md *MetaData) unifySliceArray(data, rv reflect.Value) error {
-       sliceLen := data.Len()
-       for i := 0; i < sliceLen; i++ {
-               v := data.Index(i).Interface()
-               sliceval := indirect(rv.Index(i))
-               if err := md.unify(v, sliceval); err != nil {
-                       return err
-               }
-       }
-       return nil
-}
-
-func (md *MetaData) unifyDatetime(data interface{}, rv reflect.Value) error {
-       if _, ok := data.(time.Time); ok {
-               rv.Set(reflect.ValueOf(data))
-               return nil
-       }
-       return badtype("time.Time", data)
-}
-
-func (md *MetaData) unifyString(data interface{}, rv reflect.Value) error {
-       if s, ok := data.(string); ok {
-               rv.SetString(s)
-               return nil
-       }
-       return badtype("string", data)
-}
-
-func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error {
-       if num, ok := data.(float64); ok {
-               switch rv.Kind() {
-               case reflect.Float32:
-                       fallthrough
-               case reflect.Float64:
-                       rv.SetFloat(num)
-               default:
-                       panic("bug")
-               }
-               return nil
-       }
-       return badtype("float", data)
-}
-
-func (md *MetaData) unifyInt(data interface{}, rv reflect.Value) error {
-       if num, ok := data.(int64); ok {
-               if rv.Kind() >= reflect.Int && rv.Kind() <= reflect.Int64 {
-                       switch rv.Kind() {
-                       case reflect.Int, reflect.Int64:
-                               // No bounds checking necessary.
-                       case reflect.Int8:
-                               if num < math.MinInt8 || num > math.MaxInt8 {
-                                       return e("value %d is out of range for int8", num)
-                               }
-                       case reflect.Int16:
-                               if num < math.MinInt16 || num > math.MaxInt16 {
-                                       return e("value %d is out of range for int16", num)
-                               }
-                       case reflect.Int32:
-                               if num < math.MinInt32 || num > math.MaxInt32 {
-                                       return e("value %d is out of range for int32", num)
-                               }
-                       }
-                       rv.SetInt(num)
-               } else if rv.Kind() >= reflect.Uint && rv.Kind() <= reflect.Uint64 {
-                       unum := uint64(num)
-                       switch rv.Kind() {
-                       case reflect.Uint, reflect.Uint64:
-                               // No bounds checking necessary.
-                       case reflect.Uint8:
-                               if num < 0 || unum > math.MaxUint8 {
-                                       return e("value %d is out of range for uint8", num)
-                               }
-                       case reflect.Uint16:
-                               if num < 0 || unum > math.MaxUint16 {
-                                       return e("value %d is out of range for uint16", num)
-                               }
-                       case reflect.Uint32:
-                               if num < 0 || unum > math.MaxUint32 {
-                                       return e("value %d is out of range for uint32", num)
-                               }
-                       }
-                       rv.SetUint(unum)
-               } else {
-                       panic("unreachable")
-               }
-               return nil
-       }
-       return badtype("integer", data)
-}
-
-func (md *MetaData) unifyBool(data interface{}, rv reflect.Value) error {
-       if b, ok := data.(bool); ok {
-               rv.SetBool(b)
-               return nil
-       }
-       return badtype("boolean", data)
-}
-
-func (md *MetaData) unifyAnything(data interface{}, rv reflect.Value) error {
-       rv.Set(reflect.ValueOf(data))
-       return nil
-}
-
-func (md *MetaData) unifyText(data interface{}, v TextUnmarshaler) error {
-       var s string
-       switch sdata := data.(type) {
-       case TextMarshaler:
-               text, err := sdata.MarshalText()
-               if err != nil {
-                       return err
-               }
-               s = string(text)
-       case fmt.Stringer:
-               s = sdata.String()
-       case string:
-               s = sdata
-       case bool:
-               s = fmt.Sprintf("%v", sdata)
-       case int64:
-               s = fmt.Sprintf("%d", sdata)
-       case float64:
-               s = fmt.Sprintf("%f", sdata)
-       default:
-               return badtype("primitive (string-like)", data)
-       }
-       if err := v.UnmarshalText([]byte(s)); err != nil {
-               return err
-       }
-       return nil
-}
-
-// rvalue returns a reflect.Value of `v`. All pointers are resolved.
-func rvalue(v interface{}) reflect.Value {
-       return indirect(reflect.ValueOf(v))
-}
-
-// indirect returns the value pointed to by a pointer.
-// Pointers are followed until the value is not a pointer.
-// New values are allocated for each nil pointer.
-//
-// An exception to this rule is if the value satisfies an interface of
-// interest to us (like encoding.TextUnmarshaler).
-func indirect(v reflect.Value) reflect.Value {
-       if v.Kind() != reflect.Ptr {
-               if v.CanSet() {
-                       pv := v.Addr()
-                       if _, ok := pv.Interface().(TextUnmarshaler); ok {
-                               return pv
-                       }
-               }
-               return v
-       }
-       if v.IsNil() {
-               v.Set(reflect.New(v.Type().Elem()))
-       }
-       return indirect(reflect.Indirect(v))
-}
-
-func isUnifiable(rv reflect.Value) bool {
-       if rv.CanSet() {
-               return true
-       }
-       if _, ok := rv.Interface().(TextUnmarshaler); ok {
-               return true
-       }
-       return false
-}
-
-func badtype(expected string, data interface{}) error {
-       return e("cannot load TOML value of type %T into a Go %s", data, expected)
-}
diff --git a/vendor/github.com/BurntSushi/toml/decode_meta.go b/vendor/github.com/BurntSushi/toml/decode_meta.go
deleted file mode 100644 (file)
index b9914a6..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-package toml
-
-import "strings"
-
-// MetaData allows access to meta information about TOML data that may not
-// be inferrable via reflection. In particular, whether a key has been defined
-// and the TOML type of a key.
-type MetaData struct {
-       mapping map[string]interface{}
-       types   map[string]tomlType
-       keys    []Key
-       decoded map[string]bool
-       context Key // Used only during decoding.
-}
-
-// IsDefined returns true if the key given exists in the TOML data. The key
-// should be specified hierarchially. e.g.,
-//
-//     // access the TOML key 'a.b.c'
-//     IsDefined("a", "b", "c")
-//
-// IsDefined will return false if an empty key given. Keys are case sensitive.
-func (md *MetaData) IsDefined(key ...string) bool {
-       if len(key) == 0 {
-               return false
-       }
-
-       var hash map[string]interface{}
-       var ok bool
-       var hashOrVal interface{} = md.mapping
-       for _, k := range key {
-               if hash, ok = hashOrVal.(map[string]interface{}); !ok {
-                       return false
-               }
-               if hashOrVal, ok = hash[k]; !ok {
-                       return false
-               }
-       }
-       return true
-}
-
-// Type returns a string representation of the type of the key specified.
-//
-// Type will return the empty string if given an empty key or a key that
-// does not exist. Keys are case sensitive.
-func (md *MetaData) Type(key ...string) string {
-       fullkey := strings.Join(key, ".")
-       if typ, ok := md.types[fullkey]; ok {
-               return typ.typeString()
-       }
-       return ""
-}
-
-// Key is the type of any TOML key, including key groups. Use (MetaData).Keys
-// to get values of this type.
-type Key []string
-
-func (k Key) String() string {
-       return strings.Join(k, ".")
-}
-
-func (k Key) maybeQuotedAll() string {
-       var ss []string
-       for i := range k {
-               ss = append(ss, k.maybeQuoted(i))
-       }
-       return strings.Join(ss, ".")
-}
-
-func (k Key) maybeQuoted(i int) string {
-       quote := false
-       for _, c := range k[i] {
-               if !isBareKeyChar(c) {
-                       quote = true
-                       break
-               }
-       }
-       if quote {
-               return "\"" + strings.Replace(k[i], "\"", "\\\"", -1) + "\""
-       }
-       return k[i]
-}
-
-func (k Key) add(piece string) Key {
-       newKey := make(Key, len(k)+1)
-       copy(newKey, k)
-       newKey[len(k)] = piece
-       return newKey
-}
-
-// Keys returns a slice of every key in the TOML data, including key groups.
-// Each key is itself a slice, where the first element is the top of the
-// hierarchy and the last is the most specific.
-//
-// The list will have the same order as the keys appeared in the TOML data.
-//
-// All keys returned are non-empty.
-func (md *MetaData) Keys() []Key {
-       return md.keys
-}
-
-// Undecoded returns all keys that have not been decoded in the order in which
-// they appear in the original TOML document.
-//
-// This includes keys that haven't been decoded because of a Primitive value.
-// Once the Primitive value is decoded, the keys will be considered decoded.
-//
-// Also note that decoding into an empty interface will result in no decoding,
-// and so no keys will be considered decoded.
-//
-// In this sense, the Undecoded keys correspond to keys in the TOML document
-// that do not have a concrete type in your representation.
-func (md *MetaData) Undecoded() []Key {
-       undecoded := make([]Key, 0, len(md.keys))
-       for _, key := range md.keys {
-               if !md.decoded[key.String()] {
-                       undecoded = append(undecoded, key)
-               }
-       }
-       return undecoded
-}
diff --git a/vendor/github.com/BurntSushi/toml/doc.go b/vendor/github.com/BurntSushi/toml/doc.go
deleted file mode 100644 (file)
index b371f39..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-Package toml provides facilities for decoding and encoding TOML configuration
-files via reflection. There is also support for delaying decoding with
-the Primitive type, and querying the set of keys in a TOML document with the
-MetaData type.
-
-The specification implemented: https://github.com/toml-lang/toml
-
-The sub-command github.com/BurntSushi/toml/cmd/tomlv can be used to verify
-whether a file is a valid TOML document. It can also be used to print the
-type of each key in a TOML document.
-
-Testing
-
-There are two important types of tests used for this package. The first is
-contained inside '*_test.go' files and uses the standard Go unit testing
-framework. These tests are primarily devoted to holistically testing the
-decoder and encoder.
-
-The second type of testing is used to verify the implementation's adherence
-to the TOML specification. These tests have been factored into their own
-project: https://github.com/BurntSushi/toml-test
-
-The reason the tests are in a separate project is so that they can be used by
-any implementation of TOML. Namely, it is language agnostic.
-*/
-package toml
diff --git a/vendor/github.com/BurntSushi/toml/encode.go b/vendor/github.com/BurntSushi/toml/encode.go
deleted file mode 100644 (file)
index d905c21..0000000
+++ /dev/null
@@ -1,568 +0,0 @@
-package toml
-
-import (
-       "bufio"
-       "errors"
-       "fmt"
-       "io"
-       "reflect"
-       "sort"
-       "strconv"
-       "strings"
-       "time"
-)
-
-type tomlEncodeError struct{ error }
-
-var (
-       errArrayMixedElementTypes = errors.New(
-               "toml: cannot encode array with mixed element types")
-       errArrayNilElement = errors.New(
-               "toml: cannot encode array with nil element")
-       errNonString = errors.New(
-               "toml: cannot encode a map with non-string key type")
-       errAnonNonStruct = errors.New(
-               "toml: cannot encode an anonymous field that is not a struct")
-       errArrayNoTable = errors.New(
-               "toml: TOML array element cannot contain a table")
-       errNoKey = errors.New(
-               "toml: top-level values must be Go maps or structs")
-       errAnything = errors.New("") // used in testing
-)
-
-var quotedReplacer = strings.NewReplacer(
-       "\t", "\\t",
-       "\n", "\\n",
-       "\r", "\\r",
-       "\"", "\\\"",
-       "\\", "\\\\",
-)
-
-// Encoder controls the encoding of Go values to a TOML document to some
-// io.Writer.
-//
-// The indentation level can be controlled with the Indent field.
-type Encoder struct {
-       // A single indentation level. By default it is two spaces.
-       Indent string
-
-       // hasWritten is whether we have written any output to w yet.
-       hasWritten bool
-       w          *bufio.Writer
-}
-
-// NewEncoder returns a TOML encoder that encodes Go values to the io.Writer
-// given. By default, a single indentation level is 2 spaces.
-func NewEncoder(w io.Writer) *Encoder {
-       return &Encoder{
-               w:      bufio.NewWriter(w),
-               Indent: "  ",
-       }
-}
-
-// Encode writes a TOML representation of the Go value to the underlying
-// io.Writer. If the value given cannot be encoded to a valid TOML document,
-// then an error is returned.
-//
-// The mapping between Go values and TOML values should be precisely the same
-// as for the Decode* functions. Similarly, the TextMarshaler interface is
-// supported by encoding the resulting bytes as strings. (If you want to write
-// arbitrary binary data then you will need to use something like base64 since
-// TOML does not have any binary types.)
-//
-// When encoding TOML hashes (i.e., Go maps or structs), keys without any
-// sub-hashes are encoded first.
-//
-// If a Go map is encoded, then its keys are sorted alphabetically for
-// deterministic output. More control over this behavior may be provided if
-// there is demand for it.
-//
-// Encoding Go values without a corresponding TOML representation---like map
-// types with non-string keys---will cause an error to be returned. Similarly
-// for mixed arrays/slices, arrays/slices with nil elements, embedded
-// non-struct types and nested slices containing maps or structs.
-// (e.g., [][]map[string]string is not allowed but []map[string]string is OK
-// and so is []map[string][]string.)
-func (enc *Encoder) Encode(v interface{}) error {
-       rv := eindirect(reflect.ValueOf(v))
-       if err := enc.safeEncode(Key([]string{}), rv); err != nil {
-               return err
-       }
-       return enc.w.Flush()
-}
-
-func (enc *Encoder) safeEncode(key Key, rv reflect.Value) (err error) {
-       defer func() {
-               if r := recover(); r != nil {
-                       if terr, ok := r.(tomlEncodeError); ok {
-                               err = terr.error
-                               return
-                       }
-                       panic(r)
-               }
-       }()
-       enc.encode(key, rv)
-       return nil
-}
-
-func (enc *Encoder) encode(key Key, rv reflect.Value) {
-       // Special case. Time needs to be in ISO8601 format.
-       // Special case. If we can marshal the type to text, then we used that.
-       // Basically, this prevents the encoder for handling these types as
-       // generic structs (or whatever the underlying type of a TextMarshaler is).
-       switch rv.Interface().(type) {
-       case time.Time, TextMarshaler:
-               enc.keyEqElement(key, rv)
-               return
-       }
-
-       k := rv.Kind()
-       switch k {
-       case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,
-               reflect.Int64,
-               reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
-               reflect.Uint64,
-               reflect.Float32, reflect.Float64, reflect.String, reflect.Bool:
-               enc.keyEqElement(key, rv)
-       case reflect.Array, reflect.Slice:
-               if typeEqual(tomlArrayHash, tomlTypeOfGo(rv)) {
-                       enc.eArrayOfTables(key, rv)
-               } else {
-                       enc.keyEqElement(key, rv)
-               }
-       case reflect.Interface:
-               if rv.IsNil() {
-                       return
-               }
-               enc.encode(key, rv.Elem())
-       case reflect.Map:
-               if rv.IsNil() {
-                       return
-               }
-               enc.eTable(key, rv)
-       case reflect.Ptr:
-               if rv.IsNil() {
-                       return
-               }
-               enc.encode(key, rv.Elem())
-       case reflect.Struct:
-               enc.eTable(key, rv)
-       default:
-               panic(e("unsupported type for key '%s': %s", key, k))
-       }
-}
-
-// eElement encodes any value that can be an array element (primitives and
-// arrays).
-func (enc *Encoder) eElement(rv reflect.Value) {
-       switch v := rv.Interface().(type) {
-       case time.Time:
-               // Special case time.Time as a primitive. Has to come before
-               // TextMarshaler below because time.Time implements
-               // encoding.TextMarshaler, but we need to always use UTC.
-               enc.wf(v.UTC().Format("2006-01-02T15:04:05Z"))
-               return
-       case TextMarshaler:
-               // Special case. Use text marshaler if it's available for this value.
-               if s, err := v.MarshalText(); err != nil {
-                       encPanic(err)
-               } else {
-                       enc.writeQuoted(string(s))
-               }
-               return
-       }
-       switch rv.Kind() {
-       case reflect.Bool:
-               enc.wf(strconv.FormatBool(rv.Bool()))
-       case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,
-               reflect.Int64:
-               enc.wf(strconv.FormatInt(rv.Int(), 10))
-       case reflect.Uint, reflect.Uint8, reflect.Uint16,
-               reflect.Uint32, reflect.Uint64:
-               enc.wf(strconv.FormatUint(rv.Uint(), 10))
-       case reflect.Float32:
-               enc.wf(floatAddDecimal(strconv.FormatFloat(rv.Float(), 'f', -1, 32)))
-       case reflect.Float64:
-               enc.wf(floatAddDecimal(strconv.FormatFloat(rv.Float(), 'f', -1, 64)))
-       case reflect.Array, reflect.Slice:
-               enc.eArrayOrSliceElement(rv)
-       case reflect.Interface:
-               enc.eElement(rv.Elem())
-       case reflect.String:
-               enc.writeQuoted(rv.String())
-       default:
-               panic(e("unexpected primitive type: %s", rv.Kind()))
-       }
-}
-
-// By the TOML spec, all floats must have a decimal with at least one
-// number on either side.
-func floatAddDecimal(fstr string) string {
-       if !strings.Contains(fstr, ".") {
-               return fstr + ".0"
-       }
-       return fstr
-}
-
-func (enc *Encoder) writeQuoted(s string) {
-       enc.wf("\"%s\"", quotedReplacer.Replace(s))
-}
-
-func (enc *Encoder) eArrayOrSliceElement(rv reflect.Value) {
-       length := rv.Len()
-       enc.wf("[")
-       for i := 0; i < length; i++ {
-               elem := rv.Index(i)
-               enc.eElement(elem)
-               if i != length-1 {
-                       enc.wf(", ")
-               }
-       }
-       enc.wf("]")
-}
-
-func (enc *Encoder) eArrayOfTables(key Key, rv reflect.Value) {
-       if len(key) == 0 {
-               encPanic(errNoKey)
-       }
-       for i := 0; i < rv.Len(); i++ {
-               trv := rv.Index(i)
-               if isNil(trv) {
-                       continue
-               }
-               panicIfInvalidKey(key)
-               enc.newline()
-               enc.wf("%s[[%s]]", enc.indentStr(key), key.maybeQuotedAll())
-               enc.newline()
-               enc.eMapOrStruct(key, trv)
-       }
-}
-
-func (enc *Encoder) eTable(key Key, rv reflect.Value) {
-       panicIfInvalidKey(key)
-       if len(key) == 1 {
-               // Output an extra newline between top-level tables.
-               // (The newline isn't written if nothing else has been written though.)
-               enc.newline()
-       }
-       if len(key) > 0 {
-               enc.wf("%s[%s]", enc.indentStr(key), key.maybeQuotedAll())
-               enc.newline()
-       }
-       enc.eMapOrStruct(key, rv)
-}
-
-func (enc *Encoder) eMapOrStruct(key Key, rv reflect.Value) {
-       switch rv := eindirect(rv); rv.Kind() {
-       case reflect.Map:
-               enc.eMap(key, rv)
-       case reflect.Struct:
-               enc.eStruct(key, rv)
-       default:
-               panic("eTable: unhandled reflect.Value Kind: " + rv.Kind().String())
-       }
-}
-
-func (enc *Encoder) eMap(key Key, rv reflect.Value) {
-       rt := rv.Type()
-       if rt.Key().Kind() != reflect.String {
-               encPanic(errNonString)
-       }
-
-       // Sort keys so that we have deterministic output. And write keys directly
-       // underneath this key first, before writing sub-structs or sub-maps.
-       var mapKeysDirect, mapKeysSub []string
-       for _, mapKey := range rv.MapKeys() {
-               k := mapKey.String()
-               if typeIsHash(tomlTypeOfGo(rv.MapIndex(mapKey))) {
-                       mapKeysSub = append(mapKeysSub, k)
-               } else {
-                       mapKeysDirect = append(mapKeysDirect, k)
-               }
-       }
-
-       var writeMapKeys = func(mapKeys []string) {
-               sort.Strings(mapKeys)
-               for _, mapKey := range mapKeys {
-                       mrv := rv.MapIndex(reflect.ValueOf(mapKey))
-                       if isNil(mrv) {
-                               // Don't write anything for nil fields.
-                               continue
-                       }
-                       enc.encode(key.add(mapKey), mrv)
-               }
-       }
-       writeMapKeys(mapKeysDirect)
-       writeMapKeys(mapKeysSub)
-}
-
-func (enc *Encoder) eStruct(key Key, rv reflect.Value) {
-       // Write keys for fields directly under this key first, because if we write
-       // a field that creates a new table, then all keys under it will be in that
-       // table (not the one we're writing here).
-       rt := rv.Type()
-       var fieldsDirect, fieldsSub [][]int
-       var addFields func(rt reflect.Type, rv reflect.Value, start []int)
-       addFields = func(rt reflect.Type, rv reflect.Value, start []int) {
-               for i := 0; i < rt.NumField(); i++ {
-                       f := rt.Field(i)
-                       // skip unexported fields
-                       if f.PkgPath != "" && !f.Anonymous {
-                               continue
-                       }
-                       frv := rv.Field(i)
-                       if f.Anonymous {
-                               t := f.Type
-                               switch t.Kind() {
-                               case reflect.Struct:
-                                       // Treat anonymous struct fields with
-                                       // tag names as though they are not
-                                       // anonymous, like encoding/json does.
-                                       if getOptions(f.Tag).name == "" {
-                                               addFields(t, frv, f.Index)
-                                               continue
-                                       }
-                               case reflect.Ptr:
-                                       if t.Elem().Kind() == reflect.Struct &&
-                                               getOptions(f.Tag).name == "" {
-                                               if !frv.IsNil() {
-                                                       addFields(t.Elem(), frv.Elem(), f.Index)
-                                               }
-                                               continue
-                                       }
-                                       // Fall through to the normal field encoding logic below
-                                       // for non-struct anonymous fields.
-                               }
-                       }
-
-                       if typeIsHash(tomlTypeOfGo(frv)) {
-                               fieldsSub = append(fieldsSub, append(start, f.Index...))
-                       } else {
-                               fieldsDirect = append(fieldsDirect, append(start, f.Index...))
-                       }
-               }
-       }
-       addFields(rt, rv, nil)
-
-       var writeFields = func(fields [][]int) {
-               for _, fieldIndex := range fields {
-                       sft := rt.FieldByIndex(fieldIndex)
-                       sf := rv.FieldByIndex(fieldIndex)
-                       if isNil(sf) {
-                               // Don't write anything for nil fields.
-                               continue
-                       }
-
-                       opts := getOptions(sft.Tag)
-                       if opts.skip {
-                               continue
-                       }
-                       keyName := sft.Name
-                       if opts.name != "" {
-                               keyName = opts.name
-                       }
-                       if opts.omitempty && isEmpty(sf) {
-                               continue
-                       }
-                       if opts.omitzero && isZero(sf) {
-                               continue
-                       }
-
-                       enc.encode(key.add(keyName), sf)
-               }
-       }
-       writeFields(fieldsDirect)
-       writeFields(fieldsSub)
-}
-
-// tomlTypeName returns the TOML type name of the Go value's type. It is
-// used to determine whether the types of array elements are mixed (which is
-// forbidden). If the Go value is nil, then it is illegal for it to be an array
-// element, and valueIsNil is returned as true.
-
-// Returns the TOML type of a Go value. The type may be `nil`, which means
-// no concrete TOML type could be found.
-func tomlTypeOfGo(rv reflect.Value) tomlType {
-       if isNil(rv) || !rv.IsValid() {
-               return nil
-       }
-       switch rv.Kind() {
-       case reflect.Bool:
-               return tomlBool
-       case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,
-               reflect.Int64,
-               reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
-               reflect.Uint64:
-               return tomlInteger
-       case reflect.Float32, reflect.Float64:
-               return tomlFloat
-       case reflect.Array, reflect.Slice:
-               if typeEqual(tomlHash, tomlArrayType(rv)) {
-                       return tomlArrayHash
-               }
-               return tomlArray
-       case reflect.Ptr, reflect.Interface:
-               return tomlTypeOfGo(rv.Elem())
-       case reflect.String:
-               return tomlString
-       case reflect.Map:
-               return tomlHash
-       case reflect.Struct:
-               switch rv.Interface().(type) {
-               case time.Time:
-                       return tomlDatetime
-               case TextMarshaler:
-                       return tomlString
-               default:
-                       return tomlHash
-               }
-       default:
-               panic("unexpected reflect.Kind: " + rv.Kind().String())
-       }
-}
-
-// tomlArrayType returns the element type of a TOML array. The type returned
-// may be nil if it cannot be determined (e.g., a nil slice or a zero length
-// slize). This function may also panic if it finds a type that cannot be
-// expressed in TOML (such as nil elements, heterogeneous arrays or directly
-// nested arrays of tables).
-func tomlArrayType(rv reflect.Value) tomlType {
-       if isNil(rv) || !rv.IsValid() || rv.Len() == 0 {
-               return nil
-       }
-       firstType := tomlTypeOfGo(rv.Index(0))
-       if firstType == nil {
-               encPanic(errArrayNilElement)
-       }
-
-       rvlen := rv.Len()
-       for i := 1; i < rvlen; i++ {
-               elem := rv.Index(i)
-               switch elemType := tomlTypeOfGo(elem); {
-               case elemType == nil:
-                       encPanic(errArrayNilElement)
-               case !typeEqual(firstType, elemType):
-                       encPanic(errArrayMixedElementTypes)
-               }
-       }
-       // If we have a nested array, then we must make sure that the nested
-       // array contains ONLY primitives.
-       // This checks arbitrarily nested arrays.
-       if typeEqual(firstType, tomlArray) || typeEqual(firstType, tomlArrayHash) {
-               nest := tomlArrayType(eindirect(rv.Index(0)))
-               if typeEqual(nest, tomlHash) || typeEqual(nest, tomlArrayHash) {
-                       encPanic(errArrayNoTable)
-               }
-       }
-       return firstType
-}
-
-type tagOptions struct {
-       skip      bool // "-"
-       name      string
-       omitempty bool
-       omitzero  bool
-}
-
-func getOptions(tag reflect.StructTag) tagOptions {
-       t := tag.Get("toml")
-       if t == "-" {
-               return tagOptions{skip: true}
-       }
-       var opts tagOptions
-       parts := strings.Split(t, ",")
-       opts.name = parts[0]
-       for _, s := range parts[1:] {
-               switch s {
-               case "omitempty":
-                       opts.omitempty = true
-               case "omitzero":
-                       opts.omitzero = true
-               }
-       }
-       return opts
-}
-
-func isZero(rv reflect.Value) bool {
-       switch rv.Kind() {
-       case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-               return rv.Int() == 0
-       case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-               return rv.Uint() == 0
-       case reflect.Float32, reflect.Float64:
-               return rv.Float() == 0.0
-       }
-       return false
-}
-
-func isEmpty(rv reflect.Value) bool {
-       switch rv.Kind() {
-       case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
-               return rv.Len() == 0
-       case reflect.Bool:
-               return !rv.Bool()
-       }
-       return false
-}
-
-func (enc *Encoder) newline() {
-       if enc.hasWritten {
-               enc.wf("\n")
-       }
-}
-
-func (enc *Encoder) keyEqElement(key Key, val reflect.Value) {
-       if len(key) == 0 {
-               encPanic(errNoKey)
-       }
-       panicIfInvalidKey(key)
-       enc.wf("%s%s = ", enc.indentStr(key), key.maybeQuoted(len(key)-1))
-       enc.eElement(val)
-       enc.newline()
-}
-
-func (enc *Encoder) wf(format string, v ...interface{}) {
-       if _, err := fmt.Fprintf(enc.w, format, v...); err != nil {
-               encPanic(err)
-       }
-       enc.hasWritten = true
-}
-
-func (enc *Encoder) indentStr(key Key) string {
-       return strings.Repeat(enc.Indent, len(key)-1)
-}
-
-func encPanic(err error) {
-       panic(tomlEncodeError{err})
-}
-
-func eindirect(v reflect.Value) reflect.Value {
-       switch v.Kind() {
-       case reflect.Ptr, reflect.Interface:
-               return eindirect(v.Elem())
-       default:
-               return v
-       }
-}
-
-func isNil(rv reflect.Value) bool {
-       switch rv.Kind() {
-       case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
-               return rv.IsNil()
-       default:
-               return false
-       }
-}
-
-func panicIfInvalidKey(key Key) {
-       for _, k := range key {
-               if len(k) == 0 {
-                       encPanic(e("Key '%s' is not a valid table name. Key names "+
-                               "cannot be empty.", key.maybeQuotedAll()))
-               }
-       }
-}
-
-func isValidKeyName(s string) bool {
-       return len(s) != 0
-}
diff --git a/vendor/github.com/BurntSushi/toml/encoding_types.go b/vendor/github.com/BurntSushi/toml/encoding_types.go
deleted file mode 100644 (file)
index d36e1dd..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// +build go1.2
-
-package toml
-
-// In order to support Go 1.1, we define our own TextMarshaler and
-// TextUnmarshaler types. For Go 1.2+, we just alias them with the
-// standard library interfaces.
-
-import (
-       "encoding"
-)
-
-// TextMarshaler is a synonym for encoding.TextMarshaler. It is defined here
-// so that Go 1.1 can be supported.
-type TextMarshaler encoding.TextMarshaler
-
-// TextUnmarshaler is a synonym for encoding.TextUnmarshaler. It is defined
-// here so that Go 1.1 can be supported.
-type TextUnmarshaler encoding.TextUnmarshaler
diff --git a/vendor/github.com/BurntSushi/toml/encoding_types_1.1.go b/vendor/github.com/BurntSushi/toml/encoding_types_1.1.go
deleted file mode 100644 (file)
index e8d503d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// +build !go1.2
-
-package toml
-
-// These interfaces were introduced in Go 1.2, so we add them manually when
-// compiling for Go 1.1.
-
-// TextMarshaler is a synonym for encoding.TextMarshaler. It is defined here
-// so that Go 1.1 can be supported.
-type TextMarshaler interface {
-       MarshalText() (text []byte, err error)
-}
-
-// TextUnmarshaler is a synonym for encoding.TextUnmarshaler. It is defined
-// here so that Go 1.1 can be supported.
-type TextUnmarshaler interface {
-       UnmarshalText(text []byte) error
-}
diff --git a/vendor/github.com/BurntSushi/toml/lex.go b/vendor/github.com/BurntSushi/toml/lex.go
deleted file mode 100644 (file)
index e0a742a..0000000
+++ /dev/null
@@ -1,953 +0,0 @@
-package toml
-
-import (
-       "fmt"
-       "strings"
-       "unicode"
-       "unicode/utf8"
-)
-
-type itemType int
-
-const (
-       itemError itemType = iota
-       itemNIL            // used in the parser to indicate no type
-       itemEOF
-       itemText
-       itemString
-       itemRawString
-       itemMultilineString
-       itemRawMultilineString
-       itemBool
-       itemInteger
-       itemFloat
-       itemDatetime
-       itemArray // the start of an array
-       itemArrayEnd
-       itemTableStart
-       itemTableEnd
-       itemArrayTableStart
-       itemArrayTableEnd
-       itemKeyStart
-       itemCommentStart
-       itemInlineTableStart
-       itemInlineTableEnd
-)
-
-const (
-       eof              = 0
-       comma            = ','
-       tableStart       = '['
-       tableEnd         = ']'
-       arrayTableStart  = '['
-       arrayTableEnd    = ']'
-       tableSep         = '.'
-       keySep           = '='
-       arrayStart       = '['
-       arrayEnd         = ']'
-       commentStart     = '#'
-       stringStart      = '"'
-       stringEnd        = '"'
-       rawStringStart   = '\''
-       rawStringEnd     = '\''
-       inlineTableStart = '{'
-       inlineTableEnd   = '}'
-)
-
-type stateFn func(lx *lexer) stateFn
-
-type lexer struct {
-       input string
-       start int
-       pos   int
-       line  int
-       state stateFn
-       items chan item
-
-       // Allow for backing up up to three runes.
-       // This is necessary because TOML contains 3-rune tokens (""" and ''').
-       prevWidths [3]int
-       nprev      int // how many of prevWidths are in use
-       // If we emit an eof, we can still back up, but it is not OK to call
-       // next again.
-       atEOF bool
-
-       // A stack of state functions used to maintain context.
-       // The idea is to reuse parts of the state machine in various places.
-       // For example, values can appear at the top level or within arbitrarily
-       // nested arrays. The last state on the stack is used after a value has
-       // been lexed. Similarly for comments.
-       stack []stateFn
-}
-
-type item struct {
-       typ  itemType
-       val  string
-       line int
-}
-
-func (lx *lexer) nextItem() item {
-       for {
-               select {
-               case item := <-lx.items:
-                       return item
-               default:
-                       lx.state = lx.state(lx)
-               }
-       }
-}
-
-func lex(input string) *lexer {
-       lx := &lexer{
-               input: input,
-               state: lexTop,
-               line:  1,
-               items: make(chan item, 10),
-               stack: make([]stateFn, 0, 10),
-       }
-       return lx
-}
-
-func (lx *lexer) push(state stateFn) {
-       lx.stack = append(lx.stack, state)
-}
-
-func (lx *lexer) pop() stateFn {
-       if len(lx.stack) == 0 {
-               return lx.errorf("BUG in lexer: no states to pop")
-       }
-       last := lx.stack[len(lx.stack)-1]
-       lx.stack = lx.stack[0 : len(lx.stack)-1]
-       return last
-}
-
-func (lx *lexer) current() string {
-       return lx.input[lx.start:lx.pos]
-}
-
-func (lx *lexer) emit(typ itemType) {
-       lx.items <- item{typ, lx.current(), lx.line}
-       lx.start = lx.pos
-}
-
-func (lx *lexer) emitTrim(typ itemType) {
-       lx.items <- item{typ, strings.TrimSpace(lx.current()), lx.line}
-       lx.start = lx.pos
-}
-
-func (lx *lexer) next() (r rune) {
-       if lx.atEOF {
-               panic("next called after EOF")
-       }
-       if lx.pos >= len(lx.input) {
-               lx.atEOF = true
-               return eof
-       }
-
-       if lx.input[lx.pos] == '\n' {
-               lx.line++
-       }
-       lx.prevWidths[2] = lx.prevWidths[1]
-       lx.prevWidths[1] = lx.prevWidths[0]
-       if lx.nprev < 3 {
-               lx.nprev++
-       }
-       r, w := utf8.DecodeRuneInString(lx.input[lx.pos:])
-       lx.prevWidths[0] = w
-       lx.pos += w
-       return r
-}
-
-// ignore skips over the pending input before this point.
-func (lx *lexer) ignore() {
-       lx.start = lx.pos
-}
-
-// backup steps back one rune. Can be called only twice between calls to next.
-func (lx *lexer) backup() {
-       if lx.atEOF {
-               lx.atEOF = false
-               return
-       }
-       if lx.nprev < 1 {
-               panic("backed up too far")
-       }
-       w := lx.prevWidths[0]
-       lx.prevWidths[0] = lx.prevWidths[1]
-       lx.prevWidths[1] = lx.prevWidths[2]
-       lx.nprev--
-       lx.pos -= w
-       if lx.pos < len(lx.input) && lx.input[lx.pos] == '\n' {
-               lx.line--
-       }
-}
-
-// accept consumes the next rune if it's equal to `valid`.
-func (lx *lexer) accept(valid rune) bool {
-       if lx.next() == valid {
-               return true
-       }
-       lx.backup()
-       return false
-}
-
-// peek returns but does not consume the next rune in the input.
-func (lx *lexer) peek() rune {
-       r := lx.next()
-       lx.backup()
-       return r
-}
-
-// skip ignores all input that matches the given predicate.
-func (lx *lexer) skip(pred func(rune) bool) {
-       for {
-               r := lx.next()
-               if pred(r) {
-                       continue
-               }
-               lx.backup()
-               lx.ignore()
-               return
-       }
-}
-
-// errorf stops all lexing by emitting an error and returning `nil`.
-// Note that any value that is a character is escaped if it's a special
-// character (newlines, tabs, etc.).
-func (lx *lexer) errorf(format string, values ...interface{}) stateFn {
-       lx.items <- item{
-               itemError,
-               fmt.Sprintf(format, values...),
-               lx.line,
-       }
-       return nil
-}
-
-// lexTop consumes elements at the top level of TOML data.
-func lexTop(lx *lexer) stateFn {
-       r := lx.next()
-       if isWhitespace(r) || isNL(r) {
-               return lexSkip(lx, lexTop)
-       }
-       switch r {
-       case commentStart:
-               lx.push(lexTop)
-               return lexCommentStart
-       case tableStart:
-               return lexTableStart
-       case eof:
-               if lx.pos > lx.start {
-                       return lx.errorf("unexpected EOF")
-               }
-               lx.emit(itemEOF)
-               return nil
-       }
-
-       // At this point, the only valid item can be a key, so we back up
-       // and let the key lexer do the rest.
-       lx.backup()
-       lx.push(lexTopEnd)
-       return lexKeyStart
-}
-
-// lexTopEnd is entered whenever a top-level item has been consumed. (A value
-// or a table.) It must see only whitespace, and will turn back to lexTop
-// upon a newline. If it sees EOF, it will quit the lexer successfully.
-func lexTopEnd(lx *lexer) stateFn {
-       r := lx.next()
-       switch {
-       case r == commentStart:
-               // a comment will read to a newline for us.
-               lx.push(lexTop)
-               return lexCommentStart
-       case isWhitespace(r):
-               return lexTopEnd
-       case isNL(r):
-               lx.ignore()
-               return lexTop
-       case r == eof:
-               lx.emit(itemEOF)
-               return nil
-       }
-       return lx.errorf("expected a top-level item to end with a newline, "+
-               "comment, or EOF, but got %q instead", r)
-}
-
-// lexTable lexes the beginning of a table. Namely, it makes sure that
-// it starts with a character other than '.' and ']'.
-// It assumes that '[' has already been consumed.
-// It also handles the case that this is an item in an array of tables.
-// e.g., '[[name]]'.
-func lexTableStart(lx *lexer) stateFn {
-       if lx.peek() == arrayTableStart {
-               lx.next()
-               lx.emit(itemArrayTableStart)
-               lx.push(lexArrayTableEnd)
-       } else {
-               lx.emit(itemTableStart)
-               lx.push(lexTableEnd)
-       }
-       return lexTableNameStart
-}
-
-func lexTableEnd(lx *lexer) stateFn {
-       lx.emit(itemTableEnd)
-       return lexTopEnd
-}
-
-func lexArrayTableEnd(lx *lexer) stateFn {
-       if r := lx.next(); r != arrayTableEnd {
-               return lx.errorf("expected end of table array name delimiter %q, "+
-                       "but got %q instead", arrayTableEnd, r)
-       }
-       lx.emit(itemArrayTableEnd)
-       return lexTopEnd
-}
-
-func lexTableNameStart(lx *lexer) stateFn {
-       lx.skip(isWhitespace)
-       switch r := lx.peek(); {
-       case r == tableEnd || r == eof:
-               return lx.errorf("unexpected end of table name " +
-                       "(table names cannot be empty)")
-       case r == tableSep:
-               return lx.errorf("unexpected table separator " +
-                       "(table names cannot be empty)")
-       case r == stringStart || r == rawStringStart:
-               lx.ignore()
-               lx.push(lexTableNameEnd)
-               return lexValue // reuse string lexing
-       default:
-               return lexBareTableName
-       }
-}
-
-// lexBareTableName lexes the name of a table. It assumes that at least one
-// valid character for the table has already been read.
-func lexBareTableName(lx *lexer) stateFn {
-       r := lx.next()
-       if isBareKeyChar(r) {
-               return lexBareTableName
-       }
-       lx.backup()
-       lx.emit(itemText)
-       return lexTableNameEnd
-}
-
-// lexTableNameEnd reads the end of a piece of a table name, optionally
-// consuming whitespace.
-func lexTableNameEnd(lx *lexer) stateFn {
-       lx.skip(isWhitespace)
-       switch r := lx.next(); {
-       case isWhitespace(r):
-               return lexTableNameEnd
-       case r == tableSep:
-               lx.ignore()
-               return lexTableNameStart
-       case r == tableEnd:
-               return lx.pop()
-       default:
-               return lx.errorf("expected '.' or ']' to end table name, "+
-                       "but got %q instead", r)
-       }
-}
-
-// lexKeyStart consumes a key name up until the first non-whitespace character.
-// lexKeyStart will ignore whitespace.
-func lexKeyStart(lx *lexer) stateFn {
-       r := lx.peek()
-       switch {
-       case r == keySep:
-               return lx.errorf("unexpected key separator %q", keySep)
-       case isWhitespace(r) || isNL(r):
-               lx.next()
-               return lexSkip(lx, lexKeyStart)
-       case r == stringStart || r == rawStringStart:
-               lx.ignore()
-               lx.emit(itemKeyStart)
-               lx.push(lexKeyEnd)
-               return lexValue // reuse string lexing
-       default:
-               lx.ignore()
-               lx.emit(itemKeyStart)
-               return lexBareKey
-       }
-}
-
-// lexBareKey consumes the text of a bare key. Assumes that the first character
-// (which is not whitespace) has not yet been consumed.
-func lexBareKey(lx *lexer) stateFn {
-       switch r := lx.next(); {
-       case isBareKeyChar(r):
-               return lexBareKey
-       case isWhitespace(r):
-               lx.backup()
-               lx.emit(itemText)
-               return lexKeyEnd
-       case r == keySep:
-               lx.backup()
-               lx.emit(itemText)
-               return lexKeyEnd
-       default:
-               return lx.errorf("bare keys cannot contain %q", r)
-       }
-}
-
-// lexKeyEnd consumes the end of a key and trims whitespace (up to the key
-// separator).
-func lexKeyEnd(lx *lexer) stateFn {
-       switch r := lx.next(); {
-       case r == keySep:
-               return lexSkip(lx, lexValue)
-       case isWhitespace(r):
-               return lexSkip(lx, lexKeyEnd)
-       default:
-               return lx.errorf("expected key separator %q, but got %q instead",
-                       keySep, r)
-       }
-}
-
-// lexValue starts the consumption of a value anywhere a value is expected.
-// lexValue will ignore whitespace.
-// After a value is lexed, the last state on the next is popped and returned.
-func lexValue(lx *lexer) stateFn {
-       // We allow whitespace to precede a value, but NOT newlines.
-       // In array syntax, the array states are responsible for ignoring newlines.
-       r := lx.next()
-       switch {
-       case isWhitespace(r):
-               return lexSkip(lx, lexValue)
-       case isDigit(r):
-               lx.backup() // avoid an extra state and use the same as above
-               return lexNumberOrDateStart
-       }
-       switch r {
-       case arrayStart:
-               lx.ignore()
-               lx.emit(itemArray)
-               return lexArrayValue
-       case inlineTableStart:
-               lx.ignore()
-               lx.emit(itemInlineTableStart)
-               return lexInlineTableValue
-       case stringStart:
-               if lx.accept(stringStart) {
-                       if lx.accept(stringStart) {
-                               lx.ignore() // Ignore """
-                               return lexMultilineString
-                       }
-                       lx.backup()
-               }
-               lx.ignore() // ignore the '"'
-               return lexString
-       case rawStringStart:
-               if lx.accept(rawStringStart) {
-                       if lx.accept(rawStringStart) {
-                               lx.ignore() // Ignore """
-                               return lexMultilineRawString
-                       }
-                       lx.backup()
-               }
-               lx.ignore() // ignore the "'"
-               return lexRawString
-       case '+', '-':
-               return lexNumberStart
-       case '.': // special error case, be kind to users
-               return lx.errorf("floats must start with a digit, not '.'")
-       }
-       if unicode.IsLetter(r) {
-               // Be permissive here; lexBool will give a nice error if the
-               // user wrote something like
-               //   x = foo
-               // (i.e. not 'true' or 'false' but is something else word-like.)
-               lx.backup()
-               return lexBool
-       }
-       return lx.errorf("expected value but found %q instead", r)
-}
-
-// lexArrayValue consumes one value in an array. It assumes that '[' or ','
-// have already been consumed. All whitespace and newlines are ignored.
-func lexArrayValue(lx *lexer) stateFn {
-       r := lx.next()
-       switch {
-       case isWhitespace(r) || isNL(r):
-               return lexSkip(lx, lexArrayValue)
-       case r == commentStart:
-               lx.push(lexArrayValue)
-               return lexCommentStart
-       case r == comma:
-               return lx.errorf("unexpected comma")
-       case r == arrayEnd:
-               // NOTE(caleb): The spec isn't clear about whether you can have
-               // a trailing comma or not, so we'll allow it.
-               return lexArrayEnd
-       }
-
-       lx.backup()
-       lx.push(lexArrayValueEnd)
-       return lexValue
-}
-
-// lexArrayValueEnd consumes everything between the end of an array value and
-// the next value (or the end of the array): it ignores whitespace and newlines
-// and expects either a ',' or a ']'.
-func lexArrayValueEnd(lx *lexer) stateFn {
-       r := lx.next()
-       switch {
-       case isWhitespace(r) || isNL(r):
-               return lexSkip(lx, lexArrayValueEnd)
-       case r == commentStart:
-               lx.push(lexArrayValueEnd)
-               return lexCommentStart
-       case r == comma:
-               lx.ignore()
-               return lexArrayValue // move on to the next value
-       case r == arrayEnd:
-               return lexArrayEnd
-       }
-       return lx.errorf(
-               "expected a comma or array terminator %q, but got %q instead",
-               arrayEnd, r,
-       )
-}
-
-// lexArrayEnd finishes the lexing of an array.
-// It assumes that a ']' has just been consumed.
-func lexArrayEnd(lx *lexer) stateFn {
-       lx.ignore()
-       lx.emit(itemArrayEnd)
-       return lx.pop()
-}
-
-// lexInlineTableValue consumes one key/value pair in an inline table.
-// It assumes that '{' or ',' have already been consumed. Whitespace is ignored.
-func lexInlineTableValue(lx *lexer) stateFn {
-       r := lx.next()
-       switch {
-       case isWhitespace(r):
-               return lexSkip(lx, lexInlineTableValue)
-       case isNL(r):
-               return lx.errorf("newlines not allowed within inline tables")
-       case r == commentStart:
-               lx.push(lexInlineTableValue)
-               return lexCommentStart
-       case r == comma:
-               return lx.errorf("unexpected comma")
-       case r == inlineTableEnd:
-               return lexInlineTableEnd
-       }
-       lx.backup()
-       lx.push(lexInlineTableValueEnd)
-       return lexKeyStart
-}
-
-// lexInlineTableValueEnd consumes everything between the end of an inline table
-// key/value pair and the next pair (or the end of the table):
-// it ignores whitespace and expects either a ',' or a '}'.
-func lexInlineTableValueEnd(lx *lexer) stateFn {
-       r := lx.next()
-       switch {
-       case isWhitespace(r):
-               return lexSkip(lx, lexInlineTableValueEnd)
-       case isNL(r):
-               return lx.errorf("newlines not allowed within inline tables")
-       case r == commentStart:
-               lx.push(lexInlineTableValueEnd)
-               return lexCommentStart
-       case r == comma:
-               lx.ignore()
-               return lexInlineTableValue
-       case r == inlineTableEnd:
-               return lexInlineTableEnd
-       }
-       return lx.errorf("expected a comma or an inline table terminator %q, "+
-               "but got %q instead", inlineTableEnd, r)
-}
-
-// lexInlineTableEnd finishes the lexing of an inline table.
-// It assumes that a '}' has just been consumed.
-func lexInlineTableEnd(lx *lexer) stateFn {
-       lx.ignore()
-       lx.emit(itemInlineTableEnd)
-       return lx.pop()
-}
-
-// lexString consumes the inner contents of a string. It assumes that the
-// beginning '"' has already been consumed and ignored.
-func lexString(lx *lexer) stateFn {
-       r := lx.next()
-       switch {
-       case r == eof:
-               return lx.errorf("unexpected EOF")
-       case isNL(r):
-               return lx.errorf("strings cannot contain newlines")
-       case r == '\\':
-               lx.push(lexString)
-               return lexStringEscape
-       case r == stringEnd:
-               lx.backup()
-               lx.emit(itemString)
-               lx.next()
-               lx.ignore()
-               return lx.pop()
-       }
-       return lexString
-}
-
-// lexMultilineString consumes the inner contents of a string. It assumes that
-// the beginning '"""' has already been consumed and ignored.
-func lexMultilineString(lx *lexer) stateFn {
-       switch lx.next() {
-       case eof:
-               return lx.errorf("unexpected EOF")
-       case '\\':
-               return lexMultilineStringEscape
-       case stringEnd:
-               if lx.accept(stringEnd) {
-                       if lx.accept(stringEnd) {
-                               lx.backup()
-                               lx.backup()
-                               lx.backup()
-                               lx.emit(itemMultilineString)
-                               lx.next()
-                               lx.next()
-                               lx.next()
-                               lx.ignore()
-                               return lx.pop()
-                       }
-                       lx.backup()
-               }
-       }
-       return lexMultilineString
-}
-
-// lexRawString consumes a raw string. Nothing can be escaped in such a string.
-// It assumes that the beginning "'" has already been consumed and ignored.
-func lexRawString(lx *lexer) stateFn {
-       r := lx.next()
-       switch {
-       case r == eof:
-               return lx.errorf("unexpected EOF")
-       case isNL(r):
-               return lx.errorf("strings cannot contain newlines")
-       case r == rawStringEnd:
-               lx.backup()
-               lx.emit(itemRawString)
-               lx.next()
-               lx.ignore()
-               return lx.pop()
-       }
-       return lexRawString
-}
-
-// lexMultilineRawString consumes a raw string. Nothing can be escaped in such
-// a string. It assumes that the beginning "'''" has already been consumed and
-// ignored.
-func lexMultilineRawString(lx *lexer) stateFn {
-       switch lx.next() {
-       case eof:
-               return lx.errorf("unexpected EOF")
-       case rawStringEnd:
-               if lx.accept(rawStringEnd) {
-                       if lx.accept(rawStringEnd) {
-                               lx.backup()
-                               lx.backup()
-                               lx.backup()
-                               lx.emit(itemRawMultilineString)
-                               lx.next()
-                               lx.next()
-                               lx.next()
-                               lx.ignore()
-                               return lx.pop()
-                       }
-                       lx.backup()
-               }
-       }
-       return lexMultilineRawString
-}
-
-// lexMultilineStringEscape consumes an escaped character. It assumes that the
-// preceding '\\' has already been consumed.
-func lexMultilineStringEscape(lx *lexer) stateFn {
-       // Handle the special case first:
-       if isNL(lx.next()) {
-               return lexMultilineString
-       }
-       lx.backup()
-       lx.push(lexMultilineString)
-       return lexStringEscape(lx)
-}
-
-func lexStringEscape(lx *lexer) stateFn {
-       r := lx.next()
-       switch r {
-       case 'b':
-               fallthrough
-       case 't':
-               fallthrough
-       case 'n':
-               fallthrough
-       case 'f':
-               fallthrough
-       case 'r':
-               fallthrough
-       case '"':
-               fallthrough
-       case '\\':
-               return lx.pop()
-       case 'u':
-               return lexShortUnicodeEscape
-       case 'U':
-               return lexLongUnicodeEscape
-       }
-       return lx.errorf("invalid escape character %q; only the following "+
-               "escape characters are allowed: "+
-               `\b, \t, \n, \f, \r, \", \\, \uXXXX, and \UXXXXXXXX`, r)
-}
-
-func lexShortUnicodeEscape(lx *lexer) stateFn {
-       var r rune
-       for i := 0; i < 4; i++ {
-               r = lx.next()
-               if !isHexadecimal(r) {
-                       return lx.errorf(`expected four hexadecimal digits after '\u', `+
-                               "but got %q instead", lx.current())
-               }
-       }
-       return lx.pop()
-}
-
-func lexLongUnicodeEscape(lx *lexer) stateFn {
-       var r rune
-       for i := 0; i < 8; i++ {
-               r = lx.next()
-               if !isHexadecimal(r) {
-                       return lx.errorf(`expected eight hexadecimal digits after '\U', `+
-                               "but got %q instead", lx.current())
-               }
-       }
-       return lx.pop()
-}
-
-// lexNumberOrDateStart consumes either an integer, a float, or datetime.
-func lexNumberOrDateStart(lx *lexer) stateFn {
-       r := lx.next()
-       if isDigit(r) {
-               return lexNumberOrDate
-       }
-       switch r {
-       case '_':
-               return lexNumber
-       case 'e', 'E':
-               return lexFloat
-       case '.':
-               return lx.errorf("floats must start with a digit, not '.'")
-       }
-       return lx.errorf("expected a digit but got %q", r)
-}
-
-// lexNumberOrDate consumes either an integer, float or datetime.
-func lexNumberOrDate(lx *lexer) stateFn {
-       r := lx.next()
-       if isDigit(r) {
-               return lexNumberOrDate
-       }
-       switch r {
-       case '-':
-               return lexDatetime
-       case '_':
-               return lexNumber
-       case '.', 'e', 'E':
-               return lexFloat
-       }
-
-       lx.backup()
-       lx.emit(itemInteger)
-       return lx.pop()
-}
-
-// lexDatetime consumes a Datetime, to a first approximation.
-// The parser validates that it matches one of the accepted formats.
-func lexDatetime(lx *lexer) stateFn {
-       r := lx.next()
-       if isDigit(r) {
-               return lexDatetime
-       }
-       switch r {
-       case '-', 'T', ':', '.', 'Z', '+':
-               return lexDatetime
-       }
-
-       lx.backup()
-       lx.emit(itemDatetime)
-       return lx.pop()
-}
-
-// lexNumberStart consumes either an integer or a float. It assumes that a sign
-// has already been read, but that *no* digits have been consumed.
-// lexNumberStart will move to the appropriate integer or float states.
-func lexNumberStart(lx *lexer) stateFn {
-       // We MUST see a digit. Even floats have to start with a digit.
-       r := lx.next()
-       if !isDigit(r) {
-               if r == '.' {
-                       return lx.errorf("floats must start with a digit, not '.'")
-               }
-               return lx.errorf("expected a digit but got %q", r)
-       }
-       return lexNumber
-}
-
-// lexNumber consumes an integer or a float after seeing the first digit.
-func lexNumber(lx *lexer) stateFn {
-       r := lx.next()
-       if isDigit(r) {
-               return lexNumber
-       }
-       switch r {
-       case '_':
-               return lexNumber
-       case '.', 'e', 'E':
-               return lexFloat
-       }
-
-       lx.backup()
-       lx.emit(itemInteger)
-       return lx.pop()
-}
-
-// lexFloat consumes the elements of a float. It allows any sequence of
-// float-like characters, so floats emitted by the lexer are only a first
-// approximation and must be validated by the parser.
-func lexFloat(lx *lexer) stateFn {
-       r := lx.next()
-       if isDigit(r) {
-               return lexFloat
-       }
-       switch r {
-       case '_', '.', '-', '+', 'e', 'E':
-               return lexFloat
-       }
-
-       lx.backup()
-       lx.emit(itemFloat)
-       return lx.pop()
-}
-
-// lexBool consumes a bool string: 'true' or 'false.
-func lexBool(lx *lexer) stateFn {
-       var rs []rune
-       for {
-               r := lx.next()
-               if !unicode.IsLetter(r) {
-                       lx.backup()
-                       break
-               }
-               rs = append(rs, r)
-       }
-       s := string(rs)
-       switch s {
-       case "true", "false":
-               lx.emit(itemBool)
-               return lx.pop()
-       }
-       return lx.errorf("expected value but found %q instead", s)
-}
-
-// lexCommentStart begins the lexing of a comment. It will emit
-// itemCommentStart and consume no characters, passing control to lexComment.
-func lexCommentStart(lx *lexer) stateFn {
-       lx.ignore()
-       lx.emit(itemCommentStart)
-       return lexComment
-}
-
-// lexComment lexes an entire comment. It assumes that '#' has been consumed.
-// It will consume *up to* the first newline character, and pass control
-// back to the last state on the stack.
-func lexComment(lx *lexer) stateFn {
-       r := lx.peek()
-       if isNL(r) || r == eof {
-               lx.emit(itemText)
-               return lx.pop()
-       }
-       lx.next()
-       return lexComment
-}
-
-// lexSkip ignores all slurped input and moves on to the next state.
-func lexSkip(lx *lexer, nextState stateFn) stateFn {
-       return func(lx *lexer) stateFn {
-               lx.ignore()
-               return nextState
-       }
-}
-
-// isWhitespace returns true if `r` is a whitespace character according
-// to the spec.
-func isWhitespace(r rune) bool {
-       return r == '\t' || r == ' '
-}
-
-func isNL(r rune) bool {
-       return r == '\n' || r == '\r'
-}
-
-func isDigit(r rune) bool {
-       return r >= '0' && r <= '9'
-}
-
-func isHexadecimal(r rune) bool {
-       return (r >= '0' && r <= '9') ||
-               (r >= 'a' && r <= 'f') ||
-               (r >= 'A' && r <= 'F')
-}
-
-func isBareKeyChar(r rune) bool {
-       return (r >= 'A' && r <= 'Z') ||
-               (r >= 'a' && r <= 'z') ||
-               (r >= '0' && r <= '9') ||
-               r == '_' ||
-               r == '-'
-}
-
-func (itype itemType) String() string {
-       switch itype {
-       case itemError:
-               return "Error"
-       case itemNIL:
-               return "NIL"
-       case itemEOF:
-               return "EOF"
-       case itemText:
-               return "Text"
-       case itemString, itemRawString, itemMultilineString, itemRawMultilineString:
-               return "String"
-       case itemBool:
-               return "Bool"
-       case itemInteger:
-               return "Integer"
-       case itemFloat:
-               return "Float"
-       case itemDatetime:
-               return "DateTime"
-       case itemTableStart:
-               return "TableStart"
-       case itemTableEnd:
-               return "TableEnd"
-       case itemKeyStart:
-               return "KeyStart"
-       case itemArray:
-               return "Array"
-       case itemArrayEnd:
-               return "ArrayEnd"
-       case itemCommentStart:
-               return "CommentStart"
-       }
-       panic(fmt.Sprintf("BUG: Unknown type '%d'.", int(itype)))
-}
-
-func (item item) String() string {
-       return fmt.Sprintf("(%s, %s)", item.typ.String(), item.val)
-}
diff --git a/vendor/github.com/BurntSushi/toml/parse.go b/vendor/github.com/BurntSushi/toml/parse.go
deleted file mode 100644 (file)
index 50869ef..0000000
+++ /dev/null
@@ -1,592 +0,0 @@
-package toml
-
-import (
-       "fmt"
-       "strconv"
-       "strings"
-       "time"
-       "unicode"
-       "unicode/utf8"
-)
-
-type parser struct {
-       mapping map[string]interface{}
-       types   map[string]tomlType
-       lx      *lexer
-
-       // A list of keys in the order that they appear in the TOML data.
-       ordered []Key
-
-       // the full key for the current hash in scope
-       context Key
-
-       // the base key name for everything except hashes
-       currentKey string
-
-       // rough approximation of line number
-       approxLine int
-
-       // A map of 'key.group.names' to whether they were created implicitly.
-       implicits map[string]bool
-}
-
-type parseError string
-
-func (pe parseError) Error() string {
-       return string(pe)
-}
-
-func parse(data string) (p *parser, err error) {
-       defer func() {
-               if r := recover(); r != nil {
-                       var ok bool
-                       if err, ok = r.(parseError); ok {
-                               return
-                       }
-                       panic(r)
-               }
-       }()
-
-       p = &parser{
-               mapping:   make(map[string]interface{}),
-               types:     make(map[string]tomlType),
-               lx:        lex(data),
-               ordered:   make([]Key, 0),
-               implicits: make(map[string]bool),
-       }
-       for {
-               item := p.next()
-               if item.typ == itemEOF {
-                       break
-               }
-               p.topLevel(item)
-       }
-
-       return p, nil
-}
-
-func (p *parser) panicf(format string, v ...interface{}) {
-       msg := fmt.Sprintf("Near line %d (last key parsed '%s'): %s",
-               p.approxLine, p.current(), fmt.Sprintf(format, v...))
-       panic(parseError(msg))
-}
-
-func (p *parser) next() item {
-       it := p.lx.nextItem()
-       if it.typ == itemError {
-               p.panicf("%s", it.val)
-       }
-       return it
-}
-
-func (p *parser) bug(format string, v ...interface{}) {
-       panic(fmt.Sprintf("BUG: "+format+"\n\n", v...))
-}
-
-func (p *parser) expect(typ itemType) item {
-       it := p.next()
-       p.assertEqual(typ, it.typ)
-       return it
-}
-
-func (p *parser) assertEqual(expected, got itemType) {
-       if expected != got {
-               p.bug("Expected '%s' but got '%s'.", expected, got)
-       }
-}
-
-func (p *parser) topLevel(item item) {
-       switch item.typ {
-       case itemCommentStart:
-               p.approxLine = item.line
-               p.expect(itemText)
-       case itemTableStart:
-               kg := p.next()
-               p.approxLine = kg.line
-
-               var key Key
-               for ; kg.typ != itemTableEnd && kg.typ != itemEOF; kg = p.next() {
-                       key = append(key, p.keyString(kg))
-               }
-               p.assertEqual(itemTableEnd, kg.typ)
-
-               p.establishContext(key, false)
-               p.setType("", tomlHash)
-               p.ordered = append(p.ordered, key)
-       case itemArrayTableStart:
-               kg := p.next()
-               p.approxLine = kg.line
-
-               var key Key
-               for ; kg.typ != itemArrayTableEnd && kg.typ != itemEOF; kg = p.next() {
-                       key = append(key, p.keyString(kg))
-               }
-               p.assertEqual(itemArrayTableEnd, kg.typ)
-
-               p.establishContext(key, true)
-               p.setType("", tomlArrayHash)
-               p.ordered = append(p.ordered, key)
-       case itemKeyStart:
-               kname := p.next()
-               p.approxLine = kname.line
-               p.currentKey = p.keyString(kname)
-
-               val, typ := p.value(p.next())
-               p.setValue(p.currentKey, val)
-               p.setType(p.currentKey, typ)
-               p.ordered = append(p.ordered, p.context.add(p.currentKey))
-               p.currentKey = ""
-       default:
-               p.bug("Unexpected type at top level: %s", item.typ)
-       }
-}
-
-// Gets a string for a key (or part of a key in a table name).
-func (p *parser) keyString(it item) string {
-       switch it.typ {
-       case itemText:
-               return it.val
-       case itemString, itemMultilineString,
-               itemRawString, itemRawMultilineString:
-               s, _ := p.value(it)
-               return s.(string)
-       default:
-               p.bug("Unexpected key type: %s", it.typ)
-               panic("unreachable")
-       }
-}
-
-// value translates an expected value from the lexer into a Go value wrapped
-// as an empty interface.
-func (p *parser) value(it item) (interface{}, tomlType) {
-       switch it.typ {
-       case itemString:
-               return p.replaceEscapes(it.val), p.typeOfPrimitive(it)
-       case itemMultilineString:
-               trimmed := stripFirstNewline(stripEscapedWhitespace(it.val))
-               return p.replaceEscapes(trimmed), p.typeOfPrimitive(it)
-       case itemRawString:
-               return it.val, p.typeOfPrimitive(it)
-       case itemRawMultilineString:
-               return stripFirstNewline(it.val), p.typeOfPrimitive(it)
-       case itemBool:
-               switch it.val {
-               case "true":
-                       return true, p.typeOfPrimitive(it)
-               case "false":
-                       return false, p.typeOfPrimitive(it)
-               }
-               p.bug("Expected boolean value, but got '%s'.", it.val)
-       case itemInteger:
-               if !numUnderscoresOK(it.val) {
-                       p.panicf("Invalid integer %q: underscores must be surrounded by digits",
-                               it.val)
-               }
-               val := strings.Replace(it.val, "_", "", -1)
-               num, err := strconv.ParseInt(val, 10, 64)
-               if err != nil {
-                       // Distinguish integer values. Normally, it'd be a bug if the lexer
-                       // provides an invalid integer, but it's possible that the number is
-                       // out of range of valid values (which the lexer cannot determine).
-                       // So mark the former as a bug but the latter as a legitimate user
-                       // error.
-                       if e, ok := err.(*strconv.NumError); ok &&
-                               e.Err == strconv.ErrRange {
-
-                               p.panicf("Integer '%s' is out of the range of 64-bit "+
-                                       "signed integers.", it.val)
-                       } else {
-                               p.bug("Expected integer value, but got '%s'.", it.val)
-                       }
-               }
-               return num, p.typeOfPrimitive(it)
-       case itemFloat:
-               parts := strings.FieldsFunc(it.val, func(r rune) bool {
-                       switch r {
-                       case '.', 'e', 'E':
-                               return true
-                       }
-                       return false
-               })
-               for _, part := range parts {
-                       if !numUnderscoresOK(part) {
-                               p.panicf("Invalid float %q: underscores must be "+
-                                       "surrounded by digits", it.val)
-                       }
-               }
-               if !numPeriodsOK(it.val) {
-                       // As a special case, numbers like '123.' or '1.e2',
-                       // which are valid as far as Go/strconv are concerned,
-                       // must be rejected because TOML says that a fractional
-                       // part consists of '.' followed by 1+ digits.
-                       p.panicf("Invalid float %q: '.' must be followed "+
-                               "by one or more digits", it.val)
-               }
-               val := strings.Replace(it.val, "_", "", -1)
-               num, err := strconv.ParseFloat(val, 64)
-               if err != nil {
-                       if e, ok := err.(*strconv.NumError); ok &&
-                               e.Err == strconv.ErrRange {
-
-                               p.panicf("Float '%s' is out of the range of 64-bit "+
-                                       "IEEE-754 floating-point numbers.", it.val)
-                       } else {
-                               p.panicf("Invalid float value: %q", it.val)
-                       }
-               }
-               return num, p.typeOfPrimitive(it)
-       case itemDatetime:
-               var t time.Time
-               var ok bool
-               var err error
-               for _, format := range []string{
-                       "2006-01-02T15:04:05Z07:00",
-                       "2006-01-02T15:04:05",
-                       "2006-01-02",
-               } {
-                       t, err = time.ParseInLocation(format, it.val, time.Local)
-                       if err == nil {
-                               ok = true
-                               break
-                       }
-               }
-               if !ok {
-                       p.panicf("Invalid TOML Datetime: %q.", it.val)
-               }
-               return t, p.typeOfPrimitive(it)
-       case itemArray:
-               array := make([]interface{}, 0)
-               types := make([]tomlType, 0)
-
-               for it = p.next(); it.typ != itemArrayEnd; it = p.next() {
-                       if it.typ == itemCommentStart {
-                               p.expect(itemText)
-                               continue
-                       }
-
-                       val, typ := p.value(it)
-                       array = append(array, val)
-                       types = append(types, typ)
-               }
-               return array, p.typeOfArray(types)
-       case itemInlineTableStart:
-               var (
-                       hash         = make(map[string]interface{})
-                       outerContext = p.context
-                       outerKey     = p.currentKey
-               )
-
-               p.context = append(p.context, p.currentKey)
-               p.currentKey = ""
-               for it := p.next(); it.typ != itemInlineTableEnd; it = p.next() {
-                       if it.typ != itemKeyStart {
-                               p.bug("Expected key start but instead found %q, around line %d",
-                                       it.val, p.approxLine)
-                       }
-                       if it.typ == itemCommentStart {
-                               p.expect(itemText)
-                               continue
-                       }
-
-                       // retrieve key
-                       k := p.next()
-                       p.approxLine = k.line
-                       kname := p.keyString(k)
-
-                       // retrieve value
-                       p.currentKey = kname
-                       val, typ := p.value(p.next())
-                       // make sure we keep metadata up to date
-                       p.setType(kname, typ)
-                       p.ordered = append(p.ordered, p.context.add(p.currentKey))
-                       hash[kname] = val
-               }
-               p.context = outerContext
-               p.currentKey = outerKey
-               return hash, tomlHash
-       }
-       p.bug("Unexpected value type: %s", it.typ)
-       panic("unreachable")
-}
-
-// numUnderscoresOK checks whether each underscore in s is surrounded by
-// characters that are not underscores.
-func numUnderscoresOK(s string) bool {
-       accept := false
-       for _, r := range s {
-               if r == '_' {
-                       if !accept {
-                               return false
-                       }
-                       accept = false
-                       continue
-               }
-               accept = true
-       }
-       return accept
-}
-
-// numPeriodsOK checks whether every period in s is followed by a digit.
-func numPeriodsOK(s string) bool {
-       period := false
-       for _, r := range s {
-               if period && !isDigit(r) {
-                       return false
-               }
-               period = r == '.'
-       }
-       return !period
-}
-
-// establishContext sets the current context of the parser,
-// where the context is either a hash or an array of hashes. Which one is
-// set depends on the value of the `array` parameter.
-//
-// Establishing the context also makes sure that the key isn't a duplicate, and
-// will create implicit hashes automatically.
-func (p *parser) establishContext(key Key, array bool) {
-       var ok bool
-
-       // Always start at the top level and drill down for our context.
-       hashContext := p.mapping
-       keyContext := make(Key, 0)
-
-       // We only need implicit hashes for key[0:-1]
-       for _, k := range key[0 : len(key)-1] {
-               _, ok = hashContext[k]
-               keyContext = append(keyContext, k)
-
-               // No key? Make an implicit hash and move on.
-               if !ok {
-                       p.addImplicit(keyContext)
-                       hashContext[k] = make(map[string]interface{})
-               }
-
-               // If the hash context is actually an array of tables, then set
-               // the hash context to the last element in that array.
-               //
-               // Otherwise, it better be a table, since this MUST be a key group (by
-               // virtue of it not being the last element in a key).
-               switch t := hashContext[k].(type) {
-               case []map[string]interface{}:
-                       hashContext = t[len(t)-1]
-               case map[string]interface{}:
-                       hashContext = t
-               default:
-                       p.panicf("Key '%s' was already created as a hash.", keyContext)
-               }
-       }
-
-       p.context = keyContext
-       if array {
-               // If this is the first element for this array, then allocate a new
-               // list of tables for it.
-               k := key[len(key)-1]
-               if _, ok := hashContext[k]; !ok {
-                       hashContext[k] = make([]map[string]interface{}, 0, 5)
-               }
-
-               // Add a new table. But make sure the key hasn't already been used
-               // for something else.
-               if hash, ok := hashContext[k].([]map[string]interface{}); ok {
-                       hashContext[k] = append(hash, make(map[string]interface{}))
-               } else {
-                       p.panicf("Key '%s' was already created and cannot be used as "+
-                               "an array.", keyContext)
-               }
-       } else {
-               p.setValue(key[len(key)-1], make(map[string]interface{}))
-       }
-       p.context = append(p.context, key[len(key)-1])
-}
-
-// setValue sets the given key to the given value in the current context.
-// It will make sure that the key hasn't already been defined, account for
-// implicit key groups.
-func (p *parser) setValue(key string, value interface{}) {
-       var tmpHash interface{}
-       var ok bool
-
-       hash := p.mapping
-       keyContext := make(Key, 0)
-       for _, k := range p.context {
-               keyContext = append(keyContext, k)
-               if tmpHash, ok = hash[k]; !ok {
-                       p.bug("Context for key '%s' has not been established.", keyContext)
-               }
-               switch t := tmpHash.(type) {
-               case []map[string]interface{}:
-                       // The context is a table of hashes. Pick the most recent table
-                       // defined as the current hash.
-                       hash = t[len(t)-1]
-               case map[string]interface{}:
-                       hash = t
-               default:
-                       p.bug("Expected hash to have type 'map[string]interface{}', but "+
-                               "it has '%T' instead.", tmpHash)
-               }
-       }
-       keyContext = append(keyContext, key)
-
-       if _, ok := hash[key]; ok {
-               // Typically, if the given key has already been set, then we have
-               // to raise an error since duplicate keys are disallowed. However,
-               // it's possible that a key was previously defined implicitly. In this
-               // case, it is allowed to be redefined concretely. (See the
-               // `tests/valid/implicit-and-explicit-after.toml` test in `toml-test`.)
-               //
-               // But we have to make sure to stop marking it as an implicit. (So that
-               // another redefinition provokes an error.)
-               //
-               // Note that since it has already been defined (as a hash), we don't
-               // want to overwrite it. So our business is done.
-               if p.isImplicit(keyContext) {
-                       p.removeImplicit(keyContext)
-                       return
-               }
-
-               // Otherwise, we have a concrete key trying to override a previous
-               // key, which is *always* wrong.
-               p.panicf("Key '%s' has already been defined.", keyContext)
-       }
-       hash[key] = value
-}
-
-// setType sets the type of a particular value at a given key.
-// It should be called immediately AFTER setValue.
-//
-// Note that if `key` is empty, then the type given will be applied to the
-// current context (which is either a table or an array of tables).
-func (p *parser) setType(key string, typ tomlType) {
-       keyContext := make(Key, 0, len(p.context)+1)
-       for _, k := range p.context {
-               keyContext = append(keyContext, k)
-       }
-       if len(key) > 0 { // allow type setting for hashes
-               keyContext = append(keyContext, key)
-       }
-       p.types[keyContext.String()] = typ
-}
-
-// addImplicit sets the given Key as having been created implicitly.
-func (p *parser) addImplicit(key Key) {
-       p.implicits[key.String()] = true
-}
-
-// removeImplicit stops tagging the given key as having been implicitly
-// created.
-func (p *parser) removeImplicit(key Key) {
-       p.implicits[key.String()] = false
-}
-
-// isImplicit returns true if the key group pointed to by the key was created
-// implicitly.
-func (p *parser) isImplicit(key Key) bool {
-       return p.implicits[key.String()]
-}
-
-// current returns the full key name of the current context.
-func (p *parser) current() string {
-       if len(p.currentKey) == 0 {
-               return p.context.String()
-       }
-       if len(p.context) == 0 {
-               return p.currentKey
-       }
-       return fmt.Sprintf("%s.%s", p.context, p.currentKey)
-}
-
-func stripFirstNewline(s string) string {
-       if len(s) == 0 || s[0] != '\n' {
-               return s
-       }
-       return s[1:]
-}
-
-func stripEscapedWhitespace(s string) string {
-       esc := strings.Split(s, "\\\n")
-       if len(esc) > 1 {
-               for i := 1; i < len(esc); i++ {
-                       esc[i] = strings.TrimLeftFunc(esc[i], unicode.IsSpace)
-               }
-       }
-       return strings.Join(esc, "")
-}
-
-func (p *parser) replaceEscapes(str string) string {
-       var replaced []rune
-       s := []byte(str)
-       r := 0
-       for r < len(s) {
-               if s[r] != '\\' {
-                       c, size := utf8.DecodeRune(s[r:])
-                       r += size
-                       replaced = append(replaced, c)
-                       continue
-               }
-               r += 1
-               if r >= len(s) {
-                       p.bug("Escape sequence at end of string.")
-                       return ""
-               }
-               switch s[r] {
-               default:
-                       p.bug("Expected valid escape code after \\, but got %q.", s[r])
-                       return ""
-               case 'b':
-                       replaced = append(replaced, rune(0x0008))
-                       r += 1
-               case 't':
-                       replaced = append(replaced, rune(0x0009))
-                       r += 1
-               case 'n':
-                       replaced = append(replaced, rune(0x000A))
-                       r += 1
-               case 'f':
-                       replaced = append(replaced, rune(0x000C))
-                       r += 1
-               case 'r':
-                       replaced = append(replaced, rune(0x000D))
-                       r += 1
-               case '"':
-                       replaced = append(replaced, rune(0x0022))
-                       r += 1
-               case '\\':
-                       replaced = append(replaced, rune(0x005C))
-                       r += 1
-               case 'u':
-                       // At this point, we know we have a Unicode escape of the form
-                       // `uXXXX` at [r, r+5). (Because the lexer guarantees this
-                       // for us.)
-                       escaped := p.asciiEscapeToUnicode(s[r+1 : r+5])
-                       replaced = append(replaced, escaped)
-                       r += 5
-               case 'U':
-                       // At this point, we know we have a Unicode escape of the form
-                       // `uXXXX` at [r, r+9). (Because the lexer guarantees this
-                       // for us.)
-                       escaped := p.asciiEscapeToUnicode(s[r+1 : r+9])
-                       replaced = append(replaced, escaped)
-                       r += 9
-               }
-       }
-       return string(replaced)
-}
-
-func (p *parser) asciiEscapeToUnicode(bs []byte) rune {
-       s := string(bs)
-       hex, err := strconv.ParseUint(strings.ToLower(s), 16, 32)
-       if err != nil {
-               p.bug("Could not parse '%s' as a hexadecimal number, but the "+
-                       "lexer claims it's OK: %s", s, err)
-       }
-       if !utf8.ValidRune(rune(hex)) {
-               p.panicf("Escaped character '\\u%s' is not valid UTF-8.", s)
-       }
-       return rune(hex)
-}
-
-func isStringType(ty itemType) bool {
-       return ty == itemString || ty == itemMultilineString ||
-               ty == itemRawString || ty == itemRawMultilineString
-}
diff --git a/vendor/github.com/BurntSushi/toml/session.vim b/vendor/github.com/BurntSushi/toml/session.vim
deleted file mode 100644 (file)
index 562164b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-au BufWritePost *.go silent!make tags > /dev/null 2>&1
diff --git a/vendor/github.com/BurntSushi/toml/type_check.go b/vendor/github.com/BurntSushi/toml/type_check.go
deleted file mode 100644 (file)
index c73f8af..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-package toml
-
-// tomlType represents any Go type that corresponds to a TOML type.
-// While the first draft of the TOML spec has a simplistic type system that
-// probably doesn't need this level of sophistication, we seem to be militating
-// toward adding real composite types.
-type tomlType interface {
-       typeString() string
-}
-
-// typeEqual accepts any two types and returns true if they are equal.
-func typeEqual(t1, t2 tomlType) bool {
-       if t1 == nil || t2 == nil {
-               return false
-       }
-       return t1.typeString() == t2.typeString()
-}
-
-func typeIsHash(t tomlType) bool {
-       return typeEqual(t, tomlHash) || typeEqual(t, tomlArrayHash)
-}
-
-type tomlBaseType string
-
-func (btype tomlBaseType) typeString() string {
-       return string(btype)
-}
-
-func (btype tomlBaseType) String() string {
-       return btype.typeString()
-}
-
-var (
-       tomlInteger   tomlBaseType = "Integer"
-       tomlFloat     tomlBaseType = "Float"
-       tomlDatetime  tomlBaseType = "Datetime"
-       tomlString    tomlBaseType = "String"
-       tomlBool      tomlBaseType = "Bool"
-       tomlArray     tomlBaseType = "Array"
-       tomlHash      tomlBaseType = "Hash"
-       tomlArrayHash tomlBaseType = "ArrayHash"
-)
-
-// typeOfPrimitive returns a tomlType of any primitive value in TOML.
-// Primitive values are: Integer, Float, Datetime, String and Bool.
-//
-// Passing a lexer item other than the following will cause a BUG message
-// to occur: itemString, itemBool, itemInteger, itemFloat, itemDatetime.
-func (p *parser) typeOfPrimitive(lexItem item) tomlType {
-       switch lexItem.typ {
-       case itemInteger:
-               return tomlInteger
-       case itemFloat:
-               return tomlFloat
-       case itemDatetime:
-               return tomlDatetime
-       case itemString:
-               return tomlString
-       case itemMultilineString:
-               return tomlString
-       case itemRawString:
-               return tomlString
-       case itemRawMultilineString:
-               return tomlString
-       case itemBool:
-               return tomlBool
-       }
-       p.bug("Cannot infer primitive type of lex item '%s'.", lexItem)
-       panic("unreachable")
-}
-
-// typeOfArray returns a tomlType for an array given a list of types of its
-// values.
-//
-// In the current spec, if an array is homogeneous, then its type is always
-// "Array". If the array is not homogeneous, an error is generated.
-func (p *parser) typeOfArray(types []tomlType) tomlType {
-       // Empty arrays are cool.
-       if len(types) == 0 {
-               return tomlArray
-       }
-
-       theType := types[0]
-       for _, t := range types[1:] {
-               if !typeEqual(theType, t) {
-                       p.panicf("Array contains values of type '%s' and '%s', but "+
-                               "arrays must be homogeneous.", theType, t)
-               }
-       }
-       return tomlArray
-}
diff --git a/vendor/github.com/BurntSushi/toml/type_fields.go b/vendor/github.com/BurntSushi/toml/type_fields.go
deleted file mode 100644 (file)
index 608997c..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-package toml
-
-// Struct field handling is adapted from code in encoding/json:
-//
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the Go distribution.
-
-import (
-       "reflect"
-       "sort"
-       "sync"
-)
-
-// A field represents a single field found in a struct.
-type field struct {
-       name  string       // the name of the field (`toml` tag included)
-       tag   bool         // whether field has a `toml` tag
-       index []int        // represents the depth of an anonymous field
-       typ   reflect.Type // the type of the field
-}
-
-// byName sorts field by name, breaking ties with depth,
-// then breaking ties with "name came from toml tag", then
-// breaking ties with index sequence.
-type byName []field
-
-func (x byName) Len() int { return len(x) }
-
-func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-
-func (x byName) Less(i, j int) bool {
-       if x[i].name != x[j].name {
-               return x[i].name < x[j].name
-       }
-       if len(x[i].index) != len(x[j].index) {
-               return len(x[i].index) < len(x[j].index)
-       }
-       if x[i].tag != x[j].tag {
-               return x[i].tag
-       }
-       return byIndex(x).Less(i, j)
-}
-
-// byIndex sorts field by index sequence.
-type byIndex []field
-
-func (x byIndex) Len() int { return len(x) }
-
-func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-
-func (x byIndex) Less(i, j int) bool {
-       for k, xik := range x[i].index {
-               if k >= len(x[j].index) {
-                       return false
-               }
-               if xik != x[j].index[k] {
-                       return xik < x[j].index[k]
-               }
-       }
-       return len(x[i].index) < len(x[j].index)
-}
-
-// typeFields returns a list of fields that TOML should recognize for the given
-// type. The algorithm is breadth-first search over the set of structs to
-// include - the top struct and then any reachable anonymous structs.
-func typeFields(t reflect.Type) []field {
-       // Anonymous fields to explore at the current level and the next.
-       current := []field{}
-       next := []field{{typ: t}}
-
-       // Count of queued names for current level and the next.
-       count := map[reflect.Type]int{}
-       nextCount := map[reflect.Type]int{}
-
-       // Types already visited at an earlier level.
-       visited := map[reflect.Type]bool{}
-
-       // Fields found.
-       var fields []field
-
-       for len(next) > 0 {
-               current, next = next, current[:0]
-               count, nextCount = nextCount, map[reflect.Type]int{}
-
-               for _, f := range current {
-                       if visited[f.typ] {
-                               continue
-                       }
-                       visited[f.typ] = true
-
-                       // Scan f.typ for fields to include.
-                       for i := 0; i < f.typ.NumField(); i++ {
-                               sf := f.typ.Field(i)
-                               if sf.PkgPath != "" && !sf.Anonymous { // unexported
-                                       continue
-                               }
-                               opts := getOptions(sf.Tag)
-                               if opts.skip {
-                                       continue
-                               }
-                               index := make([]int, len(f.index)+1)
-                               copy(index, f.index)
-                               index[len(f.index)] = i
-
-                               ft := sf.Type
-                               if ft.Name() == "" && ft.Kind() == reflect.Ptr {
-                                       // Follow pointer.
-                                       ft = ft.Elem()
-                               }
-
-                               // Record found field and index sequence.
-                               if opts.name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
-                                       tagged := opts.name != ""
-                                       name := opts.name
-                                       if name == "" {
-                                               name = sf.Name
-                                       }
-                                       fields = append(fields, field{name, tagged, index, ft})
-                                       if count[f.typ] > 1 {
-                                               // If there were multiple instances, add a second,
-                                               // so that the annihilation code will see a duplicate.
-                                               // It only cares about the distinction between 1 or 2,
-                                               // so don't bother generating any more copies.
-                                               fields = append(fields, fields[len(fields)-1])
-                                       }
-                                       continue
-                               }
-
-                               // Record new anonymous struct to explore in next round.
-                               nextCount[ft]++
-                               if nextCount[ft] == 1 {
-                                       f := field{name: ft.Name(), index: index, typ: ft}
-                                       next = append(next, f)
-                               }
-                       }
-               }
-       }
-
-       sort.Sort(byName(fields))
-
-       // Delete all fields that are hidden by the Go rules for embedded fields,
-       // except that fields with TOML tags are promoted.
-
-       // The fields are sorted in primary order of name, secondary order
-       // of field index length. Loop over names; for each name, delete
-       // hidden fields by choosing the one dominant field that survives.
-       out := fields[:0]
-       for advance, i := 0, 0; i < len(fields); i += advance {
-               // One iteration per name.
-               // Find the sequence of fields with the name of this first field.
-               fi := fields[i]
-               name := fi.name
-               for advance = 1; i+advance < len(fields); advance++ {
-                       fj := fields[i+advance]
-                       if fj.name != name {
-                               break
-                       }
-               }
-               if advance == 1 { // Only one field with this name
-                       out = append(out, fi)
-                       continue
-               }
-               dominant, ok := dominantField(fields[i : i+advance])
-               if ok {
-                       out = append(out, dominant)
-               }
-       }
-
-       fields = out
-       sort.Sort(byIndex(fields))
-
-       return fields
-}
-
-// dominantField looks through the fields, all of which are known to
-// have the same name, to find the single field that dominates the
-// others using Go's embedding rules, modified by the presence of
-// TOML tags. If there are multiple top-level fields, the boolean
-// will be false: This condition is an error in Go and we skip all
-// the fields.
-func dominantField(fields []field) (field, bool) {
-       // The fields are sorted in increasing index-length order. The winner
-       // must therefore be one with the shortest index length. Drop all
-       // longer entries, which is easy: just truncate the slice.
-       length := len(fields[0].index)
-       tagged := -1 // Index of first tagged field.
-       for i, f := range fields {
-               if len(f.index) > length {
-                       fields = fields[:i]
-                       break
-               }
-               if f.tag {
-                       if tagged >= 0 {
-                               // Multiple tagged fields at the same level: conflict.
-                               // Return no field.
-                               return field{}, false
-                       }
-                       tagged = i
-               }
-       }
-       if tagged >= 0 {
-               return fields[tagged], true
-       }
-       // All remaining fields have the same length. If there's more than one,
-       // we have a conflict (two fields named "X" at the same level) and we
-       // return no field.
-       if len(fields) > 1 {
-               return field{}, false
-       }
-       return fields[0], true
-}
-
-var fieldCache struct {
-       sync.RWMutex
-       m map[reflect.Type][]field
-}
-
-// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
-func cachedTypeFields(t reflect.Type) []field {
-       fieldCache.RLock()
-       f := fieldCache.m[t]
-       fieldCache.RUnlock()
-       if f != nil {
-               return f
-       }
-
-       // Compute fields without lock.
-       // Might duplicate effort but won't hold other computations back.
-       f = typeFields(t)
-       if f == nil {
-               f = []field{}
-       }
-
-       fieldCache.Lock()
-       if fieldCache.m == nil {
-               fieldCache.m = map[reflect.Type][]field{}
-       }
-       fieldCache.m[t] = f
-       fieldCache.Unlock()
-       return f
-}
diff --git a/vendor/github.com/couchbase/go-couchbase/.gitignore b/vendor/github.com/couchbase/go-couchbase/.gitignore
new file mode 100644 (file)
index 0000000..eda885c
--- /dev/null
@@ -0,0 +1,14 @@
+#*
+*.6
+*.a
+*~
+*.swp
+/examples/basic/basic
+/hello/hello
+/populate/populate
+/tools/view2go/view2go
+/tools/loadfile/loadfile
+gotags.files
+TAGS
+6.out
+_*
diff --git a/vendor/github.com/couchbase/go-couchbase/.travis.yml b/vendor/github.com/couchbase/go-couchbase/.travis.yml
new file mode 100644 (file)
index 0000000..4ecafb1
--- /dev/null
@@ -0,0 +1,5 @@
+language: go
+install: go get -v -d ./... && go build -v ./...
+script: go test -v ./...
+
+go: 1.1.1
diff --git a/vendor/github.com/couchbase/go-couchbase/LICENSE b/vendor/github.com/couchbase/go-couchbase/LICENSE
new file mode 100644 (file)
index 0000000..0b23ef3
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright (c) 2013  Couchbase, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/couchbase/go-couchbase/README.markdown b/vendor/github.com/couchbase/go-couchbase/README.markdown
new file mode 100644 (file)
index 0000000..bf5fe49
--- /dev/null
@@ -0,0 +1,37 @@
+# A smart client for couchbase in go
+
+This is a *unoffical* version of a Couchbase Golang client. If you are
+looking for the *Offical* Couchbase Golang client please see
+    [CB-go])[https://github.com/couchbaselabs/gocb].
+
+This is an evolving package, but does provide a useful interface to a
+[couchbase](http://www.couchbase.com/) server including all of the
+pool/bucket discovery features, compatible key distribution with other
+clients, and vbucket motion awareness so application can continue to
+operate during rebalances.
+
+It also supports view querying with source node randomization so you
+don't bang on all one node to do all the work.
+
+## Install
+
+    go get github.com/couchbase/go-couchbase
+
+## Example
+
+    c, err := couchbase.Connect("http://dev-couchbase.example.com:8091/")
+    if err != nil {
+       log.Fatalf("Error connecting:  %v", err)
+    }
+
+    pool, err := c.GetPool("default")
+    if err != nil {
+       log.Fatalf("Error getting pool:  %v", err)
+    }
+
+    bucket, err := pool.GetBucket("default")
+    if err != nil {
+       log.Fatalf("Error getting bucket:  %v", err)
+    }
+
+    bucket.Set("someKey", 0, []string{"an", "example", "list"})
diff --git a/vendor/github.com/couchbase/go-couchbase/audit.go b/vendor/github.com/couchbase/go-couchbase/audit.go
new file mode 100644 (file)
index 0000000..3db7d9f
--- /dev/null
@@ -0,0 +1,32 @@
+package couchbase
+
+import ()
+
+// Sample data:
+// {"disabled":["12333", "22244"],"uid":"132492431","auditdEnabled":true,
+//  "disabledUsers":[{"name":"bill","domain":"local"},{"name":"bob","domain":"local"}],
+//  "logPath":"/Users/johanlarson/Library/Application Support/Couchbase/var/lib/couchbase/logs",
+//  "rotateInterval":86400,"rotateSize":20971520}
+type AuditSpec struct {
+       Disabled       []uint32    `json:"disabled"`
+       Uid            string      `json:"uid"`
+       AuditdEnabled  bool        `json:"auditdEnabled`
+       DisabledUsers  []AuditUser `json:"disabledUsers"`
+       LogPath        string      `json:"logPath"`
+       RotateInterval int64       `json:"rotateInterval"`
+       RotateSize     int64       `json:"rotateSize"`
+}
+
+type AuditUser struct {
+       Name   string `json:"name"`
+       Domain string `json:"domain"`
+}
+
+func (c *Client) GetAuditSpec() (*AuditSpec, error) {
+       ret := &AuditSpec{}
+       err := c.parseURLResponse("/settings/audit", ret)
+       if err != nil {
+               return nil, err
+       }
+       return ret, nil
+}
diff --git a/vendor/github.com/couchbase/go-couchbase/client.go b/vendor/github.com/couchbase/go-couchbase/client.go
new file mode 100644 (file)
index 0000000..63d125d
--- /dev/null
@@ -0,0 +1,1513 @@
+/*
+Package couchbase provides a smart client for go.
+
+Usage:
+
+ client, err := couchbase.Connect("http://myserver:8091/")
+ handleError(err)
+ pool, err := client.GetPool("default")
+ handleError(err)
+ bucket, err := pool.GetBucket("MyAwesomeBucket")
+ handleError(err)
+ ...
+
+or a shortcut for the bucket directly
+
+ bucket, err := couchbase.GetBucket("http://myserver:8091/", "default", "default")
+
+in any case, you can specify authentication credentials using
+standard URL userinfo syntax:
+
+ b, err := couchbase.GetBucket("http://bucketname:bucketpass@myserver:8091/",
+         "default", "bucket")
+*/
+package couchbase
+
+import (
+       "encoding/binary"
+       "encoding/json"
+       "errors"
+       "fmt"
+       "io"
+       "runtime"
+       "strconv"
+       "strings"
+       "sync"
+       "time"
+       "unsafe"
+
+       "github.com/couchbase/gomemcached"
+       "github.com/couchbase/gomemcached/client" // package name is 'memcached'
+       "github.com/couchbase/goutils/logging"
+)
+
+// Mutation Token
+type MutationToken struct {
+       VBid  uint16 // vbucket id
+       Guard uint64 // vbuuid
+       Value uint64 // sequence number
+}
+
+// Maximum number of times to retry a chunk of a bulk get on error.
+var MaxBulkRetries = 5000
+var backOffDuration time.Duration = 100 * time.Millisecond
+var MaxBackOffRetries = 25 // exponentail backOff result in over 30sec (25*13*0.1s)
+
+// If this is set to a nonzero duration, Do() and ViewCustom() will log a warning if the call
+// takes longer than that.
+var SlowServerCallWarningThreshold time.Duration
+
+func slowLog(startTime time.Time, format string, args ...interface{}) {
+       if elapsed := time.Now().Sub(startTime); elapsed > SlowServerCallWarningThreshold {
+               pc, _, _, _ := runtime.Caller(2)
+               caller := runtime.FuncForPC(pc).Name()
+               logging.Infof("go-couchbase: "+format+" in "+caller+" took "+elapsed.String(), args...)
+       }
+}
+
+// Return true if error is KEY_ENOENT. Required by cbq-engine
+func IsKeyEExistsError(err error) bool {
+
+       res, ok := err.(*gomemcached.MCResponse)
+       if ok && res.Status == gomemcached.KEY_EEXISTS {
+               return true
+       }
+
+       return false
+}
+
+// Return true if error is KEY_ENOENT. Required by cbq-engine
+func IsKeyNoEntError(err error) bool {
+
+       res, ok := err.(*gomemcached.MCResponse)
+       if ok && res.Status == gomemcached.KEY_ENOENT {
+               return true
+       }
+
+       return false
+}
+
+// Return true if error suggests a bucket refresh is required. Required by cbq-engine
+func IsRefreshRequired(err error) bool {
+
+       res, ok := err.(*gomemcached.MCResponse)
+       if ok && (res.Status == gomemcached.NO_BUCKET || res.Status == gomemcached.NOT_MY_VBUCKET) {
+               return true
+       }
+
+       return false
+}
+
+// Return true if a collection is not known. Required by cbq-engine
+func IsUnknownCollection(err error) bool {
+
+       res, ok := err.(*gomemcached.MCResponse)
+       if ok && (res.Status == gomemcached.UNKNOWN_COLLECTION) {
+               return true
+       }
+
+       return false
+}
+
+// ClientOpCallback is called for each invocation of Do.
+var ClientOpCallback func(opname, k string, start time.Time, err error)
+
+// Do executes a function on a memcached connection to the node owning key "k"
+//
+// Note that this automatically handles transient errors by replaying
+// your function on a "not-my-vbucket" error, so don't assume
+// your command will only be executed only once.
+func (b *Bucket) Do(k string, f func(mc *memcached.Client, vb uint16) error) (err error) {
+       return b.Do2(k, f, true)
+}
+
+func (b *Bucket) Do2(k string, f func(mc *memcached.Client, vb uint16) error, deadline bool) (err error) {
+       if SlowServerCallWarningThreshold > 0 {
+               defer slowLog(time.Now(), "call to Do(%q)", k)
+       }
+
+       vb := b.VBHash(k)
+       maxTries := len(b.Nodes()) * 2
+       for i := 0; i < maxTries; i++ {
+               conn, pool, err := b.getConnectionToVBucket(vb)
+               if err != nil {
+                       if isConnError(err) && backOff(i, maxTries, backOffDuration, true) {
+                               b.Refresh()
+                               continue
+                       }
+                       return err
+               }
+
+               if deadline && DefaultTimeout > 0 {
+                       conn.SetDeadline(getDeadline(noDeadline, DefaultTimeout))
+               } else {
+                       conn.SetDeadline(noDeadline)
+               }
+               err = f(conn, uint16(vb))
+
+               var retry bool
+               discard := isOutOfBoundsError(err)
+
+               // MB-30967 / MB-31001 implement back off for transient errors
+               if resp, ok := err.(*gomemcached.MCResponse); ok {
+                       switch resp.Status {
+                       case gomemcached.NOT_MY_VBUCKET:
+                               b.Refresh()
+                               // MB-28842: in case of NMVB, check if the node is still part of the map
+                               // and ditch the connection if it isn't.
+                               discard = b.checkVBmap(pool.Node())
+                               retry = true
+                       case gomemcached.NOT_SUPPORTED:
+                               discard = true
+                               retry = true
+                       case gomemcached.ENOMEM:
+                               fallthrough
+                       case gomemcached.TMPFAIL:
+                               retry = backOff(i, maxTries, backOffDuration, true)
+                       default:
+                               retry = false
+                       }
+               } else if err != nil && isConnError(err) && backOff(i, maxTries, backOffDuration, true) {
+                       retry = true
+               }
+
+               if discard {
+                       pool.Discard(conn)
+               } else {
+                       pool.Return(conn)
+               }
+
+               if !retry {
+                       return err
+               }
+       }
+
+       return fmt.Errorf("unable to complete action after %v attemps", maxTries)
+}
+
+type GatheredStats struct {
+       Server string
+       Stats  map[string]string
+       Err    error
+}
+
+func getStatsParallel(sn string, b *Bucket, offset int, which string,
+       ch chan<- GatheredStats) {
+       pool := b.getConnPool(offset)
+       var gatheredStats GatheredStats
+
+       conn, err := pool.Get()
+       defer func() {
+               pool.Return(conn)
+               ch <- gatheredStats
+       }()
+
+       if err != nil {
+               gatheredStats = GatheredStats{Server: sn, Err: err}
+       } else {
+               conn.SetDeadline(getDeadline(time.Time{}, DefaultTimeout))
+               sm, err := conn.StatsMap(which)
+               gatheredStats = GatheredStats{Server: sn, Stats: sm, Err: err}
+       }
+}
+
+// GetStats gets a set of stats from all servers.
+//
+// Returns a map of server ID -> map of stat key to map value.
+func (b *Bucket) GetStats(which string) map[string]map[string]string {
+       rv := map[string]map[string]string{}
+       for server, gs := range b.GatherStats(which) {
+               if len(gs.Stats) > 0 {
+                       rv[server] = gs.Stats
+               }
+       }
+       return rv
+}
+
+// GatherStats returns a map of server ID -> GatheredStats from all servers.
+func (b *Bucket) GatherStats(which string) map[string]GatheredStats {
+       vsm := b.VBServerMap()
+       if vsm.ServerList == nil {
+               return nil
+       }
+
+       // Go grab all the things at once.
+       ch := make(chan GatheredStats, len(vsm.ServerList))
+       for i, sn := range vsm.ServerList {
+               go getStatsParallel(sn, b, i, which, ch)
+       }
+
+       // Gather the results
+       rv := map[string]GatheredStats{}
+       for range vsm.ServerList {
+               gs := <-ch
+               rv[gs.Server] = gs
+       }
+       return rv
+}
+
+// Get bucket count through the bucket stats
+func (b *Bucket) GetCount(refresh bool, context ...*memcached.ClientContext) (count int64, err error) {
+       if refresh {
+               b.Refresh()
+       }
+
+       var cnt int64
+       if len(context) > 0 {
+               key := fmt.Sprintf("collections-byid 0x%x", context[0].CollId)
+               resKey := ""
+               for _, gs := range b.GatherStats(key) {
+                       if len(gs.Stats) > 0 {
+
+                               // the key encodes the scope and collection id
+                               // we don't have the scope id, so we have to find it...
+                               if resKey == "" {
+                                       for k, _ := range gs.Stats {
+                                               resKey = strings.TrimRightFunc(k, func(r rune) bool {
+                                                       return r != ':'
+                                               }) + "items"
+                                               break
+                                       }
+                               }
+                               cnt, err = strconv.ParseInt(gs.Stats[resKey], 10, 64)
+                               if err != nil {
+                                       return 0, err
+                               }
+                               count += cnt
+                       } else if gs.Err != nil {
+                               return 0, gs.Err
+                       }
+               }
+       } else {
+               for _, gs := range b.GatherStats("") {
+                       if len(gs.Stats) > 0 {
+                               cnt, err = strconv.ParseInt(gs.Stats["curr_items"], 10, 64)
+                               if err != nil {
+                                       return 0, err
+                               }
+                               count += cnt
+                       } else if gs.Err != nil {
+                               return 0, gs.Err
+                       }
+               }
+       }
+
+       return count, nil
+}
+
+// Get bucket document size through the bucket stats
+func (b *Bucket) GetSize(refresh bool, context ...*memcached.ClientContext) (size int64, err error) {
+
+       if refresh {
+               b.Refresh()
+       }
+
+       var sz int64
+       if len(context) > 0 {
+               key := fmt.Sprintf("collections-byid 0x%x", context[0].CollId)
+               resKey := ""
+               for _, gs := range b.GatherStats(key) {
+                       if len(gs.Stats) > 0 {
+
+                               // the key encodes the scope and collection id
+                               // we don't have the scope id, so we have to find it...
+                               if resKey == "" {
+                                       for k, _ := range gs.Stats {
+                                               resKey = strings.TrimRightFunc(k, func(r rune) bool {
+                                                       return r != ':'
+                                               }) + "disk_size"
+                                               break
+                                       }
+                               }
+                               sz, err = strconv.ParseInt(gs.Stats[resKey], 10, 64)
+                               if err != nil {
+                                       return 0, err
+                               }
+                               size += sz
+                       } else if gs.Err != nil {
+                               return 0, gs.Err
+                       }
+               }
+       } else {
+               for _, gs := range b.GatherStats("") {
+                       if len(gs.Stats) > 0 {
+                               sz, err = strconv.ParseInt(gs.Stats["ep_value_size"], 10, 64)
+                               if err != nil {
+                                       return 0, err
+                               }
+                               size += sz
+                       } else if gs.Err != nil {
+                               return 0, gs.Err
+                       }
+               }
+       }
+
+       return size, nil
+}
+
+func isAuthError(err error) bool {
+       estr := err.Error()
+       return strings.Contains(estr, "Auth failure")
+}
+
+func IsReadTimeOutError(err error) bool {
+       estr := err.Error()
+       return strings.Contains(estr, "read tcp") ||
+               strings.Contains(estr, "i/o timeout")
+}
+
+func isTimeoutError(err error) bool {
+       estr := err.Error()
+       return strings.Contains(estr, "i/o timeout") ||
+               strings.Contains(estr, "connection timed out") ||
+               strings.Contains(estr, "no route to host")
+}
+
+// Errors that are not considered fatal for our fetch loop
+func isConnError(err error) bool {
+       if err == io.EOF {
+               return true
+       }
+       estr := err.Error()
+       return strings.Contains(estr, "broken pipe") ||
+               strings.Contains(estr, "connection reset") ||
+               strings.Contains(estr, "connection refused") ||
+               strings.Contains(estr, "connection pool is closed")
+}
+
+func isOutOfBoundsError(err error) bool {
+       return err != nil && strings.Contains(err.Error(), "Out of Bounds error")
+
+}
+
+func getDeadline(reqDeadline time.Time, duration time.Duration) time.Time {
+       if reqDeadline.IsZero() {
+               if duration > 0 {
+                       return time.Unix(time.Now().Unix(), 0).Add(duration)
+               } else {
+                       return noDeadline
+               }
+       }
+       return reqDeadline
+}
+
+func backOff(attempt, maxAttempts int, duration time.Duration, exponential bool) bool {
+       if attempt < maxAttempts {
+               // 0th attempt return immediately
+               if attempt > 0 {
+                       if exponential {
+                               duration = time.Duration(attempt) * duration
+                       }
+                       time.Sleep(duration)
+               }
+               return true
+       }
+
+       return false
+}
+
+func (b *Bucket) doBulkGet(vb uint16, keys []string, reqDeadline time.Time,
+       ch chan<- map[string]*gomemcached.MCResponse, ech chan<- error, subPaths []string,
+       eStatus *errorStatus, context ...*memcached.ClientContext) {
+       if SlowServerCallWarningThreshold > 0 {
+               defer slowLog(time.Now(), "call to doBulkGet(%d, %d keys)", vb, len(keys))
+       }
+
+       rv := _STRING_MCRESPONSE_POOL.Get()
+       attempts := 0
+       backOffAttempts := 0
+       done := false
+       bname := b.Name
+       for ; attempts < MaxBulkRetries && !done && !eStatus.errStatus; attempts++ {
+
+               if len(b.VBServerMap().VBucketMap) < int(vb) {
+                       //fatal
+                       err := fmt.Errorf("vbmap smaller than requested for %v", bname)
+                       logging.Errorf("go-couchbase: %v vb %d vbmap len %d", err.Error(), vb, len(b.VBServerMap().VBucketMap))
+                       ech <- err
+                       return
+               }
+
+               masterID := b.VBServerMap().VBucketMap[vb][0]
+
+               if masterID < 0 {
+                       // fatal
+                       err := fmt.Errorf("No master node available for %v vb %d", bname, vb)
+                       logging.Errorf("%v", err.Error())
+                       ech <- err
+                       return
+               }
+
+               // This stack frame exists to ensure we can clean up
+               // connection at a reasonable time.
+               err := func() error {
+                       pool := b.getConnPool(masterID)
+                       conn, err := pool.Get()
+                       if err != nil {
+                               if isAuthError(err) || isTimeoutError(err) {
+                                       logging.Errorf("Fatal Error %v : %v", bname, err)
+                                       ech <- err
+                                       return err
+                               } else if isConnError(err) {
+                                       if !backOff(backOffAttempts, MaxBackOffRetries, backOffDuration, true) {
+                                               logging.Errorf("Connection Error %v : %v", bname, err)
+                                               ech <- err
+                                               return err
+                                       }
+                                       b.Refresh()
+                                       backOffAttempts++
+                               }
+                               logging.Infof("Pool Get returned %v: %v", bname, err)
+                               // retry
+                               return nil
+                       }
+
+                       conn.SetDeadline(getDeadline(reqDeadline, DefaultTimeout))
+                       err = conn.GetBulk(vb, keys, rv, subPaths, context...)
+
+                       discard := false
+                       defer func() {
+                               if discard {
+                                       pool.Discard(conn)
+                               } else {
+                                       pool.Return(conn)
+                               }
+                       }()
+
+                       switch err.(type) {
+                       case *gomemcached.MCResponse:
+                               notSMaxTries := len(b.Nodes()) * 2
+                               st := err.(*gomemcached.MCResponse).Status
+                               if st == gomemcached.NOT_MY_VBUCKET || (st == gomemcached.NOT_SUPPORTED && attempts < notSMaxTries) {
+                                       b.Refresh()
+                                       discard = b.checkVBmap(pool.Node())
+                                       return nil // retry
+                               } else if st == gomemcached.EBUSY || st == gomemcached.LOCKED {
+                                       if (attempts % (MaxBulkRetries / 100)) == 0 {
+                                               logging.Infof("Retrying Memcached error (%v) FOR %v(vbid:%d, keys:<ud>%v</ud>)",
+                                                       err.Error(), bname, vb, keys)
+                                       }
+                                       return nil // retry
+                               } else if (st == gomemcached.ENOMEM || st == gomemcached.TMPFAIL) && backOff(backOffAttempts, MaxBackOffRetries, backOffDuration, true) {
+                                       // MB-30967 / MB-31001 use backoff for TMPFAIL too
+                                       backOffAttempts++
+                                       logging.Infof("Retrying Memcached error (%v) FOR %v(vbid:%d, keys:<ud>%v</ud>)",
+                                               err.Error(), bname, vb, keys)
+                                       return nil // retry
+                               }
+                               ech <- err
+                               return err
+                       case error:
+                               if isOutOfBoundsError(err) {
+                                       // We got an out of bound error, retry the operation
+                                       discard = true
+                                       return nil
+                               } else if isConnError(err) && backOff(backOffAttempts, MaxBackOffRetries, backOffDuration, true) {
+                                       backOffAttempts++
+                                       logging.Errorf("Connection Error: %s. Refreshing bucket %v (vbid:%v,keys:<ud>%v</ud>)",
+                                               err.Error(), bname, vb, keys)
+                                       discard = true
+                                       b.Refresh()
+                                       return nil // retry
+                               }
+                               ech <- err
+                               ch <- rv
+                               return err
+                       }
+
+                       done = true
+                       return nil
+               }()
+
+               if err != nil {
+                       return
+               }
+       }
+
+       if attempts >= MaxBulkRetries {
+               err := fmt.Errorf("bulkget exceeded MaxBulkRetries for %v(vbid:%d,keys:<ud>%v</ud>)", bname, vb, keys)
+               logging.Errorf("%v", err.Error())
+               ech <- err
+       }
+
+       ch <- rv
+}
+
+type errorStatus struct {
+       errStatus bool
+}
+
+type vbBulkGet struct {
+       b           *Bucket
+       ch          chan<- map[string]*gomemcached.MCResponse
+       ech         chan<- error
+       k           uint16
+       keys        []string
+       reqDeadline time.Time
+       wg          *sync.WaitGroup
+       subPaths    []string
+       groupError  *errorStatus
+       context     []*memcached.ClientContext
+}
+
+const _NUM_CHANNELS = 5
+
+var _NUM_CHANNEL_WORKERS = (runtime.NumCPU() + 1) / 2
+var DefaultDialTimeout = time.Duration(0)
+var DefaultTimeout = time.Duration(0)
+var noDeadline = time.Time{}
+
+// Buffer 4k requests per worker
+var _VB_BULK_GET_CHANNELS []chan *vbBulkGet
+
+func InitBulkGet() {
+
+       DefaultDialTimeout = 20 * time.Second
+       DefaultTimeout = 120 * time.Second
+
+       memcached.SetDefaultDialTimeout(DefaultDialTimeout)
+
+       _VB_BULK_GET_CHANNELS = make([]chan *vbBulkGet, _NUM_CHANNELS)
+
+       for i := 0; i < _NUM_CHANNELS; i++ {
+               channel := make(chan *vbBulkGet, 16*1024*_NUM_CHANNEL_WORKERS)
+               _VB_BULK_GET_CHANNELS[i] = channel
+
+               for j := 0; j < _NUM_CHANNEL_WORKERS; j++ {
+                       go vbBulkGetWorker(channel)
+               }
+       }
+}
+
+func vbBulkGetWorker(ch chan *vbBulkGet) {
+       defer func() {
+               // Workers cannot panic and die
+               recover()
+               go vbBulkGetWorker(ch)
+       }()
+
+       for vbg := range ch {
+               vbDoBulkGet(vbg)
+       }
+}
+
+func vbDoBulkGet(vbg *vbBulkGet) {
+       defer vbg.wg.Done()
+       defer func() {
+               // Workers cannot panic and die
+               recover()
+       }()
+       vbg.b.doBulkGet(vbg.k, vbg.keys, vbg.reqDeadline, vbg.ch, vbg.ech, vbg.subPaths, vbg.groupError, vbg.context...)
+}
+
+var _ERR_CHAN_FULL = fmt.Errorf("Data request queue full, aborting query.")
+
+func (b *Bucket) processBulkGet(kdm map[uint16][]string, reqDeadline time.Time,
+       ch chan<- map[string]*gomemcached.MCResponse, ech chan<- error, subPaths []string,
+       eStatus *errorStatus, context ...*memcached.ClientContext) {
+
+       defer close(ch)
+       defer close(ech)
+
+       wg := &sync.WaitGroup{}
+
+       for k, keys := range kdm {
+
+               // GetBulk() group has error donot Queue items for this group
+               if eStatus.errStatus {
+                       break
+               }
+
+               vbg := &vbBulkGet{
+                       b:           b,
+                       ch:          ch,
+                       ech:         ech,
+                       k:           k,
+                       keys:        keys,
+                       reqDeadline: reqDeadline,
+                       wg:          wg,
+                       subPaths:    subPaths,
+                       groupError:  eStatus,
+                       context:     context,
+               }
+
+               wg.Add(1)
+
+               // Random int
+               // Right shift to avoid 8-byte alignment, and take low bits
+               c := (uintptr(unsafe.Pointer(vbg)) >> 4) % _NUM_CHANNELS
+
+               select {
+               case _VB_BULK_GET_CHANNELS[c] <- vbg:
+                       // No-op
+               default:
+                       // Buffer full, abandon the bulk get
+                       ech <- _ERR_CHAN_FULL
+                       wg.Add(-1)
+               }
+       }
+
+       // Wait for my vb bulk gets
+       wg.Wait()
+}
+
+type multiError []error
+
+func (m multiError) Error() string {
+       if len(m) == 0 {
+               panic("Error of none")
+       }
+
+       return fmt.Sprintf("{%v errors, starting with %v}", len(m), m[0].Error())
+}
+
+// Convert a stream of errors from ech into a multiError (or nil) and
+// send down eout.
+//
+// At least one send is guaranteed on eout, but two is possible, so
+// buffer the out channel appropriately.
+func errorCollector(ech <-chan error, eout chan<- error, eStatus *errorStatus) {
+       defer func() { eout <- nil }()
+       var errs multiError
+       for e := range ech {
+               if !eStatus.errStatus && !IsKeyNoEntError(e) {
+                       eStatus.errStatus = true
+               }
+
+               errs = append(errs, e)
+       }
+
+       if len(errs) > 0 {
+               eout <- errs
+       }
+}
+
+// Fetches multiple keys concurrently, with []byte values
+//
+// This is a wrapper around GetBulk which converts all values returned
+// by GetBulk from raw memcached responses into []byte slices.
+// Returns one document for duplicate keys
+func (b *Bucket) GetBulkRaw(keys []string, context ...*memcached.ClientContext) (map[string][]byte, error) {
+
+       resp, eout := b.getBulk(keys, noDeadline, nil, context...)
+
+       rv := make(map[string][]byte, len(keys))
+       for k, av := range resp {
+               rv[k] = av.Body
+       }
+
+       b.ReleaseGetBulkPools(resp)
+       return rv, eout
+
+}
+
+// GetBulk fetches multiple keys concurrently.
+//
+// Unlike more convenient GETs, the entire response is returned in the
+// map array for each key.  Keys that were not found will not be included in
+// the map.
+
+func (b *Bucket) GetBulk(keys []string, reqDeadline time.Time, subPaths []string, context ...*memcached.ClientContext) (map[string]*gomemcached.MCResponse, error) {
+       return b.getBulk(keys, reqDeadline, subPaths, context...)
+}
+
+func (b *Bucket) ReleaseGetBulkPools(rv map[string]*gomemcached.MCResponse) {
+       _STRING_MCRESPONSE_POOL.Put(rv)
+}
+
+func (b *Bucket) getBulk(keys []string, reqDeadline time.Time, subPaths []string, context ...*memcached.ClientContext) (map[string]*gomemcached.MCResponse, error) {
+       kdm := _VB_STRING_POOL.Get()
+       defer _VB_STRING_POOL.Put(kdm)
+       for _, k := range keys {
+               if k != "" {
+                       vb := uint16(b.VBHash(k))
+                       a, ok1 := kdm[vb]
+                       if !ok1 {
+                               a = _STRING_POOL.Get()
+                       }
+                       kdm[vb] = append(a, k)
+               }
+       }
+
+       eout := make(chan error, 2)
+       groupErrorStatus := &errorStatus{}
+
+       // processBulkGet will own both of these channels and
+       // guarantee they're closed before it returns.
+       ch := make(chan map[string]*gomemcached.MCResponse)
+       ech := make(chan error)
+
+       go errorCollector(ech, eout, groupErrorStatus)
+       go b.processBulkGet(kdm, reqDeadline, ch, ech, subPaths, groupErrorStatus, context...)
+
+       var rv map[string]*gomemcached.MCResponse
+
+       for m := range ch {
+               if rv == nil {
+                       rv = m
+                       continue
+               }
+
+               for k, v := range m {
+                       rv[k] = v
+               }
+               _STRING_MCRESPONSE_POOL.Put(m)
+       }
+
+       return rv, <-eout
+}
+
+// WriteOptions is the set of option flags availble for the Write
+// method.  They are ORed together to specify the desired request.
+type WriteOptions int
+
+const (
+       // Raw specifies that the value is raw []byte or nil; don't
+       // JSON-encode it.
+       Raw = WriteOptions(1 << iota)
+       // AddOnly indicates an item should only be written if it
+       // doesn't exist, otherwise ErrKeyExists is returned.
+       AddOnly
+       // Persist causes the operation to block until the server
+       // confirms the item is persisted.
+       Persist
+       // Indexable causes the operation to block until it's availble via the index.
+       Indexable
+       // Append indicates the given value should be appended to the
+       // existing value for the given key.
+       Append
+)
+
+var optNames = []struct {
+       opt  WriteOptions
+       name string
+}{
+       {Raw, "raw"},
+       {AddOnly, "addonly"}, {Persist, "persist"},
+       {Indexable, "indexable"}, {Append, "append"},
+}
+
+// String representation of WriteOptions
+func (w WriteOptions) String() string {
+       f := []string{}
+       for _, on := range optNames {
+               if w&on.opt != 0 {
+                       f = append(f, on.name)
+                       w &= ^on.opt
+               }
+       }
+       if len(f) == 0 || w != 0 {
+               f = append(f, fmt.Sprintf("0x%x", int(w)))
+       }
+       return strings.Join(f, "|")
+}
+
+// Error returned from Write with AddOnly flag, when key already exists in the bucket.
+var ErrKeyExists = errors.New("key exists")
+
+// General-purpose value setter.
+//
+// The Set, Add and Delete methods are just wrappers around this.  The
+// interpretation of `v` depends on whether the `Raw` option is
+// given. If it is, v must be a byte array or nil. (A nil value causes
+// a delete.) If `Raw` is not given, `v` will be marshaled as JSON
+// before being written. It must be JSON-marshalable and it must not
+// be nil.
+func (b *Bucket) Write(k string, flags, exp int, v interface{},
+       opt WriteOptions, context ...*memcached.ClientContext) (err error) {
+
+       if ClientOpCallback != nil {
+               defer func(t time.Time) {
+                       ClientOpCallback(fmt.Sprintf("Write(%v)", opt), k, t, err)
+               }(time.Now())
+       }
+
+       var data []byte
+       if opt&Raw == 0 {
+               data, err = json.Marshal(v)
+               if err != nil {
+                       return err
+               }
+       } else if v != nil {
+               data = v.([]byte)
+       }
+
+       var res *gomemcached.MCResponse
+       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
+               if opt&AddOnly != 0 {
+                       res, err = memcached.UnwrapMemcachedError(
+                               mc.Add(vb, k, flags, exp, data, context...))
+                       if err == nil && res.Status != gomemcached.SUCCESS {
+                               if res.Status == gomemcached.KEY_EEXISTS {
+                                       err = ErrKeyExists
+                               } else {
+                                       err = res
+                               }
+                       }
+               } else if opt&Append != 0 {
+                       res, err = mc.Append(vb, k, data, context...)
+               } else if data == nil {
+                       res, err = mc.Del(vb, k, context...)
+               } else {
+                       res, err = mc.Set(vb, k, flags, exp, data, context...)
+               }
+
+               return err
+       })
+
+       if err == nil && (opt&(Persist|Indexable) != 0) {
+               err = b.WaitForPersistence(k, res.Cas, data == nil)
+       }
+
+       return err
+}
+
+func (b *Bucket) WriteWithMT(k string, flags, exp int, v interface{},
+       opt WriteOptions, context ...*memcached.ClientContext) (mt *MutationToken, err error) {
+
+       if ClientOpCallback != nil {
+               defer func(t time.Time) {
+                       ClientOpCallback(fmt.Sprintf("WriteWithMT(%v)", opt), k, t, err)
+               }(time.Now())
+       }
+
+       var data []byte
+       if opt&Raw == 0 {
+               data, err = json.Marshal(v)
+               if err != nil {
+                       return nil, err
+               }
+       } else if v != nil {
+               data = v.([]byte)
+       }
+
+       var res *gomemcached.MCResponse
+       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
+               if opt&AddOnly != 0 {
+                       res, err = memcached.UnwrapMemcachedError(
+                               mc.Add(vb, k, flags, exp, data, context...))
+                       if err == nil && res.Status != gomemcached.SUCCESS {
+                               if res.Status == gomemcached.KEY_EEXISTS {
+                                       err = ErrKeyExists
+                               } else {
+                                       err = res
+                               }
+                       }
+               } else if opt&Append != 0 {
+                       res, err = mc.Append(vb, k, data, context...)
+               } else if data == nil {
+                       res, err = mc.Del(vb, k, context...)
+               } else {
+                       res, err = mc.Set(vb, k, flags, exp, data, context...)
+               }
+
+               if len(res.Extras) >= 16 {
+                       vbuuid := uint64(binary.BigEndian.Uint64(res.Extras[0:8]))
+                       seqNo := uint64(binary.BigEndian.Uint64(res.Extras[8:16]))
+                       mt = &MutationToken{VBid: vb, Guard: vbuuid, Value: seqNo}
+               }
+
+               return err
+       })
+
+       if err == nil && (opt&(Persist|Indexable) != 0) {
+               err = b.WaitForPersistence(k, res.Cas, data == nil)
+       }
+
+       return mt, err
+}
+
+// Set a value in this bucket with Cas and return the new Cas value
+func (b *Bucket) Cas(k string, exp int, cas uint64, v interface{}, context ...*memcached.ClientContext) (uint64, error) {
+       return b.WriteCas(k, 0, exp, cas, v, 0, context...)
+}
+
+// Set a value in this bucket with Cas without json encoding it
+func (b *Bucket) CasRaw(k string, exp int, cas uint64, v interface{}, context ...*memcached.ClientContext) (uint64, error) {
+       return b.WriteCas(k, 0, exp, cas, v, Raw, context...)
+}
+
+func (b *Bucket) WriteCas(k string, flags, exp int, cas uint64, v interface{},
+       opt WriteOptions, context ...*memcached.ClientContext) (newCas uint64, err error) {
+
+       if ClientOpCallback != nil {
+               defer func(t time.Time) {
+                       ClientOpCallback(fmt.Sprintf("Write(%v)", opt), k, t, err)
+               }(time.Now())
+       }
+
+       var data []byte
+       if opt&Raw == 0 {
+               data, err = json.Marshal(v)
+               if err != nil {
+                       return 0, err
+               }
+       } else if v != nil {
+               data = v.([]byte)
+       }
+
+       var res *gomemcached.MCResponse
+       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
+               res, err = mc.SetCas(vb, k, flags, exp, cas, data, context...)
+               return err
+       })
+
+       if err == nil && (opt&(Persist|Indexable) != 0) {
+               err = b.WaitForPersistence(k, res.Cas, data == nil)
+       }
+
+       return res.Cas, err
+}
+
+// Extended CAS operation. These functions will return the mutation token, i.e vbuuid & guard
+func (b *Bucket) CasWithMeta(k string, flags int, exp int, cas uint64, v interface{}, context ...*memcached.ClientContext) (uint64, *MutationToken, error) {
+       return b.WriteCasWithMT(k, flags, exp, cas, v, 0, context...)
+}
+
+func (b *Bucket) CasWithMetaRaw(k string, flags int, exp int, cas uint64, v interface{}, context ...*memcached.ClientContext) (uint64, *MutationToken, error) {
+       return b.WriteCasWithMT(k, flags, exp, cas, v, Raw, context...)
+}
+
+func (b *Bucket) WriteCasWithMT(k string, flags, exp int, cas uint64, v interface{},
+       opt WriteOptions, context ...*memcached.ClientContext) (newCas uint64, mt *MutationToken, err error) {
+
+       if ClientOpCallback != nil {
+               defer func(t time.Time) {
+                       ClientOpCallback(fmt.Sprintf("Write(%v)", opt), k, t, err)
+               }(time.Now())
+       }
+
+       var data []byte
+       if opt&Raw == 0 {
+               data, err = json.Marshal(v)
+               if err != nil {
+                       return 0, nil, err
+               }
+       } else if v != nil {
+               data = v.([]byte)
+       }
+
+       var res *gomemcached.MCResponse
+       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
+               res, err = mc.SetCas(vb, k, flags, exp, cas, data, context...)
+               return err
+       })
+
+       if err != nil {
+               return 0, nil, err
+       }
+
+       // check for extras
+       if len(res.Extras) >= 16 {
+               vbuuid := uint64(binary.BigEndian.Uint64(res.Extras[0:8]))
+               seqNo := uint64(binary.BigEndian.Uint64(res.Extras[8:16]))
+               vb := b.VBHash(k)
+               mt = &MutationToken{VBid: uint16(vb), Guard: vbuuid, Value: seqNo}
+       }
+
+       if err == nil && (opt&(Persist|Indexable) != 0) {
+               err = b.WaitForPersistence(k, res.Cas, data == nil)
+       }
+
+       return res.Cas, mt, err
+}
+
+// Set a value in this bucket.
+// The value will be serialized into a JSON document.
+func (b *Bucket) Set(k string, exp int, v interface{}, context ...*memcached.ClientContext) error {
+       return b.Write(k, 0, exp, v, 0, context...)
+}
+
+// Set a value in this bucket with with flags
+func (b *Bucket) SetWithMeta(k string, flags int, exp int, v interface{}, context ...*memcached.ClientContext) (*MutationToken, error) {
+       return b.WriteWithMT(k, flags, exp, v, 0, context...)
+}
+
+// SetRaw sets a value in this bucket without JSON encoding it.
+func (b *Bucket) SetRaw(k string, exp int, v []byte, context ...*memcached.ClientContext) error {
+       return b.Write(k, 0, exp, v, Raw, context...)
+}
+
+// Add adds a value to this bucket; like Set except that nothing
+// happens if the key exists.  The value will be serialized into a
+// JSON document.
+func (b *Bucket) Add(k string, exp int, v interface{}, context ...*memcached.ClientContext) (added bool, err error) {
+       err = b.Write(k, 0, exp, v, AddOnly, context...)
+       if err == ErrKeyExists {
+               return false, nil
+       }
+       return (err == nil), err
+}
+
+// AddRaw adds a value to this bucket; like SetRaw except that nothing
+// happens if the key exists.  The value will be stored as raw bytes.
+func (b *Bucket) AddRaw(k string, exp int, v []byte, context ...*memcached.ClientContext) (added bool, err error) {
+       err = b.Write(k, 0, exp, v, AddOnly|Raw, context...)
+       if err == ErrKeyExists {
+               return false, nil
+       }
+       return (err == nil), err
+}
+
+// Add adds a value to this bucket; like Set except that nothing
+// happens if the key exists.  The value will be serialized into a
+// JSON document.
+func (b *Bucket) AddWithMT(k string, exp int, v interface{}, context ...*memcached.ClientContext) (added bool, mt *MutationToken, err error) {
+       mt, err = b.WriteWithMT(k, 0, exp, v, AddOnly, context...)
+       if err == ErrKeyExists {
+               return false, mt, nil
+       }
+       return (err == nil), mt, err
+}
+
+// AddRaw adds a value to this bucket; like SetRaw except that nothing
+// happens if the key exists.  The value will be stored as raw bytes.
+func (b *Bucket) AddRawWithMT(k string, exp int, v []byte, context ...*memcached.ClientContext) (added bool, mt *MutationToken, err error) {
+       mt, err = b.WriteWithMT(k, 0, exp, v, AddOnly|Raw, context...)
+       if err == ErrKeyExists {
+               return false, mt, nil
+       }
+       return (err == nil), mt, err
+}
+
+// Append appends raw data to an existing item.
+func (b *Bucket) Append(k string, data []byte, context ...*memcached.ClientContext) error {
+       return b.Write(k, 0, 0, data, Append|Raw, context...)
+}
+
+// Returns collectionUid, manifestUid, error.
+func (b *Bucket) GetCollectionCID(scope string, collection string, reqDeadline time.Time) (uint32, uint32, error) {
+       var err error
+       var response *gomemcached.MCResponse
+
+       if ClientOpCallback != nil {
+               defer func(t time.Time) { ClientOpCallback("GetCollectionCID", scope+"."+collection, t, err) }(time.Now())
+       }
+
+       var key = "DUMMY" // Contact any server.
+       var manifestUid uint32
+       var collUid uint32
+       err = b.Do2(key, func(mc *memcached.Client, vb uint16) error {
+               var err1 error
+
+               mc.SetDeadline(getDeadline(reqDeadline, DefaultTimeout))
+               _, err1 = mc.SelectBucket(b.Name)
+               if err1 != nil {
+                       return err1
+               }
+
+               response, err1 = mc.CollectionsGetCID(scope, collection)
+               if err1 != nil {
+                       return err1
+               }
+
+               manifestUid = binary.BigEndian.Uint32(response.Extras[4:8])
+               collUid = binary.BigEndian.Uint32(response.Extras[8:12])
+
+               return nil
+       }, false)
+
+       return collUid, manifestUid, err
+}
+
+// Get a value straight from Memcached
+func (b *Bucket) GetsMC(key string, reqDeadline time.Time, context ...*memcached.ClientContext) (*gomemcached.MCResponse, error) {
+       var err error
+       var response *gomemcached.MCResponse
+
+       if key == "" {
+               return nil, nil
+       }
+
+       if ClientOpCallback != nil {
+               defer func(t time.Time) { ClientOpCallback("GetsMC", key, t, err) }(time.Now())
+       }
+
+       err = b.Do2(key, func(mc *memcached.Client, vb uint16) error {
+               var err1 error
+
+               mc.SetDeadline(getDeadline(reqDeadline, DefaultTimeout))
+               response, err1 = mc.Get(vb, key, context...)
+               if err1 != nil {
+                       return err1
+               }
+               return nil
+       }, false)
+       return response, err
+}
+
+// Get a value through the subdoc API
+func (b *Bucket) GetsSubDoc(key string, reqDeadline time.Time, subPaths []string, context ...*memcached.ClientContext) (*gomemcached.MCResponse, error) {
+       var err error
+       var response *gomemcached.MCResponse
+
+       if key == "" {
+               return nil, nil
+       }
+
+       if ClientOpCallback != nil {
+               defer func(t time.Time) { ClientOpCallback("GetsSubDoc", key, t, err) }(time.Now())
+       }
+
+       err = b.Do2(key, func(mc *memcached.Client, vb uint16) error {
+               var err1 error
+
+               mc.SetDeadline(getDeadline(reqDeadline, DefaultTimeout))
+               response, err1 = mc.GetSubdoc(vb, key, subPaths, context...)
+               if err1 != nil {
+                       return err1
+               }
+               return nil
+       }, false)
+       return response, err
+}
+
+// GetsRaw gets a raw value from this bucket including its CAS
+// counter and flags.
+func (b *Bucket) GetsRaw(k string, context ...*memcached.ClientContext) (data []byte, flags int,
+       cas uint64, err error) {
+
+       if ClientOpCallback != nil {
+               defer func(t time.Time) { ClientOpCallback("GetsRaw", k, t, err) }(time.Now())
+       }
+
+       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
+               res, err := mc.Get(vb, k, context...)
+               if err != nil {
+                       return err
+               }
+               cas = res.Cas
+               if len(res.Extras) >= 4 {
+                       flags = int(binary.BigEndian.Uint32(res.Extras))
+               }
+               data = res.Body
+               return nil
+       })
+       return
+}
+
+// Gets gets a value from this bucket, including its CAS counter.  The
+// value is expected to be a JSON stream and will be deserialized into
+// rv.
+func (b *Bucket) Gets(k string, rv interface{}, caso *uint64, context ...*memcached.ClientContext) error {
+       data, _, cas, err := b.GetsRaw(k, context...)
+       if err != nil {
+               return err
+       }
+       if caso != nil {
+               *caso = cas
+       }
+       return json.Unmarshal(data, rv)
+}
+
+// Get a value from this bucket.
+// The value is expected to be a JSON stream and will be deserialized
+// into rv.
+func (b *Bucket) Get(k string, rv interface{}, context ...*memcached.ClientContext) error {
+       return b.Gets(k, rv, nil, context...)
+}
+
+// GetRaw gets a raw value from this bucket.  No marshaling is performed.
+func (b *Bucket) GetRaw(k string, context ...*memcached.ClientContext) ([]byte, error) {
+       d, _, _, err := b.GetsRaw(k, context...)
+       return d, err
+}
+
+// GetAndTouchRaw gets a raw value from this bucket including its CAS
+// counter and flags, and updates the expiry on the doc.
+func (b *Bucket) GetAndTouchRaw(k string, exp int, context ...*memcached.ClientContext) (data []byte,
+       cas uint64, err error) {
+
+       if ClientOpCallback != nil {
+               defer func(t time.Time) { ClientOpCallback("GetsRaw", k, t, err) }(time.Now())
+       }
+
+       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
+               res, err := mc.GetAndTouch(vb, k, exp, context...)
+               if err != nil {
+                       return err
+               }
+               cas = res.Cas
+               data = res.Body
+               return nil
+       })
+       return data, cas, err
+}
+
+// GetMeta returns the meta values for a key
+func (b *Bucket) GetMeta(k string, flags *int, expiry *int, cas *uint64, seqNo *uint64, context ...*memcached.ClientContext) (err error) {
+
+       if ClientOpCallback != nil {
+               defer func(t time.Time) { ClientOpCallback("GetsMeta", k, t, err) }(time.Now())
+       }
+
+       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
+               res, err := mc.GetMeta(vb, k, context...)
+               if err != nil {
+                       return err
+               }
+
+               *cas = res.Cas
+               if len(res.Extras) >= 8 {
+                       *flags = int(binary.BigEndian.Uint32(res.Extras[4:]))
+               }
+
+               if len(res.Extras) >= 12 {
+                       *expiry = int(binary.BigEndian.Uint32(res.Extras[8:]))
+               }
+
+               if len(res.Extras) >= 20 {
+                       *seqNo = uint64(binary.BigEndian.Uint64(res.Extras[12:]))
+               }
+
+               return nil
+       })
+
+       return err
+}
+
+// Delete a key from this bucket.
+func (b *Bucket) Delete(k string, context ...*memcached.ClientContext) error {
+       return b.Write(k, 0, 0, nil, Raw, context...)
+}
+
+// Incr increments the value at a given key by amt and defaults to def if no value present.
+func (b *Bucket) Incr(k string, amt, def uint64, exp int, context ...*memcached.ClientContext) (val uint64, err error) {
+       if ClientOpCallback != nil {
+               defer func(t time.Time) { ClientOpCallback("Incr", k, t, err) }(time.Now())
+       }
+
+       var rv uint64
+       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
+               res, err := mc.Incr(vb, k, amt, def, exp, context...)
+               if err != nil {
+                       return err
+               }
+               rv = res
+               return nil
+       })
+       return rv, err
+}
+
+// Decr decrements the value at a given key by amt and defaults to def if no value present
+func (b *Bucket) Decr(k string, amt, def uint64, exp int, context ...*memcached.ClientContext) (val uint64, err error) {
+       if ClientOpCallback != nil {
+               defer func(t time.Time) { ClientOpCallback("Decr", k, t, err) }(time.Now())
+       }
+
+       var rv uint64
+       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
+               res, err := mc.Decr(vb, k, amt, def, exp, context...)
+               if err != nil {
+                       return err
+               }
+               rv = res
+               return nil
+       })
+       return rv, err
+}
+
+// Wrapper around memcached.CASNext()
+func (b *Bucket) casNext(k string, exp int, state *memcached.CASState) bool {
+       if ClientOpCallback != nil {
+               defer func(t time.Time) {
+                       ClientOpCallback("casNext", k, t, state.Err)
+               }(time.Now())
+       }
+
+       keepGoing := false
+       state.Err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
+               keepGoing = mc.CASNext(vb, k, exp, state)
+               return state.Err
+       })
+       return keepGoing && state.Err == nil
+}
+
+// An UpdateFunc is a callback function to update a document
+type UpdateFunc func(current []byte) (updated []byte, err error)
+
+// Return this as the error from an UpdateFunc to cancel the Update
+// operation.
+const UpdateCancel = memcached.CASQuit
+
+// Update performs a Safe update of a document, avoiding conflicts by
+// using CAS.
+//
+// The callback function will be invoked with the current raw document
+// contents (or nil if the document doesn't exist); it should return
+// the updated raw contents (or nil to delete.)  If it decides not to
+// change anything it can return UpdateCancel as the error.
+//
+// If another writer modifies the document between the get and the
+// set, the callback will be invoked again with the newer value.
+func (b *Bucket) Update(k string, exp int, callback UpdateFunc) error {
+       _, err := b.update(k, exp, callback)
+       return err
+}
+
+// internal version of Update that returns a CAS value
+func (b *Bucket) update(k string, exp int, callback UpdateFunc) (newCas uint64, err error) {
+       var state memcached.CASState
+       for b.casNext(k, exp, &state) {
+               var err error
+               if state.Value, err = callback(state.Value); err != nil {
+                       return 0, err
+               }
+       }
+       return state.Cas, state.Err
+}
+
+// A WriteUpdateFunc is a callback function to update a document
+type WriteUpdateFunc func(current []byte) (updated []byte, opt WriteOptions, err error)
+
+// WriteUpdate performs a Safe update of a document, avoiding
+// conflicts by using CAS.  WriteUpdate is like Update, except that
+// the callback can return a set of WriteOptions, of which Persist and
+// Indexable are recognized: these cause the call to wait until the
+// document update has been persisted to disk and/or become available
+// to index.
+func (b *Bucket) WriteUpdate(k string, exp int, callback WriteUpdateFunc) error {
+       var writeOpts WriteOptions
+       var deletion bool
+       // Wrap the callback in an UpdateFunc we can pass to Update:
+       updateCallback := func(current []byte) (updated []byte, err error) {
+               update, opt, err := callback(current)
+               writeOpts = opt
+               deletion = (update == nil)
+               return update, err
+       }
+       cas, err := b.update(k, exp, updateCallback)
+       if err != nil {
+               return err
+       }
+       // If callback asked, wait for persistence or indexability:
+       if writeOpts&(Persist|Indexable) != 0 {
+               err = b.WaitForPersistence(k, cas, deletion)
+       }
+       return err
+}
+
+// Observe observes the current state of a document.
+func (b *Bucket) Observe(k string) (result memcached.ObserveResult, err error) {
+       if ClientOpCallback != nil {
+               defer func(t time.Time) { ClientOpCallback("Observe", k, t, err) }(time.Now())
+       }
+
+       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
+               result, err = mc.Observe(vb, k)
+               return err
+       })
+       return
+}
+
+// Returned from WaitForPersistence (or Write, if the Persistent or Indexable flag is used)
+// if the value has been overwritten by another before being persisted.
+var ErrOverwritten = errors.New("overwritten")
+
+// Returned from WaitForPersistence (or Write, if the Persistent or Indexable flag is used)
+// if the value hasn't been persisted by the timeout interval
+var ErrTimeout = errors.New("timeout")
+
+// WaitForPersistence waits for an item to be considered durable.
+//
+// Besides transport errors, ErrOverwritten may be returned if the
+// item is overwritten before it reaches durability.  ErrTimeout may
+// occur if the item isn't found durable in a reasonable amount of
+// time.
+func (b *Bucket) WaitForPersistence(k string, cas uint64, deletion bool) error {
+       timeout := 10 * time.Second
+       sleepDelay := 5 * time.Millisecond
+       start := time.Now()
+       for {
+               time.Sleep(sleepDelay)
+               sleepDelay += sleepDelay / 2 // multiply delay by 1.5 every time
+
+               result, err := b.Observe(k)
+               if err != nil {
+                       return err
+               }
+               if persisted, overwritten := result.CheckPersistence(cas, deletion); overwritten {
+                       return ErrOverwritten
+               } else if persisted {
+                       return nil
+               }
+
+               if result.PersistenceTime > 0 {
+                       timeout = 2 * result.PersistenceTime
+               }
+               if time.Since(start) >= timeout-sleepDelay {
+                       return ErrTimeout
+               }
+       }
+}
+
+var _STRING_MCRESPONSE_POOL = gomemcached.NewStringMCResponsePool(16)
+
+type stringPool struct {
+       pool *sync.Pool
+       size int
+}
+
+func newStringPool(size int) *stringPool {
+       rv := &stringPool{
+               pool: &sync.Pool{
+                       New: func() interface{} {
+                               return make([]string, 0, size)
+                       },
+               },
+               size: size,
+       }
+
+       return rv
+}
+
+func (this *stringPool) Get() []string {
+       return this.pool.Get().([]string)
+}
+
+func (this *stringPool) Put(s []string) {
+       if s == nil || cap(s) < this.size || cap(s) > 2*this.size {
+               return
+       }
+
+       this.pool.Put(s[0:0])
+}
+
+var _STRING_POOL = newStringPool(16)
+
+type vbStringPool struct {
+       pool    *sync.Pool
+       strPool *stringPool
+}
+
+func newVBStringPool(size int, sp *stringPool) *vbStringPool {
+       rv := &vbStringPool{
+               pool: &sync.Pool{
+                       New: func() interface{} {
+                               return make(map[uint16][]string, size)
+                       },
+               },
+               strPool: sp,
+       }
+
+       return rv
+}
+
+func (this *vbStringPool) Get() map[uint16][]string {
+       return this.pool.Get().(map[uint16][]string)
+}
+
+func (this *vbStringPool) Put(s map[uint16][]string) {
+       if s == nil {
+               return
+       }
+
+       for k, v := range s {
+               delete(s, k)
+               this.strPool.Put(v)
+       }
+
+       this.pool.Put(s)
+}
+
+var _VB_STRING_POOL = newVBStringPool(16, _STRING_POOL)
diff --git a/vendor/github.com/couchbase/go-couchbase/conn_pool.go b/vendor/github.com/couchbase/go-couchbase/conn_pool.go
new file mode 100644 (file)
index 0000000..47854c0
--- /dev/null
@@ -0,0 +1,421 @@
+package couchbase
+
+import (
+       "crypto/tls"
+       "errors"
+       "sync/atomic"
+       "time"
+
+       "github.com/couchbase/gomemcached"
+       "github.com/couchbase/gomemcached/client"
+       "github.com/couchbase/goutils/logging"
+)
+
+// GenericMcdAuthHandler is a kind of AuthHandler that performs
+// special auth exchange (like non-standard auth, possibly followed by
+// select-bucket).
+type GenericMcdAuthHandler interface {
+       AuthHandler
+       AuthenticateMemcachedConn(host string, conn *memcached.Client) error
+}
+
+// Error raised when a connection can't be retrieved from a pool.
+var TimeoutError = errors.New("timeout waiting to build connection")
+var errClosedPool = errors.New("the connection pool is closed")
+var errNoPool = errors.New("no connection pool")
+
+// Default timeout for retrieving a connection from the pool.
+var ConnPoolTimeout = time.Hour * 24 * 30
+
+// overflow connection closer cycle time
+var ConnCloserInterval = time.Second * 30
+
+// ConnPoolAvailWaitTime is the amount of time to wait for an existing
+// connection from the pool before considering the creation of a new
+// one.
+var ConnPoolAvailWaitTime = time.Millisecond
+
+type connectionPool struct {
+       host        string
+       mkConn      func(host string, ah AuthHandler, tlsConfig *tls.Config, bucketName string) (*memcached.Client, error)
+       auth        AuthHandler
+       connections chan *memcached.Client
+       createsem   chan bool
+       bailOut     chan bool
+       poolSize    int
+       connCount   uint64
+       inUse       bool
+       encrypted   bool
+       tlsConfig   *tls.Config
+       bucket      string
+}
+
+func newConnectionPool(host string, ah AuthHandler, closer bool, poolSize, poolOverflow int, tlsConfig *tls.Config, bucket string, encrypted bool) *connectionPool {
+       connSize := poolSize
+       if closer {
+               connSize += poolOverflow
+       }
+       rv := &connectionPool{
+               host:        host,
+               connections: make(chan *memcached.Client, connSize),
+               createsem:   make(chan bool, poolSize+poolOverflow),
+               mkConn:      defaultMkConn,
+               auth:        ah,
+               poolSize:    poolSize,
+               bucket:      bucket,
+               encrypted:   encrypted,
+       }
+
+       if encrypted {
+               rv.tlsConfig = tlsConfig
+       }
+
+       if closer {
+               rv.bailOut = make(chan bool, 1)
+               go rv.connCloser()
+       }
+       return rv
+}
+
+// ConnPoolTimeout is notified whenever connections are acquired from a pool.
+var ConnPoolCallback func(host string, source string, start time.Time, err error)
+
+// Use regular in-the-clear connection if tlsConfig is nil.
+// Use secure connection (TLS) if tlsConfig is set.
+func defaultMkConn(host string, ah AuthHandler, tlsConfig *tls.Config, bucketName string) (*memcached.Client, error) {
+       var features memcached.Features
+
+       var conn *memcached.Client
+       var err error
+       if tlsConfig == nil {
+               conn, err = memcached.Connect("tcp", host)
+       } else {
+               conn, err = memcached.ConnectTLS("tcp", host, tlsConfig)
+       }
+
+       if err != nil {
+               return nil, err
+       }
+
+       if DefaultTimeout > 0 {
+               conn.SetDeadline(getDeadline(noDeadline, DefaultTimeout))
+       }
+
+       if TCPKeepalive == true {
+               conn.SetKeepAliveOptions(time.Duration(TCPKeepaliveInterval) * time.Second)
+       }
+
+       if EnableMutationToken == true {
+               features = append(features, memcached.FeatureMutationToken)
+       }
+       if EnableDataType == true {
+               features = append(features, memcached.FeatureDataType)
+       }
+
+       if EnableXattr == true {
+               features = append(features, memcached.FeatureXattr)
+       }
+
+       if EnableCollections {
+               features = append(features, memcached.FeatureCollections)
+       }
+
+       if len(features) > 0 {
+               res, err := conn.EnableFeatures(features)
+               if err != nil && isTimeoutError(err) {
+                       conn.Close()
+                       return nil, err
+               }
+
+               if err != nil || res.Status != gomemcached.SUCCESS {
+                       logging.Warnf("Unable to enable features %v", err)
+               }
+       }
+
+       if gah, ok := ah.(GenericMcdAuthHandler); ok {
+               err = gah.AuthenticateMemcachedConn(host, conn)
+               if err != nil {
+                       conn.Close()
+                       return nil, err
+               }
+
+               if DefaultTimeout > 0 {
+                       conn.SetDeadline(noDeadline)
+               }
+
+               return conn, nil
+       }
+       name, pass, bucket := ah.GetCredentials()
+       if bucket == "" {
+               // Authenticator does not know specific bucket.
+               bucket = bucketName
+       }
+
+       if name != "default" {
+               _, err = conn.Auth(name, pass)
+               if err != nil {
+                       conn.Close()
+                       return nil, err
+               }
+               // Select bucket (Required for cb_auth creds)
+               // Required when doing auth with _admin credentials
+               if bucket != "" && bucket != name {
+                       _, err = conn.SelectBucket(bucket)
+                       if err != nil {
+                               conn.Close()
+                               return nil, err
+                       }
+               }
+       }
+
+       if DefaultTimeout > 0 {
+               conn.SetDeadline(noDeadline)
+       }
+
+       return conn, nil
+}
+
+func (cp *connectionPool) Close() (err error) {
+       defer func() {
+               if recover() != nil {
+                       err = errors.New("connectionPool.Close error")
+               }
+       }()
+       if cp.bailOut != nil {
+
+               // defensively, we won't wait if the channel is full
+               select {
+               case cp.bailOut <- false:
+               default:
+               }
+       }
+       close(cp.connections)
+       for c := range cp.connections {
+               c.Close()
+       }
+       return
+}
+
+func (cp *connectionPool) Node() string {
+       return cp.host
+}
+
+func (cp *connectionPool) GetWithTimeout(d time.Duration) (rv *memcached.Client, err error) {
+       if cp == nil {
+               return nil, errNoPool
+       }
+
+       path := ""
+
+       if ConnPoolCallback != nil {
+               defer func(path *string, start time.Time) {
+                       ConnPoolCallback(cp.host, *path, start, err)
+               }(&path, time.Now())
+       }
+
+       path = "short-circuit"
+
+       // short-circuit available connetions.
+       select {
+       case rv, isopen := <-cp.connections:
+               if !isopen {
+                       return nil, errClosedPool
+               }
+               atomic.AddUint64(&cp.connCount, 1)
+               return rv, nil
+       default:
+       }
+
+       t := time.NewTimer(ConnPoolAvailWaitTime)
+       defer t.Stop()
+
+       // Try to grab an available connection within 1ms
+       select {
+       case rv, isopen := <-cp.connections:
+               path = "avail1"
+               if !isopen {
+                       return nil, errClosedPool
+               }
+               atomic.AddUint64(&cp.connCount, 1)
+               return rv, nil
+       case <-t.C:
+               // No connection came around in time, let's see
+               // whether we can get one or build a new one first.
+               t.Reset(d) // Reuse the timer for the full timeout.
+               select {
+               case rv, isopen := <-cp.connections:
+                       path = "avail2"
+                       if !isopen {
+                               return nil, errClosedPool
+                       }
+                       atomic.AddUint64(&cp.connCount, 1)
+                       return rv, nil
+               case cp.createsem <- true:
+                       path = "create"
+                       // Build a connection if we can't get a real one.
+                       // This can potentially be an overflow connection, or
+                       // a pooled connection.
+                       rv, err := cp.mkConn(cp.host, cp.auth, cp.tlsConfig, cp.bucket)
+                       if err != nil {
+                               // On error, release our create hold
+                               <-cp.createsem
+                       } else {
+                               atomic.AddUint64(&cp.connCount, 1)
+                       }
+                       return rv, err
+               case <-t.C:
+                       return nil, ErrTimeout
+               }
+       }
+}
+
+func (cp *connectionPool) Get() (*memcached.Client, error) {
+       return cp.GetWithTimeout(ConnPoolTimeout)
+}
+
+func (cp *connectionPool) Return(c *memcached.Client) {
+       if c == nil {
+               return
+       }
+
+       if cp == nil {
+               c.Close()
+       }
+
+       if c.IsHealthy() {
+               defer func() {
+                       if recover() != nil {
+                               // This happens when the pool has already been
+                               // closed and we're trying to return a
+                               // connection to it anyway.  Just close the
+                               // connection.
+                               c.Close()
+                       }
+               }()
+
+               select {
+               case cp.connections <- c:
+               default:
+                       <-cp.createsem
+                       c.Close()
+               }
+       } else {
+               <-cp.createsem
+               c.Close()
+       }
+}
+
+// give the ability to discard a connection from a pool
+// useful for ditching connections to the wrong node after a rebalance
+func (cp *connectionPool) Discard(c *memcached.Client) {
+       <-cp.createsem
+       c.Close()
+}
+
+// asynchronous connection closer
+func (cp *connectionPool) connCloser() {
+       var connCount uint64
+
+       t := time.NewTimer(ConnCloserInterval)
+       defer t.Stop()
+
+       for {
+               connCount = cp.connCount
+
+               // we don't exist anymore! bail out!
+               select {
+               case <-cp.bailOut:
+                       return
+               case <-t.C:
+               }
+               t.Reset(ConnCloserInterval)
+
+               // no overflow connections open or sustained requests for connections
+               // nothing to do until the next cycle
+               if len(cp.connections) <= cp.poolSize ||
+                       ConnCloserInterval/ConnPoolAvailWaitTime < time.Duration(cp.connCount-connCount) {
+                       continue
+               }
+
+               // close overflow connections now that they are not needed
+               for c := range cp.connections {
+                       select {
+                       case <-cp.bailOut:
+                               return
+                       default:
+                       }
+
+                       // bail out if close did not work out
+                       if !cp.connCleanup(c) {
+                               return
+                       }
+                       if len(cp.connections) <= cp.poolSize {
+                               break
+                       }
+               }
+       }
+}
+
+// close connection with recovery on error
+func (cp *connectionPool) connCleanup(c *memcached.Client) (rv bool) {
+
+       // just in case we are closing a connection after
+       // bailOut has been sent but we haven't yet read it
+       defer func() {
+               if recover() != nil {
+                       rv = false
+               }
+       }()
+       rv = true
+
+       c.Close()
+       <-cp.createsem
+       return
+}
+
+func (cp *connectionPool) StartTapFeed(args *memcached.TapArguments) (*memcached.TapFeed, error) {
+       if cp == nil {
+               return nil, errNoPool
+       }
+       mc, err := cp.Get()
+       if err != nil {
+               return nil, err
+       }
+
+       // A connection can't be used after TAP; Dont' count it against the
+       // connection pool capacity
+       <-cp.createsem
+
+       return mc.StartTapFeed(*args)
+}
+
+const DEFAULT_WINDOW_SIZE = 20 * 1024 * 1024 // 20 Mb
+
+func (cp *connectionPool) StartUprFeed(name string, sequence uint32, dcp_buffer_size uint32, data_chan_size int) (*memcached.UprFeed, error) {
+       if cp == nil {
+               return nil, errNoPool
+       }
+       mc, err := cp.Get()
+       if err != nil {
+               return nil, err
+       }
+
+       // A connection can't be used after it has been allocated to UPR;
+       // Dont' count it against the connection pool capacity
+       <-cp.createsem
+
+       uf, err := mc.NewUprFeed()
+       if err != nil {
+               return nil, err
+       }
+
+       if err := uf.UprOpen(name, sequence, dcp_buffer_size); err != nil {
+               return nil, err
+       }
+
+       if err := uf.StartFeedWithConfig(data_chan_size); err != nil {
+               return nil, err
+       }
+
+       return uf, nil
+}
diff --git a/vendor/github.com/couchbase/go-couchbase/ddocs.go b/vendor/github.com/couchbase/go-couchbase/ddocs.go
new file mode 100644 (file)
index 0000000..f9cc343
--- /dev/null
@@ -0,0 +1,288 @@
+package couchbase
+
+import (
+       "bytes"
+       "encoding/json"
+       "fmt"
+       "github.com/couchbase/goutils/logging"
+       "io/ioutil"
+       "net/http"
+)
+
+// ViewDefinition represents a single view within a design document.
+type ViewDefinition struct {
+       Map    string `json:"map"`
+       Reduce string `json:"reduce,omitempty"`
+}
+
+// DDoc is the document body of a design document specifying a view.
+type DDoc struct {
+       Language string                    `json:"language,omitempty"`
+       Views    map[string]ViewDefinition `json:"views"`
+}
+
+// DDocsResult represents the result from listing the design
+// documents.
+type DDocsResult struct {
+       Rows []struct {
+               DDoc struct {
+                       Meta map[string]interface{}
+                       JSON DDoc
+               } `json:"doc"`
+       } `json:"rows"`
+}
+
+// GetDDocs lists all design documents
+func (b *Bucket) GetDDocs() (DDocsResult, error) {
+       var ddocsResult DDocsResult
+       b.RLock()
+       pool := b.pool
+       uri := b.DDocs.URI
+       b.RUnlock()
+
+       // MB-23555 ephemeral buckets have no ddocs
+       if uri == "" {
+               return DDocsResult{}, nil
+       }
+
+       err := pool.client.parseURLResponse(uri, &ddocsResult)
+       if err != nil {
+               return DDocsResult{}, err
+       }
+       return ddocsResult, nil
+}
+
+func (b *Bucket) GetDDocWithRetry(docname string, into interface{}) error {
+       ddocURI := fmt.Sprintf("/%s/_design/%s", b.GetName(), docname)
+       err := b.parseAPIResponse(ddocURI, &into)
+       if err != nil {
+               return err
+       }
+       return nil
+}
+
+func (b *Bucket) GetDDocsWithRetry() (DDocsResult, error) {
+       var ddocsResult DDocsResult
+       b.RLock()
+       uri := b.DDocs.URI
+       b.RUnlock()
+
+       // MB-23555 ephemeral buckets have no ddocs
+       if uri == "" {
+               return DDocsResult{}, nil
+       }
+
+       err := b.parseURLResponse(uri, &ddocsResult)
+       if err != nil {
+               return DDocsResult{}, err
+       }
+       return ddocsResult, nil
+}
+
+func (b *Bucket) ddocURL(docname string) (string, error) {
+       u, err := b.randomBaseURL()
+       if err != nil {
+               return "", err
+       }
+       u.Path = fmt.Sprintf("/%s/_design/%s", b.GetName(), docname)
+       return u.String(), nil
+}
+
+func (b *Bucket) ddocURLNext(nodeId int, docname string) (string, int, error) {
+       u, selected, err := b.randomNextURL(nodeId)
+       if err != nil {
+               return "", -1, err
+       }
+       u.Path = fmt.Sprintf("/%s/_design/%s", b.GetName(), docname)
+       return u.String(), selected, nil
+}
+
+const ABS_MAX_RETRIES = 10
+const ABS_MIN_RETRIES = 3
+
+func (b *Bucket) getMaxRetries() (int, error) {
+
+       maxRetries := len(b.Nodes())
+
+       if maxRetries == 0 {
+               return 0, fmt.Errorf("No available Couch rest URLs")
+       }
+
+       if maxRetries > ABS_MAX_RETRIES {
+               maxRetries = ABS_MAX_RETRIES
+       } else if maxRetries < ABS_MIN_RETRIES {
+               maxRetries = ABS_MIN_RETRIES
+       }
+
+       return maxRetries, nil
+}
+
+// PutDDoc installs a design document.
+func (b *Bucket) PutDDoc(docname string, value interface{}) error {
+
+       var Err error
+
+       maxRetries, err := b.getMaxRetries()
+       if err != nil {
+               return err
+       }
+
+       lastNode := START_NODE_ID
+
+       for retryCount := 0; retryCount < maxRetries; retryCount++ {
+
+               Err = nil
+
+               ddocU, selectedNode, err := b.ddocURLNext(lastNode, docname)
+               if err != nil {
+                       return err
+               }
+
+               lastNode = selectedNode
+
+               logging.Infof(" Trying with selected node %d", selectedNode)
+               j, err := json.Marshal(value)
+               if err != nil {
+                       return err
+               }
+
+               req, err := http.NewRequest("PUT", ddocU, bytes.NewReader(j))
+               if err != nil {
+                       return err
+               }
+               req.Header.Set("Content-Type", "application/json")
+               err = maybeAddAuth(req, b.authHandler(false /* bucket not yet locked */))
+               if err != nil {
+                       return err
+               }
+
+               res, err := doHTTPRequest(req)
+               if err != nil {
+                       return err
+               }
+
+               if res.StatusCode != 201 {
+                       body, _ := ioutil.ReadAll(res.Body)
+                       Err = fmt.Errorf("error installing view: %v / %s",
+                               res.Status, body)
+                       logging.Errorf(" Error in PutDDOC %v. Retrying...", Err)
+                       res.Body.Close()
+                       b.Refresh()
+                       continue
+               }
+
+               res.Body.Close()
+               break
+       }
+
+       return Err
+}
+
+// GetDDoc retrieves a specific a design doc.
+func (b *Bucket) GetDDoc(docname string, into interface{}) error {
+       var Err error
+       var res *http.Response
+
+       maxRetries, err := b.getMaxRetries()
+       if err != nil {
+               return err
+       }
+
+       lastNode := START_NODE_ID
+       for retryCount := 0; retryCount < maxRetries; retryCount++ {
+
+               Err = nil
+               ddocU, selectedNode, err := b.ddocURLNext(lastNode, docname)
+               if err != nil {
+                       return err
+               }
+
+               lastNode = selectedNode
+               logging.Infof(" Trying with selected node %d", selectedNode)
+
+               req, err := http.NewRequest("GET", ddocU, nil)
+               if err != nil {
+                       return err
+               }
+               req.Header.Set("Content-Type", "application/json")
+               err = maybeAddAuth(req, b.authHandler(false /* bucket not yet locked */))
+               if err != nil {
+                       return err
+               }
+
+               res, err = doHTTPRequest(req)
+               if err != nil {
+                       return err
+               }
+               if res.StatusCode != 200 {
+                       body, _ := ioutil.ReadAll(res.Body)
+                       Err = fmt.Errorf("error reading view: %v / %s",
+                               res.Status, body)
+                       logging.Errorf(" Error in GetDDOC %v Retrying...", Err)
+                       b.Refresh()
+                       res.Body.Close()
+                       continue
+               }
+               defer res.Body.Close()
+               break
+       }
+
+       if Err != nil {
+               return Err
+       }
+
+       d := json.NewDecoder(res.Body)
+       return d.Decode(into)
+}
+
+// DeleteDDoc removes a design document.
+func (b *Bucket) DeleteDDoc(docname string) error {
+
+       var Err error
+
+       maxRetries, err := b.getMaxRetries()
+       if err != nil {
+               return err
+       }
+
+       lastNode := START_NODE_ID
+
+       for retryCount := 0; retryCount < maxRetries; retryCount++ {
+
+               Err = nil
+               ddocU, selectedNode, err := b.ddocURLNext(lastNode, docname)
+               if err != nil {
+                       return err
+               }
+
+               lastNode = selectedNode
+               logging.Infof(" Trying with selected node %d", selectedNode)
+
+               req, err := http.NewRequest("DELETE", ddocU, nil)
+               if err != nil {
+                       return err
+               }
+               req.Header.Set("Content-Type", "application/json")
+               err = maybeAddAuth(req, b.authHandler(false /* bucket not already locked */))
+               if err != nil {
+                       return err
+               }
+
+               res, err := doHTTPRequest(req)
+               if err != nil {
+                       return err
+               }
+               if res.StatusCode != 200 {
+                       body, _ := ioutil.ReadAll(res.Body)
+                       Err = fmt.Errorf("error deleting view : %v / %s", res.Status, body)
+                       logging.Errorf(" Error in DeleteDDOC %v. Retrying ... ", Err)
+                       b.Refresh()
+                       res.Body.Close()
+                       continue
+               }
+
+               res.Body.Close()
+               break
+       }
+       return Err
+}
diff --git a/vendor/github.com/couchbase/go-couchbase/go.mod b/vendor/github.com/couchbase/go-couchbase/go.mod
new file mode 100644 (file)
index 0000000..4d4ed0a
--- /dev/null
@@ -0,0 +1,3 @@
+module github.com/couchbase/go-couchbase
+
+go 1.13
diff --git a/vendor/github.com/couchbase/go-couchbase/observe.go b/vendor/github.com/couchbase/go-couchbase/observe.go
new file mode 100644 (file)
index 0000000..6e746f5
--- /dev/null
@@ -0,0 +1,300 @@
+package couchbase
+
+import (
+       "fmt"
+       "github.com/couchbase/goutils/logging"
+       "sync"
+)
+
+type PersistTo uint8
+
+const (
+       PersistNone   = PersistTo(0x00)
+       PersistMaster = PersistTo(0x01)
+       PersistOne    = PersistTo(0x02)
+       PersistTwo    = PersistTo(0x03)
+       PersistThree  = PersistTo(0x04)
+       PersistFour   = PersistTo(0x05)
+)
+
+type ObserveTo uint8
+
+const (
+       ObserveNone           = ObserveTo(0x00)
+       ObserveReplicateOne   = ObserveTo(0x01)
+       ObserveReplicateTwo   = ObserveTo(0x02)
+       ObserveReplicateThree = ObserveTo(0x03)
+       ObserveReplicateFour  = ObserveTo(0x04)
+)
+
+type JobType uint8
+
+const (
+       OBSERVE = JobType(0x00)
+       PERSIST = JobType(0x01)
+)
+
+type ObservePersistJob struct {
+       vb                 uint16
+       vbuuid             uint64
+       hostname           string
+       jobType            JobType
+       failover           uint8
+       lastPersistedSeqNo uint64
+       currentSeqNo       uint64
+       resultChan         chan *ObservePersistJob
+       errorChan          chan *OPErrResponse
+}
+
+type OPErrResponse struct {
+       vb     uint16
+       vbuuid uint64
+       err    error
+       job    *ObservePersistJob
+}
+
+var ObservePersistPool = NewPool(1024)
+var OPJobChan = make(chan *ObservePersistJob, 1024)
+var OPJobDone = make(chan bool)
+
+var wg sync.WaitGroup
+
+func (b *Bucket) StartOPPollers(maxWorkers int) {
+
+       for i := 0; i < maxWorkers; i++ {
+               go b.OPJobPoll()
+               wg.Add(1)
+       }
+       wg.Wait()
+}
+
+func (b *Bucket) SetObserveAndPersist(nPersist PersistTo, nObserve ObserveTo) (err error) {
+
+       numNodes := len(b.Nodes())
+       if int(nPersist) > numNodes || int(nObserve) > numNodes {
+               return fmt.Errorf("Not enough healthy nodes in the cluster")
+       }
+
+       if int(nPersist) > (b.Replicas+1) || int(nObserve) > b.Replicas {
+               return fmt.Errorf("Not enough replicas in the cluster")
+       }
+
+       if EnableMutationToken == false {
+               return fmt.Errorf("Mutation Tokens not enabled ")
+       }
+
+       b.ds = &DurablitySettings{Persist: PersistTo(nPersist), Observe: ObserveTo(nObserve)}
+       return
+}
+
+func (b *Bucket) ObserveAndPersistPoll(vb uint16, vbuuid uint64, seqNo uint64) (err error, failover bool) {
+       b.RLock()
+       ds := b.ds
+       b.RUnlock()
+
+       if ds == nil {
+               return
+       }
+
+       nj := 0 // total number of jobs
+       resultChan := make(chan *ObservePersistJob, 10)
+       errChan := make(chan *OPErrResponse, 10)
+
+       nodes := b.GetNodeList(vb)
+       if int(ds.Observe) > len(nodes) || int(ds.Persist) > len(nodes) {
+               return fmt.Errorf("Not enough healthy nodes in the cluster"), false
+       }
+
+       logging.Infof("Node list %v", nodes)
+
+       if ds.Observe >= ObserveReplicateOne {
+               // create a job for each host
+               for i := ObserveReplicateOne; i < ds.Observe+1; i++ {
+                       opJob := ObservePersistPool.Get()
+                       opJob.vb = vb
+                       opJob.vbuuid = vbuuid
+                       opJob.jobType = OBSERVE
+                       opJob.hostname = nodes[i]
+                       opJob.resultChan = resultChan
+                       opJob.errorChan = errChan
+
+                       OPJobChan <- opJob
+                       nj++
+
+               }
+       }
+
+       if ds.Persist >= PersistMaster {
+               for i := PersistMaster; i < ds.Persist+1; i++ {
+                       opJob := ObservePersistPool.Get()
+                       opJob.vb = vb
+                       opJob.vbuuid = vbuuid
+                       opJob.jobType = PERSIST
+                       opJob.hostname = nodes[i]
+                       opJob.resultChan = resultChan
+                       opJob.errorChan = errChan
+
+                       OPJobChan <- opJob
+                       nj++
+
+               }
+       }
+
+       ok := true
+       for ok {
+               select {
+               case res := <-resultChan:
+                       jobDone := false
+                       if res.failover == 0 {
+                               // no failover
+                               if res.jobType == PERSIST {
+                                       if res.lastPersistedSeqNo >= seqNo {
+                                               jobDone = true
+                                       }
+
+                               } else {
+                                       if res.currentSeqNo >= seqNo {
+                                               jobDone = true
+                                       }
+                               }
+
+                               if jobDone == true {
+                                       nj--
+                                       ObservePersistPool.Put(res)
+                               } else {
+                                       // requeue this job
+                                       OPJobChan <- res
+                               }
+
+                       } else {
+                               // Not currently handling failover scenarios TODO
+                               nj--
+                               ObservePersistPool.Put(res)
+                               failover = true
+                       }
+
+                       if nj == 0 {
+                               // done with all the jobs
+                               ok = false
+                               close(resultChan)
+                               close(errChan)
+                       }
+
+               case Err := <-errChan:
+                       logging.Errorf("Error in Observe/Persist %v", Err.err)
+                       err = fmt.Errorf("Error in Observe/Persist job %v", Err.err)
+                       nj--
+                       ObservePersistPool.Put(Err.job)
+                       if nj == 0 {
+                               close(resultChan)
+                               close(errChan)
+                               ok = false
+                       }
+               }
+       }
+
+       return
+}
+
+func (b *Bucket) OPJobPoll() {
+
+       ok := true
+       for ok == true {
+               select {
+               case job := <-OPJobChan:
+                       pool := b.getConnPoolByHost(job.hostname, false /* bucket not already locked */)
+                       if pool == nil {
+                               errRes := &OPErrResponse{vb: job.vb, vbuuid: job.vbuuid}
+                               errRes.err = fmt.Errorf("Pool not found for host %v", job.hostname)
+                               errRes.job = job
+                               job.errorChan <- errRes
+                               continue
+                       }
+                       conn, err := pool.Get()
+                       if err != nil {
+                               errRes := &OPErrResponse{vb: job.vb, vbuuid: job.vbuuid}
+                               errRes.err = fmt.Errorf("Unable to get connection from pool %v", err)
+                               errRes.job = job
+                               job.errorChan <- errRes
+                               continue
+                       }
+
+                       res, err := conn.ObserveSeq(job.vb, job.vbuuid)
+                       if err != nil {
+                               errRes := &OPErrResponse{vb: job.vb, vbuuid: job.vbuuid}
+                               errRes.err = fmt.Errorf("Command failed %v", err)
+                               errRes.job = job
+                               job.errorChan <- errRes
+                               continue
+
+                       }
+                       pool.Return(conn)
+                       job.lastPersistedSeqNo = res.LastPersistedSeqNo
+                       job.currentSeqNo = res.CurrentSeqNo
+                       job.failover = res.Failover
+
+                       job.resultChan <- job
+               case <-OPJobDone:
+                       logging.Infof("Observe Persist Poller exitting")
+                       ok = false
+               }
+       }
+       wg.Done()
+}
+
+func (b *Bucket) GetNodeList(vb uint16) []string {
+
+       vbm := b.VBServerMap()
+       if len(vbm.VBucketMap) < int(vb) {
+               logging.Infof("vbmap smaller than vblist")
+               return nil
+       }
+
+       nodes := make([]string, len(vbm.VBucketMap[vb]))
+       for i := 0; i < len(vbm.VBucketMap[vb]); i++ {
+               n := vbm.VBucketMap[vb][i]
+               if n < 0 {
+                       continue
+               }
+
+               node := b.getMasterNode(n)
+               if len(node) > 1 {
+                       nodes[i] = node
+               }
+               continue
+
+       }
+       return nodes
+}
+
+//pool of ObservePersist Jobs
+type OPpool struct {
+       pool chan *ObservePersistJob
+}
+
+// NewPool creates a new pool of jobs
+func NewPool(max int) *OPpool {
+       return &OPpool{
+               pool: make(chan *ObservePersistJob, max),
+       }
+}
+
+// Borrow a Client from the pool.
+func (p *OPpool) Get() *ObservePersistJob {
+       var o *ObservePersistJob
+       select {
+       case o = <-p.pool:
+       default:
+               o = &ObservePersistJob{}
+       }
+       return o
+}
+
+// Return returns a Client to the pool.
+func (p *OPpool) Put(o *ObservePersistJob) {
+       select {
+       case p.pool <- o:
+       default:
+               // let it go, let it go...
+       }
+}
diff --git a/vendor/github.com/couchbase/go-couchbase/pools.go b/vendor/github.com/couchbase/go-couchbase/pools.go
new file mode 100644 (file)
index 0000000..39db2dd
--- /dev/null
@@ -0,0 +1,1746 @@
+package couchbase
+
+import (
+       "bufio"
+       "bytes"
+       "crypto/tls"
+       "crypto/x509"
+       "encoding/base64"
+       "encoding/json"
+       "errors"
+       "fmt"
+       "io"
+       "io/ioutil"
+       "math/rand"
+       "net/http"
+       "net/url"
+       "runtime"
+       "sort"
+       "strconv"
+       "strings"
+       "sync"
+       "time"
+       "unsafe"
+
+       "github.com/couchbase/goutils/logging"
+
+       "github.com/couchbase/gomemcached"        // package name is 'gomemcached'
+       "github.com/couchbase/gomemcached/client" // package name is 'memcached'
+)
+
+// HTTPClient to use for REST and view operations.
+var MaxIdleConnsPerHost = 256
+var ClientTimeOut = 10 * time.Second
+var HTTPTransport = &http.Transport{MaxIdleConnsPerHost: MaxIdleConnsPerHost}
+var HTTPClient = &http.Client{Transport: HTTPTransport, Timeout: ClientTimeOut}
+
+// Use this client for reading from streams that should be open for an extended duration.
+var HTTPClientForStreaming = &http.Client{Transport: HTTPTransport, Timeout: 0}
+
+// PoolSize is the size of each connection pool (per host).
+var PoolSize = 64
+
+// PoolOverflow is the number of overflow connections allowed in a
+// pool.
+var PoolOverflow = 16
+
+// AsynchronousCloser turns on asynchronous closing for overflow connections
+var AsynchronousCloser = false
+
+// TCP KeepAlive enabled/disabled
+var TCPKeepalive = false
+
+// Enable MutationToken
+var EnableMutationToken = false
+
+// Enable Data Type response
+var EnableDataType = false
+
+// Enable Xattr
+var EnableXattr = false
+
+// Enable Collections
+var EnableCollections = false
+
+// TCP keepalive interval in seconds. Default 30 minutes
+var TCPKeepaliveInterval = 30 * 60
+
+// Used to decide whether to skip verification of certificates when
+// connecting to an ssl port.
+var skipVerify = true
+var certFile = ""
+var keyFile = ""
+var rootFile = ""
+
+func SetSkipVerify(skip bool) {
+       skipVerify = skip
+}
+
+func SetCertFile(cert string) {
+       certFile = cert
+}
+
+func SetKeyFile(cert string) {
+       keyFile = cert
+}
+
+func SetRootFile(cert string) {
+       rootFile = cert
+}
+
+// Allow applications to speciify the Poolsize and Overflow
+func SetConnectionPoolParams(size, overflow int) {
+
+       if size > 0 {
+               PoolSize = size
+       }
+
+       if overflow > 0 {
+               PoolOverflow = overflow
+       }
+}
+
+// Turn off overflow connections
+func DisableOverflowConnections() {
+       PoolOverflow = 0
+}
+
+// Toggle asynchronous overflow closer
+func EnableAsynchronousCloser(closer bool) {
+       AsynchronousCloser = closer
+}
+
+// Allow TCP keepalive parameters to be set by the application
+func SetTcpKeepalive(enabled bool, interval int) {
+
+       TCPKeepalive = enabled
+
+       if interval > 0 {
+               TCPKeepaliveInterval = interval
+       }
+}
+
+// AuthHandler is a callback that gets the auth username and password
+// for the given bucket.
+type AuthHandler interface {
+       GetCredentials() (string, string, string)
+}
+
+// AuthHandler is a callback that gets the auth username and password
+// for the given bucket and sasl for memcached.
+type AuthWithSaslHandler interface {
+       AuthHandler
+       GetSaslCredentials() (string, string)
+}
+
+// MultiBucketAuthHandler is kind of AuthHandler that may perform
+// different auth for different buckets.
+type MultiBucketAuthHandler interface {
+       AuthHandler
+       ForBucket(bucket string) AuthHandler
+}
+
+// HTTPAuthHandler is kind of AuthHandler that performs more general
+// for outgoing http requests than is possible via simple
+// GetCredentials() call (i.e. digest auth or different auth per
+// different destinations).
+type HTTPAuthHandler interface {
+       AuthHandler
+       SetCredsForRequest(req *http.Request) error
+}
+
+// RestPool represents a single pool returned from the pools REST API.
+type RestPool struct {
+       Name         string `json:"name"`
+       StreamingURI string `json:"streamingUri"`
+       URI          string `json:"uri"`
+}
+
+// Pools represents the collection of pools as returned from the REST API.
+type Pools struct {
+       ComponentsVersion     map[string]string `json:"componentsVersion,omitempty"`
+       ImplementationVersion string            `json:"implementationVersion"`
+       IsAdmin               bool              `json:"isAdminCreds"`
+       UUID                  string            `json:"uuid"`
+       Pools                 []RestPool        `json:"pools"`
+}
+
+// A Node is a computer in a cluster running the couchbase software.
+type Node struct {
+       ClusterCompatibility int                           `json:"clusterCompatibility"`
+       ClusterMembership    string                        `json:"clusterMembership"`
+       CouchAPIBase         string                        `json:"couchApiBase"`
+       Hostname             string                        `json:"hostname"`
+       AlternateNames       map[string]NodeAlternateNames `json:"alternateAddresses"`
+       InterestingStats     map[string]float64            `json:"interestingStats,omitempty"`
+       MCDMemoryAllocated   float64                       `json:"mcdMemoryAllocated"`
+       MCDMemoryReserved    float64                       `json:"mcdMemoryReserved"`
+       MemoryFree           float64                       `json:"memoryFree"`
+       MemoryTotal          float64                       `json:"memoryTotal"`
+       OS                   string                        `json:"os"`
+       Ports                map[string]int                `json:"ports"`
+       Services             []string                      `json:"services"`
+       Status               string                        `json:"status"`
+       Uptime               int                           `json:"uptime,string"`
+       Version              string                        `json:"version"`
+       ThisNode             bool                          `json:"thisNode,omitempty"`
+}
+
+// A Pool of nodes and buckets.
+type Pool struct {
+       BucketMap map[string]*Bucket
+       Nodes     []Node
+
+       BucketURL map[string]string `json:"buckets"`
+
+       MemoryQuota         float64 `json:"memoryQuota"`
+       CbasMemoryQuota     float64 `json:"cbasMemoryQuota"`
+       EventingMemoryQuota float64 `json:"eventingMemoryQuota"`
+       FtsMemoryQuota      float64 `json:"ftsMemoryQuota"`
+       IndexMemoryQuota    float64 `json:"indexMemoryQuota"`
+
+       client *Client
+}
+
+// VBucketServerMap is the a mapping of vbuckets to nodes.
+type VBucketServerMap struct {
+       HashAlgorithm string   `json:"hashAlgorithm"`
+       NumReplicas   int      `json:"numReplicas"`
+       ServerList    []string `json:"serverList"`
+       VBucketMap    [][]int  `json:"vBucketMap"`
+}
+
+type DurablitySettings struct {
+       Persist PersistTo
+       Observe ObserveTo
+}
+
+// Bucket is the primary entry point for most data operations.
+// Bucket is a locked data structure. All access to its fields should be done using read or write locking,
+// as appropriate.
+//
+// Some access methods require locking, but rely on the caller to do so. These are appropriate
+// for calls from methods that have already locked the structure. Methods like this
+// take a boolean parameter "bucketLocked".
+type Bucket struct {
+       sync.RWMutex
+       AuthType               string             `json:"authType"`
+       Capabilities           []string           `json:"bucketCapabilities"`
+       CapabilitiesVersion    string             `json:"bucketCapabilitiesVer"`
+       CollectionsManifestUid string             `json:"collectionsManifestUid"`
+       Type                   string             `json:"bucketType"`
+       Name                   string             `json:"name"`
+       NodeLocator            string             `json:"nodeLocator"`
+       Quota                  map[string]float64 `json:"quota,omitempty"`
+       Replicas               int                `json:"replicaNumber"`
+       Password               string             `json:"saslPassword"`
+       URI                    string             `json:"uri"`
+       StreamingURI           string             `json:"streamingUri"`
+       LocalRandomKeyURI      string             `json:"localRandomKeyUri,omitempty"`
+       UUID                   string             `json:"uuid"`
+       ConflictResolutionType string             `json:"conflictResolutionType,omitempty"`
+       DDocs                  struct {
+               URI string `json:"uri"`
+       } `json:"ddocs,omitempty"`
+       BasicStats  map[string]interface{} `json:"basicStats,omitempty"`
+       Controllers map[string]interface{} `json:"controllers,omitempty"`
+
+       // These are used for JSON IO, but isn't used for processing
+       // since it needs to be swapped out safely.
+       VBSMJson  VBucketServerMap `json:"vBucketServerMap"`
+       NodesJSON []Node           `json:"nodes"`
+
+       pool             *Pool
+       connPools        unsafe.Pointer // *[]*connectionPool
+       vBucketServerMap unsafe.Pointer // *VBucketServerMap
+       nodeList         unsafe.Pointer // *[]Node
+       commonSufix      string
+       ah               AuthHandler        // auth handler
+       ds               *DurablitySettings // Durablity Settings for this bucket
+       closed           bool
+}
+
+// PoolServices is all the bucket-independent services in a pool
+type PoolServices struct {
+       Rev          int             `json:"rev"`
+       NodesExt     []NodeServices  `json:"nodesExt"`
+       Capabilities json.RawMessage `json:"clusterCapabilities"`
+}
+
+// NodeServices is all the bucket-independent services running on
+// a node (given by Hostname)
+type NodeServices struct {
+       Services       map[string]int                `json:"services,omitempty"`
+       Hostname       string                        `json:"hostname"`
+       ThisNode       bool                          `json:"thisNode"`
+       AlternateNames map[string]NodeAlternateNames `json:"alternateAddresses"`
+}
+
+type NodeAlternateNames struct {
+       Hostname string         `json:"hostname"`
+       Ports    map[string]int `json:"ports"`
+}
+
+type BucketNotFoundError struct {
+       bucket string
+}
+
+func (e *BucketNotFoundError) Error() string {
+       return fmt.Sprint("No bucket named " + e.bucket)
+}
+
+type BucketAuth struct {
+       name    string
+       saslPwd string
+       bucket  string
+}
+
+func newBucketAuth(name string, pass string, bucket string) *BucketAuth {
+       return &BucketAuth{name: name, saslPwd: pass, bucket: bucket}
+}
+
+func (ba *BucketAuth) GetCredentials() (string, string, string) {
+       return ba.name, ba.saslPwd, ba.bucket
+}
+
+// VBServerMap returns the current VBucketServerMap.
+func (b *Bucket) VBServerMap() *VBucketServerMap {
+       b.RLock()
+       defer b.RUnlock()
+       ret := (*VBucketServerMap)(b.vBucketServerMap)
+       return ret
+}
+
+func (b *Bucket) GetVBmap(addrs []string) (map[string][]uint16, error) {
+       vbmap := b.VBServerMap()
+       servers := vbmap.ServerList
+       if addrs == nil {
+               addrs = vbmap.ServerList
+       }
+
+       m := make(map[string][]uint16)
+       for _, addr := range addrs {
+               m[addr] = make([]uint16, 0)
+       }
+       for vbno, idxs := range vbmap.VBucketMap {
+               if len(idxs) == 0 {
+                       return nil, fmt.Errorf("vbmap: No KV node no for vb %d", vbno)
+               } else if idxs[0] < 0 || idxs[0] >= len(servers) {
+                       return nil, fmt.Errorf("vbmap: Invalid KV node no %d for vb %d", idxs[0], vbno)
+               }
+               addr := servers[idxs[0]]
+               if _, ok := m[addr]; ok {
+                       m[addr] = append(m[addr], uint16(vbno))
+               }
+       }
+       return m, nil
+}
+
+// true if node is not on the bucket VBmap
+func (b *Bucket) checkVBmap(node string) bool {
+       vbmap := b.VBServerMap()
+       servers := vbmap.ServerList
+
+       for _, idxs := range vbmap.VBucketMap {
+               if len(idxs) == 0 {
+                       return true
+               } else if idxs[0] < 0 || idxs[0] >= len(servers) {
+                       return true
+               }
+               if servers[idxs[0]] == node {
+                       return false
+               }
+       }
+       return true
+}
+
+func (b *Bucket) GetName() string {
+       b.RLock()
+       defer b.RUnlock()
+       ret := b.Name
+       return ret
+}
+
+func (b *Bucket) GetUUID() string {
+       b.RLock()
+       defer b.RUnlock()
+       ret := b.UUID
+       return ret
+}
+
+// Nodes returns the current list of nodes servicing this bucket.
+func (b *Bucket) Nodes() []Node {
+       b.RLock()
+       defer b.RUnlock()
+       ret := *(*[]Node)(b.nodeList)
+       return ret
+}
+
+// return the list of healthy nodes
+func (b *Bucket) HealthyNodes() []Node {
+       nodes := []Node{}
+
+       for _, n := range b.Nodes() {
+               if n.Status == "healthy" && n.CouchAPIBase != "" {
+                       nodes = append(nodes, n)
+               }
+               if n.Status != "healthy" { // log non-healthy node
+                       logging.Infof("Non-healthy node; node details:")
+                       logging.Infof("Hostname=%v, Status=%v, CouchAPIBase=%v, ThisNode=%v", n.Hostname, n.Status, n.CouchAPIBase, n.ThisNode)
+               }
+       }
+
+       return nodes
+}
+
+func (b *Bucket) getConnPools(bucketLocked bool) []*connectionPool {
+       if !bucketLocked {
+               b.RLock()
+               defer b.RUnlock()
+       }
+       if b.connPools != nil {
+               return *(*[]*connectionPool)(b.connPools)
+       } else {
+               return nil
+       }
+}
+
+func (b *Bucket) replaceConnPools(with []*connectionPool) {
+       b.Lock()
+       defer b.Unlock()
+
+       old := b.connPools
+       b.connPools = unsafe.Pointer(&with)
+       if old != nil {
+               for _, pool := range *(*[]*connectionPool)(old) {
+                       if pool != nil {
+                               pool.Close()
+                       }
+               }
+       }
+       return
+}
+
+func (b *Bucket) getConnPool(i int) *connectionPool {
+
+       if i < 0 {
+               return nil
+       }
+
+       p := b.getConnPools(false /* not already locked */)
+       if len(p) > i {
+               return p[i]
+       }
+
+       return nil
+}
+
+func (b *Bucket) getConnPoolByHost(host string, bucketLocked bool) *connectionPool {
+       pools := b.getConnPools(bucketLocked)
+       for _, p := range pools {
+               if p != nil && p.host == host {
+                       return p
+               }
+       }
+
+       return nil
+}
+
+// Given a vbucket number, returns a memcached connection to it.
+// The connection must be returned to its pool after use.
+func (b *Bucket) getConnectionToVBucket(vb uint32) (*memcached.Client, *connectionPool, error) {
+       for {
+               vbm := b.VBServerMap()
+               if len(vbm.VBucketMap) < int(vb) {
+                       return nil, nil, fmt.Errorf("go-couchbase: vbmap smaller than vbucket list: %v vs. %v",
+                               vb, vbm.VBucketMap)
+               }
+               masterId := vbm.VBucketMap[vb][0]
+               if masterId < 0 {
+                       return nil, nil, fmt.Errorf("go-couchbase: No master for vbucket %d", vb)
+               }
+               pool := b.getConnPool(masterId)
+               conn, err := pool.Get()
+               if err != errClosedPool {
+                       return conn, pool, err
+               }
+               // If conn pool was closed, because another goroutine refreshed the vbucket map, retry...
+       }
+}
+
+// To get random documents, we need to cover all the nodes, so select
+// a connection at random.
+
+func (b *Bucket) getRandomConnection() (*memcached.Client, *connectionPool, error) {
+       for {
+               var currentPool = 0
+               pools := b.getConnPools(false /* not already locked */)
+               if len(pools) == 0 {
+                       return nil, nil, fmt.Errorf("No connection pool found")
+               } else if len(pools) > 1 { // choose a random connection
+                       currentPool = rand.Intn(len(pools))
+               } // if only one pool, currentPool defaults to 0, i.e., the only pool
+
+               // get the pool
+               pool := pools[currentPool]
+               conn, err := pool.Get()
+               if err != errClosedPool {
+                       return conn, pool, err
+               }
+
+               // If conn pool was closed, because another goroutine refreshed the vbucket map, retry...
+       }
+}
+
+//
+// Get a random document from a bucket. Since the bucket may be distributed
+// across nodes, we must first select a random connection, and then use the
+// Client.GetRandomDoc() call to get a random document from that node.
+//
+
+func (b *Bucket) GetRandomDoc(context ...*memcached.ClientContext) (*gomemcached.MCResponse, error) {
+       // get a connection from the pool
+       conn, pool, err := b.getRandomConnection()
+
+       if err != nil {
+               return nil, err
+       }
+       conn.SetDeadline(getDeadline(time.Time{}, DefaultTimeout))
+
+       // We may need to select the bucket before GetRandomDoc()
+       // will work. This is sometimes done at startup (see defaultMkConn())
+       // but not always, depending on the auth type.
+       _, err = conn.SelectBucket(b.Name)
+       if err != nil {
+               return nil, err
+       }
+
+       // get a randomm document from the connection
+       doc, err := conn.GetRandomDoc(context...)
+       // need to return the connection to the pool
+       pool.Return(conn)
+       return doc, err
+}
+
+// Bucket DDL
+func uriAdj(s string) string {
+       return strings.Replace(s, "%", "%25", -1)
+}
+
+func (b *Bucket) CreateScope(scope string) error {
+       b.RLock()
+       pool := b.pool
+       client := pool.client
+       b.RUnlock()
+       args := map[string]interface{}{"name": scope}
+       return client.parsePostURLResponseTerse("/pools/default/buckets/"+uriAdj(b.Name)+"/collections", args, nil)
+}
+
+func (b *Bucket) DropScope(scope string) error {
+       b.RLock()
+       pool := b.pool
+       client := pool.client
+       b.RUnlock()
+       return client.parseDeleteURLResponseTerse("/pools/default/buckets/"+uriAdj(b.Name)+"/collections/"+uriAdj(scope), nil, nil)
+}
+
+func (b *Bucket) CreateCollection(scope string, collection string) error {
+       b.RLock()
+       pool := b.pool
+       client := pool.client
+       b.RUnlock()
+       args := map[string]interface{}{"name": collection}
+       return client.parsePostURLResponseTerse("/pools/default/buckets/"+uriAdj(b.Name)+"/collections/"+uriAdj(scope), args, nil)
+}
+
+func (b *Bucket) DropCollection(scope string, collection string) error {
+       b.RLock()
+       pool := b.pool
+       client := pool.client
+       b.RUnlock()
+       return client.parseDeleteURLResponseTerse("/pools/default/buckets/"+uriAdj(b.Name)+"/collections/"+uriAdj(scope)+"/"+uriAdj(collection), nil, nil)
+}
+
+func (b *Bucket) FlushCollection(scope string, collection string) error {
+       b.RLock()
+       pool := b.pool
+       client := pool.client
+       b.RUnlock()
+       args := map[string]interface{}{"name": collection, "scope": scope}
+       return client.parsePostURLResponseTerse("/pools/default/buckets/"+uriAdj(b.Name)+"/collections-flush", args, nil)
+}
+
+func (b *Bucket) getMasterNode(i int) string {
+       p := b.getConnPools(false /* not already locked */)
+       if len(p) > i {
+               return p[i].host
+       }
+       return ""
+}
+
+func (b *Bucket) authHandler(bucketLocked bool) (ah AuthHandler) {
+       if !bucketLocked {
+               b.RLock()
+               defer b.RUnlock()
+       }
+       pool := b.pool
+       name := b.Name
+
+       if pool != nil {
+               ah = pool.client.ah
+       }
+       if mbah, ok := ah.(MultiBucketAuthHandler); ok {
+               return mbah.ForBucket(name)
+       }
+       if ah == nil {
+               ah = &basicAuth{name, ""}
+       }
+       return
+}
+
+// NodeAddresses gets the (sorted) list of memcached node addresses
+// (hostname:port).
+func (b *Bucket) NodeAddresses() []string {
+       vsm := b.VBServerMap()
+       rv := make([]string, len(vsm.ServerList))
+       copy(rv, vsm.ServerList)
+       sort.Strings(rv)
+       return rv
+}
+
+// CommonAddressSuffix finds the longest common suffix of all
+// host:port strings in the node list.
+func (b *Bucket) CommonAddressSuffix() string {
+       input := []string{}
+       for _, n := range b.Nodes() {
+               input = append(input, n.Hostname)
+       }
+       return FindCommonSuffix(input)
+}
+
+// A Client is the starting point for all services across all buckets
+// in a Couchbase cluster.
+type Client struct {
+       BaseURL   *url.URL
+       ah        AuthHandler
+       Info      Pools
+       tlsConfig *tls.Config
+}
+
+func maybeAddAuth(req *http.Request, ah AuthHandler) error {
+       if hah, ok := ah.(HTTPAuthHandler); ok {
+               return hah.SetCredsForRequest(req)
+       }
+       if ah != nil {
+               user, pass, _ := ah.GetCredentials()
+               req.Header.Set("Authorization", "Basic "+
+                       base64.StdEncoding.EncodeToString([]byte(user+":"+pass)))
+       }
+       return nil
+}
+
+// arbitary number, may need to be tuned #FIXME
+const HTTP_MAX_RETRY = 5
+
+// Someday golang network packages will implement standard
+// error codes. Until then #sigh
+func isHttpConnError(err error) bool {
+
+       estr := err.Error()
+       return strings.Contains(estr, "broken pipe") ||
+               strings.Contains(estr, "broken connection") ||
+               strings.Contains(estr, "connection reset")
+}
+
+var client *http.Client
+var clientForStreaming *http.Client
+
+func ClientConfigForX509(certFile, keyFile, rootFile string) (*tls.Config, error) {
+       cfg := &tls.Config{}
+
+       if certFile != "" && keyFile != "" {
+               tlsCert, err := tls.LoadX509KeyPair(certFile, keyFile)
+               if err != nil {
+                       return nil, err
+               }
+               cfg.Certificates = []tls.Certificate{tlsCert}
+       } else {
+               //error need to pass both certfile and keyfile
+               return nil, fmt.Errorf("N1QL: Need to pass both certfile and keyfile")
+       }
+
+       var caCert []byte
+       var err1 error
+
+       caCertPool := x509.NewCertPool()
+       if rootFile != "" {
+               // Read that value in
+               caCert, err1 = ioutil.ReadFile(rootFile)
+               if err1 != nil {
+                       return nil, fmt.Errorf(" Error in reading cacert file, err: %v", err1)
+               }
+               caCertPool.AppendCertsFromPEM(caCert)
+       }
+
+       cfg.RootCAs = caCertPool
+       return cfg, nil
+}
+
+// This version of doHTTPRequest is for requests where the response connection is held open
+// for an extended duration since line is a new and significant output.
+//
+// The ordinary version of this method expects the results to arrive promptly, and
+// therefore use an HTTP client with a timeout. This client is not suitable
+// for streaming use.
+func doHTTPRequestForStreaming(req *http.Request) (*http.Response, error) {
+       var err error
+       var res *http.Response
+
+       // we need a client that ignores certificate errors, since we self-sign
+       // our certs
+       if clientForStreaming == nil && req.URL.Scheme == "https" {
+               var tr *http.Transport
+
+               if skipVerify {
+                       tr = &http.Transport{
+                               TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+                       }
+               } else {
+                       // Handle cases with cert
+
+                       cfg, err := ClientConfigForX509(certFile, keyFile, rootFile)
+                       if err != nil {
+                               return nil, err
+                       }
+
+                       tr = &http.Transport{
+                               TLSClientConfig: cfg,
+                       }
+               }
+
+               clientForStreaming = &http.Client{Transport: tr, Timeout: 0}
+
+       } else if clientForStreaming == nil {
+               clientForStreaming = HTTPClientForStreaming
+       }
+
+       for i := 0; i < HTTP_MAX_RETRY; i++ {
+               res, err = clientForStreaming.Do(req)
+               if err != nil && isHttpConnError(err) {
+                       continue
+               }
+               break
+       }
+
+       if err != nil {
+               return nil, err
+       }
+
+       return res, err
+}
+
+func doHTTPRequest(req *http.Request) (*http.Response, error) {
+
+       var err error
+       var res *http.Response
+
+       // we need a client that ignores certificate errors, since we self-sign
+       // our certs
+       if client == nil && req.URL.Scheme == "https" {
+               var tr *http.Transport
+
+               if skipVerify {
+                       tr = &http.Transport{
+                               TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+                       }
+               } else {
+                       // Handle cases with cert
+
+                       cfg, err := ClientConfigForX509(certFile, keyFile, rootFile)
+                       if err != nil {
+                               return nil, err
+                       }
+
+                       tr = &http.Transport{
+                               TLSClientConfig: cfg,
+                       }
+               }
+
+               client = &http.Client{Transport: tr}
+
+       } else if client == nil {
+               client = HTTPClient
+       }
+
+       for i := 0; i < HTTP_MAX_RETRY; i++ {
+               res, err = client.Do(req)
+               if err != nil && isHttpConnError(err) {
+                       continue
+               }
+               break
+       }
+
+       if err != nil {
+               return nil, err
+       }
+
+       return res, err
+}
+
+func doPutAPI(baseURL *url.URL, path string, params map[string]interface{}, authHandler AuthHandler, out interface{}, terse bool) error {
+       return doOutputAPI("PUT", baseURL, path, params, authHandler, out, terse)
+}
+
+func doPostAPI(baseURL *url.URL, path string, params map[string]interface{}, authHandler AuthHandler, out interface{}, terse bool) error {
+       return doOutputAPI("POST", baseURL, path, params, authHandler, out, terse)
+}
+
+func doDeleteAPI(baseURL *url.URL, path string, params map[string]interface{}, authHandler AuthHandler, out interface{}, terse bool) error {
+       return doOutputAPI("DELETE", baseURL, path, params, authHandler, out, terse)
+}
+
+func doOutputAPI(
+       httpVerb string,
+       baseURL *url.URL,
+       path string,
+       params map[string]interface{},
+       authHandler AuthHandler,
+       out interface{},
+       terse bool) error {
+
+       var requestUrl string
+
+       if q := strings.Index(path, "?"); q > 0 {
+               requestUrl = baseURL.Scheme + "://" + baseURL.Host + path[:q] + "?" + path[q+1:]
+       } else {
+               requestUrl = baseURL.Scheme + "://" + baseURL.Host + path
+       }
+
+       postData := url.Values{}
+       for k, v := range params {
+               postData.Set(k, fmt.Sprintf("%v", v))
+       }
+
+       req, err := http.NewRequest(httpVerb, requestUrl, bytes.NewBufferString(postData.Encode()))
+       if err != nil {
+               return err
+       }
+
+       req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
+
+       err = maybeAddAuth(req, authHandler)
+       if err != nil {
+               return err
+       }
+
+       res, err := doHTTPRequest(req)
+       if err != nil {
+               return err
+       }
+
+       defer res.Body.Close()
+       // 200 - ok, 202 - accepted (asynchronously)
+       if res.StatusCode != 200 && res.StatusCode != 202 {
+               bod, _ := ioutil.ReadAll(io.LimitReader(res.Body, 512))
+               if terse {
+                       var outBuf interface{}
+
+                       err := json.Unmarshal(bod, &outBuf)
+                       if err == nil && outBuf != nil {
+                               switch errText := outBuf.(type) {
+                               case string:
+                                       return fmt.Errorf("%s", errText)
+                               case map[string]interface{}:
+                                       errField := errText["errors"]
+                                       if errField != nil {
+
+                                               // remove annoying 'map' prefix
+                                               return fmt.Errorf("%s", strings.TrimPrefix(fmt.Sprintf("%v", errField), "map"))
+                                       }
+                               }
+                       }
+                       return fmt.Errorf("%s", string(bod))
+               }
+               return fmt.Errorf("HTTP error %v getting %q: %s",
+                       res.Status, requestUrl, bod)
+       }
+
+       d := json.NewDecoder(res.Body)
+       // PUT/POST/DELETE request may not have a response body
+       if d.More() {
+               if err = d.Decode(&out); err != nil {
+                       return err
+               }
+       }
+
+       return nil
+}
+
+func queryRestAPI(
+       baseURL *url.URL,
+       path string,
+       authHandler AuthHandler,
+       out interface{},
+       terse bool) error {
+
+       var requestUrl string
+
+       if q := strings.Index(path, "?"); q > 0 {
+               requestUrl = baseURL.Scheme + "://" + baseURL.Host + path[:q] + "?" + path[q+1:]
+       } else {
+               requestUrl = baseURL.Scheme + "://" + baseURL.Host + path
+       }
+
+       req, err := http.NewRequest("GET", requestUrl, nil)
+       if err != nil {
+               return err
+       }
+
+       err = maybeAddAuth(req, authHandler)
+       if err != nil {
+               return err
+       }
+
+       res, err := doHTTPRequest(req)
+       if err != nil {
+               return err
+       }
+
+       defer res.Body.Close()
+       if res.StatusCode != 200 {
+               bod, _ := ioutil.ReadAll(io.LimitReader(res.Body, 512))
+               if terse {
+                       var outBuf interface{}
+
+                       err := json.Unmarshal(bod, &outBuf)
+                       if err == nil && outBuf != nil {
+                               errText, ok := outBuf.(string)
+                               if ok {
+                                       return fmt.Errorf(errText)
+                               }
+                       }
+                       return fmt.Errorf(string(bod))
+               }
+               return fmt.Errorf("HTTP error %v getting %q: %s",
+                       res.Status, requestUrl, bod)
+       }
+
+       d := json.NewDecoder(res.Body)
+       // GET request should have a response body
+       if err = d.Decode(&out); err != nil {
+               return fmt.Errorf("json decode err: %#v, for requestUrl: %s",
+                       err, requestUrl)
+       }
+       return nil
+}
+
+func (c *Client) ProcessStream(path string, callb func(interface{}) error, data interface{}) error {
+       return c.processStream(c.BaseURL, path, c.ah, callb, data)
+}
+
+// Based on code in http://src.couchbase.org/source/xref/trunk/goproj/src/github.com/couchbase/indexing/secondary/dcp/pools.go#309
+func (c *Client) processStream(baseURL *url.URL, path string, authHandler AuthHandler, callb func(interface{}) error, data interface{}) error {
+       var requestUrl string
+
+       if q := strings.Index(path, "?"); q > 0 {
+               requestUrl = baseURL.Scheme + "://" + baseURL.Host + path[:q] + "?" + path[q+1:]
+       } else {
+               requestUrl = baseURL.Scheme + "://" + baseURL.Host + path
+       }
+
+       req, err := http.NewRequest("GET", requestUrl, nil)
+       if err != nil {
+               return err
+       }
+
+       err = maybeAddAuth(req, authHandler)
+       if err != nil {
+               return err
+       }
+
+       res, err := doHTTPRequestForStreaming(req)
+       if err != nil {
+               return err
+       }
+
+       defer res.Body.Close()
+       if res.StatusCode != 200 {
+               bod, _ := ioutil.ReadAll(io.LimitReader(res.Body, 512))
+               return fmt.Errorf("HTTP error %v getting %q: %s",
+                       res.Status, requestUrl, bod)
+       }
+
+       reader := bufio.NewReader(res.Body)
+       for {
+               bs, err := reader.ReadBytes('\n')
+               if err != nil {
+                       return err
+               }
+               if len(bs) == 1 && bs[0] == '\n' {
+                       continue
+               }
+
+               err = json.Unmarshal(bs, data)
+               if err != nil {
+                       return err
+               }
+               err = callb(data)
+               if err != nil {
+                       return err
+               }
+       }
+       return nil
+
+}
+
+func (c *Client) parseURLResponse(path string, out interface{}) error {
+       return queryRestAPI(c.BaseURL, path, c.ah, out, false)
+}
+
+func (c *Client) parsePostURLResponse(path string, params map[string]interface{}, out interface{}) error {
+       return doPostAPI(c.BaseURL, path, params, c.ah, out, false)
+}
+
+func (c *Client) parsePostURLResponseTerse(path string, params map[string]interface{}, out interface{}) error {
+       return doPostAPI(c.BaseURL, path, params, c.ah, out, true)
+}
+
+func (c *Client) parseDeleteURLResponse(path string, params map[string]interface{}, out interface{}) error {
+       return doDeleteAPI(c.BaseURL, path, params, c.ah, out, false)
+}
+
+func (c *Client) parseDeleteURLResponseTerse(path string, params map[string]interface{}, out interface{}) error {
+       return doDeleteAPI(c.BaseURL, path, params, c.ah, out, true)
+}
+
+func (c *Client) parsePutURLResponse(path string, params map[string]interface{}, out interface{}) error {
+       return doPutAPI(c.BaseURL, path, params, c.ah, out, false)
+}
+
+func (c *Client) parsePutURLResponseTerse(path string, params map[string]interface{}, out interface{}) error {
+       return doPutAPI(c.BaseURL, path, params, c.ah, out, true)
+}
+
+func (b *Bucket) parseURLResponse(path string, out interface{}) error {
+       nodes := b.Nodes()
+       if len(nodes) == 0 {
+               return errors.New("no couch rest URLs")
+       }
+
+       // Pick a random node to start querying.
+       startNode := rand.Intn(len(nodes))
+       maxRetries := len(nodes)
+       for i := 0; i < maxRetries; i++ {
+               node := nodes[(startNode+i)%len(nodes)] // Wrap around the nodes list.
+               // Skip non-healthy nodes.
+               if node.Status != "healthy" || node.CouchAPIBase == "" {
+                       continue
+               }
+               url := &url.URL{
+                       Host:   node.Hostname,
+                       Scheme: "http",
+               }
+
+               // Lock here to avoid having pool closed under us.
+               b.RLock()
+               err := queryRestAPI(url, path, b.pool.client.ah, out, false)
+               b.RUnlock()
+               if err == nil {
+                       return err
+               }
+       }
+       return errors.New("All nodes failed to respond or no healthy nodes for bucket found")
+}
+
+func (b *Bucket) parseAPIResponse(path string, out interface{}) error {
+       nodes := b.Nodes()
+       if len(nodes) == 0 {
+               return errors.New("no couch rest URLs")
+       }
+
+       var err error
+       var u *url.URL
+
+       // Pick a random node to start querying.
+       startNode := rand.Intn(len(nodes))
+       maxRetries := len(nodes)
+       for i := 0; i < maxRetries; i++ {
+               node := nodes[(startNode+i)%len(nodes)] // Wrap around the nodes list.
+               // Skip non-healthy nodes.
+               if node.Status != "healthy" || node.CouchAPIBase == "" {
+                       continue
+               }
+
+               u, err = ParseURL(node.CouchAPIBase)
+               // Lock here so pool does not get closed under us.
+               b.RLock()
+               if err != nil {
+                       b.RUnlock()
+                       return fmt.Errorf("config error: Bucket %q node #%d CouchAPIBase=%q: %v",
+                               b.Name, i, node.CouchAPIBase, err)
+               } else if b.pool != nil {
+                       u.User = b.pool.client.BaseURL.User
+               }
+               u.Path = path
+
+               // generate the path so that the strings are properly escaped
+               // MB-13770
+               requestPath := strings.Split(u.String(), u.Host)[1]
+
+               err = queryRestAPI(u, requestPath, b.pool.client.ah, out, false)
+               b.RUnlock()
+               if err == nil {
+                       return err
+               }
+       }
+
+       var errStr string
+       if err != nil {
+               errStr = "Error " + err.Error()
+       }
+
+       return errors.New("All nodes failed to respond or returned error or no healthy nodes for bucket found." + errStr)
+}
+
+type basicAuth struct {
+       u, p string
+}
+
+func (b basicAuth) GetCredentials() (string, string, string) {
+       return b.u, b.p, b.u
+}
+
+func basicAuthFromURL(us string) (ah AuthHandler) {
+       u, err := ParseURL(us)
+       if err != nil {
+               return
+       }
+       if user := u.User; user != nil {
+               pw, _ := user.Password()
+               ah = basicAuth{user.Username(), pw}
+       }
+       return
+}
+
+// ConnectWithAuth connects to a couchbase cluster with the given
+// authentication handler.
+func ConnectWithAuth(baseU string, ah AuthHandler) (c Client, err error) {
+       c.BaseURL, err = ParseURL(baseU)
+       if err != nil {
+               return
+       }
+       c.ah = ah
+
+       return c, c.parseURLResponse("/pools", &c.Info)
+}
+
+// Call this method with a TLS certificate file name to make communication
+// with the KV engine encrypted.
+//
+// This method should be called immediately after a Connect*() method.
+func (c *Client) InitTLS(certFile string) error {
+       serverCert, err := ioutil.ReadFile(certFile)
+       if err != nil {
+               return err
+       }
+       CA_Pool := x509.NewCertPool()
+       CA_Pool.AppendCertsFromPEM(serverCert)
+       c.tlsConfig = &tls.Config{RootCAs: CA_Pool}
+       return nil
+}
+
+func (c *Client) ClearTLS() {
+       c.tlsConfig = nil
+}
+
+// ConnectWithAuthCreds connects to a couchbase cluster with the give
+// authorization creds returned by cb_auth
+func ConnectWithAuthCreds(baseU, username, password string) (c Client, err error) {
+       c.BaseURL, err = ParseURL(baseU)
+       if err != nil {
+               return
+       }
+
+       c.ah = newBucketAuth(username, password, "")
+       return c, c.parseURLResponse("/pools", &c.Info)
+}
+
+// Connect to a couchbase cluster.  An authentication handler will be
+// created from the userinfo in the URL if provided.
+func Connect(baseU string) (Client, error) {
+       return ConnectWithAuth(baseU, basicAuthFromURL(baseU))
+}
+
+type BucketInfo struct {
+       Name     string // name of bucket
+       Password string // SASL password of bucket
+}
+
+//Get SASL buckets
+func GetBucketList(baseU string) (bInfo []BucketInfo, err error) {
+
+       c := &Client{}
+       c.BaseURL, err = ParseURL(baseU)
+       if err != nil {
+               return
+       }
+       c.ah = basicAuthFromURL(baseU)
+
+       var buckets []Bucket
+       err = c.parseURLResponse("/pools/default/buckets", &buckets)
+       if err != nil {
+               return
+       }
+       bInfo = make([]BucketInfo, 0)
+       for _, bucket := range buckets {
+               bucketInfo := BucketInfo{Name: bucket.Name, Password: bucket.Password}
+               bInfo = append(bInfo, bucketInfo)
+       }
+       return bInfo, err
+}
+
+//Set viewUpdateDaemonOptions
+func SetViewUpdateParams(baseU string, params map[string]interface{}) (viewOpts map[string]interface{}, err error) {
+
+       c := &Client{}
+       c.BaseURL, err = ParseURL(baseU)
+       if err != nil {
+               return
+       }
+       c.ah = basicAuthFromURL(baseU)
+
+       if len(params) < 1 {
+               return nil, fmt.Errorf("No params to set")
+       }
+
+       err = c.parsePostURLResponse("/settings/viewUpdateDaemon", params, &viewOpts)
+       if err != nil {
+               return
+       }
+       return viewOpts, err
+}
+
+// This API lets the caller know, if the list of nodes a bucket is
+// connected to has gone through an edit (a rebalance operation)
+// since the last update to the bucket, in which case a Refresh is
+// advised.
+func (b *Bucket) NodeListChanged() bool {
+       b.RLock()
+       pool := b.pool
+       uri := b.URI
+       b.RUnlock()
+
+       tmpb := &Bucket{}
+       err := pool.client.parseURLResponse(uri, tmpb)
+       if err != nil {
+               return true
+       }
+
+       bNodes := *(*[]Node)(b.nodeList)
+       if len(bNodes) != len(tmpb.NodesJSON) {
+               return true
+       }
+
+       bucketHostnames := map[string]bool{}
+       for _, node := range bNodes {
+               bucketHostnames[node.Hostname] = true
+       }
+
+       for _, node := range tmpb.NodesJSON {
+               if _, found := bucketHostnames[node.Hostname]; !found {
+                       return true
+               }
+       }
+
+       return false
+}
+
+// Sample data for scopes and collections as returned from the
+// /pooles/default/$BUCKET_NAME/collections API.
+// {"myScope2":{"myCollectionC":{}},"myScope1":{"myCollectionB":{},"myCollectionA":{}},"_default":{"_default":{}}}
+
+// Structures for parsing collections manifest.
+// The map key is the name of the scope.
+// Example data:
+// {"uid":"b","scopes":[
+//    {"name":"_default","uid":"0","collections":[
+//       {"name":"_default","uid":"0"}]},
+//    {"name":"myScope1","uid":"8","collections":[
+//       {"name":"myCollectionB","uid":"c"},
+//       {"name":"myCollectionA","uid":"b"}]},
+//    {"name":"myScope2","uid":"9","collections":[
+//       {"name":"myCollectionC","uid":"d"}]}]}
+type InputManifest struct {
+       Uid    string
+       Scopes []InputScope
+}
+type InputScope struct {
+       Name        string
+       Uid         string
+       Collections []InputCollection
+}
+type InputCollection struct {
+       Name string
+       Uid  string
+}
+
+// Structures for storing collections information.
+type Manifest struct {
+       Uid    uint64
+       Scopes map[string]*Scope // map by name
+}
+type Scope struct {
+       Name        string
+       Uid         uint64
+       Collections map[string]*Collection // map by name
+}
+type Collection struct {
+       Name string
+       Uid  uint64
+}
+
+var _EMPTY_MANIFEST *Manifest = &Manifest{Uid: 0, Scopes: map[string]*Scope{}}
+
+func parseCollectionsManifest(res *gomemcached.MCResponse) (*Manifest, error) {
+       if !EnableCollections {
+               return _EMPTY_MANIFEST, nil
+       }
+
+       var im InputManifest
+       err := json.Unmarshal(res.Body, &im)
+       if err != nil {
+               return nil, err
+       }
+
+       uid, err := strconv.ParseUint(im.Uid, 16, 64)
+       if err != nil {
+               return nil, err
+       }
+       mani := &Manifest{Uid: uid, Scopes: make(map[string]*Scope, len(im.Scopes))}
+       for _, iscope := range im.Scopes {
+               scope_uid, err := strconv.ParseUint(iscope.Uid, 16, 64)
+               if err != nil {
+                       return nil, err
+               }
+               scope := &Scope{Uid: scope_uid, Name: iscope.Name, Collections: make(map[string]*Collection, len(iscope.Collections))}
+               mani.Scopes[iscope.Name] = scope
+               for _, icoll := range iscope.Collections {
+                       coll_uid, err := strconv.ParseUint(icoll.Uid, 16, 64)
+                       if err != nil {
+                               return nil, err
+                       }
+                       coll := &Collection{Uid: coll_uid, Name: icoll.Name}
+                       scope.Collections[icoll.Name] = coll
+               }
+       }
+
+       return mani, nil
+}
+
+// This function assumes the bucket is locked.
+func (b *Bucket) GetCollectionsManifest() (*Manifest, error) {
+       // Collections not used?
+       if !EnableCollections {
+               return nil, fmt.Errorf("Collections not enabled.")
+       }
+
+       b.RLock()
+       pools := b.getConnPools(true /* already locked */)
+       pool := pools[0] // Any pool will do, so use the first one.
+       b.RUnlock()
+       client, err := pool.Get()
+       if err != nil {
+               return nil, fmt.Errorf("Unable to get connection to retrieve collections manifest: %v. No collections access to bucket %s.", err, b.Name)
+       }
+       client.SetDeadline(getDeadline(time.Time{}, DefaultTimeout))
+
+       // We need to select the bucket before GetCollectionsManifest()
+       // will work. This is sometimes done at startup (see defaultMkConn())
+       // but not always, depending on the auth type.
+       // Doing this is safe because we collect the the connections
+       // by bucket, so the bucket being selected will never change.
+       _, err = client.SelectBucket(b.Name)
+       if err != nil {
+               pool.Return(client)
+               return nil, fmt.Errorf("Unable to select bucket %s: %v. No collections access to bucket %s.", err, b.Name, b.Name)
+       }
+
+       res, err := client.GetCollectionsManifest()
+       if err != nil {
+               pool.Return(client)
+               return nil, fmt.Errorf("Unable to retrieve collections manifest: %v. No collections access to bucket %s.", err, b.Name)
+       }
+       mani, err := parseCollectionsManifest(res)
+       if err != nil {
+               pool.Return(client)
+               return nil, fmt.Errorf("Unable to parse collections manifest: %v. No collections access to bucket %s.", err, b.Name)
+       }
+
+       pool.Return(client)
+       return mani, nil
+}
+
+func (b *Bucket) RefreshFully() error {
+       return b.refresh(false)
+}
+
+func (b *Bucket) Refresh() error {
+       return b.refresh(true)
+}
+
+func (b *Bucket) refresh(preserveConnections bool) error {
+       b.RLock()
+       pool := b.pool
+       uri := b.URI
+       client := pool.client
+       b.RUnlock()
+
+       var poolServices PoolServices
+       var err error
+       if client.tlsConfig != nil {
+               poolServices, err = client.GetPoolServices("default")
+               if err != nil {
+                       return err
+               }
+       }
+
+       tmpb := &Bucket{}
+       err = pool.client.parseURLResponse(uri, tmpb)
+       if err != nil {
+               return err
+       }
+
+       pools := b.getConnPools(false /* bucket not already locked */)
+
+       // We need this lock to ensure that bucket refreshes happening because
+       // of NMVb errors received during bulkGet do not end up over-writing
+       // pool.inUse.
+       b.Lock()
+
+       for _, pool := range pools {
+               if pool != nil {
+                       pool.inUse = false
+               }
+       }
+
+       newcps := make([]*connectionPool, len(tmpb.VBSMJson.ServerList))
+       for i := range newcps {
+               hostport := tmpb.VBSMJson.ServerList[i]
+               if preserveConnections {
+                       pool := b.getConnPoolByHost(hostport, true /* bucket already locked */)
+                       if pool != nil && pool.inUse == false && (!pool.encrypted || pool.tlsConfig == client.tlsConfig) {
+                               // if the hostname and index is unchanged then reuse this pool
+                               newcps[i] = pool
+                               pool.inUse = true
+                               continue
+                       }
+               }
+
+               var encrypted bool
+               if client.tlsConfig != nil {
+                       hostport, encrypted, err = MapKVtoSSL(hostport, &poolServices)
+                       if err != nil {
+                               b.Unlock()
+                               return err
+                       }
+               }
+
+               if b.ah != nil {
+                       newcps[i] = newConnectionPool(hostport,
+                               b.ah, AsynchronousCloser, PoolSize, PoolOverflow, client.tlsConfig, b.Name, encrypted)
+
+               } else {
+                       newcps[i] = newConnectionPool(hostport,
+                               b.authHandler(true /* bucket already locked */),
+                               AsynchronousCloser, PoolSize, PoolOverflow, client.tlsConfig, b.Name, encrypted)
+               }
+       }
+       b.replaceConnPools2(newcps, true /* bucket already locked */)
+       tmpb.ah = b.ah
+       b.vBucketServerMap = unsafe.Pointer(&tmpb.VBSMJson)
+       b.nodeList = unsafe.Pointer(&tmpb.NodesJSON)
+
+       b.Unlock()
+       return nil
+}
+
+func (p *Pool) refresh() (err error) {
+       p.BucketMap = make(map[string]*Bucket)
+
+       buckets := []Bucket{}
+       err = p.client.parseURLResponse(p.BucketURL["uri"], &buckets)
+       if err != nil {
+               return err
+       }
+       for i, _ := range buckets {
+               b := new(Bucket)
+               *b = buckets[i]
+               b.pool = p
+               b.nodeList = unsafe.Pointer(&b.NodesJSON)
+
+               // MB-33185 this is merely defensive, just in case
+               // refresh() gets called on a perfectly node pool
+               ob, ok := p.BucketMap[b.Name]
+               if ok && ob.connPools != nil {
+                       ob.Close()
+               }
+               b.replaceConnPools(make([]*connectionPool, len(b.VBSMJson.ServerList)))
+               p.BucketMap[b.Name] = b
+               runtime.SetFinalizer(b, bucketFinalizer)
+       }
+       buckets = nil
+       return nil
+}
+
+// GetPool gets a pool from within the couchbase cluster (usually
+// "default").
+func (c *Client) GetPool(name string) (p Pool, err error) {
+       var poolURI string
+
+       for _, p := range c.Info.Pools {
+               if p.Name == name {
+                       poolURI = p.URI
+                       break
+               }
+       }
+       if poolURI == "" {
+               return p, errors.New("No pool named " + name)
+       }
+
+       err = c.parseURLResponse(poolURI, &p)
+       if err != nil {
+               return p, err
+       }
+
+       p.client = c
+
+       err = p.refresh()
+       return
+}
+
+// GetPoolServices returns all the bucket-independent services in a pool.
+// (See "Exposing services outside of bucket context" in http://goo.gl/uuXRkV)
+func (c *Client) GetPoolServices(name string) (ps PoolServices, err error) {
+       var poolName string
+       for _, p := range c.Info.Pools {
+               if p.Name == name {
+                       poolName = p.Name
+               }
+       }
+       if poolName == "" {
+               return ps, errors.New("No pool named " + name)
+       }
+
+       poolURI := "/pools/" + poolName + "/nodeServices"
+       err = c.parseURLResponse(poolURI, &ps)
+
+       return
+}
+
+func (b *Bucket) GetPoolServices(name string) (*PoolServices, error) {
+       b.RLock()
+       pool := b.pool
+       b.RUnlock()
+
+       ps, err := pool.client.GetPoolServices(name)
+       if err != nil {
+               return nil, err
+       }
+
+       return &ps, nil
+}
+
+// Close marks this bucket as no longer needed, closing connections it
+// may have open.
+func (b *Bucket) Close() {
+       b.Lock()
+       defer b.Unlock()
+       if b.connPools != nil {
+               for _, c := range b.getConnPools(true /* already locked */) {
+                       if c != nil {
+                               c.Close()
+                       }
+               }
+               b.connPools = nil
+       }
+}
+
+func bucketFinalizer(b *Bucket) {
+       if b.connPools != nil {
+               if !b.closed {
+                       logging.Warnf("Finalizing a bucket with active connections.")
+               }
+
+               // MB-33185 do not leak connection pools
+               b.Close()
+       }
+}
+
+// GetBucket gets a bucket from within this pool.
+func (p *Pool) GetBucket(name string) (*Bucket, error) {
+       rv, ok := p.BucketMap[name]
+       if !ok {
+               return nil, &BucketNotFoundError{bucket: name}
+       }
+       err := rv.Refresh()
+       if err != nil {
+               return nil, err
+       }
+       return rv, nil
+}
+
+// GetBucket gets a bucket from within this pool.
+func (p *Pool) GetBucketWithAuth(bucket, username, password string) (*Bucket, error) {
+       rv, ok := p.BucketMap[bucket]
+       if !ok {
+               return nil, &BucketNotFoundError{bucket: bucket}
+       }
+       rv.ah = newBucketAuth(username, password, bucket)
+       err := rv.Refresh()
+       if err != nil {
+               return nil, err
+       }
+       return rv, nil
+}
+
+// GetPool gets the pool to which this bucket belongs.
+func (b *Bucket) GetPool() *Pool {
+       b.RLock()
+       defer b.RUnlock()
+       ret := b.pool
+       return ret
+}
+
+// GetClient gets the client from which we got this pool.
+func (p *Pool) GetClient() *Client {
+       return p.client
+}
+
+// Release bucket connections when the pool is no longer in use
+func (p *Pool) Close() {
+
+       // MB-36186 make the bucket map inaccessible
+       bucketMap := p.BucketMap
+       p.BucketMap = nil
+
+       // fine to loop through the buckets unlocked
+       // locking happens at the bucket level
+       for b, _ := range bucketMap {
+
+               // MB-36186 make the bucket unreachable and avoid concurrent read/write map panics
+               bucket := bucketMap[b]
+               bucketMap[b] = nil
+
+               bucket.Lock()
+
+               // MB-33208 defer closing connection pools until the bucket is no longer used
+               // MB-36186 if the bucket is unused make it unreachable straight away
+               needClose := bucket.connPools == nil && !bucket.closed
+               if needClose {
+                       runtime.SetFinalizer(&bucket, nil)
+               }
+               bucket.closed = true
+               bucket.Unlock()
+               if needClose {
+                       bucket.Close()
+               }
+       }
+}
+
+// GetBucket is a convenience function for getting a named bucket from
+// a URL
+func GetBucket(endpoint, poolname, bucketname string) (*Bucket, error) {
+       var err error
+       client, err := Connect(endpoint)
+       if err != nil {
+               return nil, err
+       }
+
+       pool, err := client.GetPool(poolname)
+       if err != nil {
+               return nil, err
+       }
+
+       return pool.GetBucket(bucketname)
+}
+
+// ConnectWithAuthAndGetBucket is a convenience function for
+// getting a named bucket from a given URL and an auth callback
+func ConnectWithAuthAndGetBucket(endpoint, poolname, bucketname string,
+       ah AuthHandler) (*Bucket, error) {
+       client, err := ConnectWithAuth(endpoint, ah)
+       if err != nil {
+               return nil, err
+       }
+
+       pool, err := client.GetPool(poolname)
+       if err != nil {
+               return nil, err
+       }
+
+       return pool.GetBucket(bucketname)
+}
+
+func GetSystemBucket(c *Client, p *Pool, name string) (*Bucket, error) {
+       bucket, err := p.GetBucket(name)
+       if err != nil {
+               if _, ok := err.(*BucketNotFoundError); !ok {
+                       return nil, err
+               }
+
+               // create the bucket if not found
+               args := map[string]interface{}{
+                       "authType":     "sasl",
+                       "bucketType":   "couchbase",
+                       "name":         name,
+                       "ramQuotaMB":   100,
+                       "saslPassword": "donotuse",
+               }
+               var ret interface{}
+               // allow "bucket already exists" error in case duplicate create
+               // (e.g. two query nodes starting at same time)
+               err = c.parsePostURLResponseTerse("/pools/default/buckets", args, &ret)
+               if err != nil && !AlreadyExistsError(err) {
+                       return nil, err
+               }
+
+               // bucket created asynchronously, try to get the bucket
+               maxRetry := 8
+               interval := 100 * time.Millisecond
+               for i := 0; i < maxRetry; i++ {
+                       time.Sleep(interval)
+                       interval *= 2
+                       err = p.refresh()
+                       if err != nil {
+                               return nil, err
+                       }
+                       bucket, err = p.GetBucket(name)
+                       if bucket != nil {
+                               bucket.RLock()
+                               ok := !bucket.closed && len(bucket.getConnPools(true /* already locked */)) > 0
+                               bucket.RUnlock()
+                               if ok {
+                                       break
+                               }
+                       } else if err != nil {
+                               if _, ok := err.(*BucketNotFoundError); !ok {
+                                       break
+                               }
+                       }
+               }
+       }
+
+       return bucket, err
+}
+
+func DropSystemBucket(c *Client, name string) error {
+       err := c.parseDeleteURLResponseTerse("/pools/default/buckets/"+name, nil, nil)
+       return err
+}
+
+func AlreadyExistsError(err error) bool {
+       // Bucket error:     Bucket with given name already exists
+       // Scope error:      Scope with this name already exists
+       // Collection error: Collection with this name already exists
+       return strings.Contains(err.Error(), " name already exists")
+}
diff --git a/vendor/github.com/couchbase/go-couchbase/port_map.go b/vendor/github.com/couchbase/go-couchbase/port_map.go
new file mode 100644 (file)
index 0000000..864bd4a
--- /dev/null
@@ -0,0 +1,106 @@
+package couchbase
+
+/*
+
+The goal here is to map a hostname:port combination to another hostname:port
+combination. The original hostname:port gives the name and regular KV port
+of a couchbase server. We want to determine the corresponding SSL KV port.
+
+To do this, we have a pool services structure, as obtained from
+the /pools/default/nodeServices API.
+
+For a fully configured two-node system, the structure may look like this:
+{"rev":32,"nodesExt":[
+       {"services":{"mgmt":8091,"mgmtSSL":18091,"fts":8094,"ftsSSL":18094,"indexAdmin":9100,"indexScan":9101,"indexHttp":9102,"indexStreamInit":9103,"indexStreamCatchup":9104,"indexStreamMaint":9105,"indexHttps":19102,"capiSSL":18092,"capi":8092,"kvSSL":11207,"projector":9999,"kv":11210,"moxi":11211},"hostname":"172.23.123.101"},
+       {"services":{"mgmt":8091,"mgmtSSL":18091,"indexAdmin":9100,"indexScan":9101,"indexHttp":9102,"indexStreamInit":9103,"indexStreamCatchup":9104,"indexStreamMaint":9105,"indexHttps":19102,"capiSSL":18092,"capi":8092,"kvSSL":11207,"projector":9999,"kv":11210,"moxi":11211,"n1ql":8093,"n1qlSSL":18093},"thisNode":true,"hostname":"172.23.123.102"}]}
+
+In this case, note the "hostname" fields, and the "kv" and "kvSSL" fields.
+
+For a single-node system, perhaps brought up for testing, the structure may look like this:
+{"rev":66,"nodesExt":[
+       {"services":{"mgmt":8091,"mgmtSSL":18091,"indexAdmin":9100,"indexScan":9101,"indexHttp":9102,"indexStreamInit":9103,"indexStreamCatchup":9104,"indexStreamMaint":9105,"indexHttps":19102,"kv":11210,"kvSSL":11207,"capi":8092,"capiSSL":18092,"projector":9999,"n1ql":8093,"n1qlSSL":18093},"thisNode":true}],"clusterCapabilitiesVer":[1,0],"clusterCapabilities":{"n1ql":["enhancedPreparedStatements"]}}
+
+Here, note that there is only a single entry in the "nodeExt" array and that it does not have a "hostname" field.
+We will assume that either hostname fields are present, or there is only a single node.
+*/
+
+import (
+       "encoding/json"
+       "fmt"
+       "net"
+       "strconv"
+)
+
+func ParsePoolServices(jsonInput string) (*PoolServices, error) {
+       ps := &PoolServices{}
+       err := json.Unmarshal([]byte(jsonInput), ps)
+       return ps, err
+}
+
+// Accepts a "host:port" string representing the KV TCP port and the pools
+// nodeServices payload and returns a host:port string representing the KV
+// TLS port on the same node as the KV TCP port.
+// Returns the original host:port if in case of local communication (services
+// on the same node as source)
+func MapKVtoSSL(hostport string, ps *PoolServices) (string, bool, error) {
+       return MapKVtoSSLExt(hostport, ps, false)
+}
+
+func MapKVtoSSLExt(hostport string, ps *PoolServices, force bool) (string, bool, error) {
+       host, port, err := net.SplitHostPort(hostport)
+       if err != nil {
+               return "", false, fmt.Errorf("Unable to split hostport %s: %v", hostport, err)
+       }
+
+       portInt, err := strconv.Atoi(port)
+       if err != nil {
+               return "", false, fmt.Errorf("Unable to parse host/port combination %s: %v", hostport, err)
+       }
+
+       var ns *NodeServices
+       for i := range ps.NodesExt {
+               hostname := ps.NodesExt[i].Hostname
+               if len(hostname) != 0 && hostname != host {
+                       /* If the hostname is the empty string, it means the node (and by extension
+                          the cluster) is configured on the loopback. Further, it means that the client
+                          should use whatever hostname it used to get the nodeServices information in
+                          the first place to access the cluster. Thus, when the hostname is empty in
+                          the nodeService entry we can assume that client will use the hostname it used
+                          to access the KV TCP endpoint - and thus that it automatically "matches".
+                          If hostname is not empty and doesn't match then we move to the next entry.
+                       */
+                       continue
+               }
+               kvPort, found := ps.NodesExt[i].Services["kv"]
+               if !found {
+                       /* not a node with a KV service  */
+                       continue
+               }
+               if kvPort == portInt {
+                       ns = &(ps.NodesExt[i])
+                       break
+               }
+       }
+
+       if ns == nil {
+               return "", false, fmt.Errorf("Unable to parse host/port combination %s: no matching node found among %d", hostport, len(ps.NodesExt))
+       }
+       kvSSL, found := ns.Services["kvSSL"]
+       if !found {
+               return "", false, fmt.Errorf("Unable to map host/port combination %s: target host has no kvSSL port listed", hostport)
+       }
+
+       //Don't encrypt for communication between local nodes
+       if !force && (len(ns.Hostname) == 0 || ns.ThisNode) {
+               return hostport, false, nil
+       }
+
+       ip := net.ParseIP(host)
+       if ip != nil && ip.To4() == nil && ip.To16() != nil { // IPv6 and not a FQDN
+               // Prefix and suffix square brackets as SplitHostPort removes them,
+               // see: https://golang.org/pkg/net/#SplitHostPort
+               host = "[" + host + "]"
+       }
+
+       return fmt.Sprintf("%s:%d", host, kvSSL), true, nil
+}
diff --git a/vendor/github.com/couchbase/go-couchbase/streaming.go b/vendor/github.com/couchbase/go-couchbase/streaming.go
new file mode 100644 (file)
index 0000000..ecf5be9
--- /dev/null
@@ -0,0 +1,228 @@
+package couchbase
+
+import (
+       "encoding/json"
+       "fmt"
+       "github.com/couchbase/goutils/logging"
+       "io"
+       "io/ioutil"
+       "math/rand"
+       "net"
+       "net/http"
+       "time"
+       "unsafe"
+)
+
+// Bucket auto-updater gets the latest version of the bucket config from
+// the server. If the configuration has changed then updated the local
+// bucket information. If the bucket has been deleted then notify anyone
+// who is holding a reference to this bucket
+
+const MAX_RETRY_COUNT = 5
+const DISCONNECT_PERIOD = 120 * time.Second
+
+type NotifyFn func(bucket string, err error)
+type StreamingFn func(bucket *Bucket)
+
+// Use TCP keepalive to detect half close sockets
+var updaterTransport http.RoundTripper = &http.Transport{
+       Proxy: http.ProxyFromEnvironment,
+       Dial: (&net.Dialer{
+               Timeout:   30 * time.Second,
+               KeepAlive: 30 * time.Second,
+       }).Dial,
+}
+
+var updaterHTTPClient = &http.Client{Transport: updaterTransport}
+
+func doHTTPRequestForUpdate(req *http.Request) (*http.Response, error) {
+
+       var err error
+       var res *http.Response
+
+       for i := 0; i < HTTP_MAX_RETRY; i++ {
+               res, err = updaterHTTPClient.Do(req)
+               if err != nil && isHttpConnError(err) {
+                       continue
+               }
+               break
+       }
+
+       if err != nil {
+               return nil, err
+       }
+
+       return res, err
+}
+
+func (b *Bucket) RunBucketUpdater(notify NotifyFn) {
+       b.RunBucketUpdater2(nil, notify)
+}
+
+func (b *Bucket) RunBucketUpdater2(streamingFn StreamingFn, notify NotifyFn) {
+       go func() {
+               err := b.UpdateBucket2(streamingFn)
+               if err != nil {
+                       if notify != nil {
+                               notify(b.GetName(), err)
+                       }
+                       logging.Errorf(" Bucket Updater exited with err %v", err)
+               }
+       }()
+}
+
+func (b *Bucket) replaceConnPools2(with []*connectionPool, bucketLocked bool) {
+       if !bucketLocked {
+               b.Lock()
+               defer b.Unlock()
+       }
+       old := b.connPools
+       b.connPools = unsafe.Pointer(&with)
+       if old != nil {
+               for _, pool := range *(*[]*connectionPool)(old) {
+                       if pool != nil && pool.inUse == false {
+                               pool.Close()
+                       }
+               }
+       }
+       return
+}
+
+func (b *Bucket) UpdateBucket() error {
+       return b.UpdateBucket2(nil)
+}
+
+func (b *Bucket) UpdateBucket2(streamingFn StreamingFn) error {
+       var failures int
+       var returnErr error
+       var poolServices PoolServices
+
+       for {
+
+               if failures == MAX_RETRY_COUNT {
+                       logging.Errorf(" Maximum failures reached. Exiting loop...")
+                       return fmt.Errorf("Max failures reached. Last Error %v", returnErr)
+               }
+
+               nodes := b.Nodes()
+               if len(nodes) < 1 {
+                       return fmt.Errorf("No healthy nodes found")
+               }
+
+               startNode := rand.Intn(len(nodes))
+               node := nodes[(startNode)%len(nodes)]
+
+               streamUrl := fmt.Sprintf("http://%s/pools/default/bucketsStreaming/%s", node.Hostname, uriAdj(b.GetName()))
+               logging.Infof(" Trying with %s", streamUrl)
+               req, err := http.NewRequest("GET", streamUrl, nil)
+               if err != nil {
+                       return err
+               }
+
+               // Lock here to avoid having pool closed under us.
+               b.RLock()
+               err = maybeAddAuth(req, b.pool.client.ah)
+               b.RUnlock()
+               if err != nil {
+                       return err
+               }
+
+               res, err := doHTTPRequestForUpdate(req)
+               if err != nil {
+                       return err
+               }
+
+               if res.StatusCode != 200 {
+                       bod, _ := ioutil.ReadAll(io.LimitReader(res.Body, 512))
+                       logging.Errorf("Failed to connect to host, unexpected status code: %v. Body %s", res.StatusCode, bod)
+                       res.Body.Close()
+                       returnErr = fmt.Errorf("Failed to connect to host. Status %v Body %s", res.StatusCode, bod)
+                       failures++
+                       continue
+               }
+
+               dec := json.NewDecoder(res.Body)
+
+               tmpb := &Bucket{}
+               for {
+
+                       err := dec.Decode(&tmpb)
+                       if err != nil {
+                               returnErr = err
+                               res.Body.Close()
+                               break
+                       }
+
+                       // if we got here, reset failure count
+                       failures = 0
+
+                       if b.pool.client.tlsConfig != nil {
+                               poolServices, err = b.pool.client.GetPoolServices("default")
+                               if err != nil {
+                                       returnErr = err
+                                       res.Body.Close()
+                                       break
+                               }
+                       }
+
+                       b.Lock()
+
+                       // mark all the old connection pools for deletion
+                       pools := b.getConnPools(true /* already locked */)
+                       for _, pool := range pools {
+                               if pool != nil {
+                                       pool.inUse = false
+                               }
+                       }
+
+                       newcps := make([]*connectionPool, len(tmpb.VBSMJson.ServerList))
+                       for i := range newcps {
+                               // get the old connection pool and check if it is still valid
+                               pool := b.getConnPoolByHost(tmpb.VBSMJson.ServerList[i], true /* bucket already locked */)
+                               if pool != nil && pool.inUse == false && pool.tlsConfig == b.pool.client.tlsConfig {
+                                       // if the hostname and index is unchanged then reuse this pool
+                                       newcps[i] = pool
+                                       pool.inUse = true
+                                       continue
+                               }
+                               // else create a new pool
+                               var encrypted bool
+                               hostport := tmpb.VBSMJson.ServerList[i]
+                               if b.pool.client.tlsConfig != nil {
+                                       hostport, encrypted, err = MapKVtoSSL(hostport, &poolServices)
+                                       if err != nil {
+                                               b.Unlock()
+                                               return err
+                                       }
+                               }
+                               if b.ah != nil {
+                                       newcps[i] = newConnectionPool(hostport,
+                                               b.ah, false, PoolSize, PoolOverflow, b.pool.client.tlsConfig, b.Name, encrypted)
+
+                               } else {
+                                       newcps[i] = newConnectionPool(hostport,
+                                               b.authHandler(true /* bucket already locked */),
+                                               false, PoolSize, PoolOverflow, b.pool.client.tlsConfig, b.Name, encrypted)
+                               }
+                       }
+
+                       b.replaceConnPools2(newcps, true /* bucket already locked */)
+
+                       tmpb.ah = b.ah
+                       b.vBucketServerMap = unsafe.Pointer(&tmpb.VBSMJson)
+                       b.nodeList = unsafe.Pointer(&tmpb.NodesJSON)
+                       b.Unlock()
+
+                       if streamingFn != nil {
+                               streamingFn(tmpb)
+                       }
+                       logging.Debugf("Got new configuration for bucket %s", b.GetName())
+
+               }
+               // we are here because of an error
+               failures++
+               continue
+
+       }
+       return nil
+}
diff --git a/vendor/github.com/couchbase/go-couchbase/tap.go b/vendor/github.com/couchbase/go-couchbase/tap.go
new file mode 100644 (file)
index 0000000..86edd30
--- /dev/null
@@ -0,0 +1,143 @@
+package couchbase
+
+import (
+       "github.com/couchbase/gomemcached/client"
+       "github.com/couchbase/goutils/logging"
+       "sync"
+       "time"
+)
+
+const initialRetryInterval = 1 * time.Second
+const maximumRetryInterval = 30 * time.Second
+
+// A TapFeed streams mutation events from a bucket.
+//
+// Events from the bucket can be read from the channel 'C'.  Remember
+// to call Close() on it when you're done, unless its channel has
+// closed itself already.
+type TapFeed struct {
+       C <-chan memcached.TapEvent
+
+       bucket    *Bucket
+       args      *memcached.TapArguments
+       nodeFeeds []*memcached.TapFeed    // The TAP feeds of the individual nodes
+       output    chan memcached.TapEvent // Same as C but writeably-typed
+       wg        sync.WaitGroup
+       quit      chan bool
+}
+
+// StartTapFeed creates and starts a new Tap feed
+func (b *Bucket) StartTapFeed(args *memcached.TapArguments) (*TapFeed, error) {
+       if args == nil {
+               defaultArgs := memcached.DefaultTapArguments()
+               args = &defaultArgs
+       }
+
+       feed := &TapFeed{
+               bucket: b,
+               args:   args,
+               output: make(chan memcached.TapEvent, 10),
+               quit:   make(chan bool),
+       }
+
+       go feed.run()
+
+       feed.C = feed.output
+       return feed, nil
+}
+
+// Goroutine that runs the feed
+func (feed *TapFeed) run() {
+       retryInterval := initialRetryInterval
+       bucketOK := true
+       for {
+               // Connect to the TAP feed of each server node:
+               if bucketOK {
+                       killSwitch, err := feed.connectToNodes()
+                       if err == nil {
+                               // Run until one of the sub-feeds fails:
+                               select {
+                               case <-killSwitch:
+                               case <-feed.quit:
+                                       return
+                               }
+                               feed.closeNodeFeeds()
+                               retryInterval = initialRetryInterval
+                       }
+               }
+
+               // On error, try to refresh the bucket in case the list of nodes changed:
+               logging.Infof("go-couchbase: TAP connection lost; reconnecting to bucket %q in %v",
+                       feed.bucket.Name, retryInterval)
+               err := feed.bucket.Refresh()
+               bucketOK = err == nil
+
+               select {
+               case <-time.After(retryInterval):
+               case <-feed.quit:
+                       return
+               }
+               if retryInterval *= 2; retryInterval > maximumRetryInterval {
+                       retryInterval = maximumRetryInterval
+               }
+       }
+}
+
+func (feed *TapFeed) connectToNodes() (killSwitch chan bool, err error) {
+       killSwitch = make(chan bool)
+       for _, serverConn := range feed.bucket.getConnPools(false /* not already locked */) {
+               var singleFeed *memcached.TapFeed
+               singleFeed, err = serverConn.StartTapFeed(feed.args)
+               if err != nil {
+                       logging.Errorf("go-couchbase: Error connecting to tap feed of %s: %v", serverConn.host, err)
+                       feed.closeNodeFeeds()
+                       return
+               }
+               feed.nodeFeeds = append(feed.nodeFeeds, singleFeed)
+               go feed.forwardTapEvents(singleFeed, killSwitch, serverConn.host)
+               feed.wg.Add(1)
+       }
+       return
+}
+
+// Goroutine that forwards Tap events from a single node's feed to the aggregate feed.
+func (feed *TapFeed) forwardTapEvents(singleFeed *memcached.TapFeed, killSwitch chan bool, host string) {
+       defer feed.wg.Done()
+       for {
+               select {
+               case event, ok := <-singleFeed.C:
+                       if !ok {
+                               if singleFeed.Error != nil {
+                                       logging.Errorf("go-couchbase: Tap feed from %s failed: %v", host, singleFeed.Error)
+                               }
+                               killSwitch <- true
+                               return
+                       }
+                       feed.output <- event
+               case <-feed.quit:
+                       return
+               }
+       }
+}
+
+func (feed *TapFeed) closeNodeFeeds() {
+       for _, f := range feed.nodeFeeds {
+               f.Close()
+       }
+       feed.nodeFeeds = nil
+}
+
+// Close a Tap feed.
+func (feed *TapFeed) Close() error {
+       select {
+       case <-feed.quit:
+               return nil
+       default:
+       }
+
+       feed.closeNodeFeeds()
+       close(feed.quit)
+       feed.wg.Wait()
+       close(feed.output)
+       return nil
+}
diff --git a/vendor/github.com/couchbase/go-couchbase/upr.go b/vendor/github.com/couchbase/go-couchbase/upr.go
new file mode 100644 (file)
index 0000000..844bf91
--- /dev/null
@@ -0,0 +1,399 @@
+package couchbase
+
+import (
+       "log"
+       "sync"
+       "time"
+
+       "fmt"
+       "github.com/couchbase/gomemcached"
+       "github.com/couchbase/gomemcached/client"
+       "github.com/couchbase/goutils/logging"
+)
+
+// A UprFeed streams mutation events from a bucket.
+//
+// Events from the bucket can be read from the channel 'C'.  Remember
+// to call Close() on it when you're done, unless its channel has
+// closed itself already.
+type UprFeed struct {
+       C <-chan *memcached.UprEvent
+
+       bucket          *Bucket
+       nodeFeeds       map[string]*FeedInfo     // The UPR feeds of the individual nodes
+       output          chan *memcached.UprEvent // Same as C but writeably-typed
+       outputClosed    bool
+       quit            chan bool
+       name            string // name of this UPR feed
+       sequence        uint32 // sequence number for this feed
+       connected       bool
+       killSwitch      chan bool
+       closing         bool
+       wg              sync.WaitGroup
+       dcp_buffer_size uint32
+       data_chan_size  int
+}
+
+// UprFeed from a single connection
+type FeedInfo struct {
+       uprFeed   *memcached.UprFeed // UPR feed handle
+       host      string             // hostname
+       connected bool               // connected
+       quit      chan bool          // quit channel
+}
+
+type FailoverLog map[uint16]memcached.FailoverLog
+
+// GetFailoverLogs, get the failover logs for a set of vbucket ids
+func (b *Bucket) GetFailoverLogs(vBuckets []uint16) (FailoverLog, error) {
+
+       // map vbids to their corresponding hosts
+       vbHostList := make(map[string][]uint16)
+       vbm := b.VBServerMap()
+       if len(vbm.VBucketMap) < len(vBuckets) {
+               return nil, fmt.Errorf("vbmap smaller than vbucket list: %v vs. %v",
+                       vbm.VBucketMap, vBuckets)
+       }
+
+       for _, vb := range vBuckets {
+               masterID := vbm.VBucketMap[vb][0]
+               master := b.getMasterNode(masterID)
+               if master == "" {
+                       return nil, fmt.Errorf("No master found for vb %d", vb)
+               }
+
+               vbList := vbHostList[master]
+               if vbList == nil {
+                       vbList = make([]uint16, 0)
+               }
+               vbList = append(vbList, vb)
+               vbHostList[master] = vbList
+       }
+
+       failoverLogMap := make(FailoverLog)
+       for _, serverConn := range b.getConnPools(false /* not already locked */) {
+
+               vbList := vbHostList[serverConn.host]
+               if vbList == nil {
+                       continue
+               }
+
+               mc, err := serverConn.Get()
+               if err != nil {
+                       logging.Infof("No Free connections for vblist %v", vbList)
+                       return nil, fmt.Errorf("No Free connections for host %s",
+                               serverConn.host)
+
+               }
+               // close the connection so that it doesn't get reused for upr data
+               // connection
+               defer mc.Close()
+               mc.SetDeadline(getDeadline(time.Time{}, DefaultTimeout))
+               failoverlogs, err := mc.UprGetFailoverLog(vbList)
+               if err != nil {
+                       return nil, fmt.Errorf("Error getting failover log %s host %s",
+                               err.Error(), serverConn.host)
+
+               }
+
+               for vb, log := range failoverlogs {
+                       failoverLogMap[vb] = *log
+               }
+       }
+
+       return failoverLogMap, nil
+}
+
+func (b *Bucket) StartUprFeed(name string, sequence uint32) (*UprFeed, error) {
+       return b.StartUprFeedWithConfig(name, sequence, 10, DEFAULT_WINDOW_SIZE)
+}
+
+// StartUprFeed creates and starts a new Upr feed
+// No data will be sent on the channel unless vbuckets streams are requested
+func (b *Bucket) StartUprFeedWithConfig(name string, sequence uint32, data_chan_size int, dcp_buffer_size uint32) (*UprFeed, error) {
+
+       feed := &UprFeed{
+               bucket:          b,
+               output:          make(chan *memcached.UprEvent, data_chan_size),
+               quit:            make(chan bool),
+               nodeFeeds:       make(map[string]*FeedInfo, 0),
+               name:            name,
+               sequence:        sequence,
+               killSwitch:      make(chan bool),
+               dcp_buffer_size: dcp_buffer_size,
+               data_chan_size:  data_chan_size,
+       }
+
+       err := feed.connectToNodes()
+       if err != nil {
+               return nil, fmt.Errorf("Cannot connect to bucket %s", err.Error())
+       }
+       feed.connected = true
+       go feed.run()
+
+       feed.C = feed.output
+       return feed, nil
+}
+
+// UprRequestStream starts a stream for a vb on a feed
+func (feed *UprFeed) UprRequestStream(vb uint16, opaque uint16, flags uint32,
+       vuuid, startSequence, endSequence, snapStart, snapEnd uint64) error {
+
+       defer func() {
+               if r := recover(); r != nil {
+                       log.Panicf("Panic in UprRequestStream. Feed %v Bucket %v", feed, feed.bucket)
+               }
+       }()
+
+       vbm := feed.bucket.VBServerMap()
+       if len(vbm.VBucketMap) < int(vb) {
+               return fmt.Errorf("vbmap smaller than vbucket list: %v vs. %v",
+                       vb, vbm.VBucketMap)
+       }
+
+       if int(vb) >= len(vbm.VBucketMap) {
+               return fmt.Errorf("Invalid vbucket id %d", vb)
+       }
+
+       masterID := vbm.VBucketMap[vb][0]
+       master := feed.bucket.getMasterNode(masterID)
+       if master == "" {
+               return fmt.Errorf("Master node not found for vbucket %d", vb)
+       }
+       singleFeed := feed.nodeFeeds[master]
+       if singleFeed == nil {
+               return fmt.Errorf("UprFeed for this host not found")
+       }
+
+       if err := singleFeed.uprFeed.UprRequestStream(vb, opaque, flags,
+               vuuid, startSequence, endSequence, snapStart, snapEnd); err != nil {
+               return err
+       }
+
+       return nil
+}
+
+// UprCloseStream ends a vbucket stream.
+func (feed *UprFeed) UprCloseStream(vb, opaqueMSB uint16) error {
+
+       defer func() {
+               if r := recover(); r != nil {
+                       log.Panicf("Panic in UprCloseStream. Feed %v Bucket %v ", feed, feed.bucket)
+               }
+       }()
+
+       vbm := feed.bucket.VBServerMap()
+       if len(vbm.VBucketMap) < int(vb) {
+               return fmt.Errorf("vbmap smaller than vbucket list: %v vs. %v",
+                       vb, vbm.VBucketMap)
+       }
+
+       if int(vb) >= len(vbm.VBucketMap) {
+               return fmt.Errorf("Invalid vbucket id %d", vb)
+       }
+
+       masterID := vbm.VBucketMap[vb][0]
+       master := feed.bucket.getMasterNode(masterID)
+       if master == "" {
+               return fmt.Errorf("Master node not found for vbucket %d", vb)
+       }
+       singleFeed := feed.nodeFeeds[master]
+       if singleFeed == nil {
+               return fmt.Errorf("UprFeed for this host not found")
+       }
+
+       if err := singleFeed.uprFeed.CloseStream(vb, opaqueMSB); err != nil {
+               return err
+       }
+       return nil
+}
+
+// Goroutine that runs the feed
+func (feed *UprFeed) run() {
+       retryInterval := initialRetryInterval
+       bucketOK := true
+       for {
+               // Connect to the UPR feed of each server node:
+               if bucketOK {
+                       // Run until one of the sub-feeds fails:
+                       select {
+                       case <-feed.killSwitch:
+                       case <-feed.quit:
+                               return
+                       }
+                       //feed.closeNodeFeeds()
+                       retryInterval = initialRetryInterval
+               }
+
+               if feed.closing == true {
+                       // we have been asked to shut down
+                       return
+               }
+
+               // On error, try to refresh the bucket in case the list of nodes changed:
+               logging.Infof("go-couchbase: UPR connection lost; reconnecting to bucket %q in %v",
+                       feed.bucket.Name, retryInterval)
+
+               if err := feed.bucket.Refresh(); err != nil {
+                       // if we fail to refresh the bucket, exit the feed
+                       // MB-14917
+                       logging.Infof("Unable to refresh bucket %s ", err.Error())
+                       close(feed.output)
+                       feed.outputClosed = true
+                       feed.closeNodeFeeds()
+                       return
+               }
+
+               // this will only connect to nodes that are not connected or changed
+               // user will have to reconnect the stream
+               err := feed.connectToNodes()
+               if err != nil {
+                       logging.Infof("Unable to connect to nodes..exit ")
+                       close(feed.output)
+                       feed.outputClosed = true
+                       feed.closeNodeFeeds()
+                       return
+               }
+               bucketOK = err == nil
+
+               select {
+               case <-time.After(retryInterval):
+               case <-feed.quit:
+                       return
+               }
+               if retryInterval *= 2; retryInterval > maximumRetryInterval {
+                       retryInterval = maximumRetryInterval
+               }
+       }
+}
+
+func (feed *UprFeed) connectToNodes() (err error) {
+       nodeCount := 0
+       for _, serverConn := range feed.bucket.getConnPools(false /* not already locked */) {
+
+               // this maybe a reconnection, so check if the connection to the node
+               // already exists. Connect only if the node is not found in the list
+               // or connected == false
+               nodeFeed := feed.nodeFeeds[serverConn.host]
+
+               if nodeFeed != nil && nodeFeed.connected == true {
+                       continue
+               }
+
+               var singleFeed *memcached.UprFeed
+               var name string
+               if feed.name == "" {
+                       name = "DefaultUprClient"
+               } else {
+                       name = feed.name
+               }
+               singleFeed, err = serverConn.StartUprFeed(name, feed.sequence, feed.dcp_buffer_size, feed.data_chan_size)
+               if err != nil {
+                       logging.Errorf("go-couchbase: Error connecting to upr feed of %s: %v", serverConn.host, err)
+                       feed.closeNodeFeeds()
+                       return
+               }
+               // add the node to the connection map
+               feedInfo := &FeedInfo{
+                       uprFeed:   singleFeed,
+                       connected: true,
+                       host:      serverConn.host,
+                       quit:      make(chan bool),
+               }
+               feed.nodeFeeds[serverConn.host] = feedInfo
+               go feed.forwardUprEvents(feedInfo, feed.killSwitch, serverConn.host)
+               feed.wg.Add(1)
+               nodeCount++
+       }
+       if nodeCount == 0 {
+               return fmt.Errorf("No connection to bucket")
+       }
+
+       return nil
+}
+
+// Goroutine that forwards Upr events from a single node's feed to the aggregate feed.
+func (feed *UprFeed) forwardUprEvents(nodeFeed *FeedInfo, killSwitch chan bool, host string) {
+       singleFeed := nodeFeed.uprFeed
+
+       defer func() {
+               feed.wg.Done()
+               if r := recover(); r != nil {
+                       //if feed is not closing, re-throw the panic
+                       if feed.outputClosed != true && feed.closing != true {
+                               panic(r)
+                       } else {
+                               logging.Errorf("Panic is recovered. Since feed is closed, exit gracefully")
+
+                       }
+               }
+       }()
+
+       for {
+               select {
+               case <-nodeFeed.quit:
+                       nodeFeed.connected = false
+                       return
+
+               case event, ok := <-singleFeed.C:
+                       if !ok {
+                               if singleFeed.Error != nil {
+                                       logging.Errorf("go-couchbase: Upr feed from %s failed: %v", host, singleFeed.Error)
+                               }
+                               killSwitch <- true
+                               return
+                       }
+                       if feed.outputClosed == true {
+                               // someone closed the node feed
+                               logging.Infof("Node need closed, returning from forwardUprEvent")
+                               return
+                       }
+                       feed.output <- event
+                       if event.Status == gomemcached.NOT_MY_VBUCKET {
+                               logging.Infof(" Got a not my vbucket error !! ")
+                               if err := feed.bucket.Refresh(); err != nil {
+                                       logging.Errorf("Unable to refresh bucket %s ", err.Error())
+                                       feed.closeNodeFeeds()
+                                       return
+                               }
+                               // this will only connect to nodes that are not connected or changed
+                               // user will have to reconnect the stream
+                               if err := feed.connectToNodes(); err != nil {
+                                       logging.Errorf("Unable to connect to nodes %s", err.Error())
+                                       return
+                               }
+
+                       }
+               }
+       }
+}
+
+func (feed *UprFeed) closeNodeFeeds() {
+       for _, f := range feed.nodeFeeds {
+               logging.Infof(" Sending close to forwardUprEvent ")
+               close(f.quit)
+               f.uprFeed.Close()
+       }
+       feed.nodeFeeds = nil
+}
+
+// Close a Upr feed.
+func (feed *UprFeed) Close() error {
+       select {
+       case <-feed.quit:
+               return nil
+       default:
+       }
+
+       feed.closing = true
+       feed.closeNodeFeeds()
+       close(feed.quit)
+
+       feed.wg.Wait()
+       if feed.outputClosed == false {
+               feed.outputClosed = true
+               close(feed.output)
+       }
+
+       return nil
+}
diff --git a/vendor/github.com/couchbase/go-couchbase/users.go b/vendor/github.com/couchbase/go-couchbase/users.go
new file mode 100644 (file)
index 0000000..4e8f962
--- /dev/null
@@ -0,0 +1,121 @@
+package couchbase
+
+import (
+       "bytes"
+       "fmt"
+)
+
+type User struct {
+       Name   string
+       Id     string
+       Domain string
+       Roles  []Role
+}
+
+type Role struct {
+       Role           string
+       BucketName     string `json:"bucket_name"`
+       ScopeName      string `json:"scope_name"`
+       CollectionName string `json:"collection_name"`
+}
+
+// Sample:
+// {"role":"admin","name":"Admin","desc":"Can manage ALL cluster features including security.","ce":true}
+// {"role":"query_select","bucket_name":"*","name":"Query Select","desc":"Can execute SELECT statement on bucket to retrieve data"}
+type RoleDescription struct {
+       Role       string
+       Name       string
+       Desc       string
+       Ce         bool
+       BucketName string `json:"bucket_name"`
+}
+
+// Return user-role data, as parsed JSON.
+// Sample:
+//   [{"id":"ivanivanov","name":"Ivan Ivanov","roles":[{"role":"cluster_admin"},{"bucket_name":"default","role":"bucket_admin"}]},
+//    {"id":"petrpetrov","name":"Petr Petrov","roles":[{"role":"replication_admin"}]}]
+func (c *Client) GetUserRoles() ([]interface{}, error) {
+       ret := make([]interface{}, 0, 1)
+       err := c.parseURLResponse("/settings/rbac/users", &ret)
+       if err != nil {
+               return nil, err
+       }
+
+       // Get the configured administrator.
+       // Expected result: {"port":8091,"username":"Administrator"}
+       adminInfo := make(map[string]interface{}, 2)
+       err = c.parseURLResponse("/settings/web", &adminInfo)
+       if err != nil {
+               return nil, err
+       }
+
+       // Create a special entry for the configured administrator.
+       adminResult := map[string]interface{}{
+               "name":   adminInfo["username"],
+               "id":     adminInfo["username"],
+               "domain": "ns_server",
+               "roles": []interface{}{
+                       map[string]interface{}{
+                               "role": "admin",
+                       },
+               },
+       }
+
+       // Add the configured administrator to the list of results.
+       ret = append(ret, adminResult)
+
+       return ret, nil
+}
+
+func (c *Client) GetUserInfoAll() ([]User, error) {
+       ret := make([]User, 0, 16)
+       err := c.parseURLResponse("/settings/rbac/users", &ret)
+       if err != nil {
+               return nil, err
+       }
+       return ret, nil
+}
+
+func rolesToParamFormat(roles []Role) string {
+       var buffer bytes.Buffer
+       for i, role := range roles {
+               if i > 0 {
+                       buffer.WriteString(",")
+               }
+               buffer.WriteString(role.Role)
+               if role.BucketName != "" {
+                       buffer.WriteString("[")
+                       buffer.WriteString(role.BucketName)
+                       buffer.WriteString("]")
+               }
+       }
+       return buffer.String()
+}
+
+func (c *Client) PutUserInfo(u *User) error {
+       params := map[string]interface{}{
+               "name":  u.Name,
+               "roles": rolesToParamFormat(u.Roles),
+       }
+       var target string
+       switch u.Domain {
+       case "external":
+               target = "/settings/rbac/users/" + u.Id
+       case "local":
+               target = "/settings/rbac/users/local/" + u.Id
+       default:
+               return fmt.Errorf("Unknown user type: %s", u.Domain)
+       }
+       var ret string // PUT returns an empty string. We ignore it.
+       err := c.parsePutURLResponse(target, params, &ret)
+       return err
+}
+
+func (c *Client) GetRolesAll() ([]RoleDescription, error) {
+       ret := make([]RoleDescription, 0, 32)
+       err := c.parseURLResponse("/settings/rbac/roles", &ret)
+       if err != nil {
+               return nil, err
+       }
+       return ret, nil
+}
diff --git a/vendor/github.com/couchbase/go-couchbase/util.go b/vendor/github.com/couchbase/go-couchbase/util.go
new file mode 100644 (file)
index 0000000..4d286a3
--- /dev/null
@@ -0,0 +1,49 @@
+package couchbase
+
+import (
+       "fmt"
+       "net/url"
+       "strings"
+)
+
+// CleanupHost returns the hostname with the given suffix removed.
+func CleanupHost(h, commonSuffix string) string {
+       if strings.HasSuffix(h, commonSuffix) {
+               return h[:len(h)-len(commonSuffix)]
+       }
+       return h
+}
+
+// FindCommonSuffix returns the longest common suffix from the given
+// strings.
+func FindCommonSuffix(input []string) string {
+       rv := ""
+       if len(input) < 2 {
+               return ""
+       }
+       from := input
+       for i := len(input[0]); i > 0; i-- {
+               common := true
+               suffix := input[0][i:]
+               for _, s := range from {
+                       if !strings.HasSuffix(s, suffix) {
+                               common = false
+                               break
+                       }
+               }
+               if common {
+                       rv = suffix
+               }
+       }
+       return rv
+}
+
+// ParseURL is a wrapper around url.Parse with some sanity-checking
+func ParseURL(urlStr string) (result *url.URL, err error) {
+       result, err = url.Parse(urlStr)
+       if result != nil && result.Scheme == "" {
+               result = nil
+               err = fmt.Errorf("invalid URL <%s>", urlStr)
+       }
+       return
+}
diff --git a/vendor/github.com/couchbase/go-couchbase/vbmap.go b/vendor/github.com/couchbase/go-couchbase/vbmap.go
new file mode 100644 (file)
index 0000000..b96a18e
--- /dev/null
@@ -0,0 +1,77 @@
+package couchbase
+
+var crc32tab = []uint32{
+       0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+       0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+       0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+       0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+       0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+       0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+       0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+       0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+       0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+       0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+       0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+       0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+       0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+       0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+       0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+       0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+       0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+       0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+       0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+       0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+       0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+       0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+       0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+       0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+       0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+       0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+       0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+       0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+       0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+       0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+       0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+       0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+       0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+       0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+       0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+       0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+       0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+       0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+       0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+       0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+       0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+       0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+       0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+       0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+       0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+       0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+       0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+       0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+       0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+       0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+       0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+       0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+       0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+       0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+       0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+       0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+       0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+       0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+       0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+       0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+       0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+       0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+       0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+       0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}
+
+// VBHash finds the vbucket for the given key.
+func (b *Bucket) VBHash(key string) uint32 {
+       crc := uint32(0xffffffff)
+       for x := 0; x < len(key); x++ {
+               crc = (crc >> 8) ^ crc32tab[(uint64(crc)^uint64(key[x]))&0xff]
+       }
+       vbm := b.VBServerMap()
+       return ((^crc) >> 16) & 0x7fff & (uint32(len(vbm.VBucketMap)) - 1)
+}
diff --git a/vendor/github.com/couchbase/go-couchbase/views.go b/vendor/github.com/couchbase/go-couchbase/views.go
new file mode 100644 (file)
index 0000000..2f68642
--- /dev/null
@@ -0,0 +1,231 @@
+package couchbase
+
+import (
+       "encoding/json"
+       "errors"
+       "fmt"
+       "io/ioutil"
+       "math/rand"
+       "net/http"
+       "net/url"
+       "time"
+)
+
+// ViewRow represents a single result from a view.
+//
+// Doc is present only if include_docs was set on the request.
+type ViewRow struct {
+       ID    string
+       Key   interface{}
+       Value interface{}
+       Doc   *interface{}
+}
+
+// A ViewError is a node-specific error indicating a partial failure
+// within a view result.
+type ViewError struct {
+       From   string
+       Reason string
+}
+
+func (ve ViewError) Error() string {
+       return "Node: " + ve.From + ", reason: " + ve.Reason
+}
+
+// ViewResult holds the entire result set from a view request,
+// including the rows and the errors.
+type ViewResult struct {
+       TotalRows int `json:"total_rows"`
+       Rows      []ViewRow
+       Errors    []ViewError
+}
+
+func (b *Bucket) randomBaseURL() (*url.URL, error) {
+       nodes := b.HealthyNodes()
+       if len(nodes) == 0 {
+               return nil, errors.New("no available couch rest URLs")
+       }
+       nodeNo := rand.Intn(len(nodes))
+       node := nodes[nodeNo]
+
+       b.RLock()
+       name := b.Name
+       pool := b.pool
+       b.RUnlock()
+
+       u, err := ParseURL(node.CouchAPIBase)
+       if err != nil {
+               return nil, fmt.Errorf("config error: Bucket %q node #%d CouchAPIBase=%q: %v",
+                       name, nodeNo, node.CouchAPIBase, err)
+       } else if pool != nil {
+               u.User = pool.client.BaseURL.User
+       }
+       return u, err
+}
+
+const START_NODE_ID = -1
+
+func (b *Bucket) randomNextURL(lastNode int) (*url.URL, int, error) {
+       nodes := b.HealthyNodes()
+       if len(nodes) == 0 {
+               return nil, -1, errors.New("no available couch rest URLs")
+       }
+
+       var nodeNo int
+       if lastNode == START_NODE_ID || lastNode >= len(nodes) {
+               // randomly select a node if the value of lastNode is invalid
+               nodeNo = rand.Intn(len(nodes))
+       } else {
+               // wrap around the node list
+               nodeNo = (lastNode + 1) % len(nodes)
+       }
+
+       b.RLock()
+       name := b.Name
+       pool := b.pool
+       b.RUnlock()
+
+       node := nodes[nodeNo]
+       u, err := ParseURL(node.CouchAPIBase)
+       if err != nil {
+               return nil, -1, fmt.Errorf("config error: Bucket %q node #%d CouchAPIBase=%q: %v",
+                       name, nodeNo, node.CouchAPIBase, err)
+       } else if pool != nil {
+               u.User = pool.client.BaseURL.User
+       }
+       return u, nodeNo, err
+}
+
+// DocID is the document ID type for the startkey_docid parameter in
+// views.
+type DocID string
+
+func qParam(k, v string) string {
+       format := `"%s"`
+       switch k {
+       case "startkey_docid", "endkey_docid", "stale":
+               format = "%s"
+       }
+       return fmt.Sprintf(format, v)
+}
+
+// ViewURL constructs a URL for a view with the given ddoc, view name,
+// and parameters.
+func (b *Bucket) ViewURL(ddoc, name string,
+       params map[string]interface{}) (string, error) {
+       u, err := b.randomBaseURL()
+       if err != nil {
+               return "", err
+       }
+
+       values := url.Values{}
+       for k, v := range params {
+               switch t := v.(type) {
+               case DocID:
+                       values[k] = []string{string(t)}
+               case string:
+                       values[k] = []string{qParam(k, t)}
+               case int:
+                       values[k] = []string{fmt.Sprintf(`%d`, t)}
+               case bool:
+                       values[k] = []string{fmt.Sprintf(`%v`, t)}
+               default:
+                       b, err := json.Marshal(v)
+                       if err != nil {
+                               return "", fmt.Errorf("unsupported value-type %T in Query, "+
+                                       "json encoder said %v", t, err)
+                       }
+                       values[k] = []string{fmt.Sprintf(`%v`, string(b))}
+               }
+       }
+
+       if ddoc == "" && name == "_all_docs" {
+               u.Path = fmt.Sprintf("/%s/_all_docs", b.GetName())
+       } else {
+               u.Path = fmt.Sprintf("/%s/_design/%s/_view/%s", b.GetName(), ddoc, name)
+       }
+       u.RawQuery = values.Encode()
+
+       return u.String(), nil
+}
+
+// ViewCallback is called for each view invocation.
+var ViewCallback func(ddoc, name string, start time.Time, err error)
+
+// ViewCustom performs a view request that can map row values to a
+// custom type.
+//
+// See the source to View for an example usage.
+func (b *Bucket) ViewCustom(ddoc, name string, params map[string]interface{},
+       vres interface{}) (err error) {
+       if SlowServerCallWarningThreshold > 0 {
+               defer slowLog(time.Now(), "call to ViewCustom(%q, %q)", ddoc, name)
+       }
+
+       if ViewCallback != nil {
+               defer func(t time.Time) { ViewCallback(ddoc, name, t, err) }(time.Now())
+       }
+
+       u, err := b.ViewURL(ddoc, name, params)
+       if err != nil {
+               return err
+       }
+
+       req, err := http.NewRequest("GET", u, nil)
+       if err != nil {
+               return err
+       }
+
+       ah := b.authHandler(false /* bucket not yet locked */)
+       maybeAddAuth(req, ah)
+
+       res, err := doHTTPRequest(req)
+       if err != nil {
+               return fmt.Errorf("error starting view req at %v: %v", u, err)
+       }
+       defer res.Body.Close()
+
+       if res.StatusCode != 200 {
+               bod := make([]byte, 512)
+               l, _ := res.Body.Read(bod)
+               return fmt.Errorf("error executing view req at %v: %v - %s",
+                       u, res.Status, bod[:l])
+       }
+
+       body, err := ioutil.ReadAll(res.Body)
+       if err := json.Unmarshal(body, vres); err != nil {
+               return nil
+       }
+
+       return nil
+}
+
+// View executes a view.
+//
+// The ddoc parameter is just the bare name of your design doc without
+// the "_design/" prefix.
+//
+// Parameters are string keys with values that correspond to couchbase
+// view parameters.  Primitive should work fairly naturally (booleans,
+// ints, strings, etc...) and other values will attempt to be JSON
+// marshaled (useful for array indexing on on view keys, for example).
+//
+// Example:
+//
+//   res, err := couchbase.View("myddoc", "myview", map[string]interface{}{
+//       "group_level": 2,
+//       "startkey_docid":    []interface{}{"thing"},
+//       "endkey_docid":      []interface{}{"thing", map[string]string{}},
+//       "stale": false,
+//       })
+func (b *Bucket) View(ddoc, name string, params map[string]interface{}) (ViewResult, error) {
+       vres := ViewResult{}
+
+       if err := b.ViewCustom(ddoc, name, params, &vres); err != nil {
+               //error in accessing views. Retry once after a bucket refresh
+               b.Refresh()
+               return vres, b.ViewCustom(ddoc, name, params, &vres)
+       } else {
+               return vres, nil
+       }
+}
index 0bedae1c35a33394469e36ee5d8038bab68728ab..4da8b8f4260a7f9c64d5761e0a2b9997639395f5 100644 (file)
@@ -45,7 +45,7 @@ type streamIdNonResumeScopeMeta struct {
 }
 
 func (c *CollectionsFilter) IsValid() error {
-       if c.UseManifestUid {
+       if c.UseManifestUid && c.UseStreamId {
                return fmt.Errorf("Not implemented yet")
        }
 
@@ -99,8 +99,10 @@ func (c *CollectionsFilter) ToStreamReqBody() ([]byte, error) {
        case false:
                switch c.UseManifestUid {
                case true:
-                       // TODO
-                       return nil, fmt.Errorf("NotImplemented1")
+                       filter := &nonStreamIdResumeScopeMeta{
+                               ManifestId: fmt.Sprintf("%x", c.ManifestUid),
+                       }
+                       output = *filter
                case false:
                        switch len(c.CollectionsList) > 0 {
                        case true:
index 66c897c5d6b14bb7e7d0020ab074ebed0ea3b64a..16dd2f8f7c6dca5ac4818d6ef28e6a4856f42870 100644 (file)
@@ -19,8 +19,8 @@ import (
 )
 
 type ClientIface interface {
-       Add(vb uint16, key string, flags int, exp int, body []byte) (*gomemcached.MCResponse, error)
-       Append(vb uint16, key string, data []byte) (*gomemcached.MCResponse, error)
+       Add(vb uint16, key string, flags int, exp int, body []byte, context ...*ClientContext) (*gomemcached.MCResponse, error)
+       Append(vb uint16, key string, data []byte, context ...*ClientContext) (*gomemcached.MCResponse, error)
        Auth(user, pass string) (*gomemcached.MCResponse, error)
        AuthList() (*gomemcached.MCResponse, error)
        AuthPlain(user, pass string) (*gomemcached.MCResponse, error)
@@ -30,44 +30,87 @@ type ClientIface interface {
        CollectionsGetCID(scope string, collection string) (*gomemcached.MCResponse, error)
        CollectionEnabled() bool
        Close() error
-       Decr(vb uint16, key string, amt, def uint64, exp int) (uint64, error)
-       Del(vb uint16, key string) (*gomemcached.MCResponse, error)
+       Decr(vb uint16, key string, amt, def uint64, exp int, context ...*ClientContext) (uint64, error)
+       Del(vb uint16, key string, context ...*ClientContext) (*gomemcached.MCResponse, error)
        EnableMutationToken() (*gomemcached.MCResponse, error)
        EnableFeatures(features Features) (*gomemcached.MCResponse, error)
-       Get(vb uint16, key string) (*gomemcached.MCResponse, error)
+       Get(vb uint16, key string, context ...*ClientContext) (*gomemcached.MCResponse, error)
+       GetAllVbSeqnos(vbSeqnoMap map[uint16]uint64, context ...*ClientContext) (map[uint16]uint64, error)
+       GetAndTouch(vb uint16, key string, exp int, context ...*ClientContext) (*gomemcached.MCResponse, error)
+       GetBulk(vb uint16, keys []string, rv map[string]*gomemcached.MCResponse, subPaths []string, context ...*ClientContext) error
        GetCollectionsManifest() (*gomemcached.MCResponse, error)
-       GetFromCollection(vb uint16, cid uint32, key string) (*gomemcached.MCResponse, error)
-       GetSubdoc(vb uint16, key string, subPaths []string) (*gomemcached.MCResponse, error)
-       GetAndTouch(vb uint16, key string, exp int) (*gomemcached.MCResponse, error)
-       GetBulk(vb uint16, keys []string, rv map[string]*gomemcached.MCResponse, subPaths []string) error
-       GetMeta(vb uint16, key string) (*gomemcached.MCResponse, error)
-       GetRandomDoc() (*gomemcached.MCResponse, error)
+       GetMeta(vb uint16, key string, context ...*ClientContext) (*gomemcached.MCResponse, error)
+       GetRandomDoc(context ...*ClientContext) (*gomemcached.MCResponse, error)
+       GetSubdoc(vb uint16, key string, subPaths []string, context ...*ClientContext) (*gomemcached.MCResponse, error)
        Hijack() io.ReadWriteCloser
-       Incr(vb uint16, key string, amt, def uint64, exp int) (uint64, error)
+       Incr(vb uint16, key string, amt, def uint64, exp int, context ...*ClientContext) (uint64, error)
        Observe(vb uint16, key string) (result ObserveResult, err error)
        ObserveSeq(vb uint16, vbuuid uint64) (result *ObserveSeqResult, err error)
        Receive() (*gomemcached.MCResponse, error)
        ReceiveWithDeadline(deadline time.Time) (*gomemcached.MCResponse, error)
        Send(req *gomemcached.MCRequest) (rv *gomemcached.MCResponse, err error)
-       Set(vb uint16, key string, flags int, exp int, body []byte) (*gomemcached.MCResponse, error)
+       Set(vb uint16, key string, flags int, exp int, body []byte, context ...*ClientContext) (*gomemcached.MCResponse, error)
        SetKeepAliveOptions(interval time.Duration)
        SetReadDeadline(t time.Time)
        SetDeadline(t time.Time)
        SelectBucket(bucket string) (*gomemcached.MCResponse, error)
-       SetCas(vb uint16, key string, flags int, exp int, cas uint64, body []byte) (*gomemcached.MCResponse, error)
+       SetCas(vb uint16, key string, flags int, exp int, cas uint64, body []byte, context ...*ClientContext) (*gomemcached.MCResponse, error)
        Stats(key string) ([]StatValue, error)
        StatsMap(key string) (map[string]string, error)
        StatsMapForSpecifiedStats(key string, statsMap map[string]string) error
        Transmit(req *gomemcached.MCRequest) error
        TransmitWithDeadline(req *gomemcached.MCRequest, deadline time.Time) error
        TransmitResponse(res *gomemcached.MCResponse) error
+       UprGetFailoverLog(vb []uint16) (map[uint16]*FailoverLog, error)
 
        // UprFeed Related
        NewUprFeed() (*UprFeed, error)
        NewUprFeedIface() (UprFeedIface, error)
        NewUprFeedWithConfig(ackByClient bool) (*UprFeed, error)
        NewUprFeedWithConfigIface(ackByClient bool) (UprFeedIface, error)
-       UprGetFailoverLog(vb []uint16) (map[uint16]*FailoverLog, error)
+}
+
+type ClientContext struct {
+       // Collection-based context
+       CollId uint32
+
+       // VB-state related context
+       // nil means not used in this context
+       VbState *VbStateType
+}
+
+type VbStateType uint8
+
+const (
+       VbAlive   VbStateType = 0x00
+       VbActive  VbStateType = 0x01
+       VbReplica VbStateType = 0x02
+       VbPending VbStateType = 0x03
+       VbDead    VbStateType = 0x04
+)
+
+func (context *ClientContext) InitExtras(req *gomemcached.MCRequest, client *Client) {
+       if req == nil || client == nil {
+               return
+       }
+
+       var bytesToAllocate int
+       switch req.Opcode {
+       case gomemcached.GET_ALL_VB_SEQNOS:
+               if context.VbState != nil {
+                       bytesToAllocate += 4
+               }
+               if client.CollectionEnabled() {
+                       if context.VbState == nil {
+                               bytesToAllocate += 8
+                       } else {
+                               bytesToAllocate += 4
+                       }
+               }
+       }
+       if bytesToAllocate > 0 {
+               req.Extras = make([]byte, bytesToAllocate)
+       }
 }
 
 const bufsize = 1024
@@ -102,8 +145,8 @@ type Client struct {
 
        hdrBuf []byte
 
-       featureMtx       sync.RWMutex
-       sentHeloFeatures Features
+       collectionsEnabled uint32
+       deadline           time.Time
 }
 
 var (
@@ -156,7 +199,11 @@ func (c *Client) SetReadDeadline(t time.Time) {
 }
 
 func (c *Client) SetDeadline(t time.Time) {
+       if t.Equal(c.deadline) {
+               return
+       }
        c.conn.SetDeadline(t)
+       c.deadline = t
 }
 
 // Wrap an existing transport.
@@ -287,60 +334,103 @@ func (c *Client) EnableMutationToken() (*gomemcached.MCResponse, error) {
 //Send a hello command to enable specific features
 func (c *Client) EnableFeatures(features Features) (*gomemcached.MCResponse, error) {
        var payload []byte
+       collectionsEnabled := 0
 
        for _, feature := range features {
+               if feature == FeatureCollections {
+                       collectionsEnabled = 1
+               }
                payload = append(payload, 0, 0)
                binary.BigEndian.PutUint16(payload[len(payload)-2:], uint16(feature))
        }
 
-       c.featureMtx.Lock()
-       c.sentHeloFeatures = features
-       c.featureMtx.Unlock()
-
-       return c.Send(&gomemcached.MCRequest{
+       rv, err := c.Send(&gomemcached.MCRequest{
                Opcode: gomemcached.HELLO,
                Key:    []byte("GoMemcached"),
                Body:   payload,
        })
 
+       if err == nil && collectionsEnabled != 0 {
+               atomic.StoreUint32(&c.collectionsEnabled, uint32(collectionsEnabled))
+       }
+       return rv, err
 }
 
-// Get the value for a key.
-func (c *Client) Get(vb uint16, key string) (*gomemcached.MCResponse, error) {
-       return c.Send(&gomemcached.MCRequest{
-               Opcode:  gomemcached.GET,
-               VBucket: vb,
-               Key:     []byte(key),
-       })
+// Sets collection info for a request
+func (c *Client) setCollection(req *gomemcached.MCRequest, context ...*ClientContext) error {
+       req.CollIdLen = 0
+       collectionId := uint32(0)
+       if len(context) > 0 {
+               collectionId = context[0].CollId
+       }
+
+       // if the optional collection is specified, it must be default for clients that haven't turned on collections
+       if atomic.LoadUint32(&c.collectionsEnabled) == 0 {
+               if collectionId != 0 {
+                       return fmt.Errorf("Client does not use collections but a collection was specified")
+               }
+       } else {
+               req.CollIdLen = binary.PutUvarint(req.CollId[:], uint64(collectionId))
+       }
+       return nil
 }
 
-// Get the value for a key from a collection, identified by collection id.
-func (c *Client) GetFromCollection(vb uint16, cid uint32, key string) (*gomemcached.MCResponse, error) {
-       keyBytes := []byte(key)
-       encodedCid := make([]byte, binary.MaxVarintLen32)
-       lenEncodedCid := binary.PutUvarint(encodedCid, uint64(cid))
-       encodedKey := make([]byte, 0, lenEncodedCid+len(keyBytes))
-       encodedKey = append(encodedKey, encodedCid[0:lenEncodedCid]...)
-       encodedKey = append(encodedKey, keyBytes...)
+func (c *Client) setVbSeqnoContext(req *gomemcached.MCRequest, context ...*ClientContext) error {
+       if len(context) == 0 || req == nil {
+               return nil
+       }
 
-       return c.Send(&gomemcached.MCRequest{
+       switch req.Opcode {
+       case gomemcached.GET_ALL_VB_SEQNOS:
+               if len(context) == 0 {
+                       return nil
+               }
+
+               if len(req.Extras) == 0 {
+                       context[0].InitExtras(req, c)
+               }
+               if context[0].VbState != nil {
+                       binary.BigEndian.PutUint32(req.Extras, uint32(*(context[0].VbState)))
+               }
+               if c.CollectionEnabled() {
+                       binary.BigEndian.PutUint32(req.Extras[4:8], context[0].CollId)
+               }
+               return nil
+       default:
+               return fmt.Errorf("setVbState Not supported for opcode: %v", req.Opcode.String())
+       }
+}
+
+// Get the value for a key.
+func (c *Client) Get(vb uint16, key string, context ...*ClientContext) (*gomemcached.MCResponse, error) {
+       req := &gomemcached.MCRequest{
                Opcode:  gomemcached.GET,
                VBucket: vb,
-               Key:     encodedKey,
-       })
+               Key:     []byte(key),
+       }
+       err := c.setCollection(req, context...)
+       if err != nil {
+               return nil, err
+       }
+       return c.Send(req)
 }
 
 // Get the xattrs, doc value for the input key
-func (c *Client) GetSubdoc(vb uint16, key string, subPaths []string) (*gomemcached.MCResponse, error) {
-
+func (c *Client) GetSubdoc(vb uint16, key string, subPaths []string, context ...*ClientContext) (*gomemcached.MCResponse, error) {
        extraBuf, valueBuf := GetSubDocVal(subPaths)
-       res, err := c.Send(&gomemcached.MCRequest{
+       req := &gomemcached.MCRequest{
                Opcode:  gomemcached.SUBDOC_MULTI_LOOKUP,
                VBucket: vb,
                Key:     []byte(key),
                Extras:  extraBuf,
                Body:    valueBuf,
-       })
+       }
+       err := c.setCollection(req, context...)
+       if err != nil {
+               return nil, err
+       }
+
+       res, err := c.Send(req)
 
        if err != nil && IfResStatusError(res) {
                return res, err
@@ -376,48 +466,56 @@ func (c *Client) CollectionsGetCID(scope string, collection string) (*gomemcache
 }
 
 func (c *Client) CollectionEnabled() bool {
-       c.featureMtx.RLock()
-       defer c.featureMtx.RUnlock()
-
-       for _, feature := range c.sentHeloFeatures {
-               if feature == FeatureCollections {
-                       return true
-               }
-       }
-       return false
+       return atomic.LoadUint32(&c.collectionsEnabled) > 0
 }
 
 // Get the value for a key, and update expiry
-func (c *Client) GetAndTouch(vb uint16, key string, exp int) (*gomemcached.MCResponse, error) {
+func (c *Client) GetAndTouch(vb uint16, key string, exp int, context ...*ClientContext) (*gomemcached.MCResponse, error) {
        extraBuf := make([]byte, 4)
        binary.BigEndian.PutUint32(extraBuf[0:], uint32(exp))
-       return c.Send(&gomemcached.MCRequest{
+       req := &gomemcached.MCRequest{
                Opcode:  gomemcached.GAT,
                VBucket: vb,
                Key:     []byte(key),
                Extras:  extraBuf,
-       })
+       }
+       err := c.setCollection(req, context...)
+       if err != nil {
+               return nil, err
+       }
+       return c.Send(req)
 }
 
 // Get metadata for a key
-func (c *Client) GetMeta(vb uint16, key string) (*gomemcached.MCResponse, error) {
-       return c.Send(&gomemcached.MCRequest{
+func (c *Client) GetMeta(vb uint16, key string, context ...*ClientContext) (*gomemcached.MCResponse, error) {
+       req := &gomemcached.MCRequest{
                Opcode:  gomemcached.GET_META,
                VBucket: vb,
                Key:     []byte(key),
-       })
+       }
+       err := c.setCollection(req, context...)
+       if err != nil {
+               return nil, err
+       }
+       return c.Send(req)
 }
 
 // Del deletes a key.
-func (c *Client) Del(vb uint16, key string) (*gomemcached.MCResponse, error) {
-       return c.Send(&gomemcached.MCRequest{
+func (c *Client) Del(vb uint16, key string, context ...*ClientContext) (*gomemcached.MCResponse, error) {
+       req := &gomemcached.MCRequest{
                Opcode:  gomemcached.DELETE,
                VBucket: vb,
-               Key:     []byte(key)})
+               Key:     []byte(key),
+       }
+       err := c.setCollection(req, context...)
+       if err != nil {
+               return nil, err
+       }
+       return c.Send(req)
 }
 
 // Get a random document
-func (c *Client) GetRandomDoc() (*gomemcached.MCResponse, error) {
+func (c *Client) GetRandomDoc(context ...*ClientContext) (*gomemcached.MCResponse, error) {
        return c.Send(&gomemcached.MCRequest{
                Opcode: 0xB6,
        })
@@ -522,8 +620,7 @@ func (c *Client) SelectBucket(bucket string) (*gomemcached.MCResponse, error) {
 }
 
 func (c *Client) store(opcode gomemcached.CommandCode, vb uint16,
-       key string, flags int, exp int, body []byte) (*gomemcached.MCResponse, error) {
-
+       key string, flags int, exp int, body []byte, context ...*ClientContext) (*gomemcached.MCResponse, error) {
        req := &gomemcached.MCRequest{
                Opcode:  opcode,
                VBucket: vb,
@@ -533,13 +630,16 @@ func (c *Client) store(opcode gomemcached.CommandCode, vb uint16,
                Extras:  []byte{0, 0, 0, 0, 0, 0, 0, 0},
                Body:    body}
 
+       err := c.setCollection(req, context...)
+       if err != nil {
+               return nil, err
+       }
        binary.BigEndian.PutUint64(req.Extras, uint64(flags)<<32|uint64(exp))
        return c.Send(req)
 }
 
 func (c *Client) storeCas(opcode gomemcached.CommandCode, vb uint16,
-       key string, flags int, exp int, cas uint64, body []byte) (*gomemcached.MCResponse, error) {
-
+       key string, flags int, exp int, cas uint64, body []byte, context ...*ClientContext) (*gomemcached.MCResponse, error) {
        req := &gomemcached.MCRequest{
                Opcode:  opcode,
                VBucket: vb,
@@ -549,20 +649,29 @@ func (c *Client) storeCas(opcode gomemcached.CommandCode, vb uint16,
                Extras:  []byte{0, 0, 0, 0, 0, 0, 0, 0},
                Body:    body}
 
+       err := c.setCollection(req, context...)
+       if err != nil {
+               return nil, err
+       }
+
        binary.BigEndian.PutUint64(req.Extras, uint64(flags)<<32|uint64(exp))
        return c.Send(req)
 }
 
 // Incr increments the value at the given key.
 func (c *Client) Incr(vb uint16, key string,
-       amt, def uint64, exp int) (uint64, error) {
-
+       amt, def uint64, exp int, context ...*ClientContext) (uint64, error) {
        req := &gomemcached.MCRequest{
                Opcode:  gomemcached.INCREMENT,
                VBucket: vb,
                Key:     []byte(key),
                Extras:  make([]byte, 8+8+4),
        }
+       err := c.setCollection(req, context...)
+       if err != nil {
+               return 0, err
+       }
+
        binary.BigEndian.PutUint64(req.Extras[:8], amt)
        binary.BigEndian.PutUint64(req.Extras[8:16], def)
        binary.BigEndian.PutUint32(req.Extras[16:20], uint32(exp))
@@ -577,14 +686,18 @@ func (c *Client) Incr(vb uint16, key string,
 
 // Decr decrements the value at the given key.
 func (c *Client) Decr(vb uint16, key string,
-       amt, def uint64, exp int) (uint64, error) {
-
+       amt, def uint64, exp int, context ...*ClientContext) (uint64, error) {
        req := &gomemcached.MCRequest{
                Opcode:  gomemcached.DECREMENT,
                VBucket: vb,
                Key:     []byte(key),
                Extras:  make([]byte, 8+8+4),
        }
+       err := c.setCollection(req, context...)
+       if err != nil {
+               return 0, err
+       }
+
        binary.BigEndian.PutUint64(req.Extras[:8], amt)
        binary.BigEndian.PutUint64(req.Extras[8:16], def)
        binary.BigEndian.PutUint32(req.Extras[16:20], uint32(exp))
@@ -599,24 +712,24 @@ func (c *Client) Decr(vb uint16, key string,
 
 // Add a value for a key (store if not exists).
 func (c *Client) Add(vb uint16, key string, flags int, exp int,
-       body []byte) (*gomemcached.MCResponse, error) {
-       return c.store(gomemcached.ADD, vb, key, flags, exp, body)
+       body []byte, context ...*ClientContext) (*gomemcached.MCResponse, error) {
+       return c.store(gomemcached.ADD, vb, key, flags, exp, body, context...)
 }
 
 // Set the value for a key.
 func (c *Client) Set(vb uint16, key string, flags int, exp int,
-       body []byte) (*gomemcached.MCResponse, error) {
-       return c.store(gomemcached.SET, vb, key, flags, exp, body)
+       body []byte, context ...*ClientContext) (*gomemcached.MCResponse, error) {
+       return c.store(gomemcached.SET, vb, key, flags, exp, body, context...)
 }
 
 // SetCas set the value for a key with cas
 func (c *Client) SetCas(vb uint16, key string, flags int, exp int, cas uint64,
-       body []byte) (*gomemcached.MCResponse, error) {
-       return c.storeCas(gomemcached.SET, vb, key, flags, exp, cas, body)
+       body []byte, context ...*ClientContext) (*gomemcached.MCResponse, error) {
+       return c.storeCas(gomemcached.SET, vb, key, flags, exp, cas, body, context...)
 }
 
 // Append data to the value of a key.
-func (c *Client) Append(vb uint16, key string, data []byte) (*gomemcached.MCResponse, error) {
+func (c *Client) Append(vb uint16, key string, data []byte, context ...*ClientContext) (*gomemcached.MCResponse, error) {
        req := &gomemcached.MCRequest{
                Opcode:  gomemcached.APPEND,
                VBucket: vb,
@@ -625,11 +738,15 @@ func (c *Client) Append(vb uint16, key string, data []byte) (*gomemcached.MCResp
                Opaque:  0,
                Body:    data}
 
+       err := c.setCollection(req, context...)
+       if err != nil {
+               return nil, err
+       }
        return c.Send(req)
 }
 
 // GetBulk gets keys in bulk
-func (c *Client) GetBulk(vb uint16, keys []string, rv map[string]*gomemcached.MCResponse, subPaths []string) error {
+func (c *Client) GetBulk(vb uint16, keys []string, rv map[string]*gomemcached.MCResponse, subPaths []string, context ...*ClientContext) error {
        stopch := make(chan bool)
        var wg sync.WaitGroup
 
@@ -698,6 +815,10 @@ func (c *Client) GetBulk(vb uint16, keys []string, rv map[string]*gomemcached.MC
                Opcode:  gomemcached.GET,
                VBucket: vb,
        }
+       err := c.setCollection(memcachedReqPkt, context...)
+       if err != nil {
+               return err
+       }
 
        if len(subPaths) > 0 {
                extraBuf, valueBuf := GetSubDocVal(subPaths)
@@ -719,7 +840,7 @@ func (c *Client) GetBulk(vb uint16, keys []string, rv map[string]*gomemcached.MC
        } // End of Get request
 
        // finally transmit a NOOP
-       err := c.Transmit(&gomemcached.MCRequest{
+       err = c.Transmit(&gomemcached.MCRequest{
                Opcode:  gomemcached.NOOP,
                VBucket: vb,
                Opaque:  c.opaque,
@@ -747,7 +868,10 @@ func GetSubDocVal(subPaths []string) (extraBuf, valueBuf []byte) {
        }
 
        // Xattr retrieval - subdoc multi get
-       extraBuf = append(extraBuf, uint8(0x04))
+       // Set deleted true only if it is not expiration
+       if len(subPaths) != 1 || subPaths[0] != "$document.exptime" {
+               extraBuf = append(extraBuf, uint8(0x04))
+       }
 
        valueBuf = make([]byte, num*4+totalBytesLen)
 
@@ -1138,6 +1262,38 @@ func (c *Client) StatsMapForSpecifiedStats(key string, statsMap map[string]strin
        return nil
 }
 
+// UprGetFailoverLog for given list of vbuckets.
+func (mc *Client) UprGetFailoverLog(vb []uint16) (map[uint16]*FailoverLog, error) {
+
+       rq := &gomemcached.MCRequest{
+               Opcode: gomemcached.UPR_FAILOVERLOG,
+               Opaque: opaqueFailover,
+       }
+
+       failoverLogs := make(map[uint16]*FailoverLog)
+       for _, vBucket := range vb {
+               rq.VBucket = vBucket
+               if err := mc.Transmit(rq); err != nil {
+                       return nil, err
+               }
+               res, err := mc.Receive()
+
+               if err != nil {
+                       return nil, fmt.Errorf("failed to receive %s", err.Error())
+               } else if res.Opcode != gomemcached.UPR_FAILOVERLOG || res.Status != gomemcached.SUCCESS {
+                       return nil, fmt.Errorf("unexpected #opcode %v", res.Opcode)
+               }
+
+               flog, err := parseFailoverLog(res.Body)
+               if err != nil {
+                       return nil, fmt.Errorf("unable to parse failover logs for vb %d", vb)
+               }
+               failoverLogs[vBucket] = flog
+       }
+
+       return failoverLogs, nil
+}
+
 // Hijack exposes the underlying connection from this client.
 //
 // It also marks the connection as unhealthy since the client will
@@ -1166,3 +1322,98 @@ func IfResStatusError(response *gomemcached.MCResponse) bool {
 func (c *Client) Conn() io.ReadWriteCloser {
        return c.conn
 }
+
+// Since the binary request supports only a single collection at a time, it is possible
+// that this may be called multiple times in succession by callers to get vbSeqnos for
+// multiple collections. Thus, caller could pass in a non-nil map so the gomemcached
+// client won't need to allocate new map for each call to prevent too much GC
+// NOTE: If collection is enabled and context is not given, KV will still return stats for default collection
+func (c *Client) GetAllVbSeqnos(vbSeqnoMap map[uint16]uint64, context ...*ClientContext) (map[uint16]uint64, error) {
+       rq := &gomemcached.MCRequest{
+               Opcode: gomemcached.GET_ALL_VB_SEQNOS,
+               Opaque: opaqueGetSeqno,
+       }
+
+       err := c.setVbSeqnoContext(rq, context...)
+       if err != nil {
+               return vbSeqnoMap, err
+       }
+
+       err = c.Transmit(rq)
+       if err != nil {
+               return vbSeqnoMap, err
+       }
+
+       res, err := c.Receive()
+       if err != nil {
+               return vbSeqnoMap, fmt.Errorf("failed to receive: %v", err)
+       }
+
+       vbSeqnosList, err := parseGetSeqnoResp(res.Body)
+       if err != nil {
+               logging.Errorf("Unable to parse : err: %v\n", err)
+               return vbSeqnoMap, err
+       }
+
+       if vbSeqnoMap == nil {
+               vbSeqnoMap = make(map[uint16]uint64)
+       }
+
+       combineMapWithReturnedList(vbSeqnoMap, vbSeqnosList)
+       return vbSeqnoMap, nil
+}
+
+func combineMapWithReturnedList(vbSeqnoMap map[uint16]uint64, list *VBSeqnos) {
+       if list == nil {
+               return
+       }
+
+       // If the map contains exactly the existing vbs in the list, no need to modify
+       needToCleanupMap := true
+       if len(vbSeqnoMap) == 0 {
+               needToCleanupMap = false
+       } else if len(vbSeqnoMap) == len(*list) {
+               needToCleanupMap = false
+               for _, pair := range *list {
+                       _, vbExists := vbSeqnoMap[uint16(pair[0])]
+                       if !vbExists {
+                               needToCleanupMap = true
+                               break
+                       }
+               }
+       }
+
+       if needToCleanupMap {
+               var vbsToDelete []uint16
+               for vbInSeqnoMap, _ := range vbSeqnoMap {
+                       // If a vb in the seqno map doesn't exist in the returned list, need to clean up
+                       // to ensure returning an accurate result
+                       found := false
+                       var vbno uint16
+                       for _, pair := range *list {
+                               vbno = uint16(pair[0])
+                               if vbno == vbInSeqnoMap {
+                                       found = true
+                                       break
+                               } else if vbno > vbInSeqnoMap {
+                                       // definitely not in the list
+                                       break
+                               }
+                       }
+                       if !found {
+                               vbsToDelete = append(vbsToDelete, vbInSeqnoMap)
+                       }
+               }
+
+               for _, vbno := range vbsToDelete {
+                       delete(vbSeqnoMap, vbno)
+               }
+       }
+
+       // Set the map with data from the list
+       for _, pair := range *list {
+               vbno := uint16(pair[0])
+               seqno := pair[1]
+               vbSeqnoMap[vbno] = seqno
+       }
+}
index 31e0abfbfd2816acfc051644ba0840d8879f5fdc..7ede0a128dc9828a8d2a37996523249afdfc1dc8 100644 (file)
@@ -89,6 +89,9 @@ type UprEvent struct {
 // FailoverLog containing vvuid and sequnce number
 type FailoverLog [][2]uint64
 
+// Containing a pair of vbno and the high seqno
+type VBSeqnos [][2]uint64
+
 func makeUprEvent(rq gomemcached.MCRequest, stream *UprStream, bytesReceivedFromDCP int) *UprEvent {
        event := &UprEvent{
                Opcode:       rq.Opcode,
@@ -148,6 +151,8 @@ func makeUprEvent(rq gomemcached.MCRequest, stream *UprStream, bytesReceivedFrom
                event.SnapshotType = binary.BigEndian.Uint32(rq.Extras[16:20])
        } else if event.IsSystemEvent() {
                event.PopulateEvent(rq.Extras)
+       } else if event.IsSeqnoAdv() {
+               event.PopulateSeqnoAdv(rq.Extras)
        }
 
        return event
@@ -199,17 +204,31 @@ func (event *UprEvent) IsSystemEvent() bool {
        return event.Opcode == gomemcached.DCP_SYSTEM_EVENT
 }
 
+func (event *UprEvent) IsSeqnoAdv() bool {
+       return event.Opcode == gomemcached.DCP_SEQNO_ADV
+}
+
 func (event *UprEvent) PopulateEvent(extras []byte) {
        if len(extras) < dcpSystemEventExtraLen {
                // Wrong length, don't parse
                return
        }
+
        event.Seqno = binary.BigEndian.Uint64(extras[:8])
        event.SystemEvent = SystemEventType(binary.BigEndian.Uint32(extras[8:12]))
        var versionTemp uint16 = binary.BigEndian.Uint16(extras[12:14])
        event.SysEventVersion = uint8(versionTemp >> 8)
 }
 
+func (event *UprEvent) PopulateSeqnoAdv(extras []byte) {
+       if len(extras) < dcpSeqnoAdvExtraLen {
+               // Wrong length, don't parse
+               return
+       }
+
+       event.Seqno = binary.BigEndian.Uint64(extras[:8])
+}
+
 func (event *UprEvent) GetSystemEventName() (string, error) {
        switch event.SystemEvent {
        case CollectionCreate:
index 085b03c14582152354918c80632bcbbacecc6aaf..be676aa71cde18fed77504fcabe16533ceaddc64 100644 (file)
@@ -20,9 +20,11 @@ const uprDeletetionExtraLen = 18
 const uprDeletetionWithDeletionTimeExtraLen = 21
 const uprSnapshotExtraLen = 20
 const dcpSystemEventExtraLen = 13
+const dcpSeqnoAdvExtraLen = 8
 const bufferAckThreshold = 0.2
 const opaqueOpen = 0xBEAF0001
 const opaqueFailover = 0xDEADBEEF
+const opaqueGetSeqno = 0xDEADBEEF
 const uprDefaultNoopInterval = 120
 
 // Counter on top of opaqueOpen that others can draw from for open and control msgs
@@ -605,44 +607,6 @@ func (feed *UprFeed) uprOpen(name string, sequence uint32, bufSize uint32, featu
        return
 }
 
-// UprGetFailoverLog for given list of vbuckets.
-func (mc *Client) UprGetFailoverLog(
-       vb []uint16) (map[uint16]*FailoverLog, error) {
-
-       rq := &gomemcached.MCRequest{
-               Opcode: gomemcached.UPR_FAILOVERLOG,
-               Opaque: opaqueFailover,
-       }
-
-       var allFeaturesDisabled UprFeatures
-       if err := doUprOpen(mc, "FailoverLog", 0, allFeaturesDisabled); err != nil {
-               return nil, fmt.Errorf("UPR_OPEN Failed %s", err.Error())
-       }
-
-       failoverLogs := make(map[uint16]*FailoverLog)
-       for _, vBucket := range vb {
-               rq.VBucket = vBucket
-               if err := mc.Transmit(rq); err != nil {
-                       return nil, err
-               }
-               res, err := mc.Receive()
-
-               if err != nil {
-                       return nil, fmt.Errorf("failed to receive %s", err.Error())
-               } else if res.Opcode != gomemcached.UPR_FAILOVERLOG || res.Status != gomemcached.SUCCESS {
-                       return nil, fmt.Errorf("unexpected #opcode %v", res.Opcode)
-               }
-
-               flog, err := parseFailoverLog(res.Body)
-               if err != nil {
-                       return nil, fmt.Errorf("unable to parse failover logs for vb %d", vb)
-               }
-               failoverLogs[vBucket] = flog
-       }
-
-       return failoverLogs, nil
-}
-
 // UprRequestStream for a single vbucket.
 func (feed *UprFeed) UprRequestStream(vbno, opaqueMSB uint16, flags uint32,
        vuuid, startSequence, endSequence, snapStart, snapEnd uint64) error {
@@ -793,7 +757,6 @@ func (feed *UprFeed) StartFeedWithConfig(datachan_len int) error {
 }
 
 func parseFailoverLog(body []byte) (*FailoverLog, error) {
-
        if len(body)%16 != 0 {
                err := fmt.Errorf("invalid body length %v, in failover-log", len(body))
                return nil, err
@@ -808,6 +771,24 @@ func parseFailoverLog(body []byte) (*FailoverLog, error) {
        return &log, nil
 }
 
+func parseGetSeqnoResp(body []byte) (*VBSeqnos, error) {
+       // vbno of 2 bytes + seqno of 8 bytes
+       var entryLen int = 10
+
+       if len(body)%entryLen != 0 {
+               err := fmt.Errorf("invalid body length %v, in getVbSeqno", len(body))
+               return nil, err
+       }
+       vbSeqnos := make(VBSeqnos, len(body)/entryLen)
+       for i, j := 0, 0; i < len(body); i += entryLen {
+               vbno := binary.BigEndian.Uint16(body[i : i+2])
+               seqno := binary.BigEndian.Uint64(body[i+2 : i+10])
+               vbSeqnos[j] = [2]uint64{uint64(vbno), seqno}
+               j++
+       }
+       return &vbSeqnos, nil
+}
+
 func handleStreamRequest(
        res *gomemcached.MCResponse,
        headerBuf []byte,
@@ -987,6 +968,14 @@ loop:
                                                break loop
                                        }
                                        event = makeUprEvent(pkt, stream, bytes)
+                               case gomemcached.UPR_FAILOVERLOG:
+                                       logging.Infof("Failover log for vb %d received: %v", vb, pkt)
+                               case gomemcached.DCP_SEQNO_ADV:
+                                       if stream == nil {
+                                               logging.Infof("Stream not found for vb %d: %#v", vb, pkt)
+                                               break loop
+                                       }
+                                       event = makeUprEvent(pkt, stream, bytes)
                                default:
                                        logging.Infof("Recived an unknown response for vbucket %d", vb)
                                }
index 11f383b8ff8c867f6f01ef9df25a6d114e5e1cb9..1dfe2febf2650e6568d616a49f3a6067fbfa32b6 100644 (file)
@@ -74,6 +74,7 @@ const (
        TAP_VBUCKET_SET      = CommandCode(0x45) // Sets state of vbucket in receiver (used in takeover)
        TAP_CHECKPOINT_START = CommandCode(0x46) // Notifies start of new checkpoint
        TAP_CHECKPOINT_END   = CommandCode(0x47) // Notifies end of checkpoint
+       GET_ALL_VB_SEQNOS    = CommandCode(0x48) // Get current high sequence numbers from all vbuckets located on the server
 
        UPR_OPEN        = CommandCode(0x50) // Open a UPR connection with a name
        UPR_ADDSTREAM   = CommandCode(0x51) // Sent by ebucketMigrator to UPR Consumer
@@ -102,18 +103,21 @@ const (
        SUBDOC_MULTI_LOOKUP      = CommandCode(0xd0) // Multi lookup. Doc xattrs and meta.
 
        DCP_SYSTEM_EVENT = CommandCode(0x5f) // A system event has occurred
-
+       DCP_SEQNO_ADV    = CommandCode(0x64) // Sent when the vb seqno has advanced due to an unsubscribed event
 )
 
 // command codes that are counted toward DCP control buffer
 // when DCP clients receive DCP messages with these command codes, they need to provide acknowledgement
 var BufferedCommandCodeMap = map[CommandCode]bool{
-       SET_VBUCKET:    true,
-       UPR_STREAMEND:  true,
-       UPR_SNAPSHOT:   true,
-       UPR_MUTATION:   true,
-       UPR_DELETION:   true,
-       UPR_EXPIRATION: true}
+       SET_VBUCKET:      true,
+       UPR_STREAMEND:    true,
+       UPR_SNAPSHOT:     true,
+       UPR_MUTATION:     true,
+       UPR_DELETION:     true,
+       UPR_EXPIRATION:   true,
+       DCP_SYSTEM_EVENT: true,
+       DCP_SEQNO_ADV:    true,
+}
 
 // Status field for memcached response.
 type Status uint16
@@ -274,6 +278,8 @@ func init() {
        CommandNames[SUBDOC_MULTI_LOOKUP] = "SUBDOC_MULTI_LOOKUP"
        CommandNames[GET_COLLECTIONS_MANIFEST] = "GET_COLLECTIONS_MANIFEST"
        CommandNames[COLLECTIONS_GET_CID] = "COLLECTIONS_GET_CID"
+       CommandNames[DCP_SYSTEM_EVENT] = "DCP_SYSTEM_EVENT"
+       CommandNames[DCP_SEQNO_ADV] = "DCP_SEQNO_ADV"
 
        StatusNames = make(map[Status]string)
        StatusNames[SUCCESS] = "SUCCESS"
index 35d0fe2dafc7cb02c28e7a4c8b4a71e055352a8d..c4f154f2243aec9579067dcfa789ca30057173af 100644 (file)
@@ -11,6 +11,8 @@ import (
 // The current limit, 20MB, is the size limit supported by ep-engine.
 var MaxBodyLen = int(20 * 1024 * 1024)
 
+const _BUFLEN = 256
+
 // MCRequest is memcached Request
 type MCRequest struct {
        // The command being issued
@@ -27,6 +29,10 @@ type MCRequest struct {
        DataType uint8
        // len() calls are expensive - cache this in case for collection
        Keylen int
+       // Collection id for collection based operations
+       CollId [binary.MaxVarintLen32]byte
+       // Length of collection id
+       CollIdLen int
        // Flexible Framing Extras
        FramingExtras []FrameInfo
        // Stored length of incoming framing extras
@@ -34,8 +40,12 @@ type MCRequest struct {
 }
 
 // Size gives the number of bytes this request requires.
+func (req *MCRequest) HdrSize() int {
+       return HDR_LEN + len(req.Extras) + req.CollIdLen + req.FramingElen + len(req.Key)
+}
+
 func (req *MCRequest) Size() int {
-       return HDR_LEN + len(req.Extras) + len(req.Key) + len(req.Body) + len(req.ExtMeta) + req.FramingElen
+       return req.HdrSize() + len(req.Body) + len(req.ExtMeta)
 }
 
 // A debugging string representation of this request
@@ -68,7 +78,7 @@ func (req *MCRequest) fillRegularHeaderBytes(data []byte) int {
        data[pos] = byte(req.Opcode)
        pos++
        binary.BigEndian.PutUint16(data[pos:pos+2],
-               uint16(len(req.Key)))
+               uint16(req.CollIdLen+len(req.Key)))
        pos += 2
 
        // 4
@@ -84,7 +94,7 @@ func (req *MCRequest) fillRegularHeaderBytes(data []byte) int {
 
        // 8
        binary.BigEndian.PutUint32(data[pos:pos+4],
-               uint32(len(req.Body)+len(req.Key)+len(req.Extras)+len(req.ExtMeta)))
+               uint32(len(req.Body)+req.CollIdLen+len(req.Key)+len(req.Extras)+len(req.ExtMeta)))
        pos += 4
 
        // 12
@@ -97,15 +107,21 @@ func (req *MCRequest) fillRegularHeaderBytes(data []byte) int {
        }
        pos += 8
 
+       // 24 - extras
        if len(req.Extras) > 0 {
                copy(data[pos:pos+len(req.Extras)], req.Extras)
                pos += len(req.Extras)
        }
 
        if len(req.Key) > 0 {
+               if req.CollIdLen > 0 {
+                       copy(data[pos:pos+req.CollIdLen], req.CollId[:])
+                       pos += req.CollIdLen
+               }
                copy(data[pos:pos+len(req.Key)], req.Key)
                pos += len(req.Key)
        }
+
        return pos
 }
 
@@ -132,7 +148,7 @@ func (req *MCRequest) fillFlexHeaderBytes(data []byte) (int, bool) {
        data[0] = FLEX_MAGIC
        data[1] = byte(req.Opcode)
        data[2] = byte(req.FramingElen)
-       data[3] = byte(req.Keylen)
+       data[3] = byte(req.Keylen + req.CollIdLen)
        elen := len(req.Extras)
        data[4] = byte(elen)
        if req.DataType != 0 {
@@ -140,7 +156,7 @@ func (req *MCRequest) fillFlexHeaderBytes(data []byte) (int, bool) {
        }
        binary.BigEndian.PutUint16(data[6:8], req.VBucket)
        binary.BigEndian.PutUint32(data[8:12],
-               uint32(len(req.Body)+req.Keylen+elen+len(req.ExtMeta)+req.FramingElen))
+               uint32(len(req.Body)+req.Keylen+req.CollIdLen+elen+len(req.ExtMeta)+req.FramingElen))
        binary.BigEndian.PutUint32(data[12:16], req.Opaque)
        if req.Cas != 0 {
                binary.BigEndian.PutUint64(data[16:24], req.Cas)
@@ -205,12 +221,27 @@ func (req *MCRequest) fillFlexHeaderBytes(data []byte) (int, bool) {
        // Add keys
        if req.Keylen > 0 {
                if mergeMode {
+                       var key []byte
+                       var keylen int
+                       if req.CollIdLen == 0 {
+                               key = req.Key
+                               keylen = req.Keylen
+                       } else {
+                               key = append(key, req.CollId[:]...)
+                               key = append(key, req.Key...)
+                               keylen = req.Keylen + req.CollIdLen
+                       }
                        outputBytes = ShiftByteSliceRight4Bits(req.Key)
                        data = Merge2HalfByteSlices(data, outputBytes)
+                       pos += keylen
                } else {
+                       if req.CollIdLen > 0 {
+                               copy(data[pos:pos+req.CollIdLen], req.CollId[:])
+                               pos += req.CollIdLen
+                       }
                        copy(data[pos:pos+req.Keylen], req.Key)
+                       pos += req.Keylen
                }
-               pos += req.Keylen
        }
 
        return pos, mergeMode
@@ -227,7 +258,7 @@ func (req *MCRequest) FillHeaderBytes(data []byte) (int, bool) {
 // HeaderBytes will return the wire representation of the request header
 // (with the extras and key).
 func (req *MCRequest) HeaderBytes() []byte {
-       data := make([]byte, HDR_LEN+len(req.Extras)+len(req.Key)+req.FramingElen)
+       data := make([]byte, HDR_LEN+len(req.Extras)+req.CollIdLen+len(req.Key)+req.FramingElen)
 
        req.FillHeaderBytes(data)
 
@@ -237,7 +268,11 @@ func (req *MCRequest) HeaderBytes() []byte {
 // Bytes will return the wire representation of this request.
 func (req *MCRequest) Bytes() []byte {
        data := make([]byte, req.Size())
+       req.bytes(data)
+       return data
+}
 
+func (req *MCRequest) bytes(data []byte) {
        pos, halfByteMode := req.FillHeaderBytes(data)
        // TODO - the halfByteMode should be revisited for a more efficient
        // way of doing things
@@ -259,15 +294,19 @@ func (req *MCRequest) Bytes() []byte {
                        copy(data[pos+len(req.Body):pos+len(req.Body)+len(req.ExtMeta)], req.ExtMeta)
                }
        }
-       return data
 }
 
 // Transmit will send this request message across a writer.
 func (req *MCRequest) Transmit(w io.Writer) (n int, err error) {
-       if len(req.Body) < 128 {
-               n, err = w.Write(req.Bytes())
+       l := req.Size()
+       if l < _BUFLEN {
+               data := make([]byte, l)
+               req.bytes(data)
+               n, err = w.Write(data)
        } else {
-               n, err = w.Write(req.HeaderBytes())
+               data := make([]byte, req.HdrSize())
+               req.FillHeaderBytes(data)
+               n, err = w.Write(data)
                if err == nil {
                        m := 0
                        m, err = w.Write(req.Body)
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/.gitignore b/vendor/github.com/couchbaselabs/go-couchbase/.gitignore
deleted file mode 100644 (file)
index eda885c..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#*
-*.6
-*.a
-*~
-*.swp
-/examples/basic/basic
-/hello/hello
-/populate/populate
-/tools/view2go/view2go
-/tools/loadfile/loadfile
-gotags.files
-TAGS
-6.out
-_*
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/.travis.yml b/vendor/github.com/couchbaselabs/go-couchbase/.travis.yml
deleted file mode 100644 (file)
index 4ecafb1..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-language: go
-install: go get -v -d ./... && go build -v ./...
-script: go test -v ./...
-
-go: 1.1.1
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/LICENSE b/vendor/github.com/couchbaselabs/go-couchbase/LICENSE
deleted file mode 100644 (file)
index 0b23ef3..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2013  Couchbase, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/README.markdown b/vendor/github.com/couchbaselabs/go-couchbase/README.markdown
deleted file mode 100644 (file)
index bf5fe49..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-# A smart client for couchbase in go
-
-This is a *unoffical* version of a Couchbase Golang client. If you are
-looking for the *Offical* Couchbase Golang client please see
-    [CB-go])[https://github.com/couchbaselabs/gocb].
-
-This is an evolving package, but does provide a useful interface to a
-[couchbase](http://www.couchbase.com/) server including all of the
-pool/bucket discovery features, compatible key distribution with other
-clients, and vbucket motion awareness so application can continue to
-operate during rebalances.
-
-It also supports view querying with source node randomization so you
-don't bang on all one node to do all the work.
-
-## Install
-
-    go get github.com/couchbase/go-couchbase
-
-## Example
-
-    c, err := couchbase.Connect("http://dev-couchbase.example.com:8091/")
-    if err != nil {
-       log.Fatalf("Error connecting:  %v", err)
-    }
-
-    pool, err := c.GetPool("default")
-    if err != nil {
-       log.Fatalf("Error getting pool:  %v", err)
-    }
-
-    bucket, err := pool.GetBucket("default")
-    if err != nil {
-       log.Fatalf("Error getting bucket:  %v", err)
-    }
-
-    bucket.Set("someKey", 0, []string{"an", "example", "list"})
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/audit.go b/vendor/github.com/couchbaselabs/go-couchbase/audit.go
deleted file mode 100644 (file)
index 3db7d9f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-package couchbase
-
-import ()
-
-// Sample data:
-// {"disabled":["12333", "22244"],"uid":"132492431","auditdEnabled":true,
-//  "disabledUsers":[{"name":"bill","domain":"local"},{"name":"bob","domain":"local"}],
-//  "logPath":"/Users/johanlarson/Library/Application Support/Couchbase/var/lib/couchbase/logs",
-//  "rotateInterval":86400,"rotateSize":20971520}
-type AuditSpec struct {
-       Disabled       []uint32    `json:"disabled"`
-       Uid            string      `json:"uid"`
-       AuditdEnabled  bool        `json:"auditdEnabled`
-       DisabledUsers  []AuditUser `json:"disabledUsers"`
-       LogPath        string      `json:"logPath"`
-       RotateInterval int64       `json:"rotateInterval"`
-       RotateSize     int64       `json:"rotateSize"`
-}
-
-type AuditUser struct {
-       Name   string `json:"name"`
-       Domain string `json:"domain"`
-}
-
-func (c *Client) GetAuditSpec() (*AuditSpec, error) {
-       ret := &AuditSpec{}
-       err := c.parseURLResponse("/settings/audit", ret)
-       if err != nil {
-               return nil, err
-       }
-       return ret, nil
-}
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/client.go b/vendor/github.com/couchbaselabs/go-couchbase/client.go
deleted file mode 100644 (file)
index 433b08f..0000000
+++ /dev/null
@@ -1,1477 +0,0 @@
-/*
-Package couchbase provides a smart client for go.
-
-Usage:
-
- client, err := couchbase.Connect("http://myserver:8091/")
- handleError(err)
- pool, err := client.GetPool("default")
- handleError(err)
- bucket, err := pool.GetBucket("MyAwesomeBucket")
- handleError(err)
- ...
-
-or a shortcut for the bucket directly
-
- bucket, err := couchbase.GetBucket("http://myserver:8091/", "default", "default")
-
-in any case, you can specify authentication credentials using
-standard URL userinfo syntax:
-
- b, err := couchbase.GetBucket("http://bucketname:bucketpass@myserver:8091/",
-         "default", "bucket")
-*/
-package couchbase
-
-import (
-       "encoding/binary"
-       "encoding/json"
-       "errors"
-       "fmt"
-       "io"
-       "runtime"
-       "strconv"
-       "strings"
-       "sync"
-       "time"
-       "unsafe"
-
-       "github.com/couchbase/gomemcached"
-       "github.com/couchbase/gomemcached/client" // package name is 'memcached'
-       "github.com/couchbase/goutils/logging"
-)
-
-// Mutation Token
-type MutationToken struct {
-       VBid  uint16 // vbucket id
-       Guard uint64 // vbuuid
-       Value uint64 // sequence number
-}
-
-// Maximum number of times to retry a chunk of a bulk get on error.
-var MaxBulkRetries = 5000
-var backOffDuration time.Duration = 100 * time.Millisecond
-var MaxBackOffRetries = 25 // exponentail backOff result in over 30sec (25*13*0.1s)
-
-// If this is set to a nonzero duration, Do() and ViewCustom() will log a warning if the call
-// takes longer than that.
-var SlowServerCallWarningThreshold time.Duration
-
-func slowLog(startTime time.Time, format string, args ...interface{}) {
-       if elapsed := time.Now().Sub(startTime); elapsed > SlowServerCallWarningThreshold {
-               pc, _, _, _ := runtime.Caller(2)
-               caller := runtime.FuncForPC(pc).Name()
-               logging.Infof("go-couchbase: "+format+" in "+caller+" took "+elapsed.String(), args...)
-       }
-}
-
-// Return true if error is KEY_ENOENT. Required by cbq-engine
-func IsKeyEExistsError(err error) bool {
-
-       res, ok := err.(*gomemcached.MCResponse)
-       if ok && res.Status == gomemcached.KEY_EEXISTS {
-               return true
-       }
-
-       return false
-}
-
-// Return true if error is KEY_ENOENT. Required by cbq-engine
-func IsKeyNoEntError(err error) bool {
-
-       res, ok := err.(*gomemcached.MCResponse)
-       if ok && res.Status == gomemcached.KEY_ENOENT {
-               return true
-       }
-
-       return false
-}
-
-// Return true if error suggests a bucket refresh is required. Required by cbq-engine
-func IsRefreshRequired(err error) bool {
-
-       res, ok := err.(*gomemcached.MCResponse)
-       if ok && (res.Status == gomemcached.NO_BUCKET || res.Status == gomemcached.NOT_MY_VBUCKET) {
-               return true
-       }
-
-       return false
-}
-
-// ClientOpCallback is called for each invocation of Do.
-var ClientOpCallback func(opname, k string, start time.Time, err error)
-
-// Do executes a function on a memcached connection to the node owning key "k"
-//
-// Note that this automatically handles transient errors by replaying
-// your function on a "not-my-vbucket" error, so don't assume
-// your command will only be executed only once.
-func (b *Bucket) Do(k string, f func(mc *memcached.Client, vb uint16) error) (err error) {
-       return b.Do2(k, f, true)
-}
-
-func (b *Bucket) Do2(k string, f func(mc *memcached.Client, vb uint16) error, deadline bool) (err error) {
-       if SlowServerCallWarningThreshold > 0 {
-               defer slowLog(time.Now(), "call to Do(%q)", k)
-       }
-
-       vb := b.VBHash(k)
-       maxTries := len(b.Nodes()) * 2
-       for i := 0; i < maxTries; i++ {
-               conn, pool, err := b.getConnectionToVBucket(vb)
-               if err != nil {
-                       if isConnError(err) && backOff(i, maxTries, backOffDuration, true) {
-                               b.Refresh()
-                               continue
-                       }
-                       return err
-               }
-
-               if deadline && DefaultTimeout > 0 {
-                       conn.SetDeadline(getDeadline(noDeadline, DefaultTimeout))
-                       err = f(conn, uint16(vb))
-                       conn.SetDeadline(noDeadline)
-               } else {
-                       err = f(conn, uint16(vb))
-               }
-
-               var retry bool
-               discard := isOutOfBoundsError(err)
-
-               // MB-30967 / MB-31001 implement back off for transient errors
-               if resp, ok := err.(*gomemcached.MCResponse); ok {
-                       switch resp.Status {
-                       case gomemcached.NOT_MY_VBUCKET:
-                               b.Refresh()
-                               // MB-28842: in case of NMVB, check if the node is still part of the map
-                               // and ditch the connection if it isn't.
-                               discard = b.checkVBmap(pool.Node())
-                               retry = true
-                       case gomemcached.NOT_SUPPORTED:
-                               discard = true
-                               retry = true
-                       case gomemcached.ENOMEM:
-                               fallthrough
-                       case gomemcached.TMPFAIL:
-                               retry = backOff(i, maxTries, backOffDuration, true)
-                       default:
-                               retry = false
-                       }
-               } else if err != nil && isConnError(err) && backOff(i, maxTries, backOffDuration, true) {
-                       retry = true
-               }
-
-               if discard {
-                       pool.Discard(conn)
-               } else {
-                       pool.Return(conn)
-               }
-
-               if !retry {
-                       return err
-               }
-       }
-
-       return fmt.Errorf("unable to complete action after %v attemps", maxTries)
-}
-
-type GatheredStats struct {
-       Server string
-       Stats  map[string]string
-       Err    error
-}
-
-func getStatsParallel(sn string, b *Bucket, offset int, which string,
-       ch chan<- GatheredStats) {
-       pool := b.getConnPool(offset)
-       var gatheredStats GatheredStats
-
-       conn, err := pool.Get()
-       defer func() {
-               pool.Return(conn)
-               ch <- gatheredStats
-       }()
-
-       if err != nil {
-               gatheredStats = GatheredStats{Server: sn, Err: err}
-       } else {
-               sm, err := conn.StatsMap(which)
-               gatheredStats = GatheredStats{Server: sn, Stats: sm, Err: err}
-       }
-}
-
-// GetStats gets a set of stats from all servers.
-//
-// Returns a map of server ID -> map of stat key to map value.
-func (b *Bucket) GetStats(which string) map[string]map[string]string {
-       rv := map[string]map[string]string{}
-       for server, gs := range b.GatherStats(which) {
-               if len(gs.Stats) > 0 {
-                       rv[server] = gs.Stats
-               }
-       }
-       return rv
-}
-
-// GatherStats returns a map of server ID -> GatheredStats from all servers.
-func (b *Bucket) GatherStats(which string) map[string]GatheredStats {
-       vsm := b.VBServerMap()
-       if vsm.ServerList == nil {
-               return nil
-       }
-
-       // Go grab all the things at once.
-       ch := make(chan GatheredStats, len(vsm.ServerList))
-       for i, sn := range vsm.ServerList {
-               go getStatsParallel(sn, b, i, which, ch)
-       }
-
-       // Gather the results
-       rv := map[string]GatheredStats{}
-       for range vsm.ServerList {
-               gs := <-ch
-               rv[gs.Server] = gs
-       }
-       return rv
-}
-
-// Get bucket count through the bucket stats
-func (b *Bucket) GetCount(refresh bool) (count int64, err error) {
-       if refresh {
-               b.Refresh()
-       }
-
-       var cnt int64
-       for _, gs := range b.GatherStats("") {
-               if len(gs.Stats) > 0 {
-                       cnt, err = strconv.ParseInt(gs.Stats["curr_items"], 10, 64)
-                       if err != nil {
-                               return 0, err
-                       }
-                       count += cnt
-               }
-       }
-
-       return count, nil
-}
-
-// Get bucket document size through the bucket stats
-func (b *Bucket) GetSize(refresh bool) (size int64, err error) {
-       if refresh {
-               b.Refresh()
-       }
-
-       var sz int64
-       for _, gs := range b.GatherStats("") {
-               if len(gs.Stats) > 0 {
-                       sz, err = strconv.ParseInt(gs.Stats["ep_value_size"], 10, 64)
-                       if err != nil {
-                               return 0, err
-                       }
-                       size += sz
-               }
-       }
-
-       return size, nil
-}
-
-func isAuthError(err error) bool {
-       estr := err.Error()
-       return strings.Contains(estr, "Auth failure")
-}
-
-func IsReadTimeOutError(err error) bool {
-       estr := err.Error()
-       return strings.Contains(estr, "read tcp") ||
-               strings.Contains(estr, "i/o timeout")
-}
-
-func isTimeoutError(err error) bool {
-       estr := err.Error()
-       return strings.Contains(estr, "i/o timeout") ||
-               strings.Contains(estr, "connection timed out") ||
-               strings.Contains(estr, "no route to host")
-}
-
-// Errors that are not considered fatal for our fetch loop
-func isConnError(err error) bool {
-       if err == io.EOF {
-               return true
-       }
-       estr := err.Error()
-       return strings.Contains(estr, "broken pipe") ||
-               strings.Contains(estr, "connection reset") ||
-               strings.Contains(estr, "connection refused") ||
-               strings.Contains(estr, "connection pool is closed")
-}
-
-func isOutOfBoundsError(err error) bool {
-       return err != nil && strings.Contains(err.Error(), "Out of Bounds error")
-
-}
-
-func getDeadline(reqDeadline time.Time, duration time.Duration) time.Time {
-       if reqDeadline.IsZero() && duration > 0 {
-               return time.Now().Add(duration)
-       }
-       return reqDeadline
-}
-
-func backOff(attempt, maxAttempts int, duration time.Duration, exponential bool) bool {
-       if attempt < maxAttempts {
-               // 0th attempt return immediately
-               if attempt > 0 {
-                       if exponential {
-                               duration = time.Duration(attempt) * duration
-                       }
-                       time.Sleep(duration)
-               }
-               return true
-       }
-
-       return false
-}
-
-func (b *Bucket) doBulkGet(vb uint16, keys []string, reqDeadline time.Time,
-       ch chan<- map[string]*gomemcached.MCResponse, ech chan<- error, subPaths []string,
-       eStatus *errorStatus) {
-       if SlowServerCallWarningThreshold > 0 {
-               defer slowLog(time.Now(), "call to doBulkGet(%d, %d keys)", vb, len(keys))
-       }
-
-       rv := _STRING_MCRESPONSE_POOL.Get()
-       attempts := 0
-       backOffAttempts := 0
-       done := false
-       bname := b.Name
-       for ; attempts < MaxBulkRetries && !done && !eStatus.errStatus; attempts++ {
-
-               if len(b.VBServerMap().VBucketMap) < int(vb) {
-                       //fatal
-                       err := fmt.Errorf("vbmap smaller than requested for %v", bname)
-                       logging.Errorf("go-couchbase: %v vb %d vbmap len %d", err.Error(), vb, len(b.VBServerMap().VBucketMap))
-                       ech <- err
-                       return
-               }
-
-               masterID := b.VBServerMap().VBucketMap[vb][0]
-
-               if masterID < 0 {
-                       // fatal
-                       err := fmt.Errorf("No master node available for %v vb %d", bname, vb)
-                       logging.Errorf("%v", err.Error())
-                       ech <- err
-                       return
-               }
-
-               // This stack frame exists to ensure we can clean up
-               // connection at a reasonable time.
-               err := func() error {
-                       pool := b.getConnPool(masterID)
-                       conn, err := pool.Get()
-                       if err != nil {
-                               if isAuthError(err) || isTimeoutError(err) {
-                                       logging.Errorf("Fatal Error %v : %v", bname, err)
-                                       ech <- err
-                                       return err
-                               } else if isConnError(err) {
-                                       if !backOff(backOffAttempts, MaxBackOffRetries, backOffDuration, true) {
-                                               logging.Errorf("Connection Error %v : %v", bname, err)
-                                               ech <- err
-                                               return err
-                                       }
-                                       b.Refresh()
-                                       backOffAttempts++
-                               }
-                               logging.Infof("Pool Get returned %v: %v", bname, err)
-                               // retry
-                               return nil
-                       }
-
-                       conn.SetDeadline(getDeadline(reqDeadline, DefaultTimeout))
-                       err = conn.GetBulk(vb, keys, rv, subPaths)
-                       conn.SetDeadline(noDeadline)
-
-                       discard := false
-                       defer func() {
-                               if discard {
-                                       pool.Discard(conn)
-                               } else {
-                                       pool.Return(conn)
-                               }
-                       }()
-
-                       switch err.(type) {
-                       case *gomemcached.MCResponse:
-                               notSMaxTries := len(b.Nodes()) * 2
-                               st := err.(*gomemcached.MCResponse).Status
-                               if st == gomemcached.NOT_MY_VBUCKET || (st == gomemcached.NOT_SUPPORTED && attempts < notSMaxTries) {
-                                       b.Refresh()
-                                       discard = b.checkVBmap(pool.Node())
-                                       return nil // retry
-                               } else if st == gomemcached.EBUSY || st == gomemcached.LOCKED {
-                                       if (attempts % (MaxBulkRetries / 100)) == 0 {
-                                               logging.Infof("Retrying Memcached error (%v) FOR %v(vbid:%d, keys:<ud>%v</ud>)",
-                                                       err.Error(), bname, vb, keys)
-                                       }
-                                       return nil // retry
-                               } else if (st == gomemcached.ENOMEM || st == gomemcached.TMPFAIL) && backOff(backOffAttempts, MaxBackOffRetries, backOffDuration, true) {
-                                       // MB-30967 / MB-31001 use backoff for TMPFAIL too
-                                       backOffAttempts++
-                                       logging.Infof("Retrying Memcached error (%v) FOR %v(vbid:%d, keys:<ud>%v</ud>)",
-                                               err.Error(), bname, vb, keys)
-                                       return nil // retry
-                               }
-                               ech <- err
-                               return err
-                       case error:
-                               if isOutOfBoundsError(err) {
-                                       // We got an out of bound error, retry the operation
-                                       discard = true
-                                       return nil
-                               } else if isConnError(err) && backOff(backOffAttempts, MaxBackOffRetries, backOffDuration, true) {
-                                       backOffAttempts++
-                                       logging.Errorf("Connection Error: %s. Refreshing bucket %v (vbid:%v,keys:<ud>%v</ud>)",
-                                               err.Error(), bname, vb, keys)
-                                       discard = true
-                                       b.Refresh()
-                                       return nil // retry
-                               }
-                               ech <- err
-                               ch <- rv
-                               return err
-                       }
-
-                       done = true
-                       return nil
-               }()
-
-               if err != nil {
-                       return
-               }
-       }
-
-       if attempts >= MaxBulkRetries {
-               err := fmt.Errorf("bulkget exceeded MaxBulkRetries for %v(vbid:%d,keys:<ud>%v</ud>)", bname, vb, keys)
-               logging.Errorf("%v", err.Error())
-               ech <- err
-       }
-
-       ch <- rv
-}
-
-type errorStatus struct {
-       errStatus bool
-}
-
-type vbBulkGet struct {
-       b           *Bucket
-       ch          chan<- map[string]*gomemcached.MCResponse
-       ech         chan<- error
-       k           uint16
-       keys        []string
-       reqDeadline time.Time
-       wg          *sync.WaitGroup
-       subPaths    []string
-       groupError  *errorStatus
-}
-
-const _NUM_CHANNELS = 5
-
-var _NUM_CHANNEL_WORKERS = (runtime.NumCPU() + 1) / 2
-var DefaultDialTimeout = time.Duration(0)
-var DefaultTimeout = time.Duration(0)
-var noDeadline = time.Time{}
-
-// Buffer 4k requests per worker
-var _VB_BULK_GET_CHANNELS []chan *vbBulkGet
-
-func InitBulkGet() {
-
-       DefaultDialTimeout = 20 * time.Second
-       DefaultTimeout = 120 * time.Second
-
-       memcached.SetDefaultDialTimeout(DefaultDialTimeout)
-
-       _VB_BULK_GET_CHANNELS = make([]chan *vbBulkGet, _NUM_CHANNELS)
-
-       for i := 0; i < _NUM_CHANNELS; i++ {
-               channel := make(chan *vbBulkGet, 16*1024*_NUM_CHANNEL_WORKERS)
-               _VB_BULK_GET_CHANNELS[i] = channel
-
-               for j := 0; j < _NUM_CHANNEL_WORKERS; j++ {
-                       go vbBulkGetWorker(channel)
-               }
-       }
-}
-
-func vbBulkGetWorker(ch chan *vbBulkGet) {
-       defer func() {
-               // Workers cannot panic and die
-               recover()
-               go vbBulkGetWorker(ch)
-       }()
-
-       for vbg := range ch {
-               vbDoBulkGet(vbg)
-       }
-}
-
-func vbDoBulkGet(vbg *vbBulkGet) {
-       defer vbg.wg.Done()
-       defer func() {
-               // Workers cannot panic and die
-               recover()
-       }()
-       vbg.b.doBulkGet(vbg.k, vbg.keys, vbg.reqDeadline, vbg.ch, vbg.ech, vbg.subPaths, vbg.groupError)
-}
-
-var _ERR_CHAN_FULL = fmt.Errorf("Data request queue full, aborting query.")
-
-func (b *Bucket) processBulkGet(kdm map[uint16][]string, reqDeadline time.Time,
-       ch chan<- map[string]*gomemcached.MCResponse, ech chan<- error, subPaths []string,
-       eStatus *errorStatus) {
-
-       defer close(ch)
-       defer close(ech)
-
-       wg := &sync.WaitGroup{}
-
-       for k, keys := range kdm {
-
-               // GetBulk() group has error donot Queue items for this group
-               if eStatus.errStatus {
-                       break
-               }
-
-               vbg := &vbBulkGet{
-                       b:           b,
-                       ch:          ch,
-                       ech:         ech,
-                       k:           k,
-                       keys:        keys,
-                       reqDeadline: reqDeadline,
-                       wg:          wg,
-                       subPaths:    subPaths,
-                       groupError:  eStatus,
-               }
-
-               wg.Add(1)
-
-               // Random int
-               // Right shift to avoid 8-byte alignment, and take low bits
-               c := (uintptr(unsafe.Pointer(vbg)) >> 4) % _NUM_CHANNELS
-
-               select {
-               case _VB_BULK_GET_CHANNELS[c] <- vbg:
-                       // No-op
-               default:
-                       // Buffer full, abandon the bulk get
-                       ech <- _ERR_CHAN_FULL
-                       wg.Add(-1)
-               }
-       }
-
-       // Wait for my vb bulk gets
-       wg.Wait()
-}
-
-type multiError []error
-
-func (m multiError) Error() string {
-       if len(m) == 0 {
-               panic("Error of none")
-       }
-
-       return fmt.Sprintf("{%v errors, starting with %v}", len(m), m[0].Error())
-}
-
-// Convert a stream of errors from ech into a multiError (or nil) and
-// send down eout.
-//
-// At least one send is guaranteed on eout, but two is possible, so
-// buffer the out channel appropriately.
-func errorCollector(ech <-chan error, eout chan<- error, eStatus *errorStatus) {
-       defer func() { eout <- nil }()
-       var errs multiError
-       for e := range ech {
-               if !eStatus.errStatus && !IsKeyNoEntError(e) {
-                       eStatus.errStatus = true
-               }
-
-               errs = append(errs, e)
-       }
-
-       if len(errs) > 0 {
-               eout <- errs
-       }
-}
-
-// Fetches multiple keys concurrently, with []byte values
-//
-// This is a wrapper around GetBulk which converts all values returned
-// by GetBulk from raw memcached responses into []byte slices.
-// Returns one document for duplicate keys
-func (b *Bucket) GetBulkRaw(keys []string) (map[string][]byte, error) {
-
-       resp, eout := b.getBulk(keys, noDeadline, nil)
-
-       rv := make(map[string][]byte, len(keys))
-       for k, av := range resp {
-               rv[k] = av.Body
-       }
-
-       b.ReleaseGetBulkPools(resp)
-       return rv, eout
-
-}
-
-// GetBulk fetches multiple keys concurrently.
-//
-// Unlike more convenient GETs, the entire response is returned in the
-// map array for each key.  Keys that were not found will not be included in
-// the map.
-
-func (b *Bucket) GetBulk(keys []string, reqDeadline time.Time, subPaths []string) (map[string]*gomemcached.MCResponse, error) {
-       return b.getBulk(keys, reqDeadline, subPaths)
-}
-
-func (b *Bucket) ReleaseGetBulkPools(rv map[string]*gomemcached.MCResponse) {
-       _STRING_MCRESPONSE_POOL.Put(rv)
-}
-
-func (b *Bucket) getBulk(keys []string, reqDeadline time.Time, subPaths []string) (map[string]*gomemcached.MCResponse, error) {
-       kdm := _VB_STRING_POOL.Get()
-       defer _VB_STRING_POOL.Put(kdm)
-       for _, k := range keys {
-               if k != "" {
-                       vb := uint16(b.VBHash(k))
-                       a, ok1 := kdm[vb]
-                       if !ok1 {
-                               a = _STRING_POOL.Get()
-                       }
-                       kdm[vb] = append(a, k)
-               }
-       }
-
-       eout := make(chan error, 2)
-       groupErrorStatus := &errorStatus{}
-
-       // processBulkGet will own both of these channels and
-       // guarantee they're closed before it returns.
-       ch := make(chan map[string]*gomemcached.MCResponse)
-       ech := make(chan error)
-
-       go errorCollector(ech, eout, groupErrorStatus)
-       go b.processBulkGet(kdm, reqDeadline, ch, ech, subPaths, groupErrorStatus)
-
-       var rv map[string]*gomemcached.MCResponse
-
-       for m := range ch {
-               if rv == nil {
-                       rv = m
-                       continue
-               }
-
-               for k, v := range m {
-                       rv[k] = v
-               }
-               _STRING_MCRESPONSE_POOL.Put(m)
-       }
-
-       return rv, <-eout
-}
-
-// WriteOptions is the set of option flags availble for the Write
-// method.  They are ORed together to specify the desired request.
-type WriteOptions int
-
-const (
-       // Raw specifies that the value is raw []byte or nil; don't
-       // JSON-encode it.
-       Raw = WriteOptions(1 << iota)
-       // AddOnly indicates an item should only be written if it
-       // doesn't exist, otherwise ErrKeyExists is returned.
-       AddOnly
-       // Persist causes the operation to block until the server
-       // confirms the item is persisted.
-       Persist
-       // Indexable causes the operation to block until it's availble via the index.
-       Indexable
-       // Append indicates the given value should be appended to the
-       // existing value for the given key.
-       Append
-)
-
-var optNames = []struct {
-       opt  WriteOptions
-       name string
-}{
-       {Raw, "raw"},
-       {AddOnly, "addonly"}, {Persist, "persist"},
-       {Indexable, "indexable"}, {Append, "append"},
-}
-
-// String representation of WriteOptions
-func (w WriteOptions) String() string {
-       f := []string{}
-       for _, on := range optNames {
-               if w&on.opt != 0 {
-                       f = append(f, on.name)
-                       w &= ^on.opt
-               }
-       }
-       if len(f) == 0 || w != 0 {
-               f = append(f, fmt.Sprintf("0x%x", int(w)))
-       }
-       return strings.Join(f, "|")
-}
-
-// Error returned from Write with AddOnly flag, when key already exists in the bucket.
-var ErrKeyExists = errors.New("key exists")
-
-// General-purpose value setter.
-//
-// The Set, Add and Delete methods are just wrappers around this.  The
-// interpretation of `v` depends on whether the `Raw` option is
-// given. If it is, v must be a byte array or nil. (A nil value causes
-// a delete.) If `Raw` is not given, `v` will be marshaled as JSON
-// before being written. It must be JSON-marshalable and it must not
-// be nil.
-func (b *Bucket) Write(k string, flags, exp int, v interface{},
-       opt WriteOptions) (err error) {
-
-       if ClientOpCallback != nil {
-               defer func(t time.Time) {
-                       ClientOpCallback(fmt.Sprintf("Write(%v)", opt), k, t, err)
-               }(time.Now())
-       }
-
-       var data []byte
-       if opt&Raw == 0 {
-               data, err = json.Marshal(v)
-               if err != nil {
-                       return err
-               }
-       } else if v != nil {
-               data = v.([]byte)
-       }
-
-       var res *gomemcached.MCResponse
-       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
-               if opt&AddOnly != 0 {
-                       res, err = memcached.UnwrapMemcachedError(
-                               mc.Add(vb, k, flags, exp, data))
-                       if err == nil && res.Status != gomemcached.SUCCESS {
-                               if res.Status == gomemcached.KEY_EEXISTS {
-                                       err = ErrKeyExists
-                               } else {
-                                       err = res
-                               }
-                       }
-               } else if opt&Append != 0 {
-                       res, err = mc.Append(vb, k, data)
-               } else if data == nil {
-                       res, err = mc.Del(vb, k)
-               } else {
-                       res, err = mc.Set(vb, k, flags, exp, data)
-               }
-
-               return err
-       })
-
-       if err == nil && (opt&(Persist|Indexable) != 0) {
-               err = b.WaitForPersistence(k, res.Cas, data == nil)
-       }
-
-       return err
-}
-
-func (b *Bucket) WriteWithMT(k string, flags, exp int, v interface{},
-       opt WriteOptions) (mt *MutationToken, err error) {
-
-       if ClientOpCallback != nil {
-               defer func(t time.Time) {
-                       ClientOpCallback(fmt.Sprintf("WriteWithMT(%v)", opt), k, t, err)
-               }(time.Now())
-       }
-
-       var data []byte
-       if opt&Raw == 0 {
-               data, err = json.Marshal(v)
-               if err != nil {
-                       return nil, err
-               }
-       } else if v != nil {
-               data = v.([]byte)
-       }
-
-       var res *gomemcached.MCResponse
-       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
-               if opt&AddOnly != 0 {
-                       res, err = memcached.UnwrapMemcachedError(
-                               mc.Add(vb, k, flags, exp, data))
-                       if err == nil && res.Status != gomemcached.SUCCESS {
-                               if res.Status == gomemcached.KEY_EEXISTS {
-                                       err = ErrKeyExists
-                               } else {
-                                       err = res
-                               }
-                       }
-               } else if opt&Append != 0 {
-                       res, err = mc.Append(vb, k, data)
-               } else if data == nil {
-                       res, err = mc.Del(vb, k)
-               } else {
-                       res, err = mc.Set(vb, k, flags, exp, data)
-               }
-
-               if len(res.Extras) >= 16 {
-                       vbuuid := uint64(binary.BigEndian.Uint64(res.Extras[0:8]))
-                       seqNo := uint64(binary.BigEndian.Uint64(res.Extras[8:16]))
-                       mt = &MutationToken{VBid: vb, Guard: vbuuid, Value: seqNo}
-               }
-
-               return err
-       })
-
-       if err == nil && (opt&(Persist|Indexable) != 0) {
-               err = b.WaitForPersistence(k, res.Cas, data == nil)
-       }
-
-       return mt, err
-}
-
-// Set a value in this bucket with Cas and return the new Cas value
-func (b *Bucket) Cas(k string, exp int, cas uint64, v interface{}) (uint64, error) {
-       return b.WriteCas(k, 0, exp, cas, v, 0)
-}
-
-// Set a value in this bucket with Cas without json encoding it
-func (b *Bucket) CasRaw(k string, exp int, cas uint64, v interface{}) (uint64, error) {
-       return b.WriteCas(k, 0, exp, cas, v, Raw)
-}
-
-func (b *Bucket) WriteCas(k string, flags, exp int, cas uint64, v interface{},
-       opt WriteOptions) (newCas uint64, err error) {
-
-       if ClientOpCallback != nil {
-               defer func(t time.Time) {
-                       ClientOpCallback(fmt.Sprintf("Write(%v)", opt), k, t, err)
-               }(time.Now())
-       }
-
-       var data []byte
-       if opt&Raw == 0 {
-               data, err = json.Marshal(v)
-               if err != nil {
-                       return 0, err
-               }
-       } else if v != nil {
-               data = v.([]byte)
-       }
-
-       var res *gomemcached.MCResponse
-       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
-               res, err = mc.SetCas(vb, k, flags, exp, cas, data)
-               return err
-       })
-
-       if err == nil && (opt&(Persist|Indexable) != 0) {
-               err = b.WaitForPersistence(k, res.Cas, data == nil)
-       }
-
-       return res.Cas, err
-}
-
-// Extended CAS operation. These functions will return the mutation token, i.e vbuuid & guard
-func (b *Bucket) CasWithMeta(k string, flags int, exp int, cas uint64, v interface{}) (uint64, *MutationToken, error) {
-       return b.WriteCasWithMT(k, flags, exp, cas, v, 0)
-}
-
-func (b *Bucket) CasWithMetaRaw(k string, flags int, exp int, cas uint64, v interface{}) (uint64, *MutationToken, error) {
-       return b.WriteCasWithMT(k, flags, exp, cas, v, Raw)
-}
-
-func (b *Bucket) WriteCasWithMT(k string, flags, exp int, cas uint64, v interface{},
-       opt WriteOptions) (newCas uint64, mt *MutationToken, err error) {
-
-       if ClientOpCallback != nil {
-               defer func(t time.Time) {
-                       ClientOpCallback(fmt.Sprintf("Write(%v)", opt), k, t, err)
-               }(time.Now())
-       }
-
-       var data []byte
-       if opt&Raw == 0 {
-               data, err = json.Marshal(v)
-               if err != nil {
-                       return 0, nil, err
-               }
-       } else if v != nil {
-               data = v.([]byte)
-       }
-
-       var res *gomemcached.MCResponse
-       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
-               res, err = mc.SetCas(vb, k, flags, exp, cas, data)
-               return err
-       })
-
-       if err != nil {
-               return 0, nil, err
-       }
-
-       // check for extras
-       if len(res.Extras) >= 16 {
-               vbuuid := uint64(binary.BigEndian.Uint64(res.Extras[0:8]))
-               seqNo := uint64(binary.BigEndian.Uint64(res.Extras[8:16]))
-               vb := b.VBHash(k)
-               mt = &MutationToken{VBid: uint16(vb), Guard: vbuuid, Value: seqNo}
-       }
-
-       if err == nil && (opt&(Persist|Indexable) != 0) {
-               err = b.WaitForPersistence(k, res.Cas, data == nil)
-       }
-
-       return res.Cas, mt, err
-}
-
-// Set a value in this bucket.
-// The value will be serialized into a JSON document.
-func (b *Bucket) Set(k string, exp int, v interface{}) error {
-       return b.Write(k, 0, exp, v, 0)
-}
-
-// Set a value in this bucket with with flags
-func (b *Bucket) SetWithMeta(k string, flags int, exp int, v interface{}) (*MutationToken, error) {
-       return b.WriteWithMT(k, flags, exp, v, 0)
-}
-
-// SetRaw sets a value in this bucket without JSON encoding it.
-func (b *Bucket) SetRaw(k string, exp int, v []byte) error {
-       return b.Write(k, 0, exp, v, Raw)
-}
-
-// Add adds a value to this bucket; like Set except that nothing
-// happens if the key exists.  The value will be serialized into a
-// JSON document.
-func (b *Bucket) Add(k string, exp int, v interface{}) (added bool, err error) {
-       err = b.Write(k, 0, exp, v, AddOnly)
-       if err == ErrKeyExists {
-               return false, nil
-       }
-       return (err == nil), err
-}
-
-// AddRaw adds a value to this bucket; like SetRaw except that nothing
-// happens if the key exists.  The value will be stored as raw bytes.
-func (b *Bucket) AddRaw(k string, exp int, v []byte) (added bool, err error) {
-       err = b.Write(k, 0, exp, v, AddOnly|Raw)
-       if err == ErrKeyExists {
-               return false, nil
-       }
-       return (err == nil), err
-}
-
-// Add adds a value to this bucket; like Set except that nothing
-// happens if the key exists.  The value will be serialized into a
-// JSON document.
-func (b *Bucket) AddWithMT(k string, exp int, v interface{}) (added bool, mt *MutationToken, err error) {
-       mt, err = b.WriteWithMT(k, 0, exp, v, AddOnly)
-       if err == ErrKeyExists {
-               return false, mt, nil
-       }
-       return (err == nil), mt, err
-}
-
-// AddRaw adds a value to this bucket; like SetRaw except that nothing
-// happens if the key exists.  The value will be stored as raw bytes.
-func (b *Bucket) AddRawWithMT(k string, exp int, v []byte) (added bool, mt *MutationToken, err error) {
-       mt, err = b.WriteWithMT(k, 0, exp, v, AddOnly|Raw)
-       if err == ErrKeyExists {
-               return false, mt, nil
-       }
-       return (err == nil), mt, err
-}
-
-// Append appends raw data to an existing item.
-func (b *Bucket) Append(k string, data []byte) error {
-       return b.Write(k, 0, 0, data, Append|Raw)
-}
-
-func (b *Bucket) GetsMCFromCollection(collUid uint32, key string, reqDeadline time.Time) (*gomemcached.MCResponse, error) {
-       var err error
-       var response *gomemcached.MCResponse
-
-       if key == "" {
-               return nil, nil
-       }
-
-       if ClientOpCallback != nil {
-               defer func(t time.Time) { ClientOpCallback("GetsMCFromCollection", key, t, err) }(time.Now())
-       }
-
-       err = b.Do2(key, func(mc *memcached.Client, vb uint16) error {
-               var err1 error
-
-               mc.SetDeadline(getDeadline(reqDeadline, DefaultTimeout))
-               _, err1 = mc.SelectBucket(b.Name)
-               if err1 != nil {
-                       mc.SetDeadline(noDeadline)
-                       return err1
-               }
-
-               mc.SetDeadline(getDeadline(reqDeadline, DefaultTimeout))
-               response, err1 = mc.GetFromCollection(vb, collUid, key)
-               if err1 != nil {
-                       mc.SetDeadline(noDeadline)
-                       return err1
-               }
-
-               return nil
-       }, false)
-
-       return response, err
-}
-
-// Returns collectionUid, manifestUid, error.
-func (b *Bucket) GetCollectionCID(scope string, collection string, reqDeadline time.Time) (uint32, uint32, error) {
-       var err error
-       var response *gomemcached.MCResponse
-
-       if ClientOpCallback != nil {
-               defer func(t time.Time) { ClientOpCallback("GetCollectionCID", scope+"."+collection, t, err) }(time.Now())
-       }
-
-       var key = "DUMMY" // Contact any server.
-       var manifestUid uint32
-       var collUid uint32
-       err = b.Do2(key, func(mc *memcached.Client, vb uint16) error {
-               var err1 error
-
-               mc.SetDeadline(getDeadline(reqDeadline, DefaultTimeout))
-               _, err1 = mc.SelectBucket(b.Name)
-               if err1 != nil {
-                       mc.SetDeadline(noDeadline)
-                       return err1
-               }
-
-               response, err1 = mc.CollectionsGetCID(scope, collection)
-               if err1 != nil {
-                       mc.SetDeadline(noDeadline)
-                       return err1
-               }
-
-               manifestUid = binary.BigEndian.Uint32(response.Extras[4:8])
-               collUid = binary.BigEndian.Uint32(response.Extras[8:12])
-
-               return nil
-       }, false)
-
-       return collUid, manifestUid, err
-}
-
-// Get a value straight from Memcached
-func (b *Bucket) GetsMC(key string, reqDeadline time.Time) (*gomemcached.MCResponse, error) {
-       var err error
-       var response *gomemcached.MCResponse
-
-       if key == "" {
-               return nil, nil
-       }
-
-       if ClientOpCallback != nil {
-               defer func(t time.Time) { ClientOpCallback("GetsMC", key, t, err) }(time.Now())
-       }
-
-       err = b.Do2(key, func(mc *memcached.Client, vb uint16) error {
-               var err1 error
-
-               mc.SetDeadline(getDeadline(reqDeadline, DefaultTimeout))
-               response, err1 = mc.Get(vb, key)
-               mc.SetDeadline(noDeadline)
-               if err1 != nil {
-                       return err1
-               }
-               return nil
-       }, false)
-       return response, err
-}
-
-// Get a value through the subdoc API
-func (b *Bucket) GetsSubDoc(key string, reqDeadline time.Time, subPaths []string) (*gomemcached.MCResponse, error) {
-       var err error
-       var response *gomemcached.MCResponse
-
-       if key == "" {
-               return nil, nil
-       }
-
-       if ClientOpCallback != nil {
-               defer func(t time.Time) { ClientOpCallback("GetsSubDoc", key, t, err) }(time.Now())
-       }
-
-       err = b.Do2(key, func(mc *memcached.Client, vb uint16) error {
-               var err1 error
-
-               mc.SetDeadline(getDeadline(reqDeadline, DefaultTimeout))
-               response, err1 = mc.GetSubdoc(vb, key, subPaths)
-               mc.SetDeadline(noDeadline)
-               if err1 != nil {
-                       return err1
-               }
-               return nil
-       }, false)
-       return response, err
-}
-
-// GetsRaw gets a raw value from this bucket including its CAS
-// counter and flags.
-func (b *Bucket) GetsRaw(k string) (data []byte, flags int,
-       cas uint64, err error) {
-
-       if ClientOpCallback != nil {
-               defer func(t time.Time) { ClientOpCallback("GetsRaw", k, t, err) }(time.Now())
-       }
-
-       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
-               res, err := mc.Get(vb, k)
-               if err != nil {
-                       return err
-               }
-               cas = res.Cas
-               if len(res.Extras) >= 4 {
-                       flags = int(binary.BigEndian.Uint32(res.Extras))
-               }
-               data = res.Body
-               return nil
-       })
-       return
-}
-
-// Gets gets a value from this bucket, including its CAS counter.  The
-// value is expected to be a JSON stream and will be deserialized into
-// rv.
-func (b *Bucket) Gets(k string, rv interface{}, caso *uint64) error {
-       data, _, cas, err := b.GetsRaw(k)
-       if err != nil {
-               return err
-       }
-       if caso != nil {
-               *caso = cas
-       }
-       return json.Unmarshal(data, rv)
-}
-
-// Get a value from this bucket.
-// The value is expected to be a JSON stream and will be deserialized
-// into rv.
-func (b *Bucket) Get(k string, rv interface{}) error {
-       return b.Gets(k, rv, nil)
-}
-
-// GetRaw gets a raw value from this bucket.  No marshaling is performed.
-func (b *Bucket) GetRaw(k string) ([]byte, error) {
-       d, _, _, err := b.GetsRaw(k)
-       return d, err
-}
-
-// GetAndTouchRaw gets a raw value from this bucket including its CAS
-// counter and flags, and updates the expiry on the doc.
-func (b *Bucket) GetAndTouchRaw(k string, exp int) (data []byte,
-       cas uint64, err error) {
-
-       if ClientOpCallback != nil {
-               defer func(t time.Time) { ClientOpCallback("GetsRaw", k, t, err) }(time.Now())
-       }
-
-       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
-               res, err := mc.GetAndTouch(vb, k, exp)
-               if err != nil {
-                       return err
-               }
-               cas = res.Cas
-               data = res.Body
-               return nil
-       })
-       return data, cas, err
-}
-
-// GetMeta returns the meta values for a key
-func (b *Bucket) GetMeta(k string, flags *int, expiry *int, cas *uint64, seqNo *uint64) (err error) {
-
-       if ClientOpCallback != nil {
-               defer func(t time.Time) { ClientOpCallback("GetsMeta", k, t, err) }(time.Now())
-       }
-
-       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
-               res, err := mc.GetMeta(vb, k)
-               if err != nil {
-                       return err
-               }
-
-               *cas = res.Cas
-               if len(res.Extras) >= 8 {
-                       *flags = int(binary.BigEndian.Uint32(res.Extras[4:]))
-               }
-
-               if len(res.Extras) >= 12 {
-                       *expiry = int(binary.BigEndian.Uint32(res.Extras[8:]))
-               }
-
-               if len(res.Extras) >= 20 {
-                       *seqNo = uint64(binary.BigEndian.Uint64(res.Extras[12:]))
-               }
-
-               return nil
-       })
-
-       return err
-}
-
-// Delete a key from this bucket.
-func (b *Bucket) Delete(k string) error {
-       return b.Write(k, 0, 0, nil, Raw)
-}
-
-// Incr increments the value at a given key by amt and defaults to def if no value present.
-func (b *Bucket) Incr(k string, amt, def uint64, exp int) (val uint64, err error) {
-       if ClientOpCallback != nil {
-               defer func(t time.Time) { ClientOpCallback("Incr", k, t, err) }(time.Now())
-       }
-
-       var rv uint64
-       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
-               res, err := mc.Incr(vb, k, amt, def, exp)
-               if err != nil {
-                       return err
-               }
-               rv = res
-               return nil
-       })
-       return rv, err
-}
-
-// Decr decrements the value at a given key by amt and defaults to def if no value present
-func (b *Bucket) Decr(k string, amt, def uint64, exp int) (val uint64, err error) {
-       if ClientOpCallback != nil {
-               defer func(t time.Time) { ClientOpCallback("Decr", k, t, err) }(time.Now())
-       }
-
-       var rv uint64
-       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
-               res, err := mc.Decr(vb, k, amt, def, exp)
-               if err != nil {
-                       return err
-               }
-               rv = res
-               return nil
-       })
-       return rv, err
-}
-
-// Wrapper around memcached.CASNext()
-func (b *Bucket) casNext(k string, exp int, state *memcached.CASState) bool {
-       if ClientOpCallback != nil {
-               defer func(t time.Time) {
-                       ClientOpCallback("casNext", k, t, state.Err)
-               }(time.Now())
-       }
-
-       keepGoing := false
-       state.Err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
-               keepGoing = mc.CASNext(vb, k, exp, state)
-               return state.Err
-       })
-       return keepGoing && state.Err == nil
-}
-
-// An UpdateFunc is a callback function to update a document
-type UpdateFunc func(current []byte) (updated []byte, err error)
-
-// Return this as the error from an UpdateFunc to cancel the Update
-// operation.
-const UpdateCancel = memcached.CASQuit
-
-// Update performs a Safe update of a document, avoiding conflicts by
-// using CAS.
-//
-// The callback function will be invoked with the current raw document
-// contents (or nil if the document doesn't exist); it should return
-// the updated raw contents (or nil to delete.)  If it decides not to
-// change anything it can return UpdateCancel as the error.
-//
-// If another writer modifies the document between the get and the
-// set, the callback will be invoked again with the newer value.
-func (b *Bucket) Update(k string, exp int, callback UpdateFunc) error {
-       _, err := b.update(k, exp, callback)
-       return err
-}
-
-// internal version of Update that returns a CAS value
-func (b *Bucket) update(k string, exp int, callback UpdateFunc) (newCas uint64, err error) {
-       var state memcached.CASState
-       for b.casNext(k, exp, &state) {
-               var err error
-               if state.Value, err = callback(state.Value); err != nil {
-                       return 0, err
-               }
-       }
-       return state.Cas, state.Err
-}
-
-// A WriteUpdateFunc is a callback function to update a document
-type WriteUpdateFunc func(current []byte) (updated []byte, opt WriteOptions, err error)
-
-// WriteUpdate performs a Safe update of a document, avoiding
-// conflicts by using CAS.  WriteUpdate is like Update, except that
-// the callback can return a set of WriteOptions, of which Persist and
-// Indexable are recognized: these cause the call to wait until the
-// document update has been persisted to disk and/or become available
-// to index.
-func (b *Bucket) WriteUpdate(k string, exp int, callback WriteUpdateFunc) error {
-       var writeOpts WriteOptions
-       var deletion bool
-       // Wrap the callback in an UpdateFunc we can pass to Update:
-       updateCallback := func(current []byte) (updated []byte, err error) {
-               update, opt, err := callback(current)
-               writeOpts = opt
-               deletion = (update == nil)
-               return update, err
-       }
-       cas, err := b.update(k, exp, updateCallback)
-       if err != nil {
-               return err
-       }
-       // If callback asked, wait for persistence or indexability:
-       if writeOpts&(Persist|Indexable) != 0 {
-               err = b.WaitForPersistence(k, cas, deletion)
-       }
-       return err
-}
-
-// Observe observes the current state of a document.
-func (b *Bucket) Observe(k string) (result memcached.ObserveResult, err error) {
-       if ClientOpCallback != nil {
-               defer func(t time.Time) { ClientOpCallback("Observe", k, t, err) }(time.Now())
-       }
-
-       err = b.Do(k, func(mc *memcached.Client, vb uint16) error {
-               result, err = mc.Observe(vb, k)
-               return err
-       })
-       return
-}
-
-// Returned from WaitForPersistence (or Write, if the Persistent or Indexable flag is used)
-// if the value has been overwritten by another before being persisted.
-var ErrOverwritten = errors.New("overwritten")
-
-// Returned from WaitForPersistence (or Write, if the Persistent or Indexable flag is used)
-// if the value hasn't been persisted by the timeout interval
-var ErrTimeout = errors.New("timeout")
-
-// WaitForPersistence waits for an item to be considered durable.
-//
-// Besides transport errors, ErrOverwritten may be returned if the
-// item is overwritten before it reaches durability.  ErrTimeout may
-// occur if the item isn't found durable in a reasonable amount of
-// time.
-func (b *Bucket) WaitForPersistence(k string, cas uint64, deletion bool) error {
-       timeout := 10 * time.Second
-       sleepDelay := 5 * time.Millisecond
-       start := time.Now()
-       for {
-               time.Sleep(sleepDelay)
-               sleepDelay += sleepDelay / 2 // multiply delay by 1.5 every time
-
-               result, err := b.Observe(k)
-               if err != nil {
-                       return err
-               }
-               if persisted, overwritten := result.CheckPersistence(cas, deletion); overwritten {
-                       return ErrOverwritten
-               } else if persisted {
-                       return nil
-               }
-
-               if result.PersistenceTime > 0 {
-                       timeout = 2 * result.PersistenceTime
-               }
-               if time.Since(start) >= timeout-sleepDelay {
-                       return ErrTimeout
-               }
-       }
-}
-
-var _STRING_MCRESPONSE_POOL = gomemcached.NewStringMCResponsePool(16)
-
-type stringPool struct {
-       pool *sync.Pool
-       size int
-}
-
-func newStringPool(size int) *stringPool {
-       rv := &stringPool{
-               pool: &sync.Pool{
-                       New: func() interface{} {
-                               return make([]string, 0, size)
-                       },
-               },
-               size: size,
-       }
-
-       return rv
-}
-
-func (this *stringPool) Get() []string {
-       return this.pool.Get().([]string)
-}
-
-func (this *stringPool) Put(s []string) {
-       if s == nil || cap(s) < this.size || cap(s) > 2*this.size {
-               return
-       }
-
-       this.pool.Put(s[0:0])
-}
-
-var _STRING_POOL = newStringPool(16)
-
-type vbStringPool struct {
-       pool    *sync.Pool
-       strPool *stringPool
-}
-
-func newVBStringPool(size int, sp *stringPool) *vbStringPool {
-       rv := &vbStringPool{
-               pool: &sync.Pool{
-                       New: func() interface{} {
-                               return make(map[uint16][]string, size)
-                       },
-               },
-               strPool: sp,
-       }
-
-       return rv
-}
-
-func (this *vbStringPool) Get() map[uint16][]string {
-       return this.pool.Get().(map[uint16][]string)
-}
-
-func (this *vbStringPool) Put(s map[uint16][]string) {
-       if s == nil {
-               return
-       }
-
-       for k, v := range s {
-               delete(s, k)
-               this.strPool.Put(v)
-       }
-
-       this.pool.Put(s)
-}
-
-var _VB_STRING_POOL = newVBStringPool(16, _STRING_POOL)
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/conn_pool.go b/vendor/github.com/couchbaselabs/go-couchbase/conn_pool.go
deleted file mode 100644 (file)
index 23102ab..0000000
+++ /dev/null
@@ -1,410 +0,0 @@
-package couchbase
-
-import (
-       "crypto/tls"
-       "errors"
-       "sync/atomic"
-       "time"
-
-       "github.com/couchbase/gomemcached"
-       "github.com/couchbase/gomemcached/client"
-       "github.com/couchbase/goutils/logging"
-)
-
-// GenericMcdAuthHandler is a kind of AuthHandler that performs
-// special auth exchange (like non-standard auth, possibly followed by
-// select-bucket).
-type GenericMcdAuthHandler interface {
-       AuthHandler
-       AuthenticateMemcachedConn(host string, conn *memcached.Client) error
-}
-
-// Error raised when a connection can't be retrieved from a pool.
-var TimeoutError = errors.New("timeout waiting to build connection")
-var errClosedPool = errors.New("the connection pool is closed")
-var errNoPool = errors.New("no connection pool")
-
-// Default timeout for retrieving a connection from the pool.
-var ConnPoolTimeout = time.Hour * 24 * 30
-
-// overflow connection closer cycle time
-var ConnCloserInterval = time.Second * 30
-
-// ConnPoolAvailWaitTime is the amount of time to wait for an existing
-// connection from the pool before considering the creation of a new
-// one.
-var ConnPoolAvailWaitTime = time.Millisecond
-
-type connectionPool struct {
-       host        string
-       mkConn      func(host string, ah AuthHandler, tlsConfig *tls.Config, bucketName string) (*memcached.Client, error)
-       auth        AuthHandler
-       connections chan *memcached.Client
-       createsem   chan bool
-       bailOut     chan bool
-       poolSize    int
-       connCount   uint64
-       inUse       bool
-       tlsConfig   *tls.Config
-       bucket string
-}
-
-func newConnectionPool(host string, ah AuthHandler, closer bool, poolSize, poolOverflow int, tlsConfig *tls.Config, bucket string) *connectionPool {
-       connSize := poolSize
-       if closer {
-               connSize += poolOverflow
-       }
-       rv := &connectionPool{
-               host:        host,
-               connections: make(chan *memcached.Client, connSize),
-               createsem:   make(chan bool, poolSize+poolOverflow),
-               mkConn:      defaultMkConn,
-               auth:        ah,
-               poolSize:    poolSize,
-               tlsConfig:   tlsConfig,
-               bucket:      bucket,
-       }
-       if closer {
-               rv.bailOut = make(chan bool, 1)
-               go rv.connCloser()
-       }
-       return rv
-}
-
-// ConnPoolTimeout is notified whenever connections are acquired from a pool.
-var ConnPoolCallback func(host string, source string, start time.Time, err error)
-
-// Use regular in-the-clear connection if tlsConfig is nil.
-// Use secure connection (TLS) if tlsConfig is set.
-func defaultMkConn(host string, ah AuthHandler, tlsConfig *tls.Config, bucketName string) (*memcached.Client, error) {
-       var features memcached.Features
-
-       var conn *memcached.Client
-       var err error
-       if tlsConfig == nil {
-               conn, err = memcached.Connect("tcp", host)
-       } else {
-               conn, err = memcached.ConnectTLS("tcp", host, tlsConfig)
-       }
-
-       if err != nil {
-               return nil, err
-       }
-
-       if TCPKeepalive == true {
-               conn.SetKeepAliveOptions(time.Duration(TCPKeepaliveInterval) * time.Second)
-       }
-
-       if EnableMutationToken == true {
-               features = append(features, memcached.FeatureMutationToken)
-       }
-       if EnableDataType == true {
-               features = append(features, memcached.FeatureDataType)
-       }
-
-       if EnableXattr == true {
-               features = append(features, memcached.FeatureXattr)
-       }
-
-       if EnableCollections {
-               features = append(features, memcached.FeatureCollections)
-       }
-
-       if len(features) > 0 {
-               if DefaultTimeout > 0 {
-                       conn.SetDeadline(getDeadline(noDeadline, DefaultTimeout))
-               }
-
-               res, err := conn.EnableFeatures(features)
-
-               if DefaultTimeout > 0 {
-                       conn.SetDeadline(noDeadline)
-               }
-
-               if err != nil && isTimeoutError(err) {
-                       conn.Close()
-                       return nil, err
-               }
-
-               if err != nil || res.Status != gomemcached.SUCCESS {
-                       logging.Warnf("Unable to enable features %v", err)
-               }
-       }
-
-       if gah, ok := ah.(GenericMcdAuthHandler); ok {
-               err = gah.AuthenticateMemcachedConn(host, conn)
-               if err != nil {
-                       conn.Close()
-                       return nil, err
-               }
-               return conn, nil
-       }
-       name, pass, bucket := ah.GetCredentials()
-       if bucket  == "" {
-               // Authenticator does not know specific bucket.
-               bucket = bucketName
-       }
-
-       if name != "default" {
-               _, err = conn.Auth(name, pass)
-               if err != nil {
-                       conn.Close()
-                       return nil, err
-               }
-               // Select bucket (Required for cb_auth creds)
-               // Required when doing auth with _admin credentials
-               if bucket != "" && bucket != name {
-                       _, err = conn.SelectBucket(bucket)
-                       if err != nil {
-                               conn.Close()
-                               return nil, err
-                       }
-               }
-       }
-       return conn, nil
-}
-
-func (cp *connectionPool) Close() (err error) {
-       defer func() {
-               if recover() != nil {
-                       err = errors.New("connectionPool.Close error")
-               }
-       }()
-       if cp.bailOut != nil {
-
-               // defensively, we won't wait if the channel is full
-               select {
-               case cp.bailOut <- false:
-               default:
-               }
-       }
-       close(cp.connections)
-       for c := range cp.connections {
-               c.Close()
-       }
-       return
-}
-
-func (cp *connectionPool) Node() string {
-       return cp.host
-}
-
-func (cp *connectionPool) GetWithTimeout(d time.Duration) (rv *memcached.Client, err error) {
-       if cp == nil {
-               return nil, errNoPool
-       }
-
-       path := ""
-
-       if ConnPoolCallback != nil {
-               defer func(path *string, start time.Time) {
-                       ConnPoolCallback(cp.host, *path, start, err)
-               }(&path, time.Now())
-       }
-
-       path = "short-circuit"
-
-       // short-circuit available connetions.
-       select {
-       case rv, isopen := <-cp.connections:
-               if !isopen {
-                       return nil, errClosedPool
-               }
-               atomic.AddUint64(&cp.connCount, 1)
-               return rv, nil
-       default:
-       }
-
-       t := time.NewTimer(ConnPoolAvailWaitTime)
-       defer t.Stop()
-
-       // Try to grab an available connection within 1ms
-       select {
-       case rv, isopen := <-cp.connections:
-               path = "avail1"
-               if !isopen {
-                       return nil, errClosedPool
-               }
-               atomic.AddUint64(&cp.connCount, 1)
-               return rv, nil
-       case <-t.C:
-               // No connection came around in time, let's see
-               // whether we can get one or build a new one first.
-               t.Reset(d) // Reuse the timer for the full timeout.
-               select {
-               case rv, isopen := <-cp.connections:
-                       path = "avail2"
-                       if !isopen {
-                               return nil, errClosedPool
-                       }
-                       atomic.AddUint64(&cp.connCount, 1)
-                       return rv, nil
-               case cp.createsem <- true:
-                       path = "create"
-                       // Build a connection if we can't get a real one.
-                       // This can potentially be an overflow connection, or
-                       // a pooled connection.
-                       rv, err := cp.mkConn(cp.host, cp.auth, cp.tlsConfig, cp.bucket)
-                       if err != nil {
-                               // On error, release our create hold
-                               <-cp.createsem
-                       } else {
-                               atomic.AddUint64(&cp.connCount, 1)
-                       }
-                       return rv, err
-               case <-t.C:
-                       return nil, ErrTimeout
-               }
-       }
-}
-
-func (cp *connectionPool) Get() (*memcached.Client, error) {
-       return cp.GetWithTimeout(ConnPoolTimeout)
-}
-
-func (cp *connectionPool) Return(c *memcached.Client) {
-       if c == nil {
-               return
-       }
-
-       if cp == nil {
-               c.Close()
-       }
-
-       if c.IsHealthy() {
-               defer func() {
-                       if recover() != nil {
-                               // This happens when the pool has already been
-                               // closed and we're trying to return a
-                               // connection to it anyway.  Just close the
-                               // connection.
-                               c.Close()
-                       }
-               }()
-
-               select {
-               case cp.connections <- c:
-               default:
-                       <-cp.createsem
-                       c.Close()
-               }
-       } else {
-               <-cp.createsem
-               c.Close()
-       }
-}
-
-// give the ability to discard a connection from a pool
-// useful for ditching connections to the wrong node after a rebalance
-func (cp *connectionPool) Discard(c *memcached.Client) {
-       <-cp.createsem
-       c.Close()
-}
-
-// asynchronous connection closer
-func (cp *connectionPool) connCloser() {
-       var connCount uint64
-
-       t := time.NewTimer(ConnCloserInterval)
-       defer t.Stop()
-
-       for {
-               connCount = cp.connCount
-
-               // we don't exist anymore! bail out!
-               select {
-               case <-cp.bailOut:
-                       return
-               case <-t.C:
-               }
-               t.Reset(ConnCloserInterval)
-
-               // no overflow connections open or sustained requests for connections
-               // nothing to do until the next cycle
-               if len(cp.connections) <= cp.poolSize ||
-                       ConnCloserInterval/ConnPoolAvailWaitTime < time.Duration(cp.connCount-connCount) {
-                       continue
-               }
-
-               // close overflow connections now that they are not needed
-               for c := range cp.connections {
-                       select {
-                       case <-cp.bailOut:
-                               return
-                       default:
-                       }
-
-                       // bail out if close did not work out
-                       if !cp.connCleanup(c) {
-                               return
-                       }
-                       if len(cp.connections) <= cp.poolSize {
-                               break
-                       }
-               }
-       }
-}
-
-// close connection with recovery on error
-func (cp *connectionPool) connCleanup(c *memcached.Client) (rv bool) {
-
-       // just in case we are closing a connection after
-       // bailOut has been sent but we haven't yet read it
-       defer func() {
-               if recover() != nil {
-                       rv = false
-               }
-       }()
-       rv = true
-
-       c.Close()
-       <-cp.createsem
-       return
-}
-
-func (cp *connectionPool) StartTapFeed(args *memcached.TapArguments) (*memcached.TapFeed, error) {
-       if cp == nil {
-               return nil, errNoPool
-       }
-       mc, err := cp.Get()
-       if err != nil {
-               return nil, err
-       }
-
-       // A connection can't be used after TAP; Dont' count it against the
-       // connection pool capacity
-       <-cp.createsem
-
-       return mc.StartTapFeed(*args)
-}
-
-const DEFAULT_WINDOW_SIZE = 20 * 1024 * 1024 // 20 Mb
-
-func (cp *connectionPool) StartUprFeed(name string, sequence uint32, dcp_buffer_size uint32, data_chan_size int) (*memcached.UprFeed, error) {
-       if cp == nil {
-               return nil, errNoPool
-       }
-       mc, err := cp.Get()
-       if err != nil {
-               return nil, err
-       }
-
-       // A connection can't be used after it has been allocated to UPR;
-       // Dont' count it against the connection pool capacity
-       <-cp.createsem
-
-       uf, err := mc.NewUprFeed()
-       if err != nil {
-               return nil, err
-       }
-
-       if err := uf.UprOpen(name, sequence, dcp_buffer_size); err != nil {
-               return nil, err
-       }
-
-       if err := uf.StartFeedWithConfig(data_chan_size); err != nil {
-               return nil, err
-       }
-
-       return uf, nil
-}
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/ddocs.go b/vendor/github.com/couchbaselabs/go-couchbase/ddocs.go
deleted file mode 100644 (file)
index f9cc343..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-package couchbase
-
-import (
-       "bytes"
-       "encoding/json"
-       "fmt"
-       "github.com/couchbase/goutils/logging"
-       "io/ioutil"
-       "net/http"
-)
-
-// ViewDefinition represents a single view within a design document.
-type ViewDefinition struct {
-       Map    string `json:"map"`
-       Reduce string `json:"reduce,omitempty"`
-}
-
-// DDoc is the document body of a design document specifying a view.
-type DDoc struct {
-       Language string                    `json:"language,omitempty"`
-       Views    map[string]ViewDefinition `json:"views"`
-}
-
-// DDocsResult represents the result from listing the design
-// documents.
-type DDocsResult struct {
-       Rows []struct {
-               DDoc struct {
-                       Meta map[string]interface{}
-                       JSON DDoc
-               } `json:"doc"`
-       } `json:"rows"`
-}
-
-// GetDDocs lists all design documents
-func (b *Bucket) GetDDocs() (DDocsResult, error) {
-       var ddocsResult DDocsResult
-       b.RLock()
-       pool := b.pool
-       uri := b.DDocs.URI
-       b.RUnlock()
-
-       // MB-23555 ephemeral buckets have no ddocs
-       if uri == "" {
-               return DDocsResult{}, nil
-       }
-
-       err := pool.client.parseURLResponse(uri, &ddocsResult)
-       if err != nil {
-               return DDocsResult{}, err
-       }
-       return ddocsResult, nil
-}
-
-func (b *Bucket) GetDDocWithRetry(docname string, into interface{}) error {
-       ddocURI := fmt.Sprintf("/%s/_design/%s", b.GetName(), docname)
-       err := b.parseAPIResponse(ddocURI, &into)
-       if err != nil {
-               return err
-       }
-       return nil
-}
-
-func (b *Bucket) GetDDocsWithRetry() (DDocsResult, error) {
-       var ddocsResult DDocsResult
-       b.RLock()
-       uri := b.DDocs.URI
-       b.RUnlock()
-
-       // MB-23555 ephemeral buckets have no ddocs
-       if uri == "" {
-               return DDocsResult{}, nil
-       }
-
-       err := b.parseURLResponse(uri, &ddocsResult)
-       if err != nil {
-               return DDocsResult{}, err
-       }
-       return ddocsResult, nil
-}
-
-func (b *Bucket) ddocURL(docname string) (string, error) {
-       u, err := b.randomBaseURL()
-       if err != nil {
-               return "", err
-       }
-       u.Path = fmt.Sprintf("/%s/_design/%s", b.GetName(), docname)
-       return u.String(), nil
-}
-
-func (b *Bucket) ddocURLNext(nodeId int, docname string) (string, int, error) {
-       u, selected, err := b.randomNextURL(nodeId)
-       if err != nil {
-               return "", -1, err
-       }
-       u.Path = fmt.Sprintf("/%s/_design/%s", b.GetName(), docname)
-       return u.String(), selected, nil
-}
-
-const ABS_MAX_RETRIES = 10
-const ABS_MIN_RETRIES = 3
-
-func (b *Bucket) getMaxRetries() (int, error) {
-
-       maxRetries := len(b.Nodes())
-
-       if maxRetries == 0 {
-               return 0, fmt.Errorf("No available Couch rest URLs")
-       }
-
-       if maxRetries > ABS_MAX_RETRIES {
-               maxRetries = ABS_MAX_RETRIES
-       } else if maxRetries < ABS_MIN_RETRIES {
-               maxRetries = ABS_MIN_RETRIES
-       }
-
-       return maxRetries, nil
-}
-
-// PutDDoc installs a design document.
-func (b *Bucket) PutDDoc(docname string, value interface{}) error {
-
-       var Err error
-
-       maxRetries, err := b.getMaxRetries()
-       if err != nil {
-               return err
-       }
-
-       lastNode := START_NODE_ID
-
-       for retryCount := 0; retryCount < maxRetries; retryCount++ {
-
-               Err = nil
-
-               ddocU, selectedNode, err := b.ddocURLNext(lastNode, docname)
-               if err != nil {
-                       return err
-               }
-
-               lastNode = selectedNode
-
-               logging.Infof(" Trying with selected node %d", selectedNode)
-               j, err := json.Marshal(value)
-               if err != nil {
-                       return err
-               }
-
-               req, err := http.NewRequest("PUT", ddocU, bytes.NewReader(j))
-               if err != nil {
-                       return err
-               }
-               req.Header.Set("Content-Type", "application/json")
-               err = maybeAddAuth(req, b.authHandler(false /* bucket not yet locked */))
-               if err != nil {
-                       return err
-               }
-
-               res, err := doHTTPRequest(req)
-               if err != nil {
-                       return err
-               }
-
-               if res.StatusCode != 201 {
-                       body, _ := ioutil.ReadAll(res.Body)
-                       Err = fmt.Errorf("error installing view: %v / %s",
-                               res.Status, body)
-                       logging.Errorf(" Error in PutDDOC %v. Retrying...", Err)
-                       res.Body.Close()
-                       b.Refresh()
-                       continue
-               }
-
-               res.Body.Close()
-               break
-       }
-
-       return Err
-}
-
-// GetDDoc retrieves a specific a design doc.
-func (b *Bucket) GetDDoc(docname string, into interface{}) error {
-       var Err error
-       var res *http.Response
-
-       maxRetries, err := b.getMaxRetries()
-       if err != nil {
-               return err
-       }
-
-       lastNode := START_NODE_ID
-       for retryCount := 0; retryCount < maxRetries; retryCount++ {
-
-               Err = nil
-               ddocU, selectedNode, err := b.ddocURLNext(lastNode, docname)
-               if err != nil {
-                       return err
-               }
-
-               lastNode = selectedNode
-               logging.Infof(" Trying with selected node %d", selectedNode)
-
-               req, err := http.NewRequest("GET", ddocU, nil)
-               if err != nil {
-                       return err
-               }
-               req.Header.Set("Content-Type", "application/json")
-               err = maybeAddAuth(req, b.authHandler(false /* bucket not yet locked */))
-               if err != nil {
-                       return err
-               }
-
-               res, err = doHTTPRequest(req)
-               if err != nil {
-                       return err
-               }
-               if res.StatusCode != 200 {
-                       body, _ := ioutil.ReadAll(res.Body)
-                       Err = fmt.Errorf("error reading view: %v / %s",
-                               res.Status, body)
-                       logging.Errorf(" Error in GetDDOC %v Retrying...", Err)
-                       b.Refresh()
-                       res.Body.Close()
-                       continue
-               }
-               defer res.Body.Close()
-               break
-       }
-
-       if Err != nil {
-               return Err
-       }
-
-       d := json.NewDecoder(res.Body)
-       return d.Decode(into)
-}
-
-// DeleteDDoc removes a design document.
-func (b *Bucket) DeleteDDoc(docname string) error {
-
-       var Err error
-
-       maxRetries, err := b.getMaxRetries()
-       if err != nil {
-               return err
-       }
-
-       lastNode := START_NODE_ID
-
-       for retryCount := 0; retryCount < maxRetries; retryCount++ {
-
-               Err = nil
-               ddocU, selectedNode, err := b.ddocURLNext(lastNode, docname)
-               if err != nil {
-                       return err
-               }
-
-               lastNode = selectedNode
-               logging.Infof(" Trying with selected node %d", selectedNode)
-
-               req, err := http.NewRequest("DELETE", ddocU, nil)
-               if err != nil {
-                       return err
-               }
-               req.Header.Set("Content-Type", "application/json")
-               err = maybeAddAuth(req, b.authHandler(false /* bucket not already locked */))
-               if err != nil {
-                       return err
-               }
-
-               res, err := doHTTPRequest(req)
-               if err != nil {
-                       return err
-               }
-               if res.StatusCode != 200 {
-                       body, _ := ioutil.ReadAll(res.Body)
-                       Err = fmt.Errorf("error deleting view : %v / %s", res.Status, body)
-                       logging.Errorf(" Error in DeleteDDOC %v. Retrying ... ", Err)
-                       b.Refresh()
-                       res.Body.Close()
-                       continue
-               }
-
-               res.Body.Close()
-               break
-       }
-       return Err
-}
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/observe.go b/vendor/github.com/couchbaselabs/go-couchbase/observe.go
deleted file mode 100644 (file)
index 6e746f5..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-package couchbase
-
-import (
-       "fmt"
-       "github.com/couchbase/goutils/logging"
-       "sync"
-)
-
-type PersistTo uint8
-
-const (
-       PersistNone   = PersistTo(0x00)
-       PersistMaster = PersistTo(0x01)
-       PersistOne    = PersistTo(0x02)
-       PersistTwo    = PersistTo(0x03)
-       PersistThree  = PersistTo(0x04)
-       PersistFour   = PersistTo(0x05)
-)
-
-type ObserveTo uint8
-
-const (
-       ObserveNone           = ObserveTo(0x00)
-       ObserveReplicateOne   = ObserveTo(0x01)
-       ObserveReplicateTwo   = ObserveTo(0x02)
-       ObserveReplicateThree = ObserveTo(0x03)
-       ObserveReplicateFour  = ObserveTo(0x04)
-)
-
-type JobType uint8
-
-const (
-       OBSERVE = JobType(0x00)
-       PERSIST = JobType(0x01)
-)
-
-type ObservePersistJob struct {
-       vb                 uint16
-       vbuuid             uint64
-       hostname           string
-       jobType            JobType
-       failover           uint8
-       lastPersistedSeqNo uint64
-       currentSeqNo       uint64
-       resultChan         chan *ObservePersistJob
-       errorChan          chan *OPErrResponse
-}
-
-type OPErrResponse struct {
-       vb     uint16
-       vbuuid uint64
-       err    error
-       job    *ObservePersistJob
-}
-
-var ObservePersistPool = NewPool(1024)
-var OPJobChan = make(chan *ObservePersistJob, 1024)
-var OPJobDone = make(chan bool)
-
-var wg sync.WaitGroup
-
-func (b *Bucket) StartOPPollers(maxWorkers int) {
-
-       for i := 0; i < maxWorkers; i++ {
-               go b.OPJobPoll()
-               wg.Add(1)
-       }
-       wg.Wait()
-}
-
-func (b *Bucket) SetObserveAndPersist(nPersist PersistTo, nObserve ObserveTo) (err error) {
-
-       numNodes := len(b.Nodes())
-       if int(nPersist) > numNodes || int(nObserve) > numNodes {
-               return fmt.Errorf("Not enough healthy nodes in the cluster")
-       }
-
-       if int(nPersist) > (b.Replicas+1) || int(nObserve) > b.Replicas {
-               return fmt.Errorf("Not enough replicas in the cluster")
-       }
-
-       if EnableMutationToken == false {
-               return fmt.Errorf("Mutation Tokens not enabled ")
-       }
-
-       b.ds = &DurablitySettings{Persist: PersistTo(nPersist), Observe: ObserveTo(nObserve)}
-       return
-}
-
-func (b *Bucket) ObserveAndPersistPoll(vb uint16, vbuuid uint64, seqNo uint64) (err error, failover bool) {
-       b.RLock()
-       ds := b.ds
-       b.RUnlock()
-
-       if ds == nil {
-               return
-       }
-
-       nj := 0 // total number of jobs
-       resultChan := make(chan *ObservePersistJob, 10)
-       errChan := make(chan *OPErrResponse, 10)
-
-       nodes := b.GetNodeList(vb)
-       if int(ds.Observe) > len(nodes) || int(ds.Persist) > len(nodes) {
-               return fmt.Errorf("Not enough healthy nodes in the cluster"), false
-       }
-
-       logging.Infof("Node list %v", nodes)
-
-       if ds.Observe >= ObserveReplicateOne {
-               // create a job for each host
-               for i := ObserveReplicateOne; i < ds.Observe+1; i++ {
-                       opJob := ObservePersistPool.Get()
-                       opJob.vb = vb
-                       opJob.vbuuid = vbuuid
-                       opJob.jobType = OBSERVE
-                       opJob.hostname = nodes[i]
-                       opJob.resultChan = resultChan
-                       opJob.errorChan = errChan
-
-                       OPJobChan <- opJob
-                       nj++
-
-               }
-       }
-
-       if ds.Persist >= PersistMaster {
-               for i := PersistMaster; i < ds.Persist+1; i++ {
-                       opJob := ObservePersistPool.Get()
-                       opJob.vb = vb
-                       opJob.vbuuid = vbuuid
-                       opJob.jobType = PERSIST
-                       opJob.hostname = nodes[i]
-                       opJob.resultChan = resultChan
-                       opJob.errorChan = errChan
-
-                       OPJobChan <- opJob
-                       nj++
-
-               }
-       }
-
-       ok := true
-       for ok {
-               select {
-               case res := <-resultChan:
-                       jobDone := false
-                       if res.failover == 0 {
-                               // no failover
-                               if res.jobType == PERSIST {
-                                       if res.lastPersistedSeqNo >= seqNo {
-                                               jobDone = true
-                                       }
-
-                               } else {
-                                       if res.currentSeqNo >= seqNo {
-                                               jobDone = true
-                                       }
-                               }
-
-                               if jobDone == true {
-                                       nj--
-                                       ObservePersistPool.Put(res)
-                               } else {
-                                       // requeue this job
-                                       OPJobChan <- res
-                               }
-
-                       } else {
-                               // Not currently handling failover scenarios TODO
-                               nj--
-                               ObservePersistPool.Put(res)
-                               failover = true
-                       }
-
-                       if nj == 0 {
-                               // done with all the jobs
-                               ok = false
-                               close(resultChan)
-                               close(errChan)
-                       }
-
-               case Err := <-errChan:
-                       logging.Errorf("Error in Observe/Persist %v", Err.err)
-                       err = fmt.Errorf("Error in Observe/Persist job %v", Err.err)
-                       nj--
-                       ObservePersistPool.Put(Err.job)
-                       if nj == 0 {
-                               close(resultChan)
-                               close(errChan)
-                               ok = false
-                       }
-               }
-       }
-
-       return
-}
-
-func (b *Bucket) OPJobPoll() {
-
-       ok := true
-       for ok == true {
-               select {
-               case job := <-OPJobChan:
-                       pool := b.getConnPoolByHost(job.hostname, false /* bucket not already locked */)
-                       if pool == nil {
-                               errRes := &OPErrResponse{vb: job.vb, vbuuid: job.vbuuid}
-                               errRes.err = fmt.Errorf("Pool not found for host %v", job.hostname)
-                               errRes.job = job
-                               job.errorChan <- errRes
-                               continue
-                       }
-                       conn, err := pool.Get()
-                       if err != nil {
-                               errRes := &OPErrResponse{vb: job.vb, vbuuid: job.vbuuid}
-                               errRes.err = fmt.Errorf("Unable to get connection from pool %v", err)
-                               errRes.job = job
-                               job.errorChan <- errRes
-                               continue
-                       }
-
-                       res, err := conn.ObserveSeq(job.vb, job.vbuuid)
-                       if err != nil {
-                               errRes := &OPErrResponse{vb: job.vb, vbuuid: job.vbuuid}
-                               errRes.err = fmt.Errorf("Command failed %v", err)
-                               errRes.job = job
-                               job.errorChan <- errRes
-                               continue
-
-                       }
-                       pool.Return(conn)
-                       job.lastPersistedSeqNo = res.LastPersistedSeqNo
-                       job.currentSeqNo = res.CurrentSeqNo
-                       job.failover = res.Failover
-
-                       job.resultChan <- job
-               case <-OPJobDone:
-                       logging.Infof("Observe Persist Poller exitting")
-                       ok = false
-               }
-       }
-       wg.Done()
-}
-
-func (b *Bucket) GetNodeList(vb uint16) []string {
-
-       vbm := b.VBServerMap()
-       if len(vbm.VBucketMap) < int(vb) {
-               logging.Infof("vbmap smaller than vblist")
-               return nil
-       }
-
-       nodes := make([]string, len(vbm.VBucketMap[vb]))
-       for i := 0; i < len(vbm.VBucketMap[vb]); i++ {
-               n := vbm.VBucketMap[vb][i]
-               if n < 0 {
-                       continue
-               }
-
-               node := b.getMasterNode(n)
-               if len(node) > 1 {
-                       nodes[i] = node
-               }
-               continue
-
-       }
-       return nodes
-}
-
-//pool of ObservePersist Jobs
-type OPpool struct {
-       pool chan *ObservePersistJob
-}
-
-// NewPool creates a new pool of jobs
-func NewPool(max int) *OPpool {
-       return &OPpool{
-               pool: make(chan *ObservePersistJob, max),
-       }
-}
-
-// Borrow a Client from the pool.
-func (p *OPpool) Get() *ObservePersistJob {
-       var o *ObservePersistJob
-       select {
-       case o = <-p.pool:
-       default:
-               o = &ObservePersistJob{}
-       }
-       return o
-}
-
-// Return returns a Client to the pool.
-func (p *OPpool) Put(o *ObservePersistJob) {
-       select {
-       case p.pool <- o:
-       default:
-               // let it go, let it go...
-       }
-}
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/pools.go b/vendor/github.com/couchbaselabs/go-couchbase/pools.go
deleted file mode 100644 (file)
index 0e23793..0000000
+++ /dev/null
@@ -1,1474 +0,0 @@
-package couchbase
-
-import (
-       "bufio"
-       "bytes"
-       "crypto/tls"
-       "crypto/x509"
-       "encoding/base64"
-       "encoding/json"
-       "errors"
-       "fmt"
-       "io"
-       "io/ioutil"
-       "math/rand"
-       "net/http"
-       "net/url"
-       "runtime"
-       "sort"
-       "strconv"
-       "strings"
-       "sync"
-       "time"
-       "unsafe"
-
-       "github.com/couchbase/goutils/logging"
-
-       "github.com/couchbase/gomemcached"        // package name is 'gomemcached'
-       "github.com/couchbase/gomemcached/client" // package name is 'memcached'
-)
-
-// HTTPClient to use for REST and view operations.
-var MaxIdleConnsPerHost = 256
-var ClientTimeOut = 10 * time.Second
-var HTTPTransport = &http.Transport{MaxIdleConnsPerHost: MaxIdleConnsPerHost}
-var HTTPClient = &http.Client{Transport: HTTPTransport, Timeout: ClientTimeOut}
-
-// PoolSize is the size of each connection pool (per host).
-var PoolSize = 64
-
-// PoolOverflow is the number of overflow connections allowed in a
-// pool.
-var PoolOverflow = 16
-
-// AsynchronousCloser turns on asynchronous closing for overflow connections
-var AsynchronousCloser = false
-
-// TCP KeepAlive enabled/disabled
-var TCPKeepalive = false
-
-// Enable MutationToken
-var EnableMutationToken = false
-
-// Enable Data Type response
-var EnableDataType = false
-
-// Enable Xattr
-var EnableXattr = false
-
-// Enable Collections
-var EnableCollections = false
-
-// TCP keepalive interval in seconds. Default 30 minutes
-var TCPKeepaliveInterval = 30 * 60
-
-// Used to decide whether to skip verification of certificates when
-// connecting to an ssl port.
-var skipVerify = true
-var certFile = ""
-var keyFile = ""
-var rootFile = ""
-
-func SetSkipVerify(skip bool) {
-       skipVerify = skip
-}
-
-func SetCertFile(cert string) {
-       certFile = cert
-}
-
-func SetKeyFile(cert string) {
-       keyFile = cert
-}
-
-func SetRootFile(cert string) {
-       rootFile = cert
-}
-
-// Allow applications to speciify the Poolsize and Overflow
-func SetConnectionPoolParams(size, overflow int) {
-
-       if size > 0 {
-               PoolSize = size
-       }
-
-       if overflow > 0 {
-               PoolOverflow = overflow
-       }
-}
-
-// Turn off overflow connections
-func DisableOverflowConnections() {
-       PoolOverflow = 0
-}
-
-// Toggle asynchronous overflow closer
-func EnableAsynchronousCloser(closer bool) {
-       AsynchronousCloser = closer
-}
-
-// Allow TCP keepalive parameters to be set by the application
-func SetTcpKeepalive(enabled bool, interval int) {
-
-       TCPKeepalive = enabled
-
-       if interval > 0 {
-               TCPKeepaliveInterval = interval
-       }
-}
-
-// AuthHandler is a callback that gets the auth username and password
-// for the given bucket.
-type AuthHandler interface {
-       GetCredentials() (string, string, string)
-}
-
-// AuthHandler is a callback that gets the auth username and password
-// for the given bucket and sasl for memcached.
-type AuthWithSaslHandler interface {
-       AuthHandler
-       GetSaslCredentials() (string, string)
-}
-
-// MultiBucketAuthHandler is kind of AuthHandler that may perform
-// different auth for different buckets.
-type MultiBucketAuthHandler interface {
-       AuthHandler
-       ForBucket(bucket string) AuthHandler
-}
-
-// HTTPAuthHandler is kind of AuthHandler that performs more general
-// for outgoing http requests than is possible via simple
-// GetCredentials() call (i.e. digest auth or different auth per
-// different destinations).
-type HTTPAuthHandler interface {
-       AuthHandler
-       SetCredsForRequest(req *http.Request) error
-}
-
-// RestPool represents a single pool returned from the pools REST API.
-type RestPool struct {
-       Name         string `json:"name"`
-       StreamingURI string `json:"streamingUri"`
-       URI          string `json:"uri"`
-}
-
-// Pools represents the collection of pools as returned from the REST API.
-type Pools struct {
-       ComponentsVersion     map[string]string `json:"componentsVersion,omitempty"`
-       ImplementationVersion string            `json:"implementationVersion"`
-       IsAdmin               bool              `json:"isAdminCreds"`
-       UUID                  string            `json:"uuid"`
-       Pools                 []RestPool        `json:"pools"`
-}
-
-// A Node is a computer in a cluster running the couchbase software.
-type Node struct {
-       ClusterCompatibility int                `json:"clusterCompatibility"`
-       ClusterMembership    string             `json:"clusterMembership"`
-       CouchAPIBase         string             `json:"couchApiBase"`
-       Hostname             string             `json:"hostname"`
-       InterestingStats     map[string]float64 `json:"interestingStats,omitempty"`
-       MCDMemoryAllocated   float64            `json:"mcdMemoryAllocated"`
-       MCDMemoryReserved    float64            `json:"mcdMemoryReserved"`
-       MemoryFree           float64            `json:"memoryFree"`
-       MemoryTotal          float64            `json:"memoryTotal"`
-       OS                   string             `json:"os"`
-       Ports                map[string]int     `json:"ports"`
-       Services             []string           `json:"services"`
-       Status               string             `json:"status"`
-       Uptime               int                `json:"uptime,string"`
-       Version              string             `json:"version"`
-       ThisNode             bool               `json:"thisNode,omitempty"`
-}
-
-// A Pool of nodes and buckets.
-type Pool struct {
-       BucketMap map[string]*Bucket
-       Nodes     []Node
-
-       BucketURL map[string]string `json:"buckets"`
-
-       client *Client
-}
-
-// VBucketServerMap is the a mapping of vbuckets to nodes.
-type VBucketServerMap struct {
-       HashAlgorithm string   `json:"hashAlgorithm"`
-       NumReplicas   int      `json:"numReplicas"`
-       ServerList    []string `json:"serverList"`
-       VBucketMap    [][]int  `json:"vBucketMap"`
-}
-
-type DurablitySettings struct {
-       Persist PersistTo
-       Observe ObserveTo
-}
-
-// Bucket is the primary entry point for most data operations.
-// Bucket is a locked data structure. All access to its fields should be done using read or write locking,
-// as appropriate.
-//
-// Some access methods require locking, but rely on the caller to do so. These are appropriate
-// for calls from methods that have already locked the structure. Methods like this
-// take a boolean parameter "bucketLocked".
-type Bucket struct {
-       sync.RWMutex
-       AuthType               string             `json:"authType"`
-       Capabilities           []string           `json:"bucketCapabilities"`
-       CapabilitiesVersion    string             `json:"bucketCapabilitiesVer"`
-       Type                   string             `json:"bucketType"`
-       Name                   string             `json:"name"`
-       NodeLocator            string             `json:"nodeLocator"`
-       Quota                  map[string]float64 `json:"quota,omitempty"`
-       Replicas               int                `json:"replicaNumber"`
-       Password               string             `json:"saslPassword"`
-       URI                    string             `json:"uri"`
-       StreamingURI           string             `json:"streamingUri"`
-       LocalRandomKeyURI      string             `json:"localRandomKeyUri,omitempty"`
-       UUID                   string             `json:"uuid"`
-       ConflictResolutionType string             `json:"conflictResolutionType,omitempty"`
-       DDocs                  struct {
-               URI string `json:"uri"`
-       } `json:"ddocs,omitempty"`
-       BasicStats  map[string]interface{} `json:"basicStats,omitempty"`
-       Controllers map[string]interface{} `json:"controllers,omitempty"`
-
-       // These are used for JSON IO, but isn't used for processing
-       // since it needs to be swapped out safely.
-       VBSMJson  VBucketServerMap `json:"vBucketServerMap"`
-       NodesJSON []Node           `json:"nodes"`
-
-       pool             *Pool
-       connPools        unsafe.Pointer // *[]*connectionPool
-       vBucketServerMap unsafe.Pointer // *VBucketServerMap
-       nodeList         unsafe.Pointer // *[]Node
-       commonSufix      string
-       ah               AuthHandler        // auth handler
-       ds               *DurablitySettings // Durablity Settings for this bucket
-       closed           bool
-}
-
-// PoolServices is all the bucket-independent services in a pool
-type PoolServices struct {
-       Rev          int             `json:"rev"`
-       NodesExt     []NodeServices  `json:"nodesExt"`
-       Capabilities json.RawMessage `json:"clusterCapabilities"`
-}
-
-// NodeServices is all the bucket-independent services running on
-// a node (given by Hostname)
-type NodeServices struct {
-       Services map[string]int `json:"services,omitempty"`
-       Hostname string         `json:"hostname"`
-       ThisNode bool           `json:"thisNode"`
-}
-
-type BucketNotFoundError struct {
-       bucket string
-}
-
-func (e *BucketNotFoundError) Error() string {
-       return fmt.Sprint("No bucket named " + e.bucket)
-}
-
-type BucketAuth struct {
-       name    string
-       saslPwd string
-       bucket  string
-}
-
-func newBucketAuth(name string, pass string, bucket string) *BucketAuth {
-       return &BucketAuth{name: name, saslPwd: pass, bucket: bucket}
-}
-
-func (ba *BucketAuth) GetCredentials() (string, string, string) {
-       return ba.name, ba.saslPwd, ba.bucket
-}
-
-// VBServerMap returns the current VBucketServerMap.
-func (b *Bucket) VBServerMap() *VBucketServerMap {
-       b.RLock()
-       defer b.RUnlock()
-       ret := (*VBucketServerMap)(b.vBucketServerMap)
-       return ret
-}
-
-func (b *Bucket) GetVBmap(addrs []string) (map[string][]uint16, error) {
-       vbmap := b.VBServerMap()
-       servers := vbmap.ServerList
-       if addrs == nil {
-               addrs = vbmap.ServerList
-       }
-
-       m := make(map[string][]uint16)
-       for _, addr := range addrs {
-               m[addr] = make([]uint16, 0)
-       }
-       for vbno, idxs := range vbmap.VBucketMap {
-               if len(idxs) == 0 {
-                       return nil, fmt.Errorf("vbmap: No KV node no for vb %d", vbno)
-               } else if idxs[0] < 0 || idxs[0] >= len(servers) {
-                       return nil, fmt.Errorf("vbmap: Invalid KV node no %d for vb %d", idxs[0], vbno)
-               }
-               addr := servers[idxs[0]]
-               if _, ok := m[addr]; ok {
-                       m[addr] = append(m[addr], uint16(vbno))
-               }
-       }
-       return m, nil
-}
-
-// true if node is not on the bucket VBmap
-func (b *Bucket) checkVBmap(node string) bool {
-       vbmap := b.VBServerMap()
-       servers := vbmap.ServerList
-
-       for _, idxs := range vbmap.VBucketMap {
-               if len(idxs) == 0 {
-                       return true
-               } else if idxs[0] < 0 || idxs[0] >= len(servers) {
-                       return true
-               }
-               if servers[idxs[0]] == node {
-                       return false
-               }
-       }
-       return true
-}
-
-func (b *Bucket) GetName() string {
-       b.RLock()
-       defer b.RUnlock()
-       ret := b.Name
-       return ret
-}
-
-// Nodes returns the current list of nodes servicing this bucket.
-func (b *Bucket) Nodes() []Node {
-       b.RLock()
-       defer b.RUnlock()
-       ret := *(*[]Node)(b.nodeList)
-       return ret
-}
-
-// return the list of healthy nodes
-func (b *Bucket) HealthyNodes() []Node {
-       nodes := []Node{}
-
-       for _, n := range b.Nodes() {
-               if n.Status == "healthy" && n.CouchAPIBase != "" {
-                       nodes = append(nodes, n)
-               }
-               if n.Status != "healthy" { // log non-healthy node
-                       logging.Infof("Non-healthy node; node details:")
-                       logging.Infof("Hostname=%v, Status=%v, CouchAPIBase=%v, ThisNode=%v", n.Hostname, n.Status, n.CouchAPIBase, n.ThisNode)
-               }
-       }
-
-       return nodes
-}
-
-func (b *Bucket) getConnPools(bucketLocked bool) []*connectionPool {
-       if !bucketLocked {
-               b.RLock()
-               defer b.RUnlock()
-       }
-       if b.connPools != nil {
-               return *(*[]*connectionPool)(b.connPools)
-       } else {
-               return nil
-       }
-}
-
-func (b *Bucket) replaceConnPools(with []*connectionPool) {
-       b.Lock()
-       defer b.Unlock()
-
-       old := b.connPools
-       b.connPools = unsafe.Pointer(&with)
-       if old != nil {
-               for _, pool := range *(*[]*connectionPool)(old) {
-                       if pool != nil {
-                               pool.Close()
-                       }
-               }
-       }
-       return
-}
-
-func (b *Bucket) getConnPool(i int) *connectionPool {
-
-       if i < 0 {
-               return nil
-       }
-
-       p := b.getConnPools(false /* not already locked */)
-       if len(p) > i {
-               return p[i]
-       }
-
-       return nil
-}
-
-func (b *Bucket) getConnPoolByHost(host string, bucketLocked bool) *connectionPool {
-       pools := b.getConnPools(bucketLocked)
-       for _, p := range pools {
-               if p != nil && p.host == host {
-                       return p
-               }
-       }
-
-       return nil
-}
-
-// Given a vbucket number, returns a memcached connection to it.
-// The connection must be returned to its pool after use.
-func (b *Bucket) getConnectionToVBucket(vb uint32) (*memcached.Client, *connectionPool, error) {
-       for {
-               vbm := b.VBServerMap()
-               if len(vbm.VBucketMap) < int(vb) {
-                       return nil, nil, fmt.Errorf("go-couchbase: vbmap smaller than vbucket list: %v vs. %v",
-                               vb, vbm.VBucketMap)
-               }
-               masterId := vbm.VBucketMap[vb][0]
-               if masterId < 0 {
-                       return nil, nil, fmt.Errorf("go-couchbase: No master for vbucket %d", vb)
-               }
-               pool := b.getConnPool(masterId)
-               conn, err := pool.Get()
-               if err != errClosedPool {
-                       return conn, pool, err
-               }
-               // If conn pool was closed, because another goroutine refreshed the vbucket map, retry...
-       }
-}
-
-// To get random documents, we need to cover all the nodes, so select
-// a connection at random.
-
-func (b *Bucket) getRandomConnection() (*memcached.Client, *connectionPool, error) {
-       for {
-               var currentPool = 0
-               pools := b.getConnPools(false /* not already locked */)
-               if len(pools) == 0 {
-                       return nil, nil, fmt.Errorf("No connection pool found")
-               } else if len(pools) > 1 { // choose a random connection
-                       currentPool = rand.Intn(len(pools))
-               } // if only one pool, currentPool defaults to 0, i.e., the only pool
-
-               // get the pool
-               pool := pools[currentPool]
-               conn, err := pool.Get()
-               if err != errClosedPool {
-                       return conn, pool, err
-               }
-
-               // If conn pool was closed, because another goroutine refreshed the vbucket map, retry...
-       }
-}
-
-//
-// Get a random document from a bucket. Since the bucket may be distributed
-// across nodes, we must first select a random connection, and then use the
-// Client.GetRandomDoc() call to get a random document from that node.
-//
-
-func (b *Bucket) GetRandomDoc() (*gomemcached.MCResponse, error) {
-       // get a connection from the pool
-       conn, pool, err := b.getRandomConnection()
-
-       if err != nil {
-               return nil, err
-       }
-
-       // We may need to select the bucket before GetRandomDoc()
-       // will work. This is sometimes done at startup (see defaultMkConn())
-       // but not always, depending on the auth type.
-       _, err = conn.SelectBucket(b.Name)
-       if err != nil {
-               return nil, err
-       }
-
-       // get a randomm document from the connection
-       doc, err := conn.GetRandomDoc()
-       // need to return the connection to the pool
-       pool.Return(conn)
-       return doc, err
-}
-
-func (b *Bucket) getMasterNode(i int) string {
-       p := b.getConnPools(false /* not already locked */)
-       if len(p) > i {
-               return p[i].host
-       }
-       return ""
-}
-
-func (b *Bucket) authHandler(bucketLocked bool) (ah AuthHandler) {
-       if !bucketLocked {
-               b.RLock()
-               defer b.RUnlock()
-       }
-       pool := b.pool
-       name := b.Name
-
-       if pool != nil {
-               ah = pool.client.ah
-       }
-       if mbah, ok := ah.(MultiBucketAuthHandler); ok {
-               return mbah.ForBucket(name)
-       }
-       if ah == nil {
-               ah = &basicAuth{name, ""}
-       }
-       return
-}
-
-// NodeAddresses gets the (sorted) list of memcached node addresses
-// (hostname:port).
-func (b *Bucket) NodeAddresses() []string {
-       vsm := b.VBServerMap()
-       rv := make([]string, len(vsm.ServerList))
-       copy(rv, vsm.ServerList)
-       sort.Strings(rv)
-       return rv
-}
-
-// CommonAddressSuffix finds the longest common suffix of all
-// host:port strings in the node list.
-func (b *Bucket) CommonAddressSuffix() string {
-       input := []string{}
-       for _, n := range b.Nodes() {
-               input = append(input, n.Hostname)
-       }
-       return FindCommonSuffix(input)
-}
-
-// A Client is the starting point for all services across all buckets
-// in a Couchbase cluster.
-type Client struct {
-       BaseURL   *url.URL
-       ah        AuthHandler
-       Info      Pools
-       tlsConfig *tls.Config
-}
-
-func maybeAddAuth(req *http.Request, ah AuthHandler) error {
-       if hah, ok := ah.(HTTPAuthHandler); ok {
-               return hah.SetCredsForRequest(req)
-       }
-       if ah != nil {
-               user, pass, _ := ah.GetCredentials()
-               req.Header.Set("Authorization", "Basic "+
-                       base64.StdEncoding.EncodeToString([]byte(user+":"+pass)))
-       }
-       return nil
-}
-
-// arbitary number, may need to be tuned #FIXME
-const HTTP_MAX_RETRY = 5
-
-// Someday golang network packages will implement standard
-// error codes. Until then #sigh
-func isHttpConnError(err error) bool {
-
-       estr := err.Error()
-       return strings.Contains(estr, "broken pipe") ||
-               strings.Contains(estr, "broken connection") ||
-               strings.Contains(estr, "connection reset")
-}
-
-var client *http.Client
-
-func ClientConfigForX509(certFile, keyFile, rootFile string) (*tls.Config, error) {
-       cfg := &tls.Config{}
-
-       if certFile != "" && keyFile != "" {
-               tlsCert, err := tls.LoadX509KeyPair(certFile, keyFile)
-               if err != nil {
-                       return nil, err
-               }
-               cfg.Certificates = []tls.Certificate{tlsCert}
-       } else {
-               //error need to pass both certfile and keyfile
-               return nil, fmt.Errorf("N1QL: Need to pass both certfile and keyfile")
-       }
-
-       var caCert []byte
-       var err1 error
-
-       caCertPool := x509.NewCertPool()
-       if rootFile != "" {
-               // Read that value in
-               caCert, err1 = ioutil.ReadFile(rootFile)
-               if err1 != nil {
-                       return nil, fmt.Errorf(" Error in reading cacert file, err: %v", err1)
-               }
-               caCertPool.AppendCertsFromPEM(caCert)
-       }
-
-       cfg.RootCAs = caCertPool
-       return cfg, nil
-}
-
-func doHTTPRequest(req *http.Request) (*http.Response, error) {
-
-       var err error
-       var res *http.Response
-
-       // we need a client that ignores certificate errors, since we self-sign
-       // our certs
-       if client == nil && req.URL.Scheme == "https" {
-               var tr *http.Transport
-
-               if skipVerify {
-                       tr = &http.Transport{
-                               TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
-                       }
-               } else {
-                       // Handle cases with cert
-
-                       cfg, err := ClientConfigForX509(certFile, keyFile, rootFile)
-                       if err != nil {
-                               return nil, err
-                       }
-
-                       tr = &http.Transport{
-                               TLSClientConfig: cfg,
-                       }
-               }
-
-               client = &http.Client{Transport: tr}
-
-       } else if client == nil {
-               client = HTTPClient
-       }
-
-       for i := 0; i < HTTP_MAX_RETRY; i++ {
-               res, err = client.Do(req)
-               if err != nil && isHttpConnError(err) {
-                       continue
-               }
-               break
-       }
-
-       if err != nil {
-               return nil, err
-       }
-
-       return res, err
-}
-
-func doPutAPI(baseURL *url.URL, path string, params map[string]interface{}, authHandler AuthHandler, out interface{}) error {
-       return doOutputAPI("PUT", baseURL, path, params, authHandler, out)
-}
-
-func doPostAPI(baseURL *url.URL, path string, params map[string]interface{}, authHandler AuthHandler, out interface{}) error {
-       return doOutputAPI("POST", baseURL, path, params, authHandler, out)
-}
-
-func doOutputAPI(
-       httpVerb string,
-       baseURL *url.URL,
-       path string,
-       params map[string]interface{},
-       authHandler AuthHandler,
-       out interface{}) error {
-
-       var requestUrl string
-
-       if q := strings.Index(path, "?"); q > 0 {
-               requestUrl = baseURL.Scheme + "://" + baseURL.Host + path[:q] + "?" + path[q+1:]
-       } else {
-               requestUrl = baseURL.Scheme + "://" + baseURL.Host + path
-       }
-
-       postData := url.Values{}
-       for k, v := range params {
-               postData.Set(k, fmt.Sprintf("%v", v))
-       }
-
-       req, err := http.NewRequest(httpVerb, requestUrl, bytes.NewBufferString(postData.Encode()))
-       if err != nil {
-               return err
-       }
-
-       req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
-
-       err = maybeAddAuth(req, authHandler)
-       if err != nil {
-               return err
-       }
-
-       res, err := doHTTPRequest(req)
-       if err != nil {
-               return err
-       }
-
-       defer res.Body.Close()
-       if res.StatusCode != 200 {
-               bod, _ := ioutil.ReadAll(io.LimitReader(res.Body, 512))
-               return fmt.Errorf("HTTP error %v getting %q: %s",
-                       res.Status, requestUrl, bod)
-       }
-
-       d := json.NewDecoder(res.Body)
-       if err = d.Decode(&out); err != nil {
-               return err
-       }
-       return nil
-}
-
-func queryRestAPI(
-       baseURL *url.URL,
-       path string,
-       authHandler AuthHandler,
-       out interface{}) error {
-
-       var requestUrl string
-
-       if q := strings.Index(path, "?"); q > 0 {
-               requestUrl = baseURL.Scheme + "://" + baseURL.Host + path[:q] + "?" + path[q+1:]
-       } else {
-               requestUrl = baseURL.Scheme + "://" + baseURL.Host + path
-       }
-
-       req, err := http.NewRequest("GET", requestUrl, nil)
-       if err != nil {
-               return err
-       }
-
-       err = maybeAddAuth(req, authHandler)
-       if err != nil {
-               return err
-       }
-
-       res, err := doHTTPRequest(req)
-       if err != nil {
-               return err
-       }
-
-       defer res.Body.Close()
-       if res.StatusCode != 200 {
-               bod, _ := ioutil.ReadAll(io.LimitReader(res.Body, 512))
-               return fmt.Errorf("HTTP error %v getting %q: %s",
-                       res.Status, requestUrl, bod)
-       }
-
-       d := json.NewDecoder(res.Body)
-       if err = d.Decode(&out); err != nil {
-               return err
-       }
-       return nil
-}
-
-func (c *Client) ProcessStream(path string, callb func(interface{}) error, data interface{}) error {
-       return c.processStream(c.BaseURL, path, c.ah, callb, data)
-}
-
-// Based on code in http://src.couchbase.org/source/xref/trunk/goproj/src/github.com/couchbase/indexing/secondary/dcp/pools.go#309
-func (c *Client) processStream(baseURL *url.URL, path string, authHandler AuthHandler, callb func(interface{}) error, data interface{}) error {
-       var requestUrl string
-
-       if q := strings.Index(path, "?"); q > 0 {
-               requestUrl = baseURL.Scheme + "://" + baseURL.Host + path[:q] + "?" + path[q+1:]
-       } else {
-               requestUrl = baseURL.Scheme + "://" + baseURL.Host + path
-       }
-
-       req, err := http.NewRequest("GET", requestUrl, nil)
-       if err != nil {
-               return err
-       }
-
-       err = maybeAddAuth(req, authHandler)
-       if err != nil {
-               return err
-       }
-
-       res, err := doHTTPRequest(req)
-       if err != nil {
-               return err
-       }
-
-       defer res.Body.Close()
-       if res.StatusCode != 200 {
-               bod, _ := ioutil.ReadAll(io.LimitReader(res.Body, 512))
-               return fmt.Errorf("HTTP error %v getting %q: %s",
-                       res.Status, requestUrl, bod)
-       }
-
-       reader := bufio.NewReader(res.Body)
-       for {
-               bs, err := reader.ReadBytes('\n')
-               if err != nil {
-                       return err
-               }
-               if len(bs) == 1 && bs[0] == '\n' {
-                       continue
-               }
-
-               err = json.Unmarshal(bs, data)
-               if err != nil {
-                       return err
-               }
-               err = callb(data)
-               if err != nil {
-                       return err
-               }
-       }
-       return nil
-
-}
-
-func (c *Client) parseURLResponse(path string, out interface{}) error {
-       return queryRestAPI(c.BaseURL, path, c.ah, out)
-}
-
-func (c *Client) parsePostURLResponse(path string, params map[string]interface{}, out interface{}) error {
-       return doPostAPI(c.BaseURL, path, params, c.ah, out)
-}
-
-func (c *Client) parsePutURLResponse(path string, params map[string]interface{}, out interface{}) error {
-       return doPutAPI(c.BaseURL, path, params, c.ah, out)
-}
-
-func (b *Bucket) parseURLResponse(path string, out interface{}) error {
-       nodes := b.Nodes()
-       if len(nodes) == 0 {
-               return errors.New("no couch rest URLs")
-       }
-
-       // Pick a random node to start querying.
-       startNode := rand.Intn(len(nodes))
-       maxRetries := len(nodes)
-       for i := 0; i < maxRetries; i++ {
-               node := nodes[(startNode+i)%len(nodes)] // Wrap around the nodes list.
-               // Skip non-healthy nodes.
-               if node.Status != "healthy" || node.CouchAPIBase == "" {
-                       continue
-               }
-               url := &url.URL{
-                       Host:   node.Hostname,
-                       Scheme: "http",
-               }
-
-               // Lock here to avoid having pool closed under us.
-               b.RLock()
-               err := queryRestAPI(url, path, b.pool.client.ah, out)
-               b.RUnlock()
-               if err == nil {
-                       return err
-               }
-       }
-       return errors.New("All nodes failed to respond or no healthy nodes for bucket found")
-}
-
-func (b *Bucket) parseAPIResponse(path string, out interface{}) error {
-       nodes := b.Nodes()
-       if len(nodes) == 0 {
-               return errors.New("no couch rest URLs")
-       }
-
-       var err error
-       var u *url.URL
-
-       // Pick a random node to start querying.
-       startNode := rand.Intn(len(nodes))
-       maxRetries := len(nodes)
-       for i := 0; i < maxRetries; i++ {
-               node := nodes[(startNode+i)%len(nodes)] // Wrap around the nodes list.
-               // Skip non-healthy nodes.
-               if node.Status != "healthy" || node.CouchAPIBase == "" {
-                       continue
-               }
-
-               u, err = ParseURL(node.CouchAPIBase)
-               // Lock here so pool does not get closed under us.
-               b.RLock()
-               if err != nil {
-                       b.RUnlock()
-                       return fmt.Errorf("config error: Bucket %q node #%d CouchAPIBase=%q: %v",
-                               b.Name, i, node.CouchAPIBase, err)
-               } else if b.pool != nil {
-                       u.User = b.pool.client.BaseURL.User
-               }
-               u.Path = path
-
-               // generate the path so that the strings are properly escaped
-               // MB-13770
-               requestPath := strings.Split(u.String(), u.Host)[1]
-
-               err = queryRestAPI(u, requestPath, b.pool.client.ah, out)
-               b.RUnlock()
-               if err == nil {
-                       return err
-               }
-       }
-
-       var errStr string
-       if err != nil {
-               errStr = "Error " + err.Error()
-       }
-
-       return errors.New("All nodes failed to respond or returned error or no healthy nodes for bucket found." + errStr)
-}
-
-type basicAuth struct {
-       u, p string
-}
-
-func (b basicAuth) GetCredentials() (string, string, string) {
-       return b.u, b.p, b.u
-}
-
-func basicAuthFromURL(us string) (ah AuthHandler) {
-       u, err := ParseURL(us)
-       if err != nil {
-               return
-       }
-       if user := u.User; user != nil {
-               pw, _ := user.Password()
-               ah = basicAuth{user.Username(), pw}
-       }
-       return
-}
-
-// ConnectWithAuth connects to a couchbase cluster with the given
-// authentication handler.
-func ConnectWithAuth(baseU string, ah AuthHandler) (c Client, err error) {
-       c.BaseURL, err = ParseURL(baseU)
-       if err != nil {
-               return
-       }
-       c.ah = ah
-
-       return c, c.parseURLResponse("/pools", &c.Info)
-}
-
-// Call this method with a TLS certificate file name to make communication
-// with the KV engine encrypted.
-//
-// This method should be called immediately after a Connect*() method.
-func (c *Client) InitTLS(certFile string) error {
-       serverCert, err := ioutil.ReadFile(certFile)
-       if err != nil {
-               return err
-       }
-       CA_Pool := x509.NewCertPool()
-       CA_Pool.AppendCertsFromPEM(serverCert)
-       c.tlsConfig = &tls.Config{RootCAs: CA_Pool}
-       return nil
-}
-
-func (c *Client) ClearTLS() {
-       c.tlsConfig = nil
-}
-
-// ConnectWithAuthCreds connects to a couchbase cluster with the give
-// authorization creds returned by cb_auth
-func ConnectWithAuthCreds(baseU, username, password string) (c Client, err error) {
-       c.BaseURL, err = ParseURL(baseU)
-       if err != nil {
-               return
-       }
-
-       c.ah = newBucketAuth(username, password, "")
-       return c, c.parseURLResponse("/pools", &c.Info)
-}
-
-// Connect to a couchbase cluster.  An authentication handler will be
-// created from the userinfo in the URL if provided.
-func Connect(baseU string) (Client, error) {
-       return ConnectWithAuth(baseU, basicAuthFromURL(baseU))
-}
-
-type BucketInfo struct {
-       Name     string // name of bucket
-       Password string // SASL password of bucket
-}
-
-//Get SASL buckets
-func GetBucketList(baseU string) (bInfo []BucketInfo, err error) {
-
-       c := &Client{}
-       c.BaseURL, err = ParseURL(baseU)
-       if err != nil {
-               return
-       }
-       c.ah = basicAuthFromURL(baseU)
-
-       var buckets []Bucket
-       err = c.parseURLResponse("/pools/default/buckets", &buckets)
-       if err != nil {
-               return
-       }
-       bInfo = make([]BucketInfo, 0)
-       for _, bucket := range buckets {
-               bucketInfo := BucketInfo{Name: bucket.Name, Password: bucket.Password}
-               bInfo = append(bInfo, bucketInfo)
-       }
-       return bInfo, err
-}
-
-//Set viewUpdateDaemonOptions
-func SetViewUpdateParams(baseU string, params map[string]interface{}) (viewOpts map[string]interface{}, err error) {
-
-       c := &Client{}
-       c.BaseURL, err = ParseURL(baseU)
-       if err != nil {
-               return
-       }
-       c.ah = basicAuthFromURL(baseU)
-
-       if len(params) < 1 {
-               return nil, fmt.Errorf("No params to set")
-       }
-
-       err = c.parsePostURLResponse("/settings/viewUpdateDaemon", params, &viewOpts)
-       if err != nil {
-               return
-       }
-       return viewOpts, err
-}
-
-// This API lets the caller know, if the list of nodes a bucket is
-// connected to has gone through an edit (a rebalance operation)
-// since the last update to the bucket, in which case a Refresh is
-// advised.
-func (b *Bucket) NodeListChanged() bool {
-       b.RLock()
-       pool := b.pool
-       uri := b.URI
-       b.RUnlock()
-
-       tmpb := &Bucket{}
-       err := pool.client.parseURLResponse(uri, tmpb)
-       if err != nil {
-               return true
-       }
-
-       bNodes := *(*[]Node)(b.nodeList)
-       if len(bNodes) != len(tmpb.NodesJSON) {
-               return true
-       }
-
-       bucketHostnames := map[string]bool{}
-       for _, node := range bNodes {
-               bucketHostnames[node.Hostname] = true
-       }
-
-       for _, node := range tmpb.NodesJSON {
-               if _, found := bucketHostnames[node.Hostname]; !found {
-                       return true
-               }
-       }
-
-       return false
-}
-
-// Sample data for scopes and collections as returned from the
-// /pooles/default/$BUCKET_NAME/collections API.
-// {"myScope2":{"myCollectionC":{}},"myScope1":{"myCollectionB":{},"myCollectionA":{}},"_default":{"_default":{}}}
-
-// Structures for parsing collections manifest.
-// The map key is the name of the scope.
-// Example data:
-// {"uid":"b","scopes":[
-//    {"name":"_default","uid":"0","collections":[
-//       {"name":"_default","uid":"0"}]},
-//    {"name":"myScope1","uid":"8","collections":[
-//       {"name":"myCollectionB","uid":"c"},
-//       {"name":"myCollectionA","uid":"b"}]},
-//    {"name":"myScope2","uid":"9","collections":[
-//       {"name":"myCollectionC","uid":"d"}]}]}
-type InputManifest struct {
-       Uid    string
-       Scopes []InputScope
-}
-type InputScope struct {
-       Name        string
-       Uid         string
-       Collections []InputCollection
-}
-type InputCollection struct {
-       Name string
-       Uid  string
-}
-
-// Structures for storing collections information.
-type Manifest struct {
-       Uid    uint64
-       Scopes map[string]*Scope // map by name
-}
-type Scope struct {
-       Name        string
-       Uid         uint64
-       Collections map[string]*Collection // map by name
-}
-type Collection struct {
-       Name string
-       Uid  uint64
-}
-
-var _EMPTY_MANIFEST *Manifest = &Manifest{Uid: 0, Scopes: map[string]*Scope{}}
-
-func parseCollectionsManifest(res *gomemcached.MCResponse) (*Manifest, error) {
-       if !EnableCollections {
-               return _EMPTY_MANIFEST, nil
-       }
-
-       var im InputManifest
-       err := json.Unmarshal(res.Body, &im)
-       if err != nil {
-               return nil, err
-       }
-
-       uid, err := strconv.ParseUint(im.Uid, 16, 64)
-       if err != nil {
-               return nil, err
-       }
-       mani := &Manifest{Uid: uid, Scopes: make(map[string]*Scope, len(im.Scopes))}
-       for _, iscope := range im.Scopes {
-               scope_uid, err := strconv.ParseUint(iscope.Uid, 16, 64)
-               if err != nil {
-                       return nil, err
-               }
-               scope := &Scope{Uid: scope_uid, Name: iscope.Name, Collections: make(map[string]*Collection, len(iscope.Collections))}
-               mani.Scopes[iscope.Name] = scope
-               for _, icoll := range iscope.Collections {
-                       coll_uid, err := strconv.ParseUint(icoll.Uid, 16, 64)
-                       if err != nil {
-                               return nil, err
-                       }
-                       coll := &Collection{Uid: coll_uid, Name: icoll.Name}
-                       scope.Collections[icoll.Name] = coll
-               }
-       }
-
-       return mani, nil
-}
-
-// This function assumes the bucket is locked.
-func (b *Bucket) GetCollectionsManifest() (*Manifest, error) {
-       // Collections not used?
-       if !EnableCollections {
-               return nil, fmt.Errorf("Collections not enabled.")
-       }
-
-       b.RLock()
-       pools := b.getConnPools(true /* already locked */)
-       pool := pools[0] // Any pool will do, so use the first one.
-       b.RUnlock()
-       client, err := pool.Get()
-       if err != nil {
-               return nil, fmt.Errorf("Unable to get connection to retrieve collections manifest: %v. No collections access to bucket %s.", err, b.Name)
-       }
-
-       // We need to select the bucket before GetCollectionsManifest()
-       // will work. This is sometimes done at startup (see defaultMkConn())
-       // but not always, depending on the auth type.
-       // Doing this is safe because we collect the the connections
-       // by bucket, so the bucket being selected will never change.
-       _, err = client.SelectBucket(b.Name)
-       if err != nil {
-               pool.Return(client)
-               return nil, fmt.Errorf("Unable to select bucket %s: %v. No collections access to bucket %s.", err, b.Name, b.Name)
-       }
-
-       res, err := client.GetCollectionsManifest()
-       if err != nil {
-               pool.Return(client)
-               return nil, fmt.Errorf("Unable to retrieve collections manifest: %v. No collections access to bucket %s.", err, b.Name)
-       }
-       mani, err := parseCollectionsManifest(res)
-       if err != nil {
-               pool.Return(client)
-               return nil, fmt.Errorf("Unable to parse collections manifest: %v. No collections access to bucket %s.", err, b.Name)
-       }
-
-       pool.Return(client)
-       return mani, nil
-}
-
-func (b *Bucket) RefreshFully() error {
-       return b.refresh(false)
-}
-
-func (b *Bucket) Refresh() error {
-       return b.refresh(true)
-}
-
-func (b *Bucket) refresh(preserveConnections bool) error {
-       b.RLock()
-       pool := b.pool
-       uri := b.URI
-       client := pool.client
-       b.RUnlock()
-       tlsConfig := client.tlsConfig
-
-       var poolServices PoolServices
-       var err error
-       if tlsConfig != nil {
-               poolServices, err = client.GetPoolServices("default")
-               if err != nil {
-                       return err
-               }
-       }
-
-       tmpb := &Bucket{}
-       err = pool.client.parseURLResponse(uri, tmpb)
-       if err != nil {
-               return err
-       }
-
-       pools := b.getConnPools(false /* bucket not already locked */)
-
-       // We need this lock to ensure that bucket refreshes happening because
-       // of NMVb errors received during bulkGet do not end up over-writing
-       // pool.inUse.
-       b.Lock()
-
-       for _, pool := range pools {
-               if pool != nil {
-                       pool.inUse = false
-               }
-       }
-
-       newcps := make([]*connectionPool, len(tmpb.VBSMJson.ServerList))
-       for i := range newcps {
-
-               if preserveConnections {
-                       pool := b.getConnPoolByHost(tmpb.VBSMJson.ServerList[i], true /* bucket already locked */)
-                       if pool != nil && pool.inUse == false {
-                               // if the hostname and index is unchanged then reuse this pool
-                               newcps[i] = pool
-                               pool.inUse = true
-                               continue
-                       }
-               }
-
-               hostport := tmpb.VBSMJson.ServerList[i]
-               if tlsConfig != nil {
-                       hostport, err = MapKVtoSSL(hostport, &poolServices)
-                       if err != nil {
-                               b.Unlock()
-                               return err
-                       }
-               }
-
-               if b.ah != nil {
-                       newcps[i] = newConnectionPool(hostport,
-                               b.ah, AsynchronousCloser, PoolSize, PoolOverflow, tlsConfig, b.Name)
-
-               } else {
-                       newcps[i] = newConnectionPool(hostport,
-                               b.authHandler(true /* bucket already locked */),
-                               AsynchronousCloser, PoolSize, PoolOverflow, tlsConfig, b.Name)
-               }
-       }
-       b.replaceConnPools2(newcps, true /* bucket already locked */)
-       tmpb.ah = b.ah
-       b.vBucketServerMap = unsafe.Pointer(&tmpb.VBSMJson)
-       b.nodeList = unsafe.Pointer(&tmpb.NodesJSON)
-
-       b.Unlock()
-       return nil
-}
-
-func (p *Pool) refresh() (err error) {
-       p.BucketMap = make(map[string]*Bucket)
-
-       buckets := []Bucket{}
-       err = p.client.parseURLResponse(p.BucketURL["uri"], &buckets)
-       if err != nil {
-               return err
-       }
-       for i, _ := range buckets {
-               b := new(Bucket)
-               *b = buckets[i]
-               b.pool = p
-               b.nodeList = unsafe.Pointer(&b.NodesJSON)
-
-               // MB-33185 this is merely defensive, just in case
-               // refresh() gets called on a perfectly node pool
-               ob, ok := p.BucketMap[b.Name]
-               if ok && ob.connPools != nil {
-                       ob.Close()
-               }
-               b.replaceConnPools(make([]*connectionPool, len(b.VBSMJson.ServerList)))
-               p.BucketMap[b.Name] = b
-               runtime.SetFinalizer(b, bucketFinalizer)
-       }
-       return nil
-}
-
-// GetPool gets a pool from within the couchbase cluster (usually
-// "default").
-func (c *Client) GetPool(name string) (p Pool, err error) {
-       var poolURI string
-
-       for _, p := range c.Info.Pools {
-               if p.Name == name {
-                       poolURI = p.URI
-                       break
-               }
-       }
-       if poolURI == "" {
-               return p, errors.New("No pool named " + name)
-       }
-
-       err = c.parseURLResponse(poolURI, &p)
-
-       p.client = c
-
-       err = p.refresh()
-       return
-}
-
-// GetPoolServices returns all the bucket-independent services in a pool.
-// (See "Exposing services outside of bucket context" in http://goo.gl/uuXRkV)
-func (c *Client) GetPoolServices(name string) (ps PoolServices, err error) {
-       var poolName string
-       for _, p := range c.Info.Pools {
-               if p.Name == name {
-                       poolName = p.Name
-               }
-       }
-       if poolName == "" {
-               return ps, errors.New("No pool named " + name)
-       }
-
-       poolURI := "/pools/" + poolName + "/nodeServices"
-       err = c.parseURLResponse(poolURI, &ps)
-
-       return
-}
-
-func (b *Bucket) GetPoolServices(name string) (*PoolServices, error) {
-       b.RLock()
-       pool := b.pool
-       b.RUnlock()
-
-       ps, err := pool.client.GetPoolServices(name)
-       if err != nil {
-               return nil, err
-       }
-
-       return &ps, nil
-}
-
-// Close marks this bucket as no longer needed, closing connections it
-// may have open.
-func (b *Bucket) Close() {
-       b.Lock()
-       defer b.Unlock()
-       if b.connPools != nil {
-               for _, c := range b.getConnPools(true /* already locked */) {
-                       if c != nil {
-                               c.Close()
-                       }
-               }
-               b.connPools = nil
-       }
-}
-
-func bucketFinalizer(b *Bucket) {
-       if b.connPools != nil {
-               if !b.closed {
-                       logging.Warnf("Finalizing a bucket with active connections.")
-               }
-
-               // MB-33185 do not leak connection pools
-               b.Close()
-       }
-}
-
-// GetBucket gets a bucket from within this pool.
-func (p *Pool) GetBucket(name string) (*Bucket, error) {
-       rv, ok := p.BucketMap[name]
-       if !ok {
-               return nil, &BucketNotFoundError{bucket: name}
-       }
-       err := rv.Refresh()
-       if err != nil {
-               return nil, err
-       }
-       return rv, nil
-}
-
-// GetBucket gets a bucket from within this pool.
-func (p *Pool) GetBucketWithAuth(bucket, username, password string) (*Bucket, error) {
-       rv, ok := p.BucketMap[bucket]
-       if !ok {
-               return nil, &BucketNotFoundError{bucket: bucket}
-       }
-       rv.ah = newBucketAuth(username, password, bucket)
-       err := rv.Refresh()
-       if err != nil {
-               return nil, err
-       }
-       return rv, nil
-}
-
-// GetPool gets the pool to which this bucket belongs.
-func (b *Bucket) GetPool() *Pool {
-       b.RLock()
-       defer b.RUnlock()
-       ret := b.pool
-       return ret
-}
-
-// GetClient gets the client from which we got this pool.
-func (p *Pool) GetClient() *Client {
-       return p.client
-}
-
-// Release bucket connections when the pool is no longer in use
-func (p *Pool) Close() {
-       // fine to loop through the buckets unlocked
-       // locking happens at the bucket level
-       for b, _ := range p.BucketMap {
-
-               // MB-33208 defer closing connection pools until the bucket is no longer used
-               bucket := p.BucketMap[b]
-               bucket.Lock()
-               bucket.closed = true
-               bucket.Unlock()
-       }
-}
-
-// GetBucket is a convenience function for getting a named bucket from
-// a URL
-func GetBucket(endpoint, poolname, bucketname string) (*Bucket, error) {
-       var err error
-       client, err := Connect(endpoint)
-       if err != nil {
-               return nil, err
-       }
-
-       pool, err := client.GetPool(poolname)
-       if err != nil {
-               return nil, err
-       }
-
-       return pool.GetBucket(bucketname)
-}
-
-// ConnectWithAuthAndGetBucket is a convenience function for
-// getting a named bucket from a given URL and an auth callback
-func ConnectWithAuthAndGetBucket(endpoint, poolname, bucketname string,
-       ah AuthHandler) (*Bucket, error) {
-       client, err := ConnectWithAuth(endpoint, ah)
-       if err != nil {
-               return nil, err
-       }
-
-       pool, err := client.GetPool(poolname)
-       if err != nil {
-               return nil, err
-       }
-
-       return pool.GetBucket(bucketname)
-}
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/port_map.go b/vendor/github.com/couchbaselabs/go-couchbase/port_map.go
deleted file mode 100644 (file)
index 24c9f10..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-package couchbase
-
-/*
-
-The goal here is to map a hostname:port combination to another hostname:port
-combination. The original hostname:port gives the name and regular KV port
-of a couchbase server. We want to determine the corresponding SSL KV port.
-
-To do this, we have a pool services structure, as obtained from
-the /pools/default/nodeServices API.
-
-For a fully configured two-node system, the structure may look like this:
-{"rev":32,"nodesExt":[
-       {"services":{"mgmt":8091,"mgmtSSL":18091,"fts":8094,"ftsSSL":18094,"indexAdmin":9100,"indexScan":9101,"indexHttp":9102,"indexStreamInit":9103,"indexStreamCatchup":9104,"indexStreamMaint":9105,"indexHttps":19102,"capiSSL":18092,"capi":8092,"kvSSL":11207,"projector":9999,"kv":11210,"moxi":11211},"hostname":"172.23.123.101"},
-       {"services":{"mgmt":8091,"mgmtSSL":18091,"indexAdmin":9100,"indexScan":9101,"indexHttp":9102,"indexStreamInit":9103,"indexStreamCatchup":9104,"indexStreamMaint":9105,"indexHttps":19102,"capiSSL":18092,"capi":8092,"kvSSL":11207,"projector":9999,"kv":11210,"moxi":11211,"n1ql":8093,"n1qlSSL":18093},"thisNode":true,"hostname":"172.23.123.102"}]}
-
-In this case, note the "hostname" fields, and the "kv" and "kvSSL" fields.
-
-For a single-node system, perhaps brought up for testing, the structure may look like this:
-{"rev":66,"nodesExt":[
-       {"services":{"mgmt":8091,"mgmtSSL":18091,"indexAdmin":9100,"indexScan":9101,"indexHttp":9102,"indexStreamInit":9103,"indexStreamCatchup":9104,"indexStreamMaint":9105,"indexHttps":19102,"kv":11210,"kvSSL":11207,"capi":8092,"capiSSL":18092,"projector":9999,"n1ql":8093,"n1qlSSL":18093},"thisNode":true}],"clusterCapabilitiesVer":[1,0],"clusterCapabilities":{"n1ql":["enhancedPreparedStatements"]}}
-
-Here, note that there is only a single entry in the "nodeExt" array and that it does not have a "hostname" field.
-We will assume that either hostname fields are present, or there is only a single node.
-*/
-
-import (
-       "encoding/json"
-       "fmt"
-       "strconv"
-       "strings"
-)
-
-func ParsePoolServices(jsonInput string) (*PoolServices, error) {
-       ps := &PoolServices{}
-       err := json.Unmarshal([]byte(jsonInput), ps)
-       return ps, err
-}
-
-func MapKVtoSSL(hostport string, ps *PoolServices) (string, error) {
-       colonIndex := strings.LastIndex(hostport, ":")
-       if colonIndex < 0 {
-               return "", fmt.Errorf("Unable to find host/port separator in %s", hostport)
-       }
-       host := hostport[0:colonIndex]
-       port := hostport[colonIndex+1:]
-       portInt, err := strconv.Atoi(port)
-       if err != nil {
-               return "", fmt.Errorf("Unable to parse host/port combination %s: %v", hostport, err)
-       }
-
-       var ns *NodeServices
-       if len(ps.NodesExt) == 1 {
-               ns = &(ps.NodesExt[0])
-       } else {
-               for i := range ps.NodesExt {
-                       hostname := ps.NodesExt[i].Hostname
-                       if len(hostname) == 0 {
-                               // in case of missing hostname, check for 127.0.0.1
-                               hostname = "127.0.0.1"
-                       }
-                       if hostname == host {
-                               ns = &(ps.NodesExt[i])
-                               break
-                       }
-               }
-       }
-
-       if ns == nil {
-               return "", fmt.Errorf("Unable to parse host/port combination %s: no matching node found among %d", hostport, len(ps.NodesExt))
-       }
-       kv, found := ns.Services["kv"]
-       if !found {
-               return "", fmt.Errorf("Unable to map host/port combination %s: target host has no kv port listed", hostport)
-       }
-       kvSSL, found := ns.Services["kvSSL"]
-       if !found {
-               return "", fmt.Errorf("Unable to map host/port combination %s: target host has no kvSSL port listed", hostport)
-       }
-       if portInt != kv {
-               return "", fmt.Errorf("Unable to map hostport combination %s: expected port %d but found %d", hostport, portInt, kv)
-       }
-       return fmt.Sprintf("%s:%d", host, kvSSL), nil
-}
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/streaming.go b/vendor/github.com/couchbaselabs/go-couchbase/streaming.go
deleted file mode 100644 (file)
index 6d8f7df..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-package couchbase
-
-import (
-       "encoding/json"
-       "fmt"
-       "github.com/couchbase/goutils/logging"
-       "io"
-       "io/ioutil"
-       "math/rand"
-       "net"
-       "net/http"
-       "time"
-       "unsafe"
-)
-
-// Bucket auto-updater gets the latest version of the bucket config from
-// the server. If the configuration has changed then updated the local
-// bucket information. If the bucket has been deleted then notify anyone
-// who is holding a reference to this bucket
-
-const MAX_RETRY_COUNT = 5
-const DISCONNECT_PERIOD = 120 * time.Second
-
-type NotifyFn func(bucket string, err error)
-
-// Use TCP keepalive to detect half close sockets
-var updaterTransport http.RoundTripper = &http.Transport{
-       Proxy: http.ProxyFromEnvironment,
-       Dial: (&net.Dialer{
-               Timeout:   30 * time.Second,
-               KeepAlive: 30 * time.Second,
-       }).Dial,
-}
-
-var updaterHTTPClient = &http.Client{Transport: updaterTransport}
-
-func doHTTPRequestForUpdate(req *http.Request) (*http.Response, error) {
-
-       var err error
-       var res *http.Response
-
-       for i := 0; i < HTTP_MAX_RETRY; i++ {
-               res, err = updaterHTTPClient.Do(req)
-               if err != nil && isHttpConnError(err) {
-                       continue
-               }
-               break
-       }
-
-       if err != nil {
-               return nil, err
-       }
-
-       return res, err
-}
-
-func (b *Bucket) RunBucketUpdater(notify NotifyFn) {
-       go func() {
-               err := b.UpdateBucket()
-               if err != nil {
-                       if notify != nil {
-                               notify(b.GetName(), err)
-                       }
-                       logging.Errorf(" Bucket Updater exited with err %v", err)
-               }
-       }()
-}
-
-func (b *Bucket) replaceConnPools2(with []*connectionPool, bucketLocked bool) {
-       if !bucketLocked {
-               b.Lock()
-               defer b.Unlock()
-       }
-       old := b.connPools
-       b.connPools = unsafe.Pointer(&with)
-       if old != nil {
-               for _, pool := range *(*[]*connectionPool)(old) {
-                       if pool != nil && pool.inUse == false {
-                               pool.Close()
-                       }
-               }
-       }
-       return
-}
-
-func (b *Bucket) UpdateBucket() error {
-
-       var failures int
-       var returnErr error
-
-       var poolServices PoolServices
-       var err error
-       tlsConfig := b.pool.client.tlsConfig
-       if tlsConfig != nil {
-               poolServices, err = b.pool.client.GetPoolServices("default")
-               if err != nil {
-                       return err
-               }
-       }
-
-       for {
-
-               if failures == MAX_RETRY_COUNT {
-                       logging.Errorf(" Maximum failures reached. Exiting loop...")
-                       return fmt.Errorf("Max failures reached. Last Error %v", returnErr)
-               }
-
-               nodes := b.Nodes()
-               if len(nodes) < 1 {
-                       return fmt.Errorf("No healthy nodes found")
-               }
-
-               startNode := rand.Intn(len(nodes))
-               node := nodes[(startNode)%len(nodes)]
-
-               streamUrl := fmt.Sprintf("http://%s/pools/default/bucketsStreaming/%s", node.Hostname, b.GetName())
-               logging.Infof(" Trying with %s", streamUrl)
-               req, err := http.NewRequest("GET", streamUrl, nil)
-               if err != nil {
-                       return err
-               }
-
-               // Lock here to avoid having pool closed under us.
-               b.RLock()
-               err = maybeAddAuth(req, b.pool.client.ah)
-               b.RUnlock()
-               if err != nil {
-                       return err
-               }
-
-               res, err := doHTTPRequestForUpdate(req)
-               if err != nil {
-                       return err
-               }
-
-               if res.StatusCode != 200 {
-                       bod, _ := ioutil.ReadAll(io.LimitReader(res.Body, 512))
-                       logging.Errorf("Failed to connect to host, unexpected status code: %v. Body %s", res.StatusCode, bod)
-                       res.Body.Close()
-                       returnErr = fmt.Errorf("Failed to connect to host. Status %v Body %s", res.StatusCode, bod)
-                       failures++
-                       continue
-               }
-
-               dec := json.NewDecoder(res.Body)
-
-               tmpb := &Bucket{}
-               for {
-
-                       err := dec.Decode(&tmpb)
-                       if err != nil {
-                               returnErr = err
-                               res.Body.Close()
-                               break
-                       }
-
-                       // if we got here, reset failure count
-                       failures = 0
-                       b.Lock()
-
-                       // mark all the old connection pools for deletion
-                       pools := b.getConnPools(true /* already locked */)
-                       for _, pool := range pools {
-                               if pool != nil {
-                                       pool.inUse = false
-                               }
-                       }
-
-                       newcps := make([]*connectionPool, len(tmpb.VBSMJson.ServerList))
-                       for i := range newcps {
-                               // get the old connection pool and check if it is still valid
-                               pool := b.getConnPoolByHost(tmpb.VBSMJson.ServerList[i], true /* bucket already locked */)
-                               if pool != nil && pool.inUse == false {
-                                       // if the hostname and index is unchanged then reuse this pool
-                                       newcps[i] = pool
-                                       pool.inUse = true
-                                       continue
-                               }
-                               // else create a new pool
-                               hostport := tmpb.VBSMJson.ServerList[i]
-                               if tlsConfig != nil {
-                                       hostport, err = MapKVtoSSL(hostport, &poolServices)
-                                       if err != nil {
-                                               b.Unlock()
-                                               return err
-                                       }
-                               }
-                               if b.ah != nil {
-                                       newcps[i] = newConnectionPool(hostport,
-                                               b.ah, false, PoolSize, PoolOverflow, b.pool.client.tlsConfig, b.Name)
-
-                               } else {
-                                       newcps[i] = newConnectionPool(hostport,
-                                               b.authHandler(true /* bucket already locked */),
-                                               false, PoolSize, PoolOverflow, b.pool.client.tlsConfig, b.Name)
-                               }
-                       }
-
-                       b.replaceConnPools2(newcps, true /* bucket already locked */)
-
-                       tmpb.ah = b.ah
-                       b.vBucketServerMap = unsafe.Pointer(&tmpb.VBSMJson)
-                       b.nodeList = unsafe.Pointer(&tmpb.NodesJSON)
-                       b.Unlock()
-
-                       logging.Infof("Got new configuration for bucket %s", b.GetName())
-
-               }
-               // we are here because of an error
-               failures++
-               continue
-
-       }
-       return nil
-}
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/tap.go b/vendor/github.com/couchbaselabs/go-couchbase/tap.go
deleted file mode 100644 (file)
index 86edd30..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-package couchbase
-
-import (
-       "github.com/couchbase/gomemcached/client"
-       "github.com/couchbase/goutils/logging"
-       "sync"
-       "time"
-)
-
-const initialRetryInterval = 1 * time.Second
-const maximumRetryInterval = 30 * time.Second
-
-// A TapFeed streams mutation events from a bucket.
-//
-// Events from the bucket can be read from the channel 'C'.  Remember
-// to call Close() on it when you're done, unless its channel has
-// closed itself already.
-type TapFeed struct {
-       C <-chan memcached.TapEvent
-
-       bucket    *Bucket
-       args      *memcached.TapArguments
-       nodeFeeds []*memcached.TapFeed    // The TAP feeds of the individual nodes
-       output    chan memcached.TapEvent // Same as C but writeably-typed
-       wg        sync.WaitGroup
-       quit      chan bool
-}
-
-// StartTapFeed creates and starts a new Tap feed
-func (b *Bucket) StartTapFeed(args *memcached.TapArguments) (*TapFeed, error) {
-       if args == nil {
-               defaultArgs := memcached.DefaultTapArguments()
-               args = &defaultArgs
-       }
-
-       feed := &TapFeed{
-               bucket: b,
-               args:   args,
-               output: make(chan memcached.TapEvent, 10),
-               quit:   make(chan bool),
-       }
-
-       go feed.run()
-
-       feed.C = feed.output
-       return feed, nil
-}
-
-// Goroutine that runs the feed
-func (feed *TapFeed) run() {
-       retryInterval := initialRetryInterval
-       bucketOK := true
-       for {
-               // Connect to the TAP feed of each server node:
-               if bucketOK {
-                       killSwitch, err := feed.connectToNodes()
-                       if err == nil {
-                               // Run until one of the sub-feeds fails:
-                               select {
-                               case <-killSwitch:
-                               case <-feed.quit:
-                                       return
-                               }
-                               feed.closeNodeFeeds()
-                               retryInterval = initialRetryInterval
-                       }
-               }
-
-               // On error, try to refresh the bucket in case the list of nodes changed:
-               logging.Infof("go-couchbase: TAP connection lost; reconnecting to bucket %q in %v",
-                       feed.bucket.Name, retryInterval)
-               err := feed.bucket.Refresh()
-               bucketOK = err == nil
-
-               select {
-               case <-time.After(retryInterval):
-               case <-feed.quit:
-                       return
-               }
-               if retryInterval *= 2; retryInterval > maximumRetryInterval {
-                       retryInterval = maximumRetryInterval
-               }
-       }
-}
-
-func (feed *TapFeed) connectToNodes() (killSwitch chan bool, err error) {
-       killSwitch = make(chan bool)
-       for _, serverConn := range feed.bucket.getConnPools(false /* not already locked */) {
-               var singleFeed *memcached.TapFeed
-               singleFeed, err = serverConn.StartTapFeed(feed.args)
-               if err != nil {
-                       logging.Errorf("go-couchbase: Error connecting to tap feed of %s: %v", serverConn.host, err)
-                       feed.closeNodeFeeds()
-                       return
-               }
-               feed.nodeFeeds = append(feed.nodeFeeds, singleFeed)
-               go feed.forwardTapEvents(singleFeed, killSwitch, serverConn.host)
-               feed.wg.Add(1)
-       }
-       return
-}
-
-// Goroutine that forwards Tap events from a single node's feed to the aggregate feed.
-func (feed *TapFeed) forwardTapEvents(singleFeed *memcached.TapFeed, killSwitch chan bool, host string) {
-       defer feed.wg.Done()
-       for {
-               select {
-               case event, ok := <-singleFeed.C:
-                       if !ok {
-                               if singleFeed.Error != nil {
-                                       logging.Errorf("go-couchbase: Tap feed from %s failed: %v", host, singleFeed.Error)
-                               }
-                               killSwitch <- true
-                               return
-                       }
-                       feed.output <- event
-               case <-feed.quit:
-                       return
-               }
-       }
-}
-
-func (feed *TapFeed) closeNodeFeeds() {
-       for _, f := range feed.nodeFeeds {
-               f.Close()
-       }
-       feed.nodeFeeds = nil
-}
-
-// Close a Tap feed.
-func (feed *TapFeed) Close() error {
-       select {
-       case <-feed.quit:
-               return nil
-       default:
-       }
-
-       feed.closeNodeFeeds()
-       close(feed.quit)
-       feed.wg.Wait()
-       close(feed.output)
-       return nil
-}
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/upr.go b/vendor/github.com/couchbaselabs/go-couchbase/upr.go
deleted file mode 100644 (file)
index bf1b209..0000000
+++ /dev/null
@@ -1,398 +0,0 @@
-package couchbase
-
-import (
-       "log"
-       "sync"
-       "time"
-
-       "fmt"
-       "github.com/couchbase/gomemcached"
-       "github.com/couchbase/gomemcached/client"
-       "github.com/couchbase/goutils/logging"
-)
-
-// A UprFeed streams mutation events from a bucket.
-//
-// Events from the bucket can be read from the channel 'C'.  Remember
-// to call Close() on it when you're done, unless its channel has
-// closed itself already.
-type UprFeed struct {
-       C <-chan *memcached.UprEvent
-
-       bucket          *Bucket
-       nodeFeeds       map[string]*FeedInfo     // The UPR feeds of the individual nodes
-       output          chan *memcached.UprEvent // Same as C but writeably-typed
-       outputClosed    bool
-       quit            chan bool
-       name            string // name of this UPR feed
-       sequence        uint32 // sequence number for this feed
-       connected       bool
-       killSwitch      chan bool
-       closing         bool
-       wg              sync.WaitGroup
-       dcp_buffer_size uint32
-       data_chan_size  int
-}
-
-// UprFeed from a single connection
-type FeedInfo struct {
-       uprFeed   *memcached.UprFeed // UPR feed handle
-       host      string             // hostname
-       connected bool               // connected
-       quit      chan bool          // quit channel
-}
-
-type FailoverLog map[uint16]memcached.FailoverLog
-
-// GetFailoverLogs, get the failover logs for a set of vbucket ids
-func (b *Bucket) GetFailoverLogs(vBuckets []uint16) (FailoverLog, error) {
-
-       // map vbids to their corresponding hosts
-       vbHostList := make(map[string][]uint16)
-       vbm := b.VBServerMap()
-       if len(vbm.VBucketMap) < len(vBuckets) {
-               return nil, fmt.Errorf("vbmap smaller than vbucket list: %v vs. %v",
-                       vbm.VBucketMap, vBuckets)
-       }
-
-       for _, vb := range vBuckets {
-               masterID := vbm.VBucketMap[vb][0]
-               master := b.getMasterNode(masterID)
-               if master == "" {
-                       return nil, fmt.Errorf("No master found for vb %d", vb)
-               }
-
-               vbList := vbHostList[master]
-               if vbList == nil {
-                       vbList = make([]uint16, 0)
-               }
-               vbList = append(vbList, vb)
-               vbHostList[master] = vbList
-       }
-
-       failoverLogMap := make(FailoverLog)
-       for _, serverConn := range b.getConnPools(false /* not already locked */) {
-
-               vbList := vbHostList[serverConn.host]
-               if vbList == nil {
-                       continue
-               }
-
-               mc, err := serverConn.Get()
-               if err != nil {
-                       logging.Infof("No Free connections for vblist %v", vbList)
-                       return nil, fmt.Errorf("No Free connections for host %s",
-                               serverConn.host)
-
-               }
-               // close the connection so that it doesn't get reused for upr data
-               // connection
-               defer mc.Close()
-               failoverlogs, err := mc.UprGetFailoverLog(vbList)
-               if err != nil {
-                       return nil, fmt.Errorf("Error getting failover log %s host %s",
-                               err.Error(), serverConn.host)
-
-               }
-
-               for vb, log := range failoverlogs {
-                       failoverLogMap[vb] = *log
-               }
-       }
-
-       return failoverLogMap, nil
-}
-
-func (b *Bucket) StartUprFeed(name string, sequence uint32) (*UprFeed, error) {
-       return b.StartUprFeedWithConfig(name, sequence, 10, DEFAULT_WINDOW_SIZE)
-}
-
-// StartUprFeed creates and starts a new Upr feed
-// No data will be sent on the channel unless vbuckets streams are requested
-func (b *Bucket) StartUprFeedWithConfig(name string, sequence uint32, data_chan_size int, dcp_buffer_size uint32) (*UprFeed, error) {
-
-       feed := &UprFeed{
-               bucket:          b,
-               output:          make(chan *memcached.UprEvent, data_chan_size),
-               quit:            make(chan bool),
-               nodeFeeds:       make(map[string]*FeedInfo, 0),
-               name:            name,
-               sequence:        sequence,
-               killSwitch:      make(chan bool),
-               dcp_buffer_size: dcp_buffer_size,
-               data_chan_size:  data_chan_size,
-       }
-
-       err := feed.connectToNodes()
-       if err != nil {
-               return nil, fmt.Errorf("Cannot connect to bucket %s", err.Error())
-       }
-       feed.connected = true
-       go feed.run()
-
-       feed.C = feed.output
-       return feed, nil
-}
-
-// UprRequestStream starts a stream for a vb on a feed
-func (feed *UprFeed) UprRequestStream(vb uint16, opaque uint16, flags uint32,
-       vuuid, startSequence, endSequence, snapStart, snapEnd uint64) error {
-
-       defer func() {
-               if r := recover(); r != nil {
-                       log.Panicf("Panic in UprRequestStream. Feed %v Bucket %v", feed, feed.bucket)
-               }
-       }()
-
-       vbm := feed.bucket.VBServerMap()
-       if len(vbm.VBucketMap) < int(vb) {
-               return fmt.Errorf("vbmap smaller than vbucket list: %v vs. %v",
-                       vb, vbm.VBucketMap)
-       }
-
-       if int(vb) >= len(vbm.VBucketMap) {
-               return fmt.Errorf("Invalid vbucket id %d", vb)
-       }
-
-       masterID := vbm.VBucketMap[vb][0]
-       master := feed.bucket.getMasterNode(masterID)
-       if master == "" {
-               return fmt.Errorf("Master node not found for vbucket %d", vb)
-       }
-       singleFeed := feed.nodeFeeds[master]
-       if singleFeed == nil {
-               return fmt.Errorf("UprFeed for this host not found")
-       }
-
-       if err := singleFeed.uprFeed.UprRequestStream(vb, opaque, flags,
-               vuuid, startSequence, endSequence, snapStart, snapEnd); err != nil {
-               return err
-       }
-
-       return nil
-}
-
-// UprCloseStream ends a vbucket stream.
-func (feed *UprFeed) UprCloseStream(vb, opaqueMSB uint16) error {
-
-       defer func() {
-               if r := recover(); r != nil {
-                       log.Panicf("Panic in UprCloseStream. Feed %v Bucket %v ", feed, feed.bucket)
-               }
-       }()
-
-       vbm := feed.bucket.VBServerMap()
-       if len(vbm.VBucketMap) < int(vb) {
-               return fmt.Errorf("vbmap smaller than vbucket list: %v vs. %v",
-                       vb, vbm.VBucketMap)
-       }
-
-       if int(vb) >= len(vbm.VBucketMap) {
-               return fmt.Errorf("Invalid vbucket id %d", vb)
-       }
-
-       masterID := vbm.VBucketMap[vb][0]
-       master := feed.bucket.getMasterNode(masterID)
-       if master == "" {
-               return fmt.Errorf("Master node not found for vbucket %d", vb)
-       }
-       singleFeed := feed.nodeFeeds[master]
-       if singleFeed == nil {
-               return fmt.Errorf("UprFeed for this host not found")
-       }
-
-       if err := singleFeed.uprFeed.CloseStream(vb, opaqueMSB); err != nil {
-               return err
-       }
-       return nil
-}
-
-// Goroutine that runs the feed
-func (feed *UprFeed) run() {
-       retryInterval := initialRetryInterval
-       bucketOK := true
-       for {
-               // Connect to the UPR feed of each server node:
-               if bucketOK {
-                       // Run until one of the sub-feeds fails:
-                       select {
-                       case <-feed.killSwitch:
-                       case <-feed.quit:
-                               return
-                       }
-                       //feed.closeNodeFeeds()
-                       retryInterval = initialRetryInterval
-               }
-
-               if feed.closing == true {
-                       // we have been asked to shut down
-                       return
-               }
-
-               // On error, try to refresh the bucket in case the list of nodes changed:
-               logging.Infof("go-couchbase: UPR connection lost; reconnecting to bucket %q in %v",
-                       feed.bucket.Name, retryInterval)
-
-               if err := feed.bucket.Refresh(); err != nil {
-                       // if we fail to refresh the bucket, exit the feed
-                       // MB-14917
-                       logging.Infof("Unable to refresh bucket %s ", err.Error())
-                       close(feed.output)
-                       feed.outputClosed = true
-                       feed.closeNodeFeeds()
-                       return
-               }
-
-               // this will only connect to nodes that are not connected or changed
-               // user will have to reconnect the stream
-               err := feed.connectToNodes()
-               if err != nil {
-                       logging.Infof("Unable to connect to nodes..exit ")
-                       close(feed.output)
-                       feed.outputClosed = true
-                       feed.closeNodeFeeds()
-                       return
-               }
-               bucketOK = err == nil
-
-               select {
-               case <-time.After(retryInterval):
-               case <-feed.quit:
-                       return
-               }
-               if retryInterval *= 2; retryInterval > maximumRetryInterval {
-                       retryInterval = maximumRetryInterval
-               }
-       }
-}
-
-func (feed *UprFeed) connectToNodes() (err error) {
-       nodeCount := 0
-       for _, serverConn := range feed.bucket.getConnPools(false /* not already locked */) {
-
-               // this maybe a reconnection, so check if the connection to the node
-               // already exists. Connect only if the node is not found in the list
-               // or connected == false
-               nodeFeed := feed.nodeFeeds[serverConn.host]
-
-               if nodeFeed != nil && nodeFeed.connected == true {
-                       continue
-               }
-
-               var singleFeed *memcached.UprFeed
-               var name string
-               if feed.name == "" {
-                       name = "DefaultUprClient"
-               } else {
-                       name = feed.name
-               }
-               singleFeed, err = serverConn.StartUprFeed(name, feed.sequence, feed.dcp_buffer_size, feed.data_chan_size)
-               if err != nil {
-                       logging.Errorf("go-couchbase: Error connecting to upr feed of %s: %v", serverConn.host, err)
-                       feed.closeNodeFeeds()
-                       return
-               }
-               // add the node to the connection map
-               feedInfo := &FeedInfo{
-                       uprFeed:   singleFeed,
-                       connected: true,
-                       host:      serverConn.host,
-                       quit:      make(chan bool),
-               }
-               feed.nodeFeeds[serverConn.host] = feedInfo
-               go feed.forwardUprEvents(feedInfo, feed.killSwitch, serverConn.host)
-               feed.wg.Add(1)
-               nodeCount++
-       }
-       if nodeCount == 0 {
-               return fmt.Errorf("No connection to bucket")
-       }
-
-       return nil
-}
-
-// Goroutine that forwards Upr events from a single node's feed to the aggregate feed.
-func (feed *UprFeed) forwardUprEvents(nodeFeed *FeedInfo, killSwitch chan bool, host string) {
-       singleFeed := nodeFeed.uprFeed
-
-       defer func() {
-               feed.wg.Done()
-               if r := recover(); r != nil {
-                       //if feed is not closing, re-throw the panic
-                       if feed.outputClosed != true && feed.closing != true {
-                               panic(r)
-                       } else {
-                               logging.Errorf("Panic is recovered. Since feed is closed, exit gracefully")
-
-                       }
-               }
-       }()
-
-       for {
-               select {
-               case <-nodeFeed.quit:
-                       nodeFeed.connected = false
-                       return
-
-               case event, ok := <-singleFeed.C:
-                       if !ok {
-                               if singleFeed.Error != nil {
-                                       logging.Errorf("go-couchbase: Upr feed from %s failed: %v", host, singleFeed.Error)
-                               }
-                               killSwitch <- true
-                               return
-                       }
-                       if feed.outputClosed == true {
-                               // someone closed the node feed
-                               logging.Infof("Node need closed, returning from forwardUprEvent")
-                               return
-                       }
-                       feed.output <- event
-                       if event.Status == gomemcached.NOT_MY_VBUCKET {
-                               logging.Infof(" Got a not my vbucket error !! ")
-                               if err := feed.bucket.Refresh(); err != nil {
-                                       logging.Errorf("Unable to refresh bucket %s ", err.Error())
-                                       feed.closeNodeFeeds()
-                                       return
-                               }
-                               // this will only connect to nodes that are not connected or changed
-                               // user will have to reconnect the stream
-                               if err := feed.connectToNodes(); err != nil {
-                                       logging.Errorf("Unable to connect to nodes %s", err.Error())
-                                       return
-                               }
-
-                       }
-               }
-       }
-}
-
-func (feed *UprFeed) closeNodeFeeds() {
-       for _, f := range feed.nodeFeeds {
-               logging.Infof(" Sending close to forwardUprEvent ")
-               close(f.quit)
-               f.uprFeed.Close()
-       }
-       feed.nodeFeeds = nil
-}
-
-// Close a Upr feed.
-func (feed *UprFeed) Close() error {
-       select {
-       case <-feed.quit:
-               return nil
-       default:
-       }
-
-       feed.closing = true
-       feed.closeNodeFeeds()
-       close(feed.quit)
-
-       feed.wg.Wait()
-       if feed.outputClosed == false {
-               feed.outputClosed = true
-               close(feed.output)
-       }
-
-       return nil
-}
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/users.go b/vendor/github.com/couchbaselabs/go-couchbase/users.go
deleted file mode 100644 (file)
index 47d4861..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-package couchbase
-
-import (
-       "bytes"
-       "fmt"
-)
-
-type User struct {
-       Name   string
-       Id     string
-       Domain string
-       Roles  []Role
-}
-
-type Role struct {
-       Role       string
-       BucketName string `json:"bucket_name"`
-}
-
-// Sample:
-// {"role":"admin","name":"Admin","desc":"Can manage ALL cluster features including security.","ce":true}
-// {"role":"query_select","bucket_name":"*","name":"Query Select","desc":"Can execute SELECT statement on bucket to retrieve data"}
-type RoleDescription struct {
-       Role       string
-       Name       string
-       Desc       string
-       Ce         bool
-       BucketName string `json:"bucket_name"`
-}
-
-// Return user-role data, as parsed JSON.
-// Sample:
-//   [{"id":"ivanivanov","name":"Ivan Ivanov","roles":[{"role":"cluster_admin"},{"bucket_name":"default","role":"bucket_admin"}]},
-//    {"id":"petrpetrov","name":"Petr Petrov","roles":[{"role":"replication_admin"}]}]
-func (c *Client) GetUserRoles() ([]interface{}, error) {
-       ret := make([]interface{}, 0, 1)
-       err := c.parseURLResponse("/settings/rbac/users", &ret)
-       if err != nil {
-               return nil, err
-       }
-
-       // Get the configured administrator.
-       // Expected result: {"port":8091,"username":"Administrator"}
-       adminInfo := make(map[string]interface{}, 2)
-       err = c.parseURLResponse("/settings/web", &adminInfo)
-       if err != nil {
-               return nil, err
-       }
-
-       // Create a special entry for the configured administrator.
-       adminResult := map[string]interface{}{
-               "name":   adminInfo["username"],
-               "id":     adminInfo["username"],
-               "domain": "ns_server",
-               "roles": []interface{}{
-                       map[string]interface{}{
-                               "role": "admin",
-                       },
-               },
-       }
-
-       // Add the configured administrator to the list of results.
-       ret = append(ret, adminResult)
-
-       return ret, nil
-}
-
-func (c *Client) GetUserInfoAll() ([]User, error) {
-       ret := make([]User, 0, 16)
-       err := c.parseURLResponse("/settings/rbac/users", &ret)
-       if err != nil {
-               return nil, err
-       }
-       return ret, nil
-}
-
-func rolesToParamFormat(roles []Role) string {
-       var buffer bytes.Buffer
-       for i, role := range roles {
-               if i > 0 {
-                       buffer.WriteString(",")
-               }
-               buffer.WriteString(role.Role)
-               if role.BucketName != "" {
-                       buffer.WriteString("[")
-                       buffer.WriteString(role.BucketName)
-                       buffer.WriteString("]")
-               }
-       }
-       return buffer.String()
-}
-
-func (c *Client) PutUserInfo(u *User) error {
-       params := map[string]interface{}{
-               "name":  u.Name,
-               "roles": rolesToParamFormat(u.Roles),
-       }
-       var target string
-       switch u.Domain {
-       case "external":
-               target = "/settings/rbac/users/" + u.Id
-       case "local":
-               target = "/settings/rbac/users/local/" + u.Id
-       default:
-               return fmt.Errorf("Unknown user type: %s", u.Domain)
-       }
-       var ret string // PUT returns an empty string. We ignore it.
-       err := c.parsePutURLResponse(target, params, &ret)
-       return err
-}
-
-func (c *Client) GetRolesAll() ([]RoleDescription, error) {
-       ret := make([]RoleDescription, 0, 32)
-       err := c.parseURLResponse("/settings/rbac/roles", &ret)
-       if err != nil {
-               return nil, err
-       }
-       return ret, nil
-}
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/util.go b/vendor/github.com/couchbaselabs/go-couchbase/util.go
deleted file mode 100644 (file)
index 4d286a3..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-package couchbase
-
-import (
-       "fmt"
-       "net/url"
-       "strings"
-)
-
-// CleanupHost returns the hostname with the given suffix removed.
-func CleanupHost(h, commonSuffix string) string {
-       if strings.HasSuffix(h, commonSuffix) {
-               return h[:len(h)-len(commonSuffix)]
-       }
-       return h
-}
-
-// FindCommonSuffix returns the longest common suffix from the given
-// strings.
-func FindCommonSuffix(input []string) string {
-       rv := ""
-       if len(input) < 2 {
-               return ""
-       }
-       from := input
-       for i := len(input[0]); i > 0; i-- {
-               common := true
-               suffix := input[0][i:]
-               for _, s := range from {
-                       if !strings.HasSuffix(s, suffix) {
-                               common = false
-                               break
-                       }
-               }
-               if common {
-                       rv = suffix
-               }
-       }
-       return rv
-}
-
-// ParseURL is a wrapper around url.Parse with some sanity-checking
-func ParseURL(urlStr string) (result *url.URL, err error) {
-       result, err = url.Parse(urlStr)
-       if result != nil && result.Scheme == "" {
-               result = nil
-               err = fmt.Errorf("invalid URL <%s>", urlStr)
-       }
-       return
-}
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/vbmap.go b/vendor/github.com/couchbaselabs/go-couchbase/vbmap.go
deleted file mode 100644 (file)
index b96a18e..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-package couchbase
-
-var crc32tab = []uint32{
-       0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
-       0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
-       0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
-       0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
-       0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
-       0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
-       0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
-       0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
-       0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
-       0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
-       0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
-       0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
-       0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
-       0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
-       0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
-       0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
-       0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
-       0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
-       0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
-       0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
-       0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
-       0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
-       0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
-       0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
-       0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
-       0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
-       0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
-       0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
-       0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
-       0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
-       0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
-       0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
-       0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
-       0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
-       0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
-       0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
-       0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
-       0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
-       0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
-       0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
-       0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
-       0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
-       0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
-       0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
-       0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
-       0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
-       0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
-       0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
-       0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
-       0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
-       0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
-       0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
-       0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
-       0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
-       0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
-       0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
-       0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
-       0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
-       0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
-       0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
-       0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
-       0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
-       0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
-       0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}
-
-// VBHash finds the vbucket for the given key.
-func (b *Bucket) VBHash(key string) uint32 {
-       crc := uint32(0xffffffff)
-       for x := 0; x < len(key); x++ {
-               crc = (crc >> 8) ^ crc32tab[(uint64(crc)^uint64(key[x]))&0xff]
-       }
-       vbm := b.VBServerMap()
-       return ((^crc) >> 16) & 0x7fff & (uint32(len(vbm.VBucketMap)) - 1)
-}
diff --git a/vendor/github.com/couchbaselabs/go-couchbase/views.go b/vendor/github.com/couchbaselabs/go-couchbase/views.go
deleted file mode 100644 (file)
index 2f68642..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-package couchbase
-
-import (
-       "encoding/json"
-       "errors"
-       "fmt"
-       "io/ioutil"
-       "math/rand"
-       "net/http"
-       "net/url"
-       "time"
-)
-
-// ViewRow represents a single result from a view.
-//
-// Doc is present only if include_docs was set on the request.
-type ViewRow struct {
-       ID    string
-       Key   interface{}
-       Value interface{}
-       Doc   *interface{}
-}
-
-// A ViewError is a node-specific error indicating a partial failure
-// within a view result.
-type ViewError struct {
-       From   string
-       Reason string
-}
-
-func (ve ViewError) Error() string {
-       return "Node: " + ve.From + ", reason: " + ve.Reason
-}
-
-// ViewResult holds the entire result set from a view request,
-// including the rows and the errors.
-type ViewResult struct {
-       TotalRows int `json:"total_rows"`
-       Rows      []ViewRow
-       Errors    []ViewError
-}
-
-func (b *Bucket) randomBaseURL() (*url.URL, error) {
-       nodes := b.HealthyNodes()
-       if len(nodes) == 0 {
-               return nil, errors.New("no available couch rest URLs")
-       }
-       nodeNo := rand.Intn(len(nodes))
-       node := nodes[nodeNo]
-
-       b.RLock()
-       name := b.Name
-       pool := b.pool
-       b.RUnlock()
-
-       u, err := ParseURL(node.CouchAPIBase)
-       if err != nil {
-               return nil, fmt.Errorf("config error: Bucket %q node #%d CouchAPIBase=%q: %v",
-                       name, nodeNo, node.CouchAPIBase, err)
-       } else if pool != nil {
-               u.User = pool.client.BaseURL.User
-       }
-       return u, err
-}
-
-const START_NODE_ID = -1
-
-func (b *Bucket) randomNextURL(lastNode int) (*url.URL, int, error) {
-       nodes := b.HealthyNodes()
-       if len(nodes) == 0 {
-               return nil, -1, errors.New("no available couch rest URLs")
-       }
-
-       var nodeNo int
-       if lastNode == START_NODE_ID || lastNode >= len(nodes) {
-               // randomly select a node if the value of lastNode is invalid
-               nodeNo = rand.Intn(len(nodes))
-       } else {
-               // wrap around the node list
-               nodeNo = (lastNode + 1) % len(nodes)
-       }
-
-       b.RLock()
-       name := b.Name
-       pool := b.pool
-       b.RUnlock()
-
-       node := nodes[nodeNo]
-       u, err := ParseURL(node.CouchAPIBase)
-       if err != nil {
-               return nil, -1, fmt.Errorf("config error: Bucket %q node #%d CouchAPIBase=%q: %v",
-                       name, nodeNo, node.CouchAPIBase, err)
-       } else if pool != nil {
-               u.User = pool.client.BaseURL.User
-       }
-       return u, nodeNo, err
-}
-
-// DocID is the document ID type for the startkey_docid parameter in
-// views.
-type DocID string
-
-func qParam(k, v string) string {
-       format := `"%s"`
-       switch k {
-       case "startkey_docid", "endkey_docid", "stale":
-               format = "%s"
-       }
-       return fmt.Sprintf(format, v)
-}
-
-// ViewURL constructs a URL for a view with the given ddoc, view name,
-// and parameters.
-func (b *Bucket) ViewURL(ddoc, name string,
-       params map[string]interface{}) (string, error) {
-       u, err := b.randomBaseURL()
-       if err != nil {
-               return "", err
-       }
-
-       values := url.Values{}
-       for k, v := range params {
-               switch t := v.(type) {
-               case DocID:
-                       values[k] = []string{string(t)}
-               case string:
-                       values[k] = []string{qParam(k, t)}
-               case int:
-                       values[k] = []string{fmt.Sprintf(`%d`, t)}
-               case bool:
-                       values[k] = []string{fmt.Sprintf(`%v`, t)}
-               default:
-                       b, err := json.Marshal(v)
-                       if err != nil {
-                               return "", fmt.Errorf("unsupported value-type %T in Query, "+
-                                       "json encoder said %v", t, err)
-                       }
-                       values[k] = []string{fmt.Sprintf(`%v`, string(b))}
-               }
-       }
-
-       if ddoc == "" && name == "_all_docs" {
-               u.Path = fmt.Sprintf("/%s/_all_docs", b.GetName())
-       } else {
-               u.Path = fmt.Sprintf("/%s/_design/%s/_view/%s", b.GetName(), ddoc, name)
-       }
-       u.RawQuery = values.Encode()
-
-       return u.String(), nil
-}
-
-// ViewCallback is called for each view invocation.
-var ViewCallback func(ddoc, name string, start time.Time, err error)
-
-// ViewCustom performs a view request that can map row values to a
-// custom type.
-//
-// See the source to View for an example usage.
-func (b *Bucket) ViewCustom(ddoc, name string, params map[string]interface{},
-       vres interface{}) (err error) {
-       if SlowServerCallWarningThreshold > 0 {
-               defer slowLog(time.Now(), "call to ViewCustom(%q, %q)", ddoc, name)
-       }
-
-       if ViewCallback != nil {
-               defer func(t time.Time) { ViewCallback(ddoc, name, t, err) }(time.Now())
-       }
-
-       u, err := b.ViewURL(ddoc, name, params)
-       if err != nil {
-               return err
-       }
-
-       req, err := http.NewRequest("GET", u, nil)
-       if err != nil {
-               return err
-       }
-
-       ah := b.authHandler(false /* bucket not yet locked */)
-       maybeAddAuth(req, ah)
-
-       res, err := doHTTPRequest(req)
-       if err != nil {
-               return fmt.Errorf("error starting view req at %v: %v", u, err)
-       }
-       defer res.Body.Close()
-
-       if res.StatusCode != 200 {
-               bod := make([]byte, 512)
-               l, _ := res.Body.Read(bod)
-               return fmt.Errorf("error executing view req at %v: %v - %s",
-                       u, res.Status, bod[:l])
-       }
-
-       body, err := ioutil.ReadAll(res.Body)
-       if err := json.Unmarshal(body, vres); err != nil {
-               return nil
-       }
-
-       return nil
-}
-
-// View executes a view.
-//
-// The ddoc parameter is just the bare name of your design doc without
-// the "_design/" prefix.
-//
-// Parameters are string keys with values that correspond to couchbase
-// view parameters.  Primitive should work fairly naturally (booleans,
-// ints, strings, etc...) and other values will attempt to be JSON
-// marshaled (useful for array indexing on on view keys, for example).
-//
-// Example:
-//
-//   res, err := couchbase.View("myddoc", "myview", map[string]interface{}{
-//       "group_level": 2,
-//       "startkey_docid":    []interface{}{"thing"},
-//       "endkey_docid":      []interface{}{"thing", map[string]string{}},
-//       "stale": false,
-//       })
-func (b *Bucket) View(ddoc, name string, params map[string]interface{}) (ViewResult, error) {
-       vres := ViewResult{}
-
-       if err := b.ViewCustom(ddoc, name, params, &vres); err != nil {
-               //error in accessing views. Retry once after a bucket refresh
-               b.Refresh()
-               return vres, b.ViewCustom(ddoc, name, params, &vres)
-       } else {
-               return vres, nil
-       }
-}
index ea3e5108270c75aec7d3ecacadf9cc3d96f54200..07f7285f087804596d2d149d757591948fc9c033 100644 (file)
@@ -251,14 +251,14 @@ For streaming use a simple setup could look like this:
 import "github.com/klauspost/compress/zstd"
 
 func Decompress(in io.Reader, out io.Writer) error {
-    d, err := zstd.NewReader(input)
+    d, err := zstd.NewReader(in)
     if err != nil {
         return err
     }
     defer d.Close()
     
     // Copy content...
-    _, err := io.Copy(out, d)
+    _, err = io.Copy(out, d)
     return err
 }
 ```
diff --git a/vendor/github.com/lunny/log/.gitignore b/vendor/github.com/lunny/log/.gitignore
deleted file mode 100644 (file)
index 3a11644..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-log.db
-*.log
-logs
-.vscode
\ No newline at end of file
diff --git a/vendor/github.com/lunny/log/LICENSE b/vendor/github.com/lunny/log/LICENSE
deleted file mode 100644 (file)
index c9338f8..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2014 - 2016 lunny
-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 the {organization} 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 HOLDER 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/github.com/lunny/log/README.md b/vendor/github.com/lunny/log/README.md
deleted file mode 100644 (file)
index da21fa4..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-## log
-[![GoDoc](https://godoc.org/github.com/lunny/log?status.png)](https://godoc.org/github.com/lunny/log)
-
-[简体中文](https://github.com/lunny/log/blob/master/README_CN.md)
-
-# Installation
-
-```
-go get github.com/lunny/log
-```
-
-# Features
-
-* Add color support for unix console
-* Implemented dbwriter to save log to database
-* Implemented FileWriter to save log to file by date or time.
-* Location configuration
-
-# Example
-
-For Single File:
-```Go
-f, _ := os.Create("my.log")
-log.Std.SetOutput(f)
-```
-
-For Multiple Writer:
-```Go
-f, _ := os.Create("my.log")
-log.Std.SetOutput(io.MultiWriter(f, os.Stdout))
-```
-
-For log files by date or time:
-```Go
-w := log.NewFileWriter(log.FileOptions{
-    ByType:log.ByDay,
-    Dir:"./logs",
-})
-log.Std.SetOutput(w)
-```
-
-# About
-
-This repo is an extension of Golang log.
-
-# LICENSE
-
- BSD License
- [http://creativecommons.org/licenses/BSD/](http://creativecommons.org/licenses/BSD/)
diff --git a/vendor/github.com/lunny/log/README_CN.md b/vendor/github.com/lunny/log/README_CN.md
deleted file mode 100644 (file)
index 0fc7db5..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-## log
-[![GoDoc](https://godoc.org/github.com/lunny/log?status.png)](https://godoc.org/github.com/lunny/log)
-
-[English](https://github.com/lunny/log/blob/master/README.md)
-
-# 安装
-
-```
-go get github.com/lunny/log
-```
-
-# 特性
-
-* 对unix增加控制台颜色支持
-* 实现了保存log到数据库支持
-* 实现了保存log到按日期的文件支持
-* 实现了设置日期的地区
-
-# 例子
-
-保存到单个文件:
-
-```Go
-f, _ := os.Create("my.log")
-log.Std.SetOutput(f)
-```
-
-保存到数据库:
-
-```Go
-f, _ := os.Create("my.log")
-log.Std.SetOutput(io.MultiWriter(f, os.Stdout))
-```
-
-保存到按时间分隔的文件:
-
-```Go
-w := log.NewFileWriter(log.FileOptions{
-    ByType:log.ByDay,
-    Dir:"./logs",
-})
-log.Std.SetOutput(w)
-```
-
-# 关于
-
-本 Log 是在 golang 的 log 之上的扩展
-
-# LICENSE
-
- BSD License
- [http://creativecommons.org/licenses/BSD/](http://creativecommons.org/licenses/BSD/)
diff --git a/vendor/github.com/lunny/log/dbwriter.go b/vendor/github.com/lunny/log/dbwriter.go
deleted file mode 100644 (file)
index e8ff00b..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-package log
-
-import (
-       "database/sql"
-       "time"
-)
-
-type DBWriter struct {
-       db      *sql.DB
-       stmt    *sql.Stmt
-       content chan []byte
-}
-
-func NewDBWriter(db *sql.DB) (*DBWriter, error) {
-       _, err := db.Exec("CREATE TABLE IF NOT EXISTS log (id int, content text, created datetime)")
-       if err != nil {
-               return nil, err
-       }
-       stmt, err := db.Prepare("INSERT INTO log (content, created) values (?, ?)")
-       if err != nil {
-               return nil, err
-       }
-       return &DBWriter{db, stmt, make(chan []byte, 1000)}, nil
-}
-
-func (w *DBWriter) Write(p []byte) (n int, err error) {
-       _, err = w.stmt.Exec(string(p), time.Now())
-       if err == nil {
-               n = len(p)
-       }
-       return
-}
-
-func (w *DBWriter) Close() {
-       w.stmt.Close()
-}
diff --git a/vendor/github.com/lunny/log/filewriter.go b/vendor/github.com/lunny/log/filewriter.go
deleted file mode 100644 (file)
index f0bb4d1..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-package log
-
-import (
-       "io"
-       "os"
-       "path/filepath"
-       "sync"
-       "time"
-)
-
-var _ io.Writer = &Files{}
-
-type ByType int
-
-const (
-       ByDay ByType = iota
-       ByHour
-       ByMonth
-)
-
-var (
-       formats = map[ByType]string{
-               ByDay:   "2006-01-02",
-               ByHour:  "2006-01-02-15",
-               ByMonth: "2006-01",
-       }
-)
-
-func SetFileFormat(t ByType, format string) {
-       formats[t] = format
-}
-
-func (b ByType) Format() string {
-       return formats[b]
-}
-
-type Files struct {
-       FileOptions
-       f          *os.File
-       lastFormat string
-       lock       sync.Mutex
-}
-
-type FileOptions struct {
-       Dir    string
-       ByType ByType
-       Loc    *time.Location
-}
-
-func prepareFileOption(opts []FileOptions) FileOptions {
-       var opt FileOptions
-       if len(opts) > 0 {
-               opt = opts[0]
-       }
-       if opt.Dir == "" {
-               opt.Dir = "./"
-       }
-       err := os.MkdirAll(opt.Dir, os.ModePerm)
-       if err != nil {
-               panic(err.Error())
-       }
-
-       if opt.Loc == nil {
-               opt.Loc = time.Local
-       }
-       return opt
-}
-
-func NewFileWriter(opts ...FileOptions) *Files {
-       opt := prepareFileOption(opts)
-       return &Files{
-               FileOptions: opt,
-       }
-}
-
-func (f *Files) getFile() (*os.File, error) {
-       var err error
-       t := time.Now().In(f.Loc)
-       if f.f == nil {
-               f.lastFormat = t.Format(f.ByType.Format())
-               f.f, err = os.OpenFile(filepath.Join(f.Dir, f.lastFormat+".log"),
-                       os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
-               return f.f, err
-       }
-       if f.lastFormat != t.Format(f.ByType.Format()) {
-               f.f.Close()
-               f.lastFormat = t.Format(f.ByType.Format())
-               f.f, err = os.OpenFile(filepath.Join(f.Dir, f.lastFormat+".log"),
-                       os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
-               return f.f, err
-       }
-       return f.f, nil
-}
-
-func (f *Files) Write(bs []byte) (int, error) {
-       f.lock.Lock()
-       defer f.lock.Unlock()
-
-       w, err := f.getFile()
-       if err != nil {
-               return 0, err
-       }
-       return w.Write(bs)
-}
-
-func (f *Files) Close() {
-       if f.f != nil {
-               f.f.Close()
-               f.f = nil
-       }
-       f.lastFormat = ""
-}
diff --git a/vendor/github.com/lunny/log/logext.go b/vendor/github.com/lunny/log/logext.go
deleted file mode 100644 (file)
index 215c45f..0000000
+++ /dev/null
@@ -1,595 +0,0 @@
-package log
-
-import (
-       "bytes"
-       "fmt"
-       "io"
-       "os"
-       "runtime"
-       "strings"
-       "sync"
-       "time"
-)
-
-// These flags define which text to prefix to each log entry generated by the Logger.
-const (
-       // Bits or'ed together to control what's printed. There is no control over the
-       // order they appear (the order listed here) or the format they present (as
-       // described in the comments).  A colon appears after these items:
-       //      2009/0123 01:23:23.123123 /a/b/c/d.go:23: message
-       Ldate         = 1 << iota     // the date: 2009/0123
-       Ltime                         // the time: 01:23:23
-       Lmicroseconds                 // microsecond resolution: 01:23:23.123123.  assumes Ltime.
-       Llongfile                     // full file name and line number: /a/b/c/d.go:23
-       Lshortfile                    // final file name element and line number: d.go:23. overrides Llongfile
-       Lmodule                       // module name
-       Llevel                        // level: 0(Debug), 1(Info), 2(Warn), 3(Error), 4(Panic), 5(Fatal)
-       Llongcolor                    // color will start [info] end of line
-       Lshortcolor                   // color only include [info]
-       LstdFlags     = Ldate | Ltime // initial values for the standard logger
-       //Ldefault      = Llevel | LstdFlags | Lshortfile | Llongcolor
-) // [prefix][time][level][module][shortfile|longfile]
-
-func Ldefault() int {
-       if runtime.GOOS == "windows" {
-               return Llevel | LstdFlags | Lshortfile
-       }
-       return Llevel | LstdFlags | Lshortfile | Llongcolor
-}
-
-func Version() string {
-       return "0.2.0.1121"
-}
-
-const (
-       Lall = iota
-)
-const (
-       Ldebug = iota
-       Linfo
-       Lwarn
-       Lerror
-       Lpanic
-       Lfatal
-       Lnone
-)
-
-const (
-       ForeBlack  = iota + 30 //30
-       ForeRed                //31
-       ForeGreen              //32
-       ForeYellow             //33
-       ForeBlue               //34
-       ForePurple             //35
-       ForeCyan               //36
-       ForeWhite              //37
-)
-
-const (
-       BackBlack  = iota + 40 //40
-       BackRed                //41
-       BackGreen              //42
-       BackYellow             //43
-       BackBlue               //44
-       BackPurple             //45
-       BackCyan               //46
-       BackWhite              //47
-)
-
-var levels = []string{
-       "[Debug]",
-       "[Info]",
-       "[Warn]",
-       "[Error]",
-       "[Panic]",
-       "[Fatal]",
-}
-
-// MUST called before all logs
-func SetLevels(lvs []string) {
-       levels = lvs
-}
-
-var colors = []int{
-       ForeCyan,
-       ForeGreen,
-       ForeYellow,
-       ForeRed,
-       ForePurple,
-       ForeBlue,
-}
-
-// MUST called before all logs
-func SetColors(cls []int) {
-       colors = cls
-}
-
-// A Logger represents an active logging object that generates lines of
-// output to an io.Writer.  Each logging operation makes a single call to
-// the Writer's Write method.  A Logger can be used simultaneously from
-// multiple goroutines; it guarantees to serialize access to the Writer.
-type Logger struct {
-       mu         sync.Mutex // ensures atomic writes; protects the following fields
-       prefix     string     // prefix to write at beginning of each line
-       flag       int        // properties
-       Level      int
-       out        io.Writer    // destination for output
-       buf        bytes.Buffer // for accumulating text to write
-       levelStats [6]int64
-       loc        *time.Location
-}
-
-// New creates a new Logger.   The out variable sets the
-// destination to which log data will be written.
-// The prefix appears at the beginning of each generated log line.
-// The flag argument defines the logging properties.
-func New(out io.Writer, prefix string, flag int) *Logger {
-       l := &Logger{out: out, prefix: prefix, Level: 1, flag: flag, loc: time.Local}
-       if out != os.Stdout {
-               l.flag = RmColorFlags(l.flag)
-       }
-       return l
-}
-
-var Std = New(os.Stderr, "", Ldefault())
-
-// Cheap integer to fixed-width decimal ASCII.  Give a negative width to avoid zero-padding.
-// Knows the buffer has capacity.
-func itoa(buf *bytes.Buffer, i int, wid int) {
-       var u uint = uint(i)
-       if u == 0 && wid <= 1 {
-               buf.WriteByte('0')
-               return
-       }
-
-       // Assemble decimal in reverse order.
-       var b [32]byte
-       bp := len(b)
-       for ; u > 0 || wid > 0; u /= 10 {
-               bp--
-               wid--
-               b[bp] = byte(u%10) + '0'
-       }
-
-       // avoid slicing b to avoid an allocation.
-       for bp < len(b) {
-               buf.WriteByte(b[bp])
-               bp++
-       }
-}
-
-func moduleOf(file string) string {
-       pos := strings.LastIndex(file, "/")
-       if pos != -1 {
-               pos1 := strings.LastIndex(file[:pos], "/src/")
-               if pos1 != -1 {
-                       return file[pos1+5 : pos]
-               }
-       }
-       return "UNKNOWN"
-}
-
-func (l *Logger) formatHeader(buf *bytes.Buffer, t time.Time,
-       file string, line int, lvl int, reqId string) {
-       if l.prefix != "" {
-               buf.WriteString(l.prefix)
-       }
-       if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 {
-               if l.flag&Ldate != 0 {
-                       year, month, day := t.Date()
-                       itoa(buf, year, 4)
-                       buf.WriteByte('/')
-                       itoa(buf, int(month), 2)
-                       buf.WriteByte('/')
-                       itoa(buf, day, 2)
-                       buf.WriteByte(' ')
-               }
-               if l.flag&(Ltime|Lmicroseconds) != 0 {
-                       hour, min, sec := t.Clock()
-                       itoa(buf, hour, 2)
-                       buf.WriteByte(':')
-                       itoa(buf, min, 2)
-                       buf.WriteByte(':')
-                       itoa(buf, sec, 2)
-                       if l.flag&Lmicroseconds != 0 {
-                               buf.WriteByte('.')
-                               itoa(buf, t.Nanosecond()/1e3, 6)
-                       }
-                       buf.WriteByte(' ')
-               }
-       }
-       if reqId != "" {
-               buf.WriteByte('[')
-               buf.WriteString(reqId)
-               buf.WriteByte(']')
-               buf.WriteByte(' ')
-       }
-
-       if l.flag&(Lshortcolor|Llongcolor) != 0 {
-               buf.WriteString(fmt.Sprintf("\033[1;%dm", colors[lvl]))
-       }
-       if l.flag&Llevel != 0 {
-               buf.WriteString(levels[lvl])
-               buf.WriteByte(' ')
-       }
-       if l.flag&Lshortcolor != 0 {
-               buf.WriteString("\033[0m")
-       }
-
-       if l.flag&Lmodule != 0 {
-               buf.WriteByte('[')
-               buf.WriteString(moduleOf(file))
-               buf.WriteByte(']')
-               buf.WriteByte(' ')
-       }
-       if l.flag&(Lshortfile|Llongfile) != 0 {
-               if l.flag&Lshortfile != 0 {
-                       short := file
-                       for i := len(file) - 1; i > 0; i-- {
-                               if file[i] == '/' {
-                                       short = file[i+1:]
-                                       break
-                               }
-                       }
-                       file = short
-               }
-               buf.WriteString(file)
-               buf.WriteByte(':')
-               itoa(buf, line, -1)
-               buf.WriteByte(' ')
-       }
-}
-
-// Output writes the output for a logging event.  The string s contains
-// the text to print after the prefix specified by the flags of the
-// Logger.  A newline is appended if the last character of s is not
-// already a newline.  Calldepth is used to recover the PC and is
-// provided for generality, although at the moment on all pre-defined
-// paths it will be 2.
-func (l *Logger) Output(reqId string, lvl int, calldepth int, s string) error {
-       if lvl < l.Level {
-               return nil
-       }
-       now := time.Now().In(l.loc) // get this early.
-       var file string
-       var line int
-       l.mu.Lock()
-       defer l.mu.Unlock()
-       if l.flag&(Lshortfile|Llongfile|Lmodule) != 0 {
-               // release lock while getting caller info - it's expensive.
-               l.mu.Unlock()
-               var ok bool
-               _, file, line, ok = runtime.Caller(calldepth)
-               if !ok {
-                       file = "???"
-                       line = 0
-               }
-               l.mu.Lock()
-       }
-       l.levelStats[lvl]++
-       l.buf.Reset()
-       l.formatHeader(&l.buf, now, file, line, lvl, reqId)
-       l.buf.WriteString(s)
-       if l.flag&Llongcolor != 0 {
-               l.buf.WriteString("\033[0m")
-       }
-       if len(s) > 0 && s[len(s)-1] != '\n' {
-               l.buf.WriteByte('\n')
-       }
-       _, err := l.out.Write(l.buf.Bytes())
-       return err
-}
-
-// -----------------------------------------
-
-// Printf calls l.Output to print to the logger.
-// Arguments are handled in the manner of fmt.Printf.
-func (l *Logger) Printf(format string, v ...interface{}) {
-       l.Output("", Linfo, 2, fmt.Sprintf(format, v...))
-}
-
-// Print calls l.Output to print to the logger.
-// Arguments are handled in the manner of fmt.Print.
-func (l *Logger) Print(v ...interface{}) {
-       l.Output("", Linfo, 2, fmt.Sprint(v...))
-}
-
-// Println calls l.Output to print to the logger.
-// Arguments are handled in the manner of fmt.Println.
-func (l *Logger) Println(v ...interface{}) {
-       l.Output("", Linfo, 2, fmt.Sprintln(v...))
-}
-
-// -----------------------------------------
-
-func (l *Logger) Debugf(format string, v ...interface{}) {
-       l.Output("", Ldebug, 2, fmt.Sprintf(format, v...))
-}
-
-func (l *Logger) Debug(v ...interface{}) {
-       l.Output("", Ldebug, 2, fmt.Sprintln(v...))
-}
-
-// -----------------------------------------
-func (l *Logger) Infof(format string, v ...interface{}) {
-       l.Output("", Linfo, 2, fmt.Sprintf(format, v...))
-}
-
-func (l *Logger) Info(v ...interface{}) {
-       l.Output("", Linfo, 2, fmt.Sprintln(v...))
-}
-
-// -----------------------------------------
-func (l *Logger) Warnf(format string, v ...interface{}) {
-       l.Output("", Lwarn, 2, fmt.Sprintf(format, v...))
-}
-
-func (l *Logger) Warn(v ...interface{}) {
-       l.Output("", Lwarn, 2, fmt.Sprintln(v...))
-}
-
-// -----------------------------------------
-
-func (l *Logger) Errorf(format string, v ...interface{}) {
-       l.Output("", Lerror, 2, fmt.Sprintf(format, v...))
-}
-
-func (l *Logger) Error(v ...interface{}) {
-       l.Output("", Lerror, 2, fmt.Sprintln(v...))
-}
-
-// -----------------------------------------
-
-func (l *Logger) Fatal(v ...interface{}) {
-       l.Output("", Lfatal, 2, fmt.Sprintln(v...))
-       os.Exit(1)
-}
-
-// Fatalf is equivalent to l.Printf() followed by a call to os.Exit(1).
-func (l *Logger) Fatalf(format string, v ...interface{}) {
-       l.Output("", Lfatal, 2, fmt.Sprintf(format, v...))
-       os.Exit(1)
-}
-
-// -----------------------------------------
-// Panic is equivalent to l.Print() followed by a call to panic().
-func (l *Logger) Panic(v ...interface{}) {
-       s := fmt.Sprintln(v...)
-       l.Output("", Lpanic, 2, s)
-       panic(s)
-}
-
-// Panicf is equivalent to l.Printf() followed by a call to panic().
-func (l *Logger) Panicf(format string, v ...interface{}) {
-       s := fmt.Sprintf(format, v...)
-       l.Output("", Lpanic, 2, s)
-       panic(s)
-}
-
-// -----------------------------------------
-func (l *Logger) Stack(v ...interface{}) {
-       s := fmt.Sprint(v...)
-       s += "\n"
-       buf := make([]byte, 1024*1024)
-       n := runtime.Stack(buf, true)
-       s += string(buf[:n])
-       s += "\n"
-       l.Output("", Lerror, 2, s)
-}
-
-// -----------------------------------------
-func (l *Logger) Stat() (stats []int64) {
-       l.mu.Lock()
-       v := l.levelStats
-       l.mu.Unlock()
-       return v[:]
-}
-
-// Flags returns the output flags for the logger.
-func (l *Logger) Flags() int {
-       l.mu.Lock()
-       defer l.mu.Unlock()
-       return l.flag
-}
-
-func RmColorFlags(flag int) int {
-       // for un std out, it should not show color since almost them don't support
-       if flag&Llongcolor != 0 {
-               flag = flag ^ Llongcolor
-       }
-       if flag&Lshortcolor != 0 {
-               flag = flag ^ Lshortcolor
-       }
-       return flag
-}
-
-func (l *Logger) Location() *time.Location {
-       return l.loc
-}
-
-func (l *Logger) SetLocation(loc *time.Location) {
-       l.loc = loc
-}
-
-// SetFlags sets the output flags for the logger.
-func (l *Logger) SetFlags(flag int) {
-       l.mu.Lock()
-       defer l.mu.Unlock()
-       if l.out != os.Stdout {
-               flag = RmColorFlags(flag)
-       }
-       l.flag = flag
-}
-
-// Prefix returns the output prefix for the logger.
-func (l *Logger) Prefix() string {
-       l.mu.Lock()
-       defer l.mu.Unlock()
-       return l.prefix
-}
-
-// SetPrefix sets the output prefix for the logger.
-func (l *Logger) SetPrefix(prefix string) {
-       l.mu.Lock()
-       defer l.mu.Unlock()
-       l.prefix = prefix
-}
-
-// SetOutputLevel sets the output level for the logger.
-func (l *Logger) SetOutputLevel(lvl int) {
-       l.mu.Lock()
-       defer l.mu.Unlock()
-       l.Level = lvl
-}
-
-func (l *Logger) OutputLevel() int {
-       return l.Level
-}
-
-func (l *Logger) SetOutput(w io.Writer) {
-       l.mu.Lock()
-       defer l.mu.Unlock()
-       l.out = w
-       if w != os.Stdout {
-               l.flag = RmColorFlags(l.flag)
-       }
-}
-
-// SetOutput sets the output destination for the standard logger.
-func SetOutput(w io.Writer) {
-       Std.SetOutput(w)
-}
-
-func SetLocation(loc *time.Location) {
-       Std.SetLocation(loc)
-}
-
-func Location() *time.Location {
-       return Std.Location()
-}
-
-// Flags returns the output flags for the standard logger.
-func Flags() int {
-       return Std.Flags()
-}
-
-// SetFlags sets the output flags for the standard logger.
-func SetFlags(flag int) {
-       Std.SetFlags(flag)
-}
-
-// Prefix returns the output prefix for the standard logger.
-func Prefix() string {
-       return Std.Prefix()
-}
-
-// SetPrefix sets the output prefix for the standard logger.
-func SetPrefix(prefix string) {
-       Std.SetPrefix(prefix)
-}
-
-func SetOutputLevel(lvl int) {
-       Std.SetOutputLevel(lvl)
-}
-
-func OutputLevel() int {
-       return Std.OutputLevel()
-}
-
-// -----------------------------------------
-
-// Print calls Output to print to the standard logger.
-// Arguments are handled in the manner of fmt.Print.
-func Print(v ...interface{}) {
-       Std.Output("", Linfo, 2, fmt.Sprintln(v...))
-}
-
-// Printf calls Output to print to the standard logger.
-// Arguments are handled in the manner of fmt.Printf.
-func Printf(format string, v ...interface{}) {
-       Std.Output("", Linfo, 2, fmt.Sprintf(format, v...))
-}
-
-// Println calls Output to print to the standard logger.
-// Arguments are handled in the manner of fmt.Println.
-func Println(v ...interface{}) {
-       Std.Output("", Linfo, 2, fmt.Sprintln(v...))
-}
-
-// -----------------------------------------
-
-func Debugf(format string, v ...interface{}) {
-       Std.Output("", Ldebug, 2, fmt.Sprintf(format, v...))
-}
-
-func Debug(v ...interface{}) {
-       Std.Output("", Ldebug, 2, fmt.Sprintln(v...))
-}
-
-// -----------------------------------------
-
-func Infof(format string, v ...interface{}) {
-       Std.Output("", Linfo, 2, fmt.Sprintf(format, v...))
-}
-
-func Info(v ...interface{}) {
-       Std.Output("", Linfo, 2, fmt.Sprintln(v...))
-}
-
-// -----------------------------------------
-
-func Warnf(format string, v ...interface{}) {
-       Std.Output("", Lwarn, 2, fmt.Sprintf(format, v...))
-}
-
-func Warn(v ...interface{}) {
-       Std.Output("", Lwarn, 2, fmt.Sprintln(v...))
-}
-
-// -----------------------------------------
-
-func Errorf(format string, v ...interface{}) {
-       Std.Output("", Lerror, 2, fmt.Sprintf(format, v...))
-}
-
-func Error(v ...interface{}) {
-       Std.Output("", Lerror, 2, fmt.Sprintln(v...))
-}
-
-// -----------------------------------------
-
-// Fatal is equivalent to Print() followed by a call to os.Exit(1).
-func Fatal(v ...interface{}) {
-       Std.Output("", Lfatal, 2, fmt.Sprintln(v...))
-}
-
-// Fatalf is equivalent to Printf() followed by a call to os.Exit(1).
-func Fatalf(format string, v ...interface{}) {
-       Std.Output("", Lfatal, 2, fmt.Sprintf(format, v...))
-}
-
-// -----------------------------------------
-
-// Panic is equivalent to Print() followed by a call to panic().
-func Panic(v ...interface{}) {
-       Std.Output("", Lpanic, 2, fmt.Sprintln(v...))
-}
-
-// Panicf is equivalent to Printf() followed by a call to panic().
-func Panicf(format string, v ...interface{}) {
-       Std.Output("", Lpanic, 2, fmt.Sprintf(format, v...))
-}
-
-// -----------------------------------------
-
-func Stack(v ...interface{}) {
-       s := fmt.Sprint(v...)
-       s += "\n"
-       buf := make([]byte, 1024*1024)
-       n := runtime.Stack(buf, true)
-       s += string(buf[:n])
-       s += "\n"
-       Std.Output("", Lerror, 2, s)
-}
-
-// -----------------------------------------
diff --git a/vendor/github.com/lunny/nodb/.gitignore b/vendor/github.com/lunny/nodb/.gitignore
deleted file mode 100644 (file)
index 8f40517..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-build
-*.pyc
-.DS_Store
-nohup.out
-build_config.mk
-var
-.vscode
diff --git a/vendor/github.com/lunny/nodb/LICENSE b/vendor/github.com/lunny/nodb/LICENSE
deleted file mode 100644 (file)
index 7ece9fd..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2014 siddontang
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
\ No newline at end of file
diff --git a/vendor/github.com/lunny/nodb/README.md b/vendor/github.com/lunny/nodb/README.md
deleted file mode 100644 (file)
index ebba36b..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-# NoDB
-
-[中文](https://github.com/lunny/nodb/blob/master/README_CN.md)
-
-Nodb is a fork of [ledisdb](https://github.com/siddontang/ledisdb) and shrink version. It's get rid of all C or other language codes and only keep Go's. It aims to provide a nosql database library rather than a redis like server. So if you want a redis like server, ledisdb is the best choose.
-
-Nodb is a pure Go and high performance NoSQL database library. It supports some data structure like kv, list, hash, zset, bitmap, set.
-
-Nodb now use [goleveldb](https://github.com/syndtr/goleveldb) as backend to store data.
-
-## Features
-
-+ Rich data structure: KV, List, Hash, ZSet, Bitmap, Set.
-+ Stores lots of data, over the memory limit. 
-+ Supports expiration and ttl.
-+ Easy to embed in your own Go application.
-
-## Install
-
-    go get github.com/lunny/nodb
-
-## Package Example
-
-### Open And Select database
-```go
-import(
-  "github.com/lunny/nodb"
-  "github.com/lunny/nodb/config"
-)
-
-cfg := new(config.Config)
-cfg.DataDir = "./"
-dbs, err := nodb.Open(cfg)
-if err != nil {
-  fmt.Printf("nodb: error opening db: %v", err)
-}
-
-db, _ := dbs.Select(0)
-```
-### KV
-
-KV is the most basic nodb type like any other key-value database.
-```go
-err := db.Set(key, value)
-value, err := db.Get(key)
-```
-### List
-
-List is simply lists of values, sorted by insertion order.
-You can push or pop value on the list head (left) or tail (right).
-```go
-err := db.LPush(key, value1)
-err := db.RPush(key, value2)
-value1, err := db.LPop(key)
-value2, err := db.RPop(key)
-```
-### Hash
-
-Hash is a map between fields and values.
-```go
-n, err := db.HSet(key, field1, value1)
-n, err := db.HSet(key, field2, value2)
-value1, err := db.HGet(key, field1)
-value2, err := db.HGet(key, field2)
-```
-### ZSet
-
-ZSet is a sorted collections of values.
-Every member of zset is associated with score, a int64 value which used to sort, from smallest to greatest score.
-Members are unique, but score may be same.
-```go
-n, err := db.ZAdd(key, ScorePair{score1, member1}, ScorePair{score2, member2})
-ay, err := db.ZRangeByScore(key, minScore, maxScore, 0, -1)
-```
-## Links
-
-+ [Ledisdb Official Website](http://ledisdb.com)
-+ [GoDoc](https://godoc.org/github.com/lunny/nodb)
-+ [GoWalker](https://gowalker.org/github.com/lunny/nodb)
-
-
-## Thanks
-
-Gmail: siddontang@gmail.com
diff --git a/vendor/github.com/lunny/nodb/README_CN.md b/vendor/github.com/lunny/nodb/README_CN.md
deleted file mode 100644 (file)
index 6fa286e..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-# NoDB
-
-[English](https://github.com/lunny/nodb/blob/master/README.md)
-
-Nodb 是 [ledisdb](https://github.com/siddontang/ledisdb) 的克隆和缩减版本。该版本去掉了所有C和其它语言的依赖,只保留Go语言的。目标是提供一个Nosql数据库的开发库而不是提供一个像Redis那样的服务器。因此如果你想要的是一个独立服务器,你可以直接选择ledisdb。
-
-Nodb 是一个纯Go的高性能 NoSQL 数据库。他支持 kv, list, hash, zset, bitmap, set 等数据结构。
-
-Nodb 当前底层使用 (goleveldb)[https://github.com/syndtr/goleveldb] 来存储数据。
-
-## 特性
-
-+ 丰富的数据结构支持: KV, List, Hash, ZSet, Bitmap, Set。
-+ 永久存储并且不受内存的限制。
-+ 高性能那个。
-+ 可以方便的嵌入到你的应用程序中。
-
-## 安装
-
-    go get github.com/lunny/nodb
-
-## 例子
-
-### 打开和选择数据库
-```go
-import(
-  "github.com/lunny/nodb"
-  "github.com/lunny/nodb/config"
-)
-
-cfg := new(config.Config)
-cfg.DataDir = "./"
-dbs, err := nodb.Open(cfg)
-if err != nil {
-  fmt.Printf("nodb: error opening db: %v", err)
-}
-db, _ := dbs.Select(0)
-```
-### KV
-
-KV 是最基础的功能,和其它Nosql一样。
-```go
-err := db.Set(key, value)
-value, err := db.Get(key)
-```
-### List
-
-List 是一些值的简单列表,按照插入的顺序排列。你可以从左或右push和pop值。
-```go
-err := db.LPush(key, value1)
-err := db.RPush(key, value2)
-value1, err := db.LPop(key)
-value2, err := db.RPop(key)
-```
-### Hash
-
-Hash 是一个field和value对应的map。
-```go
-n, err := db.HSet(key, field1, value1)
-n, err := db.HSet(key, field2, value2)
-value1, err := db.HGet(key, field1)
-value2, err := db.HGet(key, field2)
-```
-### ZSet
-
-ZSet 是一个排序的值集合。zset的每个成员对应一个score,这是一个int64的值用于从小到大排序。成员不可重复,但是score可以相同。
-```go
-n, err := db.ZAdd(key, ScorePair{score1, member1}, ScorePair{score2, member2})
-ay, err := db.ZRangeByScore(key, minScore, maxScore, 0, -1)
-```
-
-## 链接
-
-+ [Ledisdb Official Website](http://ledisdb.com)
-+ [GoDoc](https://godoc.org/github.com/lunny/nodb)
-+ [GoWalker](https://gowalker.org/github.com/lunny/nodb)
-
-
-## 感谢
-
-Gmail: siddontang@gmail.com
diff --git a/vendor/github.com/lunny/nodb/batch.go b/vendor/github.com/lunny/nodb/batch.go
deleted file mode 100644 (file)
index e69d96a..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-package nodb
-
-import (
-       "sync"
-
-       "github.com/lunny/nodb/store"
-)
-
-type batch struct {
-       l *Nodb
-
-       store.WriteBatch
-
-       sync.Locker
-
-       logs [][]byte
-
-       tx *Tx
-}
-
-func (b *batch) Commit() error {
-       b.l.commitLock.Lock()
-       defer b.l.commitLock.Unlock()
-
-       err := b.WriteBatch.Commit()
-
-       if b.l.binlog != nil {
-               if err == nil {
-                       if b.tx == nil {
-                               b.l.binlog.Log(b.logs...)
-                       } else {
-                               b.tx.logs = append(b.tx.logs, b.logs...)
-                       }
-               }
-               b.logs = [][]byte{}
-       }
-
-       return err
-}
-
-func (b *batch) Lock() {
-       b.Locker.Lock()
-}
-
-func (b *batch) Unlock() {
-       if b.l.binlog != nil {
-               b.logs = [][]byte{}
-       }
-       b.WriteBatch.Rollback()
-       b.Locker.Unlock()
-}
-
-func (b *batch) Put(key []byte, value []byte) {
-       if b.l.binlog != nil {
-               buf := encodeBinLogPut(key, value)
-               b.logs = append(b.logs, buf)
-       }
-       b.WriteBatch.Put(key, value)
-}
-
-func (b *batch) Delete(key []byte) {
-       if b.l.binlog != nil {
-               buf := encodeBinLogDelete(key)
-               b.logs = append(b.logs, buf)
-       }
-       b.WriteBatch.Delete(key)
-}
-
-type dbBatchLocker struct {
-       l      *sync.Mutex
-       wrLock *sync.RWMutex
-}
-
-func (l *dbBatchLocker) Lock() {
-       l.wrLock.RLock()
-       l.l.Lock()
-}
-
-func (l *dbBatchLocker) Unlock() {
-       l.l.Unlock()
-       l.wrLock.RUnlock()
-}
-
-type txBatchLocker struct {
-}
-
-func (l *txBatchLocker) Lock()   {}
-func (l *txBatchLocker) Unlock() {}
-
-type multiBatchLocker struct {
-}
-
-func (l *multiBatchLocker) Lock()   {}
-func (l *multiBatchLocker) Unlock() {}
-
-func (l *Nodb) newBatch(wb store.WriteBatch, locker sync.Locker, tx *Tx) *batch {
-       b := new(batch)
-       b.l = l
-       b.WriteBatch = wb
-
-       b.tx = tx
-       b.Locker = locker
-
-       b.logs = [][]byte{}
-       return b
-}
diff --git a/vendor/github.com/lunny/nodb/binlog.go b/vendor/github.com/lunny/nodb/binlog.go
deleted file mode 100644 (file)
index 4c094d9..0000000
+++ /dev/null
@@ -1,391 +0,0 @@
-package nodb
-
-import (
-       "bufio"
-       "encoding/binary"
-       "fmt"
-       "io"
-       "io/ioutil"
-       "os"
-       "path"
-       "strconv"
-       "strings"
-       "sync"
-       "time"
-
-       "github.com/lunny/log"
-       "github.com/lunny/nodb/config"
-)
-
-type BinLogHead struct {
-       CreateTime uint32
-       BatchId    uint32
-       PayloadLen uint32
-}
-
-func (h *BinLogHead) Len() int {
-       return 12
-}
-
-func (h *BinLogHead) Write(w io.Writer) error {
-       if err := binary.Write(w, binary.BigEndian, h.CreateTime); err != nil {
-               return err
-       }
-
-       if err := binary.Write(w, binary.BigEndian, h.BatchId); err != nil {
-               return err
-       }
-
-       if err := binary.Write(w, binary.BigEndian, h.PayloadLen); err != nil {
-               return err
-       }
-
-       return nil
-}
-
-func (h *BinLogHead) handleReadError(err error) error {
-       if err == io.EOF {
-               return io.ErrUnexpectedEOF
-       } else {
-               return err
-       }
-}
-
-func (h *BinLogHead) Read(r io.Reader) error {
-       var err error
-       if err = binary.Read(r, binary.BigEndian, &h.CreateTime); err != nil {
-               return err
-       }
-
-       if err = binary.Read(r, binary.BigEndian, &h.BatchId); err != nil {
-               return h.handleReadError(err)
-       }
-
-       if err = binary.Read(r, binary.BigEndian, &h.PayloadLen); err != nil {
-               return h.handleReadError(err)
-       }
-
-       return nil
-}
-
-func (h *BinLogHead) InSameBatch(ho *BinLogHead) bool {
-       if h.CreateTime == ho.CreateTime && h.BatchId == ho.BatchId {
-               return true
-       } else {
-               return false
-       }
-}
-
-/*
-index file format:
-ledis-bin.00001
-ledis-bin.00002
-ledis-bin.00003
-
-log file format
-
-Log: Head|PayloadData
-
-Head: createTime|batchId|payloadData
-
-*/
-
-type BinLog struct {
-       sync.Mutex
-
-       path string
-
-       cfg *config.BinLogConfig
-
-       logFile *os.File
-
-       logWb *bufio.Writer
-
-       indexName    string
-       logNames     []string
-       lastLogIndex int64
-
-       batchId uint32
-
-       ch chan struct{}
-}
-
-func NewBinLog(cfg *config.Config) (*BinLog, error) {
-       l := new(BinLog)
-
-       l.cfg = &cfg.BinLog
-       l.cfg.Adjust()
-
-       l.path = path.Join(cfg.DataDir, "binlog")
-
-       if err := os.MkdirAll(l.path, os.ModePerm); err != nil {
-               return nil, err
-       }
-
-       l.logNames = make([]string, 0, 16)
-
-       l.ch = make(chan struct{})
-
-       if err := l.loadIndex(); err != nil {
-               return nil, err
-       }
-
-       return l, nil
-}
-
-func (l *BinLog) flushIndex() error {
-       data := strings.Join(l.logNames, "\n")
-
-       bakName := fmt.Sprintf("%s.bak", l.indexName)
-       f, err := os.OpenFile(bakName, os.O_WRONLY|os.O_CREATE, 0666)
-       if err != nil {
-               log.Error("create binlog bak index error %s", err.Error())
-               return err
-       }
-
-       if _, err := f.WriteString(data); err != nil {
-               log.Error("write binlog index error %s", err.Error())
-               f.Close()
-               return err
-       }
-
-       f.Close()
-
-       if err := os.Rename(bakName, l.indexName); err != nil {
-               log.Error("rename binlog bak index error %s", err.Error())
-               return err
-       }
-
-       return nil
-}
-
-func (l *BinLog) loadIndex() error {
-       l.indexName = path.Join(l.path, fmt.Sprintf("ledis-bin.index"))
-       if _, err := os.Stat(l.indexName); os.IsNotExist(err) {
-               //no index file, nothing to do
-       } else {
-               indexData, err := ioutil.ReadFile(l.indexName)
-               if err != nil {
-                       return err
-               }
-
-               lines := strings.Split(string(indexData), "\n")
-               for _, line := range lines {
-                       line = strings.Trim(line, "\r\n ")
-                       if len(line) == 0 {
-                               continue
-                       }
-
-                       if _, err := os.Stat(path.Join(l.path, line)); err != nil {
-                               log.Error("load index line %s error %s", line, err.Error())
-                               return err
-                       } else {
-                               l.logNames = append(l.logNames, line)
-                       }
-               }
-       }
-       if l.cfg.MaxFileNum > 0 && len(l.logNames) > l.cfg.MaxFileNum {
-               //remove oldest logfile
-               if err := l.Purge(len(l.logNames) - l.cfg.MaxFileNum); err != nil {
-                       return err
-               }
-       }
-
-       var err error
-       if len(l.logNames) == 0 {
-               l.lastLogIndex = 1
-       } else {
-               lastName := l.logNames[len(l.logNames)-1]
-
-               if l.lastLogIndex, err = strconv.ParseInt(path.Ext(lastName)[1:], 10, 64); err != nil {
-                       log.Error("invalid logfile name %s", err.Error())
-                       return err
-               }
-
-               //like mysql, if server restart, a new binlog will create
-               l.lastLogIndex++
-       }
-
-       return nil
-}
-
-func (l *BinLog) getLogFile() string {
-       return l.FormatLogFileName(l.lastLogIndex)
-}
-
-func (l *BinLog) openNewLogFile() error {
-       var err error
-       lastName := l.getLogFile()
-
-       logPath := path.Join(l.path, lastName)
-       if l.logFile, err = os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY, 0666); err != nil {
-               log.Error("open new logfile error %s", err.Error())
-               return err
-       }
-
-       if l.cfg.MaxFileNum > 0 && len(l.logNames) == l.cfg.MaxFileNum {
-               l.purge(1)
-       }
-
-       l.logNames = append(l.logNames, lastName)
-
-       if l.logWb == nil {
-               l.logWb = bufio.NewWriterSize(l.logFile, 1024)
-       } else {
-               l.logWb.Reset(l.logFile)
-       }
-
-       if err = l.flushIndex(); err != nil {
-               return err
-       }
-
-       return nil
-}
-
-func (l *BinLog) checkLogFileSize() bool {
-       if l.logFile == nil {
-               return false
-       }
-
-       st, _ := l.logFile.Stat()
-       if st.Size() >= int64(l.cfg.MaxFileSize) {
-               l.closeLog()
-               return true
-       }
-
-       return false
-}
-
-func (l *BinLog) closeLog() {
-       l.lastLogIndex++
-
-       l.logFile.Close()
-       l.logFile = nil
-}
-
-func (l *BinLog) purge(n int) {
-       for i := 0; i < n; i++ {
-               logPath := path.Join(l.path, l.logNames[i])
-               os.Remove(logPath)
-       }
-
-       copy(l.logNames[0:], l.logNames[n:])
-       l.logNames = l.logNames[0 : len(l.logNames)-n]
-}
-
-func (l *BinLog) Close() {
-       if l.logFile != nil {
-               l.logFile.Close()
-               l.logFile = nil
-       }
-}
-
-func (l *BinLog) LogNames() []string {
-       return l.logNames
-}
-
-func (l *BinLog) LogFileName() string {
-       return l.getLogFile()
-}
-
-func (l *BinLog) LogFilePos() int64 {
-       if l.logFile == nil {
-               return 0
-       } else {
-               st, _ := l.logFile.Stat()
-               return st.Size()
-       }
-}
-
-func (l *BinLog) LogFileIndex() int64 {
-       return l.lastLogIndex
-}
-
-func (l *BinLog) FormatLogFileName(index int64) string {
-       return fmt.Sprintf("ledis-bin.%07d", index)
-}
-
-func (l *BinLog) FormatLogFilePath(index int64) string {
-       return path.Join(l.path, l.FormatLogFileName(index))
-}
-
-func (l *BinLog) LogPath() string {
-       return l.path
-}
-
-func (l *BinLog) Purge(n int) error {
-       l.Lock()
-       defer l.Unlock()
-
-       if len(l.logNames) == 0 {
-               return nil
-       }
-
-       if n >= len(l.logNames) {
-               n = len(l.logNames)
-               //can not purge current log file
-               if l.logNames[n-1] == l.getLogFile() {
-                       n = n - 1
-               }
-       }
-
-       l.purge(n)
-
-       return l.flushIndex()
-}
-
-func (l *BinLog) PurgeAll() error {
-       l.Lock()
-       defer l.Unlock()
-
-       l.closeLog()
-       return l.openNewLogFile()
-}
-
-func (l *BinLog) Log(args ...[]byte) error {
-       l.Lock()
-       defer l.Unlock()
-
-       var err error
-
-       if l.logFile == nil {
-               if err = l.openNewLogFile(); err != nil {
-                       return err
-               }
-       }
-
-       head := &BinLogHead{}
-
-       head.CreateTime = uint32(time.Now().Unix())
-       head.BatchId = l.batchId
-
-       l.batchId++
-
-       for _, data := range args {
-               head.PayloadLen = uint32(len(data))
-
-               if err := head.Write(l.logWb); err != nil {
-                       return err
-               }
-
-               if _, err := l.logWb.Write(data); err != nil {
-                       return err
-               }
-       }
-
-       if err = l.logWb.Flush(); err != nil {
-               log.Error("write log error %s", err.Error())
-               return err
-       }
-
-       l.checkLogFileSize()
-
-       close(l.ch)
-       l.ch = make(chan struct{})
-
-       return nil
-}
-
-func (l *BinLog) Wait() <-chan struct{} {
-       return l.ch
-}
diff --git a/vendor/github.com/lunny/nodb/binlog_util.go b/vendor/github.com/lunny/nodb/binlog_util.go
deleted file mode 100644 (file)
index 22124dd..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-package nodb
-
-import (
-       "encoding/binary"
-       "errors"
-       "fmt"
-       "strconv"
-)
-
-var (
-       errBinLogDeleteType  = errors.New("invalid bin log delete type")
-       errBinLogPutType     = errors.New("invalid bin log put type")
-       errBinLogCommandType = errors.New("invalid bin log command type")
-)
-
-func encodeBinLogDelete(key []byte) []byte {
-       buf := make([]byte, 1+len(key))
-       buf[0] = BinLogTypeDeletion
-       copy(buf[1:], key)
-       return buf
-}
-
-func decodeBinLogDelete(sz []byte) ([]byte, error) {
-       if len(sz) < 1 || sz[0] != BinLogTypeDeletion {
-               return nil, errBinLogDeleteType
-       }
-
-       return sz[1:], nil
-}
-
-func encodeBinLogPut(key []byte, value []byte) []byte {
-       buf := make([]byte, 3+len(key)+len(value))
-       buf[0] = BinLogTypePut
-       pos := 1
-       binary.BigEndian.PutUint16(buf[pos:], uint16(len(key)))
-       pos += 2
-       copy(buf[pos:], key)
-       pos += len(key)
-       copy(buf[pos:], value)
-
-       return buf
-}
-
-func decodeBinLogPut(sz []byte) ([]byte, []byte, error) {
-       if len(sz) < 3 || sz[0] != BinLogTypePut {
-               return nil, nil, errBinLogPutType
-       }
-
-       keyLen := int(binary.BigEndian.Uint16(sz[1:]))
-       if 3+keyLen > len(sz) {
-               return nil, nil, errBinLogPutType
-       }
-
-       return sz[3 : 3+keyLen], sz[3+keyLen:], nil
-}
-
-func FormatBinLogEvent(event []byte) (string, error) {
-       logType := uint8(event[0])
-
-       var err error
-       var k []byte
-       var v []byte
-
-       var buf []byte = make([]byte, 0, 1024)
-
-       switch logType {
-       case BinLogTypePut:
-               k, v, err = decodeBinLogPut(event)
-               buf = append(buf, "PUT "...)
-       case BinLogTypeDeletion:
-               k, err = decodeBinLogDelete(event)
-               buf = append(buf, "DELETE "...)
-       default:
-               err = errInvalidBinLogEvent
-       }
-
-       if err != nil {
-               return "", err
-       }
-
-       if buf, err = formatDataKey(buf, k); err != nil {
-               return "", err
-       }
-
-       if v != nil && len(v) != 0 {
-               buf = append(buf, fmt.Sprintf(" %q", v)...)
-       }
-
-       return String(buf), nil
-}
-
-func formatDataKey(buf []byte, k []byte) ([]byte, error) {
-       if len(k) < 2 {
-               return nil, errInvalidBinLogEvent
-       }
-
-       buf = append(buf, fmt.Sprintf("DB:%2d ", k[0])...)
-       buf = append(buf, fmt.Sprintf("%s ", TypeName[k[1]])...)
-
-       db := new(DB)
-       db.index = k[0]
-
-       //to do format at respective place
-
-       switch k[1] {
-       case KVType:
-               if key, err := db.decodeKVKey(k); err != nil {
-                       return nil, err
-               } else {
-                       buf = strconv.AppendQuote(buf, String(key))
-               }
-       case HashType:
-               if key, field, err := db.hDecodeHashKey(k); err != nil {
-                       return nil, err
-               } else {
-                       buf = strconv.AppendQuote(buf, String(key))
-                       buf = append(buf, ' ')
-                       buf = strconv.AppendQuote(buf, String(field))
-               }
-       case HSizeType:
-               if key, err := db.hDecodeSizeKey(k); err != nil {
-                       return nil, err
-               } else {
-                       buf = strconv.AppendQuote(buf, String(key))
-               }
-       case ListType:
-               if key, seq, err := db.lDecodeListKey(k); err != nil {
-                       return nil, err
-               } else {
-                       buf = strconv.AppendQuote(buf, String(key))
-                       buf = append(buf, ' ')
-                       buf = strconv.AppendInt(buf, int64(seq), 10)
-               }
-       case LMetaType:
-               if key, err := db.lDecodeMetaKey(k); err != nil {
-                       return nil, err
-               } else {
-                       buf = strconv.AppendQuote(buf, String(key))
-               }
-       case ZSetType:
-               if key, m, err := db.zDecodeSetKey(k); err != nil {
-                       return nil, err
-               } else {
-                       buf = strconv.AppendQuote(buf, String(key))
-                       buf = append(buf, ' ')
-                       buf = strconv.AppendQuote(buf, String(m))
-               }
-       case ZSizeType:
-               if key, err := db.zDecodeSizeKey(k); err != nil {
-                       return nil, err
-               } else {
-                       buf = strconv.AppendQuote(buf, String(key))
-               }
-       case ZScoreType:
-               if key, m, score, err := db.zDecodeScoreKey(k); err != nil {
-                       return nil, err
-               } else {
-                       buf = strconv.AppendQuote(buf, String(key))
-                       buf = append(buf, ' ')
-                       buf = strconv.AppendQuote(buf, String(m))
-                       buf = append(buf, ' ')
-                       buf = strconv.AppendInt(buf, score, 10)
-               }
-       case BitType:
-               if key, seq, err := db.bDecodeBinKey(k); err != nil {
-                       return nil, err
-               } else {
-                       buf = strconv.AppendQuote(buf, String(key))
-                       buf = append(buf, ' ')
-                       buf = strconv.AppendUint(buf, uint64(seq), 10)
-               }
-       case BitMetaType:
-               if key, err := db.bDecodeMetaKey(k); err != nil {
-                       return nil, err
-               } else {
-                       buf = strconv.AppendQuote(buf, String(key))
-               }
-       case SetType:
-               if key, member, err := db.sDecodeSetKey(k); err != nil {
-                       return nil, err
-               } else {
-                       buf = strconv.AppendQuote(buf, String(key))
-                       buf = append(buf, ' ')
-                       buf = strconv.AppendQuote(buf, String(member))
-               }
-       case SSizeType:
-               if key, err := db.sDecodeSizeKey(k); err != nil {
-                       return nil, err
-               } else {
-                       buf = strconv.AppendQuote(buf, String(key))
-               }
-       case ExpTimeType:
-               if tp, key, t, err := db.expDecodeTimeKey(k); err != nil {
-                       return nil, err
-               } else {
-                       buf = append(buf, TypeName[tp]...)
-                       buf = append(buf, ' ')
-                       buf = strconv.AppendQuote(buf, String(key))
-                       buf = append(buf, ' ')
-                       buf = strconv.AppendInt(buf, t, 10)
-               }
-       case ExpMetaType:
-               if tp, key, err := db.expDecodeMetaKey(k); err != nil {
-                       return nil, err
-               } else {
-                       buf = append(buf, TypeName[tp]...)
-                       buf = append(buf, ' ')
-                       buf = strconv.AppendQuote(buf, String(key))
-               }
-       default:
-               return nil, errInvalidBinLogEvent
-       }
-
-       return buf, nil
-}
diff --git a/vendor/github.com/lunny/nodb/config/config.go b/vendor/github.com/lunny/nodb/config/config.go
deleted file mode 100644 (file)
index 3b44d30..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-package config
-
-import (
-       "io/ioutil"
-
-       "github.com/BurntSushi/toml"
-)
-
-type Size int
-
-const (
-       DefaultAddr     string = "127.0.0.1:6380"
-       DefaultHttpAddr string = "127.0.0.1:11181"
-
-       DefaultDBName string = "goleveldb"
-
-       DefaultDataDir string = "./data"
-)
-
-const (
-       MaxBinLogFileSize int = 1024 * 1024 * 1024
-       MaxBinLogFileNum  int = 10000
-
-       DefaultBinLogFileSize int = MaxBinLogFileSize
-       DefaultBinLogFileNum  int = 10
-)
-
-type LevelDBConfig struct {
-       Compression     bool `toml:"compression"`
-       BlockSize       int  `toml:"block_size"`
-       WriteBufferSize int  `toml:"write_buffer_size"`
-       CacheSize       int  `toml:"cache_size"`
-       MaxOpenFiles    int  `toml:"max_open_files"`
-}
-
-type LMDBConfig struct {
-       MapSize int  `toml:"map_size"`
-       NoSync  bool `toml:"nosync"`
-}
-
-type BinLogConfig struct {
-       MaxFileSize int `toml:"max_file_size"`
-       MaxFileNum  int `toml:"max_file_num"`
-}
-
-type Config struct {
-       DataDir string `toml:"data_dir"`
-
-       DBName string `toml:"db_name"`
-
-       LevelDB LevelDBConfig `toml:"leveldb"`
-
-       LMDB LMDBConfig `toml:"lmdb"`
-
-       BinLog BinLogConfig `toml:"binlog"`
-
-       SlaveOf string `toml:"slaveof"`
-
-       AccessLog string `toml:"access_log"`
-}
-
-func NewConfigWithFile(fileName string) (*Config, error) {
-       data, err := ioutil.ReadFile(fileName)
-       if err != nil {
-               return nil, err
-       }
-
-       return NewConfigWithData(data)
-}
-
-func NewConfigWithData(data []byte) (*Config, error) {
-       cfg := NewConfigDefault()
-
-       _, err := toml.Decode(string(data), cfg)
-       if err != nil {
-               return nil, err
-       }
-
-       return cfg, nil
-}
-
-func NewConfigDefault() *Config {
-       cfg := new(Config)
-
-       cfg.DataDir = DefaultDataDir
-
-       cfg.DBName = DefaultDBName
-
-       // disable binlog
-       cfg.BinLog.MaxFileNum = 0
-       cfg.BinLog.MaxFileSize = 0
-
-       // disable replication
-       cfg.SlaveOf = ""
-
-       // disable access log
-       cfg.AccessLog = ""
-
-       cfg.LMDB.MapSize = 20 * 1024 * 1024
-       cfg.LMDB.NoSync = true
-
-       return cfg
-}
-
-func (cfg *LevelDBConfig) Adjust() {
-       if cfg.CacheSize <= 0 {
-               cfg.CacheSize = 4 * 1024 * 1024
-       }
-
-       if cfg.BlockSize <= 0 {
-               cfg.BlockSize = 4 * 1024
-       }
-
-       if cfg.WriteBufferSize <= 0 {
-               cfg.WriteBufferSize = 4 * 1024 * 1024
-       }
-
-       if cfg.MaxOpenFiles < 1024 {
-               cfg.MaxOpenFiles = 1024
-       }
-}
-
-func (cfg *BinLogConfig) Adjust() {
-       if cfg.MaxFileSize <= 0 {
-               cfg.MaxFileSize = DefaultBinLogFileSize
-       } else if cfg.MaxFileSize > MaxBinLogFileSize {
-               cfg.MaxFileSize = MaxBinLogFileSize
-       }
-
-       if cfg.MaxFileNum <= 0 {
-               cfg.MaxFileNum = DefaultBinLogFileNum
-       } else if cfg.MaxFileNum > MaxBinLogFileNum {
-               cfg.MaxFileNum = MaxBinLogFileNum
-       }
-}
diff --git a/vendor/github.com/lunny/nodb/config/config.toml b/vendor/github.com/lunny/nodb/config/config.toml
deleted file mode 100644 (file)
index 2a3a246..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-# LedisDB configuration
-
-# Server listen address
-addr = "127.0.0.1:6380"
-
-# Server http listen address, set empty to disable
-http_addr = "127.0.0.1:11181"
-
-# Data store path, all ledisdb's data will be saved here
-data_dir = "/tmp/ledis_server"
-
-# Log server command, set empty to disable
-access_log = ""
-
-# Set slaveof to enable replication from master, empty, no replication
-slaveof = ""
-
-# Choose which backend storage to use, now support:
-#
-#   leveldb
-#   rocksdb
-#   goleveldb
-#   lmdb
-#   boltdb
-#   hyperleveldb
-#   memory
-#   
-db_name = "leveldb"
-
-[leveldb]
-compression = false
-block_size = 32768
-write_buffer_size = 67108864
-cache_size = 524288000
-max_open_files = 1024
-
-[lmdb]
-map_size = 524288000
-nosync = true
-
-[binlog]
-max_file_size = 0
-max_file_num = 0
-
-
diff --git a/vendor/github.com/lunny/nodb/const.go b/vendor/github.com/lunny/nodb/const.go
deleted file mode 100644 (file)
index 446dae6..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-package nodb
-
-import (
-       "errors"
-)
-
-const (
-       NoneType    byte = 0
-       KVType      byte = 1
-       HashType    byte = 2
-       HSizeType   byte = 3
-       ListType    byte = 4
-       LMetaType   byte = 5
-       ZSetType    byte = 6
-       ZSizeType   byte = 7
-       ZScoreType  byte = 8
-       BitType     byte = 9
-       BitMetaType byte = 10
-       SetType     byte = 11
-       SSizeType   byte = 12
-
-       maxDataType byte = 100
-
-       ExpTimeType byte = 101
-       ExpMetaType byte = 102
-)
-
-var (
-       TypeName = map[byte]string{
-               KVType:      "kv",
-               HashType:    "hash",
-               HSizeType:   "hsize",
-               ListType:    "list",
-               LMetaType:   "lmeta",
-               ZSetType:    "zset",
-               ZSizeType:   "zsize",
-               ZScoreType:  "zscore",
-               BitType:     "bit",
-               BitMetaType: "bitmeta",
-               SetType:     "set",
-               SSizeType:   "ssize",
-               ExpTimeType: "exptime",
-               ExpMetaType: "expmeta",
-       }
-)
-
-const (
-       defaultScanCount int = 10
-)
-
-var (
-       errKeySize        = errors.New("invalid key size")
-       errValueSize      = errors.New("invalid value size")
-       errHashFieldSize  = errors.New("invalid hash field size")
-       errSetMemberSize  = errors.New("invalid set member size")
-       errZSetMemberSize = errors.New("invalid zset member size")
-       errExpireValue    = errors.New("invalid expire value")
-)
-
-const (
-       //we don't support too many databases
-       MaxDBNumber uint8 = 16
-
-       //max key size
-       MaxKeySize int = 1024
-
-       //max hash field size
-       MaxHashFieldSize int = 1024
-
-       //max zset member size
-       MaxZSetMemberSize int = 1024
-
-       //max set member size
-       MaxSetMemberSize int = 1024
-
-       //max value size
-       MaxValueSize int = 10 * 1024 * 1024
-)
-
-var (
-       ErrScoreMiss = errors.New("zset score miss")
-)
-
-const (
-       BinLogTypeDeletion uint8 = 0x0
-       BinLogTypePut      uint8 = 0x1
-       BinLogTypeCommand  uint8 = 0x2
-)
-
-const (
-       DBAutoCommit    uint8 = 0x0
-       DBInTransaction uint8 = 0x1
-       DBInMulti       uint8 = 0x2
-)
-
-var (
-       Version = "0.1"
-)
diff --git a/vendor/github.com/lunny/nodb/doc.go b/vendor/github.com/lunny/nodb/doc.go
deleted file mode 100644 (file)
index 2f7df33..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-// package nodb is a high performance embedded NoSQL.
-//
-// nodb supports various data structure like kv, list, hash and zset like redis.
-//
-// Other features include binlog replication, data with a limited time-to-live.
-//
-// Usage
-//
-// First create a nodb instance before use:
-//
-//  l := nodb.Open(cfg)
-//
-// cfg is a Config instance which contains configuration for nodb use,
-// like DataDir (root directory for nodb working to store data).
-//
-// After you create a nodb instance, you can select a DB to store you data:
-//
-//  db, _ := l.Select(0)
-//
-// DB must be selected by a index, nodb supports only 16 databases, so the index range is [0-15].
-//
-// KV
-//
-// KV is the most basic nodb type like any other key-value database.
-//
-//  err := db.Set(key, value)
-//  value, err := db.Get(key)
-//
-// List
-//
-// List is simply lists of values, sorted by insertion order.
-// You can push or pop value on the list head (left) or tail (right).
-//
-//  err := db.LPush(key, value1)
-//  err := db.RPush(key, value2)
-//  value1, err := db.LPop(key)
-//  value2, err := db.RPop(key)
-//
-// Hash
-//
-// Hash is a map between fields and values.
-//
-//  n, err := db.HSet(key, field1, value1)
-//  n, err := db.HSet(key, field2, value2)
-//  value1, err := db.HGet(key, field1)
-//  value2, err := db.HGet(key, field2)
-//
-// ZSet
-//
-// ZSet is a sorted collections of values.
-// Every member of zset is associated with score, a int64 value which used to sort, from smallest to greatest score.
-// Members are unique, but score may be same.
-//
-//  n, err := db.ZAdd(key, ScorePair{score1, member1}, ScorePair{score2, member2})
-//  ay, err := db.ZRangeByScore(key, minScore, maxScore, 0, -1)
-//
-// Binlog
-//
-// nodb supports binlog, so you can sync binlog to another server for replication. If you want to open binlog support, set UseBinLog to true in config.
-//
-package nodb
diff --git a/vendor/github.com/lunny/nodb/dump.go b/vendor/github.com/lunny/nodb/dump.go
deleted file mode 100644 (file)
index 3c9722e..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-package nodb
-
-import (
-       "bufio"
-       "bytes"
-       "encoding/binary"
-       "io"
-       "os"
-
-       "github.com/siddontang/go-snappy/snappy"
-)
-
-//dump format
-// fileIndex(bigendian int64)|filePos(bigendian int64)
-// |keylen(bigendian int32)|key|valuelen(bigendian int32)|value......
-//
-//key and value are both compressed for fast transfer dump on network using snappy
-
-type BinLogAnchor struct {
-       LogFileIndex int64
-       LogPos       int64
-}
-
-func (m *BinLogAnchor) WriteTo(w io.Writer) error {
-       if err := binary.Write(w, binary.BigEndian, m.LogFileIndex); err != nil {
-               return err
-       }
-
-       if err := binary.Write(w, binary.BigEndian, m.LogPos); err != nil {
-               return err
-       }
-       return nil
-}
-
-func (m *BinLogAnchor) ReadFrom(r io.Reader) error {
-       err := binary.Read(r, binary.BigEndian, &m.LogFileIndex)
-       if err != nil {
-               return err
-       }
-
-       err = binary.Read(r, binary.BigEndian, &m.LogPos)
-       if err != nil {
-               return err
-       }
-
-       return nil
-}
-
-func (l *Nodb) DumpFile(path string) error {
-       f, err := os.Create(path)
-       if err != nil {
-               return err
-       }
-       defer f.Close()
-
-       return l.Dump(f)
-}
-
-func (l *Nodb) Dump(w io.Writer) error {
-       m := new(BinLogAnchor)
-
-       var err error
-
-       l.wLock.Lock()
-       defer l.wLock.Unlock()
-
-       if l.binlog != nil {
-               m.LogFileIndex = l.binlog.LogFileIndex()
-               m.LogPos = l.binlog.LogFilePos()
-       }
-
-       wb := bufio.NewWriterSize(w, 4096)
-       if err = m.WriteTo(wb); err != nil {
-               return err
-       }
-
-       it := l.ldb.NewIterator()
-       it.SeekToFirst()
-
-       compressBuf := make([]byte, 4096)
-
-       var key []byte
-       var value []byte
-       for ; it.Valid(); it.Next() {
-               key = it.RawKey()
-               value = it.RawValue()
-
-               if key, err = snappy.Encode(compressBuf, key); err != nil {
-                       return err
-               }
-
-               if err = binary.Write(wb, binary.BigEndian, uint16(len(key))); err != nil {
-                       return err
-               }
-
-               if _, err = wb.Write(key); err != nil {
-                       return err
-               }
-
-               if value, err = snappy.Encode(compressBuf, value); err != nil {
-                       return err
-               }
-
-               if err = binary.Write(wb, binary.BigEndian, uint32(len(value))); err != nil {
-                       return err
-               }
-
-               if _, err = wb.Write(value); err != nil {
-                       return err
-               }
-       }
-
-       if err = wb.Flush(); err != nil {
-               return err
-       }
-
-       compressBuf = nil
-
-       return nil
-}
-
-func (l *Nodb) LoadDumpFile(path string) (*BinLogAnchor, error) {
-       f, err := os.Open(path)
-       if err != nil {
-               return nil, err
-       }
-       defer f.Close()
-
-       return l.LoadDump(f)
-}
-
-func (l *Nodb) LoadDump(r io.Reader) (*BinLogAnchor, error) {
-       l.wLock.Lock()
-       defer l.wLock.Unlock()
-
-       info := new(BinLogAnchor)
-
-       rb := bufio.NewReaderSize(r, 4096)
-
-       err := info.ReadFrom(rb)
-       if err != nil {
-               return nil, err
-       }
-
-       var keyLen uint16
-       var valueLen uint32
-
-       var keyBuf bytes.Buffer
-       var valueBuf bytes.Buffer
-
-       deKeyBuf := make([]byte, 4096)
-       deValueBuf := make([]byte, 4096)
-
-       var key, value []byte
-
-       for {
-               if err = binary.Read(rb, binary.BigEndian, &keyLen); err != nil && err != io.EOF {
-                       return nil, err
-               } else if err == io.EOF {
-                       break
-               }
-
-               if _, err = io.CopyN(&keyBuf, rb, int64(keyLen)); err != nil {
-                       return nil, err
-               }
-
-               if key, err = snappy.Decode(deKeyBuf, keyBuf.Bytes()); err != nil {
-                       return nil, err
-               }
-
-               if err = binary.Read(rb, binary.BigEndian, &valueLen); err != nil {
-                       return nil, err
-               }
-
-               if _, err = io.CopyN(&valueBuf, rb, int64(valueLen)); err != nil {
-                       return nil, err
-               }
-
-               if value, err = snappy.Decode(deValueBuf, valueBuf.Bytes()); err != nil {
-                       return nil, err
-               }
-
-               if err = l.ldb.Put(key, value); err != nil {
-                       return nil, err
-               }
-
-               keyBuf.Reset()
-               valueBuf.Reset()
-       }
-
-       deKeyBuf = nil
-       deValueBuf = nil
-
-       //if binlog enable, we will delete all binlogs and open a new one for handling simply
-       if l.binlog != nil {
-               l.binlog.PurgeAll()
-       }
-
-       return info, nil
-}
diff --git a/vendor/github.com/lunny/nodb/info.go b/vendor/github.com/lunny/nodb/info.go
deleted file mode 100644 (file)
index 3fd37e3..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-package nodb
-
-// todo, add info
-
-// type Keyspace struct {
-//     Kvs       int `json:"kvs"`
-//     KvExpires int `json:"kv_expires"`
-
-//     Lists       int `json:"lists"`
-//     ListExpires int `json:"list_expires"`
-
-//     Bitmaps       int `json:"bitmaps"`
-//     BitmapExpires int `json:"bitmap_expires"`
-
-//     ZSets       int `json:"zsets"`
-//     ZSetExpires int `json:"zset_expires"`
-
-//     Hashes      int `json:"hashes"`
-//     HashExpires int `json:"hahsh_expires"`
-// }
-
-// type Info struct {
-//     KeySpaces [MaxDBNumber]Keyspace
-// }
diff --git a/vendor/github.com/lunny/nodb/multi.go b/vendor/github.com/lunny/nodb/multi.go
deleted file mode 100644 (file)
index ca581ce..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-package nodb
-
-import (
-       "errors"
-       "fmt"
-)
-
-var (
-       ErrNestMulti = errors.New("nest multi not supported")
-       ErrMultiDone = errors.New("multi has been closed")
-)
-
-type Multi struct {
-       *DB
-}
-
-func (db *DB) IsInMulti() bool {
-       return db.status == DBInMulti
-}
-
-// begin a mutli to execute commands,
-// it will block any other write operations before you close the multi, unlike transaction, mutli can not rollback
-func (db *DB) Multi() (*Multi, error) {
-       if db.IsInMulti() {
-               return nil, ErrNestMulti
-       }
-
-       m := new(Multi)
-
-       m.DB = new(DB)
-       m.DB.status = DBInMulti
-
-       m.DB.l = db.l
-
-       m.l.wLock.Lock()
-
-       m.DB.sdb = db.sdb
-
-       m.DB.bucket = db.sdb
-
-       m.DB.index = db.index
-
-       m.DB.kvBatch = m.newBatch()
-       m.DB.listBatch = m.newBatch()
-       m.DB.hashBatch = m.newBatch()
-       m.DB.zsetBatch = m.newBatch()
-       m.DB.binBatch = m.newBatch()
-       m.DB.setBatch = m.newBatch()
-
-       return m, nil
-}
-
-func (m *Multi) newBatch() *batch {
-       return m.l.newBatch(m.bucket.NewWriteBatch(), &multiBatchLocker{}, nil)
-}
-
-func (m *Multi) Close() error {
-       if m.bucket == nil {
-               return ErrMultiDone
-       }
-       m.l.wLock.Unlock()
-       m.bucket = nil
-       return nil
-}
-
-func (m *Multi) Select(index int) error {
-       if index < 0 || index >= int(MaxDBNumber) {
-               return fmt.Errorf("invalid db index %d", index)
-       }
-
-       m.DB.index = uint8(index)
-       return nil
-}
diff --git a/vendor/github.com/lunny/nodb/nodb.go b/vendor/github.com/lunny/nodb/nodb.go
deleted file mode 100644 (file)
index fdd0272..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-package nodb
-
-import (
-       "fmt"
-       "sync"
-       "time"
-
-       "github.com/lunny/log"
-       "github.com/lunny/nodb/config"
-       "github.com/lunny/nodb/store"
-)
-
-type Nodb struct {
-       cfg *config.Config
-
-       ldb *store.DB
-       dbs [MaxDBNumber]*DB
-
-       quit chan struct{}
-       jobs *sync.WaitGroup
-
-       binlog *BinLog
-
-       wLock      sync.RWMutex //allow one write at same time
-       commitLock sync.Mutex   //allow one write commit at same time
-}
-
-func Open(cfg *config.Config) (*Nodb, error) {
-       if len(cfg.DataDir) == 0 {
-               cfg.DataDir = config.DefaultDataDir
-       }
-
-       ldb, err := store.Open(cfg)
-       if err != nil {
-               return nil, err
-       }
-
-       l := new(Nodb)
-
-       l.quit = make(chan struct{})
-       l.jobs = new(sync.WaitGroup)
-
-       l.ldb = ldb
-
-       if cfg.BinLog.MaxFileNum > 0 && cfg.BinLog.MaxFileSize > 0 {
-               l.binlog, err = NewBinLog(cfg)
-               if err != nil {
-                       return nil, err
-               }
-       } else {
-               l.binlog = nil
-       }
-
-       for i := uint8(0); i < MaxDBNumber; i++ {
-               l.dbs[i] = l.newDB(i)
-       }
-
-       l.activeExpireCycle()
-
-       return l, nil
-}
-
-func (l *Nodb) Close() {
-       close(l.quit)
-       l.jobs.Wait()
-
-       l.ldb.Close()
-
-       if l.binlog != nil {
-               l.binlog.Close()
-               l.binlog = nil
-       }
-}
-
-func (l *Nodb) Select(index int) (*DB, error) {
-       if index < 0 || index >= int(MaxDBNumber) {
-               return nil, fmt.Errorf("invalid db index %d", index)
-       }
-
-       return l.dbs[index], nil
-}
-
-func (l *Nodb) FlushAll() error {
-       for index, db := range l.dbs {
-               if _, err := db.FlushAll(); err != nil {
-                       log.Error("flush db %d error %s", index, err.Error())
-               }
-       }
-
-       return nil
-}
-
-// very dangerous to use
-func (l *Nodb) DataDB() *store.DB {
-       return l.ldb
-}
-
-func (l *Nodb) activeExpireCycle() {
-       var executors []*elimination = make([]*elimination, len(l.dbs))
-       for i, db := range l.dbs {
-               executors[i] = db.newEliminator()
-       }
-
-       l.jobs.Add(1)
-       go func() {
-               tick := time.NewTicker(1 * time.Second)
-               end := false
-               done := make(chan struct{})
-               for !end {
-                       select {
-                       case <-tick.C:
-                               go func() {
-                                       for _, eli := range executors {
-                                               eli.active()
-                                       }
-                                       done <- struct{}{}
-                               }()
-                               <-done
-                       case <-l.quit:
-                               end = true
-                               break
-                       }
-               }
-
-               tick.Stop()
-               l.jobs.Done()
-       }()
-}
diff --git a/vendor/github.com/lunny/nodb/nodb_db.go b/vendor/github.com/lunny/nodb/nodb_db.go
deleted file mode 100644 (file)
index f68ebaa..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-package nodb
-
-import (
-       "fmt"
-       "sync"
-
-       "github.com/lunny/nodb/store"
-)
-
-type ibucket interface {
-       Get(key []byte) ([]byte, error)
-
-       Put(key []byte, value []byte) error
-       Delete(key []byte) error
-
-       NewIterator() *store.Iterator
-
-       NewWriteBatch() store.WriteBatch
-
-       RangeIterator(min []byte, max []byte, rangeType uint8) *store.RangeLimitIterator
-       RevRangeIterator(min []byte, max []byte, rangeType uint8) *store.RangeLimitIterator
-       RangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *store.RangeLimitIterator
-       RevRangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *store.RangeLimitIterator
-}
-
-type DB struct {
-       l *Nodb
-
-       sdb *store.DB
-
-       bucket ibucket
-
-       index uint8
-
-       kvBatch   *batch
-       listBatch *batch
-       hashBatch *batch
-       zsetBatch *batch
-       binBatch  *batch
-       setBatch  *batch
-
-       status uint8
-}
-
-func (l *Nodb) newDB(index uint8) *DB {
-       d := new(DB)
-
-       d.l = l
-
-       d.sdb = l.ldb
-
-       d.bucket = d.sdb
-
-       d.status = DBAutoCommit
-       d.index = index
-
-       d.kvBatch = d.newBatch()
-       d.listBatch = d.newBatch()
-       d.hashBatch = d.newBatch()
-       d.zsetBatch = d.newBatch()
-       d.binBatch = d.newBatch()
-       d.setBatch = d.newBatch()
-
-       return d
-}
-
-func (db *DB) newBatch() *batch {
-       return db.l.newBatch(db.bucket.NewWriteBatch(), &dbBatchLocker{l: &sync.Mutex{}, wrLock: &db.l.wLock}, nil)
-}
-
-func (db *DB) Index() int {
-       return int(db.index)
-}
-
-func (db *DB) IsAutoCommit() bool {
-       return db.status == DBAutoCommit
-}
-
-func (db *DB) FlushAll() (drop int64, err error) {
-       all := [...](func() (int64, error)){
-               db.flush,
-               db.lFlush,
-               db.hFlush,
-               db.zFlush,
-               db.bFlush,
-               db.sFlush}
-
-       for _, flush := range all {
-               if n, e := flush(); e != nil {
-                       err = e
-                       return
-               } else {
-                       drop += n
-               }
-       }
-
-       return
-}
-
-func (db *DB) newEliminator() *elimination {
-       eliminator := newEliminator(db)
-
-       eliminator.regRetireContext(KVType, db.kvBatch, db.delete)
-       eliminator.regRetireContext(ListType, db.listBatch, db.lDelete)
-       eliminator.regRetireContext(HashType, db.hashBatch, db.hDelete)
-       eliminator.regRetireContext(ZSetType, db.zsetBatch, db.zDelete)
-       eliminator.regRetireContext(BitType, db.binBatch, db.bDelete)
-       eliminator.regRetireContext(SetType, db.setBatch, db.sDelete)
-
-       return eliminator
-}
-
-func (db *DB) flushRegion(t *batch, minKey []byte, maxKey []byte) (drop int64, err error) {
-       it := db.bucket.RangeIterator(minKey, maxKey, store.RangeROpen)
-       for ; it.Valid(); it.Next() {
-               t.Delete(it.RawKey())
-               drop++
-               if drop&1023 == 0 {
-                       if err = t.Commit(); err != nil {
-                               return
-                       }
-               }
-       }
-       it.Close()
-       return
-}
-
-func (db *DB) flushType(t *batch, dataType byte) (drop int64, err error) {
-       var deleteFunc func(t *batch, key []byte) int64
-       var metaDataType byte
-       switch dataType {
-       case KVType:
-               deleteFunc = db.delete
-               metaDataType = KVType
-       case ListType:
-               deleteFunc = db.lDelete
-               metaDataType = LMetaType
-       case HashType:
-               deleteFunc = db.hDelete
-               metaDataType = HSizeType
-       case ZSetType:
-               deleteFunc = db.zDelete
-               metaDataType = ZSizeType
-       case BitType:
-               deleteFunc = db.bDelete
-               metaDataType = BitMetaType
-       case SetType:
-               deleteFunc = db.sDelete
-               metaDataType = SSizeType
-       default:
-               return 0, fmt.Errorf("invalid data type: %s", TypeName[dataType])
-       }
-
-       var keys [][]byte
-       keys, err = db.scan(metaDataType, nil, 1024, false, "")
-       for len(keys) != 0 || err != nil {
-               for _, key := range keys {
-                       deleteFunc(t, key)
-                       db.rmExpire(t, dataType, key)
-
-               }
-
-               if err = t.Commit(); err != nil {
-                       return
-               } else {
-                       drop += int64(len(keys))
-               }
-               keys, err = db.scan(metaDataType, nil, 1024, false, "")
-       }
-       return
-}
diff --git a/vendor/github.com/lunny/nodb/replication.go b/vendor/github.com/lunny/nodb/replication.go
deleted file mode 100644 (file)
index f9bc951..0000000
+++ /dev/null
@@ -1,312 +0,0 @@
-package nodb
-
-import (
-       "bufio"
-       "bytes"
-       "errors"
-       "io"
-       "os"
-       "time"
-
-       "github.com/lunny/log"
-       "github.com/lunny/nodb/store/driver"
-)
-
-const (
-       maxReplBatchNum = 100
-       maxReplLogSize  = 1 * 1024 * 1024
-)
-
-var (
-       ErrSkipEvent = errors.New("skip to next event")
-)
-
-var (
-       errInvalidBinLogEvent = errors.New("invalid binglog event")
-       errInvalidBinLogFile  = errors.New("invalid binlog file")
-)
-
-type replBatch struct {
-       wb     driver.IWriteBatch
-       events [][]byte
-       l      *Nodb
-
-       lastHead *BinLogHead
-}
-
-func (b *replBatch) Commit() error {
-       b.l.commitLock.Lock()
-       defer b.l.commitLock.Unlock()
-
-       err := b.wb.Commit()
-       if err != nil {
-               b.Rollback()
-               return err
-       }
-
-       if b.l.binlog != nil {
-               if err = b.l.binlog.Log(b.events...); err != nil {
-                       b.Rollback()
-                       return err
-               }
-       }
-
-       b.events = [][]byte{}
-       b.lastHead = nil
-
-       return nil
-}
-
-func (b *replBatch) Rollback() error {
-       b.wb.Rollback()
-       b.events = [][]byte{}
-       b.lastHead = nil
-       return nil
-}
-
-func (l *Nodb) replicateEvent(b *replBatch, event []byte) error {
-       if len(event) == 0 {
-               return errInvalidBinLogEvent
-       }
-
-       b.events = append(b.events, event)
-
-       logType := uint8(event[0])
-       switch logType {
-       case BinLogTypePut:
-               return l.replicatePutEvent(b, event)
-       case BinLogTypeDeletion:
-               return l.replicateDeleteEvent(b, event)
-       default:
-               return errInvalidBinLogEvent
-       }
-}
-
-func (l *Nodb) replicatePutEvent(b *replBatch, event []byte) error {
-       key, value, err := decodeBinLogPut(event)
-       if err != nil {
-               return err
-       }
-
-       b.wb.Put(key, value)
-
-       return nil
-}
-
-func (l *Nodb) replicateDeleteEvent(b *replBatch, event []byte) error {
-       key, err := decodeBinLogDelete(event)
-       if err != nil {
-               return err
-       }
-
-       b.wb.Delete(key)
-
-       return nil
-}
-
-func ReadEventFromReader(rb io.Reader, f func(head *BinLogHead, event []byte) error) error {
-       head := &BinLogHead{}
-       var err error
-
-       for {
-               if err = head.Read(rb); err != nil {
-                       if err == io.EOF {
-                               break
-                       } else {
-                               return err
-                       }
-               }
-
-               var dataBuf bytes.Buffer
-
-               if _, err = io.CopyN(&dataBuf, rb, int64(head.PayloadLen)); err != nil {
-                       return err
-               }
-
-               err = f(head, dataBuf.Bytes())
-               if err != nil && err != ErrSkipEvent {
-                       return err
-               }
-       }
-
-       return nil
-}
-
-func (l *Nodb) ReplicateFromReader(rb io.Reader) error {
-       b := new(replBatch)
-
-       b.wb = l.ldb.NewWriteBatch()
-       b.l = l
-
-       f := func(head *BinLogHead, event []byte) error {
-               if b.lastHead == nil {
-                       b.lastHead = head
-               } else if !b.lastHead.InSameBatch(head) {
-                       if err := b.Commit(); err != nil {
-                               log.Fatal("replication error %s, skip to next", err.Error())
-                               return ErrSkipEvent
-                       }
-                       b.lastHead = head
-               }
-
-               err := l.replicateEvent(b, event)
-               if err != nil {
-                       log.Fatal("replication error %s, skip to next", err.Error())
-                       return ErrSkipEvent
-               }
-               return nil
-       }
-
-       err := ReadEventFromReader(rb, f)
-       if err != nil {
-               b.Rollback()
-               return err
-       }
-       return b.Commit()
-}
-
-func (l *Nodb) ReplicateFromData(data []byte) error {
-       rb := bytes.NewReader(data)
-
-       err := l.ReplicateFromReader(rb)
-
-       return err
-}
-
-func (l *Nodb) ReplicateFromBinLog(filePath string) error {
-       f, err := os.Open(filePath)
-       if err != nil {
-               return err
-       }
-
-       rb := bufio.NewReaderSize(f, 4096)
-
-       err = l.ReplicateFromReader(rb)
-
-       f.Close()
-
-       return err
-}
-
-// try to read events, if no events read, try to wait the new event singal until timeout seconds
-func (l *Nodb) ReadEventsToTimeout(info *BinLogAnchor, w io.Writer, timeout int) (n int, err error) {
-       lastIndex := info.LogFileIndex
-       lastPos := info.LogPos
-
-       n = 0
-       if l.binlog == nil {
-               //binlog not supported
-               info.LogFileIndex = 0
-               info.LogPos = 0
-               return
-       }
-
-       n, err = l.ReadEventsTo(info, w)
-       if err == nil && info.LogFileIndex == lastIndex && info.LogPos == lastPos {
-               //no events read
-               select {
-               case <-l.binlog.Wait():
-               case <-time.After(time.Duration(timeout) * time.Second):
-               }
-               return l.ReadEventsTo(info, w)
-       }
-       return
-}
-
-func (l *Nodb) ReadEventsTo(info *BinLogAnchor, w io.Writer) (n int, err error) {
-       n = 0
-       if l.binlog == nil {
-               //binlog not supported
-               info.LogFileIndex = 0
-               info.LogPos = 0
-               return
-       }
-
-       index := info.LogFileIndex
-       offset := info.LogPos
-
-       filePath := l.binlog.FormatLogFilePath(index)
-
-       var f *os.File
-       f, err = os.Open(filePath)
-       if os.IsNotExist(err) {
-               lastIndex := l.binlog.LogFileIndex()
-
-               if index == lastIndex {
-                       //no binlog at all
-                       info.LogPos = 0
-               } else {
-                       //slave binlog info had lost
-                       info.LogFileIndex = -1
-               }
-       }
-
-       if err != nil {
-               if os.IsNotExist(err) {
-                       err = nil
-               }
-               return
-       }
-
-       defer f.Close()
-
-       var fileSize int64
-       st, _ := f.Stat()
-       fileSize = st.Size()
-
-       if fileSize == info.LogPos {
-               return
-       }
-
-       if _, err = f.Seek(offset, os.SEEK_SET); err != nil {
-               //may be invliad seek offset
-               return
-       }
-
-       var lastHead *BinLogHead = nil
-
-       head := &BinLogHead{}
-
-       batchNum := 0
-
-       for {
-               if err = head.Read(f); err != nil {
-                       if err == io.EOF {
-                               //we will try to use next binlog
-                               if index < l.binlog.LogFileIndex() {
-                                       info.LogFileIndex += 1
-                                       info.LogPos = 0
-                               }
-                               err = nil
-                               return
-                       } else {
-                               return
-                       }
-
-               }
-
-               if lastHead == nil {
-                       lastHead = head
-                       batchNum++
-               } else if !lastHead.InSameBatch(head) {
-                       lastHead = head
-                       batchNum++
-                       if batchNum > maxReplBatchNum || n > maxReplLogSize {
-                               return
-                       }
-               }
-
-               if err = head.Write(w); err != nil {
-                       return
-               }
-
-               if _, err = io.CopyN(w, f, int64(head.PayloadLen)); err != nil {
-                       return
-               }
-
-               n += (head.Len() + int(head.PayloadLen))
-               info.LogPos = info.LogPos + int64(head.Len()) + int64(head.PayloadLen)
-       }
-
-       return
-}
diff --git a/vendor/github.com/lunny/nodb/scan.go b/vendor/github.com/lunny/nodb/scan.go
deleted file mode 100644 (file)
index e989db3..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-package nodb
-
-import (
-       "bytes"
-       "errors"
-       "regexp"
-
-       "github.com/lunny/nodb/store"
-)
-
-var errDataType = errors.New("error data type")
-var errMetaKey = errors.New("error meta key")
-
-// Seek search the prefix key
-func (db *DB) Seek(key []byte) (*store.Iterator, error) {
-       return db.seek(KVType, key)
-}
-
-func (db *DB) seek(dataType byte, key []byte) (*store.Iterator, error) {
-       var minKey []byte
-       var err error
-
-       if len(key) > 0 {
-               if err = checkKeySize(key); err != nil {
-                       return nil, err
-               }
-               if minKey, err = db.encodeMetaKey(dataType, key); err != nil {
-                       return nil, err
-               }
-
-       } else {
-               if minKey, err = db.encodeMinKey(dataType); err != nil {
-                       return nil, err
-               }
-       }
-
-       it := db.bucket.NewIterator()
-       it.Seek(minKey)
-       return it, nil
-}
-
-func (db *DB) MaxKey() ([]byte, error) {
-       return db.encodeMaxKey(KVType)
-}
-
-func (db *DB) Key(it *store.Iterator) ([]byte, error) {
-       return db.decodeMetaKey(KVType, it.Key())
-}
-
-func (db *DB) scan(dataType byte, key []byte, count int, inclusive bool, match string) ([][]byte, error) {
-       var minKey, maxKey []byte
-       var err error
-       var r *regexp.Regexp
-
-       if len(match) > 0 {
-               if r, err = regexp.Compile(match); err != nil {
-                       return nil, err
-               }
-       }
-
-       if len(key) > 0 {
-               if err = checkKeySize(key); err != nil {
-                       return nil, err
-               }
-               if minKey, err = db.encodeMetaKey(dataType, key); err != nil {
-                       return nil, err
-               }
-
-       } else {
-               if minKey, err = db.encodeMinKey(dataType); err != nil {
-                       return nil, err
-               }
-       }
-
-       if maxKey, err = db.encodeMaxKey(dataType); err != nil {
-               return nil, err
-       }
-
-       if count <= 0 {
-               count = defaultScanCount
-       }
-
-       v := make([][]byte, 0, count)
-
-       it := db.bucket.NewIterator()
-       it.Seek(minKey)
-
-       if !inclusive {
-               if it.Valid() && bytes.Equal(it.RawKey(), minKey) {
-                       it.Next()
-               }
-       }
-
-       for i := 0; it.Valid() && i < count && bytes.Compare(it.RawKey(), maxKey) < 0; it.Next() {
-               if k, err := db.decodeMetaKey(dataType, it.Key()); err != nil {
-                       continue
-               } else if r != nil && !r.Match(k) {
-                       continue
-               } else {
-                       v = append(v, k)
-                       i++
-               }
-       }
-       it.Close()
-       return v, nil
-}
-
-func (db *DB) encodeMinKey(dataType byte) ([]byte, error) {
-       return db.encodeMetaKey(dataType, nil)
-}
-
-func (db *DB) encodeMaxKey(dataType byte) ([]byte, error) {
-       k, err := db.encodeMetaKey(dataType, nil)
-       if err != nil {
-               return nil, err
-       }
-       k[len(k)-1] = dataType + 1
-       return k, nil
-}
-
-func (db *DB) encodeMetaKey(dataType byte, key []byte) ([]byte, error) {
-       switch dataType {
-       case KVType:
-               return db.encodeKVKey(key), nil
-       case LMetaType:
-               return db.lEncodeMetaKey(key), nil
-       case HSizeType:
-               return db.hEncodeSizeKey(key), nil
-       case ZSizeType:
-               return db.zEncodeSizeKey(key), nil
-       case BitMetaType:
-               return db.bEncodeMetaKey(key), nil
-       case SSizeType:
-               return db.sEncodeSizeKey(key), nil
-       default:
-               return nil, errDataType
-       }
-}
-func (db *DB) decodeMetaKey(dataType byte, ek []byte) ([]byte, error) {
-       if len(ek) < 2 || ek[0] != db.index || ek[1] != dataType {
-               return nil, errMetaKey
-       }
-       return ek[2:], nil
-}
diff --git a/vendor/github.com/lunny/nodb/store/db.go b/vendor/github.com/lunny/nodb/store/db.go
deleted file mode 100644 (file)
index 00a8831..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-package store
-
-import (
-       "github.com/lunny/nodb/store/driver"
-)
-
-type DB struct {
-       driver.IDB
-}
-
-func (db *DB) NewIterator() *Iterator {
-       it := new(Iterator)
-       it.it = db.IDB.NewIterator()
-
-       return it
-}
-
-func (db *DB) NewWriteBatch() WriteBatch {
-       return db.IDB.NewWriteBatch()
-}
-
-func (db *DB) NewSnapshot() (*Snapshot, error) {
-       var err error
-       s := &Snapshot{}
-       if s.ISnapshot, err = db.IDB.NewSnapshot(); err != nil {
-               return nil, err
-       }
-
-       return s, nil
-}
-
-func (db *DB) RangeIterator(min []byte, max []byte, rangeType uint8) *RangeLimitIterator {
-       return NewRangeLimitIterator(db.NewIterator(), &Range{min, max, rangeType}, &Limit{0, -1})
-}
-
-func (db *DB) RevRangeIterator(min []byte, max []byte, rangeType uint8) *RangeLimitIterator {
-       return NewRevRangeLimitIterator(db.NewIterator(), &Range{min, max, rangeType}, &Limit{0, -1})
-}
-
-//count < 0, unlimit.
-//
-//offset must >= 0, if < 0, will get nothing.
-func (db *DB) RangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *RangeLimitIterator {
-       return NewRangeLimitIterator(db.NewIterator(), &Range{min, max, rangeType}, &Limit{offset, count})
-}
-
-//count < 0, unlimit.
-//
-//offset must >= 0, if < 0, will get nothing.
-func (db *DB) RevRangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *RangeLimitIterator {
-       return NewRevRangeLimitIterator(db.NewIterator(), &Range{min, max, rangeType}, &Limit{offset, count})
-}
-
-func (db *DB) Begin() (*Tx, error) {
-       tx, err := db.IDB.Begin()
-       if err != nil {
-               return nil, err
-       }
-
-       return &Tx{tx}, nil
-}
diff --git a/vendor/github.com/lunny/nodb/store/driver/batch.go b/vendor/github.com/lunny/nodb/store/driver/batch.go
deleted file mode 100644 (file)
index 6b79c21..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-package driver
-
-type BatchPuter interface {
-       BatchPut([]Write) error
-}
-
-type Write struct {
-       Key   []byte
-       Value []byte
-}
-
-type WriteBatch struct {
-       batch BatchPuter
-       wb    []Write
-}
-
-func (w *WriteBatch) Put(key, value []byte) {
-       if value == nil {
-               value = []byte{}
-       }
-       w.wb = append(w.wb, Write{key, value})
-}
-
-func (w *WriteBatch) Delete(key []byte) {
-       w.wb = append(w.wb, Write{key, nil})
-}
-
-func (w *WriteBatch) Commit() error {
-       return w.batch.BatchPut(w.wb)
-}
-
-func (w *WriteBatch) Rollback() error {
-       w.wb = w.wb[0:0]
-       return nil
-}
-
-func NewWriteBatch(puter BatchPuter) IWriteBatch {
-       return &WriteBatch{puter, []Write{}}
-}
diff --git a/vendor/github.com/lunny/nodb/store/driver/driver.go b/vendor/github.com/lunny/nodb/store/driver/driver.go
deleted file mode 100644 (file)
index 6da67df..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-package driver
-
-import (
-       "errors"
-)
-
-var (
-       ErrTxSupport = errors.New("transaction is not supported")
-)
-
-type IDB interface {
-       Close() error
-
-       Get(key []byte) ([]byte, error)
-
-       Put(key []byte, value []byte) error
-       Delete(key []byte) error
-
-       NewIterator() IIterator
-
-       NewWriteBatch() IWriteBatch
-
-       NewSnapshot() (ISnapshot, error)
-
-       Begin() (Tx, error)
-}
-
-type ISnapshot interface {
-       Get(key []byte) ([]byte, error)
-       NewIterator() IIterator
-       Close()
-}
-
-type IIterator interface {
-       Close() error
-
-       First()
-       Last()
-       Seek(key []byte)
-
-       Next()
-       Prev()
-
-       Valid() bool
-
-       Key() []byte
-       Value() []byte
-}
-
-type IWriteBatch interface {
-       Put(key []byte, value []byte)
-       Delete(key []byte)
-       Commit() error
-       Rollback() error
-}
-
-type Tx interface {
-       Get(key []byte) ([]byte, error)
-       Put(key []byte, value []byte) error
-       Delete(key []byte) error
-
-       NewIterator() IIterator
-       NewWriteBatch() IWriteBatch
-
-       Commit() error
-       Rollback() error
-}
diff --git a/vendor/github.com/lunny/nodb/store/driver/store.go b/vendor/github.com/lunny/nodb/store/driver/store.go
deleted file mode 100644 (file)
index 173431d..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-package driver
-
-import (
-       "fmt"
-
-       "github.com/lunny/nodb/config"
-)
-
-type Store interface {
-       String() string
-       Open(path string, cfg *config.Config) (IDB, error)
-       Repair(path string, cfg *config.Config) error
-}
-
-var dbs = map[string]Store{}
-
-func Register(s Store) {
-       name := s.String()
-       if _, ok := dbs[name]; ok {
-               panic(fmt.Errorf("store %s is registered", s))
-       }
-
-       dbs[name] = s
-}
-
-func ListStores() []string {
-       s := []string{}
-       for k, _ := range dbs {
-               s = append(s, k)
-       }
-
-       return s
-}
-
-func GetStore(cfg *config.Config) (Store, error) {
-       if len(cfg.DBName) == 0 {
-               cfg.DBName = config.DefaultDBName
-       }
-
-       s, ok := dbs[cfg.DBName]
-       if !ok {
-               return nil, fmt.Errorf("store %s is not registered", cfg.DBName)
-       }
-
-       return s, nil
-}
diff --git a/vendor/github.com/lunny/nodb/store/goleveldb/batch.go b/vendor/github.com/lunny/nodb/store/goleveldb/batch.go
deleted file mode 100644 (file)
index b17e85e..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-package goleveldb
-
-import (
-       "github.com/syndtr/goleveldb/leveldb"
-)
-
-type WriteBatch struct {
-       db     *DB
-       wbatch *leveldb.Batch
-}
-
-func (w *WriteBatch) Put(key, value []byte) {
-       w.wbatch.Put(key, value)
-}
-
-func (w *WriteBatch) Delete(key []byte) {
-       w.wbatch.Delete(key)
-}
-
-func (w *WriteBatch) Commit() error {
-       return w.db.db.Write(w.wbatch, nil)
-}
-
-func (w *WriteBatch) Rollback() error {
-       w.wbatch.Reset()
-       return nil
-}
diff --git a/vendor/github.com/lunny/nodb/store/goleveldb/const.go b/vendor/github.com/lunny/nodb/store/goleveldb/const.go
deleted file mode 100644 (file)
index 2fffa7c..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-package goleveldb
-
-const DBName = "goleveldb"
-const MemDBName = "memory"
diff --git a/vendor/github.com/lunny/nodb/store/goleveldb/db.go b/vendor/github.com/lunny/nodb/store/goleveldb/db.go
deleted file mode 100644 (file)
index a36e87f..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-package goleveldb
-
-import (
-       "github.com/syndtr/goleveldb/leveldb"
-       "github.com/syndtr/goleveldb/leveldb/cache"
-       "github.com/syndtr/goleveldb/leveldb/filter"
-       "github.com/syndtr/goleveldb/leveldb/opt"
-       "github.com/syndtr/goleveldb/leveldb/storage"
-
-       "github.com/lunny/nodb/config"
-       "github.com/lunny/nodb/store/driver"
-
-       "os"
-)
-
-const defaultFilterBits int = 10
-
-type Store struct {
-}
-
-func (s Store) String() string {
-       return DBName
-}
-
-type MemStore struct {
-}
-
-func (s MemStore) String() string {
-       return MemDBName
-}
-
-type DB struct {
-       path string
-
-       cfg *config.LevelDBConfig
-
-       db *leveldb.DB
-
-       opts *opt.Options
-
-       iteratorOpts *opt.ReadOptions
-
-       cache cache.Cache
-
-       filter filter.Filter
-}
-
-func (s Store) Open(path string, cfg *config.Config) (driver.IDB, error) {
-       if err := os.MkdirAll(path, os.ModePerm); err != nil {
-               return nil, err
-       }
-
-       db := new(DB)
-       db.path = path
-       db.cfg = &cfg.LevelDB
-
-       db.initOpts()
-
-       var err error
-       db.db, err = leveldb.OpenFile(db.path, db.opts)
-
-       if err != nil {
-               return nil, err
-       }
-
-       return db, nil
-}
-
-func (s Store) Repair(path string, cfg *config.Config) error {
-       db, err := leveldb.RecoverFile(path, newOptions(&cfg.LevelDB))
-       if err != nil {
-               return err
-       }
-
-       db.Close()
-       return nil
-}
-
-func (s MemStore) Open(path string, cfg *config.Config) (driver.IDB, error) {
-       db := new(DB)
-       db.path = path
-       db.cfg = &cfg.LevelDB
-
-       db.initOpts()
-
-       var err error
-       db.db, err = leveldb.Open(storage.NewMemStorage(), db.opts)
-       if err != nil {
-               return nil, err
-       }
-
-       return db, nil
-}
-
-func (s MemStore) Repair(path string, cfg *config.Config) error {
-       return nil
-}
-
-func (db *DB) initOpts() {
-       db.opts = newOptions(db.cfg)
-
-       db.iteratorOpts = &opt.ReadOptions{}
-       db.iteratorOpts.DontFillCache = true
-}
-
-func newOptions(cfg *config.LevelDBConfig) *opt.Options {
-       opts := &opt.Options{}
-       opts.ErrorIfMissing = false
-
-       cfg.Adjust()
-
-       //opts.BlockCacher = cache.NewLRU(cfg.CacheSize)
-       opts.BlockCacheCapacity = cfg.CacheSize
-
-       //we must use bloomfilter
-       opts.Filter = filter.NewBloomFilter(defaultFilterBits)
-
-       if !cfg.Compression {
-               opts.Compression = opt.NoCompression
-       } else {
-               opts.Compression = opt.SnappyCompression
-       }
-
-       opts.BlockSize = cfg.BlockSize
-       opts.WriteBuffer = cfg.WriteBufferSize
-
-       return opts
-}
-
-func (db *DB) Close() error {
-       return db.db.Close()
-}
-
-func (db *DB) Put(key, value []byte) error {
-       return db.db.Put(key, value, nil)
-}
-
-func (db *DB) Get(key []byte) ([]byte, error) {
-       v, err := db.db.Get(key, nil)
-       if err == leveldb.ErrNotFound {
-               return nil, nil
-       }
-       return v, nil
-}
-
-func (db *DB) Delete(key []byte) error {
-       return db.db.Delete(key, nil)
-}
-
-func (db *DB) NewWriteBatch() driver.IWriteBatch {
-       wb := &WriteBatch{
-               db:     db,
-               wbatch: new(leveldb.Batch),
-       }
-       return wb
-}
-
-func (db *DB) NewIterator() driver.IIterator {
-       it := &Iterator{
-               db.db.NewIterator(nil, db.iteratorOpts),
-       }
-
-       return it
-}
-
-func (db *DB) Begin() (driver.Tx, error) {
-       return nil, driver.ErrTxSupport
-}
-
-func (db *DB) NewSnapshot() (driver.ISnapshot, error) {
-       snapshot, err := db.db.GetSnapshot()
-       if err != nil {
-               return nil, err
-       }
-
-       s := &Snapshot{
-               db:  db,
-               snp: snapshot,
-       }
-
-       return s, nil
-}
-
-func init() {
-       driver.Register(Store{})
-       driver.Register(MemStore{})
-}
diff --git a/vendor/github.com/lunny/nodb/store/goleveldb/iterator.go b/vendor/github.com/lunny/nodb/store/goleveldb/iterator.go
deleted file mode 100644 (file)
index c1fd8b5..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-package goleveldb
-
-import (
-       "github.com/syndtr/goleveldb/leveldb/iterator"
-)
-
-type Iterator struct {
-       it iterator.Iterator
-}
-
-func (it *Iterator) Key() []byte {
-       return it.it.Key()
-}
-
-func (it *Iterator) Value() []byte {
-       return it.it.Value()
-}
-
-func (it *Iterator) Close() error {
-       if it.it != nil {
-               it.it.Release()
-               it.it = nil
-       }
-       return nil
-}
-
-func (it *Iterator) Valid() bool {
-       return it.it.Valid()
-}
-
-func (it *Iterator) Next() {
-       it.it.Next()
-}
-
-func (it *Iterator) Prev() {
-       it.it.Prev()
-}
-
-func (it *Iterator) First() {
-       it.it.First()
-}
-
-func (it *Iterator) Last() {
-       it.it.Last()
-}
-
-func (it *Iterator) Seek(key []byte) {
-       it.it.Seek(key)
-}
diff --git a/vendor/github.com/lunny/nodb/store/goleveldb/snapshot.go b/vendor/github.com/lunny/nodb/store/goleveldb/snapshot.go
deleted file mode 100644 (file)
index fe2b409..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package goleveldb
-
-import (
-       "github.com/lunny/nodb/store/driver"
-       "github.com/syndtr/goleveldb/leveldb"
-)
-
-type Snapshot struct {
-       db  *DB
-       snp *leveldb.Snapshot
-}
-
-func (s *Snapshot) Get(key []byte) ([]byte, error) {
-       return s.snp.Get(key, s.db.iteratorOpts)
-}
-
-func (s *Snapshot) NewIterator() driver.IIterator {
-       it := &Iterator{
-               s.snp.NewIterator(nil, s.db.iteratorOpts),
-       }
-       return it
-}
-
-func (s *Snapshot) Close() {
-       s.snp.Release()
-}
diff --git a/vendor/github.com/lunny/nodb/store/iterator.go b/vendor/github.com/lunny/nodb/store/iterator.go
deleted file mode 100644 (file)
index 27bf689..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-package store
-
-import (
-       "bytes"
-
-       "github.com/lunny/nodb/store/driver"
-)
-
-const (
-       IteratorForward  uint8 = 0
-       IteratorBackward uint8 = 1
-)
-
-const (
-       RangeClose uint8 = 0x00
-       RangeLOpen uint8 = 0x01
-       RangeROpen uint8 = 0x10
-       RangeOpen  uint8 = 0x11
-)
-
-// min must less or equal than max
-//
-// range type:
-//
-//  close: [min, max]
-//  open: (min, max)
-//  lopen: (min, max]
-//  ropen: [min, max)
-//
-type Range struct {
-       Min []byte
-       Max []byte
-
-       Type uint8
-}
-
-type Limit struct {
-       Offset int
-       Count  int
-}
-
-type Iterator struct {
-       it driver.IIterator
-}
-
-// Returns a copy of key.
-func (it *Iterator) Key() []byte {
-       k := it.it.Key()
-       if k == nil {
-               return nil
-       }
-
-       return append([]byte{}, k...)
-}
-
-// Returns a copy of value.
-func (it *Iterator) Value() []byte {
-       v := it.it.Value()
-       if v == nil {
-               return nil
-       }
-
-       return append([]byte{}, v...)
-}
-
-// Returns a reference of key.
-// you must be careful that it will be changed after next iterate.
-func (it *Iterator) RawKey() []byte {
-       return it.it.Key()
-}
-
-// Returns a reference of value.
-// you must be careful that it will be changed after next iterate.
-func (it *Iterator) RawValue() []byte {
-       return it.it.Value()
-}
-
-// Copy key to b, if b len is small or nil, returns a new one.
-func (it *Iterator) BufKey(b []byte) []byte {
-       k := it.RawKey()
-       if k == nil {
-               return nil
-       }
-       if b == nil {
-               b = []byte{}
-       }
-
-       b = b[0:0]
-       return append(b, k...)
-}
-
-// Copy value to b, if b len is small or nil, returns a new one.
-func (it *Iterator) BufValue(b []byte) []byte {
-       v := it.RawValue()
-       if v == nil {
-               return nil
-       }
-
-       if b == nil {
-               b = []byte{}
-       }
-
-       b = b[0:0]
-       return append(b, v...)
-}
-
-func (it *Iterator) Close() {
-       if it.it != nil {
-               it.it.Close()
-               it.it = nil
-       }
-}
-
-func (it *Iterator) Valid() bool {
-       return it.it.Valid()
-}
-
-func (it *Iterator) Next() {
-       it.it.Next()
-}
-
-func (it *Iterator) Prev() {
-       it.it.Prev()
-}
-
-func (it *Iterator) SeekToFirst() {
-       it.it.First()
-}
-
-func (it *Iterator) SeekToLast() {
-       it.it.Last()
-}
-
-func (it *Iterator) Seek(key []byte) {
-       it.it.Seek(key)
-}
-
-// Finds by key, if not found, nil returns.
-func (it *Iterator) Find(key []byte) []byte {
-       it.Seek(key)
-       if it.Valid() {
-               k := it.RawKey()
-               if k == nil {
-                       return nil
-               } else if bytes.Equal(k, key) {
-                       return it.Value()
-               }
-       }
-
-       return nil
-}
-
-// Finds by key, if not found, nil returns, else a reference of value returns.
-// you must be careful that it will be changed after next iterate.
-func (it *Iterator) RawFind(key []byte) []byte {
-       it.Seek(key)
-       if it.Valid() {
-               k := it.RawKey()
-               if k == nil {
-                       return nil
-               } else if bytes.Equal(k, key) {
-                       return it.RawValue()
-               }
-       }
-
-       return nil
-}
-
-type RangeLimitIterator struct {
-       it *Iterator
-
-       r *Range
-       l *Limit
-
-       step int
-
-       //0 for IteratorForward, 1 for IteratorBackward
-       direction uint8
-}
-
-func (it *RangeLimitIterator) Key() []byte {
-       return it.it.Key()
-}
-
-func (it *RangeLimitIterator) Value() []byte {
-       return it.it.Value()
-}
-
-func (it *RangeLimitIterator) RawKey() []byte {
-       return it.it.RawKey()
-}
-
-func (it *RangeLimitIterator) RawValue() []byte {
-       return it.it.RawValue()
-}
-
-func (it *RangeLimitIterator) BufKey(b []byte) []byte {
-       return it.it.BufKey(b)
-}
-
-func (it *RangeLimitIterator) BufValue(b []byte) []byte {
-       return it.it.BufValue(b)
-}
-
-func (it *RangeLimitIterator) Valid() bool {
-       if it.l.Offset < 0 {
-               return false
-       } else if !it.it.Valid() {
-               return false
-       } else if it.l.Count >= 0 && it.step >= it.l.Count {
-               return false
-       }
-
-       if it.direction == IteratorForward {
-               if it.r.Max != nil {
-                       r := bytes.Compare(it.it.RawKey(), it.r.Max)
-                       if it.r.Type&RangeROpen > 0 {
-                               return !(r >= 0)
-                       } else {
-                               return !(r > 0)
-                       }
-               }
-       } else {
-               if it.r.Min != nil {
-                       r := bytes.Compare(it.it.RawKey(), it.r.Min)
-                       if it.r.Type&RangeLOpen > 0 {
-                               return !(r <= 0)
-                       } else {
-                               return !(r < 0)
-                       }
-               }
-       }
-
-       return true
-}
-
-func (it *RangeLimitIterator) Next() {
-       it.step++
-
-       if it.direction == IteratorForward {
-               it.it.Next()
-       } else {
-               it.it.Prev()
-       }
-}
-
-func (it *RangeLimitIterator) Close() {
-       it.it.Close()
-}
-
-func NewRangeLimitIterator(i *Iterator, r *Range, l *Limit) *RangeLimitIterator {
-       return rangeLimitIterator(i, r, l, IteratorForward)
-}
-
-func NewRevRangeLimitIterator(i *Iterator, r *Range, l *Limit) *RangeLimitIterator {
-       return rangeLimitIterator(i, r, l, IteratorBackward)
-}
-
-func NewRangeIterator(i *Iterator, r *Range) *RangeLimitIterator {
-       return rangeLimitIterator(i, r, &Limit{0, -1}, IteratorForward)
-}
-
-func NewRevRangeIterator(i *Iterator, r *Range) *RangeLimitIterator {
-       return rangeLimitIterator(i, r, &Limit{0, -1}, IteratorBackward)
-}
-
-func rangeLimitIterator(i *Iterator, r *Range, l *Limit, direction uint8) *RangeLimitIterator {
-       it := new(RangeLimitIterator)
-
-       it.it = i
-
-       it.r = r
-       it.l = l
-       it.direction = direction
-
-       it.step = 0
-
-       if l.Offset < 0 {
-               return it
-       }
-
-       if direction == IteratorForward {
-               if r.Min == nil {
-                       it.it.SeekToFirst()
-               } else {
-                       it.it.Seek(r.Min)
-
-                       if r.Type&RangeLOpen > 0 {
-                               if it.it.Valid() && bytes.Equal(it.it.RawKey(), r.Min) {
-                                       it.it.Next()
-                               }
-                       }
-               }
-       } else {
-               if r.Max == nil {
-                       it.it.SeekToLast()
-               } else {
-                       it.it.Seek(r.Max)
-
-                       if !it.it.Valid() {
-                               it.it.SeekToLast()
-                       } else {
-                               if !bytes.Equal(it.it.RawKey(), r.Max) {
-                                       it.it.Prev()
-                               }
-                       }
-
-                       if r.Type&RangeROpen > 0 {
-                               if it.it.Valid() && bytes.Equal(it.it.RawKey(), r.Max) {
-                                       it.it.Prev()
-                               }
-                       }
-               }
-       }
-
-       for i := 0; i < l.Offset; i++ {
-               if it.it.Valid() {
-                       if it.direction == IteratorForward {
-                               it.it.Next()
-                       } else {
-                               it.it.Prev()
-                       }
-               }
-       }
-
-       return it
-}
diff --git a/vendor/github.com/lunny/nodb/store/snapshot.go b/vendor/github.com/lunny/nodb/store/snapshot.go
deleted file mode 100644 (file)
index 75ba049..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-package store
-
-import (
-       "github.com/lunny/nodb/store/driver"
-)
-
-type Snapshot struct {
-       driver.ISnapshot
-}
-
-func (s *Snapshot) NewIterator() *Iterator {
-       it := new(Iterator)
-       it.it = s.ISnapshot.NewIterator()
-
-       return it
-}
diff --git a/vendor/github.com/lunny/nodb/store/store.go b/vendor/github.com/lunny/nodb/store/store.go
deleted file mode 100644 (file)
index 5d0ade1..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-package store
-
-import (
-       "fmt"
-       "os"
-       "path"
-       "github.com/lunny/nodb/config"
-       "github.com/lunny/nodb/store/driver"
-
-       _ "github.com/lunny/nodb/store/goleveldb"
-)
-
-func getStorePath(cfg *config.Config) string {
-       return path.Join(cfg.DataDir, fmt.Sprintf("%s_data", cfg.DBName))
-}
-
-func Open(cfg *config.Config) (*DB, error) {
-       s, err := driver.GetStore(cfg)
-       if err != nil {
-               return nil, err
-       }
-
-       path := getStorePath(cfg)
-
-       if err := os.MkdirAll(path, os.ModePerm); err != nil {
-               return nil, err
-       }
-
-       idb, err := s.Open(path, cfg)
-       if err != nil {
-               return nil, err
-       }
-
-       db := &DB{idb}
-
-       return db, nil
-}
-
-func Repair(cfg *config.Config) error {
-       s, err := driver.GetStore(cfg)
-       if err != nil {
-               return err
-       }
-
-       path := getStorePath(cfg)
-
-       return s.Repair(path, cfg)
-}
-
-func init() {
-}
diff --git a/vendor/github.com/lunny/nodb/store/tx.go b/vendor/github.com/lunny/nodb/store/tx.go
deleted file mode 100644 (file)
index 32bcbcd..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-package store
-
-import (
-       "github.com/lunny/nodb/store/driver"
-)
-
-type Tx struct {
-       driver.Tx
-}
-
-func (tx *Tx) NewIterator() *Iterator {
-       it := new(Iterator)
-       it.it = tx.Tx.NewIterator()
-
-       return it
-}
-
-func (tx *Tx) NewWriteBatch() WriteBatch {
-       return tx.Tx.NewWriteBatch()
-}
-
-func (tx *Tx) RangeIterator(min []byte, max []byte, rangeType uint8) *RangeLimitIterator {
-       return NewRangeLimitIterator(tx.NewIterator(), &Range{min, max, rangeType}, &Limit{0, -1})
-}
-
-func (tx *Tx) RevRangeIterator(min []byte, max []byte, rangeType uint8) *RangeLimitIterator {
-       return NewRevRangeLimitIterator(tx.NewIterator(), &Range{min, max, rangeType}, &Limit{0, -1})
-}
-
-//count < 0, unlimit.
-//
-//offset must >= 0, if < 0, will get nothing.
-func (tx *Tx) RangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *RangeLimitIterator {
-       return NewRangeLimitIterator(tx.NewIterator(), &Range{min, max, rangeType}, &Limit{offset, count})
-}
-
-//count < 0, unlimit.
-//
-//offset must >= 0, if < 0, will get nothing.
-func (tx *Tx) RevRangeLimitIterator(min []byte, max []byte, rangeType uint8, offset int, count int) *RangeLimitIterator {
-       return NewRevRangeLimitIterator(tx.NewIterator(), &Range{min, max, rangeType}, &Limit{offset, count})
-}
diff --git a/vendor/github.com/lunny/nodb/store/writebatch.go b/vendor/github.com/lunny/nodb/store/writebatch.go
deleted file mode 100644 (file)
index 23e079e..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-package store
-
-import (
-       "github.com/lunny/nodb/store/driver"
-)
-
-type WriteBatch interface {
-       driver.IWriteBatch
-}
diff --git a/vendor/github.com/lunny/nodb/t_bit.go b/vendor/github.com/lunny/nodb/t_bit.go
deleted file mode 100644 (file)
index 930d4ba..0000000
+++ /dev/null
@@ -1,922 +0,0 @@
-package nodb
-
-import (
-       "encoding/binary"
-       "errors"
-       "sort"
-       "time"
-
-       "github.com/lunny/nodb/store"
-)
-
-const (
-       OPand uint8 = iota + 1
-       OPor
-       OPxor
-       OPnot
-)
-
-type BitPair struct {
-       Pos int32
-       Val uint8
-}
-
-type segBitInfo struct {
-       Seq uint32
-       Off uint32
-       Val uint8
-}
-
-type segBitInfoArray []segBitInfo
-
-const (
-       // byte
-       segByteWidth uint32 = 9
-       segByteSize  uint32 = 1 << segByteWidth
-
-       // bit
-       segBitWidth uint32 = segByteWidth + 3
-       segBitSize  uint32 = segByteSize << 3
-
-       maxByteSize uint32 = 8 << 20
-       maxSegCount uint32 = maxByteSize / segByteSize
-
-       minSeq uint32 = 0
-       maxSeq uint32 = uint32((maxByteSize << 3) - 1)
-)
-
-var bitsInByte = [256]int32{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3,
-       4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3,
-       3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4,
-       5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4,
-       3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4,
-       5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2,
-       2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3,
-       4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
-       3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4,
-       5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6,
-       6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5,
-       6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8}
-
-var fillBits = [...]uint8{1, 3, 7, 15, 31, 63, 127, 255}
-
-var emptySegment []byte = make([]byte, segByteSize, segByteSize)
-
-var fillSegment []byte = func() []byte {
-       data := make([]byte, segByteSize, segByteSize)
-       for i := uint32(0); i < segByteSize; i++ {
-               data[i] = 0xff
-       }
-       return data
-}()
-
-var errBinKey = errors.New("invalid bin key")
-var errOffset = errors.New("invalid offset")
-var errDuplicatePos = errors.New("duplicate bit pos")
-
-func getBit(sz []byte, offset uint32) uint8 {
-       index := offset >> 3
-       if index >= uint32(len(sz)) {
-               return 0 // error("overflow")
-       }
-
-       offset -= index << 3
-       return sz[index] >> offset & 1
-}
-
-func setBit(sz []byte, offset uint32, val uint8) bool {
-       if val != 1 && val != 0 {
-               return false // error("invalid val")
-       }
-
-       index := offset >> 3
-       if index >= uint32(len(sz)) {
-               return false // error("overflow")
-       }
-
-       offset -= index << 3
-       if sz[index]>>offset&1 != val {
-               sz[index] ^= (1 << offset)
-       }
-       return true
-}
-
-func (datas segBitInfoArray) Len() int {
-       return len(datas)
-}
-
-func (datas segBitInfoArray) Less(i, j int) bool {
-       res := (datas)[i].Seq < (datas)[j].Seq
-       if !res && (datas)[i].Seq == (datas)[j].Seq {
-               res = (datas)[i].Off < (datas)[j].Off
-       }
-       return res
-}
-
-func (datas segBitInfoArray) Swap(i, j int) {
-       datas[i], datas[j] = datas[j], datas[i]
-}
-
-func (db *DB) bEncodeMetaKey(key []byte) []byte {
-       mk := make([]byte, len(key)+2)
-       mk[0] = db.index
-       mk[1] = BitMetaType
-
-       copy(mk[2:], key)
-       return mk
-}
-
-func (db *DB) bDecodeMetaKey(bkey []byte) ([]byte, error) {
-       if len(bkey) < 2 || bkey[0] != db.index || bkey[1] != BitMetaType {
-               return nil, errBinKey
-       }
-
-       return bkey[2:], nil
-}
-
-func (db *DB) bEncodeBinKey(key []byte, seq uint32) []byte {
-       bk := make([]byte, len(key)+8)
-
-       pos := 0
-       bk[pos] = db.index
-       pos++
-       bk[pos] = BitType
-       pos++
-
-       binary.BigEndian.PutUint16(bk[pos:], uint16(len(key)))
-       pos += 2
-
-       copy(bk[pos:], key)
-       pos += len(key)
-
-       binary.BigEndian.PutUint32(bk[pos:], seq)
-
-       return bk
-}
-
-func (db *DB) bDecodeBinKey(bkey []byte) (key []byte, seq uint32, err error) {
-       if len(bkey) < 8 || bkey[0] != db.index {
-               err = errBinKey
-               return
-       }
-
-       keyLen := binary.BigEndian.Uint16(bkey[2:4])
-       if int(keyLen+8) != len(bkey) {
-               err = errBinKey
-               return
-       }
-
-       key = bkey[4 : 4+keyLen]
-       seq = uint32(binary.BigEndian.Uint32(bkey[4+keyLen:]))
-       return
-}
-
-func (db *DB) bCapByteSize(seq uint32, off uint32) uint32 {
-       var offByteSize uint32 = (off >> 3) + 1
-       if offByteSize > segByteSize {
-               offByteSize = segByteSize
-       }
-
-       return seq<<segByteWidth + offByteSize
-}
-
-func (db *DB) bParseOffset(key []byte, offset int32) (seq uint32, off uint32, err error) {
-       if offset < 0 {
-               if tailSeq, tailOff, e := db.bGetMeta(key); e != nil {
-                       err = e
-                       return
-               } else if tailSeq >= 0 {
-                       offset += int32((uint32(tailSeq)<<segBitWidth | uint32(tailOff)) + 1)
-                       if offset < 0 {
-                               err = errOffset
-                               return
-                       }
-               }
-       }
-
-       off = uint32(offset)
-
-       seq = off >> segBitWidth
-       off &= (segBitSize - 1)
-       return
-}
-
-func (db *DB) bGetMeta(key []byte) (tailSeq int32, tailOff int32, err error) {
-       var v []byte
-
-       mk := db.bEncodeMetaKey(key)
-       v, err = db.bucket.Get(mk)
-       if err != nil {
-               return
-       }
-
-       if v != nil {
-               tailSeq = int32(binary.LittleEndian.Uint32(v[0:4]))
-               tailOff = int32(binary.LittleEndian.Uint32(v[4:8]))
-       } else {
-               tailSeq = -1
-               tailOff = -1
-       }
-       return
-}
-
-func (db *DB) bSetMeta(t *batch, key []byte, tailSeq uint32, tailOff uint32) {
-       ek := db.bEncodeMetaKey(key)
-
-       buf := make([]byte, 8)
-       binary.LittleEndian.PutUint32(buf[0:4], tailSeq)
-       binary.LittleEndian.PutUint32(buf[4:8], tailOff)
-
-       t.Put(ek, buf)
-       return
-}
-
-func (db *DB) bUpdateMeta(t *batch, key []byte, seq uint32, off uint32) (tailSeq uint32, tailOff uint32, err error) {
-       var tseq, toff int32
-       var update bool = false
-
-       if tseq, toff, err = db.bGetMeta(key); err != nil {
-               return
-       } else if tseq < 0 {
-               update = true
-       } else {
-               tailSeq = uint32(MaxInt32(tseq, 0))
-               tailOff = uint32(MaxInt32(toff, 0))
-               update = (seq > tailSeq || (seq == tailSeq && off > tailOff))
-       }
-
-       if update {
-               db.bSetMeta(t, key, seq, off)
-               tailSeq = seq
-               tailOff = off
-       }
-       return
-}
-
-func (db *DB) bDelete(t *batch, key []byte) (drop int64) {
-       mk := db.bEncodeMetaKey(key)
-       t.Delete(mk)
-
-       minKey := db.bEncodeBinKey(key, minSeq)
-       maxKey := db.bEncodeBinKey(key, maxSeq)
-       it := db.bucket.RangeIterator(minKey, maxKey, store.RangeClose)
-       for ; it.Valid(); it.Next() {
-               t.Delete(it.RawKey())
-               drop++
-       }
-       it.Close()
-
-       return drop
-}
-
-func (db *DB) bGetSegment(key []byte, seq uint32) ([]byte, []byte, error) {
-       bk := db.bEncodeBinKey(key, seq)
-       segment, err := db.bucket.Get(bk)
-       if err != nil {
-               return bk, nil, err
-       }
-       return bk, segment, nil
-}
-
-func (db *DB) bAllocateSegment(key []byte, seq uint32) ([]byte, []byte, error) {
-       bk, segment, err := db.bGetSegment(key, seq)
-       if err == nil && segment == nil {
-               segment = make([]byte, segByteSize, segByteSize)
-       }
-       return bk, segment, err
-}
-
-func (db *DB) bIterator(key []byte) *store.RangeLimitIterator {
-       sk := db.bEncodeBinKey(key, minSeq)
-       ek := db.bEncodeBinKey(key, maxSeq)
-       return db.bucket.RangeIterator(sk, ek, store.RangeClose)
-}
-
-func (db *DB) bSegAnd(a []byte, b []byte, res *[]byte) {
-       if a == nil || b == nil {
-               *res = nil
-               return
-       }
-
-       data := *res
-       if data == nil {
-               data = make([]byte, segByteSize, segByteSize)
-               *res = data
-       }
-
-       for i := uint32(0); i < segByteSize; i++ {
-               data[i] = a[i] & b[i]
-       }
-       return
-}
-
-func (db *DB) bSegOr(a []byte, b []byte, res *[]byte) {
-       if a == nil || b == nil {
-               if a == nil && b == nil {
-                       *res = nil
-               } else if a == nil {
-                       *res = b
-               } else {
-                       *res = a
-               }
-               return
-       }
-
-       data := *res
-       if data == nil {
-               data = make([]byte, segByteSize, segByteSize)
-               *res = data
-       }
-
-       for i := uint32(0); i < segByteSize; i++ {
-               data[i] = a[i] | b[i]
-       }
-       return
-}
-
-func (db *DB) bSegXor(a []byte, b []byte, res *[]byte) {
-       if a == nil && b == nil {
-               *res = fillSegment
-               return
-       }
-
-       if a == nil {
-               a = emptySegment
-       }
-
-       if b == nil {
-               b = emptySegment
-       }
-
-       data := *res
-       if data == nil {
-               data = make([]byte, segByteSize, segByteSize)
-               *res = data
-       }
-
-       for i := uint32(0); i < segByteSize; i++ {
-               data[i] = a[i] ^ b[i]
-       }
-
-       return
-}
-
-func (db *DB) bExpireAt(key []byte, when int64) (int64, error) {
-       t := db.binBatch
-       t.Lock()
-       defer t.Unlock()
-
-       if seq, _, err := db.bGetMeta(key); err != nil || seq < 0 {
-               return 0, err
-       } else {
-               db.expireAt(t, BitType, key, when)
-               if err := t.Commit(); err != nil {
-                       return 0, err
-               }
-       }
-       return 1, nil
-}
-
-func (db *DB) bCountByte(val byte, soff uint32, eoff uint32) int32 {
-       if soff > eoff {
-               soff, eoff = eoff, soff
-       }
-
-       mask := uint8(0)
-       if soff > 0 {
-               mask |= fillBits[soff-1]
-       }
-       if eoff < 7 {
-               mask |= (fillBits[7] ^ fillBits[eoff])
-       }
-       mask = fillBits[7] ^ mask
-
-       return bitsInByte[val&mask]
-}
-
-func (db *DB) bCountSeg(key []byte, seq uint32, soff uint32, eoff uint32) (cnt int32, err error) {
-       if soff >= segBitSize || soff < 0 ||
-               eoff >= segBitSize || eoff < 0 {
-               return
-       }
-
-       var segment []byte
-       if _, segment, err = db.bGetSegment(key, seq); err != nil {
-               return
-       }
-
-       if segment == nil {
-               return
-       }
-
-       if soff > eoff {
-               soff, eoff = eoff, soff
-       }
-
-       headIdx := int(soff >> 3)
-       endIdx := int(eoff >> 3)
-       sByteOff := soff - ((soff >> 3) << 3)
-       eByteOff := eoff - ((eoff >> 3) << 3)
-
-       if headIdx == endIdx {
-               cnt = db.bCountByte(segment[headIdx], sByteOff, eByteOff)
-       } else {
-               cnt = db.bCountByte(segment[headIdx], sByteOff, 7) +
-                       db.bCountByte(segment[endIdx], 0, eByteOff)
-       }
-
-       // sum up following bytes
-       for idx, end := headIdx+1, endIdx-1; idx <= end; idx += 1 {
-               cnt += bitsInByte[segment[idx]]
-               if idx == end {
-                       break
-               }
-       }
-
-       return
-}
-
-func (db *DB) BGet(key []byte) (data []byte, err error) {
-       if err = checkKeySize(key); err != nil {
-               return
-       }
-
-       var ts, to int32
-       if ts, to, err = db.bGetMeta(key); err != nil || ts < 0 {
-               return
-       }
-
-       var tailSeq, tailOff = uint32(ts), uint32(to)
-       var capByteSize uint32 = db.bCapByteSize(tailSeq, tailOff)
-       data = make([]byte, capByteSize, capByteSize)
-
-       minKey := db.bEncodeBinKey(key, minSeq)
-       maxKey := db.bEncodeBinKey(key, tailSeq)
-       it := db.bucket.RangeIterator(minKey, maxKey, store.RangeClose)
-
-       var seq, s, e uint32
-       for ; it.Valid(); it.Next() {
-               if _, seq, err = db.bDecodeBinKey(it.RawKey()); err != nil {
-                       data = nil
-                       break
-               }
-
-               s = seq << segByteWidth
-               e = MinUInt32(s+segByteSize, capByteSize)
-               copy(data[s:e], it.RawValue())
-       }
-       it.Close()
-
-       return
-}
-
-func (db *DB) BDelete(key []byte) (drop int64, err error) {
-       if err = checkKeySize(key); err != nil {
-               return
-       }
-
-       t := db.binBatch
-       t.Lock()
-       defer t.Unlock()
-
-       drop = db.bDelete(t, key)
-       db.rmExpire(t, BitType, key)
-
-       err = t.Commit()
-       return
-}
-
-func (db *DB) BSetBit(key []byte, offset int32, val uint8) (ori uint8, err error) {
-       if err = checkKeySize(key); err != nil {
-               return
-       }
-
-       //      todo : check offset
-       var seq, off uint32
-       if seq, off, err = db.bParseOffset(key, offset); err != nil {
-               return 0, err
-       }
-
-       var bk, segment []byte
-       if bk, segment, err = db.bAllocateSegment(key, seq); err != nil {
-               return 0, err
-       }
-
-       if segment != nil {
-               ori = getBit(segment, off)
-               if setBit(segment, off, val) {
-                       t := db.binBatch
-                       t.Lock()
-                       defer t.Unlock()
-
-                       t.Put(bk, segment)
-                       if _, _, e := db.bUpdateMeta(t, key, seq, off); e != nil {
-                               err = e
-                               return
-                       }
-
-                       err = t.Commit()
-               }
-       }
-
-       return
-}
-
-func (db *DB) BMSetBit(key []byte, args ...BitPair) (place int64, err error) {
-       if err = checkKeySize(key); err != nil {
-               return
-       }
-
-       //      (ps : so as to aviod wasting memory copy while calling db.Get() and batch.Put(),
-       //                here we sequence the params by pos, so that we can merge the execution of
-       //                diff pos setting which targets on the same segment respectively. )
-
-       //      #1 : sequence request data
-       var argCnt = len(args)
-       var bitInfos segBitInfoArray = make(segBitInfoArray, argCnt)
-       var seq, off uint32
-
-       for i, info := range args {
-               if seq, off, err = db.bParseOffset(key, info.Pos); err != nil {
-                       return
-               }
-
-               bitInfos[i].Seq = seq
-               bitInfos[i].Off = off
-               bitInfos[i].Val = info.Val
-       }
-
-       sort.Sort(bitInfos)
-
-       for i := 1; i < argCnt; i++ {
-               if bitInfos[i].Seq == bitInfos[i-1].Seq && bitInfos[i].Off == bitInfos[i-1].Off {
-                       return 0, errDuplicatePos
-               }
-       }
-
-       //      #2 : execute bit set in order
-       t := db.binBatch
-       t.Lock()
-       defer t.Unlock()
-
-       var curBinKey, curSeg []byte
-       var curSeq, maxSeq, maxOff uint32
-
-       for _, info := range bitInfos {
-               if curSeg != nil && info.Seq != curSeq {
-                       t.Put(curBinKey, curSeg)
-                       curSeg = nil
-               }
-
-               if curSeg == nil {
-                       curSeq = info.Seq
-                       if curBinKey, curSeg, err = db.bAllocateSegment(key, info.Seq); err != nil {
-                               return
-                       }
-
-                       if curSeg == nil {
-                               continue
-                       }
-               }
-
-               if setBit(curSeg, info.Off, info.Val) {
-                       maxSeq = info.Seq
-                       maxOff = info.Off
-                       place++
-               }
-       }
-
-       if curSeg != nil {
-               t.Put(curBinKey, curSeg)
-       }
-
-       //      finally, update meta
-       if place > 0 {
-               if _, _, err = db.bUpdateMeta(t, key, maxSeq, maxOff); err != nil {
-                       return
-               }
-
-               err = t.Commit()
-       }
-
-       return
-}
-
-func (db *DB) BGetBit(key []byte, offset int32) (uint8, error) {
-       if seq, off, err := db.bParseOffset(key, offset); err != nil {
-               return 0, err
-       } else {
-               _, segment, err := db.bGetSegment(key, seq)
-               if err != nil {
-                       return 0, err
-               }
-
-               if segment == nil {
-                       return 0, nil
-               } else {
-                       return getBit(segment, off), nil
-               }
-       }
-}
-
-// func (db *DB) BGetRange(key []byte, start int32, end int32) ([]byte, error) {
-//     section := make([]byte)
-
-//     return
-// }
-
-func (db *DB) BCount(key []byte, start int32, end int32) (cnt int32, err error) {
-       var sseq, soff uint32
-       if sseq, soff, err = db.bParseOffset(key, start); err != nil {
-               return
-       }
-
-       var eseq, eoff uint32
-       if eseq, eoff, err = db.bParseOffset(key, end); err != nil {
-               return
-       }
-
-       if sseq > eseq || (sseq == eseq && soff > eoff) {
-               sseq, eseq = eseq, sseq
-               soff, eoff = eoff, soff
-       }
-
-       var segCnt int32
-       if eseq == sseq {
-               if segCnt, err = db.bCountSeg(key, sseq, soff, eoff); err != nil {
-                       return 0, err
-               }
-
-               cnt = segCnt
-
-       } else {
-               if segCnt, err = db.bCountSeg(key, sseq, soff, segBitSize-1); err != nil {
-                       return 0, err
-               } else {
-                       cnt += segCnt
-               }
-
-               if segCnt, err = db.bCountSeg(key, eseq, 0, eoff); err != nil {
-                       return 0, err
-               } else {
-                       cnt += segCnt
-               }
-       }
-
-       //      middle segs
-       var segment []byte
-       skey := db.bEncodeBinKey(key, sseq)
-       ekey := db.bEncodeBinKey(key, eseq)
-
-       it := db.bucket.RangeIterator(skey, ekey, store.RangeOpen)
-       for ; it.Valid(); it.Next() {
-               segment = it.RawValue()
-               for _, bt := range segment {
-                       cnt += bitsInByte[bt]
-               }
-       }
-       it.Close()
-
-       return
-}
-
-func (db *DB) BTail(key []byte) (int32, error) {
-       // effective length of data, the highest bit-pos set in history
-       tailSeq, tailOff, err := db.bGetMeta(key)
-       if err != nil {
-               return 0, err
-       }
-
-       tail := int32(-1)
-       if tailSeq >= 0 {
-               tail = int32(uint32(tailSeq)<<segBitWidth | uint32(tailOff))
-       }
-
-       return tail, nil
-}
-
-func (db *DB) BOperation(op uint8, dstkey []byte, srckeys ...[]byte) (blen int32, err error) {
-       //      blen -
-       //              the total bit size of data stored in destination key,
-       //              that is equal to the size of the longest input string.
-
-       var exeOp func([]byte, []byte, *[]byte)
-       switch op {
-       case OPand:
-               exeOp = db.bSegAnd
-       case OPor:
-               exeOp = db.bSegOr
-       case OPxor, OPnot:
-               exeOp = db.bSegXor
-       default:
-               return
-       }
-
-       if dstkey == nil || srckeys == nil {
-               return
-       }
-
-       t := db.binBatch
-       t.Lock()
-       defer t.Unlock()
-
-       var srcKseq, srcKoff int32
-       var seq, off, maxDstSeq, maxDstOff uint32
-
-       var keyNum int = len(srckeys)
-       var validKeyNum int
-       for i := 0; i < keyNum; i++ {
-               if srcKseq, srcKoff, err = db.bGetMeta(srckeys[i]); err != nil {
-                       return
-               } else if srcKseq < 0 {
-                       srckeys[i] = nil
-                       continue
-               }
-
-               validKeyNum++
-
-               seq = uint32(srcKseq)
-               off = uint32(srcKoff)
-               if seq > maxDstSeq || (seq == maxDstSeq && off > maxDstOff) {
-                       maxDstSeq = seq
-                       maxDstOff = off
-               }
-       }
-
-       if (op == OPnot && validKeyNum != 1) ||
-               (op != OPnot && validKeyNum < 2) {
-               return // with not enough existing source key
-       }
-
-       var srcIdx int
-       for srcIdx = 0; srcIdx < keyNum; srcIdx++ {
-               if srckeys[srcIdx] != nil {
-                       break
-               }
-       }
-
-       // init - data
-       var segments = make([][]byte, maxDstSeq+1)
-
-       if op == OPnot {
-               //      ps :
-               //              ( ~num == num ^ 0x11111111 )
-               //              we init the result segments with all bit set,
-               //              then we can calculate through the way of 'xor'.
-
-               //      ahead segments bin format : 1111 ... 1111
-               for i := uint32(0); i < maxDstSeq; i++ {
-                       segments[i] = fillSegment
-               }
-
-               //      last segment bin format : 1111..1100..0000
-               var tailSeg = make([]byte, segByteSize, segByteSize)
-               var fillByte = fillBits[7]
-               var tailSegLen = db.bCapByteSize(uint32(0), maxDstOff)
-               for i := uint32(0); i < tailSegLen-1; i++ {
-                       tailSeg[i] = fillByte
-               }
-               tailSeg[tailSegLen-1] = fillBits[maxDstOff-(tailSegLen-1)<<3]
-               segments[maxDstSeq] = tailSeg
-
-       } else {
-               // ps : init segments by data corresponding to the 1st valid source key
-               it := db.bIterator(srckeys[srcIdx])
-               for ; it.Valid(); it.Next() {
-                       if _, seq, err = db.bDecodeBinKey(it.RawKey()); err != nil {
-                               // to do ...
-                               it.Close()
-                               return
-                       }
-                       segments[seq] = it.Value()
-               }
-               it.Close()
-               srcIdx++
-       }
-
-       //      operation with following keys
-       var res []byte
-       for i := srcIdx; i < keyNum; i++ {
-               if srckeys[i] == nil {
-                       continue
-               }
-
-               it := db.bIterator(srckeys[i])
-               for idx, end := uint32(0), false; !end; it.Next() {
-                       end = !it.Valid()
-                       if !end {
-                               if _, seq, err = db.bDecodeBinKey(it.RawKey()); err != nil {
-                                       // to do ...
-                                       it.Close()
-                                       return
-                               }
-                       } else {
-                               seq = maxDstSeq + 1
-                       }
-
-                       // todo :
-                       //              operation 'and' can be optimize here :
-                       //              if seq > max_segments_idx, this loop can be break,
-                       //              which can avoid cost from Key() and bDecodeBinKey()
-
-                       for ; idx < seq; idx++ {
-                               res = nil
-                               exeOp(segments[idx], nil, &res)
-                               segments[idx] = res
-                       }
-
-                       if !end {
-                               res = it.Value()
-                               exeOp(segments[seq], res, &res)
-                               segments[seq] = res
-                               idx++
-                       }
-               }
-               it.Close()
-       }
-
-       // clear the old data in case
-       db.bDelete(t, dstkey)
-       db.rmExpire(t, BitType, dstkey)
-
-       //      set data
-       db.bSetMeta(t, dstkey, maxDstSeq, maxDstOff)
-
-       var bk []byte
-       for seq, segt := range segments {
-               if segt != nil {
-                       bk = db.bEncodeBinKey(dstkey, uint32(seq))
-                       t.Put(bk, segt)
-               }
-       }
-
-       err = t.Commit()
-       if err == nil {
-               // blen = int32(db.bCapByteSize(maxDstOff, maxDstOff))
-               blen = int32(maxDstSeq<<segBitWidth | maxDstOff + 1)
-       }
-
-       return
-}
-
-func (db *DB) BExpire(key []byte, duration int64) (int64, error) {
-       if duration <= 0 {
-               return 0, errExpireValue
-       }
-
-       if err := checkKeySize(key); err != nil {
-               return -1, err
-       }
-
-       return db.bExpireAt(key, time.Now().Unix()+duration)
-}
-
-func (db *DB) BExpireAt(key []byte, when int64) (int64, error) {
-       if when <= time.Now().Unix() {
-               return 0, errExpireValue
-       }
-
-       if err := checkKeySize(key); err != nil {
-               return -1, err
-       }
-
-       return db.bExpireAt(key, when)
-}
-
-func (db *DB) BTTL(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return -1, err
-       }
-
-       return db.ttl(BitType, key)
-}
-
-func (db *DB) BPersist(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-
-       t := db.binBatch
-       t.Lock()
-       defer t.Unlock()
-
-       n, err := db.rmExpire(t, BitType, key)
-       if err != nil {
-               return 0, err
-       }
-
-       err = t.Commit()
-       return n, err
-}
-
-func (db *DB) BScan(key []byte, count int, inclusive bool, match string) ([][]byte, error) {
-       return db.scan(BitMetaType, key, count, inclusive, match)
-}
-
-func (db *DB) bFlush() (drop int64, err error) {
-       t := db.binBatch
-       t.Lock()
-       defer t.Unlock()
-
-       return db.flushType(t, BitType)
-}
diff --git a/vendor/github.com/lunny/nodb/t_hash.go b/vendor/github.com/lunny/nodb/t_hash.go
deleted file mode 100644 (file)
index bedfbf7..0000000
+++ /dev/null
@@ -1,509 +0,0 @@
-package nodb
-
-import (
-       "encoding/binary"
-       "errors"
-       "time"
-
-       "github.com/lunny/nodb/store"
-)
-
-type FVPair struct {
-       Field []byte
-       Value []byte
-}
-
-var errHashKey = errors.New("invalid hash key")
-var errHSizeKey = errors.New("invalid hsize key")
-
-const (
-       hashStartSep byte = ':'
-       hashStopSep  byte = hashStartSep + 1
-)
-
-func checkHashKFSize(key []byte, field []byte) error {
-       if len(key) > MaxKeySize || len(key) == 0 {
-               return errKeySize
-       } else if len(field) > MaxHashFieldSize || len(field) == 0 {
-               return errHashFieldSize
-       }
-       return nil
-}
-
-func (db *DB) hEncodeSizeKey(key []byte) []byte {
-       buf := make([]byte, len(key)+2)
-
-       buf[0] = db.index
-       buf[1] = HSizeType
-
-       copy(buf[2:], key)
-       return buf
-}
-
-func (db *DB) hDecodeSizeKey(ek []byte) ([]byte, error) {
-       if len(ek) < 2 || ek[0] != db.index || ek[1] != HSizeType {
-               return nil, errHSizeKey
-       }
-
-       return ek[2:], nil
-}
-
-func (db *DB) hEncodeHashKey(key []byte, field []byte) []byte {
-       buf := make([]byte, len(key)+len(field)+1+1+2+1)
-
-       pos := 0
-       buf[pos] = db.index
-       pos++
-       buf[pos] = HashType
-       pos++
-
-       binary.BigEndian.PutUint16(buf[pos:], uint16(len(key)))
-       pos += 2
-
-       copy(buf[pos:], key)
-       pos += len(key)
-
-       buf[pos] = hashStartSep
-       pos++
-       copy(buf[pos:], field)
-
-       return buf
-}
-
-func (db *DB) hDecodeHashKey(ek []byte) ([]byte, []byte, error) {
-       if len(ek) < 5 || ek[0] != db.index || ek[1] != HashType {
-               return nil, nil, errHashKey
-       }
-
-       pos := 2
-       keyLen := int(binary.BigEndian.Uint16(ek[pos:]))
-       pos += 2
-
-       if keyLen+5 > len(ek) {
-               return nil, nil, errHashKey
-       }
-
-       key := ek[pos : pos+keyLen]
-       pos += keyLen
-
-       if ek[pos] != hashStartSep {
-               return nil, nil, errHashKey
-       }
-
-       pos++
-       field := ek[pos:]
-       return key, field, nil
-}
-
-func (db *DB) hEncodeStartKey(key []byte) []byte {
-       return db.hEncodeHashKey(key, nil)
-}
-
-func (db *DB) hEncodeStopKey(key []byte) []byte {
-       k := db.hEncodeHashKey(key, nil)
-
-       k[len(k)-1] = hashStopSep
-
-       return k
-}
-
-func (db *DB) hSetItem(key []byte, field []byte, value []byte) (int64, error) {
-       t := db.hashBatch
-
-       ek := db.hEncodeHashKey(key, field)
-
-       var n int64 = 1
-       if v, _ := db.bucket.Get(ek); v != nil {
-               n = 0
-       } else {
-               if _, err := db.hIncrSize(key, 1); err != nil {
-                       return 0, err
-               }
-       }
-
-       t.Put(ek, value)
-       return n, nil
-}
-
-//     ps : here just focus on deleting the hash data,
-//              any other likes expire is ignore.
-func (db *DB) hDelete(t *batch, key []byte) int64 {
-       sk := db.hEncodeSizeKey(key)
-       start := db.hEncodeStartKey(key)
-       stop := db.hEncodeStopKey(key)
-
-       var num int64 = 0
-       it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1)
-       for ; it.Valid(); it.Next() {
-               t.Delete(it.Key())
-               num++
-       }
-       it.Close()
-
-       t.Delete(sk)
-       return num
-}
-
-func (db *DB) hExpireAt(key []byte, when int64) (int64, error) {
-       t := db.hashBatch
-       t.Lock()
-       defer t.Unlock()
-
-       if hlen, err := db.HLen(key); err != nil || hlen == 0 {
-               return 0, err
-       } else {
-               db.expireAt(t, HashType, key, when)
-               if err := t.Commit(); err != nil {
-                       return 0, err
-               }
-       }
-       return 1, nil
-}
-
-func (db *DB) HLen(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-
-       return Int64(db.bucket.Get(db.hEncodeSizeKey(key)))
-}
-
-func (db *DB) HSet(key []byte, field []byte, value []byte) (int64, error) {
-       if err := checkHashKFSize(key, field); err != nil {
-               return 0, err
-       } else if err := checkValueSize(value); err != nil {
-               return 0, err
-       }
-
-       t := db.hashBatch
-       t.Lock()
-       defer t.Unlock()
-
-       n, err := db.hSetItem(key, field, value)
-       if err != nil {
-               return 0, err
-       }
-
-       //todo add binlog
-
-       err = t.Commit()
-       return n, err
-}
-
-func (db *DB) HGet(key []byte, field []byte) ([]byte, error) {
-       if err := checkHashKFSize(key, field); err != nil {
-               return nil, err
-       }
-
-       return db.bucket.Get(db.hEncodeHashKey(key, field))
-}
-
-func (db *DB) HMset(key []byte, args ...FVPair) error {
-       t := db.hashBatch
-       t.Lock()
-       defer t.Unlock()
-
-       var err error
-       var ek []byte
-       var num int64 = 0
-       for i := 0; i < len(args); i++ {
-               if err := checkHashKFSize(key, args[i].Field); err != nil {
-                       return err
-               } else if err := checkValueSize(args[i].Value); err != nil {
-                       return err
-               }
-
-               ek = db.hEncodeHashKey(key, args[i].Field)
-
-               if v, err := db.bucket.Get(ek); err != nil {
-                       return err
-               } else if v == nil {
-                       num++
-               }
-
-               t.Put(ek, args[i].Value)
-       }
-
-       if _, err = db.hIncrSize(key, num); err != nil {
-               return err
-       }
-
-       //todo add binglog
-       err = t.Commit()
-       return err
-}
-
-func (db *DB) HMget(key []byte, args ...[]byte) ([][]byte, error) {
-       var ek []byte
-
-       it := db.bucket.NewIterator()
-       defer it.Close()
-
-       r := make([][]byte, len(args))
-       for i := 0; i < len(args); i++ {
-               if err := checkHashKFSize(key, args[i]); err != nil {
-                       return nil, err
-               }
-
-               ek = db.hEncodeHashKey(key, args[i])
-
-               r[i] = it.Find(ek)
-       }
-
-       return r, nil
-}
-
-func (db *DB) HDel(key []byte, args ...[]byte) (int64, error) {
-       t := db.hashBatch
-
-       var ek []byte
-       var v []byte
-       var err error
-
-       t.Lock()
-       defer t.Unlock()
-
-       it := db.bucket.NewIterator()
-       defer it.Close()
-
-       var num int64 = 0
-       for i := 0; i < len(args); i++ {
-               if err := checkHashKFSize(key, args[i]); err != nil {
-                       return 0, err
-               }
-
-               ek = db.hEncodeHashKey(key, args[i])
-
-               v = it.RawFind(ek)
-               if v == nil {
-                       continue
-               } else {
-                       num++
-                       t.Delete(ek)
-               }
-       }
-
-       if _, err = db.hIncrSize(key, -num); err != nil {
-               return 0, err
-       }
-
-       err = t.Commit()
-
-       return num, err
-}
-
-func (db *DB) hIncrSize(key []byte, delta int64) (int64, error) {
-       t := db.hashBatch
-       sk := db.hEncodeSizeKey(key)
-
-       var err error
-       var size int64 = 0
-       if size, err = Int64(db.bucket.Get(sk)); err != nil {
-               return 0, err
-       } else {
-               size += delta
-               if size <= 0 {
-                       size = 0
-                       t.Delete(sk)
-                       db.rmExpire(t, HashType, key)
-               } else {
-                       t.Put(sk, PutInt64(size))
-               }
-       }
-
-       return size, nil
-}
-
-func (db *DB) HIncrBy(key []byte, field []byte, delta int64) (int64, error) {
-       if err := checkHashKFSize(key, field); err != nil {
-               return 0, err
-       }
-
-       t := db.hashBatch
-       var ek []byte
-       var err error
-
-       t.Lock()
-       defer t.Unlock()
-
-       ek = db.hEncodeHashKey(key, field)
-
-       var n int64 = 0
-       if n, err = StrInt64(db.bucket.Get(ek)); err != nil {
-               return 0, err
-       }
-
-       n += delta
-
-       _, err = db.hSetItem(key, field, StrPutInt64(n))
-       if err != nil {
-               return 0, err
-       }
-
-       err = t.Commit()
-
-       return n, err
-}
-
-func (db *DB) HGetAll(key []byte) ([]FVPair, error) {
-       if err := checkKeySize(key); err != nil {
-               return nil, err
-       }
-
-       start := db.hEncodeStartKey(key)
-       stop := db.hEncodeStopKey(key)
-
-       v := make([]FVPair, 0, 16)
-
-       it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1)
-       for ; it.Valid(); it.Next() {
-               _, f, err := db.hDecodeHashKey(it.Key())
-               if err != nil {
-                       return nil, err
-               }
-
-               v = append(v, FVPair{Field: f, Value: it.Value()})
-       }
-
-       it.Close()
-
-       return v, nil
-}
-
-func (db *DB) HKeys(key []byte) ([][]byte, error) {
-       if err := checkKeySize(key); err != nil {
-               return nil, err
-       }
-
-       start := db.hEncodeStartKey(key)
-       stop := db.hEncodeStopKey(key)
-
-       v := make([][]byte, 0, 16)
-
-       it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1)
-       for ; it.Valid(); it.Next() {
-               _, f, err := db.hDecodeHashKey(it.Key())
-               if err != nil {
-                       return nil, err
-               }
-               v = append(v, f)
-       }
-
-       it.Close()
-
-       return v, nil
-}
-
-func (db *DB) HValues(key []byte) ([][]byte, error) {
-       if err := checkKeySize(key); err != nil {
-               return nil, err
-       }
-
-       start := db.hEncodeStartKey(key)
-       stop := db.hEncodeStopKey(key)
-
-       v := make([][]byte, 0, 16)
-
-       it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1)
-       for ; it.Valid(); it.Next() {
-               _, _, err := db.hDecodeHashKey(it.Key())
-               if err != nil {
-                       return nil, err
-               }
-
-               v = append(v, it.Value())
-       }
-
-       it.Close()
-
-       return v, nil
-}
-
-func (db *DB) HClear(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-
-       t := db.hashBatch
-       t.Lock()
-       defer t.Unlock()
-
-       num := db.hDelete(t, key)
-       db.rmExpire(t, HashType, key)
-
-       err := t.Commit()
-       return num, err
-}
-
-func (db *DB) HMclear(keys ...[]byte) (int64, error) {
-       t := db.hashBatch
-       t.Lock()
-       defer t.Unlock()
-
-       for _, key := range keys {
-               if err := checkKeySize(key); err != nil {
-                       return 0, err
-               }
-
-               db.hDelete(t, key)
-               db.rmExpire(t, HashType, key)
-       }
-
-       err := t.Commit()
-       return int64(len(keys)), err
-}
-
-func (db *DB) hFlush() (drop int64, err error) {
-       t := db.hashBatch
-
-       t.Lock()
-       defer t.Unlock()
-
-       return db.flushType(t, HashType)
-}
-
-func (db *DB) HScan(key []byte, count int, inclusive bool, match string) ([][]byte, error) {
-       return db.scan(HSizeType, key, count, inclusive, match)
-}
-
-func (db *DB) HExpire(key []byte, duration int64) (int64, error) {
-       if duration <= 0 {
-               return 0, errExpireValue
-       }
-
-       return db.hExpireAt(key, time.Now().Unix()+duration)
-}
-
-func (db *DB) HExpireAt(key []byte, when int64) (int64, error) {
-       if when <= time.Now().Unix() {
-               return 0, errExpireValue
-       }
-
-       return db.hExpireAt(key, when)
-}
-
-func (db *DB) HTTL(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return -1, err
-       }
-
-       return db.ttl(HashType, key)
-}
-
-func (db *DB) HPersist(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-
-       t := db.hashBatch
-       t.Lock()
-       defer t.Unlock()
-
-       n, err := db.rmExpire(t, HashType, key)
-       if err != nil {
-               return 0, err
-       }
-
-       err = t.Commit()
-       return n, err
-}
diff --git a/vendor/github.com/lunny/nodb/t_kv.go b/vendor/github.com/lunny/nodb/t_kv.go
deleted file mode 100644 (file)
index 82a12f7..0000000
+++ /dev/null
@@ -1,387 +0,0 @@
-package nodb
-
-import (
-       "errors"
-       "time"
-)
-
-type KVPair struct {
-       Key   []byte
-       Value []byte
-}
-
-var errKVKey = errors.New("invalid encode kv key")
-
-func checkKeySize(key []byte) error {
-       if len(key) > MaxKeySize || len(key) == 0 {
-               return errKeySize
-       }
-       return nil
-}
-
-func checkValueSize(value []byte) error {
-       if len(value) > MaxValueSize {
-               return errValueSize
-       }
-
-       return nil
-}
-
-func (db *DB) encodeKVKey(key []byte) []byte {
-       ek := make([]byte, len(key)+2)
-       ek[0] = db.index
-       ek[1] = KVType
-       copy(ek[2:], key)
-       return ek
-}
-
-func (db *DB) decodeKVKey(ek []byte) ([]byte, error) {
-       if len(ek) < 2 || ek[0] != db.index || ek[1] != KVType {
-               return nil, errKVKey
-       }
-
-       return ek[2:], nil
-}
-
-func (db *DB) encodeKVMinKey() []byte {
-       ek := db.encodeKVKey(nil)
-       return ek
-}
-
-func (db *DB) encodeKVMaxKey() []byte {
-       ek := db.encodeKVKey(nil)
-       ek[len(ek)-1] = KVType + 1
-       return ek
-}
-
-func (db *DB) incr(key []byte, delta int64) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-
-       var err error
-       key = db.encodeKVKey(key)
-
-       t := db.kvBatch
-
-       t.Lock()
-       defer t.Unlock()
-
-       var n int64
-       n, err = StrInt64(db.bucket.Get(key))
-       if err != nil {
-               return 0, err
-       }
-
-       n += delta
-
-       t.Put(key, StrPutInt64(n))
-
-       //todo binlog
-
-       err = t.Commit()
-       return n, err
-}
-
-//     ps : here just focus on deleting the key-value data,
-//              any other likes expire is ignore.
-func (db *DB) delete(t *batch, key []byte) int64 {
-       key = db.encodeKVKey(key)
-       t.Delete(key)
-       return 1
-}
-
-func (db *DB) setExpireAt(key []byte, when int64) (int64, error) {
-       t := db.kvBatch
-       t.Lock()
-       defer t.Unlock()
-
-       if exist, err := db.Exists(key); err != nil || exist == 0 {
-               return 0, err
-       } else {
-               db.expireAt(t, KVType, key, when)
-               if err := t.Commit(); err != nil {
-                       return 0, err
-               }
-       }
-       return 1, nil
-}
-
-func (db *DB) Decr(key []byte) (int64, error) {
-       return db.incr(key, -1)
-}
-
-func (db *DB) DecrBy(key []byte, decrement int64) (int64, error) {
-       return db.incr(key, -decrement)
-}
-
-func (db *DB) Del(keys ...[]byte) (int64, error) {
-       if len(keys) == 0 {
-               return 0, nil
-       }
-
-       codedKeys := make([][]byte, len(keys))
-       for i, k := range keys {
-               codedKeys[i] = db.encodeKVKey(k)
-       }
-
-       t := db.kvBatch
-       t.Lock()
-       defer t.Unlock()
-
-       for i, k := range keys {
-               t.Delete(codedKeys[i])
-               db.rmExpire(t, KVType, k)
-       }
-
-       err := t.Commit()
-       return int64(len(keys)), err
-}
-
-func (db *DB) Exists(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-
-       var err error
-       key = db.encodeKVKey(key)
-
-       var v []byte
-       v, err = db.bucket.Get(key)
-       if v != nil && err == nil {
-               return 1, nil
-       }
-
-       return 0, err
-}
-
-func (db *DB) Get(key []byte) ([]byte, error) {
-       if err := checkKeySize(key); err != nil {
-               return nil, err
-       }
-
-       key = db.encodeKVKey(key)
-
-       return db.bucket.Get(key)
-}
-
-func (db *DB) GetSet(key []byte, value []byte) ([]byte, error) {
-       if err := checkKeySize(key); err != nil {
-               return nil, err
-       } else if err := checkValueSize(value); err != nil {
-               return nil, err
-       }
-
-       key = db.encodeKVKey(key)
-
-       t := db.kvBatch
-
-       t.Lock()
-       defer t.Unlock()
-
-       oldValue, err := db.bucket.Get(key)
-       if err != nil {
-               return nil, err
-       }
-
-       t.Put(key, value)
-       //todo, binlog
-
-       err = t.Commit()
-
-       return oldValue, err
-}
-
-func (db *DB) Incr(key []byte) (int64, error) {
-       return db.incr(key, 1)
-}
-
-func (db *DB) IncrBy(key []byte, increment int64) (int64, error) {
-       return db.incr(key, increment)
-}
-
-func (db *DB) MGet(keys ...[]byte) ([][]byte, error) {
-       values := make([][]byte, len(keys))
-
-       it := db.bucket.NewIterator()
-       defer it.Close()
-
-       for i := range keys {
-               if err := checkKeySize(keys[i]); err != nil {
-                       return nil, err
-               }
-
-               values[i] = it.Find(db.encodeKVKey(keys[i]))
-       }
-
-       return values, nil
-}
-
-func (db *DB) MSet(args ...KVPair) error {
-       if len(args) == 0 {
-               return nil
-       }
-
-       t := db.kvBatch
-
-       var err error
-       var key []byte
-       var value []byte
-
-       t.Lock()
-       defer t.Unlock()
-
-       for i := 0; i < len(args); i++ {
-               if err := checkKeySize(args[i].Key); err != nil {
-                       return err
-               } else if err := checkValueSize(args[i].Value); err != nil {
-                       return err
-               }
-
-               key = db.encodeKVKey(args[i].Key)
-
-               value = args[i].Value
-
-               t.Put(key, value)
-
-               //todo binlog
-       }
-
-       err = t.Commit()
-       return err
-}
-
-func (db *DB) Set(key []byte, value []byte) error {
-       if err := checkKeySize(key); err != nil {
-               return err
-       } else if err := checkValueSize(value); err != nil {
-               return err
-       }
-
-       var err error
-       key = db.encodeKVKey(key)
-
-       t := db.kvBatch
-
-       t.Lock()
-       defer t.Unlock()
-
-       t.Put(key, value)
-
-       err = t.Commit()
-
-       return err
-}
-
-func (db *DB) SetNX(key []byte, value []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       } else if err := checkValueSize(value); err != nil {
-               return 0, err
-       }
-
-       var err error
-       key = db.encodeKVKey(key)
-
-       var n int64 = 1
-
-       t := db.kvBatch
-
-       t.Lock()
-       defer t.Unlock()
-
-       if v, err := db.bucket.Get(key); err != nil {
-               return 0, err
-       } else if v != nil {
-               n = 0
-       } else {
-               t.Put(key, value)
-
-               //todo binlog
-
-               err = t.Commit()
-       }
-
-       return n, err
-}
-
-func (db *DB) flush() (drop int64, err error) {
-       t := db.kvBatch
-       t.Lock()
-       defer t.Unlock()
-       return db.flushType(t, KVType)
-}
-
-//if inclusive is true, scan range [key, inf) else (key, inf)
-func (db *DB) Scan(key []byte, count int, inclusive bool, match string) ([][]byte, error) {
-       return db.scan(KVType, key, count, inclusive, match)
-}
-
-func (db *DB) Expire(key []byte, duration int64) (int64, error) {
-       if duration <= 0 {
-               return 0, errExpireValue
-       }
-
-       return db.setExpireAt(key, time.Now().Unix()+duration)
-}
-
-func (db *DB) ExpireAt(key []byte, when int64) (int64, error) {
-       if when <= time.Now().Unix() {
-               return 0, errExpireValue
-       }
-
-       return db.setExpireAt(key, when)
-}
-
-func (db *DB) TTL(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return -1, err
-       }
-
-       return db.ttl(KVType, key)
-}
-
-func (db *DB) Persist(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-
-       t := db.kvBatch
-       t.Lock()
-       defer t.Unlock()
-       n, err := db.rmExpire(t, KVType, key)
-       if err != nil {
-               return 0, err
-       }
-
-       err = t.Commit()
-       return n, err
-}
-
-func (db *DB) Lock() {
-       t := db.kvBatch
-       t.Lock()
-}
-
-func (db *DB) Remove(key []byte) bool {
-       if len(key) == 0 {
-               return false
-       }
-       t := db.kvBatch
-       t.Delete(db.encodeKVKey(key))
-       _, err := db.rmExpire(t, KVType, key)
-       if err != nil {
-               return false
-       }
-       return true
-}
-
-func (db *DB) Commit() error {
-       t := db.kvBatch
-       return t.Commit()
-}
-
-func (db *DB) Unlock() {
-       t := db.kvBatch
-       t.Unlock()
-}
diff --git a/vendor/github.com/lunny/nodb/t_list.go b/vendor/github.com/lunny/nodb/t_list.go
deleted file mode 100644 (file)
index 5b9d9d9..0000000
+++ /dev/null
@@ -1,492 +0,0 @@
-package nodb
-
-import (
-       "encoding/binary"
-       "errors"
-       "time"
-
-       "github.com/lunny/nodb/store"
-)
-
-const (
-       listHeadSeq int32 = 1
-       listTailSeq int32 = 2
-
-       listMinSeq     int32 = 1000
-       listMaxSeq     int32 = 1<<31 - 1000
-       listInitialSeq int32 = listMinSeq + (listMaxSeq-listMinSeq)/2
-)
-
-var errLMetaKey = errors.New("invalid lmeta key")
-var errListKey = errors.New("invalid list key")
-var errListSeq = errors.New("invalid list sequence, overflow")
-
-func (db *DB) lEncodeMetaKey(key []byte) []byte {
-       buf := make([]byte, len(key)+2)
-       buf[0] = db.index
-       buf[1] = LMetaType
-
-       copy(buf[2:], key)
-       return buf
-}
-
-func (db *DB) lDecodeMetaKey(ek []byte) ([]byte, error) {
-       if len(ek) < 2 || ek[0] != db.index || ek[1] != LMetaType {
-               return nil, errLMetaKey
-       }
-
-       return ek[2:], nil
-}
-
-func (db *DB) lEncodeListKey(key []byte, seq int32) []byte {
-       buf := make([]byte, len(key)+8)
-
-       pos := 0
-       buf[pos] = db.index
-       pos++
-       buf[pos] = ListType
-       pos++
-
-       binary.BigEndian.PutUint16(buf[pos:], uint16(len(key)))
-       pos += 2
-
-       copy(buf[pos:], key)
-       pos += len(key)
-
-       binary.BigEndian.PutUint32(buf[pos:], uint32(seq))
-
-       return buf
-}
-
-func (db *DB) lDecodeListKey(ek []byte) (key []byte, seq int32, err error) {
-       if len(ek) < 8 || ek[0] != db.index || ek[1] != ListType {
-               err = errListKey
-               return
-       }
-
-       keyLen := int(binary.BigEndian.Uint16(ek[2:]))
-       if keyLen+8 != len(ek) {
-               err = errListKey
-               return
-       }
-
-       key = ek[4 : 4+keyLen]
-       seq = int32(binary.BigEndian.Uint32(ek[4+keyLen:]))
-       return
-}
-
-func (db *DB) lpush(key []byte, whereSeq int32, args ...[]byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-
-       var headSeq int32
-       var tailSeq int32
-       var size int32
-       var err error
-
-       t := db.listBatch
-       t.Lock()
-       defer t.Unlock()
-
-       metaKey := db.lEncodeMetaKey(key)
-       headSeq, tailSeq, size, err = db.lGetMeta(nil, metaKey)
-       if err != nil {
-               return 0, err
-       }
-
-       var pushCnt int = len(args)
-       if pushCnt == 0 {
-               return int64(size), nil
-       }
-
-       var seq int32 = headSeq
-       var delta int32 = -1
-       if whereSeq == listTailSeq {
-               seq = tailSeq
-               delta = 1
-       }
-
-       //      append elements
-       if size > 0 {
-               seq += delta
-       }
-
-       for i := 0; i < pushCnt; i++ {
-               ek := db.lEncodeListKey(key, seq+int32(i)*delta)
-               t.Put(ek, args[i])
-       }
-
-       seq += int32(pushCnt-1) * delta
-       if seq <= listMinSeq || seq >= listMaxSeq {
-               return 0, errListSeq
-       }
-
-       //      set meta info
-       if whereSeq == listHeadSeq {
-               headSeq = seq
-       } else {
-               tailSeq = seq
-       }
-
-       db.lSetMeta(metaKey, headSeq, tailSeq)
-
-       err = t.Commit()
-       return int64(size) + int64(pushCnt), err
-}
-
-func (db *DB) lpop(key []byte, whereSeq int32) ([]byte, error) {
-       if err := checkKeySize(key); err != nil {
-               return nil, err
-       }
-
-       t := db.listBatch
-       t.Lock()
-       defer t.Unlock()
-
-       var headSeq int32
-       var tailSeq int32
-       var err error
-
-       metaKey := db.lEncodeMetaKey(key)
-       headSeq, tailSeq, _, err = db.lGetMeta(nil, metaKey)
-       if err != nil {
-               return nil, err
-       }
-
-       var value []byte
-
-       var seq int32 = headSeq
-       if whereSeq == listTailSeq {
-               seq = tailSeq
-       }
-
-       itemKey := db.lEncodeListKey(key, seq)
-       value, err = db.bucket.Get(itemKey)
-       if err != nil {
-               return nil, err
-       }
-
-       if whereSeq == listHeadSeq {
-               headSeq += 1
-       } else {
-               tailSeq -= 1
-       }
-
-       t.Delete(itemKey)
-       size := db.lSetMeta(metaKey, headSeq, tailSeq)
-       if size == 0 {
-               db.rmExpire(t, HashType, key)
-       }
-
-       err = t.Commit()
-       return value, err
-}
-
-//     ps : here just focus on deleting the list data,
-//              any other likes expire is ignore.
-func (db *DB) lDelete(t *batch, key []byte) int64 {
-       mk := db.lEncodeMetaKey(key)
-
-       var headSeq int32
-       var tailSeq int32
-       var err error
-
-       it := db.bucket.NewIterator()
-       defer it.Close()
-
-       headSeq, tailSeq, _, err = db.lGetMeta(it, mk)
-       if err != nil {
-               return 0
-       }
-
-       var num int64 = 0
-       startKey := db.lEncodeListKey(key, headSeq)
-       stopKey := db.lEncodeListKey(key, tailSeq)
-
-       rit := store.NewRangeIterator(it, &store.Range{startKey, stopKey, store.RangeClose})
-       for ; rit.Valid(); rit.Next() {
-               t.Delete(rit.RawKey())
-               num++
-       }
-
-       t.Delete(mk)
-
-       return num
-}
-
-func (db *DB) lGetMeta(it *store.Iterator, ek []byte) (headSeq int32, tailSeq int32, size int32, err error) {
-       var v []byte
-       if it != nil {
-               v = it.Find(ek)
-       } else {
-               v, err = db.bucket.Get(ek)
-       }
-       if err != nil {
-               return
-       } else if v == nil {
-               headSeq = listInitialSeq
-               tailSeq = listInitialSeq
-               size = 0
-               return
-       } else {
-               headSeq = int32(binary.LittleEndian.Uint32(v[0:4]))
-               tailSeq = int32(binary.LittleEndian.Uint32(v[4:8]))
-               size = tailSeq - headSeq + 1
-       }
-       return
-}
-
-func (db *DB) lSetMeta(ek []byte, headSeq int32, tailSeq int32) int32 {
-       t := db.listBatch
-
-       var size int32 = tailSeq - headSeq + 1
-       if size < 0 {
-               //      todo : log error + panic
-       } else if size == 0 {
-               t.Delete(ek)
-       } else {
-               buf := make([]byte, 8)
-
-               binary.LittleEndian.PutUint32(buf[0:4], uint32(headSeq))
-               binary.LittleEndian.PutUint32(buf[4:8], uint32(tailSeq))
-
-               t.Put(ek, buf)
-       }
-
-       return size
-}
-
-func (db *DB) lExpireAt(key []byte, when int64) (int64, error) {
-       t := db.listBatch
-       t.Lock()
-       defer t.Unlock()
-
-       if llen, err := db.LLen(key); err != nil || llen == 0 {
-               return 0, err
-       } else {
-               db.expireAt(t, ListType, key, when)
-               if err := t.Commit(); err != nil {
-                       return 0, err
-               }
-       }
-       return 1, nil
-}
-
-func (db *DB) LIndex(key []byte, index int32) ([]byte, error) {
-       if err := checkKeySize(key); err != nil {
-               return nil, err
-       }
-
-       var seq int32
-       var headSeq int32
-       var tailSeq int32
-       var err error
-
-       metaKey := db.lEncodeMetaKey(key)
-
-       it := db.bucket.NewIterator()
-       defer it.Close()
-
-       headSeq, tailSeq, _, err = db.lGetMeta(it, metaKey)
-       if err != nil {
-               return nil, err
-       }
-
-       if index >= 0 {
-               seq = headSeq + index
-       } else {
-               seq = tailSeq + index + 1
-       }
-
-       sk := db.lEncodeListKey(key, seq)
-       v := it.Find(sk)
-
-       return v, nil
-}
-
-func (db *DB) LLen(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-
-       ek := db.lEncodeMetaKey(key)
-       _, _, size, err := db.lGetMeta(nil, ek)
-       return int64(size), err
-}
-
-func (db *DB) LPop(key []byte) ([]byte, error) {
-       return db.lpop(key, listHeadSeq)
-}
-
-func (db *DB) LPush(key []byte, arg1 []byte, args ...[]byte) (int64, error) {
-       var argss = [][]byte{arg1}
-       argss = append(argss, args...)
-       return db.lpush(key, listHeadSeq, argss...)
-}
-
-func (db *DB) LRange(key []byte, start int32, stop int32) ([][]byte, error) {
-       if err := checkKeySize(key); err != nil {
-               return nil, err
-       }
-
-       var headSeq int32
-       var llen int32
-       var err error
-
-       metaKey := db.lEncodeMetaKey(key)
-
-       it := db.bucket.NewIterator()
-       defer it.Close()
-
-       if headSeq, _, llen, err = db.lGetMeta(it, metaKey); err != nil {
-               return nil, err
-       }
-
-       if start < 0 {
-               start = llen + start
-       }
-       if stop < 0 {
-               stop = llen + stop
-       }
-       if start < 0 {
-               start = 0
-       }
-
-       if start > stop || start >= llen {
-               return [][]byte{}, nil
-       }
-
-       if stop >= llen {
-               stop = llen - 1
-       }
-
-       limit := (stop - start) + 1
-       headSeq += start
-
-       v := make([][]byte, 0, limit)
-
-       startKey := db.lEncodeListKey(key, headSeq)
-       rit := store.NewRangeLimitIterator(it,
-               &store.Range{
-                       Min:  startKey,
-                       Max:  nil,
-                       Type: store.RangeClose},
-               &store.Limit{
-                       Offset: 0,
-                       Count:  int(limit)})
-
-       for ; rit.Valid(); rit.Next() {
-               v = append(v, rit.Value())
-       }
-
-       return v, nil
-}
-
-func (db *DB) RPop(key []byte) ([]byte, error) {
-       return db.lpop(key, listTailSeq)
-}
-
-func (db *DB) RPush(key []byte, arg1 []byte, args ...[]byte) (int64, error) {
-       var argss = [][]byte{arg1}
-       argss = append(argss, args...)
-       return db.lpush(key, listTailSeq, argss...)
-}
-
-func (db *DB) LClear(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-
-       t := db.listBatch
-       t.Lock()
-       defer t.Unlock()
-
-       num := db.lDelete(t, key)
-       db.rmExpire(t, ListType, key)
-
-       err := t.Commit()
-       return num, err
-}
-
-func (db *DB) LMclear(keys ...[]byte) (int64, error) {
-       t := db.listBatch
-       t.Lock()
-       defer t.Unlock()
-
-       for _, key := range keys {
-               if err := checkKeySize(key); err != nil {
-                       return 0, err
-               }
-
-               db.lDelete(t, key)
-               db.rmExpire(t, ListType, key)
-
-       }
-
-       err := t.Commit()
-       return int64(len(keys)), err
-}
-
-func (db *DB) lFlush() (drop int64, err error) {
-       t := db.listBatch
-       t.Lock()
-       defer t.Unlock()
-       return db.flushType(t, ListType)
-}
-
-func (db *DB) LExpire(key []byte, duration int64) (int64, error) {
-       if duration <= 0 {
-               return 0, errExpireValue
-       }
-
-       return db.lExpireAt(key, time.Now().Unix()+duration)
-}
-
-func (db *DB) LExpireAt(key []byte, when int64) (int64, error) {
-       if when <= time.Now().Unix() {
-               return 0, errExpireValue
-       }
-
-       return db.lExpireAt(key, when)
-}
-
-func (db *DB) LTTL(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return -1, err
-       }
-
-       return db.ttl(ListType, key)
-}
-
-func (db *DB) LPersist(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-
-       t := db.listBatch
-       t.Lock()
-       defer t.Unlock()
-
-       n, err := db.rmExpire(t, ListType, key)
-       if err != nil {
-               return 0, err
-       }
-
-       err = t.Commit()
-       return n, err
-}
-
-func (db *DB) LScan(key []byte, count int, inclusive bool, match string) ([][]byte, error) {
-       return db.scan(LMetaType, key, count, inclusive, match)
-}
-
-func (db *DB) lEncodeMinKey() []byte {
-       return db.lEncodeMetaKey(nil)
-}
-
-func (db *DB) lEncodeMaxKey() []byte {
-       ek := db.lEncodeMetaKey(nil)
-       ek[len(ek)-1] = LMetaType + 1
-       return ek
-}
diff --git a/vendor/github.com/lunny/nodb/t_set.go b/vendor/github.com/lunny/nodb/t_set.go
deleted file mode 100644 (file)
index 41ce30e..0000000
+++ /dev/null
@@ -1,601 +0,0 @@
-package nodb
-
-import (
-       "encoding/binary"
-       "errors"
-       "time"
-
-       "github.com/lunny/nodb/store"
-)
-
-var errSetKey = errors.New("invalid set key")
-var errSSizeKey = errors.New("invalid ssize key")
-
-const (
-       setStartSep byte = ':'
-       setStopSep  byte = setStartSep + 1
-       UnionType   byte = 51
-       DiffType    byte = 52
-       InterType   byte = 53
-)
-
-func checkSetKMSize(key []byte, member []byte) error {
-       if len(key) > MaxKeySize || len(key) == 0 {
-               return errKeySize
-       } else if len(member) > MaxSetMemberSize || len(member) == 0 {
-               return errSetMemberSize
-       }
-       return nil
-}
-
-func (db *DB) sEncodeSizeKey(key []byte) []byte {
-       buf := make([]byte, len(key)+2)
-
-       buf[0] = db.index
-       buf[1] = SSizeType
-
-       copy(buf[2:], key)
-       return buf
-}
-
-func (db *DB) sDecodeSizeKey(ek []byte) ([]byte, error) {
-       if len(ek) < 2 || ek[0] != db.index || ek[1] != SSizeType {
-               return nil, errSSizeKey
-       }
-
-       return ek[2:], nil
-}
-
-func (db *DB) sEncodeSetKey(key []byte, member []byte) []byte {
-       buf := make([]byte, len(key)+len(member)+1+1+2+1)
-
-       pos := 0
-       buf[pos] = db.index
-       pos++
-       buf[pos] = SetType
-       pos++
-
-       binary.BigEndian.PutUint16(buf[pos:], uint16(len(key)))
-       pos += 2
-
-       copy(buf[pos:], key)
-       pos += len(key)
-
-       buf[pos] = setStartSep
-       pos++
-       copy(buf[pos:], member)
-
-       return buf
-}
-
-func (db *DB) sDecodeSetKey(ek []byte) ([]byte, []byte, error) {
-       if len(ek) < 5 || ek[0] != db.index || ek[1] != SetType {
-               return nil, nil, errSetKey
-       }
-
-       pos := 2
-       keyLen := int(binary.BigEndian.Uint16(ek[pos:]))
-       pos += 2
-
-       if keyLen+5 > len(ek) {
-               return nil, nil, errSetKey
-       }
-
-       key := ek[pos : pos+keyLen]
-       pos += keyLen
-
-       if ek[pos] != hashStartSep {
-               return nil, nil, errSetKey
-       }
-
-       pos++
-       member := ek[pos:]
-       return key, member, nil
-}
-
-func (db *DB) sEncodeStartKey(key []byte) []byte {
-       return db.sEncodeSetKey(key, nil)
-}
-
-func (db *DB) sEncodeStopKey(key []byte) []byte {
-       k := db.sEncodeSetKey(key, nil)
-
-       k[len(k)-1] = setStopSep
-
-       return k
-}
-
-func (db *DB) sFlush() (drop int64, err error) {
-
-       t := db.setBatch
-       t.Lock()
-       defer t.Unlock()
-
-       return db.flushType(t, SetType)
-}
-
-func (db *DB) sDelete(t *batch, key []byte) int64 {
-       sk := db.sEncodeSizeKey(key)
-       start := db.sEncodeStartKey(key)
-       stop := db.sEncodeStopKey(key)
-
-       var num int64 = 0
-       it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1)
-       for ; it.Valid(); it.Next() {
-               t.Delete(it.RawKey())
-               num++
-       }
-
-       it.Close()
-
-       t.Delete(sk)
-       return num
-}
-
-func (db *DB) sIncrSize(key []byte, delta int64) (int64, error) {
-       t := db.setBatch
-       sk := db.sEncodeSizeKey(key)
-
-       var err error
-       var size int64 = 0
-       if size, err = Int64(db.bucket.Get(sk)); err != nil {
-               return 0, err
-       } else {
-               size += delta
-               if size <= 0 {
-                       size = 0
-                       t.Delete(sk)
-                       db.rmExpire(t, SetType, key)
-               } else {
-                       t.Put(sk, PutInt64(size))
-               }
-       }
-
-       return size, nil
-}
-
-func (db *DB) sExpireAt(key []byte, when int64) (int64, error) {
-       t := db.setBatch
-       t.Lock()
-       defer t.Unlock()
-
-       if scnt, err := db.SCard(key); err != nil || scnt == 0 {
-               return 0, err
-       } else {
-               db.expireAt(t, SetType, key, when)
-               if err := t.Commit(); err != nil {
-                       return 0, err
-               }
-
-       }
-
-       return 1, nil
-}
-
-func (db *DB) sSetItem(key []byte, member []byte) (int64, error) {
-       t := db.setBatch
-       ek := db.sEncodeSetKey(key, member)
-
-       var n int64 = 1
-       if v, _ := db.bucket.Get(ek); v != nil {
-               n = 0
-       } else {
-               if _, err := db.sIncrSize(key, 1); err != nil {
-                       return 0, err
-               }
-       }
-
-       t.Put(ek, nil)
-       return n, nil
-}
-
-func (db *DB) SAdd(key []byte, args ...[]byte) (int64, error) {
-       t := db.setBatch
-       t.Lock()
-       defer t.Unlock()
-
-       var err error
-       var ek []byte
-       var num int64 = 0
-       for i := 0; i < len(args); i++ {
-               if err := checkSetKMSize(key, args[i]); err != nil {
-                       return 0, err
-               }
-
-               ek = db.sEncodeSetKey(key, args[i])
-
-               if v, err := db.bucket.Get(ek); err != nil {
-                       return 0, err
-               } else if v == nil {
-                       num++
-               }
-
-               t.Put(ek, nil)
-       }
-
-       if _, err = db.sIncrSize(key, num); err != nil {
-               return 0, err
-       }
-
-       err = t.Commit()
-       return num, err
-
-}
-
-func (db *DB) SCard(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-
-       sk := db.sEncodeSizeKey(key)
-
-       return Int64(db.bucket.Get(sk))
-}
-
-func (db *DB) sDiffGeneric(keys ...[]byte) ([][]byte, error) {
-       destMap := make(map[string]bool)
-
-       members, err := db.SMembers(keys[0])
-       if err != nil {
-               return nil, err
-       }
-
-       for _, m := range members {
-               destMap[String(m)] = true
-       }
-
-       for _, k := range keys[1:] {
-               members, err := db.SMembers(k)
-               if err != nil {
-                       return nil, err
-               }
-
-               for _, m := range members {
-                       if _, ok := destMap[String(m)]; !ok {
-                               continue
-                       } else if ok {
-                               delete(destMap, String(m))
-                       }
-               }
-               // O - A = O, O is zero set.
-               if len(destMap) == 0 {
-                       return nil, nil
-               }
-       }
-
-       slice := make([][]byte, len(destMap))
-       idx := 0
-       for k, v := range destMap {
-               if !v {
-                       continue
-               }
-               slice[idx] = []byte(k)
-               idx++
-       }
-
-       return slice, nil
-}
-
-func (db *DB) SDiff(keys ...[]byte) ([][]byte, error) {
-       v, err := db.sDiffGeneric(keys...)
-       return v, err
-}
-
-func (db *DB) SDiffStore(dstKey []byte, keys ...[]byte) (int64, error) {
-       n, err := db.sStoreGeneric(dstKey, DiffType, keys...)
-       return n, err
-}
-
-func (db *DB) sInterGeneric(keys ...[]byte) ([][]byte, error) {
-       destMap := make(map[string]bool)
-
-       members, err := db.SMembers(keys[0])
-       if err != nil {
-               return nil, err
-       }
-
-       for _, m := range members {
-               destMap[String(m)] = true
-       }
-
-       for _, key := range keys[1:] {
-               if err := checkKeySize(key); err != nil {
-                       return nil, err
-               }
-
-               members, err := db.SMembers(key)
-               if err != nil {
-                       return nil, err
-               } else if len(members) == 0 {
-                       return nil, err
-               }
-
-               tempMap := make(map[string]bool)
-               for _, member := range members {
-                       if err := checkKeySize(member); err != nil {
-                               return nil, err
-                       }
-                       if _, ok := destMap[String(member)]; ok {
-                               tempMap[String(member)] = true //mark this item as selected
-                       }
-               }
-               destMap = tempMap //reduce the size of the result set
-               if len(destMap) == 0 {
-                       return nil, nil
-               }
-       }
-
-       slice := make([][]byte, len(destMap))
-       idx := 0
-       for k, v := range destMap {
-               if !v {
-                       continue
-               }
-
-               slice[idx] = []byte(k)
-               idx++
-       }
-
-       return slice, nil
-
-}
-
-func (db *DB) SInter(keys ...[]byte) ([][]byte, error) {
-       v, err := db.sInterGeneric(keys...)
-       return v, err
-
-}
-
-func (db *DB) SInterStore(dstKey []byte, keys ...[]byte) (int64, error) {
-       n, err := db.sStoreGeneric(dstKey, InterType, keys...)
-       return n, err
-}
-
-func (db *DB) SIsMember(key []byte, member []byte) (int64, error) {
-       ek := db.sEncodeSetKey(key, member)
-
-       var n int64 = 1
-       if v, err := db.bucket.Get(ek); err != nil {
-               return 0, err
-       } else if v == nil {
-               n = 0
-       }
-       return n, nil
-}
-
-func (db *DB) SMembers(key []byte) ([][]byte, error) {
-       if err := checkKeySize(key); err != nil {
-               return nil, err
-       }
-
-       start := db.sEncodeStartKey(key)
-       stop := db.sEncodeStopKey(key)
-
-       v := make([][]byte, 0, 16)
-
-       it := db.bucket.RangeLimitIterator(start, stop, store.RangeROpen, 0, -1)
-       for ; it.Valid(); it.Next() {
-               _, m, err := db.sDecodeSetKey(it.Key())
-               if err != nil {
-                       return nil, err
-               }
-
-               v = append(v, m)
-       }
-
-       it.Close()
-
-       return v, nil
-}
-
-func (db *DB) SRem(key []byte, args ...[]byte) (int64, error) {
-       t := db.setBatch
-       t.Lock()
-       defer t.Unlock()
-
-       var ek []byte
-       var v []byte
-       var err error
-
-       it := db.bucket.NewIterator()
-       defer it.Close()
-
-       var num int64 = 0
-       for i := 0; i < len(args); i++ {
-               if err := checkSetKMSize(key, args[i]); err != nil {
-                       return 0, err
-               }
-
-               ek = db.sEncodeSetKey(key, args[i])
-
-               v = it.RawFind(ek)
-               if v == nil {
-                       continue
-               } else {
-                       num++
-                       t.Delete(ek)
-               }
-       }
-
-       if _, err = db.sIncrSize(key, -num); err != nil {
-               return 0, err
-       }
-
-       err = t.Commit()
-       return num, err
-
-}
-
-func (db *DB) sUnionGeneric(keys ...[]byte) ([][]byte, error) {
-       dstMap := make(map[string]bool)
-
-       for _, key := range keys {
-               if err := checkKeySize(key); err != nil {
-                       return nil, err
-               }
-
-               members, err := db.SMembers(key)
-               if err != nil {
-                       return nil, err
-               }
-
-               for _, member := range members {
-                       dstMap[String(member)] = true
-               }
-       }
-
-       slice := make([][]byte, len(dstMap))
-       idx := 0
-       for k, v := range dstMap {
-               if !v {
-                       continue
-               }
-               slice[idx] = []byte(k)
-               idx++
-       }
-
-       return slice, nil
-}
-
-func (db *DB) SUnion(keys ...[]byte) ([][]byte, error) {
-       v, err := db.sUnionGeneric(keys...)
-       return v, err
-}
-
-func (db *DB) SUnionStore(dstKey []byte, keys ...[]byte) (int64, error) {
-       n, err := db.sStoreGeneric(dstKey, UnionType, keys...)
-       return n, err
-}
-
-func (db *DB) sStoreGeneric(dstKey []byte, optType byte, keys ...[]byte) (int64, error) {
-       if err := checkKeySize(dstKey); err != nil {
-               return 0, err
-       }
-
-       t := db.setBatch
-       t.Lock()
-       defer t.Unlock()
-
-       db.sDelete(t, dstKey)
-
-       var err error
-       var ek []byte
-       var v [][]byte
-
-       switch optType {
-       case UnionType:
-               v, err = db.sUnionGeneric(keys...)
-       case DiffType:
-               v, err = db.sDiffGeneric(keys...)
-       case InterType:
-               v, err = db.sInterGeneric(keys...)
-       }
-
-       if err != nil {
-               return 0, err
-       }
-
-       for _, m := range v {
-               if err := checkSetKMSize(dstKey, m); err != nil {
-                       return 0, err
-               }
-
-               ek = db.sEncodeSetKey(dstKey, m)
-
-               if _, err := db.bucket.Get(ek); err != nil {
-                       return 0, err
-               }
-
-               t.Put(ek, nil)
-       }
-
-       var num = int64(len(v))
-       sk := db.sEncodeSizeKey(dstKey)
-       t.Put(sk, PutInt64(num))
-
-       if err = t.Commit(); err != nil {
-               return 0, err
-       }
-       return num, nil
-}
-
-func (db *DB) SClear(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-
-       t := db.setBatch
-       t.Lock()
-       defer t.Unlock()
-
-       num := db.sDelete(t, key)
-       db.rmExpire(t, SetType, key)
-
-       err := t.Commit()
-       return num, err
-}
-
-func (db *DB) SMclear(keys ...[]byte) (int64, error) {
-       t := db.setBatch
-       t.Lock()
-       defer t.Unlock()
-
-       for _, key := range keys {
-               if err := checkKeySize(key); err != nil {
-                       return 0, err
-               }
-
-               db.sDelete(t, key)
-               db.rmExpire(t, SetType, key)
-       }
-
-       err := t.Commit()
-       return int64(len(keys)), err
-}
-
-func (db *DB) SExpire(key []byte, duration int64) (int64, error) {
-       if duration <= 0 {
-               return 0, errExpireValue
-       }
-
-       return db.sExpireAt(key, time.Now().Unix()+duration)
-
-}
-
-func (db *DB) SExpireAt(key []byte, when int64) (int64, error) {
-       if when <= time.Now().Unix() {
-               return 0, errExpireValue
-       }
-
-       return db.sExpireAt(key, when)
-
-}
-
-func (db *DB) STTL(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return -1, err
-       }
-
-       return db.ttl(SetType, key)
-}
-
-func (db *DB) SPersist(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-
-       t := db.setBatch
-       t.Lock()
-       defer t.Unlock()
-
-       n, err := db.rmExpire(t, SetType, key)
-       if err != nil {
-               return 0, err
-       }
-       err = t.Commit()
-       return n, err
-}
-
-func (db *DB) SScan(key []byte, count int, inclusive bool, match string) ([][]byte, error) {
-       return db.scan(SSizeType, key, count, inclusive, match)
-}
diff --git a/vendor/github.com/lunny/nodb/t_ttl.go b/vendor/github.com/lunny/nodb/t_ttl.go
deleted file mode 100644 (file)
index 5c36388..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-package nodb
-
-import (
-       "encoding/binary"
-       "errors"
-       "time"
-
-       "github.com/lunny/nodb/store"
-)
-
-var (
-       errExpMetaKey = errors.New("invalid expire meta key")
-       errExpTimeKey = errors.New("invalid expire time key")
-)
-
-type retireCallback func(*batch, []byte) int64
-
-type elimination struct {
-       db         *DB
-       exp2Tx     []*batch
-       exp2Retire []retireCallback
-}
-
-var errExpType = errors.New("invalid expire type")
-
-func (db *DB) expEncodeTimeKey(dataType byte, key []byte, when int64) []byte {
-       buf := make([]byte, len(key)+11)
-
-       buf[0] = db.index
-       buf[1] = ExpTimeType
-       buf[2] = dataType
-       pos := 3
-
-       binary.BigEndian.PutUint64(buf[pos:], uint64(when))
-       pos += 8
-
-       copy(buf[pos:], key)
-
-       return buf
-}
-
-func (db *DB) expEncodeMetaKey(dataType byte, key []byte) []byte {
-       buf := make([]byte, len(key)+3)
-
-       buf[0] = db.index
-       buf[1] = ExpMetaType
-       buf[2] = dataType
-       pos := 3
-
-       copy(buf[pos:], key)
-
-       return buf
-}
-
-func (db *DB) expDecodeMetaKey(mk []byte) (byte, []byte, error) {
-       if len(mk) <= 3 || mk[0] != db.index || mk[1] != ExpMetaType {
-               return 0, nil, errExpMetaKey
-       }
-
-       return mk[2], mk[3:], nil
-}
-
-func (db *DB) expDecodeTimeKey(tk []byte) (byte, []byte, int64, error) {
-       if len(tk) < 11 || tk[0] != db.index || tk[1] != ExpTimeType {
-               return 0, nil, 0, errExpTimeKey
-       }
-
-       return tk[2], tk[11:], int64(binary.BigEndian.Uint64(tk[3:])), nil
-}
-
-func (db *DB) expire(t *batch, dataType byte, key []byte, duration int64) {
-       db.expireAt(t, dataType, key, time.Now().Unix()+duration)
-}
-
-func (db *DB) expireAt(t *batch, dataType byte, key []byte, when int64) {
-       mk := db.expEncodeMetaKey(dataType, key)
-       tk := db.expEncodeTimeKey(dataType, key, when)
-
-       t.Put(tk, mk)
-       t.Put(mk, PutInt64(when))
-}
-
-func (db *DB) ttl(dataType byte, key []byte) (t int64, err error) {
-       mk := db.expEncodeMetaKey(dataType, key)
-
-       if t, err = Int64(db.bucket.Get(mk)); err != nil || t == 0 {
-               t = -1
-       } else {
-               t -= time.Now().Unix()
-               if t <= 0 {
-                       t = -1
-               }
-               // if t == -1 : to remove ????
-       }
-
-       return t, err
-}
-
-func (db *DB) rmExpire(t *batch, dataType byte, key []byte) (int64, error) {
-       mk := db.expEncodeMetaKey(dataType, key)
-       if v, err := db.bucket.Get(mk); err != nil {
-               return 0, err
-       } else if v == nil {
-               return 0, nil
-       } else if when, err2 := Int64(v, nil); err2 != nil {
-               return 0, err2
-       } else {
-               tk := db.expEncodeTimeKey(dataType, key, when)
-               t.Delete(mk)
-               t.Delete(tk)
-               return 1, nil
-       }
-}
-
-func (db *DB) expFlush(t *batch, dataType byte) (err error) {
-       minKey := make([]byte, 3)
-       minKey[0] = db.index
-       minKey[1] = ExpTimeType
-       minKey[2] = dataType
-
-       maxKey := make([]byte, 3)
-       maxKey[0] = db.index
-       maxKey[1] = ExpMetaType
-       maxKey[2] = dataType + 1
-
-       _, err = db.flushRegion(t, minKey, maxKey)
-       err = t.Commit()
-       return
-}
-
-//////////////////////////////////////////////////////////
-//
-//////////////////////////////////////////////////////////
-
-func newEliminator(db *DB) *elimination {
-       eli := new(elimination)
-       eli.db = db
-       eli.exp2Tx = make([]*batch, maxDataType)
-       eli.exp2Retire = make([]retireCallback, maxDataType)
-       return eli
-}
-
-func (eli *elimination) regRetireContext(dataType byte, t *batch, onRetire retireCallback) {
-
-       //      todo .. need to ensure exist - mapExpMetaType[expType]
-
-       eli.exp2Tx[dataType] = t
-       eli.exp2Retire[dataType] = onRetire
-}
-
-//     call by outside ... (from *db to another *db)
-func (eli *elimination) active() {
-       now := time.Now().Unix()
-       db := eli.db
-       dbGet := db.bucket.Get
-
-       minKey := db.expEncodeTimeKey(NoneType, nil, 0)
-       maxKey := db.expEncodeTimeKey(maxDataType, nil, now)
-
-       it := db.bucket.RangeLimitIterator(minKey, maxKey, store.RangeROpen, 0, -1)
-       for ; it.Valid(); it.Next() {
-               tk := it.RawKey()
-               mk := it.RawValue()
-
-               dt, k, _, err := db.expDecodeTimeKey(tk)
-               if err != nil {
-                       continue
-               }
-
-               t := eli.exp2Tx[dt]
-               onRetire := eli.exp2Retire[dt]
-               if tk == nil || onRetire == nil {
-                       continue
-               }
-
-               t.Lock()
-
-               if exp, err := Int64(dbGet(mk)); err == nil {
-                       // check expire again
-                       if exp <= now {
-                               onRetire(t, k)
-                               t.Delete(tk)
-                               t.Delete(mk)
-
-                               t.Commit()
-                       }
-
-               }
-
-               t.Unlock()
-       }
-       it.Close()
-
-       return
-}
diff --git a/vendor/github.com/lunny/nodb/t_zset.go b/vendor/github.com/lunny/nodb/t_zset.go
deleted file mode 100644 (file)
index d0ffb7c..0000000
+++ /dev/null
@@ -1,943 +0,0 @@
-package nodb
-
-import (
-       "bytes"
-       "encoding/binary"
-       "errors"
-       "time"
-
-       "github.com/lunny/nodb/store"
-)
-
-const (
-       MinScore     int64 = -1<<63 + 1
-       MaxScore     int64 = 1<<63 - 1
-       InvalidScore int64 = -1 << 63
-
-       AggregateSum byte = 0
-       AggregateMin byte = 1
-       AggregateMax byte = 2
-)
-
-type ScorePair struct {
-       Score  int64
-       Member []byte
-}
-
-var errZSizeKey = errors.New("invalid zsize key")
-var errZSetKey = errors.New("invalid zset key")
-var errZScoreKey = errors.New("invalid zscore key")
-var errScoreOverflow = errors.New("zset score overflow")
-var errInvalidAggregate = errors.New("invalid aggregate")
-var errInvalidWeightNum = errors.New("invalid weight number")
-var errInvalidSrcKeyNum = errors.New("invalid src key number")
-
-const (
-       zsetNScoreSep    byte = '<'
-       zsetPScoreSep    byte = zsetNScoreSep + 1
-       zsetStopScoreSep byte = zsetPScoreSep + 1
-
-       zsetStartMemSep byte = ':'
-       zsetStopMemSep  byte = zsetStartMemSep + 1
-)
-
-func checkZSetKMSize(key []byte, member []byte) error {
-       if len(key) > MaxKeySize || len(key) == 0 {
-               return errKeySize
-       } else if len(member) > MaxZSetMemberSize || len(member) == 0 {
-               return errZSetMemberSize
-       }
-       return nil
-}
-
-func (db *DB) zEncodeSizeKey(key []byte) []byte {
-       buf := make([]byte, len(key)+2)
-       buf[0] = db.index
-       buf[1] = ZSizeType
-
-       copy(buf[2:], key)
-       return buf
-}
-
-func (db *DB) zDecodeSizeKey(ek []byte) ([]byte, error) {
-       if len(ek) < 2 || ek[0] != db.index || ek[1] != ZSizeType {
-               return nil, errZSizeKey
-       }
-
-       return ek[2:], nil
-}
-
-func (db *DB) zEncodeSetKey(key []byte, member []byte) []byte {
-       buf := make([]byte, len(key)+len(member)+5)
-
-       pos := 0
-       buf[pos] = db.index
-       pos++
-
-       buf[pos] = ZSetType
-       pos++
-
-       binary.BigEndian.PutUint16(buf[pos:], uint16(len(key)))
-       pos += 2
-
-       copy(buf[pos:], key)
-       pos += len(key)
-
-       buf[pos] = zsetStartMemSep
-       pos++
-
-       copy(buf[pos:], member)
-
-       return buf
-}
-
-func (db *DB) zDecodeSetKey(ek []byte) ([]byte, []byte, error) {
-       if len(ek) < 5 || ek[0] != db.index || ek[1] != ZSetType {
-               return nil, nil, errZSetKey
-       }
-
-       keyLen := int(binary.BigEndian.Uint16(ek[2:]))
-       if keyLen+5 > len(ek) {
-               return nil, nil, errZSetKey
-       }
-
-       key := ek[4 : 4+keyLen]
-
-       if ek[4+keyLen] != zsetStartMemSep {
-               return nil, nil, errZSetKey
-       }
-
-       member := ek[5+keyLen:]
-       return key, member, nil
-}
-
-func (db *DB) zEncodeStartSetKey(key []byte) []byte {
-       k := db.zEncodeSetKey(key, nil)
-       return k
-}
-
-func (db *DB) zEncodeStopSetKey(key []byte) []byte {
-       k := db.zEncodeSetKey(key, nil)
-       k[len(k)-1] = zsetStartMemSep + 1
-       return k
-}
-
-func (db *DB) zEncodeScoreKey(key []byte, member []byte, score int64) []byte {
-       buf := make([]byte, len(key)+len(member)+14)
-
-       pos := 0
-       buf[pos] = db.index
-       pos++
-
-       buf[pos] = ZScoreType
-       pos++
-
-       binary.BigEndian.PutUint16(buf[pos:], uint16(len(key)))
-       pos += 2
-
-       copy(buf[pos:], key)
-       pos += len(key)
-
-       if score < 0 {
-               buf[pos] = zsetNScoreSep
-       } else {
-               buf[pos] = zsetPScoreSep
-       }
-
-       pos++
-       binary.BigEndian.PutUint64(buf[pos:], uint64(score))
-       pos += 8
-
-       buf[pos] = zsetStartMemSep
-       pos++
-
-       copy(buf[pos:], member)
-       return buf
-}
-
-func (db *DB) zEncodeStartScoreKey(key []byte, score int64) []byte {
-       return db.zEncodeScoreKey(key, nil, score)
-}
-
-func (db *DB) zEncodeStopScoreKey(key []byte, score int64) []byte {
-       k := db.zEncodeScoreKey(key, nil, score)
-       k[len(k)-1] = zsetStopMemSep
-       return k
-}
-
-func (db *DB) zDecodeScoreKey(ek []byte) (key []byte, member []byte, score int64, err error) {
-       if len(ek) < 14 || ek[0] != db.index || ek[1] != ZScoreType {
-               err = errZScoreKey
-               return
-       }
-
-       keyLen := int(binary.BigEndian.Uint16(ek[2:]))
-       if keyLen+14 > len(ek) {
-               err = errZScoreKey
-               return
-       }
-
-       key = ek[4 : 4+keyLen]
-       pos := 4 + keyLen
-
-       if (ek[pos] != zsetNScoreSep) && (ek[pos] != zsetPScoreSep) {
-               err = errZScoreKey
-               return
-       }
-       pos++
-
-       score = int64(binary.BigEndian.Uint64(ek[pos:]))
-       pos += 8
-
-       if ek[pos] != zsetStartMemSep {
-               err = errZScoreKey
-               return
-       }
-
-       pos++
-
-       member = ek[pos:]
-       return
-}
-
-func (db *DB) zSetItem(t *batch, key []byte, score int64, member []byte) (int64, error) {
-       if score <= MinScore || score >= MaxScore {
-               return 0, errScoreOverflow
-       }
-
-       var exists int64 = 0
-       ek := db.zEncodeSetKey(key, member)
-
-       if v, err := db.bucket.Get(ek); err != nil {
-               return 0, err
-       } else if v != nil {
-               exists = 1
-
-               if s, err := Int64(v, err); err != nil {
-                       return 0, err
-               } else {
-                       sk := db.zEncodeScoreKey(key, member, s)
-                       t.Delete(sk)
-               }
-       }
-
-       t.Put(ek, PutInt64(score))
-
-       sk := db.zEncodeScoreKey(key, member, score)
-       t.Put(sk, []byte{})
-
-       return exists, nil
-}
-
-func (db *DB) zDelItem(t *batch, key []byte, member []byte, skipDelScore bool) (int64, error) {
-       ek := db.zEncodeSetKey(key, member)
-       if v, err := db.bucket.Get(ek); err != nil {
-               return 0, err
-       } else if v == nil {
-               //not exists
-               return 0, nil
-       } else {
-               //exists
-               if !skipDelScore {
-                       //we must del score
-                       if s, err := Int64(v, err); err != nil {
-                               return 0, err
-                       } else {
-                               sk := db.zEncodeScoreKey(key, member, s)
-                               t.Delete(sk)
-                       }
-               }
-       }
-
-       t.Delete(ek)
-
-       return 1, nil
-}
-
-func (db *DB) zDelete(t *batch, key []byte) int64 {
-       delMembCnt, _ := db.zRemRange(t, key, MinScore, MaxScore, 0, -1)
-       //      todo : log err
-       return delMembCnt
-}
-
-func (db *DB) zExpireAt(key []byte, when int64) (int64, error) {
-       t := db.zsetBatch
-       t.Lock()
-       defer t.Unlock()
-
-       if zcnt, err := db.ZCard(key); err != nil || zcnt == 0 {
-               return 0, err
-       } else {
-               db.expireAt(t, ZSetType, key, when)
-               if err := t.Commit(); err != nil {
-                       return 0, err
-               }
-       }
-       return 1, nil
-}
-
-func (db *DB) ZAdd(key []byte, args ...ScorePair) (int64, error) {
-       if len(args) == 0 {
-               return 0, nil
-       }
-
-       t := db.zsetBatch
-       t.Lock()
-       defer t.Unlock()
-
-       var num int64 = 0
-       for i := 0; i < len(args); i++ {
-               score := args[i].Score
-               member := args[i].Member
-
-               if err := checkZSetKMSize(key, member); err != nil {
-                       return 0, err
-               }
-
-               if n, err := db.zSetItem(t, key, score, member); err != nil {
-                       return 0, err
-               } else if n == 0 {
-                       //add new
-                       num++
-               }
-       }
-
-       if _, err := db.zIncrSize(t, key, num); err != nil {
-               return 0, err
-       }
-
-       //todo add binlog
-       err := t.Commit()
-       return num, err
-}
-
-func (db *DB) zIncrSize(t *batch, key []byte, delta int64) (int64, error) {
-       sk := db.zEncodeSizeKey(key)
-
-       size, err := Int64(db.bucket.Get(sk))
-       if err != nil {
-               return 0, err
-       } else {
-               size += delta
-               if size <= 0 {
-                       size = 0
-                       t.Delete(sk)
-                       db.rmExpire(t, ZSetType, key)
-               } else {
-                       t.Put(sk, PutInt64(size))
-               }
-       }
-
-       return size, nil
-}
-
-func (db *DB) ZCard(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-
-       sk := db.zEncodeSizeKey(key)
-       return Int64(db.bucket.Get(sk))
-}
-
-func (db *DB) ZScore(key []byte, member []byte) (int64, error) {
-       if err := checkZSetKMSize(key, member); err != nil {
-               return InvalidScore, err
-       }
-
-       var score int64 = InvalidScore
-
-       k := db.zEncodeSetKey(key, member)
-       if v, err := db.bucket.Get(k); err != nil {
-               return InvalidScore, err
-       } else if v == nil {
-               return InvalidScore, ErrScoreMiss
-       } else {
-               if score, err = Int64(v, nil); err != nil {
-                       return InvalidScore, err
-               }
-       }
-
-       return score, nil
-}
-
-func (db *DB) ZRem(key []byte, members ...[]byte) (int64, error) {
-       if len(members) == 0 {
-               return 0, nil
-       }
-
-       t := db.zsetBatch
-       t.Lock()
-       defer t.Unlock()
-
-       var num int64 = 0
-       for i := 0; i < len(members); i++ {
-               if err := checkZSetKMSize(key, members[i]); err != nil {
-                       return 0, err
-               }
-
-               if n, err := db.zDelItem(t, key, members[i], false); err != nil {
-                       return 0, err
-               } else if n == 1 {
-                       num++
-               }
-       }
-
-       if _, err := db.zIncrSize(t, key, -num); err != nil {
-               return 0, err
-       }
-
-       err := t.Commit()
-       return num, err
-}
-
-func (db *DB) ZIncrBy(key []byte, delta int64, member []byte) (int64, error) {
-       if err := checkZSetKMSize(key, member); err != nil {
-               return InvalidScore, err
-       }
-
-       t := db.zsetBatch
-       t.Lock()
-       defer t.Unlock()
-
-       ek := db.zEncodeSetKey(key, member)
-
-       var oldScore int64 = 0
-       v, err := db.bucket.Get(ek)
-       if err != nil {
-               return InvalidScore, err
-       } else if v == nil {
-               db.zIncrSize(t, key, 1)
-       } else {
-               if oldScore, err = Int64(v, err); err != nil {
-                       return InvalidScore, err
-               }
-       }
-
-       newScore := oldScore + delta
-       if newScore >= MaxScore || newScore <= MinScore {
-               return InvalidScore, errScoreOverflow
-       }
-
-       sk := db.zEncodeScoreKey(key, member, newScore)
-       t.Put(sk, []byte{})
-       t.Put(ek, PutInt64(newScore))
-
-       if v != nil {
-               // so as to update score, we must delete the old one
-               oldSk := db.zEncodeScoreKey(key, member, oldScore)
-               t.Delete(oldSk)
-       }
-
-       err = t.Commit()
-       return newScore, err
-}
-
-func (db *DB) ZCount(key []byte, min int64, max int64) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-       minKey := db.zEncodeStartScoreKey(key, min)
-       maxKey := db.zEncodeStopScoreKey(key, max)
-
-       rangeType := store.RangeROpen
-
-       it := db.bucket.RangeLimitIterator(minKey, maxKey, rangeType, 0, -1)
-       var n int64 = 0
-       for ; it.Valid(); it.Next() {
-               n++
-       }
-       it.Close()
-
-       return n, nil
-}
-
-func (db *DB) zrank(key []byte, member []byte, reverse bool) (int64, error) {
-       if err := checkZSetKMSize(key, member); err != nil {
-               return 0, err
-       }
-
-       k := db.zEncodeSetKey(key, member)
-
-       it := db.bucket.NewIterator()
-       defer it.Close()
-
-       if v := it.Find(k); v == nil {
-               return -1, nil
-       } else {
-               if s, err := Int64(v, nil); err != nil {
-                       return 0, err
-               } else {
-                       var rit *store.RangeLimitIterator
-
-                       sk := db.zEncodeScoreKey(key, member, s)
-
-                       if !reverse {
-                               minKey := db.zEncodeStartScoreKey(key, MinScore)
-
-                               rit = store.NewRangeIterator(it, &store.Range{minKey, sk, store.RangeClose})
-                       } else {
-                               maxKey := db.zEncodeStopScoreKey(key, MaxScore)
-                               rit = store.NewRevRangeIterator(it, &store.Range{sk, maxKey, store.RangeClose})
-                       }
-
-                       var lastKey []byte = nil
-                       var n int64 = 0
-
-                       for ; rit.Valid(); rit.Next() {
-                               n++
-
-                               lastKey = rit.BufKey(lastKey)
-                       }
-
-                       if _, m, _, err := db.zDecodeScoreKey(lastKey); err == nil && bytes.Equal(m, member) {
-                               n--
-                               return n, nil
-                       }
-               }
-       }
-
-       return -1, nil
-}
-
-func (db *DB) zIterator(key []byte, min int64, max int64, offset int, count int, reverse bool) *store.RangeLimitIterator {
-       minKey := db.zEncodeStartScoreKey(key, min)
-       maxKey := db.zEncodeStopScoreKey(key, max)
-
-       if !reverse {
-               return db.bucket.RangeLimitIterator(minKey, maxKey, store.RangeClose, offset, count)
-       } else {
-               return db.bucket.RevRangeLimitIterator(minKey, maxKey, store.RangeClose, offset, count)
-       }
-}
-
-func (db *DB) zRemRange(t *batch, key []byte, min int64, max int64, offset int, count int) (int64, error) {
-       if len(key) > MaxKeySize {
-               return 0, errKeySize
-       }
-
-       it := db.zIterator(key, min, max, offset, count, false)
-       var num int64 = 0
-       for ; it.Valid(); it.Next() {
-               sk := it.RawKey()
-               _, m, _, err := db.zDecodeScoreKey(sk)
-               if err != nil {
-                       continue
-               }
-
-               if n, err := db.zDelItem(t, key, m, true); err != nil {
-                       return 0, err
-               } else if n == 1 {
-                       num++
-               }
-
-               t.Delete(sk)
-       }
-       it.Close()
-
-       if _, err := db.zIncrSize(t, key, -num); err != nil {
-               return 0, err
-       }
-
-       return num, nil
-}
-
-func (db *DB) zRange(key []byte, min int64, max int64, offset int, count int, reverse bool) ([]ScorePair, error) {
-       if len(key) > MaxKeySize {
-               return nil, errKeySize
-       }
-
-       if offset < 0 {
-               return []ScorePair{}, nil
-       }
-
-       nv := 64
-       if count > 0 {
-               nv = count
-       }
-
-       v := make([]ScorePair, 0, nv)
-
-       var it *store.RangeLimitIterator
-
-       //if reverse and offset is 0, count < 0, we may use forward iterator then reverse
-       //because store iterator prev is slower than next
-       if !reverse || (offset == 0 && count < 0) {
-               it = db.zIterator(key, min, max, offset, count, false)
-       } else {
-               it = db.zIterator(key, min, max, offset, count, true)
-       }
-
-       for ; it.Valid(); it.Next() {
-               _, m, s, err := db.zDecodeScoreKey(it.Key())
-               //may be we will check key equal?
-               if err != nil {
-                       continue
-               }
-
-               v = append(v, ScorePair{Member: m, Score: s})
-       }
-       it.Close()
-
-       if reverse && (offset == 0 && count < 0) {
-               for i, j := 0, len(v)-1; i < j; i, j = i+1, j-1 {
-                       v[i], v[j] = v[j], v[i]
-               }
-       }
-
-       return v, nil
-}
-
-func (db *DB) zParseLimit(key []byte, start int, stop int) (offset int, count int, err error) {
-       if start < 0 || stop < 0 {
-               //refer redis implementation
-               var size int64
-               size, err = db.ZCard(key)
-               if err != nil {
-                       return
-               }
-
-               llen := int(size)
-
-               if start < 0 {
-                       start = llen + start
-               }
-               if stop < 0 {
-                       stop = llen + stop
-               }
-
-               if start < 0 {
-                       start = 0
-               }
-
-               if start >= llen {
-                       offset = -1
-                       return
-               }
-       }
-
-       if start > stop {
-               offset = -1
-               return
-       }
-
-       offset = start
-       count = (stop - start) + 1
-       return
-}
-
-func (db *DB) ZClear(key []byte) (int64, error) {
-       t := db.zsetBatch
-       t.Lock()
-       defer t.Unlock()
-
-       rmCnt, err := db.zRemRange(t, key, MinScore, MaxScore, 0, -1)
-       if err == nil {
-               err = t.Commit()
-       }
-
-       return rmCnt, err
-}
-
-func (db *DB) ZMclear(keys ...[]byte) (int64, error) {
-       t := db.zsetBatch
-       t.Lock()
-       defer t.Unlock()
-
-       for _, key := range keys {
-               if _, err := db.zRemRange(t, key, MinScore, MaxScore, 0, -1); err != nil {
-                       return 0, err
-               }
-       }
-
-       err := t.Commit()
-
-       return int64(len(keys)), err
-}
-
-func (db *DB) ZRange(key []byte, start int, stop int) ([]ScorePair, error) {
-       return db.ZRangeGeneric(key, start, stop, false)
-}
-
-//min and max must be inclusive
-//if no limit, set offset = 0 and count = -1
-func (db *DB) ZRangeByScore(key []byte, min int64, max int64,
-       offset int, count int) ([]ScorePair, error) {
-       return db.ZRangeByScoreGeneric(key, min, max, offset, count, false)
-}
-
-func (db *DB) ZRank(key []byte, member []byte) (int64, error) {
-       return db.zrank(key, member, false)
-}
-
-func (db *DB) ZRemRangeByRank(key []byte, start int, stop int) (int64, error) {
-       offset, count, err := db.zParseLimit(key, start, stop)
-       if err != nil {
-               return 0, err
-       }
-
-       var rmCnt int64
-
-       t := db.zsetBatch
-       t.Lock()
-       defer t.Unlock()
-
-       rmCnt, err = db.zRemRange(t, key, MinScore, MaxScore, offset, count)
-       if err == nil {
-               err = t.Commit()
-       }
-
-       return rmCnt, err
-}
-
-//min and max must be inclusive
-func (db *DB) ZRemRangeByScore(key []byte, min int64, max int64) (int64, error) {
-       t := db.zsetBatch
-       t.Lock()
-       defer t.Unlock()
-
-       rmCnt, err := db.zRemRange(t, key, min, max, 0, -1)
-       if err == nil {
-               err = t.Commit()
-       }
-
-       return rmCnt, err
-}
-
-func (db *DB) ZRevRange(key []byte, start int, stop int) ([]ScorePair, error) {
-       return db.ZRangeGeneric(key, start, stop, true)
-}
-
-func (db *DB) ZRevRank(key []byte, member []byte) (int64, error) {
-       return db.zrank(key, member, true)
-}
-
-//min and max must be inclusive
-//if no limit, set offset = 0 and count = -1
-func (db *DB) ZRevRangeByScore(key []byte, min int64, max int64, offset int, count int) ([]ScorePair, error) {
-       return db.ZRangeByScoreGeneric(key, min, max, offset, count, true)
-}
-
-func (db *DB) ZRangeGeneric(key []byte, start int, stop int, reverse bool) ([]ScorePair, error) {
-       offset, count, err := db.zParseLimit(key, start, stop)
-       if err != nil {
-               return nil, err
-       }
-
-       return db.zRange(key, MinScore, MaxScore, offset, count, reverse)
-}
-
-//min and max must be inclusive
-//if no limit, set offset = 0 and count = -1
-func (db *DB) ZRangeByScoreGeneric(key []byte, min int64, max int64,
-       offset int, count int, reverse bool) ([]ScorePair, error) {
-
-       return db.zRange(key, min, max, offset, count, reverse)
-}
-
-func (db *DB) zFlush() (drop int64, err error) {
-       t := db.zsetBatch
-       t.Lock()
-       defer t.Unlock()
-       return db.flushType(t, ZSetType)
-}
-
-func (db *DB) ZExpire(key []byte, duration int64) (int64, error) {
-       if duration <= 0 {
-               return 0, errExpireValue
-       }
-
-       return db.zExpireAt(key, time.Now().Unix()+duration)
-}
-
-func (db *DB) ZExpireAt(key []byte, when int64) (int64, error) {
-       if when <= time.Now().Unix() {
-               return 0, errExpireValue
-       }
-
-       return db.zExpireAt(key, when)
-}
-
-func (db *DB) ZTTL(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return -1, err
-       }
-
-       return db.ttl(ZSetType, key)
-}
-
-func (db *DB) ZPersist(key []byte) (int64, error) {
-       if err := checkKeySize(key); err != nil {
-               return 0, err
-       }
-
-       t := db.zsetBatch
-       t.Lock()
-       defer t.Unlock()
-
-       n, err := db.rmExpire(t, ZSetType, key)
-       if err != nil {
-               return 0, err
-       }
-
-       err = t.Commit()
-       return n, err
-}
-
-func getAggregateFunc(aggregate byte) func(int64, int64) int64 {
-       switch aggregate {
-       case AggregateSum:
-               return func(a int64, b int64) int64 {
-                       return a + b
-               }
-       case AggregateMax:
-               return func(a int64, b int64) int64 {
-                       if a > b {
-                               return a
-                       }
-                       return b
-               }
-       case AggregateMin:
-               return func(a int64, b int64) int64 {
-                       if a > b {
-                               return b
-                       }
-                       return a
-               }
-       }
-       return nil
-}
-
-func (db *DB) ZUnionStore(destKey []byte, srcKeys [][]byte, weights []int64, aggregate byte) (int64, error) {
-
-       var destMap = map[string]int64{}
-       aggregateFunc := getAggregateFunc(aggregate)
-       if aggregateFunc == nil {
-               return 0, errInvalidAggregate
-       }
-       if len(srcKeys) < 1 {
-               return 0, errInvalidSrcKeyNum
-       }
-       if weights != nil {
-               if len(srcKeys) != len(weights) {
-                       return 0, errInvalidWeightNum
-               }
-       } else {
-               weights = make([]int64, len(srcKeys))
-               for i := 0; i < len(weights); i++ {
-                       weights[i] = 1
-               }
-       }
-
-       for i, key := range srcKeys {
-               scorePairs, err := db.ZRange(key, 0, -1)
-               if err != nil {
-                       return 0, err
-               }
-               for _, pair := range scorePairs {
-                       if score, ok := destMap[String(pair.Member)]; !ok {
-                               destMap[String(pair.Member)] = pair.Score * weights[i]
-                       } else {
-                               destMap[String(pair.Member)] = aggregateFunc(score, pair.Score*weights[i])
-                       }
-               }
-       }
-
-       t := db.zsetBatch
-       t.Lock()
-       defer t.Unlock()
-
-       db.zDelete(t, destKey)
-
-       for member, score := range destMap {
-               if err := checkZSetKMSize(destKey, []byte(member)); err != nil {
-                       return 0, err
-               }
-
-               if _, err := db.zSetItem(t, destKey, score, []byte(member)); err != nil {
-                       return 0, err
-               }
-       }
-
-       var num = int64(len(destMap))
-       sk := db.zEncodeSizeKey(destKey)
-       t.Put(sk, PutInt64(num))
-
-       //todo add binlog
-       if err := t.Commit(); err != nil {
-               return 0, err
-       }
-       return num, nil
-}
-
-func (db *DB) ZInterStore(destKey []byte, srcKeys [][]byte, weights []int64, aggregate byte) (int64, error) {
-
-       aggregateFunc := getAggregateFunc(aggregate)
-       if aggregateFunc == nil {
-               return 0, errInvalidAggregate
-       }
-       if len(srcKeys) < 1 {
-               return 0, errInvalidSrcKeyNum
-       }
-       if weights != nil {
-               if len(srcKeys) != len(weights) {
-                       return 0, errInvalidWeightNum
-               }
-       } else {
-               weights = make([]int64, len(srcKeys))
-               for i := 0; i < len(weights); i++ {
-                       weights[i] = 1
-               }
-       }
-
-       var destMap = map[string]int64{}
-       scorePairs, err := db.ZRange(srcKeys[0], 0, -1)
-       if err != nil {
-               return 0, err
-       }
-       for _, pair := range scorePairs {
-               destMap[String(pair.Member)] = pair.Score * weights[0]
-       }
-
-       for i, key := range srcKeys[1:] {
-               scorePairs, err := db.ZRange(key, 0, -1)
-               if err != nil {
-                       return 0, err
-               }
-               tmpMap := map[string]int64{}
-               for _, pair := range scorePairs {
-                       if score, ok := destMap[String(pair.Member)]; ok {
-                               tmpMap[String(pair.Member)] = aggregateFunc(score, pair.Score*weights[i+1])
-                       }
-               }
-               destMap = tmpMap
-       }
-
-       t := db.zsetBatch
-       t.Lock()
-       defer t.Unlock()
-
-       db.zDelete(t, destKey)
-
-       for member, score := range destMap {
-               if err := checkZSetKMSize(destKey, []byte(member)); err != nil {
-                       return 0, err
-               }
-               if _, err := db.zSetItem(t, destKey, score, []byte(member)); err != nil {
-                       return 0, err
-               }
-       }
-
-       var num int64 = int64(len(destMap))
-       sk := db.zEncodeSizeKey(destKey)
-       t.Put(sk, PutInt64(num))
-       //todo add binlog
-       if err := t.Commit(); err != nil {
-               return 0, err
-       }
-       return num, nil
-}
-
-func (db *DB) ZScan(key []byte, count int, inclusive bool, match string) ([][]byte, error) {
-       return db.scan(ZSizeType, key, count, inclusive, match)
-}
diff --git a/vendor/github.com/lunny/nodb/tx.go b/vendor/github.com/lunny/nodb/tx.go
deleted file mode 100644 (file)
index 5ce99db..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-package nodb
-
-import (
-       "errors"
-       "fmt"
-
-       "github.com/lunny/nodb/store"
-)
-
-var (
-       ErrNestTx = errors.New("nest transaction not supported")
-       ErrTxDone = errors.New("Transaction has already been committed or rolled back")
-)
-
-type Tx struct {
-       *DB
-
-       tx *store.Tx
-
-       logs [][]byte
-}
-
-func (db *DB) IsTransaction() bool {
-       return db.status == DBInTransaction
-}
-
-// Begin a transaction, it will block all other write operations before calling Commit or Rollback.
-// You must be very careful to prevent long-time transaction.
-func (db *DB) Begin() (*Tx, error) {
-       if db.IsTransaction() {
-               return nil, ErrNestTx
-       }
-
-       tx := new(Tx)
-
-       tx.DB = new(DB)
-       tx.DB.l = db.l
-
-       tx.l.wLock.Lock()
-
-       tx.DB.sdb = db.sdb
-
-       var err error
-       tx.tx, err = db.sdb.Begin()
-       if err != nil {
-               tx.l.wLock.Unlock()
-               return nil, err
-       }
-
-       tx.DB.bucket = tx.tx
-
-       tx.DB.status = DBInTransaction
-
-       tx.DB.index = db.index
-
-       tx.DB.kvBatch = tx.newBatch()
-       tx.DB.listBatch = tx.newBatch()
-       tx.DB.hashBatch = tx.newBatch()
-       tx.DB.zsetBatch = tx.newBatch()
-       tx.DB.binBatch = tx.newBatch()
-       tx.DB.setBatch = tx.newBatch()
-
-       return tx, nil
-}
-
-func (tx *Tx) Commit() error {
-       if tx.tx == nil {
-               return ErrTxDone
-       }
-
-       tx.l.commitLock.Lock()
-       err := tx.tx.Commit()
-       tx.tx = nil
-
-       if len(tx.logs) > 0 {
-               tx.l.binlog.Log(tx.logs...)
-       }
-
-       tx.l.commitLock.Unlock()
-
-       tx.l.wLock.Unlock()
-
-       tx.DB.bucket = nil
-
-       return err
-}
-
-func (tx *Tx) Rollback() error {
-       if tx.tx == nil {
-               return ErrTxDone
-       }
-
-       err := tx.tx.Rollback()
-       tx.tx = nil
-
-       tx.l.wLock.Unlock()
-       tx.DB.bucket = nil
-
-       return err
-}
-
-func (tx *Tx) newBatch() *batch {
-       return tx.l.newBatch(tx.tx.NewWriteBatch(), &txBatchLocker{}, tx)
-}
-
-func (tx *Tx) Select(index int) error {
-       if index < 0 || index >= int(MaxDBNumber) {
-               return fmt.Errorf("invalid db index %d", index)
-       }
-
-       tx.DB.index = uint8(index)
-       return nil
-}
diff --git a/vendor/github.com/lunny/nodb/util.go b/vendor/github.com/lunny/nodb/util.go
deleted file mode 100644 (file)
index d5949a9..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-package nodb
-
-import (
-       "encoding/binary"
-       "errors"
-       "reflect"
-       "strconv"
-       "unsafe"
-)
-
-var errIntNumber = errors.New("invalid integer")
-
-// no copy to change slice to string
-// use your own risk
-func String(b []byte) (s string) {
-       pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
-       pstring := (*reflect.StringHeader)(unsafe.Pointer(&s))
-       pstring.Data = pbytes.Data
-       pstring.Len = pbytes.Len
-       return
-}
-
-// no copy to change string to slice
-// use your own risk
-func Slice(s string) (b []byte) {
-       pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
-       pstring := (*reflect.StringHeader)(unsafe.Pointer(&s))
-       pbytes.Data = pstring.Data
-       pbytes.Len = pstring.Len
-       pbytes.Cap = pstring.Len
-       return
-}
-
-func Int64(v []byte, err error) (int64, error) {
-       if err != nil {
-               return 0, err
-       } else if v == nil || len(v) == 0 {
-               return 0, nil
-       } else if len(v) != 8 {
-               return 0, errIntNumber
-       }
-
-       return int64(binary.LittleEndian.Uint64(v)), nil
-}
-
-func PutInt64(v int64) []byte {
-       var b []byte
-       pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
-       pbytes.Data = uintptr(unsafe.Pointer(&v))
-       pbytes.Len = 8
-       pbytes.Cap = 8
-       return b
-}
-
-func StrInt64(v []byte, err error) (int64, error) {
-       if err != nil {
-               return 0, err
-       } else if v == nil {
-               return 0, nil
-       } else {
-               return strconv.ParseInt(String(v), 10, 64)
-       }
-}
-
-func StrInt32(v []byte, err error) (int32, error) {
-       if err != nil {
-               return 0, err
-       } else if v == nil {
-               return 0, nil
-       } else {
-               res, err := strconv.ParseInt(String(v), 10, 32)
-               return int32(res), err
-       }
-}
-
-func StrInt8(v []byte, err error) (int8, error) {
-       if err != nil {
-               return 0, err
-       } else if v == nil {
-               return 0, nil
-       } else {
-               res, err := strconv.ParseInt(String(v), 10, 8)
-               return int8(res), err
-       }
-}
-
-func StrPutInt64(v int64) []byte {
-       return strconv.AppendInt(nil, v, 10)
-}
-
-func MinUInt32(a uint32, b uint32) uint32 {
-       if a > b {
-               return b
-       } else {
-               return a
-       }
-}
-
-func MaxUInt32(a uint32, b uint32) uint32 {
-       if a > b {
-               return a
-       } else {
-               return b
-       }
-}
-
-func MaxInt32(a int32, b int32) int32 {
-       if a > b {
-               return a
-       } else {
-               return b
-       }
-}
index f3265655eec43acf6638f4841d5f06e098dabe2c..c611aeb6846732f856731982345f986506731fd9 100644 (file)
@@ -471,7 +471,7 @@ func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packe
                }
 
                if len(answers) != len(prompts) {
-                       return authFailure, nil, errors.New("ssh: not enough answers from keyboard-interactive callback")
+                       return authFailure, nil, fmt.Errorf("ssh: incorrect number of answers from keyboard-interactive callback %d (expected %d)", len(answers), len(prompts))
                }
                responseLength := 1 + 4
                for _, a := range answers {
index 554ca354b63712fe89d389e3b5ee422b6e84575e..fe7ad9ea7c843a4ec21cb9b68f095f76eb3290d1 100644 (file)
@@ -802,16 +802,16 @@ var coreTags = []language.CompactCoreInfo{ // 773 elements
        0x03a0010b, 0x03a00115, 0x03a00117, 0x03a0011c,
        0x03a00120, 0x03a00128, 0x03a0015e, 0x04000000,
        0x04300000, 0x04300099, 0x04400000, 0x0440012f,
-       0x04800000, 0x0480006e, 0x05800000, 0x0581f000,
-       0x0581f032, 0x05857000, 0x05857032, 0x05e00000,
+       0x04800000, 0x0480006e, 0x05800000, 0x05820000,
+       0x05820032, 0x0585a000, 0x0585a032, 0x05e00000,
        0x05e00052, 0x07100000, 0x07100047, 0x07500000,
        0x07500162, 0x07900000, 0x0790012f, 0x07e00000,
        0x07e00038, 0x08200000, 0x0a000000, 0x0a0000c3,
        // Entry 40 - 5F
        0x0a500000, 0x0a500035, 0x0a500099, 0x0a900000,
        0x0a900053, 0x0a900099, 0x0b200000, 0x0b200078,
-       0x0b500000, 0x0b500099, 0x0b700000, 0x0b71f000,
-       0x0b71f033, 0x0b757000, 0x0b757033, 0x0d700000,
+       0x0b500000, 0x0b500099, 0x0b700000, 0x0b720000,
+       0x0b720033, 0x0b75a000, 0x0b75a033, 0x0d700000,
        0x0d700022, 0x0d70006e, 0x0d700078, 0x0d70009e,
        0x0db00000, 0x0db00035, 0x0db00099, 0x0dc00000,
        0x0dc00106, 0x0df00000, 0x0df00131, 0x0e500000,
@@ -947,7 +947,7 @@ var coreTags = []language.CompactCoreInfo{ // 773 elements
        0x38900000, 0x38900131, 0x39000000, 0x3900006f,
        0x390000a4, 0x39500000, 0x39500099, 0x39800000,
        0x3980007d, 0x39800106, 0x39d00000, 0x39d05000,
-       0x39d050e8, 0x39d33000, 0x39d33099, 0x3a100000,
+       0x39d050e8, 0x39d36000, 0x39d36099, 0x3a100000,
        0x3b300000, 0x3b3000e9, 0x3bd00000, 0x3bd00001,
        0x3be00000, 0x3be00024, 0x3c000000, 0x3c00002a,
        0x3c000041, 0x3c00004e, 0x3c00005a, 0x3c000086,
@@ -966,7 +966,7 @@ var coreTags = []language.CompactCoreInfo{ // 773 elements
        0x3fd00000, 0x3fd00072, 0x3fd000da, 0x3fd0010c,
        0x3ff00000, 0x3ff000d1, 0x40100000, 0x401000c3,
        0x40200000, 0x4020004c, 0x40700000, 0x40800000,
-       0x40857000, 0x408570ba, 0x408dc000, 0x408dc0ba,
+       0x4085a000, 0x4085a0ba, 0x408e3000, 0x408e30ba,
        0x40c00000, 0x40c000b3, 0x41200000, 0x41200111,
        0x41600000, 0x4160010f, 0x41c00000, 0x41d00000,
        // Entry 280 - 29F
@@ -974,9 +974,9 @@ var coreTags = []language.CompactCoreInfo{ // 773 elements
        0x42300000, 0x42300164, 0x42900000, 0x42900062,
        0x4290006f, 0x429000a4, 0x42900115, 0x43100000,
        0x43100027, 0x431000c2, 0x4310014d, 0x43200000,
-       0x4321f000, 0x4321f033, 0x4321f0bd, 0x4321f105,
-       0x4321f14d, 0x43257000, 0x43257033, 0x432570bd,
-       0x43257105, 0x4325714d, 0x43700000, 0x43a00000,
+       0x43220000, 0x43220033, 0x432200bd, 0x43220105,
+       0x4322014d, 0x4325a000, 0x4325a033, 0x4325a0bd,
+       0x4325a105, 0x4325a14d, 0x43700000, 0x43a00000,
        0x43b00000, 0x44400000, 0x44400031, 0x44400072,
        // Entry 2A0 - 2BF
        0x4440010c, 0x44500000, 0x4450004b, 0x445000a4,
@@ -992,24 +992,24 @@ var coreTags = []language.CompactCoreInfo{ // 773 elements
        0x49400106, 0x4a400000, 0x4a4000d4, 0x4a900000,
        0x4a9000ba, 0x4ac00000, 0x4ac00053, 0x4ae00000,
        0x4ae00130, 0x4b400000, 0x4b400099, 0x4b4000e8,
-       0x4bc00000, 0x4bc05000, 0x4bc05024, 0x4bc1f000,
-       0x4bc1f137, 0x4bc57000, 0x4bc57137, 0x4be00000,
-       0x4be57000, 0x4be570b4, 0x4bee3000, 0x4bee30b4,
+       0x4bc00000, 0x4bc05000, 0x4bc05024, 0x4bc20000,
+       0x4bc20137, 0x4bc5a000, 0x4bc5a137, 0x4be00000,
+       0x4be5a000, 0x4be5a0b4, 0x4beeb000, 0x4beeb0b4,
        0x4c000000, 0x4c300000, 0x4c30013e, 0x4c900000,
        // Entry 2E0 - 2FF
        0x4c900001, 0x4cc00000, 0x4cc0012f, 0x4ce00000,
        0x4cf00000, 0x4cf0004e, 0x4e500000, 0x4e500114,
        0x4f200000, 0x4fb00000, 0x4fb00131, 0x50900000,
        0x50900052, 0x51200000, 0x51200001, 0x51800000,
-       0x5180003b, 0x518000d6, 0x51f00000, 0x51f38000,
-       0x51f38053, 0x51f39000, 0x51f3908d, 0x52800000,
-       0x528000ba, 0x52900000, 0x52938000, 0x52938053,
-       0x5293808d, 0x529380c6, 0x5293810d, 0x52939000,
+       0x5180003b, 0x518000d6, 0x51f00000, 0x51f3b000,
+       0x51f3b053, 0x51f3c000, 0x51f3c08d, 0x52800000,
+       0x528000ba, 0x52900000, 0x5293b000, 0x5293b053,
+       0x5293b08d, 0x5293b0c6, 0x5293b10d, 0x5293c000,
        // Entry 300 - 31F
-       0x5293908d, 0x529390c6, 0x5293912e, 0x52f00000,
+       0x5293c08d, 0x5293c0c6, 0x5293c12e, 0x52f00000,
        0x52f00161,
 } // Size: 3116 bytes
 
 const specialTagsStr string = "ca-ES-valencia en-US-u-va-posix"
 
-// Total table size 3147 bytes (3KiB); checksum: F4E57D15
+// Total table size 3147 bytes (3KiB); checksum: BE816D44
index 239e2d29eb7bebed1c14623351368476f1fd04dd..a19480c5ba6a40313139448de0cf711fc7c42d13 100644 (file)
@@ -7,9 +7,9 @@ import "golang.org/x/text/internal/tag"
 // CLDRVersion is the CLDR version from which the tables in this package are derived.
 const CLDRVersion = "32"
 
-const NumLanguages = 8665
+const NumLanguages = 8717
 
-const NumScripts = 242
+const NumScripts = 251
 
 const NumRegions = 357
 
@@ -284,14 +284,14 @@ var langNoIndex = [2197]uint8{
        0xfd, 0xdf, 0xfb, 0xfe, 0x9d, 0xb4, 0xd3, 0xff,
        0xef, 0xff, 0xdf, 0xf7, 0x7f, 0xb7, 0xfd, 0xd5,
        0xa5, 0x77, 0x40, 0xff, 0x9c, 0xc1, 0x41, 0x2c,
-       0x08, 0x20, 0x41, 0x00, 0x50, 0x40, 0x00, 0x80,
+       0x08, 0x21, 0x41, 0x00, 0x50, 0x40, 0x00, 0x80,
        // Entry C0 - FF
        0xfb, 0x4a, 0xf2, 0x9f, 0xb4, 0x42, 0x41, 0x96,
-       0x1b, 0x14, 0x08, 0xf2, 0x2b, 0xe7, 0x17, 0x56,
-       0x05, 0x7d, 0x0e, 0x1c, 0x37, 0x71, 0xf3, 0xef,
+       0x1b, 0x14, 0x08, 0xf3, 0x2b, 0xe7, 0x17, 0x56,
+       0x05, 0x7d, 0x0e, 0x1c, 0x37, 0x7b, 0xf3, 0xef,
        0x97, 0xff, 0x5d, 0x38, 0x64, 0x08, 0x00, 0x10,
-       0xbc, 0x85, 0xaf, 0xdf, 0xff, 0xf7, 0x73, 0x35,
-       0x3e, 0x87, 0xc7, 0xdf, 0xff, 0x00, 0x81, 0x00,
+       0xbc, 0x85, 0xaf, 0xdf, 0xff, 0xff, 0x73, 0x35,
+       0x3e, 0x87, 0xc7, 0xdf, 0xff, 0x01, 0x81, 0x00,
        0xb0, 0x05, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03,
        0x40, 0x00, 0x40, 0x92, 0x21, 0x50, 0xb1, 0x5d,
        // Entry 100 - 13F
@@ -299,14 +299,14 @@ var langNoIndex = [2197]uint8{
        0x0d, 0x19, 0x41, 0xdf, 0x79, 0x22, 0x00, 0x00,
        0x00, 0x5e, 0x64, 0xdc, 0x24, 0xe5, 0xd9, 0xe3,
        0xfe, 0xff, 0xfd, 0xcb, 0x9f, 0x14, 0x01, 0x0c,
-       0x86, 0x00, 0xd1, 0x00, 0xf0, 0xc5, 0x67, 0x5f,
-       0x56, 0x89, 0x5e, 0xb5, 0x6c, 0xaf, 0x03, 0x00,
+       0x86, 0x00, 0xd1, 0x00, 0xf0, 0xc7, 0x67, 0x5f,
+       0x56, 0x99, 0x5e, 0xb5, 0x6c, 0xaf, 0x03, 0x00,
        0x02, 0x00, 0x00, 0x00, 0xc0, 0x37, 0xda, 0x56,
        0x90, 0x69, 0x01, 0x2c, 0x96, 0x69, 0x20, 0xfb,
        // Entry 140 - 17F
-       0xff, 0x3f, 0x00, 0x00, 0x00, 0x01, 0x08, 0x16,
-       0x01, 0x00, 0x00, 0xb0, 0x14, 0x03, 0x50, 0x06,
-       0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x09,
+       0xff, 0x3f, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x16,
+       0x03, 0x00, 0x00, 0xb0, 0x14, 0x03, 0x50, 0x06,
+       0x0a, 0x00, 0x01, 0x00, 0x00, 0x10, 0x11, 0x09,
        0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x10,
        0x00, 0x00, 0x44, 0x00, 0x00, 0x10, 0x00, 0x04,
        0x08, 0x00, 0x00, 0x04, 0x00, 0x80, 0x28, 0x04,
@@ -322,7 +322,7 @@ var langNoIndex = [2197]uint8{
        0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
        // Entry 1C0 - 1FF
-       0x00, 0x01, 0x28, 0x05, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x03, 0x28, 0x05, 0x00, 0x00, 0x00, 0x00,
        0x04, 0x20, 0x04, 0xa6, 0x00, 0x04, 0x00, 0x00,
        0x81, 0x50, 0x00, 0x00, 0x00, 0x11, 0x84, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x55,
@@ -332,28 +332,28 @@ var langNoIndex = [2197]uint8{
        0x00, 0x00, 0x00, 0x1e, 0xcd, 0xbf, 0x7a, 0xbf,
        // Entry 200 - 23F
        0xdf, 0xc3, 0x83, 0x82, 0xc0, 0xfb, 0x57, 0x27,
-       0xcd, 0x55, 0xe7, 0x01, 0x00, 0x20, 0xb2, 0xc5,
+       0xed, 0x55, 0xe7, 0x01, 0x00, 0x20, 0xb2, 0xc5,
        0xa4, 0x45, 0x25, 0x9b, 0x02, 0xdf, 0xe0, 0xdf,
-       0x03, 0x44, 0x08, 0x10, 0x01, 0x04, 0x01, 0xe3,
-       0x92, 0x54, 0xdb, 0x28, 0xd1, 0x5f, 0xf6, 0x6d,
+       0x03, 0x44, 0x08, 0x90, 0x01, 0x04, 0x01, 0xe3,
+       0x92, 0x54, 0xdb, 0x28, 0xd3, 0x5f, 0xfe, 0x6d,
        0x79, 0xed, 0x1c, 0x7d, 0x04, 0x08, 0x00, 0x01,
        0x21, 0x12, 0x64, 0x5f, 0xdd, 0x0e, 0x85, 0x4f,
        0x40, 0x40, 0x00, 0x04, 0xf1, 0xfd, 0x3d, 0x54,
        // Entry 240 - 27F
        0xe8, 0x03, 0xb4, 0x27, 0x23, 0x0d, 0x00, 0x00,
-       0x20, 0x7b, 0x38, 0x02, 0x05, 0x84, 0x00, 0xf0,
+       0x20, 0x7b, 0x78, 0x02, 0x05, 0x84, 0x00, 0xf0,
        0xbb, 0x7e, 0x5a, 0x00, 0x18, 0x04, 0x81, 0x00,
        0x00, 0x00, 0x80, 0x10, 0x90, 0x1c, 0x01, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x04,
        0x08, 0xa0, 0x70, 0xa5, 0x0c, 0x40, 0x00, 0x00,
-       0x11, 0x04, 0x04, 0x68, 0x00, 0x20, 0x70, 0xff,
-       0x7b, 0x7f, 0x60, 0x00, 0x05, 0x9b, 0xdd, 0x66,
+       0x11, 0x24, 0x04, 0x68, 0x00, 0x20, 0x70, 0xff,
+       0x7b, 0x7f, 0x70, 0x00, 0x05, 0x9b, 0xdd, 0x66,
        // Entry 280 - 2BF
        0x03, 0x00, 0x11, 0x00, 0x00, 0x00, 0x40, 0x05,
        0xb5, 0xb6, 0x80, 0x08, 0x04, 0x00, 0x04, 0x51,
        0xe2, 0xef, 0xfd, 0x3f, 0x05, 0x09, 0x08, 0x05,
        0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
-       0x08, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x60,
+       0x0c, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x60,
        0xe7, 0x48, 0x00, 0x81, 0x20, 0xc0, 0x05, 0x80,
        0x03, 0x00, 0x00, 0x00, 0x8c, 0x50, 0x40, 0x04,
        0x84, 0x47, 0x84, 0x40, 0x20, 0x10, 0x00, 0x20,
@@ -397,9 +397,9 @@ var langNoIndex = [2197]uint8{
        0x02, 0x30, 0x9f, 0x7a, 0x16, 0xbd, 0x7f, 0x57,
        0xf2, 0xff, 0x31, 0xff, 0xf2, 0x1e, 0x90, 0xf7,
        0xf1, 0xf9, 0x45, 0x80, 0x01, 0x02, 0x00, 0x00,
-       0x40, 0x54, 0x9f, 0x8a, 0xd9, 0xd9, 0x0e, 0x11,
-       0x86, 0x51, 0xc0, 0xf3, 0xfb, 0x47, 0x00, 0x01,
-       0x05, 0xd1, 0x50, 0x58, 0x00, 0x00, 0x00, 0x10,
+       0x40, 0x54, 0x9f, 0x8a, 0xd9, 0xf9, 0x2e, 0x11,
+       0x86, 0x51, 0xc0, 0xf3, 0xfb, 0x47, 0x40, 0x01,
+       0x05, 0xd1, 0x50, 0x5c, 0x00, 0x00, 0x00, 0x10,
        0x04, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x17, 0xd2,
        0xb9, 0xfd, 0xfc, 0xba, 0xfe, 0xef, 0xc7, 0xbe,
        // Entry 400 - 43F
@@ -417,14 +417,14 @@ var langNoIndex = [2197]uint8{
        0x7f, 0x4e, 0xbf, 0x8f, 0xae, 0xff, 0xee, 0xdf,
        0x7f, 0xf7, 0x73, 0x02, 0x02, 0x04, 0xfc, 0xf7,
        0xff, 0xb7, 0xd7, 0xef, 0xfe, 0xcd, 0xf5, 0xce,
-       0xe2, 0x8e, 0xe7, 0xbf, 0xb7, 0xff, 0x56, 0xbd,
+       0xe2, 0x8e, 0xe7, 0xbf, 0xb7, 0xff, 0x56, 0xfd,
        0xcd, 0xff, 0xfb, 0xff, 0xdf, 0xd7, 0xea, 0xff,
        0xe5, 0x5f, 0x6d, 0x0f, 0xa7, 0x51, 0x06, 0xc4,
        // Entry 480 - 4BF
-       0x13, 0x50, 0x5d, 0xaf, 0xa6, 0xfd, 0x99, 0xfb,
+       0x13, 0x50, 0x5d, 0xaf, 0xa6, 0xff, 0x99, 0xfb,
        0x63, 0x1d, 0x53, 0xff, 0xef, 0xb7, 0x35, 0x20,
        0x14, 0x00, 0x55, 0x51, 0x82, 0x65, 0xf5, 0x41,
-       0xe2, 0xff, 0xfc, 0xdf, 0x00, 0x05, 0xc5, 0x05,
+       0xe2, 0xff, 0xfc, 0xdf, 0x02, 0x05, 0xc5, 0x05,
        0x00, 0x22, 0x00, 0x74, 0x69, 0x10, 0x08, 0x04,
        0x41, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x51, 0x20, 0x05, 0x04, 0x01, 0x00, 0x00,
@@ -437,12 +437,12 @@ var langNoIndex = [2197]uint8{
        0x13, 0x31, 0x00, 0x20, 0x00, 0x00, 0x00, 0x90,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x10, 0x00,
        0x01, 0x00, 0x00, 0xf0, 0x5b, 0xf4, 0xbe, 0x3d,
-       0xba, 0xcf, 0xf7, 0xaf, 0x42, 0x04, 0x84, 0x41,
+       0xbe, 0xcf, 0xf7, 0xaf, 0x42, 0x04, 0x84, 0x41,
        // Entry 500 - 53F
        0x30, 0xff, 0x79, 0x72, 0x04, 0x00, 0x00, 0x49,
        0x2d, 0x14, 0x27, 0x57, 0xed, 0xf1, 0x3f, 0xe7,
        0x3f, 0x00, 0x00, 0x02, 0xc6, 0xa0, 0x1e, 0xf8,
-       0xbb, 0xff, 0xfd, 0xfb, 0xb7, 0xfd, 0xe5, 0xf7,
+       0xbb, 0xff, 0xfd, 0xfb, 0xb7, 0xfd, 0xe7, 0xf7,
        0xfd, 0xfc, 0xd5, 0xed, 0x47, 0xf4, 0x7e, 0x10,
        0x01, 0x01, 0x84, 0x6d, 0xff, 0xf7, 0xdd, 0xf9,
        0x5b, 0x05, 0x86, 0xed, 0xf5, 0x77, 0xbd, 0x3c,
@@ -473,7 +473,7 @@ var langNoIndex = [2197]uint8{
        0x31, 0x00, 0x00, 0x00, 0x01, 0x10, 0x02, 0x20,
        0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x20, 0x00,
        0x00, 0x1f, 0xdf, 0xd2, 0xb9, 0xff, 0xfd, 0x3f,
-       0x1f, 0x98, 0xcf, 0x9c, 0xbf, 0xaf, 0x5f, 0xfe,
+       0x1f, 0x98, 0xcf, 0x9c, 0xff, 0xaf, 0x5f, 0xfe,
        // Entry 600 - 63F
        0x7b, 0x4b, 0x40, 0x10, 0xe1, 0xfd, 0xaf, 0xd9,
        0xb7, 0xf6, 0xfb, 0xb3, 0xc7, 0xff, 0x6f, 0xf1,
@@ -484,28 +484,28 @@ var langNoIndex = [2197]uint8{
        0xbe, 0x5f, 0x46, 0x1b, 0xe9, 0x5f, 0x50, 0x18,
        0x02, 0xfa, 0xf7, 0x9d, 0x15, 0x97, 0x05, 0x0f,
        // Entry 640 - 67F
-       0x75, 0xc4, 0x7d, 0x81, 0x92, 0xf1, 0x57, 0x6c,
+       0x75, 0xc4, 0x7d, 0x81, 0x92, 0xf5, 0x57, 0x6c,
        0xff, 0xe4, 0xef, 0x6f, 0xff, 0xfc, 0xdd, 0xde,
-       0xfc, 0xfd, 0x76, 0x5f, 0x7a, 0x1f, 0x00, 0x98,
+       0xfc, 0xfd, 0x76, 0x5f, 0x7a, 0x3f, 0x00, 0x98,
        0x02, 0xfb, 0xa3, 0xef, 0xf3, 0xd6, 0xf2, 0xff,
-       0xb9, 0xda, 0x7d, 0x50, 0x1e, 0x15, 0x7b, 0xb4,
+       0xb9, 0xda, 0x7d, 0xd0, 0x3e, 0x15, 0x7b, 0xb4,
        0xf5, 0x3e, 0xff, 0xff, 0xf1, 0xf7, 0xff, 0xe7,
        0x5f, 0xff, 0xff, 0x9e, 0xdb, 0xf6, 0xd7, 0xb9,
        0xef, 0x27, 0x80, 0xbb, 0xc5, 0xff, 0xff, 0xe3,
        // Entry 680 - 6BF
        0x97, 0x9d, 0xbf, 0x9f, 0xf7, 0xc7, 0xfd, 0x37,
-       0xce, 0x7f, 0x04, 0x1d, 0x53, 0x7f, 0xf8, 0xda,
+       0xce, 0x7f, 0x04, 0x1d, 0x73, 0x7f, 0xf8, 0xda,
        0x5d, 0xce, 0x7d, 0x06, 0xb9, 0xea, 0x69, 0xa0,
        0x1a, 0x20, 0x00, 0x30, 0x02, 0x04, 0x24, 0x08,
        0x04, 0x00, 0x00, 0x40, 0xd4, 0x02, 0x04, 0x00,
        0x00, 0x04, 0x00, 0x04, 0x00, 0x20, 0x01, 0x06,
        0x50, 0x00, 0x08, 0x00, 0x00, 0x00, 0x24, 0x00,
-       0x04, 0x00, 0x10, 0xcc, 0x58, 0xd5, 0x0d, 0x0f,
+       0x04, 0x00, 0x10, 0xdc, 0x58, 0xd7, 0x0d, 0x0f,
        // Entry 6C0 - 6FF
        0x14, 0x4d, 0xf1, 0x16, 0x44, 0xd1, 0x42, 0x08,
        0x40, 0x00, 0x00, 0x40, 0x00, 0x08, 0x00, 0x00,
-       0x00, 0xdc, 0xfb, 0xcb, 0x0e, 0x58, 0x08, 0x41,
-       0x04, 0x20, 0x04, 0x00, 0x30, 0x12, 0x40, 0x00,
+       0x00, 0xdc, 0xfb, 0xcb, 0x0e, 0x58, 0x48, 0x41,
+       0x24, 0x20, 0x04, 0x00, 0x30, 0x12, 0x40, 0x00,
        0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x01, 0x00, 0x00, 0x00, 0x80, 0x10, 0x10, 0xab,
        0x6d, 0x93, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
@@ -524,7 +524,7 @@ var langNoIndex = [2197]uint8{
        0xb0, 0x11, 0x00, 0x00, 0x00, 0x92, 0x01, 0x44,
        0xcd, 0xf9, 0x5c, 0x00, 0x01, 0x00, 0x30, 0x04,
        0x04, 0x55, 0x00, 0x01, 0x04, 0xf4, 0x3f, 0x4a,
-       0x01, 0x00, 0x00, 0xb0, 0x80, 0x00, 0x55, 0x55,
+       0x01, 0x00, 0x00, 0xb0, 0x80, 0x20, 0x55, 0x75,
        0x97, 0x7c, 0x9f, 0x31, 0xcc, 0x68, 0xd1, 0x03,
        0xd5, 0x57, 0x27, 0x14, 0x01, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x2c, 0xf7, 0xcb, 0x1f, 0x14, 0x60,
@@ -538,8 +538,8 @@ var langNoIndex = [2197]uint8{
        0xe8, 0x30, 0x90, 0x6a, 0x92, 0x00, 0x00, 0x02,
        0xff, 0xef, 0xff, 0x4b, 0x85, 0x53, 0xf4, 0xed,
        // Entry 7C0 - 7FF
-       0xdd, 0xbf, 0x72, 0x19, 0xc7, 0x0c, 0xd5, 0x42,
-       0x54, 0xdd, 0x77, 0x14, 0x00, 0x80, 0x40, 0x56,
+       0xdd, 0xbf, 0x72, 0x1d, 0xc7, 0x0c, 0xd5, 0x42,
+       0xfc, 0xff, 0xf7, 0x1f, 0x00, 0x80, 0x40, 0x56,
        0xcc, 0x16, 0x9e, 0xea, 0x35, 0x7d, 0xef, 0xff,
        0xbd, 0xa4, 0xaf, 0x01, 0x44, 0x18, 0x01, 0x4d,
        0x4e, 0x4a, 0x08, 0x50, 0x28, 0x30, 0xe0, 0x80,
@@ -556,7 +556,7 @@ var langNoIndex = [2197]uint8{
        0x07, 0x00, 0x20, 0x10, 0x84, 0xb2, 0x45, 0x10,
        0x06, 0x44, 0x00, 0x00, 0x12, 0x02, 0x11, 0x00,
        // Entry 840 - 87F
-       0xf0, 0xfb, 0xfd, 0x3f, 0x05, 0x00, 0x12, 0x81,
+       0xf0, 0xfb, 0xfd, 0x7f, 0x05, 0x00, 0x12, 0x81,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02,
        0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x02, 0x28,
        0x84, 0x00, 0x21, 0xc0, 0x23, 0x24, 0x00, 0x00,
@@ -582,8 +582,8 @@ var altLangIndex = [6]uint16{
 }
 
 // AliasMap maps langIDs to their suggested replacements.
-// Size: 656 bytes, 164 elements
-var AliasMap = [164]FromTo{
+// Size: 704 bytes, 176 elements
+var AliasMap = [176]FromTo{
        0:   {From: 0x82, To: 0x88},
        1:   {From: 0x187, To: 0x1ae},
        2:   {From: 0x1f3, To: 0x1e1},
@@ -603,224 +603,237 @@ var AliasMap = [164]FromTo{
        16:  {From: 0x662, To: 0x431},
        17:  {From: 0x6ed, To: 0x3a},
        18:  {From: 0x6f8, To: 0x1d7},
-       19:  {From: 0x73e, To: 0x21a1},
-       20:  {From: 0x7b3, To: 0x56},
-       21:  {From: 0x7b9, To: 0x299b},
-       22:  {From: 0x7c5, To: 0x58},
-       23:  {From: 0x7e6, To: 0x145},
-       24:  {From: 0x80c, To: 0x5a},
-       25:  {From: 0x815, To: 0x8d},
-       26:  {From: 0x87e, To: 0x810},
-       27:  {From: 0x8c3, To: 0xee3},
-       28:  {From: 0x9ef, To: 0x331},
-       29:  {From: 0xa36, To: 0x2c5},
-       30:  {From: 0xa3d, To: 0xbf},
-       31:  {From: 0xabe, To: 0x3322},
-       32:  {From: 0xb38, To: 0x529},
-       33:  {From: 0xb75, To: 0x265a},
-       34:  {From: 0xb7e, To: 0xbc3},
-       35:  {From: 0xb9b, To: 0x44e},
-       36:  {From: 0xbbc, To: 0x4229},
-       37:  {From: 0xbbf, To: 0x529},
-       38:  {From: 0xbfe, To: 0x2da7},
-       39:  {From: 0xc2e, To: 0x3181},
-       40:  {From: 0xcb9, To: 0xf3},
-       41:  {From: 0xd08, To: 0xfa},
-       42:  {From: 0xdc8, To: 0x11a},
-       43:  {From: 0xdd7, To: 0x32d},
-       44:  {From: 0xdf8, To: 0xdfb},
-       45:  {From: 0xdfe, To: 0x531},
-       46:  {From: 0xedf, To: 0x205a},
-       47:  {From: 0xeee, To: 0x2e9a},
-       48:  {From: 0xf39, To: 0x367},
-       49:  {From: 0x10d0, To: 0x140},
-       50:  {From: 0x1104, To: 0x2d0},
-       51:  {From: 0x11a0, To: 0x1ec},
-       52:  {From: 0x1279, To: 0x21},
-       53:  {From: 0x1424, To: 0x15e},
-       54:  {From: 0x1470, To: 0x14e},
-       55:  {From: 0x151f, To: 0xd9b},
-       56:  {From: 0x1523, To: 0x390},
-       57:  {From: 0x1532, To: 0x19f},
-       58:  {From: 0x1580, To: 0x210},
-       59:  {From: 0x1583, To: 0x10d},
-       60:  {From: 0x15a3, To: 0x3caf},
-       61:  {From: 0x166a, To: 0x19b},
-       62:  {From: 0x16c8, To: 0x136},
-       63:  {From: 0x1700, To: 0x29f8},
-       64:  {From: 0x1718, To: 0x194},
-       65:  {From: 0x1727, To: 0xf3f},
-       66:  {From: 0x177a, To: 0x178},
-       67:  {From: 0x1809, To: 0x17b6},
-       68:  {From: 0x1816, To: 0x18f3},
-       69:  {From: 0x188a, To: 0x436},
-       70:  {From: 0x1979, To: 0x1d01},
-       71:  {From: 0x1a74, To: 0x2bb0},
-       72:  {From: 0x1a8a, To: 0x1f8},
-       73:  {From: 0x1b5a, To: 0x1fa},
-       74:  {From: 0x1b86, To: 0x1515},
-       75:  {From: 0x1d64, To: 0x2c9b},
-       76:  {From: 0x2038, To: 0x37b1},
-       77:  {From: 0x203d, To: 0x20dd},
-       78:  {From: 0x205a, To: 0x30b},
-       79:  {From: 0x20e3, To: 0x274},
-       80:  {From: 0x20ee, To: 0x263},
-       81:  {From: 0x20f2, To: 0x22d},
-       82:  {From: 0x20f9, To: 0x256},
-       83:  {From: 0x210f, To: 0x21eb},
-       84:  {From: 0x2135, To: 0x27d},
-       85:  {From: 0x2160, To: 0x913},
-       86:  {From: 0x2199, To: 0x121},
-       87:  {From: 0x21ce, To: 0x1561},
-       88:  {From: 0x21e6, To: 0x504},
-       89:  {From: 0x21f4, To: 0x49f},
-       90:  {From: 0x222d, To: 0x121},
-       91:  {From: 0x2237, To: 0x121},
-       92:  {From: 0x2262, To: 0x92a},
-       93:  {From: 0x2316, To: 0x3226},
-       94:  {From: 0x2382, To: 0x3365},
-       95:  {From: 0x2472, To: 0x2c7},
-       96:  {From: 0x24e4, To: 0x2ff},
-       97:  {From: 0x24f0, To: 0x2fa},
-       98:  {From: 0x24fa, To: 0x31f},
-       99:  {From: 0x2550, To: 0xb5b},
-       100: {From: 0x25a9, To: 0xe2},
-       101: {From: 0x263e, To: 0x2d0},
-       102: {From: 0x26c9, To: 0x26b4},
-       103: {From: 0x26f9, To: 0x3c8},
-       104: {From: 0x2727, To: 0x3caf},
-       105: {From: 0x2765, To: 0x26b4},
-       106: {From: 0x2789, To: 0x4358},
-       107: {From: 0x28ef, To: 0x2837},
-       108: {From: 0x2914, To: 0x351},
-       109: {From: 0x2986, To: 0x2da7},
-       110: {From: 0x2b1a, To: 0x38d},
-       111: {From: 0x2bfc, To: 0x395},
-       112: {From: 0x2c3f, To: 0x3caf},
-       113: {From: 0x2cfc, To: 0x3be},
-       114: {From: 0x2d13, To: 0x597},
-       115: {From: 0x2d47, To: 0x148},
-       116: {From: 0x2d48, To: 0x148},
-       117: {From: 0x2dff, To: 0x2f1},
-       118: {From: 0x2e08, To: 0x19cc},
-       119: {From: 0x2e1a, To: 0x2d95},
-       120: {From: 0x2e21, To: 0x292},
-       121: {From: 0x2e54, To: 0x7d},
-       122: {From: 0x2e65, To: 0x2282},
-       123: {From: 0x2ea0, To: 0x2e9b},
-       124: {From: 0x2eef, To: 0x2ed7},
-       125: {From: 0x3193, To: 0x3c4},
-       126: {From: 0x3366, To: 0x338e},
-       127: {From: 0x342a, To: 0x3dc},
-       128: {From: 0x34ee, To: 0x18d0},
-       129: {From: 0x35c8, To: 0x2c9b},
-       130: {From: 0x35e6, To: 0x412},
-       131: {From: 0x3658, To: 0x246},
-       132: {From: 0x3676, To: 0x3f4},
-       133: {From: 0x36fd, To: 0x445},
-       134: {From: 0x37c0, To: 0x121},
-       135: {From: 0x3816, To: 0x38f2},
-       136: {From: 0x382b, To: 0x2c9b},
-       137: {From: 0x382f, To: 0xa9},
-       138: {From: 0x3832, To: 0x3228},
-       139: {From: 0x386c, To: 0x39a6},
-       140: {From: 0x3892, To: 0x3fc0},
-       141: {From: 0x38a5, To: 0x39d7},
-       142: {From: 0x38b4, To: 0x1fa4},
-       143: {From: 0x38b5, To: 0x2e9a},
-       144: {From: 0x395c, To: 0x47e},
-       145: {From: 0x3b4e, To: 0xd91},
-       146: {From: 0x3b78, To: 0x137},
-       147: {From: 0x3c99, To: 0x4bc},
-       148: {From: 0x3fbd, To: 0x100},
-       149: {From: 0x4208, To: 0xa91},
-       150: {From: 0x42be, To: 0x573},
-       151: {From: 0x42f9, To: 0x3f60},
-       152: {From: 0x4378, To: 0x25a},
-       153: {From: 0x43cb, To: 0x36cb},
-       154: {From: 0x43cd, To: 0x10f},
-       155: {From: 0x44af, To: 0x3322},
-       156: {From: 0x44e3, To: 0x512},
-       157: {From: 0x45ca, To: 0x2409},
-       158: {From: 0x45dd, To: 0x26dc},
-       159: {From: 0x4610, To: 0x48ae},
-       160: {From: 0x46ae, To: 0x46a0},
-       161: {From: 0x473e, To: 0x4745},
-       162: {From: 0x4916, To: 0x31f},
-       163: {From: 0x49a7, To: 0x523},
+       19:  {From: 0x709, To: 0x3625},
+       20:  {From: 0x73e, To: 0x21a1},
+       21:  {From: 0x7b3, To: 0x56},
+       22:  {From: 0x7b9, To: 0x299b},
+       23:  {From: 0x7c5, To: 0x58},
+       24:  {From: 0x7e6, To: 0x145},
+       25:  {From: 0x80c, To: 0x5a},
+       26:  {From: 0x815, To: 0x8d},
+       27:  {From: 0x87e, To: 0x810},
+       28:  {From: 0x8c3, To: 0xee3},
+       29:  {From: 0x9ef, To: 0x331},
+       30:  {From: 0xa36, To: 0x2c5},
+       31:  {From: 0xa3d, To: 0xbf},
+       32:  {From: 0xabe, To: 0x3322},
+       33:  {From: 0xb38, To: 0x529},
+       34:  {From: 0xb75, To: 0x265a},
+       35:  {From: 0xb7e, To: 0xbc3},
+       36:  {From: 0xb9b, To: 0x44e},
+       37:  {From: 0xbbc, To: 0x4229},
+       38:  {From: 0xbbf, To: 0x529},
+       39:  {From: 0xbfe, To: 0x2da7},
+       40:  {From: 0xc2e, To: 0x3181},
+       41:  {From: 0xcb9, To: 0xf3},
+       42:  {From: 0xd08, To: 0xfa},
+       43:  {From: 0xdc8, To: 0x11a},
+       44:  {From: 0xdd7, To: 0x32d},
+       45:  {From: 0xdf8, To: 0xdfb},
+       46:  {From: 0xdfe, To: 0x531},
+       47:  {From: 0xe01, To: 0xdf3},
+       48:  {From: 0xedf, To: 0x205a},
+       49:  {From: 0xee9, To: 0x222e},
+       50:  {From: 0xeee, To: 0x2e9a},
+       51:  {From: 0xf39, To: 0x367},
+       52:  {From: 0x10d0, To: 0x140},
+       53:  {From: 0x1104, To: 0x2d0},
+       54:  {From: 0x11a0, To: 0x1ec},
+       55:  {From: 0x1279, To: 0x21},
+       56:  {From: 0x1424, To: 0x15e},
+       57:  {From: 0x1470, To: 0x14e},
+       58:  {From: 0x151f, To: 0xd9b},
+       59:  {From: 0x1523, To: 0x390},
+       60:  {From: 0x1532, To: 0x19f},
+       61:  {From: 0x1580, To: 0x210},
+       62:  {From: 0x1583, To: 0x10d},
+       63:  {From: 0x15a3, To: 0x3caf},
+       64:  {From: 0x1630, To: 0x222e},
+       65:  {From: 0x166a, To: 0x19b},
+       66:  {From: 0x16c8, To: 0x136},
+       67:  {From: 0x1700, To: 0x29f8},
+       68:  {From: 0x1718, To: 0x194},
+       69:  {From: 0x1727, To: 0xf3f},
+       70:  {From: 0x177a, To: 0x178},
+       71:  {From: 0x1809, To: 0x17b6},
+       72:  {From: 0x1816, To: 0x18f3},
+       73:  {From: 0x188a, To: 0x436},
+       74:  {From: 0x1979, To: 0x1d01},
+       75:  {From: 0x1a74, To: 0x2bb0},
+       76:  {From: 0x1a8a, To: 0x1f8},
+       77:  {From: 0x1b5a, To: 0x1fa},
+       78:  {From: 0x1b86, To: 0x1515},
+       79:  {From: 0x1d64, To: 0x2c9b},
+       80:  {From: 0x2038, To: 0x37b1},
+       81:  {From: 0x203d, To: 0x20dd},
+       82:  {From: 0x205a, To: 0x30b},
+       83:  {From: 0x20e3, To: 0x274},
+       84:  {From: 0x20ee, To: 0x263},
+       85:  {From: 0x20f2, To: 0x22d},
+       86:  {From: 0x20f9, To: 0x256},
+       87:  {From: 0x210f, To: 0x21eb},
+       88:  {From: 0x2135, To: 0x27d},
+       89:  {From: 0x2160, To: 0x913},
+       90:  {From: 0x2199, To: 0x121},
+       91:  {From: 0x21ce, To: 0x1561},
+       92:  {From: 0x21e6, To: 0x504},
+       93:  {From: 0x21f4, To: 0x49f},
+       94:  {From: 0x21fb, To: 0x269},
+       95:  {From: 0x222d, To: 0x121},
+       96:  {From: 0x2237, To: 0x121},
+       97:  {From: 0x2262, To: 0x92a},
+       98:  {From: 0x2316, To: 0x3226},
+       99:  {From: 0x236a, To: 0x2835},
+       100: {From: 0x2382, To: 0x3365},
+       101: {From: 0x2472, To: 0x2c7},
+       102: {From: 0x24e4, To: 0x2ff},
+       103: {From: 0x24f0, To: 0x2fa},
+       104: {From: 0x24fa, To: 0x31f},
+       105: {From: 0x2550, To: 0xb5b},
+       106: {From: 0x25a9, To: 0xe2},
+       107: {From: 0x263e, To: 0x2d0},
+       108: {From: 0x26c9, To: 0x26b4},
+       109: {From: 0x26f9, To: 0x3c8},
+       110: {From: 0x2727, To: 0x3caf},
+       111: {From: 0x2755, To: 0x6a4},
+       112: {From: 0x2765, To: 0x26b4},
+       113: {From: 0x2789, To: 0x4358},
+       114: {From: 0x27c9, To: 0x2001},
+       115: {From: 0x28ea, To: 0x27b1},
+       116: {From: 0x28ef, To: 0x2837},
+       117: {From: 0x2914, To: 0x351},
+       118: {From: 0x2986, To: 0x2da7},
+       119: {From: 0x29f0, To: 0x96b},
+       120: {From: 0x2b1a, To: 0x38d},
+       121: {From: 0x2bfc, To: 0x395},
+       122: {From: 0x2c3f, To: 0x3caf},
+       123: {From: 0x2cfc, To: 0x3be},
+       124: {From: 0x2d13, To: 0x597},
+       125: {From: 0x2d47, To: 0x148},
+       126: {From: 0x2d48, To: 0x148},
+       127: {From: 0x2dff, To: 0x2f1},
+       128: {From: 0x2e08, To: 0x19cc},
+       129: {From: 0x2e1a, To: 0x2d95},
+       130: {From: 0x2e21, To: 0x292},
+       131: {From: 0x2e54, To: 0x7d},
+       132: {From: 0x2e65, To: 0x2282},
+       133: {From: 0x2ea0, To: 0x2e9b},
+       134: {From: 0x2eef, To: 0x2ed7},
+       135: {From: 0x3193, To: 0x3c4},
+       136: {From: 0x3366, To: 0x338e},
+       137: {From: 0x342a, To: 0x3dc},
+       138: {From: 0x34ee, To: 0x18d0},
+       139: {From: 0x35c8, To: 0x2c9b},
+       140: {From: 0x35e6, To: 0x412},
+       141: {From: 0x3658, To: 0x246},
+       142: {From: 0x3676, To: 0x3f4},
+       143: {From: 0x36fd, To: 0x445},
+       144: {From: 0x37c0, To: 0x121},
+       145: {From: 0x3816, To: 0x38f2},
+       146: {From: 0x382a, To: 0x2b48},
+       147: {From: 0x382b, To: 0x2c9b},
+       148: {From: 0x382f, To: 0xa9},
+       149: {From: 0x3832, To: 0x3228},
+       150: {From: 0x386c, To: 0x39a6},
+       151: {From: 0x3892, To: 0x3fc0},
+       152: {From: 0x38a5, To: 0x39d7},
+       153: {From: 0x38b4, To: 0x1fa4},
+       154: {From: 0x38b5, To: 0x2e9a},
+       155: {From: 0x395c, To: 0x47e},
+       156: {From: 0x3b4e, To: 0xd91},
+       157: {From: 0x3b78, To: 0x137},
+       158: {From: 0x3c99, To: 0x4bc},
+       159: {From: 0x3fbd, To: 0x100},
+       160: {From: 0x4208, To: 0xa91},
+       161: {From: 0x42be, To: 0x573},
+       162: {From: 0x42f9, To: 0x3f60},
+       163: {From: 0x4378, To: 0x25a},
+       164: {From: 0x43b8, To: 0xe6c},
+       165: {From: 0x43cd, To: 0x10f},
+       166: {From: 0x44af, To: 0x3322},
+       167: {From: 0x44e3, To: 0x512},
+       168: {From: 0x45ca, To: 0x2409},
+       169: {From: 0x45dd, To: 0x26dc},
+       170: {From: 0x4610, To: 0x48ae},
+       171: {From: 0x46ae, To: 0x46a0},
+       172: {From: 0x473e, To: 0x4745},
+       173: {From: 0x4817, To: 0x3503},
+       174: {From: 0x4916, To: 0x31f},
+       175: {From: 0x49a7, To: 0x523},
 }
 
-// Size: 164 bytes, 164 elements
-var AliasTypes = [164]AliasType{
+// Size: 176 bytes, 176 elements
+var AliasTypes = [176]AliasType{
        // Entry 0 - 3F
        1, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 1, 0, 0, 1, 2,
-       1, 1, 2, 0, 1, 0, 1, 2, 1, 1, 0, 0, 2, 1, 1, 0,
-       2, 0, 0, 1, 0, 1, 0, 0, 1, 2, 1, 1, 1, 1, 0, 0,
-       2, 1, 1, 1, 1, 2, 1, 0, 1, 1, 2, 2, 0, 1, 2, 0,
+       1, 1, 2, 0, 0, 1, 0, 1, 2, 1, 1, 0, 0, 2, 1, 1,
+       0, 2, 0, 0, 1, 0, 1, 0, 0, 1, 2, 1, 1, 1, 1, 0,
+       0, 0, 0, 2, 1, 1, 1, 1, 2, 1, 0, 1, 1, 2, 2, 0,
        // Entry 40 - 7F
-       1, 0, 1, 1, 1, 1, 0, 0, 2, 1, 0, 0, 0, 0, 1, 1,
-       1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1,
-       2, 2, 2, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1,
-       0, 1, 0, 2, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 2,
+       0, 1, 2, 0, 1, 0, 1, 1, 1, 1, 0, 0, 2, 1, 0, 0,
+       0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+       0, 1, 0, 0, 0, 1, 2, 2, 2, 0, 1, 1, 0, 1, 0, 0,
+       0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 2, 1, 1,
        // Entry 80 - BF
-       0, 0, 2, 1, 1, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,
-       1, 1, 0, 1, 2, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0,
-       0, 1, 1, 1,
+       0, 0, 1, 0, 0, 0, 0, 1, 1, 2, 0, 0, 2, 1, 1, 1,
+       0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 2,
+       0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1,
 }
 
 const (
-       _Latn = 87
-       _Hani = 54
-       _Hans = 56
-       _Hant = 57
-       _Qaaa = 139
-       _Qaai = 147
-       _Qabx = 188
-       _Zinh = 236
-       _Zyyy = 241
-       _Zzzz = 242
+       _Latn = 90
+       _Hani = 57
+       _Hans = 59
+       _Hant = 60
+       _Qaaa = 143
+       _Qaai = 151
+       _Qabx = 192
+       _Zinh = 245
+       _Zyyy = 250
+       _Zzzz = 251
 )
 
 // script is an alphabetically sorted list of ISO 15924 codes. The index
 // of the script in the string, divided by 4, is the internal scriptID.
-const script tag.Index = "" + // Size: 976 bytes
+const script tag.Index = "" + // Size: 1012 bytes
        "----AdlmAfakAghbAhomArabAranArmiArmnAvstBaliBamuBassBatkBengBhksBlisBopo" +
-       "BrahBraiBugiBuhdCakmCansCariChamCherCirtCoptCpmnCprtCyrlCyrsDevaDogrDsrt" +
-       "DuplEgydEgyhEgypElbaEthiGeokGeorGlagGongGonmGothGranGrekGujrGuruHanbHang" +
-       "HaniHanoHansHantHatrHebrHiraHluwHmngHmnpHrktHungIndsItalJamoJavaJpanJurc" +
-       "KaliKanaKharKhmrKhojKitlKitsKndaKoreKpelKthiLanaLaooLatfLatgLatnLekeLepc" +
-       "LimbLinaLinbLisuLomaLyciLydiMahjMakaMandManiMarcMayaMedfMendMercMeroMlym" +
-       "ModiMongMoonMrooMteiMultMymrNarbNbatNewaNkdbNkgbNkooNshuOgamOlckOrkhOrya" +
-       "OsgeOsmaPalmPaucPermPhagPhliPhlpPhlvPhnxPiqdPlrdPrtiQaaaQaabQaacQaadQaae" +
-       "QaafQaagQaahQaaiQaajQaakQaalQaamQaanQaaoQaapQaaqQaarQaasQaatQaauQaavQaaw" +
-       "QaaxQaayQaazQabaQabbQabcQabdQabeQabfQabgQabhQabiQabjQabkQablQabmQabnQabo" +
-       "QabpQabqQabrQabsQabtQabuQabvQabwQabxRjngRoroRunrSamrSaraSarbSaurSgnwShaw" +
-       "ShrdShuiSiddSindSinhSoraSoyoSundSyloSyrcSyreSyrjSyrnTagbTakrTaleTaluTaml" +
-       "TangTavtTeluTengTfngTglgThaaThaiTibtTirhUgarVaiiVispWaraWchoWoleXpeoXsux" +
-       "YiiiZanbZinhZmthZsyeZsymZxxxZyyyZzzz\xff\xff\xff\xff"
+       "BrahBraiBugiBuhdCakmCansCariChamCherChrsCirtCoptCpmnCprtCyrlCyrsDevaDiak" +
+       "DogrDsrtDuplEgydEgyhEgypElbaElymEthiGeokGeorGlagGongGonmGothGranGrekGujr" +
+       "GuruHanbHangHaniHanoHansHantHatrHebrHiraHluwHmngHmnpHrktHungIndsItalJamo" +
+       "JavaJpanJurcKaliKanaKharKhmrKhojKitlKitsKndaKoreKpelKthiLanaLaooLatfLatg" +
+       "LatnLekeLepcLimbLinaLinbLisuLomaLyciLydiMahjMakaMandManiMarcMayaMedfMend" +
+       "MercMeroMlymModiMongMoonMrooMteiMultMymrNandNarbNbatNewaNkdbNkgbNkooNshu" +
+       "OgamOlckOrkhOryaOsgeOsmaPalmPaucPermPhagPhliPhlpPhlvPhnxPiqdPlrdPrtiQaaa" +
+       "QaabQaacQaadQaaeQaafQaagQaahQaaiQaajQaakQaalQaamQaanQaaoQaapQaaqQaarQaas" +
+       "QaatQaauQaavQaawQaaxQaayQaazQabaQabbQabcQabdQabeQabfQabgQabhQabiQabjQabk" +
+       "QablQabmQabnQaboQabpQabqQabrQabsQabtQabuQabvQabwQabxRjngRohgRoroRunrSamr" +
+       "SaraSarbSaurSgnwShawShrdShuiSiddSindSinhSogdSogoSoraSoyoSundSyloSyrcSyre" +
+       "SyrjSyrnTagbTakrTaleTaluTamlTangTavtTeluTengTfngTglgThaaThaiTibtTirhToto" +
+       "UgarVaiiVispWaraWchoWoleXpeoXsuxYeziYiiiZanbZinhZmthZsyeZsymZxxxZyyyZzzz" +
+       "\xff\xff\xff\xff"
 
 // suppressScript is an index from langID to the dominant script for that language,
 // if it exists.  If a script is given, it should be suppressed from the language tag.
 // Size: 1330 bytes, 1330 elements
 var suppressScript = [1330]uint8{
        // Entry 0 - 3F
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
        // Entry 40 - 7F
        0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00,
+       0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
        // Entry 80 - BF
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -828,66 +841,66 @@ var suppressScript = [1330]uint8{
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        // Entry C0 - FF
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
        // Entry 100 - 13F
-       0x57, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00,
+       0x5a, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0xde, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00,
-       0x00, 0x57, 0x00, 0x00, 0x57, 0x00, 0x57, 0x00,
+       0xe5, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00,
+       0x00, 0x5a, 0x00, 0x00, 0x5a, 0x00, 0x5a, 0x00,
        // Entry 140 - 17F
-       0x57, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00,
+       0x5a, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00,
        0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x57, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00,
-       0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00,
-       0x00, 0x57, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x57, 0x00,
+       0x00, 0x5a, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00,
+       0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00,
+       0x00, 0x5a, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x5a, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        // Entry 180 - 1BF
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x57, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00,
+       0x5a, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x57, 0x32, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x5a, 0x35, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x21, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x22, 0x00,
        // Entry 1C0 - 1FF
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x57, 0x57, 0x00, 0x57, 0x57, 0x00, 0x08,
+       0x00, 0x5a, 0x5a, 0x00, 0x5a, 0x5a, 0x00, 0x08,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00,
-       0x57, 0x57, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00,
+       0x5a, 0x5a, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
        // Entry 200 - 23F
-       0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        // Entry 240 - 27F
-       0x00, 0x00, 0x1f, 0x00, 0x00, 0x57, 0x00, 0x00,
-       0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x4f, 0x00, 0x00, 0x50, 0x00, 0x21, 0x00,
+       0x00, 0x00, 0x20, 0x00, 0x00, 0x5a, 0x00, 0x00,
+       0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x52, 0x00, 0x00, 0x53, 0x00, 0x22, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -895,101 +908,101 @@ var suppressScript = [1330]uint8{
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        // Entry 280 - 2BF
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00,
-       0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00,
+       0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        // Entry 2C0 - 2FF
-       0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00,
+       0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+       0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
        // Entry 300 - 33F
-       0x00, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x57,
-       0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x5a,
+       0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00,
+       0x00, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00,
        // Entry 340 - 37F
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00,
-       0x57, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57,
-       0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x57,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x57, 0x00,
-       0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00,
+       0x5a, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
+       0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x5a,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x5a, 0x00,
+       0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
        // Entry 380 - 3BF
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x57, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00,
+       0x5a, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
        // Entry 3C0 - 3FF
-       0x57, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00,
+       0x5a, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00,
-       0x00, 0x57, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x1f, 0x00, 0x00, 0x57, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00,
+       0x00, 0x5a, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x20, 0x00, 0x00, 0x5a, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        // Entry 400 - 43F
-       0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x57, 0x00,
-       0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57,
-       0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x5a, 0x00,
+       0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
+       0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00,
        // Entry 440 - 47F
-       0x00, 0x00, 0x00, 0x00, 0x57, 0x57, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x5a, 0x5a, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0xd7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0xda, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x00, 0x29,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57,
-       0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x57, 0x00,
+       0x00, 0xe1, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x2c,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
+       0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x5a, 0x00,
        // Entry 480 - 4BF
-       0x57, 0x00, 0x57, 0x00, 0x00, 0x00, 0x57, 0x00,
-       0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x57, 0x00,
+       0x5a, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x5a, 0x00,
+       0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x5a, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00,
+       0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        // Entry 4C0 - 4FF
-       0x57, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00,
+       0x5a, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        // Entry 500 - 53F
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
        0x00, 0x00,
 }
 
@@ -1255,97 +1268,117 @@ var fromM49 = [333]uint16{
        0xc759, 0xc95a, 0xcb5b, 0xcd5c, 0xcf65,
 }
 
-// Size: 1615 bytes
+// Size: 1995 bytes
 var variantIndex = map[string]uint8{
        "1606nict": 0x0,
        "1694acad": 0x1,
        "1901":     0x2,
        "1959acad": 0x3,
-       "1994":     0x4d,
+       "1994":     0x60,
        "1996":     0x4,
        "abl1943":  0x5,
        "akuapem":  0x6,
-       "alalc97":  0x4f,
+       "alalc97":  0x62,
        "aluku":    0x7,
        "ao1990":   0x8,
-       "arevela":  0x9,
-       "arevmda":  0xa,
-       "asante":   0xb,
-       "baku1926": 0xc,
-       "balanka":  0xd,
-       "barla":    0xe,
-       "basiceng": 0xf,
-       "bauddha":  0x10,
-       "biscayan": 0x11,
-       "biske":    0x48,
-       "bohoric":  0x12,
-       "boont":    0x13,
-       "colb1945": 0x14,
-       "cornu":    0x15,
-       "dajnko":   0x16,
-       "ekavsk":   0x17,
-       "emodeng":  0x18,
-       "fonipa":   0x50,
-       "fonnapa":  0x51,
-       "fonupa":   0x52,
-       "fonxsamp": 0x53,
-       "hepburn":  0x19,
-       "heploc":   0x4e,
-       "hognorsk": 0x1a,
-       "hsistemo": 0x1b,
-       "ijekavsk": 0x1c,
-       "itihasa":  0x1d,
-       "jauer":    0x1e,
-       "jyutping": 0x1f,
-       "kkcor":    0x20,
-       "kociewie": 0x21,
-       "kscor":    0x22,
-       "laukika":  0x23,
-       "lipaw":    0x49,
-       "luna1918": 0x24,
-       "metelko":  0x25,
-       "monoton":  0x26,
-       "ndyuka":   0x27,
-       "nedis":    0x28,
-       "newfound": 0x29,
-       "njiva":    0x4a,
-       "nulik":    0x2a,
-       "osojs":    0x4b,
-       "oxendict": 0x2b,
-       "pahawh2":  0x2c,
-       "pahawh3":  0x2d,
-       "pahawh4":  0x2e,
-       "pamaka":   0x2f,
-       "petr1708": 0x30,
-       "pinyin":   0x31,
-       "polyton":  0x32,
-       "puter":    0x33,
-       "rigik":    0x34,
-       "rozaj":    0x35,
-       "rumgr":    0x36,
-       "scotland": 0x37,
-       "scouse":   0x38,
-       "simple":   0x54,
-       "solba":    0x4c,
-       "sotav":    0x39,
-       "spanglis": 0x3a,
-       "surmiran": 0x3b,
-       "sursilv":  0x3c,
-       "sutsilv":  0x3d,
-       "tarask":   0x3e,
-       "uccor":    0x3f,
-       "ucrcor":   0x40,
-       "ulster":   0x41,
-       "unifon":   0x42,
-       "vaidika":  0x43,
-       "valencia": 0x44,
-       "vallader": 0x45,
-       "wadegile": 0x46,
-       "xsistemo": 0x47,
+       "aranes":   0x9,
+       "arevela":  0xa,
+       "arevmda":  0xb,
+       "asante":   0xc,
+       "auvern":   0xd,
+       "baku1926": 0xe,
+       "balanka":  0xf,
+       "barla":    0x10,
+       "basiceng": 0x11,
+       "bauddha":  0x12,
+       "biscayan": 0x13,
+       "biske":    0x5b,
+       "bohoric":  0x14,
+       "boont":    0x15,
+       "bornholm": 0x16,
+       "cisaup":   0x17,
+       "colb1945": 0x18,
+       "cornu":    0x19,
+       "creiss":   0x1a,
+       "dajnko":   0x1b,
+       "ekavsk":   0x1c,
+       "emodeng":  0x1d,
+       "fonipa":   0x63,
+       "fonkirsh": 0x64,
+       "fonnapa":  0x65,
+       "fonupa":   0x66,
+       "fonxsamp": 0x67,
+       "gascon":   0x1e,
+       "grclass":  0x1f,
+       "grital":   0x20,
+       "grmistr":  0x21,
+       "hepburn":  0x22,
+       "heploc":   0x61,
+       "hognorsk": 0x23,
+       "hsistemo": 0x24,
+       "ijekavsk": 0x25,
+       "itihasa":  0x26,
+       "ivanchov": 0x27,
+       "jauer":    0x28,
+       "jyutping": 0x29,
+       "kkcor":    0x2a,
+       "kociewie": 0x2b,
+       "kscor":    0x2c,
+       "laukika":  0x2d,
+       "lemosin":  0x2e,
+       "lengadoc": 0x2f,
+       "lipaw":    0x5c,
+       "luna1918": 0x30,
+       "metelko":  0x31,
+       "monoton":  0x32,
+       "ndyuka":   0x33,
+       "nedis":    0x34,
+       "newfound": 0x35,
+       "nicard":   0x36,
+       "njiva":    0x5d,
+       "nulik":    0x37,
+       "osojs":    0x5e,
+       "oxendict": 0x38,
+       "pahawh2":  0x39,
+       "pahawh3":  0x3a,
+       "pahawh4":  0x3b,
+       "pamaka":   0x3c,
+       "peano":    0x3d,
+       "petr1708": 0x3e,
+       "pinyin":   0x3f,
+       "polyton":  0x40,
+       "provenc":  0x41,
+       "puter":    0x42,
+       "rigik":    0x43,
+       "rozaj":    0x44,
+       "rumgr":    0x45,
+       "scotland": 0x46,
+       "scouse":   0x47,
+       "simple":   0x68,
+       "solba":    0x5f,
+       "sotav":    0x48,
+       "spanglis": 0x49,
+       "surmiran": 0x4a,
+       "sursilv":  0x4b,
+       "sutsilv":  0x4c,
+       "tarask":   0x4d,
+       "tongyong": 0x4e,
+       "tunumiit": 0x4f,
+       "uccor":    0x50,
+       "ucrcor":   0x51,
+       "ulster":   0x52,
+       "unifon":   0x53,
+       "vaidika":  0x54,
+       "valencia": 0x55,
+       "vallader": 0x56,
+       "vecdruka": 0x57,
+       "vivaraup": 0x58,
+       "wadegile": 0x59,
+       "xsistemo": 0x5a,
 }
 
 // variantNumSpecialized is the number of specialized variants in variants.
-const variantNumSpecialized = 79
+const variantNumSpecialized = 98
 
 // nRegionGroups is the number of region groups.
 const nRegionGroups = 33
@@ -1357,8 +1390,8 @@ type likelyLangRegion struct {
 
 // likelyScript is a lookup table, indexed by scriptID, for the most likely
 // languages and regions given a script.
-// Size: 976 bytes, 244 elements
-var likelyScript = [244]likelyLangRegion{
+// Size: 1012 bytes, 253 elements
+var likelyScript = [253]likelyLangRegion{
        1:   {lang: 0x14e, region: 0x84},
        3:   {lang: 0x2a2, region: 0x106},
        4:   {lang: 0x1f, region: 0x99},
@@ -1382,126 +1415,126 @@ var likelyScript = [244]likelyLangRegion{
        24:  {lang: 0x4f0, region: 0x12b},
        25:  {lang: 0xe7, region: 0x13e},
        26:  {lang: 0xe5, region: 0x135},
-       28:  {lang: 0xf1, region: 0x6b},
-       30:  {lang: 0x1a0, region: 0x5d},
-       31:  {lang: 0x3e2, region: 0x106},
-       33:  {lang: 0x1be, region: 0x99},
-       36:  {lang: 0x15e, region: 0x78},
-       39:  {lang: 0x133, region: 0x6b},
-       40:  {lang: 0x431, region: 0x27},
-       41:  {lang: 0x27, region: 0x6f},
-       43:  {lang: 0x210, region: 0x7d},
-       44:  {lang: 0xfe, region: 0x38},
-       46:  {lang: 0x19b, region: 0x99},
-       47:  {lang: 0x19e, region: 0x130},
-       48:  {lang: 0x3e9, region: 0x99},
-       49:  {lang: 0x136, region: 0x87},
-       50:  {lang: 0x1a4, region: 0x99},
-       51:  {lang: 0x39d, region: 0x99},
-       52:  {lang: 0x529, region: 0x12e},
-       53:  {lang: 0x254, region: 0xab},
-       54:  {lang: 0x529, region: 0x53},
-       55:  {lang: 0x1cb, region: 0xe7},
-       56:  {lang: 0x529, region: 0x53},
-       57:  {lang: 0x529, region: 0x12e},
-       58:  {lang: 0x2fd, region: 0x9b},
-       59:  {lang: 0x1bc, region: 0x97},
-       60:  {lang: 0x200, region: 0xa2},
-       61:  {lang: 0x1c5, region: 0x12b},
-       62:  {lang: 0x1ca, region: 0xaf},
-       65:  {lang: 0x1d5, region: 0x92},
-       67:  {lang: 0x142, region: 0x9e},
-       68:  {lang: 0x254, region: 0xab},
-       69:  {lang: 0x20e, region: 0x95},
-       70:  {lang: 0x200, region: 0xa2},
-       72:  {lang: 0x135, region: 0xc4},
+       29:  {lang: 0xf1, region: 0x6b},
+       31:  {lang: 0x1a0, region: 0x5d},
+       32:  {lang: 0x3e2, region: 0x106},
+       34:  {lang: 0x1be, region: 0x99},
+       38:  {lang: 0x15e, region: 0x78},
+       41:  {lang: 0x133, region: 0x6b},
+       42:  {lang: 0x431, region: 0x27},
+       44:  {lang: 0x27, region: 0x6f},
+       46:  {lang: 0x210, region: 0x7d},
+       47:  {lang: 0xfe, region: 0x38},
+       49:  {lang: 0x19b, region: 0x99},
+       50:  {lang: 0x19e, region: 0x130},
+       51:  {lang: 0x3e9, region: 0x99},
+       52:  {lang: 0x136, region: 0x87},
+       53:  {lang: 0x1a4, region: 0x99},
+       54:  {lang: 0x39d, region: 0x99},
+       55:  {lang: 0x529, region: 0x12e},
+       56:  {lang: 0x254, region: 0xab},
+       57:  {lang: 0x529, region: 0x53},
+       58:  {lang: 0x1cb, region: 0xe7},
+       59:  {lang: 0x529, region: 0x53},
+       60:  {lang: 0x529, region: 0x12e},
+       61:  {lang: 0x2fd, region: 0x9b},
+       62:  {lang: 0x1bc, region: 0x97},
+       63:  {lang: 0x200, region: 0xa2},
+       64:  {lang: 0x1c5, region: 0x12b},
+       65:  {lang: 0x1ca, region: 0xaf},
+       68:  {lang: 0x1d5, region: 0x92},
+       70:  {lang: 0x142, region: 0x9e},
+       71:  {lang: 0x254, region: 0xab},
+       72:  {lang: 0x20e, region: 0x95},
        73:  {lang: 0x200, region: 0xa2},
-       74:  {lang: 0x3bb, region: 0xe8},
-       75:  {lang: 0x24a, region: 0xa6},
-       76:  {lang: 0x3fa, region: 0x99},
-       79:  {lang: 0x251, region: 0x99},
-       80:  {lang: 0x254, region: 0xab},
-       82:  {lang: 0x88, region: 0x99},
-       83:  {lang: 0x370, region: 0x123},
-       84:  {lang: 0x2b8, region: 0xaf},
-       89:  {lang: 0x29f, region: 0x99},
-       90:  {lang: 0x2a8, region: 0x99},
-       91:  {lang: 0x28f, region: 0x87},
-       92:  {lang: 0x1a0, region: 0x87},
-       93:  {lang: 0x2ac, region: 0x53},
-       95:  {lang: 0x4f4, region: 0x12b},
-       96:  {lang: 0x4f5, region: 0x12b},
-       97:  {lang: 0x1be, region: 0x99},
-       99:  {lang: 0x337, region: 0x9c},
-       100: {lang: 0x4f7, region: 0x53},
-       101: {lang: 0xa9, region: 0x53},
-       104: {lang: 0x2e8, region: 0x112},
-       105: {lang: 0x4f8, region: 0x10b},
-       106: {lang: 0x4f8, region: 0x10b},
-       107: {lang: 0x304, region: 0x99},
-       108: {lang: 0x31b, region: 0x99},
-       109: {lang: 0x30b, region: 0x53},
-       111: {lang: 0x31e, region: 0x35},
-       112: {lang: 0x30e, region: 0x99},
-       113: {lang: 0x414, region: 0xe8},
-       114: {lang: 0x331, region: 0xc4},
-       115: {lang: 0x4f9, region: 0x108},
-       116: {lang: 0x3b, region: 0xa1},
-       117: {lang: 0x353, region: 0xdb},
-       120: {lang: 0x2d0, region: 0x84},
-       121: {lang: 0x52a, region: 0x53},
-       122: {lang: 0x403, region: 0x96},
-       123: {lang: 0x3ee, region: 0x99},
-       124: {lang: 0x39b, region: 0xc5},
-       125: {lang: 0x395, region: 0x99},
-       126: {lang: 0x399, region: 0x135},
-       127: {lang: 0x429, region: 0x115},
-       128: {lang: 0x3b, region: 0x11c},
-       129: {lang: 0xfd, region: 0xc4},
-       130: {lang: 0x27d, region: 0x106},
-       131: {lang: 0x2c9, region: 0x53},
-       132: {lang: 0x39f, region: 0x9c},
-       133: {lang: 0x39f, region: 0x53},
-       135: {lang: 0x3ad, region: 0xb0},
-       137: {lang: 0x1c6, region: 0x53},
-       138: {lang: 0x4fd, region: 0x9c},
-       189: {lang: 0x3cb, region: 0x95},
-       191: {lang: 0x372, region: 0x10c},
-       192: {lang: 0x420, region: 0x97},
-       194: {lang: 0x4ff, region: 0x15e},
-       195: {lang: 0x3f0, region: 0x99},
-       196: {lang: 0x45, region: 0x135},
-       197: {lang: 0x139, region: 0x7b},
-       198: {lang: 0x3e9, region: 0x99},
-       200: {lang: 0x3e9, region: 0x99},
-       201: {lang: 0x3fa, region: 0x99},
-       202: {lang: 0x40c, region: 0xb3},
-       203: {lang: 0x433, region: 0x99},
-       204: {lang: 0xef, region: 0xc5},
-       205: {lang: 0x43e, region: 0x95},
-       206: {lang: 0x44d, region: 0x35},
-       207: {lang: 0x44e, region: 0x9b},
-       211: {lang: 0x45a, region: 0xe7},
-       212: {lang: 0x11a, region: 0x99},
-       213: {lang: 0x45e, region: 0x53},
-       214: {lang: 0x232, region: 0x53},
-       215: {lang: 0x450, region: 0x99},
-       216: {lang: 0x4a5, region: 0x53},
-       217: {lang: 0x9f, region: 0x13e},
-       218: {lang: 0x461, region: 0x99},
-       220: {lang: 0x528, region: 0xba},
-       221: {lang: 0x153, region: 0xe7},
-       222: {lang: 0x128, region: 0xcd},
-       223: {lang: 0x46b, region: 0x123},
-       224: {lang: 0xa9, region: 0x53},
-       225: {lang: 0x2ce, region: 0x99},
-       226: {lang: 0x4ad, region: 0x11c},
-       227: {lang: 0x4be, region: 0xb4},
-       229: {lang: 0x1ce, region: 0x99},
-       232: {lang: 0x3a9, region: 0x9c},
-       233: {lang: 0x22, region: 0x9b},
-       234: {lang: 0x1ea, region: 0x53},
-       235: {lang: 0xef, region: 0xc5},
+       75:  {lang: 0x135, region: 0xc4},
+       76:  {lang: 0x200, region: 0xa2},
+       77:  {lang: 0x3bb, region: 0xe8},
+       78:  {lang: 0x24a, region: 0xa6},
+       79:  {lang: 0x3fa, region: 0x99},
+       82:  {lang: 0x251, region: 0x99},
+       83:  {lang: 0x254, region: 0xab},
+       85:  {lang: 0x88, region: 0x99},
+       86:  {lang: 0x370, region: 0x123},
+       87:  {lang: 0x2b8, region: 0xaf},
+       92:  {lang: 0x29f, region: 0x99},
+       93:  {lang: 0x2a8, region: 0x99},
+       94:  {lang: 0x28f, region: 0x87},
+       95:  {lang: 0x1a0, region: 0x87},
+       96:  {lang: 0x2ac, region: 0x53},
+       98:  {lang: 0x4f4, region: 0x12b},
+       99:  {lang: 0x4f5, region: 0x12b},
+       100: {lang: 0x1be, region: 0x99},
+       102: {lang: 0x337, region: 0x9c},
+       103: {lang: 0x4f7, region: 0x53},
+       104: {lang: 0xa9, region: 0x53},
+       107: {lang: 0x2e8, region: 0x112},
+       108: {lang: 0x4f8, region: 0x10b},
+       109: {lang: 0x4f8, region: 0x10b},
+       110: {lang: 0x304, region: 0x99},
+       111: {lang: 0x31b, region: 0x99},
+       112: {lang: 0x30b, region: 0x53},
+       114: {lang: 0x31e, region: 0x35},
+       115: {lang: 0x30e, region: 0x99},
+       116: {lang: 0x414, region: 0xe8},
+       117: {lang: 0x331, region: 0xc4},
+       119: {lang: 0x4f9, region: 0x108},
+       120: {lang: 0x3b, region: 0xa1},
+       121: {lang: 0x353, region: 0xdb},
+       124: {lang: 0x2d0, region: 0x84},
+       125: {lang: 0x52a, region: 0x53},
+       126: {lang: 0x403, region: 0x96},
+       127: {lang: 0x3ee, region: 0x99},
+       128: {lang: 0x39b, region: 0xc5},
+       129: {lang: 0x395, region: 0x99},
+       130: {lang: 0x399, region: 0x135},
+       131: {lang: 0x429, region: 0x115},
+       132: {lang: 0x3b, region: 0x11c},
+       133: {lang: 0xfd, region: 0xc4},
+       134: {lang: 0x27d, region: 0x106},
+       135: {lang: 0x2c9, region: 0x53},
+       136: {lang: 0x39f, region: 0x9c},
+       137: {lang: 0x39f, region: 0x53},
+       139: {lang: 0x3ad, region: 0xb0},
+       141: {lang: 0x1c6, region: 0x53},
+       142: {lang: 0x4fd, region: 0x9c},
+       193: {lang: 0x3cb, region: 0x95},
+       196: {lang: 0x372, region: 0x10c},
+       197: {lang: 0x420, region: 0x97},
+       199: {lang: 0x4ff, region: 0x15e},
+       200: {lang: 0x3f0, region: 0x99},
+       201: {lang: 0x45, region: 0x135},
+       202: {lang: 0x139, region: 0x7b},
+       203: {lang: 0x3e9, region: 0x99},
+       205: {lang: 0x3e9, region: 0x99},
+       206: {lang: 0x3fa, region: 0x99},
+       207: {lang: 0x40c, region: 0xb3},
+       210: {lang: 0x433, region: 0x99},
+       211: {lang: 0xef, region: 0xc5},
+       212: {lang: 0x43e, region: 0x95},
+       213: {lang: 0x44d, region: 0x35},
+       214: {lang: 0x44e, region: 0x9b},
+       218: {lang: 0x45a, region: 0xe7},
+       219: {lang: 0x11a, region: 0x99},
+       220: {lang: 0x45e, region: 0x53},
+       221: {lang: 0x232, region: 0x53},
+       222: {lang: 0x450, region: 0x99},
+       223: {lang: 0x4a5, region: 0x53},
+       224: {lang: 0x9f, region: 0x13e},
+       225: {lang: 0x461, region: 0x99},
+       227: {lang: 0x528, region: 0xba},
+       228: {lang: 0x153, region: 0xe7},
+       229: {lang: 0x128, region: 0xcd},
+       230: {lang: 0x46b, region: 0x123},
+       231: {lang: 0xa9, region: 0x53},
+       232: {lang: 0x2ce, region: 0x99},
+       234: {lang: 0x4ad, region: 0x11c},
+       235: {lang: 0x4be, region: 0xb4},
+       237: {lang: 0x1ce, region: 0x99},
+       240: {lang: 0x3a9, region: 0x9c},
+       241: {lang: 0x22, region: 0x9b},
+       243: {lang: 0x1ea, region: 0x53},
+       244: {lang: 0xef, region: 0xc5},
 }
 
 type likelyScriptRegion struct {
@@ -1516,1423 +1549,1423 @@ type likelyScriptRegion struct {
 // of the list in likelyLangList.
 // Size: 5320 bytes, 1330 elements
 var likelyLang = [1330]likelyScriptRegion{
-       0:    {region: 0x135, script: 0x57, flags: 0x0},
-       1:    {region: 0x6f, script: 0x57, flags: 0x0},
-       2:    {region: 0x165, script: 0x57, flags: 0x0},
-       3:    {region: 0x165, script: 0x57, flags: 0x0},
-       4:    {region: 0x165, script: 0x57, flags: 0x0},
-       5:    {region: 0x7d, script: 0x1f, flags: 0x0},
-       6:    {region: 0x165, script: 0x57, flags: 0x0},
-       7:    {region: 0x165, script: 0x1f, flags: 0x0},
-       8:    {region: 0x80, script: 0x57, flags: 0x0},
-       9:    {region: 0x165, script: 0x57, flags: 0x0},
-       10:   {region: 0x165, script: 0x57, flags: 0x0},
-       11:   {region: 0x165, script: 0x57, flags: 0x0},
-       12:   {region: 0x95, script: 0x57, flags: 0x0},
-       13:   {region: 0x131, script: 0x57, flags: 0x0},
-       14:   {region: 0x80, script: 0x57, flags: 0x0},
-       15:   {region: 0x165, script: 0x57, flags: 0x0},
-       16:   {region: 0x165, script: 0x57, flags: 0x0},
-       17:   {region: 0x106, script: 0x1f, flags: 0x0},
-       18:   {region: 0x165, script: 0x57, flags: 0x0},
+       0:    {region: 0x135, script: 0x5a, flags: 0x0},
+       1:    {region: 0x6f, script: 0x5a, flags: 0x0},
+       2:    {region: 0x165, script: 0x5a, flags: 0x0},
+       3:    {region: 0x165, script: 0x5a, flags: 0x0},
+       4:    {region: 0x165, script: 0x5a, flags: 0x0},
+       5:    {region: 0x7d, script: 0x20, flags: 0x0},
+       6:    {region: 0x165, script: 0x5a, flags: 0x0},
+       7:    {region: 0x165, script: 0x20, flags: 0x0},
+       8:    {region: 0x80, script: 0x5a, flags: 0x0},
+       9:    {region: 0x165, script: 0x5a, flags: 0x0},
+       10:   {region: 0x165, script: 0x5a, flags: 0x0},
+       11:   {region: 0x165, script: 0x5a, flags: 0x0},
+       12:   {region: 0x95, script: 0x5a, flags: 0x0},
+       13:   {region: 0x131, script: 0x5a, flags: 0x0},
+       14:   {region: 0x80, script: 0x5a, flags: 0x0},
+       15:   {region: 0x165, script: 0x5a, flags: 0x0},
+       16:   {region: 0x165, script: 0x5a, flags: 0x0},
+       17:   {region: 0x106, script: 0x20, flags: 0x0},
+       18:   {region: 0x165, script: 0x5a, flags: 0x0},
        19:   {region: 0x9c, script: 0x9, flags: 0x0},
        20:   {region: 0x128, script: 0x5, flags: 0x0},
-       21:   {region: 0x165, script: 0x57, flags: 0x0},
-       22:   {region: 0x161, script: 0x57, flags: 0x0},
-       23:   {region: 0x165, script: 0x57, flags: 0x0},
-       24:   {region: 0x165, script: 0x57, flags: 0x0},
-       25:   {region: 0x165, script: 0x57, flags: 0x0},
-       26:   {region: 0x165, script: 0x57, flags: 0x0},
-       27:   {region: 0x165, script: 0x57, flags: 0x0},
-       28:   {region: 0x52, script: 0x57, flags: 0x0},
-       29:   {region: 0x165, script: 0x57, flags: 0x0},
-       30:   {region: 0x165, script: 0x57, flags: 0x0},
+       21:   {region: 0x165, script: 0x5a, flags: 0x0},
+       22:   {region: 0x161, script: 0x5a, flags: 0x0},
+       23:   {region: 0x165, script: 0x5a, flags: 0x0},
+       24:   {region: 0x165, script: 0x5a, flags: 0x0},
+       25:   {region: 0x165, script: 0x5a, flags: 0x0},
+       26:   {region: 0x165, script: 0x5a, flags: 0x0},
+       27:   {region: 0x165, script: 0x5a, flags: 0x0},
+       28:   {region: 0x52, script: 0x5a, flags: 0x0},
+       29:   {region: 0x165, script: 0x5a, flags: 0x0},
+       30:   {region: 0x165, script: 0x5a, flags: 0x0},
        31:   {region: 0x99, script: 0x4, flags: 0x0},
-       32:   {region: 0x165, script: 0x57, flags: 0x0},
-       33:   {region: 0x80, script: 0x57, flags: 0x0},
-       34:   {region: 0x9b, script: 0xe9, flags: 0x0},
-       35:   {region: 0x165, script: 0x57, flags: 0x0},
-       36:   {region: 0x165, script: 0x57, flags: 0x0},
-       37:   {region: 0x14d, script: 0x57, flags: 0x0},
-       38:   {region: 0x106, script: 0x1f, flags: 0x0},
-       39:   {region: 0x6f, script: 0x29, flags: 0x0},
-       40:   {region: 0x165, script: 0x57, flags: 0x0},
-       41:   {region: 0x165, script: 0x57, flags: 0x0},
-       42:   {region: 0xd6, script: 0x57, flags: 0x0},
-       43:   {region: 0x165, script: 0x57, flags: 0x0},
-       45:   {region: 0x165, script: 0x57, flags: 0x0},
-       46:   {region: 0x165, script: 0x57, flags: 0x0},
-       47:   {region: 0x165, script: 0x57, flags: 0x0},
-       48:   {region: 0x165, script: 0x57, flags: 0x0},
-       49:   {region: 0x165, script: 0x57, flags: 0x0},
-       50:   {region: 0x165, script: 0x57, flags: 0x0},
-       51:   {region: 0x95, script: 0x57, flags: 0x0},
+       32:   {region: 0x165, script: 0x5a, flags: 0x0},
+       33:   {region: 0x80, script: 0x5a, flags: 0x0},
+       34:   {region: 0x9b, script: 0xf1, flags: 0x0},
+       35:   {region: 0x165, script: 0x5a, flags: 0x0},
+       36:   {region: 0x165, script: 0x5a, flags: 0x0},
+       37:   {region: 0x14d, script: 0x5a, flags: 0x0},
+       38:   {region: 0x106, script: 0x20, flags: 0x0},
+       39:   {region: 0x6f, script: 0x2c, flags: 0x0},
+       40:   {region: 0x165, script: 0x5a, flags: 0x0},
+       41:   {region: 0x165, script: 0x5a, flags: 0x0},
+       42:   {region: 0xd6, script: 0x5a, flags: 0x0},
+       43:   {region: 0x165, script: 0x5a, flags: 0x0},
+       45:   {region: 0x165, script: 0x5a, flags: 0x0},
+       46:   {region: 0x165, script: 0x5a, flags: 0x0},
+       47:   {region: 0x165, script: 0x5a, flags: 0x0},
+       48:   {region: 0x165, script: 0x5a, flags: 0x0},
+       49:   {region: 0x165, script: 0x5a, flags: 0x0},
+       50:   {region: 0x165, script: 0x5a, flags: 0x0},
+       51:   {region: 0x95, script: 0x5a, flags: 0x0},
        52:   {region: 0x165, script: 0x5, flags: 0x0},
        53:   {region: 0x122, script: 0x5, flags: 0x0},
-       54:   {region: 0x165, script: 0x57, flags: 0x0},
-       55:   {region: 0x165, script: 0x57, flags: 0x0},
-       56:   {region: 0x165, script: 0x57, flags: 0x0},
-       57:   {region: 0x165, script: 0x57, flags: 0x0},
+       54:   {region: 0x165, script: 0x5a, flags: 0x0},
+       55:   {region: 0x165, script: 0x5a, flags: 0x0},
+       56:   {region: 0x165, script: 0x5a, flags: 0x0},
+       57:   {region: 0x165, script: 0x5a, flags: 0x0},
        58:   {region: 0x6b, script: 0x5, flags: 0x0},
        59:   {region: 0x0, script: 0x3, flags: 0x1},
-       60:   {region: 0x165, script: 0x57, flags: 0x0},
-       61:   {region: 0x51, script: 0x57, flags: 0x0},
-       62:   {region: 0x3f, script: 0x57, flags: 0x0},
+       60:   {region: 0x165, script: 0x5a, flags: 0x0},
+       61:   {region: 0x51, script: 0x5a, flags: 0x0},
+       62:   {region: 0x3f, script: 0x5a, flags: 0x0},
        63:   {region: 0x67, script: 0x5, flags: 0x0},
        65:   {region: 0xba, script: 0x5, flags: 0x0},
        66:   {region: 0x6b, script: 0x5, flags: 0x0},
        67:   {region: 0x99, script: 0xe, flags: 0x0},
-       68:   {region: 0x12f, script: 0x57, flags: 0x0},
-       69:   {region: 0x135, script: 0xc4, flags: 0x0},
-       70:   {region: 0x165, script: 0x57, flags: 0x0},
-       71:   {region: 0x165, script: 0x57, flags: 0x0},
-       72:   {region: 0x6e, script: 0x57, flags: 0x0},
-       73:   {region: 0x165, script: 0x57, flags: 0x0},
-       74:   {region: 0x165, script: 0x57, flags: 0x0},
-       75:   {region: 0x49, script: 0x57, flags: 0x0},
-       76:   {region: 0x165, script: 0x57, flags: 0x0},
-       77:   {region: 0x106, script: 0x1f, flags: 0x0},
+       68:   {region: 0x12f, script: 0x5a, flags: 0x0},
+       69:   {region: 0x135, script: 0xc9, flags: 0x0},
+       70:   {region: 0x165, script: 0x5a, flags: 0x0},
+       71:   {region: 0x165, script: 0x5a, flags: 0x0},
+       72:   {region: 0x6e, script: 0x5a, flags: 0x0},
+       73:   {region: 0x165, script: 0x5a, flags: 0x0},
+       74:   {region: 0x165, script: 0x5a, flags: 0x0},
+       75:   {region: 0x49, script: 0x5a, flags: 0x0},
+       76:   {region: 0x165, script: 0x5a, flags: 0x0},
+       77:   {region: 0x106, script: 0x20, flags: 0x0},
        78:   {region: 0x165, script: 0x5, flags: 0x0},
-       79:   {region: 0x165, script: 0x57, flags: 0x0},
-       80:   {region: 0x165, script: 0x57, flags: 0x0},
-       81:   {region: 0x165, script: 0x57, flags: 0x0},
-       82:   {region: 0x99, script: 0x21, flags: 0x0},
-       83:   {region: 0x165, script: 0x57, flags: 0x0},
-       84:   {region: 0x165, script: 0x57, flags: 0x0},
-       85:   {region: 0x165, script: 0x57, flags: 0x0},
-       86:   {region: 0x3f, script: 0x57, flags: 0x0},
-       87:   {region: 0x165, script: 0x57, flags: 0x0},
+       79:   {region: 0x165, script: 0x5a, flags: 0x0},
+       80:   {region: 0x165, script: 0x5a, flags: 0x0},
+       81:   {region: 0x165, script: 0x5a, flags: 0x0},
+       82:   {region: 0x99, script: 0x22, flags: 0x0},
+       83:   {region: 0x165, script: 0x5a, flags: 0x0},
+       84:   {region: 0x165, script: 0x5a, flags: 0x0},
+       85:   {region: 0x165, script: 0x5a, flags: 0x0},
+       86:   {region: 0x3f, script: 0x5a, flags: 0x0},
+       87:   {region: 0x165, script: 0x5a, flags: 0x0},
        88:   {region: 0x3, script: 0x5, flags: 0x1},
-       89:   {region: 0x106, script: 0x1f, flags: 0x0},
+       89:   {region: 0x106, script: 0x20, flags: 0x0},
        90:   {region: 0xe8, script: 0x5, flags: 0x0},
-       91:   {region: 0x95, script: 0x57, flags: 0x0},
-       92:   {region: 0xdb, script: 0x21, flags: 0x0},
-       93:   {region: 0x2e, script: 0x57, flags: 0x0},
-       94:   {region: 0x52, script: 0x57, flags: 0x0},
-       95:   {region: 0x165, script: 0x57, flags: 0x0},
+       91:   {region: 0x95, script: 0x5a, flags: 0x0},
+       92:   {region: 0xdb, script: 0x22, flags: 0x0},
+       93:   {region: 0x2e, script: 0x5a, flags: 0x0},
+       94:   {region: 0x52, script: 0x5a, flags: 0x0},
+       95:   {region: 0x165, script: 0x5a, flags: 0x0},
        96:   {region: 0x52, script: 0xb, flags: 0x0},
-       97:   {region: 0x165, script: 0x57, flags: 0x0},
-       98:   {region: 0x165, script: 0x57, flags: 0x0},
-       99:   {region: 0x95, script: 0x57, flags: 0x0},
-       100:  {region: 0x165, script: 0x57, flags: 0x0},
-       101:  {region: 0x52, script: 0x57, flags: 0x0},
-       102:  {region: 0x165, script: 0x57, flags: 0x0},
-       103:  {region: 0x165, script: 0x57, flags: 0x0},
-       104:  {region: 0x165, script: 0x57, flags: 0x0},
-       105:  {region: 0x165, script: 0x57, flags: 0x0},
-       106:  {region: 0x4f, script: 0x57, flags: 0x0},
-       107:  {region: 0x165, script: 0x57, flags: 0x0},
-       108:  {region: 0x165, script: 0x57, flags: 0x0},
-       109:  {region: 0x165, script: 0x57, flags: 0x0},
-       110:  {region: 0x165, script: 0x29, flags: 0x0},
-       111:  {region: 0x165, script: 0x57, flags: 0x0},
-       112:  {region: 0x165, script: 0x57, flags: 0x0},
-       113:  {region: 0x47, script: 0x1f, flags: 0x0},
-       114:  {region: 0x165, script: 0x57, flags: 0x0},
-       115:  {region: 0x165, script: 0x57, flags: 0x0},
+       97:   {region: 0x165, script: 0x5a, flags: 0x0},
+       98:   {region: 0x165, script: 0x5a, flags: 0x0},
+       99:   {region: 0x95, script: 0x5a, flags: 0x0},
+       100:  {region: 0x165, script: 0x5a, flags: 0x0},
+       101:  {region: 0x52, script: 0x5a, flags: 0x0},
+       102:  {region: 0x165, script: 0x5a, flags: 0x0},
+       103:  {region: 0x165, script: 0x5a, flags: 0x0},
+       104:  {region: 0x165, script: 0x5a, flags: 0x0},
+       105:  {region: 0x165, script: 0x5a, flags: 0x0},
+       106:  {region: 0x4f, script: 0x5a, flags: 0x0},
+       107:  {region: 0x165, script: 0x5a, flags: 0x0},
+       108:  {region: 0x165, script: 0x5a, flags: 0x0},
+       109:  {region: 0x165, script: 0x5a, flags: 0x0},
+       110:  {region: 0x165, script: 0x2c, flags: 0x0},
+       111:  {region: 0x165, script: 0x5a, flags: 0x0},
+       112:  {region: 0x165, script: 0x5a, flags: 0x0},
+       113:  {region: 0x47, script: 0x20, flags: 0x0},
+       114:  {region: 0x165, script: 0x5a, flags: 0x0},
+       115:  {region: 0x165, script: 0x5a, flags: 0x0},
        116:  {region: 0x10b, script: 0x5, flags: 0x0},
-       117:  {region: 0x162, script: 0x57, flags: 0x0},
-       118:  {region: 0x165, script: 0x57, flags: 0x0},
-       119:  {region: 0x95, script: 0x57, flags: 0x0},
-       120:  {region: 0x165, script: 0x57, flags: 0x0},
-       121:  {region: 0x12f, script: 0x57, flags: 0x0},
-       122:  {region: 0x52, script: 0x57, flags: 0x0},
-       123:  {region: 0x99, script: 0xd7, flags: 0x0},
+       117:  {region: 0x162, script: 0x5a, flags: 0x0},
+       118:  {region: 0x165, script: 0x5a, flags: 0x0},
+       119:  {region: 0x95, script: 0x5a, flags: 0x0},
+       120:  {region: 0x165, script: 0x5a, flags: 0x0},
+       121:  {region: 0x12f, script: 0x5a, flags: 0x0},
+       122:  {region: 0x52, script: 0x5a, flags: 0x0},
+       123:  {region: 0x99, script: 0xde, flags: 0x0},
        124:  {region: 0xe8, script: 0x5, flags: 0x0},
-       125:  {region: 0x99, script: 0x21, flags: 0x0},
-       126:  {region: 0x38, script: 0x1f, flags: 0x0},
-       127:  {region: 0x99, script: 0x21, flags: 0x0},
+       125:  {region: 0x99, script: 0x22, flags: 0x0},
+       126:  {region: 0x38, script: 0x20, flags: 0x0},
+       127:  {region: 0x99, script: 0x22, flags: 0x0},
        128:  {region: 0xe8, script: 0x5, flags: 0x0},
-       129:  {region: 0x12b, script: 0x31, flags: 0x0},
-       131:  {region: 0x99, script: 0x21, flags: 0x0},
-       132:  {region: 0x165, script: 0x57, flags: 0x0},
-       133:  {region: 0x99, script: 0x21, flags: 0x0},
-       134:  {region: 0xe7, script: 0x57, flags: 0x0},
-       135:  {region: 0x165, script: 0x57, flags: 0x0},
-       136:  {region: 0x99, script: 0x21, flags: 0x0},
-       137:  {region: 0x165, script: 0x57, flags: 0x0},
-       138:  {region: 0x13f, script: 0x57, flags: 0x0},
-       139:  {region: 0x165, script: 0x57, flags: 0x0},
-       140:  {region: 0x165, script: 0x57, flags: 0x0},
-       141:  {region: 0xe7, script: 0x57, flags: 0x0},
-       142:  {region: 0x165, script: 0x57, flags: 0x0},
-       143:  {region: 0xd6, script: 0x57, flags: 0x0},
-       144:  {region: 0x165, script: 0x57, flags: 0x0},
-       145:  {region: 0x165, script: 0x57, flags: 0x0},
-       146:  {region: 0x165, script: 0x57, flags: 0x0},
-       147:  {region: 0x165, script: 0x29, flags: 0x0},
-       148:  {region: 0x99, script: 0x21, flags: 0x0},
-       149:  {region: 0x95, script: 0x57, flags: 0x0},
-       150:  {region: 0x165, script: 0x57, flags: 0x0},
-       151:  {region: 0x165, script: 0x57, flags: 0x0},
-       152:  {region: 0x114, script: 0x57, flags: 0x0},
-       153:  {region: 0x165, script: 0x57, flags: 0x0},
-       154:  {region: 0x165, script: 0x57, flags: 0x0},
-       155:  {region: 0x52, script: 0x57, flags: 0x0},
-       156:  {region: 0x165, script: 0x57, flags: 0x0},
-       157:  {region: 0xe7, script: 0x57, flags: 0x0},
-       158:  {region: 0x165, script: 0x57, flags: 0x0},
-       159:  {region: 0x13e, script: 0xd9, flags: 0x0},
-       160:  {region: 0xc3, script: 0x57, flags: 0x0},
-       161:  {region: 0x165, script: 0x57, flags: 0x0},
-       162:  {region: 0x165, script: 0x57, flags: 0x0},
-       163:  {region: 0xc3, script: 0x57, flags: 0x0},
-       164:  {region: 0x165, script: 0x57, flags: 0x0},
+       129:  {region: 0x12b, script: 0x34, flags: 0x0},
+       131:  {region: 0x99, script: 0x22, flags: 0x0},
+       132:  {region: 0x165, script: 0x5a, flags: 0x0},
+       133:  {region: 0x99, script: 0x22, flags: 0x0},
+       134:  {region: 0xe7, script: 0x5a, flags: 0x0},
+       135:  {region: 0x165, script: 0x5a, flags: 0x0},
+       136:  {region: 0x99, script: 0x22, flags: 0x0},
+       137:  {region: 0x165, script: 0x5a, flags: 0x0},
+       138:  {region: 0x13f, script: 0x5a, flags: 0x0},
+       139:  {region: 0x165, script: 0x5a, flags: 0x0},
+       140:  {region: 0x165, script: 0x5a, flags: 0x0},
+       141:  {region: 0xe7, script: 0x5a, flags: 0x0},
+       142:  {region: 0x165, script: 0x5a, flags: 0x0},
+       143:  {region: 0xd6, script: 0x5a, flags: 0x0},
+       144:  {region: 0x165, script: 0x5a, flags: 0x0},
+       145:  {region: 0x165, script: 0x5a, flags: 0x0},
+       146:  {region: 0x165, script: 0x5a, flags: 0x0},
+       147:  {region: 0x165, script: 0x2c, flags: 0x0},
+       148:  {region: 0x99, script: 0x22, flags: 0x0},
+       149:  {region: 0x95, script: 0x5a, flags: 0x0},
+       150:  {region: 0x165, script: 0x5a, flags: 0x0},
+       151:  {region: 0x165, script: 0x5a, flags: 0x0},
+       152:  {region: 0x114, script: 0x5a, flags: 0x0},
+       153:  {region: 0x165, script: 0x5a, flags: 0x0},
+       154:  {region: 0x165, script: 0x5a, flags: 0x0},
+       155:  {region: 0x52, script: 0x5a, flags: 0x0},
+       156:  {region: 0x165, script: 0x5a, flags: 0x0},
+       157:  {region: 0xe7, script: 0x5a, flags: 0x0},
+       158:  {region: 0x165, script: 0x5a, flags: 0x0},
+       159:  {region: 0x13e, script: 0xe0, flags: 0x0},
+       160:  {region: 0xc3, script: 0x5a, flags: 0x0},
+       161:  {region: 0x165, script: 0x5a, flags: 0x0},
+       162:  {region: 0x165, script: 0x5a, flags: 0x0},
+       163:  {region: 0xc3, script: 0x5a, flags: 0x0},
+       164:  {region: 0x165, script: 0x5a, flags: 0x0},
        165:  {region: 0x35, script: 0xe, flags: 0x0},
-       166:  {region: 0x165, script: 0x57, flags: 0x0},
-       167:  {region: 0x165, script: 0x57, flags: 0x0},
-       168:  {region: 0x165, script: 0x57, flags: 0x0},
-       169:  {region: 0x53, script: 0xe0, flags: 0x0},
-       170:  {region: 0x165, script: 0x57, flags: 0x0},
-       171:  {region: 0x165, script: 0x57, flags: 0x0},
-       172:  {region: 0x165, script: 0x57, flags: 0x0},
+       166:  {region: 0x165, script: 0x5a, flags: 0x0},
+       167:  {region: 0x165, script: 0x5a, flags: 0x0},
+       168:  {region: 0x165, script: 0x5a, flags: 0x0},
+       169:  {region: 0x53, script: 0xe7, flags: 0x0},
+       170:  {region: 0x165, script: 0x5a, flags: 0x0},
+       171:  {region: 0x165, script: 0x5a, flags: 0x0},
+       172:  {region: 0x165, script: 0x5a, flags: 0x0},
        173:  {region: 0x99, script: 0xe, flags: 0x0},
-       174:  {region: 0x165, script: 0x57, flags: 0x0},
+       174:  {region: 0x165, script: 0x5a, flags: 0x0},
        175:  {region: 0x9c, script: 0x5, flags: 0x0},
-       176:  {region: 0x165, script: 0x57, flags: 0x0},
-       177:  {region: 0x4f, script: 0x57, flags: 0x0},
-       178:  {region: 0x78, script: 0x57, flags: 0x0},
-       179:  {region: 0x99, script: 0x21, flags: 0x0},
+       176:  {region: 0x165, script: 0x5a, flags: 0x0},
+       177:  {region: 0x4f, script: 0x5a, flags: 0x0},
+       178:  {region: 0x78, script: 0x5a, flags: 0x0},
+       179:  {region: 0x99, script: 0x22, flags: 0x0},
        180:  {region: 0xe8, script: 0x5, flags: 0x0},
-       181:  {region: 0x99, script: 0x21, flags: 0x0},
-       182:  {region: 0x165, script: 0x57, flags: 0x0},
-       183:  {region: 0x33, script: 0x57, flags: 0x0},
-       184:  {region: 0x165, script: 0x57, flags: 0x0},
+       181:  {region: 0x99, script: 0x22, flags: 0x0},
+       182:  {region: 0x165, script: 0x5a, flags: 0x0},
+       183:  {region: 0x33, script: 0x5a, flags: 0x0},
+       184:  {region: 0x165, script: 0x5a, flags: 0x0},
        185:  {region: 0xb4, script: 0xc, flags: 0x0},
-       186:  {region: 0x52, script: 0x57, flags: 0x0},
-       187:  {region: 0x165, script: 0x29, flags: 0x0},
-       188:  {region: 0xe7, script: 0x57, flags: 0x0},
-       189:  {region: 0x165, script: 0x57, flags: 0x0},
-       190:  {region: 0xe8, script: 0x21, flags: 0x0},
-       191:  {region: 0x106, script: 0x1f, flags: 0x0},
-       192:  {region: 0x15f, script: 0x57, flags: 0x0},
-       193:  {region: 0x165, script: 0x57, flags: 0x0},
-       194:  {region: 0x95, script: 0x57, flags: 0x0},
-       195:  {region: 0x165, script: 0x57, flags: 0x0},
-       196:  {region: 0x52, script: 0x57, flags: 0x0},
-       197:  {region: 0x165, script: 0x57, flags: 0x0},
-       198:  {region: 0x165, script: 0x57, flags: 0x0},
-       199:  {region: 0x165, script: 0x57, flags: 0x0},
-       200:  {region: 0x86, script: 0x57, flags: 0x0},
-       201:  {region: 0x165, script: 0x57, flags: 0x0},
-       202:  {region: 0x165, script: 0x57, flags: 0x0},
-       203:  {region: 0x165, script: 0x57, flags: 0x0},
-       204:  {region: 0x165, script: 0x57, flags: 0x0},
-       205:  {region: 0x6d, script: 0x29, flags: 0x0},
-       206:  {region: 0x165, script: 0x57, flags: 0x0},
-       207:  {region: 0x165, script: 0x57, flags: 0x0},
-       208:  {region: 0x52, script: 0x57, flags: 0x0},
-       209:  {region: 0x165, script: 0x57, flags: 0x0},
-       210:  {region: 0x165, script: 0x57, flags: 0x0},
-       211:  {region: 0xc3, script: 0x57, flags: 0x0},
-       212:  {region: 0x165, script: 0x57, flags: 0x0},
-       213:  {region: 0x165, script: 0x57, flags: 0x0},
-       214:  {region: 0x165, script: 0x57, flags: 0x0},
-       215:  {region: 0x6e, script: 0x57, flags: 0x0},
-       216:  {region: 0x165, script: 0x57, flags: 0x0},
-       217:  {region: 0x165, script: 0x57, flags: 0x0},
-       218:  {region: 0xd6, script: 0x57, flags: 0x0},
+       186:  {region: 0x52, script: 0x5a, flags: 0x0},
+       187:  {region: 0x165, script: 0x2c, flags: 0x0},
+       188:  {region: 0xe7, script: 0x5a, flags: 0x0},
+       189:  {region: 0x165, script: 0x5a, flags: 0x0},
+       190:  {region: 0xe8, script: 0x22, flags: 0x0},
+       191:  {region: 0x106, script: 0x20, flags: 0x0},
+       192:  {region: 0x15f, script: 0x5a, flags: 0x0},
+       193:  {region: 0x165, script: 0x5a, flags: 0x0},
+       194:  {region: 0x95, script: 0x5a, flags: 0x0},
+       195:  {region: 0x165, script: 0x5a, flags: 0x0},
+       196:  {region: 0x52, script: 0x5a, flags: 0x0},
+       197:  {region: 0x165, script: 0x5a, flags: 0x0},
+       198:  {region: 0x165, script: 0x5a, flags: 0x0},
+       199:  {region: 0x165, script: 0x5a, flags: 0x0},
+       200:  {region: 0x86, script: 0x5a, flags: 0x0},
+       201:  {region: 0x165, script: 0x5a, flags: 0x0},
+       202:  {region: 0x165, script: 0x5a, flags: 0x0},
+       203:  {region: 0x165, script: 0x5a, flags: 0x0},
+       204:  {region: 0x165, script: 0x5a, flags: 0x0},
+       205:  {region: 0x6d, script: 0x2c, flags: 0x0},
+       206:  {region: 0x165, script: 0x5a, flags: 0x0},
+       207:  {region: 0x165, script: 0x5a, flags: 0x0},
+       208:  {region: 0x52, script: 0x5a, flags: 0x0},
+       209:  {region: 0x165, script: 0x5a, flags: 0x0},
+       210:  {region: 0x165, script: 0x5a, flags: 0x0},
+       211:  {region: 0xc3, script: 0x5a, flags: 0x0},
+       212:  {region: 0x165, script: 0x5a, flags: 0x0},
+       213:  {region: 0x165, script: 0x5a, flags: 0x0},
+       214:  {region: 0x165, script: 0x5a, flags: 0x0},
+       215:  {region: 0x6e, script: 0x5a, flags: 0x0},
+       216:  {region: 0x165, script: 0x5a, flags: 0x0},
+       217:  {region: 0x165, script: 0x5a, flags: 0x0},
+       218:  {region: 0xd6, script: 0x5a, flags: 0x0},
        219:  {region: 0x35, script: 0x16, flags: 0x0},
-       220:  {region: 0x106, script: 0x1f, flags: 0x0},
-       221:  {region: 0xe7, script: 0x57, flags: 0x0},
-       222:  {region: 0x165, script: 0x57, flags: 0x0},
-       223:  {region: 0x131, script: 0x57, flags: 0x0},
-       224:  {region: 0x8a, script: 0x57, flags: 0x0},
-       225:  {region: 0x75, script: 0x57, flags: 0x0},
-       226:  {region: 0x106, script: 0x1f, flags: 0x0},
-       227:  {region: 0x135, script: 0x57, flags: 0x0},
-       228:  {region: 0x49, script: 0x57, flags: 0x0},
+       220:  {region: 0x106, script: 0x20, flags: 0x0},
+       221:  {region: 0xe7, script: 0x5a, flags: 0x0},
+       222:  {region: 0x165, script: 0x5a, flags: 0x0},
+       223:  {region: 0x131, script: 0x5a, flags: 0x0},
+       224:  {region: 0x8a, script: 0x5a, flags: 0x0},
+       225:  {region: 0x75, script: 0x5a, flags: 0x0},
+       226:  {region: 0x106, script: 0x20, flags: 0x0},
+       227:  {region: 0x135, script: 0x5a, flags: 0x0},
+       228:  {region: 0x49, script: 0x5a, flags: 0x0},
        229:  {region: 0x135, script: 0x1a, flags: 0x0},
        230:  {region: 0xa6, script: 0x5, flags: 0x0},
        231:  {region: 0x13e, script: 0x19, flags: 0x0},
-       232:  {region: 0x165, script: 0x57, flags: 0x0},
+       232:  {region: 0x165, script: 0x5a, flags: 0x0},
        233:  {region: 0x9b, script: 0x5, flags: 0x0},
-       234:  {region: 0x165, script: 0x57, flags: 0x0},
-       235:  {region: 0x165, script: 0x57, flags: 0x0},
-       236:  {region: 0x165, script: 0x57, flags: 0x0},
-       237:  {region: 0x165, script: 0x57, flags: 0x0},
-       238:  {region: 0x165, script: 0x57, flags: 0x0},
-       239:  {region: 0xc5, script: 0xcc, flags: 0x0},
-       240:  {region: 0x78, script: 0x57, flags: 0x0},
-       241:  {region: 0x6b, script: 0x1c, flags: 0x0},
-       242:  {region: 0xe7, script: 0x57, flags: 0x0},
+       234:  {region: 0x165, script: 0x5a, flags: 0x0},
+       235:  {region: 0x165, script: 0x5a, flags: 0x0},
+       236:  {region: 0x165, script: 0x5a, flags: 0x0},
+       237:  {region: 0x165, script: 0x5a, flags: 0x0},
+       238:  {region: 0x165, script: 0x5a, flags: 0x0},
+       239:  {region: 0xc5, script: 0xd3, flags: 0x0},
+       240:  {region: 0x78, script: 0x5a, flags: 0x0},
+       241:  {region: 0x6b, script: 0x1d, flags: 0x0},
+       242:  {region: 0xe7, script: 0x5a, flags: 0x0},
        243:  {region: 0x49, script: 0x17, flags: 0x0},
-       244:  {region: 0x130, script: 0x1f, flags: 0x0},
+       244:  {region: 0x130, script: 0x20, flags: 0x0},
        245:  {region: 0x49, script: 0x17, flags: 0x0},
        246:  {region: 0x49, script: 0x17, flags: 0x0},
        247:  {region: 0x49, script: 0x17, flags: 0x0},
        248:  {region: 0x49, script: 0x17, flags: 0x0},
-       249:  {region: 0x10a, script: 0x57, flags: 0x0},
-       250:  {region: 0x5e, script: 0x57, flags: 0x0},
-       251:  {region: 0xe9, script: 0x57, flags: 0x0},
+       249:  {region: 0x10a, script: 0x5a, flags: 0x0},
+       250:  {region: 0x5e, script: 0x5a, flags: 0x0},
+       251:  {region: 0xe9, script: 0x5a, flags: 0x0},
        252:  {region: 0x49, script: 0x17, flags: 0x0},
-       253:  {region: 0xc4, script: 0x81, flags: 0x0},
+       253:  {region: 0xc4, script: 0x85, flags: 0x0},
        254:  {region: 0x8, script: 0x2, flags: 0x1},
-       255:  {region: 0x106, script: 0x1f, flags: 0x0},
-       256:  {region: 0x7b, script: 0x57, flags: 0x0},
-       257:  {region: 0x63, script: 0x57, flags: 0x0},
-       258:  {region: 0x165, script: 0x57, flags: 0x0},
-       259:  {region: 0x165, script: 0x57, flags: 0x0},
-       260:  {region: 0x165, script: 0x57, flags: 0x0},
-       261:  {region: 0x165, script: 0x57, flags: 0x0},
-       262:  {region: 0x135, script: 0x57, flags: 0x0},
-       263:  {region: 0x106, script: 0x1f, flags: 0x0},
-       264:  {region: 0xa4, script: 0x57, flags: 0x0},
-       265:  {region: 0x165, script: 0x57, flags: 0x0},
-       266:  {region: 0x165, script: 0x57, flags: 0x0},
+       255:  {region: 0x106, script: 0x20, flags: 0x0},
+       256:  {region: 0x7b, script: 0x5a, flags: 0x0},
+       257:  {region: 0x63, script: 0x5a, flags: 0x0},
+       258:  {region: 0x165, script: 0x5a, flags: 0x0},
+       259:  {region: 0x165, script: 0x5a, flags: 0x0},
+       260:  {region: 0x165, script: 0x5a, flags: 0x0},
+       261:  {region: 0x165, script: 0x5a, flags: 0x0},
+       262:  {region: 0x135, script: 0x5a, flags: 0x0},
+       263:  {region: 0x106, script: 0x20, flags: 0x0},
+       264:  {region: 0xa4, script: 0x5a, flags: 0x0},
+       265:  {region: 0x165, script: 0x5a, flags: 0x0},
+       266:  {region: 0x165, script: 0x5a, flags: 0x0},
        267:  {region: 0x99, script: 0x5, flags: 0x0},
-       268:  {region: 0x165, script: 0x57, flags: 0x0},
-       269:  {region: 0x60, script: 0x57, flags: 0x0},
-       270:  {region: 0x165, script: 0x57, flags: 0x0},
-       271:  {region: 0x49, script: 0x57, flags: 0x0},
-       272:  {region: 0x165, script: 0x57, flags: 0x0},
-       273:  {region: 0x165, script: 0x57, flags: 0x0},
-       274:  {region: 0x165, script: 0x57, flags: 0x0},
+       268:  {region: 0x165, script: 0x5a, flags: 0x0},
+       269:  {region: 0x60, script: 0x5a, flags: 0x0},
+       270:  {region: 0x165, script: 0x5a, flags: 0x0},
+       271:  {region: 0x49, script: 0x5a, flags: 0x0},
+       272:  {region: 0x165, script: 0x5a, flags: 0x0},
+       273:  {region: 0x165, script: 0x5a, flags: 0x0},
+       274:  {region: 0x165, script: 0x5a, flags: 0x0},
        275:  {region: 0x165, script: 0x5, flags: 0x0},
-       276:  {region: 0x49, script: 0x57, flags: 0x0},
-       277:  {region: 0x165, script: 0x57, flags: 0x0},
-       278:  {region: 0x165, script: 0x57, flags: 0x0},
-       279:  {region: 0xd4, script: 0x57, flags: 0x0},
-       280:  {region: 0x4f, script: 0x57, flags: 0x0},
-       281:  {region: 0x165, script: 0x57, flags: 0x0},
+       276:  {region: 0x49, script: 0x5a, flags: 0x0},
+       277:  {region: 0x165, script: 0x5a, flags: 0x0},
+       278:  {region: 0x165, script: 0x5a, flags: 0x0},
+       279:  {region: 0xd4, script: 0x5a, flags: 0x0},
+       280:  {region: 0x4f, script: 0x5a, flags: 0x0},
+       281:  {region: 0x165, script: 0x5a, flags: 0x0},
        282:  {region: 0x99, script: 0x5, flags: 0x0},
-       283:  {region: 0x165, script: 0x57, flags: 0x0},
-       284:  {region: 0x165, script: 0x57, flags: 0x0},
-       285:  {region: 0x165, script: 0x57, flags: 0x0},
-       286:  {region: 0x165, script: 0x29, flags: 0x0},
-       287:  {region: 0x60, script: 0x57, flags: 0x0},
-       288:  {region: 0xc3, script: 0x57, flags: 0x0},
-       289:  {region: 0xd0, script: 0x57, flags: 0x0},
-       290:  {region: 0x165, script: 0x57, flags: 0x0},
-       291:  {region: 0xdb, script: 0x21, flags: 0x0},
-       292:  {region: 0x52, script: 0x57, flags: 0x0},
-       293:  {region: 0x165, script: 0x57, flags: 0x0},
-       294:  {region: 0x165, script: 0x57, flags: 0x0},
-       295:  {region: 0x165, script: 0x57, flags: 0x0},
-       296:  {region: 0xcd, script: 0xde, flags: 0x0},
-       297:  {region: 0x165, script: 0x57, flags: 0x0},
-       298:  {region: 0x165, script: 0x57, flags: 0x0},
-       299:  {region: 0x114, script: 0x57, flags: 0x0},
-       300:  {region: 0x37, script: 0x57, flags: 0x0},
-       301:  {region: 0x43, script: 0xe0, flags: 0x0},
-       302:  {region: 0x165, script: 0x57, flags: 0x0},
-       303:  {region: 0xa4, script: 0x57, flags: 0x0},
-       304:  {region: 0x80, script: 0x57, flags: 0x0},
-       305:  {region: 0xd6, script: 0x57, flags: 0x0},
-       306:  {region: 0x9e, script: 0x57, flags: 0x0},
-       307:  {region: 0x6b, script: 0x27, flags: 0x0},
-       308:  {region: 0x165, script: 0x57, flags: 0x0},
-       309:  {region: 0xc4, script: 0x48, flags: 0x0},
-       310:  {region: 0x87, script: 0x31, flags: 0x0},
-       311:  {region: 0x165, script: 0x57, flags: 0x0},
-       312:  {region: 0x165, script: 0x57, flags: 0x0},
+       283:  {region: 0x165, script: 0x5a, flags: 0x0},
+       284:  {region: 0x165, script: 0x5a, flags: 0x0},
+       285:  {region: 0x165, script: 0x5a, flags: 0x0},
+       286:  {region: 0x165, script: 0x2c, flags: 0x0},
+       287:  {region: 0x60, script: 0x5a, flags: 0x0},
+       288:  {region: 0xc3, script: 0x5a, flags: 0x0},
+       289:  {region: 0xd0, script: 0x5a, flags: 0x0},
+       290:  {region: 0x165, script: 0x5a, flags: 0x0},
+       291:  {region: 0xdb, script: 0x22, flags: 0x0},
+       292:  {region: 0x52, script: 0x5a, flags: 0x0},
+       293:  {region: 0x165, script: 0x5a, flags: 0x0},
+       294:  {region: 0x165, script: 0x5a, flags: 0x0},
+       295:  {region: 0x165, script: 0x5a, flags: 0x0},
+       296:  {region: 0xcd, script: 0xe5, flags: 0x0},
+       297:  {region: 0x165, script: 0x5a, flags: 0x0},
+       298:  {region: 0x165, script: 0x5a, flags: 0x0},
+       299:  {region: 0x114, script: 0x5a, flags: 0x0},
+       300:  {region: 0x37, script: 0x5a, flags: 0x0},
+       301:  {region: 0x43, script: 0xe7, flags: 0x0},
+       302:  {region: 0x165, script: 0x5a, flags: 0x0},
+       303:  {region: 0xa4, script: 0x5a, flags: 0x0},
+       304:  {region: 0x80, script: 0x5a, flags: 0x0},
+       305:  {region: 0xd6, script: 0x5a, flags: 0x0},
+       306:  {region: 0x9e, script: 0x5a, flags: 0x0},
+       307:  {region: 0x6b, script: 0x29, flags: 0x0},
+       308:  {region: 0x165, script: 0x5a, flags: 0x0},
+       309:  {region: 0xc4, script: 0x4b, flags: 0x0},
+       310:  {region: 0x87, script: 0x34, flags: 0x0},
+       311:  {region: 0x165, script: 0x5a, flags: 0x0},
+       312:  {region: 0x165, script: 0x5a, flags: 0x0},
        313:  {region: 0xa, script: 0x2, flags: 0x1},
-       314:  {region: 0x165, script: 0x57, flags: 0x0},
-       315:  {region: 0x165, script: 0x57, flags: 0x0},
-       316:  {region: 0x1, script: 0x57, flags: 0x0},
-       317:  {region: 0x165, script: 0x57, flags: 0x0},
-       318:  {region: 0x6e, script: 0x57, flags: 0x0},
-       319:  {region: 0x135, script: 0x57, flags: 0x0},
-       320:  {region: 0x6a, script: 0x57, flags: 0x0},
-       321:  {region: 0x165, script: 0x57, flags: 0x0},
-       322:  {region: 0x9e, script: 0x43, flags: 0x0},
-       323:  {region: 0x165, script: 0x57, flags: 0x0},
-       324:  {region: 0x165, script: 0x57, flags: 0x0},
-       325:  {region: 0x6e, script: 0x57, flags: 0x0},
-       326:  {region: 0x52, script: 0x57, flags: 0x0},
-       327:  {region: 0x6e, script: 0x57, flags: 0x0},
+       314:  {region: 0x165, script: 0x5a, flags: 0x0},
+       315:  {region: 0x165, script: 0x5a, flags: 0x0},
+       316:  {region: 0x1, script: 0x5a, flags: 0x0},
+       317:  {region: 0x165, script: 0x5a, flags: 0x0},
+       318:  {region: 0x6e, script: 0x5a, flags: 0x0},
+       319:  {region: 0x135, script: 0x5a, flags: 0x0},
+       320:  {region: 0x6a, script: 0x5a, flags: 0x0},
+       321:  {region: 0x165, script: 0x5a, flags: 0x0},
+       322:  {region: 0x9e, script: 0x46, flags: 0x0},
+       323:  {region: 0x165, script: 0x5a, flags: 0x0},
+       324:  {region: 0x165, script: 0x5a, flags: 0x0},
+       325:  {region: 0x6e, script: 0x5a, flags: 0x0},
+       326:  {region: 0x52, script: 0x5a, flags: 0x0},
+       327:  {region: 0x6e, script: 0x5a, flags: 0x0},
        328:  {region: 0x9c, script: 0x5, flags: 0x0},
-       329:  {region: 0x165, script: 0x57, flags: 0x0},
-       330:  {region: 0x165, script: 0x57, flags: 0x0},
-       331:  {region: 0x165, script: 0x57, flags: 0x0},
-       332:  {region: 0x165, script: 0x57, flags: 0x0},
-       333:  {region: 0x86, script: 0x57, flags: 0x0},
+       329:  {region: 0x165, script: 0x5a, flags: 0x0},
+       330:  {region: 0x165, script: 0x5a, flags: 0x0},
+       331:  {region: 0x165, script: 0x5a, flags: 0x0},
+       332:  {region: 0x165, script: 0x5a, flags: 0x0},
+       333:  {region: 0x86, script: 0x5a, flags: 0x0},
        334:  {region: 0xc, script: 0x2, flags: 0x1},
-       335:  {region: 0x165, script: 0x57, flags: 0x0},
-       336:  {region: 0xc3, script: 0x57, flags: 0x0},
-       337:  {region: 0x72, script: 0x57, flags: 0x0},
+       335:  {region: 0x165, script: 0x5a, flags: 0x0},
+       336:  {region: 0xc3, script: 0x5a, flags: 0x0},
+       337:  {region: 0x72, script: 0x5a, flags: 0x0},
        338:  {region: 0x10b, script: 0x5, flags: 0x0},
-       339:  {region: 0xe7, script: 0x57, flags: 0x0},
-       340:  {region: 0x10c, script: 0x57, flags: 0x0},
-       341:  {region: 0x73, script: 0x57, flags: 0x0},
-       342:  {region: 0x165, script: 0x57, flags: 0x0},
-       343:  {region: 0x165, script: 0x57, flags: 0x0},
-       344:  {region: 0x76, script: 0x57, flags: 0x0},
-       345:  {region: 0x165, script: 0x57, flags: 0x0},
-       346:  {region: 0x3b, script: 0x57, flags: 0x0},
-       347:  {region: 0x165, script: 0x57, flags: 0x0},
-       348:  {region: 0x165, script: 0x57, flags: 0x0},
-       349:  {region: 0x165, script: 0x57, flags: 0x0},
-       350:  {region: 0x78, script: 0x57, flags: 0x0},
-       351:  {region: 0x135, script: 0x57, flags: 0x0},
-       352:  {region: 0x78, script: 0x57, flags: 0x0},
-       353:  {region: 0x60, script: 0x57, flags: 0x0},
-       354:  {region: 0x60, script: 0x57, flags: 0x0},
+       339:  {region: 0xe7, script: 0x5a, flags: 0x0},
+       340:  {region: 0x10c, script: 0x5a, flags: 0x0},
+       341:  {region: 0x73, script: 0x5a, flags: 0x0},
+       342:  {region: 0x165, script: 0x5a, flags: 0x0},
+       343:  {region: 0x165, script: 0x5a, flags: 0x0},
+       344:  {region: 0x76, script: 0x5a, flags: 0x0},
+       345:  {region: 0x165, script: 0x5a, flags: 0x0},
+       346:  {region: 0x3b, script: 0x5a, flags: 0x0},
+       347:  {region: 0x165, script: 0x5a, flags: 0x0},
+       348:  {region: 0x165, script: 0x5a, flags: 0x0},
+       349:  {region: 0x165, script: 0x5a, flags: 0x0},
+       350:  {region: 0x78, script: 0x5a, flags: 0x0},
+       351:  {region: 0x135, script: 0x5a, flags: 0x0},
+       352:  {region: 0x78, script: 0x5a, flags: 0x0},
+       353:  {region: 0x60, script: 0x5a, flags: 0x0},
+       354:  {region: 0x60, script: 0x5a, flags: 0x0},
        355:  {region: 0x52, script: 0x5, flags: 0x0},
-       356:  {region: 0x140, script: 0x57, flags: 0x0},
-       357:  {region: 0x165, script: 0x57, flags: 0x0},
-       358:  {region: 0x84, script: 0x57, flags: 0x0},
-       359:  {region: 0x165, script: 0x57, flags: 0x0},
-       360:  {region: 0xd4, script: 0x57, flags: 0x0},
-       361:  {region: 0x9e, script: 0x57, flags: 0x0},
-       362:  {region: 0xd6, script: 0x57, flags: 0x0},
-       363:  {region: 0x165, script: 0x57, flags: 0x0},
-       364:  {region: 0x10b, script: 0x57, flags: 0x0},
-       365:  {region: 0xd9, script: 0x57, flags: 0x0},
-       366:  {region: 0x96, script: 0x57, flags: 0x0},
-       367:  {region: 0x80, script: 0x57, flags: 0x0},
-       368:  {region: 0x165, script: 0x57, flags: 0x0},
-       369:  {region: 0xbc, script: 0x57, flags: 0x0},
-       370:  {region: 0x165, script: 0x57, flags: 0x0},
-       371:  {region: 0x165, script: 0x57, flags: 0x0},
-       372:  {region: 0x165, script: 0x57, flags: 0x0},
-       373:  {region: 0x53, script: 0x38, flags: 0x0},
-       374:  {region: 0x165, script: 0x57, flags: 0x0},
-       375:  {region: 0x95, script: 0x57, flags: 0x0},
-       376:  {region: 0x165, script: 0x57, flags: 0x0},
-       377:  {region: 0x165, script: 0x57, flags: 0x0},
-       378:  {region: 0x99, script: 0x21, flags: 0x0},
-       379:  {region: 0x165, script: 0x57, flags: 0x0},
+       356:  {region: 0x140, script: 0x5a, flags: 0x0},
+       357:  {region: 0x165, script: 0x5a, flags: 0x0},
+       358:  {region: 0x84, script: 0x5a, flags: 0x0},
+       359:  {region: 0x165, script: 0x5a, flags: 0x0},
+       360:  {region: 0xd4, script: 0x5a, flags: 0x0},
+       361:  {region: 0x9e, script: 0x5a, flags: 0x0},
+       362:  {region: 0xd6, script: 0x5a, flags: 0x0},
+       363:  {region: 0x165, script: 0x5a, flags: 0x0},
+       364:  {region: 0x10b, script: 0x5a, flags: 0x0},
+       365:  {region: 0xd9, script: 0x5a, flags: 0x0},
+       366:  {region: 0x96, script: 0x5a, flags: 0x0},
+       367:  {region: 0x80, script: 0x5a, flags: 0x0},
+       368:  {region: 0x165, script: 0x5a, flags: 0x0},
+       369:  {region: 0xbc, script: 0x5a, flags: 0x0},
+       370:  {region: 0x165, script: 0x5a, flags: 0x0},
+       371:  {region: 0x165, script: 0x5a, flags: 0x0},
+       372:  {region: 0x165, script: 0x5a, flags: 0x0},
+       373:  {region: 0x53, script: 0x3b, flags: 0x0},
+       374:  {region: 0x165, script: 0x5a, flags: 0x0},
+       375:  {region: 0x95, script: 0x5a, flags: 0x0},
+       376:  {region: 0x165, script: 0x5a, flags: 0x0},
+       377:  {region: 0x165, script: 0x5a, flags: 0x0},
+       378:  {region: 0x99, script: 0x22, flags: 0x0},
+       379:  {region: 0x165, script: 0x5a, flags: 0x0},
        380:  {region: 0x9c, script: 0x5, flags: 0x0},
-       381:  {region: 0x7e, script: 0x57, flags: 0x0},
-       382:  {region: 0x7b, script: 0x57, flags: 0x0},
-       383:  {region: 0x165, script: 0x57, flags: 0x0},
-       384:  {region: 0x165, script: 0x57, flags: 0x0},
-       385:  {region: 0x165, script: 0x57, flags: 0x0},
-       386:  {region: 0x165, script: 0x57, flags: 0x0},
-       387:  {region: 0x165, script: 0x57, flags: 0x0},
-       388:  {region: 0x165, script: 0x57, flags: 0x0},
-       389:  {region: 0x6f, script: 0x29, flags: 0x0},
-       390:  {region: 0x165, script: 0x57, flags: 0x0},
-       391:  {region: 0xdb, script: 0x21, flags: 0x0},
-       392:  {region: 0x165, script: 0x57, flags: 0x0},
-       393:  {region: 0xa7, script: 0x57, flags: 0x0},
-       394:  {region: 0x165, script: 0x57, flags: 0x0},
+       381:  {region: 0x7e, script: 0x5a, flags: 0x0},
+       382:  {region: 0x7b, script: 0x5a, flags: 0x0},
+       383:  {region: 0x165, script: 0x5a, flags: 0x0},
+       384:  {region: 0x165, script: 0x5a, flags: 0x0},
+       385:  {region: 0x165, script: 0x5a, flags: 0x0},
+       386:  {region: 0x165, script: 0x5a, flags: 0x0},
+       387:  {region: 0x165, script: 0x5a, flags: 0x0},
+       388:  {region: 0x165, script: 0x5a, flags: 0x0},
+       389:  {region: 0x6f, script: 0x2c, flags: 0x0},
+       390:  {region: 0x165, script: 0x5a, flags: 0x0},
+       391:  {region: 0xdb, script: 0x22, flags: 0x0},
+       392:  {region: 0x165, script: 0x5a, flags: 0x0},
+       393:  {region: 0xa7, script: 0x5a, flags: 0x0},
+       394:  {region: 0x165, script: 0x5a, flags: 0x0},
        395:  {region: 0xe8, script: 0x5, flags: 0x0},
-       396:  {region: 0x165, script: 0x57, flags: 0x0},
+       396:  {region: 0x165, script: 0x5a, flags: 0x0},
        397:  {region: 0xe8, script: 0x5, flags: 0x0},
-       398:  {region: 0x165, script: 0x57, flags: 0x0},
-       399:  {region: 0x165, script: 0x57, flags: 0x0},
-       400:  {region: 0x6e, script: 0x57, flags: 0x0},
+       398:  {region: 0x165, script: 0x5a, flags: 0x0},
+       399:  {region: 0x165, script: 0x5a, flags: 0x0},
+       400:  {region: 0x6e, script: 0x5a, flags: 0x0},
        401:  {region: 0x9c, script: 0x5, flags: 0x0},
-       402:  {region: 0x165, script: 0x57, flags: 0x0},
-       403:  {region: 0x165, script: 0x29, flags: 0x0},
-       404:  {region: 0xf1, script: 0x57, flags: 0x0},
-       405:  {region: 0x165, script: 0x57, flags: 0x0},
-       406:  {region: 0x165, script: 0x57, flags: 0x0},
-       407:  {region: 0x165, script: 0x57, flags: 0x0},
-       408:  {region: 0x165, script: 0x29, flags: 0x0},
-       409:  {region: 0x165, script: 0x57, flags: 0x0},
-       410:  {region: 0x99, script: 0x21, flags: 0x0},
-       411:  {region: 0x99, script: 0xda, flags: 0x0},
-       412:  {region: 0x95, script: 0x57, flags: 0x0},
-       413:  {region: 0xd9, script: 0x57, flags: 0x0},
-       414:  {region: 0x130, script: 0x2f, flags: 0x0},
-       415:  {region: 0x165, script: 0x57, flags: 0x0},
+       402:  {region: 0x165, script: 0x5a, flags: 0x0},
+       403:  {region: 0x165, script: 0x2c, flags: 0x0},
+       404:  {region: 0xf1, script: 0x5a, flags: 0x0},
+       405:  {region: 0x165, script: 0x5a, flags: 0x0},
+       406:  {region: 0x165, script: 0x5a, flags: 0x0},
+       407:  {region: 0x165, script: 0x5a, flags: 0x0},
+       408:  {region: 0x165, script: 0x2c, flags: 0x0},
+       409:  {region: 0x165, script: 0x5a, flags: 0x0},
+       410:  {region: 0x99, script: 0x22, flags: 0x0},
+       411:  {region: 0x99, script: 0xe1, flags: 0x0},
+       412:  {region: 0x95, script: 0x5a, flags: 0x0},
+       413:  {region: 0xd9, script: 0x5a, flags: 0x0},
+       414:  {region: 0x130, script: 0x32, flags: 0x0},
+       415:  {region: 0x165, script: 0x5a, flags: 0x0},
        416:  {region: 0xe, script: 0x2, flags: 0x1},
        417:  {region: 0x99, script: 0xe, flags: 0x0},
-       418:  {region: 0x165, script: 0x57, flags: 0x0},
-       419:  {region: 0x4e, script: 0x57, flags: 0x0},
-       420:  {region: 0x99, script: 0x32, flags: 0x0},
-       421:  {region: 0x41, script: 0x57, flags: 0x0},
-       422:  {region: 0x54, script: 0x57, flags: 0x0},
-       423:  {region: 0x165, script: 0x57, flags: 0x0},
-       424:  {region: 0x80, script: 0x57, flags: 0x0},
-       425:  {region: 0x165, script: 0x57, flags: 0x0},
-       426:  {region: 0x165, script: 0x57, flags: 0x0},
-       427:  {region: 0xa4, script: 0x57, flags: 0x0},
-       428:  {region: 0x98, script: 0x57, flags: 0x0},
-       429:  {region: 0x165, script: 0x57, flags: 0x0},
-       430:  {region: 0xdb, script: 0x21, flags: 0x0},
-       431:  {region: 0x165, script: 0x57, flags: 0x0},
+       418:  {region: 0x165, script: 0x5a, flags: 0x0},
+       419:  {region: 0x4e, script: 0x5a, flags: 0x0},
+       420:  {region: 0x99, script: 0x35, flags: 0x0},
+       421:  {region: 0x41, script: 0x5a, flags: 0x0},
+       422:  {region: 0x54, script: 0x5a, flags: 0x0},
+       423:  {region: 0x165, script: 0x5a, flags: 0x0},
+       424:  {region: 0x80, script: 0x5a, flags: 0x0},
+       425:  {region: 0x165, script: 0x5a, flags: 0x0},
+       426:  {region: 0x165, script: 0x5a, flags: 0x0},
+       427:  {region: 0xa4, script: 0x5a, flags: 0x0},
+       428:  {region: 0x98, script: 0x5a, flags: 0x0},
+       429:  {region: 0x165, script: 0x5a, flags: 0x0},
+       430:  {region: 0xdb, script: 0x22, flags: 0x0},
+       431:  {region: 0x165, script: 0x5a, flags: 0x0},
        432:  {region: 0x165, script: 0x5, flags: 0x0},
-       433:  {region: 0x49, script: 0x57, flags: 0x0},
+       433:  {region: 0x49, script: 0x5a, flags: 0x0},
        434:  {region: 0x165, script: 0x5, flags: 0x0},
-       435:  {region: 0x165, script: 0x57, flags: 0x0},
+       435:  {region: 0x165, script: 0x5a, flags: 0x0},
        436:  {region: 0x10, script: 0x3, flags: 0x1},
-       437:  {region: 0x165, script: 0x57, flags: 0x0},
-       438:  {region: 0x53, script: 0x38, flags: 0x0},
-       439:  {region: 0x165, script: 0x57, flags: 0x0},
-       440:  {region: 0x135, script: 0x57, flags: 0x0},
+       437:  {region: 0x165, script: 0x5a, flags: 0x0},
+       438:  {region: 0x53, script: 0x3b, flags: 0x0},
+       439:  {region: 0x165, script: 0x5a, flags: 0x0},
+       440:  {region: 0x135, script: 0x5a, flags: 0x0},
        441:  {region: 0x24, script: 0x5, flags: 0x0},
-       442:  {region: 0x165, script: 0x57, flags: 0x0},
-       443:  {region: 0x165, script: 0x29, flags: 0x0},
-       444:  {region: 0x97, script: 0x3b, flags: 0x0},
-       445:  {region: 0x165, script: 0x57, flags: 0x0},
-       446:  {region: 0x99, script: 0x21, flags: 0x0},
-       447:  {region: 0x165, script: 0x57, flags: 0x0},
-       448:  {region: 0x73, script: 0x57, flags: 0x0},
-       449:  {region: 0x165, script: 0x57, flags: 0x0},
-       450:  {region: 0x165, script: 0x57, flags: 0x0},
-       451:  {region: 0xe7, script: 0x57, flags: 0x0},
-       452:  {region: 0x165, script: 0x57, flags: 0x0},
-       453:  {region: 0x12b, script: 0x3d, flags: 0x0},
-       454:  {region: 0x53, script: 0x89, flags: 0x0},
-       455:  {region: 0x165, script: 0x57, flags: 0x0},
+       442:  {region: 0x165, script: 0x5a, flags: 0x0},
+       443:  {region: 0x165, script: 0x2c, flags: 0x0},
+       444:  {region: 0x97, script: 0x3e, flags: 0x0},
+       445:  {region: 0x165, script: 0x5a, flags: 0x0},
+       446:  {region: 0x99, script: 0x22, flags: 0x0},
+       447:  {region: 0x165, script: 0x5a, flags: 0x0},
+       448:  {region: 0x73, script: 0x5a, flags: 0x0},
+       449:  {region: 0x165, script: 0x5a, flags: 0x0},
+       450:  {region: 0x165, script: 0x5a, flags: 0x0},
+       451:  {region: 0xe7, script: 0x5a, flags: 0x0},
+       452:  {region: 0x165, script: 0x5a, flags: 0x0},
+       453:  {region: 0x12b, script: 0x40, flags: 0x0},
+       454:  {region: 0x53, script: 0x8d, flags: 0x0},
+       455:  {region: 0x165, script: 0x5a, flags: 0x0},
        456:  {region: 0xe8, script: 0x5, flags: 0x0},
-       457:  {region: 0x99, script: 0x21, flags: 0x0},
-       458:  {region: 0xaf, script: 0x3e, flags: 0x0},
-       459:  {region: 0xe7, script: 0x57, flags: 0x0},
+       457:  {region: 0x99, script: 0x22, flags: 0x0},
+       458:  {region: 0xaf, script: 0x41, flags: 0x0},
+       459:  {region: 0xe7, script: 0x5a, flags: 0x0},
        460:  {region: 0xe8, script: 0x5, flags: 0x0},
-       461:  {region: 0xe6, script: 0x57, flags: 0x0},
-       462:  {region: 0x99, script: 0x21, flags: 0x0},
-       463:  {region: 0x99, script: 0x21, flags: 0x0},
-       464:  {region: 0x165, script: 0x57, flags: 0x0},
-       465:  {region: 0x90, script: 0x57, flags: 0x0},
-       466:  {region: 0x60, script: 0x57, flags: 0x0},
-       467:  {region: 0x53, script: 0x38, flags: 0x0},
-       468:  {region: 0x91, script: 0x57, flags: 0x0},
-       469:  {region: 0x92, script: 0x57, flags: 0x0},
-       470:  {region: 0x165, script: 0x57, flags: 0x0},
+       461:  {region: 0xe6, script: 0x5a, flags: 0x0},
+       462:  {region: 0x99, script: 0x22, flags: 0x0},
+       463:  {region: 0x99, script: 0x22, flags: 0x0},
+       464:  {region: 0x165, script: 0x5a, flags: 0x0},
+       465:  {region: 0x90, script: 0x5a, flags: 0x0},
+       466:  {region: 0x60, script: 0x5a, flags: 0x0},
+       467:  {region: 0x53, script: 0x3b, flags: 0x0},
+       468:  {region: 0x91, script: 0x5a, flags: 0x0},
+       469:  {region: 0x92, script: 0x5a, flags: 0x0},
+       470:  {region: 0x165, script: 0x5a, flags: 0x0},
        471:  {region: 0x28, script: 0x8, flags: 0x0},
-       472:  {region: 0xd2, script: 0x57, flags: 0x0},
-       473:  {region: 0x78, script: 0x57, flags: 0x0},
-       474:  {region: 0x165, script: 0x57, flags: 0x0},
-       475:  {region: 0x165, script: 0x57, flags: 0x0},
-       476:  {region: 0xd0, script: 0x57, flags: 0x0},
-       477:  {region: 0xd6, script: 0x57, flags: 0x0},
-       478:  {region: 0x165, script: 0x57, flags: 0x0},
-       479:  {region: 0x165, script: 0x57, flags: 0x0},
-       480:  {region: 0x165, script: 0x57, flags: 0x0},
-       481:  {region: 0x95, script: 0x57, flags: 0x0},
-       482:  {region: 0x165, script: 0x57, flags: 0x0},
-       483:  {region: 0x165, script: 0x57, flags: 0x0},
-       484:  {region: 0x165, script: 0x57, flags: 0x0},
-       486:  {region: 0x122, script: 0x57, flags: 0x0},
-       487:  {region: 0xd6, script: 0x57, flags: 0x0},
-       488:  {region: 0x165, script: 0x57, flags: 0x0},
-       489:  {region: 0x165, script: 0x57, flags: 0x0},
-       490:  {region: 0x53, script: 0xea, flags: 0x0},
-       491:  {region: 0x165, script: 0x57, flags: 0x0},
-       492:  {region: 0x135, script: 0x57, flags: 0x0},
-       493:  {region: 0x165, script: 0x57, flags: 0x0},
-       494:  {region: 0x49, script: 0x57, flags: 0x0},
-       495:  {region: 0x165, script: 0x57, flags: 0x0},
-       496:  {region: 0x165, script: 0x57, flags: 0x0},
-       497:  {region: 0xe7, script: 0x57, flags: 0x0},
-       498:  {region: 0x165, script: 0x57, flags: 0x0},
-       499:  {region: 0x95, script: 0x57, flags: 0x0},
-       500:  {region: 0x106, script: 0x1f, flags: 0x0},
-       501:  {region: 0x1, script: 0x57, flags: 0x0},
-       502:  {region: 0x165, script: 0x57, flags: 0x0},
-       503:  {region: 0x165, script: 0x57, flags: 0x0},
-       504:  {region: 0x9d, script: 0x57, flags: 0x0},
-       505:  {region: 0x9e, script: 0x57, flags: 0x0},
+       472:  {region: 0xd2, script: 0x5a, flags: 0x0},
+       473:  {region: 0x78, script: 0x5a, flags: 0x0},
+       474:  {region: 0x165, script: 0x5a, flags: 0x0},
+       475:  {region: 0x165, script: 0x5a, flags: 0x0},
+       476:  {region: 0xd0, script: 0x5a, flags: 0x0},
+       477:  {region: 0xd6, script: 0x5a, flags: 0x0},
+       478:  {region: 0x165, script: 0x5a, flags: 0x0},
+       479:  {region: 0x165, script: 0x5a, flags: 0x0},
+       480:  {region: 0x165, script: 0x5a, flags: 0x0},
+       481:  {region: 0x95, script: 0x5a, flags: 0x0},
+       482:  {region: 0x165, script: 0x5a, flags: 0x0},
+       483:  {region: 0x165, script: 0x5a, flags: 0x0},
+       484:  {region: 0x165, script: 0x5a, flags: 0x0},
+       486:  {region: 0x122, script: 0x5a, flags: 0x0},
+       487:  {region: 0xd6, script: 0x5a, flags: 0x0},
+       488:  {region: 0x165, script: 0x5a, flags: 0x0},
+       489:  {region: 0x165, script: 0x5a, flags: 0x0},
+       490:  {region: 0x53, script: 0xf3, flags: 0x0},
+       491:  {region: 0x165, script: 0x5a, flags: 0x0},
+       492:  {region: 0x135, script: 0x5a, flags: 0x0},
+       493:  {region: 0x165, script: 0x5a, flags: 0x0},
+       494:  {region: 0x49, script: 0x5a, flags: 0x0},
+       495:  {region: 0x165, script: 0x5a, flags: 0x0},
+       496:  {region: 0x165, script: 0x5a, flags: 0x0},
+       497:  {region: 0xe7, script: 0x5a, flags: 0x0},
+       498:  {region: 0x165, script: 0x5a, flags: 0x0},
+       499:  {region: 0x95, script: 0x5a, flags: 0x0},
+       500:  {region: 0x106, script: 0x20, flags: 0x0},
+       501:  {region: 0x1, script: 0x5a, flags: 0x0},
+       502:  {region: 0x165, script: 0x5a, flags: 0x0},
+       503:  {region: 0x165, script: 0x5a, flags: 0x0},
+       504:  {region: 0x9d, script: 0x5a, flags: 0x0},
+       505:  {region: 0x9e, script: 0x5a, flags: 0x0},
        506:  {region: 0x49, script: 0x17, flags: 0x0},
-       507:  {region: 0x97, script: 0x3b, flags: 0x0},
-       508:  {region: 0x165, script: 0x57, flags: 0x0},
-       509:  {region: 0x165, script: 0x57, flags: 0x0},
-       510:  {region: 0x106, script: 0x57, flags: 0x0},
-       511:  {region: 0x165, script: 0x57, flags: 0x0},
-       512:  {region: 0xa2, script: 0x46, flags: 0x0},
-       513:  {region: 0x165, script: 0x57, flags: 0x0},
-       514:  {region: 0xa0, script: 0x57, flags: 0x0},
-       515:  {region: 0x1, script: 0x57, flags: 0x0},
-       516:  {region: 0x165, script: 0x57, flags: 0x0},
-       517:  {region: 0x165, script: 0x57, flags: 0x0},
-       518:  {region: 0x165, script: 0x57, flags: 0x0},
-       519:  {region: 0x52, script: 0x57, flags: 0x0},
-       520:  {region: 0x130, script: 0x3b, flags: 0x0},
-       521:  {region: 0x165, script: 0x57, flags: 0x0},
-       522:  {region: 0x12f, script: 0x57, flags: 0x0},
-       523:  {region: 0xdb, script: 0x21, flags: 0x0},
-       524:  {region: 0x165, script: 0x57, flags: 0x0},
-       525:  {region: 0x63, script: 0x57, flags: 0x0},
-       526:  {region: 0x95, script: 0x57, flags: 0x0},
-       527:  {region: 0x95, script: 0x57, flags: 0x0},
-       528:  {region: 0x7d, script: 0x2b, flags: 0x0},
-       529:  {region: 0x137, script: 0x1f, flags: 0x0},
-       530:  {region: 0x67, script: 0x57, flags: 0x0},
-       531:  {region: 0xc4, script: 0x57, flags: 0x0},
-       532:  {region: 0x165, script: 0x57, flags: 0x0},
-       533:  {region: 0x165, script: 0x57, flags: 0x0},
-       534:  {region: 0xd6, script: 0x57, flags: 0x0},
-       535:  {region: 0xa4, script: 0x57, flags: 0x0},
-       536:  {region: 0xc3, script: 0x57, flags: 0x0},
-       537:  {region: 0x106, script: 0x1f, flags: 0x0},
-       538:  {region: 0x165, script: 0x57, flags: 0x0},
-       539:  {region: 0x165, script: 0x57, flags: 0x0},
-       540:  {region: 0x165, script: 0x57, flags: 0x0},
-       541:  {region: 0x165, script: 0x57, flags: 0x0},
+       507:  {region: 0x97, script: 0x3e, flags: 0x0},
+       508:  {region: 0x165, script: 0x5a, flags: 0x0},
+       509:  {region: 0x165, script: 0x5a, flags: 0x0},
+       510:  {region: 0x106, script: 0x5a, flags: 0x0},
+       511:  {region: 0x165, script: 0x5a, flags: 0x0},
+       512:  {region: 0xa2, script: 0x49, flags: 0x0},
+       513:  {region: 0x165, script: 0x5a, flags: 0x0},
+       514:  {region: 0xa0, script: 0x5a, flags: 0x0},
+       515:  {region: 0x1, script: 0x5a, flags: 0x0},
+       516:  {region: 0x165, script: 0x5a, flags: 0x0},
+       517:  {region: 0x165, script: 0x5a, flags: 0x0},
+       518:  {region: 0x165, script: 0x5a, flags: 0x0},
+       519:  {region: 0x52, script: 0x5a, flags: 0x0},
+       520:  {region: 0x130, script: 0x3e, flags: 0x0},
+       521:  {region: 0x165, script: 0x5a, flags: 0x0},
+       522:  {region: 0x12f, script: 0x5a, flags: 0x0},
+       523:  {region: 0xdb, script: 0x22, flags: 0x0},
+       524:  {region: 0x165, script: 0x5a, flags: 0x0},
+       525:  {region: 0x63, script: 0x5a, flags: 0x0},
+       526:  {region: 0x95, script: 0x5a, flags: 0x0},
+       527:  {region: 0x95, script: 0x5a, flags: 0x0},
+       528:  {region: 0x7d, script: 0x2e, flags: 0x0},
+       529:  {region: 0x137, script: 0x20, flags: 0x0},
+       530:  {region: 0x67, script: 0x5a, flags: 0x0},
+       531:  {region: 0xc4, script: 0x5a, flags: 0x0},
+       532:  {region: 0x165, script: 0x5a, flags: 0x0},
+       533:  {region: 0x165, script: 0x5a, flags: 0x0},
+       534:  {region: 0xd6, script: 0x5a, flags: 0x0},
+       535:  {region: 0xa4, script: 0x5a, flags: 0x0},
+       536:  {region: 0xc3, script: 0x5a, flags: 0x0},
+       537:  {region: 0x106, script: 0x20, flags: 0x0},
+       538:  {region: 0x165, script: 0x5a, flags: 0x0},
+       539:  {region: 0x165, script: 0x5a, flags: 0x0},
+       540:  {region: 0x165, script: 0x5a, flags: 0x0},
+       541:  {region: 0x165, script: 0x5a, flags: 0x0},
        542:  {region: 0xd4, script: 0x5, flags: 0x0},
-       543:  {region: 0xd6, script: 0x57, flags: 0x0},
-       544:  {region: 0x164, script: 0x57, flags: 0x0},
-       545:  {region: 0x165, script: 0x57, flags: 0x0},
-       546:  {region: 0x165, script: 0x57, flags: 0x0},
-       547:  {region: 0x12f, script: 0x57, flags: 0x0},
+       543:  {region: 0xd6, script: 0x5a, flags: 0x0},
+       544:  {region: 0x164, script: 0x5a, flags: 0x0},
+       545:  {region: 0x165, script: 0x5a, flags: 0x0},
+       546:  {region: 0x165, script: 0x5a, flags: 0x0},
+       547:  {region: 0x12f, script: 0x5a, flags: 0x0},
        548:  {region: 0x122, script: 0x5, flags: 0x0},
-       549:  {region: 0x165, script: 0x57, flags: 0x0},
-       550:  {region: 0x123, script: 0xdf, flags: 0x0},
-       551:  {region: 0x5a, script: 0x57, flags: 0x0},
-       552:  {region: 0x52, script: 0x57, flags: 0x0},
-       553:  {region: 0x165, script: 0x57, flags: 0x0},
-       554:  {region: 0x4f, script: 0x57, flags: 0x0},
-       555:  {region: 0x99, script: 0x21, flags: 0x0},
-       556:  {region: 0x99, script: 0x21, flags: 0x0},
-       557:  {region: 0x4b, script: 0x57, flags: 0x0},
-       558:  {region: 0x95, script: 0x57, flags: 0x0},
-       559:  {region: 0x165, script: 0x57, flags: 0x0},
-       560:  {region: 0x41, script: 0x57, flags: 0x0},
-       561:  {region: 0x99, script: 0x57, flags: 0x0},
-       562:  {region: 0x53, script: 0xd6, flags: 0x0},
-       563:  {region: 0x99, script: 0x21, flags: 0x0},
-       564:  {region: 0xc3, script: 0x57, flags: 0x0},
-       565:  {region: 0x165, script: 0x57, flags: 0x0},
-       566:  {region: 0x99, script: 0x72, flags: 0x0},
+       549:  {region: 0x165, script: 0x5a, flags: 0x0},
+       550:  {region: 0x123, script: 0xe6, flags: 0x0},
+       551:  {region: 0x5a, script: 0x5a, flags: 0x0},
+       552:  {region: 0x52, script: 0x5a, flags: 0x0},
+       553:  {region: 0x165, script: 0x5a, flags: 0x0},
+       554:  {region: 0x4f, script: 0x5a, flags: 0x0},
+       555:  {region: 0x99, script: 0x22, flags: 0x0},
+       556:  {region: 0x99, script: 0x22, flags: 0x0},
+       557:  {region: 0x4b, script: 0x5a, flags: 0x0},
+       558:  {region: 0x95, script: 0x5a, flags: 0x0},
+       559:  {region: 0x165, script: 0x5a, flags: 0x0},
+       560:  {region: 0x41, script: 0x5a, flags: 0x0},
+       561:  {region: 0x99, script: 0x5a, flags: 0x0},
+       562:  {region: 0x53, script: 0xdd, flags: 0x0},
+       563:  {region: 0x99, script: 0x22, flags: 0x0},
+       564:  {region: 0xc3, script: 0x5a, flags: 0x0},
+       565:  {region: 0x165, script: 0x5a, flags: 0x0},
+       566:  {region: 0x99, script: 0x75, flags: 0x0},
        567:  {region: 0xe8, script: 0x5, flags: 0x0},
-       568:  {region: 0x165, script: 0x57, flags: 0x0},
-       569:  {region: 0xa4, script: 0x57, flags: 0x0},
-       570:  {region: 0x165, script: 0x57, flags: 0x0},
-       571:  {region: 0x12b, script: 0x57, flags: 0x0},
-       572:  {region: 0x165, script: 0x57, flags: 0x0},
-       573:  {region: 0xd2, script: 0x57, flags: 0x0},
-       574:  {region: 0x165, script: 0x57, flags: 0x0},
-       575:  {region: 0xaf, script: 0x54, flags: 0x0},
-       576:  {region: 0x165, script: 0x57, flags: 0x0},
-       577:  {region: 0x165, script: 0x57, flags: 0x0},
+       568:  {region: 0x165, script: 0x5a, flags: 0x0},
+       569:  {region: 0xa4, script: 0x5a, flags: 0x0},
+       570:  {region: 0x165, script: 0x5a, flags: 0x0},
+       571:  {region: 0x12b, script: 0x5a, flags: 0x0},
+       572:  {region: 0x165, script: 0x5a, flags: 0x0},
+       573:  {region: 0xd2, script: 0x5a, flags: 0x0},
+       574:  {region: 0x165, script: 0x5a, flags: 0x0},
+       575:  {region: 0xaf, script: 0x57, flags: 0x0},
+       576:  {region: 0x165, script: 0x5a, flags: 0x0},
+       577:  {region: 0x165, script: 0x5a, flags: 0x0},
        578:  {region: 0x13, script: 0x6, flags: 0x1},
-       579:  {region: 0x165, script: 0x57, flags: 0x0},
-       580:  {region: 0x52, script: 0x57, flags: 0x0},
-       581:  {region: 0x82, script: 0x57, flags: 0x0},
-       582:  {region: 0xa4, script: 0x57, flags: 0x0},
-       583:  {region: 0x165, script: 0x57, flags: 0x0},
-       584:  {region: 0x165, script: 0x57, flags: 0x0},
-       585:  {region: 0x165, script: 0x57, flags: 0x0},
-       586:  {region: 0xa6, script: 0x4b, flags: 0x0},
-       587:  {region: 0x2a, script: 0x57, flags: 0x0},
-       588:  {region: 0x165, script: 0x57, flags: 0x0},
-       589:  {region: 0x165, script: 0x57, flags: 0x0},
-       590:  {region: 0x165, script: 0x57, flags: 0x0},
-       591:  {region: 0x165, script: 0x57, flags: 0x0},
-       592:  {region: 0x165, script: 0x57, flags: 0x0},
-       593:  {region: 0x99, script: 0x4f, flags: 0x0},
-       594:  {region: 0x8b, script: 0x57, flags: 0x0},
-       595:  {region: 0x165, script: 0x57, flags: 0x0},
-       596:  {region: 0xab, script: 0x50, flags: 0x0},
-       597:  {region: 0x106, script: 0x1f, flags: 0x0},
-       598:  {region: 0x99, script: 0x21, flags: 0x0},
-       599:  {region: 0x165, script: 0x57, flags: 0x0},
-       600:  {region: 0x75, script: 0x57, flags: 0x0},
-       601:  {region: 0x165, script: 0x57, flags: 0x0},
-       602:  {region: 0xb4, script: 0x57, flags: 0x0},
-       603:  {region: 0x165, script: 0x57, flags: 0x0},
-       604:  {region: 0x165, script: 0x57, flags: 0x0},
-       605:  {region: 0x165, script: 0x57, flags: 0x0},
-       606:  {region: 0x165, script: 0x57, flags: 0x0},
-       607:  {region: 0x165, script: 0x57, flags: 0x0},
-       608:  {region: 0x165, script: 0x57, flags: 0x0},
-       609:  {region: 0x165, script: 0x57, flags: 0x0},
-       610:  {region: 0x165, script: 0x29, flags: 0x0},
-       611:  {region: 0x165, script: 0x57, flags: 0x0},
-       612:  {region: 0x106, script: 0x1f, flags: 0x0},
-       613:  {region: 0x112, script: 0x57, flags: 0x0},
-       614:  {region: 0xe7, script: 0x57, flags: 0x0},
-       615:  {region: 0x106, script: 0x57, flags: 0x0},
-       616:  {region: 0x165, script: 0x57, flags: 0x0},
-       617:  {region: 0x99, script: 0x21, flags: 0x0},
+       579:  {region: 0x165, script: 0x5a, flags: 0x0},
+       580:  {region: 0x52, script: 0x5a, flags: 0x0},
+       581:  {region: 0x82, script: 0x5a, flags: 0x0},
+       582:  {region: 0xa4, script: 0x5a, flags: 0x0},
+       583:  {region: 0x165, script: 0x5a, flags: 0x0},
+       584:  {region: 0x165, script: 0x5a, flags: 0x0},
+       585:  {region: 0x165, script: 0x5a, flags: 0x0},
+       586:  {region: 0xa6, script: 0x4e, flags: 0x0},
+       587:  {region: 0x2a, script: 0x5a, flags: 0x0},
+       588:  {region: 0x165, script: 0x5a, flags: 0x0},
+       589:  {region: 0x165, script: 0x5a, flags: 0x0},
+       590:  {region: 0x165, script: 0x5a, flags: 0x0},
+       591:  {region: 0x165, script: 0x5a, flags: 0x0},
+       592:  {region: 0x165, script: 0x5a, flags: 0x0},
+       593:  {region: 0x99, script: 0x52, flags: 0x0},
+       594:  {region: 0x8b, script: 0x5a, flags: 0x0},
+       595:  {region: 0x165, script: 0x5a, flags: 0x0},
+       596:  {region: 0xab, script: 0x53, flags: 0x0},
+       597:  {region: 0x106, script: 0x20, flags: 0x0},
+       598:  {region: 0x99, script: 0x22, flags: 0x0},
+       599:  {region: 0x165, script: 0x5a, flags: 0x0},
+       600:  {region: 0x75, script: 0x5a, flags: 0x0},
+       601:  {region: 0x165, script: 0x5a, flags: 0x0},
+       602:  {region: 0xb4, script: 0x5a, flags: 0x0},
+       603:  {region: 0x165, script: 0x5a, flags: 0x0},
+       604:  {region: 0x165, script: 0x5a, flags: 0x0},
+       605:  {region: 0x165, script: 0x5a, flags: 0x0},
+       606:  {region: 0x165, script: 0x5a, flags: 0x0},
+       607:  {region: 0x165, script: 0x5a, flags: 0x0},
+       608:  {region: 0x165, script: 0x5a, flags: 0x0},
+       609:  {region: 0x165, script: 0x5a, flags: 0x0},
+       610:  {region: 0x165, script: 0x2c, flags: 0x0},
+       611:  {region: 0x165, script: 0x5a, flags: 0x0},
+       612:  {region: 0x106, script: 0x20, flags: 0x0},
+       613:  {region: 0x112, script: 0x5a, flags: 0x0},
+       614:  {region: 0xe7, script: 0x5a, flags: 0x0},
+       615:  {region: 0x106, script: 0x5a, flags: 0x0},
+       616:  {region: 0x165, script: 0x5a, flags: 0x0},
+       617:  {region: 0x99, script: 0x22, flags: 0x0},
        618:  {region: 0x99, script: 0x5, flags: 0x0},
-       619:  {region: 0x12f, script: 0x57, flags: 0x0},
-       620:  {region: 0x165, script: 0x57, flags: 0x0},
-       621:  {region: 0x52, script: 0x57, flags: 0x0},
-       622:  {region: 0x60, script: 0x57, flags: 0x0},
-       623:  {region: 0x165, script: 0x57, flags: 0x0},
-       624:  {region: 0x165, script: 0x57, flags: 0x0},
-       625:  {region: 0x165, script: 0x29, flags: 0x0},
-       626:  {region: 0x165, script: 0x57, flags: 0x0},
-       627:  {region: 0x165, script: 0x57, flags: 0x0},
+       619:  {region: 0x12f, script: 0x5a, flags: 0x0},
+       620:  {region: 0x165, script: 0x5a, flags: 0x0},
+       621:  {region: 0x52, script: 0x5a, flags: 0x0},
+       622:  {region: 0x60, script: 0x5a, flags: 0x0},
+       623:  {region: 0x165, script: 0x5a, flags: 0x0},
+       624:  {region: 0x165, script: 0x5a, flags: 0x0},
+       625:  {region: 0x165, script: 0x2c, flags: 0x0},
+       626:  {region: 0x165, script: 0x5a, flags: 0x0},
+       627:  {region: 0x165, script: 0x5a, flags: 0x0},
        628:  {region: 0x19, script: 0x3, flags: 0x1},
-       629:  {region: 0x165, script: 0x57, flags: 0x0},
-       630:  {region: 0x165, script: 0x57, flags: 0x0},
-       631:  {region: 0x165, script: 0x57, flags: 0x0},
-       632:  {region: 0x165, script: 0x57, flags: 0x0},
-       633:  {region: 0x106, script: 0x1f, flags: 0x0},
-       634:  {region: 0x165, script: 0x57, flags: 0x0},
-       635:  {region: 0x165, script: 0x57, flags: 0x0},
-       636:  {region: 0x165, script: 0x57, flags: 0x0},
-       637:  {region: 0x106, script: 0x1f, flags: 0x0},
-       638:  {region: 0x165, script: 0x57, flags: 0x0},
-       639:  {region: 0x95, script: 0x57, flags: 0x0},
+       629:  {region: 0x165, script: 0x5a, flags: 0x0},
+       630:  {region: 0x165, script: 0x5a, flags: 0x0},
+       631:  {region: 0x165, script: 0x5a, flags: 0x0},
+       632:  {region: 0x165, script: 0x5a, flags: 0x0},
+       633:  {region: 0x106, script: 0x20, flags: 0x0},
+       634:  {region: 0x165, script: 0x5a, flags: 0x0},
+       635:  {region: 0x165, script: 0x5a, flags: 0x0},
+       636:  {region: 0x165, script: 0x5a, flags: 0x0},
+       637:  {region: 0x106, script: 0x20, flags: 0x0},
+       638:  {region: 0x165, script: 0x5a, flags: 0x0},
+       639:  {region: 0x95, script: 0x5a, flags: 0x0},
        640:  {region: 0xe8, script: 0x5, flags: 0x0},
-       641:  {region: 0x7b, script: 0x57, flags: 0x0},
-       642:  {region: 0x165, script: 0x57, flags: 0x0},
-       643:  {region: 0x165, script: 0x57, flags: 0x0},
-       644:  {region: 0x165, script: 0x57, flags: 0x0},
-       645:  {region: 0x165, script: 0x29, flags: 0x0},
-       646:  {region: 0x123, script: 0xdf, flags: 0x0},
+       641:  {region: 0x7b, script: 0x5a, flags: 0x0},
+       642:  {region: 0x165, script: 0x5a, flags: 0x0},
+       643:  {region: 0x165, script: 0x5a, flags: 0x0},
+       644:  {region: 0x165, script: 0x5a, flags: 0x0},
+       645:  {region: 0x165, script: 0x2c, flags: 0x0},
+       646:  {region: 0x123, script: 0xe6, flags: 0x0},
        647:  {region: 0xe8, script: 0x5, flags: 0x0},
-       648:  {region: 0x165, script: 0x57, flags: 0x0},
-       649:  {region: 0x165, script: 0x57, flags: 0x0},
+       648:  {region: 0x165, script: 0x5a, flags: 0x0},
+       649:  {region: 0x165, script: 0x5a, flags: 0x0},
        650:  {region: 0x1c, script: 0x5, flags: 0x1},
-       651:  {region: 0x165, script: 0x57, flags: 0x0},
-       652:  {region: 0x165, script: 0x57, flags: 0x0},
-       653:  {region: 0x165, script: 0x57, flags: 0x0},
-       654:  {region: 0x138, script: 0x57, flags: 0x0},
-       655:  {region: 0x87, script: 0x5b, flags: 0x0},
-       656:  {region: 0x97, script: 0x3b, flags: 0x0},
-       657:  {region: 0x12f, script: 0x57, flags: 0x0},
+       651:  {region: 0x165, script: 0x5a, flags: 0x0},
+       652:  {region: 0x165, script: 0x5a, flags: 0x0},
+       653:  {region: 0x165, script: 0x5a, flags: 0x0},
+       654:  {region: 0x138, script: 0x5a, flags: 0x0},
+       655:  {region: 0x87, script: 0x5e, flags: 0x0},
+       656:  {region: 0x97, script: 0x3e, flags: 0x0},
+       657:  {region: 0x12f, script: 0x5a, flags: 0x0},
        658:  {region: 0xe8, script: 0x5, flags: 0x0},
-       659:  {region: 0x131, script: 0x57, flags: 0x0},
-       660:  {region: 0x165, script: 0x57, flags: 0x0},
-       661:  {region: 0xb7, script: 0x57, flags: 0x0},
-       662:  {region: 0x106, script: 0x1f, flags: 0x0},
-       663:  {region: 0x165, script: 0x57, flags: 0x0},
-       664:  {region: 0x95, script: 0x57, flags: 0x0},
-       665:  {region: 0x165, script: 0x57, flags: 0x0},
-       666:  {region: 0x53, script: 0xdf, flags: 0x0},
-       667:  {region: 0x165, script: 0x57, flags: 0x0},
-       668:  {region: 0x165, script: 0x57, flags: 0x0},
-       669:  {region: 0x165, script: 0x57, flags: 0x0},
-       670:  {region: 0x165, script: 0x57, flags: 0x0},
-       671:  {region: 0x99, script: 0x59, flags: 0x0},
-       672:  {region: 0x165, script: 0x57, flags: 0x0},
-       673:  {region: 0x165, script: 0x57, flags: 0x0},
-       674:  {region: 0x106, script: 0x1f, flags: 0x0},
-       675:  {region: 0x131, script: 0x57, flags: 0x0},
-       676:  {region: 0x165, script: 0x57, flags: 0x0},
-       677:  {region: 0xd9, script: 0x57, flags: 0x0},
-       678:  {region: 0x165, script: 0x57, flags: 0x0},
-       679:  {region: 0x165, script: 0x57, flags: 0x0},
+       659:  {region: 0x131, script: 0x5a, flags: 0x0},
+       660:  {region: 0x165, script: 0x5a, flags: 0x0},
+       661:  {region: 0xb7, script: 0x5a, flags: 0x0},
+       662:  {region: 0x106, script: 0x20, flags: 0x0},
+       663:  {region: 0x165, script: 0x5a, flags: 0x0},
+       664:  {region: 0x95, script: 0x5a, flags: 0x0},
+       665:  {region: 0x165, script: 0x5a, flags: 0x0},
+       666:  {region: 0x53, script: 0xe6, flags: 0x0},
+       667:  {region: 0x165, script: 0x5a, flags: 0x0},
+       668:  {region: 0x165, script: 0x5a, flags: 0x0},
+       669:  {region: 0x165, script: 0x5a, flags: 0x0},
+       670:  {region: 0x165, script: 0x5a, flags: 0x0},
+       671:  {region: 0x99, script: 0x5c, flags: 0x0},
+       672:  {region: 0x165, script: 0x5a, flags: 0x0},
+       673:  {region: 0x165, script: 0x5a, flags: 0x0},
+       674:  {region: 0x106, script: 0x20, flags: 0x0},
+       675:  {region: 0x131, script: 0x5a, flags: 0x0},
+       676:  {region: 0x165, script: 0x5a, flags: 0x0},
+       677:  {region: 0xd9, script: 0x5a, flags: 0x0},
+       678:  {region: 0x165, script: 0x5a, flags: 0x0},
+       679:  {region: 0x165, script: 0x5a, flags: 0x0},
        680:  {region: 0x21, script: 0x2, flags: 0x1},
-       681:  {region: 0x165, script: 0x57, flags: 0x0},
-       682:  {region: 0x165, script: 0x57, flags: 0x0},
-       683:  {region: 0x9e, script: 0x57, flags: 0x0},
-       684:  {region: 0x53, script: 0x5d, flags: 0x0},
-       685:  {region: 0x95, script: 0x57, flags: 0x0},
+       681:  {region: 0x165, script: 0x5a, flags: 0x0},
+       682:  {region: 0x165, script: 0x5a, flags: 0x0},
+       683:  {region: 0x9e, script: 0x5a, flags: 0x0},
+       684:  {region: 0x53, script: 0x60, flags: 0x0},
+       685:  {region: 0x95, script: 0x5a, flags: 0x0},
        686:  {region: 0x9c, script: 0x5, flags: 0x0},
-       687:  {region: 0x135, script: 0x57, flags: 0x0},
-       688:  {region: 0x165, script: 0x57, flags: 0x0},
-       689:  {region: 0x165, script: 0x57, flags: 0x0},
-       690:  {region: 0x99, script: 0xda, flags: 0x0},
-       691:  {region: 0x9e, script: 0x57, flags: 0x0},
-       692:  {region: 0x165, script: 0x57, flags: 0x0},
-       693:  {region: 0x4b, script: 0x57, flags: 0x0},
-       694:  {region: 0x165, script: 0x57, flags: 0x0},
-       695:  {region: 0x165, script: 0x57, flags: 0x0},
-       696:  {region: 0xaf, script: 0x54, flags: 0x0},
-       697:  {region: 0x165, script: 0x57, flags: 0x0},
-       698:  {region: 0x165, script: 0x57, flags: 0x0},
-       699:  {region: 0x4b, script: 0x57, flags: 0x0},
-       700:  {region: 0x165, script: 0x57, flags: 0x0},
-       701:  {region: 0x165, script: 0x57, flags: 0x0},
-       702:  {region: 0x162, script: 0x57, flags: 0x0},
+       687:  {region: 0x135, script: 0x5a, flags: 0x0},
+       688:  {region: 0x165, script: 0x5a, flags: 0x0},
+       689:  {region: 0x165, script: 0x5a, flags: 0x0},
+       690:  {region: 0x99, script: 0xe1, flags: 0x0},
+       691:  {region: 0x9e, script: 0x5a, flags: 0x0},
+       692:  {region: 0x165, script: 0x5a, flags: 0x0},
+       693:  {region: 0x4b, script: 0x5a, flags: 0x0},
+       694:  {region: 0x165, script: 0x5a, flags: 0x0},
+       695:  {region: 0x165, script: 0x5a, flags: 0x0},
+       696:  {region: 0xaf, script: 0x57, flags: 0x0},
+       697:  {region: 0x165, script: 0x5a, flags: 0x0},
+       698:  {region: 0x165, script: 0x5a, flags: 0x0},
+       699:  {region: 0x4b, script: 0x5a, flags: 0x0},
+       700:  {region: 0x165, script: 0x5a, flags: 0x0},
+       701:  {region: 0x165, script: 0x5a, flags: 0x0},
+       702:  {region: 0x162, script: 0x5a, flags: 0x0},
        703:  {region: 0x9c, script: 0x5, flags: 0x0},
-       704:  {region: 0xb6, script: 0x57, flags: 0x0},
-       705:  {region: 0xb8, script: 0x57, flags: 0x0},
-       706:  {region: 0x4b, script: 0x57, flags: 0x0},
-       707:  {region: 0x4b, script: 0x57, flags: 0x0},
-       708:  {region: 0xa4, script: 0x57, flags: 0x0},
-       709:  {region: 0xa4, script: 0x57, flags: 0x0},
+       704:  {region: 0xb6, script: 0x5a, flags: 0x0},
+       705:  {region: 0xb8, script: 0x5a, flags: 0x0},
+       706:  {region: 0x4b, script: 0x5a, flags: 0x0},
+       707:  {region: 0x4b, script: 0x5a, flags: 0x0},
+       708:  {region: 0xa4, script: 0x5a, flags: 0x0},
+       709:  {region: 0xa4, script: 0x5a, flags: 0x0},
        710:  {region: 0x9c, script: 0x5, flags: 0x0},
-       711:  {region: 0xb8, script: 0x57, flags: 0x0},
-       712:  {region: 0x123, script: 0xdf, flags: 0x0},
-       713:  {region: 0x53, script: 0x38, flags: 0x0},
-       714:  {region: 0x12b, script: 0x57, flags: 0x0},
-       715:  {region: 0x95, script: 0x57, flags: 0x0},
-       716:  {region: 0x52, script: 0x57, flags: 0x0},
-       717:  {region: 0x99, script: 0x21, flags: 0x0},
-       718:  {region: 0x99, script: 0x21, flags: 0x0},
-       719:  {region: 0x95, script: 0x57, flags: 0x0},
+       711:  {region: 0xb8, script: 0x5a, flags: 0x0},
+       712:  {region: 0x123, script: 0xe6, flags: 0x0},
+       713:  {region: 0x53, script: 0x3b, flags: 0x0},
+       714:  {region: 0x12b, script: 0x5a, flags: 0x0},
+       715:  {region: 0x95, script: 0x5a, flags: 0x0},
+       716:  {region: 0x52, script: 0x5a, flags: 0x0},
+       717:  {region: 0x99, script: 0x22, flags: 0x0},
+       718:  {region: 0x99, script: 0x22, flags: 0x0},
+       719:  {region: 0x95, script: 0x5a, flags: 0x0},
        720:  {region: 0x23, script: 0x3, flags: 0x1},
-       721:  {region: 0xa4, script: 0x57, flags: 0x0},
-       722:  {region: 0x165, script: 0x57, flags: 0x0},
-       723:  {region: 0xcf, script: 0x57, flags: 0x0},
-       724:  {region: 0x165, script: 0x57, flags: 0x0},
-       725:  {region: 0x165, script: 0x57, flags: 0x0},
-       726:  {region: 0x165, script: 0x57, flags: 0x0},
-       727:  {region: 0x165, script: 0x57, flags: 0x0},
-       728:  {region: 0x165, script: 0x57, flags: 0x0},
-       729:  {region: 0x165, script: 0x57, flags: 0x0},
-       730:  {region: 0x165, script: 0x57, flags: 0x0},
-       731:  {region: 0x165, script: 0x57, flags: 0x0},
-       732:  {region: 0x165, script: 0x57, flags: 0x0},
-       733:  {region: 0x165, script: 0x57, flags: 0x0},
-       734:  {region: 0x165, script: 0x57, flags: 0x0},
+       721:  {region: 0xa4, script: 0x5a, flags: 0x0},
+       722:  {region: 0x165, script: 0x5a, flags: 0x0},
+       723:  {region: 0xcf, script: 0x5a, flags: 0x0},
+       724:  {region: 0x165, script: 0x5a, flags: 0x0},
+       725:  {region: 0x165, script: 0x5a, flags: 0x0},
+       726:  {region: 0x165, script: 0x5a, flags: 0x0},
+       727:  {region: 0x165, script: 0x5a, flags: 0x0},
+       728:  {region: 0x165, script: 0x5a, flags: 0x0},
+       729:  {region: 0x165, script: 0x5a, flags: 0x0},
+       730:  {region: 0x165, script: 0x5a, flags: 0x0},
+       731:  {region: 0x165, script: 0x5a, flags: 0x0},
+       732:  {region: 0x165, script: 0x5a, flags: 0x0},
+       733:  {region: 0x165, script: 0x5a, flags: 0x0},
+       734:  {region: 0x165, script: 0x5a, flags: 0x0},
        735:  {region: 0x165, script: 0x5, flags: 0x0},
-       736:  {region: 0x106, script: 0x1f, flags: 0x0},
-       737:  {region: 0xe7, script: 0x57, flags: 0x0},
-       738:  {region: 0x165, script: 0x57, flags: 0x0},
-       739:  {region: 0x95, script: 0x57, flags: 0x0},
-       740:  {region: 0x165, script: 0x29, flags: 0x0},
-       741:  {region: 0x165, script: 0x57, flags: 0x0},
-       742:  {region: 0x165, script: 0x57, flags: 0x0},
-       743:  {region: 0x165, script: 0x57, flags: 0x0},
-       744:  {region: 0x112, script: 0x57, flags: 0x0},
-       745:  {region: 0xa4, script: 0x57, flags: 0x0},
-       746:  {region: 0x165, script: 0x57, flags: 0x0},
-       747:  {region: 0x165, script: 0x57, flags: 0x0},
+       736:  {region: 0x106, script: 0x20, flags: 0x0},
+       737:  {region: 0xe7, script: 0x5a, flags: 0x0},
+       738:  {region: 0x165, script: 0x5a, flags: 0x0},
+       739:  {region: 0x95, script: 0x5a, flags: 0x0},
+       740:  {region: 0x165, script: 0x2c, flags: 0x0},
+       741:  {region: 0x165, script: 0x5a, flags: 0x0},
+       742:  {region: 0x165, script: 0x5a, flags: 0x0},
+       743:  {region: 0x165, script: 0x5a, flags: 0x0},
+       744:  {region: 0x112, script: 0x5a, flags: 0x0},
+       745:  {region: 0xa4, script: 0x5a, flags: 0x0},
+       746:  {region: 0x165, script: 0x5a, flags: 0x0},
+       747:  {region: 0x165, script: 0x5a, flags: 0x0},
        748:  {region: 0x123, script: 0x5, flags: 0x0},
-       749:  {region: 0xcc, script: 0x57, flags: 0x0},
-       750:  {region: 0x165, script: 0x57, flags: 0x0},
-       751:  {region: 0x165, script: 0x57, flags: 0x0},
-       752:  {region: 0x165, script: 0x57, flags: 0x0},
-       753:  {region: 0xbf, script: 0x57, flags: 0x0},
-       754:  {region: 0xd1, script: 0x57, flags: 0x0},
-       755:  {region: 0x165, script: 0x57, flags: 0x0},
-       756:  {region: 0x52, script: 0x57, flags: 0x0},
-       757:  {region: 0xdb, script: 0x21, flags: 0x0},
-       758:  {region: 0x12f, script: 0x57, flags: 0x0},
-       759:  {region: 0xc0, script: 0x57, flags: 0x0},
-       760:  {region: 0x165, script: 0x57, flags: 0x0},
-       761:  {region: 0x165, script: 0x57, flags: 0x0},
-       762:  {region: 0xe0, script: 0x57, flags: 0x0},
-       763:  {region: 0x165, script: 0x57, flags: 0x0},
-       764:  {region: 0x95, script: 0x57, flags: 0x0},
-       765:  {region: 0x9b, script: 0x3a, flags: 0x0},
-       766:  {region: 0x165, script: 0x57, flags: 0x0},
-       767:  {region: 0xc2, script: 0x1f, flags: 0x0},
+       749:  {region: 0xcc, script: 0x5a, flags: 0x0},
+       750:  {region: 0x165, script: 0x5a, flags: 0x0},
+       751:  {region: 0x165, script: 0x5a, flags: 0x0},
+       752:  {region: 0x165, script: 0x5a, flags: 0x0},
+       753:  {region: 0xbf, script: 0x5a, flags: 0x0},
+       754:  {region: 0xd1, script: 0x5a, flags: 0x0},
+       755:  {region: 0x165, script: 0x5a, flags: 0x0},
+       756:  {region: 0x52, script: 0x5a, flags: 0x0},
+       757:  {region: 0xdb, script: 0x22, flags: 0x0},
+       758:  {region: 0x12f, script: 0x5a, flags: 0x0},
+       759:  {region: 0xc0, script: 0x5a, flags: 0x0},
+       760:  {region: 0x165, script: 0x5a, flags: 0x0},
+       761:  {region: 0x165, script: 0x5a, flags: 0x0},
+       762:  {region: 0xe0, script: 0x5a, flags: 0x0},
+       763:  {region: 0x165, script: 0x5a, flags: 0x0},
+       764:  {region: 0x95, script: 0x5a, flags: 0x0},
+       765:  {region: 0x9b, script: 0x3d, flags: 0x0},
+       766:  {region: 0x165, script: 0x5a, flags: 0x0},
+       767:  {region: 0xc2, script: 0x20, flags: 0x0},
        768:  {region: 0x165, script: 0x5, flags: 0x0},
-       769:  {region: 0x165, script: 0x57, flags: 0x0},
-       770:  {region: 0x165, script: 0x57, flags: 0x0},
-       771:  {region: 0x165, script: 0x57, flags: 0x0},
-       772:  {region: 0x99, script: 0x6b, flags: 0x0},
-       773:  {region: 0x165, script: 0x57, flags: 0x0},
-       774:  {region: 0x165, script: 0x57, flags: 0x0},
-       775:  {region: 0x10b, script: 0x57, flags: 0x0},
-       776:  {region: 0x165, script: 0x57, flags: 0x0},
-       777:  {region: 0x165, script: 0x57, flags: 0x0},
-       778:  {region: 0x165, script: 0x57, flags: 0x0},
+       769:  {region: 0x165, script: 0x5a, flags: 0x0},
+       770:  {region: 0x165, script: 0x5a, flags: 0x0},
+       771:  {region: 0x165, script: 0x5a, flags: 0x0},
+       772:  {region: 0x99, script: 0x6e, flags: 0x0},
+       773:  {region: 0x165, script: 0x5a, flags: 0x0},
+       774:  {region: 0x165, script: 0x5a, flags: 0x0},
+       775:  {region: 0x10b, script: 0x5a, flags: 0x0},
+       776:  {region: 0x165, script: 0x5a, flags: 0x0},
+       777:  {region: 0x165, script: 0x5a, flags: 0x0},
+       778:  {region: 0x165, script: 0x5a, flags: 0x0},
        779:  {region: 0x26, script: 0x3, flags: 0x1},
-       780:  {region: 0x165, script: 0x57, flags: 0x0},
-       781:  {region: 0x165, script: 0x57, flags: 0x0},
+       780:  {region: 0x165, script: 0x5a, flags: 0x0},
+       781:  {region: 0x165, script: 0x5a, flags: 0x0},
        782:  {region: 0x99, script: 0xe, flags: 0x0},
-       783:  {region: 0xc4, script: 0x72, flags: 0x0},
-       785:  {region: 0x165, script: 0x57, flags: 0x0},
-       786:  {region: 0x49, script: 0x57, flags: 0x0},
-       787:  {region: 0x49, script: 0x57, flags: 0x0},
-       788:  {region: 0x37, script: 0x57, flags: 0x0},
-       789:  {region: 0x165, script: 0x57, flags: 0x0},
-       790:  {region: 0x165, script: 0x57, flags: 0x0},
-       791:  {region: 0x165, script: 0x57, flags: 0x0},
-       792:  {region: 0x165, script: 0x57, flags: 0x0},
-       793:  {region: 0x165, script: 0x57, flags: 0x0},
-       794:  {region: 0x165, script: 0x57, flags: 0x0},
-       795:  {region: 0x99, script: 0x21, flags: 0x0},
-       796:  {region: 0xdb, script: 0x21, flags: 0x0},
-       797:  {region: 0x106, script: 0x1f, flags: 0x0},
-       798:  {region: 0x35, script: 0x6f, flags: 0x0},
+       783:  {region: 0xc4, script: 0x75, flags: 0x0},
+       785:  {region: 0x165, script: 0x5a, flags: 0x0},
+       786:  {region: 0x49, script: 0x5a, flags: 0x0},
+       787:  {region: 0x49, script: 0x5a, flags: 0x0},
+       788:  {region: 0x37, script: 0x5a, flags: 0x0},
+       789:  {region: 0x165, script: 0x5a, flags: 0x0},
+       790:  {region: 0x165, script: 0x5a, flags: 0x0},
+       791:  {region: 0x165, script: 0x5a, flags: 0x0},
+       792:  {region: 0x165, script: 0x5a, flags: 0x0},
+       793:  {region: 0x165, script: 0x5a, flags: 0x0},
+       794:  {region: 0x165, script: 0x5a, flags: 0x0},
+       795:  {region: 0x99, script: 0x22, flags: 0x0},
+       796:  {region: 0xdb, script: 0x22, flags: 0x0},
+       797:  {region: 0x106, script: 0x20, flags: 0x0},
+       798:  {region: 0x35, script: 0x72, flags: 0x0},
        799:  {region: 0x29, script: 0x3, flags: 0x1},
-       800:  {region: 0xcb, script: 0x57, flags: 0x0},
-       801:  {region: 0x165, script: 0x57, flags: 0x0},
-       802:  {region: 0x165, script: 0x57, flags: 0x0},
-       803:  {region: 0x165, script: 0x57, flags: 0x0},
-       804:  {region: 0x99, script: 0x21, flags: 0x0},
-       805:  {region: 0x52, script: 0x57, flags: 0x0},
-       807:  {region: 0x165, script: 0x57, flags: 0x0},
-       808:  {region: 0x135, script: 0x57, flags: 0x0},
-       809:  {region: 0x165, script: 0x57, flags: 0x0},
-       810:  {region: 0x165, script: 0x57, flags: 0x0},
+       800:  {region: 0xcb, script: 0x5a, flags: 0x0},
+       801:  {region: 0x165, script: 0x5a, flags: 0x0},
+       802:  {region: 0x165, script: 0x5a, flags: 0x0},
+       803:  {region: 0x165, script: 0x5a, flags: 0x0},
+       804:  {region: 0x99, script: 0x22, flags: 0x0},
+       805:  {region: 0x52, script: 0x5a, flags: 0x0},
+       807:  {region: 0x165, script: 0x5a, flags: 0x0},
+       808:  {region: 0x135, script: 0x5a, flags: 0x0},
+       809:  {region: 0x165, script: 0x5a, flags: 0x0},
+       810:  {region: 0x165, script: 0x5a, flags: 0x0},
        811:  {region: 0xe8, script: 0x5, flags: 0x0},
-       812:  {region: 0xc3, script: 0x57, flags: 0x0},
-       813:  {region: 0x99, script: 0x21, flags: 0x0},
-       814:  {region: 0x95, script: 0x57, flags: 0x0},
-       815:  {region: 0x164, script: 0x57, flags: 0x0},
-       816:  {region: 0x165, script: 0x57, flags: 0x0},
-       817:  {region: 0xc4, script: 0x72, flags: 0x0},
-       818:  {region: 0x165, script: 0x57, flags: 0x0},
-       819:  {region: 0x165, script: 0x29, flags: 0x0},
-       820:  {region: 0x106, script: 0x1f, flags: 0x0},
-       821:  {region: 0x165, script: 0x57, flags: 0x0},
-       822:  {region: 0x131, script: 0x57, flags: 0x0},
-       823:  {region: 0x9c, script: 0x63, flags: 0x0},
-       824:  {region: 0x165, script: 0x57, flags: 0x0},
-       825:  {region: 0x165, script: 0x57, flags: 0x0},
+       812:  {region: 0xc3, script: 0x5a, flags: 0x0},
+       813:  {region: 0x99, script: 0x22, flags: 0x0},
+       814:  {region: 0x95, script: 0x5a, flags: 0x0},
+       815:  {region: 0x164, script: 0x5a, flags: 0x0},
+       816:  {region: 0x165, script: 0x5a, flags: 0x0},
+       817:  {region: 0xc4, script: 0x75, flags: 0x0},
+       818:  {region: 0x165, script: 0x5a, flags: 0x0},
+       819:  {region: 0x165, script: 0x2c, flags: 0x0},
+       820:  {region: 0x106, script: 0x20, flags: 0x0},
+       821:  {region: 0x165, script: 0x5a, flags: 0x0},
+       822:  {region: 0x131, script: 0x5a, flags: 0x0},
+       823:  {region: 0x9c, script: 0x66, flags: 0x0},
+       824:  {region: 0x165, script: 0x5a, flags: 0x0},
+       825:  {region: 0x165, script: 0x5a, flags: 0x0},
        826:  {region: 0x9c, script: 0x5, flags: 0x0},
-       827:  {region: 0x165, script: 0x57, flags: 0x0},
-       828:  {region: 0x165, script: 0x57, flags: 0x0},
-       829:  {region: 0x165, script: 0x57, flags: 0x0},
-       830:  {region: 0xdd, script: 0x57, flags: 0x0},
-       831:  {region: 0x165, script: 0x57, flags: 0x0},
-       832:  {region: 0x165, script: 0x57, flags: 0x0},
-       834:  {region: 0x165, script: 0x57, flags: 0x0},
-       835:  {region: 0x53, script: 0x38, flags: 0x0},
-       836:  {region: 0x9e, script: 0x57, flags: 0x0},
-       837:  {region: 0xd2, script: 0x57, flags: 0x0},
-       838:  {region: 0x165, script: 0x57, flags: 0x0},
-       839:  {region: 0xda, script: 0x57, flags: 0x0},
-       840:  {region: 0x165, script: 0x57, flags: 0x0},
-       841:  {region: 0x165, script: 0x57, flags: 0x0},
-       842:  {region: 0x165, script: 0x57, flags: 0x0},
-       843:  {region: 0xcf, script: 0x57, flags: 0x0},
-       844:  {region: 0x165, script: 0x57, flags: 0x0},
-       845:  {region: 0x165, script: 0x57, flags: 0x0},
-       846:  {region: 0x164, script: 0x57, flags: 0x0},
-       847:  {region: 0xd1, script: 0x57, flags: 0x0},
-       848:  {region: 0x60, script: 0x57, flags: 0x0},
-       849:  {region: 0xdb, script: 0x21, flags: 0x0},
-       850:  {region: 0x165, script: 0x57, flags: 0x0},
-       851:  {region: 0xdb, script: 0x21, flags: 0x0},
-       852:  {region: 0x165, script: 0x57, flags: 0x0},
-       853:  {region: 0x165, script: 0x57, flags: 0x0},
-       854:  {region: 0xd2, script: 0x57, flags: 0x0},
-       855:  {region: 0x165, script: 0x57, flags: 0x0},
-       856:  {region: 0x165, script: 0x57, flags: 0x0},
-       857:  {region: 0xd1, script: 0x57, flags: 0x0},
-       858:  {region: 0x165, script: 0x57, flags: 0x0},
-       859:  {region: 0xcf, script: 0x57, flags: 0x0},
-       860:  {region: 0xcf, script: 0x57, flags: 0x0},
-       861:  {region: 0x165, script: 0x57, flags: 0x0},
-       862:  {region: 0x165, script: 0x57, flags: 0x0},
-       863:  {region: 0x95, script: 0x57, flags: 0x0},
-       864:  {region: 0x165, script: 0x57, flags: 0x0},
-       865:  {region: 0xdf, script: 0x57, flags: 0x0},
-       866:  {region: 0x165, script: 0x57, flags: 0x0},
-       867:  {region: 0x165, script: 0x57, flags: 0x0},
-       868:  {region: 0x99, script: 0x57, flags: 0x0},
-       869:  {region: 0x165, script: 0x57, flags: 0x0},
-       870:  {region: 0x165, script: 0x57, flags: 0x0},
-       871:  {region: 0xd9, script: 0x57, flags: 0x0},
-       872:  {region: 0x52, script: 0x57, flags: 0x0},
-       873:  {region: 0x165, script: 0x57, flags: 0x0},
-       874:  {region: 0xda, script: 0x57, flags: 0x0},
-       875:  {region: 0x165, script: 0x57, flags: 0x0},
-       876:  {region: 0x52, script: 0x57, flags: 0x0},
-       877:  {region: 0x165, script: 0x57, flags: 0x0},
-       878:  {region: 0x165, script: 0x57, flags: 0x0},
-       879:  {region: 0xda, script: 0x57, flags: 0x0},
-       880:  {region: 0x123, script: 0x53, flags: 0x0},
-       881:  {region: 0x99, script: 0x21, flags: 0x0},
-       882:  {region: 0x10c, script: 0xbf, flags: 0x0},
-       883:  {region: 0x165, script: 0x57, flags: 0x0},
-       884:  {region: 0x165, script: 0x57, flags: 0x0},
-       885:  {region: 0x84, script: 0x78, flags: 0x0},
-       886:  {region: 0x161, script: 0x57, flags: 0x0},
-       887:  {region: 0x165, script: 0x57, flags: 0x0},
+       827:  {region: 0x165, script: 0x5a, flags: 0x0},
+       828:  {region: 0x165, script: 0x5a, flags: 0x0},
+       829:  {region: 0x165, script: 0x5a, flags: 0x0},
+       830:  {region: 0xdd, script: 0x5a, flags: 0x0},
+       831:  {region: 0x165, script: 0x5a, flags: 0x0},
+       832:  {region: 0x165, script: 0x5a, flags: 0x0},
+       834:  {region: 0x165, script: 0x5a, flags: 0x0},
+       835:  {region: 0x53, script: 0x3b, flags: 0x0},
+       836:  {region: 0x9e, script: 0x5a, flags: 0x0},
+       837:  {region: 0xd2, script: 0x5a, flags: 0x0},
+       838:  {region: 0x165, script: 0x5a, flags: 0x0},
+       839:  {region: 0xda, script: 0x5a, flags: 0x0},
+       840:  {region: 0x165, script: 0x5a, flags: 0x0},
+       841:  {region: 0x165, script: 0x5a, flags: 0x0},
+       842:  {region: 0x165, script: 0x5a, flags: 0x0},
+       843:  {region: 0xcf, script: 0x5a, flags: 0x0},
+       844:  {region: 0x165, script: 0x5a, flags: 0x0},
+       845:  {region: 0x165, script: 0x5a, flags: 0x0},
+       846:  {region: 0x164, script: 0x5a, flags: 0x0},
+       847:  {region: 0xd1, script: 0x5a, flags: 0x0},
+       848:  {region: 0x60, script: 0x5a, flags: 0x0},
+       849:  {region: 0xdb, script: 0x22, flags: 0x0},
+       850:  {region: 0x165, script: 0x5a, flags: 0x0},
+       851:  {region: 0xdb, script: 0x22, flags: 0x0},
+       852:  {region: 0x165, script: 0x5a, flags: 0x0},
+       853:  {region: 0x165, script: 0x5a, flags: 0x0},
+       854:  {region: 0xd2, script: 0x5a, flags: 0x0},
+       855:  {region: 0x165, script: 0x5a, flags: 0x0},
+       856:  {region: 0x165, script: 0x5a, flags: 0x0},
+       857:  {region: 0xd1, script: 0x5a, flags: 0x0},
+       858:  {region: 0x165, script: 0x5a, flags: 0x0},
+       859:  {region: 0xcf, script: 0x5a, flags: 0x0},
+       860:  {region: 0xcf, script: 0x5a, flags: 0x0},
+       861:  {region: 0x165, script: 0x5a, flags: 0x0},
+       862:  {region: 0x165, script: 0x5a, flags: 0x0},
+       863:  {region: 0x95, script: 0x5a, flags: 0x0},
+       864:  {region: 0x165, script: 0x5a, flags: 0x0},
+       865:  {region: 0xdf, script: 0x5a, flags: 0x0},
+       866:  {region: 0x165, script: 0x5a, flags: 0x0},
+       867:  {region: 0x165, script: 0x5a, flags: 0x0},
+       868:  {region: 0x99, script: 0x5a, flags: 0x0},
+       869:  {region: 0x165, script: 0x5a, flags: 0x0},
+       870:  {region: 0x165, script: 0x5a, flags: 0x0},
+       871:  {region: 0xd9, script: 0x5a, flags: 0x0},
+       872:  {region: 0x52, script: 0x5a, flags: 0x0},
+       873:  {region: 0x165, script: 0x5a, flags: 0x0},
+       874:  {region: 0xda, script: 0x5a, flags: 0x0},
+       875:  {region: 0x165, script: 0x5a, flags: 0x0},
+       876:  {region: 0x52, script: 0x5a, flags: 0x0},
+       877:  {region: 0x165, script: 0x5a, flags: 0x0},
+       878:  {region: 0x165, script: 0x5a, flags: 0x0},
+       879:  {region: 0xda, script: 0x5a, flags: 0x0},
+       880:  {region: 0x123, script: 0x56, flags: 0x0},
+       881:  {region: 0x99, script: 0x22, flags: 0x0},
+       882:  {region: 0x10c, script: 0xc4, flags: 0x0},
+       883:  {region: 0x165, script: 0x5a, flags: 0x0},
+       884:  {region: 0x165, script: 0x5a, flags: 0x0},
+       885:  {region: 0x84, script: 0x7c, flags: 0x0},
+       886:  {region: 0x161, script: 0x5a, flags: 0x0},
+       887:  {region: 0x165, script: 0x5a, flags: 0x0},
        888:  {region: 0x49, script: 0x17, flags: 0x0},
-       889:  {region: 0x165, script: 0x57, flags: 0x0},
-       890:  {region: 0x161, script: 0x57, flags: 0x0},
-       891:  {region: 0x165, script: 0x57, flags: 0x0},
-       892:  {region: 0x165, script: 0x57, flags: 0x0},
-       893:  {region: 0x165, script: 0x57, flags: 0x0},
-       894:  {region: 0x165, script: 0x57, flags: 0x0},
-       895:  {region: 0x165, script: 0x57, flags: 0x0},
-       896:  {region: 0x117, script: 0x57, flags: 0x0},
-       897:  {region: 0x165, script: 0x57, flags: 0x0},
-       898:  {region: 0x165, script: 0x57, flags: 0x0},
-       899:  {region: 0x135, script: 0x57, flags: 0x0},
-       900:  {region: 0x165, script: 0x57, flags: 0x0},
-       901:  {region: 0x53, script: 0x57, flags: 0x0},
-       902:  {region: 0x165, script: 0x57, flags: 0x0},
-       903:  {region: 0xce, script: 0x57, flags: 0x0},
-       904:  {region: 0x12f, script: 0x57, flags: 0x0},
-       905:  {region: 0x131, script: 0x57, flags: 0x0},
-       906:  {region: 0x80, script: 0x57, flags: 0x0},
-       907:  {region: 0x78, script: 0x57, flags: 0x0},
-       908:  {region: 0x165, script: 0x57, flags: 0x0},
-       910:  {region: 0x165, script: 0x57, flags: 0x0},
-       911:  {region: 0x165, script: 0x57, flags: 0x0},
-       912:  {region: 0x6f, script: 0x57, flags: 0x0},
-       913:  {region: 0x165, script: 0x57, flags: 0x0},
-       914:  {region: 0x165, script: 0x57, flags: 0x0},
-       915:  {region: 0x165, script: 0x57, flags: 0x0},
-       916:  {region: 0x165, script: 0x57, flags: 0x0},
-       917:  {region: 0x99, script: 0x7d, flags: 0x0},
-       918:  {region: 0x165, script: 0x57, flags: 0x0},
+       889:  {region: 0x165, script: 0x5a, flags: 0x0},
+       890:  {region: 0x161, script: 0x5a, flags: 0x0},
+       891:  {region: 0x165, script: 0x5a, flags: 0x0},
+       892:  {region: 0x165, script: 0x5a, flags: 0x0},
+       893:  {region: 0x165, script: 0x5a, flags: 0x0},
+       894:  {region: 0x165, script: 0x5a, flags: 0x0},
+       895:  {region: 0x165, script: 0x5a, flags: 0x0},
+       896:  {region: 0x117, script: 0x5a, flags: 0x0},
+       897:  {region: 0x165, script: 0x5a, flags: 0x0},
+       898:  {region: 0x165, script: 0x5a, flags: 0x0},
+       899:  {region: 0x135, script: 0x5a, flags: 0x0},
+       900:  {region: 0x165, script: 0x5a, flags: 0x0},
+       901:  {region: 0x53, script: 0x5a, flags: 0x0},
+       902:  {region: 0x165, script: 0x5a, flags: 0x0},
+       903:  {region: 0xce, script: 0x5a, flags: 0x0},
+       904:  {region: 0x12f, script: 0x5a, flags: 0x0},
+       905:  {region: 0x131, script: 0x5a, flags: 0x0},
+       906:  {region: 0x80, script: 0x5a, flags: 0x0},
+       907:  {region: 0x78, script: 0x5a, flags: 0x0},
+       908:  {region: 0x165, script: 0x5a, flags: 0x0},
+       910:  {region: 0x165, script: 0x5a, flags: 0x0},
+       911:  {region: 0x165, script: 0x5a, flags: 0x0},
+       912:  {region: 0x6f, script: 0x5a, flags: 0x0},
+       913:  {region: 0x165, script: 0x5a, flags: 0x0},
+       914:  {region: 0x165, script: 0x5a, flags: 0x0},
+       915:  {region: 0x165, script: 0x5a, flags: 0x0},
+       916:  {region: 0x165, script: 0x5a, flags: 0x0},
+       917:  {region: 0x99, script: 0x81, flags: 0x0},
+       918:  {region: 0x165, script: 0x5a, flags: 0x0},
        919:  {region: 0x165, script: 0x5, flags: 0x0},
-       920:  {region: 0x7d, script: 0x1f, flags: 0x0},
-       921:  {region: 0x135, script: 0x7e, flags: 0x0},
+       920:  {region: 0x7d, script: 0x20, flags: 0x0},
+       921:  {region: 0x135, script: 0x82, flags: 0x0},
        922:  {region: 0x165, script: 0x5, flags: 0x0},
-       923:  {region: 0xc5, script: 0x7c, flags: 0x0},
-       924:  {region: 0x165, script: 0x57, flags: 0x0},
+       923:  {region: 0xc5, script: 0x80, flags: 0x0},
+       924:  {region: 0x165, script: 0x5a, flags: 0x0},
        925:  {region: 0x2c, script: 0x3, flags: 0x1},
-       926:  {region: 0xe7, script: 0x57, flags: 0x0},
+       926:  {region: 0xe7, script: 0x5a, flags: 0x0},
        927:  {region: 0x2f, script: 0x2, flags: 0x1},
-       928:  {region: 0xe7, script: 0x57, flags: 0x0},
-       929:  {region: 0x30, script: 0x57, flags: 0x0},
-       930:  {region: 0xf0, script: 0x57, flags: 0x0},
-       931:  {region: 0x165, script: 0x57, flags: 0x0},
-       932:  {region: 0x78, script: 0x57, flags: 0x0},
-       933:  {region: 0xd6, script: 0x57, flags: 0x0},
-       934:  {region: 0x135, script: 0x57, flags: 0x0},
-       935:  {region: 0x49, script: 0x57, flags: 0x0},
-       936:  {region: 0x165, script: 0x57, flags: 0x0},
-       937:  {region: 0x9c, script: 0xe8, flags: 0x0},
-       938:  {region: 0x165, script: 0x57, flags: 0x0},
-       939:  {region: 0x60, script: 0x57, flags: 0x0},
+       928:  {region: 0xe7, script: 0x5a, flags: 0x0},
+       929:  {region: 0x30, script: 0x5a, flags: 0x0},
+       930:  {region: 0xf0, script: 0x5a, flags: 0x0},
+       931:  {region: 0x165, script: 0x5a, flags: 0x0},
+       932:  {region: 0x78, script: 0x5a, flags: 0x0},
+       933:  {region: 0xd6, script: 0x5a, flags: 0x0},
+       934:  {region: 0x135, script: 0x5a, flags: 0x0},
+       935:  {region: 0x49, script: 0x5a, flags: 0x0},
+       936:  {region: 0x165, script: 0x5a, flags: 0x0},
+       937:  {region: 0x9c, script: 0xf0, flags: 0x0},
+       938:  {region: 0x165, script: 0x5a, flags: 0x0},
+       939:  {region: 0x60, script: 0x5a, flags: 0x0},
        940:  {region: 0x165, script: 0x5, flags: 0x0},
-       941:  {region: 0xb0, script: 0x87, flags: 0x0},
-       943:  {region: 0x165, script: 0x57, flags: 0x0},
-       944:  {region: 0x165, script: 0x57, flags: 0x0},
+       941:  {region: 0xb0, script: 0x8b, flags: 0x0},
+       943:  {region: 0x165, script: 0x5a, flags: 0x0},
+       944:  {region: 0x165, script: 0x5a, flags: 0x0},
        945:  {region: 0x99, script: 0x12, flags: 0x0},
-       946:  {region: 0xa4, script: 0x57, flags: 0x0},
-       947:  {region: 0xe9, script: 0x57, flags: 0x0},
-       948:  {region: 0x165, script: 0x57, flags: 0x0},
-       949:  {region: 0x9e, script: 0x57, flags: 0x0},
-       950:  {region: 0x165, script: 0x57, flags: 0x0},
-       951:  {region: 0x165, script: 0x57, flags: 0x0},
-       952:  {region: 0x87, script: 0x31, flags: 0x0},
-       953:  {region: 0x75, script: 0x57, flags: 0x0},
-       954:  {region: 0x165, script: 0x57, flags: 0x0},
-       955:  {region: 0xe8, script: 0x4a, flags: 0x0},
+       946:  {region: 0xa4, script: 0x5a, flags: 0x0},
+       947:  {region: 0xe9, script: 0x5a, flags: 0x0},
+       948:  {region: 0x165, script: 0x5a, flags: 0x0},
+       949:  {region: 0x9e, script: 0x5a, flags: 0x0},
+       950:  {region: 0x165, script: 0x5a, flags: 0x0},
+       951:  {region: 0x165, script: 0x5a, flags: 0x0},
+       952:  {region: 0x87, script: 0x34, flags: 0x0},
+       953:  {region: 0x75, script: 0x5a, flags: 0x0},
+       954:  {region: 0x165, script: 0x5a, flags: 0x0},
+       955:  {region: 0xe8, script: 0x4d, flags: 0x0},
        956:  {region: 0x9c, script: 0x5, flags: 0x0},
-       957:  {region: 0x1, script: 0x57, flags: 0x0},
+       957:  {region: 0x1, script: 0x5a, flags: 0x0},
        958:  {region: 0x24, script: 0x5, flags: 0x0},
-       959:  {region: 0x165, script: 0x57, flags: 0x0},
-       960:  {region: 0x41, script: 0x57, flags: 0x0},
-       961:  {region: 0x165, script: 0x57, flags: 0x0},
-       962:  {region: 0x7a, script: 0x57, flags: 0x0},
-       963:  {region: 0x165, script: 0x57, flags: 0x0},
-       964:  {region: 0xe4, script: 0x57, flags: 0x0},
-       965:  {region: 0x89, script: 0x57, flags: 0x0},
-       966:  {region: 0x69, script: 0x57, flags: 0x0},
-       967:  {region: 0x165, script: 0x57, flags: 0x0},
-       968:  {region: 0x99, script: 0x21, flags: 0x0},
-       969:  {region: 0x165, script: 0x57, flags: 0x0},
-       970:  {region: 0x102, script: 0x57, flags: 0x0},
-       971:  {region: 0x95, script: 0x57, flags: 0x0},
-       972:  {region: 0x165, script: 0x57, flags: 0x0},
-       973:  {region: 0x165, script: 0x57, flags: 0x0},
-       974:  {region: 0x9e, script: 0x57, flags: 0x0},
+       959:  {region: 0x165, script: 0x5a, flags: 0x0},
+       960:  {region: 0x41, script: 0x5a, flags: 0x0},
+       961:  {region: 0x165, script: 0x5a, flags: 0x0},
+       962:  {region: 0x7a, script: 0x5a, flags: 0x0},
+       963:  {region: 0x165, script: 0x5a, flags: 0x0},
+       964:  {region: 0xe4, script: 0x5a, flags: 0x0},
+       965:  {region: 0x89, script: 0x5a, flags: 0x0},
+       966:  {region: 0x69, script: 0x5a, flags: 0x0},
+       967:  {region: 0x165, script: 0x5a, flags: 0x0},
+       968:  {region: 0x99, script: 0x22, flags: 0x0},
+       969:  {region: 0x165, script: 0x5a, flags: 0x0},
+       970:  {region: 0x102, script: 0x5a, flags: 0x0},
+       971:  {region: 0x95, script: 0x5a, flags: 0x0},
+       972:  {region: 0x165, script: 0x5a, flags: 0x0},
+       973:  {region: 0x165, script: 0x5a, flags: 0x0},
+       974:  {region: 0x9e, script: 0x5a, flags: 0x0},
        975:  {region: 0x165, script: 0x5, flags: 0x0},
-       976:  {region: 0x99, script: 0x57, flags: 0x0},
+       976:  {region: 0x99, script: 0x5a, flags: 0x0},
        977:  {region: 0x31, script: 0x2, flags: 0x1},
-       978:  {region: 0xdb, script: 0x21, flags: 0x0},
+       978:  {region: 0xdb, script: 0x22, flags: 0x0},
        979:  {region: 0x35, script: 0xe, flags: 0x0},
-       980:  {region: 0x4e, script: 0x57, flags: 0x0},
-       981:  {region: 0x72, script: 0x57, flags: 0x0},
-       982:  {region: 0x4e, script: 0x57, flags: 0x0},
+       980:  {region: 0x4e, script: 0x5a, flags: 0x0},
+       981:  {region: 0x72, script: 0x5a, flags: 0x0},
+       982:  {region: 0x4e, script: 0x5a, flags: 0x0},
        983:  {region: 0x9c, script: 0x5, flags: 0x0},
-       984:  {region: 0x10c, script: 0x57, flags: 0x0},
-       985:  {region: 0x3a, script: 0x57, flags: 0x0},
-       986:  {region: 0x165, script: 0x57, flags: 0x0},
-       987:  {region: 0xd1, script: 0x57, flags: 0x0},
-       988:  {region: 0x104, script: 0x57, flags: 0x0},
-       989:  {region: 0x95, script: 0x57, flags: 0x0},
-       990:  {region: 0x12f, script: 0x57, flags: 0x0},
-       991:  {region: 0x165, script: 0x57, flags: 0x0},
-       992:  {region: 0x165, script: 0x57, flags: 0x0},
-       993:  {region: 0x73, script: 0x57, flags: 0x0},
-       994:  {region: 0x106, script: 0x1f, flags: 0x0},
-       995:  {region: 0x130, script: 0x1f, flags: 0x0},
-       996:  {region: 0x109, script: 0x57, flags: 0x0},
-       997:  {region: 0x107, script: 0x57, flags: 0x0},
-       998:  {region: 0x12f, script: 0x57, flags: 0x0},
-       999:  {region: 0x165, script: 0x57, flags: 0x0},
-       1000: {region: 0xa2, script: 0x49, flags: 0x0},
-       1001: {region: 0x99, script: 0x21, flags: 0x0},
-       1002: {region: 0x80, script: 0x57, flags: 0x0},
-       1003: {region: 0x106, script: 0x1f, flags: 0x0},
-       1004: {region: 0xa4, script: 0x57, flags: 0x0},
-       1005: {region: 0x95, script: 0x57, flags: 0x0},
-       1006: {region: 0x99, script: 0x57, flags: 0x0},
-       1007: {region: 0x114, script: 0x57, flags: 0x0},
-       1008: {region: 0x99, script: 0xc3, flags: 0x0},
-       1009: {region: 0x165, script: 0x57, flags: 0x0},
-       1010: {region: 0x165, script: 0x57, flags: 0x0},
-       1011: {region: 0x12f, script: 0x57, flags: 0x0},
-       1012: {region: 0x9e, script: 0x57, flags: 0x0},
-       1013: {region: 0x99, script: 0x21, flags: 0x0},
+       984:  {region: 0x10c, script: 0x5a, flags: 0x0},
+       985:  {region: 0x3a, script: 0x5a, flags: 0x0},
+       986:  {region: 0x165, script: 0x5a, flags: 0x0},
+       987:  {region: 0xd1, script: 0x5a, flags: 0x0},
+       988:  {region: 0x104, script: 0x5a, flags: 0x0},
+       989:  {region: 0x95, script: 0x5a, flags: 0x0},
+       990:  {region: 0x12f, script: 0x5a, flags: 0x0},
+       991:  {region: 0x165, script: 0x5a, flags: 0x0},
+       992:  {region: 0x165, script: 0x5a, flags: 0x0},
+       993:  {region: 0x73, script: 0x5a, flags: 0x0},
+       994:  {region: 0x106, script: 0x20, flags: 0x0},
+       995:  {region: 0x130, script: 0x20, flags: 0x0},
+       996:  {region: 0x109, script: 0x5a, flags: 0x0},
+       997:  {region: 0x107, script: 0x5a, flags: 0x0},
+       998:  {region: 0x12f, script: 0x5a, flags: 0x0},
+       999:  {region: 0x165, script: 0x5a, flags: 0x0},
+       1000: {region: 0xa2, script: 0x4c, flags: 0x0},
+       1001: {region: 0x99, script: 0x22, flags: 0x0},
+       1002: {region: 0x80, script: 0x5a, flags: 0x0},
+       1003: {region: 0x106, script: 0x20, flags: 0x0},
+       1004: {region: 0xa4, script: 0x5a, flags: 0x0},
+       1005: {region: 0x95, script: 0x5a, flags: 0x0},
+       1006: {region: 0x99, script: 0x5a, flags: 0x0},
+       1007: {region: 0x114, script: 0x5a, flags: 0x0},
+       1008: {region: 0x99, script: 0xc8, flags: 0x0},
+       1009: {region: 0x165, script: 0x5a, flags: 0x0},
+       1010: {region: 0x165, script: 0x5a, flags: 0x0},
+       1011: {region: 0x12f, script: 0x5a, flags: 0x0},
+       1012: {region: 0x9e, script: 0x5a, flags: 0x0},
+       1013: {region: 0x99, script: 0x22, flags: 0x0},
        1014: {region: 0x165, script: 0x5, flags: 0x0},
-       1015: {region: 0x9e, script: 0x57, flags: 0x0},
-       1016: {region: 0x7b, script: 0x57, flags: 0x0},
-       1017: {region: 0x49, script: 0x57, flags: 0x0},
+       1015: {region: 0x9e, script: 0x5a, flags: 0x0},
+       1016: {region: 0x7b, script: 0x5a, flags: 0x0},
+       1017: {region: 0x49, script: 0x5a, flags: 0x0},
        1018: {region: 0x33, script: 0x4, flags: 0x1},
-       1019: {region: 0x9e, script: 0x57, flags: 0x0},
+       1019: {region: 0x9e, script: 0x5a, flags: 0x0},
        1020: {region: 0x9c, script: 0x5, flags: 0x0},
-       1021: {region: 0xda, script: 0x57, flags: 0x0},
-       1022: {region: 0x4f, script: 0x57, flags: 0x0},
-       1023: {region: 0xd1, script: 0x57, flags: 0x0},
-       1024: {region: 0xcf, script: 0x57, flags: 0x0},
-       1025: {region: 0xc3, script: 0x57, flags: 0x0},
-       1026: {region: 0x4c, script: 0x57, flags: 0x0},
-       1027: {region: 0x96, script: 0x7a, flags: 0x0},
-       1028: {region: 0xb6, script: 0x57, flags: 0x0},
-       1029: {region: 0x165, script: 0x29, flags: 0x0},
-       1030: {region: 0x165, script: 0x57, flags: 0x0},
-       1032: {region: 0xba, script: 0xdc, flags: 0x0},
-       1033: {region: 0x165, script: 0x57, flags: 0x0},
-       1034: {region: 0xc4, script: 0x72, flags: 0x0},
+       1021: {region: 0xda, script: 0x5a, flags: 0x0},
+       1022: {region: 0x4f, script: 0x5a, flags: 0x0},
+       1023: {region: 0xd1, script: 0x5a, flags: 0x0},
+       1024: {region: 0xcf, script: 0x5a, flags: 0x0},
+       1025: {region: 0xc3, script: 0x5a, flags: 0x0},
+       1026: {region: 0x4c, script: 0x5a, flags: 0x0},
+       1027: {region: 0x96, script: 0x7e, flags: 0x0},
+       1028: {region: 0xb6, script: 0x5a, flags: 0x0},
+       1029: {region: 0x165, script: 0x2c, flags: 0x0},
+       1030: {region: 0x165, script: 0x5a, flags: 0x0},
+       1032: {region: 0xba, script: 0xe3, flags: 0x0},
+       1033: {region: 0x165, script: 0x5a, flags: 0x0},
+       1034: {region: 0xc4, script: 0x75, flags: 0x0},
        1035: {region: 0x165, script: 0x5, flags: 0x0},
-       1036: {region: 0xb3, script: 0xca, flags: 0x0},
-       1037: {region: 0x6f, script: 0x57, flags: 0x0},
-       1038: {region: 0x165, script: 0x57, flags: 0x0},
-       1039: {region: 0x165, script: 0x57, flags: 0x0},
-       1040: {region: 0x165, script: 0x57, flags: 0x0},
-       1041: {region: 0x165, script: 0x57, flags: 0x0},
-       1042: {region: 0x111, script: 0x57, flags: 0x0},
-       1043: {region: 0x165, script: 0x57, flags: 0x0},
+       1036: {region: 0xb3, script: 0xcf, flags: 0x0},
+       1037: {region: 0x6f, script: 0x5a, flags: 0x0},
+       1038: {region: 0x165, script: 0x5a, flags: 0x0},
+       1039: {region: 0x165, script: 0x5a, flags: 0x0},
+       1040: {region: 0x165, script: 0x5a, flags: 0x0},
+       1041: {region: 0x165, script: 0x5a, flags: 0x0},
+       1042: {region: 0x111, script: 0x5a, flags: 0x0},
+       1043: {region: 0x165, script: 0x5a, flags: 0x0},
        1044: {region: 0xe8, script: 0x5, flags: 0x0},
-       1045: {region: 0x165, script: 0x57, flags: 0x0},
-       1046: {region: 0x10f, script: 0x57, flags: 0x0},
-       1047: {region: 0x165, script: 0x57, flags: 0x0},
-       1048: {region: 0xe9, script: 0x57, flags: 0x0},
-       1049: {region: 0x165, script: 0x57, flags: 0x0},
-       1050: {region: 0x95, script: 0x57, flags: 0x0},
-       1051: {region: 0x142, script: 0x57, flags: 0x0},
-       1052: {region: 0x10c, script: 0x57, flags: 0x0},
-       1054: {region: 0x10c, script: 0x57, flags: 0x0},
-       1055: {region: 0x72, script: 0x57, flags: 0x0},
-       1056: {region: 0x97, script: 0xc0, flags: 0x0},
-       1057: {region: 0x165, script: 0x57, flags: 0x0},
-       1058: {region: 0x72, script: 0x57, flags: 0x0},
-       1059: {region: 0x164, script: 0x57, flags: 0x0},
-       1060: {region: 0x165, script: 0x57, flags: 0x0},
-       1061: {region: 0xc3, script: 0x57, flags: 0x0},
-       1062: {region: 0x165, script: 0x57, flags: 0x0},
-       1063: {region: 0x165, script: 0x57, flags: 0x0},
-       1064: {region: 0x165, script: 0x57, flags: 0x0},
-       1065: {region: 0x115, script: 0x57, flags: 0x0},
-       1066: {region: 0x165, script: 0x57, flags: 0x0},
-       1067: {region: 0x165, script: 0x57, flags: 0x0},
-       1068: {region: 0x123, script: 0xdf, flags: 0x0},
-       1069: {region: 0x165, script: 0x57, flags: 0x0},
-       1070: {region: 0x165, script: 0x57, flags: 0x0},
-       1071: {region: 0x165, script: 0x57, flags: 0x0},
-       1072: {region: 0x165, script: 0x57, flags: 0x0},
-       1073: {region: 0x27, script: 0x57, flags: 0x0},
+       1045: {region: 0x165, script: 0x5a, flags: 0x0},
+       1046: {region: 0x10f, script: 0x5a, flags: 0x0},
+       1047: {region: 0x165, script: 0x5a, flags: 0x0},
+       1048: {region: 0xe9, script: 0x5a, flags: 0x0},
+       1049: {region: 0x165, script: 0x5a, flags: 0x0},
+       1050: {region: 0x95, script: 0x5a, flags: 0x0},
+       1051: {region: 0x142, script: 0x5a, flags: 0x0},
+       1052: {region: 0x10c, script: 0x5a, flags: 0x0},
+       1054: {region: 0x10c, script: 0x5a, flags: 0x0},
+       1055: {region: 0x72, script: 0x5a, flags: 0x0},
+       1056: {region: 0x97, script: 0xc5, flags: 0x0},
+       1057: {region: 0x165, script: 0x5a, flags: 0x0},
+       1058: {region: 0x72, script: 0x5a, flags: 0x0},
+       1059: {region: 0x164, script: 0x5a, flags: 0x0},
+       1060: {region: 0x165, script: 0x5a, flags: 0x0},
+       1061: {region: 0xc3, script: 0x5a, flags: 0x0},
+       1062: {region: 0x165, script: 0x5a, flags: 0x0},
+       1063: {region: 0x165, script: 0x5a, flags: 0x0},
+       1064: {region: 0x165, script: 0x5a, flags: 0x0},
+       1065: {region: 0x115, script: 0x5a, flags: 0x0},
+       1066: {region: 0x165, script: 0x5a, flags: 0x0},
+       1067: {region: 0x165, script: 0x5a, flags: 0x0},
+       1068: {region: 0x123, script: 0xe6, flags: 0x0},
+       1069: {region: 0x165, script: 0x5a, flags: 0x0},
+       1070: {region: 0x165, script: 0x5a, flags: 0x0},
+       1071: {region: 0x165, script: 0x5a, flags: 0x0},
+       1072: {region: 0x165, script: 0x5a, flags: 0x0},
+       1073: {region: 0x27, script: 0x5a, flags: 0x0},
        1074: {region: 0x37, script: 0x5, flags: 0x1},
-       1075: {region: 0x99, script: 0xcb, flags: 0x0},
-       1076: {region: 0x116, script: 0x57, flags: 0x0},
-       1077: {region: 0x114, script: 0x57, flags: 0x0},
-       1078: {region: 0x99, script: 0x21, flags: 0x0},
-       1079: {region: 0x161, script: 0x57, flags: 0x0},
-       1080: {region: 0x165, script: 0x57, flags: 0x0},
-       1081: {region: 0x165, script: 0x57, flags: 0x0},
-       1082: {region: 0x6d, script: 0x57, flags: 0x0},
-       1083: {region: 0x161, script: 0x57, flags: 0x0},
-       1084: {region: 0x165, script: 0x57, flags: 0x0},
-       1085: {region: 0x60, script: 0x57, flags: 0x0},
-       1086: {region: 0x95, script: 0x57, flags: 0x0},
-       1087: {region: 0x165, script: 0x57, flags: 0x0},
-       1088: {region: 0x165, script: 0x57, flags: 0x0},
-       1089: {region: 0x12f, script: 0x57, flags: 0x0},
-       1090: {region: 0x165, script: 0x57, flags: 0x0},
-       1091: {region: 0x84, script: 0x57, flags: 0x0},
-       1092: {region: 0x10c, script: 0x57, flags: 0x0},
-       1093: {region: 0x12f, script: 0x57, flags: 0x0},
+       1075: {region: 0x99, script: 0xd2, flags: 0x0},
+       1076: {region: 0x116, script: 0x5a, flags: 0x0},
+       1077: {region: 0x114, script: 0x5a, flags: 0x0},
+       1078: {region: 0x99, script: 0x22, flags: 0x0},
+       1079: {region: 0x161, script: 0x5a, flags: 0x0},
+       1080: {region: 0x165, script: 0x5a, flags: 0x0},
+       1081: {region: 0x165, script: 0x5a, flags: 0x0},
+       1082: {region: 0x6d, script: 0x5a, flags: 0x0},
+       1083: {region: 0x161, script: 0x5a, flags: 0x0},
+       1084: {region: 0x165, script: 0x5a, flags: 0x0},
+       1085: {region: 0x60, script: 0x5a, flags: 0x0},
+       1086: {region: 0x95, script: 0x5a, flags: 0x0},
+       1087: {region: 0x165, script: 0x5a, flags: 0x0},
+       1088: {region: 0x165, script: 0x5a, flags: 0x0},
+       1089: {region: 0x12f, script: 0x5a, flags: 0x0},
+       1090: {region: 0x165, script: 0x5a, flags: 0x0},
+       1091: {region: 0x84, script: 0x5a, flags: 0x0},
+       1092: {region: 0x10c, script: 0x5a, flags: 0x0},
+       1093: {region: 0x12f, script: 0x5a, flags: 0x0},
        1094: {region: 0x15f, script: 0x5, flags: 0x0},
-       1095: {region: 0x4b, script: 0x57, flags: 0x0},
-       1096: {region: 0x60, script: 0x57, flags: 0x0},
-       1097: {region: 0x165, script: 0x57, flags: 0x0},
-       1098: {region: 0x99, script: 0x21, flags: 0x0},
-       1099: {region: 0x95, script: 0x57, flags: 0x0},
-       1100: {region: 0x165, script: 0x57, flags: 0x0},
+       1095: {region: 0x4b, script: 0x5a, flags: 0x0},
+       1096: {region: 0x60, script: 0x5a, flags: 0x0},
+       1097: {region: 0x165, script: 0x5a, flags: 0x0},
+       1098: {region: 0x99, script: 0x22, flags: 0x0},
+       1099: {region: 0x95, script: 0x5a, flags: 0x0},
+       1100: {region: 0x165, script: 0x5a, flags: 0x0},
        1101: {region: 0x35, script: 0xe, flags: 0x0},
-       1102: {region: 0x9b, script: 0xcf, flags: 0x0},
-       1103: {region: 0xe9, script: 0x57, flags: 0x0},
-       1104: {region: 0x99, script: 0xd7, flags: 0x0},
-       1105: {region: 0xdb, script: 0x21, flags: 0x0},
-       1106: {region: 0x165, script: 0x57, flags: 0x0},
-       1107: {region: 0x165, script: 0x57, flags: 0x0},
-       1108: {region: 0x165, script: 0x57, flags: 0x0},
-       1109: {region: 0x165, script: 0x57, flags: 0x0},
-       1110: {region: 0x165, script: 0x57, flags: 0x0},
-       1111: {region: 0x165, script: 0x57, flags: 0x0},
-       1112: {region: 0x165, script: 0x57, flags: 0x0},
-       1113: {region: 0x165, script: 0x57, flags: 0x0},
-       1114: {region: 0xe7, script: 0x57, flags: 0x0},
-       1115: {region: 0x165, script: 0x57, flags: 0x0},
-       1116: {region: 0x165, script: 0x57, flags: 0x0},
-       1117: {region: 0x99, script: 0x4f, flags: 0x0},
-       1118: {region: 0x53, script: 0xd5, flags: 0x0},
-       1119: {region: 0xdb, script: 0x21, flags: 0x0},
-       1120: {region: 0xdb, script: 0x21, flags: 0x0},
-       1121: {region: 0x99, script: 0xda, flags: 0x0},
-       1122: {region: 0x165, script: 0x57, flags: 0x0},
-       1123: {region: 0x112, script: 0x57, flags: 0x0},
-       1124: {region: 0x131, script: 0x57, flags: 0x0},
-       1125: {region: 0x126, script: 0x57, flags: 0x0},
-       1126: {region: 0x165, script: 0x57, flags: 0x0},
+       1102: {region: 0x9b, script: 0xd6, flags: 0x0},
+       1103: {region: 0xe9, script: 0x5a, flags: 0x0},
+       1104: {region: 0x99, script: 0xde, flags: 0x0},
+       1105: {region: 0xdb, script: 0x22, flags: 0x0},
+       1106: {region: 0x165, script: 0x5a, flags: 0x0},
+       1107: {region: 0x165, script: 0x5a, flags: 0x0},
+       1108: {region: 0x165, script: 0x5a, flags: 0x0},
+       1109: {region: 0x165, script: 0x5a, flags: 0x0},
+       1110: {region: 0x165, script: 0x5a, flags: 0x0},
+       1111: {region: 0x165, script: 0x5a, flags: 0x0},
+       1112: {region: 0x165, script: 0x5a, flags: 0x0},
+       1113: {region: 0x165, script: 0x5a, flags: 0x0},
+       1114: {region: 0xe7, script: 0x5a, flags: 0x0},
+       1115: {region: 0x165, script: 0x5a, flags: 0x0},
+       1116: {region: 0x165, script: 0x5a, flags: 0x0},
+       1117: {region: 0x99, script: 0x52, flags: 0x0},
+       1118: {region: 0x53, script: 0xdc, flags: 0x0},
+       1119: {region: 0xdb, script: 0x22, flags: 0x0},
+       1120: {region: 0xdb, script: 0x22, flags: 0x0},
+       1121: {region: 0x99, script: 0xe1, flags: 0x0},
+       1122: {region: 0x165, script: 0x5a, flags: 0x0},
+       1123: {region: 0x112, script: 0x5a, flags: 0x0},
+       1124: {region: 0x131, script: 0x5a, flags: 0x0},
+       1125: {region: 0x126, script: 0x5a, flags: 0x0},
+       1126: {region: 0x165, script: 0x5a, flags: 0x0},
        1127: {region: 0x3c, script: 0x3, flags: 0x1},
-       1128: {region: 0x165, script: 0x57, flags: 0x0},
-       1129: {region: 0x165, script: 0x57, flags: 0x0},
-       1130: {region: 0x165, script: 0x57, flags: 0x0},
-       1131: {region: 0x123, script: 0xdf, flags: 0x0},
-       1132: {region: 0xdb, script: 0x21, flags: 0x0},
-       1133: {region: 0xdb, script: 0x21, flags: 0x0},
-       1134: {region: 0xdb, script: 0x21, flags: 0x0},
-       1135: {region: 0x6f, script: 0x29, flags: 0x0},
-       1136: {region: 0x165, script: 0x57, flags: 0x0},
-       1137: {region: 0x6d, script: 0x29, flags: 0x0},
-       1138: {region: 0x165, script: 0x57, flags: 0x0},
-       1139: {region: 0x165, script: 0x57, flags: 0x0},
-       1140: {region: 0x165, script: 0x57, flags: 0x0},
-       1141: {region: 0xd6, script: 0x57, flags: 0x0},
-       1142: {region: 0x127, script: 0x57, flags: 0x0},
-       1143: {region: 0x125, script: 0x57, flags: 0x0},
-       1144: {region: 0x32, script: 0x57, flags: 0x0},
-       1145: {region: 0xdb, script: 0x21, flags: 0x0},
-       1146: {region: 0xe7, script: 0x57, flags: 0x0},
-       1147: {region: 0x165, script: 0x57, flags: 0x0},
-       1148: {region: 0x165, script: 0x57, flags: 0x0},
-       1149: {region: 0x32, script: 0x57, flags: 0x0},
-       1150: {region: 0xd4, script: 0x57, flags: 0x0},
-       1151: {region: 0x165, script: 0x57, flags: 0x0},
-       1152: {region: 0x161, script: 0x57, flags: 0x0},
-       1153: {region: 0x165, script: 0x57, flags: 0x0},
-       1154: {region: 0x129, script: 0x57, flags: 0x0},
-       1155: {region: 0x165, script: 0x57, flags: 0x0},
-       1156: {region: 0xce, script: 0x57, flags: 0x0},
-       1157: {region: 0x165, script: 0x57, flags: 0x0},
-       1158: {region: 0xe6, script: 0x57, flags: 0x0},
-       1159: {region: 0x165, script: 0x57, flags: 0x0},
-       1160: {region: 0x165, script: 0x57, flags: 0x0},
-       1161: {region: 0x165, script: 0x57, flags: 0x0},
-       1162: {region: 0x12b, script: 0x57, flags: 0x0},
-       1163: {region: 0x12b, script: 0x57, flags: 0x0},
-       1164: {region: 0x12e, script: 0x57, flags: 0x0},
+       1128: {region: 0x165, script: 0x5a, flags: 0x0},
+       1129: {region: 0x165, script: 0x5a, flags: 0x0},
+       1130: {region: 0x165, script: 0x5a, flags: 0x0},
+       1131: {region: 0x123, script: 0xe6, flags: 0x0},
+       1132: {region: 0xdb, script: 0x22, flags: 0x0},
+       1133: {region: 0xdb, script: 0x22, flags: 0x0},
+       1134: {region: 0xdb, script: 0x22, flags: 0x0},
+       1135: {region: 0x6f, script: 0x2c, flags: 0x0},
+       1136: {region: 0x165, script: 0x5a, flags: 0x0},
+       1137: {region: 0x6d, script: 0x2c, flags: 0x0},
+       1138: {region: 0x165, script: 0x5a, flags: 0x0},
+       1139: {region: 0x165, script: 0x5a, flags: 0x0},
+       1140: {region: 0x165, script: 0x5a, flags: 0x0},
+       1141: {region: 0xd6, script: 0x5a, flags: 0x0},
+       1142: {region: 0x127, script: 0x5a, flags: 0x0},
+       1143: {region: 0x125, script: 0x5a, flags: 0x0},
+       1144: {region: 0x32, script: 0x5a, flags: 0x0},
+       1145: {region: 0xdb, script: 0x22, flags: 0x0},
+       1146: {region: 0xe7, script: 0x5a, flags: 0x0},
+       1147: {region: 0x165, script: 0x5a, flags: 0x0},
+       1148: {region: 0x165, script: 0x5a, flags: 0x0},
+       1149: {region: 0x32, script: 0x5a, flags: 0x0},
+       1150: {region: 0xd4, script: 0x5a, flags: 0x0},
+       1151: {region: 0x165, script: 0x5a, flags: 0x0},
+       1152: {region: 0x161, script: 0x5a, flags: 0x0},
+       1153: {region: 0x165, script: 0x5a, flags: 0x0},
+       1154: {region: 0x129, script: 0x5a, flags: 0x0},
+       1155: {region: 0x165, script: 0x5a, flags: 0x0},
+       1156: {region: 0xce, script: 0x5a, flags: 0x0},
+       1157: {region: 0x165, script: 0x5a, flags: 0x0},
+       1158: {region: 0xe6, script: 0x5a, flags: 0x0},
+       1159: {region: 0x165, script: 0x5a, flags: 0x0},
+       1160: {region: 0x165, script: 0x5a, flags: 0x0},
+       1161: {region: 0x165, script: 0x5a, flags: 0x0},
+       1162: {region: 0x12b, script: 0x5a, flags: 0x0},
+       1163: {region: 0x12b, script: 0x5a, flags: 0x0},
+       1164: {region: 0x12e, script: 0x5a, flags: 0x0},
        1165: {region: 0x165, script: 0x5, flags: 0x0},
-       1166: {region: 0x161, script: 0x57, flags: 0x0},
-       1167: {region: 0x87, script: 0x31, flags: 0x0},
-       1168: {region: 0xdb, script: 0x21, flags: 0x0},
-       1169: {region: 0xe7, script: 0x57, flags: 0x0},
-       1170: {region: 0x43, script: 0xe0, flags: 0x0},
-       1171: {region: 0x165, script: 0x57, flags: 0x0},
-       1172: {region: 0x106, script: 0x1f, flags: 0x0},
-       1173: {region: 0x165, script: 0x57, flags: 0x0},
-       1174: {region: 0x165, script: 0x57, flags: 0x0},
-       1175: {region: 0x131, script: 0x57, flags: 0x0},
-       1176: {region: 0x165, script: 0x57, flags: 0x0},
-       1177: {region: 0x123, script: 0xdf, flags: 0x0},
-       1178: {region: 0x32, script: 0x57, flags: 0x0},
-       1179: {region: 0x165, script: 0x57, flags: 0x0},
-       1180: {region: 0x165, script: 0x57, flags: 0x0},
-       1181: {region: 0xce, script: 0x57, flags: 0x0},
-       1182: {region: 0x165, script: 0x57, flags: 0x0},
-       1183: {region: 0x165, script: 0x57, flags: 0x0},
-       1184: {region: 0x12d, script: 0x57, flags: 0x0},
-       1185: {region: 0x165, script: 0x57, flags: 0x0},
-       1187: {region: 0x165, script: 0x57, flags: 0x0},
-       1188: {region: 0xd4, script: 0x57, flags: 0x0},
-       1189: {region: 0x53, script: 0xd8, flags: 0x0},
-       1190: {region: 0xe5, script: 0x57, flags: 0x0},
-       1191: {region: 0x165, script: 0x57, flags: 0x0},
-       1192: {region: 0x106, script: 0x1f, flags: 0x0},
-       1193: {region: 0xba, script: 0x57, flags: 0x0},
-       1194: {region: 0x165, script: 0x57, flags: 0x0},
-       1195: {region: 0x106, script: 0x1f, flags: 0x0},
+       1166: {region: 0x161, script: 0x5a, flags: 0x0},
+       1167: {region: 0x87, script: 0x34, flags: 0x0},
+       1168: {region: 0xdb, script: 0x22, flags: 0x0},
+       1169: {region: 0xe7, script: 0x5a, flags: 0x0},
+       1170: {region: 0x43, script: 0xe7, flags: 0x0},
+       1171: {region: 0x165, script: 0x5a, flags: 0x0},
+       1172: {region: 0x106, script: 0x20, flags: 0x0},
+       1173: {region: 0x165, script: 0x5a, flags: 0x0},
+       1174: {region: 0x165, script: 0x5a, flags: 0x0},
+       1175: {region: 0x131, script: 0x5a, flags: 0x0},
+       1176: {region: 0x165, script: 0x5a, flags: 0x0},
+       1177: {region: 0x123, script: 0xe6, flags: 0x0},
+       1178: {region: 0x32, script: 0x5a, flags: 0x0},
+       1179: {region: 0x165, script: 0x5a, flags: 0x0},
+       1180: {region: 0x165, script: 0x5a, flags: 0x0},
+       1181: {region: 0xce, script: 0x5a, flags: 0x0},
+       1182: {region: 0x165, script: 0x5a, flags: 0x0},
+       1183: {region: 0x165, script: 0x5a, flags: 0x0},
+       1184: {region: 0x12d, script: 0x5a, flags: 0x0},
+       1185: {region: 0x165, script: 0x5a, flags: 0x0},
+       1187: {region: 0x165, script: 0x5a, flags: 0x0},
+       1188: {region: 0xd4, script: 0x5a, flags: 0x0},
+       1189: {region: 0x53, script: 0xdf, flags: 0x0},
+       1190: {region: 0xe5, script: 0x5a, flags: 0x0},
+       1191: {region: 0x165, script: 0x5a, flags: 0x0},
+       1192: {region: 0x106, script: 0x20, flags: 0x0},
+       1193: {region: 0xba, script: 0x5a, flags: 0x0},
+       1194: {region: 0x165, script: 0x5a, flags: 0x0},
+       1195: {region: 0x106, script: 0x20, flags: 0x0},
        1196: {region: 0x3f, script: 0x4, flags: 0x1},
-       1197: {region: 0x11c, script: 0xe2, flags: 0x0},
-       1198: {region: 0x130, script: 0x1f, flags: 0x0},
-       1199: {region: 0x75, script: 0x57, flags: 0x0},
-       1200: {region: 0x2a, script: 0x57, flags: 0x0},
+       1197: {region: 0x11c, script: 0xea, flags: 0x0},
+       1198: {region: 0x130, script: 0x20, flags: 0x0},
+       1199: {region: 0x75, script: 0x5a, flags: 0x0},
+       1200: {region: 0x2a, script: 0x5a, flags: 0x0},
        1202: {region: 0x43, script: 0x3, flags: 0x1},
        1203: {region: 0x99, script: 0xe, flags: 0x0},
        1204: {region: 0xe8, script: 0x5, flags: 0x0},
-       1205: {region: 0x165, script: 0x57, flags: 0x0},
-       1206: {region: 0x165, script: 0x57, flags: 0x0},
-       1207: {region: 0x165, script: 0x57, flags: 0x0},
-       1208: {region: 0x165, script: 0x57, flags: 0x0},
-       1209: {region: 0x165, script: 0x57, flags: 0x0},
-       1210: {region: 0x165, script: 0x57, flags: 0x0},
-       1211: {region: 0x165, script: 0x57, flags: 0x0},
+       1205: {region: 0x165, script: 0x5a, flags: 0x0},
+       1206: {region: 0x165, script: 0x5a, flags: 0x0},
+       1207: {region: 0x165, script: 0x5a, flags: 0x0},
+       1208: {region: 0x165, script: 0x5a, flags: 0x0},
+       1209: {region: 0x165, script: 0x5a, flags: 0x0},
+       1210: {region: 0x165, script: 0x5a, flags: 0x0},
+       1211: {region: 0x165, script: 0x5a, flags: 0x0},
        1212: {region: 0x46, script: 0x4, flags: 0x1},
-       1213: {region: 0x165, script: 0x57, flags: 0x0},
-       1214: {region: 0xb4, script: 0xe3, flags: 0x0},
-       1215: {region: 0x165, script: 0x57, flags: 0x0},
-       1216: {region: 0x161, script: 0x57, flags: 0x0},
-       1217: {region: 0x9e, script: 0x57, flags: 0x0},
-       1218: {region: 0x106, script: 0x57, flags: 0x0},
-       1219: {region: 0x13e, script: 0x57, flags: 0x0},
-       1220: {region: 0x11b, script: 0x57, flags: 0x0},
-       1221: {region: 0x165, script: 0x57, flags: 0x0},
-       1222: {region: 0x36, script: 0x57, flags: 0x0},
-       1223: {region: 0x60, script: 0x57, flags: 0x0},
-       1224: {region: 0xd1, script: 0x57, flags: 0x0},
-       1225: {region: 0x1, script: 0x57, flags: 0x0},
-       1226: {region: 0x106, script: 0x57, flags: 0x0},
-       1227: {region: 0x6a, script: 0x57, flags: 0x0},
-       1228: {region: 0x12f, script: 0x57, flags: 0x0},
-       1229: {region: 0x165, script: 0x57, flags: 0x0},
-       1230: {region: 0x36, script: 0x57, flags: 0x0},
-       1231: {region: 0x4e, script: 0x57, flags: 0x0},
-       1232: {region: 0x165, script: 0x57, flags: 0x0},
-       1233: {region: 0x6f, script: 0x29, flags: 0x0},
-       1234: {region: 0x165, script: 0x57, flags: 0x0},
-       1235: {region: 0xe7, script: 0x57, flags: 0x0},
-       1236: {region: 0x2f, script: 0x57, flags: 0x0},
-       1237: {region: 0x99, script: 0xda, flags: 0x0},
-       1238: {region: 0x99, script: 0x21, flags: 0x0},
-       1239: {region: 0x165, script: 0x57, flags: 0x0},
-       1240: {region: 0x165, script: 0x57, flags: 0x0},
-       1241: {region: 0x165, script: 0x57, flags: 0x0},
-       1242: {region: 0x165, script: 0x57, flags: 0x0},
-       1243: {region: 0x165, script: 0x57, flags: 0x0},
-       1244: {region: 0x165, script: 0x57, flags: 0x0},
-       1245: {region: 0x165, script: 0x57, flags: 0x0},
-       1246: {region: 0x165, script: 0x57, flags: 0x0},
-       1247: {region: 0x165, script: 0x57, flags: 0x0},
-       1248: {region: 0x140, script: 0x57, flags: 0x0},
-       1249: {region: 0x165, script: 0x57, flags: 0x0},
-       1250: {region: 0x165, script: 0x57, flags: 0x0},
+       1213: {region: 0x165, script: 0x5a, flags: 0x0},
+       1214: {region: 0xb4, script: 0xeb, flags: 0x0},
+       1215: {region: 0x165, script: 0x5a, flags: 0x0},
+       1216: {region: 0x161, script: 0x5a, flags: 0x0},
+       1217: {region: 0x9e, script: 0x5a, flags: 0x0},
+       1218: {region: 0x106, script: 0x5a, flags: 0x0},
+       1219: {region: 0x13e, script: 0x5a, flags: 0x0},
+       1220: {region: 0x11b, script: 0x5a, flags: 0x0},
+       1221: {region: 0x165, script: 0x5a, flags: 0x0},
+       1222: {region: 0x36, script: 0x5a, flags: 0x0},
+       1223: {region: 0x60, script: 0x5a, flags: 0x0},
+       1224: {region: 0xd1, script: 0x5a, flags: 0x0},
+       1225: {region: 0x1, script: 0x5a, flags: 0x0},
+       1226: {region: 0x106, script: 0x5a, flags: 0x0},
+       1227: {region: 0x6a, script: 0x5a, flags: 0x0},
+       1228: {region: 0x12f, script: 0x5a, flags: 0x0},
+       1229: {region: 0x165, script: 0x5a, flags: 0x0},
+       1230: {region: 0x36, script: 0x5a, flags: 0x0},
+       1231: {region: 0x4e, script: 0x5a, flags: 0x0},
+       1232: {region: 0x165, script: 0x5a, flags: 0x0},
+       1233: {region: 0x6f, script: 0x2c, flags: 0x0},
+       1234: {region: 0x165, script: 0x5a, flags: 0x0},
+       1235: {region: 0xe7, script: 0x5a, flags: 0x0},
+       1236: {region: 0x2f, script: 0x5a, flags: 0x0},
+       1237: {region: 0x99, script: 0xe1, flags: 0x0},
+       1238: {region: 0x99, script: 0x22, flags: 0x0},
+       1239: {region: 0x165, script: 0x5a, flags: 0x0},
+       1240: {region: 0x165, script: 0x5a, flags: 0x0},
+       1241: {region: 0x165, script: 0x5a, flags: 0x0},
+       1242: {region: 0x165, script: 0x5a, flags: 0x0},
+       1243: {region: 0x165, script: 0x5a, flags: 0x0},
+       1244: {region: 0x165, script: 0x5a, flags: 0x0},
+       1245: {region: 0x165, script: 0x5a, flags: 0x0},
+       1246: {region: 0x165, script: 0x5a, flags: 0x0},
+       1247: {region: 0x165, script: 0x5a, flags: 0x0},
+       1248: {region: 0x140, script: 0x5a, flags: 0x0},
+       1249: {region: 0x165, script: 0x5a, flags: 0x0},
+       1250: {region: 0x165, script: 0x5a, flags: 0x0},
        1251: {region: 0xa8, script: 0x5, flags: 0x0},
-       1252: {region: 0x165, script: 0x57, flags: 0x0},
-       1253: {region: 0x114, script: 0x57, flags: 0x0},
-       1254: {region: 0x165, script: 0x57, flags: 0x0},
-       1255: {region: 0x165, script: 0x57, flags: 0x0},
-       1256: {region: 0x165, script: 0x57, flags: 0x0},
-       1257: {region: 0x165, script: 0x57, flags: 0x0},
-       1258: {region: 0x99, script: 0x21, flags: 0x0},
-       1259: {region: 0x53, script: 0x38, flags: 0x0},
-       1260: {region: 0x165, script: 0x57, flags: 0x0},
-       1261: {region: 0x165, script: 0x57, flags: 0x0},
-       1262: {region: 0x41, script: 0x57, flags: 0x0},
-       1263: {region: 0x165, script: 0x57, flags: 0x0},
+       1252: {region: 0x165, script: 0x5a, flags: 0x0},
+       1253: {region: 0x114, script: 0x5a, flags: 0x0},
+       1254: {region: 0x165, script: 0x5a, flags: 0x0},
+       1255: {region: 0x165, script: 0x5a, flags: 0x0},
+       1256: {region: 0x165, script: 0x5a, flags: 0x0},
+       1257: {region: 0x165, script: 0x5a, flags: 0x0},
+       1258: {region: 0x99, script: 0x22, flags: 0x0},
+       1259: {region: 0x53, script: 0x3b, flags: 0x0},
+       1260: {region: 0x165, script: 0x5a, flags: 0x0},
+       1261: {region: 0x165, script: 0x5a, flags: 0x0},
+       1262: {region: 0x41, script: 0x5a, flags: 0x0},
+       1263: {region: 0x165, script: 0x5a, flags: 0x0},
        1264: {region: 0x12b, script: 0x18, flags: 0x0},
-       1265: {region: 0x165, script: 0x57, flags: 0x0},
-       1266: {region: 0x161, script: 0x57, flags: 0x0},
-       1267: {region: 0x165, script: 0x57, flags: 0x0},
-       1268: {region: 0x12b, script: 0x5f, flags: 0x0},
-       1269: {region: 0x12b, script: 0x60, flags: 0x0},
-       1270: {region: 0x7d, script: 0x2b, flags: 0x0},
-       1271: {region: 0x53, script: 0x64, flags: 0x0},
-       1272: {region: 0x10b, script: 0x69, flags: 0x0},
-       1273: {region: 0x108, script: 0x73, flags: 0x0},
-       1274: {region: 0x99, script: 0x21, flags: 0x0},
-       1275: {region: 0x131, script: 0x57, flags: 0x0},
-       1276: {region: 0x165, script: 0x57, flags: 0x0},
-       1277: {region: 0x9c, script: 0x8a, flags: 0x0},
-       1278: {region: 0x165, script: 0x57, flags: 0x0},
-       1279: {region: 0x15e, script: 0xc2, flags: 0x0},
-       1280: {region: 0x165, script: 0x57, flags: 0x0},
-       1281: {region: 0x165, script: 0x57, flags: 0x0},
-       1282: {region: 0xdb, script: 0x21, flags: 0x0},
-       1283: {region: 0x165, script: 0x57, flags: 0x0},
-       1284: {region: 0x165, script: 0x57, flags: 0x0},
-       1285: {region: 0xd1, script: 0x57, flags: 0x0},
-       1286: {region: 0x75, script: 0x57, flags: 0x0},
-       1287: {region: 0x165, script: 0x57, flags: 0x0},
-       1288: {region: 0x165, script: 0x57, flags: 0x0},
-       1289: {region: 0x52, script: 0x57, flags: 0x0},
-       1290: {region: 0x165, script: 0x57, flags: 0x0},
-       1291: {region: 0x165, script: 0x57, flags: 0x0},
-       1292: {region: 0x165, script: 0x57, flags: 0x0},
-       1293: {region: 0x52, script: 0x57, flags: 0x0},
-       1294: {region: 0x165, script: 0x57, flags: 0x0},
-       1295: {region: 0x165, script: 0x57, flags: 0x0},
-       1296: {region: 0x165, script: 0x57, flags: 0x0},
-       1297: {region: 0x165, script: 0x57, flags: 0x0},
-       1298: {region: 0x1, script: 0x3b, flags: 0x0},
-       1299: {region: 0x165, script: 0x57, flags: 0x0},
-       1300: {region: 0x165, script: 0x57, flags: 0x0},
-       1301: {region: 0x165, script: 0x57, flags: 0x0},
-       1302: {region: 0x165, script: 0x57, flags: 0x0},
-       1303: {region: 0x165, script: 0x57, flags: 0x0},
-       1304: {region: 0xd6, script: 0x57, flags: 0x0},
-       1305: {region: 0x165, script: 0x57, flags: 0x0},
-       1306: {region: 0x165, script: 0x57, flags: 0x0},
-       1307: {region: 0x165, script: 0x57, flags: 0x0},
-       1308: {region: 0x41, script: 0x57, flags: 0x0},
-       1309: {region: 0x165, script: 0x57, flags: 0x0},
-       1310: {region: 0xcf, script: 0x57, flags: 0x0},
+       1265: {region: 0x165, script: 0x5a, flags: 0x0},
+       1266: {region: 0x161, script: 0x5a, flags: 0x0},
+       1267: {region: 0x165, script: 0x5a, flags: 0x0},
+       1268: {region: 0x12b, script: 0x62, flags: 0x0},
+       1269: {region: 0x12b, script: 0x63, flags: 0x0},
+       1270: {region: 0x7d, script: 0x2e, flags: 0x0},
+       1271: {region: 0x53, script: 0x67, flags: 0x0},
+       1272: {region: 0x10b, script: 0x6c, flags: 0x0},
+       1273: {region: 0x108, script: 0x77, flags: 0x0},
+       1274: {region: 0x99, script: 0x22, flags: 0x0},
+       1275: {region: 0x131, script: 0x5a, flags: 0x0},
+       1276: {region: 0x165, script: 0x5a, flags: 0x0},
+       1277: {region: 0x9c, script: 0x8e, flags: 0x0},
+       1278: {region: 0x165, script: 0x5a, flags: 0x0},
+       1279: {region: 0x15e, script: 0xc7, flags: 0x0},
+       1280: {region: 0x165, script: 0x5a, flags: 0x0},
+       1281: {region: 0x165, script: 0x5a, flags: 0x0},
+       1282: {region: 0xdb, script: 0x22, flags: 0x0},
+       1283: {region: 0x165, script: 0x5a, flags: 0x0},
+       1284: {region: 0x165, script: 0x5a, flags: 0x0},
+       1285: {region: 0xd1, script: 0x5a, flags: 0x0},
+       1286: {region: 0x75, script: 0x5a, flags: 0x0},
+       1287: {region: 0x165, script: 0x5a, flags: 0x0},
+       1288: {region: 0x165, script: 0x5a, flags: 0x0},
+       1289: {region: 0x52, script: 0x5a, flags: 0x0},
+       1290: {region: 0x165, script: 0x5a, flags: 0x0},
+       1291: {region: 0x165, script: 0x5a, flags: 0x0},
+       1292: {region: 0x165, script: 0x5a, flags: 0x0},
+       1293: {region: 0x52, script: 0x5a, flags: 0x0},
+       1294: {region: 0x165, script: 0x5a, flags: 0x0},
+       1295: {region: 0x165, script: 0x5a, flags: 0x0},
+       1296: {region: 0x165, script: 0x5a, flags: 0x0},
+       1297: {region: 0x165, script: 0x5a, flags: 0x0},
+       1298: {region: 0x1, script: 0x3e, flags: 0x0},
+       1299: {region: 0x165, script: 0x5a, flags: 0x0},
+       1300: {region: 0x165, script: 0x5a, flags: 0x0},
+       1301: {region: 0x165, script: 0x5a, flags: 0x0},
+       1302: {region: 0x165, script: 0x5a, flags: 0x0},
+       1303: {region: 0x165, script: 0x5a, flags: 0x0},
+       1304: {region: 0xd6, script: 0x5a, flags: 0x0},
+       1305: {region: 0x165, script: 0x5a, flags: 0x0},
+       1306: {region: 0x165, script: 0x5a, flags: 0x0},
+       1307: {region: 0x165, script: 0x5a, flags: 0x0},
+       1308: {region: 0x41, script: 0x5a, flags: 0x0},
+       1309: {region: 0x165, script: 0x5a, flags: 0x0},
+       1310: {region: 0xcf, script: 0x5a, flags: 0x0},
        1311: {region: 0x4a, script: 0x3, flags: 0x1},
-       1312: {region: 0x165, script: 0x57, flags: 0x0},
-       1313: {region: 0x165, script: 0x57, flags: 0x0},
-       1314: {region: 0x165, script: 0x57, flags: 0x0},
-       1315: {region: 0x53, script: 0x57, flags: 0x0},
-       1316: {region: 0x10b, script: 0x57, flags: 0x0},
+       1312: {region: 0x165, script: 0x5a, flags: 0x0},
+       1313: {region: 0x165, script: 0x5a, flags: 0x0},
+       1314: {region: 0x165, script: 0x5a, flags: 0x0},
+       1315: {region: 0x53, script: 0x5a, flags: 0x0},
+       1316: {region: 0x10b, script: 0x5a, flags: 0x0},
        1318: {region: 0xa8, script: 0x5, flags: 0x0},
-       1319: {region: 0xd9, script: 0x57, flags: 0x0},
-       1320: {region: 0xba, script: 0xdc, flags: 0x0},
+       1319: {region: 0xd9, script: 0x5a, flags: 0x0},
+       1320: {region: 0xba, script: 0xe3, flags: 0x0},
        1321: {region: 0x4d, script: 0x14, flags: 0x1},
-       1322: {region: 0x53, script: 0x79, flags: 0x0},
-       1323: {region: 0x165, script: 0x57, flags: 0x0},
-       1324: {region: 0x122, script: 0x57, flags: 0x0},
-       1325: {region: 0xd0, script: 0x57, flags: 0x0},
-       1326: {region: 0x165, script: 0x57, flags: 0x0},
-       1327: {region: 0x161, script: 0x57, flags: 0x0},
-       1329: {region: 0x12b, script: 0x57, flags: 0x0},
+       1322: {region: 0x53, script: 0x7d, flags: 0x0},
+       1323: {region: 0x165, script: 0x5a, flags: 0x0},
+       1324: {region: 0x122, script: 0x5a, flags: 0x0},
+       1325: {region: 0xd0, script: 0x5a, flags: 0x0},
+       1326: {region: 0x165, script: 0x5a, flags: 0x0},
+       1327: {region: 0x161, script: 0x5a, flags: 0x0},
+       1329: {region: 0x12b, script: 0x5a, flags: 0x0},
 }
 
 // likelyLangList holds lists info associated with likelyLang.
 // Size: 388 bytes, 97 elements
 var likelyLangList = [97]likelyScriptRegion{
        0:  {region: 0x9c, script: 0x7, flags: 0x0},
-       1:  {region: 0xa1, script: 0x74, flags: 0x2},
-       2:  {region: 0x11c, script: 0x80, flags: 0x2},
-       3:  {region: 0x32, script: 0x57, flags: 0x0},
+       1:  {region: 0xa1, script: 0x78, flags: 0x2},
+       2:  {region: 0x11c, script: 0x84, flags: 0x2},
+       3:  {region: 0x32, script: 0x5a, flags: 0x0},
        4:  {region: 0x9b, script: 0x5, flags: 0x4},
        5:  {region: 0x9c, script: 0x5, flags: 0x4},
-       6:  {region: 0x106, script: 0x1f, flags: 0x4},
+       6:  {region: 0x106, script: 0x20, flags: 0x4},
        7:  {region: 0x9c, script: 0x5, flags: 0x2},
-       8:  {region: 0x106, script: 0x1f, flags: 0x0},
-       9:  {region: 0x38, script: 0x2c, flags: 0x2},
-       10: {region: 0x135, script: 0x57, flags: 0x0},
-       11: {region: 0x7b, script: 0xc5, flags: 0x2},
-       12: {region: 0x114, script: 0x57, flags: 0x0},
+       8:  {region: 0x106, script: 0x20, flags: 0x0},
+       9:  {region: 0x38, script: 0x2f, flags: 0x2},
+       10: {region: 0x135, script: 0x5a, flags: 0x0},
+       11: {region: 0x7b, script: 0xca, flags: 0x2},
+       12: {region: 0x114, script: 0x5a, flags: 0x0},
        13: {region: 0x84, script: 0x1, flags: 0x2},
-       14: {region: 0x5d, script: 0x1e, flags: 0x0},
-       15: {region: 0x87, script: 0x5c, flags: 0x2},
-       16: {region: 0xd6, script: 0x57, flags: 0x0},
+       14: {region: 0x5d, script: 0x1f, flags: 0x0},
+       15: {region: 0x87, script: 0x5f, flags: 0x2},
+       16: {region: 0xd6, script: 0x5a, flags: 0x0},
        17: {region: 0x52, script: 0x5, flags: 0x4},
        18: {region: 0x10b, script: 0x5, flags: 0x4},
-       19: {region: 0xae, script: 0x1f, flags: 0x0},
+       19: {region: 0xae, script: 0x20, flags: 0x0},
        20: {region: 0x24, script: 0x5, flags: 0x4},
        21: {region: 0x53, script: 0x5, flags: 0x4},
        22: {region: 0x9c, script: 0x5, flags: 0x4},
        23: {region: 0xc5, script: 0x5, flags: 0x4},
        24: {region: 0x53, script: 0x5, flags: 0x2},
-       25: {region: 0x12b, script: 0x57, flags: 0x0},
+       25: {region: 0x12b, script: 0x5a, flags: 0x0},
        26: {region: 0xb0, script: 0x5, flags: 0x4},
        27: {region: 0x9b, script: 0x5, flags: 0x2},
-       28: {region: 0xa5, script: 0x1f, flags: 0x0},
+       28: {region: 0xa5, script: 0x20, flags: 0x0},
        29: {region: 0x53, script: 0x5, flags: 0x4},
-       30: {region: 0x12b, script: 0x57, flags: 0x4},
+       30: {region: 0x12b, script: 0x5a, flags: 0x4},
        31: {region: 0x53, script: 0x5, flags: 0x2},
-       32: {region: 0x12b, script: 0x57, flags: 0x2},
-       33: {region: 0xdb, script: 0x21, flags: 0x0},
-       34: {region: 0x99, script: 0x5a, flags: 0x2},
-       35: {region: 0x83, script: 0x57, flags: 0x0},
-       36: {region: 0x84, script: 0x78, flags: 0x4},
-       37: {region: 0x84, script: 0x78, flags: 0x2},
-       38: {region: 0xc5, script: 0x1f, flags: 0x0},
-       39: {region: 0x53, script: 0x6d, flags: 0x4},
-       40: {region: 0x53, script: 0x6d, flags: 0x2},
-       41: {region: 0xd0, script: 0x57, flags: 0x0},
+       32: {region: 0x12b, script: 0x5a, flags: 0x2},
+       33: {region: 0xdb, script: 0x22, flags: 0x0},
+       34: {region: 0x99, script: 0x5d, flags: 0x2},
+       35: {region: 0x83, script: 0x5a, flags: 0x0},
+       36: {region: 0x84, script: 0x7c, flags: 0x4},
+       37: {region: 0x84, script: 0x7c, flags: 0x2},
+       38: {region: 0xc5, script: 0x20, flags: 0x0},
+       39: {region: 0x53, script: 0x70, flags: 0x4},
+       40: {region: 0x53, script: 0x70, flags: 0x2},
+       41: {region: 0xd0, script: 0x5a, flags: 0x0},
        42: {region: 0x4a, script: 0x5, flags: 0x4},
        43: {region: 0x95, script: 0x5, flags: 0x4},
-       44: {region: 0x99, script: 0x33, flags: 0x0},
+       44: {region: 0x99, script: 0x36, flags: 0x0},
        45: {region: 0xe8, script: 0x5, flags: 0x4},
        46: {region: 0xe8, script: 0x5, flags: 0x2},
-       47: {region: 0x9c, script: 0x84, flags: 0x0},
-       48: {region: 0x53, script: 0x85, flags: 0x2},
-       49: {region: 0xba, script: 0xdc, flags: 0x0},
-       50: {region: 0xd9, script: 0x57, flags: 0x4},
+       47: {region: 0x9c, script: 0x88, flags: 0x0},
+       48: {region: 0x53, script: 0x89, flags: 0x2},
+       49: {region: 0xba, script: 0xe3, flags: 0x0},
+       50: {region: 0xd9, script: 0x5a, flags: 0x4},
        51: {region: 0xe8, script: 0x5, flags: 0x0},
-       52: {region: 0x99, script: 0x21, flags: 0x2},
-       53: {region: 0x99, script: 0x4c, flags: 0x2},
-       54: {region: 0x99, script: 0xc9, flags: 0x2},
-       55: {region: 0x105, script: 0x1f, flags: 0x0},
-       56: {region: 0xbd, script: 0x57, flags: 0x4},
-       57: {region: 0x104, script: 0x57, flags: 0x4},
-       58: {region: 0x106, script: 0x57, flags: 0x4},
-       59: {region: 0x12b, script: 0x57, flags: 0x4},
-       60: {region: 0x124, script: 0x1f, flags: 0x0},
+       52: {region: 0x99, script: 0x22, flags: 0x2},
+       53: {region: 0x99, script: 0x4f, flags: 0x2},
+       54: {region: 0x99, script: 0xce, flags: 0x2},
+       55: {region: 0x105, script: 0x20, flags: 0x0},
+       56: {region: 0xbd, script: 0x5a, flags: 0x4},
+       57: {region: 0x104, script: 0x5a, flags: 0x4},
+       58: {region: 0x106, script: 0x5a, flags: 0x4},
+       59: {region: 0x12b, script: 0x5a, flags: 0x4},
+       60: {region: 0x124, script: 0x20, flags: 0x0},
        61: {region: 0xe8, script: 0x5, flags: 0x4},
        62: {region: 0xe8, script: 0x5, flags: 0x2},
        63: {region: 0x53, script: 0x5, flags: 0x0},
-       64: {region: 0xae, script: 0x1f, flags: 0x4},
-       65: {region: 0xc5, script: 0x1f, flags: 0x4},
-       66: {region: 0xae, script: 0x1f, flags: 0x2},
+       64: {region: 0xae, script: 0x20, flags: 0x4},
+       65: {region: 0xc5, script: 0x20, flags: 0x4},
+       66: {region: 0xae, script: 0x20, flags: 0x2},
        67: {region: 0x99, script: 0xe, flags: 0x0},
-       68: {region: 0xdb, script: 0x21, flags: 0x4},
-       69: {region: 0xdb, script: 0x21, flags: 0x2},
-       70: {region: 0x137, script: 0x57, flags: 0x0},
+       68: {region: 0xdb, script: 0x22, flags: 0x4},
+       69: {region: 0xdb, script: 0x22, flags: 0x2},
+       70: {region: 0x137, script: 0x5a, flags: 0x0},
        71: {region: 0x24, script: 0x5, flags: 0x4},
-       72: {region: 0x53, script: 0x1f, flags: 0x4},
+       72: {region: 0x53, script: 0x20, flags: 0x4},
        73: {region: 0x24, script: 0x5, flags: 0x2},
-       74: {region: 0x8d, script: 0x39, flags: 0x0},
-       75: {region: 0x53, script: 0x38, flags: 0x4},
-       76: {region: 0x53, script: 0x38, flags: 0x2},
-       77: {region: 0x53, script: 0x38, flags: 0x0},
-       78: {region: 0x2f, script: 0x39, flags: 0x4},
-       79: {region: 0x3e, script: 0x39, flags: 0x4},
-       80: {region: 0x7b, script: 0x39, flags: 0x4},
-       81: {region: 0x7e, script: 0x39, flags: 0x4},
-       82: {region: 0x8d, script: 0x39, flags: 0x4},
-       83: {region: 0x95, script: 0x39, flags: 0x4},
-       84: {region: 0xc6, script: 0x39, flags: 0x4},
-       85: {region: 0xd0, script: 0x39, flags: 0x4},
-       86: {region: 0xe2, script: 0x39, flags: 0x4},
-       87: {region: 0xe5, script: 0x39, flags: 0x4},
-       88: {region: 0xe7, script: 0x39, flags: 0x4},
-       89: {region: 0x116, script: 0x39, flags: 0x4},
-       90: {region: 0x123, script: 0x39, flags: 0x4},
-       91: {region: 0x12e, script: 0x39, flags: 0x4},
-       92: {region: 0x135, script: 0x39, flags: 0x4},
-       93: {region: 0x13e, script: 0x39, flags: 0x4},
+       74: {region: 0x8d, script: 0x3c, flags: 0x0},
+       75: {region: 0x53, script: 0x3b, flags: 0x4},
+       76: {region: 0x53, script: 0x3b, flags: 0x2},
+       77: {region: 0x53, script: 0x3b, flags: 0x0},
+       78: {region: 0x2f, script: 0x3c, flags: 0x4},
+       79: {region: 0x3e, script: 0x3c, flags: 0x4},
+       80: {region: 0x7b, script: 0x3c, flags: 0x4},
+       81: {region: 0x7e, script: 0x3c, flags: 0x4},
+       82: {region: 0x8d, script: 0x3c, flags: 0x4},
+       83: {region: 0x95, script: 0x3c, flags: 0x4},
+       84: {region: 0xc6, script: 0x3c, flags: 0x4},
+       85: {region: 0xd0, script: 0x3c, flags: 0x4},
+       86: {region: 0xe2, script: 0x3c, flags: 0x4},
+       87: {region: 0xe5, script: 0x3c, flags: 0x4},
+       88: {region: 0xe7, script: 0x3c, flags: 0x4},
+       89: {region: 0x116, script: 0x3c, flags: 0x4},
+       90: {region: 0x123, script: 0x3c, flags: 0x4},
+       91: {region: 0x12e, script: 0x3c, flags: 0x4},
+       92: {region: 0x135, script: 0x3c, flags: 0x4},
+       93: {region: 0x13e, script: 0x3c, flags: 0x4},
        94: {region: 0x12e, script: 0x11, flags: 0x2},
-       95: {region: 0x12e, script: 0x34, flags: 0x2},
-       96: {region: 0x12e, script: 0x39, flags: 0x2},
+       95: {region: 0x12e, script: 0x37, flags: 0x2},
+       96: {region: 0x12e, script: 0x3c, flags: 0x2},
 }
 
 type likelyLangScript struct {
@@ -2948,304 +2981,304 @@ type likelyLangScript struct {
 // TODO: exclude containers and user-definable regions from the list.
 // Size: 1432 bytes, 358 elements
 var likelyRegion = [358]likelyLangScript{
-       34:  {lang: 0xd7, script: 0x57, flags: 0x0},
+       34:  {lang: 0xd7, script: 0x5a, flags: 0x0},
        35:  {lang: 0x3a, script: 0x5, flags: 0x0},
        36:  {lang: 0x0, script: 0x2, flags: 0x1},
        39:  {lang: 0x2, script: 0x2, flags: 0x1},
        40:  {lang: 0x4, script: 0x2, flags: 0x1},
-       42:  {lang: 0x3c0, script: 0x57, flags: 0x0},
-       43:  {lang: 0x0, script: 0x57, flags: 0x0},
-       44:  {lang: 0x13e, script: 0x57, flags: 0x0},
-       45:  {lang: 0x41b, script: 0x57, flags: 0x0},
-       46:  {lang: 0x10d, script: 0x57, flags: 0x0},
-       48:  {lang: 0x367, script: 0x57, flags: 0x0},
-       49:  {lang: 0x444, script: 0x57, flags: 0x0},
-       50:  {lang: 0x58, script: 0x57, flags: 0x0},
+       42:  {lang: 0x3c0, script: 0x5a, flags: 0x0},
+       43:  {lang: 0x0, script: 0x5a, flags: 0x0},
+       44:  {lang: 0x13e, script: 0x5a, flags: 0x0},
+       45:  {lang: 0x41b, script: 0x5a, flags: 0x0},
+       46:  {lang: 0x10d, script: 0x5a, flags: 0x0},
+       48:  {lang: 0x367, script: 0x5a, flags: 0x0},
+       49:  {lang: 0x444, script: 0x5a, flags: 0x0},
+       50:  {lang: 0x58, script: 0x5a, flags: 0x0},
        51:  {lang: 0x6, script: 0x2, flags: 0x1},
        53:  {lang: 0xa5, script: 0xe, flags: 0x0},
-       54:  {lang: 0x367, script: 0x57, flags: 0x0},
-       55:  {lang: 0x15e, script: 0x57, flags: 0x0},
-       56:  {lang: 0x7e, script: 0x1f, flags: 0x0},
+       54:  {lang: 0x367, script: 0x5a, flags: 0x0},
+       55:  {lang: 0x15e, script: 0x5a, flags: 0x0},
+       56:  {lang: 0x7e, script: 0x20, flags: 0x0},
        57:  {lang: 0x3a, script: 0x5, flags: 0x0},
-       58:  {lang: 0x3d9, script: 0x57, flags: 0x0},
-       59:  {lang: 0x15e, script: 0x57, flags: 0x0},
-       60:  {lang: 0x15e, script: 0x57, flags: 0x0},
-       62:  {lang: 0x31f, script: 0x57, flags: 0x0},
-       63:  {lang: 0x13e, script: 0x57, flags: 0x0},
-       64:  {lang: 0x3a1, script: 0x57, flags: 0x0},
-       65:  {lang: 0x3c0, script: 0x57, flags: 0x0},
+       58:  {lang: 0x3d9, script: 0x5a, flags: 0x0},
+       59:  {lang: 0x15e, script: 0x5a, flags: 0x0},
+       60:  {lang: 0x15e, script: 0x5a, flags: 0x0},
+       62:  {lang: 0x31f, script: 0x5a, flags: 0x0},
+       63:  {lang: 0x13e, script: 0x5a, flags: 0x0},
+       64:  {lang: 0x3a1, script: 0x5a, flags: 0x0},
+       65:  {lang: 0x3c0, script: 0x5a, flags: 0x0},
        67:  {lang: 0x8, script: 0x2, flags: 0x1},
-       69:  {lang: 0x0, script: 0x57, flags: 0x0},
-       71:  {lang: 0x71, script: 0x1f, flags: 0x0},
-       73:  {lang: 0x512, script: 0x3b, flags: 0x2},
+       69:  {lang: 0x0, script: 0x5a, flags: 0x0},
+       71:  {lang: 0x71, script: 0x20, flags: 0x0},
+       73:  {lang: 0x512, script: 0x3e, flags: 0x2},
        74:  {lang: 0x31f, script: 0x5, flags: 0x2},
-       75:  {lang: 0x445, script: 0x57, flags: 0x0},
-       76:  {lang: 0x15e, script: 0x57, flags: 0x0},
-       77:  {lang: 0x15e, script: 0x57, flags: 0x0},
-       78:  {lang: 0x10d, script: 0x57, flags: 0x0},
-       79:  {lang: 0x15e, script: 0x57, flags: 0x0},
-       81:  {lang: 0x13e, script: 0x57, flags: 0x0},
-       82:  {lang: 0x15e, script: 0x57, flags: 0x0},
+       75:  {lang: 0x445, script: 0x5a, flags: 0x0},
+       76:  {lang: 0x15e, script: 0x5a, flags: 0x0},
+       77:  {lang: 0x15e, script: 0x5a, flags: 0x0},
+       78:  {lang: 0x10d, script: 0x5a, flags: 0x0},
+       79:  {lang: 0x15e, script: 0x5a, flags: 0x0},
+       81:  {lang: 0x13e, script: 0x5a, flags: 0x0},
+       82:  {lang: 0x15e, script: 0x5a, flags: 0x0},
        83:  {lang: 0xa, script: 0x4, flags: 0x1},
-       84:  {lang: 0x13e, script: 0x57, flags: 0x0},
-       85:  {lang: 0x0, script: 0x57, flags: 0x0},
-       86:  {lang: 0x13e, script: 0x57, flags: 0x0},
-       89:  {lang: 0x13e, script: 0x57, flags: 0x0},
-       90:  {lang: 0x3c0, script: 0x57, flags: 0x0},
-       91:  {lang: 0x3a1, script: 0x57, flags: 0x0},
+       84:  {lang: 0x13e, script: 0x5a, flags: 0x0},
+       85:  {lang: 0x0, script: 0x5a, flags: 0x0},
+       86:  {lang: 0x13e, script: 0x5a, flags: 0x0},
+       89:  {lang: 0x13e, script: 0x5a, flags: 0x0},
+       90:  {lang: 0x3c0, script: 0x5a, flags: 0x0},
+       91:  {lang: 0x3a1, script: 0x5a, flags: 0x0},
        93:  {lang: 0xe, script: 0x2, flags: 0x1},
-       94:  {lang: 0xfa, script: 0x57, flags: 0x0},
-       96:  {lang: 0x10d, script: 0x57, flags: 0x0},
-       98:  {lang: 0x1, script: 0x57, flags: 0x0},
-       99:  {lang: 0x101, script: 0x57, flags: 0x0},
-       101: {lang: 0x13e, script: 0x57, flags: 0x0},
+       94:  {lang: 0xfa, script: 0x5a, flags: 0x0},
+       96:  {lang: 0x10d, script: 0x5a, flags: 0x0},
+       98:  {lang: 0x1, script: 0x5a, flags: 0x0},
+       99:  {lang: 0x101, script: 0x5a, flags: 0x0},
+       101: {lang: 0x13e, script: 0x5a, flags: 0x0},
        103: {lang: 0x10, script: 0x2, flags: 0x1},
-       104: {lang: 0x13e, script: 0x57, flags: 0x0},
-       105: {lang: 0x13e, script: 0x57, flags: 0x0},
-       106: {lang: 0x140, script: 0x57, flags: 0x0},
+       104: {lang: 0x13e, script: 0x5a, flags: 0x0},
+       105: {lang: 0x13e, script: 0x5a, flags: 0x0},
+       106: {lang: 0x140, script: 0x5a, flags: 0x0},
        107: {lang: 0x3a, script: 0x5, flags: 0x0},
        108: {lang: 0x3a, script: 0x5, flags: 0x0},
-       109: {lang: 0x46f, script: 0x29, flags: 0x0},
-       110: {lang: 0x13e, script: 0x57, flags: 0x0},
+       109: {lang: 0x46f, script: 0x2c, flags: 0x0},
+       110: {lang: 0x13e, script: 0x5a, flags: 0x0},
        111: {lang: 0x12, script: 0x2, flags: 0x1},
-       113: {lang: 0x10d, script: 0x57, flags: 0x0},
-       114: {lang: 0x151, script: 0x57, flags: 0x0},
-       115: {lang: 0x1c0, script: 0x21, flags: 0x2},
-       118: {lang: 0x158, script: 0x57, flags: 0x0},
-       120: {lang: 0x15e, script: 0x57, flags: 0x0},
-       122: {lang: 0x15e, script: 0x57, flags: 0x0},
+       113: {lang: 0x10d, script: 0x5a, flags: 0x0},
+       114: {lang: 0x151, script: 0x5a, flags: 0x0},
+       115: {lang: 0x1c0, script: 0x22, flags: 0x2},
+       118: {lang: 0x158, script: 0x5a, flags: 0x0},
+       120: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       122: {lang: 0x15e, script: 0x5a, flags: 0x0},
        123: {lang: 0x14, script: 0x2, flags: 0x1},
        125: {lang: 0x16, script: 0x3, flags: 0x1},
-       126: {lang: 0x15e, script: 0x57, flags: 0x0},
-       128: {lang: 0x21, script: 0x57, flags: 0x0},
-       130: {lang: 0x245, script: 0x57, flags: 0x0},
-       132: {lang: 0x15e, script: 0x57, flags: 0x0},
-       133: {lang: 0x15e, script: 0x57, flags: 0x0},
-       134: {lang: 0x13e, script: 0x57, flags: 0x0},
+       126: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       128: {lang: 0x21, script: 0x5a, flags: 0x0},
+       130: {lang: 0x245, script: 0x5a, flags: 0x0},
+       132: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       133: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       134: {lang: 0x13e, script: 0x5a, flags: 0x0},
        135: {lang: 0x19, script: 0x2, flags: 0x1},
-       136: {lang: 0x0, script: 0x57, flags: 0x0},
-       137: {lang: 0x13e, script: 0x57, flags: 0x0},
-       139: {lang: 0x3c0, script: 0x57, flags: 0x0},
-       141: {lang: 0x529, script: 0x39, flags: 0x0},
-       142: {lang: 0x0, script: 0x57, flags: 0x0},
-       143: {lang: 0x13e, script: 0x57, flags: 0x0},
-       144: {lang: 0x1d1, script: 0x57, flags: 0x0},
-       145: {lang: 0x1d4, script: 0x57, flags: 0x0},
-       146: {lang: 0x1d5, script: 0x57, flags: 0x0},
-       148: {lang: 0x13e, script: 0x57, flags: 0x0},
+       136: {lang: 0x0, script: 0x5a, flags: 0x0},
+       137: {lang: 0x13e, script: 0x5a, flags: 0x0},
+       139: {lang: 0x3c0, script: 0x5a, flags: 0x0},
+       141: {lang: 0x529, script: 0x3c, flags: 0x0},
+       142: {lang: 0x0, script: 0x5a, flags: 0x0},
+       143: {lang: 0x13e, script: 0x5a, flags: 0x0},
+       144: {lang: 0x1d1, script: 0x5a, flags: 0x0},
+       145: {lang: 0x1d4, script: 0x5a, flags: 0x0},
+       146: {lang: 0x1d5, script: 0x5a, flags: 0x0},
+       148: {lang: 0x13e, script: 0x5a, flags: 0x0},
        149: {lang: 0x1b, script: 0x2, flags: 0x1},
-       151: {lang: 0x1bc, script: 0x3b, flags: 0x0},
+       151: {lang: 0x1bc, script: 0x3e, flags: 0x0},
        153: {lang: 0x1d, script: 0x3, flags: 0x1},
        155: {lang: 0x3a, script: 0x5, flags: 0x0},
        156: {lang: 0x20, script: 0x2, flags: 0x1},
-       157: {lang: 0x1f8, script: 0x57, flags: 0x0},
-       158: {lang: 0x1f9, script: 0x57, flags: 0x0},
+       157: {lang: 0x1f8, script: 0x5a, flags: 0x0},
+       158: {lang: 0x1f9, script: 0x5a, flags: 0x0},
        161: {lang: 0x3a, script: 0x5, flags: 0x0},
-       162: {lang: 0x200, script: 0x46, flags: 0x0},
-       164: {lang: 0x445, script: 0x57, flags: 0x0},
-       165: {lang: 0x28a, script: 0x1f, flags: 0x0},
+       162: {lang: 0x200, script: 0x49, flags: 0x0},
+       164: {lang: 0x445, script: 0x5a, flags: 0x0},
+       165: {lang: 0x28a, script: 0x20, flags: 0x0},
        166: {lang: 0x22, script: 0x3, flags: 0x1},
        168: {lang: 0x25, script: 0x2, flags: 0x1},
-       170: {lang: 0x254, script: 0x50, flags: 0x0},
-       171: {lang: 0x254, script: 0x50, flags: 0x0},
+       170: {lang: 0x254, script: 0x53, flags: 0x0},
+       171: {lang: 0x254, script: 0x53, flags: 0x0},
        172: {lang: 0x3a, script: 0x5, flags: 0x0},
-       174: {lang: 0x3e2, script: 0x1f, flags: 0x0},
+       174: {lang: 0x3e2, script: 0x20, flags: 0x0},
        175: {lang: 0x27, script: 0x2, flags: 0x1},
        176: {lang: 0x3a, script: 0x5, flags: 0x0},
-       178: {lang: 0x10d, script: 0x57, flags: 0x0},
-       179: {lang: 0x40c, script: 0xca, flags: 0x0},
-       181: {lang: 0x43b, script: 0x57, flags: 0x0},
-       182: {lang: 0x2c0, script: 0x57, flags: 0x0},
-       183: {lang: 0x15e, script: 0x57, flags: 0x0},
-       184: {lang: 0x2c7, script: 0x57, flags: 0x0},
+       178: {lang: 0x10d, script: 0x5a, flags: 0x0},
+       179: {lang: 0x40c, script: 0xcf, flags: 0x0},
+       181: {lang: 0x43b, script: 0x5a, flags: 0x0},
+       182: {lang: 0x2c0, script: 0x5a, flags: 0x0},
+       183: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       184: {lang: 0x2c7, script: 0x5a, flags: 0x0},
        185: {lang: 0x3a, script: 0x5, flags: 0x0},
        186: {lang: 0x29, script: 0x2, flags: 0x1},
-       187: {lang: 0x15e, script: 0x57, flags: 0x0},
+       187: {lang: 0x15e, script: 0x5a, flags: 0x0},
        188: {lang: 0x2b, script: 0x2, flags: 0x1},
-       189: {lang: 0x432, script: 0x57, flags: 0x0},
-       190: {lang: 0x15e, script: 0x57, flags: 0x0},
-       191: {lang: 0x2f1, script: 0x57, flags: 0x0},
+       189: {lang: 0x432, script: 0x5a, flags: 0x0},
+       190: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       191: {lang: 0x2f1, script: 0x5a, flags: 0x0},
        194: {lang: 0x2d, script: 0x2, flags: 0x1},
-       195: {lang: 0xa0, script: 0x57, flags: 0x0},
+       195: {lang: 0xa0, script: 0x5a, flags: 0x0},
        196: {lang: 0x2f, script: 0x2, flags: 0x1},
        197: {lang: 0x31, script: 0x2, flags: 0x1},
        198: {lang: 0x33, script: 0x2, flags: 0x1},
-       200: {lang: 0x15e, script: 0x57, flags: 0x0},
+       200: {lang: 0x15e, script: 0x5a, flags: 0x0},
        201: {lang: 0x35, script: 0x2, flags: 0x1},
-       203: {lang: 0x320, script: 0x57, flags: 0x0},
+       203: {lang: 0x320, script: 0x5a, flags: 0x0},
        204: {lang: 0x37, script: 0x3, flags: 0x1},
-       205: {lang: 0x128, script: 0xde, flags: 0x0},
-       207: {lang: 0x13e, script: 0x57, flags: 0x0},
-       208: {lang: 0x31f, script: 0x57, flags: 0x0},
-       209: {lang: 0x3c0, script: 0x57, flags: 0x0},
-       210: {lang: 0x16, script: 0x57, flags: 0x0},
-       211: {lang: 0x15e, script: 0x57, flags: 0x0},
-       212: {lang: 0x1b4, script: 0x57, flags: 0x0},
+       205: {lang: 0x128, script: 0xe5, flags: 0x0},
+       207: {lang: 0x13e, script: 0x5a, flags: 0x0},
+       208: {lang: 0x31f, script: 0x5a, flags: 0x0},
+       209: {lang: 0x3c0, script: 0x5a, flags: 0x0},
+       210: {lang: 0x16, script: 0x5a, flags: 0x0},
+       211: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       212: {lang: 0x1b4, script: 0x5a, flags: 0x0},
        214: {lang: 0x1b4, script: 0x5, flags: 0x2},
-       216: {lang: 0x13e, script: 0x57, flags: 0x0},
-       217: {lang: 0x367, script: 0x57, flags: 0x0},
-       218: {lang: 0x347, script: 0x57, flags: 0x0},
-       219: {lang: 0x351, script: 0x21, flags: 0x0},
+       216: {lang: 0x13e, script: 0x5a, flags: 0x0},
+       217: {lang: 0x367, script: 0x5a, flags: 0x0},
+       218: {lang: 0x347, script: 0x5a, flags: 0x0},
+       219: {lang: 0x351, script: 0x22, flags: 0x0},
        225: {lang: 0x3a, script: 0x5, flags: 0x0},
-       226: {lang: 0x13e, script: 0x57, flags: 0x0},
-       228: {lang: 0x13e, script: 0x57, flags: 0x0},
-       229: {lang: 0x15e, script: 0x57, flags: 0x0},
-       230: {lang: 0x486, script: 0x57, flags: 0x0},
-       231: {lang: 0x153, script: 0x57, flags: 0x0},
+       226: {lang: 0x13e, script: 0x5a, flags: 0x0},
+       228: {lang: 0x13e, script: 0x5a, flags: 0x0},
+       229: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       230: {lang: 0x486, script: 0x5a, flags: 0x0},
+       231: {lang: 0x153, script: 0x5a, flags: 0x0},
        232: {lang: 0x3a, script: 0x3, flags: 0x1},
-       233: {lang: 0x3b3, script: 0x57, flags: 0x0},
-       234: {lang: 0x15e, script: 0x57, flags: 0x0},
-       236: {lang: 0x13e, script: 0x57, flags: 0x0},
+       233: {lang: 0x3b3, script: 0x5a, flags: 0x0},
+       234: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       236: {lang: 0x13e, script: 0x5a, flags: 0x0},
        237: {lang: 0x3a, script: 0x5, flags: 0x0},
-       238: {lang: 0x3c0, script: 0x57, flags: 0x0},
-       240: {lang: 0x3a2, script: 0x57, flags: 0x0},
-       241: {lang: 0x194, script: 0x57, flags: 0x0},
+       238: {lang: 0x3c0, script: 0x5a, flags: 0x0},
+       240: {lang: 0x3a2, script: 0x5a, flags: 0x0},
+       241: {lang: 0x194, script: 0x5a, flags: 0x0},
        243: {lang: 0x3a, script: 0x5, flags: 0x0},
-       258: {lang: 0x15e, script: 0x57, flags: 0x0},
+       258: {lang: 0x15e, script: 0x5a, flags: 0x0},
        260: {lang: 0x3d, script: 0x2, flags: 0x1},
-       261: {lang: 0x432, script: 0x1f, flags: 0x0},
+       261: {lang: 0x432, script: 0x20, flags: 0x0},
        262: {lang: 0x3f, script: 0x2, flags: 0x1},
-       263: {lang: 0x3e5, script: 0x57, flags: 0x0},
+       263: {lang: 0x3e5, script: 0x5a, flags: 0x0},
        264: {lang: 0x3a, script: 0x5, flags: 0x0},
-       266: {lang: 0x15e, script: 0x57, flags: 0x0},
+       266: {lang: 0x15e, script: 0x5a, flags: 0x0},
        267: {lang: 0x3a, script: 0x5, flags: 0x0},
        268: {lang: 0x41, script: 0x2, flags: 0x1},
-       271: {lang: 0x416, script: 0x57, flags: 0x0},
-       272: {lang: 0x347, script: 0x57, flags: 0x0},
+       271: {lang: 0x416, script: 0x5a, flags: 0x0},
+       272: {lang: 0x347, script: 0x5a, flags: 0x0},
        273: {lang: 0x43, script: 0x2, flags: 0x1},
-       275: {lang: 0x1f9, script: 0x57, flags: 0x0},
-       276: {lang: 0x15e, script: 0x57, flags: 0x0},
-       277: {lang: 0x429, script: 0x57, flags: 0x0},
-       278: {lang: 0x367, script: 0x57, flags: 0x0},
-       280: {lang: 0x3c0, script: 0x57, flags: 0x0},
-       282: {lang: 0x13e, script: 0x57, flags: 0x0},
+       275: {lang: 0x1f9, script: 0x5a, flags: 0x0},
+       276: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       277: {lang: 0x429, script: 0x5a, flags: 0x0},
+       278: {lang: 0x367, script: 0x5a, flags: 0x0},
+       280: {lang: 0x3c0, script: 0x5a, flags: 0x0},
+       282: {lang: 0x13e, script: 0x5a, flags: 0x0},
        284: {lang: 0x45, script: 0x2, flags: 0x1},
-       288: {lang: 0x15e, script: 0x57, flags: 0x0},
-       289: {lang: 0x15e, script: 0x57, flags: 0x0},
+       288: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       289: {lang: 0x15e, script: 0x5a, flags: 0x0},
        290: {lang: 0x47, script: 0x2, flags: 0x1},
        291: {lang: 0x49, script: 0x3, flags: 0x1},
        292: {lang: 0x4c, script: 0x2, flags: 0x1},
-       293: {lang: 0x477, script: 0x57, flags: 0x0},
-       294: {lang: 0x3c0, script: 0x57, flags: 0x0},
-       295: {lang: 0x476, script: 0x57, flags: 0x0},
+       293: {lang: 0x477, script: 0x5a, flags: 0x0},
+       294: {lang: 0x3c0, script: 0x5a, flags: 0x0},
+       295: {lang: 0x476, script: 0x5a, flags: 0x0},
        296: {lang: 0x4e, script: 0x2, flags: 0x1},
-       297: {lang: 0x482, script: 0x57, flags: 0x0},
+       297: {lang: 0x482, script: 0x5a, flags: 0x0},
        299: {lang: 0x50, script: 0x4, flags: 0x1},
-       301: {lang: 0x4a0, script: 0x57, flags: 0x0},
+       301: {lang: 0x4a0, script: 0x5a, flags: 0x0},
        302: {lang: 0x54, script: 0x2, flags: 0x1},
-       303: {lang: 0x445, script: 0x57, flags: 0x0},
+       303: {lang: 0x445, script: 0x5a, flags: 0x0},
        304: {lang: 0x56, script: 0x3, flags: 0x1},
-       305: {lang: 0x445, script: 0x57, flags: 0x0},
-       309: {lang: 0x512, script: 0x3b, flags: 0x2},
-       310: {lang: 0x13e, script: 0x57, flags: 0x0},
-       311: {lang: 0x4bc, script: 0x57, flags: 0x0},
-       312: {lang: 0x1f9, script: 0x57, flags: 0x0},
-       315: {lang: 0x13e, script: 0x57, flags: 0x0},
-       318: {lang: 0x4c3, script: 0x57, flags: 0x0},
-       319: {lang: 0x8a, script: 0x57, flags: 0x0},
-       320: {lang: 0x15e, script: 0x57, flags: 0x0},
-       322: {lang: 0x41b, script: 0x57, flags: 0x0},
+       305: {lang: 0x445, script: 0x5a, flags: 0x0},
+       309: {lang: 0x512, script: 0x3e, flags: 0x2},
+       310: {lang: 0x13e, script: 0x5a, flags: 0x0},
+       311: {lang: 0x4bc, script: 0x5a, flags: 0x0},
+       312: {lang: 0x1f9, script: 0x5a, flags: 0x0},
+       315: {lang: 0x13e, script: 0x5a, flags: 0x0},
+       318: {lang: 0x4c3, script: 0x5a, flags: 0x0},
+       319: {lang: 0x8a, script: 0x5a, flags: 0x0},
+       320: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       322: {lang: 0x41b, script: 0x5a, flags: 0x0},
        333: {lang: 0x59, script: 0x2, flags: 0x1},
        350: {lang: 0x3a, script: 0x5, flags: 0x0},
        351: {lang: 0x5b, script: 0x2, flags: 0x1},
-       356: {lang: 0x423, script: 0x57, flags: 0x0},
+       356: {lang: 0x423, script: 0x5a, flags: 0x0},
 }
 
 // likelyRegionList holds lists info associated with likelyRegion.
 // Size: 372 bytes, 93 elements
 var likelyRegionList = [93]likelyLangScript{
        0:  {lang: 0x148, script: 0x5, flags: 0x0},
-       1:  {lang: 0x476, script: 0x57, flags: 0x0},
-       2:  {lang: 0x431, script: 0x57, flags: 0x0},
-       3:  {lang: 0x2ff, script: 0x1f, flags: 0x0},
+       1:  {lang: 0x476, script: 0x5a, flags: 0x0},
+       2:  {lang: 0x431, script: 0x5a, flags: 0x0},
+       3:  {lang: 0x2ff, script: 0x20, flags: 0x0},
        4:  {lang: 0x1d7, script: 0x8, flags: 0x0},
-       5:  {lang: 0x274, script: 0x57, flags: 0x0},
-       6:  {lang: 0xb7, script: 0x57, flags: 0x0},
-       7:  {lang: 0x432, script: 0x1f, flags: 0x0},
-       8:  {lang: 0x12d, script: 0xe0, flags: 0x0},
-       9:  {lang: 0x351, script: 0x21, flags: 0x0},
-       10: {lang: 0x529, script: 0x38, flags: 0x0},
+       5:  {lang: 0x274, script: 0x5a, flags: 0x0},
+       6:  {lang: 0xb7, script: 0x5a, flags: 0x0},
+       7:  {lang: 0x432, script: 0x20, flags: 0x0},
+       8:  {lang: 0x12d, script: 0xe7, flags: 0x0},
+       9:  {lang: 0x351, script: 0x22, flags: 0x0},
+       10: {lang: 0x529, script: 0x3b, flags: 0x0},
        11: {lang: 0x4ac, script: 0x5, flags: 0x0},
-       12: {lang: 0x523, script: 0x57, flags: 0x0},
-       13: {lang: 0x29a, script: 0xdf, flags: 0x0},
-       14: {lang: 0x136, script: 0x31, flags: 0x0},
-       15: {lang: 0x48a, script: 0x57, flags: 0x0},
+       12: {lang: 0x523, script: 0x5a, flags: 0x0},
+       13: {lang: 0x29a, script: 0xe6, flags: 0x0},
+       14: {lang: 0x136, script: 0x34, flags: 0x0},
+       15: {lang: 0x48a, script: 0x5a, flags: 0x0},
        16: {lang: 0x3a, script: 0x5, flags: 0x0},
-       17: {lang: 0x15e, script: 0x57, flags: 0x0},
-       18: {lang: 0x27, script: 0x29, flags: 0x0},
-       19: {lang: 0x139, script: 0x57, flags: 0x0},
+       17: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       18: {lang: 0x27, script: 0x2c, flags: 0x0},
+       19: {lang: 0x139, script: 0x5a, flags: 0x0},
        20: {lang: 0x26a, script: 0x5, flags: 0x2},
-       21: {lang: 0x512, script: 0x3b, flags: 0x2},
-       22: {lang: 0x210, script: 0x2b, flags: 0x0},
-       23: {lang: 0x5, script: 0x1f, flags: 0x0},
-       24: {lang: 0x274, script: 0x57, flags: 0x0},
-       25: {lang: 0x136, script: 0x31, flags: 0x0},
-       26: {lang: 0x2ff, script: 0x1f, flags: 0x0},
-       27: {lang: 0x1e1, script: 0x57, flags: 0x0},
+       21: {lang: 0x512, script: 0x3e, flags: 0x2},
+       22: {lang: 0x210, script: 0x2e, flags: 0x0},
+       23: {lang: 0x5, script: 0x20, flags: 0x0},
+       24: {lang: 0x274, script: 0x5a, flags: 0x0},
+       25: {lang: 0x136, script: 0x34, flags: 0x0},
+       26: {lang: 0x2ff, script: 0x20, flags: 0x0},
+       27: {lang: 0x1e1, script: 0x5a, flags: 0x0},
        28: {lang: 0x31f, script: 0x5, flags: 0x0},
-       29: {lang: 0x1be, script: 0x21, flags: 0x0},
+       29: {lang: 0x1be, script: 0x22, flags: 0x0},
        30: {lang: 0x4b4, script: 0x5, flags: 0x0},
-       31: {lang: 0x236, script: 0x72, flags: 0x0},
+       31: {lang: 0x236, script: 0x75, flags: 0x0},
        32: {lang: 0x148, script: 0x5, flags: 0x0},
-       33: {lang: 0x476, script: 0x57, flags: 0x0},
-       34: {lang: 0x24a, script: 0x4b, flags: 0x0},
+       33: {lang: 0x476, script: 0x5a, flags: 0x0},
+       34: {lang: 0x24a, script: 0x4e, flags: 0x0},
        35: {lang: 0xe6, script: 0x5, flags: 0x0},
-       36: {lang: 0x226, script: 0xdf, flags: 0x0},
+       36: {lang: 0x226, script: 0xe6, flags: 0x0},
        37: {lang: 0x3a, script: 0x5, flags: 0x0},
-       38: {lang: 0x15e, script: 0x57, flags: 0x0},
-       39: {lang: 0x2b8, script: 0x54, flags: 0x0},
-       40: {lang: 0x226, script: 0xdf, flags: 0x0},
+       38: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       39: {lang: 0x2b8, script: 0x57, flags: 0x0},
+       40: {lang: 0x226, script: 0xe6, flags: 0x0},
        41: {lang: 0x3a, script: 0x5, flags: 0x0},
-       42: {lang: 0x15e, script: 0x57, flags: 0x0},
-       43: {lang: 0x3dc, script: 0x57, flags: 0x0},
-       44: {lang: 0x4ae, script: 0x1f, flags: 0x0},
-       45: {lang: 0x2ff, script: 0x1f, flags: 0x0},
-       46: {lang: 0x431, script: 0x57, flags: 0x0},
-       47: {lang: 0x331, script: 0x72, flags: 0x0},
-       48: {lang: 0x213, script: 0x57, flags: 0x0},
-       49: {lang: 0x30b, script: 0x1f, flags: 0x0},
+       42: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       43: {lang: 0x3dc, script: 0x5a, flags: 0x0},
+       44: {lang: 0x4ae, script: 0x20, flags: 0x0},
+       45: {lang: 0x2ff, script: 0x20, flags: 0x0},
+       46: {lang: 0x431, script: 0x5a, flags: 0x0},
+       47: {lang: 0x331, script: 0x75, flags: 0x0},
+       48: {lang: 0x213, script: 0x5a, flags: 0x0},
+       49: {lang: 0x30b, script: 0x20, flags: 0x0},
        50: {lang: 0x242, script: 0x5, flags: 0x0},
-       51: {lang: 0x529, script: 0x39, flags: 0x0},
-       52: {lang: 0x3c0, script: 0x57, flags: 0x0},
+       51: {lang: 0x529, script: 0x3c, flags: 0x0},
+       52: {lang: 0x3c0, script: 0x5a, flags: 0x0},
        53: {lang: 0x3a, script: 0x5, flags: 0x0},
-       54: {lang: 0x15e, script: 0x57, flags: 0x0},
-       55: {lang: 0x2ed, script: 0x57, flags: 0x0},
+       54: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       55: {lang: 0x2ed, script: 0x5a, flags: 0x0},
        56: {lang: 0x4b4, script: 0x5, flags: 0x0},
-       57: {lang: 0x88, script: 0x21, flags: 0x0},
+       57: {lang: 0x88, script: 0x22, flags: 0x0},
        58: {lang: 0x4b4, script: 0x5, flags: 0x0},
        59: {lang: 0x4b4, script: 0x5, flags: 0x0},
-       60: {lang: 0xbe, script: 0x21, flags: 0x0},
-       61: {lang: 0x3dc, script: 0x57, flags: 0x0},
-       62: {lang: 0x7e, script: 0x1f, flags: 0x0},
-       63: {lang: 0x3e2, script: 0x1f, flags: 0x0},
-       64: {lang: 0x267, script: 0x57, flags: 0x0},
-       65: {lang: 0x444, script: 0x57, flags: 0x0},
-       66: {lang: 0x512, script: 0x3b, flags: 0x0},
-       67: {lang: 0x412, script: 0x57, flags: 0x0},
-       68: {lang: 0x4ae, script: 0x1f, flags: 0x0},
+       60: {lang: 0xbe, script: 0x22, flags: 0x0},
+       61: {lang: 0x3dc, script: 0x5a, flags: 0x0},
+       62: {lang: 0x7e, script: 0x20, flags: 0x0},
+       63: {lang: 0x3e2, script: 0x20, flags: 0x0},
+       64: {lang: 0x267, script: 0x5a, flags: 0x0},
+       65: {lang: 0x444, script: 0x5a, flags: 0x0},
+       66: {lang: 0x512, script: 0x3e, flags: 0x0},
+       67: {lang: 0x412, script: 0x5a, flags: 0x0},
+       68: {lang: 0x4ae, script: 0x20, flags: 0x0},
        69: {lang: 0x3a, script: 0x5, flags: 0x0},
-       70: {lang: 0x15e, script: 0x57, flags: 0x0},
-       71: {lang: 0x15e, script: 0x57, flags: 0x0},
+       70: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       71: {lang: 0x15e, script: 0x5a, flags: 0x0},
        72: {lang: 0x35, script: 0x5, flags: 0x0},
-       73: {lang: 0x46b, script: 0xdf, flags: 0x0},
+       73: {lang: 0x46b, script: 0xe6, flags: 0x0},
        74: {lang: 0x2ec, script: 0x5, flags: 0x0},
-       75: {lang: 0x30f, script: 0x72, flags: 0x0},
-       76: {lang: 0x467, script: 0x1f, flags: 0x0},
+       75: {lang: 0x30f, script: 0x75, flags: 0x0},
+       76: {lang: 0x467, script: 0x20, flags: 0x0},
        77: {lang: 0x148, script: 0x5, flags: 0x0},
        78: {lang: 0x3a, script: 0x5, flags: 0x0},
-       79: {lang: 0x15e, script: 0x57, flags: 0x0},
-       80: {lang: 0x48a, script: 0x57, flags: 0x0},
+       79: {lang: 0x15e, script: 0x5a, flags: 0x0},
+       80: {lang: 0x48a, script: 0x5a, flags: 0x0},
        81: {lang: 0x58, script: 0x5, flags: 0x0},
-       82: {lang: 0x219, script: 0x1f, flags: 0x0},
-       83: {lang: 0x81, script: 0x31, flags: 0x0},
-       84: {lang: 0x529, script: 0x39, flags: 0x0},
-       85: {lang: 0x48c, script: 0x57, flags: 0x0},
-       86: {lang: 0x4ae, script: 0x1f, flags: 0x0},
-       87: {lang: 0x512, script: 0x3b, flags: 0x0},
-       88: {lang: 0x3b3, script: 0x57, flags: 0x0},
-       89: {lang: 0x431, script: 0x57, flags: 0x0},
-       90: {lang: 0x432, script: 0x1f, flags: 0x0},
-       91: {lang: 0x15e, script: 0x57, flags: 0x0},
+       82: {lang: 0x219, script: 0x20, flags: 0x0},
+       83: {lang: 0x81, script: 0x34, flags: 0x0},
+       84: {lang: 0x529, script: 0x3c, flags: 0x0},
+       85: {lang: 0x48c, script: 0x5a, flags: 0x0},
+       86: {lang: 0x4ae, script: 0x20, flags: 0x0},
+       87: {lang: 0x512, script: 0x3e, flags: 0x0},
+       88: {lang: 0x3b3, script: 0x5a, flags: 0x0},
+       89: {lang: 0x431, script: 0x5a, flags: 0x0},
+       90: {lang: 0x432, script: 0x20, flags: 0x0},
+       91: {lang: 0x15e, script: 0x5a, flags: 0x0},
        92: {lang: 0x446, script: 0x5, flags: 0x0},
 }
 
@@ -3257,38 +3290,38 @@ type likelyTag struct {
 
 // Size: 198 bytes, 33 elements
 var likelyRegionGroup = [33]likelyTag{
-       1:  {lang: 0x139, region: 0xd6, script: 0x57},
-       2:  {lang: 0x139, region: 0x135, script: 0x57},
-       3:  {lang: 0x3c0, region: 0x41, script: 0x57},
-       4:  {lang: 0x139, region: 0x2f, script: 0x57},
-       5:  {lang: 0x139, region: 0xd6, script: 0x57},
-       6:  {lang: 0x13e, region: 0xcf, script: 0x57},
-       7:  {lang: 0x445, region: 0x12f, script: 0x57},
+       1:  {lang: 0x139, region: 0xd6, script: 0x5a},
+       2:  {lang: 0x139, region: 0x135, script: 0x5a},
+       3:  {lang: 0x3c0, region: 0x41, script: 0x5a},
+       4:  {lang: 0x139, region: 0x2f, script: 0x5a},
+       5:  {lang: 0x139, region: 0xd6, script: 0x5a},
+       6:  {lang: 0x13e, region: 0xcf, script: 0x5a},
+       7:  {lang: 0x445, region: 0x12f, script: 0x5a},
        8:  {lang: 0x3a, region: 0x6b, script: 0x5},
-       9:  {lang: 0x445, region: 0x4b, script: 0x57},
-       10: {lang: 0x139, region: 0x161, script: 0x57},
-       11: {lang: 0x139, region: 0x135, script: 0x57},
-       12: {lang: 0x139, region: 0x135, script: 0x57},
-       13: {lang: 0x13e, region: 0x59, script: 0x57},
-       14: {lang: 0x529, region: 0x53, script: 0x38},
-       15: {lang: 0x1be, region: 0x99, script: 0x21},
-       16: {lang: 0x1e1, region: 0x95, script: 0x57},
-       17: {lang: 0x1f9, region: 0x9e, script: 0x57},
-       18: {lang: 0x139, region: 0x2f, script: 0x57},
-       19: {lang: 0x139, region: 0xe6, script: 0x57},
-       20: {lang: 0x139, region: 0x8a, script: 0x57},
-       21: {lang: 0x41b, region: 0x142, script: 0x57},
-       22: {lang: 0x529, region: 0x53, script: 0x38},
-       23: {lang: 0x4bc, region: 0x137, script: 0x57},
+       9:  {lang: 0x445, region: 0x4b, script: 0x5a},
+       10: {lang: 0x139, region: 0x161, script: 0x5a},
+       11: {lang: 0x139, region: 0x135, script: 0x5a},
+       12: {lang: 0x139, region: 0x135, script: 0x5a},
+       13: {lang: 0x13e, region: 0x59, script: 0x5a},
+       14: {lang: 0x529, region: 0x53, script: 0x3b},
+       15: {lang: 0x1be, region: 0x99, script: 0x22},
+       16: {lang: 0x1e1, region: 0x95, script: 0x5a},
+       17: {lang: 0x1f9, region: 0x9e, script: 0x5a},
+       18: {lang: 0x139, region: 0x2f, script: 0x5a},
+       19: {lang: 0x139, region: 0xe6, script: 0x5a},
+       20: {lang: 0x139, region: 0x8a, script: 0x5a},
+       21: {lang: 0x41b, region: 0x142, script: 0x5a},
+       22: {lang: 0x529, region: 0x53, script: 0x3b},
+       23: {lang: 0x4bc, region: 0x137, script: 0x5a},
        24: {lang: 0x3a, region: 0x108, script: 0x5},
-       25: {lang: 0x3e2, region: 0x106, script: 0x1f},
-       26: {lang: 0x3e2, region: 0x106, script: 0x1f},
-       27: {lang: 0x139, region: 0x7b, script: 0x57},
-       28: {lang: 0x10d, region: 0x60, script: 0x57},
-       29: {lang: 0x139, region: 0xd6, script: 0x57},
-       30: {lang: 0x13e, region: 0x1f, script: 0x57},
-       31: {lang: 0x139, region: 0x9a, script: 0x57},
-       32: {lang: 0x139, region: 0x7b, script: 0x57},
+       25: {lang: 0x3e2, region: 0x106, script: 0x20},
+       26: {lang: 0x3e2, region: 0x106, script: 0x20},
+       27: {lang: 0x139, region: 0x7b, script: 0x5a},
+       28: {lang: 0x10d, region: 0x60, script: 0x5a},
+       29: {lang: 0x139, region: 0xd6, script: 0x5a},
+       30: {lang: 0x13e, region: 0x1f, script: 0x5a},
+       31: {lang: 0x139, region: 0x9a, script: 0x5a},
+       32: {lang: 0x139, region: 0x7b, script: 0x5a},
 }
 
 // Size: 264 bytes, 33 elements
@@ -3421,11 +3454,11 @@ type parentRel struct {
 
 // Size: 414 bytes, 5 elements
 var parents = [5]parentRel{
-       0: {lang: 0x139, script: 0x0, maxScript: 0x57, toRegion: 0x1, fromRegion: []uint16{0x1a, 0x25, 0x26, 0x2f, 0x34, 0x36, 0x3d, 0x42, 0x46, 0x48, 0x49, 0x4a, 0x50, 0x52, 0x5c, 0x5d, 0x61, 0x64, 0x6d, 0x73, 0x74, 0x75, 0x7b, 0x7c, 0x7f, 0x80, 0x81, 0x83, 0x8c, 0x8d, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9f, 0xa0, 0xa4, 0xa7, 0xa9, 0xad, 0xb1, 0xb4, 0xb5, 0xbf, 0xc6, 0xca, 0xcb, 0xcc, 0xce, 0xd0, 0xd2, 0xd5, 0xd6, 0xdd, 0xdf, 0xe0, 0xe6, 0xe7, 0xe8, 0xeb, 0xf0, 0x107, 0x109, 0x10a, 0x10b, 0x10d, 0x10e, 0x112, 0x117, 0x11b, 0x11d, 0x11f, 0x125, 0x129, 0x12c, 0x12d, 0x12f, 0x131, 0x139, 0x13c, 0x13f, 0x142, 0x161, 0x162, 0x164}},
-       1: {lang: 0x139, script: 0x0, maxScript: 0x57, toRegion: 0x1a, fromRegion: []uint16{0x2e, 0x4e, 0x60, 0x63, 0x72, 0xd9, 0x10c, 0x10f}},
-       2: {lang: 0x13e, script: 0x0, maxScript: 0x57, toRegion: 0x1f, fromRegion: []uint16{0x2c, 0x3f, 0x41, 0x48, 0x51, 0x54, 0x56, 0x59, 0x65, 0x69, 0x89, 0x8f, 0xcf, 0xd8, 0xe2, 0xe4, 0xec, 0xf1, 0x11a, 0x135, 0x136, 0x13b}},
-       3: {lang: 0x3c0, script: 0x0, maxScript: 0x57, toRegion: 0xee, fromRegion: []uint16{0x2a, 0x4e, 0x5a, 0x86, 0x8b, 0xb7, 0xc6, 0xd1, 0x118, 0x126}},
-       4: {lang: 0x529, script: 0x39, maxScript: 0x39, toRegion: 0x8d, fromRegion: []uint16{0xc6}},
+       0: {lang: 0x139, script: 0x0, maxScript: 0x5a, toRegion: 0x1, fromRegion: []uint16{0x1a, 0x25, 0x26, 0x2f, 0x34, 0x36, 0x3d, 0x42, 0x46, 0x48, 0x49, 0x4a, 0x50, 0x52, 0x5c, 0x5d, 0x61, 0x64, 0x6d, 0x73, 0x74, 0x75, 0x7b, 0x7c, 0x7f, 0x80, 0x81, 0x83, 0x8c, 0x8d, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9f, 0xa0, 0xa4, 0xa7, 0xa9, 0xad, 0xb1, 0xb4, 0xb5, 0xbf, 0xc6, 0xca, 0xcb, 0xcc, 0xce, 0xd0, 0xd2, 0xd5, 0xd6, 0xdd, 0xdf, 0xe0, 0xe6, 0xe7, 0xe8, 0xeb, 0xf0, 0x107, 0x109, 0x10a, 0x10b, 0x10d, 0x10e, 0x112, 0x117, 0x11b, 0x11d, 0x11f, 0x125, 0x129, 0x12c, 0x12d, 0x12f, 0x131, 0x139, 0x13c, 0x13f, 0x142, 0x161, 0x162, 0x164}},
+       1: {lang: 0x139, script: 0x0, maxScript: 0x5a, toRegion: 0x1a, fromRegion: []uint16{0x2e, 0x4e, 0x60, 0x63, 0x72, 0xd9, 0x10c, 0x10f}},
+       2: {lang: 0x13e, script: 0x0, maxScript: 0x5a, toRegion: 0x1f, fromRegion: []uint16{0x2c, 0x3f, 0x41, 0x48, 0x51, 0x54, 0x56, 0x59, 0x65, 0x69, 0x89, 0x8f, 0xcf, 0xd8, 0xe2, 0xe4, 0xec, 0xf1, 0x11a, 0x135, 0x136, 0x13b}},
+       3: {lang: 0x3c0, script: 0x0, maxScript: 0x5a, toRegion: 0xee, fromRegion: []uint16{0x2a, 0x4e, 0x5a, 0x86, 0x8b, 0xb7, 0xc6, 0xd1, 0x118, 0x126}},
+       4: {lang: 0x529, script: 0x3c, maxScript: 0x3c, toRegion: 0x8d, fromRegion: []uint16{0xc6}},
 }
 
-// Total table size 25886 bytes (25KiB); checksum: 50D3D57D
+// Total table size 26398 bytes (25KiB); checksum: 1C859EA7
index e22807719e08a96a7b86fbc4f12f1408dd85c6f6..87e58a02a089f9433893971e10f440b165d373e4 100644 (file)
@@ -35,16 +35,16 @@ const (
        _XK  = 333
 )
 const (
-       _Latn = 87
-       _Hani = 54
-       _Hans = 56
-       _Hant = 57
-       _Qaaa = 139
-       _Qaai = 147
-       _Qabx = 188
-       _Zinh = 236
-       _Zyyy = 241
-       _Zzzz = 242
+       _Latn = 90
+       _Hani = 57
+       _Hans = 59
+       _Hant = 60
+       _Qaaa = 143
+       _Qaai = 151
+       _Qabx = 192
+       _Zinh = 245
+       _Zyyy = 250
+       _Zzzz = 251
 )
 
 var regionToGroups = []uint8{ // 357 elements
@@ -249,32 +249,32 @@ var matchLang = []mutualIntelligibility{ // 113 elements
 // matchScript holds pairs of scriptIDs where readers of one script
 // can typically also read the other. Each is associated with a confidence.
 var matchScript = []scriptIntelligibility{ // 26 elements
-       0:  {wantLang: 0x432, haveLang: 0x432, wantScript: 0x57, haveScript: 0x1f, distance: 0x5},
-       1:  {wantLang: 0x432, haveLang: 0x432, wantScript: 0x1f, haveScript: 0x57, distance: 0x5},
-       2:  {wantLang: 0x58, haveLang: 0x3e2, wantScript: 0x57, haveScript: 0x1f, distance: 0xa},
-       3:  {wantLang: 0xa5, haveLang: 0x139, wantScript: 0xe, haveScript: 0x57, distance: 0xa},
-       4:  {wantLang: 0x1d7, haveLang: 0x3e2, wantScript: 0x8, haveScript: 0x1f, distance: 0xa},
-       5:  {wantLang: 0x210, haveLang: 0x139, wantScript: 0x2b, haveScript: 0x57, distance: 0xa},
-       6:  {wantLang: 0x24a, haveLang: 0x139, wantScript: 0x4b, haveScript: 0x57, distance: 0xa},
-       7:  {wantLang: 0x251, haveLang: 0x139, wantScript: 0x4f, haveScript: 0x57, distance: 0xa},
-       8:  {wantLang: 0x2b8, haveLang: 0x139, wantScript: 0x54, haveScript: 0x57, distance: 0xa},
-       9:  {wantLang: 0x304, haveLang: 0x139, wantScript: 0x6b, haveScript: 0x57, distance: 0xa},
-       10: {wantLang: 0x331, haveLang: 0x139, wantScript: 0x72, haveScript: 0x57, distance: 0xa},
-       11: {wantLang: 0x351, haveLang: 0x139, wantScript: 0x21, haveScript: 0x57, distance: 0xa},
-       12: {wantLang: 0x395, haveLang: 0x139, wantScript: 0x7d, haveScript: 0x57, distance: 0xa},
-       13: {wantLang: 0x39d, haveLang: 0x139, wantScript: 0x33, haveScript: 0x57, distance: 0xa},
-       14: {wantLang: 0x3be, haveLang: 0x139, wantScript: 0x5, haveScript: 0x57, distance: 0xa},
-       15: {wantLang: 0x3fa, haveLang: 0x139, wantScript: 0x5, haveScript: 0x57, distance: 0xa},
-       16: {wantLang: 0x40c, haveLang: 0x139, wantScript: 0xca, haveScript: 0x57, distance: 0xa},
-       17: {wantLang: 0x450, haveLang: 0x139, wantScript: 0xd7, haveScript: 0x57, distance: 0xa},
-       18: {wantLang: 0x461, haveLang: 0x139, wantScript: 0xda, haveScript: 0x57, distance: 0xa},
-       19: {wantLang: 0x46f, haveLang: 0x139, wantScript: 0x29, haveScript: 0x57, distance: 0xa},
-       20: {wantLang: 0x476, haveLang: 0x3e2, wantScript: 0x57, haveScript: 0x1f, distance: 0xa},
-       21: {wantLang: 0x4b4, haveLang: 0x139, wantScript: 0x5, haveScript: 0x57, distance: 0xa},
-       22: {wantLang: 0x4bc, haveLang: 0x3e2, wantScript: 0x57, haveScript: 0x1f, distance: 0xa},
-       23: {wantLang: 0x512, haveLang: 0x139, wantScript: 0x3b, haveScript: 0x57, distance: 0xa},
-       24: {wantLang: 0x529, haveLang: 0x529, wantScript: 0x38, haveScript: 0x39, distance: 0xf},
-       25: {wantLang: 0x529, haveLang: 0x529, wantScript: 0x39, haveScript: 0x38, distance: 0x13},
+       0:  {wantLang: 0x432, haveLang: 0x432, wantScript: 0x5a, haveScript: 0x20, distance: 0x5},
+       1:  {wantLang: 0x432, haveLang: 0x432, wantScript: 0x20, haveScript: 0x5a, distance: 0x5},
+       2:  {wantLang: 0x58, haveLang: 0x3e2, wantScript: 0x5a, haveScript: 0x20, distance: 0xa},
+       3:  {wantLang: 0xa5, haveLang: 0x139, wantScript: 0xe, haveScript: 0x5a, distance: 0xa},
+       4:  {wantLang: 0x1d7, haveLang: 0x3e2, wantScript: 0x8, haveScript: 0x20, distance: 0xa},
+       5:  {wantLang: 0x210, haveLang: 0x139, wantScript: 0x2e, haveScript: 0x5a, distance: 0xa},
+       6:  {wantLang: 0x24a, haveLang: 0x139, wantScript: 0x4e, haveScript: 0x5a, distance: 0xa},
+       7:  {wantLang: 0x251, haveLang: 0x139, wantScript: 0x52, haveScript: 0x5a, distance: 0xa},
+       8:  {wantLang: 0x2b8, haveLang: 0x139, wantScript: 0x57, haveScript: 0x5a, distance: 0xa},
+       9:  {wantLang: 0x304, haveLang: 0x139, wantScript: 0x6e, haveScript: 0x5a, distance: 0xa},
+       10: {wantLang: 0x331, haveLang: 0x139, wantScript: 0x75, haveScript: 0x5a, distance: 0xa},
+       11: {wantLang: 0x351, haveLang: 0x139, wantScript: 0x22, haveScript: 0x5a, distance: 0xa},
+       12: {wantLang: 0x395, haveLang: 0x139, wantScript: 0x81, haveScript: 0x5a, distance: 0xa},
+       13: {wantLang: 0x39d, haveLang: 0x139, wantScript: 0x36, haveScript: 0x5a, distance: 0xa},
+       14: {wantLang: 0x3be, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5a, distance: 0xa},
+       15: {wantLang: 0x3fa, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5a, distance: 0xa},
+       16: {wantLang: 0x40c, haveLang: 0x139, wantScript: 0xcf, haveScript: 0x5a, distance: 0xa},
+       17: {wantLang: 0x450, haveLang: 0x139, wantScript: 0xde, haveScript: 0x5a, distance: 0xa},
+       18: {wantLang: 0x461, haveLang: 0x139, wantScript: 0xe1, haveScript: 0x5a, distance: 0xa},
+       19: {wantLang: 0x46f, haveLang: 0x139, wantScript: 0x2c, haveScript: 0x5a, distance: 0xa},
+       20: {wantLang: 0x476, haveLang: 0x3e2, wantScript: 0x5a, haveScript: 0x20, distance: 0xa},
+       21: {wantLang: 0x4b4, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5a, distance: 0xa},
+       22: {wantLang: 0x4bc, haveLang: 0x3e2, wantScript: 0x5a, haveScript: 0x20, distance: 0xa},
+       23: {wantLang: 0x512, haveLang: 0x139, wantScript: 0x3e, haveScript: 0x5a, distance: 0xa},
+       24: {wantLang: 0x529, haveLang: 0x529, wantScript: 0x3b, haveScript: 0x3c, distance: 0xf},
+       25: {wantLang: 0x529, haveLang: 0x529, wantScript: 0x3c, haveScript: 0x3b, distance: 0x13},
 } // Size: 232 bytes
 
 var matchRegion = []regionIntelligibility{ // 15 elements
@@ -286,13 +286,13 @@ var matchRegion = []regionIntelligibility{ // 15 elements
        5:  {lang: 0x13e, script: 0x0, group: 0x83, distance: 0x4},
        6:  {lang: 0x3c0, script: 0x0, group: 0x3, distance: 0x4},
        7:  {lang: 0x3c0, script: 0x0, group: 0x83, distance: 0x4},
-       8:  {lang: 0x529, script: 0x39, group: 0x2, distance: 0x4},
-       9:  {lang: 0x529, script: 0x39, group: 0x82, distance: 0x4},
+       8:  {lang: 0x529, script: 0x3c, group: 0x2, distance: 0x4},
+       9:  {lang: 0x529, script: 0x3c, group: 0x82, distance: 0x4},
        10: {lang: 0x3a, script: 0x0, group: 0x80, distance: 0x5},
        11: {lang: 0x139, script: 0x0, group: 0x80, distance: 0x5},
        12: {lang: 0x13e, script: 0x0, group: 0x80, distance: 0x5},
        13: {lang: 0x3c0, script: 0x0, group: 0x80, distance: 0x5},
-       14: {lang: 0x529, script: 0x39, group: 0x80, distance: 0x5},
+       14: {lang: 0x529, script: 0x3c, group: 0x80, distance: 0x5},
 } // Size: 114 bytes
 
 // Total table size 1471 bytes (1KiB); checksum: 4CB1CD46
index 7ffa365121cbfd6674fd6db87618483d9210f5bf..647f2d4279e6d917c028dd6c98f911ec7adb4fe2 100644 (file)
@@ -1,6 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
-// +build go1.14
+// +build go1.14,!go1.16
 
 package bidi
 
diff --git a/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go b/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go
new file mode 100644 (file)
index 0000000..c937d09
--- /dev/null
@@ -0,0 +1,1955 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+// +build go1.16
+
+package bidi
+
+// UnicodeVersion is the Unicode version from which the tables in this package are derived.
+const UnicodeVersion = "13.0.0"
+
+// xorMasks contains masks to be xor-ed with brackets to get the reverse
+// version.
+var xorMasks = []int32{ // 8 elements
+       0, 1, 6, 7, 3, 15, 29, 63,
+} // Size: 56 bytes
+
+// lookup returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *bidiTrie) lookup(s []byte) (v uint8, sz int) {
+       c0 := s[0]
+       switch {
+       case c0 < 0x80: // is ASCII
+               return bidiValues[c0], 1
+       case c0 < 0xC2:
+               return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+       case c0 < 0xE0: // 2-byte UTF-8
+               if len(s) < 2 {
+                       return 0, 0
+               }
+               i := bidiIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c1), 2
+       case c0 < 0xF0: // 3-byte UTF-8
+               if len(s) < 3 {
+                       return 0, 0
+               }
+               i := bidiIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               o := uint32(i)<<6 + uint32(c1)
+               i = bidiIndex[o]
+               c2 := s[2]
+               if c2 < 0x80 || 0xC0 <= c2 {
+                       return 0, 2 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c2), 3
+       case c0 < 0xF8: // 4-byte UTF-8
+               if len(s) < 4 {
+                       return 0, 0
+               }
+               i := bidiIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               o := uint32(i)<<6 + uint32(c1)
+               i = bidiIndex[o]
+               c2 := s[2]
+               if c2 < 0x80 || 0xC0 <= c2 {
+                       return 0, 2 // Illegal UTF-8: not a continuation byte.
+               }
+               o = uint32(i)<<6 + uint32(c2)
+               i = bidiIndex[o]
+               c3 := s[3]
+               if c3 < 0x80 || 0xC0 <= c3 {
+                       return 0, 3 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c3), 4
+       }
+       // Illegal rune
+       return 0, 1
+}
+
+// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *bidiTrie) lookupUnsafe(s []byte) uint8 {
+       c0 := s[0]
+       if c0 < 0x80 { // is ASCII
+               return bidiValues[c0]
+       }
+       i := bidiIndex[c0]
+       if c0 < 0xE0 { // 2-byte UTF-8
+               return t.lookupValue(uint32(i), s[1])
+       }
+       i = bidiIndex[uint32(i)<<6+uint32(s[1])]
+       if c0 < 0xF0 { // 3-byte UTF-8
+               return t.lookupValue(uint32(i), s[2])
+       }
+       i = bidiIndex[uint32(i)<<6+uint32(s[2])]
+       if c0 < 0xF8 { // 4-byte UTF-8
+               return t.lookupValue(uint32(i), s[3])
+       }
+       return 0
+}
+
+// lookupString returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *bidiTrie) lookupString(s string) (v uint8, sz int) {
+       c0 := s[0]
+       switch {
+       case c0 < 0x80: // is ASCII
+               return bidiValues[c0], 1
+       case c0 < 0xC2:
+               return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+       case c0 < 0xE0: // 2-byte UTF-8
+               if len(s) < 2 {
+                       return 0, 0
+               }
+               i := bidiIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c1), 2
+       case c0 < 0xF0: // 3-byte UTF-8
+               if len(s) < 3 {
+                       return 0, 0
+               }
+               i := bidiIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               o := uint32(i)<<6 + uint32(c1)
+               i = bidiIndex[o]
+               c2 := s[2]
+               if c2 < 0x80 || 0xC0 <= c2 {
+                       return 0, 2 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c2), 3
+       case c0 < 0xF8: // 4-byte UTF-8
+               if len(s) < 4 {
+                       return 0, 0
+               }
+               i := bidiIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               o := uint32(i)<<6 + uint32(c1)
+               i = bidiIndex[o]
+               c2 := s[2]
+               if c2 < 0x80 || 0xC0 <= c2 {
+                       return 0, 2 // Illegal UTF-8: not a continuation byte.
+               }
+               o = uint32(i)<<6 + uint32(c2)
+               i = bidiIndex[o]
+               c3 := s[3]
+               if c3 < 0x80 || 0xC0 <= c3 {
+                       return 0, 3 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c3), 4
+       }
+       // Illegal rune
+       return 0, 1
+}
+
+// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *bidiTrie) lookupStringUnsafe(s string) uint8 {
+       c0 := s[0]
+       if c0 < 0x80 { // is ASCII
+               return bidiValues[c0]
+       }
+       i := bidiIndex[c0]
+       if c0 < 0xE0 { // 2-byte UTF-8
+               return t.lookupValue(uint32(i), s[1])
+       }
+       i = bidiIndex[uint32(i)<<6+uint32(s[1])]
+       if c0 < 0xF0 { // 3-byte UTF-8
+               return t.lookupValue(uint32(i), s[2])
+       }
+       i = bidiIndex[uint32(i)<<6+uint32(s[2])]
+       if c0 < 0xF8 { // 4-byte UTF-8
+               return t.lookupValue(uint32(i), s[3])
+       }
+       return 0
+}
+
+// bidiTrie. Total size: 17408 bytes (17.00 KiB). Checksum: df85fcbfe9b8377f.
+type bidiTrie struct{}
+
+func newBidiTrie(i int) *bidiTrie {
+       return &bidiTrie{}
+}
+
+// lookupValue determines the type of block n and looks up the value for b.
+func (t *bidiTrie) lookupValue(n uint32, b byte) uint8 {
+       switch {
+       default:
+               return uint8(bidiValues[n<<6+uint32(b)])
+       }
+}
+
+// bidiValues: 248 blocks, 15872 entries, 15872 bytes
+// The third block is the zero block.
+var bidiValues = [15872]uint8{
+       // Block 0x0, offset 0x0
+       0x00: 0x000b, 0x01: 0x000b, 0x02: 0x000b, 0x03: 0x000b, 0x04: 0x000b, 0x05: 0x000b,
+       0x06: 0x000b, 0x07: 0x000b, 0x08: 0x000b, 0x09: 0x0008, 0x0a: 0x0007, 0x0b: 0x0008,
+       0x0c: 0x0009, 0x0d: 0x0007, 0x0e: 0x000b, 0x0f: 0x000b, 0x10: 0x000b, 0x11: 0x000b,
+       0x12: 0x000b, 0x13: 0x000b, 0x14: 0x000b, 0x15: 0x000b, 0x16: 0x000b, 0x17: 0x000b,
+       0x18: 0x000b, 0x19: 0x000b, 0x1a: 0x000b, 0x1b: 0x000b, 0x1c: 0x0007, 0x1d: 0x0007,
+       0x1e: 0x0007, 0x1f: 0x0008, 0x20: 0x0009, 0x21: 0x000a, 0x22: 0x000a, 0x23: 0x0004,
+       0x24: 0x0004, 0x25: 0x0004, 0x26: 0x000a, 0x27: 0x000a, 0x28: 0x003a, 0x29: 0x002a,
+       0x2a: 0x000a, 0x2b: 0x0003, 0x2c: 0x0006, 0x2d: 0x0003, 0x2e: 0x0006, 0x2f: 0x0006,
+       0x30: 0x0002, 0x31: 0x0002, 0x32: 0x0002, 0x33: 0x0002, 0x34: 0x0002, 0x35: 0x0002,
+       0x36: 0x0002, 0x37: 0x0002, 0x38: 0x0002, 0x39: 0x0002, 0x3a: 0x0006, 0x3b: 0x000a,
+       0x3c: 0x000a, 0x3d: 0x000a, 0x3e: 0x000a, 0x3f: 0x000a,
+       // Block 0x1, offset 0x40
+       0x40: 0x000a,
+       0x5b: 0x005a, 0x5c: 0x000a, 0x5d: 0x004a,
+       0x5e: 0x000a, 0x5f: 0x000a, 0x60: 0x000a,
+       0x7b: 0x005a,
+       0x7c: 0x000a, 0x7d: 0x004a, 0x7e: 0x000a, 0x7f: 0x000b,
+       // Block 0x2, offset 0x80
+       // Block 0x3, offset 0xc0
+       0xc0: 0x000b, 0xc1: 0x000b, 0xc2: 0x000b, 0xc3: 0x000b, 0xc4: 0x000b, 0xc5: 0x0007,
+       0xc6: 0x000b, 0xc7: 0x000b, 0xc8: 0x000b, 0xc9: 0x000b, 0xca: 0x000b, 0xcb: 0x000b,
+       0xcc: 0x000b, 0xcd: 0x000b, 0xce: 0x000b, 0xcf: 0x000b, 0xd0: 0x000b, 0xd1: 0x000b,
+       0xd2: 0x000b, 0xd3: 0x000b, 0xd4: 0x000b, 0xd5: 0x000b, 0xd6: 0x000b, 0xd7: 0x000b,
+       0xd8: 0x000b, 0xd9: 0x000b, 0xda: 0x000b, 0xdb: 0x000b, 0xdc: 0x000b, 0xdd: 0x000b,
+       0xde: 0x000b, 0xdf: 0x000b, 0xe0: 0x0006, 0xe1: 0x000a, 0xe2: 0x0004, 0xe3: 0x0004,
+       0xe4: 0x0004, 0xe5: 0x0004, 0xe6: 0x000a, 0xe7: 0x000a, 0xe8: 0x000a, 0xe9: 0x000a,
+       0xeb: 0x000a, 0xec: 0x000a, 0xed: 0x000b, 0xee: 0x000a, 0xef: 0x000a,
+       0xf0: 0x0004, 0xf1: 0x0004, 0xf2: 0x0002, 0xf3: 0x0002, 0xf4: 0x000a,
+       0xf6: 0x000a, 0xf7: 0x000a, 0xf8: 0x000a, 0xf9: 0x0002, 0xfb: 0x000a,
+       0xfc: 0x000a, 0xfd: 0x000a, 0xfe: 0x000a, 0xff: 0x000a,
+       // Block 0x4, offset 0x100
+       0x117: 0x000a,
+       0x137: 0x000a,
+       // Block 0x5, offset 0x140
+       0x179: 0x000a, 0x17a: 0x000a,
+       // Block 0x6, offset 0x180
+       0x182: 0x000a, 0x183: 0x000a, 0x184: 0x000a, 0x185: 0x000a,
+       0x186: 0x000a, 0x187: 0x000a, 0x188: 0x000a, 0x189: 0x000a, 0x18a: 0x000a, 0x18b: 0x000a,
+       0x18c: 0x000a, 0x18d: 0x000a, 0x18e: 0x000a, 0x18f: 0x000a,
+       0x192: 0x000a, 0x193: 0x000a, 0x194: 0x000a, 0x195: 0x000a, 0x196: 0x000a, 0x197: 0x000a,
+       0x198: 0x000a, 0x199: 0x000a, 0x19a: 0x000a, 0x19b: 0x000a, 0x19c: 0x000a, 0x19d: 0x000a,
+       0x19e: 0x000a, 0x19f: 0x000a,
+       0x1a5: 0x000a, 0x1a6: 0x000a, 0x1a7: 0x000a, 0x1a8: 0x000a, 0x1a9: 0x000a,
+       0x1aa: 0x000a, 0x1ab: 0x000a, 0x1ac: 0x000a, 0x1ad: 0x000a, 0x1af: 0x000a,
+       0x1b0: 0x000a, 0x1b1: 0x000a, 0x1b2: 0x000a, 0x1b3: 0x000a, 0x1b4: 0x000a, 0x1b5: 0x000a,
+       0x1b6: 0x000a, 0x1b7: 0x000a, 0x1b8: 0x000a, 0x1b9: 0x000a, 0x1ba: 0x000a, 0x1bb: 0x000a,
+       0x1bc: 0x000a, 0x1bd: 0x000a, 0x1be: 0x000a, 0x1bf: 0x000a,
+       // Block 0x7, offset 0x1c0
+       0x1c0: 0x000c, 0x1c1: 0x000c, 0x1c2: 0x000c, 0x1c3: 0x000c, 0x1c4: 0x000c, 0x1c5: 0x000c,
+       0x1c6: 0x000c, 0x1c7: 0x000c, 0x1c8: 0x000c, 0x1c9: 0x000c, 0x1ca: 0x000c, 0x1cb: 0x000c,
+       0x1cc: 0x000c, 0x1cd: 0x000c, 0x1ce: 0x000c, 0x1cf: 0x000c, 0x1d0: 0x000c, 0x1d1: 0x000c,
+       0x1d2: 0x000c, 0x1d3: 0x000c, 0x1d4: 0x000c, 0x1d5: 0x000c, 0x1d6: 0x000c, 0x1d7: 0x000c,
+       0x1d8: 0x000c, 0x1d9: 0x000c, 0x1da: 0x000c, 0x1db: 0x000c, 0x1dc: 0x000c, 0x1dd: 0x000c,
+       0x1de: 0x000c, 0x1df: 0x000c, 0x1e0: 0x000c, 0x1e1: 0x000c, 0x1e2: 0x000c, 0x1e3: 0x000c,
+       0x1e4: 0x000c, 0x1e5: 0x000c, 0x1e6: 0x000c, 0x1e7: 0x000c, 0x1e8: 0x000c, 0x1e9: 0x000c,
+       0x1ea: 0x000c, 0x1eb: 0x000c, 0x1ec: 0x000c, 0x1ed: 0x000c, 0x1ee: 0x000c, 0x1ef: 0x000c,
+       0x1f0: 0x000c, 0x1f1: 0x000c, 0x1f2: 0x000c, 0x1f3: 0x000c, 0x1f4: 0x000c, 0x1f5: 0x000c,
+       0x1f6: 0x000c, 0x1f7: 0x000c, 0x1f8: 0x000c, 0x1f9: 0x000c, 0x1fa: 0x000c, 0x1fb: 0x000c,
+       0x1fc: 0x000c, 0x1fd: 0x000c, 0x1fe: 0x000c, 0x1ff: 0x000c,
+       // Block 0x8, offset 0x200
+       0x200: 0x000c, 0x201: 0x000c, 0x202: 0x000c, 0x203: 0x000c, 0x204: 0x000c, 0x205: 0x000c,
+       0x206: 0x000c, 0x207: 0x000c, 0x208: 0x000c, 0x209: 0x000c, 0x20a: 0x000c, 0x20b: 0x000c,
+       0x20c: 0x000c, 0x20d: 0x000c, 0x20e: 0x000c, 0x20f: 0x000c, 0x210: 0x000c, 0x211: 0x000c,
+       0x212: 0x000c, 0x213: 0x000c, 0x214: 0x000c, 0x215: 0x000c, 0x216: 0x000c, 0x217: 0x000c,
+       0x218: 0x000c, 0x219: 0x000c, 0x21a: 0x000c, 0x21b: 0x000c, 0x21c: 0x000c, 0x21d: 0x000c,
+       0x21e: 0x000c, 0x21f: 0x000c, 0x220: 0x000c, 0x221: 0x000c, 0x222: 0x000c, 0x223: 0x000c,
+       0x224: 0x000c, 0x225: 0x000c, 0x226: 0x000c, 0x227: 0x000c, 0x228: 0x000c, 0x229: 0x000c,
+       0x22a: 0x000c, 0x22b: 0x000c, 0x22c: 0x000c, 0x22d: 0x000c, 0x22e: 0x000c, 0x22f: 0x000c,
+       0x234: 0x000a, 0x235: 0x000a,
+       0x23e: 0x000a,
+       // Block 0x9, offset 0x240
+       0x244: 0x000a, 0x245: 0x000a,
+       0x247: 0x000a,
+       // Block 0xa, offset 0x280
+       0x2b6: 0x000a,
+       // Block 0xb, offset 0x2c0
+       0x2c3: 0x000c, 0x2c4: 0x000c, 0x2c5: 0x000c,
+       0x2c6: 0x000c, 0x2c7: 0x000c, 0x2c8: 0x000c, 0x2c9: 0x000c,
+       // Block 0xc, offset 0x300
+       0x30a: 0x000a,
+       0x30d: 0x000a, 0x30e: 0x000a, 0x30f: 0x0004, 0x310: 0x0001, 0x311: 0x000c,
+       0x312: 0x000c, 0x313: 0x000c, 0x314: 0x000c, 0x315: 0x000c, 0x316: 0x000c, 0x317: 0x000c,
+       0x318: 0x000c, 0x319: 0x000c, 0x31a: 0x000c, 0x31b: 0x000c, 0x31c: 0x000c, 0x31d: 0x000c,
+       0x31e: 0x000c, 0x31f: 0x000c, 0x320: 0x000c, 0x321: 0x000c, 0x322: 0x000c, 0x323: 0x000c,
+       0x324: 0x000c, 0x325: 0x000c, 0x326: 0x000c, 0x327: 0x000c, 0x328: 0x000c, 0x329: 0x000c,
+       0x32a: 0x000c, 0x32b: 0x000c, 0x32c: 0x000c, 0x32d: 0x000c, 0x32e: 0x000c, 0x32f: 0x000c,
+       0x330: 0x000c, 0x331: 0x000c, 0x332: 0x000c, 0x333: 0x000c, 0x334: 0x000c, 0x335: 0x000c,
+       0x336: 0x000c, 0x337: 0x000c, 0x338: 0x000c, 0x339: 0x000c, 0x33a: 0x000c, 0x33b: 0x000c,
+       0x33c: 0x000c, 0x33d: 0x000c, 0x33e: 0x0001, 0x33f: 0x000c,
+       // Block 0xd, offset 0x340
+       0x340: 0x0001, 0x341: 0x000c, 0x342: 0x000c, 0x343: 0x0001, 0x344: 0x000c, 0x345: 0x000c,
+       0x346: 0x0001, 0x347: 0x000c, 0x348: 0x0001, 0x349: 0x0001, 0x34a: 0x0001, 0x34b: 0x0001,
+       0x34c: 0x0001, 0x34d: 0x0001, 0x34e: 0x0001, 0x34f: 0x0001, 0x350: 0x0001, 0x351: 0x0001,
+       0x352: 0x0001, 0x353: 0x0001, 0x354: 0x0001, 0x355: 0x0001, 0x356: 0x0001, 0x357: 0x0001,
+       0x358: 0x0001, 0x359: 0x0001, 0x35a: 0x0001, 0x35b: 0x0001, 0x35c: 0x0001, 0x35d: 0x0001,
+       0x35e: 0x0001, 0x35f: 0x0001, 0x360: 0x0001, 0x361: 0x0001, 0x362: 0x0001, 0x363: 0x0001,
+       0x364: 0x0001, 0x365: 0x0001, 0x366: 0x0001, 0x367: 0x0001, 0x368: 0x0001, 0x369: 0x0001,
+       0x36a: 0x0001, 0x36b: 0x0001, 0x36c: 0x0001, 0x36d: 0x0001, 0x36e: 0x0001, 0x36f: 0x0001,
+       0x370: 0x0001, 0x371: 0x0001, 0x372: 0x0001, 0x373: 0x0001, 0x374: 0x0001, 0x375: 0x0001,
+       0x376: 0x0001, 0x377: 0x0001, 0x378: 0x0001, 0x379: 0x0001, 0x37a: 0x0001, 0x37b: 0x0001,
+       0x37c: 0x0001, 0x37d: 0x0001, 0x37e: 0x0001, 0x37f: 0x0001,
+       // Block 0xe, offset 0x380
+       0x380: 0x0005, 0x381: 0x0005, 0x382: 0x0005, 0x383: 0x0005, 0x384: 0x0005, 0x385: 0x0005,
+       0x386: 0x000a, 0x387: 0x000a, 0x388: 0x000d, 0x389: 0x0004, 0x38a: 0x0004, 0x38b: 0x000d,
+       0x38c: 0x0006, 0x38d: 0x000d, 0x38e: 0x000a, 0x38f: 0x000a, 0x390: 0x000c, 0x391: 0x000c,
+       0x392: 0x000c, 0x393: 0x000c, 0x394: 0x000c, 0x395: 0x000c, 0x396: 0x000c, 0x397: 0x000c,
+       0x398: 0x000c, 0x399: 0x000c, 0x39a: 0x000c, 0x39b: 0x000d, 0x39c: 0x000d, 0x39d: 0x000d,
+       0x39e: 0x000d, 0x39f: 0x000d, 0x3a0: 0x000d, 0x3a1: 0x000d, 0x3a2: 0x000d, 0x3a3: 0x000d,
+       0x3a4: 0x000d, 0x3a5: 0x000d, 0x3a6: 0x000d, 0x3a7: 0x000d, 0x3a8: 0x000d, 0x3a9: 0x000d,
+       0x3aa: 0x000d, 0x3ab: 0x000d, 0x3ac: 0x000d, 0x3ad: 0x000d, 0x3ae: 0x000d, 0x3af: 0x000d,
+       0x3b0: 0x000d, 0x3b1: 0x000d, 0x3b2: 0x000d, 0x3b3: 0x000d, 0x3b4: 0x000d, 0x3b5: 0x000d,
+       0x3b6: 0x000d, 0x3b7: 0x000d, 0x3b8: 0x000d, 0x3b9: 0x000d, 0x3ba: 0x000d, 0x3bb: 0x000d,
+       0x3bc: 0x000d, 0x3bd: 0x000d, 0x3be: 0x000d, 0x3bf: 0x000d,
+       // Block 0xf, offset 0x3c0
+       0x3c0: 0x000d, 0x3c1: 0x000d, 0x3c2: 0x000d, 0x3c3: 0x000d, 0x3c4: 0x000d, 0x3c5: 0x000d,
+       0x3c6: 0x000d, 0x3c7: 0x000d, 0x3c8: 0x000d, 0x3c9: 0x000d, 0x3ca: 0x000d, 0x3cb: 0x000c,
+       0x3cc: 0x000c, 0x3cd: 0x000c, 0x3ce: 0x000c, 0x3cf: 0x000c, 0x3d0: 0x000c, 0x3d1: 0x000c,
+       0x3d2: 0x000c, 0x3d3: 0x000c, 0x3d4: 0x000c, 0x3d5: 0x000c, 0x3d6: 0x000c, 0x3d7: 0x000c,
+       0x3d8: 0x000c, 0x3d9: 0x000c, 0x3da: 0x000c, 0x3db: 0x000c, 0x3dc: 0x000c, 0x3dd: 0x000c,
+       0x3de: 0x000c, 0x3df: 0x000c, 0x3e0: 0x0005, 0x3e1: 0x0005, 0x3e2: 0x0005, 0x3e3: 0x0005,
+       0x3e4: 0x0005, 0x3e5: 0x0005, 0x3e6: 0x0005, 0x3e7: 0x0005, 0x3e8: 0x0005, 0x3e9: 0x0005,
+       0x3ea: 0x0004, 0x3eb: 0x0005, 0x3ec: 0x0005, 0x3ed: 0x000d, 0x3ee: 0x000d, 0x3ef: 0x000d,
+       0x3f0: 0x000c, 0x3f1: 0x000d, 0x3f2: 0x000d, 0x3f3: 0x000d, 0x3f4: 0x000d, 0x3f5: 0x000d,
+       0x3f6: 0x000d, 0x3f7: 0x000d, 0x3f8: 0x000d, 0x3f9: 0x000d, 0x3fa: 0x000d, 0x3fb: 0x000d,
+       0x3fc: 0x000d, 0x3fd: 0x000d, 0x3fe: 0x000d, 0x3ff: 0x000d,
+       // Block 0x10, offset 0x400
+       0x400: 0x000d, 0x401: 0x000d, 0x402: 0x000d, 0x403: 0x000d, 0x404: 0x000d, 0x405: 0x000d,
+       0x406: 0x000d, 0x407: 0x000d, 0x408: 0x000d, 0x409: 0x000d, 0x40a: 0x000d, 0x40b: 0x000d,
+       0x40c: 0x000d, 0x40d: 0x000d, 0x40e: 0x000d, 0x40f: 0x000d, 0x410: 0x000d, 0x411: 0x000d,
+       0x412: 0x000d, 0x413: 0x000d, 0x414: 0x000d, 0x415: 0x000d, 0x416: 0x000d, 0x417: 0x000d,
+       0x418: 0x000d, 0x419: 0x000d, 0x41a: 0x000d, 0x41b: 0x000d, 0x41c: 0x000d, 0x41d: 0x000d,
+       0x41e: 0x000d, 0x41f: 0x000d, 0x420: 0x000d, 0x421: 0x000d, 0x422: 0x000d, 0x423: 0x000d,
+       0x424: 0x000d, 0x425: 0x000d, 0x426: 0x000d, 0x427: 0x000d, 0x428: 0x000d, 0x429: 0x000d,
+       0x42a: 0x000d, 0x42b: 0x000d, 0x42c: 0x000d, 0x42d: 0x000d, 0x42e: 0x000d, 0x42f: 0x000d,
+       0x430: 0x000d, 0x431: 0x000d, 0x432: 0x000d, 0x433: 0x000d, 0x434: 0x000d, 0x435: 0x000d,
+       0x436: 0x000d, 0x437: 0x000d, 0x438: 0x000d, 0x439: 0x000d, 0x43a: 0x000d, 0x43b: 0x000d,
+       0x43c: 0x000d, 0x43d: 0x000d, 0x43e: 0x000d, 0x43f: 0x000d,
+       // Block 0x11, offset 0x440
+       0x440: 0x000d, 0x441: 0x000d, 0x442: 0x000d, 0x443: 0x000d, 0x444: 0x000d, 0x445: 0x000d,
+       0x446: 0x000d, 0x447: 0x000d, 0x448: 0x000d, 0x449: 0x000d, 0x44a: 0x000d, 0x44b: 0x000d,
+       0x44c: 0x000d, 0x44d: 0x000d, 0x44e: 0x000d, 0x44f: 0x000d, 0x450: 0x000d, 0x451: 0x000d,
+       0x452: 0x000d, 0x453: 0x000d, 0x454: 0x000d, 0x455: 0x000d, 0x456: 0x000c, 0x457: 0x000c,
+       0x458: 0x000c, 0x459: 0x000c, 0x45a: 0x000c, 0x45b: 0x000c, 0x45c: 0x000c, 0x45d: 0x0005,
+       0x45e: 0x000a, 0x45f: 0x000c, 0x460: 0x000c, 0x461: 0x000c, 0x462: 0x000c, 0x463: 0x000c,
+       0x464: 0x000c, 0x465: 0x000d, 0x466: 0x000d, 0x467: 0x000c, 0x468: 0x000c, 0x469: 0x000a,
+       0x46a: 0x000c, 0x46b: 0x000c, 0x46c: 0x000c, 0x46d: 0x000c, 0x46e: 0x000d, 0x46f: 0x000d,
+       0x470: 0x0002, 0x471: 0x0002, 0x472: 0x0002, 0x473: 0x0002, 0x474: 0x0002, 0x475: 0x0002,
+       0x476: 0x0002, 0x477: 0x0002, 0x478: 0x0002, 0x479: 0x0002, 0x47a: 0x000d, 0x47b: 0x000d,
+       0x47c: 0x000d, 0x47d: 0x000d, 0x47e: 0x000d, 0x47f: 0x000d,
+       // Block 0x12, offset 0x480
+       0x480: 0x000d, 0x481: 0x000d, 0x482: 0x000d, 0x483: 0x000d, 0x484: 0x000d, 0x485: 0x000d,
+       0x486: 0x000d, 0x487: 0x000d, 0x488: 0x000d, 0x489: 0x000d, 0x48a: 0x000d, 0x48b: 0x000d,
+       0x48c: 0x000d, 0x48d: 0x000d, 0x48e: 0x000d, 0x48f: 0x000d, 0x490: 0x000d, 0x491: 0x000c,
+       0x492: 0x000d, 0x493: 0x000d, 0x494: 0x000d, 0x495: 0x000d, 0x496: 0x000d, 0x497: 0x000d,
+       0x498: 0x000d, 0x499: 0x000d, 0x49a: 0x000d, 0x49b: 0x000d, 0x49c: 0x000d, 0x49d: 0x000d,
+       0x49e: 0x000d, 0x49f: 0x000d, 0x4a0: 0x000d, 0x4a1: 0x000d, 0x4a2: 0x000d, 0x4a3: 0x000d,
+       0x4a4: 0x000d, 0x4a5: 0x000d, 0x4a6: 0x000d, 0x4a7: 0x000d, 0x4a8: 0x000d, 0x4a9: 0x000d,
+       0x4aa: 0x000d, 0x4ab: 0x000d, 0x4ac: 0x000d, 0x4ad: 0x000d, 0x4ae: 0x000d, 0x4af: 0x000d,
+       0x4b0: 0x000c, 0x4b1: 0x000c, 0x4b2: 0x000c, 0x4b3: 0x000c, 0x4b4: 0x000c, 0x4b5: 0x000c,
+       0x4b6: 0x000c, 0x4b7: 0x000c, 0x4b8: 0x000c, 0x4b9: 0x000c, 0x4ba: 0x000c, 0x4bb: 0x000c,
+       0x4bc: 0x000c, 0x4bd: 0x000c, 0x4be: 0x000c, 0x4bf: 0x000c,
+       // Block 0x13, offset 0x4c0
+       0x4c0: 0x000c, 0x4c1: 0x000c, 0x4c2: 0x000c, 0x4c3: 0x000c, 0x4c4: 0x000c, 0x4c5: 0x000c,
+       0x4c6: 0x000c, 0x4c7: 0x000c, 0x4c8: 0x000c, 0x4c9: 0x000c, 0x4ca: 0x000c, 0x4cb: 0x000d,
+       0x4cc: 0x000d, 0x4cd: 0x000d, 0x4ce: 0x000d, 0x4cf: 0x000d, 0x4d0: 0x000d, 0x4d1: 0x000d,
+       0x4d2: 0x000d, 0x4d3: 0x000d, 0x4d4: 0x000d, 0x4d5: 0x000d, 0x4d6: 0x000d, 0x4d7: 0x000d,
+       0x4d8: 0x000d, 0x4d9: 0x000d, 0x4da: 0x000d, 0x4db: 0x000d, 0x4dc: 0x000d, 0x4dd: 0x000d,
+       0x4de: 0x000d, 0x4df: 0x000d, 0x4e0: 0x000d, 0x4e1: 0x000d, 0x4e2: 0x000d, 0x4e3: 0x000d,
+       0x4e4: 0x000d, 0x4e5: 0x000d, 0x4e6: 0x000d, 0x4e7: 0x000d, 0x4e8: 0x000d, 0x4e9: 0x000d,
+       0x4ea: 0x000d, 0x4eb: 0x000d, 0x4ec: 0x000d, 0x4ed: 0x000d, 0x4ee: 0x000d, 0x4ef: 0x000d,
+       0x4f0: 0x000d, 0x4f1: 0x000d, 0x4f2: 0x000d, 0x4f3: 0x000d, 0x4f4: 0x000d, 0x4f5: 0x000d,
+       0x4f6: 0x000d, 0x4f7: 0x000d, 0x4f8: 0x000d, 0x4f9: 0x000d, 0x4fa: 0x000d, 0x4fb: 0x000d,
+       0x4fc: 0x000d, 0x4fd: 0x000d, 0x4fe: 0x000d, 0x4ff: 0x000d,
+       // Block 0x14, offset 0x500
+       0x500: 0x000d, 0x501: 0x000d, 0x502: 0x000d, 0x503: 0x000d, 0x504: 0x000d, 0x505: 0x000d,
+       0x506: 0x000d, 0x507: 0x000d, 0x508: 0x000d, 0x509: 0x000d, 0x50a: 0x000d, 0x50b: 0x000d,
+       0x50c: 0x000d, 0x50d: 0x000d, 0x50e: 0x000d, 0x50f: 0x000d, 0x510: 0x000d, 0x511: 0x000d,
+       0x512: 0x000d, 0x513: 0x000d, 0x514: 0x000d, 0x515: 0x000d, 0x516: 0x000d, 0x517: 0x000d,
+       0x518: 0x000d, 0x519: 0x000d, 0x51a: 0x000d, 0x51b: 0x000d, 0x51c: 0x000d, 0x51d: 0x000d,
+       0x51e: 0x000d, 0x51f: 0x000d, 0x520: 0x000d, 0x521: 0x000d, 0x522: 0x000d, 0x523: 0x000d,
+       0x524: 0x000d, 0x525: 0x000d, 0x526: 0x000c, 0x527: 0x000c, 0x528: 0x000c, 0x529: 0x000c,
+       0x52a: 0x000c, 0x52b: 0x000c, 0x52c: 0x000c, 0x52d: 0x000c, 0x52e: 0x000c, 0x52f: 0x000c,
+       0x530: 0x000c, 0x531: 0x000d, 0x532: 0x000d, 0x533: 0x000d, 0x534: 0x000d, 0x535: 0x000d,
+       0x536: 0x000d, 0x537: 0x000d, 0x538: 0x000d, 0x539: 0x000d, 0x53a: 0x000d, 0x53b: 0x000d,
+       0x53c: 0x000d, 0x53d: 0x000d, 0x53e: 0x000d, 0x53f: 0x000d,
+       // Block 0x15, offset 0x540
+       0x540: 0x0001, 0x541: 0x0001, 0x542: 0x0001, 0x543: 0x0001, 0x544: 0x0001, 0x545: 0x0001,
+       0x546: 0x0001, 0x547: 0x0001, 0x548: 0x0001, 0x549: 0x0001, 0x54a: 0x0001, 0x54b: 0x0001,
+       0x54c: 0x0001, 0x54d: 0x0001, 0x54e: 0x0001, 0x54f: 0x0001, 0x550: 0x0001, 0x551: 0x0001,
+       0x552: 0x0001, 0x553: 0x0001, 0x554: 0x0001, 0x555: 0x0001, 0x556: 0x0001, 0x557: 0x0001,
+       0x558: 0x0001, 0x559: 0x0001, 0x55a: 0x0001, 0x55b: 0x0001, 0x55c: 0x0001, 0x55d: 0x0001,
+       0x55e: 0x0001, 0x55f: 0x0001, 0x560: 0x0001, 0x561: 0x0001, 0x562: 0x0001, 0x563: 0x0001,
+       0x564: 0x0001, 0x565: 0x0001, 0x566: 0x0001, 0x567: 0x0001, 0x568: 0x0001, 0x569: 0x0001,
+       0x56a: 0x0001, 0x56b: 0x000c, 0x56c: 0x000c, 0x56d: 0x000c, 0x56e: 0x000c, 0x56f: 0x000c,
+       0x570: 0x000c, 0x571: 0x000c, 0x572: 0x000c, 0x573: 0x000c, 0x574: 0x0001, 0x575: 0x0001,
+       0x576: 0x000a, 0x577: 0x000a, 0x578: 0x000a, 0x579: 0x000a, 0x57a: 0x0001, 0x57b: 0x0001,
+       0x57c: 0x0001, 0x57d: 0x000c, 0x57e: 0x0001, 0x57f: 0x0001,
+       // Block 0x16, offset 0x580
+       0x580: 0x0001, 0x581: 0x0001, 0x582: 0x0001, 0x583: 0x0001, 0x584: 0x0001, 0x585: 0x0001,
+       0x586: 0x0001, 0x587: 0x0001, 0x588: 0x0001, 0x589: 0x0001, 0x58a: 0x0001, 0x58b: 0x0001,
+       0x58c: 0x0001, 0x58d: 0x0001, 0x58e: 0x0001, 0x58f: 0x0001, 0x590: 0x0001, 0x591: 0x0001,
+       0x592: 0x0001, 0x593: 0x0001, 0x594: 0x0001, 0x595: 0x0001, 0x596: 0x000c, 0x597: 0x000c,
+       0x598: 0x000c, 0x599: 0x000c, 0x59a: 0x0001, 0x59b: 0x000c, 0x59c: 0x000c, 0x59d: 0x000c,
+       0x59e: 0x000c, 0x59f: 0x000c, 0x5a0: 0x000c, 0x5a1: 0x000c, 0x5a2: 0x000c, 0x5a3: 0x000c,
+       0x5a4: 0x0001, 0x5a5: 0x000c, 0x5a6: 0x000c, 0x5a7: 0x000c, 0x5a8: 0x0001, 0x5a9: 0x000c,
+       0x5aa: 0x000c, 0x5ab: 0x000c, 0x5ac: 0x000c, 0x5ad: 0x000c, 0x5ae: 0x0001, 0x5af: 0x0001,
+       0x5b0: 0x0001, 0x5b1: 0x0001, 0x5b2: 0x0001, 0x5b3: 0x0001, 0x5b4: 0x0001, 0x5b5: 0x0001,
+       0x5b6: 0x0001, 0x5b7: 0x0001, 0x5b8: 0x0001, 0x5b9: 0x0001, 0x5ba: 0x0001, 0x5bb: 0x0001,
+       0x5bc: 0x0001, 0x5bd: 0x0001, 0x5be: 0x0001, 0x5bf: 0x0001,
+       // Block 0x17, offset 0x5c0
+       0x5c0: 0x0001, 0x5c1: 0x0001, 0x5c2: 0x0001, 0x5c3: 0x0001, 0x5c4: 0x0001, 0x5c5: 0x0001,
+       0x5c6: 0x0001, 0x5c7: 0x0001, 0x5c8: 0x0001, 0x5c9: 0x0001, 0x5ca: 0x0001, 0x5cb: 0x0001,
+       0x5cc: 0x0001, 0x5cd: 0x0001, 0x5ce: 0x0001, 0x5cf: 0x0001, 0x5d0: 0x0001, 0x5d1: 0x0001,
+       0x5d2: 0x0001, 0x5d3: 0x0001, 0x5d4: 0x0001, 0x5d5: 0x0001, 0x5d6: 0x0001, 0x5d7: 0x0001,
+       0x5d8: 0x0001, 0x5d9: 0x000c, 0x5da: 0x000c, 0x5db: 0x000c, 0x5dc: 0x0001, 0x5dd: 0x0001,
+       0x5de: 0x0001, 0x5df: 0x0001, 0x5e0: 0x000d, 0x5e1: 0x000d, 0x5e2: 0x000d, 0x5e3: 0x000d,
+       0x5e4: 0x000d, 0x5e5: 0x000d, 0x5e6: 0x000d, 0x5e7: 0x000d, 0x5e8: 0x000d, 0x5e9: 0x000d,
+       0x5ea: 0x000d, 0x5eb: 0x000d, 0x5ec: 0x000d, 0x5ed: 0x000d, 0x5ee: 0x000d, 0x5ef: 0x000d,
+       0x5f0: 0x0001, 0x5f1: 0x0001, 0x5f2: 0x0001, 0x5f3: 0x0001, 0x5f4: 0x0001, 0x5f5: 0x0001,
+       0x5f6: 0x0001, 0x5f7: 0x0001, 0x5f8: 0x0001, 0x5f9: 0x0001, 0x5fa: 0x0001, 0x5fb: 0x0001,
+       0x5fc: 0x0001, 0x5fd: 0x0001, 0x5fe: 0x0001, 0x5ff: 0x0001,
+       // Block 0x18, offset 0x600
+       0x600: 0x0001, 0x601: 0x0001, 0x602: 0x0001, 0x603: 0x0001, 0x604: 0x0001, 0x605: 0x0001,
+       0x606: 0x0001, 0x607: 0x0001, 0x608: 0x0001, 0x609: 0x0001, 0x60a: 0x0001, 0x60b: 0x0001,
+       0x60c: 0x0001, 0x60d: 0x0001, 0x60e: 0x0001, 0x60f: 0x0001, 0x610: 0x0001, 0x611: 0x0001,
+       0x612: 0x0001, 0x613: 0x0001, 0x614: 0x0001, 0x615: 0x0001, 0x616: 0x0001, 0x617: 0x0001,
+       0x618: 0x0001, 0x619: 0x0001, 0x61a: 0x0001, 0x61b: 0x0001, 0x61c: 0x0001, 0x61d: 0x0001,
+       0x61e: 0x0001, 0x61f: 0x0001, 0x620: 0x000d, 0x621: 0x000d, 0x622: 0x000d, 0x623: 0x000d,
+       0x624: 0x000d, 0x625: 0x000d, 0x626: 0x000d, 0x627: 0x000d, 0x628: 0x000d, 0x629: 0x000d,
+       0x62a: 0x000d, 0x62b: 0x000d, 0x62c: 0x000d, 0x62d: 0x000d, 0x62e: 0x000d, 0x62f: 0x000d,
+       0x630: 0x000d, 0x631: 0x000d, 0x632: 0x000d, 0x633: 0x000d, 0x634: 0x000d, 0x635: 0x000d,
+       0x636: 0x000d, 0x637: 0x000d, 0x638: 0x000d, 0x639: 0x000d, 0x63a: 0x000d, 0x63b: 0x000d,
+       0x63c: 0x000d, 0x63d: 0x000d, 0x63e: 0x000d, 0x63f: 0x000d,
+       // Block 0x19, offset 0x640
+       0x640: 0x000d, 0x641: 0x000d, 0x642: 0x000d, 0x643: 0x000d, 0x644: 0x000d, 0x645: 0x000d,
+       0x646: 0x000d, 0x647: 0x000d, 0x648: 0x000d, 0x649: 0x000d, 0x64a: 0x000d, 0x64b: 0x000d,
+       0x64c: 0x000d, 0x64d: 0x000d, 0x64e: 0x000d, 0x64f: 0x000d, 0x650: 0x000d, 0x651: 0x000d,
+       0x652: 0x000d, 0x653: 0x000c, 0x654: 0x000c, 0x655: 0x000c, 0x656: 0x000c, 0x657: 0x000c,
+       0x658: 0x000c, 0x659: 0x000c, 0x65a: 0x000c, 0x65b: 0x000c, 0x65c: 0x000c, 0x65d: 0x000c,
+       0x65e: 0x000c, 0x65f: 0x000c, 0x660: 0x000c, 0x661: 0x000c, 0x662: 0x0005, 0x663: 0x000c,
+       0x664: 0x000c, 0x665: 0x000c, 0x666: 0x000c, 0x667: 0x000c, 0x668: 0x000c, 0x669: 0x000c,
+       0x66a: 0x000c, 0x66b: 0x000c, 0x66c: 0x000c, 0x66d: 0x000c, 0x66e: 0x000c, 0x66f: 0x000c,
+       0x670: 0x000c, 0x671: 0x000c, 0x672: 0x000c, 0x673: 0x000c, 0x674: 0x000c, 0x675: 0x000c,
+       0x676: 0x000c, 0x677: 0x000c, 0x678: 0x000c, 0x679: 0x000c, 0x67a: 0x000c, 0x67b: 0x000c,
+       0x67c: 0x000c, 0x67d: 0x000c, 0x67e: 0x000c, 0x67f: 0x000c,
+       // Block 0x1a, offset 0x680
+       0x680: 0x000c, 0x681: 0x000c, 0x682: 0x000c,
+       0x6ba: 0x000c,
+       0x6bc: 0x000c,
+       // Block 0x1b, offset 0x6c0
+       0x6c1: 0x000c, 0x6c2: 0x000c, 0x6c3: 0x000c, 0x6c4: 0x000c, 0x6c5: 0x000c,
+       0x6c6: 0x000c, 0x6c7: 0x000c, 0x6c8: 0x000c,
+       0x6cd: 0x000c, 0x6d1: 0x000c,
+       0x6d2: 0x000c, 0x6d3: 0x000c, 0x6d4: 0x000c, 0x6d5: 0x000c, 0x6d6: 0x000c, 0x6d7: 0x000c,
+       0x6e2: 0x000c, 0x6e3: 0x000c,
+       // Block 0x1c, offset 0x700
+       0x701: 0x000c,
+       0x73c: 0x000c,
+       // Block 0x1d, offset 0x740
+       0x741: 0x000c, 0x742: 0x000c, 0x743: 0x000c, 0x744: 0x000c,
+       0x74d: 0x000c,
+       0x762: 0x000c, 0x763: 0x000c,
+       0x772: 0x0004, 0x773: 0x0004,
+       0x77b: 0x0004,
+       0x77e: 0x000c,
+       // Block 0x1e, offset 0x780
+       0x781: 0x000c, 0x782: 0x000c,
+       0x7bc: 0x000c,
+       // Block 0x1f, offset 0x7c0
+       0x7c1: 0x000c, 0x7c2: 0x000c,
+       0x7c7: 0x000c, 0x7c8: 0x000c, 0x7cb: 0x000c,
+       0x7cc: 0x000c, 0x7cd: 0x000c, 0x7d1: 0x000c,
+       0x7f0: 0x000c, 0x7f1: 0x000c, 0x7f5: 0x000c,
+       // Block 0x20, offset 0x800
+       0x801: 0x000c, 0x802: 0x000c, 0x803: 0x000c, 0x804: 0x000c, 0x805: 0x000c,
+       0x807: 0x000c, 0x808: 0x000c,
+       0x80d: 0x000c,
+       0x822: 0x000c, 0x823: 0x000c,
+       0x831: 0x0004,
+       0x83a: 0x000c, 0x83b: 0x000c,
+       0x83c: 0x000c, 0x83d: 0x000c, 0x83e: 0x000c, 0x83f: 0x000c,
+       // Block 0x21, offset 0x840
+       0x841: 0x000c,
+       0x87c: 0x000c, 0x87f: 0x000c,
+       // Block 0x22, offset 0x880
+       0x881: 0x000c, 0x882: 0x000c, 0x883: 0x000c, 0x884: 0x000c,
+       0x88d: 0x000c,
+       0x895: 0x000c, 0x896: 0x000c,
+       0x8a2: 0x000c, 0x8a3: 0x000c,
+       // Block 0x23, offset 0x8c0
+       0x8c2: 0x000c,
+       // Block 0x24, offset 0x900
+       0x900: 0x000c,
+       0x90d: 0x000c,
+       0x933: 0x000a, 0x934: 0x000a, 0x935: 0x000a,
+       0x936: 0x000a, 0x937: 0x000a, 0x938: 0x000a, 0x939: 0x0004, 0x93a: 0x000a,
+       // Block 0x25, offset 0x940
+       0x940: 0x000c, 0x944: 0x000c,
+       0x97e: 0x000c, 0x97f: 0x000c,
+       // Block 0x26, offset 0x980
+       0x980: 0x000c,
+       0x986: 0x000c, 0x987: 0x000c, 0x988: 0x000c, 0x98a: 0x000c, 0x98b: 0x000c,
+       0x98c: 0x000c, 0x98d: 0x000c,
+       0x995: 0x000c, 0x996: 0x000c,
+       0x9a2: 0x000c, 0x9a3: 0x000c,
+       0x9b8: 0x000a, 0x9b9: 0x000a, 0x9ba: 0x000a, 0x9bb: 0x000a,
+       0x9bc: 0x000a, 0x9bd: 0x000a, 0x9be: 0x000a,
+       // Block 0x27, offset 0x9c0
+       0x9cc: 0x000c, 0x9cd: 0x000c,
+       0x9e2: 0x000c, 0x9e3: 0x000c,
+       // Block 0x28, offset 0xa00
+       0xa00: 0x000c, 0xa01: 0x000c,
+       0xa3b: 0x000c,
+       0xa3c: 0x000c,
+       // Block 0x29, offset 0xa40
+       0xa41: 0x000c, 0xa42: 0x000c, 0xa43: 0x000c, 0xa44: 0x000c,
+       0xa4d: 0x000c,
+       0xa62: 0x000c, 0xa63: 0x000c,
+       // Block 0x2a, offset 0xa80
+       0xa81: 0x000c,
+       // Block 0x2b, offset 0xac0
+       0xaca: 0x000c,
+       0xad2: 0x000c, 0xad3: 0x000c, 0xad4: 0x000c, 0xad6: 0x000c,
+       // Block 0x2c, offset 0xb00
+       0xb31: 0x000c, 0xb34: 0x000c, 0xb35: 0x000c,
+       0xb36: 0x000c, 0xb37: 0x000c, 0xb38: 0x000c, 0xb39: 0x000c, 0xb3a: 0x000c,
+       0xb3f: 0x0004,
+       // Block 0x2d, offset 0xb40
+       0xb47: 0x000c, 0xb48: 0x000c, 0xb49: 0x000c, 0xb4a: 0x000c, 0xb4b: 0x000c,
+       0xb4c: 0x000c, 0xb4d: 0x000c, 0xb4e: 0x000c,
+       // Block 0x2e, offset 0xb80
+       0xbb1: 0x000c, 0xbb4: 0x000c, 0xbb5: 0x000c,
+       0xbb6: 0x000c, 0xbb7: 0x000c, 0xbb8: 0x000c, 0xbb9: 0x000c, 0xbba: 0x000c, 0xbbb: 0x000c,
+       0xbbc: 0x000c,
+       // Block 0x2f, offset 0xbc0
+       0xbc8: 0x000c, 0xbc9: 0x000c, 0xbca: 0x000c, 0xbcb: 0x000c,
+       0xbcc: 0x000c, 0xbcd: 0x000c,
+       // Block 0x30, offset 0xc00
+       0xc18: 0x000c, 0xc19: 0x000c,
+       0xc35: 0x000c,
+       0xc37: 0x000c, 0xc39: 0x000c, 0xc3a: 0x003a, 0xc3b: 0x002a,
+       0xc3c: 0x003a, 0xc3d: 0x002a,
+       // Block 0x31, offset 0xc40
+       0xc71: 0x000c, 0xc72: 0x000c, 0xc73: 0x000c, 0xc74: 0x000c, 0xc75: 0x000c,
+       0xc76: 0x000c, 0xc77: 0x000c, 0xc78: 0x000c, 0xc79: 0x000c, 0xc7a: 0x000c, 0xc7b: 0x000c,
+       0xc7c: 0x000c, 0xc7d: 0x000c, 0xc7e: 0x000c,
+       // Block 0x32, offset 0xc80
+       0xc80: 0x000c, 0xc81: 0x000c, 0xc82: 0x000c, 0xc83: 0x000c, 0xc84: 0x000c,
+       0xc86: 0x000c, 0xc87: 0x000c,
+       0xc8d: 0x000c, 0xc8e: 0x000c, 0xc8f: 0x000c, 0xc90: 0x000c, 0xc91: 0x000c,
+       0xc92: 0x000c, 0xc93: 0x000c, 0xc94: 0x000c, 0xc95: 0x000c, 0xc96: 0x000c, 0xc97: 0x000c,
+       0xc99: 0x000c, 0xc9a: 0x000c, 0xc9b: 0x000c, 0xc9c: 0x000c, 0xc9d: 0x000c,
+       0xc9e: 0x000c, 0xc9f: 0x000c, 0xca0: 0x000c, 0xca1: 0x000c, 0xca2: 0x000c, 0xca3: 0x000c,
+       0xca4: 0x000c, 0xca5: 0x000c, 0xca6: 0x000c, 0xca7: 0x000c, 0xca8: 0x000c, 0xca9: 0x000c,
+       0xcaa: 0x000c, 0xcab: 0x000c, 0xcac: 0x000c, 0xcad: 0x000c, 0xcae: 0x000c, 0xcaf: 0x000c,
+       0xcb0: 0x000c, 0xcb1: 0x000c, 0xcb2: 0x000c, 0xcb3: 0x000c, 0xcb4: 0x000c, 0xcb5: 0x000c,
+       0xcb6: 0x000c, 0xcb7: 0x000c, 0xcb8: 0x000c, 0xcb9: 0x000c, 0xcba: 0x000c, 0xcbb: 0x000c,
+       0xcbc: 0x000c,
+       // Block 0x33, offset 0xcc0
+       0xcc6: 0x000c,
+       // Block 0x34, offset 0xd00
+       0xd2d: 0x000c, 0xd2e: 0x000c, 0xd2f: 0x000c,
+       0xd30: 0x000c, 0xd32: 0x000c, 0xd33: 0x000c, 0xd34: 0x000c, 0xd35: 0x000c,
+       0xd36: 0x000c, 0xd37: 0x000c, 0xd39: 0x000c, 0xd3a: 0x000c,
+       0xd3d: 0x000c, 0xd3e: 0x000c,
+       // Block 0x35, offset 0xd40
+       0xd58: 0x000c, 0xd59: 0x000c,
+       0xd5e: 0x000c, 0xd5f: 0x000c, 0xd60: 0x000c,
+       0xd71: 0x000c, 0xd72: 0x000c, 0xd73: 0x000c, 0xd74: 0x000c,
+       // Block 0x36, offset 0xd80
+       0xd82: 0x000c, 0xd85: 0x000c,
+       0xd86: 0x000c,
+       0xd8d: 0x000c,
+       0xd9d: 0x000c,
+       // Block 0x37, offset 0xdc0
+       0xddd: 0x000c,
+       0xdde: 0x000c, 0xddf: 0x000c,
+       // Block 0x38, offset 0xe00
+       0xe10: 0x000a, 0xe11: 0x000a,
+       0xe12: 0x000a, 0xe13: 0x000a, 0xe14: 0x000a, 0xe15: 0x000a, 0xe16: 0x000a, 0xe17: 0x000a,
+       0xe18: 0x000a, 0xe19: 0x000a,
+       // Block 0x39, offset 0xe40
+       0xe40: 0x000a,
+       // Block 0x3a, offset 0xe80
+       0xe80: 0x0009,
+       0xe9b: 0x007a, 0xe9c: 0x006a,
+       // Block 0x3b, offset 0xec0
+       0xed2: 0x000c, 0xed3: 0x000c, 0xed4: 0x000c,
+       0xef2: 0x000c, 0xef3: 0x000c, 0xef4: 0x000c,
+       // Block 0x3c, offset 0xf00
+       0xf12: 0x000c, 0xf13: 0x000c,
+       0xf32: 0x000c, 0xf33: 0x000c,
+       // Block 0x3d, offset 0xf40
+       0xf74: 0x000c, 0xf75: 0x000c,
+       0xf77: 0x000c, 0xf78: 0x000c, 0xf79: 0x000c, 0xf7a: 0x000c, 0xf7b: 0x000c,
+       0xf7c: 0x000c, 0xf7d: 0x000c,
+       // Block 0x3e, offset 0xf80
+       0xf86: 0x000c, 0xf89: 0x000c, 0xf8a: 0x000c, 0xf8b: 0x000c,
+       0xf8c: 0x000c, 0xf8d: 0x000c, 0xf8e: 0x000c, 0xf8f: 0x000c, 0xf90: 0x000c, 0xf91: 0x000c,
+       0xf92: 0x000c, 0xf93: 0x000c,
+       0xf9b: 0x0004, 0xf9d: 0x000c,
+       0xfb0: 0x000a, 0xfb1: 0x000a, 0xfb2: 0x000a, 0xfb3: 0x000a, 0xfb4: 0x000a, 0xfb5: 0x000a,
+       0xfb6: 0x000a, 0xfb7: 0x000a, 0xfb8: 0x000a, 0xfb9: 0x000a,
+       // Block 0x3f, offset 0xfc0
+       0xfc0: 0x000a, 0xfc1: 0x000a, 0xfc2: 0x000a, 0xfc3: 0x000a, 0xfc4: 0x000a, 0xfc5: 0x000a,
+       0xfc6: 0x000a, 0xfc7: 0x000a, 0xfc8: 0x000a, 0xfc9: 0x000a, 0xfca: 0x000a, 0xfcb: 0x000c,
+       0xfcc: 0x000c, 0xfcd: 0x000c, 0xfce: 0x000b,
+       // Block 0x40, offset 0x1000
+       0x1005: 0x000c,
+       0x1006: 0x000c,
+       0x1029: 0x000c,
+       // Block 0x41, offset 0x1040
+       0x1060: 0x000c, 0x1061: 0x000c, 0x1062: 0x000c,
+       0x1067: 0x000c, 0x1068: 0x000c,
+       0x1072: 0x000c,
+       0x1079: 0x000c, 0x107a: 0x000c, 0x107b: 0x000c,
+       // Block 0x42, offset 0x1080
+       0x1080: 0x000a, 0x1084: 0x000a, 0x1085: 0x000a,
+       // Block 0x43, offset 0x10c0
+       0x10de: 0x000a, 0x10df: 0x000a, 0x10e0: 0x000a, 0x10e1: 0x000a, 0x10e2: 0x000a, 0x10e3: 0x000a,
+       0x10e4: 0x000a, 0x10e5: 0x000a, 0x10e6: 0x000a, 0x10e7: 0x000a, 0x10e8: 0x000a, 0x10e9: 0x000a,
+       0x10ea: 0x000a, 0x10eb: 0x000a, 0x10ec: 0x000a, 0x10ed: 0x000a, 0x10ee: 0x000a, 0x10ef: 0x000a,
+       0x10f0: 0x000a, 0x10f1: 0x000a, 0x10f2: 0x000a, 0x10f3: 0x000a, 0x10f4: 0x000a, 0x10f5: 0x000a,
+       0x10f6: 0x000a, 0x10f7: 0x000a, 0x10f8: 0x000a, 0x10f9: 0x000a, 0x10fa: 0x000a, 0x10fb: 0x000a,
+       0x10fc: 0x000a, 0x10fd: 0x000a, 0x10fe: 0x000a, 0x10ff: 0x000a,
+       // Block 0x44, offset 0x1100
+       0x1117: 0x000c,
+       0x1118: 0x000c, 0x111b: 0x000c,
+       // Block 0x45, offset 0x1140
+       0x1156: 0x000c,
+       0x1158: 0x000c, 0x1159: 0x000c, 0x115a: 0x000c, 0x115b: 0x000c, 0x115c: 0x000c, 0x115d: 0x000c,
+       0x115e: 0x000c, 0x1160: 0x000c, 0x1162: 0x000c,
+       0x1165: 0x000c, 0x1166: 0x000c, 0x1167: 0x000c, 0x1168: 0x000c, 0x1169: 0x000c,
+       0x116a: 0x000c, 0x116b: 0x000c, 0x116c: 0x000c,
+       0x1173: 0x000c, 0x1174: 0x000c, 0x1175: 0x000c,
+       0x1176: 0x000c, 0x1177: 0x000c, 0x1178: 0x000c, 0x1179: 0x000c, 0x117a: 0x000c, 0x117b: 0x000c,
+       0x117c: 0x000c, 0x117f: 0x000c,
+       // Block 0x46, offset 0x1180
+       0x11b0: 0x000c, 0x11b1: 0x000c, 0x11b2: 0x000c, 0x11b3: 0x000c, 0x11b4: 0x000c, 0x11b5: 0x000c,
+       0x11b6: 0x000c, 0x11b7: 0x000c, 0x11b8: 0x000c, 0x11b9: 0x000c, 0x11ba: 0x000c, 0x11bb: 0x000c,
+       0x11bc: 0x000c, 0x11bd: 0x000c, 0x11be: 0x000c, 0x11bf: 0x000c,
+       // Block 0x47, offset 0x11c0
+       0x11c0: 0x000c,
+       // Block 0x48, offset 0x1200
+       0x1200: 0x000c, 0x1201: 0x000c, 0x1202: 0x000c, 0x1203: 0x000c,
+       0x1234: 0x000c,
+       0x1236: 0x000c, 0x1237: 0x000c, 0x1238: 0x000c, 0x1239: 0x000c, 0x123a: 0x000c,
+       0x123c: 0x000c,
+       // Block 0x49, offset 0x1240
+       0x1242: 0x000c,
+       0x126b: 0x000c, 0x126c: 0x000c, 0x126d: 0x000c, 0x126e: 0x000c, 0x126f: 0x000c,
+       0x1270: 0x000c, 0x1271: 0x000c, 0x1272: 0x000c, 0x1273: 0x000c,
+       // Block 0x4a, offset 0x1280
+       0x1280: 0x000c, 0x1281: 0x000c,
+       0x12a2: 0x000c, 0x12a3: 0x000c,
+       0x12a4: 0x000c, 0x12a5: 0x000c, 0x12a8: 0x000c, 0x12a9: 0x000c,
+       0x12ab: 0x000c, 0x12ac: 0x000c, 0x12ad: 0x000c,
+       // Block 0x4b, offset 0x12c0
+       0x12e6: 0x000c, 0x12e8: 0x000c, 0x12e9: 0x000c,
+       0x12ed: 0x000c, 0x12ef: 0x000c,
+       0x12f0: 0x000c, 0x12f1: 0x000c,
+       // Block 0x4c, offset 0x1300
+       0x132c: 0x000c, 0x132d: 0x000c, 0x132e: 0x000c, 0x132f: 0x000c,
+       0x1330: 0x000c, 0x1331: 0x000c, 0x1332: 0x000c, 0x1333: 0x000c,
+       0x1336: 0x000c, 0x1337: 0x000c,
+       // Block 0x4d, offset 0x1340
+       0x1350: 0x000c, 0x1351: 0x000c,
+       0x1352: 0x000c, 0x1354: 0x000c, 0x1355: 0x000c, 0x1356: 0x000c, 0x1357: 0x000c,
+       0x1358: 0x000c, 0x1359: 0x000c, 0x135a: 0x000c, 0x135b: 0x000c, 0x135c: 0x000c, 0x135d: 0x000c,
+       0x135e: 0x000c, 0x135f: 0x000c, 0x1360: 0x000c, 0x1362: 0x000c, 0x1363: 0x000c,
+       0x1364: 0x000c, 0x1365: 0x000c, 0x1366: 0x000c, 0x1367: 0x000c, 0x1368: 0x000c,
+       0x136d: 0x000c,
+       0x1374: 0x000c,
+       0x1378: 0x000c, 0x1379: 0x000c,
+       // Block 0x4e, offset 0x1380
+       0x1380: 0x000c, 0x1381: 0x000c, 0x1382: 0x000c, 0x1383: 0x000c, 0x1384: 0x000c, 0x1385: 0x000c,
+       0x1386: 0x000c, 0x1387: 0x000c, 0x1388: 0x000c, 0x1389: 0x000c, 0x138a: 0x000c, 0x138b: 0x000c,
+       0x138c: 0x000c, 0x138d: 0x000c, 0x138e: 0x000c, 0x138f: 0x000c, 0x1390: 0x000c, 0x1391: 0x000c,
+       0x1392: 0x000c, 0x1393: 0x000c, 0x1394: 0x000c, 0x1395: 0x000c, 0x1396: 0x000c, 0x1397: 0x000c,
+       0x1398: 0x000c, 0x1399: 0x000c, 0x139a: 0x000c, 0x139b: 0x000c, 0x139c: 0x000c, 0x139d: 0x000c,
+       0x139e: 0x000c, 0x139f: 0x000c, 0x13a0: 0x000c, 0x13a1: 0x000c, 0x13a2: 0x000c, 0x13a3: 0x000c,
+       0x13a4: 0x000c, 0x13a5: 0x000c, 0x13a6: 0x000c, 0x13a7: 0x000c, 0x13a8: 0x000c, 0x13a9: 0x000c,
+       0x13aa: 0x000c, 0x13ab: 0x000c, 0x13ac: 0x000c, 0x13ad: 0x000c, 0x13ae: 0x000c, 0x13af: 0x000c,
+       0x13b0: 0x000c, 0x13b1: 0x000c, 0x13b2: 0x000c, 0x13b3: 0x000c, 0x13b4: 0x000c, 0x13b5: 0x000c,
+       0x13b6: 0x000c, 0x13b7: 0x000c, 0x13b8: 0x000c, 0x13b9: 0x000c, 0x13bb: 0x000c,
+       0x13bc: 0x000c, 0x13bd: 0x000c, 0x13be: 0x000c, 0x13bf: 0x000c,
+       // Block 0x4f, offset 0x13c0
+       0x13fd: 0x000a, 0x13ff: 0x000a,
+       // Block 0x50, offset 0x1400
+       0x1400: 0x000a, 0x1401: 0x000a,
+       0x140d: 0x000a, 0x140e: 0x000a, 0x140f: 0x000a,
+       0x141d: 0x000a,
+       0x141e: 0x000a, 0x141f: 0x000a,
+       0x142d: 0x000a, 0x142e: 0x000a, 0x142f: 0x000a,
+       0x143d: 0x000a, 0x143e: 0x000a,
+       // Block 0x51, offset 0x1440
+       0x1440: 0x0009, 0x1441: 0x0009, 0x1442: 0x0009, 0x1443: 0x0009, 0x1444: 0x0009, 0x1445: 0x0009,
+       0x1446: 0x0009, 0x1447: 0x0009, 0x1448: 0x0009, 0x1449: 0x0009, 0x144a: 0x0009, 0x144b: 0x000b,
+       0x144c: 0x000b, 0x144d: 0x000b, 0x144f: 0x0001, 0x1450: 0x000a, 0x1451: 0x000a,
+       0x1452: 0x000a, 0x1453: 0x000a, 0x1454: 0x000a, 0x1455: 0x000a, 0x1456: 0x000a, 0x1457: 0x000a,
+       0x1458: 0x000a, 0x1459: 0x000a, 0x145a: 0x000a, 0x145b: 0x000a, 0x145c: 0x000a, 0x145d: 0x000a,
+       0x145e: 0x000a, 0x145f: 0x000a, 0x1460: 0x000a, 0x1461: 0x000a, 0x1462: 0x000a, 0x1463: 0x000a,
+       0x1464: 0x000a, 0x1465: 0x000a, 0x1466: 0x000a, 0x1467: 0x000a, 0x1468: 0x0009, 0x1469: 0x0007,
+       0x146a: 0x000e, 0x146b: 0x000e, 0x146c: 0x000e, 0x146d: 0x000e, 0x146e: 0x000e, 0x146f: 0x0006,
+       0x1470: 0x0004, 0x1471: 0x0004, 0x1472: 0x0004, 0x1473: 0x0004, 0x1474: 0x0004, 0x1475: 0x000a,
+       0x1476: 0x000a, 0x1477: 0x000a, 0x1478: 0x000a, 0x1479: 0x000a, 0x147a: 0x000a, 0x147b: 0x000a,
+       0x147c: 0x000a, 0x147d: 0x000a, 0x147e: 0x000a, 0x147f: 0x000a,
+       // Block 0x52, offset 0x1480
+       0x1480: 0x000a, 0x1481: 0x000a, 0x1482: 0x000a, 0x1483: 0x000a, 0x1484: 0x0006, 0x1485: 0x009a,
+       0x1486: 0x008a, 0x1487: 0x000a, 0x1488: 0x000a, 0x1489: 0x000a, 0x148a: 0x000a, 0x148b: 0x000a,
+       0x148c: 0x000a, 0x148d: 0x000a, 0x148e: 0x000a, 0x148f: 0x000a, 0x1490: 0x000a, 0x1491: 0x000a,
+       0x1492: 0x000a, 0x1493: 0x000a, 0x1494: 0x000a, 0x1495: 0x000a, 0x1496: 0x000a, 0x1497: 0x000a,
+       0x1498: 0x000a, 0x1499: 0x000a, 0x149a: 0x000a, 0x149b: 0x000a, 0x149c: 0x000a, 0x149d: 0x000a,
+       0x149e: 0x000a, 0x149f: 0x0009, 0x14a0: 0x000b, 0x14a1: 0x000b, 0x14a2: 0x000b, 0x14a3: 0x000b,
+       0x14a4: 0x000b, 0x14a5: 0x000b, 0x14a6: 0x000e, 0x14a7: 0x000e, 0x14a8: 0x000e, 0x14a9: 0x000e,
+       0x14aa: 0x000b, 0x14ab: 0x000b, 0x14ac: 0x000b, 0x14ad: 0x000b, 0x14ae: 0x000b, 0x14af: 0x000b,
+       0x14b0: 0x0002, 0x14b4: 0x0002, 0x14b5: 0x0002,
+       0x14b6: 0x0002, 0x14b7: 0x0002, 0x14b8: 0x0002, 0x14b9: 0x0002, 0x14ba: 0x0003, 0x14bb: 0x0003,
+       0x14bc: 0x000a, 0x14bd: 0x009a, 0x14be: 0x008a,
+       // Block 0x53, offset 0x14c0
+       0x14c0: 0x0002, 0x14c1: 0x0002, 0x14c2: 0x0002, 0x14c3: 0x0002, 0x14c4: 0x0002, 0x14c5: 0x0002,
+       0x14c6: 0x0002, 0x14c7: 0x0002, 0x14c8: 0x0002, 0x14c9: 0x0002, 0x14ca: 0x0003, 0x14cb: 0x0003,
+       0x14cc: 0x000a, 0x14cd: 0x009a, 0x14ce: 0x008a,
+       0x14e0: 0x0004, 0x14e1: 0x0004, 0x14e2: 0x0004, 0x14e3: 0x0004,
+       0x14e4: 0x0004, 0x14e5: 0x0004, 0x14e6: 0x0004, 0x14e7: 0x0004, 0x14e8: 0x0004, 0x14e9: 0x0004,
+       0x14ea: 0x0004, 0x14eb: 0x0004, 0x14ec: 0x0004, 0x14ed: 0x0004, 0x14ee: 0x0004, 0x14ef: 0x0004,
+       0x14f0: 0x0004, 0x14f1: 0x0004, 0x14f2: 0x0004, 0x14f3: 0x0004, 0x14f4: 0x0004, 0x14f5: 0x0004,
+       0x14f6: 0x0004, 0x14f7: 0x0004, 0x14f8: 0x0004, 0x14f9: 0x0004, 0x14fa: 0x0004, 0x14fb: 0x0004,
+       0x14fc: 0x0004, 0x14fd: 0x0004, 0x14fe: 0x0004, 0x14ff: 0x0004,
+       // Block 0x54, offset 0x1500
+       0x1500: 0x0004, 0x1501: 0x0004, 0x1502: 0x0004, 0x1503: 0x0004, 0x1504: 0x0004, 0x1505: 0x0004,
+       0x1506: 0x0004, 0x1507: 0x0004, 0x1508: 0x0004, 0x1509: 0x0004, 0x150a: 0x0004, 0x150b: 0x0004,
+       0x150c: 0x0004, 0x150d: 0x0004, 0x150e: 0x0004, 0x150f: 0x0004, 0x1510: 0x000c, 0x1511: 0x000c,
+       0x1512: 0x000c, 0x1513: 0x000c, 0x1514: 0x000c, 0x1515: 0x000c, 0x1516: 0x000c, 0x1517: 0x000c,
+       0x1518: 0x000c, 0x1519: 0x000c, 0x151a: 0x000c, 0x151b: 0x000c, 0x151c: 0x000c, 0x151d: 0x000c,
+       0x151e: 0x000c, 0x151f: 0x000c, 0x1520: 0x000c, 0x1521: 0x000c, 0x1522: 0x000c, 0x1523: 0x000c,
+       0x1524: 0x000c, 0x1525: 0x000c, 0x1526: 0x000c, 0x1527: 0x000c, 0x1528: 0x000c, 0x1529: 0x000c,
+       0x152a: 0x000c, 0x152b: 0x000c, 0x152c: 0x000c, 0x152d: 0x000c, 0x152e: 0x000c, 0x152f: 0x000c,
+       0x1530: 0x000c,
+       // Block 0x55, offset 0x1540
+       0x1540: 0x000a, 0x1541: 0x000a, 0x1543: 0x000a, 0x1544: 0x000a, 0x1545: 0x000a,
+       0x1546: 0x000a, 0x1548: 0x000a, 0x1549: 0x000a,
+       0x1554: 0x000a, 0x1556: 0x000a, 0x1557: 0x000a,
+       0x1558: 0x000a,
+       0x155e: 0x000a, 0x155f: 0x000a, 0x1560: 0x000a, 0x1561: 0x000a, 0x1562: 0x000a, 0x1563: 0x000a,
+       0x1565: 0x000a, 0x1567: 0x000a, 0x1569: 0x000a,
+       0x156e: 0x0004,
+       0x157a: 0x000a, 0x157b: 0x000a,
+       // Block 0x56, offset 0x1580
+       0x1580: 0x000a, 0x1581: 0x000a, 0x1582: 0x000a, 0x1583: 0x000a, 0x1584: 0x000a,
+       0x158a: 0x000a, 0x158b: 0x000a,
+       0x158c: 0x000a, 0x158d: 0x000a, 0x1590: 0x000a, 0x1591: 0x000a,
+       0x1592: 0x000a, 0x1593: 0x000a, 0x1594: 0x000a, 0x1595: 0x000a, 0x1596: 0x000a, 0x1597: 0x000a,
+       0x1598: 0x000a, 0x1599: 0x000a, 0x159a: 0x000a, 0x159b: 0x000a, 0x159c: 0x000a, 0x159d: 0x000a,
+       0x159e: 0x000a, 0x159f: 0x000a,
+       // Block 0x57, offset 0x15c0
+       0x15c9: 0x000a, 0x15ca: 0x000a, 0x15cb: 0x000a,
+       0x15d0: 0x000a, 0x15d1: 0x000a,
+       0x15d2: 0x000a, 0x15d3: 0x000a, 0x15d4: 0x000a, 0x15d5: 0x000a, 0x15d6: 0x000a, 0x15d7: 0x000a,
+       0x15d8: 0x000a, 0x15d9: 0x000a, 0x15da: 0x000a, 0x15db: 0x000a, 0x15dc: 0x000a, 0x15dd: 0x000a,
+       0x15de: 0x000a, 0x15df: 0x000a, 0x15e0: 0x000a, 0x15e1: 0x000a, 0x15e2: 0x000a, 0x15e3: 0x000a,
+       0x15e4: 0x000a, 0x15e5: 0x000a, 0x15e6: 0x000a, 0x15e7: 0x000a, 0x15e8: 0x000a, 0x15e9: 0x000a,
+       0x15ea: 0x000a, 0x15eb: 0x000a, 0x15ec: 0x000a, 0x15ed: 0x000a, 0x15ee: 0x000a, 0x15ef: 0x000a,
+       0x15f0: 0x000a, 0x15f1: 0x000a, 0x15f2: 0x000a, 0x15f3: 0x000a, 0x15f4: 0x000a, 0x15f5: 0x000a,
+       0x15f6: 0x000a, 0x15f7: 0x000a, 0x15f8: 0x000a, 0x15f9: 0x000a, 0x15fa: 0x000a, 0x15fb: 0x000a,
+       0x15fc: 0x000a, 0x15fd: 0x000a, 0x15fe: 0x000a, 0x15ff: 0x000a,
+       // Block 0x58, offset 0x1600
+       0x1600: 0x000a, 0x1601: 0x000a, 0x1602: 0x000a, 0x1603: 0x000a, 0x1604: 0x000a, 0x1605: 0x000a,
+       0x1606: 0x000a, 0x1607: 0x000a, 0x1608: 0x000a, 0x1609: 0x000a, 0x160a: 0x000a, 0x160b: 0x000a,
+       0x160c: 0x000a, 0x160d: 0x000a, 0x160e: 0x000a, 0x160f: 0x000a, 0x1610: 0x000a, 0x1611: 0x000a,
+       0x1612: 0x000a, 0x1613: 0x000a, 0x1614: 0x000a, 0x1615: 0x000a, 0x1616: 0x000a, 0x1617: 0x000a,
+       0x1618: 0x000a, 0x1619: 0x000a, 0x161a: 0x000a, 0x161b: 0x000a, 0x161c: 0x000a, 0x161d: 0x000a,
+       0x161e: 0x000a, 0x161f: 0x000a, 0x1620: 0x000a, 0x1621: 0x000a, 0x1622: 0x000a, 0x1623: 0x000a,
+       0x1624: 0x000a, 0x1625: 0x000a, 0x1626: 0x000a, 0x1627: 0x000a, 0x1628: 0x000a, 0x1629: 0x000a,
+       0x162a: 0x000a, 0x162b: 0x000a, 0x162c: 0x000a, 0x162d: 0x000a, 0x162e: 0x000a, 0x162f: 0x000a,
+       0x1630: 0x000a, 0x1631: 0x000a, 0x1632: 0x000a, 0x1633: 0x000a, 0x1634: 0x000a, 0x1635: 0x000a,
+       0x1636: 0x000a, 0x1637: 0x000a, 0x1638: 0x000a, 0x1639: 0x000a, 0x163a: 0x000a, 0x163b: 0x000a,
+       0x163c: 0x000a, 0x163d: 0x000a, 0x163e: 0x000a, 0x163f: 0x000a,
+       // Block 0x59, offset 0x1640
+       0x1640: 0x000a, 0x1641: 0x000a, 0x1642: 0x000a, 0x1643: 0x000a, 0x1644: 0x000a, 0x1645: 0x000a,
+       0x1646: 0x000a, 0x1647: 0x000a, 0x1648: 0x000a, 0x1649: 0x000a, 0x164a: 0x000a, 0x164b: 0x000a,
+       0x164c: 0x000a, 0x164d: 0x000a, 0x164e: 0x000a, 0x164f: 0x000a, 0x1650: 0x000a, 0x1651: 0x000a,
+       0x1652: 0x0003, 0x1653: 0x0004, 0x1654: 0x000a, 0x1655: 0x000a, 0x1656: 0x000a, 0x1657: 0x000a,
+       0x1658: 0x000a, 0x1659: 0x000a, 0x165a: 0x000a, 0x165b: 0x000a, 0x165c: 0x000a, 0x165d: 0x000a,
+       0x165e: 0x000a, 0x165f: 0x000a, 0x1660: 0x000a, 0x1661: 0x000a, 0x1662: 0x000a, 0x1663: 0x000a,
+       0x1664: 0x000a, 0x1665: 0x000a, 0x1666: 0x000a, 0x1667: 0x000a, 0x1668: 0x000a, 0x1669: 0x000a,
+       0x166a: 0x000a, 0x166b: 0x000a, 0x166c: 0x000a, 0x166d: 0x000a, 0x166e: 0x000a, 0x166f: 0x000a,
+       0x1670: 0x000a, 0x1671: 0x000a, 0x1672: 0x000a, 0x1673: 0x000a, 0x1674: 0x000a, 0x1675: 0x000a,
+       0x1676: 0x000a, 0x1677: 0x000a, 0x1678: 0x000a, 0x1679: 0x000a, 0x167a: 0x000a, 0x167b: 0x000a,
+       0x167c: 0x000a, 0x167d: 0x000a, 0x167e: 0x000a, 0x167f: 0x000a,
+       // Block 0x5a, offset 0x1680
+       0x1680: 0x000a, 0x1681: 0x000a, 0x1682: 0x000a, 0x1683: 0x000a, 0x1684: 0x000a, 0x1685: 0x000a,
+       0x1686: 0x000a, 0x1687: 0x000a, 0x1688: 0x003a, 0x1689: 0x002a, 0x168a: 0x003a, 0x168b: 0x002a,
+       0x168c: 0x000a, 0x168d: 0x000a, 0x168e: 0x000a, 0x168f: 0x000a, 0x1690: 0x000a, 0x1691: 0x000a,
+       0x1692: 0x000a, 0x1693: 0x000a, 0x1694: 0x000a, 0x1695: 0x000a, 0x1696: 0x000a, 0x1697: 0x000a,
+       0x1698: 0x000a, 0x1699: 0x000a, 0x169a: 0x000a, 0x169b: 0x000a, 0x169c: 0x000a, 0x169d: 0x000a,
+       0x169e: 0x000a, 0x169f: 0x000a, 0x16a0: 0x000a, 0x16a1: 0x000a, 0x16a2: 0x000a, 0x16a3: 0x000a,
+       0x16a4: 0x000a, 0x16a5: 0x000a, 0x16a6: 0x000a, 0x16a7: 0x000a, 0x16a8: 0x000a, 0x16a9: 0x009a,
+       0x16aa: 0x008a, 0x16ab: 0x000a, 0x16ac: 0x000a, 0x16ad: 0x000a, 0x16ae: 0x000a, 0x16af: 0x000a,
+       0x16b0: 0x000a, 0x16b1: 0x000a, 0x16b2: 0x000a, 0x16b3: 0x000a, 0x16b4: 0x000a, 0x16b5: 0x000a,
+       // Block 0x5b, offset 0x16c0
+       0x16fb: 0x000a,
+       0x16fc: 0x000a, 0x16fd: 0x000a, 0x16fe: 0x000a, 0x16ff: 0x000a,
+       // Block 0x5c, offset 0x1700
+       0x1700: 0x000a, 0x1701: 0x000a, 0x1702: 0x000a, 0x1703: 0x000a, 0x1704: 0x000a, 0x1705: 0x000a,
+       0x1706: 0x000a, 0x1707: 0x000a, 0x1708: 0x000a, 0x1709: 0x000a, 0x170a: 0x000a, 0x170b: 0x000a,
+       0x170c: 0x000a, 0x170d: 0x000a, 0x170e: 0x000a, 0x170f: 0x000a, 0x1710: 0x000a, 0x1711: 0x000a,
+       0x1712: 0x000a, 0x1713: 0x000a, 0x1714: 0x000a, 0x1716: 0x000a, 0x1717: 0x000a,
+       0x1718: 0x000a, 0x1719: 0x000a, 0x171a: 0x000a, 0x171b: 0x000a, 0x171c: 0x000a, 0x171d: 0x000a,
+       0x171e: 0x000a, 0x171f: 0x000a, 0x1720: 0x000a, 0x1721: 0x000a, 0x1722: 0x000a, 0x1723: 0x000a,
+       0x1724: 0x000a, 0x1725: 0x000a, 0x1726: 0x000a, 0x1727: 0x000a, 0x1728: 0x000a, 0x1729: 0x000a,
+       0x172a: 0x000a, 0x172b: 0x000a, 0x172c: 0x000a, 0x172d: 0x000a, 0x172e: 0x000a, 0x172f: 0x000a,
+       0x1730: 0x000a, 0x1731: 0x000a, 0x1732: 0x000a, 0x1733: 0x000a, 0x1734: 0x000a, 0x1735: 0x000a,
+       0x1736: 0x000a, 0x1737: 0x000a, 0x1738: 0x000a, 0x1739: 0x000a, 0x173a: 0x000a, 0x173b: 0x000a,
+       0x173c: 0x000a, 0x173d: 0x000a, 0x173e: 0x000a, 0x173f: 0x000a,
+       // Block 0x5d, offset 0x1740
+       0x1740: 0x000a, 0x1741: 0x000a, 0x1742: 0x000a, 0x1743: 0x000a, 0x1744: 0x000a, 0x1745: 0x000a,
+       0x1746: 0x000a, 0x1747: 0x000a, 0x1748: 0x000a, 0x1749: 0x000a, 0x174a: 0x000a, 0x174b: 0x000a,
+       0x174c: 0x000a, 0x174d: 0x000a, 0x174e: 0x000a, 0x174f: 0x000a, 0x1750: 0x000a, 0x1751: 0x000a,
+       0x1752: 0x000a, 0x1753: 0x000a, 0x1754: 0x000a, 0x1755: 0x000a, 0x1756: 0x000a, 0x1757: 0x000a,
+       0x1758: 0x000a, 0x1759: 0x000a, 0x175a: 0x000a, 0x175b: 0x000a, 0x175c: 0x000a, 0x175d: 0x000a,
+       0x175e: 0x000a, 0x175f: 0x000a, 0x1760: 0x000a, 0x1761: 0x000a, 0x1762: 0x000a, 0x1763: 0x000a,
+       0x1764: 0x000a, 0x1765: 0x000a, 0x1766: 0x000a,
+       // Block 0x5e, offset 0x1780
+       0x1780: 0x000a, 0x1781: 0x000a, 0x1782: 0x000a, 0x1783: 0x000a, 0x1784: 0x000a, 0x1785: 0x000a,
+       0x1786: 0x000a, 0x1787: 0x000a, 0x1788: 0x000a, 0x1789: 0x000a, 0x178a: 0x000a,
+       0x17a0: 0x000a, 0x17a1: 0x000a, 0x17a2: 0x000a, 0x17a3: 0x000a,
+       0x17a4: 0x000a, 0x17a5: 0x000a, 0x17a6: 0x000a, 0x17a7: 0x000a, 0x17a8: 0x000a, 0x17a9: 0x000a,
+       0x17aa: 0x000a, 0x17ab: 0x000a, 0x17ac: 0x000a, 0x17ad: 0x000a, 0x17ae: 0x000a, 0x17af: 0x000a,
+       0x17b0: 0x000a, 0x17b1: 0x000a, 0x17b2: 0x000a, 0x17b3: 0x000a, 0x17b4: 0x000a, 0x17b5: 0x000a,
+       0x17b6: 0x000a, 0x17b7: 0x000a, 0x17b8: 0x000a, 0x17b9: 0x000a, 0x17ba: 0x000a, 0x17bb: 0x000a,
+       0x17bc: 0x000a, 0x17bd: 0x000a, 0x17be: 0x000a, 0x17bf: 0x000a,
+       // Block 0x5f, offset 0x17c0
+       0x17c0: 0x000a, 0x17c1: 0x000a, 0x17c2: 0x000a, 0x17c3: 0x000a, 0x17c4: 0x000a, 0x17c5: 0x000a,
+       0x17c6: 0x000a, 0x17c7: 0x000a, 0x17c8: 0x0002, 0x17c9: 0x0002, 0x17ca: 0x0002, 0x17cb: 0x0002,
+       0x17cc: 0x0002, 0x17cd: 0x0002, 0x17ce: 0x0002, 0x17cf: 0x0002, 0x17d0: 0x0002, 0x17d1: 0x0002,
+       0x17d2: 0x0002, 0x17d3: 0x0002, 0x17d4: 0x0002, 0x17d5: 0x0002, 0x17d6: 0x0002, 0x17d7: 0x0002,
+       0x17d8: 0x0002, 0x17d9: 0x0002, 0x17da: 0x0002, 0x17db: 0x0002,
+       // Block 0x60, offset 0x1800
+       0x182a: 0x000a, 0x182b: 0x000a, 0x182c: 0x000a, 0x182d: 0x000a, 0x182e: 0x000a, 0x182f: 0x000a,
+       0x1830: 0x000a, 0x1831: 0x000a, 0x1832: 0x000a, 0x1833: 0x000a, 0x1834: 0x000a, 0x1835: 0x000a,
+       0x1836: 0x000a, 0x1837: 0x000a, 0x1838: 0x000a, 0x1839: 0x000a, 0x183a: 0x000a, 0x183b: 0x000a,
+       0x183c: 0x000a, 0x183d: 0x000a, 0x183e: 0x000a, 0x183f: 0x000a,
+       // Block 0x61, offset 0x1840
+       0x1840: 0x000a, 0x1841: 0x000a, 0x1842: 0x000a, 0x1843: 0x000a, 0x1844: 0x000a, 0x1845: 0x000a,
+       0x1846: 0x000a, 0x1847: 0x000a, 0x1848: 0x000a, 0x1849: 0x000a, 0x184a: 0x000a, 0x184b: 0x000a,
+       0x184c: 0x000a, 0x184d: 0x000a, 0x184e: 0x000a, 0x184f: 0x000a, 0x1850: 0x000a, 0x1851: 0x000a,
+       0x1852: 0x000a, 0x1853: 0x000a, 0x1854: 0x000a, 0x1855: 0x000a, 0x1856: 0x000a, 0x1857: 0x000a,
+       0x1858: 0x000a, 0x1859: 0x000a, 0x185a: 0x000a, 0x185b: 0x000a, 0x185c: 0x000a, 0x185d: 0x000a,
+       0x185e: 0x000a, 0x185f: 0x000a, 0x1860: 0x000a, 0x1861: 0x000a, 0x1862: 0x000a, 0x1863: 0x000a,
+       0x1864: 0x000a, 0x1865: 0x000a, 0x1866: 0x000a, 0x1867: 0x000a, 0x1868: 0x000a, 0x1869: 0x000a,
+       0x186a: 0x000a, 0x186b: 0x000a, 0x186d: 0x000a, 0x186e: 0x000a, 0x186f: 0x000a,
+       0x1870: 0x000a, 0x1871: 0x000a, 0x1872: 0x000a, 0x1873: 0x000a, 0x1874: 0x000a, 0x1875: 0x000a,
+       0x1876: 0x000a, 0x1877: 0x000a, 0x1878: 0x000a, 0x1879: 0x000a, 0x187a: 0x000a, 0x187b: 0x000a,
+       0x187c: 0x000a, 0x187d: 0x000a, 0x187e: 0x000a, 0x187f: 0x000a,
+       // Block 0x62, offset 0x1880
+       0x1880: 0x000a, 0x1881: 0x000a, 0x1882: 0x000a, 0x1883: 0x000a, 0x1884: 0x000a, 0x1885: 0x000a,
+       0x1886: 0x000a, 0x1887: 0x000a, 0x1888: 0x000a, 0x1889: 0x000a, 0x188a: 0x000a, 0x188b: 0x000a,
+       0x188c: 0x000a, 0x188d: 0x000a, 0x188e: 0x000a, 0x188f: 0x000a, 0x1890: 0x000a, 0x1891: 0x000a,
+       0x1892: 0x000a, 0x1893: 0x000a, 0x1894: 0x000a, 0x1895: 0x000a, 0x1896: 0x000a, 0x1897: 0x000a,
+       0x1898: 0x000a, 0x1899: 0x000a, 0x189a: 0x000a, 0x189b: 0x000a, 0x189c: 0x000a, 0x189d: 0x000a,
+       0x189e: 0x000a, 0x189f: 0x000a, 0x18a0: 0x000a, 0x18a1: 0x000a, 0x18a2: 0x000a, 0x18a3: 0x000a,
+       0x18a4: 0x000a, 0x18a5: 0x000a, 0x18a6: 0x000a, 0x18a7: 0x000a, 0x18a8: 0x003a, 0x18a9: 0x002a,
+       0x18aa: 0x003a, 0x18ab: 0x002a, 0x18ac: 0x003a, 0x18ad: 0x002a, 0x18ae: 0x003a, 0x18af: 0x002a,
+       0x18b0: 0x003a, 0x18b1: 0x002a, 0x18b2: 0x003a, 0x18b3: 0x002a, 0x18b4: 0x003a, 0x18b5: 0x002a,
+       0x18b6: 0x000a, 0x18b7: 0x000a, 0x18b8: 0x000a, 0x18b9: 0x000a, 0x18ba: 0x000a, 0x18bb: 0x000a,
+       0x18bc: 0x000a, 0x18bd: 0x000a, 0x18be: 0x000a, 0x18bf: 0x000a,
+       // Block 0x63, offset 0x18c0
+       0x18c0: 0x000a, 0x18c1: 0x000a, 0x18c2: 0x000a, 0x18c3: 0x000a, 0x18c4: 0x000a, 0x18c5: 0x009a,
+       0x18c6: 0x008a, 0x18c7: 0x000a, 0x18c8: 0x000a, 0x18c9: 0x000a, 0x18ca: 0x000a, 0x18cb: 0x000a,
+       0x18cc: 0x000a, 0x18cd: 0x000a, 0x18ce: 0x000a, 0x18cf: 0x000a, 0x18d0: 0x000a, 0x18d1: 0x000a,
+       0x18d2: 0x000a, 0x18d3: 0x000a, 0x18d4: 0x000a, 0x18d5: 0x000a, 0x18d6: 0x000a, 0x18d7: 0x000a,
+       0x18d8: 0x000a, 0x18d9: 0x000a, 0x18da: 0x000a, 0x18db: 0x000a, 0x18dc: 0x000a, 0x18dd: 0x000a,
+       0x18de: 0x000a, 0x18df: 0x000a, 0x18e0: 0x000a, 0x18e1: 0x000a, 0x18e2: 0x000a, 0x18e3: 0x000a,
+       0x18e4: 0x000a, 0x18e5: 0x000a, 0x18e6: 0x003a, 0x18e7: 0x002a, 0x18e8: 0x003a, 0x18e9: 0x002a,
+       0x18ea: 0x003a, 0x18eb: 0x002a, 0x18ec: 0x003a, 0x18ed: 0x002a, 0x18ee: 0x003a, 0x18ef: 0x002a,
+       0x18f0: 0x000a, 0x18f1: 0x000a, 0x18f2: 0x000a, 0x18f3: 0x000a, 0x18f4: 0x000a, 0x18f5: 0x000a,
+       0x18f6: 0x000a, 0x18f7: 0x000a, 0x18f8: 0x000a, 0x18f9: 0x000a, 0x18fa: 0x000a, 0x18fb: 0x000a,
+       0x18fc: 0x000a, 0x18fd: 0x000a, 0x18fe: 0x000a, 0x18ff: 0x000a,
+       // Block 0x64, offset 0x1900
+       0x1900: 0x000a, 0x1901: 0x000a, 0x1902: 0x000a, 0x1903: 0x007a, 0x1904: 0x006a, 0x1905: 0x009a,
+       0x1906: 0x008a, 0x1907: 0x00ba, 0x1908: 0x00aa, 0x1909: 0x009a, 0x190a: 0x008a, 0x190b: 0x007a,
+       0x190c: 0x006a, 0x190d: 0x00da, 0x190e: 0x002a, 0x190f: 0x003a, 0x1910: 0x00ca, 0x1911: 0x009a,
+       0x1912: 0x008a, 0x1913: 0x007a, 0x1914: 0x006a, 0x1915: 0x009a, 0x1916: 0x008a, 0x1917: 0x00ba,
+       0x1918: 0x00aa, 0x1919: 0x000a, 0x191a: 0x000a, 0x191b: 0x000a, 0x191c: 0x000a, 0x191d: 0x000a,
+       0x191e: 0x000a, 0x191f: 0x000a, 0x1920: 0x000a, 0x1921: 0x000a, 0x1922: 0x000a, 0x1923: 0x000a,
+       0x1924: 0x000a, 0x1925: 0x000a, 0x1926: 0x000a, 0x1927: 0x000a, 0x1928: 0x000a, 0x1929: 0x000a,
+       0x192a: 0x000a, 0x192b: 0x000a, 0x192c: 0x000a, 0x192d: 0x000a, 0x192e: 0x000a, 0x192f: 0x000a,
+       0x1930: 0x000a, 0x1931: 0x000a, 0x1932: 0x000a, 0x1933: 0x000a, 0x1934: 0x000a, 0x1935: 0x000a,
+       0x1936: 0x000a, 0x1937: 0x000a, 0x1938: 0x000a, 0x1939: 0x000a, 0x193a: 0x000a, 0x193b: 0x000a,
+       0x193c: 0x000a, 0x193d: 0x000a, 0x193e: 0x000a, 0x193f: 0x000a,
+       // Block 0x65, offset 0x1940
+       0x1940: 0x000a, 0x1941: 0x000a, 0x1942: 0x000a, 0x1943: 0x000a, 0x1944: 0x000a, 0x1945: 0x000a,
+       0x1946: 0x000a, 0x1947: 0x000a, 0x1948: 0x000a, 0x1949: 0x000a, 0x194a: 0x000a, 0x194b: 0x000a,
+       0x194c: 0x000a, 0x194d: 0x000a, 0x194e: 0x000a, 0x194f: 0x000a, 0x1950: 0x000a, 0x1951: 0x000a,
+       0x1952: 0x000a, 0x1953: 0x000a, 0x1954: 0x000a, 0x1955: 0x000a, 0x1956: 0x000a, 0x1957: 0x000a,
+       0x1958: 0x003a, 0x1959: 0x002a, 0x195a: 0x003a, 0x195b: 0x002a, 0x195c: 0x000a, 0x195d: 0x000a,
+       0x195e: 0x000a, 0x195f: 0x000a, 0x1960: 0x000a, 0x1961: 0x000a, 0x1962: 0x000a, 0x1963: 0x000a,
+       0x1964: 0x000a, 0x1965: 0x000a, 0x1966: 0x000a, 0x1967: 0x000a, 0x1968: 0x000a, 0x1969: 0x000a,
+       0x196a: 0x000a, 0x196b: 0x000a, 0x196c: 0x000a, 0x196d: 0x000a, 0x196e: 0x000a, 0x196f: 0x000a,
+       0x1970: 0x000a, 0x1971: 0x000a, 0x1972: 0x000a, 0x1973: 0x000a, 0x1974: 0x000a, 0x1975: 0x000a,
+       0x1976: 0x000a, 0x1977: 0x000a, 0x1978: 0x000a, 0x1979: 0x000a, 0x197a: 0x000a, 0x197b: 0x000a,
+       0x197c: 0x003a, 0x197d: 0x002a, 0x197e: 0x000a, 0x197f: 0x000a,
+       // Block 0x66, offset 0x1980
+       0x1980: 0x000a, 0x1981: 0x000a, 0x1982: 0x000a, 0x1983: 0x000a, 0x1984: 0x000a, 0x1985: 0x000a,
+       0x1986: 0x000a, 0x1987: 0x000a, 0x1988: 0x000a, 0x1989: 0x000a, 0x198a: 0x000a, 0x198b: 0x000a,
+       0x198c: 0x000a, 0x198d: 0x000a, 0x198e: 0x000a, 0x198f: 0x000a, 0x1990: 0x000a, 0x1991: 0x000a,
+       0x1992: 0x000a, 0x1993: 0x000a, 0x1994: 0x000a, 0x1995: 0x000a, 0x1996: 0x000a, 0x1997: 0x000a,
+       0x1998: 0x000a, 0x1999: 0x000a, 0x199a: 0x000a, 0x199b: 0x000a, 0x199c: 0x000a, 0x199d: 0x000a,
+       0x199e: 0x000a, 0x199f: 0x000a, 0x19a0: 0x000a, 0x19a1: 0x000a, 0x19a2: 0x000a, 0x19a3: 0x000a,
+       0x19a4: 0x000a, 0x19a5: 0x000a, 0x19a6: 0x000a, 0x19a7: 0x000a, 0x19a8: 0x000a, 0x19a9: 0x000a,
+       0x19aa: 0x000a, 0x19ab: 0x000a, 0x19ac: 0x000a, 0x19ad: 0x000a, 0x19ae: 0x000a, 0x19af: 0x000a,
+       0x19b0: 0x000a, 0x19b1: 0x000a, 0x19b2: 0x000a, 0x19b3: 0x000a,
+       0x19b6: 0x000a, 0x19b7: 0x000a, 0x19b8: 0x000a, 0x19b9: 0x000a, 0x19ba: 0x000a, 0x19bb: 0x000a,
+       0x19bc: 0x000a, 0x19bd: 0x000a, 0x19be: 0x000a, 0x19bf: 0x000a,
+       // Block 0x67, offset 0x19c0
+       0x19c0: 0x000a, 0x19c1: 0x000a, 0x19c2: 0x000a, 0x19c3: 0x000a, 0x19c4: 0x000a, 0x19c5: 0x000a,
+       0x19c6: 0x000a, 0x19c7: 0x000a, 0x19c8: 0x000a, 0x19c9: 0x000a, 0x19ca: 0x000a, 0x19cb: 0x000a,
+       0x19cc: 0x000a, 0x19cd: 0x000a, 0x19ce: 0x000a, 0x19cf: 0x000a, 0x19d0: 0x000a, 0x19d1: 0x000a,
+       0x19d2: 0x000a, 0x19d3: 0x000a, 0x19d4: 0x000a, 0x19d5: 0x000a, 0x19d7: 0x000a,
+       0x19d8: 0x000a, 0x19d9: 0x000a, 0x19da: 0x000a, 0x19db: 0x000a, 0x19dc: 0x000a, 0x19dd: 0x000a,
+       0x19de: 0x000a, 0x19df: 0x000a, 0x19e0: 0x000a, 0x19e1: 0x000a, 0x19e2: 0x000a, 0x19e3: 0x000a,
+       0x19e4: 0x000a, 0x19e5: 0x000a, 0x19e6: 0x000a, 0x19e7: 0x000a, 0x19e8: 0x000a, 0x19e9: 0x000a,
+       0x19ea: 0x000a, 0x19eb: 0x000a, 0x19ec: 0x000a, 0x19ed: 0x000a, 0x19ee: 0x000a, 0x19ef: 0x000a,
+       0x19f0: 0x000a, 0x19f1: 0x000a, 0x19f2: 0x000a, 0x19f3: 0x000a, 0x19f4: 0x000a, 0x19f5: 0x000a,
+       0x19f6: 0x000a, 0x19f7: 0x000a, 0x19f8: 0x000a, 0x19f9: 0x000a, 0x19fa: 0x000a, 0x19fb: 0x000a,
+       0x19fc: 0x000a, 0x19fd: 0x000a, 0x19fe: 0x000a, 0x19ff: 0x000a,
+       // Block 0x68, offset 0x1a00
+       0x1a25: 0x000a, 0x1a26: 0x000a, 0x1a27: 0x000a, 0x1a28: 0x000a, 0x1a29: 0x000a,
+       0x1a2a: 0x000a, 0x1a2f: 0x000c,
+       0x1a30: 0x000c, 0x1a31: 0x000c,
+       0x1a39: 0x000a, 0x1a3a: 0x000a, 0x1a3b: 0x000a,
+       0x1a3c: 0x000a, 0x1a3d: 0x000a, 0x1a3e: 0x000a, 0x1a3f: 0x000a,
+       // Block 0x69, offset 0x1a40
+       0x1a7f: 0x000c,
+       // Block 0x6a, offset 0x1a80
+       0x1aa0: 0x000c, 0x1aa1: 0x000c, 0x1aa2: 0x000c, 0x1aa3: 0x000c,
+       0x1aa4: 0x000c, 0x1aa5: 0x000c, 0x1aa6: 0x000c, 0x1aa7: 0x000c, 0x1aa8: 0x000c, 0x1aa9: 0x000c,
+       0x1aaa: 0x000c, 0x1aab: 0x000c, 0x1aac: 0x000c, 0x1aad: 0x000c, 0x1aae: 0x000c, 0x1aaf: 0x000c,
+       0x1ab0: 0x000c, 0x1ab1: 0x000c, 0x1ab2: 0x000c, 0x1ab3: 0x000c, 0x1ab4: 0x000c, 0x1ab5: 0x000c,
+       0x1ab6: 0x000c, 0x1ab7: 0x000c, 0x1ab8: 0x000c, 0x1ab9: 0x000c, 0x1aba: 0x000c, 0x1abb: 0x000c,
+       0x1abc: 0x000c, 0x1abd: 0x000c, 0x1abe: 0x000c, 0x1abf: 0x000c,
+       // Block 0x6b, offset 0x1ac0
+       0x1ac0: 0x000a, 0x1ac1: 0x000a, 0x1ac2: 0x000a, 0x1ac3: 0x000a, 0x1ac4: 0x000a, 0x1ac5: 0x000a,
+       0x1ac6: 0x000a, 0x1ac7: 0x000a, 0x1ac8: 0x000a, 0x1ac9: 0x000a, 0x1aca: 0x000a, 0x1acb: 0x000a,
+       0x1acc: 0x000a, 0x1acd: 0x000a, 0x1ace: 0x000a, 0x1acf: 0x000a, 0x1ad0: 0x000a, 0x1ad1: 0x000a,
+       0x1ad2: 0x000a, 0x1ad3: 0x000a, 0x1ad4: 0x000a, 0x1ad5: 0x000a, 0x1ad6: 0x000a, 0x1ad7: 0x000a,
+       0x1ad8: 0x000a, 0x1ad9: 0x000a, 0x1ada: 0x000a, 0x1adb: 0x000a, 0x1adc: 0x000a, 0x1add: 0x000a,
+       0x1ade: 0x000a, 0x1adf: 0x000a, 0x1ae0: 0x000a, 0x1ae1: 0x000a, 0x1ae2: 0x003a, 0x1ae3: 0x002a,
+       0x1ae4: 0x003a, 0x1ae5: 0x002a, 0x1ae6: 0x003a, 0x1ae7: 0x002a, 0x1ae8: 0x003a, 0x1ae9: 0x002a,
+       0x1aea: 0x000a, 0x1aeb: 0x000a, 0x1aec: 0x000a, 0x1aed: 0x000a, 0x1aee: 0x000a, 0x1aef: 0x000a,
+       0x1af0: 0x000a, 0x1af1: 0x000a, 0x1af2: 0x000a, 0x1af3: 0x000a, 0x1af4: 0x000a, 0x1af5: 0x000a,
+       0x1af6: 0x000a, 0x1af7: 0x000a, 0x1af8: 0x000a, 0x1af9: 0x000a, 0x1afa: 0x000a, 0x1afb: 0x000a,
+       0x1afc: 0x000a, 0x1afd: 0x000a, 0x1afe: 0x000a, 0x1aff: 0x000a,
+       // Block 0x6c, offset 0x1b00
+       0x1b00: 0x000a, 0x1b01: 0x000a, 0x1b02: 0x000a, 0x1b03: 0x000a, 0x1b04: 0x000a, 0x1b05: 0x000a,
+       0x1b06: 0x000a, 0x1b07: 0x000a, 0x1b08: 0x000a, 0x1b09: 0x000a, 0x1b0a: 0x000a, 0x1b0b: 0x000a,
+       0x1b0c: 0x000a, 0x1b0d: 0x000a, 0x1b0e: 0x000a, 0x1b0f: 0x000a, 0x1b10: 0x000a, 0x1b11: 0x000a,
+       0x1b12: 0x000a,
+       // Block 0x6d, offset 0x1b40
+       0x1b40: 0x000a, 0x1b41: 0x000a, 0x1b42: 0x000a, 0x1b43: 0x000a, 0x1b44: 0x000a, 0x1b45: 0x000a,
+       0x1b46: 0x000a, 0x1b47: 0x000a, 0x1b48: 0x000a, 0x1b49: 0x000a, 0x1b4a: 0x000a, 0x1b4b: 0x000a,
+       0x1b4c: 0x000a, 0x1b4d: 0x000a, 0x1b4e: 0x000a, 0x1b4f: 0x000a, 0x1b50: 0x000a, 0x1b51: 0x000a,
+       0x1b52: 0x000a, 0x1b53: 0x000a, 0x1b54: 0x000a, 0x1b55: 0x000a, 0x1b56: 0x000a, 0x1b57: 0x000a,
+       0x1b58: 0x000a, 0x1b59: 0x000a, 0x1b5b: 0x000a, 0x1b5c: 0x000a, 0x1b5d: 0x000a,
+       0x1b5e: 0x000a, 0x1b5f: 0x000a, 0x1b60: 0x000a, 0x1b61: 0x000a, 0x1b62: 0x000a, 0x1b63: 0x000a,
+       0x1b64: 0x000a, 0x1b65: 0x000a, 0x1b66: 0x000a, 0x1b67: 0x000a, 0x1b68: 0x000a, 0x1b69: 0x000a,
+       0x1b6a: 0x000a, 0x1b6b: 0x000a, 0x1b6c: 0x000a, 0x1b6d: 0x000a, 0x1b6e: 0x000a, 0x1b6f: 0x000a,
+       0x1b70: 0x000a, 0x1b71: 0x000a, 0x1b72: 0x000a, 0x1b73: 0x000a, 0x1b74: 0x000a, 0x1b75: 0x000a,
+       0x1b76: 0x000a, 0x1b77: 0x000a, 0x1b78: 0x000a, 0x1b79: 0x000a, 0x1b7a: 0x000a, 0x1b7b: 0x000a,
+       0x1b7c: 0x000a, 0x1b7d: 0x000a, 0x1b7e: 0x000a, 0x1b7f: 0x000a,
+       // Block 0x6e, offset 0x1b80
+       0x1b80: 0x000a, 0x1b81: 0x000a, 0x1b82: 0x000a, 0x1b83: 0x000a, 0x1b84: 0x000a, 0x1b85: 0x000a,
+       0x1b86: 0x000a, 0x1b87: 0x000a, 0x1b88: 0x000a, 0x1b89: 0x000a, 0x1b8a: 0x000a, 0x1b8b: 0x000a,
+       0x1b8c: 0x000a, 0x1b8d: 0x000a, 0x1b8e: 0x000a, 0x1b8f: 0x000a, 0x1b90: 0x000a, 0x1b91: 0x000a,
+       0x1b92: 0x000a, 0x1b93: 0x000a, 0x1b94: 0x000a, 0x1b95: 0x000a, 0x1b96: 0x000a, 0x1b97: 0x000a,
+       0x1b98: 0x000a, 0x1b99: 0x000a, 0x1b9a: 0x000a, 0x1b9b: 0x000a, 0x1b9c: 0x000a, 0x1b9d: 0x000a,
+       0x1b9e: 0x000a, 0x1b9f: 0x000a, 0x1ba0: 0x000a, 0x1ba1: 0x000a, 0x1ba2: 0x000a, 0x1ba3: 0x000a,
+       0x1ba4: 0x000a, 0x1ba5: 0x000a, 0x1ba6: 0x000a, 0x1ba7: 0x000a, 0x1ba8: 0x000a, 0x1ba9: 0x000a,
+       0x1baa: 0x000a, 0x1bab: 0x000a, 0x1bac: 0x000a, 0x1bad: 0x000a, 0x1bae: 0x000a, 0x1baf: 0x000a,
+       0x1bb0: 0x000a, 0x1bb1: 0x000a, 0x1bb2: 0x000a, 0x1bb3: 0x000a,
+       // Block 0x6f, offset 0x1bc0
+       0x1bc0: 0x000a, 0x1bc1: 0x000a, 0x1bc2: 0x000a, 0x1bc3: 0x000a, 0x1bc4: 0x000a, 0x1bc5: 0x000a,
+       0x1bc6: 0x000a, 0x1bc7: 0x000a, 0x1bc8: 0x000a, 0x1bc9: 0x000a, 0x1bca: 0x000a, 0x1bcb: 0x000a,
+       0x1bcc: 0x000a, 0x1bcd: 0x000a, 0x1bce: 0x000a, 0x1bcf: 0x000a, 0x1bd0: 0x000a, 0x1bd1: 0x000a,
+       0x1bd2: 0x000a, 0x1bd3: 0x000a, 0x1bd4: 0x000a, 0x1bd5: 0x000a,
+       0x1bf0: 0x000a, 0x1bf1: 0x000a, 0x1bf2: 0x000a, 0x1bf3: 0x000a, 0x1bf4: 0x000a, 0x1bf5: 0x000a,
+       0x1bf6: 0x000a, 0x1bf7: 0x000a, 0x1bf8: 0x000a, 0x1bf9: 0x000a, 0x1bfa: 0x000a, 0x1bfb: 0x000a,
+       // Block 0x70, offset 0x1c00
+       0x1c00: 0x0009, 0x1c01: 0x000a, 0x1c02: 0x000a, 0x1c03: 0x000a, 0x1c04: 0x000a,
+       0x1c08: 0x003a, 0x1c09: 0x002a, 0x1c0a: 0x003a, 0x1c0b: 0x002a,
+       0x1c0c: 0x003a, 0x1c0d: 0x002a, 0x1c0e: 0x003a, 0x1c0f: 0x002a, 0x1c10: 0x003a, 0x1c11: 0x002a,
+       0x1c12: 0x000a, 0x1c13: 0x000a, 0x1c14: 0x003a, 0x1c15: 0x002a, 0x1c16: 0x003a, 0x1c17: 0x002a,
+       0x1c18: 0x003a, 0x1c19: 0x002a, 0x1c1a: 0x003a, 0x1c1b: 0x002a, 0x1c1c: 0x000a, 0x1c1d: 0x000a,
+       0x1c1e: 0x000a, 0x1c1f: 0x000a, 0x1c20: 0x000a,
+       0x1c2a: 0x000c, 0x1c2b: 0x000c, 0x1c2c: 0x000c, 0x1c2d: 0x000c,
+       0x1c30: 0x000a,
+       0x1c36: 0x000a, 0x1c37: 0x000a,
+       0x1c3d: 0x000a, 0x1c3e: 0x000a, 0x1c3f: 0x000a,
+       // Block 0x71, offset 0x1c40
+       0x1c59: 0x000c, 0x1c5a: 0x000c, 0x1c5b: 0x000a, 0x1c5c: 0x000a,
+       0x1c60: 0x000a,
+       // Block 0x72, offset 0x1c80
+       0x1cbb: 0x000a,
+       // Block 0x73, offset 0x1cc0
+       0x1cc0: 0x000a, 0x1cc1: 0x000a, 0x1cc2: 0x000a, 0x1cc3: 0x000a, 0x1cc4: 0x000a, 0x1cc5: 0x000a,
+       0x1cc6: 0x000a, 0x1cc7: 0x000a, 0x1cc8: 0x000a, 0x1cc9: 0x000a, 0x1cca: 0x000a, 0x1ccb: 0x000a,
+       0x1ccc: 0x000a, 0x1ccd: 0x000a, 0x1cce: 0x000a, 0x1ccf: 0x000a, 0x1cd0: 0x000a, 0x1cd1: 0x000a,
+       0x1cd2: 0x000a, 0x1cd3: 0x000a, 0x1cd4: 0x000a, 0x1cd5: 0x000a, 0x1cd6: 0x000a, 0x1cd7: 0x000a,
+       0x1cd8: 0x000a, 0x1cd9: 0x000a, 0x1cda: 0x000a, 0x1cdb: 0x000a, 0x1cdc: 0x000a, 0x1cdd: 0x000a,
+       0x1cde: 0x000a, 0x1cdf: 0x000a, 0x1ce0: 0x000a, 0x1ce1: 0x000a, 0x1ce2: 0x000a, 0x1ce3: 0x000a,
+       // Block 0x74, offset 0x1d00
+       0x1d1d: 0x000a,
+       0x1d1e: 0x000a,
+       // Block 0x75, offset 0x1d40
+       0x1d50: 0x000a, 0x1d51: 0x000a,
+       0x1d52: 0x000a, 0x1d53: 0x000a, 0x1d54: 0x000a, 0x1d55: 0x000a, 0x1d56: 0x000a, 0x1d57: 0x000a,
+       0x1d58: 0x000a, 0x1d59: 0x000a, 0x1d5a: 0x000a, 0x1d5b: 0x000a, 0x1d5c: 0x000a, 0x1d5d: 0x000a,
+       0x1d5e: 0x000a, 0x1d5f: 0x000a,
+       0x1d7c: 0x000a, 0x1d7d: 0x000a, 0x1d7e: 0x000a,
+       // Block 0x76, offset 0x1d80
+       0x1db1: 0x000a, 0x1db2: 0x000a, 0x1db3: 0x000a, 0x1db4: 0x000a, 0x1db5: 0x000a,
+       0x1db6: 0x000a, 0x1db7: 0x000a, 0x1db8: 0x000a, 0x1db9: 0x000a, 0x1dba: 0x000a, 0x1dbb: 0x000a,
+       0x1dbc: 0x000a, 0x1dbd: 0x000a, 0x1dbe: 0x000a, 0x1dbf: 0x000a,
+       // Block 0x77, offset 0x1dc0
+       0x1dcc: 0x000a, 0x1dcd: 0x000a, 0x1dce: 0x000a, 0x1dcf: 0x000a,
+       // Block 0x78, offset 0x1e00
+       0x1e37: 0x000a, 0x1e38: 0x000a, 0x1e39: 0x000a, 0x1e3a: 0x000a,
+       // Block 0x79, offset 0x1e40
+       0x1e5e: 0x000a, 0x1e5f: 0x000a,
+       0x1e7f: 0x000a,
+       // Block 0x7a, offset 0x1e80
+       0x1e90: 0x000a, 0x1e91: 0x000a,
+       0x1e92: 0x000a, 0x1e93: 0x000a, 0x1e94: 0x000a, 0x1e95: 0x000a, 0x1e96: 0x000a, 0x1e97: 0x000a,
+       0x1e98: 0x000a, 0x1e99: 0x000a, 0x1e9a: 0x000a, 0x1e9b: 0x000a, 0x1e9c: 0x000a, 0x1e9d: 0x000a,
+       0x1e9e: 0x000a, 0x1e9f: 0x000a, 0x1ea0: 0x000a, 0x1ea1: 0x000a, 0x1ea2: 0x000a, 0x1ea3: 0x000a,
+       0x1ea4: 0x000a, 0x1ea5: 0x000a, 0x1ea6: 0x000a, 0x1ea7: 0x000a, 0x1ea8: 0x000a, 0x1ea9: 0x000a,
+       0x1eaa: 0x000a, 0x1eab: 0x000a, 0x1eac: 0x000a, 0x1ead: 0x000a, 0x1eae: 0x000a, 0x1eaf: 0x000a,
+       0x1eb0: 0x000a, 0x1eb1: 0x000a, 0x1eb2: 0x000a, 0x1eb3: 0x000a, 0x1eb4: 0x000a, 0x1eb5: 0x000a,
+       0x1eb6: 0x000a, 0x1eb7: 0x000a, 0x1eb8: 0x000a, 0x1eb9: 0x000a, 0x1eba: 0x000a, 0x1ebb: 0x000a,
+       0x1ebc: 0x000a, 0x1ebd: 0x000a, 0x1ebe: 0x000a, 0x1ebf: 0x000a,
+       // Block 0x7b, offset 0x1ec0
+       0x1ec0: 0x000a, 0x1ec1: 0x000a, 0x1ec2: 0x000a, 0x1ec3: 0x000a, 0x1ec4: 0x000a, 0x1ec5: 0x000a,
+       0x1ec6: 0x000a,
+       // Block 0x7c, offset 0x1f00
+       0x1f0d: 0x000a, 0x1f0e: 0x000a, 0x1f0f: 0x000a,
+       // Block 0x7d, offset 0x1f40
+       0x1f6f: 0x000c,
+       0x1f70: 0x000c, 0x1f71: 0x000c, 0x1f72: 0x000c, 0x1f73: 0x000a, 0x1f74: 0x000c, 0x1f75: 0x000c,
+       0x1f76: 0x000c, 0x1f77: 0x000c, 0x1f78: 0x000c, 0x1f79: 0x000c, 0x1f7a: 0x000c, 0x1f7b: 0x000c,
+       0x1f7c: 0x000c, 0x1f7d: 0x000c, 0x1f7e: 0x000a, 0x1f7f: 0x000a,
+       // Block 0x7e, offset 0x1f80
+       0x1f9e: 0x000c, 0x1f9f: 0x000c,
+       // Block 0x7f, offset 0x1fc0
+       0x1ff0: 0x000c, 0x1ff1: 0x000c,
+       // Block 0x80, offset 0x2000
+       0x2000: 0x000a, 0x2001: 0x000a, 0x2002: 0x000a, 0x2003: 0x000a, 0x2004: 0x000a, 0x2005: 0x000a,
+       0x2006: 0x000a, 0x2007: 0x000a, 0x2008: 0x000a, 0x2009: 0x000a, 0x200a: 0x000a, 0x200b: 0x000a,
+       0x200c: 0x000a, 0x200d: 0x000a, 0x200e: 0x000a, 0x200f: 0x000a, 0x2010: 0x000a, 0x2011: 0x000a,
+       0x2012: 0x000a, 0x2013: 0x000a, 0x2014: 0x000a, 0x2015: 0x000a, 0x2016: 0x000a, 0x2017: 0x000a,
+       0x2018: 0x000a, 0x2019: 0x000a, 0x201a: 0x000a, 0x201b: 0x000a, 0x201c: 0x000a, 0x201d: 0x000a,
+       0x201e: 0x000a, 0x201f: 0x000a, 0x2020: 0x000a, 0x2021: 0x000a,
+       // Block 0x81, offset 0x2040
+       0x2048: 0x000a,
+       // Block 0x82, offset 0x2080
+       0x2082: 0x000c,
+       0x2086: 0x000c, 0x208b: 0x000c,
+       0x20a5: 0x000c, 0x20a6: 0x000c, 0x20a8: 0x000a, 0x20a9: 0x000a,
+       0x20aa: 0x000a, 0x20ab: 0x000a, 0x20ac: 0x000c,
+       0x20b8: 0x0004, 0x20b9: 0x0004,
+       // Block 0x83, offset 0x20c0
+       0x20f4: 0x000a, 0x20f5: 0x000a,
+       0x20f6: 0x000a, 0x20f7: 0x000a,
+       // Block 0x84, offset 0x2100
+       0x2104: 0x000c, 0x2105: 0x000c,
+       0x2120: 0x000c, 0x2121: 0x000c, 0x2122: 0x000c, 0x2123: 0x000c,
+       0x2124: 0x000c, 0x2125: 0x000c, 0x2126: 0x000c, 0x2127: 0x000c, 0x2128: 0x000c, 0x2129: 0x000c,
+       0x212a: 0x000c, 0x212b: 0x000c, 0x212c: 0x000c, 0x212d: 0x000c, 0x212e: 0x000c, 0x212f: 0x000c,
+       0x2130: 0x000c, 0x2131: 0x000c,
+       0x213f: 0x000c,
+       // Block 0x85, offset 0x2140
+       0x2166: 0x000c, 0x2167: 0x000c, 0x2168: 0x000c, 0x2169: 0x000c,
+       0x216a: 0x000c, 0x216b: 0x000c, 0x216c: 0x000c, 0x216d: 0x000c,
+       // Block 0x86, offset 0x2180
+       0x2187: 0x000c, 0x2188: 0x000c, 0x2189: 0x000c, 0x218a: 0x000c, 0x218b: 0x000c,
+       0x218c: 0x000c, 0x218d: 0x000c, 0x218e: 0x000c, 0x218f: 0x000c, 0x2190: 0x000c, 0x2191: 0x000c,
+       // Block 0x87, offset 0x21c0
+       0x21c0: 0x000c, 0x21c1: 0x000c, 0x21c2: 0x000c,
+       0x21f3: 0x000c,
+       0x21f6: 0x000c, 0x21f7: 0x000c, 0x21f8: 0x000c, 0x21f9: 0x000c,
+       0x21fc: 0x000c, 0x21fd: 0x000c,
+       // Block 0x88, offset 0x2200
+       0x2225: 0x000c,
+       // Block 0x89, offset 0x2240
+       0x2269: 0x000c,
+       0x226a: 0x000c, 0x226b: 0x000c, 0x226c: 0x000c, 0x226d: 0x000c, 0x226e: 0x000c,
+       0x2271: 0x000c, 0x2272: 0x000c, 0x2275: 0x000c,
+       0x2276: 0x000c,
+       // Block 0x8a, offset 0x2280
+       0x2283: 0x000c,
+       0x228c: 0x000c,
+       0x22bc: 0x000c,
+       // Block 0x8b, offset 0x22c0
+       0x22f0: 0x000c, 0x22f2: 0x000c, 0x22f3: 0x000c, 0x22f4: 0x000c,
+       0x22f7: 0x000c, 0x22f8: 0x000c,
+       0x22fe: 0x000c, 0x22ff: 0x000c,
+       // Block 0x8c, offset 0x2300
+       0x2301: 0x000c,
+       0x232c: 0x000c, 0x232d: 0x000c,
+       0x2336: 0x000c,
+       // Block 0x8d, offset 0x2340
+       0x236a: 0x000a, 0x236b: 0x000a,
+       // Block 0x8e, offset 0x2380
+       0x23a5: 0x000c, 0x23a8: 0x000c,
+       0x23ad: 0x000c,
+       // Block 0x8f, offset 0x23c0
+       0x23dd: 0x0001,
+       0x23de: 0x000c, 0x23df: 0x0001, 0x23e0: 0x0001, 0x23e1: 0x0001, 0x23e2: 0x0001, 0x23e3: 0x0001,
+       0x23e4: 0x0001, 0x23e5: 0x0001, 0x23e6: 0x0001, 0x23e7: 0x0001, 0x23e8: 0x0001, 0x23e9: 0x0003,
+       0x23ea: 0x0001, 0x23eb: 0x0001, 0x23ec: 0x0001, 0x23ed: 0x0001, 0x23ee: 0x0001, 0x23ef: 0x0001,
+       0x23f0: 0x0001, 0x23f1: 0x0001, 0x23f2: 0x0001, 0x23f3: 0x0001, 0x23f4: 0x0001, 0x23f5: 0x0001,
+       0x23f6: 0x0001, 0x23f7: 0x0001, 0x23f8: 0x0001, 0x23f9: 0x0001, 0x23fa: 0x0001, 0x23fb: 0x0001,
+       0x23fc: 0x0001, 0x23fd: 0x0001, 0x23fe: 0x0001, 0x23ff: 0x0001,
+       // Block 0x90, offset 0x2400
+       0x2400: 0x0001, 0x2401: 0x0001, 0x2402: 0x0001, 0x2403: 0x0001, 0x2404: 0x0001, 0x2405: 0x0001,
+       0x2406: 0x0001, 0x2407: 0x0001, 0x2408: 0x0001, 0x2409: 0x0001, 0x240a: 0x0001, 0x240b: 0x0001,
+       0x240c: 0x0001, 0x240d: 0x0001, 0x240e: 0x0001, 0x240f: 0x0001, 0x2410: 0x000d, 0x2411: 0x000d,
+       0x2412: 0x000d, 0x2413: 0x000d, 0x2414: 0x000d, 0x2415: 0x000d, 0x2416: 0x000d, 0x2417: 0x000d,
+       0x2418: 0x000d, 0x2419: 0x000d, 0x241a: 0x000d, 0x241b: 0x000d, 0x241c: 0x000d, 0x241d: 0x000d,
+       0x241e: 0x000d, 0x241f: 0x000d, 0x2420: 0x000d, 0x2421: 0x000d, 0x2422: 0x000d, 0x2423: 0x000d,
+       0x2424: 0x000d, 0x2425: 0x000d, 0x2426: 0x000d, 0x2427: 0x000d, 0x2428: 0x000d, 0x2429: 0x000d,
+       0x242a: 0x000d, 0x242b: 0x000d, 0x242c: 0x000d, 0x242d: 0x000d, 0x242e: 0x000d, 0x242f: 0x000d,
+       0x2430: 0x000d, 0x2431: 0x000d, 0x2432: 0x000d, 0x2433: 0x000d, 0x2434: 0x000d, 0x2435: 0x000d,
+       0x2436: 0x000d, 0x2437: 0x000d, 0x2438: 0x000d, 0x2439: 0x000d, 0x243a: 0x000d, 0x243b: 0x000d,
+       0x243c: 0x000d, 0x243d: 0x000d, 0x243e: 0x000d, 0x243f: 0x000d,
+       // Block 0x91, offset 0x2440
+       0x2440: 0x000d, 0x2441: 0x000d, 0x2442: 0x000d, 0x2443: 0x000d, 0x2444: 0x000d, 0x2445: 0x000d,
+       0x2446: 0x000d, 0x2447: 0x000d, 0x2448: 0x000d, 0x2449: 0x000d, 0x244a: 0x000d, 0x244b: 0x000d,
+       0x244c: 0x000d, 0x244d: 0x000d, 0x244e: 0x000d, 0x244f: 0x000d, 0x2450: 0x000d, 0x2451: 0x000d,
+       0x2452: 0x000d, 0x2453: 0x000d, 0x2454: 0x000d, 0x2455: 0x000d, 0x2456: 0x000d, 0x2457: 0x000d,
+       0x2458: 0x000d, 0x2459: 0x000d, 0x245a: 0x000d, 0x245b: 0x000d, 0x245c: 0x000d, 0x245d: 0x000d,
+       0x245e: 0x000d, 0x245f: 0x000d, 0x2460: 0x000d, 0x2461: 0x000d, 0x2462: 0x000d, 0x2463: 0x000d,
+       0x2464: 0x000d, 0x2465: 0x000d, 0x2466: 0x000d, 0x2467: 0x000d, 0x2468: 0x000d, 0x2469: 0x000d,
+       0x246a: 0x000d, 0x246b: 0x000d, 0x246c: 0x000d, 0x246d: 0x000d, 0x246e: 0x000d, 0x246f: 0x000d,
+       0x2470: 0x000d, 0x2471: 0x000d, 0x2472: 0x000d, 0x2473: 0x000d, 0x2474: 0x000d, 0x2475: 0x000d,
+       0x2476: 0x000d, 0x2477: 0x000d, 0x2478: 0x000d, 0x2479: 0x000d, 0x247a: 0x000d, 0x247b: 0x000d,
+       0x247c: 0x000d, 0x247d: 0x000d, 0x247e: 0x000a, 0x247f: 0x000a,
+       // Block 0x92, offset 0x2480
+       0x2480: 0x000d, 0x2481: 0x000d, 0x2482: 0x000d, 0x2483: 0x000d, 0x2484: 0x000d, 0x2485: 0x000d,
+       0x2486: 0x000d, 0x2487: 0x000d, 0x2488: 0x000d, 0x2489: 0x000d, 0x248a: 0x000d, 0x248b: 0x000d,
+       0x248c: 0x000d, 0x248d: 0x000d, 0x248e: 0x000d, 0x248f: 0x000d, 0x2490: 0x000b, 0x2491: 0x000b,
+       0x2492: 0x000b, 0x2493: 0x000b, 0x2494: 0x000b, 0x2495: 0x000b, 0x2496: 0x000b, 0x2497: 0x000b,
+       0x2498: 0x000b, 0x2499: 0x000b, 0x249a: 0x000b, 0x249b: 0x000b, 0x249c: 0x000b, 0x249d: 0x000b,
+       0x249e: 0x000b, 0x249f: 0x000b, 0x24a0: 0x000b, 0x24a1: 0x000b, 0x24a2: 0x000b, 0x24a3: 0x000b,
+       0x24a4: 0x000b, 0x24a5: 0x000b, 0x24a6: 0x000b, 0x24a7: 0x000b, 0x24a8: 0x000b, 0x24a9: 0x000b,
+       0x24aa: 0x000b, 0x24ab: 0x000b, 0x24ac: 0x000b, 0x24ad: 0x000b, 0x24ae: 0x000b, 0x24af: 0x000b,
+       0x24b0: 0x000d, 0x24b1: 0x000d, 0x24b2: 0x000d, 0x24b3: 0x000d, 0x24b4: 0x000d, 0x24b5: 0x000d,
+       0x24b6: 0x000d, 0x24b7: 0x000d, 0x24b8: 0x000d, 0x24b9: 0x000d, 0x24ba: 0x000d, 0x24bb: 0x000d,
+       0x24bc: 0x000d, 0x24bd: 0x000a, 0x24be: 0x000d, 0x24bf: 0x000d,
+       // Block 0x93, offset 0x24c0
+       0x24c0: 0x000c, 0x24c1: 0x000c, 0x24c2: 0x000c, 0x24c3: 0x000c, 0x24c4: 0x000c, 0x24c5: 0x000c,
+       0x24c6: 0x000c, 0x24c7: 0x000c, 0x24c8: 0x000c, 0x24c9: 0x000c, 0x24ca: 0x000c, 0x24cb: 0x000c,
+       0x24cc: 0x000c, 0x24cd: 0x000c, 0x24ce: 0x000c, 0x24cf: 0x000c, 0x24d0: 0x000a, 0x24d1: 0x000a,
+       0x24d2: 0x000a, 0x24d3: 0x000a, 0x24d4: 0x000a, 0x24d5: 0x000a, 0x24d6: 0x000a, 0x24d7: 0x000a,
+       0x24d8: 0x000a, 0x24d9: 0x000a,
+       0x24e0: 0x000c, 0x24e1: 0x000c, 0x24e2: 0x000c, 0x24e3: 0x000c,
+       0x24e4: 0x000c, 0x24e5: 0x000c, 0x24e6: 0x000c, 0x24e7: 0x000c, 0x24e8: 0x000c, 0x24e9: 0x000c,
+       0x24ea: 0x000c, 0x24eb: 0x000c, 0x24ec: 0x000c, 0x24ed: 0x000c, 0x24ee: 0x000c, 0x24ef: 0x000c,
+       0x24f0: 0x000a, 0x24f1: 0x000a, 0x24f2: 0x000a, 0x24f3: 0x000a, 0x24f4: 0x000a, 0x24f5: 0x000a,
+       0x24f6: 0x000a, 0x24f7: 0x000a, 0x24f8: 0x000a, 0x24f9: 0x000a, 0x24fa: 0x000a, 0x24fb: 0x000a,
+       0x24fc: 0x000a, 0x24fd: 0x000a, 0x24fe: 0x000a, 0x24ff: 0x000a,
+       // Block 0x94, offset 0x2500
+       0x2500: 0x000a, 0x2501: 0x000a, 0x2502: 0x000a, 0x2503: 0x000a, 0x2504: 0x000a, 0x2505: 0x000a,
+       0x2506: 0x000a, 0x2507: 0x000a, 0x2508: 0x000a, 0x2509: 0x000a, 0x250a: 0x000a, 0x250b: 0x000a,
+       0x250c: 0x000a, 0x250d: 0x000a, 0x250e: 0x000a, 0x250f: 0x000a, 0x2510: 0x0006, 0x2511: 0x000a,
+       0x2512: 0x0006, 0x2514: 0x000a, 0x2515: 0x0006, 0x2516: 0x000a, 0x2517: 0x000a,
+       0x2518: 0x000a, 0x2519: 0x009a, 0x251a: 0x008a, 0x251b: 0x007a, 0x251c: 0x006a, 0x251d: 0x009a,
+       0x251e: 0x008a, 0x251f: 0x0004, 0x2520: 0x000a, 0x2521: 0x000a, 0x2522: 0x0003, 0x2523: 0x0003,
+       0x2524: 0x000a, 0x2525: 0x000a, 0x2526: 0x000a, 0x2528: 0x000a, 0x2529: 0x0004,
+       0x252a: 0x0004, 0x252b: 0x000a,
+       0x2530: 0x000d, 0x2531: 0x000d, 0x2532: 0x000d, 0x2533: 0x000d, 0x2534: 0x000d, 0x2535: 0x000d,
+       0x2536: 0x000d, 0x2537: 0x000d, 0x2538: 0x000d, 0x2539: 0x000d, 0x253a: 0x000d, 0x253b: 0x000d,
+       0x253c: 0x000d, 0x253d: 0x000d, 0x253e: 0x000d, 0x253f: 0x000d,
+       // Block 0x95, offset 0x2540
+       0x2540: 0x000d, 0x2541: 0x000d, 0x2542: 0x000d, 0x2543: 0x000d, 0x2544: 0x000d, 0x2545: 0x000d,
+       0x2546: 0x000d, 0x2547: 0x000d, 0x2548: 0x000d, 0x2549: 0x000d, 0x254a: 0x000d, 0x254b: 0x000d,
+       0x254c: 0x000d, 0x254d: 0x000d, 0x254e: 0x000d, 0x254f: 0x000d, 0x2550: 0x000d, 0x2551: 0x000d,
+       0x2552: 0x000d, 0x2553: 0x000d, 0x2554: 0x000d, 0x2555: 0x000d, 0x2556: 0x000d, 0x2557: 0x000d,
+       0x2558: 0x000d, 0x2559: 0x000d, 0x255a: 0x000d, 0x255b: 0x000d, 0x255c: 0x000d, 0x255d: 0x000d,
+       0x255e: 0x000d, 0x255f: 0x000d, 0x2560: 0x000d, 0x2561: 0x000d, 0x2562: 0x000d, 0x2563: 0x000d,
+       0x2564: 0x000d, 0x2565: 0x000d, 0x2566: 0x000d, 0x2567: 0x000d, 0x2568: 0x000d, 0x2569: 0x000d,
+       0x256a: 0x000d, 0x256b: 0x000d, 0x256c: 0x000d, 0x256d: 0x000d, 0x256e: 0x000d, 0x256f: 0x000d,
+       0x2570: 0x000d, 0x2571: 0x000d, 0x2572: 0x000d, 0x2573: 0x000d, 0x2574: 0x000d, 0x2575: 0x000d,
+       0x2576: 0x000d, 0x2577: 0x000d, 0x2578: 0x000d, 0x2579: 0x000d, 0x257a: 0x000d, 0x257b: 0x000d,
+       0x257c: 0x000d, 0x257d: 0x000d, 0x257e: 0x000d, 0x257f: 0x000b,
+       // Block 0x96, offset 0x2580
+       0x2581: 0x000a, 0x2582: 0x000a, 0x2583: 0x0004, 0x2584: 0x0004, 0x2585: 0x0004,
+       0x2586: 0x000a, 0x2587: 0x000a, 0x2588: 0x003a, 0x2589: 0x002a, 0x258a: 0x000a, 0x258b: 0x0003,
+       0x258c: 0x0006, 0x258d: 0x0003, 0x258e: 0x0006, 0x258f: 0x0006, 0x2590: 0x0002, 0x2591: 0x0002,
+       0x2592: 0x0002, 0x2593: 0x0002, 0x2594: 0x0002, 0x2595: 0x0002, 0x2596: 0x0002, 0x2597: 0x0002,
+       0x2598: 0x0002, 0x2599: 0x0002, 0x259a: 0x0006, 0x259b: 0x000a, 0x259c: 0x000a, 0x259d: 0x000a,
+       0x259e: 0x000a, 0x259f: 0x000a, 0x25a0: 0x000a,
+       0x25bb: 0x005a,
+       0x25bc: 0x000a, 0x25bd: 0x004a, 0x25be: 0x000a, 0x25bf: 0x000a,
+       // Block 0x97, offset 0x25c0
+       0x25c0: 0x000a,
+       0x25db: 0x005a, 0x25dc: 0x000a, 0x25dd: 0x004a,
+       0x25de: 0x000a, 0x25df: 0x00fa, 0x25e0: 0x00ea, 0x25e1: 0x000a, 0x25e2: 0x003a, 0x25e3: 0x002a,
+       0x25e4: 0x000a, 0x25e5: 0x000a,
+       // Block 0x98, offset 0x2600
+       0x2620: 0x0004, 0x2621: 0x0004, 0x2622: 0x000a, 0x2623: 0x000a,
+       0x2624: 0x000a, 0x2625: 0x0004, 0x2626: 0x0004, 0x2628: 0x000a, 0x2629: 0x000a,
+       0x262a: 0x000a, 0x262b: 0x000a, 0x262c: 0x000a, 0x262d: 0x000a, 0x262e: 0x000a,
+       0x2630: 0x000b, 0x2631: 0x000b, 0x2632: 0x000b, 0x2633: 0x000b, 0x2634: 0x000b, 0x2635: 0x000b,
+       0x2636: 0x000b, 0x2637: 0x000b, 0x2638: 0x000b, 0x2639: 0x000a, 0x263a: 0x000a, 0x263b: 0x000a,
+       0x263c: 0x000a, 0x263d: 0x000a, 0x263e: 0x000b, 0x263f: 0x000b,
+       // Block 0x99, offset 0x2640
+       0x2641: 0x000a,
+       // Block 0x9a, offset 0x2680
+       0x2680: 0x000a, 0x2681: 0x000a, 0x2682: 0x000a, 0x2683: 0x000a, 0x2684: 0x000a, 0x2685: 0x000a,
+       0x2686: 0x000a, 0x2687: 0x000a, 0x2688: 0x000a, 0x2689: 0x000a, 0x268a: 0x000a, 0x268b: 0x000a,
+       0x268c: 0x000a, 0x2690: 0x000a, 0x2691: 0x000a,
+       0x2692: 0x000a, 0x2693: 0x000a, 0x2694: 0x000a, 0x2695: 0x000a, 0x2696: 0x000a, 0x2697: 0x000a,
+       0x2698: 0x000a, 0x2699: 0x000a, 0x269a: 0x000a, 0x269b: 0x000a, 0x269c: 0x000a,
+       0x26a0: 0x000a,
+       // Block 0x9b, offset 0x26c0
+       0x26fd: 0x000c,
+       // Block 0x9c, offset 0x2700
+       0x2720: 0x000c, 0x2721: 0x0002, 0x2722: 0x0002, 0x2723: 0x0002,
+       0x2724: 0x0002, 0x2725: 0x0002, 0x2726: 0x0002, 0x2727: 0x0002, 0x2728: 0x0002, 0x2729: 0x0002,
+       0x272a: 0x0002, 0x272b: 0x0002, 0x272c: 0x0002, 0x272d: 0x0002, 0x272e: 0x0002, 0x272f: 0x0002,
+       0x2730: 0x0002, 0x2731: 0x0002, 0x2732: 0x0002, 0x2733: 0x0002, 0x2734: 0x0002, 0x2735: 0x0002,
+       0x2736: 0x0002, 0x2737: 0x0002, 0x2738: 0x0002, 0x2739: 0x0002, 0x273a: 0x0002, 0x273b: 0x0002,
+       // Block 0x9d, offset 0x2740
+       0x2776: 0x000c, 0x2777: 0x000c, 0x2778: 0x000c, 0x2779: 0x000c, 0x277a: 0x000c,
+       // Block 0x9e, offset 0x2780
+       0x2780: 0x0001, 0x2781: 0x0001, 0x2782: 0x0001, 0x2783: 0x0001, 0x2784: 0x0001, 0x2785: 0x0001,
+       0x2786: 0x0001, 0x2787: 0x0001, 0x2788: 0x0001, 0x2789: 0x0001, 0x278a: 0x0001, 0x278b: 0x0001,
+       0x278c: 0x0001, 0x278d: 0x0001, 0x278e: 0x0001, 0x278f: 0x0001, 0x2790: 0x0001, 0x2791: 0x0001,
+       0x2792: 0x0001, 0x2793: 0x0001, 0x2794: 0x0001, 0x2795: 0x0001, 0x2796: 0x0001, 0x2797: 0x0001,
+       0x2798: 0x0001, 0x2799: 0x0001, 0x279a: 0x0001, 0x279b: 0x0001, 0x279c: 0x0001, 0x279d: 0x0001,
+       0x279e: 0x0001, 0x279f: 0x0001, 0x27a0: 0x0001, 0x27a1: 0x0001, 0x27a2: 0x0001, 0x27a3: 0x0001,
+       0x27a4: 0x0001, 0x27a5: 0x0001, 0x27a6: 0x0001, 0x27a7: 0x0001, 0x27a8: 0x0001, 0x27a9: 0x0001,
+       0x27aa: 0x0001, 0x27ab: 0x0001, 0x27ac: 0x0001, 0x27ad: 0x0001, 0x27ae: 0x0001, 0x27af: 0x0001,
+       0x27b0: 0x0001, 0x27b1: 0x0001, 0x27b2: 0x0001, 0x27b3: 0x0001, 0x27b4: 0x0001, 0x27b5: 0x0001,
+       0x27b6: 0x0001, 0x27b7: 0x0001, 0x27b8: 0x0001, 0x27b9: 0x0001, 0x27ba: 0x0001, 0x27bb: 0x0001,
+       0x27bc: 0x0001, 0x27bd: 0x0001, 0x27be: 0x0001, 0x27bf: 0x0001,
+       // Block 0x9f, offset 0x27c0
+       0x27c0: 0x0001, 0x27c1: 0x0001, 0x27c2: 0x0001, 0x27c3: 0x0001, 0x27c4: 0x0001, 0x27c5: 0x0001,
+       0x27c6: 0x0001, 0x27c7: 0x0001, 0x27c8: 0x0001, 0x27c9: 0x0001, 0x27ca: 0x0001, 0x27cb: 0x0001,
+       0x27cc: 0x0001, 0x27cd: 0x0001, 0x27ce: 0x0001, 0x27cf: 0x0001, 0x27d0: 0x0001, 0x27d1: 0x0001,
+       0x27d2: 0x0001, 0x27d3: 0x0001, 0x27d4: 0x0001, 0x27d5: 0x0001, 0x27d6: 0x0001, 0x27d7: 0x0001,
+       0x27d8: 0x0001, 0x27d9: 0x0001, 0x27da: 0x0001, 0x27db: 0x0001, 0x27dc: 0x0001, 0x27dd: 0x0001,
+       0x27de: 0x0001, 0x27df: 0x000a, 0x27e0: 0x0001, 0x27e1: 0x0001, 0x27e2: 0x0001, 0x27e3: 0x0001,
+       0x27e4: 0x0001, 0x27e5: 0x0001, 0x27e6: 0x0001, 0x27e7: 0x0001, 0x27e8: 0x0001, 0x27e9: 0x0001,
+       0x27ea: 0x0001, 0x27eb: 0x0001, 0x27ec: 0x0001, 0x27ed: 0x0001, 0x27ee: 0x0001, 0x27ef: 0x0001,
+       0x27f0: 0x0001, 0x27f1: 0x0001, 0x27f2: 0x0001, 0x27f3: 0x0001, 0x27f4: 0x0001, 0x27f5: 0x0001,
+       0x27f6: 0x0001, 0x27f7: 0x0001, 0x27f8: 0x0001, 0x27f9: 0x0001, 0x27fa: 0x0001, 0x27fb: 0x0001,
+       0x27fc: 0x0001, 0x27fd: 0x0001, 0x27fe: 0x0001, 0x27ff: 0x0001,
+       // Block 0xa0, offset 0x2800
+       0x2800: 0x0001, 0x2801: 0x000c, 0x2802: 0x000c, 0x2803: 0x000c, 0x2804: 0x0001, 0x2805: 0x000c,
+       0x2806: 0x000c, 0x2807: 0x0001, 0x2808: 0x0001, 0x2809: 0x0001, 0x280a: 0x0001, 0x280b: 0x0001,
+       0x280c: 0x000c, 0x280d: 0x000c, 0x280e: 0x000c, 0x280f: 0x000c, 0x2810: 0x0001, 0x2811: 0x0001,
+       0x2812: 0x0001, 0x2813: 0x0001, 0x2814: 0x0001, 0x2815: 0x0001, 0x2816: 0x0001, 0x2817: 0x0001,
+       0x2818: 0x0001, 0x2819: 0x0001, 0x281a: 0x0001, 0x281b: 0x0001, 0x281c: 0x0001, 0x281d: 0x0001,
+       0x281e: 0x0001, 0x281f: 0x0001, 0x2820: 0x0001, 0x2821: 0x0001, 0x2822: 0x0001, 0x2823: 0x0001,
+       0x2824: 0x0001, 0x2825: 0x0001, 0x2826: 0x0001, 0x2827: 0x0001, 0x2828: 0x0001, 0x2829: 0x0001,
+       0x282a: 0x0001, 0x282b: 0x0001, 0x282c: 0x0001, 0x282d: 0x0001, 0x282e: 0x0001, 0x282f: 0x0001,
+       0x2830: 0x0001, 0x2831: 0x0001, 0x2832: 0x0001, 0x2833: 0x0001, 0x2834: 0x0001, 0x2835: 0x0001,
+       0x2836: 0x0001, 0x2837: 0x0001, 0x2838: 0x000c, 0x2839: 0x000c, 0x283a: 0x000c, 0x283b: 0x0001,
+       0x283c: 0x0001, 0x283d: 0x0001, 0x283e: 0x0001, 0x283f: 0x000c,
+       // Block 0xa1, offset 0x2840
+       0x2840: 0x0001, 0x2841: 0x0001, 0x2842: 0x0001, 0x2843: 0x0001, 0x2844: 0x0001, 0x2845: 0x0001,
+       0x2846: 0x0001, 0x2847: 0x0001, 0x2848: 0x0001, 0x2849: 0x0001, 0x284a: 0x0001, 0x284b: 0x0001,
+       0x284c: 0x0001, 0x284d: 0x0001, 0x284e: 0x0001, 0x284f: 0x0001, 0x2850: 0x0001, 0x2851: 0x0001,
+       0x2852: 0x0001, 0x2853: 0x0001, 0x2854: 0x0001, 0x2855: 0x0001, 0x2856: 0x0001, 0x2857: 0x0001,
+       0x2858: 0x0001, 0x2859: 0x0001, 0x285a: 0x0001, 0x285b: 0x0001, 0x285c: 0x0001, 0x285d: 0x0001,
+       0x285e: 0x0001, 0x285f: 0x0001, 0x2860: 0x0001, 0x2861: 0x0001, 0x2862: 0x0001, 0x2863: 0x0001,
+       0x2864: 0x0001, 0x2865: 0x000c, 0x2866: 0x000c, 0x2867: 0x0001, 0x2868: 0x0001, 0x2869: 0x0001,
+       0x286a: 0x0001, 0x286b: 0x0001, 0x286c: 0x0001, 0x286d: 0x0001, 0x286e: 0x0001, 0x286f: 0x0001,
+       0x2870: 0x0001, 0x2871: 0x0001, 0x2872: 0x0001, 0x2873: 0x0001, 0x2874: 0x0001, 0x2875: 0x0001,
+       0x2876: 0x0001, 0x2877: 0x0001, 0x2878: 0x0001, 0x2879: 0x0001, 0x287a: 0x0001, 0x287b: 0x0001,
+       0x287c: 0x0001, 0x287d: 0x0001, 0x287e: 0x0001, 0x287f: 0x0001,
+       // Block 0xa2, offset 0x2880
+       0x2880: 0x0001, 0x2881: 0x0001, 0x2882: 0x0001, 0x2883: 0x0001, 0x2884: 0x0001, 0x2885: 0x0001,
+       0x2886: 0x0001, 0x2887: 0x0001, 0x2888: 0x0001, 0x2889: 0x0001, 0x288a: 0x0001, 0x288b: 0x0001,
+       0x288c: 0x0001, 0x288d: 0x0001, 0x288e: 0x0001, 0x288f: 0x0001, 0x2890: 0x0001, 0x2891: 0x0001,
+       0x2892: 0x0001, 0x2893: 0x0001, 0x2894: 0x0001, 0x2895: 0x0001, 0x2896: 0x0001, 0x2897: 0x0001,
+       0x2898: 0x0001, 0x2899: 0x0001, 0x289a: 0x0001, 0x289b: 0x0001, 0x289c: 0x0001, 0x289d: 0x0001,
+       0x289e: 0x0001, 0x289f: 0x0001, 0x28a0: 0x0001, 0x28a1: 0x0001, 0x28a2: 0x0001, 0x28a3: 0x0001,
+       0x28a4: 0x0001, 0x28a5: 0x0001, 0x28a6: 0x0001, 0x28a7: 0x0001, 0x28a8: 0x0001, 0x28a9: 0x0001,
+       0x28aa: 0x0001, 0x28ab: 0x0001, 0x28ac: 0x0001, 0x28ad: 0x0001, 0x28ae: 0x0001, 0x28af: 0x0001,
+       0x28b0: 0x0001, 0x28b1: 0x0001, 0x28b2: 0x0001, 0x28b3: 0x0001, 0x28b4: 0x0001, 0x28b5: 0x0001,
+       0x28b6: 0x0001, 0x28b7: 0x0001, 0x28b8: 0x0001, 0x28b9: 0x000a, 0x28ba: 0x000a, 0x28bb: 0x000a,
+       0x28bc: 0x000a, 0x28bd: 0x000a, 0x28be: 0x000a, 0x28bf: 0x000a,
+       // Block 0xa3, offset 0x28c0
+       0x28c0: 0x000d, 0x28c1: 0x000d, 0x28c2: 0x000d, 0x28c3: 0x000d, 0x28c4: 0x000d, 0x28c5: 0x000d,
+       0x28c6: 0x000d, 0x28c7: 0x000d, 0x28c8: 0x000d, 0x28c9: 0x000d, 0x28ca: 0x000d, 0x28cb: 0x000d,
+       0x28cc: 0x000d, 0x28cd: 0x000d, 0x28ce: 0x000d, 0x28cf: 0x000d, 0x28d0: 0x000d, 0x28d1: 0x000d,
+       0x28d2: 0x000d, 0x28d3: 0x000d, 0x28d4: 0x000d, 0x28d5: 0x000d, 0x28d6: 0x000d, 0x28d7: 0x000d,
+       0x28d8: 0x000d, 0x28d9: 0x000d, 0x28da: 0x000d, 0x28db: 0x000d, 0x28dc: 0x000d, 0x28dd: 0x000d,
+       0x28de: 0x000d, 0x28df: 0x000d, 0x28e0: 0x000d, 0x28e1: 0x000d, 0x28e2: 0x000d, 0x28e3: 0x000d,
+       0x28e4: 0x000c, 0x28e5: 0x000c, 0x28e6: 0x000c, 0x28e7: 0x000c, 0x28e8: 0x000d, 0x28e9: 0x000d,
+       0x28ea: 0x000d, 0x28eb: 0x000d, 0x28ec: 0x000d, 0x28ed: 0x000d, 0x28ee: 0x000d, 0x28ef: 0x000d,
+       0x28f0: 0x0005, 0x28f1: 0x0005, 0x28f2: 0x0005, 0x28f3: 0x0005, 0x28f4: 0x0005, 0x28f5: 0x0005,
+       0x28f6: 0x0005, 0x28f7: 0x0005, 0x28f8: 0x0005, 0x28f9: 0x0005, 0x28fa: 0x000d, 0x28fb: 0x000d,
+       0x28fc: 0x000d, 0x28fd: 0x000d, 0x28fe: 0x000d, 0x28ff: 0x000d,
+       // Block 0xa4, offset 0x2900
+       0x2900: 0x0001, 0x2901: 0x0001, 0x2902: 0x0001, 0x2903: 0x0001, 0x2904: 0x0001, 0x2905: 0x0001,
+       0x2906: 0x0001, 0x2907: 0x0001, 0x2908: 0x0001, 0x2909: 0x0001, 0x290a: 0x0001, 0x290b: 0x0001,
+       0x290c: 0x0001, 0x290d: 0x0001, 0x290e: 0x0001, 0x290f: 0x0001, 0x2910: 0x0001, 0x2911: 0x0001,
+       0x2912: 0x0001, 0x2913: 0x0001, 0x2914: 0x0001, 0x2915: 0x0001, 0x2916: 0x0001, 0x2917: 0x0001,
+       0x2918: 0x0001, 0x2919: 0x0001, 0x291a: 0x0001, 0x291b: 0x0001, 0x291c: 0x0001, 0x291d: 0x0001,
+       0x291e: 0x0001, 0x291f: 0x0001, 0x2920: 0x0005, 0x2921: 0x0005, 0x2922: 0x0005, 0x2923: 0x0005,
+       0x2924: 0x0005, 0x2925: 0x0005, 0x2926: 0x0005, 0x2927: 0x0005, 0x2928: 0x0005, 0x2929: 0x0005,
+       0x292a: 0x0005, 0x292b: 0x0005, 0x292c: 0x0005, 0x292d: 0x0005, 0x292e: 0x0005, 0x292f: 0x0005,
+       0x2930: 0x0005, 0x2931: 0x0005, 0x2932: 0x0005, 0x2933: 0x0005, 0x2934: 0x0005, 0x2935: 0x0005,
+       0x2936: 0x0005, 0x2937: 0x0005, 0x2938: 0x0005, 0x2939: 0x0005, 0x293a: 0x0005, 0x293b: 0x0005,
+       0x293c: 0x0005, 0x293d: 0x0005, 0x293e: 0x0005, 0x293f: 0x0001,
+       // Block 0xa5, offset 0x2940
+       0x2940: 0x0001, 0x2941: 0x0001, 0x2942: 0x0001, 0x2943: 0x0001, 0x2944: 0x0001, 0x2945: 0x0001,
+       0x2946: 0x0001, 0x2947: 0x0001, 0x2948: 0x0001, 0x2949: 0x0001, 0x294a: 0x0001, 0x294b: 0x0001,
+       0x294c: 0x0001, 0x294d: 0x0001, 0x294e: 0x0001, 0x294f: 0x0001, 0x2950: 0x0001, 0x2951: 0x0001,
+       0x2952: 0x0001, 0x2953: 0x0001, 0x2954: 0x0001, 0x2955: 0x0001, 0x2956: 0x0001, 0x2957: 0x0001,
+       0x2958: 0x0001, 0x2959: 0x0001, 0x295a: 0x0001, 0x295b: 0x0001, 0x295c: 0x0001, 0x295d: 0x0001,
+       0x295e: 0x0001, 0x295f: 0x0001, 0x2960: 0x0001, 0x2961: 0x0001, 0x2962: 0x0001, 0x2963: 0x0001,
+       0x2964: 0x0001, 0x2965: 0x0001, 0x2966: 0x0001, 0x2967: 0x0001, 0x2968: 0x0001, 0x2969: 0x0001,
+       0x296a: 0x0001, 0x296b: 0x000c, 0x296c: 0x000c, 0x296d: 0x0001, 0x296e: 0x0001, 0x296f: 0x0001,
+       0x2970: 0x0001, 0x2971: 0x0001, 0x2972: 0x0001, 0x2973: 0x0001, 0x2974: 0x0001, 0x2975: 0x0001,
+       0x2976: 0x0001, 0x2977: 0x0001, 0x2978: 0x0001, 0x2979: 0x0001, 0x297a: 0x0001, 0x297b: 0x0001,
+       0x297c: 0x0001, 0x297d: 0x0001, 0x297e: 0x0001, 0x297f: 0x0001,
+       // Block 0xa6, offset 0x2980
+       0x2980: 0x0001, 0x2981: 0x0001, 0x2982: 0x0001, 0x2983: 0x0001, 0x2984: 0x0001, 0x2985: 0x0001,
+       0x2986: 0x0001, 0x2987: 0x0001, 0x2988: 0x0001, 0x2989: 0x0001, 0x298a: 0x0001, 0x298b: 0x0001,
+       0x298c: 0x0001, 0x298d: 0x0001, 0x298e: 0x0001, 0x298f: 0x0001, 0x2990: 0x0001, 0x2991: 0x0001,
+       0x2992: 0x0001, 0x2993: 0x0001, 0x2994: 0x0001, 0x2995: 0x0001, 0x2996: 0x0001, 0x2997: 0x0001,
+       0x2998: 0x0001, 0x2999: 0x0001, 0x299a: 0x0001, 0x299b: 0x0001, 0x299c: 0x0001, 0x299d: 0x0001,
+       0x299e: 0x0001, 0x299f: 0x0001, 0x29a0: 0x0001, 0x29a1: 0x0001, 0x29a2: 0x0001, 0x29a3: 0x0001,
+       0x29a4: 0x0001, 0x29a5: 0x0001, 0x29a6: 0x0001, 0x29a7: 0x0001, 0x29a8: 0x0001, 0x29a9: 0x0001,
+       0x29aa: 0x0001, 0x29ab: 0x0001, 0x29ac: 0x0001, 0x29ad: 0x0001, 0x29ae: 0x0001, 0x29af: 0x0001,
+       0x29b0: 0x000d, 0x29b1: 0x000d, 0x29b2: 0x000d, 0x29b3: 0x000d, 0x29b4: 0x000d, 0x29b5: 0x000d,
+       0x29b6: 0x000d, 0x29b7: 0x000d, 0x29b8: 0x000d, 0x29b9: 0x000d, 0x29ba: 0x000d, 0x29bb: 0x000d,
+       0x29bc: 0x000d, 0x29bd: 0x000d, 0x29be: 0x000d, 0x29bf: 0x000d,
+       // Block 0xa7, offset 0x29c0
+       0x29c0: 0x000d, 0x29c1: 0x000d, 0x29c2: 0x000d, 0x29c3: 0x000d, 0x29c4: 0x000d, 0x29c5: 0x000d,
+       0x29c6: 0x000c, 0x29c7: 0x000c, 0x29c8: 0x000c, 0x29c9: 0x000c, 0x29ca: 0x000c, 0x29cb: 0x000c,
+       0x29cc: 0x000c, 0x29cd: 0x000c, 0x29ce: 0x000c, 0x29cf: 0x000c, 0x29d0: 0x000c, 0x29d1: 0x000d,
+       0x29d2: 0x000d, 0x29d3: 0x000d, 0x29d4: 0x000d, 0x29d5: 0x000d, 0x29d6: 0x000d, 0x29d7: 0x000d,
+       0x29d8: 0x000d, 0x29d9: 0x000d, 0x29da: 0x000d, 0x29db: 0x000d, 0x29dc: 0x000d, 0x29dd: 0x000d,
+       0x29de: 0x000d, 0x29df: 0x000d, 0x29e0: 0x000d, 0x29e1: 0x000d, 0x29e2: 0x000d, 0x29e3: 0x000d,
+       0x29e4: 0x000d, 0x29e5: 0x000d, 0x29e6: 0x000d, 0x29e7: 0x000d, 0x29e8: 0x000d, 0x29e9: 0x000d,
+       0x29ea: 0x000d, 0x29eb: 0x000d, 0x29ec: 0x000d, 0x29ed: 0x000d, 0x29ee: 0x000d, 0x29ef: 0x000d,
+       0x29f0: 0x0001, 0x29f1: 0x0001, 0x29f2: 0x0001, 0x29f3: 0x0001, 0x29f4: 0x0001, 0x29f5: 0x0001,
+       0x29f6: 0x0001, 0x29f7: 0x0001, 0x29f8: 0x0001, 0x29f9: 0x0001, 0x29fa: 0x0001, 0x29fb: 0x0001,
+       0x29fc: 0x0001, 0x29fd: 0x0001, 0x29fe: 0x0001, 0x29ff: 0x0001,
+       // Block 0xa8, offset 0x2a00
+       0x2a01: 0x000c,
+       0x2a38: 0x000c, 0x2a39: 0x000c, 0x2a3a: 0x000c, 0x2a3b: 0x000c,
+       0x2a3c: 0x000c, 0x2a3d: 0x000c, 0x2a3e: 0x000c, 0x2a3f: 0x000c,
+       // Block 0xa9, offset 0x2a40
+       0x2a40: 0x000c, 0x2a41: 0x000c, 0x2a42: 0x000c, 0x2a43: 0x000c, 0x2a44: 0x000c, 0x2a45: 0x000c,
+       0x2a46: 0x000c,
+       0x2a52: 0x000a, 0x2a53: 0x000a, 0x2a54: 0x000a, 0x2a55: 0x000a, 0x2a56: 0x000a, 0x2a57: 0x000a,
+       0x2a58: 0x000a, 0x2a59: 0x000a, 0x2a5a: 0x000a, 0x2a5b: 0x000a, 0x2a5c: 0x000a, 0x2a5d: 0x000a,
+       0x2a5e: 0x000a, 0x2a5f: 0x000a, 0x2a60: 0x000a, 0x2a61: 0x000a, 0x2a62: 0x000a, 0x2a63: 0x000a,
+       0x2a64: 0x000a, 0x2a65: 0x000a,
+       0x2a7f: 0x000c,
+       // Block 0xaa, offset 0x2a80
+       0x2a80: 0x000c, 0x2a81: 0x000c,
+       0x2ab3: 0x000c, 0x2ab4: 0x000c, 0x2ab5: 0x000c,
+       0x2ab6: 0x000c, 0x2ab9: 0x000c, 0x2aba: 0x000c,
+       // Block 0xab, offset 0x2ac0
+       0x2ac0: 0x000c, 0x2ac1: 0x000c, 0x2ac2: 0x000c,
+       0x2ae7: 0x000c, 0x2ae8: 0x000c, 0x2ae9: 0x000c,
+       0x2aea: 0x000c, 0x2aeb: 0x000c, 0x2aed: 0x000c, 0x2aee: 0x000c, 0x2aef: 0x000c,
+       0x2af0: 0x000c, 0x2af1: 0x000c, 0x2af2: 0x000c, 0x2af3: 0x000c, 0x2af4: 0x000c,
+       // Block 0xac, offset 0x2b00
+       0x2b33: 0x000c,
+       // Block 0xad, offset 0x2b40
+       0x2b40: 0x000c, 0x2b41: 0x000c,
+       0x2b76: 0x000c, 0x2b77: 0x000c, 0x2b78: 0x000c, 0x2b79: 0x000c, 0x2b7a: 0x000c, 0x2b7b: 0x000c,
+       0x2b7c: 0x000c, 0x2b7d: 0x000c, 0x2b7e: 0x000c,
+       // Block 0xae, offset 0x2b80
+       0x2b89: 0x000c, 0x2b8a: 0x000c, 0x2b8b: 0x000c,
+       0x2b8c: 0x000c, 0x2b8f: 0x000c,
+       // Block 0xaf, offset 0x2bc0
+       0x2bef: 0x000c,
+       0x2bf0: 0x000c, 0x2bf1: 0x000c, 0x2bf4: 0x000c,
+       0x2bf6: 0x000c, 0x2bf7: 0x000c,
+       0x2bfe: 0x000c,
+       // Block 0xb0, offset 0x2c00
+       0x2c1f: 0x000c, 0x2c23: 0x000c,
+       0x2c24: 0x000c, 0x2c25: 0x000c, 0x2c26: 0x000c, 0x2c27: 0x000c, 0x2c28: 0x000c, 0x2c29: 0x000c,
+       0x2c2a: 0x000c,
+       // Block 0xb1, offset 0x2c40
+       0x2c40: 0x000c,
+       0x2c66: 0x000c, 0x2c67: 0x000c, 0x2c68: 0x000c, 0x2c69: 0x000c,
+       0x2c6a: 0x000c, 0x2c6b: 0x000c, 0x2c6c: 0x000c,
+       0x2c70: 0x000c, 0x2c71: 0x000c, 0x2c72: 0x000c, 0x2c73: 0x000c, 0x2c74: 0x000c,
+       // Block 0xb2, offset 0x2c80
+       0x2cb8: 0x000c, 0x2cb9: 0x000c, 0x2cba: 0x000c, 0x2cbb: 0x000c,
+       0x2cbc: 0x000c, 0x2cbd: 0x000c, 0x2cbe: 0x000c, 0x2cbf: 0x000c,
+       // Block 0xb3, offset 0x2cc0
+       0x2cc2: 0x000c, 0x2cc3: 0x000c, 0x2cc4: 0x000c,
+       0x2cc6: 0x000c,
+       0x2cde: 0x000c,
+       // Block 0xb4, offset 0x2d00
+       0x2d33: 0x000c, 0x2d34: 0x000c, 0x2d35: 0x000c,
+       0x2d36: 0x000c, 0x2d37: 0x000c, 0x2d38: 0x000c, 0x2d3a: 0x000c,
+       0x2d3f: 0x000c,
+       // Block 0xb5, offset 0x2d40
+       0x2d40: 0x000c, 0x2d42: 0x000c, 0x2d43: 0x000c,
+       // Block 0xb6, offset 0x2d80
+       0x2db2: 0x000c, 0x2db3: 0x000c, 0x2db4: 0x000c, 0x2db5: 0x000c,
+       0x2dbc: 0x000c, 0x2dbd: 0x000c, 0x2dbf: 0x000c,
+       // Block 0xb7, offset 0x2dc0
+       0x2dc0: 0x000c,
+       0x2ddc: 0x000c, 0x2ddd: 0x000c,
+       // Block 0xb8, offset 0x2e00
+       0x2e33: 0x000c, 0x2e34: 0x000c, 0x2e35: 0x000c,
+       0x2e36: 0x000c, 0x2e37: 0x000c, 0x2e38: 0x000c, 0x2e39: 0x000c, 0x2e3a: 0x000c,
+       0x2e3d: 0x000c, 0x2e3f: 0x000c,
+       // Block 0xb9, offset 0x2e40
+       0x2e40: 0x000c,
+       0x2e60: 0x000a, 0x2e61: 0x000a, 0x2e62: 0x000a, 0x2e63: 0x000a,
+       0x2e64: 0x000a, 0x2e65: 0x000a, 0x2e66: 0x000a, 0x2e67: 0x000a, 0x2e68: 0x000a, 0x2e69: 0x000a,
+       0x2e6a: 0x000a, 0x2e6b: 0x000a, 0x2e6c: 0x000a,
+       // Block 0xba, offset 0x2e80
+       0x2eab: 0x000c, 0x2ead: 0x000c,
+       0x2eb0: 0x000c, 0x2eb1: 0x000c, 0x2eb2: 0x000c, 0x2eb3: 0x000c, 0x2eb4: 0x000c, 0x2eb5: 0x000c,
+       0x2eb7: 0x000c,
+       // Block 0xbb, offset 0x2ec0
+       0x2edd: 0x000c,
+       0x2ede: 0x000c, 0x2edf: 0x000c, 0x2ee2: 0x000c, 0x2ee3: 0x000c,
+       0x2ee4: 0x000c, 0x2ee5: 0x000c, 0x2ee7: 0x000c, 0x2ee8: 0x000c, 0x2ee9: 0x000c,
+       0x2eea: 0x000c, 0x2eeb: 0x000c,
+       // Block 0xbc, offset 0x2f00
+       0x2f2f: 0x000c,
+       0x2f30: 0x000c, 0x2f31: 0x000c, 0x2f32: 0x000c, 0x2f33: 0x000c, 0x2f34: 0x000c, 0x2f35: 0x000c,
+       0x2f36: 0x000c, 0x2f37: 0x000c, 0x2f39: 0x000c, 0x2f3a: 0x000c,
+       // Block 0xbd, offset 0x2f40
+       0x2f7b: 0x000c,
+       0x2f7c: 0x000c, 0x2f7e: 0x000c,
+       // Block 0xbe, offset 0x2f80
+       0x2f83: 0x000c,
+       // Block 0xbf, offset 0x2fc0
+       0x2fd4: 0x000c, 0x2fd5: 0x000c, 0x2fd6: 0x000c, 0x2fd7: 0x000c,
+       0x2fda: 0x000c, 0x2fdb: 0x000c,
+       0x2fe0: 0x000c,
+       // Block 0xc0, offset 0x3000
+       0x3001: 0x000c, 0x3002: 0x000c, 0x3003: 0x000c, 0x3004: 0x000c, 0x3005: 0x000c,
+       0x3006: 0x000c, 0x3009: 0x000c, 0x300a: 0x000c,
+       0x3033: 0x000c, 0x3034: 0x000c, 0x3035: 0x000c,
+       0x3036: 0x000c, 0x3037: 0x000c, 0x3038: 0x000c, 0x303b: 0x000c,
+       0x303c: 0x000c, 0x303d: 0x000c, 0x303e: 0x000c,
+       // Block 0xc1, offset 0x3040
+       0x3047: 0x000c,
+       0x3051: 0x000c,
+       0x3052: 0x000c, 0x3053: 0x000c, 0x3054: 0x000c, 0x3055: 0x000c, 0x3056: 0x000c,
+       0x3059: 0x000c, 0x305a: 0x000c, 0x305b: 0x000c,
+       // Block 0xc2, offset 0x3080
+       0x308a: 0x000c, 0x308b: 0x000c,
+       0x308c: 0x000c, 0x308d: 0x000c, 0x308e: 0x000c, 0x308f: 0x000c, 0x3090: 0x000c, 0x3091: 0x000c,
+       0x3092: 0x000c, 0x3093: 0x000c, 0x3094: 0x000c, 0x3095: 0x000c, 0x3096: 0x000c,
+       0x3098: 0x000c, 0x3099: 0x000c,
+       // Block 0xc3, offset 0x30c0
+       0x30f0: 0x000c, 0x30f1: 0x000c, 0x30f2: 0x000c, 0x30f3: 0x000c, 0x30f4: 0x000c, 0x30f5: 0x000c,
+       0x30f6: 0x000c, 0x30f8: 0x000c, 0x30f9: 0x000c, 0x30fa: 0x000c, 0x30fb: 0x000c,
+       0x30fc: 0x000c, 0x30fd: 0x000c,
+       // Block 0xc4, offset 0x3100
+       0x3112: 0x000c, 0x3113: 0x000c, 0x3114: 0x000c, 0x3115: 0x000c, 0x3116: 0x000c, 0x3117: 0x000c,
+       0x3118: 0x000c, 0x3119: 0x000c, 0x311a: 0x000c, 0x311b: 0x000c, 0x311c: 0x000c, 0x311d: 0x000c,
+       0x311e: 0x000c, 0x311f: 0x000c, 0x3120: 0x000c, 0x3121: 0x000c, 0x3122: 0x000c, 0x3123: 0x000c,
+       0x3124: 0x000c, 0x3125: 0x000c, 0x3126: 0x000c, 0x3127: 0x000c,
+       0x312a: 0x000c, 0x312b: 0x000c, 0x312c: 0x000c, 0x312d: 0x000c, 0x312e: 0x000c, 0x312f: 0x000c,
+       0x3130: 0x000c, 0x3132: 0x000c, 0x3133: 0x000c, 0x3135: 0x000c,
+       0x3136: 0x000c,
+       // Block 0xc5, offset 0x3140
+       0x3171: 0x000c, 0x3172: 0x000c, 0x3173: 0x000c, 0x3174: 0x000c, 0x3175: 0x000c,
+       0x3176: 0x000c, 0x317a: 0x000c,
+       0x317c: 0x000c, 0x317d: 0x000c, 0x317f: 0x000c,
+       // Block 0xc6, offset 0x3180
+       0x3180: 0x000c, 0x3181: 0x000c, 0x3182: 0x000c, 0x3183: 0x000c, 0x3184: 0x000c, 0x3185: 0x000c,
+       0x3187: 0x000c,
+       // Block 0xc7, offset 0x31c0
+       0x31d0: 0x000c, 0x31d1: 0x000c,
+       0x31d5: 0x000c, 0x31d7: 0x000c,
+       // Block 0xc8, offset 0x3200
+       0x3233: 0x000c, 0x3234: 0x000c,
+       // Block 0xc9, offset 0x3240
+       0x3255: 0x000a, 0x3256: 0x000a, 0x3257: 0x000a,
+       0x3258: 0x000a, 0x3259: 0x000a, 0x325a: 0x000a, 0x325b: 0x000a, 0x325c: 0x000a, 0x325d: 0x0004,
+       0x325e: 0x0004, 0x325f: 0x0004, 0x3260: 0x0004, 0x3261: 0x000a, 0x3262: 0x000a, 0x3263: 0x000a,
+       0x3264: 0x000a, 0x3265: 0x000a, 0x3266: 0x000a, 0x3267: 0x000a, 0x3268: 0x000a, 0x3269: 0x000a,
+       0x326a: 0x000a, 0x326b: 0x000a, 0x326c: 0x000a, 0x326d: 0x000a, 0x326e: 0x000a, 0x326f: 0x000a,
+       0x3270: 0x000a, 0x3271: 0x000a,
+       // Block 0xca, offset 0x3280
+       0x32b0: 0x000c, 0x32b1: 0x000c, 0x32b2: 0x000c, 0x32b3: 0x000c, 0x32b4: 0x000c,
+       // Block 0xcb, offset 0x32c0
+       0x32f0: 0x000c, 0x32f1: 0x000c, 0x32f2: 0x000c, 0x32f3: 0x000c, 0x32f4: 0x000c, 0x32f5: 0x000c,
+       0x32f6: 0x000c,
+       // Block 0xcc, offset 0x3300
+       0x330f: 0x000c,
+       // Block 0xcd, offset 0x3340
+       0x334f: 0x000c, 0x3350: 0x000c, 0x3351: 0x000c,
+       0x3352: 0x000c,
+       // Block 0xce, offset 0x3380
+       0x33a2: 0x000a,
+       0x33a4: 0x000c,
+       // Block 0xcf, offset 0x33c0
+       0x33dd: 0x000c,
+       0x33de: 0x000c, 0x33e0: 0x000b, 0x33e1: 0x000b, 0x33e2: 0x000b, 0x33e3: 0x000b,
+       // Block 0xd0, offset 0x3400
+       0x3427: 0x000c, 0x3428: 0x000c, 0x3429: 0x000c,
+       0x3433: 0x000b, 0x3434: 0x000b, 0x3435: 0x000b,
+       0x3436: 0x000b, 0x3437: 0x000b, 0x3438: 0x000b, 0x3439: 0x000b, 0x343a: 0x000b, 0x343b: 0x000c,
+       0x343c: 0x000c, 0x343d: 0x000c, 0x343e: 0x000c, 0x343f: 0x000c,
+       // Block 0xd1, offset 0x3440
+       0x3440: 0x000c, 0x3441: 0x000c, 0x3442: 0x000c, 0x3445: 0x000c,
+       0x3446: 0x000c, 0x3447: 0x000c, 0x3448: 0x000c, 0x3449: 0x000c, 0x344a: 0x000c, 0x344b: 0x000c,
+       0x346a: 0x000c, 0x346b: 0x000c, 0x346c: 0x000c, 0x346d: 0x000c,
+       // Block 0xd2, offset 0x3480
+       0x3480: 0x000a, 0x3481: 0x000a, 0x3482: 0x000c, 0x3483: 0x000c, 0x3484: 0x000c, 0x3485: 0x000a,
+       // Block 0xd3, offset 0x34c0
+       0x34c0: 0x000a, 0x34c1: 0x000a, 0x34c2: 0x000a, 0x34c3: 0x000a, 0x34c4: 0x000a, 0x34c5: 0x000a,
+       0x34c6: 0x000a, 0x34c7: 0x000a, 0x34c8: 0x000a, 0x34c9: 0x000a, 0x34ca: 0x000a, 0x34cb: 0x000a,
+       0x34cc: 0x000a, 0x34cd: 0x000a, 0x34ce: 0x000a, 0x34cf: 0x000a, 0x34d0: 0x000a, 0x34d1: 0x000a,
+       0x34d2: 0x000a, 0x34d3: 0x000a, 0x34d4: 0x000a, 0x34d5: 0x000a, 0x34d6: 0x000a,
+       // Block 0xd4, offset 0x3500
+       0x351b: 0x000a,
+       // Block 0xd5, offset 0x3540
+       0x3555: 0x000a,
+       // Block 0xd6, offset 0x3580
+       0x358f: 0x000a,
+       // Block 0xd7, offset 0x35c0
+       0x35c9: 0x000a,
+       // Block 0xd8, offset 0x3600
+       0x3603: 0x000a,
+       0x360e: 0x0002, 0x360f: 0x0002, 0x3610: 0x0002, 0x3611: 0x0002,
+       0x3612: 0x0002, 0x3613: 0x0002, 0x3614: 0x0002, 0x3615: 0x0002, 0x3616: 0x0002, 0x3617: 0x0002,
+       0x3618: 0x0002, 0x3619: 0x0002, 0x361a: 0x0002, 0x361b: 0x0002, 0x361c: 0x0002, 0x361d: 0x0002,
+       0x361e: 0x0002, 0x361f: 0x0002, 0x3620: 0x0002, 0x3621: 0x0002, 0x3622: 0x0002, 0x3623: 0x0002,
+       0x3624: 0x0002, 0x3625: 0x0002, 0x3626: 0x0002, 0x3627: 0x0002, 0x3628: 0x0002, 0x3629: 0x0002,
+       0x362a: 0x0002, 0x362b: 0x0002, 0x362c: 0x0002, 0x362d: 0x0002, 0x362e: 0x0002, 0x362f: 0x0002,
+       0x3630: 0x0002, 0x3631: 0x0002, 0x3632: 0x0002, 0x3633: 0x0002, 0x3634: 0x0002, 0x3635: 0x0002,
+       0x3636: 0x0002, 0x3637: 0x0002, 0x3638: 0x0002, 0x3639: 0x0002, 0x363a: 0x0002, 0x363b: 0x0002,
+       0x363c: 0x0002, 0x363d: 0x0002, 0x363e: 0x0002, 0x363f: 0x0002,
+       // Block 0xd9, offset 0x3640
+       0x3640: 0x000c, 0x3641: 0x000c, 0x3642: 0x000c, 0x3643: 0x000c, 0x3644: 0x000c, 0x3645: 0x000c,
+       0x3646: 0x000c, 0x3647: 0x000c, 0x3648: 0x000c, 0x3649: 0x000c, 0x364a: 0x000c, 0x364b: 0x000c,
+       0x364c: 0x000c, 0x364d: 0x000c, 0x364e: 0x000c, 0x364f: 0x000c, 0x3650: 0x000c, 0x3651: 0x000c,
+       0x3652: 0x000c, 0x3653: 0x000c, 0x3654: 0x000c, 0x3655: 0x000c, 0x3656: 0x000c, 0x3657: 0x000c,
+       0x3658: 0x000c, 0x3659: 0x000c, 0x365a: 0x000c, 0x365b: 0x000c, 0x365c: 0x000c, 0x365d: 0x000c,
+       0x365e: 0x000c, 0x365f: 0x000c, 0x3660: 0x000c, 0x3661: 0x000c, 0x3662: 0x000c, 0x3663: 0x000c,
+       0x3664: 0x000c, 0x3665: 0x000c, 0x3666: 0x000c, 0x3667: 0x000c, 0x3668: 0x000c, 0x3669: 0x000c,
+       0x366a: 0x000c, 0x366b: 0x000c, 0x366c: 0x000c, 0x366d: 0x000c, 0x366e: 0x000c, 0x366f: 0x000c,
+       0x3670: 0x000c, 0x3671: 0x000c, 0x3672: 0x000c, 0x3673: 0x000c, 0x3674: 0x000c, 0x3675: 0x000c,
+       0x3676: 0x000c, 0x367b: 0x000c,
+       0x367c: 0x000c, 0x367d: 0x000c, 0x367e: 0x000c, 0x367f: 0x000c,
+       // Block 0xda, offset 0x3680
+       0x3680: 0x000c, 0x3681: 0x000c, 0x3682: 0x000c, 0x3683: 0x000c, 0x3684: 0x000c, 0x3685: 0x000c,
+       0x3686: 0x000c, 0x3687: 0x000c, 0x3688: 0x000c, 0x3689: 0x000c, 0x368a: 0x000c, 0x368b: 0x000c,
+       0x368c: 0x000c, 0x368d: 0x000c, 0x368e: 0x000c, 0x368f: 0x000c, 0x3690: 0x000c, 0x3691: 0x000c,
+       0x3692: 0x000c, 0x3693: 0x000c, 0x3694: 0x000c, 0x3695: 0x000c, 0x3696: 0x000c, 0x3697: 0x000c,
+       0x3698: 0x000c, 0x3699: 0x000c, 0x369a: 0x000c, 0x369b: 0x000c, 0x369c: 0x000c, 0x369d: 0x000c,
+       0x369e: 0x000c, 0x369f: 0x000c, 0x36a0: 0x000c, 0x36a1: 0x000c, 0x36a2: 0x000c, 0x36a3: 0x000c,
+       0x36a4: 0x000c, 0x36a5: 0x000c, 0x36a6: 0x000c, 0x36a7: 0x000c, 0x36a8: 0x000c, 0x36a9: 0x000c,
+       0x36aa: 0x000c, 0x36ab: 0x000c, 0x36ac: 0x000c,
+       0x36b5: 0x000c,
+       // Block 0xdb, offset 0x36c0
+       0x36c4: 0x000c,
+       0x36db: 0x000c, 0x36dc: 0x000c, 0x36dd: 0x000c,
+       0x36de: 0x000c, 0x36df: 0x000c, 0x36e1: 0x000c, 0x36e2: 0x000c, 0x36e3: 0x000c,
+       0x36e4: 0x000c, 0x36e5: 0x000c, 0x36e6: 0x000c, 0x36e7: 0x000c, 0x36e8: 0x000c, 0x36e9: 0x000c,
+       0x36ea: 0x000c, 0x36eb: 0x000c, 0x36ec: 0x000c, 0x36ed: 0x000c, 0x36ee: 0x000c, 0x36ef: 0x000c,
+       // Block 0xdc, offset 0x3700
+       0x3700: 0x000c, 0x3701: 0x000c, 0x3702: 0x000c, 0x3703: 0x000c, 0x3704: 0x000c, 0x3705: 0x000c,
+       0x3706: 0x000c, 0x3708: 0x000c, 0x3709: 0x000c, 0x370a: 0x000c, 0x370b: 0x000c,
+       0x370c: 0x000c, 0x370d: 0x000c, 0x370e: 0x000c, 0x370f: 0x000c, 0x3710: 0x000c, 0x3711: 0x000c,
+       0x3712: 0x000c, 0x3713: 0x000c, 0x3714: 0x000c, 0x3715: 0x000c, 0x3716: 0x000c, 0x3717: 0x000c,
+       0x3718: 0x000c, 0x371b: 0x000c, 0x371c: 0x000c, 0x371d: 0x000c,
+       0x371e: 0x000c, 0x371f: 0x000c, 0x3720: 0x000c, 0x3721: 0x000c, 0x3723: 0x000c,
+       0x3724: 0x000c, 0x3726: 0x000c, 0x3727: 0x000c, 0x3728: 0x000c, 0x3729: 0x000c,
+       0x372a: 0x000c,
+       // Block 0xdd, offset 0x3740
+       0x376c: 0x000c, 0x376d: 0x000c, 0x376e: 0x000c, 0x376f: 0x000c,
+       0x377f: 0x0004,
+       // Block 0xde, offset 0x3780
+       0x3780: 0x0001, 0x3781: 0x0001, 0x3782: 0x0001, 0x3783: 0x0001, 0x3784: 0x0001, 0x3785: 0x0001,
+       0x3786: 0x0001, 0x3787: 0x0001, 0x3788: 0x0001, 0x3789: 0x0001, 0x378a: 0x0001, 0x378b: 0x0001,
+       0x378c: 0x0001, 0x378d: 0x0001, 0x378e: 0x0001, 0x378f: 0x0001, 0x3790: 0x000c, 0x3791: 0x000c,
+       0x3792: 0x000c, 0x3793: 0x000c, 0x3794: 0x000c, 0x3795: 0x000c, 0x3796: 0x000c, 0x3797: 0x0001,
+       0x3798: 0x0001, 0x3799: 0x0001, 0x379a: 0x0001, 0x379b: 0x0001, 0x379c: 0x0001, 0x379d: 0x0001,
+       0x379e: 0x0001, 0x379f: 0x0001, 0x37a0: 0x0001, 0x37a1: 0x0001, 0x37a2: 0x0001, 0x37a3: 0x0001,
+       0x37a4: 0x0001, 0x37a5: 0x0001, 0x37a6: 0x0001, 0x37a7: 0x0001, 0x37a8: 0x0001, 0x37a9: 0x0001,
+       0x37aa: 0x0001, 0x37ab: 0x0001, 0x37ac: 0x0001, 0x37ad: 0x0001, 0x37ae: 0x0001, 0x37af: 0x0001,
+       0x37b0: 0x0001, 0x37b1: 0x0001, 0x37b2: 0x0001, 0x37b3: 0x0001, 0x37b4: 0x0001, 0x37b5: 0x0001,
+       0x37b6: 0x0001, 0x37b7: 0x0001, 0x37b8: 0x0001, 0x37b9: 0x0001, 0x37ba: 0x0001, 0x37bb: 0x0001,
+       0x37bc: 0x0001, 0x37bd: 0x0001, 0x37be: 0x0001, 0x37bf: 0x0001,
+       // Block 0xdf, offset 0x37c0
+       0x37c0: 0x0001, 0x37c1: 0x0001, 0x37c2: 0x0001, 0x37c3: 0x0001, 0x37c4: 0x000c, 0x37c5: 0x000c,
+       0x37c6: 0x000c, 0x37c7: 0x000c, 0x37c8: 0x000c, 0x37c9: 0x000c, 0x37ca: 0x000c, 0x37cb: 0x0001,
+       0x37cc: 0x0001, 0x37cd: 0x0001, 0x37ce: 0x0001, 0x37cf: 0x0001, 0x37d0: 0x0001, 0x37d1: 0x0001,
+       0x37d2: 0x0001, 0x37d3: 0x0001, 0x37d4: 0x0001, 0x37d5: 0x0001, 0x37d6: 0x0001, 0x37d7: 0x0001,
+       0x37d8: 0x0001, 0x37d9: 0x0001, 0x37da: 0x0001, 0x37db: 0x0001, 0x37dc: 0x0001, 0x37dd: 0x0001,
+       0x37de: 0x0001, 0x37df: 0x0001, 0x37e0: 0x0001, 0x37e1: 0x0001, 0x37e2: 0x0001, 0x37e3: 0x0001,
+       0x37e4: 0x0001, 0x37e5: 0x0001, 0x37e6: 0x0001, 0x37e7: 0x0001, 0x37e8: 0x0001, 0x37e9: 0x0001,
+       0x37ea: 0x0001, 0x37eb: 0x0001, 0x37ec: 0x0001, 0x37ed: 0x0001, 0x37ee: 0x0001, 0x37ef: 0x0001,
+       0x37f0: 0x0001, 0x37f1: 0x0001, 0x37f2: 0x0001, 0x37f3: 0x0001, 0x37f4: 0x0001, 0x37f5: 0x0001,
+       0x37f6: 0x0001, 0x37f7: 0x0001, 0x37f8: 0x0001, 0x37f9: 0x0001, 0x37fa: 0x0001, 0x37fb: 0x0001,
+       0x37fc: 0x0001, 0x37fd: 0x0001, 0x37fe: 0x0001, 0x37ff: 0x0001,
+       // Block 0xe0, offset 0x3800
+       0x3800: 0x000d, 0x3801: 0x000d, 0x3802: 0x000d, 0x3803: 0x000d, 0x3804: 0x000d, 0x3805: 0x000d,
+       0x3806: 0x000d, 0x3807: 0x000d, 0x3808: 0x000d, 0x3809: 0x000d, 0x380a: 0x000d, 0x380b: 0x000d,
+       0x380c: 0x000d, 0x380d: 0x000d, 0x380e: 0x000d, 0x380f: 0x000d, 0x3810: 0x0001, 0x3811: 0x0001,
+       0x3812: 0x0001, 0x3813: 0x0001, 0x3814: 0x0001, 0x3815: 0x0001, 0x3816: 0x0001, 0x3817: 0x0001,
+       0x3818: 0x0001, 0x3819: 0x0001, 0x381a: 0x0001, 0x381b: 0x0001, 0x381c: 0x0001, 0x381d: 0x0001,
+       0x381e: 0x0001, 0x381f: 0x0001, 0x3820: 0x0001, 0x3821: 0x0001, 0x3822: 0x0001, 0x3823: 0x0001,
+       0x3824: 0x0001, 0x3825: 0x0001, 0x3826: 0x0001, 0x3827: 0x0001, 0x3828: 0x0001, 0x3829: 0x0001,
+       0x382a: 0x0001, 0x382b: 0x0001, 0x382c: 0x0001, 0x382d: 0x0001, 0x382e: 0x0001, 0x382f: 0x0001,
+       0x3830: 0x0001, 0x3831: 0x0001, 0x3832: 0x0001, 0x3833: 0x0001, 0x3834: 0x0001, 0x3835: 0x0001,
+       0x3836: 0x0001, 0x3837: 0x0001, 0x3838: 0x0001, 0x3839: 0x0001, 0x383a: 0x0001, 0x383b: 0x0001,
+       0x383c: 0x0001, 0x383d: 0x0001, 0x383e: 0x0001, 0x383f: 0x0001,
+       // Block 0xe1, offset 0x3840
+       0x3840: 0x000d, 0x3841: 0x000d, 0x3842: 0x000d, 0x3843: 0x000d, 0x3844: 0x000d, 0x3845: 0x000d,
+       0x3846: 0x000d, 0x3847: 0x000d, 0x3848: 0x000d, 0x3849: 0x000d, 0x384a: 0x000d, 0x384b: 0x000d,
+       0x384c: 0x000d, 0x384d: 0x000d, 0x384e: 0x000d, 0x384f: 0x000d, 0x3850: 0x000d, 0x3851: 0x000d,
+       0x3852: 0x000d, 0x3853: 0x000d, 0x3854: 0x000d, 0x3855: 0x000d, 0x3856: 0x000d, 0x3857: 0x000d,
+       0x3858: 0x000d, 0x3859: 0x000d, 0x385a: 0x000d, 0x385b: 0x000d, 0x385c: 0x000d, 0x385d: 0x000d,
+       0x385e: 0x000d, 0x385f: 0x000d, 0x3860: 0x000d, 0x3861: 0x000d, 0x3862: 0x000d, 0x3863: 0x000d,
+       0x3864: 0x000d, 0x3865: 0x000d, 0x3866: 0x000d, 0x3867: 0x000d, 0x3868: 0x000d, 0x3869: 0x000d,
+       0x386a: 0x000d, 0x386b: 0x000d, 0x386c: 0x000d, 0x386d: 0x000d, 0x386e: 0x000d, 0x386f: 0x000d,
+       0x3870: 0x000a, 0x3871: 0x000a, 0x3872: 0x000d, 0x3873: 0x000d, 0x3874: 0x000d, 0x3875: 0x000d,
+       0x3876: 0x000d, 0x3877: 0x000d, 0x3878: 0x000d, 0x3879: 0x000d, 0x387a: 0x000d, 0x387b: 0x000d,
+       0x387c: 0x000d, 0x387d: 0x000d, 0x387e: 0x000d, 0x387f: 0x000d,
+       // Block 0xe2, offset 0x3880
+       0x3880: 0x000a, 0x3881: 0x000a, 0x3882: 0x000a, 0x3883: 0x000a, 0x3884: 0x000a, 0x3885: 0x000a,
+       0x3886: 0x000a, 0x3887: 0x000a, 0x3888: 0x000a, 0x3889: 0x000a, 0x388a: 0x000a, 0x388b: 0x000a,
+       0x388c: 0x000a, 0x388d: 0x000a, 0x388e: 0x000a, 0x388f: 0x000a, 0x3890: 0x000a, 0x3891: 0x000a,
+       0x3892: 0x000a, 0x3893: 0x000a, 0x3894: 0x000a, 0x3895: 0x000a, 0x3896: 0x000a, 0x3897: 0x000a,
+       0x3898: 0x000a, 0x3899: 0x000a, 0x389a: 0x000a, 0x389b: 0x000a, 0x389c: 0x000a, 0x389d: 0x000a,
+       0x389e: 0x000a, 0x389f: 0x000a, 0x38a0: 0x000a, 0x38a1: 0x000a, 0x38a2: 0x000a, 0x38a3: 0x000a,
+       0x38a4: 0x000a, 0x38a5: 0x000a, 0x38a6: 0x000a, 0x38a7: 0x000a, 0x38a8: 0x000a, 0x38a9: 0x000a,
+       0x38aa: 0x000a, 0x38ab: 0x000a,
+       0x38b0: 0x000a, 0x38b1: 0x000a, 0x38b2: 0x000a, 0x38b3: 0x000a, 0x38b4: 0x000a, 0x38b5: 0x000a,
+       0x38b6: 0x000a, 0x38b7: 0x000a, 0x38b8: 0x000a, 0x38b9: 0x000a, 0x38ba: 0x000a, 0x38bb: 0x000a,
+       0x38bc: 0x000a, 0x38bd: 0x000a, 0x38be: 0x000a, 0x38bf: 0x000a,
+       // Block 0xe3, offset 0x38c0
+       0x38c0: 0x000a, 0x38c1: 0x000a, 0x38c2: 0x000a, 0x38c3: 0x000a, 0x38c4: 0x000a, 0x38c5: 0x000a,
+       0x38c6: 0x000a, 0x38c7: 0x000a, 0x38c8: 0x000a, 0x38c9: 0x000a, 0x38ca: 0x000a, 0x38cb: 0x000a,
+       0x38cc: 0x000a, 0x38cd: 0x000a, 0x38ce: 0x000a, 0x38cf: 0x000a, 0x38d0: 0x000a, 0x38d1: 0x000a,
+       0x38d2: 0x000a, 0x38d3: 0x000a,
+       0x38e0: 0x000a, 0x38e1: 0x000a, 0x38e2: 0x000a, 0x38e3: 0x000a,
+       0x38e4: 0x000a, 0x38e5: 0x000a, 0x38e6: 0x000a, 0x38e7: 0x000a, 0x38e8: 0x000a, 0x38e9: 0x000a,
+       0x38ea: 0x000a, 0x38eb: 0x000a, 0x38ec: 0x000a, 0x38ed: 0x000a, 0x38ee: 0x000a,
+       0x38f1: 0x000a, 0x38f2: 0x000a, 0x38f3: 0x000a, 0x38f4: 0x000a, 0x38f5: 0x000a,
+       0x38f6: 0x000a, 0x38f7: 0x000a, 0x38f8: 0x000a, 0x38f9: 0x000a, 0x38fa: 0x000a, 0x38fb: 0x000a,
+       0x38fc: 0x000a, 0x38fd: 0x000a, 0x38fe: 0x000a, 0x38ff: 0x000a,
+       // Block 0xe4, offset 0x3900
+       0x3901: 0x000a, 0x3902: 0x000a, 0x3903: 0x000a, 0x3904: 0x000a, 0x3905: 0x000a,
+       0x3906: 0x000a, 0x3907: 0x000a, 0x3908: 0x000a, 0x3909: 0x000a, 0x390a: 0x000a, 0x390b: 0x000a,
+       0x390c: 0x000a, 0x390d: 0x000a, 0x390e: 0x000a, 0x390f: 0x000a, 0x3911: 0x000a,
+       0x3912: 0x000a, 0x3913: 0x000a, 0x3914: 0x000a, 0x3915: 0x000a, 0x3916: 0x000a, 0x3917: 0x000a,
+       0x3918: 0x000a, 0x3919: 0x000a, 0x391a: 0x000a, 0x391b: 0x000a, 0x391c: 0x000a, 0x391d: 0x000a,
+       0x391e: 0x000a, 0x391f: 0x000a, 0x3920: 0x000a, 0x3921: 0x000a, 0x3922: 0x000a, 0x3923: 0x000a,
+       0x3924: 0x000a, 0x3925: 0x000a, 0x3926: 0x000a, 0x3927: 0x000a, 0x3928: 0x000a, 0x3929: 0x000a,
+       0x392a: 0x000a, 0x392b: 0x000a, 0x392c: 0x000a, 0x392d: 0x000a, 0x392e: 0x000a, 0x392f: 0x000a,
+       0x3930: 0x000a, 0x3931: 0x000a, 0x3932: 0x000a, 0x3933: 0x000a, 0x3934: 0x000a, 0x3935: 0x000a,
+       // Block 0xe5, offset 0x3940
+       0x3940: 0x0002, 0x3941: 0x0002, 0x3942: 0x0002, 0x3943: 0x0002, 0x3944: 0x0002, 0x3945: 0x0002,
+       0x3946: 0x0002, 0x3947: 0x0002, 0x3948: 0x0002, 0x3949: 0x0002, 0x394a: 0x0002, 0x394b: 0x000a,
+       0x394c: 0x000a, 0x394d: 0x000a, 0x394e: 0x000a, 0x394f: 0x000a,
+       0x396f: 0x000a,
+       // Block 0xe6, offset 0x3980
+       0x39aa: 0x000a, 0x39ab: 0x000a, 0x39ac: 0x000a, 0x39ad: 0x000a, 0x39ae: 0x000a, 0x39af: 0x000a,
+       // Block 0xe7, offset 0x39c0
+       0x39ed: 0x000a,
+       // Block 0xe8, offset 0x3a00
+       0x3a20: 0x000a, 0x3a21: 0x000a, 0x3a22: 0x000a, 0x3a23: 0x000a,
+       0x3a24: 0x000a, 0x3a25: 0x000a,
+       // Block 0xe9, offset 0x3a40
+       0x3a40: 0x000a, 0x3a41: 0x000a, 0x3a42: 0x000a, 0x3a43: 0x000a, 0x3a44: 0x000a, 0x3a45: 0x000a,
+       0x3a46: 0x000a, 0x3a47: 0x000a, 0x3a48: 0x000a, 0x3a49: 0x000a, 0x3a4a: 0x000a, 0x3a4b: 0x000a,
+       0x3a4c: 0x000a, 0x3a4d: 0x000a, 0x3a4e: 0x000a, 0x3a4f: 0x000a, 0x3a50: 0x000a, 0x3a51: 0x000a,
+       0x3a52: 0x000a, 0x3a53: 0x000a, 0x3a54: 0x000a, 0x3a55: 0x000a, 0x3a56: 0x000a, 0x3a57: 0x000a,
+       0x3a60: 0x000a, 0x3a61: 0x000a, 0x3a62: 0x000a, 0x3a63: 0x000a,
+       0x3a64: 0x000a, 0x3a65: 0x000a, 0x3a66: 0x000a, 0x3a67: 0x000a, 0x3a68: 0x000a, 0x3a69: 0x000a,
+       0x3a6a: 0x000a, 0x3a6b: 0x000a, 0x3a6c: 0x000a,
+       0x3a70: 0x000a, 0x3a71: 0x000a, 0x3a72: 0x000a, 0x3a73: 0x000a, 0x3a74: 0x000a, 0x3a75: 0x000a,
+       0x3a76: 0x000a, 0x3a77: 0x000a, 0x3a78: 0x000a, 0x3a79: 0x000a, 0x3a7a: 0x000a, 0x3a7b: 0x000a,
+       0x3a7c: 0x000a,
+       // Block 0xea, offset 0x3a80
+       0x3a80: 0x000a, 0x3a81: 0x000a, 0x3a82: 0x000a, 0x3a83: 0x000a, 0x3a84: 0x000a, 0x3a85: 0x000a,
+       0x3a86: 0x000a, 0x3a87: 0x000a, 0x3a88: 0x000a, 0x3a89: 0x000a, 0x3a8a: 0x000a, 0x3a8b: 0x000a,
+       0x3a8c: 0x000a, 0x3a8d: 0x000a, 0x3a8e: 0x000a, 0x3a8f: 0x000a, 0x3a90: 0x000a, 0x3a91: 0x000a,
+       0x3a92: 0x000a, 0x3a93: 0x000a, 0x3a94: 0x000a, 0x3a95: 0x000a, 0x3a96: 0x000a, 0x3a97: 0x000a,
+       0x3a98: 0x000a,
+       0x3aa0: 0x000a, 0x3aa1: 0x000a, 0x3aa2: 0x000a, 0x3aa3: 0x000a,
+       0x3aa4: 0x000a, 0x3aa5: 0x000a, 0x3aa6: 0x000a, 0x3aa7: 0x000a, 0x3aa8: 0x000a, 0x3aa9: 0x000a,
+       0x3aaa: 0x000a, 0x3aab: 0x000a,
+       // Block 0xeb, offset 0x3ac0
+       0x3ac0: 0x000a, 0x3ac1: 0x000a, 0x3ac2: 0x000a, 0x3ac3: 0x000a, 0x3ac4: 0x000a, 0x3ac5: 0x000a,
+       0x3ac6: 0x000a, 0x3ac7: 0x000a, 0x3ac8: 0x000a, 0x3ac9: 0x000a, 0x3aca: 0x000a, 0x3acb: 0x000a,
+       0x3ad0: 0x000a, 0x3ad1: 0x000a,
+       0x3ad2: 0x000a, 0x3ad3: 0x000a, 0x3ad4: 0x000a, 0x3ad5: 0x000a, 0x3ad6: 0x000a, 0x3ad7: 0x000a,
+       0x3ad8: 0x000a, 0x3ad9: 0x000a, 0x3ada: 0x000a, 0x3adb: 0x000a, 0x3adc: 0x000a, 0x3add: 0x000a,
+       0x3ade: 0x000a, 0x3adf: 0x000a, 0x3ae0: 0x000a, 0x3ae1: 0x000a, 0x3ae2: 0x000a, 0x3ae3: 0x000a,
+       0x3ae4: 0x000a, 0x3ae5: 0x000a, 0x3ae6: 0x000a, 0x3ae7: 0x000a, 0x3ae8: 0x000a, 0x3ae9: 0x000a,
+       0x3aea: 0x000a, 0x3aeb: 0x000a, 0x3aec: 0x000a, 0x3aed: 0x000a, 0x3aee: 0x000a, 0x3aef: 0x000a,
+       0x3af0: 0x000a, 0x3af1: 0x000a, 0x3af2: 0x000a, 0x3af3: 0x000a, 0x3af4: 0x000a, 0x3af5: 0x000a,
+       0x3af6: 0x000a, 0x3af7: 0x000a, 0x3af8: 0x000a, 0x3af9: 0x000a, 0x3afa: 0x000a, 0x3afb: 0x000a,
+       0x3afc: 0x000a, 0x3afd: 0x000a, 0x3afe: 0x000a, 0x3aff: 0x000a,
+       // Block 0xec, offset 0x3b00
+       0x3b00: 0x000a, 0x3b01: 0x000a, 0x3b02: 0x000a, 0x3b03: 0x000a, 0x3b04: 0x000a, 0x3b05: 0x000a,
+       0x3b06: 0x000a, 0x3b07: 0x000a,
+       0x3b10: 0x000a, 0x3b11: 0x000a,
+       0x3b12: 0x000a, 0x3b13: 0x000a, 0x3b14: 0x000a, 0x3b15: 0x000a, 0x3b16: 0x000a, 0x3b17: 0x000a,
+       0x3b18: 0x000a, 0x3b19: 0x000a,
+       0x3b20: 0x000a, 0x3b21: 0x000a, 0x3b22: 0x000a, 0x3b23: 0x000a,
+       0x3b24: 0x000a, 0x3b25: 0x000a, 0x3b26: 0x000a, 0x3b27: 0x000a, 0x3b28: 0x000a, 0x3b29: 0x000a,
+       0x3b2a: 0x000a, 0x3b2b: 0x000a, 0x3b2c: 0x000a, 0x3b2d: 0x000a, 0x3b2e: 0x000a, 0x3b2f: 0x000a,
+       0x3b30: 0x000a, 0x3b31: 0x000a, 0x3b32: 0x000a, 0x3b33: 0x000a, 0x3b34: 0x000a, 0x3b35: 0x000a,
+       0x3b36: 0x000a, 0x3b37: 0x000a, 0x3b38: 0x000a, 0x3b39: 0x000a, 0x3b3a: 0x000a, 0x3b3b: 0x000a,
+       0x3b3c: 0x000a, 0x3b3d: 0x000a, 0x3b3e: 0x000a, 0x3b3f: 0x000a,
+       // Block 0xed, offset 0x3b40
+       0x3b40: 0x000a, 0x3b41: 0x000a, 0x3b42: 0x000a, 0x3b43: 0x000a, 0x3b44: 0x000a, 0x3b45: 0x000a,
+       0x3b46: 0x000a, 0x3b47: 0x000a,
+       0x3b50: 0x000a, 0x3b51: 0x000a,
+       0x3b52: 0x000a, 0x3b53: 0x000a, 0x3b54: 0x000a, 0x3b55: 0x000a, 0x3b56: 0x000a, 0x3b57: 0x000a,
+       0x3b58: 0x000a, 0x3b59: 0x000a, 0x3b5a: 0x000a, 0x3b5b: 0x000a, 0x3b5c: 0x000a, 0x3b5d: 0x000a,
+       0x3b5e: 0x000a, 0x3b5f: 0x000a, 0x3b60: 0x000a, 0x3b61: 0x000a, 0x3b62: 0x000a, 0x3b63: 0x000a,
+       0x3b64: 0x000a, 0x3b65: 0x000a, 0x3b66: 0x000a, 0x3b67: 0x000a, 0x3b68: 0x000a, 0x3b69: 0x000a,
+       0x3b6a: 0x000a, 0x3b6b: 0x000a, 0x3b6c: 0x000a, 0x3b6d: 0x000a,
+       0x3b70: 0x000a, 0x3b71: 0x000a,
+       // Block 0xee, offset 0x3b80
+       0x3b80: 0x000a, 0x3b81: 0x000a, 0x3b82: 0x000a, 0x3b83: 0x000a, 0x3b84: 0x000a, 0x3b85: 0x000a,
+       0x3b86: 0x000a, 0x3b87: 0x000a, 0x3b88: 0x000a, 0x3b89: 0x000a, 0x3b8a: 0x000a, 0x3b8b: 0x000a,
+       0x3b8c: 0x000a, 0x3b8d: 0x000a, 0x3b8e: 0x000a, 0x3b8f: 0x000a, 0x3b90: 0x000a, 0x3b91: 0x000a,
+       0x3b92: 0x000a, 0x3b93: 0x000a, 0x3b94: 0x000a, 0x3b95: 0x000a, 0x3b96: 0x000a, 0x3b97: 0x000a,
+       0x3b98: 0x000a, 0x3b99: 0x000a, 0x3b9a: 0x000a, 0x3b9b: 0x000a, 0x3b9c: 0x000a, 0x3b9d: 0x000a,
+       0x3b9e: 0x000a, 0x3b9f: 0x000a, 0x3ba0: 0x000a, 0x3ba1: 0x000a, 0x3ba2: 0x000a, 0x3ba3: 0x000a,
+       0x3ba4: 0x000a, 0x3ba5: 0x000a, 0x3ba6: 0x000a, 0x3ba7: 0x000a, 0x3ba8: 0x000a, 0x3ba9: 0x000a,
+       0x3baa: 0x000a, 0x3bab: 0x000a, 0x3bac: 0x000a, 0x3bad: 0x000a, 0x3bae: 0x000a, 0x3baf: 0x000a,
+       0x3bb0: 0x000a, 0x3bb1: 0x000a, 0x3bb2: 0x000a, 0x3bb3: 0x000a, 0x3bb4: 0x000a, 0x3bb5: 0x000a,
+       0x3bb6: 0x000a, 0x3bb7: 0x000a, 0x3bb8: 0x000a, 0x3bba: 0x000a, 0x3bbb: 0x000a,
+       0x3bbc: 0x000a, 0x3bbd: 0x000a, 0x3bbe: 0x000a, 0x3bbf: 0x000a,
+       // Block 0xef, offset 0x3bc0
+       0x3bc0: 0x000a, 0x3bc1: 0x000a, 0x3bc2: 0x000a, 0x3bc3: 0x000a, 0x3bc4: 0x000a, 0x3bc5: 0x000a,
+       0x3bc6: 0x000a, 0x3bc7: 0x000a, 0x3bc8: 0x000a, 0x3bc9: 0x000a, 0x3bca: 0x000a, 0x3bcb: 0x000a,
+       0x3bcd: 0x000a, 0x3bce: 0x000a, 0x3bcf: 0x000a, 0x3bd0: 0x000a, 0x3bd1: 0x000a,
+       0x3bd2: 0x000a, 0x3bd3: 0x000a, 0x3bd4: 0x000a, 0x3bd5: 0x000a, 0x3bd6: 0x000a, 0x3bd7: 0x000a,
+       0x3bd8: 0x000a, 0x3bd9: 0x000a, 0x3bda: 0x000a, 0x3bdb: 0x000a, 0x3bdc: 0x000a, 0x3bdd: 0x000a,
+       0x3bde: 0x000a, 0x3bdf: 0x000a, 0x3be0: 0x000a, 0x3be1: 0x000a, 0x3be2: 0x000a, 0x3be3: 0x000a,
+       0x3be4: 0x000a, 0x3be5: 0x000a, 0x3be6: 0x000a, 0x3be7: 0x000a, 0x3be8: 0x000a, 0x3be9: 0x000a,
+       0x3bea: 0x000a, 0x3beb: 0x000a, 0x3bec: 0x000a, 0x3bed: 0x000a, 0x3bee: 0x000a, 0x3bef: 0x000a,
+       0x3bf0: 0x000a, 0x3bf1: 0x000a, 0x3bf2: 0x000a, 0x3bf3: 0x000a, 0x3bf4: 0x000a, 0x3bf5: 0x000a,
+       0x3bf6: 0x000a, 0x3bf7: 0x000a, 0x3bf8: 0x000a, 0x3bf9: 0x000a, 0x3bfa: 0x000a, 0x3bfb: 0x000a,
+       0x3bfc: 0x000a, 0x3bfd: 0x000a, 0x3bfe: 0x000a, 0x3bff: 0x000a,
+       // Block 0xf0, offset 0x3c00
+       0x3c00: 0x000a, 0x3c01: 0x000a, 0x3c02: 0x000a, 0x3c03: 0x000a, 0x3c04: 0x000a, 0x3c05: 0x000a,
+       0x3c06: 0x000a, 0x3c07: 0x000a, 0x3c08: 0x000a, 0x3c09: 0x000a, 0x3c0a: 0x000a, 0x3c0b: 0x000a,
+       0x3c0c: 0x000a, 0x3c0d: 0x000a, 0x3c0e: 0x000a, 0x3c0f: 0x000a, 0x3c10: 0x000a, 0x3c11: 0x000a,
+       0x3c12: 0x000a, 0x3c13: 0x000a,
+       0x3c20: 0x000a, 0x3c21: 0x000a, 0x3c22: 0x000a, 0x3c23: 0x000a,
+       0x3c24: 0x000a, 0x3c25: 0x000a, 0x3c26: 0x000a, 0x3c27: 0x000a, 0x3c28: 0x000a, 0x3c29: 0x000a,
+       0x3c2a: 0x000a, 0x3c2b: 0x000a, 0x3c2c: 0x000a, 0x3c2d: 0x000a,
+       0x3c30: 0x000a, 0x3c31: 0x000a, 0x3c32: 0x000a, 0x3c33: 0x000a, 0x3c34: 0x000a,
+       0x3c38: 0x000a, 0x3c39: 0x000a, 0x3c3a: 0x000a,
+       // Block 0xf1, offset 0x3c40
+       0x3c40: 0x000a, 0x3c41: 0x000a, 0x3c42: 0x000a, 0x3c43: 0x000a, 0x3c44: 0x000a, 0x3c45: 0x000a,
+       0x3c46: 0x000a,
+       0x3c50: 0x000a, 0x3c51: 0x000a,
+       0x3c52: 0x000a, 0x3c53: 0x000a, 0x3c54: 0x000a, 0x3c55: 0x000a, 0x3c56: 0x000a, 0x3c57: 0x000a,
+       0x3c58: 0x000a, 0x3c59: 0x000a, 0x3c5a: 0x000a, 0x3c5b: 0x000a, 0x3c5c: 0x000a, 0x3c5d: 0x000a,
+       0x3c5e: 0x000a, 0x3c5f: 0x000a, 0x3c60: 0x000a, 0x3c61: 0x000a, 0x3c62: 0x000a, 0x3c63: 0x000a,
+       0x3c64: 0x000a, 0x3c65: 0x000a, 0x3c66: 0x000a, 0x3c67: 0x000a, 0x3c68: 0x000a,
+       0x3c70: 0x000a, 0x3c71: 0x000a, 0x3c72: 0x000a, 0x3c73: 0x000a, 0x3c74: 0x000a, 0x3c75: 0x000a,
+       0x3c76: 0x000a,
+       // Block 0xf2, offset 0x3c80
+       0x3c80: 0x000a, 0x3c81: 0x000a, 0x3c82: 0x000a,
+       0x3c90: 0x000a, 0x3c91: 0x000a,
+       0x3c92: 0x000a, 0x3c93: 0x000a, 0x3c94: 0x000a, 0x3c95: 0x000a, 0x3c96: 0x000a,
+       // Block 0xf3, offset 0x3cc0
+       0x3cc0: 0x000a, 0x3cc1: 0x000a, 0x3cc2: 0x000a, 0x3cc3: 0x000a, 0x3cc4: 0x000a, 0x3cc5: 0x000a,
+       0x3cc6: 0x000a, 0x3cc7: 0x000a, 0x3cc8: 0x000a, 0x3cc9: 0x000a, 0x3cca: 0x000a, 0x3ccb: 0x000a,
+       0x3ccc: 0x000a, 0x3ccd: 0x000a, 0x3cce: 0x000a, 0x3ccf: 0x000a, 0x3cd0: 0x000a, 0x3cd1: 0x000a,
+       0x3cd2: 0x000a, 0x3cd4: 0x000a, 0x3cd5: 0x000a, 0x3cd6: 0x000a, 0x3cd7: 0x000a,
+       0x3cd8: 0x000a, 0x3cd9: 0x000a, 0x3cda: 0x000a, 0x3cdb: 0x000a, 0x3cdc: 0x000a, 0x3cdd: 0x000a,
+       0x3cde: 0x000a, 0x3cdf: 0x000a, 0x3ce0: 0x000a, 0x3ce1: 0x000a, 0x3ce2: 0x000a, 0x3ce3: 0x000a,
+       0x3ce4: 0x000a, 0x3ce5: 0x000a, 0x3ce6: 0x000a, 0x3ce7: 0x000a, 0x3ce8: 0x000a, 0x3ce9: 0x000a,
+       0x3cea: 0x000a, 0x3ceb: 0x000a, 0x3cec: 0x000a, 0x3ced: 0x000a, 0x3cee: 0x000a, 0x3cef: 0x000a,
+       0x3cf0: 0x000a, 0x3cf1: 0x000a, 0x3cf2: 0x000a, 0x3cf3: 0x000a, 0x3cf4: 0x000a, 0x3cf5: 0x000a,
+       0x3cf6: 0x000a, 0x3cf7: 0x000a, 0x3cf8: 0x000a, 0x3cf9: 0x000a, 0x3cfa: 0x000a, 0x3cfb: 0x000a,
+       0x3cfc: 0x000a, 0x3cfd: 0x000a, 0x3cfe: 0x000a, 0x3cff: 0x000a,
+       // Block 0xf4, offset 0x3d00
+       0x3d00: 0x000a, 0x3d01: 0x000a, 0x3d02: 0x000a, 0x3d03: 0x000a, 0x3d04: 0x000a, 0x3d05: 0x000a,
+       0x3d06: 0x000a, 0x3d07: 0x000a, 0x3d08: 0x000a, 0x3d09: 0x000a, 0x3d0a: 0x000a,
+       0x3d30: 0x0002, 0x3d31: 0x0002, 0x3d32: 0x0002, 0x3d33: 0x0002, 0x3d34: 0x0002, 0x3d35: 0x0002,
+       0x3d36: 0x0002, 0x3d37: 0x0002, 0x3d38: 0x0002, 0x3d39: 0x0002,
+       // Block 0xf5, offset 0x3d40
+       0x3d7e: 0x000b, 0x3d7f: 0x000b,
+       // Block 0xf6, offset 0x3d80
+       0x3d80: 0x000b, 0x3d81: 0x000b, 0x3d82: 0x000b, 0x3d83: 0x000b, 0x3d84: 0x000b, 0x3d85: 0x000b,
+       0x3d86: 0x000b, 0x3d87: 0x000b, 0x3d88: 0x000b, 0x3d89: 0x000b, 0x3d8a: 0x000b, 0x3d8b: 0x000b,
+       0x3d8c: 0x000b, 0x3d8d: 0x000b, 0x3d8e: 0x000b, 0x3d8f: 0x000b, 0x3d90: 0x000b, 0x3d91: 0x000b,
+       0x3d92: 0x000b, 0x3d93: 0x000b, 0x3d94: 0x000b, 0x3d95: 0x000b, 0x3d96: 0x000b, 0x3d97: 0x000b,
+       0x3d98: 0x000b, 0x3d99: 0x000b, 0x3d9a: 0x000b, 0x3d9b: 0x000b, 0x3d9c: 0x000b, 0x3d9d: 0x000b,
+       0x3d9e: 0x000b, 0x3d9f: 0x000b, 0x3da0: 0x000b, 0x3da1: 0x000b, 0x3da2: 0x000b, 0x3da3: 0x000b,
+       0x3da4: 0x000b, 0x3da5: 0x000b, 0x3da6: 0x000b, 0x3da7: 0x000b, 0x3da8: 0x000b, 0x3da9: 0x000b,
+       0x3daa: 0x000b, 0x3dab: 0x000b, 0x3dac: 0x000b, 0x3dad: 0x000b, 0x3dae: 0x000b, 0x3daf: 0x000b,
+       0x3db0: 0x000b, 0x3db1: 0x000b, 0x3db2: 0x000b, 0x3db3: 0x000b, 0x3db4: 0x000b, 0x3db5: 0x000b,
+       0x3db6: 0x000b, 0x3db7: 0x000b, 0x3db8: 0x000b, 0x3db9: 0x000b, 0x3dba: 0x000b, 0x3dbb: 0x000b,
+       0x3dbc: 0x000b, 0x3dbd: 0x000b, 0x3dbe: 0x000b, 0x3dbf: 0x000b,
+       // Block 0xf7, offset 0x3dc0
+       0x3dc0: 0x000c, 0x3dc1: 0x000c, 0x3dc2: 0x000c, 0x3dc3: 0x000c, 0x3dc4: 0x000c, 0x3dc5: 0x000c,
+       0x3dc6: 0x000c, 0x3dc7: 0x000c, 0x3dc8: 0x000c, 0x3dc9: 0x000c, 0x3dca: 0x000c, 0x3dcb: 0x000c,
+       0x3dcc: 0x000c, 0x3dcd: 0x000c, 0x3dce: 0x000c, 0x3dcf: 0x000c, 0x3dd0: 0x000c, 0x3dd1: 0x000c,
+       0x3dd2: 0x000c, 0x3dd3: 0x000c, 0x3dd4: 0x000c, 0x3dd5: 0x000c, 0x3dd6: 0x000c, 0x3dd7: 0x000c,
+       0x3dd8: 0x000c, 0x3dd9: 0x000c, 0x3dda: 0x000c, 0x3ddb: 0x000c, 0x3ddc: 0x000c, 0x3ddd: 0x000c,
+       0x3dde: 0x000c, 0x3ddf: 0x000c, 0x3de0: 0x000c, 0x3de1: 0x000c, 0x3de2: 0x000c, 0x3de3: 0x000c,
+       0x3de4: 0x000c, 0x3de5: 0x000c, 0x3de6: 0x000c, 0x3de7: 0x000c, 0x3de8: 0x000c, 0x3de9: 0x000c,
+       0x3dea: 0x000c, 0x3deb: 0x000c, 0x3dec: 0x000c, 0x3ded: 0x000c, 0x3dee: 0x000c, 0x3def: 0x000c,
+       0x3df0: 0x000b, 0x3df1: 0x000b, 0x3df2: 0x000b, 0x3df3: 0x000b, 0x3df4: 0x000b, 0x3df5: 0x000b,
+       0x3df6: 0x000b, 0x3df7: 0x000b, 0x3df8: 0x000b, 0x3df9: 0x000b, 0x3dfa: 0x000b, 0x3dfb: 0x000b,
+       0x3dfc: 0x000b, 0x3dfd: 0x000b, 0x3dfe: 0x000b, 0x3dff: 0x000b,
+}
+
+// bidiIndex: 24 blocks, 1536 entries, 1536 bytes
+// Block 0 is the zero block.
+var bidiIndex = [1536]uint8{
+       // Block 0x0, offset 0x0
+       // Block 0x1, offset 0x40
+       // Block 0x2, offset 0x80
+       // Block 0x3, offset 0xc0
+       0xc2: 0x01, 0xc3: 0x02,
+       0xca: 0x03, 0xcb: 0x04, 0xcc: 0x05, 0xcd: 0x06, 0xce: 0x07, 0xcf: 0x08,
+       0xd2: 0x09, 0xd6: 0x0a, 0xd7: 0x0b,
+       0xd8: 0x0c, 0xd9: 0x0d, 0xda: 0x0e, 0xdb: 0x0f, 0xdc: 0x10, 0xdd: 0x11, 0xde: 0x12, 0xdf: 0x13,
+       0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06,
+       0xea: 0x07, 0xef: 0x08,
+       0xf0: 0x11, 0xf1: 0x12, 0xf2: 0x12, 0xf3: 0x14, 0xf4: 0x15,
+       // Block 0x4, offset 0x100
+       0x120: 0x14, 0x121: 0x15, 0x122: 0x16, 0x123: 0x17, 0x124: 0x18, 0x125: 0x19, 0x126: 0x1a, 0x127: 0x1b,
+       0x128: 0x1c, 0x129: 0x1d, 0x12a: 0x1c, 0x12b: 0x1e, 0x12c: 0x1f, 0x12d: 0x20, 0x12e: 0x21, 0x12f: 0x22,
+       0x130: 0x23, 0x131: 0x24, 0x132: 0x1a, 0x133: 0x25, 0x134: 0x26, 0x135: 0x27, 0x136: 0x28, 0x137: 0x29,
+       0x138: 0x2a, 0x139: 0x2b, 0x13a: 0x2c, 0x13b: 0x2d, 0x13c: 0x2e, 0x13d: 0x2f, 0x13e: 0x30, 0x13f: 0x31,
+       // Block 0x5, offset 0x140
+       0x140: 0x32, 0x141: 0x33, 0x142: 0x34,
+       0x14d: 0x35, 0x14e: 0x36,
+       0x150: 0x37,
+       0x15a: 0x38, 0x15c: 0x39, 0x15d: 0x3a, 0x15e: 0x3b, 0x15f: 0x3c,
+       0x160: 0x3d, 0x162: 0x3e, 0x164: 0x3f, 0x165: 0x40, 0x167: 0x41,
+       0x168: 0x42, 0x169: 0x43, 0x16a: 0x44, 0x16b: 0x45, 0x16c: 0x46, 0x16d: 0x47, 0x16e: 0x48, 0x16f: 0x49,
+       0x170: 0x4a, 0x173: 0x4b, 0x177: 0x4c,
+       0x17e: 0x4d, 0x17f: 0x4e,
+       // Block 0x6, offset 0x180
+       0x180: 0x4f, 0x181: 0x50, 0x182: 0x51, 0x183: 0x52, 0x184: 0x53, 0x185: 0x54, 0x186: 0x55, 0x187: 0x56,
+       0x188: 0x57, 0x189: 0x56, 0x18a: 0x56, 0x18b: 0x56, 0x18c: 0x58, 0x18d: 0x59, 0x18e: 0x5a, 0x18f: 0x56,
+       0x190: 0x5b, 0x191: 0x5c, 0x192: 0x5d, 0x193: 0x5e, 0x194: 0x56, 0x195: 0x56, 0x196: 0x56, 0x197: 0x56,
+       0x198: 0x56, 0x199: 0x56, 0x19a: 0x5f, 0x19b: 0x56, 0x19c: 0x56, 0x19d: 0x60, 0x19e: 0x56, 0x19f: 0x61,
+       0x1a4: 0x56, 0x1a5: 0x56, 0x1a6: 0x62, 0x1a7: 0x63,
+       0x1a8: 0x56, 0x1a9: 0x56, 0x1aa: 0x56, 0x1ab: 0x56, 0x1ac: 0x56, 0x1ad: 0x64, 0x1ae: 0x65, 0x1af: 0x56,
+       0x1b3: 0x66, 0x1b5: 0x67, 0x1b7: 0x68,
+       0x1b8: 0x69, 0x1b9: 0x6a, 0x1ba: 0x6b, 0x1bb: 0x6c, 0x1bc: 0x56, 0x1bd: 0x56, 0x1be: 0x56, 0x1bf: 0x6d,
+       // Block 0x7, offset 0x1c0
+       0x1c0: 0x6e, 0x1c2: 0x6f, 0x1c3: 0x70, 0x1c7: 0x71,
+       0x1c8: 0x72, 0x1c9: 0x73, 0x1ca: 0x74, 0x1cb: 0x75, 0x1cd: 0x76, 0x1cf: 0x77,
+       // Block 0x8, offset 0x200
+       0x237: 0x56,
+       // Block 0x9, offset 0x240
+       0x252: 0x78, 0x253: 0x79,
+       0x258: 0x7a, 0x259: 0x7b, 0x25a: 0x7c, 0x25b: 0x7d, 0x25c: 0x7e, 0x25e: 0x7f,
+       0x260: 0x80, 0x261: 0x81, 0x263: 0x82, 0x264: 0x83, 0x265: 0x84, 0x266: 0x85, 0x267: 0x86,
+       0x268: 0x87, 0x269: 0x88, 0x26a: 0x89, 0x26b: 0x8a, 0x26d: 0x8b, 0x26f: 0x8c,
+       // Block 0xa, offset 0x280
+       0x2ac: 0x8d, 0x2ad: 0x8e, 0x2ae: 0x0e, 0x2af: 0x0e,
+       0x2b0: 0x0e, 0x2b1: 0x0e, 0x2b2: 0x0e, 0x2b3: 0x0e, 0x2b4: 0x8f, 0x2b5: 0x0e, 0x2b6: 0x0e, 0x2b7: 0x90,
+       0x2b8: 0x91, 0x2b9: 0x92, 0x2ba: 0x0e, 0x2bb: 0x93, 0x2bc: 0x94, 0x2bd: 0x95, 0x2bf: 0x96,
+       // Block 0xb, offset 0x2c0
+       0x2c4: 0x97, 0x2c5: 0x56, 0x2c6: 0x98, 0x2c7: 0x99,
+       0x2cb: 0x9a, 0x2cd: 0x9b,
+       0x2e0: 0x9c, 0x2e1: 0x9c, 0x2e2: 0x9c, 0x2e3: 0x9c, 0x2e4: 0x9d, 0x2e5: 0x9c, 0x2e6: 0x9c, 0x2e7: 0x9c,
+       0x2e8: 0x9e, 0x2e9: 0x9c, 0x2ea: 0x9c, 0x2eb: 0x9f, 0x2ec: 0xa0, 0x2ed: 0x9c, 0x2ee: 0x9c, 0x2ef: 0x9c,
+       0x2f0: 0x9c, 0x2f1: 0x9c, 0x2f2: 0x9c, 0x2f3: 0x9c, 0x2f4: 0xa1, 0x2f5: 0x9c, 0x2f6: 0x9c, 0x2f7: 0x9c,
+       0x2f8: 0x9c, 0x2f9: 0xa2, 0x2fa: 0xa3, 0x2fb: 0x9c, 0x2fc: 0xa4, 0x2fd: 0xa5, 0x2fe: 0x9c, 0x2ff: 0x9c,
+       // Block 0xc, offset 0x300
+       0x300: 0xa6, 0x301: 0xa7, 0x302: 0xa8, 0x304: 0xa9, 0x305: 0xaa, 0x306: 0xab, 0x307: 0xac,
+       0x308: 0xad, 0x30b: 0xae, 0x30c: 0x26, 0x30d: 0xaf,
+       0x310: 0xb0, 0x311: 0xb1, 0x312: 0xb2, 0x313: 0xb3, 0x316: 0xb4, 0x317: 0xb5,
+       0x318: 0xb6, 0x319: 0xb7, 0x31a: 0xb8, 0x31c: 0xb9,
+       0x320: 0xba, 0x324: 0xbb, 0x325: 0xbc, 0x327: 0xbd,
+       0x328: 0xbe, 0x329: 0xbf, 0x32a: 0xc0,
+       0x330: 0xc1, 0x332: 0xc2, 0x334: 0xc3, 0x335: 0xc4, 0x336: 0xc5,
+       0x33b: 0xc6, 0x33f: 0xc7,
+       // Block 0xd, offset 0x340
+       0x36b: 0xc8, 0x36c: 0xc9,
+       0x37d: 0xca, 0x37e: 0xcb, 0x37f: 0xcc,
+       // Block 0xe, offset 0x380
+       0x3b2: 0xcd,
+       // Block 0xf, offset 0x3c0
+       0x3c5: 0xce, 0x3c6: 0xcf,
+       0x3c8: 0x56, 0x3c9: 0xd0, 0x3cc: 0x56, 0x3cd: 0xd1,
+       0x3db: 0xd2, 0x3dc: 0xd3, 0x3dd: 0xd4, 0x3de: 0xd5, 0x3df: 0xd6,
+       0x3e8: 0xd7, 0x3e9: 0xd8, 0x3ea: 0xd9,
+       // Block 0x10, offset 0x400
+       0x400: 0xda, 0x404: 0xc9,
+       0x40b: 0xdb,
+       0x420: 0x9c, 0x421: 0x9c, 0x422: 0x9c, 0x423: 0xdc, 0x424: 0x9c, 0x425: 0xdd, 0x426: 0x9c, 0x427: 0x9c,
+       0x428: 0x9c, 0x429: 0x9c, 0x42a: 0x9c, 0x42b: 0x9c, 0x42c: 0x9c, 0x42d: 0x9c, 0x42e: 0x9c, 0x42f: 0x9c,
+       0x430: 0x9c, 0x431: 0xa4, 0x432: 0x0e, 0x433: 0x9c, 0x434: 0x0e, 0x435: 0xde, 0x436: 0x9c, 0x437: 0x9c,
+       0x438: 0x0e, 0x439: 0x0e, 0x43a: 0x0e, 0x43b: 0xdf, 0x43c: 0x9c, 0x43d: 0x9c, 0x43e: 0x9c, 0x43f: 0x9c,
+       // Block 0x11, offset 0x440
+       0x440: 0xe0, 0x441: 0x56, 0x442: 0xe1, 0x443: 0xe2, 0x444: 0xe3, 0x445: 0xe4, 0x446: 0xe5,
+       0x449: 0xe6, 0x44c: 0x56, 0x44d: 0x56, 0x44e: 0x56, 0x44f: 0x56,
+       0x450: 0x56, 0x451: 0x56, 0x452: 0x56, 0x453: 0x56, 0x454: 0x56, 0x455: 0x56, 0x456: 0x56, 0x457: 0x56,
+       0x458: 0x56, 0x459: 0x56, 0x45a: 0x56, 0x45b: 0xe7, 0x45c: 0x56, 0x45d: 0x6c, 0x45e: 0x56, 0x45f: 0xe8,
+       0x460: 0xe9, 0x461: 0xea, 0x462: 0xeb, 0x464: 0x56, 0x465: 0xec, 0x466: 0x56, 0x467: 0xed,
+       0x468: 0x56, 0x469: 0xee, 0x46a: 0xef, 0x46b: 0xf0, 0x46c: 0x56, 0x46d: 0x56, 0x46e: 0xf1, 0x46f: 0xf2,
+       0x47f: 0xf3,
+       // Block 0x12, offset 0x480
+       0x4bf: 0xf3,
+       // Block 0x13, offset 0x4c0
+       0x4d0: 0x09, 0x4d1: 0x0a, 0x4d6: 0x0b,
+       0x4db: 0x0c, 0x4dd: 0x0d, 0x4de: 0x0e, 0x4df: 0x0f,
+       0x4ef: 0x10,
+       0x4ff: 0x10,
+       // Block 0x14, offset 0x500
+       0x50f: 0x10,
+       0x51f: 0x10,
+       0x52f: 0x10,
+       0x53f: 0x10,
+       // Block 0x15, offset 0x540
+       0x540: 0xf4, 0x541: 0xf4, 0x542: 0xf4, 0x543: 0xf4, 0x544: 0x05, 0x545: 0x05, 0x546: 0x05, 0x547: 0xf5,
+       0x548: 0xf4, 0x549: 0xf4, 0x54a: 0xf4, 0x54b: 0xf4, 0x54c: 0xf4, 0x54d: 0xf4, 0x54e: 0xf4, 0x54f: 0xf4,
+       0x550: 0xf4, 0x551: 0xf4, 0x552: 0xf4, 0x553: 0xf4, 0x554: 0xf4, 0x555: 0xf4, 0x556: 0xf4, 0x557: 0xf4,
+       0x558: 0xf4, 0x559: 0xf4, 0x55a: 0xf4, 0x55b: 0xf4, 0x55c: 0xf4, 0x55d: 0xf4, 0x55e: 0xf4, 0x55f: 0xf4,
+       0x560: 0xf4, 0x561: 0xf4, 0x562: 0xf4, 0x563: 0xf4, 0x564: 0xf4, 0x565: 0xf4, 0x566: 0xf4, 0x567: 0xf4,
+       0x568: 0xf4, 0x569: 0xf4, 0x56a: 0xf4, 0x56b: 0xf4, 0x56c: 0xf4, 0x56d: 0xf4, 0x56e: 0xf4, 0x56f: 0xf4,
+       0x570: 0xf4, 0x571: 0xf4, 0x572: 0xf4, 0x573: 0xf4, 0x574: 0xf4, 0x575: 0xf4, 0x576: 0xf4, 0x577: 0xf4,
+       0x578: 0xf4, 0x579: 0xf4, 0x57a: 0xf4, 0x57b: 0xf4, 0x57c: 0xf4, 0x57d: 0xf4, 0x57e: 0xf4, 0x57f: 0xf4,
+       // Block 0x16, offset 0x580
+       0x58f: 0x10,
+       0x59f: 0x10,
+       0x5a0: 0x13,
+       0x5af: 0x10,
+       0x5bf: 0x10,
+       // Block 0x17, offset 0x5c0
+       0x5cf: 0x10,
+}
+
+// Total table size 17464 bytes (17KiB); checksum: F50EF68C
index 10f5202c693fde615b4ed7bebcdb85400660e912..7e1ae096e5c00b890237ac84a7ca778b0ecea585 100644 (file)
@@ -1,6 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
-// +build go1.14
+// +build go1.14,!go1.16
 
 package norm
 
diff --git a/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go b/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go
new file mode 100644 (file)
index 0000000..9ea1b42
--- /dev/null
@@ -0,0 +1,7760 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+// +build go1.16
+
+package norm
+
+import "sync"
+
+const (
+       // Version is the Unicode edition from which the tables are derived.
+       Version = "13.0.0"
+
+       // MaxTransformChunkSize indicates the maximum number of bytes that Transform
+       // may need to write atomically for any Form. Making a destination buffer at
+       // least this size ensures that Transform can always make progress and that
+       // the user does not need to grow the buffer on an ErrShortDst.
+       MaxTransformChunkSize = 35 + maxNonStarters*4
+)
+
+var ccc = [56]uint8{
+       0, 1, 6, 7, 8, 9, 10, 11,
+       12, 13, 14, 15, 16, 17, 18, 19,
+       20, 21, 22, 23, 24, 25, 26, 27,
+       28, 29, 30, 31, 32, 33, 34, 35,
+       36, 84, 91, 103, 107, 118, 122, 129,
+       130, 132, 202, 214, 216, 218, 220, 222,
+       224, 226, 228, 230, 232, 233, 234, 240,
+}
+
+const (
+       firstMulti            = 0x1870
+       firstCCC              = 0x2CAB
+       endMulti              = 0x2F77
+       firstLeadingCCC       = 0x49C5
+       firstCCCZeroExcept    = 0x4A8F
+       firstStarterWithNLead = 0x4AB6
+       lastDecomp            = 0x4AB8
+       maxDecomp             = 0x8000
+)
+
+// decomps: 19128 bytes
+var decomps = [...]byte{
+       // Bytes 0 - 3f
+       0x00, 0x41, 0x20, 0x41, 0x21, 0x41, 0x22, 0x41,
+       0x23, 0x41, 0x24, 0x41, 0x25, 0x41, 0x26, 0x41,
+       0x27, 0x41, 0x28, 0x41, 0x29, 0x41, 0x2A, 0x41,
+       0x2B, 0x41, 0x2C, 0x41, 0x2D, 0x41, 0x2E, 0x41,
+       0x2F, 0x41, 0x30, 0x41, 0x31, 0x41, 0x32, 0x41,
+       0x33, 0x41, 0x34, 0x41, 0x35, 0x41, 0x36, 0x41,
+       0x37, 0x41, 0x38, 0x41, 0x39, 0x41, 0x3A, 0x41,
+       0x3B, 0x41, 0x3C, 0x41, 0x3D, 0x41, 0x3E, 0x41,
+       // Bytes 40 - 7f
+       0x3F, 0x41, 0x40, 0x41, 0x41, 0x41, 0x42, 0x41,
+       0x43, 0x41, 0x44, 0x41, 0x45, 0x41, 0x46, 0x41,
+       0x47, 0x41, 0x48, 0x41, 0x49, 0x41, 0x4A, 0x41,
+       0x4B, 0x41, 0x4C, 0x41, 0x4D, 0x41, 0x4E, 0x41,
+       0x4F, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41,
+       0x53, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41,
+       0x57, 0x41, 0x58, 0x41, 0x59, 0x41, 0x5A, 0x41,
+       0x5B, 0x41, 0x5C, 0x41, 0x5D, 0x41, 0x5E, 0x41,
+       // Bytes 80 - bf
+       0x5F, 0x41, 0x60, 0x41, 0x61, 0x41, 0x62, 0x41,
+       0x63, 0x41, 0x64, 0x41, 0x65, 0x41, 0x66, 0x41,
+       0x67, 0x41, 0x68, 0x41, 0x69, 0x41, 0x6A, 0x41,
+       0x6B, 0x41, 0x6C, 0x41, 0x6D, 0x41, 0x6E, 0x41,
+       0x6F, 0x41, 0x70, 0x41, 0x71, 0x41, 0x72, 0x41,
+       0x73, 0x41, 0x74, 0x41, 0x75, 0x41, 0x76, 0x41,
+       0x77, 0x41, 0x78, 0x41, 0x79, 0x41, 0x7A, 0x41,
+       0x7B, 0x41, 0x7C, 0x41, 0x7D, 0x41, 0x7E, 0x42,
+       // Bytes c0 - ff
+       0xC2, 0xA2, 0x42, 0xC2, 0xA3, 0x42, 0xC2, 0xA5,
+       0x42, 0xC2, 0xA6, 0x42, 0xC2, 0xAC, 0x42, 0xC2,
+       0xB7, 0x42, 0xC3, 0x86, 0x42, 0xC3, 0xB0, 0x42,
+       0xC4, 0xA6, 0x42, 0xC4, 0xA7, 0x42, 0xC4, 0xB1,
+       0x42, 0xC5, 0x8B, 0x42, 0xC5, 0x93, 0x42, 0xC6,
+       0x8E, 0x42, 0xC6, 0x90, 0x42, 0xC6, 0xAB, 0x42,
+       0xC8, 0xA2, 0x42, 0xC8, 0xB7, 0x42, 0xC9, 0x90,
+       0x42, 0xC9, 0x91, 0x42, 0xC9, 0x92, 0x42, 0xC9,
+       // Bytes 100 - 13f
+       0x94, 0x42, 0xC9, 0x95, 0x42, 0xC9, 0x99, 0x42,
+       0xC9, 0x9B, 0x42, 0xC9, 0x9C, 0x42, 0xC9, 0x9F,
+       0x42, 0xC9, 0xA1, 0x42, 0xC9, 0xA3, 0x42, 0xC9,
+       0xA5, 0x42, 0xC9, 0xA6, 0x42, 0xC9, 0xA8, 0x42,
+       0xC9, 0xA9, 0x42, 0xC9, 0xAA, 0x42, 0xC9, 0xAB,
+       0x42, 0xC9, 0xAD, 0x42, 0xC9, 0xAF, 0x42, 0xC9,
+       0xB0, 0x42, 0xC9, 0xB1, 0x42, 0xC9, 0xB2, 0x42,
+       0xC9, 0xB3, 0x42, 0xC9, 0xB4, 0x42, 0xC9, 0xB5,
+       // Bytes 140 - 17f
+       0x42, 0xC9, 0xB8, 0x42, 0xC9, 0xB9, 0x42, 0xC9,
+       0xBB, 0x42, 0xCA, 0x81, 0x42, 0xCA, 0x82, 0x42,
+       0xCA, 0x83, 0x42, 0xCA, 0x89, 0x42, 0xCA, 0x8A,
+       0x42, 0xCA, 0x8B, 0x42, 0xCA, 0x8C, 0x42, 0xCA,
+       0x8D, 0x42, 0xCA, 0x90, 0x42, 0xCA, 0x91, 0x42,
+       0xCA, 0x92, 0x42, 0xCA, 0x95, 0x42, 0xCA, 0x9D,
+       0x42, 0xCA, 0x9F, 0x42, 0xCA, 0xB9, 0x42, 0xCE,
+       0x91, 0x42, 0xCE, 0x92, 0x42, 0xCE, 0x93, 0x42,
+       // Bytes 180 - 1bf
+       0xCE, 0x94, 0x42, 0xCE, 0x95, 0x42, 0xCE, 0x96,
+       0x42, 0xCE, 0x97, 0x42, 0xCE, 0x98, 0x42, 0xCE,
+       0x99, 0x42, 0xCE, 0x9A, 0x42, 0xCE, 0x9B, 0x42,
+       0xCE, 0x9C, 0x42, 0xCE, 0x9D, 0x42, 0xCE, 0x9E,
+       0x42, 0xCE, 0x9F, 0x42, 0xCE, 0xA0, 0x42, 0xCE,
+       0xA1, 0x42, 0xCE, 0xA3, 0x42, 0xCE, 0xA4, 0x42,
+       0xCE, 0xA5, 0x42, 0xCE, 0xA6, 0x42, 0xCE, 0xA7,
+       0x42, 0xCE, 0xA8, 0x42, 0xCE, 0xA9, 0x42, 0xCE,
+       // Bytes 1c0 - 1ff
+       0xB1, 0x42, 0xCE, 0xB2, 0x42, 0xCE, 0xB3, 0x42,
+       0xCE, 0xB4, 0x42, 0xCE, 0xB5, 0x42, 0xCE, 0xB6,
+       0x42, 0xCE, 0xB7, 0x42, 0xCE, 0xB8, 0x42, 0xCE,
+       0xB9, 0x42, 0xCE, 0xBA, 0x42, 0xCE, 0xBB, 0x42,
+       0xCE, 0xBC, 0x42, 0xCE, 0xBD, 0x42, 0xCE, 0xBE,
+       0x42, 0xCE, 0xBF, 0x42, 0xCF, 0x80, 0x42, 0xCF,
+       0x81, 0x42, 0xCF, 0x82, 0x42, 0xCF, 0x83, 0x42,
+       0xCF, 0x84, 0x42, 0xCF, 0x85, 0x42, 0xCF, 0x86,
+       // Bytes 200 - 23f
+       0x42, 0xCF, 0x87, 0x42, 0xCF, 0x88, 0x42, 0xCF,
+       0x89, 0x42, 0xCF, 0x9C, 0x42, 0xCF, 0x9D, 0x42,
+       0xD0, 0xBD, 0x42, 0xD1, 0x8A, 0x42, 0xD1, 0x8C,
+       0x42, 0xD7, 0x90, 0x42, 0xD7, 0x91, 0x42, 0xD7,
+       0x92, 0x42, 0xD7, 0x93, 0x42, 0xD7, 0x94, 0x42,
+       0xD7, 0x9B, 0x42, 0xD7, 0x9C, 0x42, 0xD7, 0x9D,
+       0x42, 0xD7, 0xA2, 0x42, 0xD7, 0xA8, 0x42, 0xD7,
+       0xAA, 0x42, 0xD8, 0xA1, 0x42, 0xD8, 0xA7, 0x42,
+       // Bytes 240 - 27f
+       0xD8, 0xA8, 0x42, 0xD8, 0xA9, 0x42, 0xD8, 0xAA,
+       0x42, 0xD8, 0xAB, 0x42, 0xD8, 0xAC, 0x42, 0xD8,
+       0xAD, 0x42, 0xD8, 0xAE, 0x42, 0xD8, 0xAF, 0x42,
+       0xD8, 0xB0, 0x42, 0xD8, 0xB1, 0x42, 0xD8, 0xB2,
+       0x42, 0xD8, 0xB3, 0x42, 0xD8, 0xB4, 0x42, 0xD8,
+       0xB5, 0x42, 0xD8, 0xB6, 0x42, 0xD8, 0xB7, 0x42,
+       0xD8, 0xB8, 0x42, 0xD8, 0xB9, 0x42, 0xD8, 0xBA,
+       0x42, 0xD9, 0x81, 0x42, 0xD9, 0x82, 0x42, 0xD9,
+       // Bytes 280 - 2bf
+       0x83, 0x42, 0xD9, 0x84, 0x42, 0xD9, 0x85, 0x42,
+       0xD9, 0x86, 0x42, 0xD9, 0x87, 0x42, 0xD9, 0x88,
+       0x42, 0xD9, 0x89, 0x42, 0xD9, 0x8A, 0x42, 0xD9,
+       0xAE, 0x42, 0xD9, 0xAF, 0x42, 0xD9, 0xB1, 0x42,
+       0xD9, 0xB9, 0x42, 0xD9, 0xBA, 0x42, 0xD9, 0xBB,
+       0x42, 0xD9, 0xBE, 0x42, 0xD9, 0xBF, 0x42, 0xDA,
+       0x80, 0x42, 0xDA, 0x83, 0x42, 0xDA, 0x84, 0x42,
+       0xDA, 0x86, 0x42, 0xDA, 0x87, 0x42, 0xDA, 0x88,
+       // Bytes 2c0 - 2ff
+       0x42, 0xDA, 0x8C, 0x42, 0xDA, 0x8D, 0x42, 0xDA,
+       0x8E, 0x42, 0xDA, 0x91, 0x42, 0xDA, 0x98, 0x42,
+       0xDA, 0xA1, 0x42, 0xDA, 0xA4, 0x42, 0xDA, 0xA6,
+       0x42, 0xDA, 0xA9, 0x42, 0xDA, 0xAD, 0x42, 0xDA,
+       0xAF, 0x42, 0xDA, 0xB1, 0x42, 0xDA, 0xB3, 0x42,
+       0xDA, 0xBA, 0x42, 0xDA, 0xBB, 0x42, 0xDA, 0xBE,
+       0x42, 0xDB, 0x81, 0x42, 0xDB, 0x85, 0x42, 0xDB,
+       0x86, 0x42, 0xDB, 0x87, 0x42, 0xDB, 0x88, 0x42,
+       // Bytes 300 - 33f
+       0xDB, 0x89, 0x42, 0xDB, 0x8B, 0x42, 0xDB, 0x8C,
+       0x42, 0xDB, 0x90, 0x42, 0xDB, 0x92, 0x43, 0xE0,
+       0xBC, 0x8B, 0x43, 0xE1, 0x83, 0x9C, 0x43, 0xE1,
+       0x84, 0x80, 0x43, 0xE1, 0x84, 0x81, 0x43, 0xE1,
+       0x84, 0x82, 0x43, 0xE1, 0x84, 0x83, 0x43, 0xE1,
+       0x84, 0x84, 0x43, 0xE1, 0x84, 0x85, 0x43, 0xE1,
+       0x84, 0x86, 0x43, 0xE1, 0x84, 0x87, 0x43, 0xE1,
+       0x84, 0x88, 0x43, 0xE1, 0x84, 0x89, 0x43, 0xE1,
+       // Bytes 340 - 37f
+       0x84, 0x8A, 0x43, 0xE1, 0x84, 0x8B, 0x43, 0xE1,
+       0x84, 0x8C, 0x43, 0xE1, 0x84, 0x8D, 0x43, 0xE1,
+       0x84, 0x8E, 0x43, 0xE1, 0x84, 0x8F, 0x43, 0xE1,
+       0x84, 0x90, 0x43, 0xE1, 0x84, 0x91, 0x43, 0xE1,
+       0x84, 0x92, 0x43, 0xE1, 0x84, 0x94, 0x43, 0xE1,
+       0x84, 0x95, 0x43, 0xE1, 0x84, 0x9A, 0x43, 0xE1,
+       0x84, 0x9C, 0x43, 0xE1, 0x84, 0x9D, 0x43, 0xE1,
+       0x84, 0x9E, 0x43, 0xE1, 0x84, 0xA0, 0x43, 0xE1,
+       // Bytes 380 - 3bf
+       0x84, 0xA1, 0x43, 0xE1, 0x84, 0xA2, 0x43, 0xE1,
+       0x84, 0xA3, 0x43, 0xE1, 0x84, 0xA7, 0x43, 0xE1,
+       0x84, 0xA9, 0x43, 0xE1, 0x84, 0xAB, 0x43, 0xE1,
+       0x84, 0xAC, 0x43, 0xE1, 0x84, 0xAD, 0x43, 0xE1,
+       0x84, 0xAE, 0x43, 0xE1, 0x84, 0xAF, 0x43, 0xE1,
+       0x84, 0xB2, 0x43, 0xE1, 0x84, 0xB6, 0x43, 0xE1,
+       0x85, 0x80, 0x43, 0xE1, 0x85, 0x87, 0x43, 0xE1,
+       0x85, 0x8C, 0x43, 0xE1, 0x85, 0x97, 0x43, 0xE1,
+       // Bytes 3c0 - 3ff
+       0x85, 0x98, 0x43, 0xE1, 0x85, 0x99, 0x43, 0xE1,
+       0x85, 0xA0, 0x43, 0xE1, 0x86, 0x84, 0x43, 0xE1,
+       0x86, 0x85, 0x43, 0xE1, 0x86, 0x88, 0x43, 0xE1,
+       0x86, 0x91, 0x43, 0xE1, 0x86, 0x92, 0x43, 0xE1,
+       0x86, 0x94, 0x43, 0xE1, 0x86, 0x9E, 0x43, 0xE1,
+       0x86, 0xA1, 0x43, 0xE1, 0x87, 0x87, 0x43, 0xE1,
+       0x87, 0x88, 0x43, 0xE1, 0x87, 0x8C, 0x43, 0xE1,
+       0x87, 0x8E, 0x43, 0xE1, 0x87, 0x93, 0x43, 0xE1,
+       // Bytes 400 - 43f
+       0x87, 0x97, 0x43, 0xE1, 0x87, 0x99, 0x43, 0xE1,
+       0x87, 0x9D, 0x43, 0xE1, 0x87, 0x9F, 0x43, 0xE1,
+       0x87, 0xB1, 0x43, 0xE1, 0x87, 0xB2, 0x43, 0xE1,
+       0xB4, 0x82, 0x43, 0xE1, 0xB4, 0x96, 0x43, 0xE1,
+       0xB4, 0x97, 0x43, 0xE1, 0xB4, 0x9C, 0x43, 0xE1,
+       0xB4, 0x9D, 0x43, 0xE1, 0xB4, 0xA5, 0x43, 0xE1,
+       0xB5, 0xBB, 0x43, 0xE1, 0xB6, 0x85, 0x43, 0xE2,
+       0x80, 0x82, 0x43, 0xE2, 0x80, 0x83, 0x43, 0xE2,
+       // Bytes 440 - 47f
+       0x80, 0x90, 0x43, 0xE2, 0x80, 0x93, 0x43, 0xE2,
+       0x80, 0x94, 0x43, 0xE2, 0x82, 0xA9, 0x43, 0xE2,
+       0x86, 0x90, 0x43, 0xE2, 0x86, 0x91, 0x43, 0xE2,
+       0x86, 0x92, 0x43, 0xE2, 0x86, 0x93, 0x43, 0xE2,
+       0x88, 0x82, 0x43, 0xE2, 0x88, 0x87, 0x43, 0xE2,
+       0x88, 0x91, 0x43, 0xE2, 0x88, 0x92, 0x43, 0xE2,
+       0x94, 0x82, 0x43, 0xE2, 0x96, 0xA0, 0x43, 0xE2,
+       0x97, 0x8B, 0x43, 0xE2, 0xA6, 0x85, 0x43, 0xE2,
+       // Bytes 480 - 4bf
+       0xA6, 0x86, 0x43, 0xE2, 0xB5, 0xA1, 0x43, 0xE3,
+       0x80, 0x81, 0x43, 0xE3, 0x80, 0x82, 0x43, 0xE3,
+       0x80, 0x88, 0x43, 0xE3, 0x80, 0x89, 0x43, 0xE3,
+       0x80, 0x8A, 0x43, 0xE3, 0x80, 0x8B, 0x43, 0xE3,
+       0x80, 0x8C, 0x43, 0xE3, 0x80, 0x8D, 0x43, 0xE3,
+       0x80, 0x8E, 0x43, 0xE3, 0x80, 0x8F, 0x43, 0xE3,
+       0x80, 0x90, 0x43, 0xE3, 0x80, 0x91, 0x43, 0xE3,
+       0x80, 0x92, 0x43, 0xE3, 0x80, 0x94, 0x43, 0xE3,
+       // Bytes 4c0 - 4ff
+       0x80, 0x95, 0x43, 0xE3, 0x80, 0x96, 0x43, 0xE3,
+       0x80, 0x97, 0x43, 0xE3, 0x82, 0xA1, 0x43, 0xE3,
+       0x82, 0xA2, 0x43, 0xE3, 0x82, 0xA3, 0x43, 0xE3,
+       0x82, 0xA4, 0x43, 0xE3, 0x82, 0xA5, 0x43, 0xE3,
+       0x82, 0xA6, 0x43, 0xE3, 0x82, 0xA7, 0x43, 0xE3,
+       0x82, 0xA8, 0x43, 0xE3, 0x82, 0xA9, 0x43, 0xE3,
+       0x82, 0xAA, 0x43, 0xE3, 0x82, 0xAB, 0x43, 0xE3,
+       0x82, 0xAD, 0x43, 0xE3, 0x82, 0xAF, 0x43, 0xE3,
+       // Bytes 500 - 53f
+       0x82, 0xB1, 0x43, 0xE3, 0x82, 0xB3, 0x43, 0xE3,
+       0x82, 0xB5, 0x43, 0xE3, 0x82, 0xB7, 0x43, 0xE3,
+       0x82, 0xB9, 0x43, 0xE3, 0x82, 0xBB, 0x43, 0xE3,
+       0x82, 0xBD, 0x43, 0xE3, 0x82, 0xBF, 0x43, 0xE3,
+       0x83, 0x81, 0x43, 0xE3, 0x83, 0x83, 0x43, 0xE3,
+       0x83, 0x84, 0x43, 0xE3, 0x83, 0x86, 0x43, 0xE3,
+       0x83, 0x88, 0x43, 0xE3, 0x83, 0x8A, 0x43, 0xE3,
+       0x83, 0x8B, 0x43, 0xE3, 0x83, 0x8C, 0x43, 0xE3,
+       // Bytes 540 - 57f
+       0x83, 0x8D, 0x43, 0xE3, 0x83, 0x8E, 0x43, 0xE3,
+       0x83, 0x8F, 0x43, 0xE3, 0x83, 0x92, 0x43, 0xE3,
+       0x83, 0x95, 0x43, 0xE3, 0x83, 0x98, 0x43, 0xE3,
+       0x83, 0x9B, 0x43, 0xE3, 0x83, 0x9E, 0x43, 0xE3,
+       0x83, 0x9F, 0x43, 0xE3, 0x83, 0xA0, 0x43, 0xE3,
+       0x83, 0xA1, 0x43, 0xE3, 0x83, 0xA2, 0x43, 0xE3,
+       0x83, 0xA3, 0x43, 0xE3, 0x83, 0xA4, 0x43, 0xE3,
+       0x83, 0xA5, 0x43, 0xE3, 0x83, 0xA6, 0x43, 0xE3,
+       // Bytes 580 - 5bf
+       0x83, 0xA7, 0x43, 0xE3, 0x83, 0xA8, 0x43, 0xE3,
+       0x83, 0xA9, 0x43, 0xE3, 0x83, 0xAA, 0x43, 0xE3,
+       0x83, 0xAB, 0x43, 0xE3, 0x83, 0xAC, 0x43, 0xE3,
+       0x83, 0xAD, 0x43, 0xE3, 0x83, 0xAF, 0x43, 0xE3,
+       0x83, 0xB0, 0x43, 0xE3, 0x83, 0xB1, 0x43, 0xE3,
+       0x83, 0xB2, 0x43, 0xE3, 0x83, 0xB3, 0x43, 0xE3,
+       0x83, 0xBB, 0x43, 0xE3, 0x83, 0xBC, 0x43, 0xE3,
+       0x92, 0x9E, 0x43, 0xE3, 0x92, 0xB9, 0x43, 0xE3,
+       // Bytes 5c0 - 5ff
+       0x92, 0xBB, 0x43, 0xE3, 0x93, 0x9F, 0x43, 0xE3,
+       0x94, 0x95, 0x43, 0xE3, 0x9B, 0xAE, 0x43, 0xE3,
+       0x9B, 0xBC, 0x43, 0xE3, 0x9E, 0x81, 0x43, 0xE3,
+       0xA0, 0xAF, 0x43, 0xE3, 0xA1, 0xA2, 0x43, 0xE3,
+       0xA1, 0xBC, 0x43, 0xE3, 0xA3, 0x87, 0x43, 0xE3,
+       0xA3, 0xA3, 0x43, 0xE3, 0xA4, 0x9C, 0x43, 0xE3,
+       0xA4, 0xBA, 0x43, 0xE3, 0xA8, 0xAE, 0x43, 0xE3,
+       0xA9, 0xAC, 0x43, 0xE3, 0xAB, 0xA4, 0x43, 0xE3,
+       // Bytes 600 - 63f
+       0xAC, 0x88, 0x43, 0xE3, 0xAC, 0x99, 0x43, 0xE3,
+       0xAD, 0x89, 0x43, 0xE3, 0xAE, 0x9D, 0x43, 0xE3,
+       0xB0, 0x98, 0x43, 0xE3, 0xB1, 0x8E, 0x43, 0xE3,
+       0xB4, 0xB3, 0x43, 0xE3, 0xB6, 0x96, 0x43, 0xE3,
+       0xBA, 0xAC, 0x43, 0xE3, 0xBA, 0xB8, 0x43, 0xE3,
+       0xBC, 0x9B, 0x43, 0xE3, 0xBF, 0xBC, 0x43, 0xE4,
+       0x80, 0x88, 0x43, 0xE4, 0x80, 0x98, 0x43, 0xE4,
+       0x80, 0xB9, 0x43, 0xE4, 0x81, 0x86, 0x43, 0xE4,
+       // Bytes 640 - 67f
+       0x82, 0x96, 0x43, 0xE4, 0x83, 0xA3, 0x43, 0xE4,
+       0x84, 0xAF, 0x43, 0xE4, 0x88, 0x82, 0x43, 0xE4,
+       0x88, 0xA7, 0x43, 0xE4, 0x8A, 0xA0, 0x43, 0xE4,
+       0x8C, 0x81, 0x43, 0xE4, 0x8C, 0xB4, 0x43, 0xE4,
+       0x8D, 0x99, 0x43, 0xE4, 0x8F, 0x95, 0x43, 0xE4,
+       0x8F, 0x99, 0x43, 0xE4, 0x90, 0x8B, 0x43, 0xE4,
+       0x91, 0xAB, 0x43, 0xE4, 0x94, 0xAB, 0x43, 0xE4,
+       0x95, 0x9D, 0x43, 0xE4, 0x95, 0xA1, 0x43, 0xE4,
+       // Bytes 680 - 6bf
+       0x95, 0xAB, 0x43, 0xE4, 0x97, 0x97, 0x43, 0xE4,
+       0x97, 0xB9, 0x43, 0xE4, 0x98, 0xB5, 0x43, 0xE4,
+       0x9A, 0xBE, 0x43, 0xE4, 0x9B, 0x87, 0x43, 0xE4,
+       0xA6, 0x95, 0x43, 0xE4, 0xA7, 0xA6, 0x43, 0xE4,
+       0xA9, 0xAE, 0x43, 0xE4, 0xA9, 0xB6, 0x43, 0xE4,
+       0xAA, 0xB2, 0x43, 0xE4, 0xAC, 0xB3, 0x43, 0xE4,
+       0xAF, 0x8E, 0x43, 0xE4, 0xB3, 0x8E, 0x43, 0xE4,
+       0xB3, 0xAD, 0x43, 0xE4, 0xB3, 0xB8, 0x43, 0xE4,
+       // Bytes 6c0 - 6ff
+       0xB5, 0x96, 0x43, 0xE4, 0xB8, 0x80, 0x43, 0xE4,
+       0xB8, 0x81, 0x43, 0xE4, 0xB8, 0x83, 0x43, 0xE4,
+       0xB8, 0x89, 0x43, 0xE4, 0xB8, 0x8A, 0x43, 0xE4,
+       0xB8, 0x8B, 0x43, 0xE4, 0xB8, 0x8D, 0x43, 0xE4,
+       0xB8, 0x99, 0x43, 0xE4, 0xB8, 0xA6, 0x43, 0xE4,
+       0xB8, 0xA8, 0x43, 0xE4, 0xB8, 0xAD, 0x43, 0xE4,
+       0xB8, 0xB2, 0x43, 0xE4, 0xB8, 0xB6, 0x43, 0xE4,
+       0xB8, 0xB8, 0x43, 0xE4, 0xB8, 0xB9, 0x43, 0xE4,
+       // Bytes 700 - 73f
+       0xB8, 0xBD, 0x43, 0xE4, 0xB8, 0xBF, 0x43, 0xE4,
+       0xB9, 0x81, 0x43, 0xE4, 0xB9, 0x99, 0x43, 0xE4,
+       0xB9, 0x9D, 0x43, 0xE4, 0xBA, 0x82, 0x43, 0xE4,
+       0xBA, 0x85, 0x43, 0xE4, 0xBA, 0x86, 0x43, 0xE4,
+       0xBA, 0x8C, 0x43, 0xE4, 0xBA, 0x94, 0x43, 0xE4,
+       0xBA, 0xA0, 0x43, 0xE4, 0xBA, 0xA4, 0x43, 0xE4,
+       0xBA, 0xAE, 0x43, 0xE4, 0xBA, 0xBA, 0x43, 0xE4,
+       0xBB, 0x80, 0x43, 0xE4, 0xBB, 0x8C, 0x43, 0xE4,
+       // Bytes 740 - 77f
+       0xBB, 0xA4, 0x43, 0xE4, 0xBC, 0x81, 0x43, 0xE4,
+       0xBC, 0x91, 0x43, 0xE4, 0xBD, 0xA0, 0x43, 0xE4,
+       0xBE, 0x80, 0x43, 0xE4, 0xBE, 0x86, 0x43, 0xE4,
+       0xBE, 0x8B, 0x43, 0xE4, 0xBE, 0xAE, 0x43, 0xE4,
+       0xBE, 0xBB, 0x43, 0xE4, 0xBE, 0xBF, 0x43, 0xE5,
+       0x80, 0x82, 0x43, 0xE5, 0x80, 0xAB, 0x43, 0xE5,
+       0x81, 0xBA, 0x43, 0xE5, 0x82, 0x99, 0x43, 0xE5,
+       0x83, 0x8F, 0x43, 0xE5, 0x83, 0x9A, 0x43, 0xE5,
+       // Bytes 780 - 7bf
+       0x83, 0xA7, 0x43, 0xE5, 0x84, 0xAA, 0x43, 0xE5,
+       0x84, 0xBF, 0x43, 0xE5, 0x85, 0x80, 0x43, 0xE5,
+       0x85, 0x85, 0x43, 0xE5, 0x85, 0x8D, 0x43, 0xE5,
+       0x85, 0x94, 0x43, 0xE5, 0x85, 0xA4, 0x43, 0xE5,
+       0x85, 0xA5, 0x43, 0xE5, 0x85, 0xA7, 0x43, 0xE5,
+       0x85, 0xA8, 0x43, 0xE5, 0x85, 0xA9, 0x43, 0xE5,
+       0x85, 0xAB, 0x43, 0xE5, 0x85, 0xAD, 0x43, 0xE5,
+       0x85, 0xB7, 0x43, 0xE5, 0x86, 0x80, 0x43, 0xE5,
+       // Bytes 7c0 - 7ff
+       0x86, 0x82, 0x43, 0xE5, 0x86, 0x8D, 0x43, 0xE5,
+       0x86, 0x92, 0x43, 0xE5, 0x86, 0x95, 0x43, 0xE5,
+       0x86, 0x96, 0x43, 0xE5, 0x86, 0x97, 0x43, 0xE5,
+       0x86, 0x99, 0x43, 0xE5, 0x86, 0xA4, 0x43, 0xE5,
+       0x86, 0xAB, 0x43, 0xE5, 0x86, 0xAC, 0x43, 0xE5,
+       0x86, 0xB5, 0x43, 0xE5, 0x86, 0xB7, 0x43, 0xE5,
+       0x87, 0x89, 0x43, 0xE5, 0x87, 0x8C, 0x43, 0xE5,
+       0x87, 0x9C, 0x43, 0xE5, 0x87, 0x9E, 0x43, 0xE5,
+       // Bytes 800 - 83f
+       0x87, 0xA0, 0x43, 0xE5, 0x87, 0xB5, 0x43, 0xE5,
+       0x88, 0x80, 0x43, 0xE5, 0x88, 0x83, 0x43, 0xE5,
+       0x88, 0x87, 0x43, 0xE5, 0x88, 0x97, 0x43, 0xE5,
+       0x88, 0x9D, 0x43, 0xE5, 0x88, 0xA9, 0x43, 0xE5,
+       0x88, 0xBA, 0x43, 0xE5, 0x88, 0xBB, 0x43, 0xE5,
+       0x89, 0x86, 0x43, 0xE5, 0x89, 0x8D, 0x43, 0xE5,
+       0x89, 0xB2, 0x43, 0xE5, 0x89, 0xB7, 0x43, 0xE5,
+       0x8A, 0x89, 0x43, 0xE5, 0x8A, 0x9B, 0x43, 0xE5,
+       // Bytes 840 - 87f
+       0x8A, 0xA3, 0x43, 0xE5, 0x8A, 0xB3, 0x43, 0xE5,
+       0x8A, 0xB4, 0x43, 0xE5, 0x8B, 0x87, 0x43, 0xE5,
+       0x8B, 0x89, 0x43, 0xE5, 0x8B, 0x92, 0x43, 0xE5,
+       0x8B, 0x9E, 0x43, 0xE5, 0x8B, 0xA4, 0x43, 0xE5,
+       0x8B, 0xB5, 0x43, 0xE5, 0x8B, 0xB9, 0x43, 0xE5,
+       0x8B, 0xBA, 0x43, 0xE5, 0x8C, 0x85, 0x43, 0xE5,
+       0x8C, 0x86, 0x43, 0xE5, 0x8C, 0x95, 0x43, 0xE5,
+       0x8C, 0x97, 0x43, 0xE5, 0x8C, 0x9A, 0x43, 0xE5,
+       // Bytes 880 - 8bf
+       0x8C, 0xB8, 0x43, 0xE5, 0x8C, 0xBB, 0x43, 0xE5,
+       0x8C, 0xBF, 0x43, 0xE5, 0x8D, 0x81, 0x43, 0xE5,
+       0x8D, 0x84, 0x43, 0xE5, 0x8D, 0x85, 0x43, 0xE5,
+       0x8D, 0x89, 0x43, 0xE5, 0x8D, 0x91, 0x43, 0xE5,
+       0x8D, 0x94, 0x43, 0xE5, 0x8D, 0x9A, 0x43, 0xE5,
+       0x8D, 0x9C, 0x43, 0xE5, 0x8D, 0xA9, 0x43, 0xE5,
+       0x8D, 0xB0, 0x43, 0xE5, 0x8D, 0xB3, 0x43, 0xE5,
+       0x8D, 0xB5, 0x43, 0xE5, 0x8D, 0xBD, 0x43, 0xE5,
+       // Bytes 8c0 - 8ff
+       0x8D, 0xBF, 0x43, 0xE5, 0x8E, 0x82, 0x43, 0xE5,
+       0x8E, 0xB6, 0x43, 0xE5, 0x8F, 0x83, 0x43, 0xE5,
+       0x8F, 0x88, 0x43, 0xE5, 0x8F, 0x8A, 0x43, 0xE5,
+       0x8F, 0x8C, 0x43, 0xE5, 0x8F, 0x9F, 0x43, 0xE5,
+       0x8F, 0xA3, 0x43, 0xE5, 0x8F, 0xA5, 0x43, 0xE5,
+       0x8F, 0xAB, 0x43, 0xE5, 0x8F, 0xAF, 0x43, 0xE5,
+       0x8F, 0xB1, 0x43, 0xE5, 0x8F, 0xB3, 0x43, 0xE5,
+       0x90, 0x86, 0x43, 0xE5, 0x90, 0x88, 0x43, 0xE5,
+       // Bytes 900 - 93f
+       0x90, 0x8D, 0x43, 0xE5, 0x90, 0x8F, 0x43, 0xE5,
+       0x90, 0x9D, 0x43, 0xE5, 0x90, 0xB8, 0x43, 0xE5,
+       0x90, 0xB9, 0x43, 0xE5, 0x91, 0x82, 0x43, 0xE5,
+       0x91, 0x88, 0x43, 0xE5, 0x91, 0xA8, 0x43, 0xE5,
+       0x92, 0x9E, 0x43, 0xE5, 0x92, 0xA2, 0x43, 0xE5,
+       0x92, 0xBD, 0x43, 0xE5, 0x93, 0xB6, 0x43, 0xE5,
+       0x94, 0x90, 0x43, 0xE5, 0x95, 0x8F, 0x43, 0xE5,
+       0x95, 0x93, 0x43, 0xE5, 0x95, 0x95, 0x43, 0xE5,
+       // Bytes 940 - 97f
+       0x95, 0xA3, 0x43, 0xE5, 0x96, 0x84, 0x43, 0xE5,
+       0x96, 0x87, 0x43, 0xE5, 0x96, 0x99, 0x43, 0xE5,
+       0x96, 0x9D, 0x43, 0xE5, 0x96, 0xAB, 0x43, 0xE5,
+       0x96, 0xB3, 0x43, 0xE5, 0x96, 0xB6, 0x43, 0xE5,
+       0x97, 0x80, 0x43, 0xE5, 0x97, 0x82, 0x43, 0xE5,
+       0x97, 0xA2, 0x43, 0xE5, 0x98, 0x86, 0x43, 0xE5,
+       0x99, 0x91, 0x43, 0xE5, 0x99, 0xA8, 0x43, 0xE5,
+       0x99, 0xB4, 0x43, 0xE5, 0x9B, 0x97, 0x43, 0xE5,
+       // Bytes 980 - 9bf
+       0x9B, 0x9B, 0x43, 0xE5, 0x9B, 0xB9, 0x43, 0xE5,
+       0x9C, 0x96, 0x43, 0xE5, 0x9C, 0x97, 0x43, 0xE5,
+       0x9C, 0x9F, 0x43, 0xE5, 0x9C, 0xB0, 0x43, 0xE5,
+       0x9E, 0x8B, 0x43, 0xE5, 0x9F, 0x8E, 0x43, 0xE5,
+       0x9F, 0xB4, 0x43, 0xE5, 0xA0, 0x8D, 0x43, 0xE5,
+       0xA0, 0xB1, 0x43, 0xE5, 0xA0, 0xB2, 0x43, 0xE5,
+       0xA1, 0x80, 0x43, 0xE5, 0xA1, 0x9A, 0x43, 0xE5,
+       0xA1, 0x9E, 0x43, 0xE5, 0xA2, 0xA8, 0x43, 0xE5,
+       // Bytes 9c0 - 9ff
+       0xA2, 0xAC, 0x43, 0xE5, 0xA2, 0xB3, 0x43, 0xE5,
+       0xA3, 0x98, 0x43, 0xE5, 0xA3, 0x9F, 0x43, 0xE5,
+       0xA3, 0xAB, 0x43, 0xE5, 0xA3, 0xAE, 0x43, 0xE5,
+       0xA3, 0xB0, 0x43, 0xE5, 0xA3, 0xB2, 0x43, 0xE5,
+       0xA3, 0xB7, 0x43, 0xE5, 0xA4, 0x82, 0x43, 0xE5,
+       0xA4, 0x86, 0x43, 0xE5, 0xA4, 0x8A, 0x43, 0xE5,
+       0xA4, 0x95, 0x43, 0xE5, 0xA4, 0x9A, 0x43, 0xE5,
+       0xA4, 0x9C, 0x43, 0xE5, 0xA4, 0xA2, 0x43, 0xE5,
+       // Bytes a00 - a3f
+       0xA4, 0xA7, 0x43, 0xE5, 0xA4, 0xA9, 0x43, 0xE5,
+       0xA5, 0x84, 0x43, 0xE5, 0xA5, 0x88, 0x43, 0xE5,
+       0xA5, 0x91, 0x43, 0xE5, 0xA5, 0x94, 0x43, 0xE5,
+       0xA5, 0xA2, 0x43, 0xE5, 0xA5, 0xB3, 0x43, 0xE5,
+       0xA7, 0x98, 0x43, 0xE5, 0xA7, 0xAC, 0x43, 0xE5,
+       0xA8, 0x9B, 0x43, 0xE5, 0xA8, 0xA7, 0x43, 0xE5,
+       0xA9, 0xA2, 0x43, 0xE5, 0xA9, 0xA6, 0x43, 0xE5,
+       0xAA, 0xB5, 0x43, 0xE5, 0xAC, 0x88, 0x43, 0xE5,
+       // Bytes a40 - a7f
+       0xAC, 0xA8, 0x43, 0xE5, 0xAC, 0xBE, 0x43, 0xE5,
+       0xAD, 0x90, 0x43, 0xE5, 0xAD, 0x97, 0x43, 0xE5,
+       0xAD, 0xA6, 0x43, 0xE5, 0xAE, 0x80, 0x43, 0xE5,
+       0xAE, 0x85, 0x43, 0xE5, 0xAE, 0x97, 0x43, 0xE5,
+       0xAF, 0x83, 0x43, 0xE5, 0xAF, 0x98, 0x43, 0xE5,
+       0xAF, 0xA7, 0x43, 0xE5, 0xAF, 0xAE, 0x43, 0xE5,
+       0xAF, 0xB3, 0x43, 0xE5, 0xAF, 0xB8, 0x43, 0xE5,
+       0xAF, 0xBF, 0x43, 0xE5, 0xB0, 0x86, 0x43, 0xE5,
+       // Bytes a80 - abf
+       0xB0, 0x8F, 0x43, 0xE5, 0xB0, 0xA2, 0x43, 0xE5,
+       0xB0, 0xB8, 0x43, 0xE5, 0xB0, 0xBF, 0x43, 0xE5,
+       0xB1, 0xA0, 0x43, 0xE5, 0xB1, 0xA2, 0x43, 0xE5,
+       0xB1, 0xA4, 0x43, 0xE5, 0xB1, 0xA5, 0x43, 0xE5,
+       0xB1, 0xAE, 0x43, 0xE5, 0xB1, 0xB1, 0x43, 0xE5,
+       0xB2, 0x8D, 0x43, 0xE5, 0xB3, 0x80, 0x43, 0xE5,
+       0xB4, 0x99, 0x43, 0xE5, 0xB5, 0x83, 0x43, 0xE5,
+       0xB5, 0x90, 0x43, 0xE5, 0xB5, 0xAB, 0x43, 0xE5,
+       // Bytes ac0 - aff
+       0xB5, 0xAE, 0x43, 0xE5, 0xB5, 0xBC, 0x43, 0xE5,
+       0xB6, 0xB2, 0x43, 0xE5, 0xB6, 0xBA, 0x43, 0xE5,
+       0xB7, 0x9B, 0x43, 0xE5, 0xB7, 0xA1, 0x43, 0xE5,
+       0xB7, 0xA2, 0x43, 0xE5, 0xB7, 0xA5, 0x43, 0xE5,
+       0xB7, 0xA6, 0x43, 0xE5, 0xB7, 0xB1, 0x43, 0xE5,
+       0xB7, 0xBD, 0x43, 0xE5, 0xB7, 0xBE, 0x43, 0xE5,
+       0xB8, 0xA8, 0x43, 0xE5, 0xB8, 0xBD, 0x43, 0xE5,
+       0xB9, 0xA9, 0x43, 0xE5, 0xB9, 0xB2, 0x43, 0xE5,
+       // Bytes b00 - b3f
+       0xB9, 0xB4, 0x43, 0xE5, 0xB9, 0xBA, 0x43, 0xE5,
+       0xB9, 0xBC, 0x43, 0xE5, 0xB9, 0xBF, 0x43, 0xE5,
+       0xBA, 0xA6, 0x43, 0xE5, 0xBA, 0xB0, 0x43, 0xE5,
+       0xBA, 0xB3, 0x43, 0xE5, 0xBA, 0xB6, 0x43, 0xE5,
+       0xBB, 0x89, 0x43, 0xE5, 0xBB, 0x8A, 0x43, 0xE5,
+       0xBB, 0x92, 0x43, 0xE5, 0xBB, 0x93, 0x43, 0xE5,
+       0xBB, 0x99, 0x43, 0xE5, 0xBB, 0xAC, 0x43, 0xE5,
+       0xBB, 0xB4, 0x43, 0xE5, 0xBB, 0xBE, 0x43, 0xE5,
+       // Bytes b40 - b7f
+       0xBC, 0x84, 0x43, 0xE5, 0xBC, 0x8B, 0x43, 0xE5,
+       0xBC, 0x93, 0x43, 0xE5, 0xBC, 0xA2, 0x43, 0xE5,
+       0xBD, 0x90, 0x43, 0xE5, 0xBD, 0x93, 0x43, 0xE5,
+       0xBD, 0xA1, 0x43, 0xE5, 0xBD, 0xA2, 0x43, 0xE5,
+       0xBD, 0xA9, 0x43, 0xE5, 0xBD, 0xAB, 0x43, 0xE5,
+       0xBD, 0xB3, 0x43, 0xE5, 0xBE, 0x8B, 0x43, 0xE5,
+       0xBE, 0x8C, 0x43, 0xE5, 0xBE, 0x97, 0x43, 0xE5,
+       0xBE, 0x9A, 0x43, 0xE5, 0xBE, 0xA9, 0x43, 0xE5,
+       // Bytes b80 - bbf
+       0xBE, 0xAD, 0x43, 0xE5, 0xBF, 0x83, 0x43, 0xE5,
+       0xBF, 0x8D, 0x43, 0xE5, 0xBF, 0x97, 0x43, 0xE5,
+       0xBF, 0xB5, 0x43, 0xE5, 0xBF, 0xB9, 0x43, 0xE6,
+       0x80, 0x92, 0x43, 0xE6, 0x80, 0x9C, 0x43, 0xE6,
+       0x81, 0xB5, 0x43, 0xE6, 0x82, 0x81, 0x43, 0xE6,
+       0x82, 0x94, 0x43, 0xE6, 0x83, 0x87, 0x43, 0xE6,
+       0x83, 0x98, 0x43, 0xE6, 0x83, 0xA1, 0x43, 0xE6,
+       0x84, 0x88, 0x43, 0xE6, 0x85, 0x84, 0x43, 0xE6,
+       // Bytes bc0 - bff
+       0x85, 0x88, 0x43, 0xE6, 0x85, 0x8C, 0x43, 0xE6,
+       0x85, 0x8E, 0x43, 0xE6, 0x85, 0xA0, 0x43, 0xE6,
+       0x85, 0xA8, 0x43, 0xE6, 0x85, 0xBA, 0x43, 0xE6,
+       0x86, 0x8E, 0x43, 0xE6, 0x86, 0x90, 0x43, 0xE6,
+       0x86, 0xA4, 0x43, 0xE6, 0x86, 0xAF, 0x43, 0xE6,
+       0x86, 0xB2, 0x43, 0xE6, 0x87, 0x9E, 0x43, 0xE6,
+       0x87, 0xB2, 0x43, 0xE6, 0x87, 0xB6, 0x43, 0xE6,
+       0x88, 0x80, 0x43, 0xE6, 0x88, 0x88, 0x43, 0xE6,
+       // Bytes c00 - c3f
+       0x88, 0x90, 0x43, 0xE6, 0x88, 0x9B, 0x43, 0xE6,
+       0x88, 0xAE, 0x43, 0xE6, 0x88, 0xB4, 0x43, 0xE6,
+       0x88, 0xB6, 0x43, 0xE6, 0x89, 0x8B, 0x43, 0xE6,
+       0x89, 0x93, 0x43, 0xE6, 0x89, 0x9D, 0x43, 0xE6,
+       0x8A, 0x95, 0x43, 0xE6, 0x8A, 0xB1, 0x43, 0xE6,
+       0x8B, 0x89, 0x43, 0xE6, 0x8B, 0x8F, 0x43, 0xE6,
+       0x8B, 0x93, 0x43, 0xE6, 0x8B, 0x94, 0x43, 0xE6,
+       0x8B, 0xBC, 0x43, 0xE6, 0x8B, 0xBE, 0x43, 0xE6,
+       // Bytes c40 - c7f
+       0x8C, 0x87, 0x43, 0xE6, 0x8C, 0xBD, 0x43, 0xE6,
+       0x8D, 0x90, 0x43, 0xE6, 0x8D, 0x95, 0x43, 0xE6,
+       0x8D, 0xA8, 0x43, 0xE6, 0x8D, 0xBB, 0x43, 0xE6,
+       0x8E, 0x83, 0x43, 0xE6, 0x8E, 0xA0, 0x43, 0xE6,
+       0x8E, 0xA9, 0x43, 0xE6, 0x8F, 0x84, 0x43, 0xE6,
+       0x8F, 0x85, 0x43, 0xE6, 0x8F, 0xA4, 0x43, 0xE6,
+       0x90, 0x9C, 0x43, 0xE6, 0x90, 0xA2, 0x43, 0xE6,
+       0x91, 0x92, 0x43, 0xE6, 0x91, 0xA9, 0x43, 0xE6,
+       // Bytes c80 - cbf
+       0x91, 0xB7, 0x43, 0xE6, 0x91, 0xBE, 0x43, 0xE6,
+       0x92, 0x9A, 0x43, 0xE6, 0x92, 0x9D, 0x43, 0xE6,
+       0x93, 0x84, 0x43, 0xE6, 0x94, 0xAF, 0x43, 0xE6,
+       0x94, 0xB4, 0x43, 0xE6, 0x95, 0x8F, 0x43, 0xE6,
+       0x95, 0x96, 0x43, 0xE6, 0x95, 0xAC, 0x43, 0xE6,
+       0x95, 0xB8, 0x43, 0xE6, 0x96, 0x87, 0x43, 0xE6,
+       0x96, 0x97, 0x43, 0xE6, 0x96, 0x99, 0x43, 0xE6,
+       0x96, 0xA4, 0x43, 0xE6, 0x96, 0xB0, 0x43, 0xE6,
+       // Bytes cc0 - cff
+       0x96, 0xB9, 0x43, 0xE6, 0x97, 0x85, 0x43, 0xE6,
+       0x97, 0xA0, 0x43, 0xE6, 0x97, 0xA2, 0x43, 0xE6,
+       0x97, 0xA3, 0x43, 0xE6, 0x97, 0xA5, 0x43, 0xE6,
+       0x98, 0x93, 0x43, 0xE6, 0x98, 0xA0, 0x43, 0xE6,
+       0x99, 0x89, 0x43, 0xE6, 0x99, 0xB4, 0x43, 0xE6,
+       0x9A, 0x88, 0x43, 0xE6, 0x9A, 0x91, 0x43, 0xE6,
+       0x9A, 0x9C, 0x43, 0xE6, 0x9A, 0xB4, 0x43, 0xE6,
+       0x9B, 0x86, 0x43, 0xE6, 0x9B, 0xB0, 0x43, 0xE6,
+       // Bytes d00 - d3f
+       0x9B, 0xB4, 0x43, 0xE6, 0x9B, 0xB8, 0x43, 0xE6,
+       0x9C, 0x80, 0x43, 0xE6, 0x9C, 0x88, 0x43, 0xE6,
+       0x9C, 0x89, 0x43, 0xE6, 0x9C, 0x97, 0x43, 0xE6,
+       0x9C, 0x9B, 0x43, 0xE6, 0x9C, 0xA1, 0x43, 0xE6,
+       0x9C, 0xA8, 0x43, 0xE6, 0x9D, 0x8E, 0x43, 0xE6,
+       0x9D, 0x93, 0x43, 0xE6, 0x9D, 0x96, 0x43, 0xE6,
+       0x9D, 0x9E, 0x43, 0xE6, 0x9D, 0xBB, 0x43, 0xE6,
+       0x9E, 0x85, 0x43, 0xE6, 0x9E, 0x97, 0x43, 0xE6,
+       // Bytes d40 - d7f
+       0x9F, 0xB3, 0x43, 0xE6, 0x9F, 0xBA, 0x43, 0xE6,
+       0xA0, 0x97, 0x43, 0xE6, 0xA0, 0x9F, 0x43, 0xE6,
+       0xA0, 0xAA, 0x43, 0xE6, 0xA1, 0x92, 0x43, 0xE6,
+       0xA2, 0x81, 0x43, 0xE6, 0xA2, 0x85, 0x43, 0xE6,
+       0xA2, 0x8E, 0x43, 0xE6, 0xA2, 0xA8, 0x43, 0xE6,
+       0xA4, 0x94, 0x43, 0xE6, 0xA5, 0x82, 0x43, 0xE6,
+       0xA6, 0xA3, 0x43, 0xE6, 0xA7, 0xAA, 0x43, 0xE6,
+       0xA8, 0x82, 0x43, 0xE6, 0xA8, 0x93, 0x43, 0xE6,
+       // Bytes d80 - dbf
+       0xAA, 0xA8, 0x43, 0xE6, 0xAB, 0x93, 0x43, 0xE6,
+       0xAB, 0x9B, 0x43, 0xE6, 0xAC, 0x84, 0x43, 0xE6,
+       0xAC, 0xA0, 0x43, 0xE6, 0xAC, 0xA1, 0x43, 0xE6,
+       0xAD, 0x94, 0x43, 0xE6, 0xAD, 0xA2, 0x43, 0xE6,
+       0xAD, 0xA3, 0x43, 0xE6, 0xAD, 0xB2, 0x43, 0xE6,
+       0xAD, 0xB7, 0x43, 0xE6, 0xAD, 0xB9, 0x43, 0xE6,
+       0xAE, 0x9F, 0x43, 0xE6, 0xAE, 0xAE, 0x43, 0xE6,
+       0xAE, 0xB3, 0x43, 0xE6, 0xAE, 0xBA, 0x43, 0xE6,
+       // Bytes dc0 - dff
+       0xAE, 0xBB, 0x43, 0xE6, 0xAF, 0x8B, 0x43, 0xE6,
+       0xAF, 0x8D, 0x43, 0xE6, 0xAF, 0x94, 0x43, 0xE6,
+       0xAF, 0x9B, 0x43, 0xE6, 0xB0, 0x8F, 0x43, 0xE6,
+       0xB0, 0x94, 0x43, 0xE6, 0xB0, 0xB4, 0x43, 0xE6,
+       0xB1, 0x8E, 0x43, 0xE6, 0xB1, 0xA7, 0x43, 0xE6,
+       0xB2, 0x88, 0x43, 0xE6, 0xB2, 0xBF, 0x43, 0xE6,
+       0xB3, 0x8C, 0x43, 0xE6, 0xB3, 0x8D, 0x43, 0xE6,
+       0xB3, 0xA5, 0x43, 0xE6, 0xB3, 0xA8, 0x43, 0xE6,
+       // Bytes e00 - e3f
+       0xB4, 0x96, 0x43, 0xE6, 0xB4, 0x9B, 0x43, 0xE6,
+       0xB4, 0x9E, 0x43, 0xE6, 0xB4, 0xB4, 0x43, 0xE6,
+       0xB4, 0xBE, 0x43, 0xE6, 0xB5, 0x81, 0x43, 0xE6,
+       0xB5, 0xA9, 0x43, 0xE6, 0xB5, 0xAA, 0x43, 0xE6,
+       0xB5, 0xB7, 0x43, 0xE6, 0xB5, 0xB8, 0x43, 0xE6,
+       0xB6, 0x85, 0x43, 0xE6, 0xB7, 0x8B, 0x43, 0xE6,
+       0xB7, 0x9A, 0x43, 0xE6, 0xB7, 0xAA, 0x43, 0xE6,
+       0xB7, 0xB9, 0x43, 0xE6, 0xB8, 0x9A, 0x43, 0xE6,
+       // Bytes e40 - e7f
+       0xB8, 0xAF, 0x43, 0xE6, 0xB9, 0xAE, 0x43, 0xE6,
+       0xBA, 0x80, 0x43, 0xE6, 0xBA, 0x9C, 0x43, 0xE6,
+       0xBA, 0xBA, 0x43, 0xE6, 0xBB, 0x87, 0x43, 0xE6,
+       0xBB, 0x8B, 0x43, 0xE6, 0xBB, 0x91, 0x43, 0xE6,
+       0xBB, 0x9B, 0x43, 0xE6, 0xBC, 0x8F, 0x43, 0xE6,
+       0xBC, 0x94, 0x43, 0xE6, 0xBC, 0xA2, 0x43, 0xE6,
+       0xBC, 0xA3, 0x43, 0xE6, 0xBD, 0xAE, 0x43, 0xE6,
+       0xBF, 0x86, 0x43, 0xE6, 0xBF, 0xAB, 0x43, 0xE6,
+       // Bytes e80 - ebf
+       0xBF, 0xBE, 0x43, 0xE7, 0x80, 0x9B, 0x43, 0xE7,
+       0x80, 0x9E, 0x43, 0xE7, 0x80, 0xB9, 0x43, 0xE7,
+       0x81, 0x8A, 0x43, 0xE7, 0x81, 0xAB, 0x43, 0xE7,
+       0x81, 0xB0, 0x43, 0xE7, 0x81, 0xB7, 0x43, 0xE7,
+       0x81, 0xBD, 0x43, 0xE7, 0x82, 0x99, 0x43, 0xE7,
+       0x82, 0xAD, 0x43, 0xE7, 0x83, 0x88, 0x43, 0xE7,
+       0x83, 0x99, 0x43, 0xE7, 0x84, 0xA1, 0x43, 0xE7,
+       0x85, 0x85, 0x43, 0xE7, 0x85, 0x89, 0x43, 0xE7,
+       // Bytes ec0 - eff
+       0x85, 0xAE, 0x43, 0xE7, 0x86, 0x9C, 0x43, 0xE7,
+       0x87, 0x8E, 0x43, 0xE7, 0x87, 0x90, 0x43, 0xE7,
+       0x88, 0x90, 0x43, 0xE7, 0x88, 0x9B, 0x43, 0xE7,
+       0x88, 0xA8, 0x43, 0xE7, 0x88, 0xAA, 0x43, 0xE7,
+       0x88, 0xAB, 0x43, 0xE7, 0x88, 0xB5, 0x43, 0xE7,
+       0x88, 0xB6, 0x43, 0xE7, 0x88, 0xBB, 0x43, 0xE7,
+       0x88, 0xBF, 0x43, 0xE7, 0x89, 0x87, 0x43, 0xE7,
+       0x89, 0x90, 0x43, 0xE7, 0x89, 0x99, 0x43, 0xE7,
+       // Bytes f00 - f3f
+       0x89, 0x9B, 0x43, 0xE7, 0x89, 0xA2, 0x43, 0xE7,
+       0x89, 0xB9, 0x43, 0xE7, 0x8A, 0x80, 0x43, 0xE7,
+       0x8A, 0x95, 0x43, 0xE7, 0x8A, 0xAC, 0x43, 0xE7,
+       0x8A, 0xAF, 0x43, 0xE7, 0x8B, 0x80, 0x43, 0xE7,
+       0x8B, 0xBC, 0x43, 0xE7, 0x8C, 0xAA, 0x43, 0xE7,
+       0x8D, 0xB5, 0x43, 0xE7, 0x8D, 0xBA, 0x43, 0xE7,
+       0x8E, 0x84, 0x43, 0xE7, 0x8E, 0x87, 0x43, 0xE7,
+       0x8E, 0x89, 0x43, 0xE7, 0x8E, 0x8B, 0x43, 0xE7,
+       // Bytes f40 - f7f
+       0x8E, 0xA5, 0x43, 0xE7, 0x8E, 0xB2, 0x43, 0xE7,
+       0x8F, 0x9E, 0x43, 0xE7, 0x90, 0x86, 0x43, 0xE7,
+       0x90, 0x89, 0x43, 0xE7, 0x90, 0xA2, 0x43, 0xE7,
+       0x91, 0x87, 0x43, 0xE7, 0x91, 0x9C, 0x43, 0xE7,
+       0x91, 0xA9, 0x43, 0xE7, 0x91, 0xB1, 0x43, 0xE7,
+       0x92, 0x85, 0x43, 0xE7, 0x92, 0x89, 0x43, 0xE7,
+       0x92, 0x98, 0x43, 0xE7, 0x93, 0x8A, 0x43, 0xE7,
+       0x93, 0x9C, 0x43, 0xE7, 0x93, 0xA6, 0x43, 0xE7,
+       // Bytes f80 - fbf
+       0x94, 0x86, 0x43, 0xE7, 0x94, 0x98, 0x43, 0xE7,
+       0x94, 0x9F, 0x43, 0xE7, 0x94, 0xA4, 0x43, 0xE7,
+       0x94, 0xA8, 0x43, 0xE7, 0x94, 0xB0, 0x43, 0xE7,
+       0x94, 0xB2, 0x43, 0xE7, 0x94, 0xB3, 0x43, 0xE7,
+       0x94, 0xB7, 0x43, 0xE7, 0x94, 0xBB, 0x43, 0xE7,
+       0x94, 0xBE, 0x43, 0xE7, 0x95, 0x99, 0x43, 0xE7,
+       0x95, 0xA5, 0x43, 0xE7, 0x95, 0xB0, 0x43, 0xE7,
+       0x96, 0x8B, 0x43, 0xE7, 0x96, 0x92, 0x43, 0xE7,
+       // Bytes fc0 - fff
+       0x97, 0xA2, 0x43, 0xE7, 0x98, 0x90, 0x43, 0xE7,
+       0x98, 0x9D, 0x43, 0xE7, 0x98, 0x9F, 0x43, 0xE7,
+       0x99, 0x82, 0x43, 0xE7, 0x99, 0xA9, 0x43, 0xE7,
+       0x99, 0xB6, 0x43, 0xE7, 0x99, 0xBD, 0x43, 0xE7,
+       0x9A, 0xAE, 0x43, 0xE7, 0x9A, 0xBF, 0x43, 0xE7,
+       0x9B, 0x8A, 0x43, 0xE7, 0x9B, 0x9B, 0x43, 0xE7,
+       0x9B, 0xA3, 0x43, 0xE7, 0x9B, 0xA7, 0x43, 0xE7,
+       0x9B, 0xAE, 0x43, 0xE7, 0x9B, 0xB4, 0x43, 0xE7,
+       // Bytes 1000 - 103f
+       0x9C, 0x81, 0x43, 0xE7, 0x9C, 0x9E, 0x43, 0xE7,
+       0x9C, 0x9F, 0x43, 0xE7, 0x9D, 0x80, 0x43, 0xE7,
+       0x9D, 0x8A, 0x43, 0xE7, 0x9E, 0x8B, 0x43, 0xE7,
+       0x9E, 0xA7, 0x43, 0xE7, 0x9F, 0x9B, 0x43, 0xE7,
+       0x9F, 0xA2, 0x43, 0xE7, 0x9F, 0xB3, 0x43, 0xE7,
+       0xA1, 0x8E, 0x43, 0xE7, 0xA1, 0xAB, 0x43, 0xE7,
+       0xA2, 0x8C, 0x43, 0xE7, 0xA2, 0x91, 0x43, 0xE7,
+       0xA3, 0x8A, 0x43, 0xE7, 0xA3, 0x8C, 0x43, 0xE7,
+       // Bytes 1040 - 107f
+       0xA3, 0xBB, 0x43, 0xE7, 0xA4, 0xAA, 0x43, 0xE7,
+       0xA4, 0xBA, 0x43, 0xE7, 0xA4, 0xBC, 0x43, 0xE7,
+       0xA4, 0xBE, 0x43, 0xE7, 0xA5, 0x88, 0x43, 0xE7,
+       0xA5, 0x89, 0x43, 0xE7, 0xA5, 0x90, 0x43, 0xE7,
+       0xA5, 0x96, 0x43, 0xE7, 0xA5, 0x9D, 0x43, 0xE7,
+       0xA5, 0x9E, 0x43, 0xE7, 0xA5, 0xA5, 0x43, 0xE7,
+       0xA5, 0xBF, 0x43, 0xE7, 0xA6, 0x81, 0x43, 0xE7,
+       0xA6, 0x8D, 0x43, 0xE7, 0xA6, 0x8E, 0x43, 0xE7,
+       // Bytes 1080 - 10bf
+       0xA6, 0x8F, 0x43, 0xE7, 0xA6, 0xAE, 0x43, 0xE7,
+       0xA6, 0xB8, 0x43, 0xE7, 0xA6, 0xBE, 0x43, 0xE7,
+       0xA7, 0x8A, 0x43, 0xE7, 0xA7, 0x98, 0x43, 0xE7,
+       0xA7, 0xAB, 0x43, 0xE7, 0xA8, 0x9C, 0x43, 0xE7,
+       0xA9, 0x80, 0x43, 0xE7, 0xA9, 0x8A, 0x43, 0xE7,
+       0xA9, 0x8F, 0x43, 0xE7, 0xA9, 0xB4, 0x43, 0xE7,
+       0xA9, 0xBA, 0x43, 0xE7, 0xAA, 0x81, 0x43, 0xE7,
+       0xAA, 0xB1, 0x43, 0xE7, 0xAB, 0x8B, 0x43, 0xE7,
+       // Bytes 10c0 - 10ff
+       0xAB, 0xAE, 0x43, 0xE7, 0xAB, 0xB9, 0x43, 0xE7,
+       0xAC, 0xA0, 0x43, 0xE7, 0xAE, 0x8F, 0x43, 0xE7,
+       0xAF, 0x80, 0x43, 0xE7, 0xAF, 0x86, 0x43, 0xE7,
+       0xAF, 0x89, 0x43, 0xE7, 0xB0, 0xBE, 0x43, 0xE7,
+       0xB1, 0xA0, 0x43, 0xE7, 0xB1, 0xB3, 0x43, 0xE7,
+       0xB1, 0xBB, 0x43, 0xE7, 0xB2, 0x92, 0x43, 0xE7,
+       0xB2, 0xBE, 0x43, 0xE7, 0xB3, 0x92, 0x43, 0xE7,
+       0xB3, 0x96, 0x43, 0xE7, 0xB3, 0xA3, 0x43, 0xE7,
+       // Bytes 1100 - 113f
+       0xB3, 0xA7, 0x43, 0xE7, 0xB3, 0xA8, 0x43, 0xE7,
+       0xB3, 0xB8, 0x43, 0xE7, 0xB4, 0x80, 0x43, 0xE7,
+       0xB4, 0x90, 0x43, 0xE7, 0xB4, 0xA2, 0x43, 0xE7,
+       0xB4, 0xAF, 0x43, 0xE7, 0xB5, 0x82, 0x43, 0xE7,
+       0xB5, 0x9B, 0x43, 0xE7, 0xB5, 0xA3, 0x43, 0xE7,
+       0xB6, 0xA0, 0x43, 0xE7, 0xB6, 0xBE, 0x43, 0xE7,
+       0xB7, 0x87, 0x43, 0xE7, 0xB7, 0xB4, 0x43, 0xE7,
+       0xB8, 0x82, 0x43, 0xE7, 0xB8, 0x89, 0x43, 0xE7,
+       // Bytes 1140 - 117f
+       0xB8, 0xB7, 0x43, 0xE7, 0xB9, 0x81, 0x43, 0xE7,
+       0xB9, 0x85, 0x43, 0xE7, 0xBC, 0xB6, 0x43, 0xE7,
+       0xBC, 0xBE, 0x43, 0xE7, 0xBD, 0x91, 0x43, 0xE7,
+       0xBD, 0xB2, 0x43, 0xE7, 0xBD, 0xB9, 0x43, 0xE7,
+       0xBD, 0xBA, 0x43, 0xE7, 0xBE, 0x85, 0x43, 0xE7,
+       0xBE, 0x8A, 0x43, 0xE7, 0xBE, 0x95, 0x43, 0xE7,
+       0xBE, 0x9A, 0x43, 0xE7, 0xBE, 0xBD, 0x43, 0xE7,
+       0xBF, 0xBA, 0x43, 0xE8, 0x80, 0x81, 0x43, 0xE8,
+       // Bytes 1180 - 11bf
+       0x80, 0x85, 0x43, 0xE8, 0x80, 0x8C, 0x43, 0xE8,
+       0x80, 0x92, 0x43, 0xE8, 0x80, 0xB3, 0x43, 0xE8,
+       0x81, 0x86, 0x43, 0xE8, 0x81, 0xA0, 0x43, 0xE8,
+       0x81, 0xAF, 0x43, 0xE8, 0x81, 0xB0, 0x43, 0xE8,
+       0x81, 0xBE, 0x43, 0xE8, 0x81, 0xBF, 0x43, 0xE8,
+       0x82, 0x89, 0x43, 0xE8, 0x82, 0x8B, 0x43, 0xE8,
+       0x82, 0xAD, 0x43, 0xE8, 0x82, 0xB2, 0x43, 0xE8,
+       0x84, 0x83, 0x43, 0xE8, 0x84, 0xBE, 0x43, 0xE8,
+       // Bytes 11c0 - 11ff
+       0x87, 0x98, 0x43, 0xE8, 0x87, 0xA3, 0x43, 0xE8,
+       0x87, 0xA8, 0x43, 0xE8, 0x87, 0xAA, 0x43, 0xE8,
+       0x87, 0xAD, 0x43, 0xE8, 0x87, 0xB3, 0x43, 0xE8,
+       0x87, 0xBC, 0x43, 0xE8, 0x88, 0x81, 0x43, 0xE8,
+       0x88, 0x84, 0x43, 0xE8, 0x88, 0x8C, 0x43, 0xE8,
+       0x88, 0x98, 0x43, 0xE8, 0x88, 0x9B, 0x43, 0xE8,
+       0x88, 0x9F, 0x43, 0xE8, 0x89, 0xAE, 0x43, 0xE8,
+       0x89, 0xAF, 0x43, 0xE8, 0x89, 0xB2, 0x43, 0xE8,
+       // Bytes 1200 - 123f
+       0x89, 0xB8, 0x43, 0xE8, 0x89, 0xB9, 0x43, 0xE8,
+       0x8A, 0x8B, 0x43, 0xE8, 0x8A, 0x91, 0x43, 0xE8,
+       0x8A, 0x9D, 0x43, 0xE8, 0x8A, 0xB1, 0x43, 0xE8,
+       0x8A, 0xB3, 0x43, 0xE8, 0x8A, 0xBD, 0x43, 0xE8,
+       0x8B, 0xA5, 0x43, 0xE8, 0x8B, 0xA6, 0x43, 0xE8,
+       0x8C, 0x9D, 0x43, 0xE8, 0x8C, 0xA3, 0x43, 0xE8,
+       0x8C, 0xB6, 0x43, 0xE8, 0x8D, 0x92, 0x43, 0xE8,
+       0x8D, 0x93, 0x43, 0xE8, 0x8D, 0xA3, 0x43, 0xE8,
+       // Bytes 1240 - 127f
+       0x8E, 0xAD, 0x43, 0xE8, 0x8E, 0xBD, 0x43, 0xE8,
+       0x8F, 0x89, 0x43, 0xE8, 0x8F, 0x8A, 0x43, 0xE8,
+       0x8F, 0x8C, 0x43, 0xE8, 0x8F, 0x9C, 0x43, 0xE8,
+       0x8F, 0xA7, 0x43, 0xE8, 0x8F, 0xAF, 0x43, 0xE8,
+       0x8F, 0xB1, 0x43, 0xE8, 0x90, 0xBD, 0x43, 0xE8,
+       0x91, 0x89, 0x43, 0xE8, 0x91, 0x97, 0x43, 0xE8,
+       0x93, 0xAE, 0x43, 0xE8, 0x93, 0xB1, 0x43, 0xE8,
+       0x93, 0xB3, 0x43, 0xE8, 0x93, 0xBC, 0x43, 0xE8,
+       // Bytes 1280 - 12bf
+       0x94, 0x96, 0x43, 0xE8, 0x95, 0xA4, 0x43, 0xE8,
+       0x97, 0x8D, 0x43, 0xE8, 0x97, 0xBA, 0x43, 0xE8,
+       0x98, 0x86, 0x43, 0xE8, 0x98, 0x92, 0x43, 0xE8,
+       0x98, 0xAD, 0x43, 0xE8, 0x98, 0xBF, 0x43, 0xE8,
+       0x99, 0x8D, 0x43, 0xE8, 0x99, 0x90, 0x43, 0xE8,
+       0x99, 0x9C, 0x43, 0xE8, 0x99, 0xA7, 0x43, 0xE8,
+       0x99, 0xA9, 0x43, 0xE8, 0x99, 0xAB, 0x43, 0xE8,
+       0x9A, 0x88, 0x43, 0xE8, 0x9A, 0xA9, 0x43, 0xE8,
+       // Bytes 12c0 - 12ff
+       0x9B, 0xA2, 0x43, 0xE8, 0x9C, 0x8E, 0x43, 0xE8,
+       0x9C, 0xA8, 0x43, 0xE8, 0x9D, 0xAB, 0x43, 0xE8,
+       0x9D, 0xB9, 0x43, 0xE8, 0x9E, 0x86, 0x43, 0xE8,
+       0x9E, 0xBA, 0x43, 0xE8, 0x9F, 0xA1, 0x43, 0xE8,
+       0xA0, 0x81, 0x43, 0xE8, 0xA0, 0x9F, 0x43, 0xE8,
+       0xA1, 0x80, 0x43, 0xE8, 0xA1, 0x8C, 0x43, 0xE8,
+       0xA1, 0xA0, 0x43, 0xE8, 0xA1, 0xA3, 0x43, 0xE8,
+       0xA3, 0x82, 0x43, 0xE8, 0xA3, 0x8F, 0x43, 0xE8,
+       // Bytes 1300 - 133f
+       0xA3, 0x97, 0x43, 0xE8, 0xA3, 0x9E, 0x43, 0xE8,
+       0xA3, 0xA1, 0x43, 0xE8, 0xA3, 0xB8, 0x43, 0xE8,
+       0xA3, 0xBA, 0x43, 0xE8, 0xA4, 0x90, 0x43, 0xE8,
+       0xA5, 0x81, 0x43, 0xE8, 0xA5, 0xA4, 0x43, 0xE8,
+       0xA5, 0xBE, 0x43, 0xE8, 0xA6, 0x86, 0x43, 0xE8,
+       0xA6, 0x8B, 0x43, 0xE8, 0xA6, 0x96, 0x43, 0xE8,
+       0xA7, 0x92, 0x43, 0xE8, 0xA7, 0xA3, 0x43, 0xE8,
+       0xA8, 0x80, 0x43, 0xE8, 0xAA, 0xA0, 0x43, 0xE8,
+       // Bytes 1340 - 137f
+       0xAA, 0xAA, 0x43, 0xE8, 0xAA, 0xBF, 0x43, 0xE8,
+       0xAB, 0x8B, 0x43, 0xE8, 0xAB, 0x92, 0x43, 0xE8,
+       0xAB, 0x96, 0x43, 0xE8, 0xAB, 0xAD, 0x43, 0xE8,
+       0xAB, 0xB8, 0x43, 0xE8, 0xAB, 0xBE, 0x43, 0xE8,
+       0xAC, 0x81, 0x43, 0xE8, 0xAC, 0xB9, 0x43, 0xE8,
+       0xAD, 0x98, 0x43, 0xE8, 0xAE, 0x80, 0x43, 0xE8,
+       0xAE, 0x8A, 0x43, 0xE8, 0xB0, 0xB7, 0x43, 0xE8,
+       0xB1, 0x86, 0x43, 0xE8, 0xB1, 0x88, 0x43, 0xE8,
+       // Bytes 1380 - 13bf
+       0xB1, 0x95, 0x43, 0xE8, 0xB1, 0xB8, 0x43, 0xE8,
+       0xB2, 0x9D, 0x43, 0xE8, 0xB2, 0xA1, 0x43, 0xE8,
+       0xB2, 0xA9, 0x43, 0xE8, 0xB2, 0xAB, 0x43, 0xE8,
+       0xB3, 0x81, 0x43, 0xE8, 0xB3, 0x82, 0x43, 0xE8,
+       0xB3, 0x87, 0x43, 0xE8, 0xB3, 0x88, 0x43, 0xE8,
+       0xB3, 0x93, 0x43, 0xE8, 0xB4, 0x88, 0x43, 0xE8,
+       0xB4, 0x9B, 0x43, 0xE8, 0xB5, 0xA4, 0x43, 0xE8,
+       0xB5, 0xB0, 0x43, 0xE8, 0xB5, 0xB7, 0x43, 0xE8,
+       // Bytes 13c0 - 13ff
+       0xB6, 0xB3, 0x43, 0xE8, 0xB6, 0xBC, 0x43, 0xE8,
+       0xB7, 0x8B, 0x43, 0xE8, 0xB7, 0xAF, 0x43, 0xE8,
+       0xB7, 0xB0, 0x43, 0xE8, 0xBA, 0xAB, 0x43, 0xE8,
+       0xBB, 0x8A, 0x43, 0xE8, 0xBB, 0x94, 0x43, 0xE8,
+       0xBC, 0xA6, 0x43, 0xE8, 0xBC, 0xAA, 0x43, 0xE8,
+       0xBC, 0xB8, 0x43, 0xE8, 0xBC, 0xBB, 0x43, 0xE8,
+       0xBD, 0xA2, 0x43, 0xE8, 0xBE, 0x9B, 0x43, 0xE8,
+       0xBE, 0x9E, 0x43, 0xE8, 0xBE, 0xB0, 0x43, 0xE8,
+       // Bytes 1400 - 143f
+       0xBE, 0xB5, 0x43, 0xE8, 0xBE, 0xB6, 0x43, 0xE9,
+       0x80, 0xA3, 0x43, 0xE9, 0x80, 0xB8, 0x43, 0xE9,
+       0x81, 0x8A, 0x43, 0xE9, 0x81, 0xA9, 0x43, 0xE9,
+       0x81, 0xB2, 0x43, 0xE9, 0x81, 0xBC, 0x43, 0xE9,
+       0x82, 0x8F, 0x43, 0xE9, 0x82, 0x91, 0x43, 0xE9,
+       0x82, 0x94, 0x43, 0xE9, 0x83, 0x8E, 0x43, 0xE9,
+       0x83, 0x9E, 0x43, 0xE9, 0x83, 0xB1, 0x43, 0xE9,
+       0x83, 0xBD, 0x43, 0xE9, 0x84, 0x91, 0x43, 0xE9,
+       // Bytes 1440 - 147f
+       0x84, 0x9B, 0x43, 0xE9, 0x85, 0x89, 0x43, 0xE9,
+       0x85, 0x8D, 0x43, 0xE9, 0x85, 0xAA, 0x43, 0xE9,
+       0x86, 0x99, 0x43, 0xE9, 0x86, 0xB4, 0x43, 0xE9,
+       0x87, 0x86, 0x43, 0xE9, 0x87, 0x8C, 0x43, 0xE9,
+       0x87, 0x8F, 0x43, 0xE9, 0x87, 0x91, 0x43, 0xE9,
+       0x88, 0xB4, 0x43, 0xE9, 0x88, 0xB8, 0x43, 0xE9,
+       0x89, 0xB6, 0x43, 0xE9, 0x89, 0xBC, 0x43, 0xE9,
+       0x8B, 0x97, 0x43, 0xE9, 0x8B, 0x98, 0x43, 0xE9,
+       // Bytes 1480 - 14bf
+       0x8C, 0x84, 0x43, 0xE9, 0x8D, 0x8A, 0x43, 0xE9,
+       0x8F, 0xB9, 0x43, 0xE9, 0x90, 0x95, 0x43, 0xE9,
+       0x95, 0xB7, 0x43, 0xE9, 0x96, 0x80, 0x43, 0xE9,
+       0x96, 0x8B, 0x43, 0xE9, 0x96, 0xAD, 0x43, 0xE9,
+       0x96, 0xB7, 0x43, 0xE9, 0x98, 0x9C, 0x43, 0xE9,
+       0x98, 0xAE, 0x43, 0xE9, 0x99, 0x8B, 0x43, 0xE9,
+       0x99, 0x8D, 0x43, 0xE9, 0x99, 0xB5, 0x43, 0xE9,
+       0x99, 0xB8, 0x43, 0xE9, 0x99, 0xBC, 0x43, 0xE9,
+       // Bytes 14c0 - 14ff
+       0x9A, 0x86, 0x43, 0xE9, 0x9A, 0xA3, 0x43, 0xE9,
+       0x9A, 0xB6, 0x43, 0xE9, 0x9A, 0xB7, 0x43, 0xE9,
+       0x9A, 0xB8, 0x43, 0xE9, 0x9A, 0xB9, 0x43, 0xE9,
+       0x9B, 0x83, 0x43, 0xE9, 0x9B, 0xA2, 0x43, 0xE9,
+       0x9B, 0xA3, 0x43, 0xE9, 0x9B, 0xA8, 0x43, 0xE9,
+       0x9B, 0xB6, 0x43, 0xE9, 0x9B, 0xB7, 0x43, 0xE9,
+       0x9C, 0xA3, 0x43, 0xE9, 0x9C, 0xB2, 0x43, 0xE9,
+       0x9D, 0x88, 0x43, 0xE9, 0x9D, 0x91, 0x43, 0xE9,
+       // Bytes 1500 - 153f
+       0x9D, 0x96, 0x43, 0xE9, 0x9D, 0x9E, 0x43, 0xE9,
+       0x9D, 0xA2, 0x43, 0xE9, 0x9D, 0xA9, 0x43, 0xE9,
+       0x9F, 0x8B, 0x43, 0xE9, 0x9F, 0x9B, 0x43, 0xE9,
+       0x9F, 0xA0, 0x43, 0xE9, 0x9F, 0xAD, 0x43, 0xE9,
+       0x9F, 0xB3, 0x43, 0xE9, 0x9F, 0xBF, 0x43, 0xE9,
+       0xA0, 0x81, 0x43, 0xE9, 0xA0, 0x85, 0x43, 0xE9,
+       0xA0, 0x8B, 0x43, 0xE9, 0xA0, 0x98, 0x43, 0xE9,
+       0xA0, 0xA9, 0x43, 0xE9, 0xA0, 0xBB, 0x43, 0xE9,
+       // Bytes 1540 - 157f
+       0xA1, 0x9E, 0x43, 0xE9, 0xA2, 0xA8, 0x43, 0xE9,
+       0xA3, 0x9B, 0x43, 0xE9, 0xA3, 0x9F, 0x43, 0xE9,
+       0xA3, 0xA2, 0x43, 0xE9, 0xA3, 0xAF, 0x43, 0xE9,
+       0xA3, 0xBC, 0x43, 0xE9, 0xA4, 0xA8, 0x43, 0xE9,
+       0xA4, 0xA9, 0x43, 0xE9, 0xA6, 0x96, 0x43, 0xE9,
+       0xA6, 0x99, 0x43, 0xE9, 0xA6, 0xA7, 0x43, 0xE9,
+       0xA6, 0xAC, 0x43, 0xE9, 0xA7, 0x82, 0x43, 0xE9,
+       0xA7, 0xB1, 0x43, 0xE9, 0xA7, 0xBE, 0x43, 0xE9,
+       // Bytes 1580 - 15bf
+       0xA9, 0xAA, 0x43, 0xE9, 0xAA, 0xA8, 0x43, 0xE9,
+       0xAB, 0x98, 0x43, 0xE9, 0xAB, 0x9F, 0x43, 0xE9,
+       0xAC, 0x92, 0x43, 0xE9, 0xAC, 0xA5, 0x43, 0xE9,
+       0xAC, 0xAF, 0x43, 0xE9, 0xAC, 0xB2, 0x43, 0xE9,
+       0xAC, 0xBC, 0x43, 0xE9, 0xAD, 0x9A, 0x43, 0xE9,
+       0xAD, 0xAF, 0x43, 0xE9, 0xB1, 0x80, 0x43, 0xE9,
+       0xB1, 0x97, 0x43, 0xE9, 0xB3, 0xA5, 0x43, 0xE9,
+       0xB3, 0xBD, 0x43, 0xE9, 0xB5, 0xA7, 0x43, 0xE9,
+       // Bytes 15c0 - 15ff
+       0xB6, 0xB4, 0x43, 0xE9, 0xB7, 0xBA, 0x43, 0xE9,
+       0xB8, 0x9E, 0x43, 0xE9, 0xB9, 0xB5, 0x43, 0xE9,
+       0xB9, 0xBF, 0x43, 0xE9, 0xBA, 0x97, 0x43, 0xE9,
+       0xBA, 0x9F, 0x43, 0xE9, 0xBA, 0xA5, 0x43, 0xE9,
+       0xBA, 0xBB, 0x43, 0xE9, 0xBB, 0x83, 0x43, 0xE9,
+       0xBB, 0x8D, 0x43, 0xE9, 0xBB, 0x8E, 0x43, 0xE9,
+       0xBB, 0x91, 0x43, 0xE9, 0xBB, 0xB9, 0x43, 0xE9,
+       0xBB, 0xBD, 0x43, 0xE9, 0xBB, 0xBE, 0x43, 0xE9,
+       // Bytes 1600 - 163f
+       0xBC, 0x85, 0x43, 0xE9, 0xBC, 0x8E, 0x43, 0xE9,
+       0xBC, 0x8F, 0x43, 0xE9, 0xBC, 0x93, 0x43, 0xE9,
+       0xBC, 0x96, 0x43, 0xE9, 0xBC, 0xA0, 0x43, 0xE9,
+       0xBC, 0xBB, 0x43, 0xE9, 0xBD, 0x83, 0x43, 0xE9,
+       0xBD, 0x8A, 0x43, 0xE9, 0xBD, 0x92, 0x43, 0xE9,
+       0xBE, 0x8D, 0x43, 0xE9, 0xBE, 0x8E, 0x43, 0xE9,
+       0xBE, 0x9C, 0x43, 0xE9, 0xBE, 0x9F, 0x43, 0xE9,
+       0xBE, 0xA0, 0x43, 0xEA, 0x9C, 0xA7, 0x43, 0xEA,
+       // Bytes 1640 - 167f
+       0x9D, 0xAF, 0x43, 0xEA, 0xAC, 0xB7, 0x43, 0xEA,
+       0xAD, 0x92, 0x44, 0xF0, 0xA0, 0x84, 0xA2, 0x44,
+       0xF0, 0xA0, 0x94, 0x9C, 0x44, 0xF0, 0xA0, 0x94,
+       0xA5, 0x44, 0xF0, 0xA0, 0x95, 0x8B, 0x44, 0xF0,
+       0xA0, 0x98, 0xBA, 0x44, 0xF0, 0xA0, 0xA0, 0x84,
+       0x44, 0xF0, 0xA0, 0xA3, 0x9E, 0x44, 0xF0, 0xA0,
+       0xA8, 0xAC, 0x44, 0xF0, 0xA0, 0xAD, 0xA3, 0x44,
+       0xF0, 0xA1, 0x93, 0xA4, 0x44, 0xF0, 0xA1, 0x9A,
+       // Bytes 1680 - 16bf
+       0xA8, 0x44, 0xF0, 0xA1, 0x9B, 0xAA, 0x44, 0xF0,
+       0xA1, 0xA7, 0x88, 0x44, 0xF0, 0xA1, 0xAC, 0x98,
+       0x44, 0xF0, 0xA1, 0xB4, 0x8B, 0x44, 0xF0, 0xA1,
+       0xB7, 0xA4, 0x44, 0xF0, 0xA1, 0xB7, 0xA6, 0x44,
+       0xF0, 0xA2, 0x86, 0x83, 0x44, 0xF0, 0xA2, 0x86,
+       0x9F, 0x44, 0xF0, 0xA2, 0x8C, 0xB1, 0x44, 0xF0,
+       0xA2, 0x9B, 0x94, 0x44, 0xF0, 0xA2, 0xA1, 0x84,
+       0x44, 0xF0, 0xA2, 0xA1, 0x8A, 0x44, 0xF0, 0xA2,
+       // Bytes 16c0 - 16ff
+       0xAC, 0x8C, 0x44, 0xF0, 0xA2, 0xAF, 0xB1, 0x44,
+       0xF0, 0xA3, 0x80, 0x8A, 0x44, 0xF0, 0xA3, 0x8A,
+       0xB8, 0x44, 0xF0, 0xA3, 0x8D, 0x9F, 0x44, 0xF0,
+       0xA3, 0x8E, 0x93, 0x44, 0xF0, 0xA3, 0x8E, 0x9C,
+       0x44, 0xF0, 0xA3, 0x8F, 0x83, 0x44, 0xF0, 0xA3,
+       0x8F, 0x95, 0x44, 0xF0, 0xA3, 0x91, 0xAD, 0x44,
+       0xF0, 0xA3, 0x9A, 0xA3, 0x44, 0xF0, 0xA3, 0xA2,
+       0xA7, 0x44, 0xF0, 0xA3, 0xAA, 0x8D, 0x44, 0xF0,
+       // Bytes 1700 - 173f
+       0xA3, 0xAB, 0xBA, 0x44, 0xF0, 0xA3, 0xB2, 0xBC,
+       0x44, 0xF0, 0xA3, 0xB4, 0x9E, 0x44, 0xF0, 0xA3,
+       0xBB, 0x91, 0x44, 0xF0, 0xA3, 0xBD, 0x9E, 0x44,
+       0xF0, 0xA3, 0xBE, 0x8E, 0x44, 0xF0, 0xA4, 0x89,
+       0xA3, 0x44, 0xF0, 0xA4, 0x8B, 0xAE, 0x44, 0xF0,
+       0xA4, 0x8E, 0xAB, 0x44, 0xF0, 0xA4, 0x98, 0x88,
+       0x44, 0xF0, 0xA4, 0x9C, 0xB5, 0x44, 0xF0, 0xA4,
+       0xA0, 0x94, 0x44, 0xF0, 0xA4, 0xB0, 0xB6, 0x44,
+       // Bytes 1740 - 177f
+       0xF0, 0xA4, 0xB2, 0x92, 0x44, 0xF0, 0xA4, 0xBE,
+       0xA1, 0x44, 0xF0, 0xA4, 0xBE, 0xB8, 0x44, 0xF0,
+       0xA5, 0x81, 0x84, 0x44, 0xF0, 0xA5, 0x83, 0xB2,
+       0x44, 0xF0, 0xA5, 0x83, 0xB3, 0x44, 0xF0, 0xA5,
+       0x84, 0x99, 0x44, 0xF0, 0xA5, 0x84, 0xB3, 0x44,
+       0xF0, 0xA5, 0x89, 0x89, 0x44, 0xF0, 0xA5, 0x90,
+       0x9D, 0x44, 0xF0, 0xA5, 0x98, 0xA6, 0x44, 0xF0,
+       0xA5, 0x9A, 0x9A, 0x44, 0xF0, 0xA5, 0x9B, 0x85,
+       // Bytes 1780 - 17bf
+       0x44, 0xF0, 0xA5, 0xA5, 0xBC, 0x44, 0xF0, 0xA5,
+       0xAA, 0xA7, 0x44, 0xF0, 0xA5, 0xAE, 0xAB, 0x44,
+       0xF0, 0xA5, 0xB2, 0x80, 0x44, 0xF0, 0xA5, 0xB3,
+       0x90, 0x44, 0xF0, 0xA5, 0xBE, 0x86, 0x44, 0xF0,
+       0xA6, 0x87, 0x9A, 0x44, 0xF0, 0xA6, 0x88, 0xA8,
+       0x44, 0xF0, 0xA6, 0x89, 0x87, 0x44, 0xF0, 0xA6,
+       0x8B, 0x99, 0x44, 0xF0, 0xA6, 0x8C, 0xBE, 0x44,
+       0xF0, 0xA6, 0x93, 0x9A, 0x44, 0xF0, 0xA6, 0x94,
+       // Bytes 17c0 - 17ff
+       0xA3, 0x44, 0xF0, 0xA6, 0x96, 0xA8, 0x44, 0xF0,
+       0xA6, 0x9E, 0xA7, 0x44, 0xF0, 0xA6, 0x9E, 0xB5,
+       0x44, 0xF0, 0xA6, 0xAC, 0xBC, 0x44, 0xF0, 0xA6,
+       0xB0, 0xB6, 0x44, 0xF0, 0xA6, 0xB3, 0x95, 0x44,
+       0xF0, 0xA6, 0xB5, 0xAB, 0x44, 0xF0, 0xA6, 0xBC,
+       0xAC, 0x44, 0xF0, 0xA6, 0xBE, 0xB1, 0x44, 0xF0,
+       0xA7, 0x83, 0x92, 0x44, 0xF0, 0xA7, 0x8F, 0x8A,
+       0x44, 0xF0, 0xA7, 0x99, 0xA7, 0x44, 0xF0, 0xA7,
+       // Bytes 1800 - 183f
+       0xA2, 0xAE, 0x44, 0xF0, 0xA7, 0xA5, 0xA6, 0x44,
+       0xF0, 0xA7, 0xB2, 0xA8, 0x44, 0xF0, 0xA7, 0xBB,
+       0x93, 0x44, 0xF0, 0xA7, 0xBC, 0xAF, 0x44, 0xF0,
+       0xA8, 0x97, 0x92, 0x44, 0xF0, 0xA8, 0x97, 0xAD,
+       0x44, 0xF0, 0xA8, 0x9C, 0xAE, 0x44, 0xF0, 0xA8,
+       0xAF, 0xBA, 0x44, 0xF0, 0xA8, 0xB5, 0xB7, 0x44,
+       0xF0, 0xA9, 0x85, 0x85, 0x44, 0xF0, 0xA9, 0x87,
+       0x9F, 0x44, 0xF0, 0xA9, 0x88, 0x9A, 0x44, 0xF0,
+       // Bytes 1840 - 187f
+       0xA9, 0x90, 0x8A, 0x44, 0xF0, 0xA9, 0x92, 0x96,
+       0x44, 0xF0, 0xA9, 0x96, 0xB6, 0x44, 0xF0, 0xA9,
+       0xAC, 0xB0, 0x44, 0xF0, 0xAA, 0x83, 0x8E, 0x44,
+       0xF0, 0xAA, 0x84, 0x85, 0x44, 0xF0, 0xAA, 0x88,
+       0x8E, 0x44, 0xF0, 0xAA, 0x8A, 0x91, 0x44, 0xF0,
+       0xAA, 0x8E, 0x92, 0x44, 0xF0, 0xAA, 0x98, 0x80,
+       0x42, 0x21, 0x21, 0x42, 0x21, 0x3F, 0x42, 0x2E,
+       0x2E, 0x42, 0x30, 0x2C, 0x42, 0x30, 0x2E, 0x42,
+       // Bytes 1880 - 18bf
+       0x31, 0x2C, 0x42, 0x31, 0x2E, 0x42, 0x31, 0x30,
+       0x42, 0x31, 0x31, 0x42, 0x31, 0x32, 0x42, 0x31,
+       0x33, 0x42, 0x31, 0x34, 0x42, 0x31, 0x35, 0x42,
+       0x31, 0x36, 0x42, 0x31, 0x37, 0x42, 0x31, 0x38,
+       0x42, 0x31, 0x39, 0x42, 0x32, 0x2C, 0x42, 0x32,
+       0x2E, 0x42, 0x32, 0x30, 0x42, 0x32, 0x31, 0x42,
+       0x32, 0x32, 0x42, 0x32, 0x33, 0x42, 0x32, 0x34,
+       0x42, 0x32, 0x35, 0x42, 0x32, 0x36, 0x42, 0x32,
+       // Bytes 18c0 - 18ff
+       0x37, 0x42, 0x32, 0x38, 0x42, 0x32, 0x39, 0x42,
+       0x33, 0x2C, 0x42, 0x33, 0x2E, 0x42, 0x33, 0x30,
+       0x42, 0x33, 0x31, 0x42, 0x33, 0x32, 0x42, 0x33,
+       0x33, 0x42, 0x33, 0x34, 0x42, 0x33, 0x35, 0x42,
+       0x33, 0x36, 0x42, 0x33, 0x37, 0x42, 0x33, 0x38,
+       0x42, 0x33, 0x39, 0x42, 0x34, 0x2C, 0x42, 0x34,
+       0x2E, 0x42, 0x34, 0x30, 0x42, 0x34, 0x31, 0x42,
+       0x34, 0x32, 0x42, 0x34, 0x33, 0x42, 0x34, 0x34,
+       // Bytes 1900 - 193f
+       0x42, 0x34, 0x35, 0x42, 0x34, 0x36, 0x42, 0x34,
+       0x37, 0x42, 0x34, 0x38, 0x42, 0x34, 0x39, 0x42,
+       0x35, 0x2C, 0x42, 0x35, 0x2E, 0x42, 0x35, 0x30,
+       0x42, 0x36, 0x2C, 0x42, 0x36, 0x2E, 0x42, 0x37,
+       0x2C, 0x42, 0x37, 0x2E, 0x42, 0x38, 0x2C, 0x42,
+       0x38, 0x2E, 0x42, 0x39, 0x2C, 0x42, 0x39, 0x2E,
+       0x42, 0x3D, 0x3D, 0x42, 0x3F, 0x21, 0x42, 0x3F,
+       0x3F, 0x42, 0x41, 0x55, 0x42, 0x42, 0x71, 0x42,
+       // Bytes 1940 - 197f
+       0x43, 0x44, 0x42, 0x44, 0x4A, 0x42, 0x44, 0x5A,
+       0x42, 0x44, 0x7A, 0x42, 0x47, 0x42, 0x42, 0x47,
+       0x79, 0x42, 0x48, 0x50, 0x42, 0x48, 0x56, 0x42,
+       0x48, 0x67, 0x42, 0x48, 0x7A, 0x42, 0x49, 0x49,
+       0x42, 0x49, 0x4A, 0x42, 0x49, 0x55, 0x42, 0x49,
+       0x56, 0x42, 0x49, 0x58, 0x42, 0x4B, 0x42, 0x42,
+       0x4B, 0x4B, 0x42, 0x4B, 0x4D, 0x42, 0x4C, 0x4A,
+       0x42, 0x4C, 0x6A, 0x42, 0x4D, 0x42, 0x42, 0x4D,
+       // Bytes 1980 - 19bf
+       0x43, 0x42, 0x4D, 0x44, 0x42, 0x4D, 0x52, 0x42,
+       0x4D, 0x56, 0x42, 0x4D, 0x57, 0x42, 0x4E, 0x4A,
+       0x42, 0x4E, 0x6A, 0x42, 0x4E, 0x6F, 0x42, 0x50,
+       0x48, 0x42, 0x50, 0x52, 0x42, 0x50, 0x61, 0x42,
+       0x52, 0x73, 0x42, 0x53, 0x44, 0x42, 0x53, 0x4D,
+       0x42, 0x53, 0x53, 0x42, 0x53, 0x76, 0x42, 0x54,
+       0x4D, 0x42, 0x56, 0x49, 0x42, 0x57, 0x43, 0x42,
+       0x57, 0x5A, 0x42, 0x57, 0x62, 0x42, 0x58, 0x49,
+       // Bytes 19c0 - 19ff
+       0x42, 0x63, 0x63, 0x42, 0x63, 0x64, 0x42, 0x63,
+       0x6D, 0x42, 0x64, 0x42, 0x42, 0x64, 0x61, 0x42,
+       0x64, 0x6C, 0x42, 0x64, 0x6D, 0x42, 0x64, 0x7A,
+       0x42, 0x65, 0x56, 0x42, 0x66, 0x66, 0x42, 0x66,
+       0x69, 0x42, 0x66, 0x6C, 0x42, 0x66, 0x6D, 0x42,
+       0x68, 0x61, 0x42, 0x69, 0x69, 0x42, 0x69, 0x6A,
+       0x42, 0x69, 0x6E, 0x42, 0x69, 0x76, 0x42, 0x69,
+       0x78, 0x42, 0x6B, 0x41, 0x42, 0x6B, 0x56, 0x42,
+       // Bytes 1a00 - 1a3f
+       0x6B, 0x57, 0x42, 0x6B, 0x67, 0x42, 0x6B, 0x6C,
+       0x42, 0x6B, 0x6D, 0x42, 0x6B, 0x74, 0x42, 0x6C,
+       0x6A, 0x42, 0x6C, 0x6D, 0x42, 0x6C, 0x6E, 0x42,
+       0x6C, 0x78, 0x42, 0x6D, 0x32, 0x42, 0x6D, 0x33,
+       0x42, 0x6D, 0x41, 0x42, 0x6D, 0x56, 0x42, 0x6D,
+       0x57, 0x42, 0x6D, 0x62, 0x42, 0x6D, 0x67, 0x42,
+       0x6D, 0x6C, 0x42, 0x6D, 0x6D, 0x42, 0x6D, 0x73,
+       0x42, 0x6E, 0x41, 0x42, 0x6E, 0x46, 0x42, 0x6E,
+       // Bytes 1a40 - 1a7f
+       0x56, 0x42, 0x6E, 0x57, 0x42, 0x6E, 0x6A, 0x42,
+       0x6E, 0x6D, 0x42, 0x6E, 0x73, 0x42, 0x6F, 0x56,
+       0x42, 0x70, 0x41, 0x42, 0x70, 0x46, 0x42, 0x70,
+       0x56, 0x42, 0x70, 0x57, 0x42, 0x70, 0x63, 0x42,
+       0x70, 0x73, 0x42, 0x73, 0x72, 0x42, 0x73, 0x74,
+       0x42, 0x76, 0x69, 0x42, 0x78, 0x69, 0x43, 0x28,
+       0x31, 0x29, 0x43, 0x28, 0x32, 0x29, 0x43, 0x28,
+       0x33, 0x29, 0x43, 0x28, 0x34, 0x29, 0x43, 0x28,
+       // Bytes 1a80 - 1abf
+       0x35, 0x29, 0x43, 0x28, 0x36, 0x29, 0x43, 0x28,
+       0x37, 0x29, 0x43, 0x28, 0x38, 0x29, 0x43, 0x28,
+       0x39, 0x29, 0x43, 0x28, 0x41, 0x29, 0x43, 0x28,
+       0x42, 0x29, 0x43, 0x28, 0x43, 0x29, 0x43, 0x28,
+       0x44, 0x29, 0x43, 0x28, 0x45, 0x29, 0x43, 0x28,
+       0x46, 0x29, 0x43, 0x28, 0x47, 0x29, 0x43, 0x28,
+       0x48, 0x29, 0x43, 0x28, 0x49, 0x29, 0x43, 0x28,
+       0x4A, 0x29, 0x43, 0x28, 0x4B, 0x29, 0x43, 0x28,
+       // Bytes 1ac0 - 1aff
+       0x4C, 0x29, 0x43, 0x28, 0x4D, 0x29, 0x43, 0x28,
+       0x4E, 0x29, 0x43, 0x28, 0x4F, 0x29, 0x43, 0x28,
+       0x50, 0x29, 0x43, 0x28, 0x51, 0x29, 0x43, 0x28,
+       0x52, 0x29, 0x43, 0x28, 0x53, 0x29, 0x43, 0x28,
+       0x54, 0x29, 0x43, 0x28, 0x55, 0x29, 0x43, 0x28,
+       0x56, 0x29, 0x43, 0x28, 0x57, 0x29, 0x43, 0x28,
+       0x58, 0x29, 0x43, 0x28, 0x59, 0x29, 0x43, 0x28,
+       0x5A, 0x29, 0x43, 0x28, 0x61, 0x29, 0x43, 0x28,
+       // Bytes 1b00 - 1b3f
+       0x62, 0x29, 0x43, 0x28, 0x63, 0x29, 0x43, 0x28,
+       0x64, 0x29, 0x43, 0x28, 0x65, 0x29, 0x43, 0x28,
+       0x66, 0x29, 0x43, 0x28, 0x67, 0x29, 0x43, 0x28,
+       0x68, 0x29, 0x43, 0x28, 0x69, 0x29, 0x43, 0x28,
+       0x6A, 0x29, 0x43, 0x28, 0x6B, 0x29, 0x43, 0x28,
+       0x6C, 0x29, 0x43, 0x28, 0x6D, 0x29, 0x43, 0x28,
+       0x6E, 0x29, 0x43, 0x28, 0x6F, 0x29, 0x43, 0x28,
+       0x70, 0x29, 0x43, 0x28, 0x71, 0x29, 0x43, 0x28,
+       // Bytes 1b40 - 1b7f
+       0x72, 0x29, 0x43, 0x28, 0x73, 0x29, 0x43, 0x28,
+       0x74, 0x29, 0x43, 0x28, 0x75, 0x29, 0x43, 0x28,
+       0x76, 0x29, 0x43, 0x28, 0x77, 0x29, 0x43, 0x28,
+       0x78, 0x29, 0x43, 0x28, 0x79, 0x29, 0x43, 0x28,
+       0x7A, 0x29, 0x43, 0x2E, 0x2E, 0x2E, 0x43, 0x31,
+       0x30, 0x2E, 0x43, 0x31, 0x31, 0x2E, 0x43, 0x31,
+       0x32, 0x2E, 0x43, 0x31, 0x33, 0x2E, 0x43, 0x31,
+       0x34, 0x2E, 0x43, 0x31, 0x35, 0x2E, 0x43, 0x31,
+       // Bytes 1b80 - 1bbf
+       0x36, 0x2E, 0x43, 0x31, 0x37, 0x2E, 0x43, 0x31,
+       0x38, 0x2E, 0x43, 0x31, 0x39, 0x2E, 0x43, 0x32,
+       0x30, 0x2E, 0x43, 0x3A, 0x3A, 0x3D, 0x43, 0x3D,
+       0x3D, 0x3D, 0x43, 0x43, 0x6F, 0x2E, 0x43, 0x46,
+       0x41, 0x58, 0x43, 0x47, 0x48, 0x7A, 0x43, 0x47,
+       0x50, 0x61, 0x43, 0x49, 0x49, 0x49, 0x43, 0x4C,
+       0x54, 0x44, 0x43, 0x4C, 0xC2, 0xB7, 0x43, 0x4D,
+       0x48, 0x7A, 0x43, 0x4D, 0x50, 0x61, 0x43, 0x4D,
+       // Bytes 1bc0 - 1bff
+       0xCE, 0xA9, 0x43, 0x50, 0x50, 0x4D, 0x43, 0x50,
+       0x50, 0x56, 0x43, 0x50, 0x54, 0x45, 0x43, 0x54,
+       0x45, 0x4C, 0x43, 0x54, 0x48, 0x7A, 0x43, 0x56,
+       0x49, 0x49, 0x43, 0x58, 0x49, 0x49, 0x43, 0x61,
+       0x2F, 0x63, 0x43, 0x61, 0x2F, 0x73, 0x43, 0x61,
+       0xCA, 0xBE, 0x43, 0x62, 0x61, 0x72, 0x43, 0x63,
+       0x2F, 0x6F, 0x43, 0x63, 0x2F, 0x75, 0x43, 0x63,
+       0x61, 0x6C, 0x43, 0x63, 0x6D, 0x32, 0x43, 0x63,
+       // Bytes 1c00 - 1c3f
+       0x6D, 0x33, 0x43, 0x64, 0x6D, 0x32, 0x43, 0x64,
+       0x6D, 0x33, 0x43, 0x65, 0x72, 0x67, 0x43, 0x66,
+       0x66, 0x69, 0x43, 0x66, 0x66, 0x6C, 0x43, 0x67,
+       0x61, 0x6C, 0x43, 0x68, 0x50, 0x61, 0x43, 0x69,
+       0x69, 0x69, 0x43, 0x6B, 0x48, 0x7A, 0x43, 0x6B,
+       0x50, 0x61, 0x43, 0x6B, 0x6D, 0x32, 0x43, 0x6B,
+       0x6D, 0x33, 0x43, 0x6B, 0xCE, 0xA9, 0x43, 0x6C,
+       0x6F, 0x67, 0x43, 0x6C, 0xC2, 0xB7, 0x43, 0x6D,
+       // Bytes 1c40 - 1c7f
+       0x69, 0x6C, 0x43, 0x6D, 0x6D, 0x32, 0x43, 0x6D,
+       0x6D, 0x33, 0x43, 0x6D, 0x6F, 0x6C, 0x43, 0x72,
+       0x61, 0x64, 0x43, 0x76, 0x69, 0x69, 0x43, 0x78,
+       0x69, 0x69, 0x43, 0xC2, 0xB0, 0x43, 0x43, 0xC2,
+       0xB0, 0x46, 0x43, 0xCA, 0xBC, 0x6E, 0x43, 0xCE,
+       0xBC, 0x41, 0x43, 0xCE, 0xBC, 0x46, 0x43, 0xCE,
+       0xBC, 0x56, 0x43, 0xCE, 0xBC, 0x57, 0x43, 0xCE,
+       0xBC, 0x67, 0x43, 0xCE, 0xBC, 0x6C, 0x43, 0xCE,
+       // Bytes 1c80 - 1cbf
+       0xBC, 0x6D, 0x43, 0xCE, 0xBC, 0x73, 0x44, 0x28,
+       0x31, 0x30, 0x29, 0x44, 0x28, 0x31, 0x31, 0x29,
+       0x44, 0x28, 0x31, 0x32, 0x29, 0x44, 0x28, 0x31,
+       0x33, 0x29, 0x44, 0x28, 0x31, 0x34, 0x29, 0x44,
+       0x28, 0x31, 0x35, 0x29, 0x44, 0x28, 0x31, 0x36,
+       0x29, 0x44, 0x28, 0x31, 0x37, 0x29, 0x44, 0x28,
+       0x31, 0x38, 0x29, 0x44, 0x28, 0x31, 0x39, 0x29,
+       0x44, 0x28, 0x32, 0x30, 0x29, 0x44, 0x30, 0xE7,
+       // Bytes 1cc0 - 1cff
+       0x82, 0xB9, 0x44, 0x31, 0xE2, 0x81, 0x84, 0x44,
+       0x31, 0xE6, 0x97, 0xA5, 0x44, 0x31, 0xE6, 0x9C,
+       0x88, 0x44, 0x31, 0xE7, 0x82, 0xB9, 0x44, 0x32,
+       0xE6, 0x97, 0xA5, 0x44, 0x32, 0xE6, 0x9C, 0x88,
+       0x44, 0x32, 0xE7, 0x82, 0xB9, 0x44, 0x33, 0xE6,
+       0x97, 0xA5, 0x44, 0x33, 0xE6, 0x9C, 0x88, 0x44,
+       0x33, 0xE7, 0x82, 0xB9, 0x44, 0x34, 0xE6, 0x97,
+       0xA5, 0x44, 0x34, 0xE6, 0x9C, 0x88, 0x44, 0x34,
+       // Bytes 1d00 - 1d3f
+       0xE7, 0x82, 0xB9, 0x44, 0x35, 0xE6, 0x97, 0xA5,
+       0x44, 0x35, 0xE6, 0x9C, 0x88, 0x44, 0x35, 0xE7,
+       0x82, 0xB9, 0x44, 0x36, 0xE6, 0x97, 0xA5, 0x44,
+       0x36, 0xE6, 0x9C, 0x88, 0x44, 0x36, 0xE7, 0x82,
+       0xB9, 0x44, 0x37, 0xE6, 0x97, 0xA5, 0x44, 0x37,
+       0xE6, 0x9C, 0x88, 0x44, 0x37, 0xE7, 0x82, 0xB9,
+       0x44, 0x38, 0xE6, 0x97, 0xA5, 0x44, 0x38, 0xE6,
+       0x9C, 0x88, 0x44, 0x38, 0xE7, 0x82, 0xB9, 0x44,
+       // Bytes 1d40 - 1d7f
+       0x39, 0xE6, 0x97, 0xA5, 0x44, 0x39, 0xE6, 0x9C,
+       0x88, 0x44, 0x39, 0xE7, 0x82, 0xB9, 0x44, 0x56,
+       0x49, 0x49, 0x49, 0x44, 0x61, 0x2E, 0x6D, 0x2E,
+       0x44, 0x6B, 0x63, 0x61, 0x6C, 0x44, 0x70, 0x2E,
+       0x6D, 0x2E, 0x44, 0x76, 0x69, 0x69, 0x69, 0x44,
+       0xD5, 0xA5, 0xD6, 0x82, 0x44, 0xD5, 0xB4, 0xD5,
+       0xA5, 0x44, 0xD5, 0xB4, 0xD5, 0xAB, 0x44, 0xD5,
+       0xB4, 0xD5, 0xAD, 0x44, 0xD5, 0xB4, 0xD5, 0xB6,
+       // Bytes 1d80 - 1dbf
+       0x44, 0xD5, 0xBE, 0xD5, 0xB6, 0x44, 0xD7, 0x90,
+       0xD7, 0x9C, 0x44, 0xD8, 0xA7, 0xD9, 0xB4, 0x44,
+       0xD8, 0xA8, 0xD8, 0xAC, 0x44, 0xD8, 0xA8, 0xD8,
+       0xAD, 0x44, 0xD8, 0xA8, 0xD8, 0xAE, 0x44, 0xD8,
+       0xA8, 0xD8, 0xB1, 0x44, 0xD8, 0xA8, 0xD8, 0xB2,
+       0x44, 0xD8, 0xA8, 0xD9, 0x85, 0x44, 0xD8, 0xA8,
+       0xD9, 0x86, 0x44, 0xD8, 0xA8, 0xD9, 0x87, 0x44,
+       0xD8, 0xA8, 0xD9, 0x89, 0x44, 0xD8, 0xA8, 0xD9,
+       // Bytes 1dc0 - 1dff
+       0x8A, 0x44, 0xD8, 0xAA, 0xD8, 0xAC, 0x44, 0xD8,
+       0xAA, 0xD8, 0xAD, 0x44, 0xD8, 0xAA, 0xD8, 0xAE,
+       0x44, 0xD8, 0xAA, 0xD8, 0xB1, 0x44, 0xD8, 0xAA,
+       0xD8, 0xB2, 0x44, 0xD8, 0xAA, 0xD9, 0x85, 0x44,
+       0xD8, 0xAA, 0xD9, 0x86, 0x44, 0xD8, 0xAA, 0xD9,
+       0x87, 0x44, 0xD8, 0xAA, 0xD9, 0x89, 0x44, 0xD8,
+       0xAA, 0xD9, 0x8A, 0x44, 0xD8, 0xAB, 0xD8, 0xAC,
+       0x44, 0xD8, 0xAB, 0xD8, 0xB1, 0x44, 0xD8, 0xAB,
+       // Bytes 1e00 - 1e3f
+       0xD8, 0xB2, 0x44, 0xD8, 0xAB, 0xD9, 0x85, 0x44,
+       0xD8, 0xAB, 0xD9, 0x86, 0x44, 0xD8, 0xAB, 0xD9,
+       0x87, 0x44, 0xD8, 0xAB, 0xD9, 0x89, 0x44, 0xD8,
+       0xAB, 0xD9, 0x8A, 0x44, 0xD8, 0xAC, 0xD8, 0xAD,
+       0x44, 0xD8, 0xAC, 0xD9, 0x85, 0x44, 0xD8, 0xAC,
+       0xD9, 0x89, 0x44, 0xD8, 0xAC, 0xD9, 0x8A, 0x44,
+       0xD8, 0xAD, 0xD8, 0xAC, 0x44, 0xD8, 0xAD, 0xD9,
+       0x85, 0x44, 0xD8, 0xAD, 0xD9, 0x89, 0x44, 0xD8,
+       // Bytes 1e40 - 1e7f
+       0xAD, 0xD9, 0x8A, 0x44, 0xD8, 0xAE, 0xD8, 0xAC,
+       0x44, 0xD8, 0xAE, 0xD8, 0xAD, 0x44, 0xD8, 0xAE,
+       0xD9, 0x85, 0x44, 0xD8, 0xAE, 0xD9, 0x89, 0x44,
+       0xD8, 0xAE, 0xD9, 0x8A, 0x44, 0xD8, 0xB3, 0xD8,
+       0xAC, 0x44, 0xD8, 0xB3, 0xD8, 0xAD, 0x44, 0xD8,
+       0xB3, 0xD8, 0xAE, 0x44, 0xD8, 0xB3, 0xD8, 0xB1,
+       0x44, 0xD8, 0xB3, 0xD9, 0x85, 0x44, 0xD8, 0xB3,
+       0xD9, 0x87, 0x44, 0xD8, 0xB3, 0xD9, 0x89, 0x44,
+       // Bytes 1e80 - 1ebf
+       0xD8, 0xB3, 0xD9, 0x8A, 0x44, 0xD8, 0xB4, 0xD8,
+       0xAC, 0x44, 0xD8, 0xB4, 0xD8, 0xAD, 0x44, 0xD8,
+       0xB4, 0xD8, 0xAE, 0x44, 0xD8, 0xB4, 0xD8, 0xB1,
+       0x44, 0xD8, 0xB4, 0xD9, 0x85, 0x44, 0xD8, 0xB4,
+       0xD9, 0x87, 0x44, 0xD8, 0xB4, 0xD9, 0x89, 0x44,
+       0xD8, 0xB4, 0xD9, 0x8A, 0x44, 0xD8, 0xB5, 0xD8,
+       0xAD, 0x44, 0xD8, 0xB5, 0xD8, 0xAE, 0x44, 0xD8,
+       0xB5, 0xD8, 0xB1, 0x44, 0xD8, 0xB5, 0xD9, 0x85,
+       // Bytes 1ec0 - 1eff
+       0x44, 0xD8, 0xB5, 0xD9, 0x89, 0x44, 0xD8, 0xB5,
+       0xD9, 0x8A, 0x44, 0xD8, 0xB6, 0xD8, 0xAC, 0x44,
+       0xD8, 0xB6, 0xD8, 0xAD, 0x44, 0xD8, 0xB6, 0xD8,
+       0xAE, 0x44, 0xD8, 0xB6, 0xD8, 0xB1, 0x44, 0xD8,
+       0xB6, 0xD9, 0x85, 0x44, 0xD8, 0xB6, 0xD9, 0x89,
+       0x44, 0xD8, 0xB6, 0xD9, 0x8A, 0x44, 0xD8, 0xB7,
+       0xD8, 0xAD, 0x44, 0xD8, 0xB7, 0xD9, 0x85, 0x44,
+       0xD8, 0xB7, 0xD9, 0x89, 0x44, 0xD8, 0xB7, 0xD9,
+       // Bytes 1f00 - 1f3f
+       0x8A, 0x44, 0xD8, 0xB8, 0xD9, 0x85, 0x44, 0xD8,
+       0xB9, 0xD8, 0xAC, 0x44, 0xD8, 0xB9, 0xD9, 0x85,
+       0x44, 0xD8, 0xB9, 0xD9, 0x89, 0x44, 0xD8, 0xB9,
+       0xD9, 0x8A, 0x44, 0xD8, 0xBA, 0xD8, 0xAC, 0x44,
+       0xD8, 0xBA, 0xD9, 0x85, 0x44, 0xD8, 0xBA, 0xD9,
+       0x89, 0x44, 0xD8, 0xBA, 0xD9, 0x8A, 0x44, 0xD9,
+       0x81, 0xD8, 0xAC, 0x44, 0xD9, 0x81, 0xD8, 0xAD,
+       0x44, 0xD9, 0x81, 0xD8, 0xAE, 0x44, 0xD9, 0x81,
+       // Bytes 1f40 - 1f7f
+       0xD9, 0x85, 0x44, 0xD9, 0x81, 0xD9, 0x89, 0x44,
+       0xD9, 0x81, 0xD9, 0x8A, 0x44, 0xD9, 0x82, 0xD8,
+       0xAD, 0x44, 0xD9, 0x82, 0xD9, 0x85, 0x44, 0xD9,
+       0x82, 0xD9, 0x89, 0x44, 0xD9, 0x82, 0xD9, 0x8A,
+       0x44, 0xD9, 0x83, 0xD8, 0xA7, 0x44, 0xD9, 0x83,
+       0xD8, 0xAC, 0x44, 0xD9, 0x83, 0xD8, 0xAD, 0x44,
+       0xD9, 0x83, 0xD8, 0xAE, 0x44, 0xD9, 0x83, 0xD9,
+       0x84, 0x44, 0xD9, 0x83, 0xD9, 0x85, 0x44, 0xD9,
+       // Bytes 1f80 - 1fbf
+       0x83, 0xD9, 0x89, 0x44, 0xD9, 0x83, 0xD9, 0x8A,
+       0x44, 0xD9, 0x84, 0xD8, 0xA7, 0x44, 0xD9, 0x84,
+       0xD8, 0xAC, 0x44, 0xD9, 0x84, 0xD8, 0xAD, 0x44,
+       0xD9, 0x84, 0xD8, 0xAE, 0x44, 0xD9, 0x84, 0xD9,
+       0x85, 0x44, 0xD9, 0x84, 0xD9, 0x87, 0x44, 0xD9,
+       0x84, 0xD9, 0x89, 0x44, 0xD9, 0x84, 0xD9, 0x8A,
+       0x44, 0xD9, 0x85, 0xD8, 0xA7, 0x44, 0xD9, 0x85,
+       0xD8, 0xAC, 0x44, 0xD9, 0x85, 0xD8, 0xAD, 0x44,
+       // Bytes 1fc0 - 1fff
+       0xD9, 0x85, 0xD8, 0xAE, 0x44, 0xD9, 0x85, 0xD9,
+       0x85, 0x44, 0xD9, 0x85, 0xD9, 0x89, 0x44, 0xD9,
+       0x85, 0xD9, 0x8A, 0x44, 0xD9, 0x86, 0xD8, 0xAC,
+       0x44, 0xD9, 0x86, 0xD8, 0xAD, 0x44, 0xD9, 0x86,
+       0xD8, 0xAE, 0x44, 0xD9, 0x86, 0xD8, 0xB1, 0x44,
+       0xD9, 0x86, 0xD8, 0xB2, 0x44, 0xD9, 0x86, 0xD9,
+       0x85, 0x44, 0xD9, 0x86, 0xD9, 0x86, 0x44, 0xD9,
+       0x86, 0xD9, 0x87, 0x44, 0xD9, 0x86, 0xD9, 0x89,
+       // Bytes 2000 - 203f
+       0x44, 0xD9, 0x86, 0xD9, 0x8A, 0x44, 0xD9, 0x87,
+       0xD8, 0xAC, 0x44, 0xD9, 0x87, 0xD9, 0x85, 0x44,
+       0xD9, 0x87, 0xD9, 0x89, 0x44, 0xD9, 0x87, 0xD9,
+       0x8A, 0x44, 0xD9, 0x88, 0xD9, 0xB4, 0x44, 0xD9,
+       0x8A, 0xD8, 0xAC, 0x44, 0xD9, 0x8A, 0xD8, 0xAD,
+       0x44, 0xD9, 0x8A, 0xD8, 0xAE, 0x44, 0xD9, 0x8A,
+       0xD8, 0xB1, 0x44, 0xD9, 0x8A, 0xD8, 0xB2, 0x44,
+       0xD9, 0x8A, 0xD9, 0x85, 0x44, 0xD9, 0x8A, 0xD9,
+       // Bytes 2040 - 207f
+       0x86, 0x44, 0xD9, 0x8A, 0xD9, 0x87, 0x44, 0xD9,
+       0x8A, 0xD9, 0x89, 0x44, 0xD9, 0x8A, 0xD9, 0x8A,
+       0x44, 0xD9, 0x8A, 0xD9, 0xB4, 0x44, 0xDB, 0x87,
+       0xD9, 0xB4, 0x45, 0x28, 0xE1, 0x84, 0x80, 0x29,
+       0x45, 0x28, 0xE1, 0x84, 0x82, 0x29, 0x45, 0x28,
+       0xE1, 0x84, 0x83, 0x29, 0x45, 0x28, 0xE1, 0x84,
+       0x85, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x86, 0x29,
+       0x45, 0x28, 0xE1, 0x84, 0x87, 0x29, 0x45, 0x28,
+       // Bytes 2080 - 20bf
+       0xE1, 0x84, 0x89, 0x29, 0x45, 0x28, 0xE1, 0x84,
+       0x8B, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x8C, 0x29,
+       0x45, 0x28, 0xE1, 0x84, 0x8E, 0x29, 0x45, 0x28,
+       0xE1, 0x84, 0x8F, 0x29, 0x45, 0x28, 0xE1, 0x84,
+       0x90, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x91, 0x29,
+       0x45, 0x28, 0xE1, 0x84, 0x92, 0x29, 0x45, 0x28,
+       0xE4, 0xB8, 0x80, 0x29, 0x45, 0x28, 0xE4, 0xB8,
+       0x83, 0x29, 0x45, 0x28, 0xE4, 0xB8, 0x89, 0x29,
+       // Bytes 20c0 - 20ff
+       0x45, 0x28, 0xE4, 0xB9, 0x9D, 0x29, 0x45, 0x28,
+       0xE4, 0xBA, 0x8C, 0x29, 0x45, 0x28, 0xE4, 0xBA,
+       0x94, 0x29, 0x45, 0x28, 0xE4, 0xBB, 0xA3, 0x29,
+       0x45, 0x28, 0xE4, 0xBC, 0x81, 0x29, 0x45, 0x28,
+       0xE4, 0xBC, 0x91, 0x29, 0x45, 0x28, 0xE5, 0x85,
+       0xAB, 0x29, 0x45, 0x28, 0xE5, 0x85, 0xAD, 0x29,
+       0x45, 0x28, 0xE5, 0x8A, 0xB4, 0x29, 0x45, 0x28,
+       0xE5, 0x8D, 0x81, 0x29, 0x45, 0x28, 0xE5, 0x8D,
+       // Bytes 2100 - 213f
+       0x94, 0x29, 0x45, 0x28, 0xE5, 0x90, 0x8D, 0x29,
+       0x45, 0x28, 0xE5, 0x91, 0xBC, 0x29, 0x45, 0x28,
+       0xE5, 0x9B, 0x9B, 0x29, 0x45, 0x28, 0xE5, 0x9C,
+       0x9F, 0x29, 0x45, 0x28, 0xE5, 0xAD, 0xA6, 0x29,
+       0x45, 0x28, 0xE6, 0x97, 0xA5, 0x29, 0x45, 0x28,
+       0xE6, 0x9C, 0x88, 0x29, 0x45, 0x28, 0xE6, 0x9C,
+       0x89, 0x29, 0x45, 0x28, 0xE6, 0x9C, 0xA8, 0x29,
+       0x45, 0x28, 0xE6, 0xA0, 0xAA, 0x29, 0x45, 0x28,
+       // Bytes 2140 - 217f
+       0xE6, 0xB0, 0xB4, 0x29, 0x45, 0x28, 0xE7, 0x81,
+       0xAB, 0x29, 0x45, 0x28, 0xE7, 0x89, 0xB9, 0x29,
+       0x45, 0x28, 0xE7, 0x9B, 0xA3, 0x29, 0x45, 0x28,
+       0xE7, 0xA4, 0xBE, 0x29, 0x45, 0x28, 0xE7, 0xA5,
+       0x9D, 0x29, 0x45, 0x28, 0xE7, 0xA5, 0xAD, 0x29,
+       0x45, 0x28, 0xE8, 0x87, 0xAA, 0x29, 0x45, 0x28,
+       0xE8, 0x87, 0xB3, 0x29, 0x45, 0x28, 0xE8, 0xB2,
+       0xA1, 0x29, 0x45, 0x28, 0xE8, 0xB3, 0x87, 0x29,
+       // Bytes 2180 - 21bf
+       0x45, 0x28, 0xE9, 0x87, 0x91, 0x29, 0x45, 0x30,
+       0xE2, 0x81, 0x84, 0x33, 0x45, 0x31, 0x30, 0xE6,
+       0x97, 0xA5, 0x45, 0x31, 0x30, 0xE6, 0x9C, 0x88,
+       0x45, 0x31, 0x30, 0xE7, 0x82, 0xB9, 0x45, 0x31,
+       0x31, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x31, 0xE6,
+       0x9C, 0x88, 0x45, 0x31, 0x31, 0xE7, 0x82, 0xB9,
+       0x45, 0x31, 0x32, 0xE6, 0x97, 0xA5, 0x45, 0x31,
+       0x32, 0xE6, 0x9C, 0x88, 0x45, 0x31, 0x32, 0xE7,
+       // Bytes 21c0 - 21ff
+       0x82, 0xB9, 0x45, 0x31, 0x33, 0xE6, 0x97, 0xA5,
+       0x45, 0x31, 0x33, 0xE7, 0x82, 0xB9, 0x45, 0x31,
+       0x34, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x34, 0xE7,
+       0x82, 0xB9, 0x45, 0x31, 0x35, 0xE6, 0x97, 0xA5,
+       0x45, 0x31, 0x35, 0xE7, 0x82, 0xB9, 0x45, 0x31,
+       0x36, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x36, 0xE7,
+       0x82, 0xB9, 0x45, 0x31, 0x37, 0xE6, 0x97, 0xA5,
+       0x45, 0x31, 0x37, 0xE7, 0x82, 0xB9, 0x45, 0x31,
+       // Bytes 2200 - 223f
+       0x38, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x38, 0xE7,
+       0x82, 0xB9, 0x45, 0x31, 0x39, 0xE6, 0x97, 0xA5,
+       0x45, 0x31, 0x39, 0xE7, 0x82, 0xB9, 0x45, 0x31,
+       0xE2, 0x81, 0x84, 0x32, 0x45, 0x31, 0xE2, 0x81,
+       0x84, 0x33, 0x45, 0x31, 0xE2, 0x81, 0x84, 0x34,
+       0x45, 0x31, 0xE2, 0x81, 0x84, 0x35, 0x45, 0x31,
+       0xE2, 0x81, 0x84, 0x36, 0x45, 0x31, 0xE2, 0x81,
+       0x84, 0x37, 0x45, 0x31, 0xE2, 0x81, 0x84, 0x38,
+       // Bytes 2240 - 227f
+       0x45, 0x31, 0xE2, 0x81, 0x84, 0x39, 0x45, 0x32,
+       0x30, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x30, 0xE7,
+       0x82, 0xB9, 0x45, 0x32, 0x31, 0xE6, 0x97, 0xA5,
+       0x45, 0x32, 0x31, 0xE7, 0x82, 0xB9, 0x45, 0x32,
+       0x32, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x32, 0xE7,
+       0x82, 0xB9, 0x45, 0x32, 0x33, 0xE6, 0x97, 0xA5,
+       0x45, 0x32, 0x33, 0xE7, 0x82, 0xB9, 0x45, 0x32,
+       0x34, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x34, 0xE7,
+       // Bytes 2280 - 22bf
+       0x82, 0xB9, 0x45, 0x32, 0x35, 0xE6, 0x97, 0xA5,
+       0x45, 0x32, 0x36, 0xE6, 0x97, 0xA5, 0x45, 0x32,
+       0x37, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x38, 0xE6,
+       0x97, 0xA5, 0x45, 0x32, 0x39, 0xE6, 0x97, 0xA5,
+       0x45, 0x32, 0xE2, 0x81, 0x84, 0x33, 0x45, 0x32,
+       0xE2, 0x81, 0x84, 0x35, 0x45, 0x33, 0x30, 0xE6,
+       0x97, 0xA5, 0x45, 0x33, 0x31, 0xE6, 0x97, 0xA5,
+       0x45, 0x33, 0xE2, 0x81, 0x84, 0x34, 0x45, 0x33,
+       // Bytes 22c0 - 22ff
+       0xE2, 0x81, 0x84, 0x35, 0x45, 0x33, 0xE2, 0x81,
+       0x84, 0x38, 0x45, 0x34, 0xE2, 0x81, 0x84, 0x35,
+       0x45, 0x35, 0xE2, 0x81, 0x84, 0x36, 0x45, 0x35,
+       0xE2, 0x81, 0x84, 0x38, 0x45, 0x37, 0xE2, 0x81,
+       0x84, 0x38, 0x45, 0x41, 0xE2, 0x88, 0x95, 0x6D,
+       0x45, 0x56, 0xE2, 0x88, 0x95, 0x6D, 0x45, 0x6D,
+       0xE2, 0x88, 0x95, 0x73, 0x46, 0x31, 0xE2, 0x81,
+       0x84, 0x31, 0x30, 0x46, 0x43, 0xE2, 0x88, 0x95,
+       // Bytes 2300 - 233f
+       0x6B, 0x67, 0x46, 0x6D, 0xE2, 0x88, 0x95, 0x73,
+       0x32, 0x46, 0xD8, 0xA8, 0xD8, 0xAD, 0xD9, 0x8A,
+       0x46, 0xD8, 0xA8, 0xD8, 0xAE, 0xD9, 0x8A, 0x46,
+       0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x85, 0x46, 0xD8,
+       0xAA, 0xD8, 0xAC, 0xD9, 0x89, 0x46, 0xD8, 0xAA,
+       0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD8, 0xAA, 0xD8,
+       0xAD, 0xD8, 0xAC, 0x46, 0xD8, 0xAA, 0xD8, 0xAD,
+       0xD9, 0x85, 0x46, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9,
+       // Bytes 2340 - 237f
+       0x85, 0x46, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, 0x89,
+       0x46, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, 0x8A, 0x46,
+       0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAC, 0x46, 0xD8,
+       0xAA, 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD8, 0xAA,
+       0xD9, 0x85, 0xD8, 0xAE, 0x46, 0xD8, 0xAA, 0xD9,
+       0x85, 0xD9, 0x89, 0x46, 0xD8, 0xAA, 0xD9, 0x85,
+       0xD9, 0x8A, 0x46, 0xD8, 0xAC, 0xD8, 0xAD, 0xD9,
+       0x89, 0x46, 0xD8, 0xAC, 0xD8, 0xAD, 0xD9, 0x8A,
+       // Bytes 2380 - 23bf
+       0x46, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, 0xAD, 0x46,
+       0xD8, 0xAC, 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8,
+       0xAC, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD8, 0xAD,
+       0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD8, 0xAD, 0xD9,
+       0x85, 0xD9, 0x89, 0x46, 0xD8, 0xAD, 0xD9, 0x85,
+       0xD9, 0x8A, 0x46, 0xD8, 0xB3, 0xD8, 0xAC, 0xD8,
+       0xAD, 0x46, 0xD8, 0xB3, 0xD8, 0xAC, 0xD9, 0x89,
+       0x46, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8, 0xAC, 0x46,
+       // Bytes 23c0 - 23ff
+       0xD8, 0xB3, 0xD8, 0xAE, 0xD9, 0x89, 0x46, 0xD8,
+       0xB3, 0xD8, 0xAE, 0xD9, 0x8A, 0x46, 0xD8, 0xB3,
+       0xD9, 0x85, 0xD8, 0xAC, 0x46, 0xD8, 0xB3, 0xD9,
+       0x85, 0xD8, 0xAD, 0x46, 0xD8, 0xB3, 0xD9, 0x85,
+       0xD9, 0x85, 0x46, 0xD8, 0xB4, 0xD8, 0xAC, 0xD9,
+       0x8A, 0x46, 0xD8, 0xB4, 0xD8, 0xAD, 0xD9, 0x85,
+       0x46, 0xD8, 0xB4, 0xD8, 0xAD, 0xD9, 0x8A, 0x46,
+       0xD8, 0xB4, 0xD9, 0x85, 0xD8, 0xAE, 0x46, 0xD8,
+       // Bytes 2400 - 243f
+       0xB4, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xB5,
+       0xD8, 0xAD, 0xD8, 0xAD, 0x46, 0xD8, 0xB5, 0xD8,
+       0xAD, 0xD9, 0x8A, 0x46, 0xD8, 0xB5, 0xD9, 0x84,
+       0xD9, 0x89, 0x46, 0xD8, 0xB5, 0xD9, 0x84, 0xDB,
+       0x92, 0x46, 0xD8, 0xB5, 0xD9, 0x85, 0xD9, 0x85,
+       0x46, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x89, 0x46,
+       0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD8,
+       0xB6, 0xD8, 0xAE, 0xD9, 0x85, 0x46, 0xD8, 0xB7,
+       // Bytes 2440 - 247f
+       0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD8, 0xB7, 0xD9,
+       0x85, 0xD9, 0x85, 0x46, 0xD8, 0xB7, 0xD9, 0x85,
+       0xD9, 0x8A, 0x46, 0xD8, 0xB9, 0xD8, 0xAC, 0xD9,
+       0x85, 0x46, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x85,
+       0x46, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x89, 0x46,
+       0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD8,
+       0xBA, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xBA,
+       0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xBA, 0xD9,
+       // Bytes 2480 - 24bf
+       0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x81, 0xD8, 0xAE,
+       0xD9, 0x85, 0x46, 0xD9, 0x81, 0xD9, 0x85, 0xD9,
+       0x8A, 0x46, 0xD9, 0x82, 0xD9, 0x84, 0xDB, 0x92,
+       0x46, 0xD9, 0x82, 0xD9, 0x85, 0xD8, 0xAD, 0x46,
+       0xD9, 0x82, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9,
+       0x82, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x83,
+       0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9, 0x83, 0xD9,
+       0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x84, 0xD8, 0xAC,
+       // Bytes 24c0 - 24ff
+       0xD8, 0xAC, 0x46, 0xD9, 0x84, 0xD8, 0xAC, 0xD9,
+       0x85, 0x46, 0xD9, 0x84, 0xD8, 0xAC, 0xD9, 0x8A,
+       0x46, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x85, 0x46,
+       0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x89, 0x46, 0xD9,
+       0x84, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD9, 0x84,
+       0xD8, 0xAE, 0xD9, 0x85, 0x46, 0xD9, 0x84, 0xD9,
+       0x85, 0xD8, 0xAD, 0x46, 0xD9, 0x84, 0xD9, 0x85,
+       0xD9, 0x8A, 0x46, 0xD9, 0x85, 0xD8, 0xAC, 0xD8,
+       // Bytes 2500 - 253f
+       0xAD, 0x46, 0xD9, 0x85, 0xD8, 0xAC, 0xD8, 0xAE,
+       0x46, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x85, 0x46,
+       0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD9,
+       0x85, 0xD8, 0xAD, 0xD8, 0xAC, 0x46, 0xD9, 0x85,
+       0xD8, 0xAD, 0xD9, 0x85, 0x46, 0xD9, 0x85, 0xD8,
+       0xAD, 0xD9, 0x8A, 0x46, 0xD9, 0x85, 0xD8, 0xAE,
+       0xD8, 0xAC, 0x46, 0xD9, 0x85, 0xD8, 0xAE, 0xD9,
+       0x85, 0x46, 0xD9, 0x85, 0xD8, 0xAE, 0xD9, 0x8A,
+       // Bytes 2540 - 257f
+       0x46, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x8A, 0x46,
+       0xD9, 0x86, 0xD8, 0xAC, 0xD8, 0xAD, 0x46, 0xD9,
+       0x86, 0xD8, 0xAC, 0xD9, 0x85, 0x46, 0xD9, 0x86,
+       0xD8, 0xAC, 0xD9, 0x89, 0x46, 0xD9, 0x86, 0xD8,
+       0xAC, 0xD9, 0x8A, 0x46, 0xD9, 0x86, 0xD8, 0xAD,
+       0xD9, 0x85, 0x46, 0xD9, 0x86, 0xD8, 0xAD, 0xD9,
+       0x89, 0x46, 0xD9, 0x86, 0xD8, 0xAD, 0xD9, 0x8A,
+       0x46, 0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x89, 0x46,
+       // Bytes 2580 - 25bf
+       0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9,
+       0x87, 0xD9, 0x85, 0xD8, 0xAC, 0x46, 0xD9, 0x87,
+       0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9, 0x8A, 0xD8,
+       0xAC, 0xD9, 0x8A, 0x46, 0xD9, 0x8A, 0xD8, 0xAD,
+       0xD9, 0x8A, 0x46, 0xD9, 0x8A, 0xD9, 0x85, 0xD9,
+       0x85, 0x46, 0xD9, 0x8A, 0xD9, 0x85, 0xD9, 0x8A,
+       0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xA7, 0x46,
+       0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAC, 0x46, 0xD9,
+       // Bytes 25c0 - 25ff
+       0x8A, 0xD9, 0x94, 0xD8, 0xAD, 0x46, 0xD9, 0x8A,
+       0xD9, 0x94, 0xD8, 0xAE, 0x46, 0xD9, 0x8A, 0xD9,
+       0x94, 0xD8, 0xB1, 0x46, 0xD9, 0x8A, 0xD9, 0x94,
+       0xD8, 0xB2, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9,
+       0x85, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x86,
+       0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x87, 0x46,
+       0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x88, 0x46, 0xD9,
+       0x8A, 0xD9, 0x94, 0xD9, 0x89, 0x46, 0xD9, 0x8A,
+       // Bytes 2600 - 263f
+       0xD9, 0x94, 0xD9, 0x8A, 0x46, 0xD9, 0x8A, 0xD9,
+       0x94, 0xDB, 0x86, 0x46, 0xD9, 0x8A, 0xD9, 0x94,
+       0xDB, 0x87, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xDB,
+       0x88, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x90,
+       0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x95, 0x46,
+       0xE0, 0xB9, 0x8D, 0xE0, 0xB8, 0xB2, 0x46, 0xE0,
+       0xBA, 0xAB, 0xE0, 0xBA, 0x99, 0x46, 0xE0, 0xBA,
+       0xAB, 0xE0, 0xBA, 0xA1, 0x46, 0xE0, 0xBB, 0x8D,
+       // Bytes 2640 - 267f
+       0xE0, 0xBA, 0xB2, 0x46, 0xE0, 0xBD, 0x80, 0xE0,
+       0xBE, 0xB5, 0x46, 0xE0, 0xBD, 0x82, 0xE0, 0xBE,
+       0xB7, 0x46, 0xE0, 0xBD, 0x8C, 0xE0, 0xBE, 0xB7,
+       0x46, 0xE0, 0xBD, 0x91, 0xE0, 0xBE, 0xB7, 0x46,
+       0xE0, 0xBD, 0x96, 0xE0, 0xBE, 0xB7, 0x46, 0xE0,
+       0xBD, 0x9B, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE,
+       0x90, 0xE0, 0xBE, 0xB5, 0x46, 0xE0, 0xBE, 0x92,
+       0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0x9C, 0xE0,
+       // Bytes 2680 - 26bf
+       0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0xA1, 0xE0, 0xBE,
+       0xB7, 0x46, 0xE0, 0xBE, 0xA6, 0xE0, 0xBE, 0xB7,
+       0x46, 0xE0, 0xBE, 0xAB, 0xE0, 0xBE, 0xB7, 0x46,
+       0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x46, 0xE2,
+       0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x46, 0xE2, 0x88,
+       0xAB, 0xE2, 0x88, 0xAB, 0x46, 0xE2, 0x88, 0xAE,
+       0xE2, 0x88, 0xAE, 0x46, 0xE3, 0x81, 0xBB, 0xE3,
+       0x81, 0x8B, 0x46, 0xE3, 0x82, 0x88, 0xE3, 0x82,
+       // Bytes 26c0 - 26ff
+       0x8A, 0x46, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD,
+       0x46, 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0xB3, 0x46,
+       0xE3, 0x82, 0xB3, 0xE3, 0x83, 0x88, 0x46, 0xE3,
+       0x83, 0x88, 0xE3, 0x83, 0xB3, 0x46, 0xE3, 0x83,
+       0x8A, 0xE3, 0x83, 0x8E, 0x46, 0xE3, 0x83, 0x9B,
+       0xE3, 0x83, 0xB3, 0x46, 0xE3, 0x83, 0x9F, 0xE3,
+       0x83, 0xAA, 0x46, 0xE3, 0x83, 0xAA, 0xE3, 0x83,
+       0xA9, 0x46, 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xA0,
+       // Bytes 2700 - 273f
+       0x46, 0xE4, 0xBB, 0xA4, 0xE5, 0x92, 0x8C, 0x46,
+       0xE5, 0xA4, 0xA7, 0xE6, 0xAD, 0xA3, 0x46, 0xE5,
+       0xB9, 0xB3, 0xE6, 0x88, 0x90, 0x46, 0xE6, 0x98,
+       0x8E, 0xE6, 0xB2, 0xBB, 0x46, 0xE6, 0x98, 0xAD,
+       0xE5, 0x92, 0x8C, 0x47, 0x72, 0x61, 0x64, 0xE2,
+       0x88, 0x95, 0x73, 0x47, 0xE3, 0x80, 0x94, 0x53,
+       0xE3, 0x80, 0x95, 0x48, 0x28, 0xE1, 0x84, 0x80,
+       0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84,
+       // Bytes 2740 - 277f
+       0x82, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1,
+       0x84, 0x83, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28,
+       0xE1, 0x84, 0x85, 0xE1, 0x85, 0xA1, 0x29, 0x48,
+       0x28, 0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1, 0x29,
+       0x48, 0x28, 0xE1, 0x84, 0x87, 0xE1, 0x85, 0xA1,
+       0x29, 0x48, 0x28, 0xE1, 0x84, 0x89, 0xE1, 0x85,
+       0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x8B, 0xE1,
+       0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x8C,
+       // Bytes 2780 - 27bf
+       0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84,
+       0x8C, 0xE1, 0x85, 0xAE, 0x29, 0x48, 0x28, 0xE1,
+       0x84, 0x8E, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28,
+       0xE1, 0x84, 0x8F, 0xE1, 0x85, 0xA1, 0x29, 0x48,
+       0x28, 0xE1, 0x84, 0x90, 0xE1, 0x85, 0xA1, 0x29,
+       0x48, 0x28, 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1,
+       0x29, 0x48, 0x28, 0xE1, 0x84, 0x92, 0xE1, 0x85,
+       0xA1, 0x29, 0x48, 0x72, 0x61, 0x64, 0xE2, 0x88,
+       // Bytes 27c0 - 27ff
+       0x95, 0x73, 0x32, 0x48, 0xD8, 0xA7, 0xD9, 0x83,
+       0xD8, 0xA8, 0xD8, 0xB1, 0x48, 0xD8, 0xA7, 0xD9,
+       0x84, 0xD9, 0x84, 0xD9, 0x87, 0x48, 0xD8, 0xB1,
+       0xD8, 0xB3, 0xD9, 0x88, 0xD9, 0x84, 0x48, 0xD8,
+       0xB1, 0xDB, 0x8C, 0xD8, 0xA7, 0xD9, 0x84, 0x48,
+       0xD8, 0xB5, 0xD9, 0x84, 0xD8, 0xB9, 0xD9, 0x85,
+       0x48, 0xD8, 0xB9, 0xD9, 0x84, 0xD9, 0x8A, 0xD9,
+       0x87, 0x48, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x85,
+       // Bytes 2800 - 283f
+       0xD8, 0xAF, 0x48, 0xD9, 0x88, 0xD8, 0xB3, 0xD9,
+       0x84, 0xD9, 0x85, 0x49, 0xE2, 0x80, 0xB2, 0xE2,
+       0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x49, 0xE2, 0x80,
+       0xB5, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x49,
+       0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88,
+       0xAB, 0x49, 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE,
+       0xE2, 0x88, 0xAE, 0x49, 0xE3, 0x80, 0x94, 0xE4,
+       0xB8, 0x89, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80,
+       // Bytes 2840 - 287f
+       0x94, 0xE4, 0xBA, 0x8C, 0xE3, 0x80, 0x95, 0x49,
+       0xE3, 0x80, 0x94, 0xE5, 0x8B, 0x9D, 0xE3, 0x80,
+       0x95, 0x49, 0xE3, 0x80, 0x94, 0xE5, 0xAE, 0x89,
+       0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE6,
+       0x89, 0x93, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80,
+       0x94, 0xE6, 0x95, 0x97, 0xE3, 0x80, 0x95, 0x49,
+       0xE3, 0x80, 0x94, 0xE6, 0x9C, 0xAC, 0xE3, 0x80,
+       0x95, 0x49, 0xE3, 0x80, 0x94, 0xE7, 0x82, 0xB9,
+       // Bytes 2880 - 28bf
+       0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE7,
+       0x9B, 0x97, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x82,
+       0xA2, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x49,
+       0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
+       0x81, 0x49, 0xE3, 0x82, 0xA6, 0xE3, 0x82, 0xA9,
+       0xE3, 0x83, 0xB3, 0x49, 0xE3, 0x82, 0xAA, 0xE3,
+       0x83, 0xB3, 0xE3, 0x82, 0xB9, 0x49, 0xE3, 0x82,
+       0xAA, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xA0, 0x49,
+       // Bytes 28c0 - 28ff
+       0xE3, 0x82, 0xAB, 0xE3, 0x82, 0xA4, 0xE3, 0x83,
+       0xAA, 0x49, 0xE3, 0x82, 0xB1, 0xE3, 0x83, 0xBC,
+       0xE3, 0x82, 0xB9, 0x49, 0xE3, 0x82, 0xB3, 0xE3,
+       0x83, 0xAB, 0xE3, 0x83, 0x8A, 0x49, 0xE3, 0x82,
+       0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, 0x49,
+       0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
+       0x88, 0x49, 0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99,
+       0xE3, 0x82, 0xB7, 0x49, 0xE3, 0x83, 0x88, 0xE3,
+       // Bytes 2900 - 293f
+       0x82, 0x99, 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83,
+       0x8E, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0x49,
+       0xE3, 0x83, 0x8F, 0xE3, 0x82, 0xA4, 0xE3, 0x83,
+       0x84, 0x49, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99,
+       0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83, 0x92, 0xE3,
+       0x82, 0x9A, 0xE3, 0x82, 0xB3, 0x49, 0xE3, 0x83,
+       0x95, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xB3, 0x49,
+       0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x82,
+       // Bytes 2940 - 297f
+       0xBD, 0x49, 0xE3, 0x83, 0x98, 0xE3, 0x83, 0xAB,
+       0xE3, 0x83, 0x84, 0x49, 0xE3, 0x83, 0x9B, 0xE3,
+       0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83,
+       0x9B, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xB3, 0x49,
+       0xE3, 0x83, 0x9E, 0xE3, 0x82, 0xA4, 0xE3, 0x83,
+       0xAB, 0x49, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0x83,
+       0xE3, 0x83, 0x8F, 0x49, 0xE3, 0x83, 0x9E, 0xE3,
+       0x83, 0xAB, 0xE3, 0x82, 0xAF, 0x49, 0xE3, 0x83,
+       // Bytes 2980 - 29bf
+       0xA4, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x49,
+       0xE3, 0x83, 0xA6, 0xE3, 0x82, 0xA2, 0xE3, 0x83,
+       0xB3, 0x49, 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83,
+       0xE3, 0x83, 0x88, 0x4C, 0xE2, 0x80, 0xB2, 0xE2,
+       0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2,
+       0x4C, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2,
+       0x88, 0xAB, 0xE2, 0x88, 0xAB, 0x4C, 0xE3, 0x82,
+       0xA2, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x95, 0xE3,
+       // Bytes 29c0 - 29ff
+       0x82, 0xA1, 0x4C, 0xE3, 0x82, 0xA8, 0xE3, 0x83,
+       0xBC, 0xE3, 0x82, 0xAB, 0xE3, 0x83, 0xBC, 0x4C,
+       0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83,
+       0xAD, 0xE3, 0x83, 0xB3, 0x4C, 0xE3, 0x82, 0xAB,
+       0xE3, 0x82, 0x99, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
+       0x9E, 0x4C, 0xE3, 0x82, 0xAB, 0xE3, 0x83, 0xA9,
+       0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0x4C, 0xE3,
+       0x82, 0xAB, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xAA,
+       // Bytes 2a00 - 2a3f
+       0xE3, 0x83, 0xBC, 0x4C, 0xE3, 0x82, 0xAD, 0xE3,
+       0x82, 0x99, 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0xBC,
+       0x4C, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xA5, 0xE3,
+       0x83, 0xAA, 0xE3, 0x83, 0xBC, 0x4C, 0xE3, 0x82,
+       0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, 0xE3,
+       0x83, 0xA0, 0x4C, 0xE3, 0x82, 0xAF, 0xE3, 0x83,
+       0xAD, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x8D, 0x4C,
+       0xE3, 0x82, 0xB5, 0xE3, 0x82, 0xA4, 0xE3, 0x82,
+       // Bytes 2a40 - 2a7f
+       0xAF, 0xE3, 0x83, 0xAB, 0x4C, 0xE3, 0x82, 0xBF,
+       0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x82,
+       0xB9, 0x4C, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A,
+       0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x84, 0x4C, 0xE3,
+       0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xAF,
+       0xE3, 0x83, 0xAB, 0x4C, 0xE3, 0x83, 0x95, 0xE3,
+       0x82, 0xA3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88,
+       0x4C, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x99, 0xE3,
+       // Bytes 2a80 - 2abf
+       0x83, 0xBC, 0xE3, 0x82, 0xBF, 0x4C, 0xE3, 0x83,
+       0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0x8B, 0xE3,
+       0x83, 0x92, 0x4C, 0xE3, 0x83, 0x98, 0xE3, 0x82,
+       0x9A, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB9, 0x4C,
+       0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x99, 0xE3, 0x83,
+       0xAB, 0xE3, 0x83, 0x88, 0x4C, 0xE3, 0x83, 0x9E,
+       0xE3, 0x82, 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83,
+       0xAD, 0x4C, 0xE3, 0x83, 0x9F, 0xE3, 0x82, 0xAF,
+       // Bytes 2ac0 - 2aff
+       0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xB3, 0x4C, 0xE3,
+       0x83, 0xA1, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88,
+       0xE3, 0x83, 0xAB, 0x4C, 0xE3, 0x83, 0xAA, 0xE3,
+       0x83, 0x83, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB,
+       0x4C, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x92, 0xE3,
+       0x82, 0x9A, 0xE3, 0x83, 0xBC, 0x4C, 0xE6, 0xA0,
+       0xAA, 0xE5, 0xBC, 0x8F, 0xE4, 0xBC, 0x9A, 0xE7,
+       0xA4, 0xBE, 0x4E, 0x28, 0xE1, 0x84, 0x8B, 0xE1,
+       // Bytes 2b00 - 2b3f
+       0x85, 0xA9, 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xAE,
+       0x29, 0x4F, 0xD8, 0xAC, 0xD9, 0x84, 0x20, 0xD8,
+       0xAC, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x84, 0xD9,
+       0x87, 0x4F, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0x8F,
+       0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
+       0x88, 0x4F, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xB3,
+       0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x82,
+       0xA2, 0x4F, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD,
+       // Bytes 2b40 - 2b7f
+       0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83, 0xE3, 0x83,
+       0x88, 0x4F, 0xE3, 0x82, 0xB5, 0xE3, 0x83, 0xB3,
+       0xE3, 0x83, 0x81, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
+       0xA0, 0x4F, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99,
+       0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAC, 0xE3, 0x83,
+       0xAB, 0x4F, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0xAF,
+       0xE3, 0x82, 0xBF, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
+       0xAB, 0x4F, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A,
+       // Bytes 2b80 - 2bbf
+       0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
+       0x88, 0x4F, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0xB3,
+       0xE3, 0x82, 0xB7, 0xE3, 0x83, 0xA7, 0xE3, 0x83,
+       0xB3, 0x4F, 0xE3, 0x83, 0xA1, 0xE3, 0x82, 0xAB,
+       0xE3, 0x82, 0x99, 0xE3, 0x83, 0x88, 0xE3, 0x83,
+       0xB3, 0x4F, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0xBC,
+       0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0xE3, 0x83,
+       0xAB, 0x51, 0x28, 0xE1, 0x84, 0x8B, 0xE1, 0x85,
+       // Bytes 2bc0 - 2bff
+       0xA9, 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA5, 0xE1,
+       0x86, 0xAB, 0x29, 0x52, 0xE3, 0x82, 0xAD, 0xE3,
+       0x82, 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xBF,
+       0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0x52, 0xE3,
+       0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3, 0x82, 0xAF,
+       0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, 0xE3, 0x83,
+       0xA0, 0x52, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD,
+       0xE3, 0x83, 0xA1, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
+       // Bytes 2c00 - 2c3f
+       0x88, 0xE3, 0x83, 0xAB, 0x52, 0xE3, 0x82, 0xAF,
+       0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, 0xE3, 0x83,
+       0xA0, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3, 0x52,
+       0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0xE3, 0x82,
+       0xBB, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xA4, 0xE3,
+       0x83, 0xAD, 0x52, 0xE3, 0x83, 0x8F, 0xE3, 0x82,
+       0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xBB, 0xE3,
+       0x83, 0xB3, 0xE3, 0x83, 0x88, 0x52, 0xE3, 0x83,
+       // Bytes 2c40 - 2c7f
+       0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA2, 0xE3,
+       0x82, 0xB9, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB,
+       0x52, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0xE3,
+       0x83, 0x83, 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0xA7,
+       0xE3, 0x83, 0xAB, 0x52, 0xE3, 0x83, 0x9F, 0xE3,
+       0x83, 0xAA, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99,
+       0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x52, 0xE3,
+       0x83, 0xAC, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88,
+       // Bytes 2c80 - 2cbf
+       0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99, 0xE3, 0x83,
+       0xB3, 0x61, 0xD8, 0xB5, 0xD9, 0x84, 0xD9, 0x89,
+       0x20, 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x84, 0xD9,
+       0x87, 0x20, 0xD8, 0xB9, 0xD9, 0x84, 0xD9, 0x8A,
+       0xD9, 0x87, 0x20, 0xD9, 0x88, 0xD8, 0xB3, 0xD9,
+       0x84, 0xD9, 0x85, 0x06, 0xE0, 0xA7, 0x87, 0xE0,
+       0xA6, 0xBE, 0x01, 0x06, 0xE0, 0xA7, 0x87, 0xE0,
+       0xA7, 0x97, 0x01, 0x06, 0xE0, 0xAD, 0x87, 0xE0,
+       // Bytes 2cc0 - 2cff
+       0xAC, 0xBE, 0x01, 0x06, 0xE0, 0xAD, 0x87, 0xE0,
+       0xAD, 0x96, 0x01, 0x06, 0xE0, 0xAD, 0x87, 0xE0,
+       0xAD, 0x97, 0x01, 0x06, 0xE0, 0xAE, 0x92, 0xE0,
+       0xAF, 0x97, 0x01, 0x06, 0xE0, 0xAF, 0x86, 0xE0,
+       0xAE, 0xBE, 0x01, 0x06, 0xE0, 0xAF, 0x86, 0xE0,
+       0xAF, 0x97, 0x01, 0x06, 0xE0, 0xAF, 0x87, 0xE0,
+       0xAE, 0xBE, 0x01, 0x06, 0xE0, 0xB2, 0xBF, 0xE0,
+       0xB3, 0x95, 0x01, 0x06, 0xE0, 0xB3, 0x86, 0xE0,
+       // Bytes 2d00 - 2d3f
+       0xB3, 0x95, 0x01, 0x06, 0xE0, 0xB3, 0x86, 0xE0,
+       0xB3, 0x96, 0x01, 0x06, 0xE0, 0xB5, 0x86, 0xE0,
+       0xB4, 0xBE, 0x01, 0x06, 0xE0, 0xB5, 0x86, 0xE0,
+       0xB5, 0x97, 0x01, 0x06, 0xE0, 0xB5, 0x87, 0xE0,
+       0xB4, 0xBE, 0x01, 0x06, 0xE0, 0xB7, 0x99, 0xE0,
+       0xB7, 0x9F, 0x01, 0x06, 0xE1, 0x80, 0xA5, 0xE1,
+       0x80, 0xAE, 0x01, 0x06, 0xE1, 0xAC, 0x85, 0xE1,
+       0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0x87, 0xE1,
+       // Bytes 2d40 - 2d7f
+       0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0x89, 0xE1,
+       0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0x8B, 0xE1,
+       0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0x8D, 0xE1,
+       0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0x91, 0xE1,
+       0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0xBA, 0xE1,
+       0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0xBC, 0xE1,
+       0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0xBE, 0xE1,
+       0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0xBF, 0xE1,
+       // Bytes 2d80 - 2dbf
+       0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAD, 0x82, 0xE1,
+       0xAC, 0xB5, 0x01, 0x08, 0xF0, 0x91, 0x84, 0xB1,
+       0xF0, 0x91, 0x84, 0xA7, 0x01, 0x08, 0xF0, 0x91,
+       0x84, 0xB2, 0xF0, 0x91, 0x84, 0xA7, 0x01, 0x08,
+       0xF0, 0x91, 0x8D, 0x87, 0xF0, 0x91, 0x8C, 0xBE,
+       0x01, 0x08, 0xF0, 0x91, 0x8D, 0x87, 0xF0, 0x91,
+       0x8D, 0x97, 0x01, 0x08, 0xF0, 0x91, 0x92, 0xB9,
+       0xF0, 0x91, 0x92, 0xB0, 0x01, 0x08, 0xF0, 0x91,
+       // Bytes 2dc0 - 2dff
+       0x92, 0xB9, 0xF0, 0x91, 0x92, 0xBA, 0x01, 0x08,
+       0xF0, 0x91, 0x92, 0xB9, 0xF0, 0x91, 0x92, 0xBD,
+       0x01, 0x08, 0xF0, 0x91, 0x96, 0xB8, 0xF0, 0x91,
+       0x96, 0xAF, 0x01, 0x08, 0xF0, 0x91, 0x96, 0xB9,
+       0xF0, 0x91, 0x96, 0xAF, 0x01, 0x08, 0xF0, 0x91,
+       0xA4, 0xB5, 0xF0, 0x91, 0xA4, 0xB0, 0x01, 0x09,
+       0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0xE0, 0xB3,
+       0x95, 0x02, 0x09, 0xE0, 0xB7, 0x99, 0xE0, 0xB7,
+       // Bytes 2e00 - 2e3f
+       0x8F, 0xE0, 0xB7, 0x8A, 0x16, 0x44, 0x44, 0x5A,
+       0xCC, 0x8C, 0xCD, 0x44, 0x44, 0x7A, 0xCC, 0x8C,
+       0xCD, 0x44, 0x64, 0x7A, 0xCC, 0x8C, 0xCD, 0x46,
+       0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x93, 0xCD, 0x46,
+       0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x94, 0xCD, 0x46,
+       0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x95, 0xB9, 0x46,
+       0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+       0xE1, 0x84, 0x82, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+       // Bytes 2e40 - 2e7f
+       0xE1, 0x84, 0x83, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+       0xE1, 0x84, 0x85, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+       0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+       0xE1, 0x84, 0x87, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+       0xE1, 0x84, 0x89, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+       0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+       0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xAE, 0x01, 0x46,
+       0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+       // Bytes 2e80 - 2ebf
+       0xE1, 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+       0xE1, 0x84, 0x8F, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+       0xE1, 0x84, 0x90, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+       0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+       0xE1, 0x84, 0x92, 0xE1, 0x85, 0xA1, 0x01, 0x49,
+       0xE3, 0x83, 0xA1, 0xE3, 0x82, 0xAB, 0xE3, 0x82,
+       0x99, 0x11, 0x4C, 0xE1, 0x84, 0x8C, 0xE1, 0x85,
+       0xAE, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xB4, 0x01,
+       // Bytes 2ec0 - 2eff
+       0x4C, 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3,
+       0x82, 0xAB, 0xE3, 0x82, 0x99, 0x11, 0x4C, 0xE3,
+       0x82, 0xB3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x9B,
+       0xE3, 0x82, 0x9A, 0x11, 0x4C, 0xE3, 0x83, 0xA4,
+       0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x82,
+       0x99, 0x11, 0x4F, 0xE1, 0x84, 0x8E, 0xE1, 0x85,
+       0xA1, 0xE1, 0x86, 0xB7, 0xE1, 0x84, 0x80, 0xE1,
+       0x85, 0xA9, 0x01, 0x4F, 0xE3, 0x82, 0xA4, 0xE3,
+       // Bytes 2f00 - 2f3f
+       0x83, 0x8B, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xAF,
+       0xE3, 0x82, 0x99, 0x11, 0x4F, 0xE3, 0x82, 0xB7,
+       0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xB3, 0xE3, 0x82,
+       0xAF, 0xE3, 0x82, 0x99, 0x11, 0x4F, 0xE3, 0x83,
+       0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3,
+       0x82, 0xB7, 0xE3, 0x82, 0x99, 0x11, 0x4F, 0xE3,
+       0x83, 0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xB3,
+       0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x11, 0x52,
+       // Bytes 2f40 - 2f7f
+       0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xB9, 0xE3, 0x82,
+       0xAF, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3,
+       0x82, 0x99, 0x11, 0x52, 0xE3, 0x83, 0x95, 0xE3,
+       0x82, 0xA1, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83,
+       0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x11, 0x86,
+       0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0x01, 0x86,
+       0xE0, 0xB7, 0x99, 0xE0, 0xB7, 0x8F, 0x01, 0x03,
+       0x3C, 0xCC, 0xB8, 0x05, 0x03, 0x3D, 0xCC, 0xB8,
+       // Bytes 2f80 - 2fbf
+       0x05, 0x03, 0x3E, 0xCC, 0xB8, 0x05, 0x03, 0x41,
+       0xCC, 0x80, 0xCD, 0x03, 0x41, 0xCC, 0x81, 0xCD,
+       0x03, 0x41, 0xCC, 0x83, 0xCD, 0x03, 0x41, 0xCC,
+       0x84, 0xCD, 0x03, 0x41, 0xCC, 0x89, 0xCD, 0x03,
+       0x41, 0xCC, 0x8C, 0xCD, 0x03, 0x41, 0xCC, 0x8F,
+       0xCD, 0x03, 0x41, 0xCC, 0x91, 0xCD, 0x03, 0x41,
+       0xCC, 0xA5, 0xB9, 0x03, 0x41, 0xCC, 0xA8, 0xA9,
+       0x03, 0x42, 0xCC, 0x87, 0xCD, 0x03, 0x42, 0xCC,
+       // Bytes 2fc0 - 2fff
+       0xA3, 0xB9, 0x03, 0x42, 0xCC, 0xB1, 0xB9, 0x03,
+       0x43, 0xCC, 0x81, 0xCD, 0x03, 0x43, 0xCC, 0x82,
+       0xCD, 0x03, 0x43, 0xCC, 0x87, 0xCD, 0x03, 0x43,
+       0xCC, 0x8C, 0xCD, 0x03, 0x44, 0xCC, 0x87, 0xCD,
+       0x03, 0x44, 0xCC, 0x8C, 0xCD, 0x03, 0x44, 0xCC,
+       0xA3, 0xB9, 0x03, 0x44, 0xCC, 0xA7, 0xA9, 0x03,
+       0x44, 0xCC, 0xAD, 0xB9, 0x03, 0x44, 0xCC, 0xB1,
+       0xB9, 0x03, 0x45, 0xCC, 0x80, 0xCD, 0x03, 0x45,
+       // Bytes 3000 - 303f
+       0xCC, 0x81, 0xCD, 0x03, 0x45, 0xCC, 0x83, 0xCD,
+       0x03, 0x45, 0xCC, 0x86, 0xCD, 0x03, 0x45, 0xCC,
+       0x87, 0xCD, 0x03, 0x45, 0xCC, 0x88, 0xCD, 0x03,
+       0x45, 0xCC, 0x89, 0xCD, 0x03, 0x45, 0xCC, 0x8C,
+       0xCD, 0x03, 0x45, 0xCC, 0x8F, 0xCD, 0x03, 0x45,
+       0xCC, 0x91, 0xCD, 0x03, 0x45, 0xCC, 0xA8, 0xA9,
+       0x03, 0x45, 0xCC, 0xAD, 0xB9, 0x03, 0x45, 0xCC,
+       0xB0, 0xB9, 0x03, 0x46, 0xCC, 0x87, 0xCD, 0x03,
+       // Bytes 3040 - 307f
+       0x47, 0xCC, 0x81, 0xCD, 0x03, 0x47, 0xCC, 0x82,
+       0xCD, 0x03, 0x47, 0xCC, 0x84, 0xCD, 0x03, 0x47,
+       0xCC, 0x86, 0xCD, 0x03, 0x47, 0xCC, 0x87, 0xCD,
+       0x03, 0x47, 0xCC, 0x8C, 0xCD, 0x03, 0x47, 0xCC,
+       0xA7, 0xA9, 0x03, 0x48, 0xCC, 0x82, 0xCD, 0x03,
+       0x48, 0xCC, 0x87, 0xCD, 0x03, 0x48, 0xCC, 0x88,
+       0xCD, 0x03, 0x48, 0xCC, 0x8C, 0xCD, 0x03, 0x48,
+       0xCC, 0xA3, 0xB9, 0x03, 0x48, 0xCC, 0xA7, 0xA9,
+       // Bytes 3080 - 30bf
+       0x03, 0x48, 0xCC, 0xAE, 0xB9, 0x03, 0x49, 0xCC,
+       0x80, 0xCD, 0x03, 0x49, 0xCC, 0x81, 0xCD, 0x03,
+       0x49, 0xCC, 0x82, 0xCD, 0x03, 0x49, 0xCC, 0x83,
+       0xCD, 0x03, 0x49, 0xCC, 0x84, 0xCD, 0x03, 0x49,
+       0xCC, 0x86, 0xCD, 0x03, 0x49, 0xCC, 0x87, 0xCD,
+       0x03, 0x49, 0xCC, 0x89, 0xCD, 0x03, 0x49, 0xCC,
+       0x8C, 0xCD, 0x03, 0x49, 0xCC, 0x8F, 0xCD, 0x03,
+       0x49, 0xCC, 0x91, 0xCD, 0x03, 0x49, 0xCC, 0xA3,
+       // Bytes 30c0 - 30ff
+       0xB9, 0x03, 0x49, 0xCC, 0xA8, 0xA9, 0x03, 0x49,
+       0xCC, 0xB0, 0xB9, 0x03, 0x4A, 0xCC, 0x82, 0xCD,
+       0x03, 0x4B, 0xCC, 0x81, 0xCD, 0x03, 0x4B, 0xCC,
+       0x8C, 0xCD, 0x03, 0x4B, 0xCC, 0xA3, 0xB9, 0x03,
+       0x4B, 0xCC, 0xA7, 0xA9, 0x03, 0x4B, 0xCC, 0xB1,
+       0xB9, 0x03, 0x4C, 0xCC, 0x81, 0xCD, 0x03, 0x4C,
+       0xCC, 0x8C, 0xCD, 0x03, 0x4C, 0xCC, 0xA7, 0xA9,
+       0x03, 0x4C, 0xCC, 0xAD, 0xB9, 0x03, 0x4C, 0xCC,
+       // Bytes 3100 - 313f
+       0xB1, 0xB9, 0x03, 0x4D, 0xCC, 0x81, 0xCD, 0x03,
+       0x4D, 0xCC, 0x87, 0xCD, 0x03, 0x4D, 0xCC, 0xA3,
+       0xB9, 0x03, 0x4E, 0xCC, 0x80, 0xCD, 0x03, 0x4E,
+       0xCC, 0x81, 0xCD, 0x03, 0x4E, 0xCC, 0x83, 0xCD,
+       0x03, 0x4E, 0xCC, 0x87, 0xCD, 0x03, 0x4E, 0xCC,
+       0x8C, 0xCD, 0x03, 0x4E, 0xCC, 0xA3, 0xB9, 0x03,
+       0x4E, 0xCC, 0xA7, 0xA9, 0x03, 0x4E, 0xCC, 0xAD,
+       0xB9, 0x03, 0x4E, 0xCC, 0xB1, 0xB9, 0x03, 0x4F,
+       // Bytes 3140 - 317f
+       0xCC, 0x80, 0xCD, 0x03, 0x4F, 0xCC, 0x81, 0xCD,
+       0x03, 0x4F, 0xCC, 0x86, 0xCD, 0x03, 0x4F, 0xCC,
+       0x89, 0xCD, 0x03, 0x4F, 0xCC, 0x8B, 0xCD, 0x03,
+       0x4F, 0xCC, 0x8C, 0xCD, 0x03, 0x4F, 0xCC, 0x8F,
+       0xCD, 0x03, 0x4F, 0xCC, 0x91, 0xCD, 0x03, 0x50,
+       0xCC, 0x81, 0xCD, 0x03, 0x50, 0xCC, 0x87, 0xCD,
+       0x03, 0x52, 0xCC, 0x81, 0xCD, 0x03, 0x52, 0xCC,
+       0x87, 0xCD, 0x03, 0x52, 0xCC, 0x8C, 0xCD, 0x03,
+       // Bytes 3180 - 31bf
+       0x52, 0xCC, 0x8F, 0xCD, 0x03, 0x52, 0xCC, 0x91,
+       0xCD, 0x03, 0x52, 0xCC, 0xA7, 0xA9, 0x03, 0x52,
+       0xCC, 0xB1, 0xB9, 0x03, 0x53, 0xCC, 0x82, 0xCD,
+       0x03, 0x53, 0xCC, 0x87, 0xCD, 0x03, 0x53, 0xCC,
+       0xA6, 0xB9, 0x03, 0x53, 0xCC, 0xA7, 0xA9, 0x03,
+       0x54, 0xCC, 0x87, 0xCD, 0x03, 0x54, 0xCC, 0x8C,
+       0xCD, 0x03, 0x54, 0xCC, 0xA3, 0xB9, 0x03, 0x54,
+       0xCC, 0xA6, 0xB9, 0x03, 0x54, 0xCC, 0xA7, 0xA9,
+       // Bytes 31c0 - 31ff
+       0x03, 0x54, 0xCC, 0xAD, 0xB9, 0x03, 0x54, 0xCC,
+       0xB1, 0xB9, 0x03, 0x55, 0xCC, 0x80, 0xCD, 0x03,
+       0x55, 0xCC, 0x81, 0xCD, 0x03, 0x55, 0xCC, 0x82,
+       0xCD, 0x03, 0x55, 0xCC, 0x86, 0xCD, 0x03, 0x55,
+       0xCC, 0x89, 0xCD, 0x03, 0x55, 0xCC, 0x8A, 0xCD,
+       0x03, 0x55, 0xCC, 0x8B, 0xCD, 0x03, 0x55, 0xCC,
+       0x8C, 0xCD, 0x03, 0x55, 0xCC, 0x8F, 0xCD, 0x03,
+       0x55, 0xCC, 0x91, 0xCD, 0x03, 0x55, 0xCC, 0xA3,
+       // Bytes 3200 - 323f
+       0xB9, 0x03, 0x55, 0xCC, 0xA4, 0xB9, 0x03, 0x55,
+       0xCC, 0xA8, 0xA9, 0x03, 0x55, 0xCC, 0xAD, 0xB9,
+       0x03, 0x55, 0xCC, 0xB0, 0xB9, 0x03, 0x56, 0xCC,
+       0x83, 0xCD, 0x03, 0x56, 0xCC, 0xA3, 0xB9, 0x03,
+       0x57, 0xCC, 0x80, 0xCD, 0x03, 0x57, 0xCC, 0x81,
+       0xCD, 0x03, 0x57, 0xCC, 0x82, 0xCD, 0x03, 0x57,
+       0xCC, 0x87, 0xCD, 0x03, 0x57, 0xCC, 0x88, 0xCD,
+       0x03, 0x57, 0xCC, 0xA3, 0xB9, 0x03, 0x58, 0xCC,
+       // Bytes 3240 - 327f
+       0x87, 0xCD, 0x03, 0x58, 0xCC, 0x88, 0xCD, 0x03,
+       0x59, 0xCC, 0x80, 0xCD, 0x03, 0x59, 0xCC, 0x81,
+       0xCD, 0x03, 0x59, 0xCC, 0x82, 0xCD, 0x03, 0x59,
+       0xCC, 0x83, 0xCD, 0x03, 0x59, 0xCC, 0x84, 0xCD,
+       0x03, 0x59, 0xCC, 0x87, 0xCD, 0x03, 0x59, 0xCC,
+       0x88, 0xCD, 0x03, 0x59, 0xCC, 0x89, 0xCD, 0x03,
+       0x59, 0xCC, 0xA3, 0xB9, 0x03, 0x5A, 0xCC, 0x81,
+       0xCD, 0x03, 0x5A, 0xCC, 0x82, 0xCD, 0x03, 0x5A,
+       // Bytes 3280 - 32bf
+       0xCC, 0x87, 0xCD, 0x03, 0x5A, 0xCC, 0x8C, 0xCD,
+       0x03, 0x5A, 0xCC, 0xA3, 0xB9, 0x03, 0x5A, 0xCC,
+       0xB1, 0xB9, 0x03, 0x61, 0xCC, 0x80, 0xCD, 0x03,
+       0x61, 0xCC, 0x81, 0xCD, 0x03, 0x61, 0xCC, 0x83,
+       0xCD, 0x03, 0x61, 0xCC, 0x84, 0xCD, 0x03, 0x61,
+       0xCC, 0x89, 0xCD, 0x03, 0x61, 0xCC, 0x8C, 0xCD,
+       0x03, 0x61, 0xCC, 0x8F, 0xCD, 0x03, 0x61, 0xCC,
+       0x91, 0xCD, 0x03, 0x61, 0xCC, 0xA5, 0xB9, 0x03,
+       // Bytes 32c0 - 32ff
+       0x61, 0xCC, 0xA8, 0xA9, 0x03, 0x62, 0xCC, 0x87,
+       0xCD, 0x03, 0x62, 0xCC, 0xA3, 0xB9, 0x03, 0x62,
+       0xCC, 0xB1, 0xB9, 0x03, 0x63, 0xCC, 0x81, 0xCD,
+       0x03, 0x63, 0xCC, 0x82, 0xCD, 0x03, 0x63, 0xCC,
+       0x87, 0xCD, 0x03, 0x63, 0xCC, 0x8C, 0xCD, 0x03,
+       0x64, 0xCC, 0x87, 0xCD, 0x03, 0x64, 0xCC, 0x8C,
+       0xCD, 0x03, 0x64, 0xCC, 0xA3, 0xB9, 0x03, 0x64,
+       0xCC, 0xA7, 0xA9, 0x03, 0x64, 0xCC, 0xAD, 0xB9,
+       // Bytes 3300 - 333f
+       0x03, 0x64, 0xCC, 0xB1, 0xB9, 0x03, 0x65, 0xCC,
+       0x80, 0xCD, 0x03, 0x65, 0xCC, 0x81, 0xCD, 0x03,
+       0x65, 0xCC, 0x83, 0xCD, 0x03, 0x65, 0xCC, 0x86,
+       0xCD, 0x03, 0x65, 0xCC, 0x87, 0xCD, 0x03, 0x65,
+       0xCC, 0x88, 0xCD, 0x03, 0x65, 0xCC, 0x89, 0xCD,
+       0x03, 0x65, 0xCC, 0x8C, 0xCD, 0x03, 0x65, 0xCC,
+       0x8F, 0xCD, 0x03, 0x65, 0xCC, 0x91, 0xCD, 0x03,
+       0x65, 0xCC, 0xA8, 0xA9, 0x03, 0x65, 0xCC, 0xAD,
+       // Bytes 3340 - 337f
+       0xB9, 0x03, 0x65, 0xCC, 0xB0, 0xB9, 0x03, 0x66,
+       0xCC, 0x87, 0xCD, 0x03, 0x67, 0xCC, 0x81, 0xCD,
+       0x03, 0x67, 0xCC, 0x82, 0xCD, 0x03, 0x67, 0xCC,
+       0x84, 0xCD, 0x03, 0x67, 0xCC, 0x86, 0xCD, 0x03,
+       0x67, 0xCC, 0x87, 0xCD, 0x03, 0x67, 0xCC, 0x8C,
+       0xCD, 0x03, 0x67, 0xCC, 0xA7, 0xA9, 0x03, 0x68,
+       0xCC, 0x82, 0xCD, 0x03, 0x68, 0xCC, 0x87, 0xCD,
+       0x03, 0x68, 0xCC, 0x88, 0xCD, 0x03, 0x68, 0xCC,
+       // Bytes 3380 - 33bf
+       0x8C, 0xCD, 0x03, 0x68, 0xCC, 0xA3, 0xB9, 0x03,
+       0x68, 0xCC, 0xA7, 0xA9, 0x03, 0x68, 0xCC, 0xAE,
+       0xB9, 0x03, 0x68, 0xCC, 0xB1, 0xB9, 0x03, 0x69,
+       0xCC, 0x80, 0xCD, 0x03, 0x69, 0xCC, 0x81, 0xCD,
+       0x03, 0x69, 0xCC, 0x82, 0xCD, 0x03, 0x69, 0xCC,
+       0x83, 0xCD, 0x03, 0x69, 0xCC, 0x84, 0xCD, 0x03,
+       0x69, 0xCC, 0x86, 0xCD, 0x03, 0x69, 0xCC, 0x89,
+       0xCD, 0x03, 0x69, 0xCC, 0x8C, 0xCD, 0x03, 0x69,
+       // Bytes 33c0 - 33ff
+       0xCC, 0x8F, 0xCD, 0x03, 0x69, 0xCC, 0x91, 0xCD,
+       0x03, 0x69, 0xCC, 0xA3, 0xB9, 0x03, 0x69, 0xCC,
+       0xA8, 0xA9, 0x03, 0x69, 0xCC, 0xB0, 0xB9, 0x03,
+       0x6A, 0xCC, 0x82, 0xCD, 0x03, 0x6A, 0xCC, 0x8C,
+       0xCD, 0x03, 0x6B, 0xCC, 0x81, 0xCD, 0x03, 0x6B,
+       0xCC, 0x8C, 0xCD, 0x03, 0x6B, 0xCC, 0xA3, 0xB9,
+       0x03, 0x6B, 0xCC, 0xA7, 0xA9, 0x03, 0x6B, 0xCC,
+       0xB1, 0xB9, 0x03, 0x6C, 0xCC, 0x81, 0xCD, 0x03,
+       // Bytes 3400 - 343f
+       0x6C, 0xCC, 0x8C, 0xCD, 0x03, 0x6C, 0xCC, 0xA7,
+       0xA9, 0x03, 0x6C, 0xCC, 0xAD, 0xB9, 0x03, 0x6C,
+       0xCC, 0xB1, 0xB9, 0x03, 0x6D, 0xCC, 0x81, 0xCD,
+       0x03, 0x6D, 0xCC, 0x87, 0xCD, 0x03, 0x6D, 0xCC,
+       0xA3, 0xB9, 0x03, 0x6E, 0xCC, 0x80, 0xCD, 0x03,
+       0x6E, 0xCC, 0x81, 0xCD, 0x03, 0x6E, 0xCC, 0x83,
+       0xCD, 0x03, 0x6E, 0xCC, 0x87, 0xCD, 0x03, 0x6E,
+       0xCC, 0x8C, 0xCD, 0x03, 0x6E, 0xCC, 0xA3, 0xB9,
+       // Bytes 3440 - 347f
+       0x03, 0x6E, 0xCC, 0xA7, 0xA9, 0x03, 0x6E, 0xCC,
+       0xAD, 0xB9, 0x03, 0x6E, 0xCC, 0xB1, 0xB9, 0x03,
+       0x6F, 0xCC, 0x80, 0xCD, 0x03, 0x6F, 0xCC, 0x81,
+       0xCD, 0x03, 0x6F, 0xCC, 0x86, 0xCD, 0x03, 0x6F,
+       0xCC, 0x89, 0xCD, 0x03, 0x6F, 0xCC, 0x8B, 0xCD,
+       0x03, 0x6F, 0xCC, 0x8C, 0xCD, 0x03, 0x6F, 0xCC,
+       0x8F, 0xCD, 0x03, 0x6F, 0xCC, 0x91, 0xCD, 0x03,
+       0x70, 0xCC, 0x81, 0xCD, 0x03, 0x70, 0xCC, 0x87,
+       // Bytes 3480 - 34bf
+       0xCD, 0x03, 0x72, 0xCC, 0x81, 0xCD, 0x03, 0x72,
+       0xCC, 0x87, 0xCD, 0x03, 0x72, 0xCC, 0x8C, 0xCD,
+       0x03, 0x72, 0xCC, 0x8F, 0xCD, 0x03, 0x72, 0xCC,
+       0x91, 0xCD, 0x03, 0x72, 0xCC, 0xA7, 0xA9, 0x03,
+       0x72, 0xCC, 0xB1, 0xB9, 0x03, 0x73, 0xCC, 0x82,
+       0xCD, 0x03, 0x73, 0xCC, 0x87, 0xCD, 0x03, 0x73,
+       0xCC, 0xA6, 0xB9, 0x03, 0x73, 0xCC, 0xA7, 0xA9,
+       0x03, 0x74, 0xCC, 0x87, 0xCD, 0x03, 0x74, 0xCC,
+       // Bytes 34c0 - 34ff
+       0x88, 0xCD, 0x03, 0x74, 0xCC, 0x8C, 0xCD, 0x03,
+       0x74, 0xCC, 0xA3, 0xB9, 0x03, 0x74, 0xCC, 0xA6,
+       0xB9, 0x03, 0x74, 0xCC, 0xA7, 0xA9, 0x03, 0x74,
+       0xCC, 0xAD, 0xB9, 0x03, 0x74, 0xCC, 0xB1, 0xB9,
+       0x03, 0x75, 0xCC, 0x80, 0xCD, 0x03, 0x75, 0xCC,
+       0x81, 0xCD, 0x03, 0x75, 0xCC, 0x82, 0xCD, 0x03,
+       0x75, 0xCC, 0x86, 0xCD, 0x03, 0x75, 0xCC, 0x89,
+       0xCD, 0x03, 0x75, 0xCC, 0x8A, 0xCD, 0x03, 0x75,
+       // Bytes 3500 - 353f
+       0xCC, 0x8B, 0xCD, 0x03, 0x75, 0xCC, 0x8C, 0xCD,
+       0x03, 0x75, 0xCC, 0x8F, 0xCD, 0x03, 0x75, 0xCC,
+       0x91, 0xCD, 0x03, 0x75, 0xCC, 0xA3, 0xB9, 0x03,
+       0x75, 0xCC, 0xA4, 0xB9, 0x03, 0x75, 0xCC, 0xA8,
+       0xA9, 0x03, 0x75, 0xCC, 0xAD, 0xB9, 0x03, 0x75,
+       0xCC, 0xB0, 0xB9, 0x03, 0x76, 0xCC, 0x83, 0xCD,
+       0x03, 0x76, 0xCC, 0xA3, 0xB9, 0x03, 0x77, 0xCC,
+       0x80, 0xCD, 0x03, 0x77, 0xCC, 0x81, 0xCD, 0x03,
+       // Bytes 3540 - 357f
+       0x77, 0xCC, 0x82, 0xCD, 0x03, 0x77, 0xCC, 0x87,
+       0xCD, 0x03, 0x77, 0xCC, 0x88, 0xCD, 0x03, 0x77,
+       0xCC, 0x8A, 0xCD, 0x03, 0x77, 0xCC, 0xA3, 0xB9,
+       0x03, 0x78, 0xCC, 0x87, 0xCD, 0x03, 0x78, 0xCC,
+       0x88, 0xCD, 0x03, 0x79, 0xCC, 0x80, 0xCD, 0x03,
+       0x79, 0xCC, 0x81, 0xCD, 0x03, 0x79, 0xCC, 0x82,
+       0xCD, 0x03, 0x79, 0xCC, 0x83, 0xCD, 0x03, 0x79,
+       0xCC, 0x84, 0xCD, 0x03, 0x79, 0xCC, 0x87, 0xCD,
+       // Bytes 3580 - 35bf
+       0x03, 0x79, 0xCC, 0x88, 0xCD, 0x03, 0x79, 0xCC,
+       0x89, 0xCD, 0x03, 0x79, 0xCC, 0x8A, 0xCD, 0x03,
+       0x79, 0xCC, 0xA3, 0xB9, 0x03, 0x7A, 0xCC, 0x81,
+       0xCD, 0x03, 0x7A, 0xCC, 0x82, 0xCD, 0x03, 0x7A,
+       0xCC, 0x87, 0xCD, 0x03, 0x7A, 0xCC, 0x8C, 0xCD,
+       0x03, 0x7A, 0xCC, 0xA3, 0xB9, 0x03, 0x7A, 0xCC,
+       0xB1, 0xB9, 0x04, 0xC2, 0xA8, 0xCC, 0x80, 0xCE,
+       0x04, 0xC2, 0xA8, 0xCC, 0x81, 0xCE, 0x04, 0xC2,
+       // Bytes 35c0 - 35ff
+       0xA8, 0xCD, 0x82, 0xCE, 0x04, 0xC3, 0x86, 0xCC,
+       0x81, 0xCD, 0x04, 0xC3, 0x86, 0xCC, 0x84, 0xCD,
+       0x04, 0xC3, 0x98, 0xCC, 0x81, 0xCD, 0x04, 0xC3,
+       0xA6, 0xCC, 0x81, 0xCD, 0x04, 0xC3, 0xA6, 0xCC,
+       0x84, 0xCD, 0x04, 0xC3, 0xB8, 0xCC, 0x81, 0xCD,
+       0x04, 0xC5, 0xBF, 0xCC, 0x87, 0xCD, 0x04, 0xC6,
+       0xB7, 0xCC, 0x8C, 0xCD, 0x04, 0xCA, 0x92, 0xCC,
+       0x8C, 0xCD, 0x04, 0xCE, 0x91, 0xCC, 0x80, 0xCD,
+       // Bytes 3600 - 363f
+       0x04, 0xCE, 0x91, 0xCC, 0x81, 0xCD, 0x04, 0xCE,
+       0x91, 0xCC, 0x84, 0xCD, 0x04, 0xCE, 0x91, 0xCC,
+       0x86, 0xCD, 0x04, 0xCE, 0x91, 0xCD, 0x85, 0xDD,
+       0x04, 0xCE, 0x95, 0xCC, 0x80, 0xCD, 0x04, 0xCE,
+       0x95, 0xCC, 0x81, 0xCD, 0x04, 0xCE, 0x97, 0xCC,
+       0x80, 0xCD, 0x04, 0xCE, 0x97, 0xCC, 0x81, 0xCD,
+       0x04, 0xCE, 0x97, 0xCD, 0x85, 0xDD, 0x04, 0xCE,
+       0x99, 0xCC, 0x80, 0xCD, 0x04, 0xCE, 0x99, 0xCC,
+       // Bytes 3640 - 367f
+       0x81, 0xCD, 0x04, 0xCE, 0x99, 0xCC, 0x84, 0xCD,
+       0x04, 0xCE, 0x99, 0xCC, 0x86, 0xCD, 0x04, 0xCE,
+       0x99, 0xCC, 0x88, 0xCD, 0x04, 0xCE, 0x9F, 0xCC,
+       0x80, 0xCD, 0x04, 0xCE, 0x9F, 0xCC, 0x81, 0xCD,
+       0x04, 0xCE, 0xA1, 0xCC, 0x94, 0xCD, 0x04, 0xCE,
+       0xA5, 0xCC, 0x80, 0xCD, 0x04, 0xCE, 0xA5, 0xCC,
+       0x81, 0xCD, 0x04, 0xCE, 0xA5, 0xCC, 0x84, 0xCD,
+       0x04, 0xCE, 0xA5, 0xCC, 0x86, 0xCD, 0x04, 0xCE,
+       // Bytes 3680 - 36bf
+       0xA5, 0xCC, 0x88, 0xCD, 0x04, 0xCE, 0xA9, 0xCC,
+       0x80, 0xCD, 0x04, 0xCE, 0xA9, 0xCC, 0x81, 0xCD,
+       0x04, 0xCE, 0xA9, 0xCD, 0x85, 0xDD, 0x04, 0xCE,
+       0xB1, 0xCC, 0x84, 0xCD, 0x04, 0xCE, 0xB1, 0xCC,
+       0x86, 0xCD, 0x04, 0xCE, 0xB1, 0xCD, 0x85, 0xDD,
+       0x04, 0xCE, 0xB5, 0xCC, 0x80, 0xCD, 0x04, 0xCE,
+       0xB5, 0xCC, 0x81, 0xCD, 0x04, 0xCE, 0xB7, 0xCD,
+       0x85, 0xDD, 0x04, 0xCE, 0xB9, 0xCC, 0x80, 0xCD,
+       // Bytes 36c0 - 36ff
+       0x04, 0xCE, 0xB9, 0xCC, 0x81, 0xCD, 0x04, 0xCE,
+       0xB9, 0xCC, 0x84, 0xCD, 0x04, 0xCE, 0xB9, 0xCC,
+       0x86, 0xCD, 0x04, 0xCE, 0xB9, 0xCD, 0x82, 0xCD,
+       0x04, 0xCE, 0xBF, 0xCC, 0x80, 0xCD, 0x04, 0xCE,
+       0xBF, 0xCC, 0x81, 0xCD, 0x04, 0xCF, 0x81, 0xCC,
+       0x93, 0xCD, 0x04, 0xCF, 0x81, 0xCC, 0x94, 0xCD,
+       0x04, 0xCF, 0x85, 0xCC, 0x80, 0xCD, 0x04, 0xCF,
+       0x85, 0xCC, 0x81, 0xCD, 0x04, 0xCF, 0x85, 0xCC,
+       // Bytes 3700 - 373f
+       0x84, 0xCD, 0x04, 0xCF, 0x85, 0xCC, 0x86, 0xCD,
+       0x04, 0xCF, 0x85, 0xCD, 0x82, 0xCD, 0x04, 0xCF,
+       0x89, 0xCD, 0x85, 0xDD, 0x04, 0xCF, 0x92, 0xCC,
+       0x81, 0xCD, 0x04, 0xCF, 0x92, 0xCC, 0x88, 0xCD,
+       0x04, 0xD0, 0x86, 0xCC, 0x88, 0xCD, 0x04, 0xD0,
+       0x90, 0xCC, 0x86, 0xCD, 0x04, 0xD0, 0x90, 0xCC,
+       0x88, 0xCD, 0x04, 0xD0, 0x93, 0xCC, 0x81, 0xCD,
+       0x04, 0xD0, 0x95, 0xCC, 0x80, 0xCD, 0x04, 0xD0,
+       // Bytes 3740 - 377f
+       0x95, 0xCC, 0x86, 0xCD, 0x04, 0xD0, 0x95, 0xCC,
+       0x88, 0xCD, 0x04, 0xD0, 0x96, 0xCC, 0x86, 0xCD,
+       0x04, 0xD0, 0x96, 0xCC, 0x88, 0xCD, 0x04, 0xD0,
+       0x97, 0xCC, 0x88, 0xCD, 0x04, 0xD0, 0x98, 0xCC,
+       0x80, 0xCD, 0x04, 0xD0, 0x98, 0xCC, 0x84, 0xCD,
+       0x04, 0xD0, 0x98, 0xCC, 0x86, 0xCD, 0x04, 0xD0,
+       0x98, 0xCC, 0x88, 0xCD, 0x04, 0xD0, 0x9A, 0xCC,
+       0x81, 0xCD, 0x04, 0xD0, 0x9E, 0xCC, 0x88, 0xCD,
+       // Bytes 3780 - 37bf
+       0x04, 0xD0, 0xA3, 0xCC, 0x84, 0xCD, 0x04, 0xD0,
+       0xA3, 0xCC, 0x86, 0xCD, 0x04, 0xD0, 0xA3, 0xCC,
+       0x88, 0xCD, 0x04, 0xD0, 0xA3, 0xCC, 0x8B, 0xCD,
+       0x04, 0xD0, 0xA7, 0xCC, 0x88, 0xCD, 0x04, 0xD0,
+       0xAB, 0xCC, 0x88, 0xCD, 0x04, 0xD0, 0xAD, 0xCC,
+       0x88, 0xCD, 0x04, 0xD0, 0xB0, 0xCC, 0x86, 0xCD,
+       0x04, 0xD0, 0xB0, 0xCC, 0x88, 0xCD, 0x04, 0xD0,
+       0xB3, 0xCC, 0x81, 0xCD, 0x04, 0xD0, 0xB5, 0xCC,
+       // Bytes 37c0 - 37ff
+       0x80, 0xCD, 0x04, 0xD0, 0xB5, 0xCC, 0x86, 0xCD,
+       0x04, 0xD0, 0xB5, 0xCC, 0x88, 0xCD, 0x04, 0xD0,
+       0xB6, 0xCC, 0x86, 0xCD, 0x04, 0xD0, 0xB6, 0xCC,
+       0x88, 0xCD, 0x04, 0xD0, 0xB7, 0xCC, 0x88, 0xCD,
+       0x04, 0xD0, 0xB8, 0xCC, 0x80, 0xCD, 0x04, 0xD0,
+       0xB8, 0xCC, 0x84, 0xCD, 0x04, 0xD0, 0xB8, 0xCC,
+       0x86, 0xCD, 0x04, 0xD0, 0xB8, 0xCC, 0x88, 0xCD,
+       0x04, 0xD0, 0xBA, 0xCC, 0x81, 0xCD, 0x04, 0xD0,
+       // Bytes 3800 - 383f
+       0xBE, 0xCC, 0x88, 0xCD, 0x04, 0xD1, 0x83, 0xCC,
+       0x84, 0xCD, 0x04, 0xD1, 0x83, 0xCC, 0x86, 0xCD,
+       0x04, 0xD1, 0x83, 0xCC, 0x88, 0xCD, 0x04, 0xD1,
+       0x83, 0xCC, 0x8B, 0xCD, 0x04, 0xD1, 0x87, 0xCC,
+       0x88, 0xCD, 0x04, 0xD1, 0x8B, 0xCC, 0x88, 0xCD,
+       0x04, 0xD1, 0x8D, 0xCC, 0x88, 0xCD, 0x04, 0xD1,
+       0x96, 0xCC, 0x88, 0xCD, 0x04, 0xD1, 0xB4, 0xCC,
+       0x8F, 0xCD, 0x04, 0xD1, 0xB5, 0xCC, 0x8F, 0xCD,
+       // Bytes 3840 - 387f
+       0x04, 0xD3, 0x98, 0xCC, 0x88, 0xCD, 0x04, 0xD3,
+       0x99, 0xCC, 0x88, 0xCD, 0x04, 0xD3, 0xA8, 0xCC,
+       0x88, 0xCD, 0x04, 0xD3, 0xA9, 0xCC, 0x88, 0xCD,
+       0x04, 0xD8, 0xA7, 0xD9, 0x93, 0xCD, 0x04, 0xD8,
+       0xA7, 0xD9, 0x94, 0xCD, 0x04, 0xD8, 0xA7, 0xD9,
+       0x95, 0xB9, 0x04, 0xD9, 0x88, 0xD9, 0x94, 0xCD,
+       0x04, 0xD9, 0x8A, 0xD9, 0x94, 0xCD, 0x04, 0xDB,
+       0x81, 0xD9, 0x94, 0xCD, 0x04, 0xDB, 0x92, 0xD9,
+       // Bytes 3880 - 38bf
+       0x94, 0xCD, 0x04, 0xDB, 0x95, 0xD9, 0x94, 0xCD,
+       0x05, 0x41, 0xCC, 0x82, 0xCC, 0x80, 0xCE, 0x05,
+       0x41, 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, 0x41,
+       0xCC, 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x41, 0xCC,
+       0x82, 0xCC, 0x89, 0xCE, 0x05, 0x41, 0xCC, 0x86,
+       0xCC, 0x80, 0xCE, 0x05, 0x41, 0xCC, 0x86, 0xCC,
+       0x81, 0xCE, 0x05, 0x41, 0xCC, 0x86, 0xCC, 0x83,
+       0xCE, 0x05, 0x41, 0xCC, 0x86, 0xCC, 0x89, 0xCE,
+       // Bytes 38c0 - 38ff
+       0x05, 0x41, 0xCC, 0x87, 0xCC, 0x84, 0xCE, 0x05,
+       0x41, 0xCC, 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x41,
+       0xCC, 0x8A, 0xCC, 0x81, 0xCE, 0x05, 0x41, 0xCC,
+       0xA3, 0xCC, 0x82, 0xCE, 0x05, 0x41, 0xCC, 0xA3,
+       0xCC, 0x86, 0xCE, 0x05, 0x43, 0xCC, 0xA7, 0xCC,
+       0x81, 0xCE, 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x80,
+       0xCE, 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x81, 0xCE,
+       0x05, 0x45, 0xCC, 0x82, 0xCC, 0x83, 0xCE, 0x05,
+       // Bytes 3900 - 393f
+       0x45, 0xCC, 0x82, 0xCC, 0x89, 0xCE, 0x05, 0x45,
+       0xCC, 0x84, 0xCC, 0x80, 0xCE, 0x05, 0x45, 0xCC,
+       0x84, 0xCC, 0x81, 0xCE, 0x05, 0x45, 0xCC, 0xA3,
+       0xCC, 0x82, 0xCE, 0x05, 0x45, 0xCC, 0xA7, 0xCC,
+       0x86, 0xCE, 0x05, 0x49, 0xCC, 0x88, 0xCC, 0x81,
+       0xCE, 0x05, 0x4C, 0xCC, 0xA3, 0xCC, 0x84, 0xCE,
+       0x05, 0x4F, 0xCC, 0x82, 0xCC, 0x80, 0xCE, 0x05,
+       0x4F, 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, 0x4F,
+       // Bytes 3940 - 397f
+       0xCC, 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x4F, 0xCC,
+       0x82, 0xCC, 0x89, 0xCE, 0x05, 0x4F, 0xCC, 0x83,
+       0xCC, 0x81, 0xCE, 0x05, 0x4F, 0xCC, 0x83, 0xCC,
+       0x84, 0xCE, 0x05, 0x4F, 0xCC, 0x83, 0xCC, 0x88,
+       0xCE, 0x05, 0x4F, 0xCC, 0x84, 0xCC, 0x80, 0xCE,
+       0x05, 0x4F, 0xCC, 0x84, 0xCC, 0x81, 0xCE, 0x05,
+       0x4F, 0xCC, 0x87, 0xCC, 0x84, 0xCE, 0x05, 0x4F,
+       0xCC, 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x4F, 0xCC,
+       // Bytes 3980 - 39bf
+       0x9B, 0xCC, 0x80, 0xCE, 0x05, 0x4F, 0xCC, 0x9B,
+       0xCC, 0x81, 0xCE, 0x05, 0x4F, 0xCC, 0x9B, 0xCC,
+       0x83, 0xCE, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, 0x89,
+       0xCE, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, 0xA3, 0xBA,
+       0x05, 0x4F, 0xCC, 0xA3, 0xCC, 0x82, 0xCE, 0x05,
+       0x4F, 0xCC, 0xA8, 0xCC, 0x84, 0xCE, 0x05, 0x52,
+       0xCC, 0xA3, 0xCC, 0x84, 0xCE, 0x05, 0x53, 0xCC,
+       0x81, 0xCC, 0x87, 0xCE, 0x05, 0x53, 0xCC, 0x8C,
+       // Bytes 39c0 - 39ff
+       0xCC, 0x87, 0xCE, 0x05, 0x53, 0xCC, 0xA3, 0xCC,
+       0x87, 0xCE, 0x05, 0x55, 0xCC, 0x83, 0xCC, 0x81,
+       0xCE, 0x05, 0x55, 0xCC, 0x84, 0xCC, 0x88, 0xCE,
+       0x05, 0x55, 0xCC, 0x88, 0xCC, 0x80, 0xCE, 0x05,
+       0x55, 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x05, 0x55,
+       0xCC, 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x55, 0xCC,
+       0x88, 0xCC, 0x8C, 0xCE, 0x05, 0x55, 0xCC, 0x9B,
+       0xCC, 0x80, 0xCE, 0x05, 0x55, 0xCC, 0x9B, 0xCC,
+       // Bytes 3a00 - 3a3f
+       0x81, 0xCE, 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0x83,
+       0xCE, 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0x89, 0xCE,
+       0x05, 0x55, 0xCC, 0x9B, 0xCC, 0xA3, 0xBA, 0x05,
+       0x61, 0xCC, 0x82, 0xCC, 0x80, 0xCE, 0x05, 0x61,
+       0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, 0x61, 0xCC,
+       0x82, 0xCC, 0x83, 0xCE, 0x05, 0x61, 0xCC, 0x82,
+       0xCC, 0x89, 0xCE, 0x05, 0x61, 0xCC, 0x86, 0xCC,
+       0x80, 0xCE, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x81,
+       // Bytes 3a40 - 3a7f
+       0xCE, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x83, 0xCE,
+       0x05, 0x61, 0xCC, 0x86, 0xCC, 0x89, 0xCE, 0x05,
+       0x61, 0xCC, 0x87, 0xCC, 0x84, 0xCE, 0x05, 0x61,
+       0xCC, 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x61, 0xCC,
+       0x8A, 0xCC, 0x81, 0xCE, 0x05, 0x61, 0xCC, 0xA3,
+       0xCC, 0x82, 0xCE, 0x05, 0x61, 0xCC, 0xA3, 0xCC,
+       0x86, 0xCE, 0x05, 0x63, 0xCC, 0xA7, 0xCC, 0x81,
+       0xCE, 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x80, 0xCE,
+       // Bytes 3a80 - 3abf
+       0x05, 0x65, 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05,
+       0x65, 0xCC, 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x65,
+       0xCC, 0x82, 0xCC, 0x89, 0xCE, 0x05, 0x65, 0xCC,
+       0x84, 0xCC, 0x80, 0xCE, 0x05, 0x65, 0xCC, 0x84,
+       0xCC, 0x81, 0xCE, 0x05, 0x65, 0xCC, 0xA3, 0xCC,
+       0x82, 0xCE, 0x05, 0x65, 0xCC, 0xA7, 0xCC, 0x86,
+       0xCE, 0x05, 0x69, 0xCC, 0x88, 0xCC, 0x81, 0xCE,
+       0x05, 0x6C, 0xCC, 0xA3, 0xCC, 0x84, 0xCE, 0x05,
+       // Bytes 3ac0 - 3aff
+       0x6F, 0xCC, 0x82, 0xCC, 0x80, 0xCE, 0x05, 0x6F,
+       0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, 0x6F, 0xCC,
+       0x82, 0xCC, 0x83, 0xCE, 0x05, 0x6F, 0xCC, 0x82,
+       0xCC, 0x89, 0xCE, 0x05, 0x6F, 0xCC, 0x83, 0xCC,
+       0x81, 0xCE, 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x84,
+       0xCE, 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x88, 0xCE,
+       0x05, 0x6F, 0xCC, 0x84, 0xCC, 0x80, 0xCE, 0x05,
+       0x6F, 0xCC, 0x84, 0xCC, 0x81, 0xCE, 0x05, 0x6F,
+       // Bytes 3b00 - 3b3f
+       0xCC, 0x87, 0xCC, 0x84, 0xCE, 0x05, 0x6F, 0xCC,
+       0x88, 0xCC, 0x84, 0xCE, 0x05, 0x6F, 0xCC, 0x9B,
+       0xCC, 0x80, 0xCE, 0x05, 0x6F, 0xCC, 0x9B, 0xCC,
+       0x81, 0xCE, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x83,
+       0xCE, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x89, 0xCE,
+       0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0xA3, 0xBA, 0x05,
+       0x6F, 0xCC, 0xA3, 0xCC, 0x82, 0xCE, 0x05, 0x6F,
+       0xCC, 0xA8, 0xCC, 0x84, 0xCE, 0x05, 0x72, 0xCC,
+       // Bytes 3b40 - 3b7f
+       0xA3, 0xCC, 0x84, 0xCE, 0x05, 0x73, 0xCC, 0x81,
+       0xCC, 0x87, 0xCE, 0x05, 0x73, 0xCC, 0x8C, 0xCC,
+       0x87, 0xCE, 0x05, 0x73, 0xCC, 0xA3, 0xCC, 0x87,
+       0xCE, 0x05, 0x75, 0xCC, 0x83, 0xCC, 0x81, 0xCE,
+       0x05, 0x75, 0xCC, 0x84, 0xCC, 0x88, 0xCE, 0x05,
+       0x75, 0xCC, 0x88, 0xCC, 0x80, 0xCE, 0x05, 0x75,
+       0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x05, 0x75, 0xCC,
+       0x88, 0xCC, 0x84, 0xCE, 0x05, 0x75, 0xCC, 0x88,
+       // Bytes 3b80 - 3bbf
+       0xCC, 0x8C, 0xCE, 0x05, 0x75, 0xCC, 0x9B, 0xCC,
+       0x80, 0xCE, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x81,
+       0xCE, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x83, 0xCE,
+       0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x89, 0xCE, 0x05,
+       0x75, 0xCC, 0x9B, 0xCC, 0xA3, 0xBA, 0x05, 0xE1,
+       0xBE, 0xBF, 0xCC, 0x80, 0xCE, 0x05, 0xE1, 0xBE,
+       0xBF, 0xCC, 0x81, 0xCE, 0x05, 0xE1, 0xBE, 0xBF,
+       0xCD, 0x82, 0xCE, 0x05, 0xE1, 0xBF, 0xBE, 0xCC,
+       // Bytes 3bc0 - 3bff
+       0x80, 0xCE, 0x05, 0xE1, 0xBF, 0xBE, 0xCC, 0x81,
+       0xCE, 0x05, 0xE1, 0xBF, 0xBE, 0xCD, 0x82, 0xCE,
+       0x05, 0xE2, 0x86, 0x90, 0xCC, 0xB8, 0x05, 0x05,
+       0xE2, 0x86, 0x92, 0xCC, 0xB8, 0x05, 0x05, 0xE2,
+       0x86, 0x94, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x87,
+       0x90, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x87, 0x92,
+       0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x87, 0x94, 0xCC,
+       0xB8, 0x05, 0x05, 0xE2, 0x88, 0x83, 0xCC, 0xB8,
+       // Bytes 3c00 - 3c3f
+       0x05, 0x05, 0xE2, 0x88, 0x88, 0xCC, 0xB8, 0x05,
+       0x05, 0xE2, 0x88, 0x8B, 0xCC, 0xB8, 0x05, 0x05,
+       0xE2, 0x88, 0xA3, 0xCC, 0xB8, 0x05, 0x05, 0xE2,
+       0x88, 0xA5, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x88,
+       0xBC, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x83,
+       0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x85, 0xCC,
+       0xB8, 0x05, 0x05, 0xE2, 0x89, 0x88, 0xCC, 0xB8,
+       0x05, 0x05, 0xE2, 0x89, 0x8D, 0xCC, 0xB8, 0x05,
+       // Bytes 3c40 - 3c7f
+       0x05, 0xE2, 0x89, 0xA1, 0xCC, 0xB8, 0x05, 0x05,
+       0xE2, 0x89, 0xA4, 0xCC, 0xB8, 0x05, 0x05, 0xE2,
+       0x89, 0xA5, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89,
+       0xB2, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xB3,
+       0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xB6, 0xCC,
+       0xB8, 0x05, 0x05, 0xE2, 0x89, 0xB7, 0xCC, 0xB8,
+       0x05, 0x05, 0xE2, 0x89, 0xBA, 0xCC, 0xB8, 0x05,
+       0x05, 0xE2, 0x89, 0xBB, 0xCC, 0xB8, 0x05, 0x05,
+       // Bytes 3c80 - 3cbf
+       0xE2, 0x89, 0xBC, 0xCC, 0xB8, 0x05, 0x05, 0xE2,
+       0x89, 0xBD, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A,
+       0x82, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x83,
+       0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x86, 0xCC,
+       0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x87, 0xCC, 0xB8,
+       0x05, 0x05, 0xE2, 0x8A, 0x91, 0xCC, 0xB8, 0x05,
+       0x05, 0xE2, 0x8A, 0x92, 0xCC, 0xB8, 0x05, 0x05,
+       0xE2, 0x8A, 0xA2, 0xCC, 0xB8, 0x05, 0x05, 0xE2,
+       // Bytes 3cc0 - 3cff
+       0x8A, 0xA8, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A,
+       0xA9, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xAB,
+       0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xB2, 0xCC,
+       0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xB3, 0xCC, 0xB8,
+       0x05, 0x05, 0xE2, 0x8A, 0xB4, 0xCC, 0xB8, 0x05,
+       0x05, 0xE2, 0x8A, 0xB5, 0xCC, 0xB8, 0x05, 0x06,
+       0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
+       0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
+       // Bytes 3d00 - 3d3f
+       0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
+       0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
+       0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
+       0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
+       0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
+       0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
+       0xCE, 0x99, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
+       0xCE, 0x99, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
+       // Bytes 3d40 - 3d7f
+       0xCE, 0x99, 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x06,
+       0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
+       0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
+       0xCE, 0x99, 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x06,
+       0xCE, 0x9F, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
+       0xCE, 0x9F, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
+       0xCE, 0x9F, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
+       0xCE, 0x9F, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
+       // Bytes 3d80 - 3dbf
+       0xCE, 0xA5, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
+       0xCE, 0xA5, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
+       0xCE, 0xA5, 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x06,
+       0xCE, 0xA9, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
+       0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
+       0xCE, 0xB1, 0xCC, 0x80, 0xCD, 0x85, 0xDE, 0x06,
+       0xCE, 0xB1, 0xCC, 0x81, 0xCD, 0x85, 0xDE, 0x06,
+       0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
+       // Bytes 3dc0 - 3dff
+       0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
+       0xCE, 0xB1, 0xCD, 0x82, 0xCD, 0x85, 0xDE, 0x06,
+       0xCE, 0xB5, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
+       0xCE, 0xB5, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
+       0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
+       0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
+       0xCE, 0xB7, 0xCC, 0x80, 0xCD, 0x85, 0xDE, 0x06,
+       0xCE, 0xB7, 0xCC, 0x81, 0xCD, 0x85, 0xDE, 0x06,
+       // Bytes 3e00 - 3e3f
+       0xCE, 0xB7, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
+       0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
+       0xCE, 0xB7, 0xCD, 0x82, 0xCD, 0x85, 0xDE, 0x06,
+       0xCE, 0xB9, 0xCC, 0x88, 0xCC, 0x80, 0xCE, 0x06,
+       0xCE, 0xB9, 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x06,
+       0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x82, 0xCE, 0x06,
+       0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
+       0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
+       // Bytes 3e40 - 3e7f
+       0xCE, 0xB9, 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x06,
+       0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
+       0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
+       0xCE, 0xB9, 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x06,
+       0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
+       0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
+       0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
+       0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
+       // Bytes 3e80 - 3ebf
+       0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x80, 0xCE, 0x06,
+       0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x06,
+       0xCF, 0x85, 0xCC, 0x88, 0xCD, 0x82, 0xCE, 0x06,
+       0xCF, 0x85, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
+       0xCF, 0x85, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
+       0xCF, 0x85, 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x06,
+       0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
+       0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
+       // Bytes 3ec0 - 3eff
+       0xCF, 0x85, 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x06,
+       0xCF, 0x89, 0xCC, 0x80, 0xCD, 0x85, 0xDE, 0x06,
+       0xCF, 0x89, 0xCC, 0x81, 0xCD, 0x85, 0xDE, 0x06,
+       0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
+       0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
+       0xCF, 0x89, 0xCD, 0x82, 0xCD, 0x85, 0xDE, 0x06,
+       0xE0, 0xA4, 0xA8, 0xE0, 0xA4, 0xBC, 0x0D, 0x06,
+       0xE0, 0xA4, 0xB0, 0xE0, 0xA4, 0xBC, 0x0D, 0x06,
+       // Bytes 3f00 - 3f3f
+       0xE0, 0xA4, 0xB3, 0xE0, 0xA4, 0xBC, 0x0D, 0x06,
+       0xE0, 0xB1, 0x86, 0xE0, 0xB1, 0x96, 0x89, 0x06,
+       0xE0, 0xB7, 0x99, 0xE0, 0xB7, 0x8A, 0x15, 0x06,
+       0xE3, 0x81, 0x86, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0x8B, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0x8D, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0x8F, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0x91, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       // Bytes 3f40 - 3f7f
+       0xE3, 0x81, 0x93, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0x95, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0x97, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0x99, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0x9B, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0x9D, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0x9F, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0xA1, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       // Bytes 3f80 - 3fbf
+       0xE3, 0x81, 0xA4, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0xA6, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0xA8, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+       0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+       0xE3, 0x81, 0xB5, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       // Bytes 3fc0 - 3fff
+       0xE3, 0x81, 0xB5, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+       0xE3, 0x81, 0xB8, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0xB8, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+       0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+       0xE3, 0x82, 0x9D, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x82, 0xA6, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       // Bytes 4000 - 403f
+       0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x82, 0xB3, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x82, 0xB5, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x82, 0xB7, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x82, 0xB9, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       // Bytes 4040 - 407f
+       0xE3, 0x82, 0xBD, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x83, 0x81, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x83, 0x84, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+       // Bytes 4080 - 40bf
+       0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+       0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x83, 0x95, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+       0xE3, 0x83, 0x98, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+       0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+       // Bytes 40c0 - 40ff
+       0xE3, 0x83, 0xAF, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x83, 0xB0, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x83, 0xB1, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x83, 0xB2, 0xE3, 0x82, 0x99, 0x11, 0x06,
+       0xE3, 0x83, 0xBD, 0xE3, 0x82, 0x99, 0x11, 0x08,
+       0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85,
+       0xDF, 0x08, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x81,
+       0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x91, 0xCC, 0x93,
+       // Bytes 4100 - 413f
+       0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x91,
+       0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08,
+       0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85,
+       0xDF, 0x08, 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x82,
+       0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x97, 0xCC, 0x93,
+       0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x97,
+       0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08,
+       0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85,
+       // Bytes 4140 - 417f
+       0xDF, 0x08, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x80,
+       0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x97, 0xCC, 0x94,
+       0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x97,
+       0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08,
+       0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85,
+       0xDF, 0x08, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x81,
+       0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xA9, 0xCC, 0x93,
+       0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xA9,
+       // Bytes 4180 - 41bf
+       0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08,
+       0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85,
+       0xDF, 0x08, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x82,
+       0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB1, 0xCC, 0x93,
+       0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB1,
+       0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08,
+       0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85,
+       0xDF, 0x08, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, 0x80,
+       // Bytes 41c0 - 41ff
+       0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB1, 0xCC, 0x94,
+       0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB1,
+       0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08,
+       0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85,
+       0xDF, 0x08, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x81,
+       0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB7, 0xCC, 0x93,
+       0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB7,
+       0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08,
+       // Bytes 4200 - 423f
+       0xCE, 0xB7, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85,
+       0xDF, 0x08, 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x82,
+       0xCD, 0x85, 0xDF, 0x08, 0xCF, 0x89, 0xCC, 0x93,
+       0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08, 0xCF, 0x89,
+       0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08,
+       0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85,
+       0xDF, 0x08, 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x80,
+       0xCD, 0x85, 0xDF, 0x08, 0xCF, 0x89, 0xCC, 0x94,
+       // Bytes 4240 - 427f
+       0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08, 0xCF, 0x89,
+       0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08,
+       0xF0, 0x91, 0x82, 0x99, 0xF0, 0x91, 0x82, 0xBA,
+       0x0D, 0x08, 0xF0, 0x91, 0x82, 0x9B, 0xF0, 0x91,
+       0x82, 0xBA, 0x0D, 0x08, 0xF0, 0x91, 0x82, 0xA5,
+       0xF0, 0x91, 0x82, 0xBA, 0x0D, 0x42, 0xC2, 0xB4,
+       0x01, 0x43, 0x20, 0xCC, 0x81, 0xCD, 0x43, 0x20,
+       0xCC, 0x83, 0xCD, 0x43, 0x20, 0xCC, 0x84, 0xCD,
+       // Bytes 4280 - 42bf
+       0x43, 0x20, 0xCC, 0x85, 0xCD, 0x43, 0x20, 0xCC,
+       0x86, 0xCD, 0x43, 0x20, 0xCC, 0x87, 0xCD, 0x43,
+       0x20, 0xCC, 0x88, 0xCD, 0x43, 0x20, 0xCC, 0x8A,
+       0xCD, 0x43, 0x20, 0xCC, 0x8B, 0xCD, 0x43, 0x20,
+       0xCC, 0x93, 0xCD, 0x43, 0x20, 0xCC, 0x94, 0xCD,
+       0x43, 0x20, 0xCC, 0xA7, 0xA9, 0x43, 0x20, 0xCC,
+       0xA8, 0xA9, 0x43, 0x20, 0xCC, 0xB3, 0xB9, 0x43,
+       0x20, 0xCD, 0x82, 0xCD, 0x43, 0x20, 0xCD, 0x85,
+       // Bytes 42c0 - 42ff
+       0xDD, 0x43, 0x20, 0xD9, 0x8B, 0x5D, 0x43, 0x20,
+       0xD9, 0x8C, 0x61, 0x43, 0x20, 0xD9, 0x8D, 0x65,
+       0x43, 0x20, 0xD9, 0x8E, 0x69, 0x43, 0x20, 0xD9,
+       0x8F, 0x6D, 0x43, 0x20, 0xD9, 0x90, 0x71, 0x43,
+       0x20, 0xD9, 0x91, 0x75, 0x43, 0x20, 0xD9, 0x92,
+       0x79, 0x43, 0x41, 0xCC, 0x8A, 0xCD, 0x43, 0x73,
+       0xCC, 0x87, 0xCD, 0x44, 0x20, 0xE3, 0x82, 0x99,
+       0x11, 0x44, 0x20, 0xE3, 0x82, 0x9A, 0x11, 0x44,
+       // Bytes 4300 - 433f
+       0xC2, 0xA8, 0xCC, 0x81, 0xCE, 0x44, 0xCE, 0x91,
+       0xCC, 0x81, 0xCD, 0x44, 0xCE, 0x95, 0xCC, 0x81,
+       0xCD, 0x44, 0xCE, 0x97, 0xCC, 0x81, 0xCD, 0x44,
+       0xCE, 0x99, 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0x9F,
+       0xCC, 0x81, 0xCD, 0x44, 0xCE, 0xA5, 0xCC, 0x81,
+       0xCD, 0x44, 0xCE, 0xA5, 0xCC, 0x88, 0xCD, 0x44,
+       0xCE, 0xA9, 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0xB1,
+       0xCC, 0x81, 0xCD, 0x44, 0xCE, 0xB5, 0xCC, 0x81,
+       // Bytes 4340 - 437f
+       0xCD, 0x44, 0xCE, 0xB7, 0xCC, 0x81, 0xCD, 0x44,
+       0xCE, 0xB9, 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0xBF,
+       0xCC, 0x81, 0xCD, 0x44, 0xCF, 0x85, 0xCC, 0x81,
+       0xCD, 0x44, 0xCF, 0x89, 0xCC, 0x81, 0xCD, 0x44,
+       0xD7, 0x90, 0xD6, 0xB7, 0x35, 0x44, 0xD7, 0x90,
+       0xD6, 0xB8, 0x39, 0x44, 0xD7, 0x90, 0xD6, 0xBC,
+       0x45, 0x44, 0xD7, 0x91, 0xD6, 0xBC, 0x45, 0x44,
+       0xD7, 0x91, 0xD6, 0xBF, 0x4D, 0x44, 0xD7, 0x92,
+       // Bytes 4380 - 43bf
+       0xD6, 0xBC, 0x45, 0x44, 0xD7, 0x93, 0xD6, 0xBC,
+       0x45, 0x44, 0xD7, 0x94, 0xD6, 0xBC, 0x45, 0x44,
+       0xD7, 0x95, 0xD6, 0xB9, 0x3D, 0x44, 0xD7, 0x95,
+       0xD6, 0xBC, 0x45, 0x44, 0xD7, 0x96, 0xD6, 0xBC,
+       0x45, 0x44, 0xD7, 0x98, 0xD6, 0xBC, 0x45, 0x44,
+       0xD7, 0x99, 0xD6, 0xB4, 0x29, 0x44, 0xD7, 0x99,
+       0xD6, 0xBC, 0x45, 0x44, 0xD7, 0x9A, 0xD6, 0xBC,
+       0x45, 0x44, 0xD7, 0x9B, 0xD6, 0xBC, 0x45, 0x44,
+       // Bytes 43c0 - 43ff
+       0xD7, 0x9B, 0xD6, 0xBF, 0x4D, 0x44, 0xD7, 0x9C,
+       0xD6, 0xBC, 0x45, 0x44, 0xD7, 0x9E, 0xD6, 0xBC,
+       0x45, 0x44, 0xD7, 0xA0, 0xD6, 0xBC, 0x45, 0x44,
+       0xD7, 0xA1, 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0xA3,
+       0xD6, 0xBC, 0x45, 0x44, 0xD7, 0xA4, 0xD6, 0xBC,
+       0x45, 0x44, 0xD7, 0xA4, 0xD6, 0xBF, 0x4D, 0x44,
+       0xD7, 0xA6, 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0xA7,
+       0xD6, 0xBC, 0x45, 0x44, 0xD7, 0xA8, 0xD6, 0xBC,
+       // Bytes 4400 - 443f
+       0x45, 0x44, 0xD7, 0xA9, 0xD6, 0xBC, 0x45, 0x44,
+       0xD7, 0xA9, 0xD7, 0x81, 0x51, 0x44, 0xD7, 0xA9,
+       0xD7, 0x82, 0x55, 0x44, 0xD7, 0xAA, 0xD6, 0xBC,
+       0x45, 0x44, 0xD7, 0xB2, 0xD6, 0xB7, 0x35, 0x44,
+       0xD8, 0xA7, 0xD9, 0x8B, 0x5D, 0x44, 0xD8, 0xA7,
+       0xD9, 0x93, 0xCD, 0x44, 0xD8, 0xA7, 0xD9, 0x94,
+       0xCD, 0x44, 0xD8, 0xA7, 0xD9, 0x95, 0xB9, 0x44,
+       0xD8, 0xB0, 0xD9, 0xB0, 0x7D, 0x44, 0xD8, 0xB1,
+       // Bytes 4440 - 447f
+       0xD9, 0xB0, 0x7D, 0x44, 0xD9, 0x80, 0xD9, 0x8B,
+       0x5D, 0x44, 0xD9, 0x80, 0xD9, 0x8E, 0x69, 0x44,
+       0xD9, 0x80, 0xD9, 0x8F, 0x6D, 0x44, 0xD9, 0x80,
+       0xD9, 0x90, 0x71, 0x44, 0xD9, 0x80, 0xD9, 0x91,
+       0x75, 0x44, 0xD9, 0x80, 0xD9, 0x92, 0x79, 0x44,
+       0xD9, 0x87, 0xD9, 0xB0, 0x7D, 0x44, 0xD9, 0x88,
+       0xD9, 0x94, 0xCD, 0x44, 0xD9, 0x89, 0xD9, 0xB0,
+       0x7D, 0x44, 0xD9, 0x8A, 0xD9, 0x94, 0xCD, 0x44,
+       // Bytes 4480 - 44bf
+       0xDB, 0x92, 0xD9, 0x94, 0xCD, 0x44, 0xDB, 0x95,
+       0xD9, 0x94, 0xCD, 0x45, 0x20, 0xCC, 0x88, 0xCC,
+       0x80, 0xCE, 0x45, 0x20, 0xCC, 0x88, 0xCC, 0x81,
+       0xCE, 0x45, 0x20, 0xCC, 0x88, 0xCD, 0x82, 0xCE,
+       0x45, 0x20, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x45,
+       0x20, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x45, 0x20,
+       0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x45, 0x20, 0xCC,
+       0x94, 0xCC, 0x80, 0xCE, 0x45, 0x20, 0xCC, 0x94,
+       // Bytes 44c0 - 44ff
+       0xCC, 0x81, 0xCE, 0x45, 0x20, 0xCC, 0x94, 0xCD,
+       0x82, 0xCE, 0x45, 0x20, 0xD9, 0x8C, 0xD9, 0x91,
+       0x76, 0x45, 0x20, 0xD9, 0x8D, 0xD9, 0x91, 0x76,
+       0x45, 0x20, 0xD9, 0x8E, 0xD9, 0x91, 0x76, 0x45,
+       0x20, 0xD9, 0x8F, 0xD9, 0x91, 0x76, 0x45, 0x20,
+       0xD9, 0x90, 0xD9, 0x91, 0x76, 0x45, 0x20, 0xD9,
+       0x91, 0xD9, 0xB0, 0x7E, 0x45, 0xE2, 0xAB, 0x9D,
+       0xCC, 0xB8, 0x05, 0x46, 0xCE, 0xB9, 0xCC, 0x88,
+       // Bytes 4500 - 453f
+       0xCC, 0x81, 0xCE, 0x46, 0xCF, 0x85, 0xCC, 0x88,
+       0xCC, 0x81, 0xCE, 0x46, 0xD7, 0xA9, 0xD6, 0xBC,
+       0xD7, 0x81, 0x52, 0x46, 0xD7, 0xA9, 0xD6, 0xBC,
+       0xD7, 0x82, 0x56, 0x46, 0xD9, 0x80, 0xD9, 0x8E,
+       0xD9, 0x91, 0x76, 0x46, 0xD9, 0x80, 0xD9, 0x8F,
+       0xD9, 0x91, 0x76, 0x46, 0xD9, 0x80, 0xD9, 0x90,
+       0xD9, 0x91, 0x76, 0x46, 0xE0, 0xA4, 0x95, 0xE0,
+       0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0x96, 0xE0,
+       // Bytes 4540 - 457f
+       0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0x97, 0xE0,
+       0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0x9C, 0xE0,
+       0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0xA1, 0xE0,
+       0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0xA2, 0xE0,
+       0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0xAB, 0xE0,
+       0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0xAF, 0xE0,
+       0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA6, 0xA1, 0xE0,
+       0xA6, 0xBC, 0x0D, 0x46, 0xE0, 0xA6, 0xA2, 0xE0,
+       // Bytes 4580 - 45bf
+       0xA6, 0xBC, 0x0D, 0x46, 0xE0, 0xA6, 0xAF, 0xE0,
+       0xA6, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0x96, 0xE0,
+       0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0x97, 0xE0,
+       0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0x9C, 0xE0,
+       0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0xAB, 0xE0,
+       0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0xB2, 0xE0,
+       0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0xB8, 0xE0,
+       0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xAC, 0xA1, 0xE0,
+       // Bytes 45c0 - 45ff
+       0xAC, 0xBC, 0x0D, 0x46, 0xE0, 0xAC, 0xA2, 0xE0,
+       0xAC, 0xBC, 0x0D, 0x46, 0xE0, 0xBE, 0xB2, 0xE0,
+       0xBE, 0x80, 0xA1, 0x46, 0xE0, 0xBE, 0xB3, 0xE0,
+       0xBE, 0x80, 0xA1, 0x46, 0xE3, 0x83, 0x86, 0xE3,
+       0x82, 0x99, 0x11, 0x48, 0xF0, 0x9D, 0x85, 0x97,
+       0xF0, 0x9D, 0x85, 0xA5, 0xB1, 0x48, 0xF0, 0x9D,
+       0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xB1, 0x48,
+       0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5,
+       // Bytes 4600 - 463f
+       0xB1, 0x48, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D,
+       0x85, 0xA5, 0xB1, 0x49, 0xE0, 0xBE, 0xB2, 0xE0,
+       0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0xA2, 0x49, 0xE0,
+       0xBE, 0xB3, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80,
+       0xA2, 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D,
+       0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0xB2, 0x4C,
+       0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5,
+       0xF0, 0x9D, 0x85, 0xAF, 0xB2, 0x4C, 0xF0, 0x9D,
+       // Bytes 4640 - 467f
+       0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D,
+       0x85, 0xB0, 0xB2, 0x4C, 0xF0, 0x9D, 0x85, 0x98,
+       0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB1,
+       0xB2, 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D,
+       0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB2, 0xB2, 0x4C,
+       0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5,
+       0xF0, 0x9D, 0x85, 0xAE, 0xB2, 0x4C, 0xF0, 0x9D,
+       0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D,
+       // Bytes 4680 - 46bf
+       0x85, 0xAF, 0xB2, 0x4C, 0xF0, 0x9D, 0x86, 0xBA,
+       0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE,
+       0xB2, 0x4C, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D,
+       0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0xB2, 0x83,
+       0x41, 0xCC, 0x82, 0xCD, 0x83, 0x41, 0xCC, 0x86,
+       0xCD, 0x83, 0x41, 0xCC, 0x87, 0xCD, 0x83, 0x41,
+       0xCC, 0x88, 0xCD, 0x83, 0x41, 0xCC, 0x8A, 0xCD,
+       0x83, 0x41, 0xCC, 0xA3, 0xB9, 0x83, 0x43, 0xCC,
+       // Bytes 46c0 - 46ff
+       0xA7, 0xA9, 0x83, 0x45, 0xCC, 0x82, 0xCD, 0x83,
+       0x45, 0xCC, 0x84, 0xCD, 0x83, 0x45, 0xCC, 0xA3,
+       0xB9, 0x83, 0x45, 0xCC, 0xA7, 0xA9, 0x83, 0x49,
+       0xCC, 0x88, 0xCD, 0x83, 0x4C, 0xCC, 0xA3, 0xB9,
+       0x83, 0x4F, 0xCC, 0x82, 0xCD, 0x83, 0x4F, 0xCC,
+       0x83, 0xCD, 0x83, 0x4F, 0xCC, 0x84, 0xCD, 0x83,
+       0x4F, 0xCC, 0x87, 0xCD, 0x83, 0x4F, 0xCC, 0x88,
+       0xCD, 0x83, 0x4F, 0xCC, 0x9B, 0xB1, 0x83, 0x4F,
+       // Bytes 4700 - 473f
+       0xCC, 0xA3, 0xB9, 0x83, 0x4F, 0xCC, 0xA8, 0xA9,
+       0x83, 0x52, 0xCC, 0xA3, 0xB9, 0x83, 0x53, 0xCC,
+       0x81, 0xCD, 0x83, 0x53, 0xCC, 0x8C, 0xCD, 0x83,
+       0x53, 0xCC, 0xA3, 0xB9, 0x83, 0x55, 0xCC, 0x83,
+       0xCD, 0x83, 0x55, 0xCC, 0x84, 0xCD, 0x83, 0x55,
+       0xCC, 0x88, 0xCD, 0x83, 0x55, 0xCC, 0x9B, 0xB1,
+       0x83, 0x61, 0xCC, 0x82, 0xCD, 0x83, 0x61, 0xCC,
+       0x86, 0xCD, 0x83, 0x61, 0xCC, 0x87, 0xCD, 0x83,
+       // Bytes 4740 - 477f
+       0x61, 0xCC, 0x88, 0xCD, 0x83, 0x61, 0xCC, 0x8A,
+       0xCD, 0x83, 0x61, 0xCC, 0xA3, 0xB9, 0x83, 0x63,
+       0xCC, 0xA7, 0xA9, 0x83, 0x65, 0xCC, 0x82, 0xCD,
+       0x83, 0x65, 0xCC, 0x84, 0xCD, 0x83, 0x65, 0xCC,
+       0xA3, 0xB9, 0x83, 0x65, 0xCC, 0xA7, 0xA9, 0x83,
+       0x69, 0xCC, 0x88, 0xCD, 0x83, 0x6C, 0xCC, 0xA3,
+       0xB9, 0x83, 0x6F, 0xCC, 0x82, 0xCD, 0x83, 0x6F,
+       0xCC, 0x83, 0xCD, 0x83, 0x6F, 0xCC, 0x84, 0xCD,
+       // Bytes 4780 - 47bf
+       0x83, 0x6F, 0xCC, 0x87, 0xCD, 0x83, 0x6F, 0xCC,
+       0x88, 0xCD, 0x83, 0x6F, 0xCC, 0x9B, 0xB1, 0x83,
+       0x6F, 0xCC, 0xA3, 0xB9, 0x83, 0x6F, 0xCC, 0xA8,
+       0xA9, 0x83, 0x72, 0xCC, 0xA3, 0xB9, 0x83, 0x73,
+       0xCC, 0x81, 0xCD, 0x83, 0x73, 0xCC, 0x8C, 0xCD,
+       0x83, 0x73, 0xCC, 0xA3, 0xB9, 0x83, 0x75, 0xCC,
+       0x83, 0xCD, 0x83, 0x75, 0xCC, 0x84, 0xCD, 0x83,
+       0x75, 0xCC, 0x88, 0xCD, 0x83, 0x75, 0xCC, 0x9B,
+       // Bytes 47c0 - 47ff
+       0xB1, 0x84, 0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x84,
+       0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x84, 0xCE, 0x95,
+       0xCC, 0x93, 0xCD, 0x84, 0xCE, 0x95, 0xCC, 0x94,
+       0xCD, 0x84, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x84,
+       0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x84, 0xCE, 0x99,
+       0xCC, 0x93, 0xCD, 0x84, 0xCE, 0x99, 0xCC, 0x94,
+       0xCD, 0x84, 0xCE, 0x9F, 0xCC, 0x93, 0xCD, 0x84,
+       0xCE, 0x9F, 0xCC, 0x94, 0xCD, 0x84, 0xCE, 0xA5,
+       // Bytes 4800 - 483f
+       0xCC, 0x94, 0xCD, 0x84, 0xCE, 0xA9, 0xCC, 0x93,
+       0xCD, 0x84, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x84,
+       0xCE, 0xB1, 0xCC, 0x80, 0xCD, 0x84, 0xCE, 0xB1,
+       0xCC, 0x81, 0xCD, 0x84, 0xCE, 0xB1, 0xCC, 0x93,
+       0xCD, 0x84, 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x84,
+       0xCE, 0xB1, 0xCD, 0x82, 0xCD, 0x84, 0xCE, 0xB5,
+       0xCC, 0x93, 0xCD, 0x84, 0xCE, 0xB5, 0xCC, 0x94,
+       0xCD, 0x84, 0xCE, 0xB7, 0xCC, 0x80, 0xCD, 0x84,
+       // Bytes 4840 - 487f
+       0xCE, 0xB7, 0xCC, 0x81, 0xCD, 0x84, 0xCE, 0xB7,
+       0xCC, 0x93, 0xCD, 0x84, 0xCE, 0xB7, 0xCC, 0x94,
+       0xCD, 0x84, 0xCE, 0xB7, 0xCD, 0x82, 0xCD, 0x84,
+       0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x84, 0xCE, 0xB9,
+       0xCC, 0x93, 0xCD, 0x84, 0xCE, 0xB9, 0xCC, 0x94,
+       0xCD, 0x84, 0xCE, 0xBF, 0xCC, 0x93, 0xCD, 0x84,
+       0xCE, 0xBF, 0xCC, 0x94, 0xCD, 0x84, 0xCF, 0x85,
+       0xCC, 0x88, 0xCD, 0x84, 0xCF, 0x85, 0xCC, 0x93,
+       // Bytes 4880 - 48bf
+       0xCD, 0x84, 0xCF, 0x85, 0xCC, 0x94, 0xCD, 0x84,
+       0xCF, 0x89, 0xCC, 0x80, 0xCD, 0x84, 0xCF, 0x89,
+       0xCC, 0x81, 0xCD, 0x84, 0xCF, 0x89, 0xCC, 0x93,
+       0xCD, 0x84, 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x84,
+       0xCF, 0x89, 0xCD, 0x82, 0xCD, 0x86, 0xCE, 0x91,
+       0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0x91,
+       0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0x91,
+       0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0x91,
+       // Bytes 48c0 - 48ff
+       0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0x91,
+       0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0x91,
+       0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0x97,
+       0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0x97,
+       0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0x97,
+       0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0x97,
+       0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0x97,
+       0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0x97,
+       // Bytes 4900 - 493f
+       0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xA9,
+       0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xA9,
+       0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xA9,
+       0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xA9,
+       0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xA9,
+       0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xA9,
+       0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xB1,
+       0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xB1,
+       // Bytes 4940 - 497f
+       0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xB1,
+       0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xB1,
+       0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xB1,
+       0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xB1,
+       0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xB7,
+       0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xB7,
+       0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xB7,
+       0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xB7,
+       // Bytes 4980 - 49bf
+       0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xB7,
+       0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xB7,
+       0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCF, 0x89,
+       0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCF, 0x89,
+       0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCF, 0x89,
+       0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCF, 0x89,
+       0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCF, 0x89,
+       0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCF, 0x89,
+       // Bytes 49c0 - 49ff
+       0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x42, 0xCC, 0x80,
+       0xCD, 0x33, 0x42, 0xCC, 0x81, 0xCD, 0x33, 0x42,
+       0xCC, 0x93, 0xCD, 0x33, 0x43, 0xE1, 0x85, 0xA1,
+       0x01, 0x00, 0x43, 0xE1, 0x85, 0xA2, 0x01, 0x00,
+       0x43, 0xE1, 0x85, 0xA3, 0x01, 0x00, 0x43, 0xE1,
+       0x85, 0xA4, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA5,
+       0x01, 0x00, 0x43, 0xE1, 0x85, 0xA6, 0x01, 0x00,
+       0x43, 0xE1, 0x85, 0xA7, 0x01, 0x00, 0x43, 0xE1,
+       // Bytes 4a00 - 4a3f
+       0x85, 0xA8, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA9,
+       0x01, 0x00, 0x43, 0xE1, 0x85, 0xAA, 0x01, 0x00,
+       0x43, 0xE1, 0x85, 0xAB, 0x01, 0x00, 0x43, 0xE1,
+       0x85, 0xAC, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAD,
+       0x01, 0x00, 0x43, 0xE1, 0x85, 0xAE, 0x01, 0x00,
+       0x43, 0xE1, 0x85, 0xAF, 0x01, 0x00, 0x43, 0xE1,
+       0x85, 0xB0, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xB1,
+       0x01, 0x00, 0x43, 0xE1, 0x85, 0xB2, 0x01, 0x00,
+       // Bytes 4a40 - 4a7f
+       0x43, 0xE1, 0x85, 0xB3, 0x01, 0x00, 0x43, 0xE1,
+       0x85, 0xB4, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xB5,
+       0x01, 0x00, 0x43, 0xE1, 0x86, 0xAA, 0x01, 0x00,
+       0x43, 0xE1, 0x86, 0xAC, 0x01, 0x00, 0x43, 0xE1,
+       0x86, 0xAD, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB0,
+       0x01, 0x00, 0x43, 0xE1, 0x86, 0xB1, 0x01, 0x00,
+       0x43, 0xE1, 0x86, 0xB2, 0x01, 0x00, 0x43, 0xE1,
+       0x86, 0xB3, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB4,
+       // Bytes 4a80 - 4abf
+       0x01, 0x00, 0x43, 0xE1, 0x86, 0xB5, 0x01, 0x00,
+       0x44, 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x33, 0x43,
+       0xE3, 0x82, 0x99, 0x11, 0x04, 0x43, 0xE3, 0x82,
+       0x9A, 0x11, 0x04, 0x46, 0xE0, 0xBD, 0xB1, 0xE0,
+       0xBD, 0xB2, 0xA2, 0x27, 0x46, 0xE0, 0xBD, 0xB1,
+       0xE0, 0xBD, 0xB4, 0xA6, 0x27, 0x46, 0xE0, 0xBD,
+       0xB1, 0xE0, 0xBE, 0x80, 0xA2, 0x27, 0x00, 0x01,
+}
+
+// lookup returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *nfcTrie) lookup(s []byte) (v uint16, sz int) {
+       c0 := s[0]
+       switch {
+       case c0 < 0x80: // is ASCII
+               return nfcValues[c0], 1
+       case c0 < 0xC2:
+               return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+       case c0 < 0xE0: // 2-byte UTF-8
+               if len(s) < 2 {
+                       return 0, 0
+               }
+               i := nfcIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c1), 2
+       case c0 < 0xF0: // 3-byte UTF-8
+               if len(s) < 3 {
+                       return 0, 0
+               }
+               i := nfcIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               o := uint32(i)<<6 + uint32(c1)
+               i = nfcIndex[o]
+               c2 := s[2]
+               if c2 < 0x80 || 0xC0 <= c2 {
+                       return 0, 2 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c2), 3
+       case c0 < 0xF8: // 4-byte UTF-8
+               if len(s) < 4 {
+                       return 0, 0
+               }
+               i := nfcIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               o := uint32(i)<<6 + uint32(c1)
+               i = nfcIndex[o]
+               c2 := s[2]
+               if c2 < 0x80 || 0xC0 <= c2 {
+                       return 0, 2 // Illegal UTF-8: not a continuation byte.
+               }
+               o = uint32(i)<<6 + uint32(c2)
+               i = nfcIndex[o]
+               c3 := s[3]
+               if c3 < 0x80 || 0xC0 <= c3 {
+                       return 0, 3 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c3), 4
+       }
+       // Illegal rune
+       return 0, 1
+}
+
+// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *nfcTrie) lookupUnsafe(s []byte) uint16 {
+       c0 := s[0]
+       if c0 < 0x80 { // is ASCII
+               return nfcValues[c0]
+       }
+       i := nfcIndex[c0]
+       if c0 < 0xE0 { // 2-byte UTF-8
+               return t.lookupValue(uint32(i), s[1])
+       }
+       i = nfcIndex[uint32(i)<<6+uint32(s[1])]
+       if c0 < 0xF0 { // 3-byte UTF-8
+               return t.lookupValue(uint32(i), s[2])
+       }
+       i = nfcIndex[uint32(i)<<6+uint32(s[2])]
+       if c0 < 0xF8 { // 4-byte UTF-8
+               return t.lookupValue(uint32(i), s[3])
+       }
+       return 0
+}
+
+// lookupString returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *nfcTrie) lookupString(s string) (v uint16, sz int) {
+       c0 := s[0]
+       switch {
+       case c0 < 0x80: // is ASCII
+               return nfcValues[c0], 1
+       case c0 < 0xC2:
+               return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+       case c0 < 0xE0: // 2-byte UTF-8
+               if len(s) < 2 {
+                       return 0, 0
+               }
+               i := nfcIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c1), 2
+       case c0 < 0xF0: // 3-byte UTF-8
+               if len(s) < 3 {
+                       return 0, 0
+               }
+               i := nfcIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               o := uint32(i)<<6 + uint32(c1)
+               i = nfcIndex[o]
+               c2 := s[2]
+               if c2 < 0x80 || 0xC0 <= c2 {
+                       return 0, 2 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c2), 3
+       case c0 < 0xF8: // 4-byte UTF-8
+               if len(s) < 4 {
+                       return 0, 0
+               }
+               i := nfcIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               o := uint32(i)<<6 + uint32(c1)
+               i = nfcIndex[o]
+               c2 := s[2]
+               if c2 < 0x80 || 0xC0 <= c2 {
+                       return 0, 2 // Illegal UTF-8: not a continuation byte.
+               }
+               o = uint32(i)<<6 + uint32(c2)
+               i = nfcIndex[o]
+               c3 := s[3]
+               if c3 < 0x80 || 0xC0 <= c3 {
+                       return 0, 3 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c3), 4
+       }
+       // Illegal rune
+       return 0, 1
+}
+
+// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *nfcTrie) lookupStringUnsafe(s string) uint16 {
+       c0 := s[0]
+       if c0 < 0x80 { // is ASCII
+               return nfcValues[c0]
+       }
+       i := nfcIndex[c0]
+       if c0 < 0xE0 { // 2-byte UTF-8
+               return t.lookupValue(uint32(i), s[1])
+       }
+       i = nfcIndex[uint32(i)<<6+uint32(s[1])]
+       if c0 < 0xF0 { // 3-byte UTF-8
+               return t.lookupValue(uint32(i), s[2])
+       }
+       i = nfcIndex[uint32(i)<<6+uint32(s[2])]
+       if c0 < 0xF8 { // 4-byte UTF-8
+               return t.lookupValue(uint32(i), s[3])
+       }
+       return 0
+}
+
+// nfcTrie. Total size: 10680 bytes (10.43 KiB). Checksum: a555db76d4becdd2.
+type nfcTrie struct{}
+
+func newNfcTrie(i int) *nfcTrie {
+       return &nfcTrie{}
+}
+
+// lookupValue determines the type of block n and looks up the value for b.
+func (t *nfcTrie) lookupValue(n uint32, b byte) uint16 {
+       switch {
+       case n < 46:
+               return uint16(nfcValues[n<<6+uint32(b)])
+       default:
+               n -= 46
+               return uint16(nfcSparse.lookup(n, b))
+       }
+}
+
+// nfcValues: 48 blocks, 3072 entries, 6144 bytes
+// The third block is the zero block.
+var nfcValues = [3072]uint16{
+       // Block 0x0, offset 0x0
+       0x3c: 0xa000, 0x3d: 0xa000, 0x3e: 0xa000,
+       // Block 0x1, offset 0x40
+       0x41: 0xa000, 0x42: 0xa000, 0x43: 0xa000, 0x44: 0xa000, 0x45: 0xa000,
+       0x46: 0xa000, 0x47: 0xa000, 0x48: 0xa000, 0x49: 0xa000, 0x4a: 0xa000, 0x4b: 0xa000,
+       0x4c: 0xa000, 0x4d: 0xa000, 0x4e: 0xa000, 0x4f: 0xa000, 0x50: 0xa000,
+       0x52: 0xa000, 0x53: 0xa000, 0x54: 0xa000, 0x55: 0xa000, 0x56: 0xa000, 0x57: 0xa000,
+       0x58: 0xa000, 0x59: 0xa000, 0x5a: 0xa000,
+       0x61: 0xa000, 0x62: 0xa000, 0x63: 0xa000,
+       0x64: 0xa000, 0x65: 0xa000, 0x66: 0xa000, 0x67: 0xa000, 0x68: 0xa000, 0x69: 0xa000,
+       0x6a: 0xa000, 0x6b: 0xa000, 0x6c: 0xa000, 0x6d: 0xa000, 0x6e: 0xa000, 0x6f: 0xa000,
+       0x70: 0xa000, 0x72: 0xa000, 0x73: 0xa000, 0x74: 0xa000, 0x75: 0xa000,
+       0x76: 0xa000, 0x77: 0xa000, 0x78: 0xa000, 0x79: 0xa000, 0x7a: 0xa000,
+       // Block 0x2, offset 0x80
+       // Block 0x3, offset 0xc0
+       0xc0: 0x2f86, 0xc1: 0x2f8b, 0xc2: 0x469f, 0xc3: 0x2f90, 0xc4: 0x46ae, 0xc5: 0x46b3,
+       0xc6: 0xa000, 0xc7: 0x46bd, 0xc8: 0x2ff9, 0xc9: 0x2ffe, 0xca: 0x46c2, 0xcb: 0x3012,
+       0xcc: 0x3085, 0xcd: 0x308a, 0xce: 0x308f, 0xcf: 0x46d6, 0xd1: 0x311b,
+       0xd2: 0x313e, 0xd3: 0x3143, 0xd4: 0x46e0, 0xd5: 0x46e5, 0xd6: 0x46f4,
+       0xd8: 0xa000, 0xd9: 0x31ca, 0xda: 0x31cf, 0xdb: 0x31d4, 0xdc: 0x4726, 0xdd: 0x324c,
+       0xe0: 0x3292, 0xe1: 0x3297, 0xe2: 0x4730, 0xe3: 0x329c,
+       0xe4: 0x473f, 0xe5: 0x4744, 0xe6: 0xa000, 0xe7: 0x474e, 0xe8: 0x3305, 0xe9: 0x330a,
+       0xea: 0x4753, 0xeb: 0x331e, 0xec: 0x3396, 0xed: 0x339b, 0xee: 0x33a0, 0xef: 0x4767,
+       0xf1: 0x342c, 0xf2: 0x344f, 0xf3: 0x3454, 0xf4: 0x4771, 0xf5: 0x4776,
+       0xf6: 0x4785, 0xf8: 0xa000, 0xf9: 0x34e0, 0xfa: 0x34e5, 0xfb: 0x34ea,
+       0xfc: 0x47b7, 0xfd: 0x3567, 0xff: 0x3580,
+       // Block 0x4, offset 0x100
+       0x100: 0x2f95, 0x101: 0x32a1, 0x102: 0x46a4, 0x103: 0x4735, 0x104: 0x2fb3, 0x105: 0x32bf,
+       0x106: 0x2fc7, 0x107: 0x32d3, 0x108: 0x2fcc, 0x109: 0x32d8, 0x10a: 0x2fd1, 0x10b: 0x32dd,
+       0x10c: 0x2fd6, 0x10d: 0x32e2, 0x10e: 0x2fe0, 0x10f: 0x32ec,
+       0x112: 0x46c7, 0x113: 0x4758, 0x114: 0x3008, 0x115: 0x3314, 0x116: 0x300d, 0x117: 0x3319,
+       0x118: 0x302b, 0x119: 0x3337, 0x11a: 0x301c, 0x11b: 0x3328, 0x11c: 0x3044, 0x11d: 0x3350,
+       0x11e: 0x304e, 0x11f: 0x335a, 0x120: 0x3053, 0x121: 0x335f, 0x122: 0x305d, 0x123: 0x3369,
+       0x124: 0x3062, 0x125: 0x336e, 0x128: 0x3094, 0x129: 0x33a5,
+       0x12a: 0x3099, 0x12b: 0x33aa, 0x12c: 0x309e, 0x12d: 0x33af, 0x12e: 0x30c1, 0x12f: 0x33cd,
+       0x130: 0x30a3, 0x134: 0x30cb, 0x135: 0x33d7,
+       0x136: 0x30df, 0x137: 0x33f0, 0x139: 0x30e9, 0x13a: 0x33fa, 0x13b: 0x30f3,
+       0x13c: 0x3404, 0x13d: 0x30ee, 0x13e: 0x33ff,
+       // Block 0x5, offset 0x140
+       0x143: 0x3116, 0x144: 0x3427, 0x145: 0x312f,
+       0x146: 0x3440, 0x147: 0x3125, 0x148: 0x3436,
+       0x14c: 0x46ea, 0x14d: 0x477b, 0x14e: 0x3148, 0x14f: 0x3459, 0x150: 0x3152, 0x151: 0x3463,
+       0x154: 0x3170, 0x155: 0x3481, 0x156: 0x3189, 0x157: 0x349a,
+       0x158: 0x317a, 0x159: 0x348b, 0x15a: 0x470d, 0x15b: 0x479e, 0x15c: 0x3193, 0x15d: 0x34a4,
+       0x15e: 0x31a2, 0x15f: 0x34b3, 0x160: 0x4712, 0x161: 0x47a3, 0x162: 0x31bb, 0x163: 0x34d1,
+       0x164: 0x31ac, 0x165: 0x34c2, 0x168: 0x471c, 0x169: 0x47ad,
+       0x16a: 0x4721, 0x16b: 0x47b2, 0x16c: 0x31d9, 0x16d: 0x34ef, 0x16e: 0x31e3, 0x16f: 0x34f9,
+       0x170: 0x31e8, 0x171: 0x34fe, 0x172: 0x3206, 0x173: 0x351c, 0x174: 0x3229, 0x175: 0x353f,
+       0x176: 0x3251, 0x177: 0x356c, 0x178: 0x3265, 0x179: 0x3274, 0x17a: 0x3594, 0x17b: 0x327e,
+       0x17c: 0x359e, 0x17d: 0x3283, 0x17e: 0x35a3, 0x17f: 0xa000,
+       // Block 0x6, offset 0x180
+       0x184: 0x8100, 0x185: 0x8100,
+       0x186: 0x8100,
+       0x18d: 0x2f9f, 0x18e: 0x32ab, 0x18f: 0x30ad, 0x190: 0x33b9, 0x191: 0x3157,
+       0x192: 0x3468, 0x193: 0x31ed, 0x194: 0x3503, 0x195: 0x39e6, 0x196: 0x3b75, 0x197: 0x39df,
+       0x198: 0x3b6e, 0x199: 0x39ed, 0x19a: 0x3b7c, 0x19b: 0x39d8, 0x19c: 0x3b67,
+       0x19e: 0x38c7, 0x19f: 0x3a56, 0x1a0: 0x38c0, 0x1a1: 0x3a4f, 0x1a2: 0x35ca, 0x1a3: 0x35dc,
+       0x1a6: 0x3058, 0x1a7: 0x3364, 0x1a8: 0x30d5, 0x1a9: 0x33e6,
+       0x1aa: 0x4703, 0x1ab: 0x4794, 0x1ac: 0x39a7, 0x1ad: 0x3b36, 0x1ae: 0x35ee, 0x1af: 0x35f4,
+       0x1b0: 0x33dc, 0x1b4: 0x303f, 0x1b5: 0x334b,
+       0x1b8: 0x3111, 0x1b9: 0x3422, 0x1ba: 0x38ce, 0x1bb: 0x3a5d,
+       0x1bc: 0x35c4, 0x1bd: 0x35d6, 0x1be: 0x35d0, 0x1bf: 0x35e2,
+       // Block 0x7, offset 0x1c0
+       0x1c0: 0x2fa4, 0x1c1: 0x32b0, 0x1c2: 0x2fa9, 0x1c3: 0x32b5, 0x1c4: 0x3021, 0x1c5: 0x332d,
+       0x1c6: 0x3026, 0x1c7: 0x3332, 0x1c8: 0x30b2, 0x1c9: 0x33be, 0x1ca: 0x30b7, 0x1cb: 0x33c3,
+       0x1cc: 0x315c, 0x1cd: 0x346d, 0x1ce: 0x3161, 0x1cf: 0x3472, 0x1d0: 0x317f, 0x1d1: 0x3490,
+       0x1d2: 0x3184, 0x1d3: 0x3495, 0x1d4: 0x31f2, 0x1d5: 0x3508, 0x1d6: 0x31f7, 0x1d7: 0x350d,
+       0x1d8: 0x319d, 0x1d9: 0x34ae, 0x1da: 0x31b6, 0x1db: 0x34cc,
+       0x1de: 0x3071, 0x1df: 0x337d,
+       0x1e6: 0x46a9, 0x1e7: 0x473a, 0x1e8: 0x46d1, 0x1e9: 0x4762,
+       0x1ea: 0x3976, 0x1eb: 0x3b05, 0x1ec: 0x3953, 0x1ed: 0x3ae2, 0x1ee: 0x46ef, 0x1ef: 0x4780,
+       0x1f0: 0x396f, 0x1f1: 0x3afe, 0x1f2: 0x325b, 0x1f3: 0x3576,
+       // Block 0x8, offset 0x200
+       0x200: 0x9933, 0x201: 0x9933, 0x202: 0x9933, 0x203: 0x9933, 0x204: 0x9933, 0x205: 0x8133,
+       0x206: 0x9933, 0x207: 0x9933, 0x208: 0x9933, 0x209: 0x9933, 0x20a: 0x9933, 0x20b: 0x9933,
+       0x20c: 0x9933, 0x20d: 0x8133, 0x20e: 0x8133, 0x20f: 0x9933, 0x210: 0x8133, 0x211: 0x9933,
+       0x212: 0x8133, 0x213: 0x9933, 0x214: 0x9933, 0x215: 0x8134, 0x216: 0x812e, 0x217: 0x812e,
+       0x218: 0x812e, 0x219: 0x812e, 0x21a: 0x8134, 0x21b: 0x992c, 0x21c: 0x812e, 0x21d: 0x812e,
+       0x21e: 0x812e, 0x21f: 0x812e, 0x220: 0x812e, 0x221: 0x812a, 0x222: 0x812a, 0x223: 0x992e,
+       0x224: 0x992e, 0x225: 0x992e, 0x226: 0x992e, 0x227: 0x992a, 0x228: 0x992a, 0x229: 0x812e,
+       0x22a: 0x812e, 0x22b: 0x812e, 0x22c: 0x812e, 0x22d: 0x992e, 0x22e: 0x992e, 0x22f: 0x812e,
+       0x230: 0x992e, 0x231: 0x992e, 0x232: 0x812e, 0x233: 0x812e, 0x234: 0x8101, 0x235: 0x8101,
+       0x236: 0x8101, 0x237: 0x8101, 0x238: 0x9901, 0x239: 0x812e, 0x23a: 0x812e, 0x23b: 0x812e,
+       0x23c: 0x812e, 0x23d: 0x8133, 0x23e: 0x8133, 0x23f: 0x8133,
+       // Block 0x9, offset 0x240
+       0x240: 0x49c5, 0x241: 0x49ca, 0x242: 0x9933, 0x243: 0x49cf, 0x244: 0x4a88, 0x245: 0x9937,
+       0x246: 0x8133, 0x247: 0x812e, 0x248: 0x812e, 0x249: 0x812e, 0x24a: 0x8133, 0x24b: 0x8133,
+       0x24c: 0x8133, 0x24d: 0x812e, 0x24e: 0x812e, 0x250: 0x8133, 0x251: 0x8133,
+       0x252: 0x8133, 0x253: 0x812e, 0x254: 0x812e, 0x255: 0x812e, 0x256: 0x812e, 0x257: 0x8133,
+       0x258: 0x8134, 0x259: 0x812e, 0x25a: 0x812e, 0x25b: 0x8133, 0x25c: 0x8135, 0x25d: 0x8136,
+       0x25e: 0x8136, 0x25f: 0x8135, 0x260: 0x8136, 0x261: 0x8136, 0x262: 0x8135, 0x263: 0x8133,
+       0x264: 0x8133, 0x265: 0x8133, 0x266: 0x8133, 0x267: 0x8133, 0x268: 0x8133, 0x269: 0x8133,
+       0x26a: 0x8133, 0x26b: 0x8133, 0x26c: 0x8133, 0x26d: 0x8133, 0x26e: 0x8133, 0x26f: 0x8133,
+       0x274: 0x0173,
+       0x27a: 0x8100,
+       0x27e: 0x0037,
+       // Block 0xa, offset 0x280
+       0x284: 0x8100, 0x285: 0x35b8,
+       0x286: 0x3600, 0x287: 0x00ce, 0x288: 0x361e, 0x289: 0x362a, 0x28a: 0x363c,
+       0x28c: 0x365a, 0x28e: 0x366c, 0x28f: 0x368a, 0x290: 0x3e1f, 0x291: 0xa000,
+       0x295: 0xa000, 0x297: 0xa000,
+       0x299: 0xa000,
+       0x29f: 0xa000, 0x2a1: 0xa000,
+       0x2a5: 0xa000, 0x2a9: 0xa000,
+       0x2aa: 0x364e, 0x2ab: 0x367e, 0x2ac: 0x4815, 0x2ad: 0x36ae, 0x2ae: 0x483f, 0x2af: 0x36c0,
+       0x2b0: 0x3e87, 0x2b1: 0xa000, 0x2b5: 0xa000,
+       0x2b7: 0xa000, 0x2b9: 0xa000,
+       0x2bf: 0xa000,
+       // Block 0xb, offset 0x2c0
+       0x2c0: 0x3738, 0x2c1: 0x3744, 0x2c3: 0x3732,
+       0x2c6: 0xa000, 0x2c7: 0x3720,
+       0x2cc: 0x3774, 0x2cd: 0x375c, 0x2ce: 0x3786, 0x2d0: 0xa000,
+       0x2d3: 0xa000, 0x2d5: 0xa000, 0x2d6: 0xa000, 0x2d7: 0xa000,
+       0x2d8: 0xa000, 0x2d9: 0x3768, 0x2da: 0xa000,
+       0x2de: 0xa000, 0x2e3: 0xa000,
+       0x2e7: 0xa000,
+       0x2eb: 0xa000, 0x2ed: 0xa000,
+       0x2f0: 0xa000, 0x2f3: 0xa000, 0x2f5: 0xa000,
+       0x2f6: 0xa000, 0x2f7: 0xa000, 0x2f8: 0xa000, 0x2f9: 0x37ec, 0x2fa: 0xa000,
+       0x2fe: 0xa000,
+       // Block 0xc, offset 0x300
+       0x301: 0x374a, 0x302: 0x37ce,
+       0x310: 0x3726, 0x311: 0x37aa,
+       0x312: 0x372c, 0x313: 0x37b0, 0x316: 0x373e, 0x317: 0x37c2,
+       0x318: 0xa000, 0x319: 0xa000, 0x31a: 0x3840, 0x31b: 0x3846, 0x31c: 0x3750, 0x31d: 0x37d4,
+       0x31e: 0x3756, 0x31f: 0x37da, 0x322: 0x3762, 0x323: 0x37e6,
+       0x324: 0x376e, 0x325: 0x37f2, 0x326: 0x377a, 0x327: 0x37fe, 0x328: 0xa000, 0x329: 0xa000,
+       0x32a: 0x384c, 0x32b: 0x3852, 0x32c: 0x37a4, 0x32d: 0x3828, 0x32e: 0x3780, 0x32f: 0x3804,
+       0x330: 0x378c, 0x331: 0x3810, 0x332: 0x3792, 0x333: 0x3816, 0x334: 0x3798, 0x335: 0x381c,
+       0x338: 0x379e, 0x339: 0x3822,
+       // Block 0xd, offset 0x340
+       0x351: 0x812e,
+       0x352: 0x8133, 0x353: 0x8133, 0x354: 0x8133, 0x355: 0x8133, 0x356: 0x812e, 0x357: 0x8133,
+       0x358: 0x8133, 0x359: 0x8133, 0x35a: 0x812f, 0x35b: 0x812e, 0x35c: 0x8133, 0x35d: 0x8133,
+       0x35e: 0x8133, 0x35f: 0x8133, 0x360: 0x8133, 0x361: 0x8133, 0x362: 0x812e, 0x363: 0x812e,
+       0x364: 0x812e, 0x365: 0x812e, 0x366: 0x812e, 0x367: 0x812e, 0x368: 0x8133, 0x369: 0x8133,
+       0x36a: 0x812e, 0x36b: 0x8133, 0x36c: 0x8133, 0x36d: 0x812f, 0x36e: 0x8132, 0x36f: 0x8133,
+       0x370: 0x8106, 0x371: 0x8107, 0x372: 0x8108, 0x373: 0x8109, 0x374: 0x810a, 0x375: 0x810b,
+       0x376: 0x810c, 0x377: 0x810d, 0x378: 0x810e, 0x379: 0x810f, 0x37a: 0x810f, 0x37b: 0x8110,
+       0x37c: 0x8111, 0x37d: 0x8112, 0x37f: 0x8113,
+       // Block 0xe, offset 0x380
+       0x388: 0xa000, 0x38a: 0xa000, 0x38b: 0x8117,
+       0x38c: 0x8118, 0x38d: 0x8119, 0x38e: 0x811a, 0x38f: 0x811b, 0x390: 0x811c, 0x391: 0x811d,
+       0x392: 0x811e, 0x393: 0x9933, 0x394: 0x9933, 0x395: 0x992e, 0x396: 0x812e, 0x397: 0x8133,
+       0x398: 0x8133, 0x399: 0x8133, 0x39a: 0x8133, 0x39b: 0x8133, 0x39c: 0x812e, 0x39d: 0x8133,
+       0x39e: 0x8133, 0x39f: 0x812e,
+       0x3b0: 0x811f,
+       // Block 0xf, offset 0x3c0
+       0x3d3: 0x812e, 0x3d4: 0x8133, 0x3d5: 0x8133, 0x3d6: 0x8133, 0x3d7: 0x8133,
+       0x3d8: 0x8133, 0x3d9: 0x8133, 0x3da: 0x8133, 0x3db: 0x8133, 0x3dc: 0x8133, 0x3dd: 0x8133,
+       0x3de: 0x8133, 0x3df: 0x8133, 0x3e0: 0x8133, 0x3e1: 0x8133, 0x3e3: 0x812e,
+       0x3e4: 0x8133, 0x3e5: 0x8133, 0x3e6: 0x812e, 0x3e7: 0x8133, 0x3e8: 0x8133, 0x3e9: 0x812e,
+       0x3ea: 0x8133, 0x3eb: 0x8133, 0x3ec: 0x8133, 0x3ed: 0x812e, 0x3ee: 0x812e, 0x3ef: 0x812e,
+       0x3f0: 0x8117, 0x3f1: 0x8118, 0x3f2: 0x8119, 0x3f3: 0x8133, 0x3f4: 0x8133, 0x3f5: 0x8133,
+       0x3f6: 0x812e, 0x3f7: 0x8133, 0x3f8: 0x8133, 0x3f9: 0x812e, 0x3fa: 0x812e, 0x3fb: 0x8133,
+       0x3fc: 0x8133, 0x3fd: 0x8133, 0x3fe: 0x8133, 0x3ff: 0x8133,
+       // Block 0x10, offset 0x400
+       0x405: 0xa000,
+       0x406: 0x2d33, 0x407: 0xa000, 0x408: 0x2d3b, 0x409: 0xa000, 0x40a: 0x2d43, 0x40b: 0xa000,
+       0x40c: 0x2d4b, 0x40d: 0xa000, 0x40e: 0x2d53, 0x411: 0xa000,
+       0x412: 0x2d5b,
+       0x434: 0x8103, 0x435: 0x9900,
+       0x43a: 0xa000, 0x43b: 0x2d63,
+       0x43c: 0xa000, 0x43d: 0x2d6b, 0x43e: 0xa000, 0x43f: 0xa000,
+       // Block 0x11, offset 0x440
+       0x440: 0x8133, 0x441: 0x8133, 0x442: 0x812e, 0x443: 0x8133, 0x444: 0x8133, 0x445: 0x8133,
+       0x446: 0x8133, 0x447: 0x8133, 0x448: 0x8133, 0x449: 0x8133, 0x44a: 0x812e, 0x44b: 0x8133,
+       0x44c: 0x8133, 0x44d: 0x8136, 0x44e: 0x812b, 0x44f: 0x812e, 0x450: 0x812a, 0x451: 0x8133,
+       0x452: 0x8133, 0x453: 0x8133, 0x454: 0x8133, 0x455: 0x8133, 0x456: 0x8133, 0x457: 0x8133,
+       0x458: 0x8133, 0x459: 0x8133, 0x45a: 0x8133, 0x45b: 0x8133, 0x45c: 0x8133, 0x45d: 0x8133,
+       0x45e: 0x8133, 0x45f: 0x8133, 0x460: 0x8133, 0x461: 0x8133, 0x462: 0x8133, 0x463: 0x8133,
+       0x464: 0x8133, 0x465: 0x8133, 0x466: 0x8133, 0x467: 0x8133, 0x468: 0x8133, 0x469: 0x8133,
+       0x46a: 0x8133, 0x46b: 0x8133, 0x46c: 0x8133, 0x46d: 0x8133, 0x46e: 0x8133, 0x46f: 0x8133,
+       0x470: 0x8133, 0x471: 0x8133, 0x472: 0x8133, 0x473: 0x8133, 0x474: 0x8133, 0x475: 0x8133,
+       0x476: 0x8134, 0x477: 0x8132, 0x478: 0x8132, 0x479: 0x812e, 0x47b: 0x8133,
+       0x47c: 0x8135, 0x47d: 0x812e, 0x47e: 0x8133, 0x47f: 0x812e,
+       // Block 0x12, offset 0x480
+       0x480: 0x2fae, 0x481: 0x32ba, 0x482: 0x2fb8, 0x483: 0x32c4, 0x484: 0x2fbd, 0x485: 0x32c9,
+       0x486: 0x2fc2, 0x487: 0x32ce, 0x488: 0x38e3, 0x489: 0x3a72, 0x48a: 0x2fdb, 0x48b: 0x32e7,
+       0x48c: 0x2fe5, 0x48d: 0x32f1, 0x48e: 0x2ff4, 0x48f: 0x3300, 0x490: 0x2fea, 0x491: 0x32f6,
+       0x492: 0x2fef, 0x493: 0x32fb, 0x494: 0x3906, 0x495: 0x3a95, 0x496: 0x390d, 0x497: 0x3a9c,
+       0x498: 0x3030, 0x499: 0x333c, 0x49a: 0x3035, 0x49b: 0x3341, 0x49c: 0x391b, 0x49d: 0x3aaa,
+       0x49e: 0x303a, 0x49f: 0x3346, 0x4a0: 0x3049, 0x4a1: 0x3355, 0x4a2: 0x3067, 0x4a3: 0x3373,
+       0x4a4: 0x3076, 0x4a5: 0x3382, 0x4a6: 0x306c, 0x4a7: 0x3378, 0x4a8: 0x307b, 0x4a9: 0x3387,
+       0x4aa: 0x3080, 0x4ab: 0x338c, 0x4ac: 0x30c6, 0x4ad: 0x33d2, 0x4ae: 0x3922, 0x4af: 0x3ab1,
+       0x4b0: 0x30d0, 0x4b1: 0x33e1, 0x4b2: 0x30da, 0x4b3: 0x33eb, 0x4b4: 0x30e4, 0x4b5: 0x33f5,
+       0x4b6: 0x46db, 0x4b7: 0x476c, 0x4b8: 0x3929, 0x4b9: 0x3ab8, 0x4ba: 0x30fd, 0x4bb: 0x340e,
+       0x4bc: 0x30f8, 0x4bd: 0x3409, 0x4be: 0x3102, 0x4bf: 0x3413,
+       // Block 0x13, offset 0x4c0
+       0x4c0: 0x3107, 0x4c1: 0x3418, 0x4c2: 0x310c, 0x4c3: 0x341d, 0x4c4: 0x3120, 0x4c5: 0x3431,
+       0x4c6: 0x312a, 0x4c7: 0x343b, 0x4c8: 0x3139, 0x4c9: 0x344a, 0x4ca: 0x3134, 0x4cb: 0x3445,
+       0x4cc: 0x394c, 0x4cd: 0x3adb, 0x4ce: 0x395a, 0x4cf: 0x3ae9, 0x4d0: 0x3961, 0x4d1: 0x3af0,
+       0x4d2: 0x3968, 0x4d3: 0x3af7, 0x4d4: 0x3166, 0x4d5: 0x3477, 0x4d6: 0x316b, 0x4d7: 0x347c,
+       0x4d8: 0x3175, 0x4d9: 0x3486, 0x4da: 0x4708, 0x4db: 0x4799, 0x4dc: 0x39ae, 0x4dd: 0x3b3d,
+       0x4de: 0x318e, 0x4df: 0x349f, 0x4e0: 0x3198, 0x4e1: 0x34a9, 0x4e2: 0x4717, 0x4e3: 0x47a8,
+       0x4e4: 0x39b5, 0x4e5: 0x3b44, 0x4e6: 0x39bc, 0x4e7: 0x3b4b, 0x4e8: 0x39c3, 0x4e9: 0x3b52,
+       0x4ea: 0x31a7, 0x4eb: 0x34b8, 0x4ec: 0x31b1, 0x4ed: 0x34c7, 0x4ee: 0x31c5, 0x4ef: 0x34db,
+       0x4f0: 0x31c0, 0x4f1: 0x34d6, 0x4f2: 0x3201, 0x4f3: 0x3517, 0x4f4: 0x3210, 0x4f5: 0x3526,
+       0x4f6: 0x320b, 0x4f7: 0x3521, 0x4f8: 0x39ca, 0x4f9: 0x3b59, 0x4fa: 0x39d1, 0x4fb: 0x3b60,
+       0x4fc: 0x3215, 0x4fd: 0x352b, 0x4fe: 0x321a, 0x4ff: 0x3530,
+       // Block 0x14, offset 0x500
+       0x500: 0x321f, 0x501: 0x3535, 0x502: 0x3224, 0x503: 0x353a, 0x504: 0x3233, 0x505: 0x3549,
+       0x506: 0x322e, 0x507: 0x3544, 0x508: 0x3238, 0x509: 0x3553, 0x50a: 0x323d, 0x50b: 0x3558,
+       0x50c: 0x3242, 0x50d: 0x355d, 0x50e: 0x3260, 0x50f: 0x357b, 0x510: 0x3279, 0x511: 0x3599,
+       0x512: 0x3288, 0x513: 0x35a8, 0x514: 0x328d, 0x515: 0x35ad, 0x516: 0x3391, 0x517: 0x34bd,
+       0x518: 0x354e, 0x519: 0x358a, 0x51b: 0x35e8,
+       0x520: 0x46b8, 0x521: 0x4749, 0x522: 0x2f9a, 0x523: 0x32a6,
+       0x524: 0x388f, 0x525: 0x3a1e, 0x526: 0x3888, 0x527: 0x3a17, 0x528: 0x389d, 0x529: 0x3a2c,
+       0x52a: 0x3896, 0x52b: 0x3a25, 0x52c: 0x38d5, 0x52d: 0x3a64, 0x52e: 0x38ab, 0x52f: 0x3a3a,
+       0x530: 0x38a4, 0x531: 0x3a33, 0x532: 0x38b9, 0x533: 0x3a48, 0x534: 0x38b2, 0x535: 0x3a41,
+       0x536: 0x38dc, 0x537: 0x3a6b, 0x538: 0x46cc, 0x539: 0x475d, 0x53a: 0x3017, 0x53b: 0x3323,
+       0x53c: 0x3003, 0x53d: 0x330f, 0x53e: 0x38f1, 0x53f: 0x3a80,
+       // Block 0x15, offset 0x540
+       0x540: 0x38ea, 0x541: 0x3a79, 0x542: 0x38ff, 0x543: 0x3a8e, 0x544: 0x38f8, 0x545: 0x3a87,
+       0x546: 0x3914, 0x547: 0x3aa3, 0x548: 0x30a8, 0x549: 0x33b4, 0x54a: 0x30bc, 0x54b: 0x33c8,
+       0x54c: 0x46fe, 0x54d: 0x478f, 0x54e: 0x314d, 0x54f: 0x345e, 0x550: 0x3937, 0x551: 0x3ac6,
+       0x552: 0x3930, 0x553: 0x3abf, 0x554: 0x3945, 0x555: 0x3ad4, 0x556: 0x393e, 0x557: 0x3acd,
+       0x558: 0x39a0, 0x559: 0x3b2f, 0x55a: 0x3984, 0x55b: 0x3b13, 0x55c: 0x397d, 0x55d: 0x3b0c,
+       0x55e: 0x3992, 0x55f: 0x3b21, 0x560: 0x398b, 0x561: 0x3b1a, 0x562: 0x3999, 0x563: 0x3b28,
+       0x564: 0x31fc, 0x565: 0x3512, 0x566: 0x31de, 0x567: 0x34f4, 0x568: 0x39fb, 0x569: 0x3b8a,
+       0x56a: 0x39f4, 0x56b: 0x3b83, 0x56c: 0x3a09, 0x56d: 0x3b98, 0x56e: 0x3a02, 0x56f: 0x3b91,
+       0x570: 0x3a10, 0x571: 0x3b9f, 0x572: 0x3247, 0x573: 0x3562, 0x574: 0x326f, 0x575: 0x358f,
+       0x576: 0x326a, 0x577: 0x3585, 0x578: 0x3256, 0x579: 0x3571,
+       // Block 0x16, offset 0x580
+       0x580: 0x481b, 0x581: 0x4821, 0x582: 0x4935, 0x583: 0x494d, 0x584: 0x493d, 0x585: 0x4955,
+       0x586: 0x4945, 0x587: 0x495d, 0x588: 0x47c1, 0x589: 0x47c7, 0x58a: 0x48a5, 0x58b: 0x48bd,
+       0x58c: 0x48ad, 0x58d: 0x48c5, 0x58e: 0x48b5, 0x58f: 0x48cd, 0x590: 0x482d, 0x591: 0x4833,
+       0x592: 0x3dcf, 0x593: 0x3ddf, 0x594: 0x3dd7, 0x595: 0x3de7,
+       0x598: 0x47cd, 0x599: 0x47d3, 0x59a: 0x3cff, 0x59b: 0x3d0f, 0x59c: 0x3d07, 0x59d: 0x3d17,
+       0x5a0: 0x4845, 0x5a1: 0x484b, 0x5a2: 0x4965, 0x5a3: 0x497d,
+       0x5a4: 0x496d, 0x5a5: 0x4985, 0x5a6: 0x4975, 0x5a7: 0x498d, 0x5a8: 0x47d9, 0x5a9: 0x47df,
+       0x5aa: 0x48d5, 0x5ab: 0x48ed, 0x5ac: 0x48dd, 0x5ad: 0x48f5, 0x5ae: 0x48e5, 0x5af: 0x48fd,
+       0x5b0: 0x485d, 0x5b1: 0x4863, 0x5b2: 0x3e2f, 0x5b3: 0x3e47, 0x5b4: 0x3e37, 0x5b5: 0x3e4f,
+       0x5b6: 0x3e3f, 0x5b7: 0x3e57, 0x5b8: 0x47e5, 0x5b9: 0x47eb, 0x5ba: 0x3d2f, 0x5bb: 0x3d47,
+       0x5bc: 0x3d37, 0x5bd: 0x3d4f, 0x5be: 0x3d3f, 0x5bf: 0x3d57,
+       // Block 0x17, offset 0x5c0
+       0x5c0: 0x4869, 0x5c1: 0x486f, 0x5c2: 0x3e5f, 0x5c3: 0x3e6f, 0x5c4: 0x3e67, 0x5c5: 0x3e77,
+       0x5c8: 0x47f1, 0x5c9: 0x47f7, 0x5ca: 0x3d5f, 0x5cb: 0x3d6f,
+       0x5cc: 0x3d67, 0x5cd: 0x3d77, 0x5d0: 0x487b, 0x5d1: 0x4881,
+       0x5d2: 0x3e97, 0x5d3: 0x3eaf, 0x5d4: 0x3e9f, 0x5d5: 0x3eb7, 0x5d6: 0x3ea7, 0x5d7: 0x3ebf,
+       0x5d9: 0x47fd, 0x5db: 0x3d7f, 0x5dd: 0x3d87,
+       0x5df: 0x3d8f, 0x5e0: 0x4893, 0x5e1: 0x4899, 0x5e2: 0x4995, 0x5e3: 0x49ad,
+       0x5e4: 0x499d, 0x5e5: 0x49b5, 0x5e6: 0x49a5, 0x5e7: 0x49bd, 0x5e8: 0x4803, 0x5e9: 0x4809,
+       0x5ea: 0x4905, 0x5eb: 0x491d, 0x5ec: 0x490d, 0x5ed: 0x4925, 0x5ee: 0x4915, 0x5ef: 0x492d,
+       0x5f0: 0x480f, 0x5f1: 0x4335, 0x5f2: 0x36a8, 0x5f3: 0x433b, 0x5f4: 0x4839, 0x5f5: 0x4341,
+       0x5f6: 0x36ba, 0x5f7: 0x4347, 0x5f8: 0x36d8, 0x5f9: 0x434d, 0x5fa: 0x36f0, 0x5fb: 0x4353,
+       0x5fc: 0x4887, 0x5fd: 0x4359,
+       // Block 0x18, offset 0x600
+       0x600: 0x3db7, 0x601: 0x3dbf, 0x602: 0x419b, 0x603: 0x41b9, 0x604: 0x41a5, 0x605: 0x41c3,
+       0x606: 0x41af, 0x607: 0x41cd, 0x608: 0x3cef, 0x609: 0x3cf7, 0x60a: 0x40e7, 0x60b: 0x4105,
+       0x60c: 0x40f1, 0x60d: 0x410f, 0x60e: 0x40fb, 0x60f: 0x4119, 0x610: 0x3dff, 0x611: 0x3e07,
+       0x612: 0x41d7, 0x613: 0x41f5, 0x614: 0x41e1, 0x615: 0x41ff, 0x616: 0x41eb, 0x617: 0x4209,
+       0x618: 0x3d1f, 0x619: 0x3d27, 0x61a: 0x4123, 0x61b: 0x4141, 0x61c: 0x412d, 0x61d: 0x414b,
+       0x61e: 0x4137, 0x61f: 0x4155, 0x620: 0x3ed7, 0x621: 0x3edf, 0x622: 0x4213, 0x623: 0x4231,
+       0x624: 0x421d, 0x625: 0x423b, 0x626: 0x4227, 0x627: 0x4245, 0x628: 0x3d97, 0x629: 0x3d9f,
+       0x62a: 0x415f, 0x62b: 0x417d, 0x62c: 0x4169, 0x62d: 0x4187, 0x62e: 0x4173, 0x62f: 0x4191,
+       0x630: 0x369c, 0x631: 0x3696, 0x632: 0x3da7, 0x633: 0x36a2, 0x634: 0x3daf,
+       0x636: 0x4827, 0x637: 0x3dc7, 0x638: 0x360c, 0x639: 0x3606, 0x63a: 0x35fa, 0x63b: 0x4305,
+       0x63c: 0x3612, 0x63d: 0x8100, 0x63e: 0x01d6, 0x63f: 0xa100,
+       // Block 0x19, offset 0x640
+       0x640: 0x8100, 0x641: 0x35be, 0x642: 0x3def, 0x643: 0x36b4, 0x644: 0x3df7,
+       0x646: 0x4851, 0x647: 0x3e0f, 0x648: 0x3618, 0x649: 0x430b, 0x64a: 0x3624, 0x64b: 0x4311,
+       0x64c: 0x3630, 0x64d: 0x3ba6, 0x64e: 0x3bad, 0x64f: 0x3bb4, 0x650: 0x36cc, 0x651: 0x36c6,
+       0x652: 0x3e17, 0x653: 0x44fb, 0x656: 0x36d2, 0x657: 0x3e27,
+       0x658: 0x3648, 0x659: 0x3642, 0x65a: 0x3636, 0x65b: 0x4317, 0x65d: 0x3bbb,
+       0x65e: 0x3bc2, 0x65f: 0x3bc9, 0x660: 0x3702, 0x661: 0x36fc, 0x662: 0x3e7f, 0x663: 0x4503,
+       0x664: 0x36e4, 0x665: 0x36ea, 0x666: 0x3708, 0x667: 0x3e8f, 0x668: 0x3678, 0x669: 0x3672,
+       0x66a: 0x3666, 0x66b: 0x4323, 0x66c: 0x3660, 0x66d: 0x35b2, 0x66e: 0x42ff, 0x66f: 0x0081,
+       0x672: 0x3ec7, 0x673: 0x370e, 0x674: 0x3ecf,
+       0x676: 0x489f, 0x677: 0x3ee7, 0x678: 0x3654, 0x679: 0x431d, 0x67a: 0x3684, 0x67b: 0x432f,
+       0x67c: 0x3690, 0x67d: 0x426d, 0x67e: 0xa100,
+       // Block 0x1a, offset 0x680
+       0x681: 0x3c1d, 0x683: 0xa000, 0x684: 0x3c24, 0x685: 0xa000,
+       0x687: 0x3c2b, 0x688: 0xa000, 0x689: 0x3c32,
+       0x68d: 0xa000,
+       0x6a0: 0x2f7c, 0x6a1: 0xa000, 0x6a2: 0x3c40,
+       0x6a4: 0xa000, 0x6a5: 0xa000,
+       0x6ad: 0x3c39, 0x6ae: 0x2f77, 0x6af: 0x2f81,
+       0x6b0: 0x3c47, 0x6b1: 0x3c4e, 0x6b2: 0xa000, 0x6b3: 0xa000, 0x6b4: 0x3c55, 0x6b5: 0x3c5c,
+       0x6b6: 0xa000, 0x6b7: 0xa000, 0x6b8: 0x3c63, 0x6b9: 0x3c6a, 0x6ba: 0xa000, 0x6bb: 0xa000,
+       0x6bc: 0xa000, 0x6bd: 0xa000,
+       // Block 0x1b, offset 0x6c0
+       0x6c0: 0x3c71, 0x6c1: 0x3c78, 0x6c2: 0xa000, 0x6c3: 0xa000, 0x6c4: 0x3c8d, 0x6c5: 0x3c94,
+       0x6c6: 0xa000, 0x6c7: 0xa000, 0x6c8: 0x3c9b, 0x6c9: 0x3ca2,
+       0x6d1: 0xa000,
+       0x6d2: 0xa000,
+       0x6e2: 0xa000,
+       0x6e8: 0xa000, 0x6e9: 0xa000,
+       0x6eb: 0xa000, 0x6ec: 0x3cb7, 0x6ed: 0x3cbe, 0x6ee: 0x3cc5, 0x6ef: 0x3ccc,
+       0x6f2: 0xa000, 0x6f3: 0xa000, 0x6f4: 0xa000, 0x6f5: 0xa000,
+       // Block 0x1c, offset 0x700
+       0x706: 0xa000, 0x70b: 0xa000,
+       0x70c: 0x3f1f, 0x70d: 0xa000, 0x70e: 0x3f27, 0x70f: 0xa000, 0x710: 0x3f2f, 0x711: 0xa000,
+       0x712: 0x3f37, 0x713: 0xa000, 0x714: 0x3f3f, 0x715: 0xa000, 0x716: 0x3f47, 0x717: 0xa000,
+       0x718: 0x3f4f, 0x719: 0xa000, 0x71a: 0x3f57, 0x71b: 0xa000, 0x71c: 0x3f5f, 0x71d: 0xa000,
+       0x71e: 0x3f67, 0x71f: 0xa000, 0x720: 0x3f6f, 0x721: 0xa000, 0x722: 0x3f77,
+       0x724: 0xa000, 0x725: 0x3f7f, 0x726: 0xa000, 0x727: 0x3f87, 0x728: 0xa000, 0x729: 0x3f8f,
+       0x72f: 0xa000,
+       0x730: 0x3f97, 0x731: 0x3f9f, 0x732: 0xa000, 0x733: 0x3fa7, 0x734: 0x3faf, 0x735: 0xa000,
+       0x736: 0x3fb7, 0x737: 0x3fbf, 0x738: 0xa000, 0x739: 0x3fc7, 0x73a: 0x3fcf, 0x73b: 0xa000,
+       0x73c: 0x3fd7, 0x73d: 0x3fdf,
+       // Block 0x1d, offset 0x740
+       0x754: 0x3f17,
+       0x759: 0x9904, 0x75a: 0x9904, 0x75b: 0x8100, 0x75c: 0x8100, 0x75d: 0xa000,
+       0x75e: 0x3fe7,
+       0x766: 0xa000,
+       0x76b: 0xa000, 0x76c: 0x3ff7, 0x76d: 0xa000, 0x76e: 0x3fff, 0x76f: 0xa000,
+       0x770: 0x4007, 0x771: 0xa000, 0x772: 0x400f, 0x773: 0xa000, 0x774: 0x4017, 0x775: 0xa000,
+       0x776: 0x401f, 0x777: 0xa000, 0x778: 0x4027, 0x779: 0xa000, 0x77a: 0x402f, 0x77b: 0xa000,
+       0x77c: 0x4037, 0x77d: 0xa000, 0x77e: 0x403f, 0x77f: 0xa000,
+       // Block 0x1e, offset 0x780
+       0x780: 0x4047, 0x781: 0xa000, 0x782: 0x404f, 0x784: 0xa000, 0x785: 0x4057,
+       0x786: 0xa000, 0x787: 0x405f, 0x788: 0xa000, 0x789: 0x4067,
+       0x78f: 0xa000, 0x790: 0x406f, 0x791: 0x4077,
+       0x792: 0xa000, 0x793: 0x407f, 0x794: 0x4087, 0x795: 0xa000, 0x796: 0x408f, 0x797: 0x4097,
+       0x798: 0xa000, 0x799: 0x409f, 0x79a: 0x40a7, 0x79b: 0xa000, 0x79c: 0x40af, 0x79d: 0x40b7,
+       0x7af: 0xa000,
+       0x7b0: 0xa000, 0x7b1: 0xa000, 0x7b2: 0xa000, 0x7b4: 0x3fef,
+       0x7b7: 0x40bf, 0x7b8: 0x40c7, 0x7b9: 0x40cf, 0x7ba: 0x40d7,
+       0x7bd: 0xa000, 0x7be: 0x40df,
+       // Block 0x1f, offset 0x7c0
+       0x7c0: 0x137a, 0x7c1: 0x0cfe, 0x7c2: 0x13d6, 0x7c3: 0x13a2, 0x7c4: 0x0e5a, 0x7c5: 0x06ee,
+       0x7c6: 0x08e2, 0x7c7: 0x162e, 0x7c8: 0x162e, 0x7c9: 0x0a0e, 0x7ca: 0x1462, 0x7cb: 0x0946,
+       0x7cc: 0x0a0a, 0x7cd: 0x0bf2, 0x7ce: 0x0fd2, 0x7cf: 0x1162, 0x7d0: 0x129a, 0x7d1: 0x12d6,
+       0x7d2: 0x130a, 0x7d3: 0x141e, 0x7d4: 0x0d76, 0x7d5: 0x0e02, 0x7d6: 0x0eae, 0x7d7: 0x0f46,
+       0x7d8: 0x1262, 0x7d9: 0x144a, 0x7da: 0x1576, 0x7db: 0x0712, 0x7dc: 0x08b6, 0x7dd: 0x0d8a,
+       0x7de: 0x0ed2, 0x7df: 0x1296, 0x7e0: 0x15c6, 0x7e1: 0x0ab6, 0x7e2: 0x0e7a, 0x7e3: 0x1286,
+       0x7e4: 0x131a, 0x7e5: 0x0c26, 0x7e6: 0x11be, 0x7e7: 0x12e2, 0x7e8: 0x0b22, 0x7e9: 0x0d12,
+       0x7ea: 0x0e1a, 0x7eb: 0x0f1e, 0x7ec: 0x142a, 0x7ed: 0x0752, 0x7ee: 0x07ea, 0x7ef: 0x0856,
+       0x7f0: 0x0c8e, 0x7f1: 0x0d82, 0x7f2: 0x0ece, 0x7f3: 0x0ff2, 0x7f4: 0x117a, 0x7f5: 0x128e,
+       0x7f6: 0x12a6, 0x7f7: 0x13ca, 0x7f8: 0x14f2, 0x7f9: 0x15a6, 0x7fa: 0x15c2, 0x7fb: 0x102e,
+       0x7fc: 0x106e, 0x7fd: 0x1126, 0x7fe: 0x1246, 0x7ff: 0x147e,
+       // Block 0x20, offset 0x800
+       0x800: 0x15ce, 0x801: 0x134e, 0x802: 0x09ca, 0x803: 0x0b3e, 0x804: 0x10de, 0x805: 0x119e,
+       0x806: 0x0f02, 0x807: 0x1036, 0x808: 0x139a, 0x809: 0x14ea, 0x80a: 0x09c6, 0x80b: 0x0a92,
+       0x80c: 0x0d7a, 0x80d: 0x0e2e, 0x80e: 0x0e62, 0x80f: 0x1116, 0x810: 0x113e, 0x811: 0x14aa,
+       0x812: 0x0852, 0x813: 0x11aa, 0x814: 0x07f6, 0x815: 0x07f2, 0x816: 0x109a, 0x817: 0x112a,
+       0x818: 0x125e, 0x819: 0x14b2, 0x81a: 0x136a, 0x81b: 0x0c2a, 0x81c: 0x0d76, 0x81d: 0x135a,
+       0x81e: 0x06fa, 0x81f: 0x0a66, 0x820: 0x0b96, 0x821: 0x0f32, 0x822: 0x0fb2, 0x823: 0x0876,
+       0x824: 0x103e, 0x825: 0x0762, 0x826: 0x0b7a, 0x827: 0x06da, 0x828: 0x0dee, 0x829: 0x0ca6,
+       0x82a: 0x1112, 0x82b: 0x08ca, 0x82c: 0x09b6, 0x82d: 0x0ffe, 0x82e: 0x1266, 0x82f: 0x133e,
+       0x830: 0x0dba, 0x831: 0x13fa, 0x832: 0x0de6, 0x833: 0x0c3a, 0x834: 0x121e, 0x835: 0x0c5a,
+       0x836: 0x0fae, 0x837: 0x072e, 0x838: 0x07aa, 0x839: 0x07ee, 0x83a: 0x0d56, 0x83b: 0x10fe,
+       0x83c: 0x11f6, 0x83d: 0x134a, 0x83e: 0x145e, 0x83f: 0x085e,
+       // Block 0x21, offset 0x840
+       0x840: 0x0912, 0x841: 0x0a1a, 0x842: 0x0b32, 0x843: 0x0cc2, 0x844: 0x0e7e, 0x845: 0x1042,
+       0x846: 0x149a, 0x847: 0x157e, 0x848: 0x15d2, 0x849: 0x15ea, 0x84a: 0x083a, 0x84b: 0x0cf6,
+       0x84c: 0x0da6, 0x84d: 0x13ee, 0x84e: 0x0afe, 0x84f: 0x0bda, 0x850: 0x0bf6, 0x851: 0x0c86,
+       0x852: 0x0e6e, 0x853: 0x0eba, 0x854: 0x0f6a, 0x855: 0x108e, 0x856: 0x1132, 0x857: 0x1196,
+       0x858: 0x13de, 0x859: 0x126e, 0x85a: 0x1406, 0x85b: 0x1482, 0x85c: 0x0812, 0x85d: 0x083e,
+       0x85e: 0x0926, 0x85f: 0x0eaa, 0x860: 0x12f6, 0x861: 0x133e, 0x862: 0x0b1e, 0x863: 0x0b8e,
+       0x864: 0x0c52, 0x865: 0x0db2, 0x866: 0x10da, 0x867: 0x0f26, 0x868: 0x073e, 0x869: 0x0982,
+       0x86a: 0x0a66, 0x86b: 0x0aca, 0x86c: 0x0b9a, 0x86d: 0x0f42, 0x86e: 0x0f5e, 0x86f: 0x116e,
+       0x870: 0x118e, 0x871: 0x1466, 0x872: 0x14e6, 0x873: 0x14f6, 0x874: 0x1532, 0x875: 0x0756,
+       0x876: 0x1082, 0x877: 0x1452, 0x878: 0x14ce, 0x879: 0x0bb2, 0x87a: 0x071a, 0x87b: 0x077a,
+       0x87c: 0x0a6a, 0x87d: 0x0a8a, 0x87e: 0x0cb2, 0x87f: 0x0d76,
+       // Block 0x22, offset 0x880
+       0x880: 0x0ec6, 0x881: 0x0fce, 0x882: 0x127a, 0x883: 0x141a, 0x884: 0x1626, 0x885: 0x0ce6,
+       0x886: 0x14a6, 0x887: 0x0836, 0x888: 0x0d32, 0x889: 0x0d3e, 0x88a: 0x0e12, 0x88b: 0x0e4a,
+       0x88c: 0x0f4e, 0x88d: 0x0faa, 0x88e: 0x102a, 0x88f: 0x110e, 0x890: 0x153e, 0x891: 0x07b2,
+       0x892: 0x0c06, 0x893: 0x14b6, 0x894: 0x076a, 0x895: 0x0aae, 0x896: 0x0e32, 0x897: 0x13e2,
+       0x898: 0x0b6a, 0x899: 0x0bba, 0x89a: 0x0d46, 0x89b: 0x0f32, 0x89c: 0x14be, 0x89d: 0x081a,
+       0x89e: 0x0902, 0x89f: 0x0a9a, 0x8a0: 0x0cd6, 0x8a1: 0x0d22, 0x8a2: 0x0d62, 0x8a3: 0x0df6,
+       0x8a4: 0x0f4a, 0x8a5: 0x0fbe, 0x8a6: 0x115a, 0x8a7: 0x12fa, 0x8a8: 0x1306, 0x8a9: 0x145a,
+       0x8aa: 0x14da, 0x8ab: 0x0886, 0x8ac: 0x0e4e, 0x8ad: 0x0906, 0x8ae: 0x0eca, 0x8af: 0x0f6e,
+       0x8b0: 0x128a, 0x8b1: 0x14c2, 0x8b2: 0x15ae, 0x8b3: 0x15d6, 0x8b4: 0x0d3a, 0x8b5: 0x0e2a,
+       0x8b6: 0x11c6, 0x8b7: 0x10ba, 0x8b8: 0x10c6, 0x8b9: 0x10ea, 0x8ba: 0x0f1a, 0x8bb: 0x0ea2,
+       0x8bc: 0x1366, 0x8bd: 0x0736, 0x8be: 0x122e, 0x8bf: 0x081e,
+       // Block 0x23, offset 0x8c0
+       0x8c0: 0x080e, 0x8c1: 0x0b0e, 0x8c2: 0x0c2e, 0x8c3: 0x10f6, 0x8c4: 0x0a56, 0x8c5: 0x0e06,
+       0x8c6: 0x0cf2, 0x8c7: 0x13ea, 0x8c8: 0x12ea, 0x8c9: 0x14ae, 0x8ca: 0x1326, 0x8cb: 0x0b2a,
+       0x8cc: 0x078a, 0x8cd: 0x095e, 0x8d0: 0x09b2,
+       0x8d2: 0x0ce2, 0x8d5: 0x07fa, 0x8d6: 0x0f22, 0x8d7: 0x0fe6,
+       0x8d8: 0x104a, 0x8d9: 0x1066, 0x8da: 0x106a, 0x8db: 0x107e, 0x8dc: 0x14fe, 0x8dd: 0x10ee,
+       0x8de: 0x1172, 0x8e0: 0x1292, 0x8e2: 0x1356,
+       0x8e5: 0x140a, 0x8e6: 0x1436,
+       0x8ea: 0x1552, 0x8eb: 0x1556, 0x8ec: 0x155a, 0x8ed: 0x15be, 0x8ee: 0x142e, 0x8ef: 0x14ca,
+       0x8f0: 0x075a, 0x8f1: 0x077e, 0x8f2: 0x0792, 0x8f3: 0x084e, 0x8f4: 0x085a, 0x8f5: 0x089a,
+       0x8f6: 0x094e, 0x8f7: 0x096a, 0x8f8: 0x0972, 0x8f9: 0x09ae, 0x8fa: 0x09ba, 0x8fb: 0x0a96,
+       0x8fc: 0x0a9e, 0x8fd: 0x0ba6, 0x8fe: 0x0bce, 0x8ff: 0x0bd6,
+       // Block 0x24, offset 0x900
+       0x900: 0x0bee, 0x901: 0x0c9a, 0x902: 0x0cca, 0x903: 0x0cea, 0x904: 0x0d5a, 0x905: 0x0e1e,
+       0x906: 0x0e3a, 0x907: 0x0e6a, 0x908: 0x0ebe, 0x909: 0x0ede, 0x90a: 0x0f52, 0x90b: 0x1032,
+       0x90c: 0x104e, 0x90d: 0x1056, 0x90e: 0x1052, 0x90f: 0x105a, 0x910: 0x105e, 0x911: 0x1062,
+       0x912: 0x1076, 0x913: 0x107a, 0x914: 0x109e, 0x915: 0x10b2, 0x916: 0x10ce, 0x917: 0x1132,
+       0x918: 0x113a, 0x919: 0x1142, 0x91a: 0x1156, 0x91b: 0x117e, 0x91c: 0x11ce, 0x91d: 0x1202,
+       0x91e: 0x1202, 0x91f: 0x126a, 0x920: 0x1312, 0x921: 0x132a, 0x922: 0x135e, 0x923: 0x1362,
+       0x924: 0x13a6, 0x925: 0x13aa, 0x926: 0x1402, 0x927: 0x140a, 0x928: 0x14de, 0x929: 0x1522,
+       0x92a: 0x153a, 0x92b: 0x0b9e, 0x92c: 0x1721, 0x92d: 0x11e6,
+       0x930: 0x06e2, 0x931: 0x07e6, 0x932: 0x07a6, 0x933: 0x074e, 0x934: 0x078e, 0x935: 0x07ba,
+       0x936: 0x084a, 0x937: 0x0866, 0x938: 0x094e, 0x939: 0x093a, 0x93a: 0x094a, 0x93b: 0x0966,
+       0x93c: 0x09b2, 0x93d: 0x09c2, 0x93e: 0x0a06, 0x93f: 0x0a12,
+       // Block 0x25, offset 0x940
+       0x940: 0x0a2e, 0x941: 0x0a3e, 0x942: 0x0b26, 0x943: 0x0b2e, 0x944: 0x0b5e, 0x945: 0x0b7e,
+       0x946: 0x0bae, 0x947: 0x0bc6, 0x948: 0x0bb6, 0x949: 0x0bd6, 0x94a: 0x0bca, 0x94b: 0x0bee,
+       0x94c: 0x0c0a, 0x94d: 0x0c62, 0x94e: 0x0c6e, 0x94f: 0x0c76, 0x950: 0x0c9e, 0x951: 0x0ce2,
+       0x952: 0x0d12, 0x953: 0x0d16, 0x954: 0x0d2a, 0x955: 0x0daa, 0x956: 0x0dba, 0x957: 0x0e12,
+       0x958: 0x0e5e, 0x959: 0x0e56, 0x95a: 0x0e6a, 0x95b: 0x0e86, 0x95c: 0x0ebe, 0x95d: 0x1016,
+       0x95e: 0x0ee2, 0x95f: 0x0f16, 0x960: 0x0f22, 0x961: 0x0f62, 0x962: 0x0f7e, 0x963: 0x0fa2,
+       0x964: 0x0fc6, 0x965: 0x0fca, 0x966: 0x0fe6, 0x967: 0x0fea, 0x968: 0x0ffa, 0x969: 0x100e,
+       0x96a: 0x100a, 0x96b: 0x103a, 0x96c: 0x10b6, 0x96d: 0x10ce, 0x96e: 0x10e6, 0x96f: 0x111e,
+       0x970: 0x1132, 0x971: 0x114e, 0x972: 0x117e, 0x973: 0x1232, 0x974: 0x125a, 0x975: 0x12ce,
+       0x976: 0x1316, 0x977: 0x1322, 0x978: 0x132a, 0x979: 0x1342, 0x97a: 0x1356, 0x97b: 0x1346,
+       0x97c: 0x135e, 0x97d: 0x135a, 0x97e: 0x1352, 0x97f: 0x1362,
+       // Block 0x26, offset 0x980
+       0x980: 0x136e, 0x981: 0x13aa, 0x982: 0x13e6, 0x983: 0x1416, 0x984: 0x144e, 0x985: 0x146e,
+       0x986: 0x14ba, 0x987: 0x14de, 0x988: 0x14fe, 0x989: 0x1512, 0x98a: 0x1522, 0x98b: 0x152e,
+       0x98c: 0x153a, 0x98d: 0x158e, 0x98e: 0x162e, 0x98f: 0x16b8, 0x990: 0x16b3, 0x991: 0x16e5,
+       0x992: 0x060a, 0x993: 0x0632, 0x994: 0x0636, 0x995: 0x1767, 0x996: 0x1794, 0x997: 0x180c,
+       0x998: 0x161a, 0x999: 0x162a,
+       // Block 0x27, offset 0x9c0
+       0x9c0: 0x06fe, 0x9c1: 0x06f6, 0x9c2: 0x0706, 0x9c3: 0x164a, 0x9c4: 0x074a, 0x9c5: 0x075a,
+       0x9c6: 0x075e, 0x9c7: 0x0766, 0x9c8: 0x076e, 0x9c9: 0x0772, 0x9ca: 0x077e, 0x9cb: 0x0776,
+       0x9cc: 0x05b6, 0x9cd: 0x165e, 0x9ce: 0x0792, 0x9cf: 0x0796, 0x9d0: 0x079a, 0x9d1: 0x07b6,
+       0x9d2: 0x164f, 0x9d3: 0x05ba, 0x9d4: 0x07a2, 0x9d5: 0x07c2, 0x9d6: 0x1659, 0x9d7: 0x07d2,
+       0x9d8: 0x07da, 0x9d9: 0x073a, 0x9da: 0x07e2, 0x9db: 0x07e6, 0x9dc: 0x1834, 0x9dd: 0x0802,
+       0x9de: 0x080a, 0x9df: 0x05c2, 0x9e0: 0x0822, 0x9e1: 0x0826, 0x9e2: 0x082e, 0x9e3: 0x0832,
+       0x9e4: 0x05c6, 0x9e5: 0x084a, 0x9e6: 0x084e, 0x9e7: 0x085a, 0x9e8: 0x0866, 0x9e9: 0x086a,
+       0x9ea: 0x086e, 0x9eb: 0x0876, 0x9ec: 0x0896, 0x9ed: 0x089a, 0x9ee: 0x08a2, 0x9ef: 0x08b2,
+       0x9f0: 0x08ba, 0x9f1: 0x08be, 0x9f2: 0x08be, 0x9f3: 0x08be, 0x9f4: 0x166d, 0x9f5: 0x0e96,
+       0x9f6: 0x08d2, 0x9f7: 0x08da, 0x9f8: 0x1672, 0x9f9: 0x08e6, 0x9fa: 0x08ee, 0x9fb: 0x08f6,
+       0x9fc: 0x091e, 0x9fd: 0x090a, 0x9fe: 0x0916, 0x9ff: 0x091a,
+       // Block 0x28, offset 0xa00
+       0xa00: 0x0922, 0xa01: 0x092a, 0xa02: 0x092e, 0xa03: 0x0936, 0xa04: 0x093e, 0xa05: 0x0942,
+       0xa06: 0x0942, 0xa07: 0x094a, 0xa08: 0x0952, 0xa09: 0x0956, 0xa0a: 0x0962, 0xa0b: 0x0986,
+       0xa0c: 0x096a, 0xa0d: 0x098a, 0xa0e: 0x096e, 0xa0f: 0x0976, 0xa10: 0x080e, 0xa11: 0x09d2,
+       0xa12: 0x099a, 0xa13: 0x099e, 0xa14: 0x09a2, 0xa15: 0x0996, 0xa16: 0x09aa, 0xa17: 0x09a6,
+       0xa18: 0x09be, 0xa19: 0x1677, 0xa1a: 0x09da, 0xa1b: 0x09de, 0xa1c: 0x09e6, 0xa1d: 0x09f2,
+       0xa1e: 0x09fa, 0xa1f: 0x0a16, 0xa20: 0x167c, 0xa21: 0x1681, 0xa22: 0x0a22, 0xa23: 0x0a26,
+       0xa24: 0x0a2a, 0xa25: 0x0a1e, 0xa26: 0x0a32, 0xa27: 0x05ca, 0xa28: 0x05ce, 0xa29: 0x0a3a,
+       0xa2a: 0x0a42, 0xa2b: 0x0a42, 0xa2c: 0x1686, 0xa2d: 0x0a5e, 0xa2e: 0x0a62, 0xa2f: 0x0a66,
+       0xa30: 0x0a6e, 0xa31: 0x168b, 0xa32: 0x0a76, 0xa33: 0x0a7a, 0xa34: 0x0b52, 0xa35: 0x0a82,
+       0xa36: 0x05d2, 0xa37: 0x0a8e, 0xa38: 0x0a9e, 0xa39: 0x0aaa, 0xa3a: 0x0aa6, 0xa3b: 0x1695,
+       0xa3c: 0x0ab2, 0xa3d: 0x169a, 0xa3e: 0x0abe, 0xa3f: 0x0aba,
+       // Block 0x29, offset 0xa40
+       0xa40: 0x0ac2, 0xa41: 0x0ad2, 0xa42: 0x0ad6, 0xa43: 0x05d6, 0xa44: 0x0ae6, 0xa45: 0x0aee,
+       0xa46: 0x0af2, 0xa47: 0x0af6, 0xa48: 0x05da, 0xa49: 0x169f, 0xa4a: 0x05de, 0xa4b: 0x0b12,
+       0xa4c: 0x0b16, 0xa4d: 0x0b1a, 0xa4e: 0x0b22, 0xa4f: 0x1866, 0xa50: 0x0b3a, 0xa51: 0x16a9,
+       0xa52: 0x16a9, 0xa53: 0x11da, 0xa54: 0x0b4a, 0xa55: 0x0b4a, 0xa56: 0x05e2, 0xa57: 0x16cc,
+       0xa58: 0x179e, 0xa59: 0x0b5a, 0xa5a: 0x0b62, 0xa5b: 0x05e6, 0xa5c: 0x0b76, 0xa5d: 0x0b86,
+       0xa5e: 0x0b8a, 0xa5f: 0x0b92, 0xa60: 0x0ba2, 0xa61: 0x05ee, 0xa62: 0x05ea, 0xa63: 0x0ba6,
+       0xa64: 0x16ae, 0xa65: 0x0baa, 0xa66: 0x0bbe, 0xa67: 0x0bc2, 0xa68: 0x0bc6, 0xa69: 0x0bc2,
+       0xa6a: 0x0bd2, 0xa6b: 0x0bd6, 0xa6c: 0x0be6, 0xa6d: 0x0bde, 0xa6e: 0x0be2, 0xa6f: 0x0bea,
+       0xa70: 0x0bee, 0xa71: 0x0bf2, 0xa72: 0x0bfe, 0xa73: 0x0c02, 0xa74: 0x0c1a, 0xa75: 0x0c22,
+       0xa76: 0x0c32, 0xa77: 0x0c46, 0xa78: 0x16bd, 0xa79: 0x0c42, 0xa7a: 0x0c36, 0xa7b: 0x0c4e,
+       0xa7c: 0x0c56, 0xa7d: 0x0c6a, 0xa7e: 0x16c2, 0xa7f: 0x0c72,
+       // Block 0x2a, offset 0xa80
+       0xa80: 0x0c66, 0xa81: 0x0c5e, 0xa82: 0x05f2, 0xa83: 0x0c7a, 0xa84: 0x0c82, 0xa85: 0x0c8a,
+       0xa86: 0x0c7e, 0xa87: 0x05f6, 0xa88: 0x0c9a, 0xa89: 0x0ca2, 0xa8a: 0x16c7, 0xa8b: 0x0cce,
+       0xa8c: 0x0d02, 0xa8d: 0x0cde, 0xa8e: 0x0602, 0xa8f: 0x0cea, 0xa90: 0x05fe, 0xa91: 0x05fa,
+       0xa92: 0x07c6, 0xa93: 0x07ca, 0xa94: 0x0d06, 0xa95: 0x0cee, 0xa96: 0x11ae, 0xa97: 0x0666,
+       0xa98: 0x0d12, 0xa99: 0x0d16, 0xa9a: 0x0d1a, 0xa9b: 0x0d2e, 0xa9c: 0x0d26, 0xa9d: 0x16e0,
+       0xa9e: 0x0606, 0xa9f: 0x0d42, 0xaa0: 0x0d36, 0xaa1: 0x0d52, 0xaa2: 0x0d5a, 0xaa3: 0x16ea,
+       0xaa4: 0x0d5e, 0xaa5: 0x0d4a, 0xaa6: 0x0d66, 0xaa7: 0x060a, 0xaa8: 0x0d6a, 0xaa9: 0x0d6e,
+       0xaaa: 0x0d72, 0xaab: 0x0d7e, 0xaac: 0x16ef, 0xaad: 0x0d86, 0xaae: 0x060e, 0xaaf: 0x0d92,
+       0xab0: 0x16f4, 0xab1: 0x0d96, 0xab2: 0x0612, 0xab3: 0x0da2, 0xab4: 0x0dae, 0xab5: 0x0dba,
+       0xab6: 0x0dbe, 0xab7: 0x16f9, 0xab8: 0x1690, 0xab9: 0x16fe, 0xaba: 0x0dde, 0xabb: 0x1703,
+       0xabc: 0x0dea, 0xabd: 0x0df2, 0xabe: 0x0de2, 0xabf: 0x0dfe,
+       // Block 0x2b, offset 0xac0
+       0xac0: 0x0e0e, 0xac1: 0x0e1e, 0xac2: 0x0e12, 0xac3: 0x0e16, 0xac4: 0x0e22, 0xac5: 0x0e26,
+       0xac6: 0x1708, 0xac7: 0x0e0a, 0xac8: 0x0e3e, 0xac9: 0x0e42, 0xaca: 0x0616, 0xacb: 0x0e56,
+       0xacc: 0x0e52, 0xacd: 0x170d, 0xace: 0x0e36, 0xacf: 0x0e72, 0xad0: 0x1712, 0xad1: 0x1717,
+       0xad2: 0x0e76, 0xad3: 0x0e8a, 0xad4: 0x0e86, 0xad5: 0x0e82, 0xad6: 0x061a, 0xad7: 0x0e8e,
+       0xad8: 0x0e9e, 0xad9: 0x0e9a, 0xada: 0x0ea6, 0xadb: 0x1654, 0xadc: 0x0eb6, 0xadd: 0x171c,
+       0xade: 0x0ec2, 0xadf: 0x1726, 0xae0: 0x0ed6, 0xae1: 0x0ee2, 0xae2: 0x0ef6, 0xae3: 0x172b,
+       0xae4: 0x0f0a, 0xae5: 0x0f0e, 0xae6: 0x1730, 0xae7: 0x1735, 0xae8: 0x0f2a, 0xae9: 0x0f3a,
+       0xaea: 0x061e, 0xaeb: 0x0f3e, 0xaec: 0x0622, 0xaed: 0x0622, 0xaee: 0x0f56, 0xaef: 0x0f5a,
+       0xaf0: 0x0f62, 0xaf1: 0x0f66, 0xaf2: 0x0f72, 0xaf3: 0x0626, 0xaf4: 0x0f8a, 0xaf5: 0x173a,
+       0xaf6: 0x0fa6, 0xaf7: 0x173f, 0xaf8: 0x0fb2, 0xaf9: 0x16a4, 0xafa: 0x0fc2, 0xafb: 0x1744,
+       0xafc: 0x1749, 0xafd: 0x174e, 0xafe: 0x062a, 0xaff: 0x062e,
+       // Block 0x2c, offset 0xb00
+       0xb00: 0x0ffa, 0xb01: 0x1758, 0xb02: 0x1753, 0xb03: 0x175d, 0xb04: 0x1762, 0xb05: 0x1002,
+       0xb06: 0x1006, 0xb07: 0x1006, 0xb08: 0x100e, 0xb09: 0x0636, 0xb0a: 0x1012, 0xb0b: 0x063a,
+       0xb0c: 0x063e, 0xb0d: 0x176c, 0xb0e: 0x1026, 0xb0f: 0x102e, 0xb10: 0x103a, 0xb11: 0x0642,
+       0xb12: 0x1771, 0xb13: 0x105e, 0xb14: 0x1776, 0xb15: 0x177b, 0xb16: 0x107e, 0xb17: 0x1096,
+       0xb18: 0x0646, 0xb19: 0x109e, 0xb1a: 0x10a2, 0xb1b: 0x10a6, 0xb1c: 0x1780, 0xb1d: 0x1785,
+       0xb1e: 0x1785, 0xb1f: 0x10be, 0xb20: 0x064a, 0xb21: 0x178a, 0xb22: 0x10d2, 0xb23: 0x10d6,
+       0xb24: 0x064e, 0xb25: 0x178f, 0xb26: 0x10f2, 0xb27: 0x0652, 0xb28: 0x1102, 0xb29: 0x10fa,
+       0xb2a: 0x110a, 0xb2b: 0x1799, 0xb2c: 0x1122, 0xb2d: 0x0656, 0xb2e: 0x112e, 0xb2f: 0x1136,
+       0xb30: 0x1146, 0xb31: 0x065a, 0xb32: 0x17a3, 0xb33: 0x17a8, 0xb34: 0x065e, 0xb35: 0x17ad,
+       0xb36: 0x115e, 0xb37: 0x17b2, 0xb38: 0x116a, 0xb39: 0x1176, 0xb3a: 0x117e, 0xb3b: 0x17b7,
+       0xb3c: 0x17bc, 0xb3d: 0x1192, 0xb3e: 0x17c1, 0xb3f: 0x119a,
+       // Block 0x2d, offset 0xb40
+       0xb40: 0x16d1, 0xb41: 0x0662, 0xb42: 0x11b2, 0xb43: 0x11b6, 0xb44: 0x066a, 0xb45: 0x11ba,
+       0xb46: 0x0a36, 0xb47: 0x17c6, 0xb48: 0x17cb, 0xb49: 0x16d6, 0xb4a: 0x16db, 0xb4b: 0x11da,
+       0xb4c: 0x11de, 0xb4d: 0x13f6, 0xb4e: 0x066e, 0xb4f: 0x120a, 0xb50: 0x1206, 0xb51: 0x120e,
+       0xb52: 0x0842, 0xb53: 0x1212, 0xb54: 0x1216, 0xb55: 0x121a, 0xb56: 0x1222, 0xb57: 0x17d0,
+       0xb58: 0x121e, 0xb59: 0x1226, 0xb5a: 0x123a, 0xb5b: 0x123e, 0xb5c: 0x122a, 0xb5d: 0x1242,
+       0xb5e: 0x1256, 0xb5f: 0x126a, 0xb60: 0x1236, 0xb61: 0x124a, 0xb62: 0x124e, 0xb63: 0x1252,
+       0xb64: 0x17d5, 0xb65: 0x17df, 0xb66: 0x17da, 0xb67: 0x0672, 0xb68: 0x1272, 0xb69: 0x1276,
+       0xb6a: 0x127e, 0xb6b: 0x17f3, 0xb6c: 0x1282, 0xb6d: 0x17e4, 0xb6e: 0x0676, 0xb6f: 0x067a,
+       0xb70: 0x17e9, 0xb71: 0x17ee, 0xb72: 0x067e, 0xb73: 0x12a2, 0xb74: 0x12a6, 0xb75: 0x12aa,
+       0xb76: 0x12ae, 0xb77: 0x12ba, 0xb78: 0x12b6, 0xb79: 0x12c2, 0xb7a: 0x12be, 0xb7b: 0x12ce,
+       0xb7c: 0x12c6, 0xb7d: 0x12ca, 0xb7e: 0x12d2, 0xb7f: 0x0682,
+       // Block 0x2e, offset 0xb80
+       0xb80: 0x12da, 0xb81: 0x12de, 0xb82: 0x0686, 0xb83: 0x12ee, 0xb84: 0x12f2, 0xb85: 0x17f8,
+       0xb86: 0x12fe, 0xb87: 0x1302, 0xb88: 0x068a, 0xb89: 0x130e, 0xb8a: 0x05be, 0xb8b: 0x17fd,
+       0xb8c: 0x1802, 0xb8d: 0x068e, 0xb8e: 0x0692, 0xb8f: 0x133a, 0xb90: 0x1352, 0xb91: 0x136e,
+       0xb92: 0x137e, 0xb93: 0x1807, 0xb94: 0x1392, 0xb95: 0x1396, 0xb96: 0x13ae, 0xb97: 0x13ba,
+       0xb98: 0x1811, 0xb99: 0x1663, 0xb9a: 0x13c6, 0xb9b: 0x13c2, 0xb9c: 0x13ce, 0xb9d: 0x1668,
+       0xb9e: 0x13da, 0xb9f: 0x13e6, 0xba0: 0x1816, 0xba1: 0x181b, 0xba2: 0x1426, 0xba3: 0x1432,
+       0xba4: 0x143a, 0xba5: 0x1820, 0xba6: 0x143e, 0xba7: 0x146a, 0xba8: 0x1476, 0xba9: 0x147a,
+       0xbaa: 0x1472, 0xbab: 0x1486, 0xbac: 0x148a, 0xbad: 0x1825, 0xbae: 0x1496, 0xbaf: 0x0696,
+       0xbb0: 0x149e, 0xbb1: 0x182a, 0xbb2: 0x069a, 0xbb3: 0x14d6, 0xbb4: 0x0ac6, 0xbb5: 0x14ee,
+       0xbb6: 0x182f, 0xbb7: 0x1839, 0xbb8: 0x069e, 0xbb9: 0x06a2, 0xbba: 0x1516, 0xbbb: 0x183e,
+       0xbbc: 0x06a6, 0xbbd: 0x1843, 0xbbe: 0x152e, 0xbbf: 0x152e,
+       // Block 0x2f, offset 0xbc0
+       0xbc0: 0x1536, 0xbc1: 0x1848, 0xbc2: 0x154e, 0xbc3: 0x06aa, 0xbc4: 0x155e, 0xbc5: 0x156a,
+       0xbc6: 0x1572, 0xbc7: 0x157a, 0xbc8: 0x06ae, 0xbc9: 0x184d, 0xbca: 0x158e, 0xbcb: 0x15aa,
+       0xbcc: 0x15b6, 0xbcd: 0x06b2, 0xbce: 0x06b6, 0xbcf: 0x15ba, 0xbd0: 0x1852, 0xbd1: 0x06ba,
+       0xbd2: 0x1857, 0xbd3: 0x185c, 0xbd4: 0x1861, 0xbd5: 0x15de, 0xbd6: 0x06be, 0xbd7: 0x15f2,
+       0xbd8: 0x15fa, 0xbd9: 0x15fe, 0xbda: 0x1606, 0xbdb: 0x160e, 0xbdc: 0x1616, 0xbdd: 0x186b,
+}
+
+// nfcIndex: 22 blocks, 1408 entries, 1408 bytes
+// Block 0 is the zero block.
+var nfcIndex = [1408]uint8{
+       // Block 0x0, offset 0x0
+       // Block 0x1, offset 0x40
+       // Block 0x2, offset 0x80
+       // Block 0x3, offset 0xc0
+       0xc2: 0x2e, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x2f, 0xc7: 0x04,
+       0xc8: 0x05, 0xca: 0x30, 0xcb: 0x31, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x32,
+       0xd0: 0x09, 0xd1: 0x33, 0xd2: 0x34, 0xd3: 0x0a, 0xd6: 0x0b, 0xd7: 0x35,
+       0xd8: 0x36, 0xd9: 0x0c, 0xdb: 0x37, 0xdc: 0x38, 0xdd: 0x39, 0xdf: 0x3a,
+       0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05,
+       0xea: 0x06, 0xeb: 0x07, 0xec: 0x08, 0xed: 0x09, 0xef: 0x0a,
+       0xf0: 0x13,
+       // Block 0x4, offset 0x100
+       0x120: 0x3b, 0x121: 0x3c, 0x123: 0x0d, 0x124: 0x3d, 0x125: 0x3e, 0x126: 0x3f, 0x127: 0x40,
+       0x128: 0x41, 0x129: 0x42, 0x12a: 0x43, 0x12b: 0x44, 0x12c: 0x3f, 0x12d: 0x45, 0x12e: 0x46, 0x12f: 0x47,
+       0x131: 0x48, 0x132: 0x49, 0x133: 0x4a, 0x134: 0x4b, 0x135: 0x4c, 0x137: 0x4d,
+       0x138: 0x4e, 0x139: 0x4f, 0x13a: 0x50, 0x13b: 0x51, 0x13c: 0x52, 0x13d: 0x53, 0x13e: 0x54, 0x13f: 0x55,
+       // Block 0x5, offset 0x140
+       0x140: 0x56, 0x142: 0x57, 0x144: 0x58, 0x145: 0x59, 0x146: 0x5a, 0x147: 0x5b,
+       0x14d: 0x5c,
+       0x15c: 0x5d, 0x15f: 0x5e,
+       0x162: 0x5f, 0x164: 0x60,
+       0x168: 0x61, 0x169: 0x62, 0x16a: 0x63, 0x16b: 0x64, 0x16c: 0x0e, 0x16d: 0x65, 0x16e: 0x66, 0x16f: 0x67,
+       0x170: 0x68, 0x173: 0x69, 0x177: 0x0f,
+       0x178: 0x10, 0x179: 0x11, 0x17a: 0x12, 0x17b: 0x13, 0x17c: 0x14, 0x17d: 0x15, 0x17e: 0x16, 0x17f: 0x17,
+       // Block 0x6, offset 0x180
+       0x180: 0x6a, 0x183: 0x6b, 0x184: 0x6c, 0x186: 0x6d, 0x187: 0x6e,
+       0x188: 0x6f, 0x189: 0x18, 0x18a: 0x19, 0x18b: 0x70, 0x18c: 0x71,
+       0x1ab: 0x72,
+       0x1b3: 0x73, 0x1b5: 0x74, 0x1b7: 0x75,
+       // Block 0x7, offset 0x1c0
+       0x1c0: 0x76, 0x1c1: 0x1a, 0x1c2: 0x1b, 0x1c3: 0x1c, 0x1c4: 0x77, 0x1c5: 0x78,
+       0x1c9: 0x79, 0x1cc: 0x7a, 0x1cd: 0x7b,
+       // Block 0x8, offset 0x200
+       0x219: 0x7c, 0x21a: 0x7d, 0x21b: 0x7e,
+       0x220: 0x7f, 0x223: 0x80, 0x224: 0x81, 0x225: 0x82, 0x226: 0x83, 0x227: 0x84,
+       0x22a: 0x85, 0x22b: 0x86, 0x22f: 0x87,
+       0x230: 0x88, 0x231: 0x89, 0x232: 0x8a, 0x233: 0x8b, 0x234: 0x8c, 0x235: 0x8d, 0x236: 0x8e, 0x237: 0x88,
+       0x238: 0x89, 0x239: 0x8a, 0x23a: 0x8b, 0x23b: 0x8c, 0x23c: 0x8d, 0x23d: 0x8e, 0x23e: 0x88, 0x23f: 0x89,
+       // Block 0x9, offset 0x240
+       0x240: 0x8a, 0x241: 0x8b, 0x242: 0x8c, 0x243: 0x8d, 0x244: 0x8e, 0x245: 0x88, 0x246: 0x89, 0x247: 0x8a,
+       0x248: 0x8b, 0x249: 0x8c, 0x24a: 0x8d, 0x24b: 0x8e, 0x24c: 0x88, 0x24d: 0x89, 0x24e: 0x8a, 0x24f: 0x8b,
+       0x250: 0x8c, 0x251: 0x8d, 0x252: 0x8e, 0x253: 0x88, 0x254: 0x89, 0x255: 0x8a, 0x256: 0x8b, 0x257: 0x8c,
+       0x258: 0x8d, 0x259: 0x8e, 0x25a: 0x88, 0x25b: 0x89, 0x25c: 0x8a, 0x25d: 0x8b, 0x25e: 0x8c, 0x25f: 0x8d,
+       0x260: 0x8e, 0x261: 0x88, 0x262: 0x89, 0x263: 0x8a, 0x264: 0x8b, 0x265: 0x8c, 0x266: 0x8d, 0x267: 0x8e,
+       0x268: 0x88, 0x269: 0x89, 0x26a: 0x8a, 0x26b: 0x8b, 0x26c: 0x8c, 0x26d: 0x8d, 0x26e: 0x8e, 0x26f: 0x88,
+       0x270: 0x89, 0x271: 0x8a, 0x272: 0x8b, 0x273: 0x8c, 0x274: 0x8d, 0x275: 0x8e, 0x276: 0x88, 0x277: 0x89,
+       0x278: 0x8a, 0x279: 0x8b, 0x27a: 0x8c, 0x27b: 0x8d, 0x27c: 0x8e, 0x27d: 0x88, 0x27e: 0x89, 0x27f: 0x8a,
+       // Block 0xa, offset 0x280
+       0x280: 0x8b, 0x281: 0x8c, 0x282: 0x8d, 0x283: 0x8e, 0x284: 0x88, 0x285: 0x89, 0x286: 0x8a, 0x287: 0x8b,
+       0x288: 0x8c, 0x289: 0x8d, 0x28a: 0x8e, 0x28b: 0x88, 0x28c: 0x89, 0x28d: 0x8a, 0x28e: 0x8b, 0x28f: 0x8c,
+       0x290: 0x8d, 0x291: 0x8e, 0x292: 0x88, 0x293: 0x89, 0x294: 0x8a, 0x295: 0x8b, 0x296: 0x8c, 0x297: 0x8d,
+       0x298: 0x8e, 0x299: 0x88, 0x29a: 0x89, 0x29b: 0x8a, 0x29c: 0x8b, 0x29d: 0x8c, 0x29e: 0x8d, 0x29f: 0x8e,
+       0x2a0: 0x88, 0x2a1: 0x89, 0x2a2: 0x8a, 0x2a3: 0x8b, 0x2a4: 0x8c, 0x2a5: 0x8d, 0x2a6: 0x8e, 0x2a7: 0x88,
+       0x2a8: 0x89, 0x2a9: 0x8a, 0x2aa: 0x8b, 0x2ab: 0x8c, 0x2ac: 0x8d, 0x2ad: 0x8e, 0x2ae: 0x88, 0x2af: 0x89,
+       0x2b0: 0x8a, 0x2b1: 0x8b, 0x2b2: 0x8c, 0x2b3: 0x8d, 0x2b4: 0x8e, 0x2b5: 0x88, 0x2b6: 0x89, 0x2b7: 0x8a,
+       0x2b8: 0x8b, 0x2b9: 0x8c, 0x2ba: 0x8d, 0x2bb: 0x8e, 0x2bc: 0x88, 0x2bd: 0x89, 0x2be: 0x8a, 0x2bf: 0x8b,
+       // Block 0xb, offset 0x2c0
+       0x2c0: 0x8c, 0x2c1: 0x8d, 0x2c2: 0x8e, 0x2c3: 0x88, 0x2c4: 0x89, 0x2c5: 0x8a, 0x2c6: 0x8b, 0x2c7: 0x8c,
+       0x2c8: 0x8d, 0x2c9: 0x8e, 0x2ca: 0x88, 0x2cb: 0x89, 0x2cc: 0x8a, 0x2cd: 0x8b, 0x2ce: 0x8c, 0x2cf: 0x8d,
+       0x2d0: 0x8e, 0x2d1: 0x88, 0x2d2: 0x89, 0x2d3: 0x8a, 0x2d4: 0x8b, 0x2d5: 0x8c, 0x2d6: 0x8d, 0x2d7: 0x8e,
+       0x2d8: 0x88, 0x2d9: 0x89, 0x2da: 0x8a, 0x2db: 0x8b, 0x2dc: 0x8c, 0x2dd: 0x8d, 0x2de: 0x8f,
+       // Block 0xc, offset 0x300
+       0x324: 0x1d, 0x325: 0x1e, 0x326: 0x1f, 0x327: 0x20,
+       0x328: 0x21, 0x329: 0x22, 0x32a: 0x23, 0x32b: 0x24, 0x32c: 0x90, 0x32d: 0x91, 0x32e: 0x92,
+       0x331: 0x93, 0x332: 0x94, 0x333: 0x95, 0x334: 0x96,
+       0x338: 0x97, 0x339: 0x98, 0x33a: 0x99, 0x33b: 0x9a, 0x33e: 0x9b, 0x33f: 0x9c,
+       // Block 0xd, offset 0x340
+       0x347: 0x9d,
+       0x34b: 0x9e, 0x34d: 0x9f,
+       0x368: 0xa0, 0x36b: 0xa1,
+       0x374: 0xa2,
+       0x37a: 0xa3, 0x37d: 0xa4,
+       // Block 0xe, offset 0x380
+       0x381: 0xa5, 0x382: 0xa6, 0x384: 0xa7, 0x385: 0x83, 0x387: 0xa8,
+       0x388: 0xa9, 0x38b: 0xaa, 0x38c: 0xab, 0x38d: 0xac,
+       0x391: 0xad, 0x392: 0xae, 0x393: 0xaf, 0x396: 0xb0, 0x397: 0xb1,
+       0x398: 0x74, 0x39a: 0xb2, 0x39c: 0xb3,
+       0x3a0: 0xb4, 0x3a4: 0xb5, 0x3a5: 0xb6, 0x3a7: 0xb7,
+       0x3a8: 0xb8, 0x3a9: 0xb9, 0x3aa: 0xba,
+       0x3b0: 0x74, 0x3b5: 0xbb, 0x3b6: 0xbc,
+       // Block 0xf, offset 0x3c0
+       0x3eb: 0xbd, 0x3ec: 0xbe,
+       0x3ff: 0xbf,
+       // Block 0x10, offset 0x400
+       0x432: 0xc0,
+       // Block 0x11, offset 0x440
+       0x445: 0xc1, 0x446: 0xc2, 0x447: 0xc3,
+       0x449: 0xc4,
+       // Block 0x12, offset 0x480
+       0x480: 0xc5, 0x484: 0xbe,
+       0x48b: 0xc6,
+       0x4a3: 0xc7, 0x4a5: 0xc8,
+       // Block 0x13, offset 0x4c0
+       0x4c8: 0xc9,
+       // Block 0x14, offset 0x500
+       0x520: 0x25, 0x521: 0x26, 0x522: 0x27, 0x523: 0x28, 0x524: 0x29, 0x525: 0x2a, 0x526: 0x2b, 0x527: 0x2c,
+       0x528: 0x2d,
+       // Block 0x15, offset 0x540
+       0x550: 0x0b, 0x551: 0x0c, 0x556: 0x0d,
+       0x55b: 0x0e, 0x55d: 0x0f, 0x55e: 0x10, 0x55f: 0x11,
+       0x56f: 0x12,
+}
+
+// nfcSparseOffset: 156 entries, 312 bytes
+var nfcSparseOffset = []uint16{0x0, 0x5, 0x9, 0xb, 0xd, 0x18, 0x28, 0x2a, 0x2f, 0x3a, 0x49, 0x56, 0x5e, 0x63, 0x68, 0x6a, 0x72, 0x79, 0x7c, 0x84, 0x88, 0x8c, 0x8e, 0x90, 0x99, 0x9d, 0xa4, 0xa9, 0xac, 0xb6, 0xb9, 0xc0, 0xc8, 0xcb, 0xcd, 0xd0, 0xd2, 0xd7, 0xe8, 0xf4, 0xf6, 0xfc, 0xfe, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10b, 0x10e, 0x110, 0x113, 0x116, 0x11a, 0x120, 0x122, 0x12b, 0x12d, 0x130, 0x132, 0x13d, 0x141, 0x14f, 0x152, 0x158, 0x15e, 0x169, 0x16d, 0x16f, 0x171, 0x173, 0x175, 0x177, 0x17d, 0x181, 0x183, 0x185, 0x18d, 0x191, 0x194, 0x196, 0x198, 0x19b, 0x19e, 0x1a0, 0x1a2, 0x1a4, 0x1a6, 0x1ac, 0x1af, 0x1b1, 0x1b8, 0x1be, 0x1c4, 0x1cc, 0x1d2, 0x1d8, 0x1de, 0x1e2, 0x1f0, 0x1f9, 0x1fc, 0x1ff, 0x201, 0x204, 0x206, 0x20a, 0x20f, 0x211, 0x213, 0x218, 0x21e, 0x220, 0x222, 0x224, 0x22a, 0x22d, 0x22f, 0x231, 0x237, 0x23a, 0x242, 0x249, 0x24c, 0x24f, 0x251, 0x254, 0x25c, 0x260, 0x267, 0x26a, 0x270, 0x272, 0x275, 0x277, 0x27a, 0x27f, 0x281, 0x283, 0x285, 0x287, 0x289, 0x28c, 0x28e, 0x290, 0x292, 0x294, 0x296, 0x2a3, 0x2ad, 0x2af, 0x2b1, 0x2b7, 0x2b9, 0x2bb, 0x2be}
+
+// nfcSparseValues: 704 entries, 2816 bytes
+var nfcSparseValues = [704]valueRange{
+       // Block 0x0, offset 0x0
+       {value: 0x0000, lo: 0x04},
+       {value: 0xa100, lo: 0xa8, hi: 0xa8},
+       {value: 0x8100, lo: 0xaf, hi: 0xaf},
+       {value: 0x8100, lo: 0xb4, hi: 0xb4},
+       {value: 0x8100, lo: 0xb8, hi: 0xb8},
+       // Block 0x1, offset 0x5
+       {value: 0x0091, lo: 0x03},
+       {value: 0x46f9, lo: 0xa0, hi: 0xa1},
+       {value: 0x472b, lo: 0xaf, hi: 0xb0},
+       {value: 0xa000, lo: 0xb7, hi: 0xb7},
+       // Block 0x2, offset 0x9
+       {value: 0x0000, lo: 0x01},
+       {value: 0xa000, lo: 0x92, hi: 0x92},
+       // Block 0x3, offset 0xb
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8100, lo: 0x98, hi: 0x9d},
+       // Block 0x4, offset 0xd
+       {value: 0x0006, lo: 0x0a},
+       {value: 0xa000, lo: 0x81, hi: 0x81},
+       {value: 0xa000, lo: 0x85, hi: 0x85},
+       {value: 0xa000, lo: 0x89, hi: 0x89},
+       {value: 0x4857, lo: 0x8a, hi: 0x8a},
+       {value: 0x4875, lo: 0x8b, hi: 0x8b},
+       {value: 0x36de, lo: 0x8c, hi: 0x8c},
+       {value: 0x36f6, lo: 0x8d, hi: 0x8d},
+       {value: 0x488d, lo: 0x8e, hi: 0x8e},
+       {value: 0xa000, lo: 0x92, hi: 0x92},
+       {value: 0x3714, lo: 0x93, hi: 0x94},
+       // Block 0x5, offset 0x18
+       {value: 0x0000, lo: 0x0f},
+       {value: 0xa000, lo: 0x83, hi: 0x83},
+       {value: 0xa000, lo: 0x87, hi: 0x87},
+       {value: 0xa000, lo: 0x8b, hi: 0x8b},
+       {value: 0xa000, lo: 0x8d, hi: 0x8d},
+       {value: 0x37bc, lo: 0x90, hi: 0x90},
+       {value: 0x37c8, lo: 0x91, hi: 0x91},
+       {value: 0x37b6, lo: 0x93, hi: 0x93},
+       {value: 0xa000, lo: 0x96, hi: 0x96},
+       {value: 0x382e, lo: 0x97, hi: 0x97},
+       {value: 0x37f8, lo: 0x9c, hi: 0x9c},
+       {value: 0x37e0, lo: 0x9d, hi: 0x9d},
+       {value: 0x380a, lo: 0x9e, hi: 0x9e},
+       {value: 0xa000, lo: 0xb4, hi: 0xb5},
+       {value: 0x3834, lo: 0xb6, hi: 0xb6},
+       {value: 0x383a, lo: 0xb7, hi: 0xb7},
+       // Block 0x6, offset 0x28
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0x83, hi: 0x87},
+       // Block 0x7, offset 0x2a
+       {value: 0x0001, lo: 0x04},
+       {value: 0x8114, lo: 0x81, hi: 0x82},
+       {value: 0x8133, lo: 0x84, hi: 0x84},
+       {value: 0x812e, lo: 0x85, hi: 0x85},
+       {value: 0x810e, lo: 0x87, hi: 0x87},
+       // Block 0x8, offset 0x2f
+       {value: 0x0000, lo: 0x0a},
+       {value: 0x8133, lo: 0x90, hi: 0x97},
+       {value: 0x811a, lo: 0x98, hi: 0x98},
+       {value: 0x811b, lo: 0x99, hi: 0x99},
+       {value: 0x811c, lo: 0x9a, hi: 0x9a},
+       {value: 0x3858, lo: 0xa2, hi: 0xa2},
+       {value: 0x385e, lo: 0xa3, hi: 0xa3},
+       {value: 0x386a, lo: 0xa4, hi: 0xa4},
+       {value: 0x3864, lo: 0xa5, hi: 0xa5},
+       {value: 0x3870, lo: 0xa6, hi: 0xa6},
+       {value: 0xa000, lo: 0xa7, hi: 0xa7},
+       // Block 0x9, offset 0x3a
+       {value: 0x0000, lo: 0x0e},
+       {value: 0x3882, lo: 0x80, hi: 0x80},
+       {value: 0xa000, lo: 0x81, hi: 0x81},
+       {value: 0x3876, lo: 0x82, hi: 0x82},
+       {value: 0xa000, lo: 0x92, hi: 0x92},
+       {value: 0x387c, lo: 0x93, hi: 0x93},
+       {value: 0xa000, lo: 0x95, hi: 0x95},
+       {value: 0x8133, lo: 0x96, hi: 0x9c},
+       {value: 0x8133, lo: 0x9f, hi: 0xa2},
+       {value: 0x812e, lo: 0xa3, hi: 0xa3},
+       {value: 0x8133, lo: 0xa4, hi: 0xa4},
+       {value: 0x8133, lo: 0xa7, hi: 0xa8},
+       {value: 0x812e, lo: 0xaa, hi: 0xaa},
+       {value: 0x8133, lo: 0xab, hi: 0xac},
+       {value: 0x812e, lo: 0xad, hi: 0xad},
+       // Block 0xa, offset 0x49
+       {value: 0x0000, lo: 0x0c},
+       {value: 0x8120, lo: 0x91, hi: 0x91},
+       {value: 0x8133, lo: 0xb0, hi: 0xb0},
+       {value: 0x812e, lo: 0xb1, hi: 0xb1},
+       {value: 0x8133, lo: 0xb2, hi: 0xb3},
+       {value: 0x812e, lo: 0xb4, hi: 0xb4},
+       {value: 0x8133, lo: 0xb5, hi: 0xb6},
+       {value: 0x812e, lo: 0xb7, hi: 0xb9},
+       {value: 0x8133, lo: 0xba, hi: 0xba},
+       {value: 0x812e, lo: 0xbb, hi: 0xbc},
+       {value: 0x8133, lo: 0xbd, hi: 0xbd},
+       {value: 0x812e, lo: 0xbe, hi: 0xbe},
+       {value: 0x8133, lo: 0xbf, hi: 0xbf},
+       // Block 0xb, offset 0x56
+       {value: 0x0005, lo: 0x07},
+       {value: 0x8133, lo: 0x80, hi: 0x80},
+       {value: 0x8133, lo: 0x81, hi: 0x81},
+       {value: 0x812e, lo: 0x82, hi: 0x83},
+       {value: 0x812e, lo: 0x84, hi: 0x85},
+       {value: 0x812e, lo: 0x86, hi: 0x87},
+       {value: 0x812e, lo: 0x88, hi: 0x89},
+       {value: 0x8133, lo: 0x8a, hi: 0x8a},
+       // Block 0xc, offset 0x5e
+       {value: 0x0000, lo: 0x04},
+       {value: 0x8133, lo: 0xab, hi: 0xb1},
+       {value: 0x812e, lo: 0xb2, hi: 0xb2},
+       {value: 0x8133, lo: 0xb3, hi: 0xb3},
+       {value: 0x812e, lo: 0xbd, hi: 0xbd},
+       // Block 0xd, offset 0x63
+       {value: 0x0000, lo: 0x04},
+       {value: 0x8133, lo: 0x96, hi: 0x99},
+       {value: 0x8133, lo: 0x9b, hi: 0xa3},
+       {value: 0x8133, lo: 0xa5, hi: 0xa7},
+       {value: 0x8133, lo: 0xa9, hi: 0xad},
+       // Block 0xe, offset 0x68
+       {value: 0x0000, lo: 0x01},
+       {value: 0x812e, lo: 0x99, hi: 0x9b},
+       // Block 0xf, offset 0x6a
+       {value: 0x0000, lo: 0x07},
+       {value: 0xa000, lo: 0xa8, hi: 0xa8},
+       {value: 0x3eef, lo: 0xa9, hi: 0xa9},
+       {value: 0xa000, lo: 0xb0, hi: 0xb0},
+       {value: 0x3ef7, lo: 0xb1, hi: 0xb1},
+       {value: 0xa000, lo: 0xb3, hi: 0xb3},
+       {value: 0x3eff, lo: 0xb4, hi: 0xb4},
+       {value: 0x9903, lo: 0xbc, hi: 0xbc},
+       // Block 0x10, offset 0x72
+       {value: 0x0008, lo: 0x06},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x8133, lo: 0x91, hi: 0x91},
+       {value: 0x812e, lo: 0x92, hi: 0x92},
+       {value: 0x8133, lo: 0x93, hi: 0x93},
+       {value: 0x8133, lo: 0x94, hi: 0x94},
+       {value: 0x4533, lo: 0x98, hi: 0x9f},
+       // Block 0x11, offset 0x79
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8103, lo: 0xbc, hi: 0xbc},
+       {value: 0x9900, lo: 0xbe, hi: 0xbe},
+       // Block 0x12, offset 0x7c
+       {value: 0x0008, lo: 0x07},
+       {value: 0xa000, lo: 0x87, hi: 0x87},
+       {value: 0x2cab, lo: 0x8b, hi: 0x8c},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x9900, lo: 0x97, hi: 0x97},
+       {value: 0x4573, lo: 0x9c, hi: 0x9d},
+       {value: 0x4583, lo: 0x9f, hi: 0x9f},
+       {value: 0x8133, lo: 0xbe, hi: 0xbe},
+       // Block 0x13, offset 0x84
+       {value: 0x0000, lo: 0x03},
+       {value: 0x45ab, lo: 0xb3, hi: 0xb3},
+       {value: 0x45b3, lo: 0xb6, hi: 0xb6},
+       {value: 0x8103, lo: 0xbc, hi: 0xbc},
+       // Block 0x14, offset 0x88
+       {value: 0x0008, lo: 0x03},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x458b, lo: 0x99, hi: 0x9b},
+       {value: 0x45a3, lo: 0x9e, hi: 0x9e},
+       // Block 0x15, offset 0x8c
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8103, lo: 0xbc, hi: 0xbc},
+       // Block 0x16, offset 0x8e
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       // Block 0x17, offset 0x90
+       {value: 0x0000, lo: 0x08},
+       {value: 0xa000, lo: 0x87, hi: 0x87},
+       {value: 0x2cc3, lo: 0x88, hi: 0x88},
+       {value: 0x2cbb, lo: 0x8b, hi: 0x8b},
+       {value: 0x2ccb, lo: 0x8c, hi: 0x8c},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x9900, lo: 0x96, hi: 0x97},
+       {value: 0x45bb, lo: 0x9c, hi: 0x9c},
+       {value: 0x45c3, lo: 0x9d, hi: 0x9d},
+       // Block 0x18, offset 0x99
+       {value: 0x0000, lo: 0x03},
+       {value: 0xa000, lo: 0x92, hi: 0x92},
+       {value: 0x2cd3, lo: 0x94, hi: 0x94},
+       {value: 0x9900, lo: 0xbe, hi: 0xbe},
+       // Block 0x19, offset 0x9d
+       {value: 0x0000, lo: 0x06},
+       {value: 0xa000, lo: 0x86, hi: 0x87},
+       {value: 0x2cdb, lo: 0x8a, hi: 0x8a},
+       {value: 0x2ceb, lo: 0x8b, hi: 0x8b},
+       {value: 0x2ce3, lo: 0x8c, hi: 0x8c},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x9900, lo: 0x97, hi: 0x97},
+       // Block 0x1a, offset 0xa4
+       {value: 0x1801, lo: 0x04},
+       {value: 0xa000, lo: 0x86, hi: 0x86},
+       {value: 0x3f07, lo: 0x88, hi: 0x88},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x8121, lo: 0x95, hi: 0x96},
+       // Block 0x1b, offset 0xa9
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8103, lo: 0xbc, hi: 0xbc},
+       {value: 0xa000, lo: 0xbf, hi: 0xbf},
+       // Block 0x1c, offset 0xac
+       {value: 0x0000, lo: 0x09},
+       {value: 0x2cf3, lo: 0x80, hi: 0x80},
+       {value: 0x9900, lo: 0x82, hi: 0x82},
+       {value: 0xa000, lo: 0x86, hi: 0x86},
+       {value: 0x2cfb, lo: 0x87, hi: 0x87},
+       {value: 0x2d03, lo: 0x88, hi: 0x88},
+       {value: 0x2f67, lo: 0x8a, hi: 0x8a},
+       {value: 0x2def, lo: 0x8b, hi: 0x8b},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x9900, lo: 0x95, hi: 0x96},
+       // Block 0x1d, offset 0xb6
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0xbb, hi: 0xbc},
+       {value: 0x9900, lo: 0xbe, hi: 0xbe},
+       // Block 0x1e, offset 0xb9
+       {value: 0x0000, lo: 0x06},
+       {value: 0xa000, lo: 0x86, hi: 0x87},
+       {value: 0x2d0b, lo: 0x8a, hi: 0x8a},
+       {value: 0x2d1b, lo: 0x8b, hi: 0x8b},
+       {value: 0x2d13, lo: 0x8c, hi: 0x8c},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x9900, lo: 0x97, hi: 0x97},
+       // Block 0x1f, offset 0xc0
+       {value: 0x6bdd, lo: 0x07},
+       {value: 0x9905, lo: 0x8a, hi: 0x8a},
+       {value: 0x9900, lo: 0x8f, hi: 0x8f},
+       {value: 0xa000, lo: 0x99, hi: 0x99},
+       {value: 0x3f0f, lo: 0x9a, hi: 0x9a},
+       {value: 0x2f6f, lo: 0x9c, hi: 0x9c},
+       {value: 0x2dfa, lo: 0x9d, hi: 0x9d},
+       {value: 0x2d23, lo: 0x9e, hi: 0x9f},
+       // Block 0x20, offset 0xc8
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8123, lo: 0xb8, hi: 0xb9},
+       {value: 0x8105, lo: 0xba, hi: 0xba},
+       // Block 0x21, offset 0xcb
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8124, lo: 0x88, hi: 0x8b},
+       // Block 0x22, offset 0xcd
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8125, lo: 0xb8, hi: 0xb9},
+       {value: 0x8105, lo: 0xba, hi: 0xba},
+       // Block 0x23, offset 0xd0
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8126, lo: 0x88, hi: 0x8b},
+       // Block 0x24, offset 0xd2
+       {value: 0x0000, lo: 0x04},
+       {value: 0x812e, lo: 0x98, hi: 0x99},
+       {value: 0x812e, lo: 0xb5, hi: 0xb5},
+       {value: 0x812e, lo: 0xb7, hi: 0xb7},
+       {value: 0x812c, lo: 0xb9, hi: 0xb9},
+       // Block 0x25, offset 0xd7
+       {value: 0x0000, lo: 0x10},
+       {value: 0x264a, lo: 0x83, hi: 0x83},
+       {value: 0x2651, lo: 0x8d, hi: 0x8d},
+       {value: 0x2658, lo: 0x92, hi: 0x92},
+       {value: 0x265f, lo: 0x97, hi: 0x97},
+       {value: 0x2666, lo: 0x9c, hi: 0x9c},
+       {value: 0x2643, lo: 0xa9, hi: 0xa9},
+       {value: 0x8127, lo: 0xb1, hi: 0xb1},
+       {value: 0x8128, lo: 0xb2, hi: 0xb2},
+       {value: 0x4a9b, lo: 0xb3, hi: 0xb3},
+       {value: 0x8129, lo: 0xb4, hi: 0xb4},
+       {value: 0x4aa4, lo: 0xb5, hi: 0xb5},
+       {value: 0x45cb, lo: 0xb6, hi: 0xb6},
+       {value: 0x8200, lo: 0xb7, hi: 0xb7},
+       {value: 0x45d3, lo: 0xb8, hi: 0xb8},
+       {value: 0x8200, lo: 0xb9, hi: 0xb9},
+       {value: 0x8128, lo: 0xba, hi: 0xbd},
+       // Block 0x26, offset 0xe8
+       {value: 0x0000, lo: 0x0b},
+       {value: 0x8128, lo: 0x80, hi: 0x80},
+       {value: 0x4aad, lo: 0x81, hi: 0x81},
+       {value: 0x8133, lo: 0x82, hi: 0x83},
+       {value: 0x8105, lo: 0x84, hi: 0x84},
+       {value: 0x8133, lo: 0x86, hi: 0x87},
+       {value: 0x2674, lo: 0x93, hi: 0x93},
+       {value: 0x267b, lo: 0x9d, hi: 0x9d},
+       {value: 0x2682, lo: 0xa2, hi: 0xa2},
+       {value: 0x2689, lo: 0xa7, hi: 0xa7},
+       {value: 0x2690, lo: 0xac, hi: 0xac},
+       {value: 0x266d, lo: 0xb9, hi: 0xb9},
+       // Block 0x27, offset 0xf4
+       {value: 0x0000, lo: 0x01},
+       {value: 0x812e, lo: 0x86, hi: 0x86},
+       // Block 0x28, offset 0xf6
+       {value: 0x0000, lo: 0x05},
+       {value: 0xa000, lo: 0xa5, hi: 0xa5},
+       {value: 0x2d2b, lo: 0xa6, hi: 0xa6},
+       {value: 0x9900, lo: 0xae, hi: 0xae},
+       {value: 0x8103, lo: 0xb7, hi: 0xb7},
+       {value: 0x8105, lo: 0xb9, hi: 0xba},
+       // Block 0x29, offset 0xfc
+       {value: 0x0000, lo: 0x01},
+       {value: 0x812e, lo: 0x8d, hi: 0x8d},
+       // Block 0x2a, offset 0xfe
+       {value: 0x0000, lo: 0x01},
+       {value: 0xa000, lo: 0x80, hi: 0x92},
+       // Block 0x2b, offset 0x100
+       {value: 0x0000, lo: 0x01},
+       {value: 0xb900, lo: 0xa1, hi: 0xb5},
+       // Block 0x2c, offset 0x102
+       {value: 0x0000, lo: 0x01},
+       {value: 0x9900, lo: 0xa8, hi: 0xbf},
+       // Block 0x2d, offset 0x104
+       {value: 0x0000, lo: 0x01},
+       {value: 0x9900, lo: 0x80, hi: 0x82},
+       // Block 0x2e, offset 0x106
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0x9d, hi: 0x9f},
+       // Block 0x2f, offset 0x108
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0x94, hi: 0x94},
+       {value: 0x8105, lo: 0xb4, hi: 0xb4},
+       // Block 0x30, offset 0x10b
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0x92, hi: 0x92},
+       {value: 0x8133, lo: 0x9d, hi: 0x9d},
+       // Block 0x31, offset 0x10e
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8132, lo: 0xa9, hi: 0xa9},
+       // Block 0x32, offset 0x110
+       {value: 0x0004, lo: 0x02},
+       {value: 0x812f, lo: 0xb9, hi: 0xba},
+       {value: 0x812e, lo: 0xbb, hi: 0xbb},
+       // Block 0x33, offset 0x113
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8133, lo: 0x97, hi: 0x97},
+       {value: 0x812e, lo: 0x98, hi: 0x98},
+       // Block 0x34, offset 0x116
+       {value: 0x0000, lo: 0x03},
+       {value: 0x8105, lo: 0xa0, hi: 0xa0},
+       {value: 0x8133, lo: 0xb5, hi: 0xbc},
+       {value: 0x812e, lo: 0xbf, hi: 0xbf},
+       // Block 0x35, offset 0x11a
+       {value: 0x0000, lo: 0x05},
+       {value: 0x8133, lo: 0xb0, hi: 0xb4},
+       {value: 0x812e, lo: 0xb5, hi: 0xba},
+       {value: 0x8133, lo: 0xbb, hi: 0xbc},
+       {value: 0x812e, lo: 0xbd, hi: 0xbd},
+       {value: 0x812e, lo: 0xbf, hi: 0xbf},
+       // Block 0x36, offset 0x120
+       {value: 0x0000, lo: 0x01},
+       {value: 0x812e, lo: 0x80, hi: 0x80},
+       // Block 0x37, offset 0x122
+       {value: 0x0000, lo: 0x08},
+       {value: 0x2d73, lo: 0x80, hi: 0x80},
+       {value: 0x2d7b, lo: 0x81, hi: 0x81},
+       {value: 0xa000, lo: 0x82, hi: 0x82},
+       {value: 0x2d83, lo: 0x83, hi: 0x83},
+       {value: 0x8105, lo: 0x84, hi: 0x84},
+       {value: 0x8133, lo: 0xab, hi: 0xab},
+       {value: 0x812e, lo: 0xac, hi: 0xac},
+       {value: 0x8133, lo: 0xad, hi: 0xb3},
+       // Block 0x38, offset 0x12b
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0xaa, hi: 0xab},
+       // Block 0x39, offset 0x12d
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8103, lo: 0xa6, hi: 0xa6},
+       {value: 0x8105, lo: 0xb2, hi: 0xb3},
+       // Block 0x3a, offset 0x130
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8103, lo: 0xb7, hi: 0xb7},
+       // Block 0x3b, offset 0x132
+       {value: 0x0000, lo: 0x0a},
+       {value: 0x8133, lo: 0x90, hi: 0x92},
+       {value: 0x8101, lo: 0x94, hi: 0x94},
+       {value: 0x812e, lo: 0x95, hi: 0x99},
+       {value: 0x8133, lo: 0x9a, hi: 0x9b},
+       {value: 0x812e, lo: 0x9c, hi: 0x9f},
+       {value: 0x8133, lo: 0xa0, hi: 0xa0},
+       {value: 0x8101, lo: 0xa2, hi: 0xa8},
+       {value: 0x812e, lo: 0xad, hi: 0xad},
+       {value: 0x8133, lo: 0xb4, hi: 0xb4},
+       {value: 0x8133, lo: 0xb8, hi: 0xb9},
+       // Block 0x3c, offset 0x13d
+       {value: 0x0004, lo: 0x03},
+       {value: 0x0436, lo: 0x80, hi: 0x81},
+       {value: 0x8100, lo: 0x97, hi: 0x97},
+       {value: 0x8100, lo: 0xbe, hi: 0xbe},
+       // Block 0x3d, offset 0x141
+       {value: 0x0000, lo: 0x0d},
+       {value: 0x8133, lo: 0x90, hi: 0x91},
+       {value: 0x8101, lo: 0x92, hi: 0x93},
+       {value: 0x8133, lo: 0x94, hi: 0x97},
+       {value: 0x8101, lo: 0x98, hi: 0x9a},
+       {value: 0x8133, lo: 0x9b, hi: 0x9c},
+       {value: 0x8133, lo: 0xa1, hi: 0xa1},
+       {value: 0x8101, lo: 0xa5, hi: 0xa6},
+       {value: 0x8133, lo: 0xa7, hi: 0xa7},
+       {value: 0x812e, lo: 0xa8, hi: 0xa8},
+       {value: 0x8133, lo: 0xa9, hi: 0xa9},
+       {value: 0x8101, lo: 0xaa, hi: 0xab},
+       {value: 0x812e, lo: 0xac, hi: 0xaf},
+       {value: 0x8133, lo: 0xb0, hi: 0xb0},
+       // Block 0x3e, offset 0x14f
+       {value: 0x4292, lo: 0x02},
+       {value: 0x01bb, lo: 0xa6, hi: 0xa6},
+       {value: 0x0057, lo: 0xaa, hi: 0xab},
+       // Block 0x3f, offset 0x152
+       {value: 0x0007, lo: 0x05},
+       {value: 0xa000, lo: 0x90, hi: 0x90},
+       {value: 0xa000, lo: 0x92, hi: 0x92},
+       {value: 0xa000, lo: 0x94, hi: 0x94},
+       {value: 0x3bd0, lo: 0x9a, hi: 0x9b},
+       {value: 0x3bde, lo: 0xae, hi: 0xae},
+       // Block 0x40, offset 0x158
+       {value: 0x000e, lo: 0x05},
+       {value: 0x3be5, lo: 0x8d, hi: 0x8e},
+       {value: 0x3bec, lo: 0x8f, hi: 0x8f},
+       {value: 0xa000, lo: 0x90, hi: 0x90},
+       {value: 0xa000, lo: 0x92, hi: 0x92},
+       {value: 0xa000, lo: 0x94, hi: 0x94},
+       // Block 0x41, offset 0x15e
+       {value: 0x63f1, lo: 0x0a},
+       {value: 0xa000, lo: 0x83, hi: 0x83},
+       {value: 0x3bfa, lo: 0x84, hi: 0x84},
+       {value: 0xa000, lo: 0x88, hi: 0x88},
+       {value: 0x3c01, lo: 0x89, hi: 0x89},
+       {value: 0xa000, lo: 0x8b, hi: 0x8b},
+       {value: 0x3c08, lo: 0x8c, hi: 0x8c},
+       {value: 0xa000, lo: 0xa3, hi: 0xa3},
+       {value: 0x3c0f, lo: 0xa4, hi: 0xa5},
+       {value: 0x3c16, lo: 0xa6, hi: 0xa6},
+       {value: 0xa000, lo: 0xbc, hi: 0xbc},
+       // Block 0x42, offset 0x169
+       {value: 0x0007, lo: 0x03},
+       {value: 0x3c7f, lo: 0xa0, hi: 0xa1},
+       {value: 0x3ca9, lo: 0xa2, hi: 0xa3},
+       {value: 0x3cd3, lo: 0xaa, hi: 0xad},
+       // Block 0x43, offset 0x16d
+       {value: 0x0004, lo: 0x01},
+       {value: 0x048e, lo: 0xa9, hi: 0xaa},
+       // Block 0x44, offset 0x16f
+       {value: 0x0000, lo: 0x01},
+       {value: 0x44f4, lo: 0x9c, hi: 0x9c},
+       // Block 0x45, offset 0x171
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0xaf, hi: 0xb1},
+       // Block 0x46, offset 0x173
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0xbf, hi: 0xbf},
+       // Block 0x47, offset 0x175
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0xa0, hi: 0xbf},
+       // Block 0x48, offset 0x177
+       {value: 0x0000, lo: 0x05},
+       {value: 0x812d, lo: 0xaa, hi: 0xaa},
+       {value: 0x8132, lo: 0xab, hi: 0xab},
+       {value: 0x8134, lo: 0xac, hi: 0xac},
+       {value: 0x812f, lo: 0xad, hi: 0xad},
+       {value: 0x8130, lo: 0xae, hi: 0xaf},
+       // Block 0x49, offset 0x17d
+       {value: 0x0000, lo: 0x03},
+       {value: 0x4ab6, lo: 0xb3, hi: 0xb3},
+       {value: 0x4ab6, lo: 0xb5, hi: 0xb6},
+       {value: 0x4ab6, lo: 0xba, hi: 0xbf},
+       // Block 0x4a, offset 0x181
+       {value: 0x0000, lo: 0x01},
+       {value: 0x4ab6, lo: 0x8f, hi: 0xa3},
+       // Block 0x4b, offset 0x183
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8100, lo: 0xae, hi: 0xbe},
+       // Block 0x4c, offset 0x185
+       {value: 0x0000, lo: 0x07},
+       {value: 0x8100, lo: 0x84, hi: 0x84},
+       {value: 0x8100, lo: 0x87, hi: 0x87},
+       {value: 0x8100, lo: 0x90, hi: 0x90},
+       {value: 0x8100, lo: 0x9e, hi: 0x9e},
+       {value: 0x8100, lo: 0xa1, hi: 0xa1},
+       {value: 0x8100, lo: 0xb2, hi: 0xb2},
+       {value: 0x8100, lo: 0xbb, hi: 0xbb},
+       // Block 0x4d, offset 0x18d
+       {value: 0x0000, lo: 0x03},
+       {value: 0x8100, lo: 0x80, hi: 0x80},
+       {value: 0x8100, lo: 0x8b, hi: 0x8b},
+       {value: 0x8100, lo: 0x8e, hi: 0x8e},
+       // Block 0x4e, offset 0x191
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8133, lo: 0xaf, hi: 0xaf},
+       {value: 0x8133, lo: 0xb4, hi: 0xbd},
+       // Block 0x4f, offset 0x194
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0x9e, hi: 0x9f},
+       // Block 0x50, offset 0x196
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0xb0, hi: 0xb1},
+       // Block 0x51, offset 0x198
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0x86, hi: 0x86},
+       {value: 0x8105, lo: 0xac, hi: 0xac},
+       // Block 0x52, offset 0x19b
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0x84, hi: 0x84},
+       {value: 0x8133, lo: 0xa0, hi: 0xb1},
+       // Block 0x53, offset 0x19e
+       {value: 0x0000, lo: 0x01},
+       {value: 0x812e, lo: 0xab, hi: 0xad},
+       // Block 0x54, offset 0x1a0
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0x93, hi: 0x93},
+       // Block 0x55, offset 0x1a2
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8103, lo: 0xb3, hi: 0xb3},
+       // Block 0x56, offset 0x1a4
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0x80, hi: 0x80},
+       // Block 0x57, offset 0x1a6
+       {value: 0x0000, lo: 0x05},
+       {value: 0x8133, lo: 0xb0, hi: 0xb0},
+       {value: 0x8133, lo: 0xb2, hi: 0xb3},
+       {value: 0x812e, lo: 0xb4, hi: 0xb4},
+       {value: 0x8133, lo: 0xb7, hi: 0xb8},
+       {value: 0x8133, lo: 0xbe, hi: 0xbf},
+       // Block 0x58, offset 0x1ac
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8133, lo: 0x81, hi: 0x81},
+       {value: 0x8105, lo: 0xb6, hi: 0xb6},
+       // Block 0x59, offset 0x1af
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0xad, hi: 0xad},
+       // Block 0x5a, offset 0x1b1
+       {value: 0x0000, lo: 0x06},
+       {value: 0xe500, lo: 0x80, hi: 0x80},
+       {value: 0xc600, lo: 0x81, hi: 0x9b},
+       {value: 0xe500, lo: 0x9c, hi: 0x9c},
+       {value: 0xc600, lo: 0x9d, hi: 0xb7},
+       {value: 0xe500, lo: 0xb8, hi: 0xb8},
+       {value: 0xc600, lo: 0xb9, hi: 0xbf},
+       // Block 0x5b, offset 0x1b8
+       {value: 0x0000, lo: 0x05},
+       {value: 0xc600, lo: 0x80, hi: 0x93},
+       {value: 0xe500, lo: 0x94, hi: 0x94},
+       {value: 0xc600, lo: 0x95, hi: 0xaf},
+       {value: 0xe500, lo: 0xb0, hi: 0xb0},
+       {value: 0xc600, lo: 0xb1, hi: 0xbf},
+       // Block 0x5c, offset 0x1be
+       {value: 0x0000, lo: 0x05},
+       {value: 0xc600, lo: 0x80, hi: 0x8b},
+       {value: 0xe500, lo: 0x8c, hi: 0x8c},
+       {value: 0xc600, lo: 0x8d, hi: 0xa7},
+       {value: 0xe500, lo: 0xa8, hi: 0xa8},
+       {value: 0xc600, lo: 0xa9, hi: 0xbf},
+       // Block 0x5d, offset 0x1c4
+       {value: 0x0000, lo: 0x07},
+       {value: 0xc600, lo: 0x80, hi: 0x83},
+       {value: 0xe500, lo: 0x84, hi: 0x84},
+       {value: 0xc600, lo: 0x85, hi: 0x9f},
+       {value: 0xe500, lo: 0xa0, hi: 0xa0},
+       {value: 0xc600, lo: 0xa1, hi: 0xbb},
+       {value: 0xe500, lo: 0xbc, hi: 0xbc},
+       {value: 0xc600, lo: 0xbd, hi: 0xbf},
+       // Block 0x5e, offset 0x1cc
+       {value: 0x0000, lo: 0x05},
+       {value: 0xc600, lo: 0x80, hi: 0x97},
+       {value: 0xe500, lo: 0x98, hi: 0x98},
+       {value: 0xc600, lo: 0x99, hi: 0xb3},
+       {value: 0xe500, lo: 0xb4, hi: 0xb4},
+       {value: 0xc600, lo: 0xb5, hi: 0xbf},
+       // Block 0x5f, offset 0x1d2
+       {value: 0x0000, lo: 0x05},
+       {value: 0xc600, lo: 0x80, hi: 0x8f},
+       {value: 0xe500, lo: 0x90, hi: 0x90},
+       {value: 0xc600, lo: 0x91, hi: 0xab},
+       {value: 0xe500, lo: 0xac, hi: 0xac},
+       {value: 0xc600, lo: 0xad, hi: 0xbf},
+       // Block 0x60, offset 0x1d8
+       {value: 0x0000, lo: 0x05},
+       {value: 0xc600, lo: 0x80, hi: 0x87},
+       {value: 0xe500, lo: 0x88, hi: 0x88},
+       {value: 0xc600, lo: 0x89, hi: 0xa3},
+       {value: 0xe500, lo: 0xa4, hi: 0xa4},
+       {value: 0xc600, lo: 0xa5, hi: 0xbf},
+       // Block 0x61, offset 0x1de
+       {value: 0x0000, lo: 0x03},
+       {value: 0xc600, lo: 0x80, hi: 0x87},
+       {value: 0xe500, lo: 0x88, hi: 0x88},
+       {value: 0xc600, lo: 0x89, hi: 0xa3},
+       // Block 0x62, offset 0x1e2
+       {value: 0x0006, lo: 0x0d},
+       {value: 0x43a7, lo: 0x9d, hi: 0x9d},
+       {value: 0x8116, lo: 0x9e, hi: 0x9e},
+       {value: 0x4419, lo: 0x9f, hi: 0x9f},
+       {value: 0x4407, lo: 0xaa, hi: 0xab},
+       {value: 0x450b, lo: 0xac, hi: 0xac},
+       {value: 0x4513, lo: 0xad, hi: 0xad},
+       {value: 0x435f, lo: 0xae, hi: 0xb1},
+       {value: 0x437d, lo: 0xb2, hi: 0xb4},
+       {value: 0x4395, lo: 0xb5, hi: 0xb6},
+       {value: 0x43a1, lo: 0xb8, hi: 0xb8},
+       {value: 0x43ad, lo: 0xb9, hi: 0xbb},
+       {value: 0x43c5, lo: 0xbc, hi: 0xbc},
+       {value: 0x43cb, lo: 0xbe, hi: 0xbe},
+       // Block 0x63, offset 0x1f0
+       {value: 0x0006, lo: 0x08},
+       {value: 0x43d1, lo: 0x80, hi: 0x81},
+       {value: 0x43dd, lo: 0x83, hi: 0x84},
+       {value: 0x43ef, lo: 0x86, hi: 0x89},
+       {value: 0x4413, lo: 0x8a, hi: 0x8a},
+       {value: 0x438f, lo: 0x8b, hi: 0x8b},
+       {value: 0x4377, lo: 0x8c, hi: 0x8c},
+       {value: 0x43bf, lo: 0x8d, hi: 0x8d},
+       {value: 0x43e9, lo: 0x8e, hi: 0x8e},
+       // Block 0x64, offset 0x1f9
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8100, lo: 0xa4, hi: 0xa5},
+       {value: 0x8100, lo: 0xb0, hi: 0xb1},
+       // Block 0x65, offset 0x1fc
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8100, lo: 0x9b, hi: 0x9d},
+       {value: 0x8200, lo: 0x9e, hi: 0xa3},
+       // Block 0x66, offset 0x1ff
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8100, lo: 0x90, hi: 0x90},
+       // Block 0x67, offset 0x201
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8100, lo: 0x99, hi: 0x99},
+       {value: 0x8200, lo: 0xb2, hi: 0xb4},
+       // Block 0x68, offset 0x204
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8100, lo: 0xbc, hi: 0xbd},
+       // Block 0x69, offset 0x206
+       {value: 0x0000, lo: 0x03},
+       {value: 0x8133, lo: 0xa0, hi: 0xa6},
+       {value: 0x812e, lo: 0xa7, hi: 0xad},
+       {value: 0x8133, lo: 0xae, hi: 0xaf},
+       // Block 0x6a, offset 0x20a
+       {value: 0x0000, lo: 0x04},
+       {value: 0x8100, lo: 0x89, hi: 0x8c},
+       {value: 0x8100, lo: 0xb0, hi: 0xb2},
+       {value: 0x8100, lo: 0xb4, hi: 0xb4},
+       {value: 0x8100, lo: 0xb6, hi: 0xbf},
+       // Block 0x6b, offset 0x20f
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8100, lo: 0x81, hi: 0x8c},
+       // Block 0x6c, offset 0x211
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8100, lo: 0xb5, hi: 0xba},
+       // Block 0x6d, offset 0x213
+       {value: 0x0000, lo: 0x04},
+       {value: 0x4ab6, lo: 0x9e, hi: 0x9f},
+       {value: 0x4ab6, lo: 0xa3, hi: 0xa3},
+       {value: 0x4ab6, lo: 0xa5, hi: 0xa6},
+       {value: 0x4ab6, lo: 0xaa, hi: 0xaf},
+       // Block 0x6e, offset 0x218
+       {value: 0x0000, lo: 0x05},
+       {value: 0x4ab6, lo: 0x82, hi: 0x87},
+       {value: 0x4ab6, lo: 0x8a, hi: 0x8f},
+       {value: 0x4ab6, lo: 0x92, hi: 0x97},
+       {value: 0x4ab6, lo: 0x9a, hi: 0x9c},
+       {value: 0x8100, lo: 0xa3, hi: 0xa3},
+       // Block 0x6f, offset 0x21e
+       {value: 0x0000, lo: 0x01},
+       {value: 0x812e, lo: 0xbd, hi: 0xbd},
+       // Block 0x70, offset 0x220
+       {value: 0x0000, lo: 0x01},
+       {value: 0x812e, lo: 0xa0, hi: 0xa0},
+       // Block 0x71, offset 0x222
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0xb6, hi: 0xba},
+       // Block 0x72, offset 0x224
+       {value: 0x002d, lo: 0x05},
+       {value: 0x812e, lo: 0x8d, hi: 0x8d},
+       {value: 0x8133, lo: 0x8f, hi: 0x8f},
+       {value: 0x8133, lo: 0xb8, hi: 0xb8},
+       {value: 0x8101, lo: 0xb9, hi: 0xba},
+       {value: 0x8105, lo: 0xbf, hi: 0xbf},
+       // Block 0x73, offset 0x22a
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8133, lo: 0xa5, hi: 0xa5},
+       {value: 0x812e, lo: 0xa6, hi: 0xa6},
+       // Block 0x74, offset 0x22d
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0xa4, hi: 0xa7},
+       // Block 0x75, offset 0x22f
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0xab, hi: 0xac},
+       // Block 0x76, offset 0x231
+       {value: 0x0000, lo: 0x05},
+       {value: 0x812e, lo: 0x86, hi: 0x87},
+       {value: 0x8133, lo: 0x88, hi: 0x8a},
+       {value: 0x812e, lo: 0x8b, hi: 0x8b},
+       {value: 0x8133, lo: 0x8c, hi: 0x8c},
+       {value: 0x812e, lo: 0x8d, hi: 0x90},
+       // Block 0x77, offset 0x237
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0x86, hi: 0x86},
+       {value: 0x8105, lo: 0xbf, hi: 0xbf},
+       // Block 0x78, offset 0x23a
+       {value: 0x17fe, lo: 0x07},
+       {value: 0xa000, lo: 0x99, hi: 0x99},
+       {value: 0x424f, lo: 0x9a, hi: 0x9a},
+       {value: 0xa000, lo: 0x9b, hi: 0x9b},
+       {value: 0x4259, lo: 0x9c, hi: 0x9c},
+       {value: 0xa000, lo: 0xa5, hi: 0xa5},
+       {value: 0x4263, lo: 0xab, hi: 0xab},
+       {value: 0x8105, lo: 0xb9, hi: 0xba},
+       // Block 0x79, offset 0x242
+       {value: 0x0000, lo: 0x06},
+       {value: 0x8133, lo: 0x80, hi: 0x82},
+       {value: 0x9900, lo: 0xa7, hi: 0xa7},
+       {value: 0x2d8b, lo: 0xae, hi: 0xae},
+       {value: 0x2d95, lo: 0xaf, hi: 0xaf},
+       {value: 0xa000, lo: 0xb1, hi: 0xb2},
+       {value: 0x8105, lo: 0xb3, hi: 0xb4},
+       // Block 0x7a, offset 0x249
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0x80, hi: 0x80},
+       {value: 0x8103, lo: 0x8a, hi: 0x8a},
+       // Block 0x7b, offset 0x24c
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0xb5, hi: 0xb5},
+       {value: 0x8103, lo: 0xb6, hi: 0xb6},
+       // Block 0x7c, offset 0x24f
+       {value: 0x0002, lo: 0x01},
+       {value: 0x8103, lo: 0xa9, hi: 0xaa},
+       // Block 0x7d, offset 0x251
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8103, lo: 0xbb, hi: 0xbc},
+       {value: 0x9900, lo: 0xbe, hi: 0xbe},
+       // Block 0x7e, offset 0x254
+       {value: 0x0000, lo: 0x07},
+       {value: 0xa000, lo: 0x87, hi: 0x87},
+       {value: 0x2d9f, lo: 0x8b, hi: 0x8b},
+       {value: 0x2da9, lo: 0x8c, hi: 0x8c},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x9900, lo: 0x97, hi: 0x97},
+       {value: 0x8133, lo: 0xa6, hi: 0xac},
+       {value: 0x8133, lo: 0xb0, hi: 0xb4},
+       // Block 0x7f, offset 0x25c
+       {value: 0x0000, lo: 0x03},
+       {value: 0x8105, lo: 0x82, hi: 0x82},
+       {value: 0x8103, lo: 0x86, hi: 0x86},
+       {value: 0x8133, lo: 0x9e, hi: 0x9e},
+       // Block 0x80, offset 0x260
+       {value: 0x6b4d, lo: 0x06},
+       {value: 0x9900, lo: 0xb0, hi: 0xb0},
+       {value: 0xa000, lo: 0xb9, hi: 0xb9},
+       {value: 0x9900, lo: 0xba, hi: 0xba},
+       {value: 0x2dbd, lo: 0xbb, hi: 0xbb},
+       {value: 0x2db3, lo: 0xbc, hi: 0xbd},
+       {value: 0x2dc7, lo: 0xbe, hi: 0xbe},
+       // Block 0x81, offset 0x267
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0x82, hi: 0x82},
+       {value: 0x8103, lo: 0x83, hi: 0x83},
+       // Block 0x82, offset 0x26a
+       {value: 0x0000, lo: 0x05},
+       {value: 0x9900, lo: 0xaf, hi: 0xaf},
+       {value: 0xa000, lo: 0xb8, hi: 0xb9},
+       {value: 0x2dd1, lo: 0xba, hi: 0xba},
+       {value: 0x2ddb, lo: 0xbb, hi: 0xbb},
+       {value: 0x8105, lo: 0xbf, hi: 0xbf},
+       // Block 0x83, offset 0x270
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8103, lo: 0x80, hi: 0x80},
+       // Block 0x84, offset 0x272
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0xb6, hi: 0xb6},
+       {value: 0x8103, lo: 0xb7, hi: 0xb7},
+       // Block 0x85, offset 0x275
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0xab, hi: 0xab},
+       // Block 0x86, offset 0x277
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0xb9, hi: 0xb9},
+       {value: 0x8103, lo: 0xba, hi: 0xba},
+       // Block 0x87, offset 0x27a
+       {value: 0x0000, lo: 0x04},
+       {value: 0x9900, lo: 0xb0, hi: 0xb0},
+       {value: 0xa000, lo: 0xb5, hi: 0xb5},
+       {value: 0x2de5, lo: 0xb8, hi: 0xb8},
+       {value: 0x8105, lo: 0xbd, hi: 0xbe},
+       // Block 0x88, offset 0x27f
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8103, lo: 0x83, hi: 0x83},
+       // Block 0x89, offset 0x281
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0xa0, hi: 0xa0},
+       // Block 0x8a, offset 0x283
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0xb4, hi: 0xb4},
+       // Block 0x8b, offset 0x285
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0x87, hi: 0x87},
+       // Block 0x8c, offset 0x287
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0x99, hi: 0x99},
+       // Block 0x8d, offset 0x289
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8103, lo: 0x82, hi: 0x82},
+       {value: 0x8105, lo: 0x84, hi: 0x85},
+       // Block 0x8e, offset 0x28c
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0x97, hi: 0x97},
+       // Block 0x8f, offset 0x28e
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8101, lo: 0xb0, hi: 0xb4},
+       // Block 0x90, offset 0x290
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0xb0, hi: 0xb6},
+       // Block 0x91, offset 0x292
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8102, lo: 0xb0, hi: 0xb1},
+       // Block 0x92, offset 0x294
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8101, lo: 0x9e, hi: 0x9e},
+       // Block 0x93, offset 0x296
+       {value: 0x0000, lo: 0x0c},
+       {value: 0x45e3, lo: 0x9e, hi: 0x9e},
+       {value: 0x45ed, lo: 0x9f, hi: 0x9f},
+       {value: 0x4621, lo: 0xa0, hi: 0xa0},
+       {value: 0x462f, lo: 0xa1, hi: 0xa1},
+       {value: 0x463d, lo: 0xa2, hi: 0xa2},
+       {value: 0x464b, lo: 0xa3, hi: 0xa3},
+       {value: 0x4659, lo: 0xa4, hi: 0xa4},
+       {value: 0x812c, lo: 0xa5, hi: 0xa6},
+       {value: 0x8101, lo: 0xa7, hi: 0xa9},
+       {value: 0x8131, lo: 0xad, hi: 0xad},
+       {value: 0x812c, lo: 0xae, hi: 0xb2},
+       {value: 0x812e, lo: 0xbb, hi: 0xbf},
+       // Block 0x94, offset 0x2a3
+       {value: 0x0000, lo: 0x09},
+       {value: 0x812e, lo: 0x80, hi: 0x82},
+       {value: 0x8133, lo: 0x85, hi: 0x89},
+       {value: 0x812e, lo: 0x8a, hi: 0x8b},
+       {value: 0x8133, lo: 0xaa, hi: 0xad},
+       {value: 0x45f7, lo: 0xbb, hi: 0xbb},
+       {value: 0x4601, lo: 0xbc, hi: 0xbc},
+       {value: 0x4667, lo: 0xbd, hi: 0xbd},
+       {value: 0x4683, lo: 0xbe, hi: 0xbe},
+       {value: 0x4675, lo: 0xbf, hi: 0xbf},
+       // Block 0x95, offset 0x2ad
+       {value: 0x0000, lo: 0x01},
+       {value: 0x4691, lo: 0x80, hi: 0x80},
+       // Block 0x96, offset 0x2af
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0x82, hi: 0x84},
+       // Block 0x97, offset 0x2b1
+       {value: 0x0000, lo: 0x05},
+       {value: 0x8133, lo: 0x80, hi: 0x86},
+       {value: 0x8133, lo: 0x88, hi: 0x98},
+       {value: 0x8133, lo: 0x9b, hi: 0xa1},
+       {value: 0x8133, lo: 0xa3, hi: 0xa4},
+       {value: 0x8133, lo: 0xa6, hi: 0xaa},
+       // Block 0x98, offset 0x2b7
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0xac, hi: 0xaf},
+       // Block 0x99, offset 0x2b9
+       {value: 0x0000, lo: 0x01},
+       {value: 0x812e, lo: 0x90, hi: 0x96},
+       // Block 0x9a, offset 0x2bb
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8133, lo: 0x84, hi: 0x89},
+       {value: 0x8103, lo: 0x8a, hi: 0x8a},
+       // Block 0x9b, offset 0x2be
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8100, lo: 0x93, hi: 0x93},
+}
+
+// lookup returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *nfkcTrie) lookup(s []byte) (v uint16, sz int) {
+       c0 := s[0]
+       switch {
+       case c0 < 0x80: // is ASCII
+               return nfkcValues[c0], 1
+       case c0 < 0xC2:
+               return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+       case c0 < 0xE0: // 2-byte UTF-8
+               if len(s) < 2 {
+                       return 0, 0
+               }
+               i := nfkcIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c1), 2
+       case c0 < 0xF0: // 3-byte UTF-8
+               if len(s) < 3 {
+                       return 0, 0
+               }
+               i := nfkcIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               o := uint32(i)<<6 + uint32(c1)
+               i = nfkcIndex[o]
+               c2 := s[2]
+               if c2 < 0x80 || 0xC0 <= c2 {
+                       return 0, 2 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c2), 3
+       case c0 < 0xF8: // 4-byte UTF-8
+               if len(s) < 4 {
+                       return 0, 0
+               }
+               i := nfkcIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               o := uint32(i)<<6 + uint32(c1)
+               i = nfkcIndex[o]
+               c2 := s[2]
+               if c2 < 0x80 || 0xC0 <= c2 {
+                       return 0, 2 // Illegal UTF-8: not a continuation byte.
+               }
+               o = uint32(i)<<6 + uint32(c2)
+               i = nfkcIndex[o]
+               c3 := s[3]
+               if c3 < 0x80 || 0xC0 <= c3 {
+                       return 0, 3 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c3), 4
+       }
+       // Illegal rune
+       return 0, 1
+}
+
+// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *nfkcTrie) lookupUnsafe(s []byte) uint16 {
+       c0 := s[0]
+       if c0 < 0x80 { // is ASCII
+               return nfkcValues[c0]
+       }
+       i := nfkcIndex[c0]
+       if c0 < 0xE0 { // 2-byte UTF-8
+               return t.lookupValue(uint32(i), s[1])
+       }
+       i = nfkcIndex[uint32(i)<<6+uint32(s[1])]
+       if c0 < 0xF0 { // 3-byte UTF-8
+               return t.lookupValue(uint32(i), s[2])
+       }
+       i = nfkcIndex[uint32(i)<<6+uint32(s[2])]
+       if c0 < 0xF8 { // 4-byte UTF-8
+               return t.lookupValue(uint32(i), s[3])
+       }
+       return 0
+}
+
+// lookupString returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *nfkcTrie) lookupString(s string) (v uint16, sz int) {
+       c0 := s[0]
+       switch {
+       case c0 < 0x80: // is ASCII
+               return nfkcValues[c0], 1
+       case c0 < 0xC2:
+               return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+       case c0 < 0xE0: // 2-byte UTF-8
+               if len(s) < 2 {
+                       return 0, 0
+               }
+               i := nfkcIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c1), 2
+       case c0 < 0xF0: // 3-byte UTF-8
+               if len(s) < 3 {
+                       return 0, 0
+               }
+               i := nfkcIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               o := uint32(i)<<6 + uint32(c1)
+               i = nfkcIndex[o]
+               c2 := s[2]
+               if c2 < 0x80 || 0xC0 <= c2 {
+                       return 0, 2 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c2), 3
+       case c0 < 0xF8: // 4-byte UTF-8
+               if len(s) < 4 {
+                       return 0, 0
+               }
+               i := nfkcIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               o := uint32(i)<<6 + uint32(c1)
+               i = nfkcIndex[o]
+               c2 := s[2]
+               if c2 < 0x80 || 0xC0 <= c2 {
+                       return 0, 2 // Illegal UTF-8: not a continuation byte.
+               }
+               o = uint32(i)<<6 + uint32(c2)
+               i = nfkcIndex[o]
+               c3 := s[3]
+               if c3 < 0x80 || 0xC0 <= c3 {
+                       return 0, 3 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c3), 4
+       }
+       // Illegal rune
+       return 0, 1
+}
+
+// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *nfkcTrie) lookupStringUnsafe(s string) uint16 {
+       c0 := s[0]
+       if c0 < 0x80 { // is ASCII
+               return nfkcValues[c0]
+       }
+       i := nfkcIndex[c0]
+       if c0 < 0xE0 { // 2-byte UTF-8
+               return t.lookupValue(uint32(i), s[1])
+       }
+       i = nfkcIndex[uint32(i)<<6+uint32(s[1])]
+       if c0 < 0xF0 { // 3-byte UTF-8
+               return t.lookupValue(uint32(i), s[2])
+       }
+       i = nfkcIndex[uint32(i)<<6+uint32(s[2])]
+       if c0 < 0xF8 { // 4-byte UTF-8
+               return t.lookupValue(uint32(i), s[3])
+       }
+       return 0
+}
+
+// nfkcTrie. Total size: 18768 bytes (18.33 KiB). Checksum: c51186dd2412943d.
+type nfkcTrie struct{}
+
+func newNfkcTrie(i int) *nfkcTrie {
+       return &nfkcTrie{}
+}
+
+// lookupValue determines the type of block n and looks up the value for b.
+func (t *nfkcTrie) lookupValue(n uint32, b byte) uint16 {
+       switch {
+       case n < 92:
+               return uint16(nfkcValues[n<<6+uint32(b)])
+       default:
+               n -= 92
+               return uint16(nfkcSparse.lookup(n, b))
+       }
+}
+
+// nfkcValues: 94 blocks, 6016 entries, 12032 bytes
+// The third block is the zero block.
+var nfkcValues = [6016]uint16{
+       // Block 0x0, offset 0x0
+       0x3c: 0xa000, 0x3d: 0xa000, 0x3e: 0xa000,
+       // Block 0x1, offset 0x40
+       0x41: 0xa000, 0x42: 0xa000, 0x43: 0xa000, 0x44: 0xa000, 0x45: 0xa000,
+       0x46: 0xa000, 0x47: 0xa000, 0x48: 0xa000, 0x49: 0xa000, 0x4a: 0xa000, 0x4b: 0xa000,
+       0x4c: 0xa000, 0x4d: 0xa000, 0x4e: 0xa000, 0x4f: 0xa000, 0x50: 0xa000,
+       0x52: 0xa000, 0x53: 0xa000, 0x54: 0xa000, 0x55: 0xa000, 0x56: 0xa000, 0x57: 0xa000,
+       0x58: 0xa000, 0x59: 0xa000, 0x5a: 0xa000,
+       0x61: 0xa000, 0x62: 0xa000, 0x63: 0xa000,
+       0x64: 0xa000, 0x65: 0xa000, 0x66: 0xa000, 0x67: 0xa000, 0x68: 0xa000, 0x69: 0xa000,
+       0x6a: 0xa000, 0x6b: 0xa000, 0x6c: 0xa000, 0x6d: 0xa000, 0x6e: 0xa000, 0x6f: 0xa000,
+       0x70: 0xa000, 0x72: 0xa000, 0x73: 0xa000, 0x74: 0xa000, 0x75: 0xa000,
+       0x76: 0xa000, 0x77: 0xa000, 0x78: 0xa000, 0x79: 0xa000, 0x7a: 0xa000,
+       // Block 0x2, offset 0x80
+       // Block 0x3, offset 0xc0
+       0xc0: 0x2f86, 0xc1: 0x2f8b, 0xc2: 0x469f, 0xc3: 0x2f90, 0xc4: 0x46ae, 0xc5: 0x46b3,
+       0xc6: 0xa000, 0xc7: 0x46bd, 0xc8: 0x2ff9, 0xc9: 0x2ffe, 0xca: 0x46c2, 0xcb: 0x3012,
+       0xcc: 0x3085, 0xcd: 0x308a, 0xce: 0x308f, 0xcf: 0x46d6, 0xd1: 0x311b,
+       0xd2: 0x313e, 0xd3: 0x3143, 0xd4: 0x46e0, 0xd5: 0x46e5, 0xd6: 0x46f4,
+       0xd8: 0xa000, 0xd9: 0x31ca, 0xda: 0x31cf, 0xdb: 0x31d4, 0xdc: 0x4726, 0xdd: 0x324c,
+       0xe0: 0x3292, 0xe1: 0x3297, 0xe2: 0x4730, 0xe3: 0x329c,
+       0xe4: 0x473f, 0xe5: 0x4744, 0xe6: 0xa000, 0xe7: 0x474e, 0xe8: 0x3305, 0xe9: 0x330a,
+       0xea: 0x4753, 0xeb: 0x331e, 0xec: 0x3396, 0xed: 0x339b, 0xee: 0x33a0, 0xef: 0x4767,
+       0xf1: 0x342c, 0xf2: 0x344f, 0xf3: 0x3454, 0xf4: 0x4771, 0xf5: 0x4776,
+       0xf6: 0x4785, 0xf8: 0xa000, 0xf9: 0x34e0, 0xfa: 0x34e5, 0xfb: 0x34ea,
+       0xfc: 0x47b7, 0xfd: 0x3567, 0xff: 0x3580,
+       // Block 0x4, offset 0x100
+       0x100: 0x2f95, 0x101: 0x32a1, 0x102: 0x46a4, 0x103: 0x4735, 0x104: 0x2fb3, 0x105: 0x32bf,
+       0x106: 0x2fc7, 0x107: 0x32d3, 0x108: 0x2fcc, 0x109: 0x32d8, 0x10a: 0x2fd1, 0x10b: 0x32dd,
+       0x10c: 0x2fd6, 0x10d: 0x32e2, 0x10e: 0x2fe0, 0x10f: 0x32ec,
+       0x112: 0x46c7, 0x113: 0x4758, 0x114: 0x3008, 0x115: 0x3314, 0x116: 0x300d, 0x117: 0x3319,
+       0x118: 0x302b, 0x119: 0x3337, 0x11a: 0x301c, 0x11b: 0x3328, 0x11c: 0x3044, 0x11d: 0x3350,
+       0x11e: 0x304e, 0x11f: 0x335a, 0x120: 0x3053, 0x121: 0x335f, 0x122: 0x305d, 0x123: 0x3369,
+       0x124: 0x3062, 0x125: 0x336e, 0x128: 0x3094, 0x129: 0x33a5,
+       0x12a: 0x3099, 0x12b: 0x33aa, 0x12c: 0x309e, 0x12d: 0x33af, 0x12e: 0x30c1, 0x12f: 0x33cd,
+       0x130: 0x30a3, 0x132: 0x1960, 0x133: 0x19ed, 0x134: 0x30cb, 0x135: 0x33d7,
+       0x136: 0x30df, 0x137: 0x33f0, 0x139: 0x30e9, 0x13a: 0x33fa, 0x13b: 0x30f3,
+       0x13c: 0x3404, 0x13d: 0x30ee, 0x13e: 0x33ff, 0x13f: 0x1bb2,
+       // Block 0x5, offset 0x140
+       0x140: 0x1c3a, 0x143: 0x3116, 0x144: 0x3427, 0x145: 0x312f,
+       0x146: 0x3440, 0x147: 0x3125, 0x148: 0x3436, 0x149: 0x1c62,
+       0x14c: 0x46ea, 0x14d: 0x477b, 0x14e: 0x3148, 0x14f: 0x3459, 0x150: 0x3152, 0x151: 0x3463,
+       0x154: 0x3170, 0x155: 0x3481, 0x156: 0x3189, 0x157: 0x349a,
+       0x158: 0x317a, 0x159: 0x348b, 0x15a: 0x470d, 0x15b: 0x479e, 0x15c: 0x3193, 0x15d: 0x34a4,
+       0x15e: 0x31a2, 0x15f: 0x34b3, 0x160: 0x4712, 0x161: 0x47a3, 0x162: 0x31bb, 0x163: 0x34d1,
+       0x164: 0x31ac, 0x165: 0x34c2, 0x168: 0x471c, 0x169: 0x47ad,
+       0x16a: 0x4721, 0x16b: 0x47b2, 0x16c: 0x31d9, 0x16d: 0x34ef, 0x16e: 0x31e3, 0x16f: 0x34f9,
+       0x170: 0x31e8, 0x171: 0x34fe, 0x172: 0x3206, 0x173: 0x351c, 0x174: 0x3229, 0x175: 0x353f,
+       0x176: 0x3251, 0x177: 0x356c, 0x178: 0x3265, 0x179: 0x3274, 0x17a: 0x3594, 0x17b: 0x327e,
+       0x17c: 0x359e, 0x17d: 0x3283, 0x17e: 0x35a3, 0x17f: 0x00a7,
+       // Block 0x6, offset 0x180
+       0x184: 0x2e05, 0x185: 0x2e0b,
+       0x186: 0x2e11, 0x187: 0x1975, 0x188: 0x1978, 0x189: 0x1a0e, 0x18a: 0x198d, 0x18b: 0x1990,
+       0x18c: 0x1a44, 0x18d: 0x2f9f, 0x18e: 0x32ab, 0x18f: 0x30ad, 0x190: 0x33b9, 0x191: 0x3157,
+       0x192: 0x3468, 0x193: 0x31ed, 0x194: 0x3503, 0x195: 0x39e6, 0x196: 0x3b75, 0x197: 0x39df,
+       0x198: 0x3b6e, 0x199: 0x39ed, 0x19a: 0x3b7c, 0x19b: 0x39d8, 0x19c: 0x3b67,
+       0x19e: 0x38c7, 0x19f: 0x3a56, 0x1a0: 0x38c0, 0x1a1: 0x3a4f, 0x1a2: 0x35ca, 0x1a3: 0x35dc,
+       0x1a6: 0x3058, 0x1a7: 0x3364, 0x1a8: 0x30d5, 0x1a9: 0x33e6,
+       0x1aa: 0x4703, 0x1ab: 0x4794, 0x1ac: 0x39a7, 0x1ad: 0x3b36, 0x1ae: 0x35ee, 0x1af: 0x35f4,
+       0x1b0: 0x33dc, 0x1b1: 0x1945, 0x1b2: 0x1948, 0x1b3: 0x19d5, 0x1b4: 0x303f, 0x1b5: 0x334b,
+       0x1b8: 0x3111, 0x1b9: 0x3422, 0x1ba: 0x38ce, 0x1bb: 0x3a5d,
+       0x1bc: 0x35c4, 0x1bd: 0x35d6, 0x1be: 0x35d0, 0x1bf: 0x35e2,
+       // Block 0x7, offset 0x1c0
+       0x1c0: 0x2fa4, 0x1c1: 0x32b0, 0x1c2: 0x2fa9, 0x1c3: 0x32b5, 0x1c4: 0x3021, 0x1c5: 0x332d,
+       0x1c6: 0x3026, 0x1c7: 0x3332, 0x1c8: 0x30b2, 0x1c9: 0x33be, 0x1ca: 0x30b7, 0x1cb: 0x33c3,
+       0x1cc: 0x315c, 0x1cd: 0x346d, 0x1ce: 0x3161, 0x1cf: 0x3472, 0x1d0: 0x317f, 0x1d1: 0x3490,
+       0x1d2: 0x3184, 0x1d3: 0x3495, 0x1d4: 0x31f2, 0x1d5: 0x3508, 0x1d6: 0x31f7, 0x1d7: 0x350d,
+       0x1d8: 0x319d, 0x1d9: 0x34ae, 0x1da: 0x31b6, 0x1db: 0x34cc,
+       0x1de: 0x3071, 0x1df: 0x337d,
+       0x1e6: 0x46a9, 0x1e7: 0x473a, 0x1e8: 0x46d1, 0x1e9: 0x4762,
+       0x1ea: 0x3976, 0x1eb: 0x3b05, 0x1ec: 0x3953, 0x1ed: 0x3ae2, 0x1ee: 0x46ef, 0x1ef: 0x4780,
+       0x1f0: 0x396f, 0x1f1: 0x3afe, 0x1f2: 0x325b, 0x1f3: 0x3576,
+       // Block 0x8, offset 0x200
+       0x200: 0x9933, 0x201: 0x9933, 0x202: 0x9933, 0x203: 0x9933, 0x204: 0x9933, 0x205: 0x8133,
+       0x206: 0x9933, 0x207: 0x9933, 0x208: 0x9933, 0x209: 0x9933, 0x20a: 0x9933, 0x20b: 0x9933,
+       0x20c: 0x9933, 0x20d: 0x8133, 0x20e: 0x8133, 0x20f: 0x9933, 0x210: 0x8133, 0x211: 0x9933,
+       0x212: 0x8133, 0x213: 0x9933, 0x214: 0x9933, 0x215: 0x8134, 0x216: 0x812e, 0x217: 0x812e,
+       0x218: 0x812e, 0x219: 0x812e, 0x21a: 0x8134, 0x21b: 0x992c, 0x21c: 0x812e, 0x21d: 0x812e,
+       0x21e: 0x812e, 0x21f: 0x812e, 0x220: 0x812e, 0x221: 0x812a, 0x222: 0x812a, 0x223: 0x992e,
+       0x224: 0x992e, 0x225: 0x992e, 0x226: 0x992e, 0x227: 0x992a, 0x228: 0x992a, 0x229: 0x812e,
+       0x22a: 0x812e, 0x22b: 0x812e, 0x22c: 0x812e, 0x22d: 0x992e, 0x22e: 0x992e, 0x22f: 0x812e,
+       0x230: 0x992e, 0x231: 0x992e, 0x232: 0x812e, 0x233: 0x812e, 0x234: 0x8101, 0x235: 0x8101,
+       0x236: 0x8101, 0x237: 0x8101, 0x238: 0x9901, 0x239: 0x812e, 0x23a: 0x812e, 0x23b: 0x812e,
+       0x23c: 0x812e, 0x23d: 0x8133, 0x23e: 0x8133, 0x23f: 0x8133,
+       // Block 0x9, offset 0x240
+       0x240: 0x49c5, 0x241: 0x49ca, 0x242: 0x9933, 0x243: 0x49cf, 0x244: 0x4a88, 0x245: 0x9937,
+       0x246: 0x8133, 0x247: 0x812e, 0x248: 0x812e, 0x249: 0x812e, 0x24a: 0x8133, 0x24b: 0x8133,
+       0x24c: 0x8133, 0x24d: 0x812e, 0x24e: 0x812e, 0x250: 0x8133, 0x251: 0x8133,
+       0x252: 0x8133, 0x253: 0x812e, 0x254: 0x812e, 0x255: 0x812e, 0x256: 0x812e, 0x257: 0x8133,
+       0x258: 0x8134, 0x259: 0x812e, 0x25a: 0x812e, 0x25b: 0x8133, 0x25c: 0x8135, 0x25d: 0x8136,
+       0x25e: 0x8136, 0x25f: 0x8135, 0x260: 0x8136, 0x261: 0x8136, 0x262: 0x8135, 0x263: 0x8133,
+       0x264: 0x8133, 0x265: 0x8133, 0x266: 0x8133, 0x267: 0x8133, 0x268: 0x8133, 0x269: 0x8133,
+       0x26a: 0x8133, 0x26b: 0x8133, 0x26c: 0x8133, 0x26d: 0x8133, 0x26e: 0x8133, 0x26f: 0x8133,
+       0x274: 0x0173,
+       0x27a: 0x42bc,
+       0x27e: 0x0037,
+       // Block 0xa, offset 0x280
+       0x284: 0x4271, 0x285: 0x4492,
+       0x286: 0x3600, 0x287: 0x00ce, 0x288: 0x361e, 0x289: 0x362a, 0x28a: 0x363c,
+       0x28c: 0x365a, 0x28e: 0x366c, 0x28f: 0x368a, 0x290: 0x3e1f, 0x291: 0xa000,
+       0x295: 0xa000, 0x297: 0xa000,
+       0x299: 0xa000,
+       0x29f: 0xa000, 0x2a1: 0xa000,
+       0x2a5: 0xa000, 0x2a9: 0xa000,
+       0x2aa: 0x364e, 0x2ab: 0x367e, 0x2ac: 0x4815, 0x2ad: 0x36ae, 0x2ae: 0x483f, 0x2af: 0x36c0,
+       0x2b0: 0x3e87, 0x2b1: 0xa000, 0x2b5: 0xa000,
+       0x2b7: 0xa000, 0x2b9: 0xa000,
+       0x2bf: 0xa000,
+       // Block 0xb, offset 0x2c0
+       0x2c1: 0xa000, 0x2c5: 0xa000,
+       0x2c9: 0xa000, 0x2ca: 0x4857, 0x2cb: 0x4875,
+       0x2cc: 0x36de, 0x2cd: 0x36f6, 0x2ce: 0x488d, 0x2d0: 0x01c1, 0x2d1: 0x01d3,
+       0x2d2: 0x01af, 0x2d3: 0x4323, 0x2d4: 0x4329, 0x2d5: 0x01fd, 0x2d6: 0x01eb,
+       0x2f0: 0x01d9, 0x2f1: 0x01ee, 0x2f2: 0x01f1, 0x2f4: 0x018b, 0x2f5: 0x01ca,
+       0x2f9: 0x01a9,
+       // Block 0xc, offset 0x300
+       0x300: 0x3738, 0x301: 0x3744, 0x303: 0x3732,
+       0x306: 0xa000, 0x307: 0x3720,
+       0x30c: 0x3774, 0x30d: 0x375c, 0x30e: 0x3786, 0x310: 0xa000,
+       0x313: 0xa000, 0x315: 0xa000, 0x316: 0xa000, 0x317: 0xa000,
+       0x318: 0xa000, 0x319: 0x3768, 0x31a: 0xa000,
+       0x31e: 0xa000, 0x323: 0xa000,
+       0x327: 0xa000,
+       0x32b: 0xa000, 0x32d: 0xa000,
+       0x330: 0xa000, 0x333: 0xa000, 0x335: 0xa000,
+       0x336: 0xa000, 0x337: 0xa000, 0x338: 0xa000, 0x339: 0x37ec, 0x33a: 0xa000,
+       0x33e: 0xa000,
+       // Block 0xd, offset 0x340
+       0x341: 0x374a, 0x342: 0x37ce,
+       0x350: 0x3726, 0x351: 0x37aa,
+       0x352: 0x372c, 0x353: 0x37b0, 0x356: 0x373e, 0x357: 0x37c2,
+       0x358: 0xa000, 0x359: 0xa000, 0x35a: 0x3840, 0x35b: 0x3846, 0x35c: 0x3750, 0x35d: 0x37d4,
+       0x35e: 0x3756, 0x35f: 0x37da, 0x362: 0x3762, 0x363: 0x37e6,
+       0x364: 0x376e, 0x365: 0x37f2, 0x366: 0x377a, 0x367: 0x37fe, 0x368: 0xa000, 0x369: 0xa000,
+       0x36a: 0x384c, 0x36b: 0x3852, 0x36c: 0x37a4, 0x36d: 0x3828, 0x36e: 0x3780, 0x36f: 0x3804,
+       0x370: 0x378c, 0x371: 0x3810, 0x372: 0x3792, 0x373: 0x3816, 0x374: 0x3798, 0x375: 0x381c,
+       0x378: 0x379e, 0x379: 0x3822,
+       // Block 0xe, offset 0x380
+       0x387: 0x1d67,
+       0x391: 0x812e,
+       0x392: 0x8133, 0x393: 0x8133, 0x394: 0x8133, 0x395: 0x8133, 0x396: 0x812e, 0x397: 0x8133,
+       0x398: 0x8133, 0x399: 0x8133, 0x39a: 0x812f, 0x39b: 0x812e, 0x39c: 0x8133, 0x39d: 0x8133,
+       0x39e: 0x8133, 0x39f: 0x8133, 0x3a0: 0x8133, 0x3a1: 0x8133, 0x3a2: 0x812e, 0x3a3: 0x812e,
+       0x3a4: 0x812e, 0x3a5: 0x812e, 0x3a6: 0x812e, 0x3a7: 0x812e, 0x3a8: 0x8133, 0x3a9: 0x8133,
+       0x3aa: 0x812e, 0x3ab: 0x8133, 0x3ac: 0x8133, 0x3ad: 0x812f, 0x3ae: 0x8132, 0x3af: 0x8133,
+       0x3b0: 0x8106, 0x3b1: 0x8107, 0x3b2: 0x8108, 0x3b3: 0x8109, 0x3b4: 0x810a, 0x3b5: 0x810b,
+       0x3b6: 0x810c, 0x3b7: 0x810d, 0x3b8: 0x810e, 0x3b9: 0x810f, 0x3ba: 0x810f, 0x3bb: 0x8110,
+       0x3bc: 0x8111, 0x3bd: 0x8112, 0x3bf: 0x8113,
+       // Block 0xf, offset 0x3c0
+       0x3c8: 0xa000, 0x3ca: 0xa000, 0x3cb: 0x8117,
+       0x3cc: 0x8118, 0x3cd: 0x8119, 0x3ce: 0x811a, 0x3cf: 0x811b, 0x3d0: 0x811c, 0x3d1: 0x811d,
+       0x3d2: 0x811e, 0x3d3: 0x9933, 0x3d4: 0x9933, 0x3d5: 0x992e, 0x3d6: 0x812e, 0x3d7: 0x8133,
+       0x3d8: 0x8133, 0x3d9: 0x8133, 0x3da: 0x8133, 0x3db: 0x8133, 0x3dc: 0x812e, 0x3dd: 0x8133,
+       0x3de: 0x8133, 0x3df: 0x812e,
+       0x3f0: 0x811f, 0x3f5: 0x1d8a,
+       0x3f6: 0x2019, 0x3f7: 0x2055, 0x3f8: 0x2050,
+       // Block 0x10, offset 0x400
+       0x413: 0x812e, 0x414: 0x8133, 0x415: 0x8133, 0x416: 0x8133, 0x417: 0x8133,
+       0x418: 0x8133, 0x419: 0x8133, 0x41a: 0x8133, 0x41b: 0x8133, 0x41c: 0x8133, 0x41d: 0x8133,
+       0x41e: 0x8133, 0x41f: 0x8133, 0x420: 0x8133, 0x421: 0x8133, 0x423: 0x812e,
+       0x424: 0x8133, 0x425: 0x8133, 0x426: 0x812e, 0x427: 0x8133, 0x428: 0x8133, 0x429: 0x812e,
+       0x42a: 0x8133, 0x42b: 0x8133, 0x42c: 0x8133, 0x42d: 0x812e, 0x42e: 0x812e, 0x42f: 0x812e,
+       0x430: 0x8117, 0x431: 0x8118, 0x432: 0x8119, 0x433: 0x8133, 0x434: 0x8133, 0x435: 0x8133,
+       0x436: 0x812e, 0x437: 0x8133, 0x438: 0x8133, 0x439: 0x812e, 0x43a: 0x812e, 0x43b: 0x8133,
+       0x43c: 0x8133, 0x43d: 0x8133, 0x43e: 0x8133, 0x43f: 0x8133,
+       // Block 0x11, offset 0x440
+       0x445: 0xa000,
+       0x446: 0x2d33, 0x447: 0xa000, 0x448: 0x2d3b, 0x449: 0xa000, 0x44a: 0x2d43, 0x44b: 0xa000,
+       0x44c: 0x2d4b, 0x44d: 0xa000, 0x44e: 0x2d53, 0x451: 0xa000,
+       0x452: 0x2d5b,
+       0x474: 0x8103, 0x475: 0x9900,
+       0x47a: 0xa000, 0x47b: 0x2d63,
+       0x47c: 0xa000, 0x47d: 0x2d6b, 0x47e: 0xa000, 0x47f: 0xa000,
+       // Block 0x12, offset 0x480
+       0x480: 0x0069, 0x481: 0x006b, 0x482: 0x006f, 0x483: 0x0083, 0x484: 0x00f5, 0x485: 0x00f8,
+       0x486: 0x0416, 0x487: 0x0085, 0x488: 0x0089, 0x489: 0x008b, 0x48a: 0x0104, 0x48b: 0x0107,
+       0x48c: 0x010a, 0x48d: 0x008f, 0x48f: 0x0097, 0x490: 0x009b, 0x491: 0x00e0,
+       0x492: 0x009f, 0x493: 0x00fe, 0x494: 0x041a, 0x495: 0x041e, 0x496: 0x00a1, 0x497: 0x00a9,
+       0x498: 0x00ab, 0x499: 0x0426, 0x49a: 0x012b, 0x49b: 0x00ad, 0x49c: 0x042a, 0x49d: 0x01c1,
+       0x49e: 0x01c4, 0x49f: 0x01c7, 0x4a0: 0x01fd, 0x4a1: 0x0200, 0x4a2: 0x0093, 0x4a3: 0x00a5,
+       0x4a4: 0x00ab, 0x4a5: 0x00ad, 0x4a6: 0x01c1, 0x4a7: 0x01c4, 0x4a8: 0x01ee, 0x4a9: 0x01fd,
+       0x4aa: 0x0200,
+       0x4b8: 0x020f,
+       // Block 0x13, offset 0x4c0
+       0x4db: 0x00fb, 0x4dc: 0x0087, 0x4dd: 0x0101,
+       0x4de: 0x00d4, 0x4df: 0x010a, 0x4e0: 0x008d, 0x4e1: 0x010d, 0x4e2: 0x0110, 0x4e3: 0x0116,
+       0x4e4: 0x011c, 0x4e5: 0x011f, 0x4e6: 0x0122, 0x4e7: 0x042e, 0x4e8: 0x016d, 0x4e9: 0x0128,
+       0x4ea: 0x0432, 0x4eb: 0x0170, 0x4ec: 0x0131, 0x4ed: 0x012e, 0x4ee: 0x0134, 0x4ef: 0x0137,
+       0x4f0: 0x013a, 0x4f1: 0x013d, 0x4f2: 0x0140, 0x4f3: 0x014c, 0x4f4: 0x014f, 0x4f5: 0x00ec,
+       0x4f6: 0x0152, 0x4f7: 0x0155, 0x4f8: 0x0422, 0x4f9: 0x0158, 0x4fa: 0x015b, 0x4fb: 0x00b5,
+       0x4fc: 0x0161, 0x4fd: 0x0164, 0x4fe: 0x0167, 0x4ff: 0x01d3,
+       // Block 0x14, offset 0x500
+       0x500: 0x8133, 0x501: 0x8133, 0x502: 0x812e, 0x503: 0x8133, 0x504: 0x8133, 0x505: 0x8133,
+       0x506: 0x8133, 0x507: 0x8133, 0x508: 0x8133, 0x509: 0x8133, 0x50a: 0x812e, 0x50b: 0x8133,
+       0x50c: 0x8133, 0x50d: 0x8136, 0x50e: 0x812b, 0x50f: 0x812e, 0x510: 0x812a, 0x511: 0x8133,
+       0x512: 0x8133, 0x513: 0x8133, 0x514: 0x8133, 0x515: 0x8133, 0x516: 0x8133, 0x517: 0x8133,
+       0x518: 0x8133, 0x519: 0x8133, 0x51a: 0x8133, 0x51b: 0x8133, 0x51c: 0x8133, 0x51d: 0x8133,
+       0x51e: 0x8133, 0x51f: 0x8133, 0x520: 0x8133, 0x521: 0x8133, 0x522: 0x8133, 0x523: 0x8133,
+       0x524: 0x8133, 0x525: 0x8133, 0x526: 0x8133, 0x527: 0x8133, 0x528: 0x8133, 0x529: 0x8133,
+       0x52a: 0x8133, 0x52b: 0x8133, 0x52c: 0x8133, 0x52d: 0x8133, 0x52e: 0x8133, 0x52f: 0x8133,
+       0x530: 0x8133, 0x531: 0x8133, 0x532: 0x8133, 0x533: 0x8133, 0x534: 0x8133, 0x535: 0x8133,
+       0x536: 0x8134, 0x537: 0x8132, 0x538: 0x8132, 0x539: 0x812e, 0x53b: 0x8133,
+       0x53c: 0x8135, 0x53d: 0x812e, 0x53e: 0x8133, 0x53f: 0x812e,
+       // Block 0x15, offset 0x540
+       0x540: 0x2fae, 0x541: 0x32ba, 0x542: 0x2fb8, 0x543: 0x32c4, 0x544: 0x2fbd, 0x545: 0x32c9,
+       0x546: 0x2fc2, 0x547: 0x32ce, 0x548: 0x38e3, 0x549: 0x3a72, 0x54a: 0x2fdb, 0x54b: 0x32e7,
+       0x54c: 0x2fe5, 0x54d: 0x32f1, 0x54e: 0x2ff4, 0x54f: 0x3300, 0x550: 0x2fea, 0x551: 0x32f6,
+       0x552: 0x2fef, 0x553: 0x32fb, 0x554: 0x3906, 0x555: 0x3a95, 0x556: 0x390d, 0x557: 0x3a9c,
+       0x558: 0x3030, 0x559: 0x333c, 0x55a: 0x3035, 0x55b: 0x3341, 0x55c: 0x391b, 0x55d: 0x3aaa,
+       0x55e: 0x303a, 0x55f: 0x3346, 0x560: 0x3049, 0x561: 0x3355, 0x562: 0x3067, 0x563: 0x3373,
+       0x564: 0x3076, 0x565: 0x3382, 0x566: 0x306c, 0x567: 0x3378, 0x568: 0x307b, 0x569: 0x3387,
+       0x56a: 0x3080, 0x56b: 0x338c, 0x56c: 0x30c6, 0x56d: 0x33d2, 0x56e: 0x3922, 0x56f: 0x3ab1,
+       0x570: 0x30d0, 0x571: 0x33e1, 0x572: 0x30da, 0x573: 0x33eb, 0x574: 0x30e4, 0x575: 0x33f5,
+       0x576: 0x46db, 0x577: 0x476c, 0x578: 0x3929, 0x579: 0x3ab8, 0x57a: 0x30fd, 0x57b: 0x340e,
+       0x57c: 0x30f8, 0x57d: 0x3409, 0x57e: 0x3102, 0x57f: 0x3413,
+       // Block 0x16, offset 0x580
+       0x580: 0x3107, 0x581: 0x3418, 0x582: 0x310c, 0x583: 0x341d, 0x584: 0x3120, 0x585: 0x3431,
+       0x586: 0x312a, 0x587: 0x343b, 0x588: 0x3139, 0x589: 0x344a, 0x58a: 0x3134, 0x58b: 0x3445,
+       0x58c: 0x394c, 0x58d: 0x3adb, 0x58e: 0x395a, 0x58f: 0x3ae9, 0x590: 0x3961, 0x591: 0x3af0,
+       0x592: 0x3968, 0x593: 0x3af7, 0x594: 0x3166, 0x595: 0x3477, 0x596: 0x316b, 0x597: 0x347c,
+       0x598: 0x3175, 0x599: 0x3486, 0x59a: 0x4708, 0x59b: 0x4799, 0x59c: 0x39ae, 0x59d: 0x3b3d,
+       0x59e: 0x318e, 0x59f: 0x349f, 0x5a0: 0x3198, 0x5a1: 0x34a9, 0x5a2: 0x4717, 0x5a3: 0x47a8,
+       0x5a4: 0x39b5, 0x5a5: 0x3b44, 0x5a6: 0x39bc, 0x5a7: 0x3b4b, 0x5a8: 0x39c3, 0x5a9: 0x3b52,
+       0x5aa: 0x31a7, 0x5ab: 0x34b8, 0x5ac: 0x31b1, 0x5ad: 0x34c7, 0x5ae: 0x31c5, 0x5af: 0x34db,
+       0x5b0: 0x31c0, 0x5b1: 0x34d6, 0x5b2: 0x3201, 0x5b3: 0x3517, 0x5b4: 0x3210, 0x5b5: 0x3526,
+       0x5b6: 0x320b, 0x5b7: 0x3521, 0x5b8: 0x39ca, 0x5b9: 0x3b59, 0x5ba: 0x39d1, 0x5bb: 0x3b60,
+       0x5bc: 0x3215, 0x5bd: 0x352b, 0x5be: 0x321a, 0x5bf: 0x3530,
+       // Block 0x17, offset 0x5c0
+       0x5c0: 0x321f, 0x5c1: 0x3535, 0x5c2: 0x3224, 0x5c3: 0x353a, 0x5c4: 0x3233, 0x5c5: 0x3549,
+       0x5c6: 0x322e, 0x5c7: 0x3544, 0x5c8: 0x3238, 0x5c9: 0x3553, 0x5ca: 0x323d, 0x5cb: 0x3558,
+       0x5cc: 0x3242, 0x5cd: 0x355d, 0x5ce: 0x3260, 0x5cf: 0x357b, 0x5d0: 0x3279, 0x5d1: 0x3599,
+       0x5d2: 0x3288, 0x5d3: 0x35a8, 0x5d4: 0x328d, 0x5d5: 0x35ad, 0x5d6: 0x3391, 0x5d7: 0x34bd,
+       0x5d8: 0x354e, 0x5d9: 0x358a, 0x5da: 0x1be6, 0x5db: 0x42ee,
+       0x5e0: 0x46b8, 0x5e1: 0x4749, 0x5e2: 0x2f9a, 0x5e3: 0x32a6,
+       0x5e4: 0x388f, 0x5e5: 0x3a1e, 0x5e6: 0x3888, 0x5e7: 0x3a17, 0x5e8: 0x389d, 0x5e9: 0x3a2c,
+       0x5ea: 0x3896, 0x5eb: 0x3a25, 0x5ec: 0x38d5, 0x5ed: 0x3a64, 0x5ee: 0x38ab, 0x5ef: 0x3a3a,
+       0x5f0: 0x38a4, 0x5f1: 0x3a33, 0x5f2: 0x38b9, 0x5f3: 0x3a48, 0x5f4: 0x38b2, 0x5f5: 0x3a41,
+       0x5f6: 0x38dc, 0x5f7: 0x3a6b, 0x5f8: 0x46cc, 0x5f9: 0x475d, 0x5fa: 0x3017, 0x5fb: 0x3323,
+       0x5fc: 0x3003, 0x5fd: 0x330f, 0x5fe: 0x38f1, 0x5ff: 0x3a80,
+       // Block 0x18, offset 0x600
+       0x600: 0x38ea, 0x601: 0x3a79, 0x602: 0x38ff, 0x603: 0x3a8e, 0x604: 0x38f8, 0x605: 0x3a87,
+       0x606: 0x3914, 0x607: 0x3aa3, 0x608: 0x30a8, 0x609: 0x33b4, 0x60a: 0x30bc, 0x60b: 0x33c8,
+       0x60c: 0x46fe, 0x60d: 0x478f, 0x60e: 0x314d, 0x60f: 0x345e, 0x610: 0x3937, 0x611: 0x3ac6,
+       0x612: 0x3930, 0x613: 0x3abf, 0x614: 0x3945, 0x615: 0x3ad4, 0x616: 0x393e, 0x617: 0x3acd,
+       0x618: 0x39a0, 0x619: 0x3b2f, 0x61a: 0x3984, 0x61b: 0x3b13, 0x61c: 0x397d, 0x61d: 0x3b0c,
+       0x61e: 0x3992, 0x61f: 0x3b21, 0x620: 0x398b, 0x621: 0x3b1a, 0x622: 0x3999, 0x623: 0x3b28,
+       0x624: 0x31fc, 0x625: 0x3512, 0x626: 0x31de, 0x627: 0x34f4, 0x628: 0x39fb, 0x629: 0x3b8a,
+       0x62a: 0x39f4, 0x62b: 0x3b83, 0x62c: 0x3a09, 0x62d: 0x3b98, 0x62e: 0x3a02, 0x62f: 0x3b91,
+       0x630: 0x3a10, 0x631: 0x3b9f, 0x632: 0x3247, 0x633: 0x3562, 0x634: 0x326f, 0x635: 0x358f,
+       0x636: 0x326a, 0x637: 0x3585, 0x638: 0x3256, 0x639: 0x3571,
+       // Block 0x19, offset 0x640
+       0x640: 0x481b, 0x641: 0x4821, 0x642: 0x4935, 0x643: 0x494d, 0x644: 0x493d, 0x645: 0x4955,
+       0x646: 0x4945, 0x647: 0x495d, 0x648: 0x47c1, 0x649: 0x47c7, 0x64a: 0x48a5, 0x64b: 0x48bd,
+       0x64c: 0x48ad, 0x64d: 0x48c5, 0x64e: 0x48b5, 0x64f: 0x48cd, 0x650: 0x482d, 0x651: 0x4833,
+       0x652: 0x3dcf, 0x653: 0x3ddf, 0x654: 0x3dd7, 0x655: 0x3de7,
+       0x658: 0x47cd, 0x659: 0x47d3, 0x65a: 0x3cff, 0x65b: 0x3d0f, 0x65c: 0x3d07, 0x65d: 0x3d17,
+       0x660: 0x4845, 0x661: 0x484b, 0x662: 0x4965, 0x663: 0x497d,
+       0x664: 0x496d, 0x665: 0x4985, 0x666: 0x4975, 0x667: 0x498d, 0x668: 0x47d9, 0x669: 0x47df,
+       0x66a: 0x48d5, 0x66b: 0x48ed, 0x66c: 0x48dd, 0x66d: 0x48f5, 0x66e: 0x48e5, 0x66f: 0x48fd,
+       0x670: 0x485d, 0x671: 0x4863, 0x672: 0x3e2f, 0x673: 0x3e47, 0x674: 0x3e37, 0x675: 0x3e4f,
+       0x676: 0x3e3f, 0x677: 0x3e57, 0x678: 0x47e5, 0x679: 0x47eb, 0x67a: 0x3d2f, 0x67b: 0x3d47,
+       0x67c: 0x3d37, 0x67d: 0x3d4f, 0x67e: 0x3d3f, 0x67f: 0x3d57,
+       // Block 0x1a, offset 0x680
+       0x680: 0x4869, 0x681: 0x486f, 0x682: 0x3e5f, 0x683: 0x3e6f, 0x684: 0x3e67, 0x685: 0x3e77,
+       0x688: 0x47f1, 0x689: 0x47f7, 0x68a: 0x3d5f, 0x68b: 0x3d6f,
+       0x68c: 0x3d67, 0x68d: 0x3d77, 0x690: 0x487b, 0x691: 0x4881,
+       0x692: 0x3e97, 0x693: 0x3eaf, 0x694: 0x3e9f, 0x695: 0x3eb7, 0x696: 0x3ea7, 0x697: 0x3ebf,
+       0x699: 0x47fd, 0x69b: 0x3d7f, 0x69d: 0x3d87,
+       0x69f: 0x3d8f, 0x6a0: 0x4893, 0x6a1: 0x4899, 0x6a2: 0x4995, 0x6a3: 0x49ad,
+       0x6a4: 0x499d, 0x6a5: 0x49b5, 0x6a6: 0x49a5, 0x6a7: 0x49bd, 0x6a8: 0x4803, 0x6a9: 0x4809,
+       0x6aa: 0x4905, 0x6ab: 0x491d, 0x6ac: 0x490d, 0x6ad: 0x4925, 0x6ae: 0x4915, 0x6af: 0x492d,
+       0x6b0: 0x480f, 0x6b1: 0x4335, 0x6b2: 0x36a8, 0x6b3: 0x433b, 0x6b4: 0x4839, 0x6b5: 0x4341,
+       0x6b6: 0x36ba, 0x6b7: 0x4347, 0x6b8: 0x36d8, 0x6b9: 0x434d, 0x6ba: 0x36f0, 0x6bb: 0x4353,
+       0x6bc: 0x4887, 0x6bd: 0x4359,
+       // Block 0x1b, offset 0x6c0
+       0x6c0: 0x3db7, 0x6c1: 0x3dbf, 0x6c2: 0x419b, 0x6c3: 0x41b9, 0x6c4: 0x41a5, 0x6c5: 0x41c3,
+       0x6c6: 0x41af, 0x6c7: 0x41cd, 0x6c8: 0x3cef, 0x6c9: 0x3cf7, 0x6ca: 0x40e7, 0x6cb: 0x4105,
+       0x6cc: 0x40f1, 0x6cd: 0x410f, 0x6ce: 0x40fb, 0x6cf: 0x4119, 0x6d0: 0x3dff, 0x6d1: 0x3e07,
+       0x6d2: 0x41d7, 0x6d3: 0x41f5, 0x6d4: 0x41e1, 0x6d5: 0x41ff, 0x6d6: 0x41eb, 0x6d7: 0x4209,
+       0x6d8: 0x3d1f, 0x6d9: 0x3d27, 0x6da: 0x4123, 0x6db: 0x4141, 0x6dc: 0x412d, 0x6dd: 0x414b,
+       0x6de: 0x4137, 0x6df: 0x4155, 0x6e0: 0x3ed7, 0x6e1: 0x3edf, 0x6e2: 0x4213, 0x6e3: 0x4231,
+       0x6e4: 0x421d, 0x6e5: 0x423b, 0x6e6: 0x4227, 0x6e7: 0x4245, 0x6e8: 0x3d97, 0x6e9: 0x3d9f,
+       0x6ea: 0x415f, 0x6eb: 0x417d, 0x6ec: 0x4169, 0x6ed: 0x4187, 0x6ee: 0x4173, 0x6ef: 0x4191,
+       0x6f0: 0x369c, 0x6f1: 0x3696, 0x6f2: 0x3da7, 0x6f3: 0x36a2, 0x6f4: 0x3daf,
+       0x6f6: 0x4827, 0x6f7: 0x3dc7, 0x6f8: 0x360c, 0x6f9: 0x3606, 0x6fa: 0x35fa, 0x6fb: 0x4305,
+       0x6fc: 0x3612, 0x6fd: 0x429e, 0x6fe: 0x01d6, 0x6ff: 0x429e,
+       // Block 0x1c, offset 0x700
+       0x700: 0x42b7, 0x701: 0x4499, 0x702: 0x3def, 0x703: 0x36b4, 0x704: 0x3df7,
+       0x706: 0x4851, 0x707: 0x3e0f, 0x708: 0x3618, 0x709: 0x430b, 0x70a: 0x3624, 0x70b: 0x4311,
+       0x70c: 0x3630, 0x70d: 0x44a0, 0x70e: 0x44a7, 0x70f: 0x44ae, 0x710: 0x36cc, 0x711: 0x36c6,
+       0x712: 0x3e17, 0x713: 0x44fb, 0x716: 0x36d2, 0x717: 0x3e27,
+       0x718: 0x3648, 0x719: 0x3642, 0x71a: 0x3636, 0x71b: 0x4317, 0x71d: 0x44b5,
+       0x71e: 0x44bc, 0x71f: 0x44c3, 0x720: 0x3702, 0x721: 0x36fc, 0x722: 0x3e7f, 0x723: 0x4503,
+       0x724: 0x36e4, 0x725: 0x36ea, 0x726: 0x3708, 0x727: 0x3e8f, 0x728: 0x3678, 0x729: 0x3672,
+       0x72a: 0x3666, 0x72b: 0x4323, 0x72c: 0x3660, 0x72d: 0x448b, 0x72e: 0x4492, 0x72f: 0x0081,
+       0x732: 0x3ec7, 0x733: 0x370e, 0x734: 0x3ecf,
+       0x736: 0x489f, 0x737: 0x3ee7, 0x738: 0x3654, 0x739: 0x431d, 0x73a: 0x3684, 0x73b: 0x432f,
+       0x73c: 0x3690, 0x73d: 0x4271, 0x73e: 0x42a3,
+       // Block 0x1d, offset 0x740
+       0x740: 0x1bde, 0x741: 0x1be2, 0x742: 0x0047, 0x743: 0x1c5a, 0x745: 0x1bee,
+       0x746: 0x1bf2, 0x747: 0x00e9, 0x749: 0x1c5e, 0x74a: 0x008f, 0x74b: 0x0051,
+       0x74c: 0x0051, 0x74d: 0x0051, 0x74e: 0x0091, 0x74f: 0x00da, 0x750: 0x0053, 0x751: 0x0053,
+       0x752: 0x0059, 0x753: 0x0099, 0x755: 0x005d, 0x756: 0x1993,
+       0x759: 0x0061, 0x75a: 0x0063, 0x75b: 0x0065, 0x75c: 0x0065, 0x75d: 0x0065,
+       0x760: 0x19a5, 0x761: 0x1bce, 0x762: 0x19ae,
+       0x764: 0x0075, 0x766: 0x01bb, 0x768: 0x0075,
+       0x76a: 0x0057, 0x76b: 0x42e9, 0x76c: 0x0045, 0x76d: 0x0047, 0x76f: 0x008b,
+       0x770: 0x004b, 0x771: 0x004d, 0x773: 0x005b, 0x774: 0x009f, 0x775: 0x0218,
+       0x776: 0x021b, 0x777: 0x021e, 0x778: 0x0221, 0x779: 0x0093, 0x77b: 0x1b9e,
+       0x77c: 0x01eb, 0x77d: 0x01c4, 0x77e: 0x017c, 0x77f: 0x01a3,
+       // Block 0x1e, offset 0x780
+       0x780: 0x0466, 0x785: 0x0049,
+       0x786: 0x0089, 0x787: 0x008b, 0x788: 0x0093, 0x789: 0x0095,
+       0x790: 0x2234, 0x791: 0x2240,
+       0x792: 0x22f4, 0x793: 0x221c, 0x794: 0x22a0, 0x795: 0x2228, 0x796: 0x22a6, 0x797: 0x22be,
+       0x798: 0x22ca, 0x799: 0x222e, 0x79a: 0x22d0, 0x79b: 0x223a, 0x79c: 0x22c4, 0x79d: 0x22d6,
+       0x79e: 0x22dc, 0x79f: 0x1cc2, 0x7a0: 0x0053, 0x7a1: 0x195d, 0x7a2: 0x1baa, 0x7a3: 0x1966,
+       0x7a4: 0x006d, 0x7a5: 0x19b1, 0x7a6: 0x1bd6, 0x7a7: 0x1d4e, 0x7a8: 0x1969, 0x7a9: 0x0071,
+       0x7aa: 0x19bd, 0x7ab: 0x1bda, 0x7ac: 0x0059, 0x7ad: 0x0047, 0x7ae: 0x0049, 0x7af: 0x005b,
+       0x7b0: 0x0093, 0x7b1: 0x19ea, 0x7b2: 0x1c1e, 0x7b3: 0x19f3, 0x7b4: 0x00ad, 0x7b5: 0x1a68,
+       0x7b6: 0x1c52, 0x7b7: 0x1d62, 0x7b8: 0x19f6, 0x7b9: 0x00b1, 0x7ba: 0x1a6b, 0x7bb: 0x1c56,
+       0x7bc: 0x0099, 0x7bd: 0x0087, 0x7be: 0x0089, 0x7bf: 0x009b,
+       // Block 0x1f, offset 0x7c0
+       0x7c1: 0x3c1d, 0x7c3: 0xa000, 0x7c4: 0x3c24, 0x7c5: 0xa000,
+       0x7c7: 0x3c2b, 0x7c8: 0xa000, 0x7c9: 0x3c32,
+       0x7cd: 0xa000,
+       0x7e0: 0x2f7c, 0x7e1: 0xa000, 0x7e2: 0x3c40,
+       0x7e4: 0xa000, 0x7e5: 0xa000,
+       0x7ed: 0x3c39, 0x7ee: 0x2f77, 0x7ef: 0x2f81,
+       0x7f0: 0x3c47, 0x7f1: 0x3c4e, 0x7f2: 0xa000, 0x7f3: 0xa000, 0x7f4: 0x3c55, 0x7f5: 0x3c5c,
+       0x7f6: 0xa000, 0x7f7: 0xa000, 0x7f8: 0x3c63, 0x7f9: 0x3c6a, 0x7fa: 0xa000, 0x7fb: 0xa000,
+       0x7fc: 0xa000, 0x7fd: 0xa000,
+       // Block 0x20, offset 0x800
+       0x800: 0x3c71, 0x801: 0x3c78, 0x802: 0xa000, 0x803: 0xa000, 0x804: 0x3c8d, 0x805: 0x3c94,
+       0x806: 0xa000, 0x807: 0xa000, 0x808: 0x3c9b, 0x809: 0x3ca2,
+       0x811: 0xa000,
+       0x812: 0xa000,
+       0x822: 0xa000,
+       0x828: 0xa000, 0x829: 0xa000,
+       0x82b: 0xa000, 0x82c: 0x3cb7, 0x82d: 0x3cbe, 0x82e: 0x3cc5, 0x82f: 0x3ccc,
+       0x832: 0xa000, 0x833: 0xa000, 0x834: 0xa000, 0x835: 0xa000,
+       // Block 0x21, offset 0x840
+       0x860: 0x0023, 0x861: 0x0025, 0x862: 0x0027, 0x863: 0x0029,
+       0x864: 0x002b, 0x865: 0x002d, 0x866: 0x002f, 0x867: 0x0031, 0x868: 0x0033, 0x869: 0x1885,
+       0x86a: 0x1888, 0x86b: 0x188b, 0x86c: 0x188e, 0x86d: 0x1891, 0x86e: 0x1894, 0x86f: 0x1897,
+       0x870: 0x189a, 0x871: 0x189d, 0x872: 0x18a0, 0x873: 0x18a9, 0x874: 0x1a6e, 0x875: 0x1a72,
+       0x876: 0x1a76, 0x877: 0x1a7a, 0x878: 0x1a7e, 0x879: 0x1a82, 0x87a: 0x1a86, 0x87b: 0x1a8a,
+       0x87c: 0x1a8e, 0x87d: 0x1c86, 0x87e: 0x1c8b, 0x87f: 0x1c90,
+       // Block 0x22, offset 0x880
+       0x880: 0x1c95, 0x881: 0x1c9a, 0x882: 0x1c9f, 0x883: 0x1ca4, 0x884: 0x1ca9, 0x885: 0x1cae,
+       0x886: 0x1cb3, 0x887: 0x1cb8, 0x888: 0x1882, 0x889: 0x18a6, 0x88a: 0x18ca, 0x88b: 0x18ee,
+       0x88c: 0x1912, 0x88d: 0x191b, 0x88e: 0x1921, 0x88f: 0x1927, 0x890: 0x192d, 0x891: 0x1b66,
+       0x892: 0x1b6a, 0x893: 0x1b6e, 0x894: 0x1b72, 0x895: 0x1b76, 0x896: 0x1b7a, 0x897: 0x1b7e,
+       0x898: 0x1b82, 0x899: 0x1b86, 0x89a: 0x1b8a, 0x89b: 0x1b8e, 0x89c: 0x1afa, 0x89d: 0x1afe,
+       0x89e: 0x1b02, 0x89f: 0x1b06, 0x8a0: 0x1b0a, 0x8a1: 0x1b0e, 0x8a2: 0x1b12, 0x8a3: 0x1b16,
+       0x8a4: 0x1b1a, 0x8a5: 0x1b1e, 0x8a6: 0x1b22, 0x8a7: 0x1b26, 0x8a8: 0x1b2a, 0x8a9: 0x1b2e,
+       0x8aa: 0x1b32, 0x8ab: 0x1b36, 0x8ac: 0x1b3a, 0x8ad: 0x1b3e, 0x8ae: 0x1b42, 0x8af: 0x1b46,
+       0x8b0: 0x1b4a, 0x8b1: 0x1b4e, 0x8b2: 0x1b52, 0x8b3: 0x1b56, 0x8b4: 0x1b5a, 0x8b5: 0x1b5e,
+       0x8b6: 0x0043, 0x8b7: 0x0045, 0x8b8: 0x0047, 0x8b9: 0x0049, 0x8ba: 0x004b, 0x8bb: 0x004d,
+       0x8bc: 0x004f, 0x8bd: 0x0051, 0x8be: 0x0053, 0x8bf: 0x0055,
+       // Block 0x23, offset 0x8c0
+       0x8c0: 0x06c2, 0x8c1: 0x06e6, 0x8c2: 0x06f2, 0x8c3: 0x0702, 0x8c4: 0x070a, 0x8c5: 0x0716,
+       0x8c6: 0x071e, 0x8c7: 0x0726, 0x8c8: 0x0732, 0x8c9: 0x0786, 0x8ca: 0x079e, 0x8cb: 0x07ae,
+       0x8cc: 0x07be, 0x8cd: 0x07ce, 0x8ce: 0x07de, 0x8cf: 0x07fe, 0x8d0: 0x0802, 0x8d1: 0x0806,
+       0x8d2: 0x083a, 0x8d3: 0x0862, 0x8d4: 0x0872, 0x8d5: 0x087a, 0x8d6: 0x087e, 0x8d7: 0x088a,
+       0x8d8: 0x08a6, 0x8d9: 0x08aa, 0x8da: 0x08c2, 0x8db: 0x08c6, 0x8dc: 0x08ce, 0x8dd: 0x08de,
+       0x8de: 0x097a, 0x8df: 0x098e, 0x8e0: 0x09ce, 0x8e1: 0x09e2, 0x8e2: 0x09ea, 0x8e3: 0x09ee,
+       0x8e4: 0x09fe, 0x8e5: 0x0a1a, 0x8e6: 0x0a46, 0x8e7: 0x0a52, 0x8e8: 0x0a72, 0x8e9: 0x0a7e,
+       0x8ea: 0x0a82, 0x8eb: 0x0a86, 0x8ec: 0x0a9e, 0x8ed: 0x0aa2, 0x8ee: 0x0ace, 0x8ef: 0x0ada,
+       0x8f0: 0x0ae2, 0x8f1: 0x0aea, 0x8f2: 0x0afa, 0x8f3: 0x0b02, 0x8f4: 0x0b0a, 0x8f5: 0x0b36,
+       0x8f6: 0x0b3a, 0x8f7: 0x0b42, 0x8f8: 0x0b46, 0x8f9: 0x0b4e, 0x8fa: 0x0b56, 0x8fb: 0x0b66,
+       0x8fc: 0x0b82, 0x8fd: 0x0bfa, 0x8fe: 0x0c0e, 0x8ff: 0x0c12,
+       // Block 0x24, offset 0x900
+       0x900: 0x0c92, 0x901: 0x0c96, 0x902: 0x0caa, 0x903: 0x0cae, 0x904: 0x0cb6, 0x905: 0x0cbe,
+       0x906: 0x0cc6, 0x907: 0x0cd2, 0x908: 0x0cfa, 0x909: 0x0d0a, 0x90a: 0x0d1e, 0x90b: 0x0d8e,
+       0x90c: 0x0d9a, 0x90d: 0x0daa, 0x90e: 0x0db6, 0x90f: 0x0dc2, 0x910: 0x0dca, 0x911: 0x0dce,
+       0x912: 0x0dd2, 0x913: 0x0dd6, 0x914: 0x0dda, 0x915: 0x0e92, 0x916: 0x0eda, 0x917: 0x0ee6,
+       0x918: 0x0eea, 0x919: 0x0eee, 0x91a: 0x0ef2, 0x91b: 0x0efa, 0x91c: 0x0efe, 0x91d: 0x0f12,
+       0x91e: 0x0f2e, 0x91f: 0x0f36, 0x920: 0x0f76, 0x921: 0x0f7a, 0x922: 0x0f82, 0x923: 0x0f86,
+       0x924: 0x0f8e, 0x925: 0x0f92, 0x926: 0x0fb6, 0x927: 0x0fba, 0x928: 0x0fd6, 0x929: 0x0fda,
+       0x92a: 0x0fde, 0x92b: 0x0fe2, 0x92c: 0x0ff6, 0x92d: 0x101a, 0x92e: 0x101e, 0x92f: 0x1022,
+       0x930: 0x1046, 0x931: 0x1086, 0x932: 0x108a, 0x933: 0x10aa, 0x934: 0x10ba, 0x935: 0x10c2,
+       0x936: 0x10e2, 0x937: 0x1106, 0x938: 0x114a, 0x939: 0x1152, 0x93a: 0x1166, 0x93b: 0x1172,
+       0x93c: 0x117a, 0x93d: 0x1182, 0x93e: 0x1186, 0x93f: 0x118a,
+       // Block 0x25, offset 0x940
+       0x940: 0x11a2, 0x941: 0x11a6, 0x942: 0x11c2, 0x943: 0x11ca, 0x944: 0x11d2, 0x945: 0x11d6,
+       0x946: 0x11e2, 0x947: 0x11ea, 0x948: 0x11ee, 0x949: 0x11f2, 0x94a: 0x11fa, 0x94b: 0x11fe,
+       0x94c: 0x129e, 0x94d: 0x12b2, 0x94e: 0x12e6, 0x94f: 0x12ea, 0x950: 0x12f2, 0x951: 0x131e,
+       0x952: 0x1326, 0x953: 0x132e, 0x954: 0x1336, 0x955: 0x1372, 0x956: 0x1376, 0x957: 0x137e,
+       0x958: 0x1382, 0x959: 0x1386, 0x95a: 0x13b2, 0x95b: 0x13b6, 0x95c: 0x13be, 0x95d: 0x13d2,
+       0x95e: 0x13d6, 0x95f: 0x13f2, 0x960: 0x13fa, 0x961: 0x13fe, 0x962: 0x1422, 0x963: 0x1442,
+       0x964: 0x1456, 0x965: 0x145a, 0x966: 0x1462, 0x967: 0x148e, 0x968: 0x1492, 0x969: 0x14a2,
+       0x96a: 0x14c6, 0x96b: 0x14d2, 0x96c: 0x14e2, 0x96d: 0x14fa, 0x96e: 0x1502, 0x96f: 0x1506,
+       0x970: 0x150a, 0x971: 0x150e, 0x972: 0x151a, 0x973: 0x151e, 0x974: 0x1526, 0x975: 0x1542,
+       0x976: 0x1546, 0x977: 0x154a, 0x978: 0x1562, 0x979: 0x1566, 0x97a: 0x156e, 0x97b: 0x1582,
+       0x97c: 0x1586, 0x97d: 0x158a, 0x97e: 0x1592, 0x97f: 0x1596,
+       // Block 0x26, offset 0x980
+       0x986: 0xa000, 0x98b: 0xa000,
+       0x98c: 0x3f1f, 0x98d: 0xa000, 0x98e: 0x3f27, 0x98f: 0xa000, 0x990: 0x3f2f, 0x991: 0xa000,
+       0x992: 0x3f37, 0x993: 0xa000, 0x994: 0x3f3f, 0x995: 0xa000, 0x996: 0x3f47, 0x997: 0xa000,
+       0x998: 0x3f4f, 0x999: 0xa000, 0x99a: 0x3f57, 0x99b: 0xa000, 0x99c: 0x3f5f, 0x99d: 0xa000,
+       0x99e: 0x3f67, 0x99f: 0xa000, 0x9a0: 0x3f6f, 0x9a1: 0xa000, 0x9a2: 0x3f77,
+       0x9a4: 0xa000, 0x9a5: 0x3f7f, 0x9a6: 0xa000, 0x9a7: 0x3f87, 0x9a8: 0xa000, 0x9a9: 0x3f8f,
+       0x9af: 0xa000,
+       0x9b0: 0x3f97, 0x9b1: 0x3f9f, 0x9b2: 0xa000, 0x9b3: 0x3fa7, 0x9b4: 0x3faf, 0x9b5: 0xa000,
+       0x9b6: 0x3fb7, 0x9b7: 0x3fbf, 0x9b8: 0xa000, 0x9b9: 0x3fc7, 0x9ba: 0x3fcf, 0x9bb: 0xa000,
+       0x9bc: 0x3fd7, 0x9bd: 0x3fdf,
+       // Block 0x27, offset 0x9c0
+       0x9d4: 0x3f17,
+       0x9d9: 0x9904, 0x9da: 0x9904, 0x9db: 0x42f3, 0x9dc: 0x42f9, 0x9dd: 0xa000,
+       0x9de: 0x3fe7, 0x9df: 0x26ba,
+       0x9e6: 0xa000,
+       0x9eb: 0xa000, 0x9ec: 0x3ff7, 0x9ed: 0xa000, 0x9ee: 0x3fff, 0x9ef: 0xa000,
+       0x9f0: 0x4007, 0x9f1: 0xa000, 0x9f2: 0x400f, 0x9f3: 0xa000, 0x9f4: 0x4017, 0x9f5: 0xa000,
+       0x9f6: 0x401f, 0x9f7: 0xa000, 0x9f8: 0x4027, 0x9f9: 0xa000, 0x9fa: 0x402f, 0x9fb: 0xa000,
+       0x9fc: 0x4037, 0x9fd: 0xa000, 0x9fe: 0x403f, 0x9ff: 0xa000,
+       // Block 0x28, offset 0xa00
+       0xa00: 0x4047, 0xa01: 0xa000, 0xa02: 0x404f, 0xa04: 0xa000, 0xa05: 0x4057,
+       0xa06: 0xa000, 0xa07: 0x405f, 0xa08: 0xa000, 0xa09: 0x4067,
+       0xa0f: 0xa000, 0xa10: 0x406f, 0xa11: 0x4077,
+       0xa12: 0xa000, 0xa13: 0x407f, 0xa14: 0x4087, 0xa15: 0xa000, 0xa16: 0x408f, 0xa17: 0x4097,
+       0xa18: 0xa000, 0xa19: 0x409f, 0xa1a: 0x40a7, 0xa1b: 0xa000, 0xa1c: 0x40af, 0xa1d: 0x40b7,
+       0xa2f: 0xa000,
+       0xa30: 0xa000, 0xa31: 0xa000, 0xa32: 0xa000, 0xa34: 0x3fef,
+       0xa37: 0x40bf, 0xa38: 0x40c7, 0xa39: 0x40cf, 0xa3a: 0x40d7,
+       0xa3d: 0xa000, 0xa3e: 0x40df, 0xa3f: 0x26cf,
+       // Block 0x29, offset 0xa40
+       0xa40: 0x036a, 0xa41: 0x032e, 0xa42: 0x0332, 0xa43: 0x0336, 0xa44: 0x037e, 0xa45: 0x033a,
+       0xa46: 0x033e, 0xa47: 0x0342, 0xa48: 0x0346, 0xa49: 0x034a, 0xa4a: 0x034e, 0xa4b: 0x0352,
+       0xa4c: 0x0356, 0xa4d: 0x035a, 0xa4e: 0x035e, 0xa4f: 0x49d4, 0xa50: 0x49da, 0xa51: 0x49e0,
+       0xa52: 0x49e6, 0xa53: 0x49ec, 0xa54: 0x49f2, 0xa55: 0x49f8, 0xa56: 0x49fe, 0xa57: 0x4a04,
+       0xa58: 0x4a0a, 0xa59: 0x4a10, 0xa5a: 0x4a16, 0xa5b: 0x4a1c, 0xa5c: 0x4a22, 0xa5d: 0x4a28,
+       0xa5e: 0x4a2e, 0xa5f: 0x4a34, 0xa60: 0x4a3a, 0xa61: 0x4a40, 0xa62: 0x4a46, 0xa63: 0x4a4c,
+       0xa64: 0x03c6, 0xa65: 0x0362, 0xa66: 0x0366, 0xa67: 0x03ea, 0xa68: 0x03ee, 0xa69: 0x03f2,
+       0xa6a: 0x03f6, 0xa6b: 0x03fa, 0xa6c: 0x03fe, 0xa6d: 0x0402, 0xa6e: 0x036e, 0xa6f: 0x0406,
+       0xa70: 0x040a, 0xa71: 0x0372, 0xa72: 0x0376, 0xa73: 0x037a, 0xa74: 0x0382, 0xa75: 0x0386,
+       0xa76: 0x038a, 0xa77: 0x038e, 0xa78: 0x0392, 0xa79: 0x0396, 0xa7a: 0x039a, 0xa7b: 0x039e,
+       0xa7c: 0x03a2, 0xa7d: 0x03a6, 0xa7e: 0x03aa, 0xa7f: 0x03ae,
+       // Block 0x2a, offset 0xa80
+       0xa80: 0x03b2, 0xa81: 0x03b6, 0xa82: 0x040e, 0xa83: 0x0412, 0xa84: 0x03ba, 0xa85: 0x03be,
+       0xa86: 0x03c2, 0xa87: 0x03ca, 0xa88: 0x03ce, 0xa89: 0x03d2, 0xa8a: 0x03d6, 0xa8b: 0x03da,
+       0xa8c: 0x03de, 0xa8d: 0x03e2, 0xa8e: 0x03e6,
+       0xa92: 0x06c2, 0xa93: 0x071e, 0xa94: 0x06ce, 0xa95: 0x097e, 0xa96: 0x06d2, 0xa97: 0x06ea,
+       0xa98: 0x06d6, 0xa99: 0x0f96, 0xa9a: 0x070a, 0xa9b: 0x06de, 0xa9c: 0x06c6, 0xa9d: 0x0a02,
+       0xa9e: 0x0992, 0xa9f: 0x0732,
+       // Block 0x2b, offset 0xac0
+       0xac0: 0x205a, 0xac1: 0x2060, 0xac2: 0x2066, 0xac3: 0x206c, 0xac4: 0x2072, 0xac5: 0x2078,
+       0xac6: 0x207e, 0xac7: 0x2084, 0xac8: 0x208a, 0xac9: 0x2090, 0xaca: 0x2096, 0xacb: 0x209c,
+       0xacc: 0x20a2, 0xacd: 0x20a8, 0xace: 0x2733, 0xacf: 0x273c, 0xad0: 0x2745, 0xad1: 0x274e,
+       0xad2: 0x2757, 0xad3: 0x2760, 0xad4: 0x2769, 0xad5: 0x2772, 0xad6: 0x277b, 0xad7: 0x278d,
+       0xad8: 0x2796, 0xad9: 0x279f, 0xada: 0x27a8, 0xadb: 0x27b1, 0xadc: 0x2784, 0xadd: 0x2bb9,
+       0xade: 0x2afa, 0xae0: 0x20ae, 0xae1: 0x20c6, 0xae2: 0x20ba, 0xae3: 0x210e,
+       0xae4: 0x20cc, 0xae5: 0x20ea, 0xae6: 0x20b4, 0xae7: 0x20e4, 0xae8: 0x20c0, 0xae9: 0x20f6,
+       0xaea: 0x2126, 0xaeb: 0x2144, 0xaec: 0x213e, 0xaed: 0x2132, 0xaee: 0x2180, 0xaef: 0x2114,
+       0xaf0: 0x2120, 0xaf1: 0x2138, 0xaf2: 0x212c, 0xaf3: 0x2156, 0xaf4: 0x2102, 0xaf5: 0x214a,
+       0xaf6: 0x2174, 0xaf7: 0x215c, 0xaf8: 0x20f0, 0xaf9: 0x20d2, 0xafa: 0x2108, 0xafb: 0x211a,
+       0xafc: 0x2150, 0xafd: 0x20d8, 0xafe: 0x217a, 0xaff: 0x20fc,
+       // Block 0x2c, offset 0xb00
+       0xb00: 0x2162, 0xb01: 0x20de, 0xb02: 0x2168, 0xb03: 0x216e, 0xb04: 0x0932, 0xb05: 0x0b06,
+       0xb06: 0x0caa, 0xb07: 0x10ca,
+       0xb10: 0x1bca, 0xb11: 0x18ac,
+       0xb12: 0x18af, 0xb13: 0x18b2, 0xb14: 0x18b5, 0xb15: 0x18b8, 0xb16: 0x18bb, 0xb17: 0x18be,
+       0xb18: 0x18c1, 0xb19: 0x18c4, 0xb1a: 0x18cd, 0xb1b: 0x18d0, 0xb1c: 0x18d3, 0xb1d: 0x18d6,
+       0xb1e: 0x18d9, 0xb1f: 0x18dc, 0xb20: 0x0316, 0xb21: 0x031e, 0xb22: 0x0322, 0xb23: 0x032a,
+       0xb24: 0x032e, 0xb25: 0x0332, 0xb26: 0x033a, 0xb27: 0x0342, 0xb28: 0x0346, 0xb29: 0x034e,
+       0xb2a: 0x0352, 0xb2b: 0x0356, 0xb2c: 0x035a, 0xb2d: 0x035e, 0xb2e: 0x2e2f, 0xb2f: 0x2e37,
+       0xb30: 0x2e3f, 0xb31: 0x2e47, 0xb32: 0x2e4f, 0xb33: 0x2e57, 0xb34: 0x2e5f, 0xb35: 0x2e67,
+       0xb36: 0x2e77, 0xb37: 0x2e7f, 0xb38: 0x2e87, 0xb39: 0x2e8f, 0xb3a: 0x2e97, 0xb3b: 0x2e9f,
+       0xb3c: 0x2eea, 0xb3d: 0x2eb2, 0xb3e: 0x2e6f,
+       // Block 0x2d, offset 0xb40
+       0xb40: 0x06c2, 0xb41: 0x071e, 0xb42: 0x06ce, 0xb43: 0x097e, 0xb44: 0x0722, 0xb45: 0x07b2,
+       0xb46: 0x06ca, 0xb47: 0x07ae, 0xb48: 0x070e, 0xb49: 0x088a, 0xb4a: 0x0d0a, 0xb4b: 0x0e92,
+       0xb4c: 0x0dda, 0xb4d: 0x0d1e, 0xb4e: 0x1462, 0xb4f: 0x098e, 0xb50: 0x0cd2, 0xb51: 0x0d4e,
+       0xb52: 0x0d0e, 0xb53: 0x104e, 0xb54: 0x08fe, 0xb55: 0x0f06, 0xb56: 0x138a, 0xb57: 0x1062,
+       0xb58: 0x0846, 0xb59: 0x1092, 0xb5a: 0x0f9e, 0xb5b: 0x0a1a, 0xb5c: 0x1412, 0xb5d: 0x0782,
+       0xb5e: 0x08ae, 0xb5f: 0x0dfa, 0xb60: 0x152a, 0xb61: 0x0746, 0xb62: 0x07d6, 0xb63: 0x0d9e,
+       0xb64: 0x06d2, 0xb65: 0x06ea, 0xb66: 0x06d6, 0xb67: 0x0ade, 0xb68: 0x08f2, 0xb69: 0x0882,
+       0xb6a: 0x0a5a, 0xb6b: 0x0a4e, 0xb6c: 0x0fee, 0xb6d: 0x0742, 0xb6e: 0x139e, 0xb6f: 0x089e,
+       0xb70: 0x09f6, 0xb71: 0x18df, 0xb72: 0x18e2, 0xb73: 0x18e5, 0xb74: 0x18e8, 0xb75: 0x18f1,
+       0xb76: 0x18f4, 0xb77: 0x18f7, 0xb78: 0x18fa, 0xb79: 0x18fd, 0xb7a: 0x1900, 0xb7b: 0x1903,
+       0xb7c: 0x1906, 0xb7d: 0x1909, 0xb7e: 0x190c, 0xb7f: 0x1915,
+       // Block 0x2e, offset 0xb80
+       0xb80: 0x1ccc, 0xb81: 0x1cdb, 0xb82: 0x1cea, 0xb83: 0x1cf9, 0xb84: 0x1d08, 0xb85: 0x1d17,
+       0xb86: 0x1d26, 0xb87: 0x1d35, 0xb88: 0x1d44, 0xb89: 0x2192, 0xb8a: 0x21a4, 0xb8b: 0x21b6,
+       0xb8c: 0x1957, 0xb8d: 0x1c0a, 0xb8e: 0x19d8, 0xb8f: 0x1bae, 0xb90: 0x04ce, 0xb91: 0x04d6,
+       0xb92: 0x04de, 0xb93: 0x04e6, 0xb94: 0x04ee, 0xb95: 0x04f2, 0xb96: 0x04f6, 0xb97: 0x04fa,
+       0xb98: 0x04fe, 0xb99: 0x0502, 0xb9a: 0x0506, 0xb9b: 0x050a, 0xb9c: 0x050e, 0xb9d: 0x0512,
+       0xb9e: 0x0516, 0xb9f: 0x051a, 0xba0: 0x051e, 0xba1: 0x0526, 0xba2: 0x052a, 0xba3: 0x052e,
+       0xba4: 0x0532, 0xba5: 0x0536, 0xba6: 0x053a, 0xba7: 0x053e, 0xba8: 0x0542, 0xba9: 0x0546,
+       0xbaa: 0x054a, 0xbab: 0x054e, 0xbac: 0x0552, 0xbad: 0x0556, 0xbae: 0x055a, 0xbaf: 0x055e,
+       0xbb0: 0x0562, 0xbb1: 0x0566, 0xbb2: 0x056a, 0xbb3: 0x0572, 0xbb4: 0x057a, 0xbb5: 0x0582,
+       0xbb6: 0x0586, 0xbb7: 0x058a, 0xbb8: 0x058e, 0xbb9: 0x0592, 0xbba: 0x0596, 0xbbb: 0x059a,
+       0xbbc: 0x059e, 0xbbd: 0x05a2, 0xbbe: 0x05a6, 0xbbf: 0x2700,
+       // Block 0x2f, offset 0xbc0
+       0xbc0: 0x2b19, 0xbc1: 0x29b5, 0xbc2: 0x2b29, 0xbc3: 0x288d, 0xbc4: 0x2efb, 0xbc5: 0x2897,
+       0xbc6: 0x28a1, 0xbc7: 0x2f3f, 0xbc8: 0x29c2, 0xbc9: 0x28ab, 0xbca: 0x28b5, 0xbcb: 0x28bf,
+       0xbcc: 0x29e9, 0xbcd: 0x29f6, 0xbce: 0x29cf, 0xbcf: 0x29dc, 0xbd0: 0x2ec0, 0xbd1: 0x2a03,
+       0xbd2: 0x2a10, 0xbd3: 0x2bcb, 0xbd4: 0x26c1, 0xbd5: 0x2bde, 0xbd6: 0x2bf1, 0xbd7: 0x2b39,
+       0xbd8: 0x2a1d, 0xbd9: 0x2c04, 0xbda: 0x2c17, 0xbdb: 0x2a2a, 0xbdc: 0x28c9, 0xbdd: 0x28d3,
+       0xbde: 0x2ece, 0xbdf: 0x2a37, 0xbe0: 0x2b49, 0xbe1: 0x2f0c, 0xbe2: 0x28dd, 0xbe3: 0x28e7,
+       0xbe4: 0x2a44, 0xbe5: 0x28f1, 0xbe6: 0x28fb, 0xbe7: 0x26d6, 0xbe8: 0x26dd, 0xbe9: 0x2905,
+       0xbea: 0x290f, 0xbeb: 0x2c2a, 0xbec: 0x2a51, 0xbed: 0x2b59, 0xbee: 0x2c3d, 0xbef: 0x2a5e,
+       0xbf0: 0x2923, 0xbf1: 0x2919, 0xbf2: 0x2f53, 0xbf3: 0x2a6b, 0xbf4: 0x2c50, 0xbf5: 0x292d,
+       0xbf6: 0x2b69, 0xbf7: 0x2937, 0xbf8: 0x2a85, 0xbf9: 0x2941, 0xbfa: 0x2a92, 0xbfb: 0x2f1d,
+       0xbfc: 0x2a78, 0xbfd: 0x2b79, 0xbfe: 0x2a9f, 0xbff: 0x26e4,
+       // Block 0x30, offset 0xc00
+       0xc00: 0x2f2e, 0xc01: 0x294b, 0xc02: 0x2955, 0xc03: 0x2aac, 0xc04: 0x295f, 0xc05: 0x2969,
+       0xc06: 0x2973, 0xc07: 0x2b89, 0xc08: 0x2ab9, 0xc09: 0x26eb, 0xc0a: 0x2c63, 0xc0b: 0x2ea7,
+       0xc0c: 0x2b99, 0xc0d: 0x2ac6, 0xc0e: 0x2edc, 0xc0f: 0x297d, 0xc10: 0x2987, 0xc11: 0x2ad3,
+       0xc12: 0x26f2, 0xc13: 0x2ae0, 0xc14: 0x2ba9, 0xc15: 0x26f9, 0xc16: 0x2c76, 0xc17: 0x2991,
+       0xc18: 0x1cbd, 0xc19: 0x1cd1, 0xc1a: 0x1ce0, 0xc1b: 0x1cef, 0xc1c: 0x1cfe, 0xc1d: 0x1d0d,
+       0xc1e: 0x1d1c, 0xc1f: 0x1d2b, 0xc20: 0x1d3a, 0xc21: 0x1d49, 0xc22: 0x2198, 0xc23: 0x21aa,
+       0xc24: 0x21bc, 0xc25: 0x21c8, 0xc26: 0x21d4, 0xc27: 0x21e0, 0xc28: 0x21ec, 0xc29: 0x21f8,
+       0xc2a: 0x2204, 0xc2b: 0x2210, 0xc2c: 0x224c, 0xc2d: 0x2258, 0xc2e: 0x2264, 0xc2f: 0x2270,
+       0xc30: 0x227c, 0xc31: 0x1c1a, 0xc32: 0x19cc, 0xc33: 0x1939, 0xc34: 0x1bea, 0xc35: 0x1a4d,
+       0xc36: 0x1a5c, 0xc37: 0x19d2, 0xc38: 0x1c02, 0xc39: 0x1c06, 0xc3a: 0x1963, 0xc3b: 0x270e,
+       0xc3c: 0x271c, 0xc3d: 0x2707, 0xc3e: 0x2715, 0xc3f: 0x2aed,
+       // Block 0x31, offset 0xc40
+       0xc40: 0x1a50, 0xc41: 0x1a38, 0xc42: 0x1c66, 0xc43: 0x1a20, 0xc44: 0x19f9, 0xc45: 0x196c,
+       0xc46: 0x197b, 0xc47: 0x194b, 0xc48: 0x1bf6, 0xc49: 0x1d58, 0xc4a: 0x1a53, 0xc4b: 0x1a3b,
+       0xc4c: 0x1c6a, 0xc4d: 0x1c76, 0xc4e: 0x1a2c, 0xc4f: 0x1a02, 0xc50: 0x195a, 0xc51: 0x1c22,
+       0xc52: 0x1bb6, 0xc53: 0x1ba2, 0xc54: 0x1bd2, 0xc55: 0x1c7a, 0xc56: 0x1a2f, 0xc57: 0x19cf,
+       0xc58: 0x1a05, 0xc59: 0x19e4, 0xc5a: 0x1a47, 0xc5b: 0x1c7e, 0xc5c: 0x1a32, 0xc5d: 0x19c6,
+       0xc5e: 0x1a08, 0xc5f: 0x1c42, 0xc60: 0x1bfa, 0xc61: 0x1a1a, 0xc62: 0x1c2a, 0xc63: 0x1c46,
+       0xc64: 0x1bfe, 0xc65: 0x1a1d, 0xc66: 0x1c2e, 0xc67: 0x22ee, 0xc68: 0x2302, 0xc69: 0x199c,
+       0xc6a: 0x1c26, 0xc6b: 0x1bba, 0xc6c: 0x1ba6, 0xc6d: 0x1c4e, 0xc6e: 0x2723, 0xc6f: 0x27ba,
+       0xc70: 0x1a5f, 0xc71: 0x1a4a, 0xc72: 0x1c82, 0xc73: 0x1a35, 0xc74: 0x1a56, 0xc75: 0x1a3e,
+       0xc76: 0x1c6e, 0xc77: 0x1a23, 0xc78: 0x19fc, 0xc79: 0x1987, 0xc7a: 0x1a59, 0xc7b: 0x1a41,
+       0xc7c: 0x1c72, 0xc7d: 0x1a26, 0xc7e: 0x19ff, 0xc7f: 0x198a,
+       // Block 0x32, offset 0xc80
+       0xc80: 0x1c32, 0xc81: 0x1bbe, 0xc82: 0x1d53, 0xc83: 0x193c, 0xc84: 0x19c0, 0xc85: 0x19c3,
+       0xc86: 0x22fb, 0xc87: 0x1b9a, 0xc88: 0x19c9, 0xc89: 0x194e, 0xc8a: 0x19e7, 0xc8b: 0x1951,
+       0xc8c: 0x19f0, 0xc8d: 0x196f, 0xc8e: 0x1972, 0xc8f: 0x1a0b, 0xc90: 0x1a11, 0xc91: 0x1a14,
+       0xc92: 0x1c36, 0xc93: 0x1a17, 0xc94: 0x1a29, 0xc95: 0x1c3e, 0xc96: 0x1c4a, 0xc97: 0x1996,
+       0xc98: 0x1d5d, 0xc99: 0x1bc2, 0xc9a: 0x1999, 0xc9b: 0x1a62, 0xc9c: 0x19ab, 0xc9d: 0x19ba,
+       0xc9e: 0x22e8, 0xc9f: 0x22e2, 0xca0: 0x1cc7, 0xca1: 0x1cd6, 0xca2: 0x1ce5, 0xca3: 0x1cf4,
+       0xca4: 0x1d03, 0xca5: 0x1d12, 0xca6: 0x1d21, 0xca7: 0x1d30, 0xca8: 0x1d3f, 0xca9: 0x218c,
+       0xcaa: 0x219e, 0xcab: 0x21b0, 0xcac: 0x21c2, 0xcad: 0x21ce, 0xcae: 0x21da, 0xcaf: 0x21e6,
+       0xcb0: 0x21f2, 0xcb1: 0x21fe, 0xcb2: 0x220a, 0xcb3: 0x2246, 0xcb4: 0x2252, 0xcb5: 0x225e,
+       0xcb6: 0x226a, 0xcb7: 0x2276, 0xcb8: 0x2282, 0xcb9: 0x2288, 0xcba: 0x228e, 0xcbb: 0x2294,
+       0xcbc: 0x229a, 0xcbd: 0x22ac, 0xcbe: 0x22b2, 0xcbf: 0x1c16,
+       // Block 0x33, offset 0xcc0
+       0xcc0: 0x137a, 0xcc1: 0x0cfe, 0xcc2: 0x13d6, 0xcc3: 0x13a2, 0xcc4: 0x0e5a, 0xcc5: 0x06ee,
+       0xcc6: 0x08e2, 0xcc7: 0x162e, 0xcc8: 0x162e, 0xcc9: 0x0a0e, 0xcca: 0x1462, 0xccb: 0x0946,
+       0xccc: 0x0a0a, 0xccd: 0x0bf2, 0xcce: 0x0fd2, 0xccf: 0x1162, 0xcd0: 0x129a, 0xcd1: 0x12d6,
+       0xcd2: 0x130a, 0xcd3: 0x141e, 0xcd4: 0x0d76, 0xcd5: 0x0e02, 0xcd6: 0x0eae, 0xcd7: 0x0f46,
+       0xcd8: 0x1262, 0xcd9: 0x144a, 0xcda: 0x1576, 0xcdb: 0x0712, 0xcdc: 0x08b6, 0xcdd: 0x0d8a,
+       0xcde: 0x0ed2, 0xcdf: 0x1296, 0xce0: 0x15c6, 0xce1: 0x0ab6, 0xce2: 0x0e7a, 0xce3: 0x1286,
+       0xce4: 0x131a, 0xce5: 0x0c26, 0xce6: 0x11be, 0xce7: 0x12e2, 0xce8: 0x0b22, 0xce9: 0x0d12,
+       0xcea: 0x0e1a, 0xceb: 0x0f1e, 0xcec: 0x142a, 0xced: 0x0752, 0xcee: 0x07ea, 0xcef: 0x0856,
+       0xcf0: 0x0c8e, 0xcf1: 0x0d82, 0xcf2: 0x0ece, 0xcf3: 0x0ff2, 0xcf4: 0x117a, 0xcf5: 0x128e,
+       0xcf6: 0x12a6, 0xcf7: 0x13ca, 0xcf8: 0x14f2, 0xcf9: 0x15a6, 0xcfa: 0x15c2, 0xcfb: 0x102e,
+       0xcfc: 0x106e, 0xcfd: 0x1126, 0xcfe: 0x1246, 0xcff: 0x147e,
+       // Block 0x34, offset 0xd00
+       0xd00: 0x15ce, 0xd01: 0x134e, 0xd02: 0x09ca, 0xd03: 0x0b3e, 0xd04: 0x10de, 0xd05: 0x119e,
+       0xd06: 0x0f02, 0xd07: 0x1036, 0xd08: 0x139a, 0xd09: 0x14ea, 0xd0a: 0x09c6, 0xd0b: 0x0a92,
+       0xd0c: 0x0d7a, 0xd0d: 0x0e2e, 0xd0e: 0x0e62, 0xd0f: 0x1116, 0xd10: 0x113e, 0xd11: 0x14aa,
+       0xd12: 0x0852, 0xd13: 0x11aa, 0xd14: 0x07f6, 0xd15: 0x07f2, 0xd16: 0x109a, 0xd17: 0x112a,
+       0xd18: 0x125e, 0xd19: 0x14b2, 0xd1a: 0x136a, 0xd1b: 0x0c2a, 0xd1c: 0x0d76, 0xd1d: 0x135a,
+       0xd1e: 0x06fa, 0xd1f: 0x0a66, 0xd20: 0x0b96, 0xd21: 0x0f32, 0xd22: 0x0fb2, 0xd23: 0x0876,
+       0xd24: 0x103e, 0xd25: 0x0762, 0xd26: 0x0b7a, 0xd27: 0x06da, 0xd28: 0x0dee, 0xd29: 0x0ca6,
+       0xd2a: 0x1112, 0xd2b: 0x08ca, 0xd2c: 0x09b6, 0xd2d: 0x0ffe, 0xd2e: 0x1266, 0xd2f: 0x133e,
+       0xd30: 0x0dba, 0xd31: 0x13fa, 0xd32: 0x0de6, 0xd33: 0x0c3a, 0xd34: 0x121e, 0xd35: 0x0c5a,
+       0xd36: 0x0fae, 0xd37: 0x072e, 0xd38: 0x07aa, 0xd39: 0x07ee, 0xd3a: 0x0d56, 0xd3b: 0x10fe,
+       0xd3c: 0x11f6, 0xd3d: 0x134a, 0xd3e: 0x145e, 0xd3f: 0x085e,
+       // Block 0x35, offset 0xd40
+       0xd40: 0x0912, 0xd41: 0x0a1a, 0xd42: 0x0b32, 0xd43: 0x0cc2, 0xd44: 0x0e7e, 0xd45: 0x1042,
+       0xd46: 0x149a, 0xd47: 0x157e, 0xd48: 0x15d2, 0xd49: 0x15ea, 0xd4a: 0x083a, 0xd4b: 0x0cf6,
+       0xd4c: 0x0da6, 0xd4d: 0x13ee, 0xd4e: 0x0afe, 0xd4f: 0x0bda, 0xd50: 0x0bf6, 0xd51: 0x0c86,
+       0xd52: 0x0e6e, 0xd53: 0x0eba, 0xd54: 0x0f6a, 0xd55: 0x108e, 0xd56: 0x1132, 0xd57: 0x1196,
+       0xd58: 0x13de, 0xd59: 0x126e, 0xd5a: 0x1406, 0xd5b: 0x1482, 0xd5c: 0x0812, 0xd5d: 0x083e,
+       0xd5e: 0x0926, 0xd5f: 0x0eaa, 0xd60: 0x12f6, 0xd61: 0x133e, 0xd62: 0x0b1e, 0xd63: 0x0b8e,
+       0xd64: 0x0c52, 0xd65: 0x0db2, 0xd66: 0x10da, 0xd67: 0x0f26, 0xd68: 0x073e, 0xd69: 0x0982,
+       0xd6a: 0x0a66, 0xd6b: 0x0aca, 0xd6c: 0x0b9a, 0xd6d: 0x0f42, 0xd6e: 0x0f5e, 0xd6f: 0x116e,
+       0xd70: 0x118e, 0xd71: 0x1466, 0xd72: 0x14e6, 0xd73: 0x14f6, 0xd74: 0x1532, 0xd75: 0x0756,
+       0xd76: 0x1082, 0xd77: 0x1452, 0xd78: 0x14ce, 0xd79: 0x0bb2, 0xd7a: 0x071a, 0xd7b: 0x077a,
+       0xd7c: 0x0a6a, 0xd7d: 0x0a8a, 0xd7e: 0x0cb2, 0xd7f: 0x0d76,
+       // Block 0x36, offset 0xd80
+       0xd80: 0x0ec6, 0xd81: 0x0fce, 0xd82: 0x127a, 0xd83: 0x141a, 0xd84: 0x1626, 0xd85: 0x0ce6,
+       0xd86: 0x14a6, 0xd87: 0x0836, 0xd88: 0x0d32, 0xd89: 0x0d3e, 0xd8a: 0x0e12, 0xd8b: 0x0e4a,
+       0xd8c: 0x0f4e, 0xd8d: 0x0faa, 0xd8e: 0x102a, 0xd8f: 0x110e, 0xd90: 0x153e, 0xd91: 0x07b2,
+       0xd92: 0x0c06, 0xd93: 0x14b6, 0xd94: 0x076a, 0xd95: 0x0aae, 0xd96: 0x0e32, 0xd97: 0x13e2,
+       0xd98: 0x0b6a, 0xd99: 0x0bba, 0xd9a: 0x0d46, 0xd9b: 0x0f32, 0xd9c: 0x14be, 0xd9d: 0x081a,
+       0xd9e: 0x0902, 0xd9f: 0x0a9a, 0xda0: 0x0cd6, 0xda1: 0x0d22, 0xda2: 0x0d62, 0xda3: 0x0df6,
+       0xda4: 0x0f4a, 0xda5: 0x0fbe, 0xda6: 0x115a, 0xda7: 0x12fa, 0xda8: 0x1306, 0xda9: 0x145a,
+       0xdaa: 0x14da, 0xdab: 0x0886, 0xdac: 0x0e4e, 0xdad: 0x0906, 0xdae: 0x0eca, 0xdaf: 0x0f6e,
+       0xdb0: 0x128a, 0xdb1: 0x14c2, 0xdb2: 0x15ae, 0xdb3: 0x15d6, 0xdb4: 0x0d3a, 0xdb5: 0x0e2a,
+       0xdb6: 0x11c6, 0xdb7: 0x10ba, 0xdb8: 0x10c6, 0xdb9: 0x10ea, 0xdba: 0x0f1a, 0xdbb: 0x0ea2,
+       0xdbc: 0x1366, 0xdbd: 0x0736, 0xdbe: 0x122e, 0xdbf: 0x081e,
+       // Block 0x37, offset 0xdc0
+       0xdc0: 0x080e, 0xdc1: 0x0b0e, 0xdc2: 0x0c2e, 0xdc3: 0x10f6, 0xdc4: 0x0a56, 0xdc5: 0x0e06,
+       0xdc6: 0x0cf2, 0xdc7: 0x13ea, 0xdc8: 0x12ea, 0xdc9: 0x14ae, 0xdca: 0x1326, 0xdcb: 0x0b2a,
+       0xdcc: 0x078a, 0xdcd: 0x095e, 0xdd0: 0x09b2,
+       0xdd2: 0x0ce2, 0xdd5: 0x07fa, 0xdd6: 0x0f22, 0xdd7: 0x0fe6,
+       0xdd8: 0x104a, 0xdd9: 0x1066, 0xdda: 0x106a, 0xddb: 0x107e, 0xddc: 0x14fe, 0xddd: 0x10ee,
+       0xdde: 0x1172, 0xde0: 0x1292, 0xde2: 0x1356,
+       0xde5: 0x140a, 0xde6: 0x1436,
+       0xdea: 0x1552, 0xdeb: 0x1556, 0xdec: 0x155a, 0xded: 0x15be, 0xdee: 0x142e, 0xdef: 0x14ca,
+       0xdf0: 0x075a, 0xdf1: 0x077e, 0xdf2: 0x0792, 0xdf3: 0x084e, 0xdf4: 0x085a, 0xdf5: 0x089a,
+       0xdf6: 0x094e, 0xdf7: 0x096a, 0xdf8: 0x0972, 0xdf9: 0x09ae, 0xdfa: 0x09ba, 0xdfb: 0x0a96,
+       0xdfc: 0x0a9e, 0xdfd: 0x0ba6, 0xdfe: 0x0bce, 0xdff: 0x0bd6,
+       // Block 0x38, offset 0xe00
+       0xe00: 0x0bee, 0xe01: 0x0c9a, 0xe02: 0x0cca, 0xe03: 0x0cea, 0xe04: 0x0d5a, 0xe05: 0x0e1e,
+       0xe06: 0x0e3a, 0xe07: 0x0e6a, 0xe08: 0x0ebe, 0xe09: 0x0ede, 0xe0a: 0x0f52, 0xe0b: 0x1032,
+       0xe0c: 0x104e, 0xe0d: 0x1056, 0xe0e: 0x1052, 0xe0f: 0x105a, 0xe10: 0x105e, 0xe11: 0x1062,
+       0xe12: 0x1076, 0xe13: 0x107a, 0xe14: 0x109e, 0xe15: 0x10b2, 0xe16: 0x10ce, 0xe17: 0x1132,
+       0xe18: 0x113a, 0xe19: 0x1142, 0xe1a: 0x1156, 0xe1b: 0x117e, 0xe1c: 0x11ce, 0xe1d: 0x1202,
+       0xe1e: 0x1202, 0xe1f: 0x126a, 0xe20: 0x1312, 0xe21: 0x132a, 0xe22: 0x135e, 0xe23: 0x1362,
+       0xe24: 0x13a6, 0xe25: 0x13aa, 0xe26: 0x1402, 0xe27: 0x140a, 0xe28: 0x14de, 0xe29: 0x1522,
+       0xe2a: 0x153a, 0xe2b: 0x0b9e, 0xe2c: 0x1721, 0xe2d: 0x11e6,
+       0xe30: 0x06e2, 0xe31: 0x07e6, 0xe32: 0x07a6, 0xe33: 0x074e, 0xe34: 0x078e, 0xe35: 0x07ba,
+       0xe36: 0x084a, 0xe37: 0x0866, 0xe38: 0x094e, 0xe39: 0x093a, 0xe3a: 0x094a, 0xe3b: 0x0966,
+       0xe3c: 0x09b2, 0xe3d: 0x09c2, 0xe3e: 0x0a06, 0xe3f: 0x0a12,
+       // Block 0x39, offset 0xe40
+       0xe40: 0x0a2e, 0xe41: 0x0a3e, 0xe42: 0x0b26, 0xe43: 0x0b2e, 0xe44: 0x0b5e, 0xe45: 0x0b7e,
+       0xe46: 0x0bae, 0xe47: 0x0bc6, 0xe48: 0x0bb6, 0xe49: 0x0bd6, 0xe4a: 0x0bca, 0xe4b: 0x0bee,
+       0xe4c: 0x0c0a, 0xe4d: 0x0c62, 0xe4e: 0x0c6e, 0xe4f: 0x0c76, 0xe50: 0x0c9e, 0xe51: 0x0ce2,
+       0xe52: 0x0d12, 0xe53: 0x0d16, 0xe54: 0x0d2a, 0xe55: 0x0daa, 0xe56: 0x0dba, 0xe57: 0x0e12,
+       0xe58: 0x0e5e, 0xe59: 0x0e56, 0xe5a: 0x0e6a, 0xe5b: 0x0e86, 0xe5c: 0x0ebe, 0xe5d: 0x1016,
+       0xe5e: 0x0ee2, 0xe5f: 0x0f16, 0xe60: 0x0f22, 0xe61: 0x0f62, 0xe62: 0x0f7e, 0xe63: 0x0fa2,
+       0xe64: 0x0fc6, 0xe65: 0x0fca, 0xe66: 0x0fe6, 0xe67: 0x0fea, 0xe68: 0x0ffa, 0xe69: 0x100e,
+       0xe6a: 0x100a, 0xe6b: 0x103a, 0xe6c: 0x10b6, 0xe6d: 0x10ce, 0xe6e: 0x10e6, 0xe6f: 0x111e,
+       0xe70: 0x1132, 0xe71: 0x114e, 0xe72: 0x117e, 0xe73: 0x1232, 0xe74: 0x125a, 0xe75: 0x12ce,
+       0xe76: 0x1316, 0xe77: 0x1322, 0xe78: 0x132a, 0xe79: 0x1342, 0xe7a: 0x1356, 0xe7b: 0x1346,
+       0xe7c: 0x135e, 0xe7d: 0x135a, 0xe7e: 0x1352, 0xe7f: 0x1362,
+       // Block 0x3a, offset 0xe80
+       0xe80: 0x136e, 0xe81: 0x13aa, 0xe82: 0x13e6, 0xe83: 0x1416, 0xe84: 0x144e, 0xe85: 0x146e,
+       0xe86: 0x14ba, 0xe87: 0x14de, 0xe88: 0x14fe, 0xe89: 0x1512, 0xe8a: 0x1522, 0xe8b: 0x152e,
+       0xe8c: 0x153a, 0xe8d: 0x158e, 0xe8e: 0x162e, 0xe8f: 0x16b8, 0xe90: 0x16b3, 0xe91: 0x16e5,
+       0xe92: 0x060a, 0xe93: 0x0632, 0xe94: 0x0636, 0xe95: 0x1767, 0xe96: 0x1794, 0xe97: 0x180c,
+       0xe98: 0x161a, 0xe99: 0x162a,
+       // Block 0x3b, offset 0xec0
+       0xec0: 0x19db, 0xec1: 0x19de, 0xec2: 0x19e1, 0xec3: 0x1c0e, 0xec4: 0x1c12, 0xec5: 0x1a65,
+       0xec6: 0x1a65,
+       0xed3: 0x1d7b, 0xed4: 0x1d6c, 0xed5: 0x1d71, 0xed6: 0x1d80, 0xed7: 0x1d76,
+       0xedd: 0x43a7,
+       0xede: 0x8116, 0xedf: 0x4419, 0xee0: 0x0230, 0xee1: 0x0218, 0xee2: 0x0221, 0xee3: 0x0224,
+       0xee4: 0x0227, 0xee5: 0x022a, 0xee6: 0x022d, 0xee7: 0x0233, 0xee8: 0x0236, 0xee9: 0x0017,
+       0xeea: 0x4407, 0xeeb: 0x440d, 0xeec: 0x450b, 0xeed: 0x4513, 0xeee: 0x435f, 0xeef: 0x4365,
+       0xef0: 0x436b, 0xef1: 0x4371, 0xef2: 0x437d, 0xef3: 0x4383, 0xef4: 0x4389, 0xef5: 0x4395,
+       0xef6: 0x439b, 0xef8: 0x43a1, 0xef9: 0x43ad, 0xefa: 0x43b3, 0xefb: 0x43b9,
+       0xefc: 0x43c5, 0xefe: 0x43cb,
+       // Block 0x3c, offset 0xf00
+       0xf00: 0x43d1, 0xf01: 0x43d7, 0xf03: 0x43dd, 0xf04: 0x43e3,
+       0xf06: 0x43ef, 0xf07: 0x43f5, 0xf08: 0x43fb, 0xf09: 0x4401, 0xf0a: 0x4413, 0xf0b: 0x438f,
+       0xf0c: 0x4377, 0xf0d: 0x43bf, 0xf0e: 0x43e9, 0xf0f: 0x1d85, 0xf10: 0x029c, 0xf11: 0x029c,
+       0xf12: 0x02a5, 0xf13: 0x02a5, 0xf14: 0x02a5, 0xf15: 0x02a5, 0xf16: 0x02a8, 0xf17: 0x02a8,
+       0xf18: 0x02a8, 0xf19: 0x02a8, 0xf1a: 0x02ae, 0xf1b: 0x02ae, 0xf1c: 0x02ae, 0xf1d: 0x02ae,
+       0xf1e: 0x02a2, 0xf1f: 0x02a2, 0xf20: 0x02a2, 0xf21: 0x02a2, 0xf22: 0x02ab, 0xf23: 0x02ab,
+       0xf24: 0x02ab, 0xf25: 0x02ab, 0xf26: 0x029f, 0xf27: 0x029f, 0xf28: 0x029f, 0xf29: 0x029f,
+       0xf2a: 0x02d2, 0xf2b: 0x02d2, 0xf2c: 0x02d2, 0xf2d: 0x02d2, 0xf2e: 0x02d5, 0xf2f: 0x02d5,
+       0xf30: 0x02d5, 0xf31: 0x02d5, 0xf32: 0x02b4, 0xf33: 0x02b4, 0xf34: 0x02b4, 0xf35: 0x02b4,
+       0xf36: 0x02b1, 0xf37: 0x02b1, 0xf38: 0x02b1, 0xf39: 0x02b1, 0xf3a: 0x02b7, 0xf3b: 0x02b7,
+       0xf3c: 0x02b7, 0xf3d: 0x02b7, 0xf3e: 0x02ba, 0xf3f: 0x02ba,
+       // Block 0x3d, offset 0xf40
+       0xf40: 0x02ba, 0xf41: 0x02ba, 0xf42: 0x02c3, 0xf43: 0x02c3, 0xf44: 0x02c0, 0xf45: 0x02c0,
+       0xf46: 0x02c6, 0xf47: 0x02c6, 0xf48: 0x02bd, 0xf49: 0x02bd, 0xf4a: 0x02cc, 0xf4b: 0x02cc,
+       0xf4c: 0x02c9, 0xf4d: 0x02c9, 0xf4e: 0x02d8, 0xf4f: 0x02d8, 0xf50: 0x02d8, 0xf51: 0x02d8,
+       0xf52: 0x02de, 0xf53: 0x02de, 0xf54: 0x02de, 0xf55: 0x02de, 0xf56: 0x02e4, 0xf57: 0x02e4,
+       0xf58: 0x02e4, 0xf59: 0x02e4, 0xf5a: 0x02e1, 0xf5b: 0x02e1, 0xf5c: 0x02e1, 0xf5d: 0x02e1,
+       0xf5e: 0x02e7, 0xf5f: 0x02e7, 0xf60: 0x02ea, 0xf61: 0x02ea, 0xf62: 0x02ea, 0xf63: 0x02ea,
+       0xf64: 0x4485, 0xf65: 0x4485, 0xf66: 0x02f0, 0xf67: 0x02f0, 0xf68: 0x02f0, 0xf69: 0x02f0,
+       0xf6a: 0x02ed, 0xf6b: 0x02ed, 0xf6c: 0x02ed, 0xf6d: 0x02ed, 0xf6e: 0x030b, 0xf6f: 0x030b,
+       0xf70: 0x447f, 0xf71: 0x447f,
+       // Block 0x3e, offset 0xf80
+       0xf93: 0x02db, 0xf94: 0x02db, 0xf95: 0x02db, 0xf96: 0x02db, 0xf97: 0x02f9,
+       0xf98: 0x02f9, 0xf99: 0x02f6, 0xf9a: 0x02f6, 0xf9b: 0x02fc, 0xf9c: 0x02fc, 0xf9d: 0x2055,
+       0xf9e: 0x0302, 0xf9f: 0x0302, 0xfa0: 0x02f3, 0xfa1: 0x02f3, 0xfa2: 0x02ff, 0xfa3: 0x02ff,
+       0xfa4: 0x0308, 0xfa5: 0x0308, 0xfa6: 0x0308, 0xfa7: 0x0308, 0xfa8: 0x0290, 0xfa9: 0x0290,
+       0xfaa: 0x25b0, 0xfab: 0x25b0, 0xfac: 0x2620, 0xfad: 0x2620, 0xfae: 0x25ef, 0xfaf: 0x25ef,
+       0xfb0: 0x260b, 0xfb1: 0x260b, 0xfb2: 0x2604, 0xfb3: 0x2604, 0xfb4: 0x2612, 0xfb5: 0x2612,
+       0xfb6: 0x2619, 0xfb7: 0x2619, 0xfb8: 0x2619, 0xfb9: 0x25f6, 0xfba: 0x25f6, 0xfbb: 0x25f6,
+       0xfbc: 0x0305, 0xfbd: 0x0305, 0xfbe: 0x0305, 0xfbf: 0x0305,
+       // Block 0x3f, offset 0xfc0
+       0xfc0: 0x25b7, 0xfc1: 0x25be, 0xfc2: 0x25da, 0xfc3: 0x25f6, 0xfc4: 0x25fd, 0xfc5: 0x1d8f,
+       0xfc6: 0x1d94, 0xfc7: 0x1d99, 0xfc8: 0x1da8, 0xfc9: 0x1db7, 0xfca: 0x1dbc, 0xfcb: 0x1dc1,
+       0xfcc: 0x1dc6, 0xfcd: 0x1dcb, 0xfce: 0x1dda, 0xfcf: 0x1de9, 0xfd0: 0x1dee, 0xfd1: 0x1df3,
+       0xfd2: 0x1e02, 0xfd3: 0x1e11, 0xfd4: 0x1e16, 0xfd5: 0x1e1b, 0xfd6: 0x1e20, 0xfd7: 0x1e2f,
+       0xfd8: 0x1e34, 0xfd9: 0x1e43, 0xfda: 0x1e48, 0xfdb: 0x1e4d, 0xfdc: 0x1e5c, 0xfdd: 0x1e61,
+       0xfde: 0x1e66, 0xfdf: 0x1e70, 0xfe0: 0x1eac, 0xfe1: 0x1ebb, 0xfe2: 0x1eca, 0xfe3: 0x1ecf,
+       0xfe4: 0x1ed4, 0xfe5: 0x1ede, 0xfe6: 0x1eed, 0xfe7: 0x1ef2, 0xfe8: 0x1f01, 0xfe9: 0x1f06,
+       0xfea: 0x1f0b, 0xfeb: 0x1f1a, 0xfec: 0x1f1f, 0xfed: 0x1f2e, 0xfee: 0x1f33, 0xfef: 0x1f38,
+       0xff0: 0x1f3d, 0xff1: 0x1f42, 0xff2: 0x1f47, 0xff3: 0x1f4c, 0xff4: 0x1f51, 0xff5: 0x1f56,
+       0xff6: 0x1f5b, 0xff7: 0x1f60, 0xff8: 0x1f65, 0xff9: 0x1f6a, 0xffa: 0x1f6f, 0xffb: 0x1f74,
+       0xffc: 0x1f79, 0xffd: 0x1f7e, 0xffe: 0x1f83, 0xfff: 0x1f8d,
+       // Block 0x40, offset 0x1000
+       0x1000: 0x1f92, 0x1001: 0x1f97, 0x1002: 0x1f9c, 0x1003: 0x1fa6, 0x1004: 0x1fab, 0x1005: 0x1fb5,
+       0x1006: 0x1fba, 0x1007: 0x1fbf, 0x1008: 0x1fc4, 0x1009: 0x1fc9, 0x100a: 0x1fce, 0x100b: 0x1fd3,
+       0x100c: 0x1fd8, 0x100d: 0x1fdd, 0x100e: 0x1fec, 0x100f: 0x1ffb, 0x1010: 0x2000, 0x1011: 0x2005,
+       0x1012: 0x200a, 0x1013: 0x200f, 0x1014: 0x2014, 0x1015: 0x201e, 0x1016: 0x2023, 0x1017: 0x2028,
+       0x1018: 0x2037, 0x1019: 0x2046, 0x101a: 0x204b, 0x101b: 0x4437, 0x101c: 0x443d, 0x101d: 0x4473,
+       0x101e: 0x44ca, 0x101f: 0x44d1, 0x1020: 0x44d8, 0x1021: 0x44df, 0x1022: 0x44e6, 0x1023: 0x44ed,
+       0x1024: 0x25cc, 0x1025: 0x25d3, 0x1026: 0x25da, 0x1027: 0x25e1, 0x1028: 0x25f6, 0x1029: 0x25fd,
+       0x102a: 0x1d9e, 0x102b: 0x1da3, 0x102c: 0x1da8, 0x102d: 0x1dad, 0x102e: 0x1db7, 0x102f: 0x1dbc,
+       0x1030: 0x1dd0, 0x1031: 0x1dd5, 0x1032: 0x1dda, 0x1033: 0x1ddf, 0x1034: 0x1de9, 0x1035: 0x1dee,
+       0x1036: 0x1df8, 0x1037: 0x1dfd, 0x1038: 0x1e02, 0x1039: 0x1e07, 0x103a: 0x1e11, 0x103b: 0x1e16,
+       0x103c: 0x1f42, 0x103d: 0x1f47, 0x103e: 0x1f56, 0x103f: 0x1f5b,
+       // Block 0x41, offset 0x1040
+       0x1040: 0x1f60, 0x1041: 0x1f74, 0x1042: 0x1f79, 0x1043: 0x1f7e, 0x1044: 0x1f83, 0x1045: 0x1f9c,
+       0x1046: 0x1fa6, 0x1047: 0x1fab, 0x1048: 0x1fb0, 0x1049: 0x1fc4, 0x104a: 0x1fe2, 0x104b: 0x1fe7,
+       0x104c: 0x1fec, 0x104d: 0x1ff1, 0x104e: 0x1ffb, 0x104f: 0x2000, 0x1050: 0x4473, 0x1051: 0x202d,
+       0x1052: 0x2032, 0x1053: 0x2037, 0x1054: 0x203c, 0x1055: 0x2046, 0x1056: 0x204b, 0x1057: 0x25b7,
+       0x1058: 0x25be, 0x1059: 0x25c5, 0x105a: 0x25da, 0x105b: 0x25e8, 0x105c: 0x1d8f, 0x105d: 0x1d94,
+       0x105e: 0x1d99, 0x105f: 0x1da8, 0x1060: 0x1db2, 0x1061: 0x1dc1, 0x1062: 0x1dc6, 0x1063: 0x1dcb,
+       0x1064: 0x1dda, 0x1065: 0x1de4, 0x1066: 0x1e02, 0x1067: 0x1e1b, 0x1068: 0x1e20, 0x1069: 0x1e2f,
+       0x106a: 0x1e34, 0x106b: 0x1e43, 0x106c: 0x1e4d, 0x106d: 0x1e5c, 0x106e: 0x1e61, 0x106f: 0x1e66,
+       0x1070: 0x1e70, 0x1071: 0x1eac, 0x1072: 0x1eb1, 0x1073: 0x1ebb, 0x1074: 0x1eca, 0x1075: 0x1ecf,
+       0x1076: 0x1ed4, 0x1077: 0x1ede, 0x1078: 0x1eed, 0x1079: 0x1f01, 0x107a: 0x1f06, 0x107b: 0x1f0b,
+       0x107c: 0x1f1a, 0x107d: 0x1f1f, 0x107e: 0x1f2e, 0x107f: 0x1f33,
+       // Block 0x42, offset 0x1080
+       0x1080: 0x1f38, 0x1081: 0x1f3d, 0x1082: 0x1f4c, 0x1083: 0x1f51, 0x1084: 0x1f65, 0x1085: 0x1f6a,
+       0x1086: 0x1f6f, 0x1087: 0x1f74, 0x1088: 0x1f79, 0x1089: 0x1f8d, 0x108a: 0x1f92, 0x108b: 0x1f97,
+       0x108c: 0x1f9c, 0x108d: 0x1fa1, 0x108e: 0x1fb5, 0x108f: 0x1fba, 0x1090: 0x1fbf, 0x1091: 0x1fc4,
+       0x1092: 0x1fd3, 0x1093: 0x1fd8, 0x1094: 0x1fdd, 0x1095: 0x1fec, 0x1096: 0x1ff6, 0x1097: 0x2005,
+       0x1098: 0x200a, 0x1099: 0x4467, 0x109a: 0x201e, 0x109b: 0x2023, 0x109c: 0x2028, 0x109d: 0x2037,
+       0x109e: 0x2041, 0x109f: 0x25da, 0x10a0: 0x25e8, 0x10a1: 0x1da8, 0x10a2: 0x1db2, 0x10a3: 0x1dda,
+       0x10a4: 0x1de4, 0x10a5: 0x1e02, 0x10a6: 0x1e0c, 0x10a7: 0x1e70, 0x10a8: 0x1e75, 0x10a9: 0x1e98,
+       0x10aa: 0x1e9d, 0x10ab: 0x1f74, 0x10ac: 0x1f79, 0x10ad: 0x1f9c, 0x10ae: 0x1fec, 0x10af: 0x1ff6,
+       0x10b0: 0x2037, 0x10b1: 0x2041, 0x10b2: 0x451b, 0x10b3: 0x4523, 0x10b4: 0x452b, 0x10b5: 0x1ef7,
+       0x10b6: 0x1efc, 0x10b7: 0x1f10, 0x10b8: 0x1f15, 0x10b9: 0x1f24, 0x10ba: 0x1f29, 0x10bb: 0x1e7a,
+       0x10bc: 0x1e7f, 0x10bd: 0x1ea2, 0x10be: 0x1ea7, 0x10bf: 0x1e39,
+       // Block 0x43, offset 0x10c0
+       0x10c0: 0x1e3e, 0x10c1: 0x1e25, 0x10c2: 0x1e2a, 0x10c3: 0x1e52, 0x10c4: 0x1e57, 0x10c5: 0x1ec0,
+       0x10c6: 0x1ec5, 0x10c7: 0x1ee3, 0x10c8: 0x1ee8, 0x10c9: 0x1e84, 0x10ca: 0x1e89, 0x10cb: 0x1e8e,
+       0x10cc: 0x1e98, 0x10cd: 0x1e93, 0x10ce: 0x1e6b, 0x10cf: 0x1eb6, 0x10d0: 0x1ed9, 0x10d1: 0x1ef7,
+       0x10d2: 0x1efc, 0x10d3: 0x1f10, 0x10d4: 0x1f15, 0x10d5: 0x1f24, 0x10d6: 0x1f29, 0x10d7: 0x1e7a,
+       0x10d8: 0x1e7f, 0x10d9: 0x1ea2, 0x10da: 0x1ea7, 0x10db: 0x1e39, 0x10dc: 0x1e3e, 0x10dd: 0x1e25,
+       0x10de: 0x1e2a, 0x10df: 0x1e52, 0x10e0: 0x1e57, 0x10e1: 0x1ec0, 0x10e2: 0x1ec5, 0x10e3: 0x1ee3,
+       0x10e4: 0x1ee8, 0x10e5: 0x1e84, 0x10e6: 0x1e89, 0x10e7: 0x1e8e, 0x10e8: 0x1e98, 0x10e9: 0x1e93,
+       0x10ea: 0x1e6b, 0x10eb: 0x1eb6, 0x10ec: 0x1ed9, 0x10ed: 0x1e84, 0x10ee: 0x1e89, 0x10ef: 0x1e8e,
+       0x10f0: 0x1e98, 0x10f1: 0x1e75, 0x10f2: 0x1e9d, 0x10f3: 0x1ef2, 0x10f4: 0x1e5c, 0x10f5: 0x1e61,
+       0x10f6: 0x1e66, 0x10f7: 0x1e84, 0x10f8: 0x1e89, 0x10f9: 0x1e8e, 0x10fa: 0x1ef2, 0x10fb: 0x1f01,
+       0x10fc: 0x441f, 0x10fd: 0x441f,
+       // Block 0x44, offset 0x1100
+       0x1110: 0x2317, 0x1111: 0x232c,
+       0x1112: 0x232c, 0x1113: 0x2333, 0x1114: 0x233a, 0x1115: 0x234f, 0x1116: 0x2356, 0x1117: 0x235d,
+       0x1118: 0x2380, 0x1119: 0x2380, 0x111a: 0x23a3, 0x111b: 0x239c, 0x111c: 0x23b8, 0x111d: 0x23aa,
+       0x111e: 0x23b1, 0x111f: 0x23d4, 0x1120: 0x23d4, 0x1121: 0x23cd, 0x1122: 0x23db, 0x1123: 0x23db,
+       0x1124: 0x2405, 0x1125: 0x2405, 0x1126: 0x2421, 0x1127: 0x23e9, 0x1128: 0x23e9, 0x1129: 0x23e2,
+       0x112a: 0x23f7, 0x112b: 0x23f7, 0x112c: 0x23fe, 0x112d: 0x23fe, 0x112e: 0x2428, 0x112f: 0x2436,
+       0x1130: 0x2436, 0x1131: 0x243d, 0x1132: 0x243d, 0x1133: 0x2444, 0x1134: 0x244b, 0x1135: 0x2452,
+       0x1136: 0x2459, 0x1137: 0x2459, 0x1138: 0x2460, 0x1139: 0x246e, 0x113a: 0x247c, 0x113b: 0x2475,
+       0x113c: 0x2483, 0x113d: 0x2483, 0x113e: 0x2498, 0x113f: 0x249f,
+       // Block 0x45, offset 0x1140
+       0x1140: 0x24d0, 0x1141: 0x24de, 0x1142: 0x24d7, 0x1143: 0x24bb, 0x1144: 0x24bb, 0x1145: 0x24e5,
+       0x1146: 0x24e5, 0x1147: 0x24ec, 0x1148: 0x24ec, 0x1149: 0x2516, 0x114a: 0x251d, 0x114b: 0x2524,
+       0x114c: 0x24fa, 0x114d: 0x2508, 0x114e: 0x252b, 0x114f: 0x2532,
+       0x1152: 0x2501, 0x1153: 0x2586, 0x1154: 0x258d, 0x1155: 0x2563, 0x1156: 0x256a, 0x1157: 0x254e,
+       0x1158: 0x254e, 0x1159: 0x2555, 0x115a: 0x257f, 0x115b: 0x2578, 0x115c: 0x25a2, 0x115d: 0x25a2,
+       0x115e: 0x2310, 0x115f: 0x2325, 0x1160: 0x231e, 0x1161: 0x2348, 0x1162: 0x2341, 0x1163: 0x236b,
+       0x1164: 0x2364, 0x1165: 0x238e, 0x1166: 0x2372, 0x1167: 0x2387, 0x1168: 0x23bf, 0x1169: 0x240c,
+       0x116a: 0x23f0, 0x116b: 0x242f, 0x116c: 0x24c9, 0x116d: 0x24f3, 0x116e: 0x259b, 0x116f: 0x2594,
+       0x1170: 0x25a9, 0x1171: 0x2540, 0x1172: 0x24a6, 0x1173: 0x2571, 0x1174: 0x2498, 0x1175: 0x24d0,
+       0x1176: 0x2467, 0x1177: 0x24b4, 0x1178: 0x2547, 0x1179: 0x2539, 0x117a: 0x24c2, 0x117b: 0x24ad,
+       0x117c: 0x24c2, 0x117d: 0x2547, 0x117e: 0x2379, 0x117f: 0x2395,
+       // Block 0x46, offset 0x1180
+       0x1180: 0x250f, 0x1181: 0x248a, 0x1182: 0x2309, 0x1183: 0x24ad, 0x1184: 0x2452, 0x1185: 0x2421,
+       0x1186: 0x23c6, 0x1187: 0x255c,
+       0x11b0: 0x241a, 0x11b1: 0x2491, 0x11b2: 0x27cc, 0x11b3: 0x27c3, 0x11b4: 0x27f9, 0x11b5: 0x27e7,
+       0x11b6: 0x27d5, 0x11b7: 0x27f0, 0x11b8: 0x2802, 0x11b9: 0x2413, 0x11ba: 0x2c89, 0x11bb: 0x2b09,
+       0x11bc: 0x27de,
+       // Block 0x47, offset 0x11c0
+       0x11d0: 0x0019, 0x11d1: 0x0486,
+       0x11d2: 0x048a, 0x11d3: 0x0035, 0x11d4: 0x0037, 0x11d5: 0x0003, 0x11d6: 0x003f, 0x11d7: 0x04c2,
+       0x11d8: 0x04c6, 0x11d9: 0x1b62,
+       0x11e0: 0x8133, 0x11e1: 0x8133, 0x11e2: 0x8133, 0x11e3: 0x8133,
+       0x11e4: 0x8133, 0x11e5: 0x8133, 0x11e6: 0x8133, 0x11e7: 0x812e, 0x11e8: 0x812e, 0x11e9: 0x812e,
+       0x11ea: 0x812e, 0x11eb: 0x812e, 0x11ec: 0x812e, 0x11ed: 0x812e, 0x11ee: 0x8133, 0x11ef: 0x8133,
+       0x11f0: 0x1876, 0x11f1: 0x0446, 0x11f2: 0x0442, 0x11f3: 0x007f, 0x11f4: 0x007f, 0x11f5: 0x0011,
+       0x11f6: 0x0013, 0x11f7: 0x00b7, 0x11f8: 0x00bb, 0x11f9: 0x04ba, 0x11fa: 0x04be, 0x11fb: 0x04ae,
+       0x11fc: 0x04b2, 0x11fd: 0x0496, 0x11fe: 0x049a, 0x11ff: 0x048e,
+       // Block 0x48, offset 0x1200
+       0x1200: 0x0492, 0x1201: 0x049e, 0x1202: 0x04a2, 0x1203: 0x04a6, 0x1204: 0x04aa,
+       0x1207: 0x0077, 0x1208: 0x007b, 0x1209: 0x4280, 0x120a: 0x4280, 0x120b: 0x4280,
+       0x120c: 0x4280, 0x120d: 0x007f, 0x120e: 0x007f, 0x120f: 0x007f, 0x1210: 0x0019, 0x1211: 0x0486,
+       0x1212: 0x001d, 0x1214: 0x0037, 0x1215: 0x0035, 0x1216: 0x003f, 0x1217: 0x0003,
+       0x1218: 0x0446, 0x1219: 0x0011, 0x121a: 0x0013, 0x121b: 0x00b7, 0x121c: 0x00bb, 0x121d: 0x04ba,
+       0x121e: 0x04be, 0x121f: 0x0007, 0x1220: 0x000d, 0x1221: 0x0015, 0x1222: 0x0017, 0x1223: 0x001b,
+       0x1224: 0x0039, 0x1225: 0x003d, 0x1226: 0x003b, 0x1228: 0x0079, 0x1229: 0x0009,
+       0x122a: 0x000b, 0x122b: 0x0041,
+       0x1230: 0x42c1, 0x1231: 0x4443, 0x1232: 0x42c6, 0x1234: 0x42cb,
+       0x1236: 0x42d0, 0x1237: 0x4449, 0x1238: 0x42d5, 0x1239: 0x444f, 0x123a: 0x42da, 0x123b: 0x4455,
+       0x123c: 0x42df, 0x123d: 0x445b, 0x123e: 0x42e4, 0x123f: 0x4461,
+       // Block 0x49, offset 0x1240
+       0x1240: 0x0239, 0x1241: 0x4425, 0x1242: 0x4425, 0x1243: 0x442b, 0x1244: 0x442b, 0x1245: 0x446d,
+       0x1246: 0x446d, 0x1247: 0x4431, 0x1248: 0x4431, 0x1249: 0x4479, 0x124a: 0x4479, 0x124b: 0x4479,
+       0x124c: 0x4479, 0x124d: 0x023c, 0x124e: 0x023c, 0x124f: 0x023f, 0x1250: 0x023f, 0x1251: 0x023f,
+       0x1252: 0x023f, 0x1253: 0x0242, 0x1254: 0x0242, 0x1255: 0x0245, 0x1256: 0x0245, 0x1257: 0x0245,
+       0x1258: 0x0245, 0x1259: 0x0248, 0x125a: 0x0248, 0x125b: 0x0248, 0x125c: 0x0248, 0x125d: 0x024b,
+       0x125e: 0x024b, 0x125f: 0x024b, 0x1260: 0x024b, 0x1261: 0x024e, 0x1262: 0x024e, 0x1263: 0x024e,
+       0x1264: 0x024e, 0x1265: 0x0251, 0x1266: 0x0251, 0x1267: 0x0251, 0x1268: 0x0251, 0x1269: 0x0254,
+       0x126a: 0x0254, 0x126b: 0x0257, 0x126c: 0x0257, 0x126d: 0x025a, 0x126e: 0x025a, 0x126f: 0x025d,
+       0x1270: 0x025d, 0x1271: 0x0260, 0x1272: 0x0260, 0x1273: 0x0260, 0x1274: 0x0260, 0x1275: 0x0263,
+       0x1276: 0x0263, 0x1277: 0x0263, 0x1278: 0x0263, 0x1279: 0x0266, 0x127a: 0x0266, 0x127b: 0x0266,
+       0x127c: 0x0266, 0x127d: 0x0269, 0x127e: 0x0269, 0x127f: 0x0269,
+       // Block 0x4a, offset 0x1280
+       0x1280: 0x0269, 0x1281: 0x026c, 0x1282: 0x026c, 0x1283: 0x026c, 0x1284: 0x026c, 0x1285: 0x026f,
+       0x1286: 0x026f, 0x1287: 0x026f, 0x1288: 0x026f, 0x1289: 0x0272, 0x128a: 0x0272, 0x128b: 0x0272,
+       0x128c: 0x0272, 0x128d: 0x0275, 0x128e: 0x0275, 0x128f: 0x0275, 0x1290: 0x0275, 0x1291: 0x0278,
+       0x1292: 0x0278, 0x1293: 0x0278, 0x1294: 0x0278, 0x1295: 0x027b, 0x1296: 0x027b, 0x1297: 0x027b,
+       0x1298: 0x027b, 0x1299: 0x027e, 0x129a: 0x027e, 0x129b: 0x027e, 0x129c: 0x027e, 0x129d: 0x0281,
+       0x129e: 0x0281, 0x129f: 0x0281, 0x12a0: 0x0281, 0x12a1: 0x0284, 0x12a2: 0x0284, 0x12a3: 0x0284,
+       0x12a4: 0x0284, 0x12a5: 0x0287, 0x12a6: 0x0287, 0x12a7: 0x0287, 0x12a8: 0x0287, 0x12a9: 0x028a,
+       0x12aa: 0x028a, 0x12ab: 0x028a, 0x12ac: 0x028a, 0x12ad: 0x028d, 0x12ae: 0x028d, 0x12af: 0x0290,
+       0x12b0: 0x0290, 0x12b1: 0x0293, 0x12b2: 0x0293, 0x12b3: 0x0293, 0x12b4: 0x0293, 0x12b5: 0x2e17,
+       0x12b6: 0x2e17, 0x12b7: 0x2e1f, 0x12b8: 0x2e1f, 0x12b9: 0x2e27, 0x12ba: 0x2e27, 0x12bb: 0x1f88,
+       0x12bc: 0x1f88,
+       // Block 0x4b, offset 0x12c0
+       0x12c0: 0x0081, 0x12c1: 0x0083, 0x12c2: 0x0085, 0x12c3: 0x0087, 0x12c4: 0x0089, 0x12c5: 0x008b,
+       0x12c6: 0x008d, 0x12c7: 0x008f, 0x12c8: 0x0091, 0x12c9: 0x0093, 0x12ca: 0x0095, 0x12cb: 0x0097,
+       0x12cc: 0x0099, 0x12cd: 0x009b, 0x12ce: 0x009d, 0x12cf: 0x009f, 0x12d0: 0x00a1, 0x12d1: 0x00a3,
+       0x12d2: 0x00a5, 0x12d3: 0x00a7, 0x12d4: 0x00a9, 0x12d5: 0x00ab, 0x12d6: 0x00ad, 0x12d7: 0x00af,
+       0x12d8: 0x00b1, 0x12d9: 0x00b3, 0x12da: 0x00b5, 0x12db: 0x00b7, 0x12dc: 0x00b9, 0x12dd: 0x00bb,
+       0x12de: 0x00bd, 0x12df: 0x047a, 0x12e0: 0x047e, 0x12e1: 0x048a, 0x12e2: 0x049e, 0x12e3: 0x04a2,
+       0x12e4: 0x0486, 0x12e5: 0x05ae, 0x12e6: 0x05a6, 0x12e7: 0x04ca, 0x12e8: 0x04d2, 0x12e9: 0x04da,
+       0x12ea: 0x04e2, 0x12eb: 0x04ea, 0x12ec: 0x056e, 0x12ed: 0x0576, 0x12ee: 0x057e, 0x12ef: 0x0522,
+       0x12f0: 0x05b2, 0x12f1: 0x04ce, 0x12f2: 0x04d6, 0x12f3: 0x04de, 0x12f4: 0x04e6, 0x12f5: 0x04ee,
+       0x12f6: 0x04f2, 0x12f7: 0x04f6, 0x12f8: 0x04fa, 0x12f9: 0x04fe, 0x12fa: 0x0502, 0x12fb: 0x0506,
+       0x12fc: 0x050a, 0x12fd: 0x050e, 0x12fe: 0x0512, 0x12ff: 0x0516,
+       // Block 0x4c, offset 0x1300
+       0x1300: 0x051a, 0x1301: 0x051e, 0x1302: 0x0526, 0x1303: 0x052a, 0x1304: 0x052e, 0x1305: 0x0532,
+       0x1306: 0x0536, 0x1307: 0x053a, 0x1308: 0x053e, 0x1309: 0x0542, 0x130a: 0x0546, 0x130b: 0x054a,
+       0x130c: 0x054e, 0x130d: 0x0552, 0x130e: 0x0556, 0x130f: 0x055a, 0x1310: 0x055e, 0x1311: 0x0562,
+       0x1312: 0x0566, 0x1313: 0x056a, 0x1314: 0x0572, 0x1315: 0x057a, 0x1316: 0x0582, 0x1317: 0x0586,
+       0x1318: 0x058a, 0x1319: 0x058e, 0x131a: 0x0592, 0x131b: 0x0596, 0x131c: 0x059a, 0x131d: 0x05aa,
+       0x131e: 0x4a8f, 0x131f: 0x4a95, 0x1320: 0x03c6, 0x1321: 0x0316, 0x1322: 0x031a, 0x1323: 0x4a52,
+       0x1324: 0x031e, 0x1325: 0x4a58, 0x1326: 0x4a5e, 0x1327: 0x0322, 0x1328: 0x0326, 0x1329: 0x032a,
+       0x132a: 0x4a64, 0x132b: 0x4a6a, 0x132c: 0x4a70, 0x132d: 0x4a76, 0x132e: 0x4a7c, 0x132f: 0x4a82,
+       0x1330: 0x036a, 0x1331: 0x032e, 0x1332: 0x0332, 0x1333: 0x0336, 0x1334: 0x037e, 0x1335: 0x033a,
+       0x1336: 0x033e, 0x1337: 0x0342, 0x1338: 0x0346, 0x1339: 0x034a, 0x133a: 0x034e, 0x133b: 0x0352,
+       0x133c: 0x0356, 0x133d: 0x035a, 0x133e: 0x035e,
+       // Block 0x4d, offset 0x1340
+       0x1342: 0x49d4, 0x1343: 0x49da, 0x1344: 0x49e0, 0x1345: 0x49e6,
+       0x1346: 0x49ec, 0x1347: 0x49f2, 0x134a: 0x49f8, 0x134b: 0x49fe,
+       0x134c: 0x4a04, 0x134d: 0x4a0a, 0x134e: 0x4a10, 0x134f: 0x4a16,
+       0x1352: 0x4a1c, 0x1353: 0x4a22, 0x1354: 0x4a28, 0x1355: 0x4a2e, 0x1356: 0x4a34, 0x1357: 0x4a3a,
+       0x135a: 0x4a40, 0x135b: 0x4a46, 0x135c: 0x4a4c,
+       0x1360: 0x00bf, 0x1361: 0x00c2, 0x1362: 0x00cb, 0x1363: 0x427b,
+       0x1364: 0x00c8, 0x1365: 0x00c5, 0x1366: 0x044a, 0x1368: 0x046e, 0x1369: 0x044e,
+       0x136a: 0x0452, 0x136b: 0x0456, 0x136c: 0x045a, 0x136d: 0x0472, 0x136e: 0x0476,
+       // Block 0x4e, offset 0x1380
+       0x1380: 0x0063, 0x1381: 0x0065, 0x1382: 0x0067, 0x1383: 0x0069, 0x1384: 0x006b, 0x1385: 0x006d,
+       0x1386: 0x006f, 0x1387: 0x0071, 0x1388: 0x0073, 0x1389: 0x0075, 0x138a: 0x0083, 0x138b: 0x0085,
+       0x138c: 0x0087, 0x138d: 0x0089, 0x138e: 0x008b, 0x138f: 0x008d, 0x1390: 0x008f, 0x1391: 0x0091,
+       0x1392: 0x0093, 0x1393: 0x0095, 0x1394: 0x0097, 0x1395: 0x0099, 0x1396: 0x009b, 0x1397: 0x009d,
+       0x1398: 0x009f, 0x1399: 0x00a1, 0x139a: 0x00a3, 0x139b: 0x00a5, 0x139c: 0x00a7, 0x139d: 0x00a9,
+       0x139e: 0x00ab, 0x139f: 0x00ad, 0x13a0: 0x00af, 0x13a1: 0x00b1, 0x13a2: 0x00b3, 0x13a3: 0x00b5,
+       0x13a4: 0x00dd, 0x13a5: 0x00f2, 0x13a8: 0x0176, 0x13a9: 0x0179,
+       0x13aa: 0x017c, 0x13ab: 0x017f, 0x13ac: 0x0182, 0x13ad: 0x0185, 0x13ae: 0x0188, 0x13af: 0x018b,
+       0x13b0: 0x018e, 0x13b1: 0x0191, 0x13b2: 0x0194, 0x13b3: 0x0197, 0x13b4: 0x019a, 0x13b5: 0x019d,
+       0x13b6: 0x01a0, 0x13b7: 0x01a3, 0x13b8: 0x01a6, 0x13b9: 0x018b, 0x13ba: 0x01a9, 0x13bb: 0x01ac,
+       0x13bc: 0x01af, 0x13bd: 0x01b2, 0x13be: 0x01b5, 0x13bf: 0x01b8,
+       // Block 0x4f, offset 0x13c0
+       0x13c0: 0x0200, 0x13c1: 0x0203, 0x13c2: 0x0206, 0x13c3: 0x045e, 0x13c4: 0x01ca, 0x13c5: 0x01d3,
+       0x13c6: 0x01d9, 0x13c7: 0x01fd, 0x13c8: 0x01ee, 0x13c9: 0x01eb, 0x13ca: 0x0209, 0x13cb: 0x020c,
+       0x13ce: 0x0021, 0x13cf: 0x0023, 0x13d0: 0x0025, 0x13d1: 0x0027,
+       0x13d2: 0x0029, 0x13d3: 0x002b, 0x13d4: 0x002d, 0x13d5: 0x002f, 0x13d6: 0x0031, 0x13d7: 0x0033,
+       0x13d8: 0x0021, 0x13d9: 0x0023, 0x13da: 0x0025, 0x13db: 0x0027, 0x13dc: 0x0029, 0x13dd: 0x002b,
+       0x13de: 0x002d, 0x13df: 0x002f, 0x13e0: 0x0031, 0x13e1: 0x0033, 0x13e2: 0x0021, 0x13e3: 0x0023,
+       0x13e4: 0x0025, 0x13e5: 0x0027, 0x13e6: 0x0029, 0x13e7: 0x002b, 0x13e8: 0x002d, 0x13e9: 0x002f,
+       0x13ea: 0x0031, 0x13eb: 0x0033, 0x13ec: 0x0021, 0x13ed: 0x0023, 0x13ee: 0x0025, 0x13ef: 0x0027,
+       0x13f0: 0x0029, 0x13f1: 0x002b, 0x13f2: 0x002d, 0x13f3: 0x002f, 0x13f4: 0x0031, 0x13f5: 0x0033,
+       0x13f6: 0x0021, 0x13f7: 0x0023, 0x13f8: 0x0025, 0x13f9: 0x0027, 0x13fa: 0x0029, 0x13fb: 0x002b,
+       0x13fc: 0x002d, 0x13fd: 0x002f, 0x13fe: 0x0031, 0x13ff: 0x0033,
+       // Block 0x50, offset 0x1400
+       0x1400: 0x023c, 0x1401: 0x023f, 0x1402: 0x024b, 0x1403: 0x0254, 0x1405: 0x028d,
+       0x1406: 0x025d, 0x1407: 0x024e, 0x1408: 0x026c, 0x1409: 0x0293, 0x140a: 0x027e, 0x140b: 0x0281,
+       0x140c: 0x0284, 0x140d: 0x0287, 0x140e: 0x0260, 0x140f: 0x0272, 0x1410: 0x0278, 0x1411: 0x0266,
+       0x1412: 0x027b, 0x1413: 0x025a, 0x1414: 0x0263, 0x1415: 0x0245, 0x1416: 0x0248, 0x1417: 0x0251,
+       0x1418: 0x0257, 0x1419: 0x0269, 0x141a: 0x026f, 0x141b: 0x0275, 0x141c: 0x0296, 0x141d: 0x02e7,
+       0x141e: 0x02cf, 0x141f: 0x0299, 0x1421: 0x023f, 0x1422: 0x024b,
+       0x1424: 0x028a, 0x1427: 0x024e, 0x1429: 0x0293,
+       0x142a: 0x027e, 0x142b: 0x0281, 0x142c: 0x0284, 0x142d: 0x0287, 0x142e: 0x0260, 0x142f: 0x0272,
+       0x1430: 0x0278, 0x1431: 0x0266, 0x1432: 0x027b, 0x1434: 0x0263, 0x1435: 0x0245,
+       0x1436: 0x0248, 0x1437: 0x0251, 0x1439: 0x0269, 0x143b: 0x0275,
+       // Block 0x51, offset 0x1440
+       0x1442: 0x024b,
+       0x1447: 0x024e, 0x1449: 0x0293, 0x144b: 0x0281,
+       0x144d: 0x0287, 0x144e: 0x0260, 0x144f: 0x0272, 0x1451: 0x0266,
+       0x1452: 0x027b, 0x1454: 0x0263, 0x1457: 0x0251,
+       0x1459: 0x0269, 0x145b: 0x0275, 0x145d: 0x02e7,
+       0x145f: 0x0299, 0x1461: 0x023f, 0x1462: 0x024b,
+       0x1464: 0x028a, 0x1467: 0x024e, 0x1468: 0x026c, 0x1469: 0x0293,
+       0x146a: 0x027e, 0x146c: 0x0284, 0x146d: 0x0287, 0x146e: 0x0260, 0x146f: 0x0272,
+       0x1470: 0x0278, 0x1471: 0x0266, 0x1472: 0x027b, 0x1474: 0x0263, 0x1475: 0x0245,
+       0x1476: 0x0248, 0x1477: 0x0251, 0x1479: 0x0269, 0x147a: 0x026f, 0x147b: 0x0275,
+       0x147c: 0x0296, 0x147e: 0x02cf,
+       // Block 0x52, offset 0x1480
+       0x1480: 0x023c, 0x1481: 0x023f, 0x1482: 0x024b, 0x1483: 0x0254, 0x1484: 0x028a, 0x1485: 0x028d,
+       0x1486: 0x025d, 0x1487: 0x024e, 0x1488: 0x026c, 0x1489: 0x0293, 0x148b: 0x0281,
+       0x148c: 0x0284, 0x148d: 0x0287, 0x148e: 0x0260, 0x148f: 0x0272, 0x1490: 0x0278, 0x1491: 0x0266,
+       0x1492: 0x027b, 0x1493: 0x025a, 0x1494: 0x0263, 0x1495: 0x0245, 0x1496: 0x0248, 0x1497: 0x0251,
+       0x1498: 0x0257, 0x1499: 0x0269, 0x149a: 0x026f, 0x149b: 0x0275,
+       0x14a1: 0x023f, 0x14a2: 0x024b, 0x14a3: 0x0254,
+       0x14a5: 0x028d, 0x14a6: 0x025d, 0x14a7: 0x024e, 0x14a8: 0x026c, 0x14a9: 0x0293,
+       0x14ab: 0x0281, 0x14ac: 0x0284, 0x14ad: 0x0287, 0x14ae: 0x0260, 0x14af: 0x0272,
+       0x14b0: 0x0278, 0x14b1: 0x0266, 0x14b2: 0x027b, 0x14b3: 0x025a, 0x14b4: 0x0263, 0x14b5: 0x0245,
+       0x14b6: 0x0248, 0x14b7: 0x0251, 0x14b8: 0x0257, 0x14b9: 0x0269, 0x14ba: 0x026f, 0x14bb: 0x0275,
+       // Block 0x53, offset 0x14c0
+       0x14c0: 0x187c, 0x14c1: 0x1879, 0x14c2: 0x187f, 0x14c3: 0x18a3, 0x14c4: 0x18c7, 0x14c5: 0x18eb,
+       0x14c6: 0x190f, 0x14c7: 0x1918, 0x14c8: 0x191e, 0x14c9: 0x1924, 0x14ca: 0x192a,
+       0x14d0: 0x1a92, 0x14d1: 0x1a96,
+       0x14d2: 0x1a9a, 0x14d3: 0x1a9e, 0x14d4: 0x1aa2, 0x14d5: 0x1aa6, 0x14d6: 0x1aaa, 0x14d7: 0x1aae,
+       0x14d8: 0x1ab2, 0x14d9: 0x1ab6, 0x14da: 0x1aba, 0x14db: 0x1abe, 0x14dc: 0x1ac2, 0x14dd: 0x1ac6,
+       0x14de: 0x1aca, 0x14df: 0x1ace, 0x14e0: 0x1ad2, 0x14e1: 0x1ad6, 0x14e2: 0x1ada, 0x14e3: 0x1ade,
+       0x14e4: 0x1ae2, 0x14e5: 0x1ae6, 0x14e6: 0x1aea, 0x14e7: 0x1aee, 0x14e8: 0x1af2, 0x14e9: 0x1af6,
+       0x14ea: 0x272b, 0x14eb: 0x0047, 0x14ec: 0x0065, 0x14ed: 0x193f, 0x14ee: 0x19b7,
+       0x14f0: 0x0043, 0x14f1: 0x0045, 0x14f2: 0x0047, 0x14f3: 0x0049, 0x14f4: 0x004b, 0x14f5: 0x004d,
+       0x14f6: 0x004f, 0x14f7: 0x0051, 0x14f8: 0x0053, 0x14f9: 0x0055, 0x14fa: 0x0057, 0x14fb: 0x0059,
+       0x14fc: 0x005b, 0x14fd: 0x005d, 0x14fe: 0x005f, 0x14ff: 0x0061,
+       // Block 0x54, offset 0x1500
+       0x1500: 0x26b3, 0x1501: 0x26c8, 0x1502: 0x0506,
+       0x1510: 0x0c12, 0x1511: 0x0a4a,
+       0x1512: 0x08d6, 0x1513: 0x45db, 0x1514: 0x071e, 0x1515: 0x09f2, 0x1516: 0x1332, 0x1517: 0x0a02,
+       0x1518: 0x072a, 0x1519: 0x0cda, 0x151a: 0x0eb2, 0x151b: 0x0cb2, 0x151c: 0x082a, 0x151d: 0x0b6e,
+       0x151e: 0x07c2, 0x151f: 0x0cba, 0x1520: 0x0816, 0x1521: 0x111a, 0x1522: 0x0f86, 0x1523: 0x138e,
+       0x1524: 0x09d6, 0x1525: 0x090e, 0x1526: 0x0e66, 0x1527: 0x0c1e, 0x1528: 0x0c4a, 0x1529: 0x06c2,
+       0x152a: 0x06ce, 0x152b: 0x140e, 0x152c: 0x0ade, 0x152d: 0x06ea, 0x152e: 0x08f2, 0x152f: 0x0c3e,
+       0x1530: 0x13b6, 0x1531: 0x0c16, 0x1532: 0x1072, 0x1533: 0x10ae, 0x1534: 0x08fa, 0x1535: 0x0e46,
+       0x1536: 0x0d0e, 0x1537: 0x0d0a, 0x1538: 0x0f9a, 0x1539: 0x082e, 0x153a: 0x095a, 0x153b: 0x1446,
+       // Block 0x55, offset 0x1540
+       0x1540: 0x06fe, 0x1541: 0x06f6, 0x1542: 0x0706, 0x1543: 0x164a, 0x1544: 0x074a, 0x1545: 0x075a,
+       0x1546: 0x075e, 0x1547: 0x0766, 0x1548: 0x076e, 0x1549: 0x0772, 0x154a: 0x077e, 0x154b: 0x0776,
+       0x154c: 0x05b6, 0x154d: 0x165e, 0x154e: 0x0792, 0x154f: 0x0796, 0x1550: 0x079a, 0x1551: 0x07b6,
+       0x1552: 0x164f, 0x1553: 0x05ba, 0x1554: 0x07a2, 0x1555: 0x07c2, 0x1556: 0x1659, 0x1557: 0x07d2,
+       0x1558: 0x07da, 0x1559: 0x073a, 0x155a: 0x07e2, 0x155b: 0x07e6, 0x155c: 0x1834, 0x155d: 0x0802,
+       0x155e: 0x080a, 0x155f: 0x05c2, 0x1560: 0x0822, 0x1561: 0x0826, 0x1562: 0x082e, 0x1563: 0x0832,
+       0x1564: 0x05c6, 0x1565: 0x084a, 0x1566: 0x084e, 0x1567: 0x085a, 0x1568: 0x0866, 0x1569: 0x086a,
+       0x156a: 0x086e, 0x156b: 0x0876, 0x156c: 0x0896, 0x156d: 0x089a, 0x156e: 0x08a2, 0x156f: 0x08b2,
+       0x1570: 0x08ba, 0x1571: 0x08be, 0x1572: 0x08be, 0x1573: 0x08be, 0x1574: 0x166d, 0x1575: 0x0e96,
+       0x1576: 0x08d2, 0x1577: 0x08da, 0x1578: 0x1672, 0x1579: 0x08e6, 0x157a: 0x08ee, 0x157b: 0x08f6,
+       0x157c: 0x091e, 0x157d: 0x090a, 0x157e: 0x0916, 0x157f: 0x091a,
+       // Block 0x56, offset 0x1580
+       0x1580: 0x0922, 0x1581: 0x092a, 0x1582: 0x092e, 0x1583: 0x0936, 0x1584: 0x093e, 0x1585: 0x0942,
+       0x1586: 0x0942, 0x1587: 0x094a, 0x1588: 0x0952, 0x1589: 0x0956, 0x158a: 0x0962, 0x158b: 0x0986,
+       0x158c: 0x096a, 0x158d: 0x098a, 0x158e: 0x096e, 0x158f: 0x0976, 0x1590: 0x080e, 0x1591: 0x09d2,
+       0x1592: 0x099a, 0x1593: 0x099e, 0x1594: 0x09a2, 0x1595: 0x0996, 0x1596: 0x09aa, 0x1597: 0x09a6,
+       0x1598: 0x09be, 0x1599: 0x1677, 0x159a: 0x09da, 0x159b: 0x09de, 0x159c: 0x09e6, 0x159d: 0x09f2,
+       0x159e: 0x09fa, 0x159f: 0x0a16, 0x15a0: 0x167c, 0x15a1: 0x1681, 0x15a2: 0x0a22, 0x15a3: 0x0a26,
+       0x15a4: 0x0a2a, 0x15a5: 0x0a1e, 0x15a6: 0x0a32, 0x15a7: 0x05ca, 0x15a8: 0x05ce, 0x15a9: 0x0a3a,
+       0x15aa: 0x0a42, 0x15ab: 0x0a42, 0x15ac: 0x1686, 0x15ad: 0x0a5e, 0x15ae: 0x0a62, 0x15af: 0x0a66,
+       0x15b0: 0x0a6e, 0x15b1: 0x168b, 0x15b2: 0x0a76, 0x15b3: 0x0a7a, 0x15b4: 0x0b52, 0x15b5: 0x0a82,
+       0x15b6: 0x05d2, 0x15b7: 0x0a8e, 0x15b8: 0x0a9e, 0x15b9: 0x0aaa, 0x15ba: 0x0aa6, 0x15bb: 0x1695,
+       0x15bc: 0x0ab2, 0x15bd: 0x169a, 0x15be: 0x0abe, 0x15bf: 0x0aba,
+       // Block 0x57, offset 0x15c0
+       0x15c0: 0x0ac2, 0x15c1: 0x0ad2, 0x15c2: 0x0ad6, 0x15c3: 0x05d6, 0x15c4: 0x0ae6, 0x15c5: 0x0aee,
+       0x15c6: 0x0af2, 0x15c7: 0x0af6, 0x15c8: 0x05da, 0x15c9: 0x169f, 0x15ca: 0x05de, 0x15cb: 0x0b12,
+       0x15cc: 0x0b16, 0x15cd: 0x0b1a, 0x15ce: 0x0b22, 0x15cf: 0x1866, 0x15d0: 0x0b3a, 0x15d1: 0x16a9,
+       0x15d2: 0x16a9, 0x15d3: 0x11da, 0x15d4: 0x0b4a, 0x15d5: 0x0b4a, 0x15d6: 0x05e2, 0x15d7: 0x16cc,
+       0x15d8: 0x179e, 0x15d9: 0x0b5a, 0x15da: 0x0b62, 0x15db: 0x05e6, 0x15dc: 0x0b76, 0x15dd: 0x0b86,
+       0x15de: 0x0b8a, 0x15df: 0x0b92, 0x15e0: 0x0ba2, 0x15e1: 0x05ee, 0x15e2: 0x05ea, 0x15e3: 0x0ba6,
+       0x15e4: 0x16ae, 0x15e5: 0x0baa, 0x15e6: 0x0bbe, 0x15e7: 0x0bc2, 0x15e8: 0x0bc6, 0x15e9: 0x0bc2,
+       0x15ea: 0x0bd2, 0x15eb: 0x0bd6, 0x15ec: 0x0be6, 0x15ed: 0x0bde, 0x15ee: 0x0be2, 0x15ef: 0x0bea,
+       0x15f0: 0x0bee, 0x15f1: 0x0bf2, 0x15f2: 0x0bfe, 0x15f3: 0x0c02, 0x15f4: 0x0c1a, 0x15f5: 0x0c22,
+       0x15f6: 0x0c32, 0x15f7: 0x0c46, 0x15f8: 0x16bd, 0x15f9: 0x0c42, 0x15fa: 0x0c36, 0x15fb: 0x0c4e,
+       0x15fc: 0x0c56, 0x15fd: 0x0c6a, 0x15fe: 0x16c2, 0x15ff: 0x0c72,
+       // Block 0x58, offset 0x1600
+       0x1600: 0x0c66, 0x1601: 0x0c5e, 0x1602: 0x05f2, 0x1603: 0x0c7a, 0x1604: 0x0c82, 0x1605: 0x0c8a,
+       0x1606: 0x0c7e, 0x1607: 0x05f6, 0x1608: 0x0c9a, 0x1609: 0x0ca2, 0x160a: 0x16c7, 0x160b: 0x0cce,
+       0x160c: 0x0d02, 0x160d: 0x0cde, 0x160e: 0x0602, 0x160f: 0x0cea, 0x1610: 0x05fe, 0x1611: 0x05fa,
+       0x1612: 0x07c6, 0x1613: 0x07ca, 0x1614: 0x0d06, 0x1615: 0x0cee, 0x1616: 0x11ae, 0x1617: 0x0666,
+       0x1618: 0x0d12, 0x1619: 0x0d16, 0x161a: 0x0d1a, 0x161b: 0x0d2e, 0x161c: 0x0d26, 0x161d: 0x16e0,
+       0x161e: 0x0606, 0x161f: 0x0d42, 0x1620: 0x0d36, 0x1621: 0x0d52, 0x1622: 0x0d5a, 0x1623: 0x16ea,
+       0x1624: 0x0d5e, 0x1625: 0x0d4a, 0x1626: 0x0d66, 0x1627: 0x060a, 0x1628: 0x0d6a, 0x1629: 0x0d6e,
+       0x162a: 0x0d72, 0x162b: 0x0d7e, 0x162c: 0x16ef, 0x162d: 0x0d86, 0x162e: 0x060e, 0x162f: 0x0d92,
+       0x1630: 0x16f4, 0x1631: 0x0d96, 0x1632: 0x0612, 0x1633: 0x0da2, 0x1634: 0x0dae, 0x1635: 0x0dba,
+       0x1636: 0x0dbe, 0x1637: 0x16f9, 0x1638: 0x1690, 0x1639: 0x16fe, 0x163a: 0x0dde, 0x163b: 0x1703,
+       0x163c: 0x0dea, 0x163d: 0x0df2, 0x163e: 0x0de2, 0x163f: 0x0dfe,
+       // Block 0x59, offset 0x1640
+       0x1640: 0x0e0e, 0x1641: 0x0e1e, 0x1642: 0x0e12, 0x1643: 0x0e16, 0x1644: 0x0e22, 0x1645: 0x0e26,
+       0x1646: 0x1708, 0x1647: 0x0e0a, 0x1648: 0x0e3e, 0x1649: 0x0e42, 0x164a: 0x0616, 0x164b: 0x0e56,
+       0x164c: 0x0e52, 0x164d: 0x170d, 0x164e: 0x0e36, 0x164f: 0x0e72, 0x1650: 0x1712, 0x1651: 0x1717,
+       0x1652: 0x0e76, 0x1653: 0x0e8a, 0x1654: 0x0e86, 0x1655: 0x0e82, 0x1656: 0x061a, 0x1657: 0x0e8e,
+       0x1658: 0x0e9e, 0x1659: 0x0e9a, 0x165a: 0x0ea6, 0x165b: 0x1654, 0x165c: 0x0eb6, 0x165d: 0x171c,
+       0x165e: 0x0ec2, 0x165f: 0x1726, 0x1660: 0x0ed6, 0x1661: 0x0ee2, 0x1662: 0x0ef6, 0x1663: 0x172b,
+       0x1664: 0x0f0a, 0x1665: 0x0f0e, 0x1666: 0x1730, 0x1667: 0x1735, 0x1668: 0x0f2a, 0x1669: 0x0f3a,
+       0x166a: 0x061e, 0x166b: 0x0f3e, 0x166c: 0x0622, 0x166d: 0x0622, 0x166e: 0x0f56, 0x166f: 0x0f5a,
+       0x1670: 0x0f62, 0x1671: 0x0f66, 0x1672: 0x0f72, 0x1673: 0x0626, 0x1674: 0x0f8a, 0x1675: 0x173a,
+       0x1676: 0x0fa6, 0x1677: 0x173f, 0x1678: 0x0fb2, 0x1679: 0x16a4, 0x167a: 0x0fc2, 0x167b: 0x1744,
+       0x167c: 0x1749, 0x167d: 0x174e, 0x167e: 0x062a, 0x167f: 0x062e,
+       // Block 0x5a, offset 0x1680
+       0x1680: 0x0ffa, 0x1681: 0x1758, 0x1682: 0x1753, 0x1683: 0x175d, 0x1684: 0x1762, 0x1685: 0x1002,
+       0x1686: 0x1006, 0x1687: 0x1006, 0x1688: 0x100e, 0x1689: 0x0636, 0x168a: 0x1012, 0x168b: 0x063a,
+       0x168c: 0x063e, 0x168d: 0x176c, 0x168e: 0x1026, 0x168f: 0x102e, 0x1690: 0x103a, 0x1691: 0x0642,
+       0x1692: 0x1771, 0x1693: 0x105e, 0x1694: 0x1776, 0x1695: 0x177b, 0x1696: 0x107e, 0x1697: 0x1096,
+       0x1698: 0x0646, 0x1699: 0x109e, 0x169a: 0x10a2, 0x169b: 0x10a6, 0x169c: 0x1780, 0x169d: 0x1785,
+       0x169e: 0x1785, 0x169f: 0x10be, 0x16a0: 0x064a, 0x16a1: 0x178a, 0x16a2: 0x10d2, 0x16a3: 0x10d6,
+       0x16a4: 0x064e, 0x16a5: 0x178f, 0x16a6: 0x10f2, 0x16a7: 0x0652, 0x16a8: 0x1102, 0x16a9: 0x10fa,
+       0x16aa: 0x110a, 0x16ab: 0x1799, 0x16ac: 0x1122, 0x16ad: 0x0656, 0x16ae: 0x112e, 0x16af: 0x1136,
+       0x16b0: 0x1146, 0x16b1: 0x065a, 0x16b2: 0x17a3, 0x16b3: 0x17a8, 0x16b4: 0x065e, 0x16b5: 0x17ad,
+       0x16b6: 0x115e, 0x16b7: 0x17b2, 0x16b8: 0x116a, 0x16b9: 0x1176, 0x16ba: 0x117e, 0x16bb: 0x17b7,
+       0x16bc: 0x17bc, 0x16bd: 0x1192, 0x16be: 0x17c1, 0x16bf: 0x119a,
+       // Block 0x5b, offset 0x16c0
+       0x16c0: 0x16d1, 0x16c1: 0x0662, 0x16c2: 0x11b2, 0x16c3: 0x11b6, 0x16c4: 0x066a, 0x16c5: 0x11ba,
+       0x16c6: 0x0a36, 0x16c7: 0x17c6, 0x16c8: 0x17cb, 0x16c9: 0x16d6, 0x16ca: 0x16db, 0x16cb: 0x11da,
+       0x16cc: 0x11de, 0x16cd: 0x13f6, 0x16ce: 0x066e, 0x16cf: 0x120a, 0x16d0: 0x1206, 0x16d1: 0x120e,
+       0x16d2: 0x0842, 0x16d3: 0x1212, 0x16d4: 0x1216, 0x16d5: 0x121a, 0x16d6: 0x1222, 0x16d7: 0x17d0,
+       0x16d8: 0x121e, 0x16d9: 0x1226, 0x16da: 0x123a, 0x16db: 0x123e, 0x16dc: 0x122a, 0x16dd: 0x1242,
+       0x16de: 0x1256, 0x16df: 0x126a, 0x16e0: 0x1236, 0x16e1: 0x124a, 0x16e2: 0x124e, 0x16e3: 0x1252,
+       0x16e4: 0x17d5, 0x16e5: 0x17df, 0x16e6: 0x17da, 0x16e7: 0x0672, 0x16e8: 0x1272, 0x16e9: 0x1276,
+       0x16ea: 0x127e, 0x16eb: 0x17f3, 0x16ec: 0x1282, 0x16ed: 0x17e4, 0x16ee: 0x0676, 0x16ef: 0x067a,
+       0x16f0: 0x17e9, 0x16f1: 0x17ee, 0x16f2: 0x067e, 0x16f3: 0x12a2, 0x16f4: 0x12a6, 0x16f5: 0x12aa,
+       0x16f6: 0x12ae, 0x16f7: 0x12ba, 0x16f8: 0x12b6, 0x16f9: 0x12c2, 0x16fa: 0x12be, 0x16fb: 0x12ce,
+       0x16fc: 0x12c6, 0x16fd: 0x12ca, 0x16fe: 0x12d2, 0x16ff: 0x0682,
+       // Block 0x5c, offset 0x1700
+       0x1700: 0x12da, 0x1701: 0x12de, 0x1702: 0x0686, 0x1703: 0x12ee, 0x1704: 0x12f2, 0x1705: 0x17f8,
+       0x1706: 0x12fe, 0x1707: 0x1302, 0x1708: 0x068a, 0x1709: 0x130e, 0x170a: 0x05be, 0x170b: 0x17fd,
+       0x170c: 0x1802, 0x170d: 0x068e, 0x170e: 0x0692, 0x170f: 0x133a, 0x1710: 0x1352, 0x1711: 0x136e,
+       0x1712: 0x137e, 0x1713: 0x1807, 0x1714: 0x1392, 0x1715: 0x1396, 0x1716: 0x13ae, 0x1717: 0x13ba,
+       0x1718: 0x1811, 0x1719: 0x1663, 0x171a: 0x13c6, 0x171b: 0x13c2, 0x171c: 0x13ce, 0x171d: 0x1668,
+       0x171e: 0x13da, 0x171f: 0x13e6, 0x1720: 0x1816, 0x1721: 0x181b, 0x1722: 0x1426, 0x1723: 0x1432,
+       0x1724: 0x143a, 0x1725: 0x1820, 0x1726: 0x143e, 0x1727: 0x146a, 0x1728: 0x1476, 0x1729: 0x147a,
+       0x172a: 0x1472, 0x172b: 0x1486, 0x172c: 0x148a, 0x172d: 0x1825, 0x172e: 0x1496, 0x172f: 0x0696,
+       0x1730: 0x149e, 0x1731: 0x182a, 0x1732: 0x069a, 0x1733: 0x14d6, 0x1734: 0x0ac6, 0x1735: 0x14ee,
+       0x1736: 0x182f, 0x1737: 0x1839, 0x1738: 0x069e, 0x1739: 0x06a2, 0x173a: 0x1516, 0x173b: 0x183e,
+       0x173c: 0x06a6, 0x173d: 0x1843, 0x173e: 0x152e, 0x173f: 0x152e,
+       // Block 0x5d, offset 0x1740
+       0x1740: 0x1536, 0x1741: 0x1848, 0x1742: 0x154e, 0x1743: 0x06aa, 0x1744: 0x155e, 0x1745: 0x156a,
+       0x1746: 0x1572, 0x1747: 0x157a, 0x1748: 0x06ae, 0x1749: 0x184d, 0x174a: 0x158e, 0x174b: 0x15aa,
+       0x174c: 0x15b6, 0x174d: 0x06b2, 0x174e: 0x06b6, 0x174f: 0x15ba, 0x1750: 0x1852, 0x1751: 0x06ba,
+       0x1752: 0x1857, 0x1753: 0x185c, 0x1754: 0x1861, 0x1755: 0x15de, 0x1756: 0x06be, 0x1757: 0x15f2,
+       0x1758: 0x15fa, 0x1759: 0x15fe, 0x175a: 0x1606, 0x175b: 0x160e, 0x175c: 0x1616, 0x175d: 0x186b,
+}
+
+// nfkcIndex: 22 blocks, 1408 entries, 2816 bytes
+// Block 0 is the zero block.
+var nfkcIndex = [1408]uint16{
+       // Block 0x0, offset 0x0
+       // Block 0x1, offset 0x40
+       // Block 0x2, offset 0x80
+       // Block 0x3, offset 0xc0
+       0xc2: 0x5c, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x5d, 0xc7: 0x04,
+       0xc8: 0x05, 0xca: 0x5e, 0xcb: 0x5f, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x09,
+       0xd0: 0x0a, 0xd1: 0x60, 0xd2: 0x61, 0xd3: 0x0b, 0xd6: 0x0c, 0xd7: 0x62,
+       0xd8: 0x63, 0xd9: 0x0d, 0xdb: 0x64, 0xdc: 0x65, 0xdd: 0x66, 0xdf: 0x67,
+       0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05,
+       0xea: 0x06, 0xeb: 0x07, 0xec: 0x08, 0xed: 0x09, 0xef: 0x0a,
+       0xf0: 0x13,
+       // Block 0x4, offset 0x100
+       0x120: 0x68, 0x121: 0x69, 0x123: 0x0e, 0x124: 0x6a, 0x125: 0x6b, 0x126: 0x6c, 0x127: 0x6d,
+       0x128: 0x6e, 0x129: 0x6f, 0x12a: 0x70, 0x12b: 0x71, 0x12c: 0x6c, 0x12d: 0x72, 0x12e: 0x73, 0x12f: 0x74,
+       0x131: 0x75, 0x132: 0x76, 0x133: 0x77, 0x134: 0x78, 0x135: 0x79, 0x137: 0x7a,
+       0x138: 0x7b, 0x139: 0x7c, 0x13a: 0x7d, 0x13b: 0x7e, 0x13c: 0x7f, 0x13d: 0x80, 0x13e: 0x81, 0x13f: 0x82,
+       // Block 0x5, offset 0x140
+       0x140: 0x83, 0x142: 0x84, 0x143: 0x85, 0x144: 0x86, 0x145: 0x87, 0x146: 0x88, 0x147: 0x89,
+       0x14d: 0x8a,
+       0x15c: 0x8b, 0x15f: 0x8c,
+       0x162: 0x8d, 0x164: 0x8e,
+       0x168: 0x8f, 0x169: 0x90, 0x16a: 0x91, 0x16b: 0x92, 0x16c: 0x0f, 0x16d: 0x93, 0x16e: 0x94, 0x16f: 0x95,
+       0x170: 0x96, 0x173: 0x97, 0x174: 0x98, 0x175: 0x10, 0x176: 0x11, 0x177: 0x12,
+       0x178: 0x13, 0x179: 0x14, 0x17a: 0x15, 0x17b: 0x16, 0x17c: 0x17, 0x17d: 0x18, 0x17e: 0x19, 0x17f: 0x1a,
+       // Block 0x6, offset 0x180
+       0x180: 0x99, 0x181: 0x9a, 0x182: 0x9b, 0x183: 0x9c, 0x184: 0x1b, 0x185: 0x1c, 0x186: 0x9d, 0x187: 0x9e,
+       0x188: 0x9f, 0x189: 0x1d, 0x18a: 0x1e, 0x18b: 0xa0, 0x18c: 0xa1,
+       0x191: 0x1f, 0x192: 0x20, 0x193: 0xa2,
+       0x1a8: 0xa3, 0x1a9: 0xa4, 0x1ab: 0xa5,
+       0x1b1: 0xa6, 0x1b3: 0xa7, 0x1b5: 0xa8, 0x1b7: 0xa9,
+       0x1ba: 0xaa, 0x1bb: 0xab, 0x1bc: 0x21, 0x1bd: 0x22, 0x1be: 0x23, 0x1bf: 0xac,
+       // Block 0x7, offset 0x1c0
+       0x1c0: 0xad, 0x1c1: 0x24, 0x1c2: 0x25, 0x1c3: 0x26, 0x1c4: 0xae, 0x1c5: 0x27, 0x1c6: 0x28,
+       0x1c8: 0x29, 0x1c9: 0x2a, 0x1ca: 0x2b, 0x1cb: 0x2c, 0x1cc: 0x2d, 0x1cd: 0x2e, 0x1ce: 0x2f, 0x1cf: 0x30,
+       // Block 0x8, offset 0x200
+       0x219: 0xaf, 0x21a: 0xb0, 0x21b: 0xb1, 0x21d: 0xb2, 0x21f: 0xb3,
+       0x220: 0xb4, 0x223: 0xb5, 0x224: 0xb6, 0x225: 0xb7, 0x226: 0xb8, 0x227: 0xb9,
+       0x22a: 0xba, 0x22b: 0xbb, 0x22d: 0xbc, 0x22f: 0xbd,
+       0x230: 0xbe, 0x231: 0xbf, 0x232: 0xc0, 0x233: 0xc1, 0x234: 0xc2, 0x235: 0xc3, 0x236: 0xc4, 0x237: 0xbe,
+       0x238: 0xbf, 0x239: 0xc0, 0x23a: 0xc1, 0x23b: 0xc2, 0x23c: 0xc3, 0x23d: 0xc4, 0x23e: 0xbe, 0x23f: 0xbf,
+       // Block 0x9, offset 0x240
+       0x240: 0xc0, 0x241: 0xc1, 0x242: 0xc2, 0x243: 0xc3, 0x244: 0xc4, 0x245: 0xbe, 0x246: 0xbf, 0x247: 0xc0,
+       0x248: 0xc1, 0x249: 0xc2, 0x24a: 0xc3, 0x24b: 0xc4, 0x24c: 0xbe, 0x24d: 0xbf, 0x24e: 0xc0, 0x24f: 0xc1,
+       0x250: 0xc2, 0x251: 0xc3, 0x252: 0xc4, 0x253: 0xbe, 0x254: 0xbf, 0x255: 0xc0, 0x256: 0xc1, 0x257: 0xc2,
+       0x258: 0xc3, 0x259: 0xc4, 0x25a: 0xbe, 0x25b: 0xbf, 0x25c: 0xc0, 0x25d: 0xc1, 0x25e: 0xc2, 0x25f: 0xc3,
+       0x260: 0xc4, 0x261: 0xbe, 0x262: 0xbf, 0x263: 0xc0, 0x264: 0xc1, 0x265: 0xc2, 0x266: 0xc3, 0x267: 0xc4,
+       0x268: 0xbe, 0x269: 0xbf, 0x26a: 0xc0, 0x26b: 0xc1, 0x26c: 0xc2, 0x26d: 0xc3, 0x26e: 0xc4, 0x26f: 0xbe,
+       0x270: 0xbf, 0x271: 0xc0, 0x272: 0xc1, 0x273: 0xc2, 0x274: 0xc3, 0x275: 0xc4, 0x276: 0xbe, 0x277: 0xbf,
+       0x278: 0xc0, 0x279: 0xc1, 0x27a: 0xc2, 0x27b: 0xc3, 0x27c: 0xc4, 0x27d: 0xbe, 0x27e: 0xbf, 0x27f: 0xc0,
+       // Block 0xa, offset 0x280
+       0x280: 0xc1, 0x281: 0xc2, 0x282: 0xc3, 0x283: 0xc4, 0x284: 0xbe, 0x285: 0xbf, 0x286: 0xc0, 0x287: 0xc1,
+       0x288: 0xc2, 0x289: 0xc3, 0x28a: 0xc4, 0x28b: 0xbe, 0x28c: 0xbf, 0x28d: 0xc0, 0x28e: 0xc1, 0x28f: 0xc2,
+       0x290: 0xc3, 0x291: 0xc4, 0x292: 0xbe, 0x293: 0xbf, 0x294: 0xc0, 0x295: 0xc1, 0x296: 0xc2, 0x297: 0xc3,
+       0x298: 0xc4, 0x299: 0xbe, 0x29a: 0xbf, 0x29b: 0xc0, 0x29c: 0xc1, 0x29d: 0xc2, 0x29e: 0xc3, 0x29f: 0xc4,
+       0x2a0: 0xbe, 0x2a1: 0xbf, 0x2a2: 0xc0, 0x2a3: 0xc1, 0x2a4: 0xc2, 0x2a5: 0xc3, 0x2a6: 0xc4, 0x2a7: 0xbe,
+       0x2a8: 0xbf, 0x2a9: 0xc0, 0x2aa: 0xc1, 0x2ab: 0xc2, 0x2ac: 0xc3, 0x2ad: 0xc4, 0x2ae: 0xbe, 0x2af: 0xbf,
+       0x2b0: 0xc0, 0x2b1: 0xc1, 0x2b2: 0xc2, 0x2b3: 0xc3, 0x2b4: 0xc4, 0x2b5: 0xbe, 0x2b6: 0xbf, 0x2b7: 0xc0,
+       0x2b8: 0xc1, 0x2b9: 0xc2, 0x2ba: 0xc3, 0x2bb: 0xc4, 0x2bc: 0xbe, 0x2bd: 0xbf, 0x2be: 0xc0, 0x2bf: 0xc1,
+       // Block 0xb, offset 0x2c0
+       0x2c0: 0xc2, 0x2c1: 0xc3, 0x2c2: 0xc4, 0x2c3: 0xbe, 0x2c4: 0xbf, 0x2c5: 0xc0, 0x2c6: 0xc1, 0x2c7: 0xc2,
+       0x2c8: 0xc3, 0x2c9: 0xc4, 0x2ca: 0xbe, 0x2cb: 0xbf, 0x2cc: 0xc0, 0x2cd: 0xc1, 0x2ce: 0xc2, 0x2cf: 0xc3,
+       0x2d0: 0xc4, 0x2d1: 0xbe, 0x2d2: 0xbf, 0x2d3: 0xc0, 0x2d4: 0xc1, 0x2d5: 0xc2, 0x2d6: 0xc3, 0x2d7: 0xc4,
+       0x2d8: 0xbe, 0x2d9: 0xbf, 0x2da: 0xc0, 0x2db: 0xc1, 0x2dc: 0xc2, 0x2dd: 0xc3, 0x2de: 0xc5,
+       // Block 0xc, offset 0x300
+       0x324: 0x31, 0x325: 0x32, 0x326: 0x33, 0x327: 0x34,
+       0x328: 0x35, 0x329: 0x36, 0x32a: 0x37, 0x32b: 0x38, 0x32c: 0x39, 0x32d: 0x3a, 0x32e: 0x3b, 0x32f: 0x3c,
+       0x330: 0x3d, 0x331: 0x3e, 0x332: 0x3f, 0x333: 0x40, 0x334: 0x41, 0x335: 0x42, 0x336: 0x43, 0x337: 0x44,
+       0x338: 0x45, 0x339: 0x46, 0x33a: 0x47, 0x33b: 0x48, 0x33c: 0xc6, 0x33d: 0x49, 0x33e: 0x4a, 0x33f: 0x4b,
+       // Block 0xd, offset 0x340
+       0x347: 0xc7,
+       0x34b: 0xc8, 0x34d: 0xc9,
+       0x368: 0xca, 0x36b: 0xcb,
+       0x374: 0xcc,
+       0x37a: 0xcd, 0x37d: 0xce,
+       // Block 0xe, offset 0x380
+       0x381: 0xcf, 0x382: 0xd0, 0x384: 0xd1, 0x385: 0xb8, 0x387: 0xd2,
+       0x388: 0xd3, 0x38b: 0xd4, 0x38c: 0xd5, 0x38d: 0xd6,
+       0x391: 0xd7, 0x392: 0xd8, 0x393: 0xd9, 0x396: 0xda, 0x397: 0xdb,
+       0x398: 0xdc, 0x39a: 0xdd, 0x39c: 0xde,
+       0x3a0: 0xdf, 0x3a4: 0xe0, 0x3a5: 0xe1, 0x3a7: 0xe2,
+       0x3a8: 0xe3, 0x3a9: 0xe4, 0x3aa: 0xe5,
+       0x3b0: 0xdc, 0x3b5: 0xe6, 0x3b6: 0xe7,
+       // Block 0xf, offset 0x3c0
+       0x3eb: 0xe8, 0x3ec: 0xe9,
+       0x3ff: 0xea,
+       // Block 0x10, offset 0x400
+       0x432: 0xeb,
+       // Block 0x11, offset 0x440
+       0x445: 0xec, 0x446: 0xed, 0x447: 0xee,
+       0x449: 0xef,
+       0x450: 0xf0, 0x451: 0xf1, 0x452: 0xf2, 0x453: 0xf3, 0x454: 0xf4, 0x455: 0xf5, 0x456: 0xf6, 0x457: 0xf7,
+       0x458: 0xf8, 0x459: 0xf9, 0x45a: 0x4c, 0x45b: 0xfa, 0x45c: 0xfb, 0x45d: 0xfc, 0x45e: 0xfd, 0x45f: 0x4d,
+       // Block 0x12, offset 0x480
+       0x480: 0xfe, 0x484: 0xe9,
+       0x48b: 0xff,
+       0x4a3: 0x100, 0x4a5: 0x101,
+       0x4b8: 0x4e, 0x4b9: 0x4f, 0x4ba: 0x50,
+       // Block 0x13, offset 0x4c0
+       0x4c4: 0x51, 0x4c5: 0x102, 0x4c6: 0x103,
+       0x4c8: 0x52, 0x4c9: 0x104,
+       0x4ef: 0x105,
+       // Block 0x14, offset 0x500
+       0x520: 0x53, 0x521: 0x54, 0x522: 0x55, 0x523: 0x56, 0x524: 0x57, 0x525: 0x58, 0x526: 0x59, 0x527: 0x5a,
+       0x528: 0x5b,
+       // Block 0x15, offset 0x540
+       0x550: 0x0b, 0x551: 0x0c, 0x556: 0x0d,
+       0x55b: 0x0e, 0x55d: 0x0f, 0x55e: 0x10, 0x55f: 0x11,
+       0x56f: 0x12,
+}
+
+// nfkcSparseOffset: 170 entries, 340 bytes
+var nfkcSparseOffset = []uint16{0x0, 0xe, 0x12, 0x1b, 0x25, 0x35, 0x37, 0x3c, 0x47, 0x56, 0x63, 0x6b, 0x70, 0x75, 0x77, 0x7f, 0x86, 0x89, 0x91, 0x95, 0x99, 0x9b, 0x9d, 0xa6, 0xaa, 0xb1, 0xb6, 0xb9, 0xc3, 0xc6, 0xcd, 0xd5, 0xd9, 0xdb, 0xdf, 0xe3, 0xe9, 0xfa, 0x106, 0x108, 0x10e, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11a, 0x11c, 0x11f, 0x122, 0x124, 0x127, 0x12a, 0x12e, 0x134, 0x136, 0x13f, 0x141, 0x144, 0x146, 0x151, 0x15c, 0x16a, 0x178, 0x188, 0x196, 0x19d, 0x1a3, 0x1b2, 0x1b6, 0x1b8, 0x1bc, 0x1be, 0x1c1, 0x1c3, 0x1c6, 0x1c8, 0x1cb, 0x1cd, 0x1cf, 0x1d1, 0x1dd, 0x1e7, 0x1f1, 0x1f4, 0x1f8, 0x1fa, 0x1fc, 0x1fe, 0x201, 0x204, 0x206, 0x208, 0x20a, 0x20c, 0x212, 0x215, 0x21a, 0x21c, 0x223, 0x229, 0x22f, 0x237, 0x23d, 0x243, 0x249, 0x24d, 0x24f, 0x251, 0x253, 0x255, 0x25b, 0x25e, 0x260, 0x262, 0x268, 0x26b, 0x273, 0x27a, 0x27d, 0x280, 0x282, 0x285, 0x28d, 0x291, 0x298, 0x29b, 0x2a1, 0x2a3, 0x2a5, 0x2a8, 0x2aa, 0x2ad, 0x2b2, 0x2b4, 0x2b6, 0x2b8, 0x2ba, 0x2bc, 0x2bf, 0x2c1, 0x2c3, 0x2c5, 0x2c7, 0x2c9, 0x2d6, 0x2e0, 0x2e2, 0x2e4, 0x2e8, 0x2ed, 0x2f9, 0x2fe, 0x307, 0x30d, 0x312, 0x316, 0x31b, 0x31f, 0x32f, 0x33d, 0x34b, 0x359, 0x35f, 0x361, 0x363, 0x366, 0x371, 0x373, 0x37d}
+
+// nfkcSparseValues: 895 entries, 3580 bytes
+var nfkcSparseValues = [895]valueRange{
+       // Block 0x0, offset 0x0
+       {value: 0x0002, lo: 0x0d},
+       {value: 0x0001, lo: 0xa0, hi: 0xa0},
+       {value: 0x428f, lo: 0xa8, hi: 0xa8},
+       {value: 0x0083, lo: 0xaa, hi: 0xaa},
+       {value: 0x427b, lo: 0xaf, hi: 0xaf},
+       {value: 0x0025, lo: 0xb2, hi: 0xb3},
+       {value: 0x4271, lo: 0xb4, hi: 0xb4},
+       {value: 0x01df, lo: 0xb5, hi: 0xb5},
+       {value: 0x42a8, lo: 0xb8, hi: 0xb8},
+       {value: 0x0023, lo: 0xb9, hi: 0xb9},
+       {value: 0x009f, lo: 0xba, hi: 0xba},
+       {value: 0x2222, lo: 0xbc, hi: 0xbc},
+       {value: 0x2216, lo: 0xbd, hi: 0xbd},
+       {value: 0x22b8, lo: 0xbe, hi: 0xbe},
+       // Block 0x1, offset 0xe
+       {value: 0x0091, lo: 0x03},
+       {value: 0x46f9, lo: 0xa0, hi: 0xa1},
+       {value: 0x472b, lo: 0xaf, hi: 0xb0},
+       {value: 0xa000, lo: 0xb7, hi: 0xb7},
+       // Block 0x2, offset 0x12
+       {value: 0x0003, lo: 0x08},
+       {value: 0xa000, lo: 0x92, hi: 0x92},
+       {value: 0x0091, lo: 0xb0, hi: 0xb0},
+       {value: 0x0119, lo: 0xb1, hi: 0xb1},
+       {value: 0x0095, lo: 0xb2, hi: 0xb2},
+       {value: 0x00a5, lo: 0xb3, hi: 0xb3},
+       {value: 0x0143, lo: 0xb4, hi: 0xb6},
+       {value: 0x00af, lo: 0xb7, hi: 0xb7},
+       {value: 0x00b3, lo: 0xb8, hi: 0xb8},
+       // Block 0x3, offset 0x1b
+       {value: 0x000a, lo: 0x09},
+       {value: 0x4285, lo: 0x98, hi: 0x98},
+       {value: 0x428a, lo: 0x99, hi: 0x9a},
+       {value: 0x42ad, lo: 0x9b, hi: 0x9b},
+       {value: 0x4276, lo: 0x9c, hi: 0x9c},
+       {value: 0x4299, lo: 0x9d, hi: 0x9d},
+       {value: 0x0113, lo: 0xa0, hi: 0xa0},
+       {value: 0x0099, lo: 0xa1, hi: 0xa1},
+       {value: 0x00a7, lo: 0xa2, hi: 0xa3},
+       {value: 0x016a, lo: 0xa4, hi: 0xa4},
+       // Block 0x4, offset 0x25
+       {value: 0x0000, lo: 0x0f},
+       {value: 0xa000, lo: 0x83, hi: 0x83},
+       {value: 0xa000, lo: 0x87, hi: 0x87},
+       {value: 0xa000, lo: 0x8b, hi: 0x8b},
+       {value: 0xa000, lo: 0x8d, hi: 0x8d},
+       {value: 0x37bc, lo: 0x90, hi: 0x90},
+       {value: 0x37c8, lo: 0x91, hi: 0x91},
+       {value: 0x37b6, lo: 0x93, hi: 0x93},
+       {value: 0xa000, lo: 0x96, hi: 0x96},
+       {value: 0x382e, lo: 0x97, hi: 0x97},
+       {value: 0x37f8, lo: 0x9c, hi: 0x9c},
+       {value: 0x37e0, lo: 0x9d, hi: 0x9d},
+       {value: 0x380a, lo: 0x9e, hi: 0x9e},
+       {value: 0xa000, lo: 0xb4, hi: 0xb5},
+       {value: 0x3834, lo: 0xb6, hi: 0xb6},
+       {value: 0x383a, lo: 0xb7, hi: 0xb7},
+       // Block 0x5, offset 0x35
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0x83, hi: 0x87},
+       // Block 0x6, offset 0x37
+       {value: 0x0001, lo: 0x04},
+       {value: 0x8114, lo: 0x81, hi: 0x82},
+       {value: 0x8133, lo: 0x84, hi: 0x84},
+       {value: 0x812e, lo: 0x85, hi: 0x85},
+       {value: 0x810e, lo: 0x87, hi: 0x87},
+       // Block 0x7, offset 0x3c
+       {value: 0x0000, lo: 0x0a},
+       {value: 0x8133, lo: 0x90, hi: 0x97},
+       {value: 0x811a, lo: 0x98, hi: 0x98},
+       {value: 0x811b, lo: 0x99, hi: 0x99},
+       {value: 0x811c, lo: 0x9a, hi: 0x9a},
+       {value: 0x3858, lo: 0xa2, hi: 0xa2},
+       {value: 0x385e, lo: 0xa3, hi: 0xa3},
+       {value: 0x386a, lo: 0xa4, hi: 0xa4},
+       {value: 0x3864, lo: 0xa5, hi: 0xa5},
+       {value: 0x3870, lo: 0xa6, hi: 0xa6},
+       {value: 0xa000, lo: 0xa7, hi: 0xa7},
+       // Block 0x8, offset 0x47
+       {value: 0x0000, lo: 0x0e},
+       {value: 0x3882, lo: 0x80, hi: 0x80},
+       {value: 0xa000, lo: 0x81, hi: 0x81},
+       {value: 0x3876, lo: 0x82, hi: 0x82},
+       {value: 0xa000, lo: 0x92, hi: 0x92},
+       {value: 0x387c, lo: 0x93, hi: 0x93},
+       {value: 0xa000, lo: 0x95, hi: 0x95},
+       {value: 0x8133, lo: 0x96, hi: 0x9c},
+       {value: 0x8133, lo: 0x9f, hi: 0xa2},
+       {value: 0x812e, lo: 0xa3, hi: 0xa3},
+       {value: 0x8133, lo: 0xa4, hi: 0xa4},
+       {value: 0x8133, lo: 0xa7, hi: 0xa8},
+       {value: 0x812e, lo: 0xaa, hi: 0xaa},
+       {value: 0x8133, lo: 0xab, hi: 0xac},
+       {value: 0x812e, lo: 0xad, hi: 0xad},
+       // Block 0x9, offset 0x56
+       {value: 0x0000, lo: 0x0c},
+       {value: 0x8120, lo: 0x91, hi: 0x91},
+       {value: 0x8133, lo: 0xb0, hi: 0xb0},
+       {value: 0x812e, lo: 0xb1, hi: 0xb1},
+       {value: 0x8133, lo: 0xb2, hi: 0xb3},
+       {value: 0x812e, lo: 0xb4, hi: 0xb4},
+       {value: 0x8133, lo: 0xb5, hi: 0xb6},
+       {value: 0x812e, lo: 0xb7, hi: 0xb9},
+       {value: 0x8133, lo: 0xba, hi: 0xba},
+       {value: 0x812e, lo: 0xbb, hi: 0xbc},
+       {value: 0x8133, lo: 0xbd, hi: 0xbd},
+       {value: 0x812e, lo: 0xbe, hi: 0xbe},
+       {value: 0x8133, lo: 0xbf, hi: 0xbf},
+       // Block 0xa, offset 0x63
+       {value: 0x0005, lo: 0x07},
+       {value: 0x8133, lo: 0x80, hi: 0x80},
+       {value: 0x8133, lo: 0x81, hi: 0x81},
+       {value: 0x812e, lo: 0x82, hi: 0x83},
+       {value: 0x812e, lo: 0x84, hi: 0x85},
+       {value: 0x812e, lo: 0x86, hi: 0x87},
+       {value: 0x812e, lo: 0x88, hi: 0x89},
+       {value: 0x8133, lo: 0x8a, hi: 0x8a},
+       // Block 0xb, offset 0x6b
+       {value: 0x0000, lo: 0x04},
+       {value: 0x8133, lo: 0xab, hi: 0xb1},
+       {value: 0x812e, lo: 0xb2, hi: 0xb2},
+       {value: 0x8133, lo: 0xb3, hi: 0xb3},
+       {value: 0x812e, lo: 0xbd, hi: 0xbd},
+       // Block 0xc, offset 0x70
+       {value: 0x0000, lo: 0x04},
+       {value: 0x8133, lo: 0x96, hi: 0x99},
+       {value: 0x8133, lo: 0x9b, hi: 0xa3},
+       {value: 0x8133, lo: 0xa5, hi: 0xa7},
+       {value: 0x8133, lo: 0xa9, hi: 0xad},
+       // Block 0xd, offset 0x75
+       {value: 0x0000, lo: 0x01},
+       {value: 0x812e, lo: 0x99, hi: 0x9b},
+       // Block 0xe, offset 0x77
+       {value: 0x0000, lo: 0x07},
+       {value: 0xa000, lo: 0xa8, hi: 0xa8},
+       {value: 0x3eef, lo: 0xa9, hi: 0xa9},
+       {value: 0xa000, lo: 0xb0, hi: 0xb0},
+       {value: 0x3ef7, lo: 0xb1, hi: 0xb1},
+       {value: 0xa000, lo: 0xb3, hi: 0xb3},
+       {value: 0x3eff, lo: 0xb4, hi: 0xb4},
+       {value: 0x9903, lo: 0xbc, hi: 0xbc},
+       // Block 0xf, offset 0x7f
+       {value: 0x0008, lo: 0x06},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x8133, lo: 0x91, hi: 0x91},
+       {value: 0x812e, lo: 0x92, hi: 0x92},
+       {value: 0x8133, lo: 0x93, hi: 0x93},
+       {value: 0x8133, lo: 0x94, hi: 0x94},
+       {value: 0x4533, lo: 0x98, hi: 0x9f},
+       // Block 0x10, offset 0x86
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8103, lo: 0xbc, hi: 0xbc},
+       {value: 0x9900, lo: 0xbe, hi: 0xbe},
+       // Block 0x11, offset 0x89
+       {value: 0x0008, lo: 0x07},
+       {value: 0xa000, lo: 0x87, hi: 0x87},
+       {value: 0x2cab, lo: 0x8b, hi: 0x8c},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x9900, lo: 0x97, hi: 0x97},
+       {value: 0x4573, lo: 0x9c, hi: 0x9d},
+       {value: 0x4583, lo: 0x9f, hi: 0x9f},
+       {value: 0x8133, lo: 0xbe, hi: 0xbe},
+       // Block 0x12, offset 0x91
+       {value: 0x0000, lo: 0x03},
+       {value: 0x45ab, lo: 0xb3, hi: 0xb3},
+       {value: 0x45b3, lo: 0xb6, hi: 0xb6},
+       {value: 0x8103, lo: 0xbc, hi: 0xbc},
+       // Block 0x13, offset 0x95
+       {value: 0x0008, lo: 0x03},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x458b, lo: 0x99, hi: 0x9b},
+       {value: 0x45a3, lo: 0x9e, hi: 0x9e},
+       // Block 0x14, offset 0x99
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8103, lo: 0xbc, hi: 0xbc},
+       // Block 0x15, offset 0x9b
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       // Block 0x16, offset 0x9d
+       {value: 0x0000, lo: 0x08},
+       {value: 0xa000, lo: 0x87, hi: 0x87},
+       {value: 0x2cc3, lo: 0x88, hi: 0x88},
+       {value: 0x2cbb, lo: 0x8b, hi: 0x8b},
+       {value: 0x2ccb, lo: 0x8c, hi: 0x8c},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x9900, lo: 0x96, hi: 0x97},
+       {value: 0x45bb, lo: 0x9c, hi: 0x9c},
+       {value: 0x45c3, lo: 0x9d, hi: 0x9d},
+       // Block 0x17, offset 0xa6
+       {value: 0x0000, lo: 0x03},
+       {value: 0xa000, lo: 0x92, hi: 0x92},
+       {value: 0x2cd3, lo: 0x94, hi: 0x94},
+       {value: 0x9900, lo: 0xbe, hi: 0xbe},
+       // Block 0x18, offset 0xaa
+       {value: 0x0000, lo: 0x06},
+       {value: 0xa000, lo: 0x86, hi: 0x87},
+       {value: 0x2cdb, lo: 0x8a, hi: 0x8a},
+       {value: 0x2ceb, lo: 0x8b, hi: 0x8b},
+       {value: 0x2ce3, lo: 0x8c, hi: 0x8c},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x9900, lo: 0x97, hi: 0x97},
+       // Block 0x19, offset 0xb1
+       {value: 0x1801, lo: 0x04},
+       {value: 0xa000, lo: 0x86, hi: 0x86},
+       {value: 0x3f07, lo: 0x88, hi: 0x88},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x8121, lo: 0x95, hi: 0x96},
+       // Block 0x1a, offset 0xb6
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8103, lo: 0xbc, hi: 0xbc},
+       {value: 0xa000, lo: 0xbf, hi: 0xbf},
+       // Block 0x1b, offset 0xb9
+       {value: 0x0000, lo: 0x09},
+       {value: 0x2cf3, lo: 0x80, hi: 0x80},
+       {value: 0x9900, lo: 0x82, hi: 0x82},
+       {value: 0xa000, lo: 0x86, hi: 0x86},
+       {value: 0x2cfb, lo: 0x87, hi: 0x87},
+       {value: 0x2d03, lo: 0x88, hi: 0x88},
+       {value: 0x2f67, lo: 0x8a, hi: 0x8a},
+       {value: 0x2def, lo: 0x8b, hi: 0x8b},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x9900, lo: 0x95, hi: 0x96},
+       // Block 0x1c, offset 0xc3
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0xbb, hi: 0xbc},
+       {value: 0x9900, lo: 0xbe, hi: 0xbe},
+       // Block 0x1d, offset 0xc6
+       {value: 0x0000, lo: 0x06},
+       {value: 0xa000, lo: 0x86, hi: 0x87},
+       {value: 0x2d0b, lo: 0x8a, hi: 0x8a},
+       {value: 0x2d1b, lo: 0x8b, hi: 0x8b},
+       {value: 0x2d13, lo: 0x8c, hi: 0x8c},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x9900, lo: 0x97, hi: 0x97},
+       // Block 0x1e, offset 0xcd
+       {value: 0x6bdd, lo: 0x07},
+       {value: 0x9905, lo: 0x8a, hi: 0x8a},
+       {value: 0x9900, lo: 0x8f, hi: 0x8f},
+       {value: 0xa000, lo: 0x99, hi: 0x99},
+       {value: 0x3f0f, lo: 0x9a, hi: 0x9a},
+       {value: 0x2f6f, lo: 0x9c, hi: 0x9c},
+       {value: 0x2dfa, lo: 0x9d, hi: 0x9d},
+       {value: 0x2d23, lo: 0x9e, hi: 0x9f},
+       // Block 0x1f, offset 0xd5
+       {value: 0x0000, lo: 0x03},
+       {value: 0x2627, lo: 0xb3, hi: 0xb3},
+       {value: 0x8123, lo: 0xb8, hi: 0xb9},
+       {value: 0x8105, lo: 0xba, hi: 0xba},
+       // Block 0x20, offset 0xd9
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8124, lo: 0x88, hi: 0x8b},
+       // Block 0x21, offset 0xdb
+       {value: 0x0000, lo: 0x03},
+       {value: 0x263c, lo: 0xb3, hi: 0xb3},
+       {value: 0x8125, lo: 0xb8, hi: 0xb9},
+       {value: 0x8105, lo: 0xba, hi: 0xba},
+       // Block 0x22, offset 0xdf
+       {value: 0x0000, lo: 0x03},
+       {value: 0x8126, lo: 0x88, hi: 0x8b},
+       {value: 0x262e, lo: 0x9c, hi: 0x9c},
+       {value: 0x2635, lo: 0x9d, hi: 0x9d},
+       // Block 0x23, offset 0xe3
+       {value: 0x0000, lo: 0x05},
+       {value: 0x030e, lo: 0x8c, hi: 0x8c},
+       {value: 0x812e, lo: 0x98, hi: 0x99},
+       {value: 0x812e, lo: 0xb5, hi: 0xb5},
+       {value: 0x812e, lo: 0xb7, hi: 0xb7},
+       {value: 0x812c, lo: 0xb9, hi: 0xb9},
+       // Block 0x24, offset 0xe9
+       {value: 0x0000, lo: 0x10},
+       {value: 0x264a, lo: 0x83, hi: 0x83},
+       {value: 0x2651, lo: 0x8d, hi: 0x8d},
+       {value: 0x2658, lo: 0x92, hi: 0x92},
+       {value: 0x265f, lo: 0x97, hi: 0x97},
+       {value: 0x2666, lo: 0x9c, hi: 0x9c},
+       {value: 0x2643, lo: 0xa9, hi: 0xa9},
+       {value: 0x8127, lo: 0xb1, hi: 0xb1},
+       {value: 0x8128, lo: 0xb2, hi: 0xb2},
+       {value: 0x4a9b, lo: 0xb3, hi: 0xb3},
+       {value: 0x8129, lo: 0xb4, hi: 0xb4},
+       {value: 0x4aa4, lo: 0xb5, hi: 0xb5},
+       {value: 0x45cb, lo: 0xb6, hi: 0xb6},
+       {value: 0x460b, lo: 0xb7, hi: 0xb7},
+       {value: 0x45d3, lo: 0xb8, hi: 0xb8},
+       {value: 0x4616, lo: 0xb9, hi: 0xb9},
+       {value: 0x8128, lo: 0xba, hi: 0xbd},
+       // Block 0x25, offset 0xfa
+       {value: 0x0000, lo: 0x0b},
+       {value: 0x8128, lo: 0x80, hi: 0x80},
+       {value: 0x4aad, lo: 0x81, hi: 0x81},
+       {value: 0x8133, lo: 0x82, hi: 0x83},
+       {value: 0x8105, lo: 0x84, hi: 0x84},
+       {value: 0x8133, lo: 0x86, hi: 0x87},
+       {value: 0x2674, lo: 0x93, hi: 0x93},
+       {value: 0x267b, lo: 0x9d, hi: 0x9d},
+       {value: 0x2682, lo: 0xa2, hi: 0xa2},
+       {value: 0x2689, lo: 0xa7, hi: 0xa7},
+       {value: 0x2690, lo: 0xac, hi: 0xac},
+       {value: 0x266d, lo: 0xb9, hi: 0xb9},
+       // Block 0x26, offset 0x106
+       {value: 0x0000, lo: 0x01},
+       {value: 0x812e, lo: 0x86, hi: 0x86},
+       // Block 0x27, offset 0x108
+       {value: 0x0000, lo: 0x05},
+       {value: 0xa000, lo: 0xa5, hi: 0xa5},
+       {value: 0x2d2b, lo: 0xa6, hi: 0xa6},
+       {value: 0x9900, lo: 0xae, hi: 0xae},
+       {value: 0x8103, lo: 0xb7, hi: 0xb7},
+       {value: 0x8105, lo: 0xb9, hi: 0xba},
+       // Block 0x28, offset 0x10e
+       {value: 0x0000, lo: 0x01},
+       {value: 0x812e, lo: 0x8d, hi: 0x8d},
+       // Block 0x29, offset 0x110
+       {value: 0x0000, lo: 0x01},
+       {value: 0x0312, lo: 0xbc, hi: 0xbc},
+       // Block 0x2a, offset 0x112
+       {value: 0x0000, lo: 0x01},
+       {value: 0xa000, lo: 0x80, hi: 0x92},
+       // Block 0x2b, offset 0x114
+       {value: 0x0000, lo: 0x01},
+       {value: 0xb900, lo: 0xa1, hi: 0xb5},
+       // Block 0x2c, offset 0x116
+       {value: 0x0000, lo: 0x01},
+       {value: 0x9900, lo: 0xa8, hi: 0xbf},
+       // Block 0x2d, offset 0x118
+       {value: 0x0000, lo: 0x01},
+       {value: 0x9900, lo: 0x80, hi: 0x82},
+       // Block 0x2e, offset 0x11a
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0x9d, hi: 0x9f},
+       // Block 0x2f, offset 0x11c
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0x94, hi: 0x94},
+       {value: 0x8105, lo: 0xb4, hi: 0xb4},
+       // Block 0x30, offset 0x11f
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0x92, hi: 0x92},
+       {value: 0x8133, lo: 0x9d, hi: 0x9d},
+       // Block 0x31, offset 0x122
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8132, lo: 0xa9, hi: 0xa9},
+       // Block 0x32, offset 0x124
+       {value: 0x0004, lo: 0x02},
+       {value: 0x812f, lo: 0xb9, hi: 0xba},
+       {value: 0x812e, lo: 0xbb, hi: 0xbb},
+       // Block 0x33, offset 0x127
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8133, lo: 0x97, hi: 0x97},
+       {value: 0x812e, lo: 0x98, hi: 0x98},
+       // Block 0x34, offset 0x12a
+       {value: 0x0000, lo: 0x03},
+       {value: 0x8105, lo: 0xa0, hi: 0xa0},
+       {value: 0x8133, lo: 0xb5, hi: 0xbc},
+       {value: 0x812e, lo: 0xbf, hi: 0xbf},
+       // Block 0x35, offset 0x12e
+       {value: 0x0000, lo: 0x05},
+       {value: 0x8133, lo: 0xb0, hi: 0xb4},
+       {value: 0x812e, lo: 0xb5, hi: 0xba},
+       {value: 0x8133, lo: 0xbb, hi: 0xbc},
+       {value: 0x812e, lo: 0xbd, hi: 0xbd},
+       {value: 0x812e, lo: 0xbf, hi: 0xbf},
+       // Block 0x36, offset 0x134
+       {value: 0x0000, lo: 0x01},
+       {value: 0x812e, lo: 0x80, hi: 0x80},
+       // Block 0x37, offset 0x136
+       {value: 0x0000, lo: 0x08},
+       {value: 0x2d73, lo: 0x80, hi: 0x80},
+       {value: 0x2d7b, lo: 0x81, hi: 0x81},
+       {value: 0xa000, lo: 0x82, hi: 0x82},
+       {value: 0x2d83, lo: 0x83, hi: 0x83},
+       {value: 0x8105, lo: 0x84, hi: 0x84},
+       {value: 0x8133, lo: 0xab, hi: 0xab},
+       {value: 0x812e, lo: 0xac, hi: 0xac},
+       {value: 0x8133, lo: 0xad, hi: 0xb3},
+       // Block 0x38, offset 0x13f
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0xaa, hi: 0xab},
+       // Block 0x39, offset 0x141
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8103, lo: 0xa6, hi: 0xa6},
+       {value: 0x8105, lo: 0xb2, hi: 0xb3},
+       // Block 0x3a, offset 0x144
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8103, lo: 0xb7, hi: 0xb7},
+       // Block 0x3b, offset 0x146
+       {value: 0x0000, lo: 0x0a},
+       {value: 0x8133, lo: 0x90, hi: 0x92},
+       {value: 0x8101, lo: 0x94, hi: 0x94},
+       {value: 0x812e, lo: 0x95, hi: 0x99},
+       {value: 0x8133, lo: 0x9a, hi: 0x9b},
+       {value: 0x812e, lo: 0x9c, hi: 0x9f},
+       {value: 0x8133, lo: 0xa0, hi: 0xa0},
+       {value: 0x8101, lo: 0xa2, hi: 0xa8},
+       {value: 0x812e, lo: 0xad, hi: 0xad},
+       {value: 0x8133, lo: 0xb4, hi: 0xb4},
+       {value: 0x8133, lo: 0xb8, hi: 0xb9},
+       // Block 0x3c, offset 0x151
+       {value: 0x0002, lo: 0x0a},
+       {value: 0x0043, lo: 0xac, hi: 0xac},
+       {value: 0x00d1, lo: 0xad, hi: 0xad},
+       {value: 0x0045, lo: 0xae, hi: 0xae},
+       {value: 0x0049, lo: 0xb0, hi: 0xb1},
+       {value: 0x00e6, lo: 0xb2, hi: 0xb2},
+       {value: 0x004f, lo: 0xb3, hi: 0xba},
+       {value: 0x005f, lo: 0xbc, hi: 0xbc},
+       {value: 0x00ef, lo: 0xbd, hi: 0xbd},
+       {value: 0x0061, lo: 0xbe, hi: 0xbe},
+       {value: 0x0065, lo: 0xbf, hi: 0xbf},
+       // Block 0x3d, offset 0x15c
+       {value: 0x0000, lo: 0x0d},
+       {value: 0x0001, lo: 0x80, hi: 0x8a},
+       {value: 0x043e, lo: 0x91, hi: 0x91},
+       {value: 0x42b2, lo: 0x97, hi: 0x97},
+       {value: 0x001d, lo: 0xa4, hi: 0xa4},
+       {value: 0x1876, lo: 0xa5, hi: 0xa5},
+       {value: 0x1b62, lo: 0xa6, hi: 0xa6},
+       {value: 0x0001, lo: 0xaf, hi: 0xaf},
+       {value: 0x2697, lo: 0xb3, hi: 0xb3},
+       {value: 0x280b, lo: 0xb4, hi: 0xb4},
+       {value: 0x269e, lo: 0xb6, hi: 0xb6},
+       {value: 0x2815, lo: 0xb7, hi: 0xb7},
+       {value: 0x1870, lo: 0xbc, hi: 0xbc},
+       {value: 0x4280, lo: 0xbe, hi: 0xbe},
+       // Block 0x3e, offset 0x16a
+       {value: 0x0002, lo: 0x0d},
+       {value: 0x1936, lo: 0x87, hi: 0x87},
+       {value: 0x1933, lo: 0x88, hi: 0x88},
+       {value: 0x1873, lo: 0x89, hi: 0x89},
+       {value: 0x299b, lo: 0x97, hi: 0x97},
+       {value: 0x0001, lo: 0x9f, hi: 0x9f},
+       {value: 0x0021, lo: 0xb0, hi: 0xb0},
+       {value: 0x0093, lo: 0xb1, hi: 0xb1},
+       {value: 0x0029, lo: 0xb4, hi: 0xb9},
+       {value: 0x0017, lo: 0xba, hi: 0xba},
+       {value: 0x046a, lo: 0xbb, hi: 0xbb},
+       {value: 0x003b, lo: 0xbc, hi: 0xbc},
+       {value: 0x0011, lo: 0xbd, hi: 0xbe},
+       {value: 0x009d, lo: 0xbf, hi: 0xbf},
+       // Block 0x3f, offset 0x178
+       {value: 0x0002, lo: 0x0f},
+       {value: 0x0021, lo: 0x80, hi: 0x89},
+       {value: 0x0017, lo: 0x8a, hi: 0x8a},
+       {value: 0x046a, lo: 0x8b, hi: 0x8b},
+       {value: 0x003b, lo: 0x8c, hi: 0x8c},
+       {value: 0x0011, lo: 0x8d, hi: 0x8e},
+       {value: 0x0083, lo: 0x90, hi: 0x90},
+       {value: 0x008b, lo: 0x91, hi: 0x91},
+       {value: 0x009f, lo: 0x92, hi: 0x92},
+       {value: 0x00b1, lo: 0x93, hi: 0x93},
+       {value: 0x0104, lo: 0x94, hi: 0x94},
+       {value: 0x0091, lo: 0x95, hi: 0x95},
+       {value: 0x0097, lo: 0x96, hi: 0x99},
+       {value: 0x00a1, lo: 0x9a, hi: 0x9a},
+       {value: 0x00a7, lo: 0x9b, hi: 0x9c},
+       {value: 0x199f, lo: 0xa8, hi: 0xa8},
+       // Block 0x40, offset 0x188
+       {value: 0x0000, lo: 0x0d},
+       {value: 0x8133, lo: 0x90, hi: 0x91},
+       {value: 0x8101, lo: 0x92, hi: 0x93},
+       {value: 0x8133, lo: 0x94, hi: 0x97},
+       {value: 0x8101, lo: 0x98, hi: 0x9a},
+       {value: 0x8133, lo: 0x9b, hi: 0x9c},
+       {value: 0x8133, lo: 0xa1, hi: 0xa1},
+       {value: 0x8101, lo: 0xa5, hi: 0xa6},
+       {value: 0x8133, lo: 0xa7, hi: 0xa7},
+       {value: 0x812e, lo: 0xa8, hi: 0xa8},
+       {value: 0x8133, lo: 0xa9, hi: 0xa9},
+       {value: 0x8101, lo: 0xaa, hi: 0xab},
+       {value: 0x812e, lo: 0xac, hi: 0xaf},
+       {value: 0x8133, lo: 0xb0, hi: 0xb0},
+       // Block 0x41, offset 0x196
+       {value: 0x0007, lo: 0x06},
+       {value: 0x2186, lo: 0x89, hi: 0x89},
+       {value: 0xa000, lo: 0x90, hi: 0x90},
+       {value: 0xa000, lo: 0x92, hi: 0x92},
+       {value: 0xa000, lo: 0x94, hi: 0x94},
+       {value: 0x3bd0, lo: 0x9a, hi: 0x9b},
+       {value: 0x3bde, lo: 0xae, hi: 0xae},
+       // Block 0x42, offset 0x19d
+       {value: 0x000e, lo: 0x05},
+       {value: 0x3be5, lo: 0x8d, hi: 0x8e},
+       {value: 0x3bec, lo: 0x8f, hi: 0x8f},
+       {value: 0xa000, lo: 0x90, hi: 0x90},
+       {value: 0xa000, lo: 0x92, hi: 0x92},
+       {value: 0xa000, lo: 0x94, hi: 0x94},
+       // Block 0x43, offset 0x1a3
+       {value: 0x017a, lo: 0x0e},
+       {value: 0xa000, lo: 0x83, hi: 0x83},
+       {value: 0x3bfa, lo: 0x84, hi: 0x84},
+       {value: 0xa000, lo: 0x88, hi: 0x88},
+       {value: 0x3c01, lo: 0x89, hi: 0x89},
+       {value: 0xa000, lo: 0x8b, hi: 0x8b},
+       {value: 0x3c08, lo: 0x8c, hi: 0x8c},
+       {value: 0xa000, lo: 0xa3, hi: 0xa3},
+       {value: 0x3c0f, lo: 0xa4, hi: 0xa4},
+       {value: 0xa000, lo: 0xa5, hi: 0xa5},
+       {value: 0x3c16, lo: 0xa6, hi: 0xa6},
+       {value: 0x26a5, lo: 0xac, hi: 0xad},
+       {value: 0x26ac, lo: 0xaf, hi: 0xaf},
+       {value: 0x2829, lo: 0xb0, hi: 0xb0},
+       {value: 0xa000, lo: 0xbc, hi: 0xbc},
+       // Block 0x44, offset 0x1b2
+       {value: 0x0007, lo: 0x03},
+       {value: 0x3c7f, lo: 0xa0, hi: 0xa1},
+       {value: 0x3ca9, lo: 0xa2, hi: 0xa3},
+       {value: 0x3cd3, lo: 0xaa, hi: 0xad},
+       // Block 0x45, offset 0x1b6
+       {value: 0x0004, lo: 0x01},
+       {value: 0x048e, lo: 0xa9, hi: 0xaa},
+       // Block 0x46, offset 0x1b8
+       {value: 0x0002, lo: 0x03},
+       {value: 0x0057, lo: 0x80, hi: 0x8f},
+       {value: 0x0083, lo: 0x90, hi: 0xa9},
+       {value: 0x0021, lo: 0xaa, hi: 0xaa},
+       // Block 0x47, offset 0x1bc
+       {value: 0x0000, lo: 0x01},
+       {value: 0x29a8, lo: 0x8c, hi: 0x8c},
+       // Block 0x48, offset 0x1be
+       {value: 0x0266, lo: 0x02},
+       {value: 0x1b92, lo: 0xb4, hi: 0xb4},
+       {value: 0x1930, lo: 0xb5, hi: 0xb6},
+       // Block 0x49, offset 0x1c1
+       {value: 0x0000, lo: 0x01},
+       {value: 0x44f4, lo: 0x9c, hi: 0x9c},
+       // Block 0x4a, offset 0x1c3
+       {value: 0x0000, lo: 0x02},
+       {value: 0x0095, lo: 0xbc, hi: 0xbc},
+       {value: 0x006d, lo: 0xbd, hi: 0xbd},
+       // Block 0x4b, offset 0x1c6
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0xaf, hi: 0xb1},
+       // Block 0x4c, offset 0x1c8
+       {value: 0x0000, lo: 0x02},
+       {value: 0x0482, lo: 0xaf, hi: 0xaf},
+       {value: 0x8105, lo: 0xbf, hi: 0xbf},
+       // Block 0x4d, offset 0x1cb
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0xa0, hi: 0xbf},
+       // Block 0x4e, offset 0x1cd
+       {value: 0x0000, lo: 0x01},
+       {value: 0x0dc6, lo: 0x9f, hi: 0x9f},
+       // Block 0x4f, offset 0x1cf
+       {value: 0x0000, lo: 0x01},
+       {value: 0x1632, lo: 0xb3, hi: 0xb3},
+       // Block 0x50, offset 0x1d1
+       {value: 0x0004, lo: 0x0b},
+       {value: 0x159a, lo: 0x80, hi: 0x82},
+       {value: 0x15b2, lo: 0x83, hi: 0x83},
+       {value: 0x15ca, lo: 0x84, hi: 0x85},
+       {value: 0x15da, lo: 0x86, hi: 0x89},
+       {value: 0x15ee, lo: 0x8a, hi: 0x8c},
+       {value: 0x1602, lo: 0x8d, hi: 0x8d},
+       {value: 0x160a, lo: 0x8e, hi: 0x8e},
+       {value: 0x1612, lo: 0x8f, hi: 0x90},
+       {value: 0x161e, lo: 0x91, hi: 0x93},
+       {value: 0x162e, lo: 0x94, hi: 0x94},
+       {value: 0x1636, lo: 0x95, hi: 0x95},
+       // Block 0x51, offset 0x1dd
+       {value: 0x0004, lo: 0x09},
+       {value: 0x0001, lo: 0x80, hi: 0x80},
+       {value: 0x812d, lo: 0xaa, hi: 0xaa},
+       {value: 0x8132, lo: 0xab, hi: 0xab},
+       {value: 0x8134, lo: 0xac, hi: 0xac},
+       {value: 0x812f, lo: 0xad, hi: 0xad},
+       {value: 0x8130, lo: 0xae, hi: 0xae},
+       {value: 0x8130, lo: 0xaf, hi: 0xaf},
+       {value: 0x04b6, lo: 0xb6, hi: 0xb6},
+       {value: 0x088a, lo: 0xb8, hi: 0xba},
+       // Block 0x52, offset 0x1e7
+       {value: 0x0006, lo: 0x09},
+       {value: 0x0316, lo: 0xb1, hi: 0xb1},
+       {value: 0x031a, lo: 0xb2, hi: 0xb2},
+       {value: 0x4a52, lo: 0xb3, hi: 0xb3},
+       {value: 0x031e, lo: 0xb4, hi: 0xb4},
+       {value: 0x4a58, lo: 0xb5, hi: 0xb6},
+       {value: 0x0322, lo: 0xb7, hi: 0xb7},
+       {value: 0x0326, lo: 0xb8, hi: 0xb8},
+       {value: 0x032a, lo: 0xb9, hi: 0xb9},
+       {value: 0x4a64, lo: 0xba, hi: 0xbf},
+       // Block 0x53, offset 0x1f1
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8133, lo: 0xaf, hi: 0xaf},
+       {value: 0x8133, lo: 0xb4, hi: 0xbd},
+       // Block 0x54, offset 0x1f4
+       {value: 0x0000, lo: 0x03},
+       {value: 0x0212, lo: 0x9c, hi: 0x9c},
+       {value: 0x0215, lo: 0x9d, hi: 0x9d},
+       {value: 0x8133, lo: 0x9e, hi: 0x9f},
+       // Block 0x55, offset 0x1f8
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0xb0, hi: 0xb1},
+       // Block 0x56, offset 0x1fa
+       {value: 0x0000, lo: 0x01},
+       {value: 0x163e, lo: 0xb0, hi: 0xb0},
+       // Block 0x57, offset 0x1fc
+       {value: 0x000c, lo: 0x01},
+       {value: 0x00d7, lo: 0xb8, hi: 0xb9},
+       // Block 0x58, offset 0x1fe
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0x86, hi: 0x86},
+       {value: 0x8105, lo: 0xac, hi: 0xac},
+       // Block 0x59, offset 0x201
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0x84, hi: 0x84},
+       {value: 0x8133, lo: 0xa0, hi: 0xb1},
+       // Block 0x5a, offset 0x204
+       {value: 0x0000, lo: 0x01},
+       {value: 0x812e, lo: 0xab, hi: 0xad},
+       // Block 0x5b, offset 0x206
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0x93, hi: 0x93},
+       // Block 0x5c, offset 0x208
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8103, lo: 0xb3, hi: 0xb3},
+       // Block 0x5d, offset 0x20a
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0x80, hi: 0x80},
+       // Block 0x5e, offset 0x20c
+       {value: 0x0000, lo: 0x05},
+       {value: 0x8133, lo: 0xb0, hi: 0xb0},
+       {value: 0x8133, lo: 0xb2, hi: 0xb3},
+       {value: 0x812e, lo: 0xb4, hi: 0xb4},
+       {value: 0x8133, lo: 0xb7, hi: 0xb8},
+       {value: 0x8133, lo: 0xbe, hi: 0xbf},
+       // Block 0x5f, offset 0x212
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8133, lo: 0x81, hi: 0x81},
+       {value: 0x8105, lo: 0xb6, hi: 0xb6},
+       // Block 0x60, offset 0x215
+       {value: 0x0008, lo: 0x04},
+       {value: 0x163a, lo: 0x9c, hi: 0x9d},
+       {value: 0x0125, lo: 0x9e, hi: 0x9e},
+       {value: 0x1646, lo: 0x9f, hi: 0x9f},
+       {value: 0x015e, lo: 0xa9, hi: 0xa9},
+       // Block 0x61, offset 0x21a
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0xad, hi: 0xad},
+       // Block 0x62, offset 0x21c
+       {value: 0x0000, lo: 0x06},
+       {value: 0xe500, lo: 0x80, hi: 0x80},
+       {value: 0xc600, lo: 0x81, hi: 0x9b},
+       {value: 0xe500, lo: 0x9c, hi: 0x9c},
+       {value: 0xc600, lo: 0x9d, hi: 0xb7},
+       {value: 0xe500, lo: 0xb8, hi: 0xb8},
+       {value: 0xc600, lo: 0xb9, hi: 0xbf},
+       // Block 0x63, offset 0x223
+       {value: 0x0000, lo: 0x05},
+       {value: 0xc600, lo: 0x80, hi: 0x93},
+       {value: 0xe500, lo: 0x94, hi: 0x94},
+       {value: 0xc600, lo: 0x95, hi: 0xaf},
+       {value: 0xe500, lo: 0xb0, hi: 0xb0},
+       {value: 0xc600, lo: 0xb1, hi: 0xbf},
+       // Block 0x64, offset 0x229
+       {value: 0x0000, lo: 0x05},
+       {value: 0xc600, lo: 0x80, hi: 0x8b},
+       {value: 0xe500, lo: 0x8c, hi: 0x8c},
+       {value: 0xc600, lo: 0x8d, hi: 0xa7},
+       {value: 0xe500, lo: 0xa8, hi: 0xa8},
+       {value: 0xc600, lo: 0xa9, hi: 0xbf},
+       // Block 0x65, offset 0x22f
+       {value: 0x0000, lo: 0x07},
+       {value: 0xc600, lo: 0x80, hi: 0x83},
+       {value: 0xe500, lo: 0x84, hi: 0x84},
+       {value: 0xc600, lo: 0x85, hi: 0x9f},
+       {value: 0xe500, lo: 0xa0, hi: 0xa0},
+       {value: 0xc600, lo: 0xa1, hi: 0xbb},
+       {value: 0xe500, lo: 0xbc, hi: 0xbc},
+       {value: 0xc600, lo: 0xbd, hi: 0xbf},
+       // Block 0x66, offset 0x237
+       {value: 0x0000, lo: 0x05},
+       {value: 0xc600, lo: 0x80, hi: 0x97},
+       {value: 0xe500, lo: 0x98, hi: 0x98},
+       {value: 0xc600, lo: 0x99, hi: 0xb3},
+       {value: 0xe500, lo: 0xb4, hi: 0xb4},
+       {value: 0xc600, lo: 0xb5, hi: 0xbf},
+       // Block 0x67, offset 0x23d
+       {value: 0x0000, lo: 0x05},
+       {value: 0xc600, lo: 0x80, hi: 0x8f},
+       {value: 0xe500, lo: 0x90, hi: 0x90},
+       {value: 0xc600, lo: 0x91, hi: 0xab},
+       {value: 0xe500, lo: 0xac, hi: 0xac},
+       {value: 0xc600, lo: 0xad, hi: 0xbf},
+       // Block 0x68, offset 0x243
+       {value: 0x0000, lo: 0x05},
+       {value: 0xc600, lo: 0x80, hi: 0x87},
+       {value: 0xe500, lo: 0x88, hi: 0x88},
+       {value: 0xc600, lo: 0x89, hi: 0xa3},
+       {value: 0xe500, lo: 0xa4, hi: 0xa4},
+       {value: 0xc600, lo: 0xa5, hi: 0xbf},
+       // Block 0x69, offset 0x249
+       {value: 0x0000, lo: 0x03},
+       {value: 0xc600, lo: 0x80, hi: 0x87},
+       {value: 0xe500, lo: 0x88, hi: 0x88},
+       {value: 0xc600, lo: 0x89, hi: 0xa3},
+       // Block 0x6a, offset 0x24d
+       {value: 0x0002, lo: 0x01},
+       {value: 0x0003, lo: 0x81, hi: 0xbf},
+       // Block 0x6b, offset 0x24f
+       {value: 0x0000, lo: 0x01},
+       {value: 0x812e, lo: 0xbd, hi: 0xbd},
+       // Block 0x6c, offset 0x251
+       {value: 0x0000, lo: 0x01},
+       {value: 0x812e, lo: 0xa0, hi: 0xa0},
+       // Block 0x6d, offset 0x253
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0xb6, hi: 0xba},
+       // Block 0x6e, offset 0x255
+       {value: 0x002d, lo: 0x05},
+       {value: 0x812e, lo: 0x8d, hi: 0x8d},
+       {value: 0x8133, lo: 0x8f, hi: 0x8f},
+       {value: 0x8133, lo: 0xb8, hi: 0xb8},
+       {value: 0x8101, lo: 0xb9, hi: 0xba},
+       {value: 0x8105, lo: 0xbf, hi: 0xbf},
+       // Block 0x6f, offset 0x25b
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8133, lo: 0xa5, hi: 0xa5},
+       {value: 0x812e, lo: 0xa6, hi: 0xa6},
+       // Block 0x70, offset 0x25e
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0xa4, hi: 0xa7},
+       // Block 0x71, offset 0x260
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0xab, hi: 0xac},
+       // Block 0x72, offset 0x262
+       {value: 0x0000, lo: 0x05},
+       {value: 0x812e, lo: 0x86, hi: 0x87},
+       {value: 0x8133, lo: 0x88, hi: 0x8a},
+       {value: 0x812e, lo: 0x8b, hi: 0x8b},
+       {value: 0x8133, lo: 0x8c, hi: 0x8c},
+       {value: 0x812e, lo: 0x8d, hi: 0x90},
+       // Block 0x73, offset 0x268
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0x86, hi: 0x86},
+       {value: 0x8105, lo: 0xbf, hi: 0xbf},
+       // Block 0x74, offset 0x26b
+       {value: 0x17fe, lo: 0x07},
+       {value: 0xa000, lo: 0x99, hi: 0x99},
+       {value: 0x424f, lo: 0x9a, hi: 0x9a},
+       {value: 0xa000, lo: 0x9b, hi: 0x9b},
+       {value: 0x4259, lo: 0x9c, hi: 0x9c},
+       {value: 0xa000, lo: 0xa5, hi: 0xa5},
+       {value: 0x4263, lo: 0xab, hi: 0xab},
+       {value: 0x8105, lo: 0xb9, hi: 0xba},
+       // Block 0x75, offset 0x273
+       {value: 0x0000, lo: 0x06},
+       {value: 0x8133, lo: 0x80, hi: 0x82},
+       {value: 0x9900, lo: 0xa7, hi: 0xa7},
+       {value: 0x2d8b, lo: 0xae, hi: 0xae},
+       {value: 0x2d95, lo: 0xaf, hi: 0xaf},
+       {value: 0xa000, lo: 0xb1, hi: 0xb2},
+       {value: 0x8105, lo: 0xb3, hi: 0xb4},
+       // Block 0x76, offset 0x27a
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0x80, hi: 0x80},
+       {value: 0x8103, lo: 0x8a, hi: 0x8a},
+       // Block 0x77, offset 0x27d
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0xb5, hi: 0xb5},
+       {value: 0x8103, lo: 0xb6, hi: 0xb6},
+       // Block 0x78, offset 0x280
+       {value: 0x0002, lo: 0x01},
+       {value: 0x8103, lo: 0xa9, hi: 0xaa},
+       // Block 0x79, offset 0x282
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8103, lo: 0xbb, hi: 0xbc},
+       {value: 0x9900, lo: 0xbe, hi: 0xbe},
+       // Block 0x7a, offset 0x285
+       {value: 0x0000, lo: 0x07},
+       {value: 0xa000, lo: 0x87, hi: 0x87},
+       {value: 0x2d9f, lo: 0x8b, hi: 0x8b},
+       {value: 0x2da9, lo: 0x8c, hi: 0x8c},
+       {value: 0x8105, lo: 0x8d, hi: 0x8d},
+       {value: 0x9900, lo: 0x97, hi: 0x97},
+       {value: 0x8133, lo: 0xa6, hi: 0xac},
+       {value: 0x8133, lo: 0xb0, hi: 0xb4},
+       // Block 0x7b, offset 0x28d
+       {value: 0x0000, lo: 0x03},
+       {value: 0x8105, lo: 0x82, hi: 0x82},
+       {value: 0x8103, lo: 0x86, hi: 0x86},
+       {value: 0x8133, lo: 0x9e, hi: 0x9e},
+       // Block 0x7c, offset 0x291
+       {value: 0x6b4d, lo: 0x06},
+       {value: 0x9900, lo: 0xb0, hi: 0xb0},
+       {value: 0xa000, lo: 0xb9, hi: 0xb9},
+       {value: 0x9900, lo: 0xba, hi: 0xba},
+       {value: 0x2dbd, lo: 0xbb, hi: 0xbb},
+       {value: 0x2db3, lo: 0xbc, hi: 0xbd},
+       {value: 0x2dc7, lo: 0xbe, hi: 0xbe},
+       // Block 0x7d, offset 0x298
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0x82, hi: 0x82},
+       {value: 0x8103, lo: 0x83, hi: 0x83},
+       // Block 0x7e, offset 0x29b
+       {value: 0x0000, lo: 0x05},
+       {value: 0x9900, lo: 0xaf, hi: 0xaf},
+       {value: 0xa000, lo: 0xb8, hi: 0xb9},
+       {value: 0x2dd1, lo: 0xba, hi: 0xba},
+       {value: 0x2ddb, lo: 0xbb, hi: 0xbb},
+       {value: 0x8105, lo: 0xbf, hi: 0xbf},
+       // Block 0x7f, offset 0x2a1
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8103, lo: 0x80, hi: 0x80},
+       // Block 0x80, offset 0x2a3
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0xbf, hi: 0xbf},
+       // Block 0x81, offset 0x2a5
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0xb6, hi: 0xb6},
+       {value: 0x8103, lo: 0xb7, hi: 0xb7},
+       // Block 0x82, offset 0x2a8
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0xab, hi: 0xab},
+       // Block 0x83, offset 0x2aa
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8105, lo: 0xb9, hi: 0xb9},
+       {value: 0x8103, lo: 0xba, hi: 0xba},
+       // Block 0x84, offset 0x2ad
+       {value: 0x0000, lo: 0x04},
+       {value: 0x9900, lo: 0xb0, hi: 0xb0},
+       {value: 0xa000, lo: 0xb5, hi: 0xb5},
+       {value: 0x2de5, lo: 0xb8, hi: 0xb8},
+       {value: 0x8105, lo: 0xbd, hi: 0xbe},
+       // Block 0x85, offset 0x2b2
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8103, lo: 0x83, hi: 0x83},
+       // Block 0x86, offset 0x2b4
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0xa0, hi: 0xa0},
+       // Block 0x87, offset 0x2b6
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0xb4, hi: 0xb4},
+       // Block 0x88, offset 0x2b8
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0x87, hi: 0x87},
+       // Block 0x89, offset 0x2ba
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0x99, hi: 0x99},
+       // Block 0x8a, offset 0x2bc
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8103, lo: 0x82, hi: 0x82},
+       {value: 0x8105, lo: 0x84, hi: 0x85},
+       // Block 0x8b, offset 0x2bf
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8105, lo: 0x97, hi: 0x97},
+       // Block 0x8c, offset 0x2c1
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8101, lo: 0xb0, hi: 0xb4},
+       // Block 0x8d, offset 0x2c3
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0xb0, hi: 0xb6},
+       // Block 0x8e, offset 0x2c5
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8102, lo: 0xb0, hi: 0xb1},
+       // Block 0x8f, offset 0x2c7
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8101, lo: 0x9e, hi: 0x9e},
+       // Block 0x90, offset 0x2c9
+       {value: 0x0000, lo: 0x0c},
+       {value: 0x45e3, lo: 0x9e, hi: 0x9e},
+       {value: 0x45ed, lo: 0x9f, hi: 0x9f},
+       {value: 0x4621, lo: 0xa0, hi: 0xa0},
+       {value: 0x462f, lo: 0xa1, hi: 0xa1},
+       {value: 0x463d, lo: 0xa2, hi: 0xa2},
+       {value: 0x464b, lo: 0xa3, hi: 0xa3},
+       {value: 0x4659, lo: 0xa4, hi: 0xa4},
+       {value: 0x812c, lo: 0xa5, hi: 0xa6},
+       {value: 0x8101, lo: 0xa7, hi: 0xa9},
+       {value: 0x8131, lo: 0xad, hi: 0xad},
+       {value: 0x812c, lo: 0xae, hi: 0xb2},
+       {value: 0x812e, lo: 0xbb, hi: 0xbf},
+       // Block 0x91, offset 0x2d6
+       {value: 0x0000, lo: 0x09},
+       {value: 0x812e, lo: 0x80, hi: 0x82},
+       {value: 0x8133, lo: 0x85, hi: 0x89},
+       {value: 0x812e, lo: 0x8a, hi: 0x8b},
+       {value: 0x8133, lo: 0xaa, hi: 0xad},
+       {value: 0x45f7, lo: 0xbb, hi: 0xbb},
+       {value: 0x4601, lo: 0xbc, hi: 0xbc},
+       {value: 0x4667, lo: 0xbd, hi: 0xbd},
+       {value: 0x4683, lo: 0xbe, hi: 0xbe},
+       {value: 0x4675, lo: 0xbf, hi: 0xbf},
+       // Block 0x92, offset 0x2e0
+       {value: 0x0000, lo: 0x01},
+       {value: 0x4691, lo: 0x80, hi: 0x80},
+       // Block 0x93, offset 0x2e2
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0x82, hi: 0x84},
+       // Block 0x94, offset 0x2e4
+       {value: 0x0002, lo: 0x03},
+       {value: 0x0043, lo: 0x80, hi: 0x99},
+       {value: 0x0083, lo: 0x9a, hi: 0xb3},
+       {value: 0x0043, lo: 0xb4, hi: 0xbf},
+       // Block 0x95, offset 0x2e8
+       {value: 0x0002, lo: 0x04},
+       {value: 0x005b, lo: 0x80, hi: 0x8d},
+       {value: 0x0083, lo: 0x8e, hi: 0x94},
+       {value: 0x0093, lo: 0x96, hi: 0xa7},
+       {value: 0x0043, lo: 0xa8, hi: 0xbf},
+       // Block 0x96, offset 0x2ed
+       {value: 0x0002, lo: 0x0b},
+       {value: 0x0073, lo: 0x80, hi: 0x81},
+       {value: 0x0083, lo: 0x82, hi: 0x9b},
+       {value: 0x0043, lo: 0x9c, hi: 0x9c},
+       {value: 0x0047, lo: 0x9e, hi: 0x9f},
+       {value: 0x004f, lo: 0xa2, hi: 0xa2},
+       {value: 0x0055, lo: 0xa5, hi: 0xa6},
+       {value: 0x005d, lo: 0xa9, hi: 0xac},
+       {value: 0x0067, lo: 0xae, hi: 0xb5},
+       {value: 0x0083, lo: 0xb6, hi: 0xb9},
+       {value: 0x008d, lo: 0xbb, hi: 0xbb},
+       {value: 0x0091, lo: 0xbd, hi: 0xbf},
+       // Block 0x97, offset 0x2f9
+       {value: 0x0002, lo: 0x04},
+       {value: 0x0097, lo: 0x80, hi: 0x83},
+       {value: 0x00a1, lo: 0x85, hi: 0x8f},
+       {value: 0x0043, lo: 0x90, hi: 0xa9},
+       {value: 0x0083, lo: 0xaa, hi: 0xbf},
+       // Block 0x98, offset 0x2fe
+       {value: 0x0002, lo: 0x08},
+       {value: 0x00af, lo: 0x80, hi: 0x83},
+       {value: 0x0043, lo: 0x84, hi: 0x85},
+       {value: 0x0049, lo: 0x87, hi: 0x8a},
+       {value: 0x0055, lo: 0x8d, hi: 0x94},
+       {value: 0x0067, lo: 0x96, hi: 0x9c},
+       {value: 0x0083, lo: 0x9e, hi: 0xb7},
+       {value: 0x0043, lo: 0xb8, hi: 0xb9},
+       {value: 0x0049, lo: 0xbb, hi: 0xbe},
+       // Block 0x99, offset 0x307
+       {value: 0x0002, lo: 0x05},
+       {value: 0x0053, lo: 0x80, hi: 0x84},
+       {value: 0x005f, lo: 0x86, hi: 0x86},
+       {value: 0x0067, lo: 0x8a, hi: 0x90},
+       {value: 0x0083, lo: 0x92, hi: 0xab},
+       {value: 0x0043, lo: 0xac, hi: 0xbf},
+       // Block 0x9a, offset 0x30d
+       {value: 0x0002, lo: 0x04},
+       {value: 0x006b, lo: 0x80, hi: 0x85},
+       {value: 0x0083, lo: 0x86, hi: 0x9f},
+       {value: 0x0043, lo: 0xa0, hi: 0xb9},
+       {value: 0x0083, lo: 0xba, hi: 0xbf},
+       // Block 0x9b, offset 0x312
+       {value: 0x0002, lo: 0x03},
+       {value: 0x008f, lo: 0x80, hi: 0x93},
+       {value: 0x0043, lo: 0x94, hi: 0xad},
+       {value: 0x0083, lo: 0xae, hi: 0xbf},
+       // Block 0x9c, offset 0x316
+       {value: 0x0002, lo: 0x04},
+       {value: 0x00a7, lo: 0x80, hi: 0x87},
+       {value: 0x0043, lo: 0x88, hi: 0xa1},
+       {value: 0x0083, lo: 0xa2, hi: 0xbb},
+       {value: 0x0043, lo: 0xbc, hi: 0xbf},
+       // Block 0x9d, offset 0x31b
+       {value: 0x0002, lo: 0x03},
+       {value: 0x004b, lo: 0x80, hi: 0x95},
+       {value: 0x0083, lo: 0x96, hi: 0xaf},
+       {value: 0x0043, lo: 0xb0, hi: 0xbf},
+       // Block 0x9e, offset 0x31f
+       {value: 0x0003, lo: 0x0f},
+       {value: 0x01bb, lo: 0x80, hi: 0x80},
+       {value: 0x0462, lo: 0x81, hi: 0x81},
+       {value: 0x01be, lo: 0x82, hi: 0x9a},
+       {value: 0x045e, lo: 0x9b, hi: 0x9b},
+       {value: 0x01ca, lo: 0x9c, hi: 0x9c},
+       {value: 0x01d3, lo: 0x9d, hi: 0x9d},
+       {value: 0x01d9, lo: 0x9e, hi: 0x9e},
+       {value: 0x01fd, lo: 0x9f, hi: 0x9f},
+       {value: 0x01ee, lo: 0xa0, hi: 0xa0},
+       {value: 0x01eb, lo: 0xa1, hi: 0xa1},
+       {value: 0x0176, lo: 0xa2, hi: 0xb2},
+       {value: 0x018b, lo: 0xb3, hi: 0xb3},
+       {value: 0x01a9, lo: 0xb4, hi: 0xba},
+       {value: 0x0462, lo: 0xbb, hi: 0xbb},
+       {value: 0x01be, lo: 0xbc, hi: 0xbf},
+       // Block 0x9f, offset 0x32f
+       {value: 0x0003, lo: 0x0d},
+       {value: 0x01ca, lo: 0x80, hi: 0x94},
+       {value: 0x045e, lo: 0x95, hi: 0x95},
+       {value: 0x01ca, lo: 0x96, hi: 0x96},
+       {value: 0x01d3, lo: 0x97, hi: 0x97},
+       {value: 0x01d9, lo: 0x98, hi: 0x98},
+       {value: 0x01fd, lo: 0x99, hi: 0x99},
+       {value: 0x01ee, lo: 0x9a, hi: 0x9a},
+       {value: 0x01eb, lo: 0x9b, hi: 0x9b},
+       {value: 0x0176, lo: 0x9c, hi: 0xac},
+       {value: 0x018b, lo: 0xad, hi: 0xad},
+       {value: 0x01a9, lo: 0xae, hi: 0xb4},
+       {value: 0x0462, lo: 0xb5, hi: 0xb5},
+       {value: 0x01be, lo: 0xb6, hi: 0xbf},
+       // Block 0xa0, offset 0x33d
+       {value: 0x0003, lo: 0x0d},
+       {value: 0x01dc, lo: 0x80, hi: 0x8e},
+       {value: 0x045e, lo: 0x8f, hi: 0x8f},
+       {value: 0x01ca, lo: 0x90, hi: 0x90},
+       {value: 0x01d3, lo: 0x91, hi: 0x91},
+       {value: 0x01d9, lo: 0x92, hi: 0x92},
+       {value: 0x01fd, lo: 0x93, hi: 0x93},
+       {value: 0x01ee, lo: 0x94, hi: 0x94},
+       {value: 0x01eb, lo: 0x95, hi: 0x95},
+       {value: 0x0176, lo: 0x96, hi: 0xa6},
+       {value: 0x018b, lo: 0xa7, hi: 0xa7},
+       {value: 0x01a9, lo: 0xa8, hi: 0xae},
+       {value: 0x0462, lo: 0xaf, hi: 0xaf},
+       {value: 0x01be, lo: 0xb0, hi: 0xbf},
+       // Block 0xa1, offset 0x34b
+       {value: 0x0003, lo: 0x0d},
+       {value: 0x01ee, lo: 0x80, hi: 0x88},
+       {value: 0x045e, lo: 0x89, hi: 0x89},
+       {value: 0x01ca, lo: 0x8a, hi: 0x8a},
+       {value: 0x01d3, lo: 0x8b, hi: 0x8b},
+       {value: 0x01d9, lo: 0x8c, hi: 0x8c},
+       {value: 0x01fd, lo: 0x8d, hi: 0x8d},
+       {value: 0x01ee, lo: 0x8e, hi: 0x8e},
+       {value: 0x01eb, lo: 0x8f, hi: 0x8f},
+       {value: 0x0176, lo: 0x90, hi: 0xa0},
+       {value: 0x018b, lo: 0xa1, hi: 0xa1},
+       {value: 0x01a9, lo: 0xa2, hi: 0xa8},
+       {value: 0x0462, lo: 0xa9, hi: 0xa9},
+       {value: 0x01be, lo: 0xaa, hi: 0xbf},
+       // Block 0xa2, offset 0x359
+       {value: 0x0000, lo: 0x05},
+       {value: 0x8133, lo: 0x80, hi: 0x86},
+       {value: 0x8133, lo: 0x88, hi: 0x98},
+       {value: 0x8133, lo: 0x9b, hi: 0xa1},
+       {value: 0x8133, lo: 0xa3, hi: 0xa4},
+       {value: 0x8133, lo: 0xa6, hi: 0xaa},
+       // Block 0xa3, offset 0x35f
+       {value: 0x0000, lo: 0x01},
+       {value: 0x8133, lo: 0xac, hi: 0xaf},
+       // Block 0xa4, offset 0x361
+       {value: 0x0000, lo: 0x01},
+       {value: 0x812e, lo: 0x90, hi: 0x96},
+       // Block 0xa5, offset 0x363
+       {value: 0x0000, lo: 0x02},
+       {value: 0x8133, lo: 0x84, hi: 0x89},
+       {value: 0x8103, lo: 0x8a, hi: 0x8a},
+       // Block 0xa6, offset 0x366
+       {value: 0x0002, lo: 0x0a},
+       {value: 0x0063, lo: 0x80, hi: 0x89},
+       {value: 0x1954, lo: 0x8a, hi: 0x8a},
+       {value: 0x1987, lo: 0x8b, hi: 0x8b},
+       {value: 0x19a2, lo: 0x8c, hi: 0x8c},
+       {value: 0x19a8, lo: 0x8d, hi: 0x8d},
+       {value: 0x1bc6, lo: 0x8e, hi: 0x8e},
+       {value: 0x19b4, lo: 0x8f, hi: 0x8f},
+       {value: 0x197e, lo: 0xaa, hi: 0xaa},
+       {value: 0x1981, lo: 0xab, hi: 0xab},
+       {value: 0x1984, lo: 0xac, hi: 0xac},
+       // Block 0xa7, offset 0x371
+       {value: 0x0000, lo: 0x01},
+       {value: 0x1942, lo: 0x90, hi: 0x90},
+       // Block 0xa8, offset 0x373
+       {value: 0x0028, lo: 0x09},
+       {value: 0x286f, lo: 0x80, hi: 0x80},
+       {value: 0x2833, lo: 0x81, hi: 0x81},
+       {value: 0x283d, lo: 0x82, hi: 0x82},
+       {value: 0x2851, lo: 0x83, hi: 0x84},
+       {value: 0x285b, lo: 0x85, hi: 0x86},
+       {value: 0x2847, lo: 0x87, hi: 0x87},
+       {value: 0x2865, lo: 0x88, hi: 0x88},
+       {value: 0x0b72, lo: 0x90, hi: 0x90},
+       {value: 0x08ea, lo: 0x91, hi: 0x91},
+       // Block 0xa9, offset 0x37d
+       {value: 0x0002, lo: 0x01},
+       {value: 0x0021, lo: 0xb0, hi: 0xb9},
+}
+
+// recompMap: 7528 bytes (entries only)
+var recompMap map[uint32]rune
+var recompMapOnce sync.Once
+
+const recompMapPacked = "" +
+       "\x00A\x03\x00\x00\x00\x00\xc0" + // 0x00410300: 0x000000C0
+       "\x00A\x03\x01\x00\x00\x00\xc1" + // 0x00410301: 0x000000C1
+       "\x00A\x03\x02\x00\x00\x00\xc2" + // 0x00410302: 0x000000C2
+       "\x00A\x03\x03\x00\x00\x00\xc3" + // 0x00410303: 0x000000C3
+       "\x00A\x03\b\x00\x00\x00\xc4" + // 0x00410308: 0x000000C4
+       "\x00A\x03\n\x00\x00\x00\xc5" + // 0x0041030A: 0x000000C5
+       "\x00C\x03'\x00\x00\x00\xc7" + // 0x00430327: 0x000000C7
+       "\x00E\x03\x00\x00\x00\x00\xc8" + // 0x00450300: 0x000000C8
+       "\x00E\x03\x01\x00\x00\x00\xc9" + // 0x00450301: 0x000000C9
+       "\x00E\x03\x02\x00\x00\x00\xca" + // 0x00450302: 0x000000CA
+       "\x00E\x03\b\x00\x00\x00\xcb" + // 0x00450308: 0x000000CB
+       "\x00I\x03\x00\x00\x00\x00\xcc" + // 0x00490300: 0x000000CC
+       "\x00I\x03\x01\x00\x00\x00\xcd" + // 0x00490301: 0x000000CD
+       "\x00I\x03\x02\x00\x00\x00\xce" + // 0x00490302: 0x000000CE
+       "\x00I\x03\b\x00\x00\x00\xcf" + // 0x00490308: 0x000000CF
+       "\x00N\x03\x03\x00\x00\x00\xd1" + // 0x004E0303: 0x000000D1
+       "\x00O\x03\x00\x00\x00\x00\xd2" + // 0x004F0300: 0x000000D2
+       "\x00O\x03\x01\x00\x00\x00\xd3" + // 0x004F0301: 0x000000D3
+       "\x00O\x03\x02\x00\x00\x00\xd4" + // 0x004F0302: 0x000000D4
+       "\x00O\x03\x03\x00\x00\x00\xd5" + // 0x004F0303: 0x000000D5
+       "\x00O\x03\b\x00\x00\x00\xd6" + // 0x004F0308: 0x000000D6
+       "\x00U\x03\x00\x00\x00\x00\xd9" + // 0x00550300: 0x000000D9
+       "\x00U\x03\x01\x00\x00\x00\xda" + // 0x00550301: 0x000000DA
+       "\x00U\x03\x02\x00\x00\x00\xdb" + // 0x00550302: 0x000000DB
+       "\x00U\x03\b\x00\x00\x00\xdc" + // 0x00550308: 0x000000DC
+       "\x00Y\x03\x01\x00\x00\x00\xdd" + // 0x00590301: 0x000000DD
+       "\x00a\x03\x00\x00\x00\x00\xe0" + // 0x00610300: 0x000000E0
+       "\x00a\x03\x01\x00\x00\x00\xe1" + // 0x00610301: 0x000000E1
+       "\x00a\x03\x02\x00\x00\x00\xe2" + // 0x00610302: 0x000000E2
+       "\x00a\x03\x03\x00\x00\x00\xe3" + // 0x00610303: 0x000000E3
+       "\x00a\x03\b\x00\x00\x00\xe4" + // 0x00610308: 0x000000E4
+       "\x00a\x03\n\x00\x00\x00\xe5" + // 0x0061030A: 0x000000E5
+       "\x00c\x03'\x00\x00\x00\xe7" + // 0x00630327: 0x000000E7
+       "\x00e\x03\x00\x00\x00\x00\xe8" + // 0x00650300: 0x000000E8
+       "\x00e\x03\x01\x00\x00\x00\xe9" + // 0x00650301: 0x000000E9
+       "\x00e\x03\x02\x00\x00\x00\xea" + // 0x00650302: 0x000000EA
+       "\x00e\x03\b\x00\x00\x00\xeb" + // 0x00650308: 0x000000EB
+       "\x00i\x03\x00\x00\x00\x00\xec" + // 0x00690300: 0x000000EC
+       "\x00i\x03\x01\x00\x00\x00\xed" + // 0x00690301: 0x000000ED
+       "\x00i\x03\x02\x00\x00\x00\xee" + // 0x00690302: 0x000000EE
+       "\x00i\x03\b\x00\x00\x00\xef" + // 0x00690308: 0x000000EF
+       "\x00n\x03\x03\x00\x00\x00\xf1" + // 0x006E0303: 0x000000F1
+       "\x00o\x03\x00\x00\x00\x00\xf2" + // 0x006F0300: 0x000000F2
+       "\x00o\x03\x01\x00\x00\x00\xf3" + // 0x006F0301: 0x000000F3
+       "\x00o\x03\x02\x00\x00\x00\xf4" + // 0x006F0302: 0x000000F4
+       "\x00o\x03\x03\x00\x00\x00\xf5" + // 0x006F0303: 0x000000F5
+       "\x00o\x03\b\x00\x00\x00\xf6" + // 0x006F0308: 0x000000F6
+       "\x00u\x03\x00\x00\x00\x00\xf9" + // 0x00750300: 0x000000F9
+       "\x00u\x03\x01\x00\x00\x00\xfa" + // 0x00750301: 0x000000FA
+       "\x00u\x03\x02\x00\x00\x00\xfb" + // 0x00750302: 0x000000FB
+       "\x00u\x03\b\x00\x00\x00\xfc" + // 0x00750308: 0x000000FC
+       "\x00y\x03\x01\x00\x00\x00\xfd" + // 0x00790301: 0x000000FD
+       "\x00y\x03\b\x00\x00\x00\xff" + // 0x00790308: 0x000000FF
+       "\x00A\x03\x04\x00\x00\x01\x00" + // 0x00410304: 0x00000100
+       "\x00a\x03\x04\x00\x00\x01\x01" + // 0x00610304: 0x00000101
+       "\x00A\x03\x06\x00\x00\x01\x02" + // 0x00410306: 0x00000102
+       "\x00a\x03\x06\x00\x00\x01\x03" + // 0x00610306: 0x00000103
+       "\x00A\x03(\x00\x00\x01\x04" + // 0x00410328: 0x00000104
+       "\x00a\x03(\x00\x00\x01\x05" + // 0x00610328: 0x00000105
+       "\x00C\x03\x01\x00\x00\x01\x06" + // 0x00430301: 0x00000106
+       "\x00c\x03\x01\x00\x00\x01\a" + // 0x00630301: 0x00000107
+       "\x00C\x03\x02\x00\x00\x01\b" + // 0x00430302: 0x00000108
+       "\x00c\x03\x02\x00\x00\x01\t" + // 0x00630302: 0x00000109
+       "\x00C\x03\a\x00\x00\x01\n" + // 0x00430307: 0x0000010A
+       "\x00c\x03\a\x00\x00\x01\v" + // 0x00630307: 0x0000010B
+       "\x00C\x03\f\x00\x00\x01\f" + // 0x0043030C: 0x0000010C
+       "\x00c\x03\f\x00\x00\x01\r" + // 0x0063030C: 0x0000010D
+       "\x00D\x03\f\x00\x00\x01\x0e" + // 0x0044030C: 0x0000010E
+       "\x00d\x03\f\x00\x00\x01\x0f" + // 0x0064030C: 0x0000010F
+       "\x00E\x03\x04\x00\x00\x01\x12" + // 0x00450304: 0x00000112
+       "\x00e\x03\x04\x00\x00\x01\x13" + // 0x00650304: 0x00000113
+       "\x00E\x03\x06\x00\x00\x01\x14" + // 0x00450306: 0x00000114
+       "\x00e\x03\x06\x00\x00\x01\x15" + // 0x00650306: 0x00000115
+       "\x00E\x03\a\x00\x00\x01\x16" + // 0x00450307: 0x00000116
+       "\x00e\x03\a\x00\x00\x01\x17" + // 0x00650307: 0x00000117
+       "\x00E\x03(\x00\x00\x01\x18" + // 0x00450328: 0x00000118
+       "\x00e\x03(\x00\x00\x01\x19" + // 0x00650328: 0x00000119
+       "\x00E\x03\f\x00\x00\x01\x1a" + // 0x0045030C: 0x0000011A
+       "\x00e\x03\f\x00\x00\x01\x1b" + // 0x0065030C: 0x0000011B
+       "\x00G\x03\x02\x00\x00\x01\x1c" + // 0x00470302: 0x0000011C
+       "\x00g\x03\x02\x00\x00\x01\x1d" + // 0x00670302: 0x0000011D
+       "\x00G\x03\x06\x00\x00\x01\x1e" + // 0x00470306: 0x0000011E
+       "\x00g\x03\x06\x00\x00\x01\x1f" + // 0x00670306: 0x0000011F
+       "\x00G\x03\a\x00\x00\x01 " + // 0x00470307: 0x00000120
+       "\x00g\x03\a\x00\x00\x01!" + // 0x00670307: 0x00000121
+       "\x00G\x03'\x00\x00\x01\"" + // 0x00470327: 0x00000122
+       "\x00g\x03'\x00\x00\x01#" + // 0x00670327: 0x00000123
+       "\x00H\x03\x02\x00\x00\x01$" + // 0x00480302: 0x00000124
+       "\x00h\x03\x02\x00\x00\x01%" + // 0x00680302: 0x00000125
+       "\x00I\x03\x03\x00\x00\x01(" + // 0x00490303: 0x00000128
+       "\x00i\x03\x03\x00\x00\x01)" + // 0x00690303: 0x00000129
+       "\x00I\x03\x04\x00\x00\x01*" + // 0x00490304: 0x0000012A
+       "\x00i\x03\x04\x00\x00\x01+" + // 0x00690304: 0x0000012B
+       "\x00I\x03\x06\x00\x00\x01," + // 0x00490306: 0x0000012C
+       "\x00i\x03\x06\x00\x00\x01-" + // 0x00690306: 0x0000012D
+       "\x00I\x03(\x00\x00\x01." + // 0x00490328: 0x0000012E
+       "\x00i\x03(\x00\x00\x01/" + // 0x00690328: 0x0000012F
+       "\x00I\x03\a\x00\x00\x010" + // 0x00490307: 0x00000130
+       "\x00J\x03\x02\x00\x00\x014" + // 0x004A0302: 0x00000134
+       "\x00j\x03\x02\x00\x00\x015" + // 0x006A0302: 0x00000135
+       "\x00K\x03'\x00\x00\x016" + // 0x004B0327: 0x00000136
+       "\x00k\x03'\x00\x00\x017" + // 0x006B0327: 0x00000137
+       "\x00L\x03\x01\x00\x00\x019" + // 0x004C0301: 0x00000139
+       "\x00l\x03\x01\x00\x00\x01:" + // 0x006C0301: 0x0000013A
+       "\x00L\x03'\x00\x00\x01;" + // 0x004C0327: 0x0000013B
+       "\x00l\x03'\x00\x00\x01<" + // 0x006C0327: 0x0000013C
+       "\x00L\x03\f\x00\x00\x01=" + // 0x004C030C: 0x0000013D
+       "\x00l\x03\f\x00\x00\x01>" + // 0x006C030C: 0x0000013E
+       "\x00N\x03\x01\x00\x00\x01C" + // 0x004E0301: 0x00000143
+       "\x00n\x03\x01\x00\x00\x01D" + // 0x006E0301: 0x00000144
+       "\x00N\x03'\x00\x00\x01E" + // 0x004E0327: 0x00000145
+       "\x00n\x03'\x00\x00\x01F" + // 0x006E0327: 0x00000146
+       "\x00N\x03\f\x00\x00\x01G" + // 0x004E030C: 0x00000147
+       "\x00n\x03\f\x00\x00\x01H" + // 0x006E030C: 0x00000148
+       "\x00O\x03\x04\x00\x00\x01L" + // 0x004F0304: 0x0000014C
+       "\x00o\x03\x04\x00\x00\x01M" + // 0x006F0304: 0x0000014D
+       "\x00O\x03\x06\x00\x00\x01N" + // 0x004F0306: 0x0000014E
+       "\x00o\x03\x06\x00\x00\x01O" + // 0x006F0306: 0x0000014F
+       "\x00O\x03\v\x00\x00\x01P" + // 0x004F030B: 0x00000150
+       "\x00o\x03\v\x00\x00\x01Q" + // 0x006F030B: 0x00000151
+       "\x00R\x03\x01\x00\x00\x01T" + // 0x00520301: 0x00000154
+       "\x00r\x03\x01\x00\x00\x01U" + // 0x00720301: 0x00000155
+       "\x00R\x03'\x00\x00\x01V" + // 0x00520327: 0x00000156
+       "\x00r\x03'\x00\x00\x01W" + // 0x00720327: 0x00000157
+       "\x00R\x03\f\x00\x00\x01X" + // 0x0052030C: 0x00000158
+       "\x00r\x03\f\x00\x00\x01Y" + // 0x0072030C: 0x00000159
+       "\x00S\x03\x01\x00\x00\x01Z" + // 0x00530301: 0x0000015A
+       "\x00s\x03\x01\x00\x00\x01[" + // 0x00730301: 0x0000015B
+       "\x00S\x03\x02\x00\x00\x01\\" + // 0x00530302: 0x0000015C
+       "\x00s\x03\x02\x00\x00\x01]" + // 0x00730302: 0x0000015D
+       "\x00S\x03'\x00\x00\x01^" + // 0x00530327: 0x0000015E
+       "\x00s\x03'\x00\x00\x01_" + // 0x00730327: 0x0000015F
+       "\x00S\x03\f\x00\x00\x01`" + // 0x0053030C: 0x00000160
+       "\x00s\x03\f\x00\x00\x01a" + // 0x0073030C: 0x00000161
+       "\x00T\x03'\x00\x00\x01b" + // 0x00540327: 0x00000162
+       "\x00t\x03'\x00\x00\x01c" + // 0x00740327: 0x00000163
+       "\x00T\x03\f\x00\x00\x01d" + // 0x0054030C: 0x00000164
+       "\x00t\x03\f\x00\x00\x01e" + // 0x0074030C: 0x00000165
+       "\x00U\x03\x03\x00\x00\x01h" + // 0x00550303: 0x00000168
+       "\x00u\x03\x03\x00\x00\x01i" + // 0x00750303: 0x00000169
+       "\x00U\x03\x04\x00\x00\x01j" + // 0x00550304: 0x0000016A
+       "\x00u\x03\x04\x00\x00\x01k" + // 0x00750304: 0x0000016B
+       "\x00U\x03\x06\x00\x00\x01l" + // 0x00550306: 0x0000016C
+       "\x00u\x03\x06\x00\x00\x01m" + // 0x00750306: 0x0000016D
+       "\x00U\x03\n\x00\x00\x01n" + // 0x0055030A: 0x0000016E
+       "\x00u\x03\n\x00\x00\x01o" + // 0x0075030A: 0x0000016F
+       "\x00U\x03\v\x00\x00\x01p" + // 0x0055030B: 0x00000170
+       "\x00u\x03\v\x00\x00\x01q" + // 0x0075030B: 0x00000171
+       "\x00U\x03(\x00\x00\x01r" + // 0x00550328: 0x00000172
+       "\x00u\x03(\x00\x00\x01s" + // 0x00750328: 0x00000173
+       "\x00W\x03\x02\x00\x00\x01t" + // 0x00570302: 0x00000174
+       "\x00w\x03\x02\x00\x00\x01u" + // 0x00770302: 0x00000175
+       "\x00Y\x03\x02\x00\x00\x01v" + // 0x00590302: 0x00000176
+       "\x00y\x03\x02\x00\x00\x01w" + // 0x00790302: 0x00000177
+       "\x00Y\x03\b\x00\x00\x01x" + // 0x00590308: 0x00000178
+       "\x00Z\x03\x01\x00\x00\x01y" + // 0x005A0301: 0x00000179
+       "\x00z\x03\x01\x00\x00\x01z" + // 0x007A0301: 0x0000017A
+       "\x00Z\x03\a\x00\x00\x01{" + // 0x005A0307: 0x0000017B
+       "\x00z\x03\a\x00\x00\x01|" + // 0x007A0307: 0x0000017C
+       "\x00Z\x03\f\x00\x00\x01}" + // 0x005A030C: 0x0000017D
+       "\x00z\x03\f\x00\x00\x01~" + // 0x007A030C: 0x0000017E
+       "\x00O\x03\x1b\x00\x00\x01\xa0" + // 0x004F031B: 0x000001A0
+       "\x00o\x03\x1b\x00\x00\x01\xa1" + // 0x006F031B: 0x000001A1
+       "\x00U\x03\x1b\x00\x00\x01\xaf" + // 0x0055031B: 0x000001AF
+       "\x00u\x03\x1b\x00\x00\x01\xb0" + // 0x0075031B: 0x000001B0
+       "\x00A\x03\f\x00\x00\x01\xcd" + // 0x0041030C: 0x000001CD
+       "\x00a\x03\f\x00\x00\x01\xce" + // 0x0061030C: 0x000001CE
+       "\x00I\x03\f\x00\x00\x01\xcf" + // 0x0049030C: 0x000001CF
+       "\x00i\x03\f\x00\x00\x01\xd0" + // 0x0069030C: 0x000001D0
+       "\x00O\x03\f\x00\x00\x01\xd1" + // 0x004F030C: 0x000001D1
+       "\x00o\x03\f\x00\x00\x01\xd2" + // 0x006F030C: 0x000001D2
+       "\x00U\x03\f\x00\x00\x01\xd3" + // 0x0055030C: 0x000001D3
+       "\x00u\x03\f\x00\x00\x01\xd4" + // 0x0075030C: 0x000001D4
+       "\x00\xdc\x03\x04\x00\x00\x01\xd5" + // 0x00DC0304: 0x000001D5
+       "\x00\xfc\x03\x04\x00\x00\x01\xd6" + // 0x00FC0304: 0x000001D6
+       "\x00\xdc\x03\x01\x00\x00\x01\xd7" + // 0x00DC0301: 0x000001D7
+       "\x00\xfc\x03\x01\x00\x00\x01\xd8" + // 0x00FC0301: 0x000001D8
+       "\x00\xdc\x03\f\x00\x00\x01\xd9" + // 0x00DC030C: 0x000001D9
+       "\x00\xfc\x03\f\x00\x00\x01\xda" + // 0x00FC030C: 0x000001DA
+       "\x00\xdc\x03\x00\x00\x00\x01\xdb" + // 0x00DC0300: 0x000001DB
+       "\x00\xfc\x03\x00\x00\x00\x01\xdc" + // 0x00FC0300: 0x000001DC
+       "\x00\xc4\x03\x04\x00\x00\x01\xde" + // 0x00C40304: 0x000001DE
+       "\x00\xe4\x03\x04\x00\x00\x01\xdf" + // 0x00E40304: 0x000001DF
+       "\x02&\x03\x04\x00\x00\x01\xe0" + // 0x02260304: 0x000001E0
+       "\x02'\x03\x04\x00\x00\x01\xe1" + // 0x02270304: 0x000001E1
+       "\x00\xc6\x03\x04\x00\x00\x01\xe2" + // 0x00C60304: 0x000001E2
+       "\x00\xe6\x03\x04\x00\x00\x01\xe3" + // 0x00E60304: 0x000001E3
+       "\x00G\x03\f\x00\x00\x01\xe6" + // 0x0047030C: 0x000001E6
+       "\x00g\x03\f\x00\x00\x01\xe7" + // 0x0067030C: 0x000001E7
+       "\x00K\x03\f\x00\x00\x01\xe8" + // 0x004B030C: 0x000001E8
+       "\x00k\x03\f\x00\x00\x01\xe9" + // 0x006B030C: 0x000001E9
+       "\x00O\x03(\x00\x00\x01\xea" + // 0x004F0328: 0x000001EA
+       "\x00o\x03(\x00\x00\x01\xeb" + // 0x006F0328: 0x000001EB
+       "\x01\xea\x03\x04\x00\x00\x01\xec" + // 0x01EA0304: 0x000001EC
+       "\x01\xeb\x03\x04\x00\x00\x01\xed" + // 0x01EB0304: 0x000001ED
+       "\x01\xb7\x03\f\x00\x00\x01\xee" + // 0x01B7030C: 0x000001EE
+       "\x02\x92\x03\f\x00\x00\x01\xef" + // 0x0292030C: 0x000001EF
+       "\x00j\x03\f\x00\x00\x01\xf0" + // 0x006A030C: 0x000001F0
+       "\x00G\x03\x01\x00\x00\x01\xf4" + // 0x00470301: 0x000001F4
+       "\x00g\x03\x01\x00\x00\x01\xf5" + // 0x00670301: 0x000001F5
+       "\x00N\x03\x00\x00\x00\x01\xf8" + // 0x004E0300: 0x000001F8
+       "\x00n\x03\x00\x00\x00\x01\xf9" + // 0x006E0300: 0x000001F9
+       "\x00\xc5\x03\x01\x00\x00\x01\xfa" + // 0x00C50301: 0x000001FA
+       "\x00\xe5\x03\x01\x00\x00\x01\xfb" + // 0x00E50301: 0x000001FB
+       "\x00\xc6\x03\x01\x00\x00\x01\xfc" + // 0x00C60301: 0x000001FC
+       "\x00\xe6\x03\x01\x00\x00\x01\xfd" + // 0x00E60301: 0x000001FD
+       "\x00\xd8\x03\x01\x00\x00\x01\xfe" + // 0x00D80301: 0x000001FE
+       "\x00\xf8\x03\x01\x00\x00\x01\xff" + // 0x00F80301: 0x000001FF
+       "\x00A\x03\x0f\x00\x00\x02\x00" + // 0x0041030F: 0x00000200
+       "\x00a\x03\x0f\x00\x00\x02\x01" + // 0x0061030F: 0x00000201
+       "\x00A\x03\x11\x00\x00\x02\x02" + // 0x00410311: 0x00000202
+       "\x00a\x03\x11\x00\x00\x02\x03" + // 0x00610311: 0x00000203
+       "\x00E\x03\x0f\x00\x00\x02\x04" + // 0x0045030F: 0x00000204
+       "\x00e\x03\x0f\x00\x00\x02\x05" + // 0x0065030F: 0x00000205
+       "\x00E\x03\x11\x00\x00\x02\x06" + // 0x00450311: 0x00000206
+       "\x00e\x03\x11\x00\x00\x02\a" + // 0x00650311: 0x00000207
+       "\x00I\x03\x0f\x00\x00\x02\b" + // 0x0049030F: 0x00000208
+       "\x00i\x03\x0f\x00\x00\x02\t" + // 0x0069030F: 0x00000209
+       "\x00I\x03\x11\x00\x00\x02\n" + // 0x00490311: 0x0000020A
+       "\x00i\x03\x11\x00\x00\x02\v" + // 0x00690311: 0x0000020B
+       "\x00O\x03\x0f\x00\x00\x02\f" + // 0x004F030F: 0x0000020C
+       "\x00o\x03\x0f\x00\x00\x02\r" + // 0x006F030F: 0x0000020D
+       "\x00O\x03\x11\x00\x00\x02\x0e" + // 0x004F0311: 0x0000020E
+       "\x00o\x03\x11\x00\x00\x02\x0f" + // 0x006F0311: 0x0000020F
+       "\x00R\x03\x0f\x00\x00\x02\x10" + // 0x0052030F: 0x00000210
+       "\x00r\x03\x0f\x00\x00\x02\x11" + // 0x0072030F: 0x00000211
+       "\x00R\x03\x11\x00\x00\x02\x12" + // 0x00520311: 0x00000212
+       "\x00r\x03\x11\x00\x00\x02\x13" + // 0x00720311: 0x00000213
+       "\x00U\x03\x0f\x00\x00\x02\x14" + // 0x0055030F: 0x00000214
+       "\x00u\x03\x0f\x00\x00\x02\x15" + // 0x0075030F: 0x00000215
+       "\x00U\x03\x11\x00\x00\x02\x16" + // 0x00550311: 0x00000216
+       "\x00u\x03\x11\x00\x00\x02\x17" + // 0x00750311: 0x00000217
+       "\x00S\x03&\x00\x00\x02\x18" + // 0x00530326: 0x00000218
+       "\x00s\x03&\x00\x00\x02\x19" + // 0x00730326: 0x00000219
+       "\x00T\x03&\x00\x00\x02\x1a" + // 0x00540326: 0x0000021A
+       "\x00t\x03&\x00\x00\x02\x1b" + // 0x00740326: 0x0000021B
+       "\x00H\x03\f\x00\x00\x02\x1e" + // 0x0048030C: 0x0000021E
+       "\x00h\x03\f\x00\x00\x02\x1f" + // 0x0068030C: 0x0000021F
+       "\x00A\x03\a\x00\x00\x02&" + // 0x00410307: 0x00000226
+       "\x00a\x03\a\x00\x00\x02'" + // 0x00610307: 0x00000227
+       "\x00E\x03'\x00\x00\x02(" + // 0x00450327: 0x00000228
+       "\x00e\x03'\x00\x00\x02)" + // 0x00650327: 0x00000229
+       "\x00\xd6\x03\x04\x00\x00\x02*" + // 0x00D60304: 0x0000022A
+       "\x00\xf6\x03\x04\x00\x00\x02+" + // 0x00F60304: 0x0000022B
+       "\x00\xd5\x03\x04\x00\x00\x02," + // 0x00D50304: 0x0000022C
+       "\x00\xf5\x03\x04\x00\x00\x02-" + // 0x00F50304: 0x0000022D
+       "\x00O\x03\a\x00\x00\x02." + // 0x004F0307: 0x0000022E
+       "\x00o\x03\a\x00\x00\x02/" + // 0x006F0307: 0x0000022F
+       "\x02.\x03\x04\x00\x00\x020" + // 0x022E0304: 0x00000230
+       "\x02/\x03\x04\x00\x00\x021" + // 0x022F0304: 0x00000231
+       "\x00Y\x03\x04\x00\x00\x022" + // 0x00590304: 0x00000232
+       "\x00y\x03\x04\x00\x00\x023" + // 0x00790304: 0x00000233
+       "\x00\xa8\x03\x01\x00\x00\x03\x85" + // 0x00A80301: 0x00000385
+       "\x03\x91\x03\x01\x00\x00\x03\x86" + // 0x03910301: 0x00000386
+       "\x03\x95\x03\x01\x00\x00\x03\x88" + // 0x03950301: 0x00000388
+       "\x03\x97\x03\x01\x00\x00\x03\x89" + // 0x03970301: 0x00000389
+       "\x03\x99\x03\x01\x00\x00\x03\x8a" + // 0x03990301: 0x0000038A
+       "\x03\x9f\x03\x01\x00\x00\x03\x8c" + // 0x039F0301: 0x0000038C
+       "\x03\xa5\x03\x01\x00\x00\x03\x8e" + // 0x03A50301: 0x0000038E
+       "\x03\xa9\x03\x01\x00\x00\x03\x8f" + // 0x03A90301: 0x0000038F
+       "\x03\xca\x03\x01\x00\x00\x03\x90" + // 0x03CA0301: 0x00000390
+       "\x03\x99\x03\b\x00\x00\x03\xaa" + // 0x03990308: 0x000003AA
+       "\x03\xa5\x03\b\x00\x00\x03\xab" + // 0x03A50308: 0x000003AB
+       "\x03\xb1\x03\x01\x00\x00\x03\xac" + // 0x03B10301: 0x000003AC
+       "\x03\xb5\x03\x01\x00\x00\x03\xad" + // 0x03B50301: 0x000003AD
+       "\x03\xb7\x03\x01\x00\x00\x03\xae" + // 0x03B70301: 0x000003AE
+       "\x03\xb9\x03\x01\x00\x00\x03\xaf" + // 0x03B90301: 0x000003AF
+       "\x03\xcb\x03\x01\x00\x00\x03\xb0" + // 0x03CB0301: 0x000003B0
+       "\x03\xb9\x03\b\x00\x00\x03\xca" + // 0x03B90308: 0x000003CA
+       "\x03\xc5\x03\b\x00\x00\x03\xcb" + // 0x03C50308: 0x000003CB
+       "\x03\xbf\x03\x01\x00\x00\x03\xcc" + // 0x03BF0301: 0x000003CC
+       "\x03\xc5\x03\x01\x00\x00\x03\xcd" + // 0x03C50301: 0x000003CD
+       "\x03\xc9\x03\x01\x00\x00\x03\xce" + // 0x03C90301: 0x000003CE
+       "\x03\xd2\x03\x01\x00\x00\x03\xd3" + // 0x03D20301: 0x000003D3
+       "\x03\xd2\x03\b\x00\x00\x03\xd4" + // 0x03D20308: 0x000003D4
+       "\x04\x15\x03\x00\x00\x00\x04\x00" + // 0x04150300: 0x00000400
+       "\x04\x15\x03\b\x00\x00\x04\x01" + // 0x04150308: 0x00000401
+       "\x04\x13\x03\x01\x00\x00\x04\x03" + // 0x04130301: 0x00000403
+       "\x04\x06\x03\b\x00\x00\x04\a" + // 0x04060308: 0x00000407
+       "\x04\x1a\x03\x01\x00\x00\x04\f" + // 0x041A0301: 0x0000040C
+       "\x04\x18\x03\x00\x00\x00\x04\r" + // 0x04180300: 0x0000040D
+       "\x04#\x03\x06\x00\x00\x04\x0e" + // 0x04230306: 0x0000040E
+       "\x04\x18\x03\x06\x00\x00\x04\x19" + // 0x04180306: 0x00000419
+       "\x048\x03\x06\x00\x00\x049" + // 0x04380306: 0x00000439
+       "\x045\x03\x00\x00\x00\x04P" + // 0x04350300: 0x00000450
+       "\x045\x03\b\x00\x00\x04Q" + // 0x04350308: 0x00000451
+       "\x043\x03\x01\x00\x00\x04S" + // 0x04330301: 0x00000453
+       "\x04V\x03\b\x00\x00\x04W" + // 0x04560308: 0x00000457
+       "\x04:\x03\x01\x00\x00\x04\\" + // 0x043A0301: 0x0000045C
+       "\x048\x03\x00\x00\x00\x04]" + // 0x04380300: 0x0000045D
+       "\x04C\x03\x06\x00\x00\x04^" + // 0x04430306: 0x0000045E
+       "\x04t\x03\x0f\x00\x00\x04v" + // 0x0474030F: 0x00000476
+       "\x04u\x03\x0f\x00\x00\x04w" + // 0x0475030F: 0x00000477
+       "\x04\x16\x03\x06\x00\x00\x04\xc1" + // 0x04160306: 0x000004C1
+       "\x046\x03\x06\x00\x00\x04\xc2" + // 0x04360306: 0x000004C2
+       "\x04\x10\x03\x06\x00\x00\x04\xd0" + // 0x04100306: 0x000004D0
+       "\x040\x03\x06\x00\x00\x04\xd1" + // 0x04300306: 0x000004D1
+       "\x04\x10\x03\b\x00\x00\x04\xd2" + // 0x04100308: 0x000004D2
+       "\x040\x03\b\x00\x00\x04\xd3" + // 0x04300308: 0x000004D3
+       "\x04\x15\x03\x06\x00\x00\x04\xd6" + // 0x04150306: 0x000004D6
+       "\x045\x03\x06\x00\x00\x04\xd7" + // 0x04350306: 0x000004D7
+       "\x04\xd8\x03\b\x00\x00\x04\xda" + // 0x04D80308: 0x000004DA
+       "\x04\xd9\x03\b\x00\x00\x04\xdb" + // 0x04D90308: 0x000004DB
+       "\x04\x16\x03\b\x00\x00\x04\xdc" + // 0x04160308: 0x000004DC
+       "\x046\x03\b\x00\x00\x04\xdd" + // 0x04360308: 0x000004DD
+       "\x04\x17\x03\b\x00\x00\x04\xde" + // 0x04170308: 0x000004DE
+       "\x047\x03\b\x00\x00\x04\xdf" + // 0x04370308: 0x000004DF
+       "\x04\x18\x03\x04\x00\x00\x04\xe2" + // 0x04180304: 0x000004E2
+       "\x048\x03\x04\x00\x00\x04\xe3" + // 0x04380304: 0x000004E3
+       "\x04\x18\x03\b\x00\x00\x04\xe4" + // 0x04180308: 0x000004E4
+       "\x048\x03\b\x00\x00\x04\xe5" + // 0x04380308: 0x000004E5
+       "\x04\x1e\x03\b\x00\x00\x04\xe6" + // 0x041E0308: 0x000004E6
+       "\x04>\x03\b\x00\x00\x04\xe7" + // 0x043E0308: 0x000004E7
+       "\x04\xe8\x03\b\x00\x00\x04\xea" + // 0x04E80308: 0x000004EA
+       "\x04\xe9\x03\b\x00\x00\x04\xeb" + // 0x04E90308: 0x000004EB
+       "\x04-\x03\b\x00\x00\x04\xec" + // 0x042D0308: 0x000004EC
+       "\x04M\x03\b\x00\x00\x04\xed" + // 0x044D0308: 0x000004ED
+       "\x04#\x03\x04\x00\x00\x04\xee" + // 0x04230304: 0x000004EE
+       "\x04C\x03\x04\x00\x00\x04\xef" + // 0x04430304: 0x000004EF
+       "\x04#\x03\b\x00\x00\x04\xf0" + // 0x04230308: 0x000004F0
+       "\x04C\x03\b\x00\x00\x04\xf1" + // 0x04430308: 0x000004F1
+       "\x04#\x03\v\x00\x00\x04\xf2" + // 0x0423030B: 0x000004F2
+       "\x04C\x03\v\x00\x00\x04\xf3" + // 0x0443030B: 0x000004F3
+       "\x04'\x03\b\x00\x00\x04\xf4" + // 0x04270308: 0x000004F4
+       "\x04G\x03\b\x00\x00\x04\xf5" + // 0x04470308: 0x000004F5
+       "\x04+\x03\b\x00\x00\x04\xf8" + // 0x042B0308: 0x000004F8
+       "\x04K\x03\b\x00\x00\x04\xf9" + // 0x044B0308: 0x000004F9
+       "\x06'\x06S\x00\x00\x06\"" + // 0x06270653: 0x00000622
+       "\x06'\x06T\x00\x00\x06#" + // 0x06270654: 0x00000623
+       "\x06H\x06T\x00\x00\x06$" + // 0x06480654: 0x00000624
+       "\x06'\x06U\x00\x00\x06%" + // 0x06270655: 0x00000625
+       "\x06J\x06T\x00\x00\x06&" + // 0x064A0654: 0x00000626
+       "\x06\xd5\x06T\x00\x00\x06\xc0" + // 0x06D50654: 0x000006C0
+       "\x06\xc1\x06T\x00\x00\x06\xc2" + // 0x06C10654: 0x000006C2
+       "\x06\xd2\x06T\x00\x00\x06\xd3" + // 0x06D20654: 0x000006D3
+       "\t(\t<\x00\x00\t)" + // 0x0928093C: 0x00000929
+       "\t0\t<\x00\x00\t1" + // 0x0930093C: 0x00000931
+       "\t3\t<\x00\x00\t4" + // 0x0933093C: 0x00000934
+       "\t\xc7\t\xbe\x00\x00\t\xcb" + // 0x09C709BE: 0x000009CB
+       "\t\xc7\t\xd7\x00\x00\t\xcc" + // 0x09C709D7: 0x000009CC
+       "\vG\vV\x00\x00\vH" + // 0x0B470B56: 0x00000B48
+       "\vG\v>\x00\x00\vK" + // 0x0B470B3E: 0x00000B4B
+       "\vG\vW\x00\x00\vL" + // 0x0B470B57: 0x00000B4C
+       "\v\x92\v\xd7\x00\x00\v\x94" + // 0x0B920BD7: 0x00000B94
+       "\v\xc6\v\xbe\x00\x00\v\xca" + // 0x0BC60BBE: 0x00000BCA
+       "\v\xc7\v\xbe\x00\x00\v\xcb" + // 0x0BC70BBE: 0x00000BCB
+       "\v\xc6\v\xd7\x00\x00\v\xcc" + // 0x0BC60BD7: 0x00000BCC
+       "\fF\fV\x00\x00\fH" + // 0x0C460C56: 0x00000C48
+       "\f\xbf\f\xd5\x00\x00\f\xc0" + // 0x0CBF0CD5: 0x00000CC0
+       "\f\xc6\f\xd5\x00\x00\f\xc7" + // 0x0CC60CD5: 0x00000CC7
+       "\f\xc6\f\xd6\x00\x00\f\xc8" + // 0x0CC60CD6: 0x00000CC8
+       "\f\xc6\f\xc2\x00\x00\f\xca" + // 0x0CC60CC2: 0x00000CCA
+       "\f\xca\f\xd5\x00\x00\f\xcb" + // 0x0CCA0CD5: 0x00000CCB
+       "\rF\r>\x00\x00\rJ" + // 0x0D460D3E: 0x00000D4A
+       "\rG\r>\x00\x00\rK" + // 0x0D470D3E: 0x00000D4B
+       "\rF\rW\x00\x00\rL" + // 0x0D460D57: 0x00000D4C
+       "\r\xd9\r\xca\x00\x00\r\xda" + // 0x0DD90DCA: 0x00000DDA
+       "\r\xd9\r\xcf\x00\x00\r\xdc" + // 0x0DD90DCF: 0x00000DDC
+       "\r\xdc\r\xca\x00\x00\r\xdd" + // 0x0DDC0DCA: 0x00000DDD
+       "\r\xd9\r\xdf\x00\x00\r\xde" + // 0x0DD90DDF: 0x00000DDE
+       "\x10%\x10.\x00\x00\x10&" + // 0x1025102E: 0x00001026
+       "\x1b\x05\x1b5\x00\x00\x1b\x06" + // 0x1B051B35: 0x00001B06
+       "\x1b\a\x1b5\x00\x00\x1b\b" + // 0x1B071B35: 0x00001B08
+       "\x1b\t\x1b5\x00\x00\x1b\n" + // 0x1B091B35: 0x00001B0A
+       "\x1b\v\x1b5\x00\x00\x1b\f" + // 0x1B0B1B35: 0x00001B0C
+       "\x1b\r\x1b5\x00\x00\x1b\x0e" + // 0x1B0D1B35: 0x00001B0E
+       "\x1b\x11\x1b5\x00\x00\x1b\x12" + // 0x1B111B35: 0x00001B12
+       "\x1b:\x1b5\x00\x00\x1b;" + // 0x1B3A1B35: 0x00001B3B
+       "\x1b<\x1b5\x00\x00\x1b=" + // 0x1B3C1B35: 0x00001B3D
+       "\x1b>\x1b5\x00\x00\x1b@" + // 0x1B3E1B35: 0x00001B40
+       "\x1b?\x1b5\x00\x00\x1bA" + // 0x1B3F1B35: 0x00001B41
+       "\x1bB\x1b5\x00\x00\x1bC" + // 0x1B421B35: 0x00001B43
+       "\x00A\x03%\x00\x00\x1e\x00" + // 0x00410325: 0x00001E00
+       "\x00a\x03%\x00\x00\x1e\x01" + // 0x00610325: 0x00001E01
+       "\x00B\x03\a\x00\x00\x1e\x02" + // 0x00420307: 0x00001E02
+       "\x00b\x03\a\x00\x00\x1e\x03" + // 0x00620307: 0x00001E03
+       "\x00B\x03#\x00\x00\x1e\x04" + // 0x00420323: 0x00001E04
+       "\x00b\x03#\x00\x00\x1e\x05" + // 0x00620323: 0x00001E05
+       "\x00B\x031\x00\x00\x1e\x06" + // 0x00420331: 0x00001E06
+       "\x00b\x031\x00\x00\x1e\a" + // 0x00620331: 0x00001E07
+       "\x00\xc7\x03\x01\x00\x00\x1e\b" + // 0x00C70301: 0x00001E08
+       "\x00\xe7\x03\x01\x00\x00\x1e\t" + // 0x00E70301: 0x00001E09
+       "\x00D\x03\a\x00\x00\x1e\n" + // 0x00440307: 0x00001E0A
+       "\x00d\x03\a\x00\x00\x1e\v" + // 0x00640307: 0x00001E0B
+       "\x00D\x03#\x00\x00\x1e\f" + // 0x00440323: 0x00001E0C
+       "\x00d\x03#\x00\x00\x1e\r" + // 0x00640323: 0x00001E0D
+       "\x00D\x031\x00\x00\x1e\x0e" + // 0x00440331: 0x00001E0E
+       "\x00d\x031\x00\x00\x1e\x0f" + // 0x00640331: 0x00001E0F
+       "\x00D\x03'\x00\x00\x1e\x10" + // 0x00440327: 0x00001E10
+       "\x00d\x03'\x00\x00\x1e\x11" + // 0x00640327: 0x00001E11
+       "\x00D\x03-\x00\x00\x1e\x12" + // 0x0044032D: 0x00001E12
+       "\x00d\x03-\x00\x00\x1e\x13" + // 0x0064032D: 0x00001E13
+       "\x01\x12\x03\x00\x00\x00\x1e\x14" + // 0x01120300: 0x00001E14
+       "\x01\x13\x03\x00\x00\x00\x1e\x15" + // 0x01130300: 0x00001E15
+       "\x01\x12\x03\x01\x00\x00\x1e\x16" + // 0x01120301: 0x00001E16
+       "\x01\x13\x03\x01\x00\x00\x1e\x17" + // 0x01130301: 0x00001E17
+       "\x00E\x03-\x00\x00\x1e\x18" + // 0x0045032D: 0x00001E18
+       "\x00e\x03-\x00\x00\x1e\x19" + // 0x0065032D: 0x00001E19
+       "\x00E\x030\x00\x00\x1e\x1a" + // 0x00450330: 0x00001E1A
+       "\x00e\x030\x00\x00\x1e\x1b" + // 0x00650330: 0x00001E1B
+       "\x02(\x03\x06\x00\x00\x1e\x1c" + // 0x02280306: 0x00001E1C
+       "\x02)\x03\x06\x00\x00\x1e\x1d" + // 0x02290306: 0x00001E1D
+       "\x00F\x03\a\x00\x00\x1e\x1e" + // 0x00460307: 0x00001E1E
+       "\x00f\x03\a\x00\x00\x1e\x1f" + // 0x00660307: 0x00001E1F
+       "\x00G\x03\x04\x00\x00\x1e " + // 0x00470304: 0x00001E20
+       "\x00g\x03\x04\x00\x00\x1e!" + // 0x00670304: 0x00001E21
+       "\x00H\x03\a\x00\x00\x1e\"" + // 0x00480307: 0x00001E22
+       "\x00h\x03\a\x00\x00\x1e#" + // 0x00680307: 0x00001E23
+       "\x00H\x03#\x00\x00\x1e$" + // 0x00480323: 0x00001E24
+       "\x00h\x03#\x00\x00\x1e%" + // 0x00680323: 0x00001E25
+       "\x00H\x03\b\x00\x00\x1e&" + // 0x00480308: 0x00001E26
+       "\x00h\x03\b\x00\x00\x1e'" + // 0x00680308: 0x00001E27
+       "\x00H\x03'\x00\x00\x1e(" + // 0x00480327: 0x00001E28
+       "\x00h\x03'\x00\x00\x1e)" + // 0x00680327: 0x00001E29
+       "\x00H\x03.\x00\x00\x1e*" + // 0x0048032E: 0x00001E2A
+       "\x00h\x03.\x00\x00\x1e+" + // 0x0068032E: 0x00001E2B
+       "\x00I\x030\x00\x00\x1e," + // 0x00490330: 0x00001E2C
+       "\x00i\x030\x00\x00\x1e-" + // 0x00690330: 0x00001E2D
+       "\x00\xcf\x03\x01\x00\x00\x1e." + // 0x00CF0301: 0x00001E2E
+       "\x00\xef\x03\x01\x00\x00\x1e/" + // 0x00EF0301: 0x00001E2F
+       "\x00K\x03\x01\x00\x00\x1e0" + // 0x004B0301: 0x00001E30
+       "\x00k\x03\x01\x00\x00\x1e1" + // 0x006B0301: 0x00001E31
+       "\x00K\x03#\x00\x00\x1e2" + // 0x004B0323: 0x00001E32
+       "\x00k\x03#\x00\x00\x1e3" + // 0x006B0323: 0x00001E33
+       "\x00K\x031\x00\x00\x1e4" + // 0x004B0331: 0x00001E34
+       "\x00k\x031\x00\x00\x1e5" + // 0x006B0331: 0x00001E35
+       "\x00L\x03#\x00\x00\x1e6" + // 0x004C0323: 0x00001E36
+       "\x00l\x03#\x00\x00\x1e7" + // 0x006C0323: 0x00001E37
+       "\x1e6\x03\x04\x00\x00\x1e8" + // 0x1E360304: 0x00001E38
+       "\x1e7\x03\x04\x00\x00\x1e9" + // 0x1E370304: 0x00001E39
+       "\x00L\x031\x00\x00\x1e:" + // 0x004C0331: 0x00001E3A
+       "\x00l\x031\x00\x00\x1e;" + // 0x006C0331: 0x00001E3B
+       "\x00L\x03-\x00\x00\x1e<" + // 0x004C032D: 0x00001E3C
+       "\x00l\x03-\x00\x00\x1e=" + // 0x006C032D: 0x00001E3D
+       "\x00M\x03\x01\x00\x00\x1e>" + // 0x004D0301: 0x00001E3E
+       "\x00m\x03\x01\x00\x00\x1e?" + // 0x006D0301: 0x00001E3F
+       "\x00M\x03\a\x00\x00\x1e@" + // 0x004D0307: 0x00001E40
+       "\x00m\x03\a\x00\x00\x1eA" + // 0x006D0307: 0x00001E41
+       "\x00M\x03#\x00\x00\x1eB" + // 0x004D0323: 0x00001E42
+       "\x00m\x03#\x00\x00\x1eC" + // 0x006D0323: 0x00001E43
+       "\x00N\x03\a\x00\x00\x1eD" + // 0x004E0307: 0x00001E44
+       "\x00n\x03\a\x00\x00\x1eE" + // 0x006E0307: 0x00001E45
+       "\x00N\x03#\x00\x00\x1eF" + // 0x004E0323: 0x00001E46
+       "\x00n\x03#\x00\x00\x1eG" + // 0x006E0323: 0x00001E47
+       "\x00N\x031\x00\x00\x1eH" + // 0x004E0331: 0x00001E48
+       "\x00n\x031\x00\x00\x1eI" + // 0x006E0331: 0x00001E49
+       "\x00N\x03-\x00\x00\x1eJ" + // 0x004E032D: 0x00001E4A
+       "\x00n\x03-\x00\x00\x1eK" + // 0x006E032D: 0x00001E4B
+       "\x00\xd5\x03\x01\x00\x00\x1eL" + // 0x00D50301: 0x00001E4C
+       "\x00\xf5\x03\x01\x00\x00\x1eM" + // 0x00F50301: 0x00001E4D
+       "\x00\xd5\x03\b\x00\x00\x1eN" + // 0x00D50308: 0x00001E4E
+       "\x00\xf5\x03\b\x00\x00\x1eO" + // 0x00F50308: 0x00001E4F
+       "\x01L\x03\x00\x00\x00\x1eP" + // 0x014C0300: 0x00001E50
+       "\x01M\x03\x00\x00\x00\x1eQ" + // 0x014D0300: 0x00001E51
+       "\x01L\x03\x01\x00\x00\x1eR" + // 0x014C0301: 0x00001E52
+       "\x01M\x03\x01\x00\x00\x1eS" + // 0x014D0301: 0x00001E53
+       "\x00P\x03\x01\x00\x00\x1eT" + // 0x00500301: 0x00001E54
+       "\x00p\x03\x01\x00\x00\x1eU" + // 0x00700301: 0x00001E55
+       "\x00P\x03\a\x00\x00\x1eV" + // 0x00500307: 0x00001E56
+       "\x00p\x03\a\x00\x00\x1eW" + // 0x00700307: 0x00001E57
+       "\x00R\x03\a\x00\x00\x1eX" + // 0x00520307: 0x00001E58
+       "\x00r\x03\a\x00\x00\x1eY" + // 0x00720307: 0x00001E59
+       "\x00R\x03#\x00\x00\x1eZ" + // 0x00520323: 0x00001E5A
+       "\x00r\x03#\x00\x00\x1e[" + // 0x00720323: 0x00001E5B
+       "\x1eZ\x03\x04\x00\x00\x1e\\" + // 0x1E5A0304: 0x00001E5C
+       "\x1e[\x03\x04\x00\x00\x1e]" + // 0x1E5B0304: 0x00001E5D
+       "\x00R\x031\x00\x00\x1e^" + // 0x00520331: 0x00001E5E
+       "\x00r\x031\x00\x00\x1e_" + // 0x00720331: 0x00001E5F
+       "\x00S\x03\a\x00\x00\x1e`" + // 0x00530307: 0x00001E60
+       "\x00s\x03\a\x00\x00\x1ea" + // 0x00730307: 0x00001E61
+       "\x00S\x03#\x00\x00\x1eb" + // 0x00530323: 0x00001E62
+       "\x00s\x03#\x00\x00\x1ec" + // 0x00730323: 0x00001E63
+       "\x01Z\x03\a\x00\x00\x1ed" + // 0x015A0307: 0x00001E64
+       "\x01[\x03\a\x00\x00\x1ee" + // 0x015B0307: 0x00001E65
+       "\x01`\x03\a\x00\x00\x1ef" + // 0x01600307: 0x00001E66
+       "\x01a\x03\a\x00\x00\x1eg" + // 0x01610307: 0x00001E67
+       "\x1eb\x03\a\x00\x00\x1eh" + // 0x1E620307: 0x00001E68
+       "\x1ec\x03\a\x00\x00\x1ei" + // 0x1E630307: 0x00001E69
+       "\x00T\x03\a\x00\x00\x1ej" + // 0x00540307: 0x00001E6A
+       "\x00t\x03\a\x00\x00\x1ek" + // 0x00740307: 0x00001E6B
+       "\x00T\x03#\x00\x00\x1el" + // 0x00540323: 0x00001E6C
+       "\x00t\x03#\x00\x00\x1em" + // 0x00740323: 0x00001E6D
+       "\x00T\x031\x00\x00\x1en" + // 0x00540331: 0x00001E6E
+       "\x00t\x031\x00\x00\x1eo" + // 0x00740331: 0x00001E6F
+       "\x00T\x03-\x00\x00\x1ep" + // 0x0054032D: 0x00001E70
+       "\x00t\x03-\x00\x00\x1eq" + // 0x0074032D: 0x00001E71
+       "\x00U\x03$\x00\x00\x1er" + // 0x00550324: 0x00001E72
+       "\x00u\x03$\x00\x00\x1es" + // 0x00750324: 0x00001E73
+       "\x00U\x030\x00\x00\x1et" + // 0x00550330: 0x00001E74
+       "\x00u\x030\x00\x00\x1eu" + // 0x00750330: 0x00001E75
+       "\x00U\x03-\x00\x00\x1ev" + // 0x0055032D: 0x00001E76
+       "\x00u\x03-\x00\x00\x1ew" + // 0x0075032D: 0x00001E77
+       "\x01h\x03\x01\x00\x00\x1ex" + // 0x01680301: 0x00001E78
+       "\x01i\x03\x01\x00\x00\x1ey" + // 0x01690301: 0x00001E79
+       "\x01j\x03\b\x00\x00\x1ez" + // 0x016A0308: 0x00001E7A
+       "\x01k\x03\b\x00\x00\x1e{" + // 0x016B0308: 0x00001E7B
+       "\x00V\x03\x03\x00\x00\x1e|" + // 0x00560303: 0x00001E7C
+       "\x00v\x03\x03\x00\x00\x1e}" + // 0x00760303: 0x00001E7D
+       "\x00V\x03#\x00\x00\x1e~" + // 0x00560323: 0x00001E7E
+       "\x00v\x03#\x00\x00\x1e\u007f" + // 0x00760323: 0x00001E7F
+       "\x00W\x03\x00\x00\x00\x1e\x80" + // 0x00570300: 0x00001E80
+       "\x00w\x03\x00\x00\x00\x1e\x81" + // 0x00770300: 0x00001E81
+       "\x00W\x03\x01\x00\x00\x1e\x82" + // 0x00570301: 0x00001E82
+       "\x00w\x03\x01\x00\x00\x1e\x83" + // 0x00770301: 0x00001E83
+       "\x00W\x03\b\x00\x00\x1e\x84" + // 0x00570308: 0x00001E84
+       "\x00w\x03\b\x00\x00\x1e\x85" + // 0x00770308: 0x00001E85
+       "\x00W\x03\a\x00\x00\x1e\x86" + // 0x00570307: 0x00001E86
+       "\x00w\x03\a\x00\x00\x1e\x87" + // 0x00770307: 0x00001E87
+       "\x00W\x03#\x00\x00\x1e\x88" + // 0x00570323: 0x00001E88
+       "\x00w\x03#\x00\x00\x1e\x89" + // 0x00770323: 0x00001E89
+       "\x00X\x03\a\x00\x00\x1e\x8a" + // 0x00580307: 0x00001E8A
+       "\x00x\x03\a\x00\x00\x1e\x8b" + // 0x00780307: 0x00001E8B
+       "\x00X\x03\b\x00\x00\x1e\x8c" + // 0x00580308: 0x00001E8C
+       "\x00x\x03\b\x00\x00\x1e\x8d" + // 0x00780308: 0x00001E8D
+       "\x00Y\x03\a\x00\x00\x1e\x8e" + // 0x00590307: 0x00001E8E
+       "\x00y\x03\a\x00\x00\x1e\x8f" + // 0x00790307: 0x00001E8F
+       "\x00Z\x03\x02\x00\x00\x1e\x90" + // 0x005A0302: 0x00001E90
+       "\x00z\x03\x02\x00\x00\x1e\x91" + // 0x007A0302: 0x00001E91
+       "\x00Z\x03#\x00\x00\x1e\x92" + // 0x005A0323: 0x00001E92
+       "\x00z\x03#\x00\x00\x1e\x93" + // 0x007A0323: 0x00001E93
+       "\x00Z\x031\x00\x00\x1e\x94" + // 0x005A0331: 0x00001E94
+       "\x00z\x031\x00\x00\x1e\x95" + // 0x007A0331: 0x00001E95
+       "\x00h\x031\x00\x00\x1e\x96" + // 0x00680331: 0x00001E96
+       "\x00t\x03\b\x00\x00\x1e\x97" + // 0x00740308: 0x00001E97
+       "\x00w\x03\n\x00\x00\x1e\x98" + // 0x0077030A: 0x00001E98
+       "\x00y\x03\n\x00\x00\x1e\x99" + // 0x0079030A: 0x00001E99
+       "\x01\u007f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B
+       "\x00A\x03#\x00\x00\x1e\xa0" + // 0x00410323: 0x00001EA0
+       "\x00a\x03#\x00\x00\x1e\xa1" + // 0x00610323: 0x00001EA1
+       "\x00A\x03\t\x00\x00\x1e\xa2" + // 0x00410309: 0x00001EA2
+       "\x00a\x03\t\x00\x00\x1e\xa3" + // 0x00610309: 0x00001EA3
+       "\x00\xc2\x03\x01\x00\x00\x1e\xa4" + // 0x00C20301: 0x00001EA4
+       "\x00\xe2\x03\x01\x00\x00\x1e\xa5" + // 0x00E20301: 0x00001EA5
+       "\x00\xc2\x03\x00\x00\x00\x1e\xa6" + // 0x00C20300: 0x00001EA6
+       "\x00\xe2\x03\x00\x00\x00\x1e\xa7" + // 0x00E20300: 0x00001EA7
+       "\x00\xc2\x03\t\x00\x00\x1e\xa8" + // 0x00C20309: 0x00001EA8
+       "\x00\xe2\x03\t\x00\x00\x1e\xa9" + // 0x00E20309: 0x00001EA9
+       "\x00\xc2\x03\x03\x00\x00\x1e\xaa" + // 0x00C20303: 0x00001EAA
+       "\x00\xe2\x03\x03\x00\x00\x1e\xab" + // 0x00E20303: 0x00001EAB
+       "\x1e\xa0\x03\x02\x00\x00\x1e\xac" + // 0x1EA00302: 0x00001EAC
+       "\x1e\xa1\x03\x02\x00\x00\x1e\xad" + // 0x1EA10302: 0x00001EAD
+       "\x01\x02\x03\x01\x00\x00\x1e\xae" + // 0x01020301: 0x00001EAE
+       "\x01\x03\x03\x01\x00\x00\x1e\xaf" + // 0x01030301: 0x00001EAF
+       "\x01\x02\x03\x00\x00\x00\x1e\xb0" + // 0x01020300: 0x00001EB0
+       "\x01\x03\x03\x00\x00\x00\x1e\xb1" + // 0x01030300: 0x00001EB1
+       "\x01\x02\x03\t\x00\x00\x1e\xb2" + // 0x01020309: 0x00001EB2
+       "\x01\x03\x03\t\x00\x00\x1e\xb3" + // 0x01030309: 0x00001EB3
+       "\x01\x02\x03\x03\x00\x00\x1e\xb4" + // 0x01020303: 0x00001EB4
+       "\x01\x03\x03\x03\x00\x00\x1e\xb5" + // 0x01030303: 0x00001EB5
+       "\x1e\xa0\x03\x06\x00\x00\x1e\xb6" + // 0x1EA00306: 0x00001EB6
+       "\x1e\xa1\x03\x06\x00\x00\x1e\xb7" + // 0x1EA10306: 0x00001EB7
+       "\x00E\x03#\x00\x00\x1e\xb8" + // 0x00450323: 0x00001EB8
+       "\x00e\x03#\x00\x00\x1e\xb9" + // 0x00650323: 0x00001EB9
+       "\x00E\x03\t\x00\x00\x1e\xba" + // 0x00450309: 0x00001EBA
+       "\x00e\x03\t\x00\x00\x1e\xbb" + // 0x00650309: 0x00001EBB
+       "\x00E\x03\x03\x00\x00\x1e\xbc" + // 0x00450303: 0x00001EBC
+       "\x00e\x03\x03\x00\x00\x1e\xbd" + // 0x00650303: 0x00001EBD
+       "\x00\xca\x03\x01\x00\x00\x1e\xbe" + // 0x00CA0301: 0x00001EBE
+       "\x00\xea\x03\x01\x00\x00\x1e\xbf" + // 0x00EA0301: 0x00001EBF
+       "\x00\xca\x03\x00\x00\x00\x1e\xc0" + // 0x00CA0300: 0x00001EC0
+       "\x00\xea\x03\x00\x00\x00\x1e\xc1" + // 0x00EA0300: 0x00001EC1
+       "\x00\xca\x03\t\x00\x00\x1e\xc2" + // 0x00CA0309: 0x00001EC2
+       "\x00\xea\x03\t\x00\x00\x1e\xc3" + // 0x00EA0309: 0x00001EC3
+       "\x00\xca\x03\x03\x00\x00\x1e\xc4" + // 0x00CA0303: 0x00001EC4
+       "\x00\xea\x03\x03\x00\x00\x1e\xc5" + // 0x00EA0303: 0x00001EC5
+       "\x1e\xb8\x03\x02\x00\x00\x1e\xc6" + // 0x1EB80302: 0x00001EC6
+       "\x1e\xb9\x03\x02\x00\x00\x1e\xc7" + // 0x1EB90302: 0x00001EC7
+       "\x00I\x03\t\x00\x00\x1e\xc8" + // 0x00490309: 0x00001EC8
+       "\x00i\x03\t\x00\x00\x1e\xc9" + // 0x00690309: 0x00001EC9
+       "\x00I\x03#\x00\x00\x1e\xca" + // 0x00490323: 0x00001ECA
+       "\x00i\x03#\x00\x00\x1e\xcb" + // 0x00690323: 0x00001ECB
+       "\x00O\x03#\x00\x00\x1e\xcc" + // 0x004F0323: 0x00001ECC
+       "\x00o\x03#\x00\x00\x1e\xcd" + // 0x006F0323: 0x00001ECD
+       "\x00O\x03\t\x00\x00\x1e\xce" + // 0x004F0309: 0x00001ECE
+       "\x00o\x03\t\x00\x00\x1e\xcf" + // 0x006F0309: 0x00001ECF
+       "\x00\xd4\x03\x01\x00\x00\x1e\xd0" + // 0x00D40301: 0x00001ED0
+       "\x00\xf4\x03\x01\x00\x00\x1e\xd1" + // 0x00F40301: 0x00001ED1
+       "\x00\xd4\x03\x00\x00\x00\x1e\xd2" + // 0x00D40300: 0x00001ED2
+       "\x00\xf4\x03\x00\x00\x00\x1e\xd3" + // 0x00F40300: 0x00001ED3
+       "\x00\xd4\x03\t\x00\x00\x1e\xd4" + // 0x00D40309: 0x00001ED4
+       "\x00\xf4\x03\t\x00\x00\x1e\xd5" + // 0x00F40309: 0x00001ED5
+       "\x00\xd4\x03\x03\x00\x00\x1e\xd6" + // 0x00D40303: 0x00001ED6
+       "\x00\xf4\x03\x03\x00\x00\x1e\xd7" + // 0x00F40303: 0x00001ED7
+       "\x1e\xcc\x03\x02\x00\x00\x1e\xd8" + // 0x1ECC0302: 0x00001ED8
+       "\x1e\xcd\x03\x02\x00\x00\x1e\xd9" + // 0x1ECD0302: 0x00001ED9
+       "\x01\xa0\x03\x01\x00\x00\x1e\xda" + // 0x01A00301: 0x00001EDA
+       "\x01\xa1\x03\x01\x00\x00\x1e\xdb" + // 0x01A10301: 0x00001EDB
+       "\x01\xa0\x03\x00\x00\x00\x1e\xdc" + // 0x01A00300: 0x00001EDC
+       "\x01\xa1\x03\x00\x00\x00\x1e\xdd" + // 0x01A10300: 0x00001EDD
+       "\x01\xa0\x03\t\x00\x00\x1e\xde" + // 0x01A00309: 0x00001EDE
+       "\x01\xa1\x03\t\x00\x00\x1e\xdf" + // 0x01A10309: 0x00001EDF
+       "\x01\xa0\x03\x03\x00\x00\x1e\xe0" + // 0x01A00303: 0x00001EE0
+       "\x01\xa1\x03\x03\x00\x00\x1e\xe1" + // 0x01A10303: 0x00001EE1
+       "\x01\xa0\x03#\x00\x00\x1e\xe2" + // 0x01A00323: 0x00001EE2
+       "\x01\xa1\x03#\x00\x00\x1e\xe3" + // 0x01A10323: 0x00001EE3
+       "\x00U\x03#\x00\x00\x1e\xe4" + // 0x00550323: 0x00001EE4
+       "\x00u\x03#\x00\x00\x1e\xe5" + // 0x00750323: 0x00001EE5
+       "\x00U\x03\t\x00\x00\x1e\xe6" + // 0x00550309: 0x00001EE6
+       "\x00u\x03\t\x00\x00\x1e\xe7" + // 0x00750309: 0x00001EE7
+       "\x01\xaf\x03\x01\x00\x00\x1e\xe8" + // 0x01AF0301: 0x00001EE8
+       "\x01\xb0\x03\x01\x00\x00\x1e\xe9" + // 0x01B00301: 0x00001EE9
+       "\x01\xaf\x03\x00\x00\x00\x1e\xea" + // 0x01AF0300: 0x00001EEA
+       "\x01\xb0\x03\x00\x00\x00\x1e\xeb" + // 0x01B00300: 0x00001EEB
+       "\x01\xaf\x03\t\x00\x00\x1e\xec" + // 0x01AF0309: 0x00001EEC
+       "\x01\xb0\x03\t\x00\x00\x1e\xed" + // 0x01B00309: 0x00001EED
+       "\x01\xaf\x03\x03\x00\x00\x1e\xee" + // 0x01AF0303: 0x00001EEE
+       "\x01\xb0\x03\x03\x00\x00\x1e\xef" + // 0x01B00303: 0x00001EEF
+       "\x01\xaf\x03#\x00\x00\x1e\xf0" + // 0x01AF0323: 0x00001EF0
+       "\x01\xb0\x03#\x00\x00\x1e\xf1" + // 0x01B00323: 0x00001EF1
+       "\x00Y\x03\x00\x00\x00\x1e\xf2" + // 0x00590300: 0x00001EF2
+       "\x00y\x03\x00\x00\x00\x1e\xf3" + // 0x00790300: 0x00001EF3
+       "\x00Y\x03#\x00\x00\x1e\xf4" + // 0x00590323: 0x00001EF4
+       "\x00y\x03#\x00\x00\x1e\xf5" + // 0x00790323: 0x00001EF5
+       "\x00Y\x03\t\x00\x00\x1e\xf6" + // 0x00590309: 0x00001EF6
+       "\x00y\x03\t\x00\x00\x1e\xf7" + // 0x00790309: 0x00001EF7
+       "\x00Y\x03\x03\x00\x00\x1e\xf8" + // 0x00590303: 0x00001EF8
+       "\x00y\x03\x03\x00\x00\x1e\xf9" + // 0x00790303: 0x00001EF9
+       "\x03\xb1\x03\x13\x00\x00\x1f\x00" + // 0x03B10313: 0x00001F00
+       "\x03\xb1\x03\x14\x00\x00\x1f\x01" + // 0x03B10314: 0x00001F01
+       "\x1f\x00\x03\x00\x00\x00\x1f\x02" + // 0x1F000300: 0x00001F02
+       "\x1f\x01\x03\x00\x00\x00\x1f\x03" + // 0x1F010300: 0x00001F03
+       "\x1f\x00\x03\x01\x00\x00\x1f\x04" + // 0x1F000301: 0x00001F04
+       "\x1f\x01\x03\x01\x00\x00\x1f\x05" + // 0x1F010301: 0x00001F05
+       "\x1f\x00\x03B\x00\x00\x1f\x06" + // 0x1F000342: 0x00001F06
+       "\x1f\x01\x03B\x00\x00\x1f\a" + // 0x1F010342: 0x00001F07
+       "\x03\x91\x03\x13\x00\x00\x1f\b" + // 0x03910313: 0x00001F08
+       "\x03\x91\x03\x14\x00\x00\x1f\t" + // 0x03910314: 0x00001F09
+       "\x1f\b\x03\x00\x00\x00\x1f\n" + // 0x1F080300: 0x00001F0A
+       "\x1f\t\x03\x00\x00\x00\x1f\v" + // 0x1F090300: 0x00001F0B
+       "\x1f\b\x03\x01\x00\x00\x1f\f" + // 0x1F080301: 0x00001F0C
+       "\x1f\t\x03\x01\x00\x00\x1f\r" + // 0x1F090301: 0x00001F0D
+       "\x1f\b\x03B\x00\x00\x1f\x0e" + // 0x1F080342: 0x00001F0E
+       "\x1f\t\x03B\x00\x00\x1f\x0f" + // 0x1F090342: 0x00001F0F
+       "\x03\xb5\x03\x13\x00\x00\x1f\x10" + // 0x03B50313: 0x00001F10
+       "\x03\xb5\x03\x14\x00\x00\x1f\x11" + // 0x03B50314: 0x00001F11
+       "\x1f\x10\x03\x00\x00\x00\x1f\x12" + // 0x1F100300: 0x00001F12
+       "\x1f\x11\x03\x00\x00\x00\x1f\x13" + // 0x1F110300: 0x00001F13
+       "\x1f\x10\x03\x01\x00\x00\x1f\x14" + // 0x1F100301: 0x00001F14
+       "\x1f\x11\x03\x01\x00\x00\x1f\x15" + // 0x1F110301: 0x00001F15
+       "\x03\x95\x03\x13\x00\x00\x1f\x18" + // 0x03950313: 0x00001F18
+       "\x03\x95\x03\x14\x00\x00\x1f\x19" + // 0x03950314: 0x00001F19
+       "\x1f\x18\x03\x00\x00\x00\x1f\x1a" + // 0x1F180300: 0x00001F1A
+       "\x1f\x19\x03\x00\x00\x00\x1f\x1b" + // 0x1F190300: 0x00001F1B
+       "\x1f\x18\x03\x01\x00\x00\x1f\x1c" + // 0x1F180301: 0x00001F1C
+       "\x1f\x19\x03\x01\x00\x00\x1f\x1d" + // 0x1F190301: 0x00001F1D
+       "\x03\xb7\x03\x13\x00\x00\x1f " + // 0x03B70313: 0x00001F20
+       "\x03\xb7\x03\x14\x00\x00\x1f!" + // 0x03B70314: 0x00001F21
+       "\x1f \x03\x00\x00\x00\x1f\"" + // 0x1F200300: 0x00001F22
+       "\x1f!\x03\x00\x00\x00\x1f#" + // 0x1F210300: 0x00001F23
+       "\x1f \x03\x01\x00\x00\x1f$" + // 0x1F200301: 0x00001F24
+       "\x1f!\x03\x01\x00\x00\x1f%" + // 0x1F210301: 0x00001F25
+       "\x1f \x03B\x00\x00\x1f&" + // 0x1F200342: 0x00001F26
+       "\x1f!\x03B\x00\x00\x1f'" + // 0x1F210342: 0x00001F27
+       "\x03\x97\x03\x13\x00\x00\x1f(" + // 0x03970313: 0x00001F28
+       "\x03\x97\x03\x14\x00\x00\x1f)" + // 0x03970314: 0x00001F29
+       "\x1f(\x03\x00\x00\x00\x1f*" + // 0x1F280300: 0x00001F2A
+       "\x1f)\x03\x00\x00\x00\x1f+" + // 0x1F290300: 0x00001F2B
+       "\x1f(\x03\x01\x00\x00\x1f," + // 0x1F280301: 0x00001F2C
+       "\x1f)\x03\x01\x00\x00\x1f-" + // 0x1F290301: 0x00001F2D
+       "\x1f(\x03B\x00\x00\x1f." + // 0x1F280342: 0x00001F2E
+       "\x1f)\x03B\x00\x00\x1f/" + // 0x1F290342: 0x00001F2F
+       "\x03\xb9\x03\x13\x00\x00\x1f0" + // 0x03B90313: 0x00001F30
+       "\x03\xb9\x03\x14\x00\x00\x1f1" + // 0x03B90314: 0x00001F31
+       "\x1f0\x03\x00\x00\x00\x1f2" + // 0x1F300300: 0x00001F32
+       "\x1f1\x03\x00\x00\x00\x1f3" + // 0x1F310300: 0x00001F33
+       "\x1f0\x03\x01\x00\x00\x1f4" + // 0x1F300301: 0x00001F34
+       "\x1f1\x03\x01\x00\x00\x1f5" + // 0x1F310301: 0x00001F35
+       "\x1f0\x03B\x00\x00\x1f6" + // 0x1F300342: 0x00001F36
+       "\x1f1\x03B\x00\x00\x1f7" + // 0x1F310342: 0x00001F37
+       "\x03\x99\x03\x13\x00\x00\x1f8" + // 0x03990313: 0x00001F38
+       "\x03\x99\x03\x14\x00\x00\x1f9" + // 0x03990314: 0x00001F39
+       "\x1f8\x03\x00\x00\x00\x1f:" + // 0x1F380300: 0x00001F3A
+       "\x1f9\x03\x00\x00\x00\x1f;" + // 0x1F390300: 0x00001F3B
+       "\x1f8\x03\x01\x00\x00\x1f<" + // 0x1F380301: 0x00001F3C
+       "\x1f9\x03\x01\x00\x00\x1f=" + // 0x1F390301: 0x00001F3D
+       "\x1f8\x03B\x00\x00\x1f>" + // 0x1F380342: 0x00001F3E
+       "\x1f9\x03B\x00\x00\x1f?" + // 0x1F390342: 0x00001F3F
+       "\x03\xbf\x03\x13\x00\x00\x1f@" + // 0x03BF0313: 0x00001F40
+       "\x03\xbf\x03\x14\x00\x00\x1fA" + // 0x03BF0314: 0x00001F41
+       "\x1f@\x03\x00\x00\x00\x1fB" + // 0x1F400300: 0x00001F42
+       "\x1fA\x03\x00\x00\x00\x1fC" + // 0x1F410300: 0x00001F43
+       "\x1f@\x03\x01\x00\x00\x1fD" + // 0x1F400301: 0x00001F44
+       "\x1fA\x03\x01\x00\x00\x1fE" + // 0x1F410301: 0x00001F45
+       "\x03\x9f\x03\x13\x00\x00\x1fH" + // 0x039F0313: 0x00001F48
+       "\x03\x9f\x03\x14\x00\x00\x1fI" + // 0x039F0314: 0x00001F49
+       "\x1fH\x03\x00\x00\x00\x1fJ" + // 0x1F480300: 0x00001F4A
+       "\x1fI\x03\x00\x00\x00\x1fK" + // 0x1F490300: 0x00001F4B
+       "\x1fH\x03\x01\x00\x00\x1fL" + // 0x1F480301: 0x00001F4C
+       "\x1fI\x03\x01\x00\x00\x1fM" + // 0x1F490301: 0x00001F4D
+       "\x03\xc5\x03\x13\x00\x00\x1fP" + // 0x03C50313: 0x00001F50
+       "\x03\xc5\x03\x14\x00\x00\x1fQ" + // 0x03C50314: 0x00001F51
+       "\x1fP\x03\x00\x00\x00\x1fR" + // 0x1F500300: 0x00001F52
+       "\x1fQ\x03\x00\x00\x00\x1fS" + // 0x1F510300: 0x00001F53
+       "\x1fP\x03\x01\x00\x00\x1fT" + // 0x1F500301: 0x00001F54
+       "\x1fQ\x03\x01\x00\x00\x1fU" + // 0x1F510301: 0x00001F55
+       "\x1fP\x03B\x00\x00\x1fV" + // 0x1F500342: 0x00001F56
+       "\x1fQ\x03B\x00\x00\x1fW" + // 0x1F510342: 0x00001F57
+       "\x03\xa5\x03\x14\x00\x00\x1fY" + // 0x03A50314: 0x00001F59
+       "\x1fY\x03\x00\x00\x00\x1f[" + // 0x1F590300: 0x00001F5B
+       "\x1fY\x03\x01\x00\x00\x1f]" + // 0x1F590301: 0x00001F5D
+       "\x1fY\x03B\x00\x00\x1f_" + // 0x1F590342: 0x00001F5F
+       "\x03\xc9\x03\x13\x00\x00\x1f`" + // 0x03C90313: 0x00001F60
+       "\x03\xc9\x03\x14\x00\x00\x1fa" + // 0x03C90314: 0x00001F61
+       "\x1f`\x03\x00\x00\x00\x1fb" + // 0x1F600300: 0x00001F62
+       "\x1fa\x03\x00\x00\x00\x1fc" + // 0x1F610300: 0x00001F63
+       "\x1f`\x03\x01\x00\x00\x1fd" + // 0x1F600301: 0x00001F64
+       "\x1fa\x03\x01\x00\x00\x1fe" + // 0x1F610301: 0x00001F65
+       "\x1f`\x03B\x00\x00\x1ff" + // 0x1F600342: 0x00001F66
+       "\x1fa\x03B\x00\x00\x1fg" + // 0x1F610342: 0x00001F67
+       "\x03\xa9\x03\x13\x00\x00\x1fh" + // 0x03A90313: 0x00001F68
+       "\x03\xa9\x03\x14\x00\x00\x1fi" + // 0x03A90314: 0x00001F69
+       "\x1fh\x03\x00\x00\x00\x1fj" + // 0x1F680300: 0x00001F6A
+       "\x1fi\x03\x00\x00\x00\x1fk" + // 0x1F690300: 0x00001F6B
+       "\x1fh\x03\x01\x00\x00\x1fl" + // 0x1F680301: 0x00001F6C
+       "\x1fi\x03\x01\x00\x00\x1fm" + // 0x1F690301: 0x00001F6D
+       "\x1fh\x03B\x00\x00\x1fn" + // 0x1F680342: 0x00001F6E
+       "\x1fi\x03B\x00\x00\x1fo" + // 0x1F690342: 0x00001F6F
+       "\x03\xb1\x03\x00\x00\x00\x1fp" + // 0x03B10300: 0x00001F70
+       "\x03\xb5\x03\x00\x00\x00\x1fr" + // 0x03B50300: 0x00001F72
+       "\x03\xb7\x03\x00\x00\x00\x1ft" + // 0x03B70300: 0x00001F74
+       "\x03\xb9\x03\x00\x00\x00\x1fv" + // 0x03B90300: 0x00001F76
+       "\x03\xbf\x03\x00\x00\x00\x1fx" + // 0x03BF0300: 0x00001F78
+       "\x03\xc5\x03\x00\x00\x00\x1fz" + // 0x03C50300: 0x00001F7A
+       "\x03\xc9\x03\x00\x00\x00\x1f|" + // 0x03C90300: 0x00001F7C
+       "\x1f\x00\x03E\x00\x00\x1f\x80" + // 0x1F000345: 0x00001F80
+       "\x1f\x01\x03E\x00\x00\x1f\x81" + // 0x1F010345: 0x00001F81
+       "\x1f\x02\x03E\x00\x00\x1f\x82" + // 0x1F020345: 0x00001F82
+       "\x1f\x03\x03E\x00\x00\x1f\x83" + // 0x1F030345: 0x00001F83
+       "\x1f\x04\x03E\x00\x00\x1f\x84" + // 0x1F040345: 0x00001F84
+       "\x1f\x05\x03E\x00\x00\x1f\x85" + // 0x1F050345: 0x00001F85
+       "\x1f\x06\x03E\x00\x00\x1f\x86" + // 0x1F060345: 0x00001F86
+       "\x1f\a\x03E\x00\x00\x1f\x87" + // 0x1F070345: 0x00001F87
+       "\x1f\b\x03E\x00\x00\x1f\x88" + // 0x1F080345: 0x00001F88
+       "\x1f\t\x03E\x00\x00\x1f\x89" + // 0x1F090345: 0x00001F89
+       "\x1f\n\x03E\x00\x00\x1f\x8a" + // 0x1F0A0345: 0x00001F8A
+       "\x1f\v\x03E\x00\x00\x1f\x8b" + // 0x1F0B0345: 0x00001F8B
+       "\x1f\f\x03E\x00\x00\x1f\x8c" + // 0x1F0C0345: 0x00001F8C
+       "\x1f\r\x03E\x00\x00\x1f\x8d" + // 0x1F0D0345: 0x00001F8D
+       "\x1f\x0e\x03E\x00\x00\x1f\x8e" + // 0x1F0E0345: 0x00001F8E
+       "\x1f\x0f\x03E\x00\x00\x1f\x8f" + // 0x1F0F0345: 0x00001F8F
+       "\x1f \x03E\x00\x00\x1f\x90" + // 0x1F200345: 0x00001F90
+       "\x1f!\x03E\x00\x00\x1f\x91" + // 0x1F210345: 0x00001F91
+       "\x1f\"\x03E\x00\x00\x1f\x92" + // 0x1F220345: 0x00001F92
+       "\x1f#\x03E\x00\x00\x1f\x93" + // 0x1F230345: 0x00001F93
+       "\x1f$\x03E\x00\x00\x1f\x94" + // 0x1F240345: 0x00001F94
+       "\x1f%\x03E\x00\x00\x1f\x95" + // 0x1F250345: 0x00001F95
+       "\x1f&\x03E\x00\x00\x1f\x96" + // 0x1F260345: 0x00001F96
+       "\x1f'\x03E\x00\x00\x1f\x97" + // 0x1F270345: 0x00001F97
+       "\x1f(\x03E\x00\x00\x1f\x98" + // 0x1F280345: 0x00001F98
+       "\x1f)\x03E\x00\x00\x1f\x99" + // 0x1F290345: 0x00001F99
+       "\x1f*\x03E\x00\x00\x1f\x9a" + // 0x1F2A0345: 0x00001F9A
+       "\x1f+\x03E\x00\x00\x1f\x9b" + // 0x1F2B0345: 0x00001F9B
+       "\x1f,\x03E\x00\x00\x1f\x9c" + // 0x1F2C0345: 0x00001F9C
+       "\x1f-\x03E\x00\x00\x1f\x9d" + // 0x1F2D0345: 0x00001F9D
+       "\x1f.\x03E\x00\x00\x1f\x9e" + // 0x1F2E0345: 0x00001F9E
+       "\x1f/\x03E\x00\x00\x1f\x9f" + // 0x1F2F0345: 0x00001F9F
+       "\x1f`\x03E\x00\x00\x1f\xa0" + // 0x1F600345: 0x00001FA0
+       "\x1fa\x03E\x00\x00\x1f\xa1" + // 0x1F610345: 0x00001FA1
+       "\x1fb\x03E\x00\x00\x1f\xa2" + // 0x1F620345: 0x00001FA2
+       "\x1fc\x03E\x00\x00\x1f\xa3" + // 0x1F630345: 0x00001FA3
+       "\x1fd\x03E\x00\x00\x1f\xa4" + // 0x1F640345: 0x00001FA4
+       "\x1fe\x03E\x00\x00\x1f\xa5" + // 0x1F650345: 0x00001FA5
+       "\x1ff\x03E\x00\x00\x1f\xa6" + // 0x1F660345: 0x00001FA6
+       "\x1fg\x03E\x00\x00\x1f\xa7" + // 0x1F670345: 0x00001FA7
+       "\x1fh\x03E\x00\x00\x1f\xa8" + // 0x1F680345: 0x00001FA8
+       "\x1fi\x03E\x00\x00\x1f\xa9" + // 0x1F690345: 0x00001FA9
+       "\x1fj\x03E\x00\x00\x1f\xaa" + // 0x1F6A0345: 0x00001FAA
+       "\x1fk\x03E\x00\x00\x1f\xab" + // 0x1F6B0345: 0x00001FAB
+       "\x1fl\x03E\x00\x00\x1f\xac" + // 0x1F6C0345: 0x00001FAC
+       "\x1fm\x03E\x00\x00\x1f\xad" + // 0x1F6D0345: 0x00001FAD
+       "\x1fn\x03E\x00\x00\x1f\xae" + // 0x1F6E0345: 0x00001FAE
+       "\x1fo\x03E\x00\x00\x1f\xaf" + // 0x1F6F0345: 0x00001FAF
+       "\x03\xb1\x03\x06\x00\x00\x1f\xb0" + // 0x03B10306: 0x00001FB0
+       "\x03\xb1\x03\x04\x00\x00\x1f\xb1" + // 0x03B10304: 0x00001FB1
+       "\x1fp\x03E\x00\x00\x1f\xb2" + // 0x1F700345: 0x00001FB2
+       "\x03\xb1\x03E\x00\x00\x1f\xb3" + // 0x03B10345: 0x00001FB3
+       "\x03\xac\x03E\x00\x00\x1f\xb4" + // 0x03AC0345: 0x00001FB4
+       "\x03\xb1\x03B\x00\x00\x1f\xb6" + // 0x03B10342: 0x00001FB6
+       "\x1f\xb6\x03E\x00\x00\x1f\xb7" + // 0x1FB60345: 0x00001FB7
+       "\x03\x91\x03\x06\x00\x00\x1f\xb8" + // 0x03910306: 0x00001FB8
+       "\x03\x91\x03\x04\x00\x00\x1f\xb9" + // 0x03910304: 0x00001FB9
+       "\x03\x91\x03\x00\x00\x00\x1f\xba" + // 0x03910300: 0x00001FBA
+       "\x03\x91\x03E\x00\x00\x1f\xbc" + // 0x03910345: 0x00001FBC
+       "\x00\xa8\x03B\x00\x00\x1f\xc1" + // 0x00A80342: 0x00001FC1
+       "\x1ft\x03E\x00\x00\x1f\xc2" + // 0x1F740345: 0x00001FC2
+       "\x03\xb7\x03E\x00\x00\x1f\xc3" + // 0x03B70345: 0x00001FC3
+       "\x03\xae\x03E\x00\x00\x1f\xc4" + // 0x03AE0345: 0x00001FC4
+       "\x03\xb7\x03B\x00\x00\x1f\xc6" + // 0x03B70342: 0x00001FC6
+       "\x1f\xc6\x03E\x00\x00\x1f\xc7" + // 0x1FC60345: 0x00001FC7
+       "\x03\x95\x03\x00\x00\x00\x1f\xc8" + // 0x03950300: 0x00001FC8
+       "\x03\x97\x03\x00\x00\x00\x1f\xca" + // 0x03970300: 0x00001FCA
+       "\x03\x97\x03E\x00\x00\x1f\xcc" + // 0x03970345: 0x00001FCC
+       "\x1f\xbf\x03\x00\x00\x00\x1f\xcd" + // 0x1FBF0300: 0x00001FCD
+       "\x1f\xbf\x03\x01\x00\x00\x1f\xce" + // 0x1FBF0301: 0x00001FCE
+       "\x1f\xbf\x03B\x00\x00\x1f\xcf" + // 0x1FBF0342: 0x00001FCF
+       "\x03\xb9\x03\x06\x00\x00\x1f\xd0" + // 0x03B90306: 0x00001FD0
+       "\x03\xb9\x03\x04\x00\x00\x1f\xd1" + // 0x03B90304: 0x00001FD1
+       "\x03\xca\x03\x00\x00\x00\x1f\xd2" + // 0x03CA0300: 0x00001FD2
+       "\x03\xb9\x03B\x00\x00\x1f\xd6" + // 0x03B90342: 0x00001FD6
+       "\x03\xca\x03B\x00\x00\x1f\xd7" + // 0x03CA0342: 0x00001FD7
+       "\x03\x99\x03\x06\x00\x00\x1f\xd8" + // 0x03990306: 0x00001FD8
+       "\x03\x99\x03\x04\x00\x00\x1f\xd9" + // 0x03990304: 0x00001FD9
+       "\x03\x99\x03\x00\x00\x00\x1f\xda" + // 0x03990300: 0x00001FDA
+       "\x1f\xfe\x03\x00\x00\x00\x1f\xdd" + // 0x1FFE0300: 0x00001FDD
+       "\x1f\xfe\x03\x01\x00\x00\x1f\xde" + // 0x1FFE0301: 0x00001FDE
+       "\x1f\xfe\x03B\x00\x00\x1f\xdf" + // 0x1FFE0342: 0x00001FDF
+       "\x03\xc5\x03\x06\x00\x00\x1f\xe0" + // 0x03C50306: 0x00001FE0
+       "\x03\xc5\x03\x04\x00\x00\x1f\xe1" + // 0x03C50304: 0x00001FE1
+       "\x03\xcb\x03\x00\x00\x00\x1f\xe2" + // 0x03CB0300: 0x00001FE2
+       "\x03\xc1\x03\x13\x00\x00\x1f\xe4" + // 0x03C10313: 0x00001FE4
+       "\x03\xc1\x03\x14\x00\x00\x1f\xe5" + // 0x03C10314: 0x00001FE5
+       "\x03\xc5\x03B\x00\x00\x1f\xe6" + // 0x03C50342: 0x00001FE6
+       "\x03\xcb\x03B\x00\x00\x1f\xe7" + // 0x03CB0342: 0x00001FE7
+       "\x03\xa5\x03\x06\x00\x00\x1f\xe8" + // 0x03A50306: 0x00001FE8
+       "\x03\xa5\x03\x04\x00\x00\x1f\xe9" + // 0x03A50304: 0x00001FE9
+       "\x03\xa5\x03\x00\x00\x00\x1f\xea" + // 0x03A50300: 0x00001FEA
+       "\x03\xa1\x03\x14\x00\x00\x1f\xec" + // 0x03A10314: 0x00001FEC
+       "\x00\xa8\x03\x00\x00\x00\x1f\xed" + // 0x00A80300: 0x00001FED
+       "\x1f|\x03E\x00\x00\x1f\xf2" + // 0x1F7C0345: 0x00001FF2
+       "\x03\xc9\x03E\x00\x00\x1f\xf3" + // 0x03C90345: 0x00001FF3
+       "\x03\xce\x03E\x00\x00\x1f\xf4" + // 0x03CE0345: 0x00001FF4
+       "\x03\xc9\x03B\x00\x00\x1f\xf6" + // 0x03C90342: 0x00001FF6
+       "\x1f\xf6\x03E\x00\x00\x1f\xf7" + // 0x1FF60345: 0x00001FF7
+       "\x03\x9f\x03\x00\x00\x00\x1f\xf8" + // 0x039F0300: 0x00001FF8
+       "\x03\xa9\x03\x00\x00\x00\x1f\xfa" + // 0x03A90300: 0x00001FFA
+       "\x03\xa9\x03E\x00\x00\x1f\xfc" + // 0x03A90345: 0x00001FFC
+       "!\x90\x038\x00\x00!\x9a" + // 0x21900338: 0x0000219A
+       "!\x92\x038\x00\x00!\x9b" + // 0x21920338: 0x0000219B
+       "!\x94\x038\x00\x00!\xae" + // 0x21940338: 0x000021AE
+       "!\xd0\x038\x00\x00!\xcd" + // 0x21D00338: 0x000021CD
+       "!\xd4\x038\x00\x00!\xce" + // 0x21D40338: 0x000021CE
+       "!\xd2\x038\x00\x00!\xcf" + // 0x21D20338: 0x000021CF
+       "\"\x03\x038\x00\x00\"\x04" + // 0x22030338: 0x00002204
+       "\"\b\x038\x00\x00\"\t" + // 0x22080338: 0x00002209
+       "\"\v\x038\x00\x00\"\f" + // 0x220B0338: 0x0000220C
+       "\"#\x038\x00\x00\"$" + // 0x22230338: 0x00002224
+       "\"%\x038\x00\x00\"&" + // 0x22250338: 0x00002226
+       "\"<\x038\x00\x00\"A" + // 0x223C0338: 0x00002241
+       "\"C\x038\x00\x00\"D" + // 0x22430338: 0x00002244
+       "\"E\x038\x00\x00\"G" + // 0x22450338: 0x00002247
+       "\"H\x038\x00\x00\"I" + // 0x22480338: 0x00002249
+       "\x00=\x038\x00\x00\"`" + // 0x003D0338: 0x00002260
+       "\"a\x038\x00\x00\"b" + // 0x22610338: 0x00002262
+       "\"M\x038\x00\x00\"m" + // 0x224D0338: 0x0000226D
+       "\x00<\x038\x00\x00\"n" + // 0x003C0338: 0x0000226E
+       "\x00>\x038\x00\x00\"o" + // 0x003E0338: 0x0000226F
+       "\"d\x038\x00\x00\"p" + // 0x22640338: 0x00002270
+       "\"e\x038\x00\x00\"q" + // 0x22650338: 0x00002271
+       "\"r\x038\x00\x00\"t" + // 0x22720338: 0x00002274
+       "\"s\x038\x00\x00\"u" + // 0x22730338: 0x00002275
+       "\"v\x038\x00\x00\"x" + // 0x22760338: 0x00002278
+       "\"w\x038\x00\x00\"y" + // 0x22770338: 0x00002279
+       "\"z\x038\x00\x00\"\x80" + // 0x227A0338: 0x00002280
+       "\"{\x038\x00\x00\"\x81" + // 0x227B0338: 0x00002281
+       "\"\x82\x038\x00\x00\"\x84" + // 0x22820338: 0x00002284
+       "\"\x83\x038\x00\x00\"\x85" + // 0x22830338: 0x00002285
+       "\"\x86\x038\x00\x00\"\x88" + // 0x22860338: 0x00002288
+       "\"\x87\x038\x00\x00\"\x89" + // 0x22870338: 0x00002289
+       "\"\xa2\x038\x00\x00\"\xac" + // 0x22A20338: 0x000022AC
+       "\"\xa8\x038\x00\x00\"\xad" + // 0x22A80338: 0x000022AD
+       "\"\xa9\x038\x00\x00\"\xae" + // 0x22A90338: 0x000022AE
+       "\"\xab\x038\x00\x00\"\xaf" + // 0x22AB0338: 0x000022AF
+       "\"|\x038\x00\x00\"\xe0" + // 0x227C0338: 0x000022E0
+       "\"}\x038\x00\x00\"\xe1" + // 0x227D0338: 0x000022E1
+       "\"\x91\x038\x00\x00\"\xe2" + // 0x22910338: 0x000022E2
+       "\"\x92\x038\x00\x00\"\xe3" + // 0x22920338: 0x000022E3
+       "\"\xb2\x038\x00\x00\"\xea" + // 0x22B20338: 0x000022EA
+       "\"\xb3\x038\x00\x00\"\xeb" + // 0x22B30338: 0x000022EB
+       "\"\xb4\x038\x00\x00\"\xec" + // 0x22B40338: 0x000022EC
+       "\"\xb5\x038\x00\x00\"\xed" + // 0x22B50338: 0x000022ED
+       "0K0\x99\x00\x000L" + // 0x304B3099: 0x0000304C
+       "0M0\x99\x00\x000N" + // 0x304D3099: 0x0000304E
+       "0O0\x99\x00\x000P" + // 0x304F3099: 0x00003050
+       "0Q0\x99\x00\x000R" + // 0x30513099: 0x00003052
+       "0S0\x99\x00\x000T" + // 0x30533099: 0x00003054
+       "0U0\x99\x00\x000V" + // 0x30553099: 0x00003056
+       "0W0\x99\x00\x000X" + // 0x30573099: 0x00003058
+       "0Y0\x99\x00\x000Z" + // 0x30593099: 0x0000305A
+       "0[0\x99\x00\x000\\" + // 0x305B3099: 0x0000305C
+       "0]0\x99\x00\x000^" + // 0x305D3099: 0x0000305E
+       "0_0\x99\x00\x000`" + // 0x305F3099: 0x00003060
+       "0a0\x99\x00\x000b" + // 0x30613099: 0x00003062
+       "0d0\x99\x00\x000e" + // 0x30643099: 0x00003065
+       "0f0\x99\x00\x000g" + // 0x30663099: 0x00003067
+       "0h0\x99\x00\x000i" + // 0x30683099: 0x00003069
+       "0o0\x99\x00\x000p" + // 0x306F3099: 0x00003070
+       "0o0\x9a\x00\x000q" + // 0x306F309A: 0x00003071
+       "0r0\x99\x00\x000s" + // 0x30723099: 0x00003073
+       "0r0\x9a\x00\x000t" + // 0x3072309A: 0x00003074
+       "0u0\x99\x00\x000v" + // 0x30753099: 0x00003076
+       "0u0\x9a\x00\x000w" + // 0x3075309A: 0x00003077
+       "0x0\x99\x00\x000y" + // 0x30783099: 0x00003079
+       "0x0\x9a\x00\x000z" + // 0x3078309A: 0x0000307A
+       "0{0\x99\x00\x000|" + // 0x307B3099: 0x0000307C
+       "0{0\x9a\x00\x000}" + // 0x307B309A: 0x0000307D
+       "0F0\x99\x00\x000\x94" + // 0x30463099: 0x00003094
+       "0\x9d0\x99\x00\x000\x9e" + // 0x309D3099: 0x0000309E
+       "0\xab0\x99\x00\x000\xac" + // 0x30AB3099: 0x000030AC
+       "0\xad0\x99\x00\x000\xae" + // 0x30AD3099: 0x000030AE
+       "0\xaf0\x99\x00\x000\xb0" + // 0x30AF3099: 0x000030B0
+       "0\xb10\x99\x00\x000\xb2" + // 0x30B13099: 0x000030B2
+       "0\xb30\x99\x00\x000\xb4" + // 0x30B33099: 0x000030B4
+       "0\xb50\x99\x00\x000\xb6" + // 0x30B53099: 0x000030B6
+       "0\xb70\x99\x00\x000\xb8" + // 0x30B73099: 0x000030B8
+       "0\xb90\x99\x00\x000\xba" + // 0x30B93099: 0x000030BA
+       "0\xbb0\x99\x00\x000\xbc" + // 0x30BB3099: 0x000030BC
+       "0\xbd0\x99\x00\x000\xbe" + // 0x30BD3099: 0x000030BE
+       "0\xbf0\x99\x00\x000\xc0" + // 0x30BF3099: 0x000030C0
+       "0\xc10\x99\x00\x000\xc2" + // 0x30C13099: 0x000030C2
+       "0\xc40\x99\x00\x000\xc5" + // 0x30C43099: 0x000030C5
+       "0\xc60\x99\x00\x000\xc7" + // 0x30C63099: 0x000030C7
+       "0\xc80\x99\x00\x000\xc9" + // 0x30C83099: 0x000030C9
+       "0\xcf0\x99\x00\x000\xd0" + // 0x30CF3099: 0x000030D0
+       "0\xcf0\x9a\x00\x000\xd1" + // 0x30CF309A: 0x000030D1
+       "0\xd20\x99\x00\x000\xd3" + // 0x30D23099: 0x000030D3
+       "0\xd20\x9a\x00\x000\xd4" + // 0x30D2309A: 0x000030D4
+       "0\xd50\x99\x00\x000\xd6" + // 0x30D53099: 0x000030D6
+       "0\xd50\x9a\x00\x000\xd7" + // 0x30D5309A: 0x000030D7
+       "0\xd80\x99\x00\x000\xd9" + // 0x30D83099: 0x000030D9
+       "0\xd80\x9a\x00\x000\xda" + // 0x30D8309A: 0x000030DA
+       "0\xdb0\x99\x00\x000\xdc" + // 0x30DB3099: 0x000030DC
+       "0\xdb0\x9a\x00\x000\xdd" + // 0x30DB309A: 0x000030DD
+       "0\xa60\x99\x00\x000\xf4" + // 0x30A63099: 0x000030F4
+       "0\xef0\x99\x00\x000\xf7" + // 0x30EF3099: 0x000030F7
+       "0\xf00\x99\x00\x000\xf8" + // 0x30F03099: 0x000030F8
+       "0\xf10\x99\x00\x000\xf9" + // 0x30F13099: 0x000030F9
+       "0\xf20\x99\x00\x000\xfa" + // 0x30F23099: 0x000030FA
+       "0\xfd0\x99\x00\x000\xfe" + // 0x30FD3099: 0x000030FE
+       "\x10\x99\x10\xba\x00\x01\x10\x9a" + // 0x109910BA: 0x0001109A
+       "\x10\x9b\x10\xba\x00\x01\x10\x9c" + // 0x109B10BA: 0x0001109C
+       "\x10\xa5\x10\xba\x00\x01\x10\xab" + // 0x10A510BA: 0x000110AB
+       "\x111\x11'\x00\x01\x11." + // 0x11311127: 0x0001112E
+       "\x112\x11'\x00\x01\x11/" + // 0x11321127: 0x0001112F
+       "\x13G\x13>\x00\x01\x13K" + // 0x1347133E: 0x0001134B
+       "\x13G\x13W\x00\x01\x13L" + // 0x13471357: 0x0001134C
+       "\x14\xb9\x14\xba\x00\x01\x14\xbb" + // 0x14B914BA: 0x000114BB
+       "\x14\xb9\x14\xb0\x00\x01\x14\xbc" + // 0x14B914B0: 0x000114BC
+       "\x14\xb9\x14\xbd\x00\x01\x14\xbe" + // 0x14B914BD: 0x000114BE
+       "\x15\xb8\x15\xaf\x00\x01\x15\xba" + // 0x15B815AF: 0x000115BA
+       "\x15\xb9\x15\xaf\x00\x01\x15\xbb" + // 0x15B915AF: 0x000115BB
+       "\x195\x190\x00\x01\x198" + // 0x19351930: 0x00011938
+       ""
+       // Total size of tables: 55KB (56160 bytes)
index 5c859677a7981adc1f27bcdca99517ea816deb15..543942b9e781b3b4409f1cd5557e18af8eef54f0 100644 (file)
@@ -1,6 +1,6 @@
 // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
 
-// +build go1.14
+// +build go1.14,!go1.16
 
 package width
 
diff --git a/vendor/golang.org/x/text/width/tables13.0.0.go b/vendor/golang.org/x/text/width/tables13.0.0.go
new file mode 100644 (file)
index 0000000..804264c
--- /dev/null
@@ -0,0 +1,1351 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+// +build go1.16
+
+package width
+
+// UnicodeVersion is the Unicode version from which the tables in this package are derived.
+const UnicodeVersion = "13.0.0"
+
+// lookup returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *widthTrie) lookup(s []byte) (v uint16, sz int) {
+       c0 := s[0]
+       switch {
+       case c0 < 0x80: // is ASCII
+               return widthValues[c0], 1
+       case c0 < 0xC2:
+               return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+       case c0 < 0xE0: // 2-byte UTF-8
+               if len(s) < 2 {
+                       return 0, 0
+               }
+               i := widthIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c1), 2
+       case c0 < 0xF0: // 3-byte UTF-8
+               if len(s) < 3 {
+                       return 0, 0
+               }
+               i := widthIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               o := uint32(i)<<6 + uint32(c1)
+               i = widthIndex[o]
+               c2 := s[2]
+               if c2 < 0x80 || 0xC0 <= c2 {
+                       return 0, 2 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c2), 3
+       case c0 < 0xF8: // 4-byte UTF-8
+               if len(s) < 4 {
+                       return 0, 0
+               }
+               i := widthIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               o := uint32(i)<<6 + uint32(c1)
+               i = widthIndex[o]
+               c2 := s[2]
+               if c2 < 0x80 || 0xC0 <= c2 {
+                       return 0, 2 // Illegal UTF-8: not a continuation byte.
+               }
+               o = uint32(i)<<6 + uint32(c2)
+               i = widthIndex[o]
+               c3 := s[3]
+               if c3 < 0x80 || 0xC0 <= c3 {
+                       return 0, 3 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c3), 4
+       }
+       // Illegal rune
+       return 0, 1
+}
+
+// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *widthTrie) lookupUnsafe(s []byte) uint16 {
+       c0 := s[0]
+       if c0 < 0x80 { // is ASCII
+               return widthValues[c0]
+       }
+       i := widthIndex[c0]
+       if c0 < 0xE0 { // 2-byte UTF-8
+               return t.lookupValue(uint32(i), s[1])
+       }
+       i = widthIndex[uint32(i)<<6+uint32(s[1])]
+       if c0 < 0xF0 { // 3-byte UTF-8
+               return t.lookupValue(uint32(i), s[2])
+       }
+       i = widthIndex[uint32(i)<<6+uint32(s[2])]
+       if c0 < 0xF8 { // 4-byte UTF-8
+               return t.lookupValue(uint32(i), s[3])
+       }
+       return 0
+}
+
+// lookupString returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *widthTrie) lookupString(s string) (v uint16, sz int) {
+       c0 := s[0]
+       switch {
+       case c0 < 0x80: // is ASCII
+               return widthValues[c0], 1
+       case c0 < 0xC2:
+               return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+       case c0 < 0xE0: // 2-byte UTF-8
+               if len(s) < 2 {
+                       return 0, 0
+               }
+               i := widthIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c1), 2
+       case c0 < 0xF0: // 3-byte UTF-8
+               if len(s) < 3 {
+                       return 0, 0
+               }
+               i := widthIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               o := uint32(i)<<6 + uint32(c1)
+               i = widthIndex[o]
+               c2 := s[2]
+               if c2 < 0x80 || 0xC0 <= c2 {
+                       return 0, 2 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c2), 3
+       case c0 < 0xF8: // 4-byte UTF-8
+               if len(s) < 4 {
+                       return 0, 0
+               }
+               i := widthIndex[c0]
+               c1 := s[1]
+               if c1 < 0x80 || 0xC0 <= c1 {
+                       return 0, 1 // Illegal UTF-8: not a continuation byte.
+               }
+               o := uint32(i)<<6 + uint32(c1)
+               i = widthIndex[o]
+               c2 := s[2]
+               if c2 < 0x80 || 0xC0 <= c2 {
+                       return 0, 2 // Illegal UTF-8: not a continuation byte.
+               }
+               o = uint32(i)<<6 + uint32(c2)
+               i = widthIndex[o]
+               c3 := s[3]
+               if c3 < 0x80 || 0xC0 <= c3 {
+                       return 0, 3 // Illegal UTF-8: not a continuation byte.
+               }
+               return t.lookupValue(uint32(i), c3), 4
+       }
+       // Illegal rune
+       return 0, 1
+}
+
+// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *widthTrie) lookupStringUnsafe(s string) uint16 {
+       c0 := s[0]
+       if c0 < 0x80 { // is ASCII
+               return widthValues[c0]
+       }
+       i := widthIndex[c0]
+       if c0 < 0xE0 { // 2-byte UTF-8
+               return t.lookupValue(uint32(i), s[1])
+       }
+       i = widthIndex[uint32(i)<<6+uint32(s[1])]
+       if c0 < 0xF0 { // 3-byte UTF-8
+               return t.lookupValue(uint32(i), s[2])
+       }
+       i = widthIndex[uint32(i)<<6+uint32(s[2])]
+       if c0 < 0xF8 { // 4-byte UTF-8
+               return t.lookupValue(uint32(i), s[3])
+       }
+       return 0
+}
+
+// widthTrie. Total size: 14848 bytes (14.50 KiB). Checksum: 17e24343536472f6.
+type widthTrie struct{}
+
+func newWidthTrie(i int) *widthTrie {
+       return &widthTrie{}
+}
+
+// lookupValue determines the type of block n and looks up the value for b.
+func (t *widthTrie) lookupValue(n uint32, b byte) uint16 {
+       switch {
+       default:
+               return uint16(widthValues[n<<6+uint32(b)])
+       }
+}
+
+// widthValues: 105 blocks, 6720 entries, 13440 bytes
+// The third block is the zero block.
+var widthValues = [6720]uint16{
+       // Block 0x0, offset 0x0
+       0x20: 0x6001, 0x21: 0x6002, 0x22: 0x6002, 0x23: 0x6002,
+       0x24: 0x6002, 0x25: 0x6002, 0x26: 0x6002, 0x27: 0x6002, 0x28: 0x6002, 0x29: 0x6002,
+       0x2a: 0x6002, 0x2b: 0x6002, 0x2c: 0x6002, 0x2d: 0x6002, 0x2e: 0x6002, 0x2f: 0x6002,
+       0x30: 0x6002, 0x31: 0x6002, 0x32: 0x6002, 0x33: 0x6002, 0x34: 0x6002, 0x35: 0x6002,
+       0x36: 0x6002, 0x37: 0x6002, 0x38: 0x6002, 0x39: 0x6002, 0x3a: 0x6002, 0x3b: 0x6002,
+       0x3c: 0x6002, 0x3d: 0x6002, 0x3e: 0x6002, 0x3f: 0x6002,
+       // Block 0x1, offset 0x40
+       0x40: 0x6003, 0x41: 0x6003, 0x42: 0x6003, 0x43: 0x6003, 0x44: 0x6003, 0x45: 0x6003,
+       0x46: 0x6003, 0x47: 0x6003, 0x48: 0x6003, 0x49: 0x6003, 0x4a: 0x6003, 0x4b: 0x6003,
+       0x4c: 0x6003, 0x4d: 0x6003, 0x4e: 0x6003, 0x4f: 0x6003, 0x50: 0x6003, 0x51: 0x6003,
+       0x52: 0x6003, 0x53: 0x6003, 0x54: 0x6003, 0x55: 0x6003, 0x56: 0x6003, 0x57: 0x6003,
+       0x58: 0x6003, 0x59: 0x6003, 0x5a: 0x6003, 0x5b: 0x6003, 0x5c: 0x6003, 0x5d: 0x6003,
+       0x5e: 0x6003, 0x5f: 0x6003, 0x60: 0x6004, 0x61: 0x6004, 0x62: 0x6004, 0x63: 0x6004,
+       0x64: 0x6004, 0x65: 0x6004, 0x66: 0x6004, 0x67: 0x6004, 0x68: 0x6004, 0x69: 0x6004,
+       0x6a: 0x6004, 0x6b: 0x6004, 0x6c: 0x6004, 0x6d: 0x6004, 0x6e: 0x6004, 0x6f: 0x6004,
+       0x70: 0x6004, 0x71: 0x6004, 0x72: 0x6004, 0x73: 0x6004, 0x74: 0x6004, 0x75: 0x6004,
+       0x76: 0x6004, 0x77: 0x6004, 0x78: 0x6004, 0x79: 0x6004, 0x7a: 0x6004, 0x7b: 0x6004,
+       0x7c: 0x6004, 0x7d: 0x6004, 0x7e: 0x6004,
+       // Block 0x2, offset 0x80
+       // Block 0x3, offset 0xc0
+       0xe1: 0x2000, 0xe2: 0x6005, 0xe3: 0x6005,
+       0xe4: 0x2000, 0xe5: 0x6006, 0xe6: 0x6005, 0xe7: 0x2000, 0xe8: 0x2000,
+       0xea: 0x2000, 0xec: 0x6007, 0xed: 0x2000, 0xee: 0x2000, 0xef: 0x6008,
+       0xf0: 0x2000, 0xf1: 0x2000, 0xf2: 0x2000, 0xf3: 0x2000, 0xf4: 0x2000,
+       0xf6: 0x2000, 0xf7: 0x2000, 0xf8: 0x2000, 0xf9: 0x2000, 0xfa: 0x2000,
+       0xfc: 0x2000, 0xfd: 0x2000, 0xfe: 0x2000, 0xff: 0x2000,
+       // Block 0x4, offset 0x100
+       0x106: 0x2000,
+       0x110: 0x2000,
+       0x117: 0x2000,
+       0x118: 0x2000,
+       0x11e: 0x2000, 0x11f: 0x2000, 0x120: 0x2000, 0x121: 0x2000,
+       0x126: 0x2000, 0x128: 0x2000, 0x129: 0x2000,
+       0x12a: 0x2000, 0x12c: 0x2000, 0x12d: 0x2000,
+       0x130: 0x2000, 0x132: 0x2000, 0x133: 0x2000,
+       0x137: 0x2000, 0x138: 0x2000, 0x139: 0x2000, 0x13a: 0x2000,
+       0x13c: 0x2000, 0x13e: 0x2000,
+       // Block 0x5, offset 0x140
+       0x141: 0x2000,
+       0x151: 0x2000,
+       0x153: 0x2000,
+       0x15b: 0x2000,
+       0x166: 0x2000, 0x167: 0x2000,
+       0x16b: 0x2000,
+       0x171: 0x2000, 0x172: 0x2000, 0x173: 0x2000,
+       0x178: 0x2000,
+       0x17f: 0x2000,
+       // Block 0x6, offset 0x180
+       0x180: 0x2000, 0x181: 0x2000, 0x182: 0x2000, 0x184: 0x2000,
+       0x188: 0x2000, 0x189: 0x2000, 0x18a: 0x2000, 0x18b: 0x2000,
+       0x18d: 0x2000,
+       0x192: 0x2000, 0x193: 0x2000,
+       0x1a6: 0x2000, 0x1a7: 0x2000,
+       0x1ab: 0x2000,
+       // Block 0x7, offset 0x1c0
+       0x1ce: 0x2000, 0x1d0: 0x2000,
+       0x1d2: 0x2000, 0x1d4: 0x2000, 0x1d6: 0x2000,
+       0x1d8: 0x2000, 0x1da: 0x2000, 0x1dc: 0x2000,
+       // Block 0x8, offset 0x200
+       0x211: 0x2000,
+       0x221: 0x2000,
+       // Block 0x9, offset 0x240
+       0x244: 0x2000,
+       0x247: 0x2000, 0x249: 0x2000, 0x24a: 0x2000, 0x24b: 0x2000,
+       0x24d: 0x2000, 0x250: 0x2000,
+       0x258: 0x2000, 0x259: 0x2000, 0x25a: 0x2000, 0x25b: 0x2000, 0x25d: 0x2000,
+       0x25f: 0x2000,
+       // Block 0xa, offset 0x280
+       0x280: 0x2000, 0x281: 0x2000, 0x282: 0x2000, 0x283: 0x2000, 0x284: 0x2000, 0x285: 0x2000,
+       0x286: 0x2000, 0x287: 0x2000, 0x288: 0x2000, 0x289: 0x2000, 0x28a: 0x2000, 0x28b: 0x2000,
+       0x28c: 0x2000, 0x28d: 0x2000, 0x28e: 0x2000, 0x28f: 0x2000, 0x290: 0x2000, 0x291: 0x2000,
+       0x292: 0x2000, 0x293: 0x2000, 0x294: 0x2000, 0x295: 0x2000, 0x296: 0x2000, 0x297: 0x2000,
+       0x298: 0x2000, 0x299: 0x2000, 0x29a: 0x2000, 0x29b: 0x2000, 0x29c: 0x2000, 0x29d: 0x2000,
+       0x29e: 0x2000, 0x29f: 0x2000, 0x2a0: 0x2000, 0x2a1: 0x2000, 0x2a2: 0x2000, 0x2a3: 0x2000,
+       0x2a4: 0x2000, 0x2a5: 0x2000, 0x2a6: 0x2000, 0x2a7: 0x2000, 0x2a8: 0x2000, 0x2a9: 0x2000,
+       0x2aa: 0x2000, 0x2ab: 0x2000, 0x2ac: 0x2000, 0x2ad: 0x2000, 0x2ae: 0x2000, 0x2af: 0x2000,
+       0x2b0: 0x2000, 0x2b1: 0x2000, 0x2b2: 0x2000, 0x2b3: 0x2000, 0x2b4: 0x2000, 0x2b5: 0x2000,
+       0x2b6: 0x2000, 0x2b7: 0x2000, 0x2b8: 0x2000, 0x2b9: 0x2000, 0x2ba: 0x2000, 0x2bb: 0x2000,
+       0x2bc: 0x2000, 0x2bd: 0x2000, 0x2be: 0x2000, 0x2bf: 0x2000,
+       // Block 0xb, offset 0x2c0
+       0x2c0: 0x2000, 0x2c1: 0x2000, 0x2c2: 0x2000, 0x2c3: 0x2000, 0x2c4: 0x2000, 0x2c5: 0x2000,
+       0x2c6: 0x2000, 0x2c7: 0x2000, 0x2c8: 0x2000, 0x2c9: 0x2000, 0x2ca: 0x2000, 0x2cb: 0x2000,
+       0x2cc: 0x2000, 0x2cd: 0x2000, 0x2ce: 0x2000, 0x2cf: 0x2000, 0x2d0: 0x2000, 0x2d1: 0x2000,
+       0x2d2: 0x2000, 0x2d3: 0x2000, 0x2d4: 0x2000, 0x2d5: 0x2000, 0x2d6: 0x2000, 0x2d7: 0x2000,
+       0x2d8: 0x2000, 0x2d9: 0x2000, 0x2da: 0x2000, 0x2db: 0x2000, 0x2dc: 0x2000, 0x2dd: 0x2000,
+       0x2de: 0x2000, 0x2df: 0x2000, 0x2e0: 0x2000, 0x2e1: 0x2000, 0x2e2: 0x2000, 0x2e3: 0x2000,
+       0x2e4: 0x2000, 0x2e5: 0x2000, 0x2e6: 0x2000, 0x2e7: 0x2000, 0x2e8: 0x2000, 0x2e9: 0x2000,
+       0x2ea: 0x2000, 0x2eb: 0x2000, 0x2ec: 0x2000, 0x2ed: 0x2000, 0x2ee: 0x2000, 0x2ef: 0x2000,
+       // Block 0xc, offset 0x300
+       0x311: 0x2000,
+       0x312: 0x2000, 0x313: 0x2000, 0x314: 0x2000, 0x315: 0x2000, 0x316: 0x2000, 0x317: 0x2000,
+       0x318: 0x2000, 0x319: 0x2000, 0x31a: 0x2000, 0x31b: 0x2000, 0x31c: 0x2000, 0x31d: 0x2000,
+       0x31e: 0x2000, 0x31f: 0x2000, 0x320: 0x2000, 0x321: 0x2000, 0x323: 0x2000,
+       0x324: 0x2000, 0x325: 0x2000, 0x326: 0x2000, 0x327: 0x2000, 0x328: 0x2000, 0x329: 0x2000,
+       0x331: 0x2000, 0x332: 0x2000, 0x333: 0x2000, 0x334: 0x2000, 0x335: 0x2000,
+       0x336: 0x2000, 0x337: 0x2000, 0x338: 0x2000, 0x339: 0x2000, 0x33a: 0x2000, 0x33b: 0x2000,
+       0x33c: 0x2000, 0x33d: 0x2000, 0x33e: 0x2000, 0x33f: 0x2000,
+       // Block 0xd, offset 0x340
+       0x340: 0x2000, 0x341: 0x2000, 0x343: 0x2000, 0x344: 0x2000, 0x345: 0x2000,
+       0x346: 0x2000, 0x347: 0x2000, 0x348: 0x2000, 0x349: 0x2000,
+       // Block 0xe, offset 0x380
+       0x381: 0x2000,
+       0x390: 0x2000, 0x391: 0x2000,
+       0x392: 0x2000, 0x393: 0x2000, 0x394: 0x2000, 0x395: 0x2000, 0x396: 0x2000, 0x397: 0x2000,
+       0x398: 0x2000, 0x399: 0x2000, 0x39a: 0x2000, 0x39b: 0x2000, 0x39c: 0x2000, 0x39d: 0x2000,
+       0x39e: 0x2000, 0x39f: 0x2000, 0x3a0: 0x2000, 0x3a1: 0x2000, 0x3a2: 0x2000, 0x3a3: 0x2000,
+       0x3a4: 0x2000, 0x3a5: 0x2000, 0x3a6: 0x2000, 0x3a7: 0x2000, 0x3a8: 0x2000, 0x3a9: 0x2000,
+       0x3aa: 0x2000, 0x3ab: 0x2000, 0x3ac: 0x2000, 0x3ad: 0x2000, 0x3ae: 0x2000, 0x3af: 0x2000,
+       0x3b0: 0x2000, 0x3b1: 0x2000, 0x3b2: 0x2000, 0x3b3: 0x2000, 0x3b4: 0x2000, 0x3b5: 0x2000,
+       0x3b6: 0x2000, 0x3b7: 0x2000, 0x3b8: 0x2000, 0x3b9: 0x2000, 0x3ba: 0x2000, 0x3bb: 0x2000,
+       0x3bc: 0x2000, 0x3bd: 0x2000, 0x3be: 0x2000, 0x3bf: 0x2000,
+       // Block 0xf, offset 0x3c0
+       0x3c0: 0x2000, 0x3c1: 0x2000, 0x3c2: 0x2000, 0x3c3: 0x2000, 0x3c4: 0x2000, 0x3c5: 0x2000,
+       0x3c6: 0x2000, 0x3c7: 0x2000, 0x3c8: 0x2000, 0x3c9: 0x2000, 0x3ca: 0x2000, 0x3cb: 0x2000,
+       0x3cc: 0x2000, 0x3cd: 0x2000, 0x3ce: 0x2000, 0x3cf: 0x2000, 0x3d1: 0x2000,
+       // Block 0x10, offset 0x400
+       0x400: 0x4000, 0x401: 0x4000, 0x402: 0x4000, 0x403: 0x4000, 0x404: 0x4000, 0x405: 0x4000,
+       0x406: 0x4000, 0x407: 0x4000, 0x408: 0x4000, 0x409: 0x4000, 0x40a: 0x4000, 0x40b: 0x4000,
+       0x40c: 0x4000, 0x40d: 0x4000, 0x40e: 0x4000, 0x40f: 0x4000, 0x410: 0x4000, 0x411: 0x4000,
+       0x412: 0x4000, 0x413: 0x4000, 0x414: 0x4000, 0x415: 0x4000, 0x416: 0x4000, 0x417: 0x4000,
+       0x418: 0x4000, 0x419: 0x4000, 0x41a: 0x4000, 0x41b: 0x4000, 0x41c: 0x4000, 0x41d: 0x4000,
+       0x41e: 0x4000, 0x41f: 0x4000, 0x420: 0x4000, 0x421: 0x4000, 0x422: 0x4000, 0x423: 0x4000,
+       0x424: 0x4000, 0x425: 0x4000, 0x426: 0x4000, 0x427: 0x4000, 0x428: 0x4000, 0x429: 0x4000,
+       0x42a: 0x4000, 0x42b: 0x4000, 0x42c: 0x4000, 0x42d: 0x4000, 0x42e: 0x4000, 0x42f: 0x4000,
+       0x430: 0x4000, 0x431: 0x4000, 0x432: 0x4000, 0x433: 0x4000, 0x434: 0x4000, 0x435: 0x4000,
+       0x436: 0x4000, 0x437: 0x4000, 0x438: 0x4000, 0x439: 0x4000, 0x43a: 0x4000, 0x43b: 0x4000,
+       0x43c: 0x4000, 0x43d: 0x4000, 0x43e: 0x4000, 0x43f: 0x4000,
+       // Block 0x11, offset 0x440
+       0x440: 0x4000, 0x441: 0x4000, 0x442: 0x4000, 0x443: 0x4000, 0x444: 0x4000, 0x445: 0x4000,
+       0x446: 0x4000, 0x447: 0x4000, 0x448: 0x4000, 0x449: 0x4000, 0x44a: 0x4000, 0x44b: 0x4000,
+       0x44c: 0x4000, 0x44d: 0x4000, 0x44e: 0x4000, 0x44f: 0x4000, 0x450: 0x4000, 0x451: 0x4000,
+       0x452: 0x4000, 0x453: 0x4000, 0x454: 0x4000, 0x455: 0x4000, 0x456: 0x4000, 0x457: 0x4000,
+       0x458: 0x4000, 0x459: 0x4000, 0x45a: 0x4000, 0x45b: 0x4000, 0x45c: 0x4000, 0x45d: 0x4000,
+       0x45e: 0x4000, 0x45f: 0x4000,
+       // Block 0x12, offset 0x480
+       0x490: 0x2000,
+       0x493: 0x2000, 0x494: 0x2000, 0x495: 0x2000, 0x496: 0x2000,
+       0x498: 0x2000, 0x499: 0x2000, 0x49c: 0x2000, 0x49d: 0x2000,
+       0x4a0: 0x2000, 0x4a1: 0x2000, 0x4a2: 0x2000,
+       0x4a4: 0x2000, 0x4a5: 0x2000, 0x4a6: 0x2000, 0x4a7: 0x2000,
+       0x4b0: 0x2000, 0x4b2: 0x2000, 0x4b3: 0x2000, 0x4b5: 0x2000,
+       0x4bb: 0x2000,
+       0x4be: 0x2000,
+       // Block 0x13, offset 0x4c0
+       0x4f4: 0x2000,
+       0x4ff: 0x2000,
+       // Block 0x14, offset 0x500
+       0x501: 0x2000, 0x502: 0x2000, 0x503: 0x2000, 0x504: 0x2000,
+       0x529: 0xa009,
+       0x52c: 0x2000,
+       // Block 0x15, offset 0x540
+       0x543: 0x2000, 0x545: 0x2000,
+       0x549: 0x2000,
+       0x553: 0x2000, 0x556: 0x2000,
+       0x561: 0x2000, 0x562: 0x2000,
+       0x566: 0x2000,
+       0x56b: 0x2000,
+       // Block 0x16, offset 0x580
+       0x593: 0x2000, 0x594: 0x2000,
+       0x59b: 0x2000, 0x59c: 0x2000, 0x59d: 0x2000,
+       0x59e: 0x2000, 0x5a0: 0x2000, 0x5a1: 0x2000, 0x5a2: 0x2000, 0x5a3: 0x2000,
+       0x5a4: 0x2000, 0x5a5: 0x2000, 0x5a6: 0x2000, 0x5a7: 0x2000, 0x5a8: 0x2000, 0x5a9: 0x2000,
+       0x5aa: 0x2000, 0x5ab: 0x2000,
+       0x5b0: 0x2000, 0x5b1: 0x2000, 0x5b2: 0x2000, 0x5b3: 0x2000, 0x5b4: 0x2000, 0x5b5: 0x2000,
+       0x5b6: 0x2000, 0x5b7: 0x2000, 0x5b8: 0x2000, 0x5b9: 0x2000,
+       // Block 0x17, offset 0x5c0
+       0x5c9: 0x2000,
+       0x5d0: 0x200a, 0x5d1: 0x200b,
+       0x5d2: 0x200a, 0x5d3: 0x200c, 0x5d4: 0x2000, 0x5d5: 0x2000, 0x5d6: 0x2000, 0x5d7: 0x2000,
+       0x5d8: 0x2000, 0x5d9: 0x2000,
+       0x5f8: 0x2000, 0x5f9: 0x2000,
+       // Block 0x18, offset 0x600
+       0x612: 0x2000, 0x614: 0x2000,
+       0x627: 0x2000,
+       // Block 0x19, offset 0x640
+       0x640: 0x2000, 0x642: 0x2000, 0x643: 0x2000,
+       0x647: 0x2000, 0x648: 0x2000, 0x64b: 0x2000,
+       0x64f: 0x2000, 0x651: 0x2000,
+       0x655: 0x2000,
+       0x65a: 0x2000, 0x65d: 0x2000,
+       0x65e: 0x2000, 0x65f: 0x2000, 0x660: 0x2000, 0x663: 0x2000,
+       0x665: 0x2000, 0x667: 0x2000, 0x668: 0x2000, 0x669: 0x2000,
+       0x66a: 0x2000, 0x66b: 0x2000, 0x66c: 0x2000, 0x66e: 0x2000,
+       0x674: 0x2000, 0x675: 0x2000,
+       0x676: 0x2000, 0x677: 0x2000,
+       0x67c: 0x2000, 0x67d: 0x2000,
+       // Block 0x1a, offset 0x680
+       0x688: 0x2000,
+       0x68c: 0x2000,
+       0x692: 0x2000,
+       0x6a0: 0x2000, 0x6a1: 0x2000,
+       0x6a4: 0x2000, 0x6a5: 0x2000, 0x6a6: 0x2000, 0x6a7: 0x2000,
+       0x6aa: 0x2000, 0x6ab: 0x2000, 0x6ae: 0x2000, 0x6af: 0x2000,
+       // Block 0x1b, offset 0x6c0
+       0x6c2: 0x2000, 0x6c3: 0x2000,
+       0x6c6: 0x2000, 0x6c7: 0x2000,
+       0x6d5: 0x2000,
+       0x6d9: 0x2000,
+       0x6e5: 0x2000,
+       0x6ff: 0x2000,
+       // Block 0x1c, offset 0x700
+       0x712: 0x2000,
+       0x71a: 0x4000, 0x71b: 0x4000,
+       0x729: 0x4000,
+       0x72a: 0x4000,
+       // Block 0x1d, offset 0x740
+       0x769: 0x4000,
+       0x76a: 0x4000, 0x76b: 0x4000, 0x76c: 0x4000,
+       0x770: 0x4000, 0x773: 0x4000,
+       // Block 0x1e, offset 0x780
+       0x7a0: 0x2000, 0x7a1: 0x2000, 0x7a2: 0x2000, 0x7a3: 0x2000,
+       0x7a4: 0x2000, 0x7a5: 0x2000, 0x7a6: 0x2000, 0x7a7: 0x2000, 0x7a8: 0x2000, 0x7a9: 0x2000,
+       0x7aa: 0x2000, 0x7ab: 0x2000, 0x7ac: 0x2000, 0x7ad: 0x2000, 0x7ae: 0x2000, 0x7af: 0x2000,
+       0x7b0: 0x2000, 0x7b1: 0x2000, 0x7b2: 0x2000, 0x7b3: 0x2000, 0x7b4: 0x2000, 0x7b5: 0x2000,
+       0x7b6: 0x2000, 0x7b7: 0x2000, 0x7b8: 0x2000, 0x7b9: 0x2000, 0x7ba: 0x2000, 0x7bb: 0x2000,
+       0x7bc: 0x2000, 0x7bd: 0x2000, 0x7be: 0x2000, 0x7bf: 0x2000,
+       // Block 0x1f, offset 0x7c0
+       0x7c0: 0x2000, 0x7c1: 0x2000, 0x7c2: 0x2000, 0x7c3: 0x2000, 0x7c4: 0x2000, 0x7c5: 0x2000,
+       0x7c6: 0x2000, 0x7c7: 0x2000, 0x7c8: 0x2000, 0x7c9: 0x2000, 0x7ca: 0x2000, 0x7cb: 0x2000,
+       0x7cc: 0x2000, 0x7cd: 0x2000, 0x7ce: 0x2000, 0x7cf: 0x2000, 0x7d0: 0x2000, 0x7d1: 0x2000,
+       0x7d2: 0x2000, 0x7d3: 0x2000, 0x7d4: 0x2000, 0x7d5: 0x2000, 0x7d6: 0x2000, 0x7d7: 0x2000,
+       0x7d8: 0x2000, 0x7d9: 0x2000, 0x7da: 0x2000, 0x7db: 0x2000, 0x7dc: 0x2000, 0x7dd: 0x2000,
+       0x7de: 0x2000, 0x7df: 0x2000, 0x7e0: 0x2000, 0x7e1: 0x2000, 0x7e2: 0x2000, 0x7e3: 0x2000,
+       0x7e4: 0x2000, 0x7e5: 0x2000, 0x7e6: 0x2000, 0x7e7: 0x2000, 0x7e8: 0x2000, 0x7e9: 0x2000,
+       0x7eb: 0x2000, 0x7ec: 0x2000, 0x7ed: 0x2000, 0x7ee: 0x2000, 0x7ef: 0x2000,
+       0x7f0: 0x2000, 0x7f1: 0x2000, 0x7f2: 0x2000, 0x7f3: 0x2000, 0x7f4: 0x2000, 0x7f5: 0x2000,
+       0x7f6: 0x2000, 0x7f7: 0x2000, 0x7f8: 0x2000, 0x7f9: 0x2000, 0x7fa: 0x2000, 0x7fb: 0x2000,
+       0x7fc: 0x2000, 0x7fd: 0x2000, 0x7fe: 0x2000, 0x7ff: 0x2000,
+       // Block 0x20, offset 0x800
+       0x800: 0x2000, 0x801: 0x2000, 0x802: 0x200d, 0x803: 0x2000, 0x804: 0x2000, 0x805: 0x2000,
+       0x806: 0x2000, 0x807: 0x2000, 0x808: 0x2000, 0x809: 0x2000, 0x80a: 0x2000, 0x80b: 0x2000,
+       0x80c: 0x2000, 0x80d: 0x2000, 0x80e: 0x2000, 0x80f: 0x2000, 0x810: 0x2000, 0x811: 0x2000,
+       0x812: 0x2000, 0x813: 0x2000, 0x814: 0x2000, 0x815: 0x2000, 0x816: 0x2000, 0x817: 0x2000,
+       0x818: 0x2000, 0x819: 0x2000, 0x81a: 0x2000, 0x81b: 0x2000, 0x81c: 0x2000, 0x81d: 0x2000,
+       0x81e: 0x2000, 0x81f: 0x2000, 0x820: 0x2000, 0x821: 0x2000, 0x822: 0x2000, 0x823: 0x2000,
+       0x824: 0x2000, 0x825: 0x2000, 0x826: 0x2000, 0x827: 0x2000, 0x828: 0x2000, 0x829: 0x2000,
+       0x82a: 0x2000, 0x82b: 0x2000, 0x82c: 0x2000, 0x82d: 0x2000, 0x82e: 0x2000, 0x82f: 0x2000,
+       0x830: 0x2000, 0x831: 0x2000, 0x832: 0x2000, 0x833: 0x2000, 0x834: 0x2000, 0x835: 0x2000,
+       0x836: 0x2000, 0x837: 0x2000, 0x838: 0x2000, 0x839: 0x2000, 0x83a: 0x2000, 0x83b: 0x2000,
+       0x83c: 0x2000, 0x83d: 0x2000, 0x83e: 0x2000, 0x83f: 0x2000,
+       // Block 0x21, offset 0x840
+       0x840: 0x2000, 0x841: 0x2000, 0x842: 0x2000, 0x843: 0x2000, 0x844: 0x2000, 0x845: 0x2000,
+       0x846: 0x2000, 0x847: 0x2000, 0x848: 0x2000, 0x849: 0x2000, 0x84a: 0x2000, 0x84b: 0x2000,
+       0x850: 0x2000, 0x851: 0x2000,
+       0x852: 0x2000, 0x853: 0x2000, 0x854: 0x2000, 0x855: 0x2000, 0x856: 0x2000, 0x857: 0x2000,
+       0x858: 0x2000, 0x859: 0x2000, 0x85a: 0x2000, 0x85b: 0x2000, 0x85c: 0x2000, 0x85d: 0x2000,
+       0x85e: 0x2000, 0x85f: 0x2000, 0x860: 0x2000, 0x861: 0x2000, 0x862: 0x2000, 0x863: 0x2000,
+       0x864: 0x2000, 0x865: 0x2000, 0x866: 0x2000, 0x867: 0x2000, 0x868: 0x2000, 0x869: 0x2000,
+       0x86a: 0x2000, 0x86b: 0x2000, 0x86c: 0x2000, 0x86d: 0x2000, 0x86e: 0x2000, 0x86f: 0x2000,
+       0x870: 0x2000, 0x871: 0x2000, 0x872: 0x2000, 0x873: 0x2000,
+       // Block 0x22, offset 0x880
+       0x880: 0x2000, 0x881: 0x2000, 0x882: 0x2000, 0x883: 0x2000, 0x884: 0x2000, 0x885: 0x2000,
+       0x886: 0x2000, 0x887: 0x2000, 0x888: 0x2000, 0x889: 0x2000, 0x88a: 0x2000, 0x88b: 0x2000,
+       0x88c: 0x2000, 0x88d: 0x2000, 0x88e: 0x2000, 0x88f: 0x2000,
+       0x892: 0x2000, 0x893: 0x2000, 0x894: 0x2000, 0x895: 0x2000,
+       0x8a0: 0x200e, 0x8a1: 0x2000, 0x8a3: 0x2000,
+       0x8a4: 0x2000, 0x8a5: 0x2000, 0x8a6: 0x2000, 0x8a7: 0x2000, 0x8a8: 0x2000, 0x8a9: 0x2000,
+       0x8b2: 0x2000, 0x8b3: 0x2000,
+       0x8b6: 0x2000, 0x8b7: 0x2000,
+       0x8bc: 0x2000, 0x8bd: 0x2000,
+       // Block 0x23, offset 0x8c0
+       0x8c0: 0x2000, 0x8c1: 0x2000,
+       0x8c6: 0x2000, 0x8c7: 0x2000, 0x8c8: 0x2000, 0x8cb: 0x200f,
+       0x8ce: 0x2000, 0x8cf: 0x2000, 0x8d0: 0x2000, 0x8d1: 0x2000,
+       0x8e2: 0x2000, 0x8e3: 0x2000,
+       0x8e4: 0x2000, 0x8e5: 0x2000,
+       0x8ef: 0x2000,
+       0x8fd: 0x4000, 0x8fe: 0x4000,
+       // Block 0x24, offset 0x900
+       0x905: 0x2000,
+       0x906: 0x2000, 0x909: 0x2000,
+       0x90e: 0x2000, 0x90f: 0x2000,
+       0x914: 0x4000, 0x915: 0x4000,
+       0x91c: 0x2000,
+       0x91e: 0x2000,
+       // Block 0x25, offset 0x940
+       0x940: 0x2000, 0x942: 0x2000,
+       0x948: 0x4000, 0x949: 0x4000, 0x94a: 0x4000, 0x94b: 0x4000,
+       0x94c: 0x4000, 0x94d: 0x4000, 0x94e: 0x4000, 0x94f: 0x4000, 0x950: 0x4000, 0x951: 0x4000,
+       0x952: 0x4000, 0x953: 0x4000,
+       0x960: 0x2000, 0x961: 0x2000, 0x963: 0x2000,
+       0x964: 0x2000, 0x965: 0x2000, 0x967: 0x2000, 0x968: 0x2000, 0x969: 0x2000,
+       0x96a: 0x2000, 0x96c: 0x2000, 0x96d: 0x2000, 0x96f: 0x2000,
+       0x97f: 0x4000,
+       // Block 0x26, offset 0x980
+       0x993: 0x4000,
+       0x99e: 0x2000, 0x99f: 0x2000, 0x9a1: 0x4000,
+       0x9aa: 0x4000, 0x9ab: 0x4000,
+       0x9bd: 0x4000, 0x9be: 0x4000, 0x9bf: 0x2000,
+       // Block 0x27, offset 0x9c0
+       0x9c4: 0x4000, 0x9c5: 0x4000,
+       0x9c6: 0x2000, 0x9c7: 0x2000, 0x9c8: 0x2000, 0x9c9: 0x2000, 0x9ca: 0x2000, 0x9cb: 0x2000,
+       0x9cc: 0x2000, 0x9cd: 0x2000, 0x9ce: 0x4000, 0x9cf: 0x2000, 0x9d0: 0x2000, 0x9d1: 0x2000,
+       0x9d2: 0x2000, 0x9d3: 0x2000, 0x9d4: 0x4000, 0x9d5: 0x2000, 0x9d6: 0x2000, 0x9d7: 0x2000,
+       0x9d8: 0x2000, 0x9d9: 0x2000, 0x9da: 0x2000, 0x9db: 0x2000, 0x9dc: 0x2000, 0x9dd: 0x2000,
+       0x9de: 0x2000, 0x9df: 0x2000, 0x9e0: 0x2000, 0x9e1: 0x2000, 0x9e3: 0x2000,
+       0x9e8: 0x2000, 0x9e9: 0x2000,
+       0x9ea: 0x4000, 0x9eb: 0x2000, 0x9ec: 0x2000, 0x9ed: 0x2000, 0x9ee: 0x2000, 0x9ef: 0x2000,
+       0x9f0: 0x2000, 0x9f1: 0x2000, 0x9f2: 0x4000, 0x9f3: 0x4000, 0x9f4: 0x2000, 0x9f5: 0x4000,
+       0x9f6: 0x2000, 0x9f7: 0x2000, 0x9f8: 0x2000, 0x9f9: 0x2000, 0x9fa: 0x4000, 0x9fb: 0x2000,
+       0x9fc: 0x2000, 0x9fd: 0x4000, 0x9fe: 0x2000, 0x9ff: 0x2000,
+       // Block 0x28, offset 0xa00
+       0xa05: 0x4000,
+       0xa0a: 0x4000, 0xa0b: 0x4000,
+       0xa28: 0x4000,
+       0xa3d: 0x2000,
+       // Block 0x29, offset 0xa40
+       0xa4c: 0x4000, 0xa4e: 0x4000,
+       0xa53: 0x4000, 0xa54: 0x4000, 0xa55: 0x4000, 0xa57: 0x4000,
+       0xa76: 0x2000, 0xa77: 0x2000, 0xa78: 0x2000, 0xa79: 0x2000, 0xa7a: 0x2000, 0xa7b: 0x2000,
+       0xa7c: 0x2000, 0xa7d: 0x2000, 0xa7e: 0x2000, 0xa7f: 0x2000,
+       // Block 0x2a, offset 0xa80
+       0xa95: 0x4000, 0xa96: 0x4000, 0xa97: 0x4000,
+       0xab0: 0x4000,
+       0xabf: 0x4000,
+       // Block 0x2b, offset 0xac0
+       0xae6: 0x6000, 0xae7: 0x6000, 0xae8: 0x6000, 0xae9: 0x6000,
+       0xaea: 0x6000, 0xaeb: 0x6000, 0xaec: 0x6000, 0xaed: 0x6000,
+       // Block 0x2c, offset 0xb00
+       0xb05: 0x6010,
+       0xb06: 0x6011,
+       // Block 0x2d, offset 0xb40
+       0xb5b: 0x4000, 0xb5c: 0x4000,
+       // Block 0x2e, offset 0xb80
+       0xb90: 0x4000,
+       0xb95: 0x4000, 0xb96: 0x2000, 0xb97: 0x2000,
+       0xb98: 0x2000, 0xb99: 0x2000,
+       // Block 0x2f, offset 0xbc0
+       0xbc0: 0x4000, 0xbc1: 0x4000, 0xbc2: 0x4000, 0xbc3: 0x4000, 0xbc4: 0x4000, 0xbc5: 0x4000,
+       0xbc6: 0x4000, 0xbc7: 0x4000, 0xbc8: 0x4000, 0xbc9: 0x4000, 0xbca: 0x4000, 0xbcb: 0x4000,
+       0xbcc: 0x4000, 0xbcd: 0x4000, 0xbce: 0x4000, 0xbcf: 0x4000, 0xbd0: 0x4000, 0xbd1: 0x4000,
+       0xbd2: 0x4000, 0xbd3: 0x4000, 0xbd4: 0x4000, 0xbd5: 0x4000, 0xbd6: 0x4000, 0xbd7: 0x4000,
+       0xbd8: 0x4000, 0xbd9: 0x4000, 0xbdb: 0x4000, 0xbdc: 0x4000, 0xbdd: 0x4000,
+       0xbde: 0x4000, 0xbdf: 0x4000, 0xbe0: 0x4000, 0xbe1: 0x4000, 0xbe2: 0x4000, 0xbe3: 0x4000,
+       0xbe4: 0x4000, 0xbe5: 0x4000, 0xbe6: 0x4000, 0xbe7: 0x4000, 0xbe8: 0x4000, 0xbe9: 0x4000,
+       0xbea: 0x4000, 0xbeb: 0x4000, 0xbec: 0x4000, 0xbed: 0x4000, 0xbee: 0x4000, 0xbef: 0x4000,
+       0xbf0: 0x4000, 0xbf1: 0x4000, 0xbf2: 0x4000, 0xbf3: 0x4000, 0xbf4: 0x4000, 0xbf5: 0x4000,
+       0xbf6: 0x4000, 0xbf7: 0x4000, 0xbf8: 0x4000, 0xbf9: 0x4000, 0xbfa: 0x4000, 0xbfb: 0x4000,
+       0xbfc: 0x4000, 0xbfd: 0x4000, 0xbfe: 0x4000, 0xbff: 0x4000,
+       // Block 0x30, offset 0xc00
+       0xc00: 0x4000, 0xc01: 0x4000, 0xc02: 0x4000, 0xc03: 0x4000, 0xc04: 0x4000, 0xc05: 0x4000,
+       0xc06: 0x4000, 0xc07: 0x4000, 0xc08: 0x4000, 0xc09: 0x4000, 0xc0a: 0x4000, 0xc0b: 0x4000,
+       0xc0c: 0x4000, 0xc0d: 0x4000, 0xc0e: 0x4000, 0xc0f: 0x4000, 0xc10: 0x4000, 0xc11: 0x4000,
+       0xc12: 0x4000, 0xc13: 0x4000, 0xc14: 0x4000, 0xc15: 0x4000, 0xc16: 0x4000, 0xc17: 0x4000,
+       0xc18: 0x4000, 0xc19: 0x4000, 0xc1a: 0x4000, 0xc1b: 0x4000, 0xc1c: 0x4000, 0xc1d: 0x4000,
+       0xc1e: 0x4000, 0xc1f: 0x4000, 0xc20: 0x4000, 0xc21: 0x4000, 0xc22: 0x4000, 0xc23: 0x4000,
+       0xc24: 0x4000, 0xc25: 0x4000, 0xc26: 0x4000, 0xc27: 0x4000, 0xc28: 0x4000, 0xc29: 0x4000,
+       0xc2a: 0x4000, 0xc2b: 0x4000, 0xc2c: 0x4000, 0xc2d: 0x4000, 0xc2e: 0x4000, 0xc2f: 0x4000,
+       0xc30: 0x4000, 0xc31: 0x4000, 0xc32: 0x4000, 0xc33: 0x4000,
+       // Block 0x31, offset 0xc40
+       0xc40: 0x4000, 0xc41: 0x4000, 0xc42: 0x4000, 0xc43: 0x4000, 0xc44: 0x4000, 0xc45: 0x4000,
+       0xc46: 0x4000, 0xc47: 0x4000, 0xc48: 0x4000, 0xc49: 0x4000, 0xc4a: 0x4000, 0xc4b: 0x4000,
+       0xc4c: 0x4000, 0xc4d: 0x4000, 0xc4e: 0x4000, 0xc4f: 0x4000, 0xc50: 0x4000, 0xc51: 0x4000,
+       0xc52: 0x4000, 0xc53: 0x4000, 0xc54: 0x4000, 0xc55: 0x4000,
+       0xc70: 0x4000, 0xc71: 0x4000, 0xc72: 0x4000, 0xc73: 0x4000, 0xc74: 0x4000, 0xc75: 0x4000,
+       0xc76: 0x4000, 0xc77: 0x4000, 0xc78: 0x4000, 0xc79: 0x4000, 0xc7a: 0x4000, 0xc7b: 0x4000,
+       // Block 0x32, offset 0xc80
+       0xc80: 0x9012, 0xc81: 0x4013, 0xc82: 0x4014, 0xc83: 0x4000, 0xc84: 0x4000, 0xc85: 0x4000,
+       0xc86: 0x4000, 0xc87: 0x4000, 0xc88: 0x4000, 0xc89: 0x4000, 0xc8a: 0x4000, 0xc8b: 0x4000,
+       0xc8c: 0x4015, 0xc8d: 0x4015, 0xc8e: 0x4000, 0xc8f: 0x4000, 0xc90: 0x4000, 0xc91: 0x4000,
+       0xc92: 0x4000, 0xc93: 0x4000, 0xc94: 0x4000, 0xc95: 0x4000, 0xc96: 0x4000, 0xc97: 0x4000,
+       0xc98: 0x4000, 0xc99: 0x4000, 0xc9a: 0x4000, 0xc9b: 0x4000, 0xc9c: 0x4000, 0xc9d: 0x4000,
+       0xc9e: 0x4000, 0xc9f: 0x4000, 0xca0: 0x4000, 0xca1: 0x4000, 0xca2: 0x4000, 0xca3: 0x4000,
+       0xca4: 0x4000, 0xca5: 0x4000, 0xca6: 0x4000, 0xca7: 0x4000, 0xca8: 0x4000, 0xca9: 0x4000,
+       0xcaa: 0x4000, 0xcab: 0x4000, 0xcac: 0x4000, 0xcad: 0x4000, 0xcae: 0x4000, 0xcaf: 0x4000,
+       0xcb0: 0x4000, 0xcb1: 0x4000, 0xcb2: 0x4000, 0xcb3: 0x4000, 0xcb4: 0x4000, 0xcb5: 0x4000,
+       0xcb6: 0x4000, 0xcb7: 0x4000, 0xcb8: 0x4000, 0xcb9: 0x4000, 0xcba: 0x4000, 0xcbb: 0x4000,
+       0xcbc: 0x4000, 0xcbd: 0x4000, 0xcbe: 0x4000,
+       // Block 0x33, offset 0xcc0
+       0xcc1: 0x4000, 0xcc2: 0x4000, 0xcc3: 0x4000, 0xcc4: 0x4000, 0xcc5: 0x4000,
+       0xcc6: 0x4000, 0xcc7: 0x4000, 0xcc8: 0x4000, 0xcc9: 0x4000, 0xcca: 0x4000, 0xccb: 0x4000,
+       0xccc: 0x4000, 0xccd: 0x4000, 0xcce: 0x4000, 0xccf: 0x4000, 0xcd0: 0x4000, 0xcd1: 0x4000,
+       0xcd2: 0x4000, 0xcd3: 0x4000, 0xcd4: 0x4000, 0xcd5: 0x4000, 0xcd6: 0x4000, 0xcd7: 0x4000,
+       0xcd8: 0x4000, 0xcd9: 0x4000, 0xcda: 0x4000, 0xcdb: 0x4000, 0xcdc: 0x4000, 0xcdd: 0x4000,
+       0xcde: 0x4000, 0xcdf: 0x4000, 0xce0: 0x4000, 0xce1: 0x4000, 0xce2: 0x4000, 0xce3: 0x4000,
+       0xce4: 0x4000, 0xce5: 0x4000, 0xce6: 0x4000, 0xce7: 0x4000, 0xce8: 0x4000, 0xce9: 0x4000,
+       0xcea: 0x4000, 0xceb: 0x4000, 0xcec: 0x4000, 0xced: 0x4000, 0xcee: 0x4000, 0xcef: 0x4000,
+       0xcf0: 0x4000, 0xcf1: 0x4000, 0xcf2: 0x4000, 0xcf3: 0x4000, 0xcf4: 0x4000, 0xcf5: 0x4000,
+       0xcf6: 0x4000, 0xcf7: 0x4000, 0xcf8: 0x4000, 0xcf9: 0x4000, 0xcfa: 0x4000, 0xcfb: 0x4000,
+       0xcfc: 0x4000, 0xcfd: 0x4000, 0xcfe: 0x4000, 0xcff: 0x4000,
+       // Block 0x34, offset 0xd00
+       0xd00: 0x4000, 0xd01: 0x4000, 0xd02: 0x4000, 0xd03: 0x4000, 0xd04: 0x4000, 0xd05: 0x4000,
+       0xd06: 0x4000, 0xd07: 0x4000, 0xd08: 0x4000, 0xd09: 0x4000, 0xd0a: 0x4000, 0xd0b: 0x4000,
+       0xd0c: 0x4000, 0xd0d: 0x4000, 0xd0e: 0x4000, 0xd0f: 0x4000, 0xd10: 0x4000, 0xd11: 0x4000,
+       0xd12: 0x4000, 0xd13: 0x4000, 0xd14: 0x4000, 0xd15: 0x4000, 0xd16: 0x4000,
+       0xd19: 0x4016, 0xd1a: 0x4017, 0xd1b: 0x4000, 0xd1c: 0x4000, 0xd1d: 0x4000,
+       0xd1e: 0x4000, 0xd1f: 0x4000, 0xd20: 0x4000, 0xd21: 0x4018, 0xd22: 0x4019, 0xd23: 0x401a,
+       0xd24: 0x401b, 0xd25: 0x401c, 0xd26: 0x401d, 0xd27: 0x401e, 0xd28: 0x401f, 0xd29: 0x4020,
+       0xd2a: 0x4021, 0xd2b: 0x4022, 0xd2c: 0x4000, 0xd2d: 0x4010, 0xd2e: 0x4000, 0xd2f: 0x4023,
+       0xd30: 0x4000, 0xd31: 0x4024, 0xd32: 0x4000, 0xd33: 0x4025, 0xd34: 0x4000, 0xd35: 0x4026,
+       0xd36: 0x4000, 0xd37: 0x401a, 0xd38: 0x4000, 0xd39: 0x4027, 0xd3a: 0x4000, 0xd3b: 0x4028,
+       0xd3c: 0x4000, 0xd3d: 0x4020, 0xd3e: 0x4000, 0xd3f: 0x4029,
+       // Block 0x35, offset 0xd40
+       0xd40: 0x4000, 0xd41: 0x402a, 0xd42: 0x4000, 0xd43: 0x402b, 0xd44: 0x402c, 0xd45: 0x4000,
+       0xd46: 0x4017, 0xd47: 0x4000, 0xd48: 0x402d, 0xd49: 0x4000, 0xd4a: 0x402e, 0xd4b: 0x402f,
+       0xd4c: 0x4030, 0xd4d: 0x4017, 0xd4e: 0x4016, 0xd4f: 0x4017, 0xd50: 0x4000, 0xd51: 0x4000,
+       0xd52: 0x4031, 0xd53: 0x4000, 0xd54: 0x4000, 0xd55: 0x4031, 0xd56: 0x4000, 0xd57: 0x4000,
+       0xd58: 0x4032, 0xd59: 0x4000, 0xd5a: 0x4000, 0xd5b: 0x4032, 0xd5c: 0x4000, 0xd5d: 0x4000,
+       0xd5e: 0x4033, 0xd5f: 0x402e, 0xd60: 0x4034, 0xd61: 0x4035, 0xd62: 0x4034, 0xd63: 0x4036,
+       0xd64: 0x4037, 0xd65: 0x4024, 0xd66: 0x4035, 0xd67: 0x4025, 0xd68: 0x4038, 0xd69: 0x4038,
+       0xd6a: 0x4039, 0xd6b: 0x4039, 0xd6c: 0x403a, 0xd6d: 0x403a, 0xd6e: 0x4000, 0xd6f: 0x4035,
+       0xd70: 0x4000, 0xd71: 0x4000, 0xd72: 0x403b, 0xd73: 0x403c, 0xd74: 0x4000, 0xd75: 0x4000,
+       0xd76: 0x4000, 0xd77: 0x4000, 0xd78: 0x4000, 0xd79: 0x4000, 0xd7a: 0x4000, 0xd7b: 0x403d,
+       0xd7c: 0x401c, 0xd7d: 0x4000, 0xd7e: 0x4000, 0xd7f: 0x4000,
+       // Block 0x36, offset 0xd80
+       0xd85: 0x4000,
+       0xd86: 0x4000, 0xd87: 0x4000, 0xd88: 0x4000, 0xd89: 0x4000, 0xd8a: 0x4000, 0xd8b: 0x4000,
+       0xd8c: 0x4000, 0xd8d: 0x4000, 0xd8e: 0x4000, 0xd8f: 0x4000, 0xd90: 0x4000, 0xd91: 0x4000,
+       0xd92: 0x4000, 0xd93: 0x4000, 0xd94: 0x4000, 0xd95: 0x4000, 0xd96: 0x4000, 0xd97: 0x4000,
+       0xd98: 0x4000, 0xd99: 0x4000, 0xd9a: 0x4000, 0xd9b: 0x4000, 0xd9c: 0x4000, 0xd9d: 0x4000,
+       0xd9e: 0x4000, 0xd9f: 0x4000, 0xda0: 0x4000, 0xda1: 0x4000, 0xda2: 0x4000, 0xda3: 0x4000,
+       0xda4: 0x4000, 0xda5: 0x4000, 0xda6: 0x4000, 0xda7: 0x4000, 0xda8: 0x4000, 0xda9: 0x4000,
+       0xdaa: 0x4000, 0xdab: 0x4000, 0xdac: 0x4000, 0xdad: 0x4000, 0xdae: 0x4000, 0xdaf: 0x4000,
+       0xdb1: 0x403e, 0xdb2: 0x403e, 0xdb3: 0x403e, 0xdb4: 0x403e, 0xdb5: 0x403e,
+       0xdb6: 0x403e, 0xdb7: 0x403e, 0xdb8: 0x403e, 0xdb9: 0x403e, 0xdba: 0x403e, 0xdbb: 0x403e,
+       0xdbc: 0x403e, 0xdbd: 0x403e, 0xdbe: 0x403e, 0xdbf: 0x403e,
+       // Block 0x37, offset 0xdc0
+       0xdc0: 0x4037, 0xdc1: 0x4037, 0xdc2: 0x4037, 0xdc3: 0x4037, 0xdc4: 0x4037, 0xdc5: 0x4037,
+       0xdc6: 0x4037, 0xdc7: 0x4037, 0xdc8: 0x4037, 0xdc9: 0x4037, 0xdca: 0x4037, 0xdcb: 0x4037,
+       0xdcc: 0x4037, 0xdcd: 0x4037, 0xdce: 0x4037, 0xdcf: 0x400e, 0xdd0: 0x403f, 0xdd1: 0x4040,
+       0xdd2: 0x4041, 0xdd3: 0x4040, 0xdd4: 0x403f, 0xdd5: 0x4042, 0xdd6: 0x4043, 0xdd7: 0x4044,
+       0xdd8: 0x4040, 0xdd9: 0x4041, 0xdda: 0x4040, 0xddb: 0x4045, 0xddc: 0x4009, 0xddd: 0x4045,
+       0xdde: 0x4046, 0xddf: 0x4045, 0xde0: 0x4047, 0xde1: 0x400b, 0xde2: 0x400a, 0xde3: 0x400c,
+       0xde4: 0x4048, 0xde5: 0x4000, 0xde6: 0x4000, 0xde7: 0x4000, 0xde8: 0x4000, 0xde9: 0x4000,
+       0xdea: 0x4000, 0xdeb: 0x4000, 0xdec: 0x4000, 0xded: 0x4000, 0xdee: 0x4000, 0xdef: 0x4000,
+       0xdf0: 0x4000, 0xdf1: 0x4000, 0xdf2: 0x4000, 0xdf3: 0x4000, 0xdf4: 0x4000, 0xdf5: 0x4000,
+       0xdf6: 0x4000, 0xdf7: 0x4000, 0xdf8: 0x4000, 0xdf9: 0x4000, 0xdfa: 0x4000, 0xdfb: 0x4000,
+       0xdfc: 0x4000, 0xdfd: 0x4000, 0xdfe: 0x4000, 0xdff: 0x4000,
+       // Block 0x38, offset 0xe00
+       0xe00: 0x4000, 0xe01: 0x4000, 0xe02: 0x4000, 0xe03: 0x4000, 0xe04: 0x4000, 0xe05: 0x4000,
+       0xe06: 0x4000, 0xe07: 0x4000, 0xe08: 0x4000, 0xe09: 0x4000, 0xe0a: 0x4000, 0xe0b: 0x4000,
+       0xe0c: 0x4000, 0xe0d: 0x4000, 0xe0e: 0x4000, 0xe10: 0x4000, 0xe11: 0x4000,
+       0xe12: 0x4000, 0xe13: 0x4000, 0xe14: 0x4000, 0xe15: 0x4000, 0xe16: 0x4000, 0xe17: 0x4000,
+       0xe18: 0x4000, 0xe19: 0x4000, 0xe1a: 0x4000, 0xe1b: 0x4000, 0xe1c: 0x4000, 0xe1d: 0x4000,
+       0xe1e: 0x4000, 0xe1f: 0x4000, 0xe20: 0x4000, 0xe21: 0x4000, 0xe22: 0x4000, 0xe23: 0x4000,
+       0xe24: 0x4000, 0xe25: 0x4000, 0xe26: 0x4000, 0xe27: 0x4000, 0xe28: 0x4000, 0xe29: 0x4000,
+       0xe2a: 0x4000, 0xe2b: 0x4000, 0xe2c: 0x4000, 0xe2d: 0x4000, 0xe2e: 0x4000, 0xe2f: 0x4000,
+       0xe30: 0x4000, 0xe31: 0x4000, 0xe32: 0x4000, 0xe33: 0x4000, 0xe34: 0x4000, 0xe35: 0x4000,
+       0xe36: 0x4000, 0xe37: 0x4000, 0xe38: 0x4000, 0xe39: 0x4000, 0xe3a: 0x4000, 0xe3b: 0x4000,
+       0xe3c: 0x4000, 0xe3d: 0x4000, 0xe3e: 0x4000, 0xe3f: 0x4000,
+       // Block 0x39, offset 0xe40
+       0xe40: 0x4000, 0xe41: 0x4000, 0xe42: 0x4000, 0xe43: 0x4000, 0xe44: 0x4000, 0xe45: 0x4000,
+       0xe46: 0x4000, 0xe47: 0x4000, 0xe48: 0x4000, 0xe49: 0x4000, 0xe4a: 0x4000, 0xe4b: 0x4000,
+       0xe4c: 0x4000, 0xe4d: 0x4000, 0xe4e: 0x4000, 0xe4f: 0x4000, 0xe50: 0x4000, 0xe51: 0x4000,
+       0xe52: 0x4000, 0xe53: 0x4000, 0xe54: 0x4000, 0xe55: 0x4000, 0xe56: 0x4000, 0xe57: 0x4000,
+       0xe58: 0x4000, 0xe59: 0x4000, 0xe5a: 0x4000, 0xe5b: 0x4000, 0xe5c: 0x4000, 0xe5d: 0x4000,
+       0xe5e: 0x4000, 0xe5f: 0x4000, 0xe60: 0x4000, 0xe61: 0x4000, 0xe62: 0x4000, 0xe63: 0x4000,
+       0xe70: 0x4000, 0xe71: 0x4000, 0xe72: 0x4000, 0xe73: 0x4000, 0xe74: 0x4000, 0xe75: 0x4000,
+       0xe76: 0x4000, 0xe77: 0x4000, 0xe78: 0x4000, 0xe79: 0x4000, 0xe7a: 0x4000, 0xe7b: 0x4000,
+       0xe7c: 0x4000, 0xe7d: 0x4000, 0xe7e: 0x4000, 0xe7f: 0x4000,
+       // Block 0x3a, offset 0xe80
+       0xe80: 0x4000, 0xe81: 0x4000, 0xe82: 0x4000, 0xe83: 0x4000, 0xe84: 0x4000, 0xe85: 0x4000,
+       0xe86: 0x4000, 0xe87: 0x4000, 0xe88: 0x4000, 0xe89: 0x4000, 0xe8a: 0x4000, 0xe8b: 0x4000,
+       0xe8c: 0x4000, 0xe8d: 0x4000, 0xe8e: 0x4000, 0xe8f: 0x4000, 0xe90: 0x4000, 0xe91: 0x4000,
+       0xe92: 0x4000, 0xe93: 0x4000, 0xe94: 0x4000, 0xe95: 0x4000, 0xe96: 0x4000, 0xe97: 0x4000,
+       0xe98: 0x4000, 0xe99: 0x4000, 0xe9a: 0x4000, 0xe9b: 0x4000, 0xe9c: 0x4000, 0xe9d: 0x4000,
+       0xe9e: 0x4000, 0xea0: 0x4000, 0xea1: 0x4000, 0xea2: 0x4000, 0xea3: 0x4000,
+       0xea4: 0x4000, 0xea5: 0x4000, 0xea6: 0x4000, 0xea7: 0x4000, 0xea8: 0x4000, 0xea9: 0x4000,
+       0xeaa: 0x4000, 0xeab: 0x4000, 0xeac: 0x4000, 0xead: 0x4000, 0xeae: 0x4000, 0xeaf: 0x4000,
+       0xeb0: 0x4000, 0xeb1: 0x4000, 0xeb2: 0x4000, 0xeb3: 0x4000, 0xeb4: 0x4000, 0xeb5: 0x4000,
+       0xeb6: 0x4000, 0xeb7: 0x4000, 0xeb8: 0x4000, 0xeb9: 0x4000, 0xeba: 0x4000, 0xebb: 0x4000,
+       0xebc: 0x4000, 0xebd: 0x4000, 0xebe: 0x4000, 0xebf: 0x4000,
+       // Block 0x3b, offset 0xec0
+       0xec0: 0x4000, 0xec1: 0x4000, 0xec2: 0x4000, 0xec3: 0x4000, 0xec4: 0x4000, 0xec5: 0x4000,
+       0xec6: 0x4000, 0xec7: 0x4000, 0xec8: 0x2000, 0xec9: 0x2000, 0xeca: 0x2000, 0xecb: 0x2000,
+       0xecc: 0x2000, 0xecd: 0x2000, 0xece: 0x2000, 0xecf: 0x2000, 0xed0: 0x4000, 0xed1: 0x4000,
+       0xed2: 0x4000, 0xed3: 0x4000, 0xed4: 0x4000, 0xed5: 0x4000, 0xed6: 0x4000, 0xed7: 0x4000,
+       0xed8: 0x4000, 0xed9: 0x4000, 0xeda: 0x4000, 0xedb: 0x4000, 0xedc: 0x4000, 0xedd: 0x4000,
+       0xede: 0x4000, 0xedf: 0x4000, 0xee0: 0x4000, 0xee1: 0x4000, 0xee2: 0x4000, 0xee3: 0x4000,
+       0xee4: 0x4000, 0xee5: 0x4000, 0xee6: 0x4000, 0xee7: 0x4000, 0xee8: 0x4000, 0xee9: 0x4000,
+       0xeea: 0x4000, 0xeeb: 0x4000, 0xeec: 0x4000, 0xeed: 0x4000, 0xeee: 0x4000, 0xeef: 0x4000,
+       0xef0: 0x4000, 0xef1: 0x4000, 0xef2: 0x4000, 0xef3: 0x4000, 0xef4: 0x4000, 0xef5: 0x4000,
+       0xef6: 0x4000, 0xef7: 0x4000, 0xef8: 0x4000, 0xef9: 0x4000, 0xefa: 0x4000, 0xefb: 0x4000,
+       0xefc: 0x4000, 0xefd: 0x4000, 0xefe: 0x4000, 0xeff: 0x4000,
+       // Block 0x3c, offset 0xf00
+       0xf00: 0x4000, 0xf01: 0x4000, 0xf02: 0x4000, 0xf03: 0x4000, 0xf04: 0x4000, 0xf05: 0x4000,
+       0xf06: 0x4000, 0xf07: 0x4000, 0xf08: 0x4000, 0xf09: 0x4000, 0xf0a: 0x4000, 0xf0b: 0x4000,
+       0xf0c: 0x4000, 0xf10: 0x4000, 0xf11: 0x4000,
+       0xf12: 0x4000, 0xf13: 0x4000, 0xf14: 0x4000, 0xf15: 0x4000, 0xf16: 0x4000, 0xf17: 0x4000,
+       0xf18: 0x4000, 0xf19: 0x4000, 0xf1a: 0x4000, 0xf1b: 0x4000, 0xf1c: 0x4000, 0xf1d: 0x4000,
+       0xf1e: 0x4000, 0xf1f: 0x4000, 0xf20: 0x4000, 0xf21: 0x4000, 0xf22: 0x4000, 0xf23: 0x4000,
+       0xf24: 0x4000, 0xf25: 0x4000, 0xf26: 0x4000, 0xf27: 0x4000, 0xf28: 0x4000, 0xf29: 0x4000,
+       0xf2a: 0x4000, 0xf2b: 0x4000, 0xf2c: 0x4000, 0xf2d: 0x4000, 0xf2e: 0x4000, 0xf2f: 0x4000,
+       0xf30: 0x4000, 0xf31: 0x4000, 0xf32: 0x4000, 0xf33: 0x4000, 0xf34: 0x4000, 0xf35: 0x4000,
+       0xf36: 0x4000, 0xf37: 0x4000, 0xf38: 0x4000, 0xf39: 0x4000, 0xf3a: 0x4000, 0xf3b: 0x4000,
+       0xf3c: 0x4000, 0xf3d: 0x4000, 0xf3e: 0x4000, 0xf3f: 0x4000,
+       // Block 0x3d, offset 0xf40
+       0xf40: 0x4000, 0xf41: 0x4000, 0xf42: 0x4000, 0xf43: 0x4000, 0xf44: 0x4000, 0xf45: 0x4000,
+       0xf46: 0x4000,
+       // Block 0x3e, offset 0xf80
+       0xfa0: 0x4000, 0xfa1: 0x4000, 0xfa2: 0x4000, 0xfa3: 0x4000,
+       0xfa4: 0x4000, 0xfa5: 0x4000, 0xfa6: 0x4000, 0xfa7: 0x4000, 0xfa8: 0x4000, 0xfa9: 0x4000,
+       0xfaa: 0x4000, 0xfab: 0x4000, 0xfac: 0x4000, 0xfad: 0x4000, 0xfae: 0x4000, 0xfaf: 0x4000,
+       0xfb0: 0x4000, 0xfb1: 0x4000, 0xfb2: 0x4000, 0xfb3: 0x4000, 0xfb4: 0x4000, 0xfb5: 0x4000,
+       0xfb6: 0x4000, 0xfb7: 0x4000, 0xfb8: 0x4000, 0xfb9: 0x4000, 0xfba: 0x4000, 0xfbb: 0x4000,
+       0xfbc: 0x4000,
+       // Block 0x3f, offset 0xfc0
+       0xfc0: 0x4000, 0xfc1: 0x4000, 0xfc2: 0x4000, 0xfc3: 0x4000, 0xfc4: 0x4000, 0xfc5: 0x4000,
+       0xfc6: 0x4000, 0xfc7: 0x4000, 0xfc8: 0x4000, 0xfc9: 0x4000, 0xfca: 0x4000, 0xfcb: 0x4000,
+       0xfcc: 0x4000, 0xfcd: 0x4000, 0xfce: 0x4000, 0xfcf: 0x4000, 0xfd0: 0x4000, 0xfd1: 0x4000,
+       0xfd2: 0x4000, 0xfd3: 0x4000, 0xfd4: 0x4000, 0xfd5: 0x4000, 0xfd6: 0x4000, 0xfd7: 0x4000,
+       0xfd8: 0x4000, 0xfd9: 0x4000, 0xfda: 0x4000, 0xfdb: 0x4000, 0xfdc: 0x4000, 0xfdd: 0x4000,
+       0xfde: 0x4000, 0xfdf: 0x4000, 0xfe0: 0x4000, 0xfe1: 0x4000, 0xfe2: 0x4000, 0xfe3: 0x4000,
+       // Block 0x40, offset 0x1000
+       0x1000: 0x2000, 0x1001: 0x2000, 0x1002: 0x2000, 0x1003: 0x2000, 0x1004: 0x2000, 0x1005: 0x2000,
+       0x1006: 0x2000, 0x1007: 0x2000, 0x1008: 0x2000, 0x1009: 0x2000, 0x100a: 0x2000, 0x100b: 0x2000,
+       0x100c: 0x2000, 0x100d: 0x2000, 0x100e: 0x2000, 0x100f: 0x2000, 0x1010: 0x4000, 0x1011: 0x4000,
+       0x1012: 0x4000, 0x1013: 0x4000, 0x1014: 0x4000, 0x1015: 0x4000, 0x1016: 0x4000, 0x1017: 0x4000,
+       0x1018: 0x4000, 0x1019: 0x4000,
+       0x1030: 0x4000, 0x1031: 0x4000, 0x1032: 0x4000, 0x1033: 0x4000, 0x1034: 0x4000, 0x1035: 0x4000,
+       0x1036: 0x4000, 0x1037: 0x4000, 0x1038: 0x4000, 0x1039: 0x4000, 0x103a: 0x4000, 0x103b: 0x4000,
+       0x103c: 0x4000, 0x103d: 0x4000, 0x103e: 0x4000, 0x103f: 0x4000,
+       // Block 0x41, offset 0x1040
+       0x1040: 0x4000, 0x1041: 0x4000, 0x1042: 0x4000, 0x1043: 0x4000, 0x1044: 0x4000, 0x1045: 0x4000,
+       0x1046: 0x4000, 0x1047: 0x4000, 0x1048: 0x4000, 0x1049: 0x4000, 0x104a: 0x4000, 0x104b: 0x4000,
+       0x104c: 0x4000, 0x104d: 0x4000, 0x104e: 0x4000, 0x104f: 0x4000, 0x1050: 0x4000, 0x1051: 0x4000,
+       0x1052: 0x4000, 0x1054: 0x4000, 0x1055: 0x4000, 0x1056: 0x4000, 0x1057: 0x4000,
+       0x1058: 0x4000, 0x1059: 0x4000, 0x105a: 0x4000, 0x105b: 0x4000, 0x105c: 0x4000, 0x105d: 0x4000,
+       0x105e: 0x4000, 0x105f: 0x4000, 0x1060: 0x4000, 0x1061: 0x4000, 0x1062: 0x4000, 0x1063: 0x4000,
+       0x1064: 0x4000, 0x1065: 0x4000, 0x1066: 0x4000, 0x1068: 0x4000, 0x1069: 0x4000,
+       0x106a: 0x4000, 0x106b: 0x4000,
+       // Block 0x42, offset 0x1080
+       0x1081: 0x9012, 0x1082: 0x9012, 0x1083: 0x9012, 0x1084: 0x9012, 0x1085: 0x9012,
+       0x1086: 0x9012, 0x1087: 0x9012, 0x1088: 0x9012, 0x1089: 0x9012, 0x108a: 0x9012, 0x108b: 0x9012,
+       0x108c: 0x9012, 0x108d: 0x9012, 0x108e: 0x9012, 0x108f: 0x9012, 0x1090: 0x9012, 0x1091: 0x9012,
+       0x1092: 0x9012, 0x1093: 0x9012, 0x1094: 0x9012, 0x1095: 0x9012, 0x1096: 0x9012, 0x1097: 0x9012,
+       0x1098: 0x9012, 0x1099: 0x9012, 0x109a: 0x9012, 0x109b: 0x9012, 0x109c: 0x9012, 0x109d: 0x9012,
+       0x109e: 0x9012, 0x109f: 0x9012, 0x10a0: 0x9049, 0x10a1: 0x9049, 0x10a2: 0x9049, 0x10a3: 0x9049,
+       0x10a4: 0x9049, 0x10a5: 0x9049, 0x10a6: 0x9049, 0x10a7: 0x9049, 0x10a8: 0x9049, 0x10a9: 0x9049,
+       0x10aa: 0x9049, 0x10ab: 0x9049, 0x10ac: 0x9049, 0x10ad: 0x9049, 0x10ae: 0x9049, 0x10af: 0x9049,
+       0x10b0: 0x9049, 0x10b1: 0x9049, 0x10b2: 0x9049, 0x10b3: 0x9049, 0x10b4: 0x9049, 0x10b5: 0x9049,
+       0x10b6: 0x9049, 0x10b7: 0x9049, 0x10b8: 0x9049, 0x10b9: 0x9049, 0x10ba: 0x9049, 0x10bb: 0x9049,
+       0x10bc: 0x9049, 0x10bd: 0x9049, 0x10be: 0x9049, 0x10bf: 0x9049,
+       // Block 0x43, offset 0x10c0
+       0x10c0: 0x9049, 0x10c1: 0x9049, 0x10c2: 0x9049, 0x10c3: 0x9049, 0x10c4: 0x9049, 0x10c5: 0x9049,
+       0x10c6: 0x9049, 0x10c7: 0x9049, 0x10c8: 0x9049, 0x10c9: 0x9049, 0x10ca: 0x9049, 0x10cb: 0x9049,
+       0x10cc: 0x9049, 0x10cd: 0x9049, 0x10ce: 0x9049, 0x10cf: 0x9049, 0x10d0: 0x9049, 0x10d1: 0x9049,
+       0x10d2: 0x9049, 0x10d3: 0x9049, 0x10d4: 0x9049, 0x10d5: 0x9049, 0x10d6: 0x9049, 0x10d7: 0x9049,
+       0x10d8: 0x9049, 0x10d9: 0x9049, 0x10da: 0x9049, 0x10db: 0x9049, 0x10dc: 0x9049, 0x10dd: 0x9049,
+       0x10de: 0x9049, 0x10df: 0x904a, 0x10e0: 0x904b, 0x10e1: 0xb04c, 0x10e2: 0xb04d, 0x10e3: 0xb04d,
+       0x10e4: 0xb04e, 0x10e5: 0xb04f, 0x10e6: 0xb050, 0x10e7: 0xb051, 0x10e8: 0xb052, 0x10e9: 0xb053,
+       0x10ea: 0xb054, 0x10eb: 0xb055, 0x10ec: 0xb056, 0x10ed: 0xb057, 0x10ee: 0xb058, 0x10ef: 0xb059,
+       0x10f0: 0xb05a, 0x10f1: 0xb05b, 0x10f2: 0xb05c, 0x10f3: 0xb05d, 0x10f4: 0xb05e, 0x10f5: 0xb05f,
+       0x10f6: 0xb060, 0x10f7: 0xb061, 0x10f8: 0xb062, 0x10f9: 0xb063, 0x10fa: 0xb064, 0x10fb: 0xb065,
+       0x10fc: 0xb052, 0x10fd: 0xb066, 0x10fe: 0xb067, 0x10ff: 0xb055,
+       // Block 0x44, offset 0x1100
+       0x1100: 0xb068, 0x1101: 0xb069, 0x1102: 0xb06a, 0x1103: 0xb06b, 0x1104: 0xb05a, 0x1105: 0xb056,
+       0x1106: 0xb06c, 0x1107: 0xb06d, 0x1108: 0xb06b, 0x1109: 0xb06e, 0x110a: 0xb06b, 0x110b: 0xb06f,
+       0x110c: 0xb06f, 0x110d: 0xb070, 0x110e: 0xb070, 0x110f: 0xb071, 0x1110: 0xb056, 0x1111: 0xb072,
+       0x1112: 0xb073, 0x1113: 0xb072, 0x1114: 0xb074, 0x1115: 0xb073, 0x1116: 0xb075, 0x1117: 0xb075,
+       0x1118: 0xb076, 0x1119: 0xb076, 0x111a: 0xb077, 0x111b: 0xb077, 0x111c: 0xb073, 0x111d: 0xb078,
+       0x111e: 0xb079, 0x111f: 0xb067, 0x1120: 0xb07a, 0x1121: 0xb07b, 0x1122: 0xb07b, 0x1123: 0xb07b,
+       0x1124: 0xb07b, 0x1125: 0xb07b, 0x1126: 0xb07b, 0x1127: 0xb07b, 0x1128: 0xb07b, 0x1129: 0xb07b,
+       0x112a: 0xb07b, 0x112b: 0xb07b, 0x112c: 0xb07b, 0x112d: 0xb07b, 0x112e: 0xb07b, 0x112f: 0xb07b,
+       0x1130: 0xb07c, 0x1131: 0xb07c, 0x1132: 0xb07c, 0x1133: 0xb07c, 0x1134: 0xb07c, 0x1135: 0xb07c,
+       0x1136: 0xb07c, 0x1137: 0xb07c, 0x1138: 0xb07c, 0x1139: 0xb07c, 0x113a: 0xb07c, 0x113b: 0xb07c,
+       0x113c: 0xb07c, 0x113d: 0xb07c, 0x113e: 0xb07c,
+       // Block 0x45, offset 0x1140
+       0x1142: 0xb07d, 0x1143: 0xb07e, 0x1144: 0xb07f, 0x1145: 0xb080,
+       0x1146: 0xb07f, 0x1147: 0xb07e, 0x114a: 0xb081, 0x114b: 0xb082,
+       0x114c: 0xb083, 0x114d: 0xb07f, 0x114e: 0xb080, 0x114f: 0xb07f,
+       0x1152: 0xb084, 0x1153: 0xb085, 0x1154: 0xb084, 0x1155: 0xb086, 0x1156: 0xb084, 0x1157: 0xb087,
+       0x115a: 0xb088, 0x115b: 0xb089, 0x115c: 0xb08a,
+       0x1160: 0x908b, 0x1161: 0x908b, 0x1162: 0x908c, 0x1163: 0x908d,
+       0x1164: 0x908b, 0x1165: 0x908e, 0x1166: 0x908f, 0x1168: 0xb090, 0x1169: 0xb091,
+       0x116a: 0xb092, 0x116b: 0xb091, 0x116c: 0xb093, 0x116d: 0xb094, 0x116e: 0xb095,
+       0x117d: 0x2000,
+       // Block 0x46, offset 0x1180
+       0x11a0: 0x4000, 0x11a1: 0x4000, 0x11a2: 0x4000, 0x11a3: 0x4000,
+       0x11a4: 0x4000,
+       0x11b0: 0x4000, 0x11b1: 0x4000,
+       // Block 0x47, offset 0x11c0
+       0x11c0: 0x4000, 0x11c1: 0x4000, 0x11c2: 0x4000, 0x11c3: 0x4000, 0x11c4: 0x4000, 0x11c5: 0x4000,
+       0x11c6: 0x4000, 0x11c7: 0x4000, 0x11c8: 0x4000, 0x11c9: 0x4000, 0x11ca: 0x4000, 0x11cb: 0x4000,
+       0x11cc: 0x4000, 0x11cd: 0x4000, 0x11ce: 0x4000, 0x11cf: 0x4000, 0x11d0: 0x4000, 0x11d1: 0x4000,
+       0x11d2: 0x4000, 0x11d3: 0x4000, 0x11d4: 0x4000, 0x11d5: 0x4000, 0x11d6: 0x4000, 0x11d7: 0x4000,
+       0x11d8: 0x4000, 0x11d9: 0x4000, 0x11da: 0x4000, 0x11db: 0x4000, 0x11dc: 0x4000, 0x11dd: 0x4000,
+       0x11de: 0x4000, 0x11df: 0x4000, 0x11e0: 0x4000, 0x11e1: 0x4000, 0x11e2: 0x4000, 0x11e3: 0x4000,
+       0x11e4: 0x4000, 0x11e5: 0x4000, 0x11e6: 0x4000, 0x11e7: 0x4000, 0x11e8: 0x4000, 0x11e9: 0x4000,
+       0x11ea: 0x4000, 0x11eb: 0x4000, 0x11ec: 0x4000, 0x11ed: 0x4000, 0x11ee: 0x4000, 0x11ef: 0x4000,
+       0x11f0: 0x4000, 0x11f1: 0x4000, 0x11f2: 0x4000, 0x11f3: 0x4000, 0x11f4: 0x4000, 0x11f5: 0x4000,
+       0x11f6: 0x4000, 0x11f7: 0x4000,
+       // Block 0x48, offset 0x1200
+       0x1200: 0x4000, 0x1201: 0x4000, 0x1202: 0x4000, 0x1203: 0x4000, 0x1204: 0x4000, 0x1205: 0x4000,
+       0x1206: 0x4000, 0x1207: 0x4000, 0x1208: 0x4000, 0x1209: 0x4000, 0x120a: 0x4000, 0x120b: 0x4000,
+       0x120c: 0x4000, 0x120d: 0x4000, 0x120e: 0x4000, 0x120f: 0x4000, 0x1210: 0x4000, 0x1211: 0x4000,
+       0x1212: 0x4000, 0x1213: 0x4000, 0x1214: 0x4000, 0x1215: 0x4000,
+       // Block 0x49, offset 0x1240
+       0x1240: 0x4000, 0x1241: 0x4000, 0x1242: 0x4000, 0x1243: 0x4000, 0x1244: 0x4000, 0x1245: 0x4000,
+       0x1246: 0x4000, 0x1247: 0x4000, 0x1248: 0x4000,
+       // Block 0x4a, offset 0x1280
+       0x1280: 0x4000, 0x1281: 0x4000, 0x1282: 0x4000, 0x1283: 0x4000, 0x1284: 0x4000, 0x1285: 0x4000,
+       0x1286: 0x4000, 0x1287: 0x4000, 0x1288: 0x4000, 0x1289: 0x4000, 0x128a: 0x4000, 0x128b: 0x4000,
+       0x128c: 0x4000, 0x128d: 0x4000, 0x128e: 0x4000, 0x128f: 0x4000, 0x1290: 0x4000, 0x1291: 0x4000,
+       0x1292: 0x4000, 0x1293: 0x4000, 0x1294: 0x4000, 0x1295: 0x4000, 0x1296: 0x4000, 0x1297: 0x4000,
+       0x1298: 0x4000, 0x1299: 0x4000, 0x129a: 0x4000, 0x129b: 0x4000, 0x129c: 0x4000, 0x129d: 0x4000,
+       0x129e: 0x4000,
+       // Block 0x4b, offset 0x12c0
+       0x12d0: 0x4000, 0x12d1: 0x4000,
+       0x12d2: 0x4000,
+       0x12e4: 0x4000, 0x12e5: 0x4000, 0x12e6: 0x4000, 0x12e7: 0x4000,
+       0x12f0: 0x4000, 0x12f1: 0x4000, 0x12f2: 0x4000, 0x12f3: 0x4000, 0x12f4: 0x4000, 0x12f5: 0x4000,
+       0x12f6: 0x4000, 0x12f7: 0x4000, 0x12f8: 0x4000, 0x12f9: 0x4000, 0x12fa: 0x4000, 0x12fb: 0x4000,
+       0x12fc: 0x4000, 0x12fd: 0x4000, 0x12fe: 0x4000, 0x12ff: 0x4000,
+       // Block 0x4c, offset 0x1300
+       0x1300: 0x4000, 0x1301: 0x4000, 0x1302: 0x4000, 0x1303: 0x4000, 0x1304: 0x4000, 0x1305: 0x4000,
+       0x1306: 0x4000, 0x1307: 0x4000, 0x1308: 0x4000, 0x1309: 0x4000, 0x130a: 0x4000, 0x130b: 0x4000,
+       0x130c: 0x4000, 0x130d: 0x4000, 0x130e: 0x4000, 0x130f: 0x4000, 0x1310: 0x4000, 0x1311: 0x4000,
+       0x1312: 0x4000, 0x1313: 0x4000, 0x1314: 0x4000, 0x1315: 0x4000, 0x1316: 0x4000, 0x1317: 0x4000,
+       0x1318: 0x4000, 0x1319: 0x4000, 0x131a: 0x4000, 0x131b: 0x4000, 0x131c: 0x4000, 0x131d: 0x4000,
+       0x131e: 0x4000, 0x131f: 0x4000, 0x1320: 0x4000, 0x1321: 0x4000, 0x1322: 0x4000, 0x1323: 0x4000,
+       0x1324: 0x4000, 0x1325: 0x4000, 0x1326: 0x4000, 0x1327: 0x4000, 0x1328: 0x4000, 0x1329: 0x4000,
+       0x132a: 0x4000, 0x132b: 0x4000, 0x132c: 0x4000, 0x132d: 0x4000, 0x132e: 0x4000, 0x132f: 0x4000,
+       0x1330: 0x4000, 0x1331: 0x4000, 0x1332: 0x4000, 0x1333: 0x4000, 0x1334: 0x4000, 0x1335: 0x4000,
+       0x1336: 0x4000, 0x1337: 0x4000, 0x1338: 0x4000, 0x1339: 0x4000, 0x133a: 0x4000, 0x133b: 0x4000,
+       // Block 0x4d, offset 0x1340
+       0x1344: 0x4000,
+       // Block 0x4e, offset 0x1380
+       0x138f: 0x4000,
+       // Block 0x4f, offset 0x13c0
+       0x13c0: 0x2000, 0x13c1: 0x2000, 0x13c2: 0x2000, 0x13c3: 0x2000, 0x13c4: 0x2000, 0x13c5: 0x2000,
+       0x13c6: 0x2000, 0x13c7: 0x2000, 0x13c8: 0x2000, 0x13c9: 0x2000, 0x13ca: 0x2000,
+       0x13d0: 0x2000, 0x13d1: 0x2000,
+       0x13d2: 0x2000, 0x13d3: 0x2000, 0x13d4: 0x2000, 0x13d5: 0x2000, 0x13d6: 0x2000, 0x13d7: 0x2000,
+       0x13d8: 0x2000, 0x13d9: 0x2000, 0x13da: 0x2000, 0x13db: 0x2000, 0x13dc: 0x2000, 0x13dd: 0x2000,
+       0x13de: 0x2000, 0x13df: 0x2000, 0x13e0: 0x2000, 0x13e1: 0x2000, 0x13e2: 0x2000, 0x13e3: 0x2000,
+       0x13e4: 0x2000, 0x13e5: 0x2000, 0x13e6: 0x2000, 0x13e7: 0x2000, 0x13e8: 0x2000, 0x13e9: 0x2000,
+       0x13ea: 0x2000, 0x13eb: 0x2000, 0x13ec: 0x2000, 0x13ed: 0x2000,
+       0x13f0: 0x2000, 0x13f1: 0x2000, 0x13f2: 0x2000, 0x13f3: 0x2000, 0x13f4: 0x2000, 0x13f5: 0x2000,
+       0x13f6: 0x2000, 0x13f7: 0x2000, 0x13f8: 0x2000, 0x13f9: 0x2000, 0x13fa: 0x2000, 0x13fb: 0x2000,
+       0x13fc: 0x2000, 0x13fd: 0x2000, 0x13fe: 0x2000, 0x13ff: 0x2000,
+       // Block 0x50, offset 0x1400
+       0x1400: 0x2000, 0x1401: 0x2000, 0x1402: 0x2000, 0x1403: 0x2000, 0x1404: 0x2000, 0x1405: 0x2000,
+       0x1406: 0x2000, 0x1407: 0x2000, 0x1408: 0x2000, 0x1409: 0x2000, 0x140a: 0x2000, 0x140b: 0x2000,
+       0x140c: 0x2000, 0x140d: 0x2000, 0x140e: 0x2000, 0x140f: 0x2000, 0x1410: 0x2000, 0x1411: 0x2000,
+       0x1412: 0x2000, 0x1413: 0x2000, 0x1414: 0x2000, 0x1415: 0x2000, 0x1416: 0x2000, 0x1417: 0x2000,
+       0x1418: 0x2000, 0x1419: 0x2000, 0x141a: 0x2000, 0x141b: 0x2000, 0x141c: 0x2000, 0x141d: 0x2000,
+       0x141e: 0x2000, 0x141f: 0x2000, 0x1420: 0x2000, 0x1421: 0x2000, 0x1422: 0x2000, 0x1423: 0x2000,
+       0x1424: 0x2000, 0x1425: 0x2000, 0x1426: 0x2000, 0x1427: 0x2000, 0x1428: 0x2000, 0x1429: 0x2000,
+       0x1430: 0x2000, 0x1431: 0x2000, 0x1432: 0x2000, 0x1433: 0x2000, 0x1434: 0x2000, 0x1435: 0x2000,
+       0x1436: 0x2000, 0x1437: 0x2000, 0x1438: 0x2000, 0x1439: 0x2000, 0x143a: 0x2000, 0x143b: 0x2000,
+       0x143c: 0x2000, 0x143d: 0x2000, 0x143e: 0x2000, 0x143f: 0x2000,
+       // Block 0x51, offset 0x1440
+       0x1440: 0x2000, 0x1441: 0x2000, 0x1442: 0x2000, 0x1443: 0x2000, 0x1444: 0x2000, 0x1445: 0x2000,
+       0x1446: 0x2000, 0x1447: 0x2000, 0x1448: 0x2000, 0x1449: 0x2000, 0x144a: 0x2000, 0x144b: 0x2000,
+       0x144c: 0x2000, 0x144d: 0x2000, 0x144e: 0x4000, 0x144f: 0x2000, 0x1450: 0x2000, 0x1451: 0x4000,
+       0x1452: 0x4000, 0x1453: 0x4000, 0x1454: 0x4000, 0x1455: 0x4000, 0x1456: 0x4000, 0x1457: 0x4000,
+       0x1458: 0x4000, 0x1459: 0x4000, 0x145a: 0x4000, 0x145b: 0x2000, 0x145c: 0x2000, 0x145d: 0x2000,
+       0x145e: 0x2000, 0x145f: 0x2000, 0x1460: 0x2000, 0x1461: 0x2000, 0x1462: 0x2000, 0x1463: 0x2000,
+       0x1464: 0x2000, 0x1465: 0x2000, 0x1466: 0x2000, 0x1467: 0x2000, 0x1468: 0x2000, 0x1469: 0x2000,
+       0x146a: 0x2000, 0x146b: 0x2000, 0x146c: 0x2000,
+       // Block 0x52, offset 0x1480
+       0x1480: 0x4000, 0x1481: 0x4000, 0x1482: 0x4000,
+       0x1490: 0x4000, 0x1491: 0x4000,
+       0x1492: 0x4000, 0x1493: 0x4000, 0x1494: 0x4000, 0x1495: 0x4000, 0x1496: 0x4000, 0x1497: 0x4000,
+       0x1498: 0x4000, 0x1499: 0x4000, 0x149a: 0x4000, 0x149b: 0x4000, 0x149c: 0x4000, 0x149d: 0x4000,
+       0x149e: 0x4000, 0x149f: 0x4000, 0x14a0: 0x4000, 0x14a1: 0x4000, 0x14a2: 0x4000, 0x14a3: 0x4000,
+       0x14a4: 0x4000, 0x14a5: 0x4000, 0x14a6: 0x4000, 0x14a7: 0x4000, 0x14a8: 0x4000, 0x14a9: 0x4000,
+       0x14aa: 0x4000, 0x14ab: 0x4000, 0x14ac: 0x4000, 0x14ad: 0x4000, 0x14ae: 0x4000, 0x14af: 0x4000,
+       0x14b0: 0x4000, 0x14b1: 0x4000, 0x14b2: 0x4000, 0x14b3: 0x4000, 0x14b4: 0x4000, 0x14b5: 0x4000,
+       0x14b6: 0x4000, 0x14b7: 0x4000, 0x14b8: 0x4000, 0x14b9: 0x4000, 0x14ba: 0x4000, 0x14bb: 0x4000,
+       // Block 0x53, offset 0x14c0
+       0x14c0: 0x4000, 0x14c1: 0x4000, 0x14c2: 0x4000, 0x14c3: 0x4000, 0x14c4: 0x4000, 0x14c5: 0x4000,
+       0x14c6: 0x4000, 0x14c7: 0x4000, 0x14c8: 0x4000,
+       0x14d0: 0x4000, 0x14d1: 0x4000,
+       0x14e0: 0x4000, 0x14e1: 0x4000, 0x14e2: 0x4000, 0x14e3: 0x4000,
+       0x14e4: 0x4000, 0x14e5: 0x4000,
+       // Block 0x54, offset 0x1500
+       0x1500: 0x4000, 0x1501: 0x4000, 0x1502: 0x4000, 0x1503: 0x4000, 0x1504: 0x4000, 0x1505: 0x4000,
+       0x1506: 0x4000, 0x1507: 0x4000, 0x1508: 0x4000, 0x1509: 0x4000, 0x150a: 0x4000, 0x150b: 0x4000,
+       0x150c: 0x4000, 0x150d: 0x4000, 0x150e: 0x4000, 0x150f: 0x4000, 0x1510: 0x4000, 0x1511: 0x4000,
+       0x1512: 0x4000, 0x1513: 0x4000, 0x1514: 0x4000, 0x1515: 0x4000, 0x1516: 0x4000, 0x1517: 0x4000,
+       0x1518: 0x4000, 0x1519: 0x4000, 0x151a: 0x4000, 0x151b: 0x4000, 0x151c: 0x4000, 0x151d: 0x4000,
+       0x151e: 0x4000, 0x151f: 0x4000, 0x1520: 0x4000,
+       0x152d: 0x4000, 0x152e: 0x4000, 0x152f: 0x4000,
+       0x1530: 0x4000, 0x1531: 0x4000, 0x1532: 0x4000, 0x1533: 0x4000, 0x1534: 0x4000, 0x1535: 0x4000,
+       0x1537: 0x4000, 0x1538: 0x4000, 0x1539: 0x4000, 0x153a: 0x4000, 0x153b: 0x4000,
+       0x153c: 0x4000, 0x153d: 0x4000, 0x153e: 0x4000, 0x153f: 0x4000,
+       // Block 0x55, offset 0x1540
+       0x1540: 0x4000, 0x1541: 0x4000, 0x1542: 0x4000, 0x1543: 0x4000, 0x1544: 0x4000, 0x1545: 0x4000,
+       0x1546: 0x4000, 0x1547: 0x4000, 0x1548: 0x4000, 0x1549: 0x4000, 0x154a: 0x4000, 0x154b: 0x4000,
+       0x154c: 0x4000, 0x154d: 0x4000, 0x154e: 0x4000, 0x154f: 0x4000, 0x1550: 0x4000, 0x1551: 0x4000,
+       0x1552: 0x4000, 0x1553: 0x4000, 0x1554: 0x4000, 0x1555: 0x4000, 0x1556: 0x4000, 0x1557: 0x4000,
+       0x1558: 0x4000, 0x1559: 0x4000, 0x155a: 0x4000, 0x155b: 0x4000, 0x155c: 0x4000, 0x155d: 0x4000,
+       0x155e: 0x4000, 0x155f: 0x4000, 0x1560: 0x4000, 0x1561: 0x4000, 0x1562: 0x4000, 0x1563: 0x4000,
+       0x1564: 0x4000, 0x1565: 0x4000, 0x1566: 0x4000, 0x1567: 0x4000, 0x1568: 0x4000, 0x1569: 0x4000,
+       0x156a: 0x4000, 0x156b: 0x4000, 0x156c: 0x4000, 0x156d: 0x4000, 0x156e: 0x4000, 0x156f: 0x4000,
+       0x1570: 0x4000, 0x1571: 0x4000, 0x1572: 0x4000, 0x1573: 0x4000, 0x1574: 0x4000, 0x1575: 0x4000,
+       0x1576: 0x4000, 0x1577: 0x4000, 0x1578: 0x4000, 0x1579: 0x4000, 0x157a: 0x4000, 0x157b: 0x4000,
+       0x157c: 0x4000, 0x157e: 0x4000, 0x157f: 0x4000,
+       // Block 0x56, offset 0x1580
+       0x1580: 0x4000, 0x1581: 0x4000, 0x1582: 0x4000, 0x1583: 0x4000, 0x1584: 0x4000, 0x1585: 0x4000,
+       0x1586: 0x4000, 0x1587: 0x4000, 0x1588: 0x4000, 0x1589: 0x4000, 0x158a: 0x4000, 0x158b: 0x4000,
+       0x158c: 0x4000, 0x158d: 0x4000, 0x158e: 0x4000, 0x158f: 0x4000, 0x1590: 0x4000, 0x1591: 0x4000,
+       0x1592: 0x4000, 0x1593: 0x4000,
+       0x15a0: 0x4000, 0x15a1: 0x4000, 0x15a2: 0x4000, 0x15a3: 0x4000,
+       0x15a4: 0x4000, 0x15a5: 0x4000, 0x15a6: 0x4000, 0x15a7: 0x4000, 0x15a8: 0x4000, 0x15a9: 0x4000,
+       0x15aa: 0x4000, 0x15ab: 0x4000, 0x15ac: 0x4000, 0x15ad: 0x4000, 0x15ae: 0x4000, 0x15af: 0x4000,
+       0x15b0: 0x4000, 0x15b1: 0x4000, 0x15b2: 0x4000, 0x15b3: 0x4000, 0x15b4: 0x4000, 0x15b5: 0x4000,
+       0x15b6: 0x4000, 0x15b7: 0x4000, 0x15b8: 0x4000, 0x15b9: 0x4000, 0x15ba: 0x4000, 0x15bb: 0x4000,
+       0x15bc: 0x4000, 0x15bd: 0x4000, 0x15be: 0x4000, 0x15bf: 0x4000,
+       // Block 0x57, offset 0x15c0
+       0x15c0: 0x4000, 0x15c1: 0x4000, 0x15c2: 0x4000, 0x15c3: 0x4000, 0x15c4: 0x4000, 0x15c5: 0x4000,
+       0x15c6: 0x4000, 0x15c7: 0x4000, 0x15c8: 0x4000, 0x15c9: 0x4000, 0x15ca: 0x4000,
+       0x15cf: 0x4000, 0x15d0: 0x4000, 0x15d1: 0x4000,
+       0x15d2: 0x4000, 0x15d3: 0x4000,
+       0x15e0: 0x4000, 0x15e1: 0x4000, 0x15e2: 0x4000, 0x15e3: 0x4000,
+       0x15e4: 0x4000, 0x15e5: 0x4000, 0x15e6: 0x4000, 0x15e7: 0x4000, 0x15e8: 0x4000, 0x15e9: 0x4000,
+       0x15ea: 0x4000, 0x15eb: 0x4000, 0x15ec: 0x4000, 0x15ed: 0x4000, 0x15ee: 0x4000, 0x15ef: 0x4000,
+       0x15f0: 0x4000, 0x15f4: 0x4000,
+       0x15f8: 0x4000, 0x15f9: 0x4000, 0x15fa: 0x4000, 0x15fb: 0x4000,
+       0x15fc: 0x4000, 0x15fd: 0x4000, 0x15fe: 0x4000, 0x15ff: 0x4000,
+       // Block 0x58, offset 0x1600
+       0x1600: 0x4000, 0x1601: 0x4000, 0x1602: 0x4000, 0x1603: 0x4000, 0x1604: 0x4000, 0x1605: 0x4000,
+       0x1606: 0x4000, 0x1607: 0x4000, 0x1608: 0x4000, 0x1609: 0x4000, 0x160a: 0x4000, 0x160b: 0x4000,
+       0x160c: 0x4000, 0x160d: 0x4000, 0x160e: 0x4000, 0x160f: 0x4000, 0x1610: 0x4000, 0x1611: 0x4000,
+       0x1612: 0x4000, 0x1613: 0x4000, 0x1614: 0x4000, 0x1615: 0x4000, 0x1616: 0x4000, 0x1617: 0x4000,
+       0x1618: 0x4000, 0x1619: 0x4000, 0x161a: 0x4000, 0x161b: 0x4000, 0x161c: 0x4000, 0x161d: 0x4000,
+       0x161e: 0x4000, 0x161f: 0x4000, 0x1620: 0x4000, 0x1621: 0x4000, 0x1622: 0x4000, 0x1623: 0x4000,
+       0x1624: 0x4000, 0x1625: 0x4000, 0x1626: 0x4000, 0x1627: 0x4000, 0x1628: 0x4000, 0x1629: 0x4000,
+       0x162a: 0x4000, 0x162b: 0x4000, 0x162c: 0x4000, 0x162d: 0x4000, 0x162e: 0x4000, 0x162f: 0x4000,
+       0x1630: 0x4000, 0x1631: 0x4000, 0x1632: 0x4000, 0x1633: 0x4000, 0x1634: 0x4000, 0x1635: 0x4000,
+       0x1636: 0x4000, 0x1637: 0x4000, 0x1638: 0x4000, 0x1639: 0x4000, 0x163a: 0x4000, 0x163b: 0x4000,
+       0x163c: 0x4000, 0x163d: 0x4000, 0x163e: 0x4000,
+       // Block 0x59, offset 0x1640
+       0x1640: 0x4000, 0x1642: 0x4000, 0x1643: 0x4000, 0x1644: 0x4000, 0x1645: 0x4000,
+       0x1646: 0x4000, 0x1647: 0x4000, 0x1648: 0x4000, 0x1649: 0x4000, 0x164a: 0x4000, 0x164b: 0x4000,
+       0x164c: 0x4000, 0x164d: 0x4000, 0x164e: 0x4000, 0x164f: 0x4000, 0x1650: 0x4000, 0x1651: 0x4000,
+       0x1652: 0x4000, 0x1653: 0x4000, 0x1654: 0x4000, 0x1655: 0x4000, 0x1656: 0x4000, 0x1657: 0x4000,
+       0x1658: 0x4000, 0x1659: 0x4000, 0x165a: 0x4000, 0x165b: 0x4000, 0x165c: 0x4000, 0x165d: 0x4000,
+       0x165e: 0x4000, 0x165f: 0x4000, 0x1660: 0x4000, 0x1661: 0x4000, 0x1662: 0x4000, 0x1663: 0x4000,
+       0x1664: 0x4000, 0x1665: 0x4000, 0x1666: 0x4000, 0x1667: 0x4000, 0x1668: 0x4000, 0x1669: 0x4000,
+       0x166a: 0x4000, 0x166b: 0x4000, 0x166c: 0x4000, 0x166d: 0x4000, 0x166e: 0x4000, 0x166f: 0x4000,
+       0x1670: 0x4000, 0x1671: 0x4000, 0x1672: 0x4000, 0x1673: 0x4000, 0x1674: 0x4000, 0x1675: 0x4000,
+       0x1676: 0x4000, 0x1677: 0x4000, 0x1678: 0x4000, 0x1679: 0x4000, 0x167a: 0x4000, 0x167b: 0x4000,
+       0x167c: 0x4000, 0x167d: 0x4000, 0x167e: 0x4000, 0x167f: 0x4000,
+       // Block 0x5a, offset 0x1680
+       0x1680: 0x4000, 0x1681: 0x4000, 0x1682: 0x4000, 0x1683: 0x4000, 0x1684: 0x4000, 0x1685: 0x4000,
+       0x1686: 0x4000, 0x1687: 0x4000, 0x1688: 0x4000, 0x1689: 0x4000, 0x168a: 0x4000, 0x168b: 0x4000,
+       0x168c: 0x4000, 0x168d: 0x4000, 0x168e: 0x4000, 0x168f: 0x4000, 0x1690: 0x4000, 0x1691: 0x4000,
+       0x1692: 0x4000, 0x1693: 0x4000, 0x1694: 0x4000, 0x1695: 0x4000, 0x1696: 0x4000, 0x1697: 0x4000,
+       0x1698: 0x4000, 0x1699: 0x4000, 0x169a: 0x4000, 0x169b: 0x4000, 0x169c: 0x4000, 0x169d: 0x4000,
+       0x169e: 0x4000, 0x169f: 0x4000, 0x16a0: 0x4000, 0x16a1: 0x4000, 0x16a2: 0x4000, 0x16a3: 0x4000,
+       0x16a4: 0x4000, 0x16a5: 0x4000, 0x16a6: 0x4000, 0x16a7: 0x4000, 0x16a8: 0x4000, 0x16a9: 0x4000,
+       0x16aa: 0x4000, 0x16ab: 0x4000, 0x16ac: 0x4000, 0x16ad: 0x4000, 0x16ae: 0x4000, 0x16af: 0x4000,
+       0x16b0: 0x4000, 0x16b1: 0x4000, 0x16b2: 0x4000, 0x16b3: 0x4000, 0x16b4: 0x4000, 0x16b5: 0x4000,
+       0x16b6: 0x4000, 0x16b7: 0x4000, 0x16b8: 0x4000, 0x16b9: 0x4000, 0x16ba: 0x4000, 0x16bb: 0x4000,
+       0x16bc: 0x4000, 0x16bf: 0x4000,
+       // Block 0x5b, offset 0x16c0
+       0x16c0: 0x4000, 0x16c1: 0x4000, 0x16c2: 0x4000, 0x16c3: 0x4000, 0x16c4: 0x4000, 0x16c5: 0x4000,
+       0x16c6: 0x4000, 0x16c7: 0x4000, 0x16c8: 0x4000, 0x16c9: 0x4000, 0x16ca: 0x4000, 0x16cb: 0x4000,
+       0x16cc: 0x4000, 0x16cd: 0x4000, 0x16ce: 0x4000, 0x16cf: 0x4000, 0x16d0: 0x4000, 0x16d1: 0x4000,
+       0x16d2: 0x4000, 0x16d3: 0x4000, 0x16d4: 0x4000, 0x16d5: 0x4000, 0x16d6: 0x4000, 0x16d7: 0x4000,
+       0x16d8: 0x4000, 0x16d9: 0x4000, 0x16da: 0x4000, 0x16db: 0x4000, 0x16dc: 0x4000, 0x16dd: 0x4000,
+       0x16de: 0x4000, 0x16df: 0x4000, 0x16e0: 0x4000, 0x16e1: 0x4000, 0x16e2: 0x4000, 0x16e3: 0x4000,
+       0x16e4: 0x4000, 0x16e5: 0x4000, 0x16e6: 0x4000, 0x16e7: 0x4000, 0x16e8: 0x4000, 0x16e9: 0x4000,
+       0x16ea: 0x4000, 0x16eb: 0x4000, 0x16ec: 0x4000, 0x16ed: 0x4000, 0x16ee: 0x4000, 0x16ef: 0x4000,
+       0x16f0: 0x4000, 0x16f1: 0x4000, 0x16f2: 0x4000, 0x16f3: 0x4000, 0x16f4: 0x4000, 0x16f5: 0x4000,
+       0x16f6: 0x4000, 0x16f7: 0x4000, 0x16f8: 0x4000, 0x16f9: 0x4000, 0x16fa: 0x4000, 0x16fb: 0x4000,
+       0x16fc: 0x4000, 0x16fd: 0x4000,
+       // Block 0x5c, offset 0x1700
+       0x170b: 0x4000,
+       0x170c: 0x4000, 0x170d: 0x4000, 0x170e: 0x4000, 0x1710: 0x4000, 0x1711: 0x4000,
+       0x1712: 0x4000, 0x1713: 0x4000, 0x1714: 0x4000, 0x1715: 0x4000, 0x1716: 0x4000, 0x1717: 0x4000,
+       0x1718: 0x4000, 0x1719: 0x4000, 0x171a: 0x4000, 0x171b: 0x4000, 0x171c: 0x4000, 0x171d: 0x4000,
+       0x171e: 0x4000, 0x171f: 0x4000, 0x1720: 0x4000, 0x1721: 0x4000, 0x1722: 0x4000, 0x1723: 0x4000,
+       0x1724: 0x4000, 0x1725: 0x4000, 0x1726: 0x4000, 0x1727: 0x4000,
+       0x173a: 0x4000,
+       // Block 0x5d, offset 0x1740
+       0x1755: 0x4000, 0x1756: 0x4000,
+       0x1764: 0x4000,
+       // Block 0x5e, offset 0x1780
+       0x17bb: 0x4000,
+       0x17bc: 0x4000, 0x17bd: 0x4000, 0x17be: 0x4000, 0x17bf: 0x4000,
+       // Block 0x5f, offset 0x17c0
+       0x17c0: 0x4000, 0x17c1: 0x4000, 0x17c2: 0x4000, 0x17c3: 0x4000, 0x17c4: 0x4000, 0x17c5: 0x4000,
+       0x17c6: 0x4000, 0x17c7: 0x4000, 0x17c8: 0x4000, 0x17c9: 0x4000, 0x17ca: 0x4000, 0x17cb: 0x4000,
+       0x17cc: 0x4000, 0x17cd: 0x4000, 0x17ce: 0x4000, 0x17cf: 0x4000,
+       // Block 0x60, offset 0x1800
+       0x1800: 0x4000, 0x1801: 0x4000, 0x1802: 0x4000, 0x1803: 0x4000, 0x1804: 0x4000, 0x1805: 0x4000,
+       0x180c: 0x4000, 0x1810: 0x4000, 0x1811: 0x4000,
+       0x1812: 0x4000, 0x1815: 0x4000, 0x1816: 0x4000, 0x1817: 0x4000,
+       0x182b: 0x4000, 0x182c: 0x4000,
+       0x1834: 0x4000, 0x1835: 0x4000,
+       0x1836: 0x4000, 0x1837: 0x4000, 0x1838: 0x4000, 0x1839: 0x4000, 0x183a: 0x4000, 0x183b: 0x4000,
+       0x183c: 0x4000,
+       // Block 0x61, offset 0x1840
+       0x1860: 0x4000, 0x1861: 0x4000, 0x1862: 0x4000, 0x1863: 0x4000,
+       0x1864: 0x4000, 0x1865: 0x4000, 0x1866: 0x4000, 0x1867: 0x4000, 0x1868: 0x4000, 0x1869: 0x4000,
+       0x186a: 0x4000, 0x186b: 0x4000,
+       // Block 0x62, offset 0x1880
+       0x188c: 0x4000, 0x188d: 0x4000, 0x188e: 0x4000, 0x188f: 0x4000, 0x1890: 0x4000, 0x1891: 0x4000,
+       0x1892: 0x4000, 0x1893: 0x4000, 0x1894: 0x4000, 0x1895: 0x4000, 0x1896: 0x4000, 0x1897: 0x4000,
+       0x1898: 0x4000, 0x1899: 0x4000, 0x189a: 0x4000, 0x189b: 0x4000, 0x189c: 0x4000, 0x189d: 0x4000,
+       0x189e: 0x4000, 0x189f: 0x4000, 0x18a0: 0x4000, 0x18a1: 0x4000, 0x18a2: 0x4000, 0x18a3: 0x4000,
+       0x18a4: 0x4000, 0x18a5: 0x4000, 0x18a6: 0x4000, 0x18a7: 0x4000, 0x18a8: 0x4000, 0x18a9: 0x4000,
+       0x18aa: 0x4000, 0x18ab: 0x4000, 0x18ac: 0x4000, 0x18ad: 0x4000, 0x18ae: 0x4000, 0x18af: 0x4000,
+       0x18b0: 0x4000, 0x18b1: 0x4000, 0x18b2: 0x4000, 0x18b3: 0x4000, 0x18b4: 0x4000, 0x18b5: 0x4000,
+       0x18b6: 0x4000, 0x18b7: 0x4000, 0x18b8: 0x4000, 0x18b9: 0x4000, 0x18ba: 0x4000,
+       0x18bc: 0x4000, 0x18bd: 0x4000, 0x18be: 0x4000, 0x18bf: 0x4000,
+       // Block 0x63, offset 0x18c0
+       0x18c0: 0x4000, 0x18c1: 0x4000, 0x18c2: 0x4000, 0x18c3: 0x4000, 0x18c4: 0x4000, 0x18c5: 0x4000,
+       0x18c7: 0x4000, 0x18c8: 0x4000, 0x18c9: 0x4000, 0x18ca: 0x4000, 0x18cb: 0x4000,
+       0x18cc: 0x4000, 0x18cd: 0x4000, 0x18ce: 0x4000, 0x18cf: 0x4000, 0x18d0: 0x4000, 0x18d1: 0x4000,
+       0x18d2: 0x4000, 0x18d3: 0x4000, 0x18d4: 0x4000, 0x18d5: 0x4000, 0x18d6: 0x4000, 0x18d7: 0x4000,
+       0x18d8: 0x4000, 0x18d9: 0x4000, 0x18da: 0x4000, 0x18db: 0x4000, 0x18dc: 0x4000, 0x18dd: 0x4000,
+       0x18de: 0x4000, 0x18df: 0x4000, 0x18e0: 0x4000, 0x18e1: 0x4000, 0x18e2: 0x4000, 0x18e3: 0x4000,
+       0x18e4: 0x4000, 0x18e5: 0x4000, 0x18e6: 0x4000, 0x18e7: 0x4000, 0x18e8: 0x4000, 0x18e9: 0x4000,
+       0x18ea: 0x4000, 0x18eb: 0x4000, 0x18ec: 0x4000, 0x18ed: 0x4000, 0x18ee: 0x4000, 0x18ef: 0x4000,
+       0x18f0: 0x4000, 0x18f1: 0x4000, 0x18f2: 0x4000, 0x18f3: 0x4000, 0x18f4: 0x4000, 0x18f5: 0x4000,
+       0x18f6: 0x4000, 0x18f7: 0x4000, 0x18f8: 0x4000, 0x18fa: 0x4000, 0x18fb: 0x4000,
+       0x18fc: 0x4000, 0x18fd: 0x4000, 0x18fe: 0x4000, 0x18ff: 0x4000,
+       // Block 0x64, offset 0x1900
+       0x1900: 0x4000, 0x1901: 0x4000, 0x1902: 0x4000, 0x1903: 0x4000, 0x1904: 0x4000, 0x1905: 0x4000,
+       0x1906: 0x4000, 0x1907: 0x4000, 0x1908: 0x4000, 0x1909: 0x4000, 0x190a: 0x4000, 0x190b: 0x4000,
+       0x190d: 0x4000, 0x190e: 0x4000, 0x190f: 0x4000, 0x1910: 0x4000, 0x1911: 0x4000,
+       0x1912: 0x4000, 0x1913: 0x4000, 0x1914: 0x4000, 0x1915: 0x4000, 0x1916: 0x4000, 0x1917: 0x4000,
+       0x1918: 0x4000, 0x1919: 0x4000, 0x191a: 0x4000, 0x191b: 0x4000, 0x191c: 0x4000, 0x191d: 0x4000,
+       0x191e: 0x4000, 0x191f: 0x4000, 0x1920: 0x4000, 0x1921: 0x4000, 0x1922: 0x4000, 0x1923: 0x4000,
+       0x1924: 0x4000, 0x1925: 0x4000, 0x1926: 0x4000, 0x1927: 0x4000, 0x1928: 0x4000, 0x1929: 0x4000,
+       0x192a: 0x4000, 0x192b: 0x4000, 0x192c: 0x4000, 0x192d: 0x4000, 0x192e: 0x4000, 0x192f: 0x4000,
+       0x1930: 0x4000, 0x1931: 0x4000, 0x1932: 0x4000, 0x1933: 0x4000, 0x1934: 0x4000, 0x1935: 0x4000,
+       0x1936: 0x4000, 0x1937: 0x4000, 0x1938: 0x4000, 0x1939: 0x4000, 0x193a: 0x4000, 0x193b: 0x4000,
+       0x193c: 0x4000, 0x193d: 0x4000, 0x193e: 0x4000, 0x193f: 0x4000,
+       // Block 0x65, offset 0x1940
+       0x1970: 0x4000, 0x1971: 0x4000, 0x1972: 0x4000, 0x1973: 0x4000, 0x1974: 0x4000,
+       0x1978: 0x4000, 0x1979: 0x4000, 0x197a: 0x4000,
+       // Block 0x66, offset 0x1980
+       0x1980: 0x4000, 0x1981: 0x4000, 0x1982: 0x4000, 0x1983: 0x4000, 0x1984: 0x4000, 0x1985: 0x4000,
+       0x1986: 0x4000,
+       0x1990: 0x4000, 0x1991: 0x4000,
+       0x1992: 0x4000, 0x1993: 0x4000, 0x1994: 0x4000, 0x1995: 0x4000, 0x1996: 0x4000, 0x1997: 0x4000,
+       0x1998: 0x4000, 0x1999: 0x4000, 0x199a: 0x4000, 0x199b: 0x4000, 0x199c: 0x4000, 0x199d: 0x4000,
+       0x199e: 0x4000, 0x199f: 0x4000, 0x19a0: 0x4000, 0x19a1: 0x4000, 0x19a2: 0x4000, 0x19a3: 0x4000,
+       0x19a4: 0x4000, 0x19a5: 0x4000, 0x19a6: 0x4000, 0x19a7: 0x4000, 0x19a8: 0x4000,
+       0x19b0: 0x4000, 0x19b1: 0x4000, 0x19b2: 0x4000, 0x19b3: 0x4000, 0x19b4: 0x4000, 0x19b5: 0x4000,
+       0x19b6: 0x4000,
+       // Block 0x67, offset 0x19c0
+       0x19c0: 0x4000, 0x19c1: 0x4000, 0x19c2: 0x4000,
+       0x19d0: 0x4000, 0x19d1: 0x4000,
+       0x19d2: 0x4000, 0x19d3: 0x4000, 0x19d4: 0x4000, 0x19d5: 0x4000, 0x19d6: 0x4000,
+       // Block 0x68, offset 0x1a00
+       0x1a00: 0x2000, 0x1a01: 0x2000, 0x1a02: 0x2000, 0x1a03: 0x2000, 0x1a04: 0x2000, 0x1a05: 0x2000,
+       0x1a06: 0x2000, 0x1a07: 0x2000, 0x1a08: 0x2000, 0x1a09: 0x2000, 0x1a0a: 0x2000, 0x1a0b: 0x2000,
+       0x1a0c: 0x2000, 0x1a0d: 0x2000, 0x1a0e: 0x2000, 0x1a0f: 0x2000, 0x1a10: 0x2000, 0x1a11: 0x2000,
+       0x1a12: 0x2000, 0x1a13: 0x2000, 0x1a14: 0x2000, 0x1a15: 0x2000, 0x1a16: 0x2000, 0x1a17: 0x2000,
+       0x1a18: 0x2000, 0x1a19: 0x2000, 0x1a1a: 0x2000, 0x1a1b: 0x2000, 0x1a1c: 0x2000, 0x1a1d: 0x2000,
+       0x1a1e: 0x2000, 0x1a1f: 0x2000, 0x1a20: 0x2000, 0x1a21: 0x2000, 0x1a22: 0x2000, 0x1a23: 0x2000,
+       0x1a24: 0x2000, 0x1a25: 0x2000, 0x1a26: 0x2000, 0x1a27: 0x2000, 0x1a28: 0x2000, 0x1a29: 0x2000,
+       0x1a2a: 0x2000, 0x1a2b: 0x2000, 0x1a2c: 0x2000, 0x1a2d: 0x2000, 0x1a2e: 0x2000, 0x1a2f: 0x2000,
+       0x1a30: 0x2000, 0x1a31: 0x2000, 0x1a32: 0x2000, 0x1a33: 0x2000, 0x1a34: 0x2000, 0x1a35: 0x2000,
+       0x1a36: 0x2000, 0x1a37: 0x2000, 0x1a38: 0x2000, 0x1a39: 0x2000, 0x1a3a: 0x2000, 0x1a3b: 0x2000,
+       0x1a3c: 0x2000, 0x1a3d: 0x2000,
+}
+
+// widthIndex: 22 blocks, 1408 entries, 1408 bytes
+// Block 0 is the zero block.
+var widthIndex = [1408]uint8{
+       // Block 0x0, offset 0x0
+       // Block 0x1, offset 0x40
+       // Block 0x2, offset 0x80
+       // Block 0x3, offset 0xc0
+       0xc2: 0x01, 0xc3: 0x02, 0xc4: 0x03, 0xc5: 0x04, 0xc7: 0x05,
+       0xc9: 0x06, 0xcb: 0x07, 0xcc: 0x08, 0xcd: 0x09, 0xce: 0x0a, 0xcf: 0x0b,
+       0xd0: 0x0c, 0xd1: 0x0d,
+       0xe1: 0x02, 0xe2: 0x03, 0xe3: 0x04, 0xe4: 0x05, 0xe5: 0x06, 0xe6: 0x06, 0xe7: 0x06,
+       0xe8: 0x06, 0xe9: 0x06, 0xea: 0x07, 0xeb: 0x06, 0xec: 0x06, 0xed: 0x08, 0xee: 0x09, 0xef: 0x0a,
+       0xf0: 0x0f, 0xf3: 0x12, 0xf4: 0x13,
+       // Block 0x4, offset 0x100
+       0x104: 0x0e, 0x105: 0x0f,
+       // Block 0x5, offset 0x140
+       0x140: 0x10, 0x141: 0x11, 0x142: 0x12, 0x144: 0x13, 0x145: 0x14, 0x146: 0x15, 0x147: 0x16,
+       0x148: 0x17, 0x149: 0x18, 0x14a: 0x19, 0x14c: 0x1a, 0x14f: 0x1b,
+       0x151: 0x1c, 0x152: 0x08, 0x153: 0x1d, 0x154: 0x1e, 0x155: 0x1f, 0x156: 0x20, 0x157: 0x21,
+       0x158: 0x22, 0x159: 0x23, 0x15a: 0x24, 0x15b: 0x25, 0x15c: 0x26, 0x15d: 0x27, 0x15e: 0x28, 0x15f: 0x29,
+       0x166: 0x2a,
+       0x16c: 0x2b, 0x16d: 0x2c,
+       0x17a: 0x2d, 0x17b: 0x2e, 0x17c: 0x0e, 0x17d: 0x0e, 0x17e: 0x0e, 0x17f: 0x2f,
+       // Block 0x6, offset 0x180
+       0x180: 0x30, 0x181: 0x31, 0x182: 0x32, 0x183: 0x33, 0x184: 0x34, 0x185: 0x35, 0x186: 0x36, 0x187: 0x37,
+       0x188: 0x38, 0x189: 0x39, 0x18a: 0x0e, 0x18b: 0x0e, 0x18c: 0x0e, 0x18d: 0x0e, 0x18e: 0x0e, 0x18f: 0x0e,
+       0x190: 0x0e, 0x191: 0x0e, 0x192: 0x0e, 0x193: 0x0e, 0x194: 0x0e, 0x195: 0x0e, 0x196: 0x0e, 0x197: 0x0e,
+       0x198: 0x0e, 0x199: 0x0e, 0x19a: 0x0e, 0x19b: 0x0e, 0x19c: 0x0e, 0x19d: 0x0e, 0x19e: 0x0e, 0x19f: 0x0e,
+       0x1a0: 0x0e, 0x1a1: 0x0e, 0x1a2: 0x0e, 0x1a3: 0x0e, 0x1a4: 0x0e, 0x1a5: 0x0e, 0x1a6: 0x0e, 0x1a7: 0x0e,
+       0x1a8: 0x0e, 0x1a9: 0x0e, 0x1aa: 0x0e, 0x1ab: 0x0e, 0x1ac: 0x0e, 0x1ad: 0x0e, 0x1ae: 0x0e, 0x1af: 0x0e,
+       0x1b0: 0x0e, 0x1b1: 0x0e, 0x1b2: 0x0e, 0x1b3: 0x0e, 0x1b4: 0x0e, 0x1b5: 0x0e, 0x1b6: 0x0e, 0x1b7: 0x0e,
+       0x1b8: 0x0e, 0x1b9: 0x0e, 0x1ba: 0x0e, 0x1bb: 0x0e, 0x1bc: 0x0e, 0x1bd: 0x0e, 0x1be: 0x0e, 0x1bf: 0x0e,
+       // Block 0x7, offset 0x1c0
+       0x1c0: 0x0e, 0x1c1: 0x0e, 0x1c2: 0x0e, 0x1c3: 0x0e, 0x1c4: 0x0e, 0x1c5: 0x0e, 0x1c6: 0x0e, 0x1c7: 0x0e,
+       0x1c8: 0x0e, 0x1c9: 0x0e, 0x1ca: 0x0e, 0x1cb: 0x0e, 0x1cc: 0x0e, 0x1cd: 0x0e, 0x1ce: 0x0e, 0x1cf: 0x0e,
+       0x1d0: 0x0e, 0x1d1: 0x0e, 0x1d2: 0x0e, 0x1d3: 0x0e, 0x1d4: 0x0e, 0x1d5: 0x0e, 0x1d6: 0x0e, 0x1d7: 0x0e,
+       0x1d8: 0x0e, 0x1d9: 0x0e, 0x1da: 0x0e, 0x1db: 0x0e, 0x1dc: 0x0e, 0x1dd: 0x0e, 0x1de: 0x0e, 0x1df: 0x0e,
+       0x1e0: 0x0e, 0x1e1: 0x0e, 0x1e2: 0x0e, 0x1e3: 0x0e, 0x1e4: 0x0e, 0x1e5: 0x0e, 0x1e6: 0x0e, 0x1e7: 0x0e,
+       0x1e8: 0x0e, 0x1e9: 0x0e, 0x1ea: 0x0e, 0x1eb: 0x0e, 0x1ec: 0x0e, 0x1ed: 0x0e, 0x1ee: 0x0e, 0x1ef: 0x0e,
+       0x1f0: 0x0e, 0x1f1: 0x0e, 0x1f2: 0x0e, 0x1f3: 0x0e, 0x1f4: 0x0e, 0x1f5: 0x0e, 0x1f6: 0x0e,
+       0x1f8: 0x0e, 0x1f9: 0x0e, 0x1fa: 0x0e, 0x1fb: 0x0e, 0x1fc: 0x0e, 0x1fd: 0x0e, 0x1fe: 0x0e, 0x1ff: 0x0e,
+       // Block 0x8, offset 0x200
+       0x200: 0x0e, 0x201: 0x0e, 0x202: 0x0e, 0x203: 0x0e, 0x204: 0x0e, 0x205: 0x0e, 0x206: 0x0e, 0x207: 0x0e,
+       0x208: 0x0e, 0x209: 0x0e, 0x20a: 0x0e, 0x20b: 0x0e, 0x20c: 0x0e, 0x20d: 0x0e, 0x20e: 0x0e, 0x20f: 0x0e,
+       0x210: 0x0e, 0x211: 0x0e, 0x212: 0x0e, 0x213: 0x0e, 0x214: 0x0e, 0x215: 0x0e, 0x216: 0x0e, 0x217: 0x0e,
+       0x218: 0x0e, 0x219: 0x0e, 0x21a: 0x0e, 0x21b: 0x0e, 0x21c: 0x0e, 0x21d: 0x0e, 0x21e: 0x0e, 0x21f: 0x0e,
+       0x220: 0x0e, 0x221: 0x0e, 0x222: 0x0e, 0x223: 0x0e, 0x224: 0x0e, 0x225: 0x0e, 0x226: 0x0e, 0x227: 0x0e,
+       0x228: 0x0e, 0x229: 0x0e, 0x22a: 0x0e, 0x22b: 0x0e, 0x22c: 0x0e, 0x22d: 0x0e, 0x22e: 0x0e, 0x22f: 0x0e,
+       0x230: 0x0e, 0x231: 0x0e, 0x232: 0x0e, 0x233: 0x0e, 0x234: 0x0e, 0x235: 0x0e, 0x236: 0x0e, 0x237: 0x0e,
+       0x238: 0x0e, 0x239: 0x0e, 0x23a: 0x0e, 0x23b: 0x0e, 0x23c: 0x0e, 0x23d: 0x0e, 0x23e: 0x0e, 0x23f: 0x0e,
+       // Block 0x9, offset 0x240
+       0x240: 0x0e, 0x241: 0x0e, 0x242: 0x0e, 0x243: 0x0e, 0x244: 0x0e, 0x245: 0x0e, 0x246: 0x0e, 0x247: 0x0e,
+       0x248: 0x0e, 0x249: 0x0e, 0x24a: 0x0e, 0x24b: 0x0e, 0x24c: 0x0e, 0x24d: 0x0e, 0x24e: 0x0e, 0x24f: 0x0e,
+       0x250: 0x0e, 0x251: 0x0e, 0x252: 0x3a, 0x253: 0x3b,
+       0x265: 0x3c,
+       0x270: 0x0e, 0x271: 0x0e, 0x272: 0x0e, 0x273: 0x0e, 0x274: 0x0e, 0x275: 0x0e, 0x276: 0x0e, 0x277: 0x0e,
+       0x278: 0x0e, 0x279: 0x0e, 0x27a: 0x0e, 0x27b: 0x0e, 0x27c: 0x0e, 0x27d: 0x0e, 0x27e: 0x0e, 0x27f: 0x0e,
+       // Block 0xa, offset 0x280
+       0x280: 0x0e, 0x281: 0x0e, 0x282: 0x0e, 0x283: 0x0e, 0x284: 0x0e, 0x285: 0x0e, 0x286: 0x0e, 0x287: 0x0e,
+       0x288: 0x0e, 0x289: 0x0e, 0x28a: 0x0e, 0x28b: 0x0e, 0x28c: 0x0e, 0x28d: 0x0e, 0x28e: 0x0e, 0x28f: 0x0e,
+       0x290: 0x0e, 0x291: 0x0e, 0x292: 0x0e, 0x293: 0x0e, 0x294: 0x0e, 0x295: 0x0e, 0x296: 0x0e, 0x297: 0x0e,
+       0x298: 0x0e, 0x299: 0x0e, 0x29a: 0x0e, 0x29b: 0x0e, 0x29c: 0x0e, 0x29d: 0x0e, 0x29e: 0x3d,
+       // Block 0xb, offset 0x2c0
+       0x2c0: 0x08, 0x2c1: 0x08, 0x2c2: 0x08, 0x2c3: 0x08, 0x2c4: 0x08, 0x2c5: 0x08, 0x2c6: 0x08, 0x2c7: 0x08,
+       0x2c8: 0x08, 0x2c9: 0x08, 0x2ca: 0x08, 0x2cb: 0x08, 0x2cc: 0x08, 0x2cd: 0x08, 0x2ce: 0x08, 0x2cf: 0x08,
+       0x2d0: 0x08, 0x2d1: 0x08, 0x2d2: 0x08, 0x2d3: 0x08, 0x2d4: 0x08, 0x2d5: 0x08, 0x2d6: 0x08, 0x2d7: 0x08,
+       0x2d8: 0x08, 0x2d9: 0x08, 0x2da: 0x08, 0x2db: 0x08, 0x2dc: 0x08, 0x2dd: 0x08, 0x2de: 0x08, 0x2df: 0x08,
+       0x2e0: 0x08, 0x2e1: 0x08, 0x2e2: 0x08, 0x2e3: 0x08, 0x2e4: 0x08, 0x2e5: 0x08, 0x2e6: 0x08, 0x2e7: 0x08,
+       0x2e8: 0x08, 0x2e9: 0x08, 0x2ea: 0x08, 0x2eb: 0x08, 0x2ec: 0x08, 0x2ed: 0x08, 0x2ee: 0x08, 0x2ef: 0x08,
+       0x2f0: 0x08, 0x2f1: 0x08, 0x2f2: 0x08, 0x2f3: 0x08, 0x2f4: 0x08, 0x2f5: 0x08, 0x2f6: 0x08, 0x2f7: 0x08,
+       0x2f8: 0x08, 0x2f9: 0x08, 0x2fa: 0x08, 0x2fb: 0x08, 0x2fc: 0x08, 0x2fd: 0x08, 0x2fe: 0x08, 0x2ff: 0x08,
+       // Block 0xc, offset 0x300
+       0x300: 0x08, 0x301: 0x08, 0x302: 0x08, 0x303: 0x08, 0x304: 0x08, 0x305: 0x08, 0x306: 0x08, 0x307: 0x08,
+       0x308: 0x08, 0x309: 0x08, 0x30a: 0x08, 0x30b: 0x08, 0x30c: 0x08, 0x30d: 0x08, 0x30e: 0x08, 0x30f: 0x08,
+       0x310: 0x08, 0x311: 0x08, 0x312: 0x08, 0x313: 0x08, 0x314: 0x08, 0x315: 0x08, 0x316: 0x08, 0x317: 0x08,
+       0x318: 0x08, 0x319: 0x08, 0x31a: 0x08, 0x31b: 0x08, 0x31c: 0x08, 0x31d: 0x08, 0x31e: 0x08, 0x31f: 0x08,
+       0x320: 0x08, 0x321: 0x08, 0x322: 0x08, 0x323: 0x08, 0x324: 0x0e, 0x325: 0x0e, 0x326: 0x0e, 0x327: 0x0e,
+       0x328: 0x0e, 0x329: 0x0e, 0x32a: 0x0e, 0x32b: 0x0e,
+       0x338: 0x3e, 0x339: 0x3f, 0x33c: 0x40, 0x33d: 0x41, 0x33e: 0x42, 0x33f: 0x43,
+       // Block 0xd, offset 0x340
+       0x37f: 0x44,
+       // Block 0xe, offset 0x380
+       0x380: 0x0e, 0x381: 0x0e, 0x382: 0x0e, 0x383: 0x0e, 0x384: 0x0e, 0x385: 0x0e, 0x386: 0x0e, 0x387: 0x0e,
+       0x388: 0x0e, 0x389: 0x0e, 0x38a: 0x0e, 0x38b: 0x0e, 0x38c: 0x0e, 0x38d: 0x0e, 0x38e: 0x0e, 0x38f: 0x0e,
+       0x390: 0x0e, 0x391: 0x0e, 0x392: 0x0e, 0x393: 0x0e, 0x394: 0x0e, 0x395: 0x0e, 0x396: 0x0e, 0x397: 0x0e,
+       0x398: 0x0e, 0x399: 0x0e, 0x39a: 0x0e, 0x39b: 0x0e, 0x39c: 0x0e, 0x39d: 0x0e, 0x39e: 0x0e, 0x39f: 0x45,
+       0x3a0: 0x0e, 0x3a1: 0x0e, 0x3a2: 0x0e, 0x3a3: 0x0e, 0x3a4: 0x0e, 0x3a5: 0x0e, 0x3a6: 0x0e, 0x3a7: 0x0e,
+       0x3a8: 0x0e, 0x3a9: 0x0e, 0x3aa: 0x0e, 0x3ab: 0x0e, 0x3ac: 0x0e, 0x3ad: 0x0e, 0x3ae: 0x0e, 0x3af: 0x0e,
+       0x3b0: 0x0e, 0x3b1: 0x0e, 0x3b2: 0x0e, 0x3b3: 0x46, 0x3b4: 0x47,
+       // Block 0xf, offset 0x3c0
+       0x3c0: 0x0e, 0x3c1: 0x0e, 0x3c2: 0x0e, 0x3c3: 0x0e, 0x3c4: 0x48, 0x3c5: 0x49, 0x3c6: 0x0e, 0x3c7: 0x0e,
+       0x3c8: 0x0e, 0x3c9: 0x0e, 0x3ca: 0x0e, 0x3cb: 0x4a,
+       // Block 0x10, offset 0x400
+       0x400: 0x4b, 0x403: 0x4c, 0x404: 0x4d, 0x405: 0x4e, 0x406: 0x4f,
+       0x408: 0x50, 0x409: 0x51, 0x40c: 0x52, 0x40d: 0x53, 0x40e: 0x54, 0x40f: 0x55,
+       0x410: 0x56, 0x411: 0x57, 0x412: 0x0e, 0x413: 0x58, 0x414: 0x59, 0x415: 0x5a, 0x416: 0x5b, 0x417: 0x5c,
+       0x418: 0x0e, 0x419: 0x5d, 0x41a: 0x0e, 0x41b: 0x5e, 0x41f: 0x5f,
+       0x424: 0x60, 0x425: 0x61, 0x426: 0x0e, 0x427: 0x62,
+       0x429: 0x63, 0x42a: 0x64, 0x42b: 0x65,
+       // Block 0x11, offset 0x440
+       0x456: 0x0b, 0x457: 0x06,
+       0x458: 0x0c, 0x45b: 0x0d, 0x45f: 0x0e,
+       0x460: 0x06, 0x461: 0x06, 0x462: 0x06, 0x463: 0x06, 0x464: 0x06, 0x465: 0x06, 0x466: 0x06, 0x467: 0x06,
+       0x468: 0x06, 0x469: 0x06, 0x46a: 0x06, 0x46b: 0x06, 0x46c: 0x06, 0x46d: 0x06, 0x46e: 0x06, 0x46f: 0x06,
+       0x470: 0x06, 0x471: 0x06, 0x472: 0x06, 0x473: 0x06, 0x474: 0x06, 0x475: 0x06, 0x476: 0x06, 0x477: 0x06,
+       0x478: 0x06, 0x479: 0x06, 0x47a: 0x06, 0x47b: 0x06, 0x47c: 0x06, 0x47d: 0x06, 0x47e: 0x06, 0x47f: 0x06,
+       // Block 0x12, offset 0x480
+       0x484: 0x08, 0x485: 0x08, 0x486: 0x08, 0x487: 0x09,
+       // Block 0x13, offset 0x4c0
+       0x4c0: 0x08, 0x4c1: 0x08, 0x4c2: 0x08, 0x4c3: 0x08, 0x4c4: 0x08, 0x4c5: 0x08, 0x4c6: 0x08, 0x4c7: 0x08,
+       0x4c8: 0x08, 0x4c9: 0x08, 0x4ca: 0x08, 0x4cb: 0x08, 0x4cc: 0x08, 0x4cd: 0x08, 0x4ce: 0x08, 0x4cf: 0x08,
+       0x4d0: 0x08, 0x4d1: 0x08, 0x4d2: 0x08, 0x4d3: 0x08, 0x4d4: 0x08, 0x4d5: 0x08, 0x4d6: 0x08, 0x4d7: 0x08,
+       0x4d8: 0x08, 0x4d9: 0x08, 0x4da: 0x08, 0x4db: 0x08, 0x4dc: 0x08, 0x4dd: 0x08, 0x4de: 0x08, 0x4df: 0x08,
+       0x4e0: 0x08, 0x4e1: 0x08, 0x4e2: 0x08, 0x4e3: 0x08, 0x4e4: 0x08, 0x4e5: 0x08, 0x4e6: 0x08, 0x4e7: 0x08,
+       0x4e8: 0x08, 0x4e9: 0x08, 0x4ea: 0x08, 0x4eb: 0x08, 0x4ec: 0x08, 0x4ed: 0x08, 0x4ee: 0x08, 0x4ef: 0x08,
+       0x4f0: 0x08, 0x4f1: 0x08, 0x4f2: 0x08, 0x4f3: 0x08, 0x4f4: 0x08, 0x4f5: 0x08, 0x4f6: 0x08, 0x4f7: 0x08,
+       0x4f8: 0x08, 0x4f9: 0x08, 0x4fa: 0x08, 0x4fb: 0x08, 0x4fc: 0x08, 0x4fd: 0x08, 0x4fe: 0x08, 0x4ff: 0x66,
+       // Block 0x14, offset 0x500
+       0x520: 0x10,
+       0x530: 0x09, 0x531: 0x09, 0x532: 0x09, 0x533: 0x09, 0x534: 0x09, 0x535: 0x09, 0x536: 0x09, 0x537: 0x09,
+       0x538: 0x09, 0x539: 0x09, 0x53a: 0x09, 0x53b: 0x09, 0x53c: 0x09, 0x53d: 0x09, 0x53e: 0x09, 0x53f: 0x11,
+       // Block 0x15, offset 0x540
+       0x540: 0x09, 0x541: 0x09, 0x542: 0x09, 0x543: 0x09, 0x544: 0x09, 0x545: 0x09, 0x546: 0x09, 0x547: 0x09,
+       0x548: 0x09, 0x549: 0x09, 0x54a: 0x09, 0x54b: 0x09, 0x54c: 0x09, 0x54d: 0x09, 0x54e: 0x09, 0x54f: 0x11,
+}
+
+// inverseData contains 4-byte entries of the following format:
+//   <length> <modified UTF-8-encoded rune> <0 padding>
+// The last byte of the UTF-8-encoded rune is xor-ed with the last byte of the
+// UTF-8 encoding of the original rune. Mappings often have the following
+// pattern:
+//   A -> A  (U+FF21 -> U+0041)
+//   B -> B  (U+FF22 -> U+0042)
+//   ...
+// By xor-ing the last byte the same entry can be shared by many mappings. This
+// reduces the total number of distinct entries by about two thirds.
+// The resulting entry for the aforementioned mappings is
+//   { 0x01, 0xE0, 0x00, 0x00 }
+// Using this entry to map U+FF21 (UTF-8 [EF BC A1]), we get
+//   E0 ^ A1 = 41.
+// Similarly, for U+FF22 (UTF-8 [EF BC A2]), we get
+//   E0 ^ A2 = 42.
+// Note that because of the xor-ing, the byte sequence stored in the entry is
+// not valid UTF-8.
+var inverseData = [150][4]byte{
+       {0x00, 0x00, 0x00, 0x00},
+       {0x03, 0xe3, 0x80, 0xa0},
+       {0x03, 0xef, 0xbc, 0xa0},
+       {0x03, 0xef, 0xbc, 0xe0},
+       {0x03, 0xef, 0xbd, 0xe0},
+       {0x03, 0xef, 0xbf, 0x02},
+       {0x03, 0xef, 0xbf, 0x00},
+       {0x03, 0xef, 0xbf, 0x0e},
+       {0x03, 0xef, 0xbf, 0x0c},
+       {0x03, 0xef, 0xbf, 0x0f},
+       {0x03, 0xef, 0xbf, 0x39},
+       {0x03, 0xef, 0xbf, 0x3b},
+       {0x03, 0xef, 0xbf, 0x3f},
+       {0x03, 0xef, 0xbf, 0x2a},
+       {0x03, 0xef, 0xbf, 0x0d},
+       {0x03, 0xef, 0xbf, 0x25},
+       {0x03, 0xef, 0xbd, 0x1a},
+       {0x03, 0xef, 0xbd, 0x26},
+       {0x01, 0xa0, 0x00, 0x00},
+       {0x03, 0xef, 0xbd, 0x25},
+       {0x03, 0xef, 0xbd, 0x23},
+       {0x03, 0xef, 0xbd, 0x2e},
+       {0x03, 0xef, 0xbe, 0x07},
+       {0x03, 0xef, 0xbe, 0x05},
+       {0x03, 0xef, 0xbd, 0x06},
+       {0x03, 0xef, 0xbd, 0x13},
+       {0x03, 0xef, 0xbd, 0x0b},
+       {0x03, 0xef, 0xbd, 0x16},
+       {0x03, 0xef, 0xbd, 0x0c},
+       {0x03, 0xef, 0xbd, 0x15},
+       {0x03, 0xef, 0xbd, 0x0d},
+       {0x03, 0xef, 0xbd, 0x1c},
+       {0x03, 0xef, 0xbd, 0x02},
+       {0x03, 0xef, 0xbd, 0x1f},
+       {0x03, 0xef, 0xbd, 0x1d},
+       {0x03, 0xef, 0xbd, 0x17},
+       {0x03, 0xef, 0xbd, 0x08},
+       {0x03, 0xef, 0xbd, 0x09},
+       {0x03, 0xef, 0xbd, 0x0e},
+       {0x03, 0xef, 0xbd, 0x04},
+       {0x03, 0xef, 0xbd, 0x05},
+       {0x03, 0xef, 0xbe, 0x3f},
+       {0x03, 0xef, 0xbe, 0x00},
+       {0x03, 0xef, 0xbd, 0x2c},
+       {0x03, 0xef, 0xbe, 0x06},
+       {0x03, 0xef, 0xbe, 0x0c},
+       {0x03, 0xef, 0xbe, 0x0f},
+       {0x03, 0xef, 0xbe, 0x0d},
+       {0x03, 0xef, 0xbe, 0x0b},
+       {0x03, 0xef, 0xbe, 0x19},
+       {0x03, 0xef, 0xbe, 0x15},
+       {0x03, 0xef, 0xbe, 0x11},
+       {0x03, 0xef, 0xbe, 0x31},
+       {0x03, 0xef, 0xbe, 0x33},
+       {0x03, 0xef, 0xbd, 0x0f},
+       {0x03, 0xef, 0xbe, 0x30},
+       {0x03, 0xef, 0xbe, 0x3e},
+       {0x03, 0xef, 0xbe, 0x32},
+       {0x03, 0xef, 0xbe, 0x36},
+       {0x03, 0xef, 0xbd, 0x14},
+       {0x03, 0xef, 0xbe, 0x2e},
+       {0x03, 0xef, 0xbd, 0x1e},
+       {0x03, 0xef, 0xbe, 0x10},
+       {0x03, 0xef, 0xbf, 0x13},
+       {0x03, 0xef, 0xbf, 0x15},
+       {0x03, 0xef, 0xbf, 0x17},
+       {0x03, 0xef, 0xbf, 0x1f},
+       {0x03, 0xef, 0xbf, 0x1d},
+       {0x03, 0xef, 0xbf, 0x1b},
+       {0x03, 0xef, 0xbf, 0x09},
+       {0x03, 0xef, 0xbf, 0x0b},
+       {0x03, 0xef, 0xbf, 0x37},
+       {0x03, 0xef, 0xbe, 0x04},
+       {0x01, 0xe0, 0x00, 0x00},
+       {0x03, 0xe2, 0xa6, 0x1a},
+       {0x03, 0xe2, 0xa6, 0x26},
+       {0x03, 0xe3, 0x80, 0x23},
+       {0x03, 0xe3, 0x80, 0x2e},
+       {0x03, 0xe3, 0x80, 0x25},
+       {0x03, 0xe3, 0x83, 0x1e},
+       {0x03, 0xe3, 0x83, 0x14},
+       {0x03, 0xe3, 0x82, 0x06},
+       {0x03, 0xe3, 0x82, 0x0b},
+       {0x03, 0xe3, 0x82, 0x0c},
+       {0x03, 0xe3, 0x82, 0x0d},
+       {0x03, 0xe3, 0x82, 0x02},
+       {0x03, 0xe3, 0x83, 0x0f},
+       {0x03, 0xe3, 0x83, 0x08},
+       {0x03, 0xe3, 0x83, 0x09},
+       {0x03, 0xe3, 0x83, 0x2c},
+       {0x03, 0xe3, 0x83, 0x0c},
+       {0x03, 0xe3, 0x82, 0x13},
+       {0x03, 0xe3, 0x82, 0x16},
+       {0x03, 0xe3, 0x82, 0x15},
+       {0x03, 0xe3, 0x82, 0x1c},
+       {0x03, 0xe3, 0x82, 0x1f},
+       {0x03, 0xe3, 0x82, 0x1d},
+       {0x03, 0xe3, 0x82, 0x1a},
+       {0x03, 0xe3, 0x82, 0x17},
+       {0x03, 0xe3, 0x82, 0x08},
+       {0x03, 0xe3, 0x82, 0x09},
+       {0x03, 0xe3, 0x82, 0x0e},
+       {0x03, 0xe3, 0x82, 0x04},
+       {0x03, 0xe3, 0x82, 0x05},
+       {0x03, 0xe3, 0x82, 0x3f},
+       {0x03, 0xe3, 0x83, 0x00},
+       {0x03, 0xe3, 0x83, 0x06},
+       {0x03, 0xe3, 0x83, 0x05},
+       {0x03, 0xe3, 0x83, 0x0d},
+       {0x03, 0xe3, 0x83, 0x0b},
+       {0x03, 0xe3, 0x83, 0x07},
+       {0x03, 0xe3, 0x83, 0x19},
+       {0x03, 0xe3, 0x83, 0x15},
+       {0x03, 0xe3, 0x83, 0x11},
+       {0x03, 0xe3, 0x83, 0x31},
+       {0x03, 0xe3, 0x83, 0x33},
+       {0x03, 0xe3, 0x83, 0x30},
+       {0x03, 0xe3, 0x83, 0x3e},
+       {0x03, 0xe3, 0x83, 0x32},
+       {0x03, 0xe3, 0x83, 0x36},
+       {0x03, 0xe3, 0x83, 0x2e},
+       {0x03, 0xe3, 0x82, 0x07},
+       {0x03, 0xe3, 0x85, 0x04},
+       {0x03, 0xe3, 0x84, 0x10},
+       {0x03, 0xe3, 0x85, 0x30},
+       {0x03, 0xe3, 0x85, 0x0d},
+       {0x03, 0xe3, 0x85, 0x13},
+       {0x03, 0xe3, 0x85, 0x15},
+       {0x03, 0xe3, 0x85, 0x17},
+       {0x03, 0xe3, 0x85, 0x1f},
+       {0x03, 0xe3, 0x85, 0x1d},
+       {0x03, 0xe3, 0x85, 0x1b},
+       {0x03, 0xe3, 0x85, 0x09},
+       {0x03, 0xe3, 0x85, 0x0f},
+       {0x03, 0xe3, 0x85, 0x0b},
+       {0x03, 0xe3, 0x85, 0x37},
+       {0x03, 0xe3, 0x85, 0x3b},
+       {0x03, 0xe3, 0x85, 0x39},
+       {0x03, 0xe3, 0x85, 0x3f},
+       {0x02, 0xc2, 0x02, 0x00},
+       {0x02, 0xc2, 0x0e, 0x00},
+       {0x02, 0xc2, 0x0c, 0x00},
+       {0x02, 0xc2, 0x00, 0x00},
+       {0x03, 0xe2, 0x82, 0x0f},
+       {0x03, 0xe2, 0x94, 0x2a},
+       {0x03, 0xe2, 0x86, 0x39},
+       {0x03, 0xe2, 0x86, 0x3b},
+       {0x03, 0xe2, 0x86, 0x3f},
+       {0x03, 0xe2, 0x96, 0x0d},
+       {0x03, 0xe2, 0x97, 0x25},
+}
+
+// Total table size 15448 bytes (15KiB)
index 53e4514c9afb45088086f30ab27022b412e9a9f6..2b0dd44c375f4f9fa305ff875870f97c0ade740d 100644 (file)
@@ -10,14 +10,22 @@ code.gitea.io/sdk/gitea
 # gitea.com/lunny/levelqueue v0.3.0
 ## explicit
 gitea.com/lunny/levelqueue
+# gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e
+gitea.com/lunny/log
+# gitea.com/lunny/nodb v0.0.0-20200923032308-3238c4655727
+gitea.com/lunny/nodb
+gitea.com/lunny/nodb/config
+gitea.com/lunny/nodb/store
+gitea.com/lunny/nodb/store/driver
+gitea.com/lunny/nodb/store/goleveldb
 # gitea.com/macaron/binding v0.0.0-20190822013154-a5f53841ed2b
 ## explicit
 gitea.com/macaron/binding
-# gitea.com/macaron/cache v0.0.0-20190822004001-a6e7fee4ee76
+# gitea.com/macaron/cache v0.0.0-20200924044943-905232fba10b
 ## explicit
 gitea.com/macaron/cache
 gitea.com/macaron/cache/memcache
-# gitea.com/macaron/captcha v0.0.0-20190822015246-daa973478bae
+# gitea.com/macaron/captcha v0.0.0-20200825161008-e8597820aaca
 ## explicit
 gitea.com/macaron/captcha
 # gitea.com/macaron/cors v0.0.0-20190826180238-95aec09ea8b4
@@ -29,16 +37,16 @@ gitea.com/macaron/csrf
 # gitea.com/macaron/gzip v0.0.0-20200827120000-efa5e8477cf5
 ## explicit
 gitea.com/macaron/gzip
-# gitea.com/macaron/i18n v0.0.0-20200910171939-7bbf54aa4c76
+# gitea.com/macaron/i18n v0.0.0-20200911004404-4ca3dd0cbd60
 ## explicit
 gitea.com/macaron/i18n
 # gitea.com/macaron/inject v0.0.0-20190805023432-d4c86e31027a
 ## explicit
 gitea.com/macaron/inject
-# gitea.com/macaron/macaron v1.5.0
+# gitea.com/macaron/macaron v1.5.1-0.20201027213641-0db5d4584804
 ## explicit
 gitea.com/macaron/macaron
-# gitea.com/macaron/session v0.0.0-20200902202411-e3a87877db6e
+# gitea.com/macaron/session v0.0.0-20201103015045-a177a2701dee
 ## explicit
 gitea.com/macaron/session
 gitea.com/macaron/session/couchbase
@@ -51,8 +59,6 @@ gitea.com/macaron/session/postgres
 gitea.com/macaron/toolbox
 # github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c
 github.com/Azure/go-ntlmssp
-# github.com/BurntSushi/toml v0.3.1
-github.com/BurntSushi/toml
 # github.com/PuerkitoBio/goquery v1.5.1
 ## explicit
 github.com/PuerkitoBio/goquery
@@ -180,11 +186,12 @@ github.com/bradfitz/gomemcache/memcache
 github.com/cespare/xxhash/v2
 # github.com/chris-ramon/douceur v0.2.0
 github.com/chris-ramon/douceur/parser
-# github.com/couchbase/gomemcached v0.0.0-20191004160342-7b5da2ec40b2
-## explicit
+# github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89
+github.com/couchbase/go-couchbase
+# github.com/couchbase/gomemcached v0.1.0
 github.com/couchbase/gomemcached
 github.com/couchbase/gomemcached/client
-# github.com/couchbase/goutils v0.0.0-20191018232750-b49639060d85
+# github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67
 github.com/couchbase/goutils/logging
 github.com/couchbase/goutils/scramsha
 # github.com/couchbase/vellum v1.0.2
@@ -192,8 +199,6 @@ github.com/couchbase/vellum
 github.com/couchbase/vellum/levenshtein
 github.com/couchbase/vellum/regexp
 github.com/couchbase/vellum/utf8
-# github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7
-github.com/couchbaselabs/go-couchbase
 # github.com/cpuguy83/go-md2man/v2 v2.0.0
 github.com/cpuguy83/go-md2man/v2/md2man
 # github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d
@@ -416,7 +421,6 @@ github.com/golang/protobuf/ptypes/any
 github.com/golang/protobuf/ptypes/duration
 github.com/golang/protobuf/ptypes/timestamp
 # github.com/golang/snappy v0.0.2
-## explicit
 github.com/golang/snappy
 # github.com/google/go-github/v32 v32.1.0
 ## explicit
@@ -502,7 +506,7 @@ github.com/keybase/go-crypto/openpgp/errors
 github.com/keybase/go-crypto/openpgp/packet
 github.com/keybase/go-crypto/openpgp/s2k
 github.com/keybase/go-crypto/rsa
-# github.com/klauspost/compress v1.11.1
+# github.com/klauspost/compress v1.11.2
 ## explicit
 github.com/klauspost/compress/flate
 github.com/klauspost/compress/fse
@@ -532,14 +536,6 @@ github.com/lib/pq/scram
 # github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96
 ## explicit
 github.com/lunny/dingtalk_webhook
-# github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de
-github.com/lunny/log
-# github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af
-github.com/lunny/nodb
-github.com/lunny/nodb/config
-github.com/lunny/nodb/store
-github.com/lunny/nodb/store/driver
-github.com/lunny/nodb/store/goleveldb
 # github.com/magiconair/properties v1.8.1
 github.com/magiconair/properties
 # github.com/mailru/easyjson v0.7.6
@@ -805,7 +801,7 @@ go.mongodb.org/mongo-driver/bson/bsonrw
 go.mongodb.org/mongo-driver/bson/bsontype
 go.mongodb.org/mongo-driver/bson/primitive
 go.mongodb.org/mongo-driver/x/bsonx/bsoncore
-# golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee
+# golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
 ## explicit
 golang.org/x/crypto/acme
 golang.org/x/crypto/acme/autocert
@@ -863,7 +859,7 @@ golang.org/x/sys/unix
 golang.org/x/sys/windows
 golang.org/x/sys/windows/svc
 golang.org/x/sys/windows/svc/debug
-# golang.org/x/text v0.3.3
+# golang.org/x/text v0.3.4
 ## explicit
 golang.org/x/text/encoding
 golang.org/x/text/encoding/charmap