├── vendor └── github.com │ ├── nsf │ └── termbox-go │ │ ├── AUTHORS │ │ ├── escwait_darwin.go │ │ ├── escwait.go │ │ ├── syscalls_freebsd.go │ │ ├── syscalls_netbsd.go │ │ ├── syscalls_openbsd.go │ │ ├── syscalls_dragonfly.go │ │ ├── syscalls.go │ │ ├── syscalls_darwin.go │ │ ├── syscalls_darwin_amd64.go │ │ ├── syscalls_linux.go │ │ ├── LICENSE │ │ ├── termbox_common.go │ │ ├── syscalls_windows.go │ │ ├── collect_terminfo.py │ │ ├── README.md │ │ ├── terminfo_builtin.go │ │ ├── api_common.go │ │ ├── terminfo.go │ │ ├── api_windows.go │ │ ├── termbox.go │ │ ├── api.go │ │ └── termbox_windows.go │ ├── pkg │ └── errors │ │ ├── .travis.yml │ │ ├── .gitignore │ │ ├── appveyor.yml │ │ ├── LICENSE │ │ ├── README.md │ │ ├── stack.go │ │ └── errors.go │ └── mattn │ └── go-runewidth │ ├── runewidth_js.go │ ├── .travis.yml │ ├── runewidth_windows.go │ ├── README.mkd │ ├── LICENSE │ ├── runewidth_posix.go │ └── runewidth.go ├── README.md ├── Gopkg.lock ├── Gopkg.toml └── main.go /vendor/github.com/nsf/termbox-go/AUTHORS: -------------------------------------------------------------------------------- 1 | # Please keep this file sorted. 2 | 3 | Georg Reinke 4 | nsf 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Demo 2 | [![asciicast](https://asciinema.org/a/MaDXDzArlOeYwkoJDkpLOBohA.png)](https://asciinema.org/a/MaDXDzArlOeYwkoJDkpLOBohA) 3 | 4 | Inspired by http://zty.pe/ 5 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/errors/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go_import_path: github.com/pkg/errors 3 | go: 4 | - 1.4.3 5 | - 1.5.4 6 | - 1.6.2 7 | - 1.7.1 8 | - tip 9 | 10 | script: 11 | - go test -v ./... 12 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-runewidth/runewidth_js.go: -------------------------------------------------------------------------------- 1 | // +build js 2 | 3 | package runewidth 4 | 5 | func IsEastAsian() bool { 6 | // TODO: Implement this for the web. Detect east asian in a compatible way, and return true. 7 | return false 8 | } 9 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-runewidth/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - tip 4 | before_install: 5 | - go get github.com/mattn/goveralls 6 | - go get golang.org/x/tools/cmd/cover 7 | script: 8 | - $HOME/gopath/bin/goveralls -repotoken lAKAWPzcGsD3A8yBX3BGGtRUdJ6CaGERL 9 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/escwait_darwin.go: -------------------------------------------------------------------------------- 1 | package termbox 2 | 3 | // On macOS, enable behavior which will wait before deciding that the escape 4 | // key was pressed, to account for partially send escape sequences, especially 5 | // with regard to lengthy mouse sequences. 6 | // See https://github.com/nsf/termbox-go/issues/132 7 | func enable_wait_for_escape_sequence() bool { 8 | return true 9 | } 10 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/errors/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/escwait.go: -------------------------------------------------------------------------------- 1 | // +build !darwin 2 | 3 | package termbox 4 | 5 | // On all systems other than macOS, disable behavior which will wait before 6 | // deciding that the escape key was pressed, to account for partially send 7 | // escape sequences, especially with regard to lengthy mouse sequences. 8 | // See https://github.com/nsf/termbox-go/issues/132 9 | func enable_wait_for_escape_sequence() bool { 10 | return false 11 | } 12 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-runewidth/runewidth_windows.go: -------------------------------------------------------------------------------- 1 | package runewidth 2 | 3 | import ( 4 | "syscall" 5 | ) 6 | 7 | var ( 8 | kernel32 = syscall.NewLazyDLL("kernel32") 9 | procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP") 10 | ) 11 | 12 | // IsEastAsian return true if the current locale is CJK 13 | func IsEastAsian() bool { 14 | r1, _, _ := procGetConsoleOutputCP.Call() 15 | if r1 == 0 { 16 | return false 17 | } 18 | 19 | switch int(r1) { 20 | case 932, 51932, 936, 949, 950: 21 | return true 22 | } 23 | 24 | return false 25 | } 26 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/errors/appveyor.yml: -------------------------------------------------------------------------------- 1 | version: build-{build}.{branch} 2 | 3 | clone_folder: C:\gopath\src\github.com\pkg\errors 4 | shallow_clone: true # for startup speed 5 | 6 | environment: 7 | GOPATH: C:\gopath 8 | 9 | platform: 10 | - x64 11 | 12 | # http://www.appveyor.com/docs/installed-software 13 | install: 14 | # some helpful output for debugging builds 15 | - go version 16 | - go env 17 | # pre-installed MinGW at C:\MinGW is 32bit only 18 | # but MSYS2 at C:\msys64 has mingw64 19 | - set PATH=C:\msys64\mingw64\bin;%PATH% 20 | - gcc --version 21 | - g++ --version 22 | 23 | build_script: 24 | - go install -v ./... 25 | 26 | test_script: 27 | - set PATH=C:\gopath\bin;%PATH% 28 | - go test -v ./... 29 | 30 | #artifacts: 31 | # - path: '%GOPATH%\bin\*.exe' 32 | deploy: off 33 | -------------------------------------------------------------------------------- /Gopkg.lock: -------------------------------------------------------------------------------- 1 | # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. 2 | 3 | 4 | [[projects]] 5 | name = "github.com/mattn/go-runewidth" 6 | packages = ["."] 7 | revision = "9e777a8366cce605130a531d2cd6363d07ad7317" 8 | version = "v0.0.2" 9 | 10 | [[projects]] 11 | branch = "master" 12 | name = "github.com/nsf/termbox-go" 13 | packages = ["."] 14 | revision = "157ff97de075fe3e9e54bda782b8ca6b552dfff7" 15 | 16 | [[projects]] 17 | name = "github.com/pkg/errors" 18 | packages = ["."] 19 | revision = "645ef00459ed84a119197bfb8d8205042c6df63d" 20 | version = "v0.8.0" 21 | 22 | [solve-meta] 23 | analyzer-name = "dep" 24 | analyzer-version = 1 25 | inputs-digest = "fc68c5a8b0df9e4bcbea5f49c75f95491f3df8d6d7caaa247ed2026c072ec21a" 26 | solver-name = "gps-cdcl" 27 | solver-version = 1 28 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-runewidth/README.mkd: -------------------------------------------------------------------------------- 1 | go-runewidth 2 | ============ 3 | 4 | [![Build Status](https://travis-ci.org/mattn/go-runewidth.png?branch=master)](https://travis-ci.org/mattn/go-runewidth) 5 | [![Coverage Status](https://coveralls.io/repos/mattn/go-runewidth/badge.png?branch=HEAD)](https://coveralls.io/r/mattn/go-runewidth?branch=HEAD) 6 | [![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth) 7 | [![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-runewidth)](https://goreportcard.com/report/github.com/mattn/go-runewidth) 8 | 9 | Provides functions to get fixed width of the character or string. 10 | 11 | Usage 12 | ----- 13 | 14 | ```go 15 | runewidth.StringWidth("つのだ☆HIRO") == 12 16 | ``` 17 | 18 | 19 | Author 20 | ------ 21 | 22 | Yasuhiro Matsumoto 23 | 24 | License 25 | ------- 26 | 27 | under the MIT License: http://mattn.mit-license.org/2013 28 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/syscalls_freebsd.go: -------------------------------------------------------------------------------- 1 | // Created by cgo -godefs - DO NOT EDIT 2 | // cgo -godefs syscalls.go 3 | 4 | package termbox 5 | 6 | type syscall_Termios struct { 7 | Iflag uint32 8 | Oflag uint32 9 | Cflag uint32 10 | Lflag uint32 11 | Cc [20]uint8 12 | Ispeed uint32 13 | Ospeed uint32 14 | } 15 | 16 | const ( 17 | syscall_IGNBRK = 0x1 18 | syscall_BRKINT = 0x2 19 | syscall_PARMRK = 0x8 20 | syscall_ISTRIP = 0x20 21 | syscall_INLCR = 0x40 22 | syscall_IGNCR = 0x80 23 | syscall_ICRNL = 0x100 24 | syscall_IXON = 0x200 25 | syscall_OPOST = 0x1 26 | syscall_ECHO = 0x8 27 | syscall_ECHONL = 0x10 28 | syscall_ICANON = 0x100 29 | syscall_ISIG = 0x80 30 | syscall_IEXTEN = 0x400 31 | syscall_CSIZE = 0x300 32 | syscall_PARENB = 0x1000 33 | syscall_CS8 = 0x300 34 | syscall_VMIN = 0x10 35 | syscall_VTIME = 0x11 36 | 37 | syscall_TCGETS = 0x402c7413 38 | syscall_TCSETS = 0x802c7414 39 | ) 40 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/syscalls_netbsd.go: -------------------------------------------------------------------------------- 1 | // Created by cgo -godefs - DO NOT EDIT 2 | // cgo -godefs syscalls.go 3 | 4 | package termbox 5 | 6 | type syscall_Termios struct { 7 | Iflag uint32 8 | Oflag uint32 9 | Cflag uint32 10 | Lflag uint32 11 | Cc [20]uint8 12 | Ispeed int32 13 | Ospeed int32 14 | } 15 | 16 | const ( 17 | syscall_IGNBRK = 0x1 18 | syscall_BRKINT = 0x2 19 | syscall_PARMRK = 0x8 20 | syscall_ISTRIP = 0x20 21 | syscall_INLCR = 0x40 22 | syscall_IGNCR = 0x80 23 | syscall_ICRNL = 0x100 24 | syscall_IXON = 0x200 25 | syscall_OPOST = 0x1 26 | syscall_ECHO = 0x8 27 | syscall_ECHONL = 0x10 28 | syscall_ICANON = 0x100 29 | syscall_ISIG = 0x80 30 | syscall_IEXTEN = 0x400 31 | syscall_CSIZE = 0x300 32 | syscall_PARENB = 0x1000 33 | syscall_CS8 = 0x300 34 | syscall_VMIN = 0x10 35 | syscall_VTIME = 0x11 36 | 37 | syscall_TCGETS = 0x402c7413 38 | syscall_TCSETS = 0x802c7414 39 | ) 40 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/syscalls_openbsd.go: -------------------------------------------------------------------------------- 1 | // Created by cgo -godefs - DO NOT EDIT 2 | // cgo -godefs syscalls.go 3 | 4 | package termbox 5 | 6 | type syscall_Termios struct { 7 | Iflag uint32 8 | Oflag uint32 9 | Cflag uint32 10 | Lflag uint32 11 | Cc [20]uint8 12 | Ispeed int32 13 | Ospeed int32 14 | } 15 | 16 | const ( 17 | syscall_IGNBRK = 0x1 18 | syscall_BRKINT = 0x2 19 | syscall_PARMRK = 0x8 20 | syscall_ISTRIP = 0x20 21 | syscall_INLCR = 0x40 22 | syscall_IGNCR = 0x80 23 | syscall_ICRNL = 0x100 24 | syscall_IXON = 0x200 25 | syscall_OPOST = 0x1 26 | syscall_ECHO = 0x8 27 | syscall_ECHONL = 0x10 28 | syscall_ICANON = 0x100 29 | syscall_ISIG = 0x80 30 | syscall_IEXTEN = 0x400 31 | syscall_CSIZE = 0x300 32 | syscall_PARENB = 0x1000 33 | syscall_CS8 = 0x300 34 | syscall_VMIN = 0x10 35 | syscall_VTIME = 0x11 36 | 37 | syscall_TCGETS = 0x402c7413 38 | syscall_TCSETS = 0x802c7414 39 | ) 40 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/syscalls_dragonfly.go: -------------------------------------------------------------------------------- 1 | // Created by cgo -godefs - DO NOT EDIT 2 | // cgo -godefs syscalls.go 3 | 4 | package termbox 5 | 6 | type syscall_Termios struct { 7 | Iflag uint32 8 | Oflag uint32 9 | Cflag uint32 10 | Lflag uint32 11 | Cc [20]uint8 12 | Ispeed uint32 13 | Ospeed uint32 14 | } 15 | 16 | const ( 17 | syscall_IGNBRK = 0x1 18 | syscall_BRKINT = 0x2 19 | syscall_PARMRK = 0x8 20 | syscall_ISTRIP = 0x20 21 | syscall_INLCR = 0x40 22 | syscall_IGNCR = 0x80 23 | syscall_ICRNL = 0x100 24 | syscall_IXON = 0x200 25 | syscall_OPOST = 0x1 26 | syscall_ECHO = 0x8 27 | syscall_ECHONL = 0x10 28 | syscall_ICANON = 0x100 29 | syscall_ISIG = 0x80 30 | syscall_IEXTEN = 0x400 31 | syscall_CSIZE = 0x300 32 | syscall_PARENB = 0x1000 33 | syscall_CS8 = 0x300 34 | syscall_VMIN = 0x10 35 | syscall_VTIME = 0x11 36 | 37 | syscall_TCGETS = 0x402c7413 38 | syscall_TCSETS = 0x802c7414 39 | ) 40 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/syscalls.go: -------------------------------------------------------------------------------- 1 | // +build ignore 2 | 3 | package termbox 4 | 5 | /* 6 | #include 7 | #include 8 | */ 9 | import "C" 10 | 11 | type syscall_Termios C.struct_termios 12 | 13 | const ( 14 | syscall_IGNBRK = C.IGNBRK 15 | syscall_BRKINT = C.BRKINT 16 | syscall_PARMRK = C.PARMRK 17 | syscall_ISTRIP = C.ISTRIP 18 | syscall_INLCR = C.INLCR 19 | syscall_IGNCR = C.IGNCR 20 | syscall_ICRNL = C.ICRNL 21 | syscall_IXON = C.IXON 22 | syscall_OPOST = C.OPOST 23 | syscall_ECHO = C.ECHO 24 | syscall_ECHONL = C.ECHONL 25 | syscall_ICANON = C.ICANON 26 | syscall_ISIG = C.ISIG 27 | syscall_IEXTEN = C.IEXTEN 28 | syscall_CSIZE = C.CSIZE 29 | syscall_PARENB = C.PARENB 30 | syscall_CS8 = C.CS8 31 | syscall_VMIN = C.VMIN 32 | syscall_VTIME = C.VTIME 33 | 34 | // on darwin change these to (on *bsd too?): 35 | // C.TIOCGETA 36 | // C.TIOCSETA 37 | syscall_TCGETS = C.TCGETS 38 | syscall_TCSETS = C.TCSETS 39 | ) 40 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/syscalls_darwin.go: -------------------------------------------------------------------------------- 1 | // Created by cgo -godefs - DO NOT EDIT 2 | // cgo -godefs syscalls.go 3 | 4 | // +build !amd64 5 | 6 | package termbox 7 | 8 | type syscall_Termios struct { 9 | Iflag uint32 10 | Oflag uint32 11 | Cflag uint32 12 | Lflag uint32 13 | Cc [20]uint8 14 | Ispeed uint32 15 | Ospeed uint32 16 | } 17 | 18 | const ( 19 | syscall_IGNBRK = 0x1 20 | syscall_BRKINT = 0x2 21 | syscall_PARMRK = 0x8 22 | syscall_ISTRIP = 0x20 23 | syscall_INLCR = 0x40 24 | syscall_IGNCR = 0x80 25 | syscall_ICRNL = 0x100 26 | syscall_IXON = 0x200 27 | syscall_OPOST = 0x1 28 | syscall_ECHO = 0x8 29 | syscall_ECHONL = 0x10 30 | syscall_ICANON = 0x100 31 | syscall_ISIG = 0x80 32 | syscall_IEXTEN = 0x400 33 | syscall_CSIZE = 0x300 34 | syscall_PARENB = 0x1000 35 | syscall_CS8 = 0x300 36 | syscall_VMIN = 0x10 37 | syscall_VTIME = 0x11 38 | 39 | syscall_TCGETS = 0x402c7413 40 | syscall_TCSETS = 0x802c7414 41 | ) 42 | -------------------------------------------------------------------------------- /Gopkg.toml: -------------------------------------------------------------------------------- 1 | # Gopkg.toml example 2 | # 3 | # Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md 4 | # for detailed Gopkg.toml documentation. 5 | # 6 | # required = ["github.com/user/thing/cmd/thing"] 7 | # ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] 8 | # 9 | # [[constraint]] 10 | # name = "github.com/user/project" 11 | # version = "1.0.0" 12 | # 13 | # [[constraint]] 14 | # name = "github.com/user/project2" 15 | # branch = "dev" 16 | # source = "github.com/myfork/project2" 17 | # 18 | # [[override]] 19 | # name = "github.com/x/y" 20 | # version = "2.4.0" 21 | # 22 | # [prune] 23 | # non-go = false 24 | # go-tests = true 25 | # unused-packages = true 26 | 27 | 28 | [prune] 29 | go-tests = true 30 | unused-packages = true 31 | 32 | [[constraint]] 33 | branch = "master" 34 | name = "github.com/JoelOtter/termloop" 35 | 36 | [[constraint]] 37 | branch = "master" 38 | name = "github.com/nsf/termbox-go" 39 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/syscalls_darwin_amd64.go: -------------------------------------------------------------------------------- 1 | // Created by cgo -godefs - DO NOT EDIT 2 | // cgo -godefs syscalls.go 3 | 4 | package termbox 5 | 6 | type syscall_Termios struct { 7 | Iflag uint64 8 | Oflag uint64 9 | Cflag uint64 10 | Lflag uint64 11 | Cc [20]uint8 12 | Pad_cgo_0 [4]byte 13 | Ispeed uint64 14 | Ospeed uint64 15 | } 16 | 17 | const ( 18 | syscall_IGNBRK = 0x1 19 | syscall_BRKINT = 0x2 20 | syscall_PARMRK = 0x8 21 | syscall_ISTRIP = 0x20 22 | syscall_INLCR = 0x40 23 | syscall_IGNCR = 0x80 24 | syscall_ICRNL = 0x100 25 | syscall_IXON = 0x200 26 | syscall_OPOST = 0x1 27 | syscall_ECHO = 0x8 28 | syscall_ECHONL = 0x10 29 | syscall_ICANON = 0x100 30 | syscall_ISIG = 0x80 31 | syscall_IEXTEN = 0x400 32 | syscall_CSIZE = 0x300 33 | syscall_PARENB = 0x1000 34 | syscall_CS8 = 0x300 35 | syscall_VMIN = 0x10 36 | syscall_VTIME = 0x11 37 | 38 | syscall_TCGETS = 0x40487413 39 | syscall_TCSETS = 0x80487414 40 | ) 41 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/syscalls_linux.go: -------------------------------------------------------------------------------- 1 | // Created by cgo -godefs - DO NOT EDIT 2 | // cgo -godefs syscalls.go 3 | 4 | package termbox 5 | 6 | import "syscall" 7 | 8 | type syscall_Termios syscall.Termios 9 | 10 | const ( 11 | syscall_IGNBRK = syscall.IGNBRK 12 | syscall_BRKINT = syscall.BRKINT 13 | syscall_PARMRK = syscall.PARMRK 14 | syscall_ISTRIP = syscall.ISTRIP 15 | syscall_INLCR = syscall.INLCR 16 | syscall_IGNCR = syscall.IGNCR 17 | syscall_ICRNL = syscall.ICRNL 18 | syscall_IXON = syscall.IXON 19 | syscall_OPOST = syscall.OPOST 20 | syscall_ECHO = syscall.ECHO 21 | syscall_ECHONL = syscall.ECHONL 22 | syscall_ICANON = syscall.ICANON 23 | syscall_ISIG = syscall.ISIG 24 | syscall_IEXTEN = syscall.IEXTEN 25 | syscall_CSIZE = syscall.CSIZE 26 | syscall_PARENB = syscall.PARENB 27 | syscall_CS8 = syscall.CS8 28 | syscall_VMIN = syscall.VMIN 29 | syscall_VTIME = syscall.VTIME 30 | 31 | syscall_TCGETS = syscall.TCGETS 32 | syscall_TCSETS = syscall.TCSETS 33 | ) 34 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2012 termbox-go authors 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-runewidth/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Yasuhiro Matsumoto 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/termbox_common.go: -------------------------------------------------------------------------------- 1 | package termbox 2 | 3 | // private API, common OS agnostic part 4 | 5 | type cellbuf struct { 6 | width int 7 | height int 8 | cells []Cell 9 | } 10 | 11 | func (this *cellbuf) init(width, height int) { 12 | this.width = width 13 | this.height = height 14 | this.cells = make([]Cell, width*height) 15 | } 16 | 17 | func (this *cellbuf) resize(width, height int) { 18 | if this.width == width && this.height == height { 19 | return 20 | } 21 | 22 | oldw := this.width 23 | oldh := this.height 24 | oldcells := this.cells 25 | 26 | this.init(width, height) 27 | this.clear() 28 | 29 | minw, minh := oldw, oldh 30 | 31 | if width < minw { 32 | minw = width 33 | } 34 | if height < minh { 35 | minh = height 36 | } 37 | 38 | for i := 0; i < minh; i++ { 39 | srco, dsto := i*oldw, i*width 40 | src := oldcells[srco : srco+minw] 41 | dst := this.cells[dsto : dsto+minw] 42 | copy(dst, src) 43 | } 44 | } 45 | 46 | func (this *cellbuf) clear() { 47 | for i := range this.cells { 48 | c := &this.cells[i] 49 | c.Ch = ' ' 50 | c.Fg = foreground 51 | c.Bg = background 52 | } 53 | } 54 | 55 | const cursor_hidden = -1 56 | 57 | func is_cursor_hidden(x, y int) bool { 58 | return x == cursor_hidden || y == cursor_hidden 59 | } 60 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/errors/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Dave Cheney 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-runewidth/runewidth_posix.go: -------------------------------------------------------------------------------- 1 | // +build !windows,!js 2 | 3 | package runewidth 4 | 5 | import ( 6 | "os" 7 | "regexp" 8 | "strings" 9 | ) 10 | 11 | var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`) 12 | 13 | var mblenTable = map[string]int{ 14 | "utf-8": 6, 15 | "utf8": 6, 16 | "jis": 8, 17 | "eucjp": 3, 18 | "euckr": 2, 19 | "euccn": 2, 20 | "sjis": 2, 21 | "cp932": 2, 22 | "cp51932": 2, 23 | "cp936": 2, 24 | "cp949": 2, 25 | "cp950": 2, 26 | "big5": 2, 27 | "gbk": 2, 28 | "gb2312": 2, 29 | } 30 | 31 | func isEastAsian(locale string) bool { 32 | charset := strings.ToLower(locale) 33 | r := reLoc.FindStringSubmatch(locale) 34 | if len(r) == 2 { 35 | charset = strings.ToLower(r[1]) 36 | } 37 | 38 | if strings.HasSuffix(charset, "@cjk_narrow") { 39 | return false 40 | } 41 | 42 | for pos, b := range []byte(charset) { 43 | if b == '@' { 44 | charset = charset[:pos] 45 | break 46 | } 47 | } 48 | max := 1 49 | if m, ok := mblenTable[charset]; ok { 50 | max = m 51 | } 52 | if max > 1 && (charset[0] != 'u' || 53 | strings.HasPrefix(locale, "ja") || 54 | strings.HasPrefix(locale, "ko") || 55 | strings.HasPrefix(locale, "zh")) { 56 | return true 57 | } 58 | return false 59 | } 60 | 61 | // IsEastAsian return true if the current locale is CJK 62 | func IsEastAsian() bool { 63 | locale := os.Getenv("LC_CTYPE") 64 | if locale == "" { 65 | locale = os.Getenv("LANG") 66 | } 67 | 68 | // ignore C locale 69 | if locale == "POSIX" || locale == "C" { 70 | return false 71 | } 72 | if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') { 73 | return false 74 | } 75 | 76 | return isEastAsian(locale) 77 | } 78 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/syscalls_windows.go: -------------------------------------------------------------------------------- 1 | // Created by cgo -godefs - DO NOT EDIT 2 | // cgo -godefs -- -DUNICODE syscalls.go 3 | 4 | package termbox 5 | 6 | const ( 7 | foreground_blue = 0x1 8 | foreground_green = 0x2 9 | foreground_red = 0x4 10 | foreground_intensity = 0x8 11 | background_blue = 0x10 12 | background_green = 0x20 13 | background_red = 0x40 14 | background_intensity = 0x80 15 | std_input_handle = -0xa 16 | std_output_handle = -0xb 17 | key_event = 0x1 18 | mouse_event = 0x2 19 | window_buffer_size_event = 0x4 20 | enable_window_input = 0x8 21 | enable_mouse_input = 0x10 22 | enable_extended_flags = 0x80 23 | 24 | vk_f1 = 0x70 25 | vk_f2 = 0x71 26 | vk_f3 = 0x72 27 | vk_f4 = 0x73 28 | vk_f5 = 0x74 29 | vk_f6 = 0x75 30 | vk_f7 = 0x76 31 | vk_f8 = 0x77 32 | vk_f9 = 0x78 33 | vk_f10 = 0x79 34 | vk_f11 = 0x7a 35 | vk_f12 = 0x7b 36 | vk_insert = 0x2d 37 | vk_delete = 0x2e 38 | vk_home = 0x24 39 | vk_end = 0x23 40 | vk_pgup = 0x21 41 | vk_pgdn = 0x22 42 | vk_arrow_up = 0x26 43 | vk_arrow_down = 0x28 44 | vk_arrow_left = 0x25 45 | vk_arrow_right = 0x27 46 | vk_backspace = 0x8 47 | vk_tab = 0x9 48 | vk_enter = 0xd 49 | vk_esc = 0x1b 50 | vk_space = 0x20 51 | 52 | left_alt_pressed = 0x2 53 | left_ctrl_pressed = 0x8 54 | right_alt_pressed = 0x1 55 | right_ctrl_pressed = 0x4 56 | shift_pressed = 0x10 57 | 58 | generic_read = 0x80000000 59 | generic_write = 0x40000000 60 | console_textmode_buffer = 0x1 61 | ) 62 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/errors/README.md: -------------------------------------------------------------------------------- 1 | # errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors) 2 | 3 | Package errors provides simple error handling primitives. 4 | 5 | `go get github.com/pkg/errors` 6 | 7 | The traditional error handling idiom in Go is roughly akin to 8 | ```go 9 | if err != nil { 10 | return err 11 | } 12 | ``` 13 | which applied recursively up the call stack results in error reports without context or debugging information. The errors package allows programmers to add context to the failure path in their code in a way that does not destroy the original value of the error. 14 | 15 | ## Adding context to an error 16 | 17 | The errors.Wrap function returns a new error that adds context to the original error. For example 18 | ```go 19 | _, err := ioutil.ReadAll(r) 20 | if err != nil { 21 | return errors.Wrap(err, "read failed") 22 | } 23 | ``` 24 | ## Retrieving the cause of an error 25 | 26 | Using `errors.Wrap` constructs a stack of errors, adding context to the preceding error. Depending on the nature of the error it may be necessary to reverse the operation of errors.Wrap to retrieve the original error for inspection. Any error value which implements this interface can be inspected by `errors.Cause`. 27 | ```go 28 | type causer interface { 29 | Cause() error 30 | } 31 | ``` 32 | `errors.Cause` will recursively retrieve the topmost error which does not implement `causer`, which is assumed to be the original cause. For example: 33 | ```go 34 | switch err := errors.Cause(err).(type) { 35 | case *MyError: 36 | // handle specifically 37 | default: 38 | // unknown error 39 | } 40 | ``` 41 | 42 | [Read the package documentation for more information](https://godoc.org/github.com/pkg/errors). 43 | 44 | ## Contributing 45 | 46 | We welcome pull requests, bug fixes and issue reports. With that said, the bar for adding new symbols to this package is intentionally set high. 47 | 48 | Before proposing a change, please discuss your change by raising an issue. 49 | 50 | ## Licence 51 | 52 | BSD-2-Clause 53 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/collect_terminfo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys, os, subprocess 4 | 5 | def escaped(s): 6 | return repr(s)[1:-1] 7 | 8 | def tput(term, name): 9 | try: 10 | return subprocess.check_output(['tput', '-T%s' % term, name]).decode() 11 | except subprocess.CalledProcessError as e: 12 | return e.output.decode() 13 | 14 | 15 | def w(s): 16 | if s == None: 17 | return 18 | sys.stdout.write(s) 19 | 20 | terminals = { 21 | 'xterm' : 'xterm', 22 | 'rxvt-256color' : 'rxvt_256color', 23 | 'rxvt-unicode' : 'rxvt_unicode', 24 | 'linux' : 'linux', 25 | 'Eterm' : 'eterm', 26 | 'screen' : 'screen' 27 | } 28 | 29 | keys = [ 30 | "F1", "kf1", 31 | "F2", "kf2", 32 | "F3", "kf3", 33 | "F4", "kf4", 34 | "F5", "kf5", 35 | "F6", "kf6", 36 | "F7", "kf7", 37 | "F8", "kf8", 38 | "F9", "kf9", 39 | "F10", "kf10", 40 | "F11", "kf11", 41 | "F12", "kf12", 42 | "INSERT", "kich1", 43 | "DELETE", "kdch1", 44 | "HOME", "khome", 45 | "END", "kend", 46 | "PGUP", "kpp", 47 | "PGDN", "knp", 48 | "KEY_UP", "kcuu1", 49 | "KEY_DOWN", "kcud1", 50 | "KEY_LEFT", "kcub1", 51 | "KEY_RIGHT", "kcuf1" 52 | ] 53 | 54 | funcs = [ 55 | "T_ENTER_CA", "smcup", 56 | "T_EXIT_CA", "rmcup", 57 | "T_SHOW_CURSOR", "cnorm", 58 | "T_HIDE_CURSOR", "civis", 59 | "T_CLEAR_SCREEN", "clear", 60 | "T_SGR0", "sgr0", 61 | "T_UNDERLINE", "smul", 62 | "T_BOLD", "bold", 63 | "T_BLINK", "blink", 64 | "T_REVERSE", "rev", 65 | "T_ENTER_KEYPAD", "smkx", 66 | "T_EXIT_KEYPAD", "rmkx" 67 | ] 68 | 69 | def iter_pairs(iterable): 70 | iterable = iter(iterable) 71 | while True: 72 | yield (next(iterable), next(iterable)) 73 | 74 | def do_term(term, nick): 75 | w("// %s\n" % term) 76 | w("var %s_keys = []string{\n\t" % nick) 77 | for k, v in iter_pairs(keys): 78 | w('"') 79 | w(escaped(tput(term, v))) 80 | w('",') 81 | w("\n}\n") 82 | w("var %s_funcs = []string{\n\t" % nick) 83 | for k,v in iter_pairs(funcs): 84 | w('"') 85 | if v == "sgr": 86 | w("\\033[3%d;4%dm") 87 | elif v == "cup": 88 | w("\\033[%d;%dH") 89 | else: 90 | w(escaped(tput(term, v))) 91 | w('", ') 92 | w("\n}\n\n") 93 | 94 | def do_terms(d): 95 | w("var terms = []struct {\n") 96 | w("\tname string\n") 97 | w("\tkeys []string\n") 98 | w("\tfuncs []string\n") 99 | w("}{\n") 100 | for k, v in d.items(): 101 | w('\t{"%s", %s_keys, %s_funcs},\n' % (k, v, v)) 102 | w("}\n\n") 103 | 104 | w("// +build !windows\n\npackage termbox\n\n") 105 | 106 | for k,v in terminals.items(): 107 | do_term(k, v) 108 | 109 | do_terms(terminals) 110 | 111 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/README.md: -------------------------------------------------------------------------------- 1 | ## Termbox 2 | Termbox is a library that provides a minimalistic API which allows the programmer to write text-based user interfaces. The library is crossplatform and has both terminal-based implementations on *nix operating systems and a winapi console based implementation for windows operating systems. The basic idea is an abstraction of the greatest common subset of features available on all major terminals and other terminal-like APIs in a minimalistic fashion. Small API means it is easy to implement, test, maintain and learn it, that's what makes the termbox a distinct library in its area. 3 | 4 | ### Installation 5 | Install and update this go package with `go get -u github.com/nsf/termbox-go` 6 | 7 | ### Examples 8 | For examples of what can be done take a look at demos in the _demos directory. You can try them with go run: `go run _demos/keyboard.go` 9 | 10 | There are also some interesting projects using termbox-go: 11 | - [godit](https://github.com/nsf/godit) is an emacsish lightweight text editor written using termbox. 12 | - [gomatrix](https://github.com/GeertJohan/gomatrix) connects to The Matrix and displays its data streams in your terminal. 13 | - [gotetris](https://github.com/jjinux/gotetris) is an implementation of Tetris. 14 | - [sokoban-go](https://github.com/rn2dy/sokoban-go) is an implementation of sokoban game. 15 | - [hecate](https://github.com/evanmiller/hecate) is a hex editor designed by Satan. 16 | - [httopd](https://github.com/verdverm/httopd) is top for httpd logs. 17 | - [mop](https://github.com/mop-tracker/mop) is stock market tracker for hackers. 18 | - [termui](https://github.com/gizak/termui) is a terminal dashboard. 19 | - [termloop](https://github.com/JoelOtter/termloop) is a terminal game engine. 20 | - [xterm-color-chart](https://github.com/kutuluk/xterm-color-chart) is a XTerm 256 color chart. 21 | - [gocui](https://github.com/jroimartin/gocui) is a minimalist Go library aimed at creating console user interfaces. 22 | - [dry](https://github.com/moncho/dry) is an interactive cli to manage Docker containers. 23 | - [pxl](https://github.com/ichinaski/pxl) displays images in the terminal. 24 | - [snake-game](https://github.com/DyegoCosta/snake-game) is an implementation of the Snake game. 25 | - [gone](https://github.com/guillaumebreton/gone) is a CLI pomodoro® timer. 26 | - [Spoof.go](https://github.com/sabey/spoofgo) controllable movement spoofing from the cli 27 | - [lf](https://github.com/gokcehan/lf) is a terminal file manager 28 | - [rat](https://github.com/ericfreese/rat) lets you compose shell commands to build terminal applications. 29 | - [httplab](https://github.com/gchaincl/httplab) An interactive web server. 30 | - [tetris](https://github.com/MichaelS11/tetris) Go Tetris with AI option 31 | - [wot](https://github.com/kyu-suke/wot) Wait time during command is completed. 32 | - [2048-go](https://github.com/1984weed/2048-go) is 2048 in Go 33 | - [jv](https://github.com/maxzender/jv) helps you view JSON on the command-line. 34 | - [pinger](https://github.com/hirose31/pinger) helps you to monitor numerous hosts using ICMP ECHO_REQUEST. 35 | - [vixl44](https://github.com/sebashwa/vixl44) lets you create pixel art inside your terminal using vim movements 36 | 37 | ### API reference 38 | [godoc.org/github.com/nsf/termbox-go](http://godoc.org/github.com/nsf/termbox-go) 39 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/terminfo_builtin.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package termbox 4 | 5 | // Eterm 6 | var eterm_keys = []string{ 7 | "\x1b[11~", "\x1b[12~", "\x1b[13~", "\x1b[14~", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[7~", "\x1b[8~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C", 8 | } 9 | var eterm_funcs = []string{ 10 | "\x1b7\x1b[?47h", "\x1b[2J\x1b[?47l\x1b8", "\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[2J", "\x1b[m\x0f", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "", "", "", "", 11 | } 12 | 13 | // screen 14 | var screen_keys = []string{ 15 | "\x1bOP", "\x1bOQ", "\x1bOR", "\x1bOS", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[1~", "\x1b[4~", "\x1b[5~", "\x1b[6~", "\x1bOA", "\x1bOB", "\x1bOD", "\x1bOC", 16 | } 17 | var screen_funcs = []string{ 18 | "\x1b[?1049h", "\x1b[?1049l", "\x1b[34h\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[J", "\x1b[m\x0f", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "\x1b[?1h\x1b=", "\x1b[?1l\x1b>", ti_mouse_enter, ti_mouse_leave, 19 | } 20 | 21 | // xterm 22 | var xterm_keys = []string{ 23 | "\x1bOP", "\x1bOQ", "\x1bOR", "\x1bOS", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1bOH", "\x1bOF", "\x1b[5~", "\x1b[6~", "\x1bOA", "\x1bOB", "\x1bOD", "\x1bOC", 24 | } 25 | var xterm_funcs = []string{ 26 | "\x1b[?1049h", "\x1b[?1049l", "\x1b[?12l\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[2J", "\x1b(B\x1b[m", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "\x1b[?1h\x1b=", "\x1b[?1l\x1b>", ti_mouse_enter, ti_mouse_leave, 27 | } 28 | 29 | // rxvt-unicode 30 | var rxvt_unicode_keys = []string{ 31 | "\x1b[11~", "\x1b[12~", "\x1b[13~", "\x1b[14~", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[7~", "\x1b[8~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C", 32 | } 33 | var rxvt_unicode_funcs = []string{ 34 | "\x1b[?1049h", "\x1b[r\x1b[?1049l", "\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[2J", "\x1b[m\x1b(B", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "\x1b=", "\x1b>", ti_mouse_enter, ti_mouse_leave, 35 | } 36 | 37 | // linux 38 | var linux_keys = []string{ 39 | "\x1b[[A", "\x1b[[B", "\x1b[[C", "\x1b[[D", "\x1b[[E", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[1~", "\x1b[4~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C", 40 | } 41 | var linux_funcs = []string{ 42 | "", "", "\x1b[?25h\x1b[?0c", "\x1b[?25l\x1b[?1c", "\x1b[H\x1b[J", "\x1b[0;10m", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "", "", "", "", 43 | } 44 | 45 | // rxvt-256color 46 | var rxvt_256color_keys = []string{ 47 | "\x1b[11~", "\x1b[12~", "\x1b[13~", "\x1b[14~", "\x1b[15~", "\x1b[17~", "\x1b[18~", "\x1b[19~", "\x1b[20~", "\x1b[21~", "\x1b[23~", "\x1b[24~", "\x1b[2~", "\x1b[3~", "\x1b[7~", "\x1b[8~", "\x1b[5~", "\x1b[6~", "\x1b[A", "\x1b[B", "\x1b[D", "\x1b[C", 48 | } 49 | var rxvt_256color_funcs = []string{ 50 | "\x1b7\x1b[?47h", "\x1b[2J\x1b[?47l\x1b8", "\x1b[?25h", "\x1b[?25l", "\x1b[H\x1b[2J", "\x1b[m\x0f", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "\x1b=", "\x1b>", ti_mouse_enter, ti_mouse_leave, 51 | } 52 | 53 | var terms = []struct { 54 | name string 55 | keys []string 56 | funcs []string 57 | }{ 58 | {"Eterm", eterm_keys, eterm_funcs}, 59 | {"screen", screen_keys, screen_funcs}, 60 | {"xterm", xterm_keys, xterm_funcs}, 61 | {"rxvt-unicode", rxvt_unicode_keys, rxvt_unicode_funcs}, 62 | {"linux", linux_keys, linux_funcs}, 63 | {"rxvt-256color", rxvt_256color_keys, rxvt_256color_funcs}, 64 | } 65 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/errors/stack.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "path" 7 | "runtime" 8 | "strings" 9 | ) 10 | 11 | // Frame represents a program counter inside a stack frame. 12 | type Frame uintptr 13 | 14 | // pc returns the program counter for this frame; 15 | // multiple frames may have the same PC value. 16 | func (f Frame) pc() uintptr { return uintptr(f) - 1 } 17 | 18 | // file returns the full path to the file that contains the 19 | // function for this Frame's pc. 20 | func (f Frame) file() string { 21 | fn := runtime.FuncForPC(f.pc()) 22 | if fn == nil { 23 | return "unknown" 24 | } 25 | file, _ := fn.FileLine(f.pc()) 26 | return file 27 | } 28 | 29 | // line returns the line number of source code of the 30 | // function for this Frame's pc. 31 | func (f Frame) line() int { 32 | fn := runtime.FuncForPC(f.pc()) 33 | if fn == nil { 34 | return 0 35 | } 36 | _, line := fn.FileLine(f.pc()) 37 | return line 38 | } 39 | 40 | // Format formats the frame according to the fmt.Formatter interface. 41 | // 42 | // %s source file 43 | // %d source line 44 | // %n function name 45 | // %v equivalent to %s:%d 46 | // 47 | // Format accepts flags that alter the printing of some verbs, as follows: 48 | // 49 | // %+s path of source file relative to the compile time GOPATH 50 | // %+v equivalent to %+s:%d 51 | func (f Frame) Format(s fmt.State, verb rune) { 52 | switch verb { 53 | case 's': 54 | switch { 55 | case s.Flag('+'): 56 | pc := f.pc() 57 | fn := runtime.FuncForPC(pc) 58 | if fn == nil { 59 | io.WriteString(s, "unknown") 60 | } else { 61 | file, _ := fn.FileLine(pc) 62 | fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file) 63 | } 64 | default: 65 | io.WriteString(s, path.Base(f.file())) 66 | } 67 | case 'd': 68 | fmt.Fprintf(s, "%d", f.line()) 69 | case 'n': 70 | name := runtime.FuncForPC(f.pc()).Name() 71 | io.WriteString(s, funcname(name)) 72 | case 'v': 73 | f.Format(s, 's') 74 | io.WriteString(s, ":") 75 | f.Format(s, 'd') 76 | } 77 | } 78 | 79 | // StackTrace is stack of Frames from innermost (newest) to outermost (oldest). 80 | type StackTrace []Frame 81 | 82 | func (st StackTrace) Format(s fmt.State, verb rune) { 83 | switch verb { 84 | case 'v': 85 | switch { 86 | case s.Flag('+'): 87 | for _, f := range st { 88 | fmt.Fprintf(s, "\n%+v", f) 89 | } 90 | case s.Flag('#'): 91 | fmt.Fprintf(s, "%#v", []Frame(st)) 92 | default: 93 | fmt.Fprintf(s, "%v", []Frame(st)) 94 | } 95 | case 's': 96 | fmt.Fprintf(s, "%s", []Frame(st)) 97 | } 98 | } 99 | 100 | // stack represents a stack of program counters. 101 | type stack []uintptr 102 | 103 | func (s *stack) Format(st fmt.State, verb rune) { 104 | switch verb { 105 | case 'v': 106 | switch { 107 | case st.Flag('+'): 108 | for _, pc := range *s { 109 | f := Frame(pc) 110 | fmt.Fprintf(st, "\n%+v", f) 111 | } 112 | } 113 | } 114 | } 115 | 116 | func (s *stack) StackTrace() StackTrace { 117 | f := make([]Frame, len(*s)) 118 | for i := 0; i < len(f); i++ { 119 | f[i] = Frame((*s)[i]) 120 | } 121 | return f 122 | } 123 | 124 | func callers() *stack { 125 | const depth = 32 126 | var pcs [depth]uintptr 127 | n := runtime.Callers(3, pcs[:]) 128 | var st stack = pcs[0:n] 129 | return &st 130 | } 131 | 132 | // funcname removes the path prefix component of a function's name reported by func.Name(). 133 | func funcname(name string) string { 134 | i := strings.LastIndex(name, "/") 135 | name = name[i+1:] 136 | i = strings.Index(name, ".") 137 | return name[i+1:] 138 | } 139 | 140 | func trimGOPATH(name, file string) string { 141 | // Here we want to get the source file path relative to the compile time 142 | // GOPATH. As of Go 1.6.x there is no direct way to know the compiled 143 | // GOPATH at runtime, but we can infer the number of path segments in the 144 | // GOPATH. We note that fn.Name() returns the function name qualified by 145 | // the import path, which does not include the GOPATH. Thus we can trim 146 | // segments from the beginning of the file path until the number of path 147 | // separators remaining is one more than the number of path separators in 148 | // the function name. For example, given: 149 | // 150 | // GOPATH /home/user 151 | // file /home/user/src/pkg/sub/file.go 152 | // fn.Name() pkg/sub.Type.Method 153 | // 154 | // We want to produce: 155 | // 156 | // pkg/sub/file.go 157 | // 158 | // From this we can easily see that fn.Name() has one less path separator 159 | // than our desired output. We count separators from the end of the file 160 | // path until it finds two more than in the function name and then move 161 | // one character forward to preserve the initial path segment without a 162 | // leading separator. 163 | const sep = "/" 164 | goal := strings.Count(name, sep) + 2 165 | i := len(file) 166 | for n := 0; n < goal; n++ { 167 | i = strings.LastIndex(file[:i], sep) 168 | if i == -1 { 169 | // not enough separators found, set i so that the slice expression 170 | // below leaves file unmodified 171 | i = -len(sep) 172 | break 173 | } 174 | } 175 | // get back to 0 or trim the leading separator 176 | file = file[i+len(sep):] 177 | return file 178 | } 179 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/api_common.go: -------------------------------------------------------------------------------- 1 | // termbox is a library for creating cross-platform text-based interfaces 2 | package termbox 3 | 4 | // public API, common OS agnostic part 5 | 6 | type ( 7 | InputMode int 8 | OutputMode int 9 | EventType uint8 10 | Modifier uint8 11 | Key uint16 12 | Attribute uint16 13 | ) 14 | 15 | // This type represents a termbox event. The 'Mod', 'Key' and 'Ch' fields are 16 | // valid if 'Type' is EventKey. The 'Width' and 'Height' fields are valid if 17 | // 'Type' is EventResize. The 'Err' field is valid if 'Type' is EventError. 18 | type Event struct { 19 | Type EventType // one of Event* constants 20 | Mod Modifier // one of Mod* constants or 0 21 | Key Key // one of Key* constants, invalid if 'Ch' is not 0 22 | Ch rune // a unicode character 23 | Width int // width of the screen 24 | Height int // height of the screen 25 | Err error // error in case if input failed 26 | MouseX int // x coord of mouse 27 | MouseY int // y coord of mouse 28 | N int // number of bytes written when getting a raw event 29 | } 30 | 31 | // A cell, single conceptual entity on the screen. The screen is basically a 2d 32 | // array of cells. 'Ch' is a unicode character, 'Fg' and 'Bg' are foreground 33 | // and background attributes respectively. 34 | type Cell struct { 35 | Ch rune 36 | Fg Attribute 37 | Bg Attribute 38 | } 39 | 40 | // To know if termbox has been initialized or not 41 | var ( 42 | IsInit bool = false 43 | ) 44 | 45 | // Key constants, see Event.Key field. 46 | const ( 47 | KeyF1 Key = 0xFFFF - iota 48 | KeyF2 49 | KeyF3 50 | KeyF4 51 | KeyF5 52 | KeyF6 53 | KeyF7 54 | KeyF8 55 | KeyF9 56 | KeyF10 57 | KeyF11 58 | KeyF12 59 | KeyInsert 60 | KeyDelete 61 | KeyHome 62 | KeyEnd 63 | KeyPgup 64 | KeyPgdn 65 | KeyArrowUp 66 | KeyArrowDown 67 | KeyArrowLeft 68 | KeyArrowRight 69 | key_min // see terminfo 70 | MouseLeft 71 | MouseMiddle 72 | MouseRight 73 | MouseRelease 74 | MouseWheelUp 75 | MouseWheelDown 76 | ) 77 | 78 | const ( 79 | KeyCtrlTilde Key = 0x00 80 | KeyCtrl2 Key = 0x00 81 | KeyCtrlSpace Key = 0x00 82 | KeyCtrlA Key = 0x01 83 | KeyCtrlB Key = 0x02 84 | KeyCtrlC Key = 0x03 85 | KeyCtrlD Key = 0x04 86 | KeyCtrlE Key = 0x05 87 | KeyCtrlF Key = 0x06 88 | KeyCtrlG Key = 0x07 89 | KeyBackspace Key = 0x08 90 | KeyCtrlH Key = 0x08 91 | KeyTab Key = 0x09 92 | KeyCtrlI Key = 0x09 93 | KeyCtrlJ Key = 0x0A 94 | KeyCtrlK Key = 0x0B 95 | KeyCtrlL Key = 0x0C 96 | KeyEnter Key = 0x0D 97 | KeyCtrlM Key = 0x0D 98 | KeyCtrlN Key = 0x0E 99 | KeyCtrlO Key = 0x0F 100 | KeyCtrlP Key = 0x10 101 | KeyCtrlQ Key = 0x11 102 | KeyCtrlR Key = 0x12 103 | KeyCtrlS Key = 0x13 104 | KeyCtrlT Key = 0x14 105 | KeyCtrlU Key = 0x15 106 | KeyCtrlV Key = 0x16 107 | KeyCtrlW Key = 0x17 108 | KeyCtrlX Key = 0x18 109 | KeyCtrlY Key = 0x19 110 | KeyCtrlZ Key = 0x1A 111 | KeyEsc Key = 0x1B 112 | KeyCtrlLsqBracket Key = 0x1B 113 | KeyCtrl3 Key = 0x1B 114 | KeyCtrl4 Key = 0x1C 115 | KeyCtrlBackslash Key = 0x1C 116 | KeyCtrl5 Key = 0x1D 117 | KeyCtrlRsqBracket Key = 0x1D 118 | KeyCtrl6 Key = 0x1E 119 | KeyCtrl7 Key = 0x1F 120 | KeyCtrlSlash Key = 0x1F 121 | KeyCtrlUnderscore Key = 0x1F 122 | KeySpace Key = 0x20 123 | KeyBackspace2 Key = 0x7F 124 | KeyCtrl8 Key = 0x7F 125 | ) 126 | 127 | // Alt modifier constant, see Event.Mod field and SetInputMode function. 128 | const ( 129 | ModAlt Modifier = 1 << iota 130 | ModMotion 131 | ) 132 | 133 | // Cell colors, you can combine a color with multiple attributes using bitwise 134 | // OR ('|'). 135 | const ( 136 | ColorDefault Attribute = iota 137 | ColorBlack 138 | ColorRed 139 | ColorGreen 140 | ColorYellow 141 | ColorBlue 142 | ColorMagenta 143 | ColorCyan 144 | ColorWhite 145 | ) 146 | 147 | // Cell attributes, it is possible to use multiple attributes by combining them 148 | // using bitwise OR ('|'). Although, colors cannot be combined. But you can 149 | // combine attributes and a single color. 150 | // 151 | // It's worth mentioning that some platforms don't support certain attributes. 152 | // For example windows console doesn't support AttrUnderline. And on some 153 | // terminals applying AttrBold to background may result in blinking text. Use 154 | // them with caution and test your code on various terminals. 155 | const ( 156 | AttrBold Attribute = 1 << (iota + 9) 157 | AttrUnderline 158 | AttrReverse 159 | ) 160 | 161 | // Input mode. See SetInputMode function. 162 | const ( 163 | InputEsc InputMode = 1 << iota 164 | InputAlt 165 | InputMouse 166 | InputCurrent InputMode = 0 167 | ) 168 | 169 | // Output mode. See SetOutputMode function. 170 | const ( 171 | OutputCurrent OutputMode = iota 172 | OutputNormal 173 | Output256 174 | Output216 175 | OutputGrayscale 176 | ) 177 | 178 | // Event type. See Event.Type field. 179 | const ( 180 | EventKey EventType = iota 181 | EventResize 182 | EventMouse 183 | EventError 184 | EventInterrupt 185 | EventRaw 186 | EventNone 187 | ) 188 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "github.com/nsf/termbox-go" 8 | "github.com/pkg/errors" 9 | "io/ioutil" 10 | "math/rand" 11 | "os" 12 | "strconv" 13 | "time" 14 | "unicode" 15 | ) 16 | 17 | var debug bool 18 | 19 | type state struct { 20 | currentLevel level 21 | status string 22 | dict []string 23 | } 24 | 25 | type point struct { 26 | x int 27 | y int 28 | } 29 | 30 | type level struct { 31 | numWords int 32 | maxWordLength int 33 | words []word 34 | activeWordIndex int 35 | levelNumber int 36 | } 37 | 38 | type word struct { 39 | text string 40 | location point 41 | cursor int 42 | } 43 | 44 | func newState() state { 45 | s := state{ 46 | currentLevel: level{ 47 | numWords: 3, 48 | activeWordIndex: -1, 49 | levelNumber: 0, 50 | }, 51 | dict: readWords(), 52 | } 53 | s.newLevel() 54 | return s 55 | } 56 | 57 | func readWords() []string { 58 | ioutil.ReadFile("en.txt") 59 | file, err := os.Open("en.txt") 60 | if err != nil { 61 | panic(errors.Wrap(err, "couldn't open word file")) 62 | } 63 | defer file.Close() 64 | scanner := bufio.NewScanner(file) 65 | words := []string{} 66 | for scanner.Scan() { 67 | line := scanner.Text() 68 | words = append(words, line) 69 | if len(words) >= 1000000 { 70 | break 71 | } 72 | } 73 | return words 74 | } 75 | 76 | func (s *state) newLevel() { 77 | currentLevel := s.currentLevel 78 | s.currentLevel = level{ 79 | numWords: currentLevel.numWords + 1, 80 | activeWordIndex: -1, 81 | levelNumber: currentLevel.levelNumber + 1, 82 | } 83 | wordSet := map[int]struct{}{} 84 | for len(s.currentLevel.words) < s.currentLevel.numWords { 85 | word := newWord(s.dict, wordSet) 86 | _, ok := wordSet[word.location.y] 87 | if !ok { 88 | wordSet[word.location.y] = struct{}{} 89 | s.currentLevel.words = append(s.currentLevel.words, word) 90 | } 91 | } 92 | } 93 | 94 | func newWord(dict []string, wordSet map[int]struct{}) word { 95 | _, height := termbox.Size() 96 | return word{ 97 | text: dict[rand.Intn(len(dict))], 98 | location: point{ 99 | x: 0, 100 | y: rand.Intn(height-1) + 1, 101 | }, 102 | cursor: 0, 103 | } 104 | } 105 | 106 | func exit(events chan termbox.Event, timer <-chan time.Time) { 107 | close(events) 108 | termbox.Close() 109 | } 110 | 111 | func gameLoop(events chan termbox.Event, timer <-chan time.Time, gameState chan state) state { 112 | s := newState() 113 | gameState <- s 114 | 115 | for { 116 | select { 117 | case key := <-events: 118 | switch { 119 | case key.Key == termbox.KeyEsc || key.Key == termbox.KeyCtrlC: // exit 120 | return s 121 | case unicode.IsLetter(key.Ch): // character 122 | if s.currentLevel.activeWordIndex == -1 { 123 | for i, word := range s.currentLevel.words { 124 | if word.text[0] == byte(key.Ch) { 125 | s.currentLevel.activeWordIndex = i 126 | s.currentLevel.words[i].cursor = 1 127 | } 128 | } 129 | } else { 130 | aIndex := s.currentLevel.activeWordIndex 131 | activeWord := s.currentLevel.words[aIndex] 132 | if activeWord.text[activeWord.cursor] == byte(key.Ch) { 133 | if len(activeWord.text) == activeWord.cursor+1 { 134 | // remove word 135 | s.currentLevel.words = append(s.currentLevel.words[:aIndex], s.currentLevel.words[aIndex+1:]...) 136 | s.currentLevel.activeWordIndex = -1 137 | if len(s.currentLevel.words) == 0 { 138 | s.newLevel() 139 | } 140 | } else { 141 | s.currentLevel.words[aIndex].cursor++ 142 | } 143 | } 144 | } 145 | } 146 | case <-timer: 147 | width, _ := termbox.Size() 148 | for i := range s.currentLevel.words { 149 | s.currentLevel.words[i].location.x++ 150 | if s.currentLevel.words[i].location.x >= width { 151 | return s 152 | } 153 | } 154 | default: 155 | break 156 | } 157 | gameState <- s 158 | } 159 | } 160 | 161 | func renderLoop(gameState chan state) { 162 | for { 163 | s := <-gameState 164 | 165 | termbox.Clear(termbox.ColorDefault, termbox.ColorDefault) 166 | 167 | if debug { 168 | drawDebugger(s) 169 | } 170 | 171 | drawText(0, 0, fmt.Sprintf("Level #%s", string(strconv.Itoa(s.currentLevel.levelNumber)))) 172 | 173 | for i, word := range s.currentLevel.words { 174 | drawWord(word, i == s.currentLevel.activeWordIndex) 175 | } 176 | 177 | termbox.Flush() 178 | } 179 | } 180 | 181 | func drawWord(w word, active bool) { 182 | runes := []rune(w.text) 183 | for i, r := range runes { 184 | fgColor := termbox.ColorDefault 185 | if i == w.cursor && active { 186 | fgColor = termbox.ColorRed 187 | } 188 | termbox.SetCell(w.location.x+i, w.location.y, r, fgColor, termbox.ColorDefault) 189 | } 190 | } 191 | 192 | func drawDebugger(gameState state) { 193 | i := 0 194 | drawText(0, i, "DEBUG") 195 | i++ 196 | for x, word := range gameState.currentLevel.words { 197 | if x == gameState.currentLevel.activeWordIndex { 198 | drawText(0, i+x, word.text+"*"+string(strconv.Itoa(word.cursor))) 199 | } else { 200 | drawText(0, i+x, word.text) 201 | } 202 | } 203 | } 204 | 205 | func drawText(x int, y int, str string) { 206 | runes := []rune(str) 207 | for i, r := range runes { 208 | termbox.SetCell(x+i, y, r, termbox.ColorRed, termbox.ColorDefault) 209 | } 210 | } 211 | 212 | func eventLoop(e chan termbox.Event) { 213 | for { 214 | e <- termbox.PollEvent() 215 | } 216 | } 217 | 218 | func main() { 219 | isDebug := flag.Bool("debug", false, "true or false") 220 | flag.Parse() 221 | debug = isDebug != nil && *isDebug 222 | 223 | rand.Seed(time.Now().Unix()) 224 | readWords() 225 | err := termbox.Init() 226 | if err != nil { 227 | panic(errors.Wrap(err, "failed to init termbox")) 228 | } 229 | 230 | events := make(chan termbox.Event) 231 | timer := time.Tick(500 * time.Millisecond) 232 | gameState := make(chan state) 233 | 234 | go renderLoop(gameState) 235 | go eventLoop(events) 236 | 237 | finalState := gameLoop(events, timer, gameState) 238 | 239 | exit(events, timer) 240 | fmt.Println(fmt.Sprintf("You reached level %d!", finalState.currentLevel.levelNumber)) 241 | } 242 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/terminfo.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | // This file contains a simple and incomplete implementation of the terminfo 3 | // database. Information was taken from the ncurses manpages term(5) and 4 | // terminfo(5). Currently, only the string capabilities for special keys and for 5 | // functions without parameters are actually used. Colors are still done with 6 | // ANSI escape sequences. Other special features that are not (yet?) supported 7 | // are reading from ~/.terminfo, the TERMINFO_DIRS variable, Berkeley database 8 | // format and extended capabilities. 9 | 10 | package termbox 11 | 12 | import ( 13 | "bytes" 14 | "encoding/binary" 15 | "encoding/hex" 16 | "errors" 17 | "fmt" 18 | "io/ioutil" 19 | "os" 20 | "strings" 21 | ) 22 | 23 | const ( 24 | ti_magic = 0432 25 | ti_header_length = 12 26 | ti_mouse_enter = "\x1b[?1000h\x1b[?1002h\x1b[?1015h\x1b[?1006h" 27 | ti_mouse_leave = "\x1b[?1006l\x1b[?1015l\x1b[?1002l\x1b[?1000l" 28 | ) 29 | 30 | func load_terminfo() ([]byte, error) { 31 | var data []byte 32 | var err error 33 | 34 | term := os.Getenv("TERM") 35 | if term == "" { 36 | return nil, fmt.Errorf("termbox: TERM not set") 37 | } 38 | 39 | // The following behaviour follows the one described in terminfo(5) as 40 | // distributed by ncurses. 41 | 42 | terminfo := os.Getenv("TERMINFO") 43 | if terminfo != "" { 44 | // if TERMINFO is set, no other directory should be searched 45 | return ti_try_path(terminfo) 46 | } 47 | 48 | // next, consider ~/.terminfo 49 | home := os.Getenv("HOME") 50 | if home != "" { 51 | data, err = ti_try_path(home + "/.terminfo") 52 | if err == nil { 53 | return data, nil 54 | } 55 | } 56 | 57 | // next, TERMINFO_DIRS 58 | dirs := os.Getenv("TERMINFO_DIRS") 59 | if dirs != "" { 60 | for _, dir := range strings.Split(dirs, ":") { 61 | if dir == "" { 62 | // "" -> "/usr/share/terminfo" 63 | dir = "/usr/share/terminfo" 64 | } 65 | data, err = ti_try_path(dir) 66 | if err == nil { 67 | return data, nil 68 | } 69 | } 70 | } 71 | 72 | // fall back to /usr/share/terminfo 73 | return ti_try_path("/usr/share/terminfo") 74 | } 75 | 76 | func ti_try_path(path string) (data []byte, err error) { 77 | // load_terminfo already made sure it is set 78 | term := os.Getenv("TERM") 79 | 80 | // first try, the typical *nix path 81 | terminfo := path + "/" + term[0:1] + "/" + term 82 | data, err = ioutil.ReadFile(terminfo) 83 | if err == nil { 84 | return 85 | } 86 | 87 | // fallback to darwin specific dirs structure 88 | terminfo = path + "/" + hex.EncodeToString([]byte(term[:1])) + "/" + term 89 | data, err = ioutil.ReadFile(terminfo) 90 | return 91 | } 92 | 93 | func setup_term_builtin() error { 94 | name := os.Getenv("TERM") 95 | if name == "" { 96 | return errors.New("termbox: TERM environment variable not set") 97 | } 98 | 99 | for _, t := range terms { 100 | if t.name == name { 101 | keys = t.keys 102 | funcs = t.funcs 103 | return nil 104 | } 105 | } 106 | 107 | compat_table := []struct { 108 | partial string 109 | keys []string 110 | funcs []string 111 | }{ 112 | {"xterm", xterm_keys, xterm_funcs}, 113 | {"rxvt", rxvt_unicode_keys, rxvt_unicode_funcs}, 114 | {"linux", linux_keys, linux_funcs}, 115 | {"Eterm", eterm_keys, eterm_funcs}, 116 | {"screen", screen_keys, screen_funcs}, 117 | // let's assume that 'cygwin' is xterm compatible 118 | {"cygwin", xterm_keys, xterm_funcs}, 119 | {"st", xterm_keys, xterm_funcs}, 120 | } 121 | 122 | // try compatibility variants 123 | for _, it := range compat_table { 124 | if strings.Contains(name, it.partial) { 125 | keys = it.keys 126 | funcs = it.funcs 127 | return nil 128 | } 129 | } 130 | 131 | return errors.New("termbox: unsupported terminal") 132 | } 133 | 134 | func setup_term() (err error) { 135 | var data []byte 136 | var header [6]int16 137 | var str_offset, table_offset int16 138 | 139 | data, err = load_terminfo() 140 | if err != nil { 141 | return setup_term_builtin() 142 | } 143 | 144 | rd := bytes.NewReader(data) 145 | // 0: magic number, 1: size of names section, 2: size of boolean section, 3: 146 | // size of numbers section (in integers), 4: size of the strings section (in 147 | // integers), 5: size of the string table 148 | 149 | err = binary.Read(rd, binary.LittleEndian, header[:]) 150 | if err != nil { 151 | return 152 | } 153 | 154 | if (header[1]+header[2])%2 != 0 { 155 | // old quirk to align everything on word boundaries 156 | header[2] += 1 157 | } 158 | str_offset = ti_header_length + header[1] + header[2] + 2*header[3] 159 | table_offset = str_offset + 2*header[4] 160 | 161 | keys = make([]string, 0xFFFF-key_min) 162 | for i, _ := range keys { 163 | keys[i], err = ti_read_string(rd, str_offset+2*ti_keys[i], table_offset) 164 | if err != nil { 165 | return 166 | } 167 | } 168 | funcs = make([]string, t_max_funcs) 169 | // the last two entries are reserved for mouse. because the table offset is 170 | // not there, the two entries have to fill in manually 171 | for i, _ := range funcs[:len(funcs)-2] { 172 | funcs[i], err = ti_read_string(rd, str_offset+2*ti_funcs[i], table_offset) 173 | if err != nil { 174 | return 175 | } 176 | } 177 | funcs[t_max_funcs-2] = ti_mouse_enter 178 | funcs[t_max_funcs-1] = ti_mouse_leave 179 | return nil 180 | } 181 | 182 | func ti_read_string(rd *bytes.Reader, str_off, table int16) (string, error) { 183 | var off int16 184 | 185 | _, err := rd.Seek(int64(str_off), 0) 186 | if err != nil { 187 | return "", err 188 | } 189 | err = binary.Read(rd, binary.LittleEndian, &off) 190 | if err != nil { 191 | return "", err 192 | } 193 | _, err = rd.Seek(int64(table+off), 0) 194 | if err != nil { 195 | return "", err 196 | } 197 | var bs []byte 198 | for { 199 | b, err := rd.ReadByte() 200 | if err != nil { 201 | return "", err 202 | } 203 | if b == byte(0x00) { 204 | break 205 | } 206 | bs = append(bs, b) 207 | } 208 | return string(bs), nil 209 | } 210 | 211 | // "Maps" the function constants from termbox.go to the number of the respective 212 | // string capability in the terminfo file. Taken from (ncurses) term.h. 213 | var ti_funcs = []int16{ 214 | 28, 40, 16, 13, 5, 39, 36, 27, 26, 34, 89, 88, 215 | } 216 | 217 | // Same as above for the special keys. 218 | var ti_keys = []int16{ 219 | 66, 68 /* apparently not a typo; 67 is F10 for whatever reason */, 69, 70, 220 | 71, 72, 73, 74, 75, 67, 216, 217, 77, 59, 76, 164, 82, 81, 87, 61, 79, 83, 221 | } 222 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/api_windows.go: -------------------------------------------------------------------------------- 1 | package termbox 2 | 3 | import ( 4 | "syscall" 5 | ) 6 | 7 | // public API 8 | 9 | // Initializes termbox library. This function should be called before any other functions. 10 | // After successful initialization, the library must be finalized using 'Close' function. 11 | // 12 | // Example usage: 13 | // err := termbox.Init() 14 | // if err != nil { 15 | // panic(err) 16 | // } 17 | // defer termbox.Close() 18 | func Init() error { 19 | var err error 20 | 21 | interrupt, err = create_event() 22 | if err != nil { 23 | return err 24 | } 25 | 26 | in, err = syscall.Open("CONIN$", syscall.O_RDWR, 0) 27 | if err != nil { 28 | return err 29 | } 30 | out, err = syscall.Open("CONOUT$", syscall.O_RDWR, 0) 31 | if err != nil { 32 | return err 33 | } 34 | 35 | err = get_console_mode(in, &orig_mode) 36 | if err != nil { 37 | return err 38 | } 39 | 40 | err = set_console_mode(in, enable_window_input) 41 | if err != nil { 42 | return err 43 | } 44 | 45 | orig_size = get_term_size(out) 46 | win_size := get_win_size(out) 47 | 48 | err = set_console_screen_buffer_size(out, win_size) 49 | if err != nil { 50 | return err 51 | } 52 | 53 | err = get_console_cursor_info(out, &orig_cursor_info) 54 | if err != nil { 55 | return err 56 | } 57 | 58 | show_cursor(false) 59 | term_size = get_term_size(out) 60 | back_buffer.init(int(term_size.x), int(term_size.y)) 61 | front_buffer.init(int(term_size.x), int(term_size.y)) 62 | back_buffer.clear() 63 | front_buffer.clear() 64 | clear() 65 | 66 | diffbuf = make([]diff_msg, 0, 32) 67 | 68 | go input_event_producer() 69 | IsInit = true 70 | return nil 71 | } 72 | 73 | // Finalizes termbox library, should be called after successful initialization 74 | // when termbox's functionality isn't required anymore. 75 | func Close() { 76 | // we ignore errors here, because we can't really do anything about them 77 | Clear(0, 0) 78 | Flush() 79 | 80 | // stop event producer 81 | cancel_comm <- true 82 | set_event(interrupt) 83 | select { 84 | case <-input_comm: 85 | default: 86 | } 87 | <-cancel_done_comm 88 | 89 | set_console_cursor_info(out, &orig_cursor_info) 90 | set_console_cursor_position(out, coord{}) 91 | set_console_screen_buffer_size(out, orig_size) 92 | set_console_mode(in, orig_mode) 93 | syscall.Close(in) 94 | syscall.Close(out) 95 | syscall.Close(interrupt) 96 | IsInit = false 97 | } 98 | 99 | // Interrupt an in-progress call to PollEvent by causing it to return 100 | // EventInterrupt. Note that this function will block until the PollEvent 101 | // function has successfully been interrupted. 102 | func Interrupt() { 103 | interrupt_comm <- struct{}{} 104 | } 105 | 106 | // Synchronizes the internal back buffer with the terminal. 107 | func Flush() error { 108 | update_size_maybe() 109 | prepare_diff_messages() 110 | for _, diff := range diffbuf { 111 | r := small_rect{ 112 | left: 0, 113 | top: diff.pos, 114 | right: term_size.x - 1, 115 | bottom: diff.pos + diff.lines - 1, 116 | } 117 | write_console_output(out, diff.chars, r) 118 | } 119 | if !is_cursor_hidden(cursor_x, cursor_y) { 120 | move_cursor(cursor_x, cursor_y) 121 | } 122 | return nil 123 | } 124 | 125 | // Sets the position of the cursor. See also HideCursor(). 126 | func SetCursor(x, y int) { 127 | if is_cursor_hidden(cursor_x, cursor_y) && !is_cursor_hidden(x, y) { 128 | show_cursor(true) 129 | } 130 | 131 | if !is_cursor_hidden(cursor_x, cursor_y) && is_cursor_hidden(x, y) { 132 | show_cursor(false) 133 | } 134 | 135 | cursor_x, cursor_y = x, y 136 | if !is_cursor_hidden(cursor_x, cursor_y) { 137 | move_cursor(cursor_x, cursor_y) 138 | } 139 | } 140 | 141 | // The shortcut for SetCursor(-1, -1). 142 | func HideCursor() { 143 | SetCursor(cursor_hidden, cursor_hidden) 144 | } 145 | 146 | // Changes cell's parameters in the internal back buffer at the specified 147 | // position. 148 | func SetCell(x, y int, ch rune, fg, bg Attribute) { 149 | if x < 0 || x >= back_buffer.width { 150 | return 151 | } 152 | if y < 0 || y >= back_buffer.height { 153 | return 154 | } 155 | 156 | back_buffer.cells[y*back_buffer.width+x] = Cell{ch, fg, bg} 157 | } 158 | 159 | // Returns a slice into the termbox's back buffer. You can get its dimensions 160 | // using 'Size' function. The slice remains valid as long as no 'Clear' or 161 | // 'Flush' function calls were made after call to this function. 162 | func CellBuffer() []Cell { 163 | return back_buffer.cells 164 | } 165 | 166 | // Wait for an event and return it. This is a blocking function call. 167 | func PollEvent() Event { 168 | select { 169 | case ev := <-input_comm: 170 | return ev 171 | case <-interrupt_comm: 172 | return Event{Type: EventInterrupt} 173 | } 174 | } 175 | 176 | // Returns the size of the internal back buffer (which is mostly the same as 177 | // console's window size in characters). But it doesn't always match the size 178 | // of the console window, after the console size has changed, the internal back 179 | // buffer will get in sync only after Clear or Flush function calls. 180 | func Size() (int, int) { 181 | return int(term_size.x), int(term_size.y) 182 | } 183 | 184 | // Clears the internal back buffer. 185 | func Clear(fg, bg Attribute) error { 186 | foreground, background = fg, bg 187 | update_size_maybe() 188 | back_buffer.clear() 189 | return nil 190 | } 191 | 192 | // Sets termbox input mode. Termbox has two input modes: 193 | // 194 | // 1. Esc input mode. When ESC sequence is in the buffer and it doesn't match 195 | // any known sequence. ESC means KeyEsc. This is the default input mode. 196 | // 197 | // 2. Alt input mode. When ESC sequence is in the buffer and it doesn't match 198 | // any known sequence. ESC enables ModAlt modifier for the next keyboard event. 199 | // 200 | // Both input modes can be OR'ed with Mouse mode. Setting Mouse mode bit up will 201 | // enable mouse button press/release and drag events. 202 | // 203 | // If 'mode' is InputCurrent, returns the current input mode. See also Input* 204 | // constants. 205 | func SetInputMode(mode InputMode) InputMode { 206 | if mode == InputCurrent { 207 | return input_mode 208 | } 209 | if mode&InputMouse != 0 { 210 | err := set_console_mode(in, enable_window_input|enable_mouse_input|enable_extended_flags) 211 | if err != nil { 212 | panic(err) 213 | } 214 | } else { 215 | err := set_console_mode(in, enable_window_input) 216 | if err != nil { 217 | panic(err) 218 | } 219 | } 220 | 221 | input_mode = mode 222 | return input_mode 223 | } 224 | 225 | // Sets the termbox output mode. 226 | // 227 | // Windows console does not support extra colour modes, 228 | // so this will always set and return OutputNormal. 229 | func SetOutputMode(mode OutputMode) OutputMode { 230 | return OutputNormal 231 | } 232 | 233 | // Sync comes handy when something causes desync between termbox's understanding 234 | // of a terminal buffer and the reality. Such as a third party process. Sync 235 | // forces a complete resync between the termbox and a terminal, it may not be 236 | // visually pretty though. At the moment on Windows it does nothing. 237 | func Sync() error { 238 | return nil 239 | } 240 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/errors/errors.go: -------------------------------------------------------------------------------- 1 | // Package errors provides simple error handling primitives. 2 | // 3 | // The traditional error handling idiom in Go is roughly akin to 4 | // 5 | // if err != nil { 6 | // return err 7 | // } 8 | // 9 | // which applied recursively up the call stack results in error reports 10 | // without context or debugging information. The errors package allows 11 | // programmers to add context to the failure path in their code in a way 12 | // that does not destroy the original value of the error. 13 | // 14 | // Adding context to an error 15 | // 16 | // The errors.Wrap function returns a new error that adds context to the 17 | // original error by recording a stack trace at the point Wrap is called, 18 | // and the supplied message. For example 19 | // 20 | // _, err := ioutil.ReadAll(r) 21 | // if err != nil { 22 | // return errors.Wrap(err, "read failed") 23 | // } 24 | // 25 | // If additional control is required the errors.WithStack and errors.WithMessage 26 | // functions destructure errors.Wrap into its component operations of annotating 27 | // an error with a stack trace and an a message, respectively. 28 | // 29 | // Retrieving the cause of an error 30 | // 31 | // Using errors.Wrap constructs a stack of errors, adding context to the 32 | // preceding error. Depending on the nature of the error it may be necessary 33 | // to reverse the operation of errors.Wrap to retrieve the original error 34 | // for inspection. Any error value which implements this interface 35 | // 36 | // type causer interface { 37 | // Cause() error 38 | // } 39 | // 40 | // can be inspected by errors.Cause. errors.Cause will recursively retrieve 41 | // the topmost error which does not implement causer, which is assumed to be 42 | // the original cause. For example: 43 | // 44 | // switch err := errors.Cause(err).(type) { 45 | // case *MyError: 46 | // // handle specifically 47 | // default: 48 | // // unknown error 49 | // } 50 | // 51 | // causer interface is not exported by this package, but is considered a part 52 | // of stable public API. 53 | // 54 | // Formatted printing of errors 55 | // 56 | // All error values returned from this package implement fmt.Formatter and can 57 | // be formatted by the fmt package. The following verbs are supported 58 | // 59 | // %s print the error. If the error has a Cause it will be 60 | // printed recursively 61 | // %v see %s 62 | // %+v extended format. Each Frame of the error's StackTrace will 63 | // be printed in detail. 64 | // 65 | // Retrieving the stack trace of an error or wrapper 66 | // 67 | // New, Errorf, Wrap, and Wrapf record a stack trace at the point they are 68 | // invoked. This information can be retrieved with the following interface. 69 | // 70 | // type stackTracer interface { 71 | // StackTrace() errors.StackTrace 72 | // } 73 | // 74 | // Where errors.StackTrace is defined as 75 | // 76 | // type StackTrace []Frame 77 | // 78 | // The Frame type represents a call site in the stack trace. Frame supports 79 | // the fmt.Formatter interface that can be used for printing information about 80 | // the stack trace of this error. For example: 81 | // 82 | // if err, ok := err.(stackTracer); ok { 83 | // for _, f := range err.StackTrace() { 84 | // fmt.Printf("%+s:%d", f) 85 | // } 86 | // } 87 | // 88 | // stackTracer interface is not exported by this package, but is considered a part 89 | // of stable public API. 90 | // 91 | // See the documentation for Frame.Format for more details. 92 | package errors 93 | 94 | import ( 95 | "fmt" 96 | "io" 97 | ) 98 | 99 | // New returns an error with the supplied message. 100 | // New also records the stack trace at the point it was called. 101 | func New(message string) error { 102 | return &fundamental{ 103 | msg: message, 104 | stack: callers(), 105 | } 106 | } 107 | 108 | // Errorf formats according to a format specifier and returns the string 109 | // as a value that satisfies error. 110 | // Errorf also records the stack trace at the point it was called. 111 | func Errorf(format string, args ...interface{}) error { 112 | return &fundamental{ 113 | msg: fmt.Sprintf(format, args...), 114 | stack: callers(), 115 | } 116 | } 117 | 118 | // fundamental is an error that has a message and a stack, but no caller. 119 | type fundamental struct { 120 | msg string 121 | *stack 122 | } 123 | 124 | func (f *fundamental) Error() string { return f.msg } 125 | 126 | func (f *fundamental) Format(s fmt.State, verb rune) { 127 | switch verb { 128 | case 'v': 129 | if s.Flag('+') { 130 | io.WriteString(s, f.msg) 131 | f.stack.Format(s, verb) 132 | return 133 | } 134 | fallthrough 135 | case 's': 136 | io.WriteString(s, f.msg) 137 | case 'q': 138 | fmt.Fprintf(s, "%q", f.msg) 139 | } 140 | } 141 | 142 | // WithStack annotates err with a stack trace at the point WithStack was called. 143 | // If err is nil, WithStack returns nil. 144 | func WithStack(err error) error { 145 | if err == nil { 146 | return nil 147 | } 148 | return &withStack{ 149 | err, 150 | callers(), 151 | } 152 | } 153 | 154 | type withStack struct { 155 | error 156 | *stack 157 | } 158 | 159 | func (w *withStack) Cause() error { return w.error } 160 | 161 | func (w *withStack) Format(s fmt.State, verb rune) { 162 | switch verb { 163 | case 'v': 164 | if s.Flag('+') { 165 | fmt.Fprintf(s, "%+v", w.Cause()) 166 | w.stack.Format(s, verb) 167 | return 168 | } 169 | fallthrough 170 | case 's': 171 | io.WriteString(s, w.Error()) 172 | case 'q': 173 | fmt.Fprintf(s, "%q", w.Error()) 174 | } 175 | } 176 | 177 | // Wrap returns an error annotating err with a stack trace 178 | // at the point Wrap is called, and the supplied message. 179 | // If err is nil, Wrap returns nil. 180 | func Wrap(err error, message string) error { 181 | if err == nil { 182 | return nil 183 | } 184 | err = &withMessage{ 185 | cause: err, 186 | msg: message, 187 | } 188 | return &withStack{ 189 | err, 190 | callers(), 191 | } 192 | } 193 | 194 | // Wrapf returns an error annotating err with a stack trace 195 | // at the point Wrapf is call, and the format specifier. 196 | // If err is nil, Wrapf returns nil. 197 | func Wrapf(err error, format string, args ...interface{}) error { 198 | if err == nil { 199 | return nil 200 | } 201 | err = &withMessage{ 202 | cause: err, 203 | msg: fmt.Sprintf(format, args...), 204 | } 205 | return &withStack{ 206 | err, 207 | callers(), 208 | } 209 | } 210 | 211 | // WithMessage annotates err with a new message. 212 | // If err is nil, WithMessage returns nil. 213 | func WithMessage(err error, message string) error { 214 | if err == nil { 215 | return nil 216 | } 217 | return &withMessage{ 218 | cause: err, 219 | msg: message, 220 | } 221 | } 222 | 223 | type withMessage struct { 224 | cause error 225 | msg string 226 | } 227 | 228 | func (w *withMessage) Error() string { return w.msg + ": " + w.cause.Error() } 229 | func (w *withMessage) Cause() error { return w.cause } 230 | 231 | func (w *withMessage) Format(s fmt.State, verb rune) { 232 | switch verb { 233 | case 'v': 234 | if s.Flag('+') { 235 | fmt.Fprintf(s, "%+v\n", w.Cause()) 236 | io.WriteString(s, w.msg) 237 | return 238 | } 239 | fallthrough 240 | case 's', 'q': 241 | io.WriteString(s, w.Error()) 242 | } 243 | } 244 | 245 | // Cause returns the underlying cause of the error, if possible. 246 | // An error value has a cause if it implements the following 247 | // interface: 248 | // 249 | // type causer interface { 250 | // Cause() error 251 | // } 252 | // 253 | // If the error does not implement Cause, the original error will 254 | // be returned. If the error is nil, nil will be returned without further 255 | // investigation. 256 | func Cause(err error) error { 257 | type causer interface { 258 | Cause() error 259 | } 260 | 261 | for err != nil { 262 | cause, ok := err.(causer) 263 | if !ok { 264 | break 265 | } 266 | err = cause.Cause() 267 | } 268 | return err 269 | } 270 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/termbox.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package termbox 4 | 5 | import "unicode/utf8" 6 | import "bytes" 7 | import "syscall" 8 | import "unsafe" 9 | import "strings" 10 | import "strconv" 11 | import "os" 12 | import "io" 13 | 14 | // private API 15 | 16 | const ( 17 | t_enter_ca = iota 18 | t_exit_ca 19 | t_show_cursor 20 | t_hide_cursor 21 | t_clear_screen 22 | t_sgr0 23 | t_underline 24 | t_bold 25 | t_blink 26 | t_reverse 27 | t_enter_keypad 28 | t_exit_keypad 29 | t_enter_mouse 30 | t_exit_mouse 31 | t_max_funcs 32 | ) 33 | 34 | const ( 35 | coord_invalid = -2 36 | attr_invalid = Attribute(0xFFFF) 37 | ) 38 | 39 | type input_event struct { 40 | data []byte 41 | err error 42 | } 43 | 44 | type extract_event_res int 45 | 46 | const ( 47 | event_not_extracted extract_event_res = iota 48 | event_extracted 49 | esc_wait 50 | ) 51 | 52 | var ( 53 | // term specific sequences 54 | keys []string 55 | funcs []string 56 | 57 | // termbox inner state 58 | orig_tios syscall_Termios 59 | back_buffer cellbuf 60 | front_buffer cellbuf 61 | termw int 62 | termh int 63 | input_mode = InputEsc 64 | output_mode = OutputNormal 65 | out *os.File 66 | in int 67 | lastfg = attr_invalid 68 | lastbg = attr_invalid 69 | lastx = coord_invalid 70 | lasty = coord_invalid 71 | cursor_x = cursor_hidden 72 | cursor_y = cursor_hidden 73 | foreground = ColorDefault 74 | background = ColorDefault 75 | inbuf = make([]byte, 0, 64) 76 | outbuf bytes.Buffer 77 | sigwinch = make(chan os.Signal, 1) 78 | sigio = make(chan os.Signal, 1) 79 | quit = make(chan int) 80 | input_comm = make(chan input_event) 81 | interrupt_comm = make(chan struct{}) 82 | intbuf = make([]byte, 0, 16) 83 | 84 | // grayscale indexes 85 | grayscale = []Attribute{ 86 | 0, 17, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 87 | 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 232, 88 | } 89 | ) 90 | 91 | func write_cursor(x, y int) { 92 | outbuf.WriteString("\033[") 93 | outbuf.Write(strconv.AppendUint(intbuf, uint64(y+1), 10)) 94 | outbuf.WriteString(";") 95 | outbuf.Write(strconv.AppendUint(intbuf, uint64(x+1), 10)) 96 | outbuf.WriteString("H") 97 | } 98 | 99 | func write_sgr_fg(a Attribute) { 100 | switch output_mode { 101 | case Output256, Output216, OutputGrayscale: 102 | outbuf.WriteString("\033[38;5;") 103 | outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10)) 104 | outbuf.WriteString("m") 105 | default: 106 | outbuf.WriteString("\033[3") 107 | outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10)) 108 | outbuf.WriteString("m") 109 | } 110 | } 111 | 112 | func write_sgr_bg(a Attribute) { 113 | switch output_mode { 114 | case Output256, Output216, OutputGrayscale: 115 | outbuf.WriteString("\033[48;5;") 116 | outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10)) 117 | outbuf.WriteString("m") 118 | default: 119 | outbuf.WriteString("\033[4") 120 | outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10)) 121 | outbuf.WriteString("m") 122 | } 123 | } 124 | 125 | func write_sgr(fg, bg Attribute) { 126 | switch output_mode { 127 | case Output256, Output216, OutputGrayscale: 128 | outbuf.WriteString("\033[38;5;") 129 | outbuf.Write(strconv.AppendUint(intbuf, uint64(fg-1), 10)) 130 | outbuf.WriteString("m") 131 | outbuf.WriteString("\033[48;5;") 132 | outbuf.Write(strconv.AppendUint(intbuf, uint64(bg-1), 10)) 133 | outbuf.WriteString("m") 134 | default: 135 | outbuf.WriteString("\033[3") 136 | outbuf.Write(strconv.AppendUint(intbuf, uint64(fg-1), 10)) 137 | outbuf.WriteString(";4") 138 | outbuf.Write(strconv.AppendUint(intbuf, uint64(bg-1), 10)) 139 | outbuf.WriteString("m") 140 | } 141 | } 142 | 143 | type winsize struct { 144 | rows uint16 145 | cols uint16 146 | xpixels uint16 147 | ypixels uint16 148 | } 149 | 150 | func get_term_size(fd uintptr) (int, int) { 151 | var sz winsize 152 | _, _, _ = syscall.Syscall(syscall.SYS_IOCTL, 153 | fd, uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&sz))) 154 | return int(sz.cols), int(sz.rows) 155 | } 156 | 157 | func send_attr(fg, bg Attribute) { 158 | if fg == lastfg && bg == lastbg { 159 | return 160 | } 161 | 162 | outbuf.WriteString(funcs[t_sgr0]) 163 | 164 | var fgcol, bgcol Attribute 165 | 166 | switch output_mode { 167 | case Output256: 168 | fgcol = fg & 0x1FF 169 | bgcol = bg & 0x1FF 170 | case Output216: 171 | fgcol = fg & 0xFF 172 | bgcol = bg & 0xFF 173 | if fgcol > 216 { 174 | fgcol = ColorDefault 175 | } 176 | if bgcol > 216 { 177 | bgcol = ColorDefault 178 | } 179 | if fgcol != ColorDefault { 180 | fgcol += 0x10 181 | } 182 | if bgcol != ColorDefault { 183 | bgcol += 0x10 184 | } 185 | case OutputGrayscale: 186 | fgcol = fg & 0x1F 187 | bgcol = bg & 0x1F 188 | if fgcol > 26 { 189 | fgcol = ColorDefault 190 | } 191 | if bgcol > 26 { 192 | bgcol = ColorDefault 193 | } 194 | if fgcol != ColorDefault { 195 | fgcol = grayscale[fgcol] 196 | } 197 | if bgcol != ColorDefault { 198 | bgcol = grayscale[bgcol] 199 | } 200 | default: 201 | fgcol = fg & 0x0F 202 | bgcol = bg & 0x0F 203 | } 204 | 205 | if fgcol != ColorDefault { 206 | if bgcol != ColorDefault { 207 | write_sgr(fgcol, bgcol) 208 | } else { 209 | write_sgr_fg(fgcol) 210 | } 211 | } else if bgcol != ColorDefault { 212 | write_sgr_bg(bgcol) 213 | } 214 | 215 | if fg&AttrBold != 0 { 216 | outbuf.WriteString(funcs[t_bold]) 217 | } 218 | if bg&AttrBold != 0 { 219 | outbuf.WriteString(funcs[t_blink]) 220 | } 221 | if fg&AttrUnderline != 0 { 222 | outbuf.WriteString(funcs[t_underline]) 223 | } 224 | if fg&AttrReverse|bg&AttrReverse != 0 { 225 | outbuf.WriteString(funcs[t_reverse]) 226 | } 227 | 228 | lastfg, lastbg = fg, bg 229 | } 230 | 231 | func send_char(x, y int, ch rune) { 232 | var buf [8]byte 233 | n := utf8.EncodeRune(buf[:], ch) 234 | if x-1 != lastx || y != lasty { 235 | write_cursor(x, y) 236 | } 237 | lastx, lasty = x, y 238 | outbuf.Write(buf[:n]) 239 | } 240 | 241 | func flush() error { 242 | _, err := io.Copy(out, &outbuf) 243 | outbuf.Reset() 244 | return err 245 | } 246 | 247 | func send_clear() error { 248 | send_attr(foreground, background) 249 | outbuf.WriteString(funcs[t_clear_screen]) 250 | if !is_cursor_hidden(cursor_x, cursor_y) { 251 | write_cursor(cursor_x, cursor_y) 252 | } 253 | 254 | // we need to invalidate cursor position too and these two vars are 255 | // used only for simple cursor positioning optimization, cursor 256 | // actually may be in the correct place, but we simply discard 257 | // optimization once and it gives us simple solution for the case when 258 | // cursor moved 259 | lastx = coord_invalid 260 | lasty = coord_invalid 261 | 262 | return flush() 263 | } 264 | 265 | func update_size_maybe() error { 266 | w, h := get_term_size(out.Fd()) 267 | if w != termw || h != termh { 268 | termw, termh = w, h 269 | back_buffer.resize(termw, termh) 270 | front_buffer.resize(termw, termh) 271 | front_buffer.clear() 272 | return send_clear() 273 | } 274 | return nil 275 | } 276 | 277 | func tcsetattr(fd uintptr, termios *syscall_Termios) error { 278 | r, _, e := syscall.Syscall(syscall.SYS_IOCTL, 279 | fd, uintptr(syscall_TCSETS), uintptr(unsafe.Pointer(termios))) 280 | if r != 0 { 281 | return os.NewSyscallError("SYS_IOCTL", e) 282 | } 283 | return nil 284 | } 285 | 286 | func tcgetattr(fd uintptr, termios *syscall_Termios) error { 287 | r, _, e := syscall.Syscall(syscall.SYS_IOCTL, 288 | fd, uintptr(syscall_TCGETS), uintptr(unsafe.Pointer(termios))) 289 | if r != 0 { 290 | return os.NewSyscallError("SYS_IOCTL", e) 291 | } 292 | return nil 293 | } 294 | 295 | func parse_mouse_event(event *Event, buf string) (int, bool) { 296 | if strings.HasPrefix(buf, "\033[M") && len(buf) >= 6 { 297 | // X10 mouse encoding, the simplest one 298 | // \033 [ M Cb Cx Cy 299 | b := buf[3] - 32 300 | switch b & 3 { 301 | case 0: 302 | if b&64 != 0 { 303 | event.Key = MouseWheelUp 304 | } else { 305 | event.Key = MouseLeft 306 | } 307 | case 1: 308 | if b&64 != 0 { 309 | event.Key = MouseWheelDown 310 | } else { 311 | event.Key = MouseMiddle 312 | } 313 | case 2: 314 | event.Key = MouseRight 315 | case 3: 316 | event.Key = MouseRelease 317 | default: 318 | return 6, false 319 | } 320 | event.Type = EventMouse // KeyEvent by default 321 | if b&32 != 0 { 322 | event.Mod |= ModMotion 323 | } 324 | 325 | // the coord is 1,1 for upper left 326 | event.MouseX = int(buf[4]) - 1 - 32 327 | event.MouseY = int(buf[5]) - 1 - 32 328 | return 6, true 329 | } else if strings.HasPrefix(buf, "\033[<") || strings.HasPrefix(buf, "\033[") { 330 | // xterm 1006 extended mode or urxvt 1015 extended mode 331 | // xterm: \033 [ < Cb ; Cx ; Cy (M or m) 332 | // urxvt: \033 [ Cb ; Cx ; Cy M 333 | 334 | // find the first M or m, that's where we stop 335 | mi := strings.IndexAny(buf, "Mm") 336 | if mi == -1 { 337 | return 0, false 338 | } 339 | 340 | // whether it's a capital M or not 341 | isM := buf[mi] == 'M' 342 | 343 | // whether it's urxvt or not 344 | isU := false 345 | 346 | // buf[2] is safe here, because having M or m found means we have at 347 | // least 3 bytes in a string 348 | if buf[2] == '<' { 349 | buf = buf[3:mi] 350 | } else { 351 | isU = true 352 | buf = buf[2:mi] 353 | } 354 | 355 | s1 := strings.Index(buf, ";") 356 | s2 := strings.LastIndex(buf, ";") 357 | // not found or only one ';' 358 | if s1 == -1 || s2 == -1 || s1 == s2 { 359 | return 0, false 360 | } 361 | 362 | n1, err := strconv.ParseInt(buf[0:s1], 10, 64) 363 | if err != nil { 364 | return 0, false 365 | } 366 | n2, err := strconv.ParseInt(buf[s1+1:s2], 10, 64) 367 | if err != nil { 368 | return 0, false 369 | } 370 | n3, err := strconv.ParseInt(buf[s2+1:], 10, 64) 371 | if err != nil { 372 | return 0, false 373 | } 374 | 375 | // on urxvt, first number is encoded exactly as in X10, but we need to 376 | // make it zero-based, on xterm it is zero-based already 377 | if isU { 378 | n1 -= 32 379 | } 380 | switch n1 & 3 { 381 | case 0: 382 | if n1&64 != 0 { 383 | event.Key = MouseWheelUp 384 | } else { 385 | event.Key = MouseLeft 386 | } 387 | case 1: 388 | if n1&64 != 0 { 389 | event.Key = MouseWheelDown 390 | } else { 391 | event.Key = MouseMiddle 392 | } 393 | case 2: 394 | event.Key = MouseRight 395 | case 3: 396 | event.Key = MouseRelease 397 | default: 398 | return mi + 1, false 399 | } 400 | if !isM { 401 | // on xterm mouse release is signaled by lowercase m 402 | event.Key = MouseRelease 403 | } 404 | 405 | event.Type = EventMouse // KeyEvent by default 406 | if n1&32 != 0 { 407 | event.Mod |= ModMotion 408 | } 409 | 410 | event.MouseX = int(n2) - 1 411 | event.MouseY = int(n3) - 1 412 | return mi + 1, true 413 | } 414 | 415 | return 0, false 416 | } 417 | 418 | func parse_escape_sequence(event *Event, buf []byte) (int, bool) { 419 | bufstr := string(buf) 420 | for i, key := range keys { 421 | if strings.HasPrefix(bufstr, key) { 422 | event.Ch = 0 423 | event.Key = Key(0xFFFF - i) 424 | return len(key), true 425 | } 426 | } 427 | 428 | // if none of the keys match, let's try mouse sequences 429 | return parse_mouse_event(event, bufstr) 430 | } 431 | 432 | func extract_raw_event(data []byte, event *Event) bool { 433 | if len(inbuf) == 0 { 434 | return false 435 | } 436 | 437 | n := len(data) 438 | if n == 0 { 439 | return false 440 | } 441 | 442 | n = copy(data, inbuf) 443 | copy(inbuf, inbuf[n:]) 444 | inbuf = inbuf[:len(inbuf)-n] 445 | 446 | event.N = n 447 | event.Type = EventRaw 448 | return true 449 | } 450 | 451 | func extract_event(inbuf []byte, event *Event, allow_esc_wait bool) extract_event_res { 452 | if len(inbuf) == 0 { 453 | event.N = 0 454 | return event_not_extracted 455 | } 456 | 457 | if inbuf[0] == '\033' { 458 | // possible escape sequence 459 | if n, ok := parse_escape_sequence(event, inbuf); n != 0 { 460 | event.N = n 461 | if ok { 462 | return event_extracted 463 | } else { 464 | return event_not_extracted 465 | } 466 | } 467 | 468 | // possible partially read escape sequence; trigger a wait if appropriate 469 | if enable_wait_for_escape_sequence() && allow_esc_wait { 470 | event.N = 0 471 | return esc_wait 472 | } 473 | 474 | // it's not escape sequence, then it's Alt or Esc, check input_mode 475 | switch { 476 | case input_mode&InputEsc != 0: 477 | // if we're in escape mode, fill Esc event, pop buffer, return success 478 | event.Ch = 0 479 | event.Key = KeyEsc 480 | event.Mod = 0 481 | event.N = 1 482 | return event_extracted 483 | case input_mode&InputAlt != 0: 484 | // if we're in alt mode, set Alt modifier to event and redo parsing 485 | event.Mod = ModAlt 486 | status := extract_event(inbuf[1:], event, false) 487 | if status == event_extracted { 488 | event.N++ 489 | } else { 490 | event.N = 0 491 | } 492 | return status 493 | default: 494 | panic("unreachable") 495 | } 496 | } 497 | 498 | // if we're here, this is not an escape sequence and not an alt sequence 499 | // so, it's a FUNCTIONAL KEY or a UNICODE character 500 | 501 | // first of all check if it's a functional key 502 | if Key(inbuf[0]) <= KeySpace || Key(inbuf[0]) == KeyBackspace2 { 503 | // fill event, pop buffer, return success 504 | event.Ch = 0 505 | event.Key = Key(inbuf[0]) 506 | event.N = 1 507 | return event_extracted 508 | } 509 | 510 | // the only possible option is utf8 rune 511 | if r, n := utf8.DecodeRune(inbuf); r != utf8.RuneError { 512 | event.Ch = r 513 | event.Key = 0 514 | event.N = n 515 | return event_extracted 516 | } 517 | 518 | return event_not_extracted 519 | } 520 | 521 | func fcntl(fd int, cmd int, arg int) (val int, err error) { 522 | r, _, e := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), uintptr(cmd), 523 | uintptr(arg)) 524 | val = int(r) 525 | if e != 0 { 526 | err = e 527 | } 528 | return 529 | } 530 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/api.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package termbox 4 | 5 | import "github.com/mattn/go-runewidth" 6 | import "fmt" 7 | import "os" 8 | import "os/signal" 9 | import "syscall" 10 | import "runtime" 11 | import "time" 12 | 13 | // public API 14 | 15 | // Initializes termbox library. This function should be called before any other functions. 16 | // After successful initialization, the library must be finalized using 'Close' function. 17 | // 18 | // Example usage: 19 | // err := termbox.Init() 20 | // if err != nil { 21 | // panic(err) 22 | // } 23 | // defer termbox.Close() 24 | func Init() error { 25 | var err error 26 | 27 | out, err = os.OpenFile("/dev/tty", syscall.O_WRONLY, 0) 28 | if err != nil { 29 | return err 30 | } 31 | in, err = syscall.Open("/dev/tty", syscall.O_RDONLY, 0) 32 | if err != nil { 33 | return err 34 | } 35 | 36 | err = setup_term() 37 | if err != nil { 38 | return fmt.Errorf("termbox: error while reading terminfo data: %v", err) 39 | } 40 | 41 | signal.Notify(sigwinch, syscall.SIGWINCH) 42 | signal.Notify(sigio, syscall.SIGIO) 43 | 44 | _, err = fcntl(in, syscall.F_SETFL, syscall.O_ASYNC|syscall.O_NONBLOCK) 45 | if err != nil { 46 | return err 47 | } 48 | _, err = fcntl(in, syscall.F_SETOWN, syscall.Getpid()) 49 | if runtime.GOOS != "darwin" && err != nil { 50 | return err 51 | } 52 | err = tcgetattr(out.Fd(), &orig_tios) 53 | if err != nil { 54 | return err 55 | } 56 | 57 | tios := orig_tios 58 | tios.Iflag &^= syscall_IGNBRK | syscall_BRKINT | syscall_PARMRK | 59 | syscall_ISTRIP | syscall_INLCR | syscall_IGNCR | 60 | syscall_ICRNL | syscall_IXON 61 | tios.Lflag &^= syscall_ECHO | syscall_ECHONL | syscall_ICANON | 62 | syscall_ISIG | syscall_IEXTEN 63 | tios.Cflag &^= syscall_CSIZE | syscall_PARENB 64 | tios.Cflag |= syscall_CS8 65 | tios.Cc[syscall_VMIN] = 1 66 | tios.Cc[syscall_VTIME] = 0 67 | 68 | err = tcsetattr(out.Fd(), &tios) 69 | if err != nil { 70 | return err 71 | } 72 | 73 | out.WriteString(funcs[t_enter_ca]) 74 | out.WriteString(funcs[t_enter_keypad]) 75 | out.WriteString(funcs[t_hide_cursor]) 76 | out.WriteString(funcs[t_clear_screen]) 77 | 78 | termw, termh = get_term_size(out.Fd()) 79 | back_buffer.init(termw, termh) 80 | front_buffer.init(termw, termh) 81 | back_buffer.clear() 82 | front_buffer.clear() 83 | 84 | go func() { 85 | buf := make([]byte, 128) 86 | for { 87 | select { 88 | case <-sigio: 89 | for { 90 | n, err := syscall.Read(in, buf) 91 | if err == syscall.EAGAIN || err == syscall.EWOULDBLOCK { 92 | break 93 | } 94 | select { 95 | case input_comm <- input_event{buf[:n], err}: 96 | ie := <-input_comm 97 | buf = ie.data[:128] 98 | case <-quit: 99 | return 100 | } 101 | } 102 | case <-quit: 103 | return 104 | } 105 | } 106 | }() 107 | 108 | IsInit = true 109 | return nil 110 | } 111 | 112 | // Interrupt an in-progress call to PollEvent by causing it to return 113 | // EventInterrupt. Note that this function will block until the PollEvent 114 | // function has successfully been interrupted. 115 | func Interrupt() { 116 | interrupt_comm <- struct{}{} 117 | } 118 | 119 | // Finalizes termbox library, should be called after successful initialization 120 | // when termbox's functionality isn't required anymore. 121 | func Close() { 122 | quit <- 1 123 | out.WriteString(funcs[t_show_cursor]) 124 | out.WriteString(funcs[t_sgr0]) 125 | out.WriteString(funcs[t_clear_screen]) 126 | out.WriteString(funcs[t_exit_ca]) 127 | out.WriteString(funcs[t_exit_keypad]) 128 | out.WriteString(funcs[t_exit_mouse]) 129 | tcsetattr(out.Fd(), &orig_tios) 130 | 131 | out.Close() 132 | syscall.Close(in) 133 | 134 | // reset the state, so that on next Init() it will work again 135 | termw = 0 136 | termh = 0 137 | input_mode = InputEsc 138 | out = nil 139 | in = 0 140 | lastfg = attr_invalid 141 | lastbg = attr_invalid 142 | lastx = coord_invalid 143 | lasty = coord_invalid 144 | cursor_x = cursor_hidden 145 | cursor_y = cursor_hidden 146 | foreground = ColorDefault 147 | background = ColorDefault 148 | IsInit = false 149 | } 150 | 151 | // Synchronizes the internal back buffer with the terminal. 152 | func Flush() error { 153 | // invalidate cursor position 154 | lastx = coord_invalid 155 | lasty = coord_invalid 156 | 157 | update_size_maybe() 158 | 159 | for y := 0; y < front_buffer.height; y++ { 160 | line_offset := y * front_buffer.width 161 | for x := 0; x < front_buffer.width; { 162 | cell_offset := line_offset + x 163 | back := &back_buffer.cells[cell_offset] 164 | front := &front_buffer.cells[cell_offset] 165 | if back.Ch < ' ' { 166 | back.Ch = ' ' 167 | } 168 | w := runewidth.RuneWidth(back.Ch) 169 | if w == 0 || w == 2 && runewidth.IsAmbiguousWidth(back.Ch) { 170 | w = 1 171 | } 172 | if *back == *front { 173 | x += w 174 | continue 175 | } 176 | *front = *back 177 | send_attr(back.Fg, back.Bg) 178 | 179 | if w == 2 && x == front_buffer.width-1 { 180 | // there's not enough space for 2-cells rune, 181 | // let's just put a space in there 182 | send_char(x, y, ' ') 183 | } else { 184 | send_char(x, y, back.Ch) 185 | if w == 2 { 186 | next := cell_offset + 1 187 | front_buffer.cells[next] = Cell{ 188 | Ch: 0, 189 | Fg: back.Fg, 190 | Bg: back.Bg, 191 | } 192 | } 193 | } 194 | x += w 195 | } 196 | } 197 | if !is_cursor_hidden(cursor_x, cursor_y) { 198 | write_cursor(cursor_x, cursor_y) 199 | } 200 | return flush() 201 | } 202 | 203 | // Sets the position of the cursor. See also HideCursor(). 204 | func SetCursor(x, y int) { 205 | if is_cursor_hidden(cursor_x, cursor_y) && !is_cursor_hidden(x, y) { 206 | outbuf.WriteString(funcs[t_show_cursor]) 207 | } 208 | 209 | if !is_cursor_hidden(cursor_x, cursor_y) && is_cursor_hidden(x, y) { 210 | outbuf.WriteString(funcs[t_hide_cursor]) 211 | } 212 | 213 | cursor_x, cursor_y = x, y 214 | if !is_cursor_hidden(cursor_x, cursor_y) { 215 | write_cursor(cursor_x, cursor_y) 216 | } 217 | } 218 | 219 | // The shortcut for SetCursor(-1, -1). 220 | func HideCursor() { 221 | SetCursor(cursor_hidden, cursor_hidden) 222 | } 223 | 224 | // Changes cell's parameters in the internal back buffer at the specified 225 | // position. 226 | func SetCell(x, y int, ch rune, fg, bg Attribute) { 227 | if x < 0 || x >= back_buffer.width { 228 | return 229 | } 230 | if y < 0 || y >= back_buffer.height { 231 | return 232 | } 233 | 234 | back_buffer.cells[y*back_buffer.width+x] = Cell{ch, fg, bg} 235 | } 236 | 237 | // Returns a slice into the termbox's back buffer. You can get its dimensions 238 | // using 'Size' function. The slice remains valid as long as no 'Clear' or 239 | // 'Flush' function calls were made after call to this function. 240 | func CellBuffer() []Cell { 241 | return back_buffer.cells 242 | } 243 | 244 | // After getting a raw event from PollRawEvent function call, you can parse it 245 | // again into an ordinary one using termbox logic. That is parse an event as 246 | // termbox would do it. Returned event in addition to usual Event struct fields 247 | // sets N field to the amount of bytes used within 'data' slice. If the length 248 | // of 'data' slice is zero or event cannot be parsed for some other reason, the 249 | // function will return a special event type: EventNone. 250 | // 251 | // IMPORTANT: EventNone may contain a non-zero N, which means you should skip 252 | // these bytes, because termbox cannot recognize them. 253 | // 254 | // NOTE: This API is experimental and may change in future. 255 | func ParseEvent(data []byte) Event { 256 | event := Event{Type: EventKey} 257 | status := extract_event(data, &event, false) 258 | if status != event_extracted { 259 | return Event{Type: EventNone, N: event.N} 260 | } 261 | return event 262 | } 263 | 264 | // Wait for an event and return it. This is a blocking function call. Instead 265 | // of EventKey and EventMouse it returns EventRaw events. Raw event is written 266 | // into `data` slice and Event's N field is set to the amount of bytes written. 267 | // The minimum required length of the 'data' slice is 1. This requirement may 268 | // vary on different platforms. 269 | // 270 | // NOTE: This API is experimental and may change in future. 271 | func PollRawEvent(data []byte) Event { 272 | if len(data) == 0 { 273 | panic("len(data) >= 1 is a requirement") 274 | } 275 | 276 | var event Event 277 | if extract_raw_event(data, &event) { 278 | return event 279 | } 280 | 281 | for { 282 | select { 283 | case ev := <-input_comm: 284 | if ev.err != nil { 285 | return Event{Type: EventError, Err: ev.err} 286 | } 287 | 288 | inbuf = append(inbuf, ev.data...) 289 | input_comm <- ev 290 | if extract_raw_event(data, &event) { 291 | return event 292 | } 293 | case <-interrupt_comm: 294 | event.Type = EventInterrupt 295 | return event 296 | 297 | case <-sigwinch: 298 | event.Type = EventResize 299 | event.Width, event.Height = get_term_size(out.Fd()) 300 | return event 301 | } 302 | } 303 | } 304 | 305 | // Wait for an event and return it. This is a blocking function call. 306 | func PollEvent() Event { 307 | // Constant governing macOS specific behavior. See https://github.com/nsf/termbox-go/issues/132 308 | // This is an arbitrary delay which hopefully will be enough time for any lagging 309 | // partial escape sequences to come through. 310 | const esc_wait_delay = 100 * time.Millisecond 311 | 312 | var event Event 313 | var esc_wait_timer *time.Timer 314 | var esc_timeout <-chan time.Time 315 | 316 | // try to extract event from input buffer, return on success 317 | event.Type = EventKey 318 | status := extract_event(inbuf, &event, true) 319 | if event.N != 0 { 320 | copy(inbuf, inbuf[event.N:]) 321 | inbuf = inbuf[:len(inbuf)-event.N] 322 | } 323 | if status == event_extracted { 324 | return event 325 | } else if status == esc_wait { 326 | esc_wait_timer = time.NewTimer(esc_wait_delay) 327 | esc_timeout = esc_wait_timer.C 328 | } 329 | 330 | for { 331 | select { 332 | case ev := <-input_comm: 333 | if esc_wait_timer != nil { 334 | if !esc_wait_timer.Stop() { 335 | <-esc_wait_timer.C 336 | } 337 | esc_wait_timer = nil 338 | } 339 | 340 | if ev.err != nil { 341 | return Event{Type: EventError, Err: ev.err} 342 | } 343 | 344 | inbuf = append(inbuf, ev.data...) 345 | input_comm <- ev 346 | status := extract_event(inbuf, &event, true) 347 | if event.N != 0 { 348 | copy(inbuf, inbuf[event.N:]) 349 | inbuf = inbuf[:len(inbuf)-event.N] 350 | } 351 | if status == event_extracted { 352 | return event 353 | } else if status == esc_wait { 354 | esc_wait_timer = time.NewTimer(esc_wait_delay) 355 | esc_timeout = esc_wait_timer.C 356 | } 357 | case <-esc_timeout: 358 | esc_wait_timer = nil 359 | 360 | status := extract_event(inbuf, &event, false) 361 | if event.N != 0 { 362 | copy(inbuf, inbuf[event.N:]) 363 | inbuf = inbuf[:len(inbuf)-event.N] 364 | } 365 | if status == event_extracted { 366 | return event 367 | } 368 | case <-interrupt_comm: 369 | event.Type = EventInterrupt 370 | return event 371 | 372 | case <-sigwinch: 373 | event.Type = EventResize 374 | event.Width, event.Height = get_term_size(out.Fd()) 375 | return event 376 | } 377 | } 378 | } 379 | 380 | // Returns the size of the internal back buffer (which is mostly the same as 381 | // terminal's window size in characters). But it doesn't always match the size 382 | // of the terminal window, after the terminal size has changed, the internal 383 | // back buffer will get in sync only after Clear or Flush function calls. 384 | func Size() (width int, height int) { 385 | return termw, termh 386 | } 387 | 388 | // Clears the internal back buffer. 389 | func Clear(fg, bg Attribute) error { 390 | foreground, background = fg, bg 391 | err := update_size_maybe() 392 | back_buffer.clear() 393 | return err 394 | } 395 | 396 | // Sets termbox input mode. Termbox has two input modes: 397 | // 398 | // 1. Esc input mode. When ESC sequence is in the buffer and it doesn't match 399 | // any known sequence. ESC means KeyEsc. This is the default input mode. 400 | // 401 | // 2. Alt input mode. When ESC sequence is in the buffer and it doesn't match 402 | // any known sequence. ESC enables ModAlt modifier for the next keyboard event. 403 | // 404 | // Both input modes can be OR'ed with Mouse mode. Setting Mouse mode bit up will 405 | // enable mouse button press/release and drag events. 406 | // 407 | // If 'mode' is InputCurrent, returns the current input mode. See also Input* 408 | // constants. 409 | func SetInputMode(mode InputMode) InputMode { 410 | if mode == InputCurrent { 411 | return input_mode 412 | } 413 | if mode&(InputEsc|InputAlt) == 0 { 414 | mode |= InputEsc 415 | } 416 | if mode&(InputEsc|InputAlt) == InputEsc|InputAlt { 417 | mode &^= InputAlt 418 | } 419 | if mode&InputMouse != 0 { 420 | out.WriteString(funcs[t_enter_mouse]) 421 | } else { 422 | out.WriteString(funcs[t_exit_mouse]) 423 | } 424 | 425 | input_mode = mode 426 | return input_mode 427 | } 428 | 429 | // Sets the termbox output mode. Termbox has four output options: 430 | // 431 | // 1. OutputNormal => [1..8] 432 | // This mode provides 8 different colors: 433 | // black, red, green, yellow, blue, magenta, cyan, white 434 | // Shortcut: ColorBlack, ColorRed, ... 435 | // Attributes: AttrBold, AttrUnderline, AttrReverse 436 | // 437 | // Example usage: 438 | // SetCell(x, y, '@', ColorBlack | AttrBold, ColorRed); 439 | // 440 | // 2. Output256 => [1..256] 441 | // In this mode you can leverage the 256 terminal mode: 442 | // 0x01 - 0x08: the 8 colors as in OutputNormal 443 | // 0x09 - 0x10: Color* | AttrBold 444 | // 0x11 - 0xe8: 216 different colors 445 | // 0xe9 - 0x1ff: 24 different shades of grey 446 | // 447 | // Example usage: 448 | // SetCell(x, y, '@', 184, 240); 449 | // SetCell(x, y, '@', 0xb8, 0xf0); 450 | // 451 | // 3. Output216 => [1..216] 452 | // This mode supports the 3rd range of the 256 mode only. 453 | // But you don't need to provide an offset. 454 | // 455 | // 4. OutputGrayscale => [1..26] 456 | // This mode supports the 4th range of the 256 mode 457 | // and black and white colors from 3th range of the 256 mode 458 | // But you don't need to provide an offset. 459 | // 460 | // In all modes, 0x00 represents the default color. 461 | // 462 | // `go run _demos/output.go` to see its impact on your terminal. 463 | // 464 | // If 'mode' is OutputCurrent, it returns the current output mode. 465 | // 466 | // Note that this may return a different OutputMode than the one requested, 467 | // as the requested mode may not be available on the target platform. 468 | func SetOutputMode(mode OutputMode) OutputMode { 469 | if mode == OutputCurrent { 470 | return output_mode 471 | } 472 | 473 | output_mode = mode 474 | return output_mode 475 | } 476 | 477 | // Sync comes handy when something causes desync between termbox's understanding 478 | // of a terminal buffer and the reality. Such as a third party process. Sync 479 | // forces a complete resync between the termbox and a terminal, it may not be 480 | // visually pretty though. 481 | func Sync() error { 482 | front_buffer.clear() 483 | err := send_clear() 484 | if err != nil { 485 | return err 486 | } 487 | 488 | return Flush() 489 | } 490 | -------------------------------------------------------------------------------- /vendor/github.com/nsf/termbox-go/termbox_windows.go: -------------------------------------------------------------------------------- 1 | package termbox 2 | 3 | import "syscall" 4 | import "unsafe" 5 | import "unicode/utf16" 6 | import "github.com/mattn/go-runewidth" 7 | 8 | type ( 9 | wchar uint16 10 | short int16 11 | dword uint32 12 | word uint16 13 | char_info struct { 14 | char wchar 15 | attr word 16 | } 17 | coord struct { 18 | x short 19 | y short 20 | } 21 | small_rect struct { 22 | left short 23 | top short 24 | right short 25 | bottom short 26 | } 27 | console_screen_buffer_info struct { 28 | size coord 29 | cursor_position coord 30 | attributes word 31 | window small_rect 32 | maximum_window_size coord 33 | } 34 | console_cursor_info struct { 35 | size dword 36 | visible int32 37 | } 38 | input_record struct { 39 | event_type word 40 | _ [2]byte 41 | event [16]byte 42 | } 43 | key_event_record struct { 44 | key_down int32 45 | repeat_count word 46 | virtual_key_code word 47 | virtual_scan_code word 48 | unicode_char wchar 49 | control_key_state dword 50 | } 51 | window_buffer_size_record struct { 52 | size coord 53 | } 54 | mouse_event_record struct { 55 | mouse_pos coord 56 | button_state dword 57 | control_key_state dword 58 | event_flags dword 59 | } 60 | ) 61 | 62 | const ( 63 | mouse_lmb = 0x1 64 | mouse_rmb = 0x2 65 | mouse_mmb = 0x4 | 0x8 | 0x10 66 | SM_CXMIN = 28 67 | SM_CYMIN = 29 68 | ) 69 | 70 | func (this coord) uintptr() uintptr { 71 | return uintptr(*(*int32)(unsafe.Pointer(&this))) 72 | } 73 | 74 | var kernel32 = syscall.NewLazyDLL("kernel32.dll") 75 | var moduser32 = syscall.NewLazyDLL("user32.dll") 76 | var is_cjk = runewidth.IsEastAsian() 77 | 78 | var ( 79 | proc_set_console_active_screen_buffer = kernel32.NewProc("SetConsoleActiveScreenBuffer") 80 | proc_set_console_screen_buffer_size = kernel32.NewProc("SetConsoleScreenBufferSize") 81 | proc_create_console_screen_buffer = kernel32.NewProc("CreateConsoleScreenBuffer") 82 | proc_get_console_screen_buffer_info = kernel32.NewProc("GetConsoleScreenBufferInfo") 83 | proc_write_console_output = kernel32.NewProc("WriteConsoleOutputW") 84 | proc_write_console_output_character = kernel32.NewProc("WriteConsoleOutputCharacterW") 85 | proc_write_console_output_attribute = kernel32.NewProc("WriteConsoleOutputAttribute") 86 | proc_set_console_cursor_info = kernel32.NewProc("SetConsoleCursorInfo") 87 | proc_set_console_cursor_position = kernel32.NewProc("SetConsoleCursorPosition") 88 | proc_get_console_cursor_info = kernel32.NewProc("GetConsoleCursorInfo") 89 | proc_read_console_input = kernel32.NewProc("ReadConsoleInputW") 90 | proc_get_console_mode = kernel32.NewProc("GetConsoleMode") 91 | proc_set_console_mode = kernel32.NewProc("SetConsoleMode") 92 | proc_fill_console_output_character = kernel32.NewProc("FillConsoleOutputCharacterW") 93 | proc_fill_console_output_attribute = kernel32.NewProc("FillConsoleOutputAttribute") 94 | proc_create_event = kernel32.NewProc("CreateEventW") 95 | proc_wait_for_multiple_objects = kernel32.NewProc("WaitForMultipleObjects") 96 | proc_set_event = kernel32.NewProc("SetEvent") 97 | get_system_metrics = moduser32.NewProc("GetSystemMetrics") 98 | ) 99 | 100 | func set_console_active_screen_buffer(h syscall.Handle) (err error) { 101 | r0, _, e1 := syscall.Syscall(proc_set_console_active_screen_buffer.Addr(), 102 | 1, uintptr(h), 0, 0) 103 | if int(r0) == 0 { 104 | if e1 != 0 { 105 | err = error(e1) 106 | } else { 107 | err = syscall.EINVAL 108 | } 109 | } 110 | return 111 | } 112 | 113 | func set_console_screen_buffer_size(h syscall.Handle, size coord) (err error) { 114 | r0, _, e1 := syscall.Syscall(proc_set_console_screen_buffer_size.Addr(), 115 | 2, uintptr(h), size.uintptr(), 0) 116 | if int(r0) == 0 { 117 | if e1 != 0 { 118 | err = error(e1) 119 | } else { 120 | err = syscall.EINVAL 121 | } 122 | } 123 | return 124 | } 125 | 126 | func create_console_screen_buffer() (h syscall.Handle, err error) { 127 | r0, _, e1 := syscall.Syscall6(proc_create_console_screen_buffer.Addr(), 128 | 5, uintptr(generic_read|generic_write), 0, 0, console_textmode_buffer, 0, 0) 129 | if int(r0) == 0 { 130 | if e1 != 0 { 131 | err = error(e1) 132 | } else { 133 | err = syscall.EINVAL 134 | } 135 | } 136 | return syscall.Handle(r0), err 137 | } 138 | 139 | func get_console_screen_buffer_info(h syscall.Handle, info *console_screen_buffer_info) (err error) { 140 | r0, _, e1 := syscall.Syscall(proc_get_console_screen_buffer_info.Addr(), 141 | 2, uintptr(h), uintptr(unsafe.Pointer(info)), 0) 142 | if int(r0) == 0 { 143 | if e1 != 0 { 144 | err = error(e1) 145 | } else { 146 | err = syscall.EINVAL 147 | } 148 | } 149 | return 150 | } 151 | 152 | func write_console_output(h syscall.Handle, chars []char_info, dst small_rect) (err error) { 153 | tmp_coord = coord{dst.right - dst.left + 1, dst.bottom - dst.top + 1} 154 | tmp_rect = dst 155 | r0, _, e1 := syscall.Syscall6(proc_write_console_output.Addr(), 156 | 5, uintptr(h), uintptr(unsafe.Pointer(&chars[0])), tmp_coord.uintptr(), 157 | tmp_coord0.uintptr(), uintptr(unsafe.Pointer(&tmp_rect)), 0) 158 | if int(r0) == 0 { 159 | if e1 != 0 { 160 | err = error(e1) 161 | } else { 162 | err = syscall.EINVAL 163 | } 164 | } 165 | return 166 | } 167 | 168 | func write_console_output_character(h syscall.Handle, chars []wchar, pos coord) (err error) { 169 | r0, _, e1 := syscall.Syscall6(proc_write_console_output_character.Addr(), 170 | 5, uintptr(h), uintptr(unsafe.Pointer(&chars[0])), uintptr(len(chars)), 171 | pos.uintptr(), uintptr(unsafe.Pointer(&tmp_arg)), 0) 172 | if int(r0) == 0 { 173 | if e1 != 0 { 174 | err = error(e1) 175 | } else { 176 | err = syscall.EINVAL 177 | } 178 | } 179 | return 180 | } 181 | 182 | func write_console_output_attribute(h syscall.Handle, attrs []word, pos coord) (err error) { 183 | r0, _, e1 := syscall.Syscall6(proc_write_console_output_attribute.Addr(), 184 | 5, uintptr(h), uintptr(unsafe.Pointer(&attrs[0])), uintptr(len(attrs)), 185 | pos.uintptr(), uintptr(unsafe.Pointer(&tmp_arg)), 0) 186 | if int(r0) == 0 { 187 | if e1 != 0 { 188 | err = error(e1) 189 | } else { 190 | err = syscall.EINVAL 191 | } 192 | } 193 | return 194 | } 195 | 196 | func set_console_cursor_info(h syscall.Handle, info *console_cursor_info) (err error) { 197 | r0, _, e1 := syscall.Syscall(proc_set_console_cursor_info.Addr(), 198 | 2, uintptr(h), uintptr(unsafe.Pointer(info)), 0) 199 | if int(r0) == 0 { 200 | if e1 != 0 { 201 | err = error(e1) 202 | } else { 203 | err = syscall.EINVAL 204 | } 205 | } 206 | return 207 | } 208 | 209 | func get_console_cursor_info(h syscall.Handle, info *console_cursor_info) (err error) { 210 | r0, _, e1 := syscall.Syscall(proc_get_console_cursor_info.Addr(), 211 | 2, uintptr(h), uintptr(unsafe.Pointer(info)), 0) 212 | if int(r0) == 0 { 213 | if e1 != 0 { 214 | err = error(e1) 215 | } else { 216 | err = syscall.EINVAL 217 | } 218 | } 219 | return 220 | } 221 | 222 | func set_console_cursor_position(h syscall.Handle, pos coord) (err error) { 223 | r0, _, e1 := syscall.Syscall(proc_set_console_cursor_position.Addr(), 224 | 2, uintptr(h), pos.uintptr(), 0) 225 | if int(r0) == 0 { 226 | if e1 != 0 { 227 | err = error(e1) 228 | } else { 229 | err = syscall.EINVAL 230 | } 231 | } 232 | return 233 | } 234 | 235 | func read_console_input(h syscall.Handle, record *input_record) (err error) { 236 | r0, _, e1 := syscall.Syscall6(proc_read_console_input.Addr(), 237 | 4, uintptr(h), uintptr(unsafe.Pointer(record)), 1, uintptr(unsafe.Pointer(&tmp_arg)), 0, 0) 238 | if int(r0) == 0 { 239 | if e1 != 0 { 240 | err = error(e1) 241 | } else { 242 | err = syscall.EINVAL 243 | } 244 | } 245 | return 246 | } 247 | 248 | func get_console_mode(h syscall.Handle, mode *dword) (err error) { 249 | r0, _, e1 := syscall.Syscall(proc_get_console_mode.Addr(), 250 | 2, uintptr(h), uintptr(unsafe.Pointer(mode)), 0) 251 | if int(r0) == 0 { 252 | if e1 != 0 { 253 | err = error(e1) 254 | } else { 255 | err = syscall.EINVAL 256 | } 257 | } 258 | return 259 | } 260 | 261 | func set_console_mode(h syscall.Handle, mode dword) (err error) { 262 | r0, _, e1 := syscall.Syscall(proc_set_console_mode.Addr(), 263 | 2, uintptr(h), uintptr(mode), 0) 264 | if int(r0) == 0 { 265 | if e1 != 0 { 266 | err = error(e1) 267 | } else { 268 | err = syscall.EINVAL 269 | } 270 | } 271 | return 272 | } 273 | 274 | func fill_console_output_character(h syscall.Handle, char wchar, n int) (err error) { 275 | r0, _, e1 := syscall.Syscall6(proc_fill_console_output_character.Addr(), 276 | 5, uintptr(h), uintptr(char), uintptr(n), tmp_coord.uintptr(), 277 | uintptr(unsafe.Pointer(&tmp_arg)), 0) 278 | if int(r0) == 0 { 279 | if e1 != 0 { 280 | err = error(e1) 281 | } else { 282 | err = syscall.EINVAL 283 | } 284 | } 285 | return 286 | } 287 | 288 | func fill_console_output_attribute(h syscall.Handle, attr word, n int) (err error) { 289 | r0, _, e1 := syscall.Syscall6(proc_fill_console_output_attribute.Addr(), 290 | 5, uintptr(h), uintptr(attr), uintptr(n), tmp_coord.uintptr(), 291 | uintptr(unsafe.Pointer(&tmp_arg)), 0) 292 | if int(r0) == 0 { 293 | if e1 != 0 { 294 | err = error(e1) 295 | } else { 296 | err = syscall.EINVAL 297 | } 298 | } 299 | return 300 | } 301 | 302 | func create_event() (out syscall.Handle, err error) { 303 | r0, _, e1 := syscall.Syscall6(proc_create_event.Addr(), 304 | 4, 0, 0, 0, 0, 0, 0) 305 | if int(r0) == 0 { 306 | if e1 != 0 { 307 | err = error(e1) 308 | } else { 309 | err = syscall.EINVAL 310 | } 311 | } 312 | return syscall.Handle(r0), err 313 | } 314 | 315 | func wait_for_multiple_objects(objects []syscall.Handle) (err error) { 316 | r0, _, e1 := syscall.Syscall6(proc_wait_for_multiple_objects.Addr(), 317 | 4, uintptr(len(objects)), uintptr(unsafe.Pointer(&objects[0])), 318 | 0, 0xFFFFFFFF, 0, 0) 319 | if uint32(r0) == 0xFFFFFFFF { 320 | if e1 != 0 { 321 | err = error(e1) 322 | } else { 323 | err = syscall.EINVAL 324 | } 325 | } 326 | return 327 | } 328 | 329 | func set_event(ev syscall.Handle) (err error) { 330 | r0, _, e1 := syscall.Syscall(proc_set_event.Addr(), 331 | 1, uintptr(ev), 0, 0) 332 | if int(r0) == 0 { 333 | if e1 != 0 { 334 | err = error(e1) 335 | } else { 336 | err = syscall.EINVAL 337 | } 338 | } 339 | return 340 | } 341 | 342 | type diff_msg struct { 343 | pos short 344 | lines short 345 | chars []char_info 346 | } 347 | 348 | type input_event struct { 349 | event Event 350 | err error 351 | } 352 | 353 | var ( 354 | orig_cursor_info console_cursor_info 355 | orig_size coord 356 | orig_mode dword 357 | orig_screen syscall.Handle 358 | back_buffer cellbuf 359 | front_buffer cellbuf 360 | term_size coord 361 | input_mode = InputEsc 362 | cursor_x = cursor_hidden 363 | cursor_y = cursor_hidden 364 | foreground = ColorDefault 365 | background = ColorDefault 366 | in syscall.Handle 367 | out syscall.Handle 368 | interrupt syscall.Handle 369 | charbuf []char_info 370 | diffbuf []diff_msg 371 | beg_x = -1 372 | beg_y = -1 373 | beg_i = -1 374 | input_comm = make(chan Event) 375 | interrupt_comm = make(chan struct{}) 376 | cancel_comm = make(chan bool, 1) 377 | cancel_done_comm = make(chan bool) 378 | alt_mode_esc = false 379 | 380 | // these ones just to prevent heap allocs at all costs 381 | tmp_info console_screen_buffer_info 382 | tmp_arg dword 383 | tmp_coord0 = coord{0, 0} 384 | tmp_coord = coord{0, 0} 385 | tmp_rect = small_rect{0, 0, 0, 0} 386 | ) 387 | 388 | func get_cursor_position(out syscall.Handle) coord { 389 | err := get_console_screen_buffer_info(out, &tmp_info) 390 | if err != nil { 391 | panic(err) 392 | } 393 | return tmp_info.cursor_position 394 | } 395 | 396 | func get_term_size(out syscall.Handle) coord { 397 | err := get_console_screen_buffer_info(out, &tmp_info) 398 | if err != nil { 399 | panic(err) 400 | } 401 | return tmp_info.size 402 | } 403 | 404 | func get_win_min_size(out syscall.Handle) coord { 405 | x, _, err := get_system_metrics.Call(SM_CXMIN) 406 | y, _, err := get_system_metrics.Call(SM_CYMIN) 407 | 408 | if x == 0 || y == 0 { 409 | if err != nil { 410 | panic(err) 411 | } 412 | } 413 | 414 | return coord{ 415 | x: short(x), 416 | y: short(y), 417 | } 418 | } 419 | 420 | func get_win_size(out syscall.Handle) coord { 421 | err := get_console_screen_buffer_info(out, &tmp_info) 422 | if err != nil { 423 | panic(err) 424 | } 425 | 426 | min_size := get_win_min_size(out) 427 | 428 | size := coord{ 429 | x: tmp_info.window.right - tmp_info.window.left + 1, 430 | y: tmp_info.window.bottom - tmp_info.window.top + 1, 431 | } 432 | 433 | if size.x < min_size.x { 434 | size.x = min_size.x 435 | } 436 | 437 | if size.y < min_size.y { 438 | size.y = min_size.y 439 | } 440 | 441 | return size 442 | } 443 | 444 | func update_size_maybe() { 445 | size := get_term_size(out) 446 | if size.x != term_size.x || size.y != term_size.y { 447 | term_size = size 448 | back_buffer.resize(int(size.x), int(size.y)) 449 | front_buffer.resize(int(size.x), int(size.y)) 450 | front_buffer.clear() 451 | clear() 452 | 453 | area := int(size.x) * int(size.y) 454 | if cap(charbuf) < area { 455 | charbuf = make([]char_info, 0, area) 456 | } 457 | } 458 | } 459 | 460 | var color_table_bg = []word{ 461 | 0, // default (black) 462 | 0, // black 463 | background_red, 464 | background_green, 465 | background_red | background_green, // yellow 466 | background_blue, 467 | background_red | background_blue, // magenta 468 | background_green | background_blue, // cyan 469 | background_red | background_blue | background_green, // white 470 | } 471 | 472 | var color_table_fg = []word{ 473 | foreground_red | foreground_blue | foreground_green, // default (white) 474 | 0, 475 | foreground_red, 476 | foreground_green, 477 | foreground_red | foreground_green, // yellow 478 | foreground_blue, 479 | foreground_red | foreground_blue, // magenta 480 | foreground_green | foreground_blue, // cyan 481 | foreground_red | foreground_blue | foreground_green, // white 482 | } 483 | 484 | const ( 485 | replacement_char = '\uFFFD' 486 | max_rune = '\U0010FFFF' 487 | surr1 = 0xd800 488 | surr2 = 0xdc00 489 | surr3 = 0xe000 490 | surr_self = 0x10000 491 | ) 492 | 493 | func append_diff_line(y int) int { 494 | n := 0 495 | for x := 0; x < front_buffer.width; { 496 | cell_offset := y*front_buffer.width + x 497 | back := &back_buffer.cells[cell_offset] 498 | front := &front_buffer.cells[cell_offset] 499 | attr, char := cell_to_char_info(*back) 500 | charbuf = append(charbuf, char_info{attr: attr, char: char[0]}) 501 | *front = *back 502 | n++ 503 | w := runewidth.RuneWidth(back.Ch) 504 | if w == 0 || w == 2 && runewidth.IsAmbiguousWidth(back.Ch) { 505 | w = 1 506 | } 507 | x += w 508 | // If not CJK, fill trailing space with whitespace 509 | if !is_cjk && w == 2 { 510 | charbuf = append(charbuf, char_info{attr: attr, char: ' '}) 511 | } 512 | } 513 | return n 514 | } 515 | 516 | // compares 'back_buffer' with 'front_buffer' and prepares all changes in the form of 517 | // 'diff_msg's in the 'diff_buf' 518 | func prepare_diff_messages() { 519 | // clear buffers 520 | diffbuf = diffbuf[:0] 521 | charbuf = charbuf[:0] 522 | 523 | var diff diff_msg 524 | gbeg := 0 525 | for y := 0; y < front_buffer.height; y++ { 526 | same := true 527 | line_offset := y * front_buffer.width 528 | for x := 0; x < front_buffer.width; x++ { 529 | cell_offset := line_offset + x 530 | back := &back_buffer.cells[cell_offset] 531 | front := &front_buffer.cells[cell_offset] 532 | if *back != *front { 533 | same = false 534 | break 535 | } 536 | } 537 | if same && diff.lines > 0 { 538 | diffbuf = append(diffbuf, diff) 539 | diff = diff_msg{} 540 | } 541 | if !same { 542 | beg := len(charbuf) 543 | end := beg + append_diff_line(y) 544 | if diff.lines == 0 { 545 | diff.pos = short(y) 546 | gbeg = beg 547 | } 548 | diff.lines++ 549 | diff.chars = charbuf[gbeg:end] 550 | } 551 | } 552 | if diff.lines > 0 { 553 | diffbuf = append(diffbuf, diff) 554 | diff = diff_msg{} 555 | } 556 | } 557 | 558 | func get_ct(table []word, idx int) word { 559 | idx = idx & 0x0F 560 | if idx >= len(table) { 561 | idx = len(table) - 1 562 | } 563 | return table[idx] 564 | } 565 | 566 | func cell_to_char_info(c Cell) (attr word, wc [2]wchar) { 567 | attr = get_ct(color_table_fg, int(c.Fg)) | get_ct(color_table_bg, int(c.Bg)) 568 | if c.Fg&AttrReverse|c.Bg&AttrReverse != 0 { 569 | attr = (attr&0xF0)>>4 | (attr&0x0F)<<4 570 | } 571 | if c.Fg&AttrBold != 0 { 572 | attr |= foreground_intensity 573 | } 574 | if c.Bg&AttrBold != 0 { 575 | attr |= background_intensity 576 | } 577 | 578 | r0, r1 := utf16.EncodeRune(c.Ch) 579 | if r0 == 0xFFFD { 580 | wc[0] = wchar(c.Ch) 581 | wc[1] = ' ' 582 | } else { 583 | wc[0] = wchar(r0) 584 | wc[1] = wchar(r1) 585 | } 586 | return 587 | } 588 | 589 | func move_cursor(x, y int) { 590 | err := set_console_cursor_position(out, coord{short(x), short(y)}) 591 | if err != nil { 592 | panic(err) 593 | } 594 | } 595 | 596 | func show_cursor(visible bool) { 597 | var v int32 598 | if visible { 599 | v = 1 600 | } 601 | 602 | var info console_cursor_info 603 | info.size = 100 604 | info.visible = v 605 | err := set_console_cursor_info(out, &info) 606 | if err != nil { 607 | panic(err) 608 | } 609 | } 610 | 611 | func clear() { 612 | var err error 613 | attr, char := cell_to_char_info(Cell{ 614 | ' ', 615 | foreground, 616 | background, 617 | }) 618 | 619 | area := int(term_size.x) * int(term_size.y) 620 | err = fill_console_output_attribute(out, attr, area) 621 | if err != nil { 622 | panic(err) 623 | } 624 | err = fill_console_output_character(out, char[0], area) 625 | if err != nil { 626 | panic(err) 627 | } 628 | if !is_cursor_hidden(cursor_x, cursor_y) { 629 | move_cursor(cursor_x, cursor_y) 630 | } 631 | } 632 | 633 | func key_event_record_to_event(r *key_event_record) (Event, bool) { 634 | if r.key_down == 0 { 635 | return Event{}, false 636 | } 637 | 638 | e := Event{Type: EventKey} 639 | if input_mode&InputAlt != 0 { 640 | if alt_mode_esc { 641 | e.Mod = ModAlt 642 | alt_mode_esc = false 643 | } 644 | if r.control_key_state&(left_alt_pressed|right_alt_pressed) != 0 { 645 | e.Mod = ModAlt 646 | } 647 | } 648 | 649 | ctrlpressed := r.control_key_state&(left_ctrl_pressed|right_ctrl_pressed) != 0 650 | 651 | if r.virtual_key_code >= vk_f1 && r.virtual_key_code <= vk_f12 { 652 | switch r.virtual_key_code { 653 | case vk_f1: 654 | e.Key = KeyF1 655 | case vk_f2: 656 | e.Key = KeyF2 657 | case vk_f3: 658 | e.Key = KeyF3 659 | case vk_f4: 660 | e.Key = KeyF4 661 | case vk_f5: 662 | e.Key = KeyF5 663 | case vk_f6: 664 | e.Key = KeyF6 665 | case vk_f7: 666 | e.Key = KeyF7 667 | case vk_f8: 668 | e.Key = KeyF8 669 | case vk_f9: 670 | e.Key = KeyF9 671 | case vk_f10: 672 | e.Key = KeyF10 673 | case vk_f11: 674 | e.Key = KeyF11 675 | case vk_f12: 676 | e.Key = KeyF12 677 | default: 678 | panic("unreachable") 679 | } 680 | 681 | return e, true 682 | } 683 | 684 | if r.virtual_key_code <= vk_delete { 685 | switch r.virtual_key_code { 686 | case vk_insert: 687 | e.Key = KeyInsert 688 | case vk_delete: 689 | e.Key = KeyDelete 690 | case vk_home: 691 | e.Key = KeyHome 692 | case vk_end: 693 | e.Key = KeyEnd 694 | case vk_pgup: 695 | e.Key = KeyPgup 696 | case vk_pgdn: 697 | e.Key = KeyPgdn 698 | case vk_arrow_up: 699 | e.Key = KeyArrowUp 700 | case vk_arrow_down: 701 | e.Key = KeyArrowDown 702 | case vk_arrow_left: 703 | e.Key = KeyArrowLeft 704 | case vk_arrow_right: 705 | e.Key = KeyArrowRight 706 | case vk_backspace: 707 | if ctrlpressed { 708 | e.Key = KeyBackspace2 709 | } else { 710 | e.Key = KeyBackspace 711 | } 712 | case vk_tab: 713 | e.Key = KeyTab 714 | case vk_enter: 715 | e.Key = KeyEnter 716 | case vk_esc: 717 | switch { 718 | case input_mode&InputEsc != 0: 719 | e.Key = KeyEsc 720 | case input_mode&InputAlt != 0: 721 | alt_mode_esc = true 722 | return Event{}, false 723 | } 724 | case vk_space: 725 | if ctrlpressed { 726 | // manual return here, because KeyCtrlSpace is zero 727 | e.Key = KeyCtrlSpace 728 | return e, true 729 | } else { 730 | e.Key = KeySpace 731 | } 732 | } 733 | 734 | if e.Key != 0 { 735 | return e, true 736 | } 737 | } 738 | 739 | if ctrlpressed { 740 | if Key(r.unicode_char) >= KeyCtrlA && Key(r.unicode_char) <= KeyCtrlRsqBracket { 741 | e.Key = Key(r.unicode_char) 742 | if input_mode&InputAlt != 0 && e.Key == KeyEsc { 743 | alt_mode_esc = true 744 | return Event{}, false 745 | } 746 | return e, true 747 | } 748 | switch r.virtual_key_code { 749 | case 192, 50: 750 | // manual return here, because KeyCtrl2 is zero 751 | e.Key = KeyCtrl2 752 | return e, true 753 | case 51: 754 | if input_mode&InputAlt != 0 { 755 | alt_mode_esc = true 756 | return Event{}, false 757 | } 758 | e.Key = KeyCtrl3 759 | case 52: 760 | e.Key = KeyCtrl4 761 | case 53: 762 | e.Key = KeyCtrl5 763 | case 54: 764 | e.Key = KeyCtrl6 765 | case 189, 191, 55: 766 | e.Key = KeyCtrl7 767 | case 8, 56: 768 | e.Key = KeyCtrl8 769 | } 770 | 771 | if e.Key != 0 { 772 | return e, true 773 | } 774 | } 775 | 776 | if r.unicode_char != 0 { 777 | e.Ch = rune(r.unicode_char) 778 | return e, true 779 | } 780 | 781 | return Event{}, false 782 | } 783 | 784 | func input_event_producer() { 785 | var r input_record 786 | var err error 787 | var last_button Key 788 | var last_button_pressed Key 789 | var last_state = dword(0) 790 | var last_x, last_y = -1, -1 791 | handles := []syscall.Handle{in, interrupt} 792 | for { 793 | err = wait_for_multiple_objects(handles) 794 | if err != nil { 795 | input_comm <- Event{Type: EventError, Err: err} 796 | } 797 | 798 | select { 799 | case <-cancel_comm: 800 | cancel_done_comm <- true 801 | return 802 | default: 803 | } 804 | 805 | err = read_console_input(in, &r) 806 | if err != nil { 807 | input_comm <- Event{Type: EventError, Err: err} 808 | } 809 | 810 | switch r.event_type { 811 | case key_event: 812 | kr := (*key_event_record)(unsafe.Pointer(&r.event)) 813 | ev, ok := key_event_record_to_event(kr) 814 | if ok { 815 | for i := 0; i < int(kr.repeat_count); i++ { 816 | input_comm <- ev 817 | } 818 | } 819 | case window_buffer_size_event: 820 | sr := *(*window_buffer_size_record)(unsafe.Pointer(&r.event)) 821 | input_comm <- Event{ 822 | Type: EventResize, 823 | Width: int(sr.size.x), 824 | Height: int(sr.size.y), 825 | } 826 | case mouse_event: 827 | mr := *(*mouse_event_record)(unsafe.Pointer(&r.event)) 828 | ev := Event{Type: EventMouse} 829 | switch mr.event_flags { 830 | case 0, 2: 831 | // single or double click 832 | cur_state := mr.button_state 833 | switch { 834 | case last_state&mouse_lmb == 0 && cur_state&mouse_lmb != 0: 835 | last_button = MouseLeft 836 | last_button_pressed = last_button 837 | case last_state&mouse_rmb == 0 && cur_state&mouse_rmb != 0: 838 | last_button = MouseRight 839 | last_button_pressed = last_button 840 | case last_state&mouse_mmb == 0 && cur_state&mouse_mmb != 0: 841 | last_button = MouseMiddle 842 | last_button_pressed = last_button 843 | case last_state&mouse_lmb != 0 && cur_state&mouse_lmb == 0: 844 | last_button = MouseRelease 845 | case last_state&mouse_rmb != 0 && cur_state&mouse_rmb == 0: 846 | last_button = MouseRelease 847 | case last_state&mouse_mmb != 0 && cur_state&mouse_mmb == 0: 848 | last_button = MouseRelease 849 | default: 850 | last_state = cur_state 851 | continue 852 | } 853 | last_state = cur_state 854 | ev.Key = last_button 855 | last_x, last_y = int(mr.mouse_pos.x), int(mr.mouse_pos.y) 856 | ev.MouseX = last_x 857 | ev.MouseY = last_y 858 | case 1: 859 | // mouse motion 860 | x, y := int(mr.mouse_pos.x), int(mr.mouse_pos.y) 861 | if last_state != 0 && (last_x != x || last_y != y) { 862 | ev.Key = last_button_pressed 863 | ev.Mod = ModMotion 864 | ev.MouseX = x 865 | ev.MouseY = y 866 | last_x, last_y = x, y 867 | } else { 868 | ev.Type = EventNone 869 | } 870 | case 4: 871 | // mouse wheel 872 | n := int16(mr.button_state >> 16) 873 | if n > 0 { 874 | ev.Key = MouseWheelUp 875 | } else { 876 | ev.Key = MouseWheelDown 877 | } 878 | last_x, last_y = int(mr.mouse_pos.x), int(mr.mouse_pos.y) 879 | ev.MouseX = last_x 880 | ev.MouseY = last_y 881 | default: 882 | ev.Type = EventNone 883 | } 884 | if ev.Type != EventNone { 885 | input_comm <- ev 886 | } 887 | } 888 | } 889 | } 890 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-runewidth/runewidth.go: -------------------------------------------------------------------------------- 1 | package runewidth 2 | 3 | var ( 4 | // EastAsianWidth will be set true if the current locale is CJK 5 | EastAsianWidth = IsEastAsian() 6 | 7 | // DefaultCondition is a condition in current locale 8 | DefaultCondition = &Condition{EastAsianWidth} 9 | ) 10 | 11 | type interval struct { 12 | first rune 13 | last rune 14 | } 15 | 16 | type table []interval 17 | 18 | func inTables(r rune, ts ...table) bool { 19 | for _, t := range ts { 20 | if inTable(r, t) { 21 | return true 22 | } 23 | } 24 | return false 25 | } 26 | 27 | func inTable(r rune, t table) bool { 28 | // func (t table) IncludesRune(r rune) bool { 29 | if r < t[0].first { 30 | return false 31 | } 32 | 33 | bot := 0 34 | top := len(t) - 1 35 | for top >= bot { 36 | mid := (bot + top) / 2 37 | 38 | switch { 39 | case t[mid].last < r: 40 | bot = mid + 1 41 | case t[mid].first > r: 42 | top = mid - 1 43 | default: 44 | return true 45 | } 46 | } 47 | 48 | return false 49 | } 50 | 51 | var private = table{ 52 | {0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD}, 53 | } 54 | 55 | var nonprint = table{ 56 | {0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD}, 57 | {0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F}, 58 | {0x202A, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF}, 59 | {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF}, 60 | } 61 | 62 | var combining = table{ 63 | {0x0300, 0x036F}, {0x0483, 0x0489}, {0x0591, 0x05BD}, 64 | {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, {0x05C4, 0x05C5}, 65 | {0x05C7, 0x05C7}, {0x0610, 0x061A}, {0x064B, 0x065F}, 66 | {0x0670, 0x0670}, {0x06D6, 0x06DC}, {0x06DF, 0x06E4}, 67 | {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, {0x0711, 0x0711}, 68 | {0x0730, 0x074A}, {0x07A6, 0x07B0}, {0x07EB, 0x07F3}, 69 | {0x0816, 0x0819}, {0x081B, 0x0823}, {0x0825, 0x0827}, 70 | {0x0829, 0x082D}, {0x0859, 0x085B}, {0x08D4, 0x08E1}, 71 | {0x08E3, 0x0903}, {0x093A, 0x093C}, {0x093E, 0x094F}, 72 | {0x0951, 0x0957}, {0x0962, 0x0963}, {0x0981, 0x0983}, 73 | {0x09BC, 0x09BC}, {0x09BE, 0x09C4}, {0x09C7, 0x09C8}, 74 | {0x09CB, 0x09CD}, {0x09D7, 0x09D7}, {0x09E2, 0x09E3}, 75 | {0x0A01, 0x0A03}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42}, 76 | {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, 77 | {0x0A70, 0x0A71}, {0x0A75, 0x0A75}, {0x0A81, 0x0A83}, 78 | {0x0ABC, 0x0ABC}, {0x0ABE, 0x0AC5}, {0x0AC7, 0x0AC9}, 79 | {0x0ACB, 0x0ACD}, {0x0AE2, 0x0AE3}, {0x0B01, 0x0B03}, 80 | {0x0B3C, 0x0B3C}, {0x0B3E, 0x0B44}, {0x0B47, 0x0B48}, 81 | {0x0B4B, 0x0B4D}, {0x0B56, 0x0B57}, {0x0B62, 0x0B63}, 82 | {0x0B82, 0x0B82}, {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8}, 83 | {0x0BCA, 0x0BCD}, {0x0BD7, 0x0BD7}, {0x0C00, 0x0C03}, 84 | {0x0C3E, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, 85 | {0x0C55, 0x0C56}, {0x0C62, 0x0C63}, {0x0C81, 0x0C83}, 86 | {0x0CBC, 0x0CBC}, {0x0CBE, 0x0CC4}, {0x0CC6, 0x0CC8}, 87 | {0x0CCA, 0x0CCD}, {0x0CD5, 0x0CD6}, {0x0CE2, 0x0CE3}, 88 | {0x0D01, 0x0D03}, {0x0D3E, 0x0D44}, {0x0D46, 0x0D48}, 89 | {0x0D4A, 0x0D4D}, {0x0D57, 0x0D57}, {0x0D62, 0x0D63}, 90 | {0x0D82, 0x0D83}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4}, 91 | {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, {0x0DF2, 0x0DF3}, 92 | {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, 93 | {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, 94 | {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, 95 | {0x0F37, 0x0F37}, {0x0F39, 0x0F39}, {0x0F3E, 0x0F3F}, 96 | {0x0F71, 0x0F84}, {0x0F86, 0x0F87}, {0x0F8D, 0x0F97}, 97 | {0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102B, 0x103E}, 98 | {0x1056, 0x1059}, {0x105E, 0x1060}, {0x1062, 0x1064}, 99 | {0x1067, 0x106D}, {0x1071, 0x1074}, {0x1082, 0x108D}, 100 | {0x108F, 0x108F}, {0x109A, 0x109D}, {0x135D, 0x135F}, 101 | {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753}, 102 | {0x1772, 0x1773}, {0x17B4, 0x17D3}, {0x17DD, 0x17DD}, 103 | {0x180B, 0x180D}, {0x1885, 0x1886}, {0x18A9, 0x18A9}, 104 | {0x1920, 0x192B}, {0x1930, 0x193B}, {0x1A17, 0x1A1B}, 105 | {0x1A55, 0x1A5E}, {0x1A60, 0x1A7C}, {0x1A7F, 0x1A7F}, 106 | {0x1AB0, 0x1ABE}, {0x1B00, 0x1B04}, {0x1B34, 0x1B44}, 107 | {0x1B6B, 0x1B73}, {0x1B80, 0x1B82}, {0x1BA1, 0x1BAD}, 108 | {0x1BE6, 0x1BF3}, {0x1C24, 0x1C37}, {0x1CD0, 0x1CD2}, 109 | {0x1CD4, 0x1CE8}, {0x1CED, 0x1CED}, {0x1CF2, 0x1CF4}, 110 | {0x1CF8, 0x1CF9}, {0x1DC0, 0x1DF5}, {0x1DFB, 0x1DFF}, 111 | {0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2D7F, 0x2D7F}, 112 | {0x2DE0, 0x2DFF}, {0x302A, 0x302F}, {0x3099, 0x309A}, 113 | {0xA66F, 0xA672}, {0xA674, 0xA67D}, {0xA69E, 0xA69F}, 114 | {0xA6F0, 0xA6F1}, {0xA802, 0xA802}, {0xA806, 0xA806}, 115 | {0xA80B, 0xA80B}, {0xA823, 0xA827}, {0xA880, 0xA881}, 116 | {0xA8B4, 0xA8C5}, {0xA8E0, 0xA8F1}, {0xA926, 0xA92D}, 117 | {0xA947, 0xA953}, {0xA980, 0xA983}, {0xA9B3, 0xA9C0}, 118 | {0xA9E5, 0xA9E5}, {0xAA29, 0xAA36}, {0xAA43, 0xAA43}, 119 | {0xAA4C, 0xAA4D}, {0xAA7B, 0xAA7D}, {0xAAB0, 0xAAB0}, 120 | {0xAAB2, 0xAAB4}, {0xAAB7, 0xAAB8}, {0xAABE, 0xAABF}, 121 | {0xAAC1, 0xAAC1}, {0xAAEB, 0xAAEF}, {0xAAF5, 0xAAF6}, 122 | {0xABE3, 0xABEA}, {0xABEC, 0xABED}, {0xFB1E, 0xFB1E}, 123 | {0xFE00, 0xFE0F}, {0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, 124 | {0x102E0, 0x102E0}, {0x10376, 0x1037A}, {0x10A01, 0x10A03}, 125 | {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, {0x10A38, 0x10A3A}, 126 | {0x10A3F, 0x10A3F}, {0x10AE5, 0x10AE6}, {0x11000, 0x11002}, 127 | {0x11038, 0x11046}, {0x1107F, 0x11082}, {0x110B0, 0x110BA}, 128 | {0x11100, 0x11102}, {0x11127, 0x11134}, {0x11173, 0x11173}, 129 | {0x11180, 0x11182}, {0x111B3, 0x111C0}, {0x111CA, 0x111CC}, 130 | {0x1122C, 0x11237}, {0x1123E, 0x1123E}, {0x112DF, 0x112EA}, 131 | {0x11300, 0x11303}, {0x1133C, 0x1133C}, {0x1133E, 0x11344}, 132 | {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11357, 0x11357}, 133 | {0x11362, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374}, 134 | {0x11435, 0x11446}, {0x114B0, 0x114C3}, {0x115AF, 0x115B5}, 135 | {0x115B8, 0x115C0}, {0x115DC, 0x115DD}, {0x11630, 0x11640}, 136 | {0x116AB, 0x116B7}, {0x1171D, 0x1172B}, {0x11C2F, 0x11C36}, 137 | {0x11C38, 0x11C3F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, 138 | {0x16AF0, 0x16AF4}, {0x16B30, 0x16B36}, {0x16F51, 0x16F7E}, 139 | {0x16F8F, 0x16F92}, {0x1BC9D, 0x1BC9E}, {0x1D165, 0x1D169}, 140 | {0x1D16D, 0x1D172}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, 141 | {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0x1DA00, 0x1DA36}, 142 | {0x1DA3B, 0x1DA6C}, {0x1DA75, 0x1DA75}, {0x1DA84, 0x1DA84}, 143 | {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006}, 144 | {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, 145 | {0x1E026, 0x1E02A}, {0x1E8D0, 0x1E8D6}, {0x1E944, 0x1E94A}, 146 | {0xE0100, 0xE01EF}, 147 | } 148 | 149 | var doublewidth = table{ 150 | {0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A}, 151 | {0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3}, 152 | {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653}, 153 | {0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1}, 154 | {0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, 155 | {0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA}, 156 | {0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA}, 157 | {0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B}, 158 | {0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E}, 159 | {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797}, 160 | {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C}, 161 | {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99}, 162 | {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB}, 163 | {0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF}, 164 | {0x3105, 0x312D}, {0x3131, 0x318E}, {0x3190, 0x31BA}, 165 | {0x31C0, 0x31E3}, {0x31F0, 0x321E}, {0x3220, 0x3247}, 166 | {0x3250, 0x32FE}, {0x3300, 0x4DBF}, {0x4E00, 0xA48C}, 167 | {0xA490, 0xA4C6}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3}, 168 | {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52}, 169 | {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60}, 170 | {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE0}, {0x17000, 0x187EC}, 171 | {0x18800, 0x18AF2}, {0x1B000, 0x1B001}, {0x1F004, 0x1F004}, 172 | {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A}, 173 | {0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248}, 174 | {0x1F250, 0x1F251}, {0x1F300, 0x1F320}, {0x1F32D, 0x1F335}, 175 | {0x1F337, 0x1F37C}, {0x1F37E, 0x1F393}, {0x1F3A0, 0x1F3CA}, 176 | {0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0}, {0x1F3F4, 0x1F3F4}, 177 | {0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440}, {0x1F442, 0x1F4FC}, 178 | {0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E}, {0x1F550, 0x1F567}, 179 | {0x1F57A, 0x1F57A}, {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A4}, 180 | {0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC}, 181 | {0x1F6D0, 0x1F6D2}, {0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6F6}, 182 | {0x1F910, 0x1F91E}, {0x1F920, 0x1F927}, {0x1F930, 0x1F930}, 183 | {0x1F933, 0x1F93E}, {0x1F940, 0x1F94B}, {0x1F950, 0x1F95E}, 184 | {0x1F980, 0x1F991}, {0x1F9C0, 0x1F9C0}, {0x20000, 0x2FFFD}, 185 | {0x30000, 0x3FFFD}, 186 | } 187 | 188 | var ambiguous = table{ 189 | {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, 190 | {0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4}, 191 | {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6}, 192 | {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, 193 | {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, 194 | {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, 195 | {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101}, 196 | {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, 197 | {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133}, 198 | {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144}, 199 | {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153}, 200 | {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE}, 201 | {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, 202 | {0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, 203 | {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261}, 204 | {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, 205 | {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB}, 206 | {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F}, 207 | {0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1}, 208 | {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F}, 209 | {0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016}, 210 | {0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022}, 211 | {0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033}, 212 | {0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E}, 213 | {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084}, 214 | {0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105}, 215 | {0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116}, 216 | {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B}, 217 | {0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B}, 218 | {0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199}, 219 | {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4}, 220 | {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203}, 221 | {0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F}, 222 | {0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A}, 223 | {0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225}, 224 | {0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237}, 225 | {0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C}, 226 | {0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267}, 227 | {0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283}, 228 | {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299}, 229 | {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312}, 230 | {0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573}, 231 | {0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1}, 232 | {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7}, 233 | {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8}, 234 | {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5}, 235 | {0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609}, 236 | {0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E}, 237 | {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661}, 238 | {0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D}, 239 | {0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF}, 240 | {0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1}, 241 | {0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1}, 242 | {0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC}, 243 | {0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F}, 244 | {0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF}, 245 | {0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A}, 246 | {0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D}, 247 | {0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF}, 248 | {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD}, 249 | } 250 | 251 | var emoji = table{ 252 | {0x1F1E6, 0x1F1FF}, {0x1F321, 0x1F321}, {0x1F324, 0x1F32C}, 253 | {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, {0x1F396, 0x1F397}, 254 | {0x1F399, 0x1F39B}, {0x1F39E, 0x1F39F}, {0x1F3CB, 0x1F3CE}, 255 | {0x1F3D4, 0x1F3DF}, {0x1F3F3, 0x1F3F5}, {0x1F3F7, 0x1F3F7}, 256 | {0x1F43F, 0x1F43F}, {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FD}, 257 | {0x1F549, 0x1F54A}, {0x1F56F, 0x1F570}, {0x1F573, 0x1F579}, 258 | {0x1F587, 0x1F587}, {0x1F58A, 0x1F58D}, {0x1F590, 0x1F590}, 259 | {0x1F5A5, 0x1F5A5}, {0x1F5A8, 0x1F5A8}, {0x1F5B1, 0x1F5B2}, 260 | {0x1F5BC, 0x1F5BC}, {0x1F5C2, 0x1F5C4}, {0x1F5D1, 0x1F5D3}, 261 | {0x1F5DC, 0x1F5DE}, {0x1F5E1, 0x1F5E1}, {0x1F5E3, 0x1F5E3}, 262 | {0x1F5E8, 0x1F5E8}, {0x1F5EF, 0x1F5EF}, {0x1F5F3, 0x1F5F3}, 263 | {0x1F5FA, 0x1F5FA}, {0x1F6CB, 0x1F6CF}, {0x1F6E0, 0x1F6E5}, 264 | {0x1F6E9, 0x1F6E9}, {0x1F6F0, 0x1F6F0}, {0x1F6F3, 0x1F6F3}, 265 | } 266 | 267 | var notassigned = table{ 268 | {0x0378, 0x0379}, {0x0380, 0x0383}, {0x038B, 0x038B}, 269 | {0x038D, 0x038D}, {0x03A2, 0x03A2}, {0x0530, 0x0530}, 270 | {0x0557, 0x0558}, {0x0560, 0x0560}, {0x0588, 0x0588}, 271 | {0x058B, 0x058C}, {0x0590, 0x0590}, {0x05C8, 0x05CF}, 272 | {0x05EB, 0x05EF}, {0x05F5, 0x05FF}, {0x061D, 0x061D}, 273 | {0x070E, 0x070E}, {0x074B, 0x074C}, {0x07B2, 0x07BF}, 274 | {0x07FB, 0x07FF}, {0x082E, 0x082F}, {0x083F, 0x083F}, 275 | {0x085C, 0x085D}, {0x085F, 0x089F}, {0x08B5, 0x08B5}, 276 | {0x08BE, 0x08D3}, {0x0984, 0x0984}, {0x098D, 0x098E}, 277 | {0x0991, 0x0992}, {0x09A9, 0x09A9}, {0x09B1, 0x09B1}, 278 | {0x09B3, 0x09B5}, {0x09BA, 0x09BB}, {0x09C5, 0x09C6}, 279 | {0x09C9, 0x09CA}, {0x09CF, 0x09D6}, {0x09D8, 0x09DB}, 280 | {0x09DE, 0x09DE}, {0x09E4, 0x09E5}, {0x09FC, 0x0A00}, 281 | {0x0A04, 0x0A04}, {0x0A0B, 0x0A0E}, {0x0A11, 0x0A12}, 282 | {0x0A29, 0x0A29}, {0x0A31, 0x0A31}, {0x0A34, 0x0A34}, 283 | {0x0A37, 0x0A37}, {0x0A3A, 0x0A3B}, {0x0A3D, 0x0A3D}, 284 | {0x0A43, 0x0A46}, {0x0A49, 0x0A4A}, {0x0A4E, 0x0A50}, 285 | {0x0A52, 0x0A58}, {0x0A5D, 0x0A5D}, {0x0A5F, 0x0A65}, 286 | {0x0A76, 0x0A80}, {0x0A84, 0x0A84}, {0x0A8E, 0x0A8E}, 287 | {0x0A92, 0x0A92}, {0x0AA9, 0x0AA9}, {0x0AB1, 0x0AB1}, 288 | {0x0AB4, 0x0AB4}, {0x0ABA, 0x0ABB}, {0x0AC6, 0x0AC6}, 289 | {0x0ACA, 0x0ACA}, {0x0ACE, 0x0ACF}, {0x0AD1, 0x0ADF}, 290 | {0x0AE4, 0x0AE5}, {0x0AF2, 0x0AF8}, {0x0AFA, 0x0B00}, 291 | {0x0B04, 0x0B04}, {0x0B0D, 0x0B0E}, {0x0B11, 0x0B12}, 292 | {0x0B29, 0x0B29}, {0x0B31, 0x0B31}, {0x0B34, 0x0B34}, 293 | {0x0B3A, 0x0B3B}, {0x0B45, 0x0B46}, {0x0B49, 0x0B4A}, 294 | {0x0B4E, 0x0B55}, {0x0B58, 0x0B5B}, {0x0B5E, 0x0B5E}, 295 | {0x0B64, 0x0B65}, {0x0B78, 0x0B81}, {0x0B84, 0x0B84}, 296 | {0x0B8B, 0x0B8D}, {0x0B91, 0x0B91}, {0x0B96, 0x0B98}, 297 | {0x0B9B, 0x0B9B}, {0x0B9D, 0x0B9D}, {0x0BA0, 0x0BA2}, 298 | {0x0BA5, 0x0BA7}, {0x0BAB, 0x0BAD}, {0x0BBA, 0x0BBD}, 299 | {0x0BC3, 0x0BC5}, {0x0BC9, 0x0BC9}, {0x0BCE, 0x0BCF}, 300 | {0x0BD1, 0x0BD6}, {0x0BD8, 0x0BE5}, {0x0BFB, 0x0BFF}, 301 | {0x0C04, 0x0C04}, {0x0C0D, 0x0C0D}, {0x0C11, 0x0C11}, 302 | {0x0C29, 0x0C29}, {0x0C3A, 0x0C3C}, {0x0C45, 0x0C45}, 303 | {0x0C49, 0x0C49}, {0x0C4E, 0x0C54}, {0x0C57, 0x0C57}, 304 | {0x0C5B, 0x0C5F}, {0x0C64, 0x0C65}, {0x0C70, 0x0C77}, 305 | {0x0C84, 0x0C84}, {0x0C8D, 0x0C8D}, {0x0C91, 0x0C91}, 306 | {0x0CA9, 0x0CA9}, {0x0CB4, 0x0CB4}, {0x0CBA, 0x0CBB}, 307 | {0x0CC5, 0x0CC5}, {0x0CC9, 0x0CC9}, {0x0CCE, 0x0CD4}, 308 | {0x0CD7, 0x0CDD}, {0x0CDF, 0x0CDF}, {0x0CE4, 0x0CE5}, 309 | {0x0CF0, 0x0CF0}, {0x0CF3, 0x0D00}, {0x0D04, 0x0D04}, 310 | {0x0D0D, 0x0D0D}, {0x0D11, 0x0D11}, {0x0D3B, 0x0D3C}, 311 | {0x0D45, 0x0D45}, {0x0D49, 0x0D49}, {0x0D50, 0x0D53}, 312 | {0x0D64, 0x0D65}, {0x0D80, 0x0D81}, {0x0D84, 0x0D84}, 313 | {0x0D97, 0x0D99}, {0x0DB2, 0x0DB2}, {0x0DBC, 0x0DBC}, 314 | {0x0DBE, 0x0DBF}, {0x0DC7, 0x0DC9}, {0x0DCB, 0x0DCE}, 315 | {0x0DD5, 0x0DD5}, {0x0DD7, 0x0DD7}, {0x0DE0, 0x0DE5}, 316 | {0x0DF0, 0x0DF1}, {0x0DF5, 0x0E00}, {0x0E3B, 0x0E3E}, 317 | {0x0E5C, 0x0E80}, {0x0E83, 0x0E83}, {0x0E85, 0x0E86}, 318 | {0x0E89, 0x0E89}, {0x0E8B, 0x0E8C}, {0x0E8E, 0x0E93}, 319 | {0x0E98, 0x0E98}, {0x0EA0, 0x0EA0}, {0x0EA4, 0x0EA4}, 320 | {0x0EA6, 0x0EA6}, {0x0EA8, 0x0EA9}, {0x0EAC, 0x0EAC}, 321 | {0x0EBA, 0x0EBA}, {0x0EBE, 0x0EBF}, {0x0EC5, 0x0EC5}, 322 | {0x0EC7, 0x0EC7}, {0x0ECE, 0x0ECF}, {0x0EDA, 0x0EDB}, 323 | {0x0EE0, 0x0EFF}, {0x0F48, 0x0F48}, {0x0F6D, 0x0F70}, 324 | {0x0F98, 0x0F98}, {0x0FBD, 0x0FBD}, {0x0FCD, 0x0FCD}, 325 | {0x0FDB, 0x0FFF}, {0x10C6, 0x10C6}, {0x10C8, 0x10CC}, 326 | {0x10CE, 0x10CF}, {0x1249, 0x1249}, {0x124E, 0x124F}, 327 | {0x1257, 0x1257}, {0x1259, 0x1259}, {0x125E, 0x125F}, 328 | {0x1289, 0x1289}, {0x128E, 0x128F}, {0x12B1, 0x12B1}, 329 | {0x12B6, 0x12B7}, {0x12BF, 0x12BF}, {0x12C1, 0x12C1}, 330 | {0x12C6, 0x12C7}, {0x12D7, 0x12D7}, {0x1311, 0x1311}, 331 | {0x1316, 0x1317}, {0x135B, 0x135C}, {0x137D, 0x137F}, 332 | {0x139A, 0x139F}, {0x13F6, 0x13F7}, {0x13FE, 0x13FF}, 333 | {0x169D, 0x169F}, {0x16F9, 0x16FF}, {0x170D, 0x170D}, 334 | {0x1715, 0x171F}, {0x1737, 0x173F}, {0x1754, 0x175F}, 335 | {0x176D, 0x176D}, {0x1771, 0x1771}, {0x1774, 0x177F}, 336 | {0x17DE, 0x17DF}, {0x17EA, 0x17EF}, {0x17FA, 0x17FF}, 337 | {0x180F, 0x180F}, {0x181A, 0x181F}, {0x1878, 0x187F}, 338 | {0x18AB, 0x18AF}, {0x18F6, 0x18FF}, {0x191F, 0x191F}, 339 | {0x192C, 0x192F}, {0x193C, 0x193F}, {0x1941, 0x1943}, 340 | {0x196E, 0x196F}, {0x1975, 0x197F}, {0x19AC, 0x19AF}, 341 | {0x19CA, 0x19CF}, {0x19DB, 0x19DD}, {0x1A1C, 0x1A1D}, 342 | {0x1A5F, 0x1A5F}, {0x1A7D, 0x1A7E}, {0x1A8A, 0x1A8F}, 343 | {0x1A9A, 0x1A9F}, {0x1AAE, 0x1AAF}, {0x1ABF, 0x1AFF}, 344 | {0x1B4C, 0x1B4F}, {0x1B7D, 0x1B7F}, {0x1BF4, 0x1BFB}, 345 | {0x1C38, 0x1C3A}, {0x1C4A, 0x1C4C}, {0x1C89, 0x1CBF}, 346 | {0x1CC8, 0x1CCF}, {0x1CF7, 0x1CF7}, {0x1CFA, 0x1CFF}, 347 | {0x1DF6, 0x1DFA}, {0x1F16, 0x1F17}, {0x1F1E, 0x1F1F}, 348 | {0x1F46, 0x1F47}, {0x1F4E, 0x1F4F}, {0x1F58, 0x1F58}, 349 | {0x1F5A, 0x1F5A}, {0x1F5C, 0x1F5C}, {0x1F5E, 0x1F5E}, 350 | {0x1F7E, 0x1F7F}, {0x1FB5, 0x1FB5}, {0x1FC5, 0x1FC5}, 351 | {0x1FD4, 0x1FD5}, {0x1FDC, 0x1FDC}, {0x1FF0, 0x1FF1}, 352 | {0x1FF5, 0x1FF5}, {0x1FFF, 0x1FFF}, {0x2065, 0x2065}, 353 | {0x2072, 0x2073}, {0x208F, 0x208F}, {0x209D, 0x209F}, 354 | {0x20BF, 0x20CF}, {0x20F1, 0x20FF}, {0x218C, 0x218F}, 355 | {0x23FF, 0x23FF}, {0x2427, 0x243F}, {0x244B, 0x245F}, 356 | {0x2B74, 0x2B75}, {0x2B96, 0x2B97}, {0x2BBA, 0x2BBC}, 357 | {0x2BC9, 0x2BC9}, {0x2BD2, 0x2BEB}, {0x2BF0, 0x2BFF}, 358 | {0x2C2F, 0x2C2F}, {0x2C5F, 0x2C5F}, {0x2CF4, 0x2CF8}, 359 | {0x2D26, 0x2D26}, {0x2D28, 0x2D2C}, {0x2D2E, 0x2D2F}, 360 | {0x2D68, 0x2D6E}, {0x2D71, 0x2D7E}, {0x2D97, 0x2D9F}, 361 | {0x2DA7, 0x2DA7}, {0x2DAF, 0x2DAF}, {0x2DB7, 0x2DB7}, 362 | {0x2DBF, 0x2DBF}, {0x2DC7, 0x2DC7}, {0x2DCF, 0x2DCF}, 363 | {0x2DD7, 0x2DD7}, {0x2DDF, 0x2DDF}, {0x2E45, 0x2E7F}, 364 | {0x2E9A, 0x2E9A}, {0x2EF4, 0x2EFF}, {0x2FD6, 0x2FEF}, 365 | {0x2FFC, 0x2FFF}, {0x3040, 0x3040}, {0x3097, 0x3098}, 366 | {0x3100, 0x3104}, {0x312E, 0x3130}, {0x318F, 0x318F}, 367 | {0x31BB, 0x31BF}, {0x31E4, 0x31EF}, {0x321F, 0x321F}, 368 | {0x32FF, 0x32FF}, {0x4DB6, 0x4DBF}, {0x9FD6, 0x9FFF}, 369 | {0xA48D, 0xA48F}, {0xA4C7, 0xA4CF}, {0xA62C, 0xA63F}, 370 | {0xA6F8, 0xA6FF}, {0xA7AF, 0xA7AF}, {0xA7B8, 0xA7F6}, 371 | {0xA82C, 0xA82F}, {0xA83A, 0xA83F}, {0xA878, 0xA87F}, 372 | {0xA8C6, 0xA8CD}, {0xA8DA, 0xA8DF}, {0xA8FE, 0xA8FF}, 373 | {0xA954, 0xA95E}, {0xA97D, 0xA97F}, {0xA9CE, 0xA9CE}, 374 | {0xA9DA, 0xA9DD}, {0xA9FF, 0xA9FF}, {0xAA37, 0xAA3F}, 375 | {0xAA4E, 0xAA4F}, {0xAA5A, 0xAA5B}, {0xAAC3, 0xAADA}, 376 | {0xAAF7, 0xAB00}, {0xAB07, 0xAB08}, {0xAB0F, 0xAB10}, 377 | {0xAB17, 0xAB1F}, {0xAB27, 0xAB27}, {0xAB2F, 0xAB2F}, 378 | {0xAB66, 0xAB6F}, {0xABEE, 0xABEF}, {0xABFA, 0xABFF}, 379 | {0xD7A4, 0xD7AF}, {0xD7C7, 0xD7CA}, {0xD7FC, 0xD7FF}, 380 | {0xFA6E, 0xFA6F}, {0xFADA, 0xFAFF}, {0xFB07, 0xFB12}, 381 | {0xFB18, 0xFB1C}, {0xFB37, 0xFB37}, {0xFB3D, 0xFB3D}, 382 | {0xFB3F, 0xFB3F}, {0xFB42, 0xFB42}, {0xFB45, 0xFB45}, 383 | {0xFBC2, 0xFBD2}, {0xFD40, 0xFD4F}, {0xFD90, 0xFD91}, 384 | {0xFDC8, 0xFDEF}, {0xFDFE, 0xFDFF}, {0xFE1A, 0xFE1F}, 385 | {0xFE53, 0xFE53}, {0xFE67, 0xFE67}, {0xFE6C, 0xFE6F}, 386 | {0xFE75, 0xFE75}, {0xFEFD, 0xFEFE}, {0xFF00, 0xFF00}, 387 | {0xFFBF, 0xFFC1}, {0xFFC8, 0xFFC9}, {0xFFD0, 0xFFD1}, 388 | {0xFFD8, 0xFFD9}, {0xFFDD, 0xFFDF}, {0xFFE7, 0xFFE7}, 389 | {0xFFEF, 0xFFF8}, {0xFFFE, 0xFFFF}, {0x1000C, 0x1000C}, 390 | {0x10027, 0x10027}, {0x1003B, 0x1003B}, {0x1003E, 0x1003E}, 391 | {0x1004E, 0x1004F}, {0x1005E, 0x1007F}, {0x100FB, 0x100FF}, 392 | {0x10103, 0x10106}, {0x10134, 0x10136}, {0x1018F, 0x1018F}, 393 | {0x1019C, 0x1019F}, {0x101A1, 0x101CF}, {0x101FE, 0x1027F}, 394 | {0x1029D, 0x1029F}, {0x102D1, 0x102DF}, {0x102FC, 0x102FF}, 395 | {0x10324, 0x1032F}, {0x1034B, 0x1034F}, {0x1037B, 0x1037F}, 396 | {0x1039E, 0x1039E}, {0x103C4, 0x103C7}, {0x103D6, 0x103FF}, 397 | {0x1049E, 0x1049F}, {0x104AA, 0x104AF}, {0x104D4, 0x104D7}, 398 | {0x104FC, 0x104FF}, {0x10528, 0x1052F}, {0x10564, 0x1056E}, 399 | {0x10570, 0x105FF}, {0x10737, 0x1073F}, {0x10756, 0x1075F}, 400 | {0x10768, 0x107FF}, {0x10806, 0x10807}, {0x10809, 0x10809}, 401 | {0x10836, 0x10836}, {0x10839, 0x1083B}, {0x1083D, 0x1083E}, 402 | {0x10856, 0x10856}, {0x1089F, 0x108A6}, {0x108B0, 0x108DF}, 403 | {0x108F3, 0x108F3}, {0x108F6, 0x108FA}, {0x1091C, 0x1091E}, 404 | {0x1093A, 0x1093E}, {0x10940, 0x1097F}, {0x109B8, 0x109BB}, 405 | {0x109D0, 0x109D1}, {0x10A04, 0x10A04}, {0x10A07, 0x10A0B}, 406 | {0x10A14, 0x10A14}, {0x10A18, 0x10A18}, {0x10A34, 0x10A37}, 407 | {0x10A3B, 0x10A3E}, {0x10A48, 0x10A4F}, {0x10A59, 0x10A5F}, 408 | {0x10AA0, 0x10ABF}, {0x10AE7, 0x10AEA}, {0x10AF7, 0x10AFF}, 409 | {0x10B36, 0x10B38}, {0x10B56, 0x10B57}, {0x10B73, 0x10B77}, 410 | {0x10B92, 0x10B98}, {0x10B9D, 0x10BA8}, {0x10BB0, 0x10BFF}, 411 | {0x10C49, 0x10C7F}, {0x10CB3, 0x10CBF}, {0x10CF3, 0x10CF9}, 412 | {0x10D00, 0x10E5F}, {0x10E7F, 0x10FFF}, {0x1104E, 0x11051}, 413 | {0x11070, 0x1107E}, {0x110C2, 0x110CF}, {0x110E9, 0x110EF}, 414 | {0x110FA, 0x110FF}, {0x11135, 0x11135}, {0x11144, 0x1114F}, 415 | {0x11177, 0x1117F}, {0x111CE, 0x111CF}, {0x111E0, 0x111E0}, 416 | {0x111F5, 0x111FF}, {0x11212, 0x11212}, {0x1123F, 0x1127F}, 417 | {0x11287, 0x11287}, {0x11289, 0x11289}, {0x1128E, 0x1128E}, 418 | {0x1129E, 0x1129E}, {0x112AA, 0x112AF}, {0x112EB, 0x112EF}, 419 | {0x112FA, 0x112FF}, {0x11304, 0x11304}, {0x1130D, 0x1130E}, 420 | {0x11311, 0x11312}, {0x11329, 0x11329}, {0x11331, 0x11331}, 421 | {0x11334, 0x11334}, {0x1133A, 0x1133B}, {0x11345, 0x11346}, 422 | {0x11349, 0x1134A}, {0x1134E, 0x1134F}, {0x11351, 0x11356}, 423 | {0x11358, 0x1135C}, {0x11364, 0x11365}, {0x1136D, 0x1136F}, 424 | {0x11375, 0x113FF}, {0x1145A, 0x1145A}, {0x1145C, 0x1145C}, 425 | {0x1145E, 0x1147F}, {0x114C8, 0x114CF}, {0x114DA, 0x1157F}, 426 | {0x115B6, 0x115B7}, {0x115DE, 0x115FF}, {0x11645, 0x1164F}, 427 | {0x1165A, 0x1165F}, {0x1166D, 0x1167F}, {0x116B8, 0x116BF}, 428 | {0x116CA, 0x116FF}, {0x1171A, 0x1171C}, {0x1172C, 0x1172F}, 429 | {0x11740, 0x1189F}, {0x118F3, 0x118FE}, {0x11900, 0x11ABF}, 430 | {0x11AF9, 0x11BFF}, {0x11C09, 0x11C09}, {0x11C37, 0x11C37}, 431 | {0x11C46, 0x11C4F}, {0x11C6D, 0x11C6F}, {0x11C90, 0x11C91}, 432 | {0x11CA8, 0x11CA8}, {0x11CB7, 0x11FFF}, {0x1239A, 0x123FF}, 433 | {0x1246F, 0x1246F}, {0x12475, 0x1247F}, {0x12544, 0x12FFF}, 434 | {0x1342F, 0x143FF}, {0x14647, 0x167FF}, {0x16A39, 0x16A3F}, 435 | {0x16A5F, 0x16A5F}, {0x16A6A, 0x16A6D}, {0x16A70, 0x16ACF}, 436 | {0x16AEE, 0x16AEF}, {0x16AF6, 0x16AFF}, {0x16B46, 0x16B4F}, 437 | {0x16B5A, 0x16B5A}, {0x16B62, 0x16B62}, {0x16B78, 0x16B7C}, 438 | {0x16B90, 0x16EFF}, {0x16F45, 0x16F4F}, {0x16F7F, 0x16F8E}, 439 | {0x16FA0, 0x16FDF}, {0x16FE1, 0x16FFF}, {0x187ED, 0x187FF}, 440 | {0x18AF3, 0x1AFFF}, {0x1B002, 0x1BBFF}, {0x1BC6B, 0x1BC6F}, 441 | {0x1BC7D, 0x1BC7F}, {0x1BC89, 0x1BC8F}, {0x1BC9A, 0x1BC9B}, 442 | {0x1BCA4, 0x1CFFF}, {0x1D0F6, 0x1D0FF}, {0x1D127, 0x1D128}, 443 | {0x1D1E9, 0x1D1FF}, {0x1D246, 0x1D2FF}, {0x1D357, 0x1D35F}, 444 | {0x1D372, 0x1D3FF}, {0x1D455, 0x1D455}, {0x1D49D, 0x1D49D}, 445 | {0x1D4A0, 0x1D4A1}, {0x1D4A3, 0x1D4A4}, {0x1D4A7, 0x1D4A8}, 446 | {0x1D4AD, 0x1D4AD}, {0x1D4BA, 0x1D4BA}, {0x1D4BC, 0x1D4BC}, 447 | {0x1D4C4, 0x1D4C4}, {0x1D506, 0x1D506}, {0x1D50B, 0x1D50C}, 448 | {0x1D515, 0x1D515}, {0x1D51D, 0x1D51D}, {0x1D53A, 0x1D53A}, 449 | {0x1D53F, 0x1D53F}, {0x1D545, 0x1D545}, {0x1D547, 0x1D549}, 450 | {0x1D551, 0x1D551}, {0x1D6A6, 0x1D6A7}, {0x1D7CC, 0x1D7CD}, 451 | {0x1DA8C, 0x1DA9A}, {0x1DAA0, 0x1DAA0}, {0x1DAB0, 0x1DFFF}, 452 | {0x1E007, 0x1E007}, {0x1E019, 0x1E01A}, {0x1E022, 0x1E022}, 453 | {0x1E025, 0x1E025}, {0x1E02B, 0x1E7FF}, {0x1E8C5, 0x1E8C6}, 454 | {0x1E8D7, 0x1E8FF}, {0x1E94B, 0x1E94F}, {0x1E95A, 0x1E95D}, 455 | {0x1E960, 0x1EDFF}, {0x1EE04, 0x1EE04}, {0x1EE20, 0x1EE20}, 456 | {0x1EE23, 0x1EE23}, {0x1EE25, 0x1EE26}, {0x1EE28, 0x1EE28}, 457 | {0x1EE33, 0x1EE33}, {0x1EE38, 0x1EE38}, {0x1EE3A, 0x1EE3A}, 458 | {0x1EE3C, 0x1EE41}, {0x1EE43, 0x1EE46}, {0x1EE48, 0x1EE48}, 459 | {0x1EE4A, 0x1EE4A}, {0x1EE4C, 0x1EE4C}, {0x1EE50, 0x1EE50}, 460 | {0x1EE53, 0x1EE53}, {0x1EE55, 0x1EE56}, {0x1EE58, 0x1EE58}, 461 | {0x1EE5A, 0x1EE5A}, {0x1EE5C, 0x1EE5C}, {0x1EE5E, 0x1EE5E}, 462 | {0x1EE60, 0x1EE60}, {0x1EE63, 0x1EE63}, {0x1EE65, 0x1EE66}, 463 | {0x1EE6B, 0x1EE6B}, {0x1EE73, 0x1EE73}, {0x1EE78, 0x1EE78}, 464 | {0x1EE7D, 0x1EE7D}, {0x1EE7F, 0x1EE7F}, {0x1EE8A, 0x1EE8A}, 465 | {0x1EE9C, 0x1EEA0}, {0x1EEA4, 0x1EEA4}, {0x1EEAA, 0x1EEAA}, 466 | {0x1EEBC, 0x1EEEF}, {0x1EEF2, 0x1EFFF}, {0x1F02C, 0x1F02F}, 467 | {0x1F094, 0x1F09F}, {0x1F0AF, 0x1F0B0}, {0x1F0C0, 0x1F0C0}, 468 | {0x1F0D0, 0x1F0D0}, {0x1F0F6, 0x1F0FF}, {0x1F10D, 0x1F10F}, 469 | {0x1F12F, 0x1F12F}, {0x1F16C, 0x1F16F}, {0x1F1AD, 0x1F1E5}, 470 | {0x1F203, 0x1F20F}, {0x1F23C, 0x1F23F}, {0x1F249, 0x1F24F}, 471 | {0x1F252, 0x1F2FF}, {0x1F6D3, 0x1F6DF}, {0x1F6ED, 0x1F6EF}, 472 | {0x1F6F7, 0x1F6FF}, {0x1F774, 0x1F77F}, {0x1F7D5, 0x1F7FF}, 473 | {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F}, {0x1F85A, 0x1F85F}, 474 | {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F90F}, {0x1F91F, 0x1F91F}, 475 | {0x1F928, 0x1F92F}, {0x1F931, 0x1F932}, {0x1F93F, 0x1F93F}, 476 | {0x1F94C, 0x1F94F}, {0x1F95F, 0x1F97F}, {0x1F992, 0x1F9BF}, 477 | {0x1F9C1, 0x1FFFF}, {0x2A6D7, 0x2A6FF}, {0x2B735, 0x2B73F}, 478 | {0x2B81E, 0x2B81F}, {0x2CEA2, 0x2F7FF}, {0x2FA1E, 0xE0000}, 479 | {0xE0002, 0xE001F}, {0xE0080, 0xE00FF}, {0xE01F0, 0xEFFFF}, 480 | {0xFFFFE, 0xFFFFF}, 481 | } 482 | 483 | var neutral = table{ 484 | {0x0000, 0x001F}, {0x007F, 0x007F}, {0x0080, 0x009F}, 485 | {0x00A0, 0x00A0}, {0x00A9, 0x00A9}, {0x00AB, 0x00AB}, 486 | {0x00B5, 0x00B5}, {0x00BB, 0x00BB}, {0x00C0, 0x00C5}, 487 | {0x00C7, 0x00CF}, {0x00D1, 0x00D6}, {0x00D9, 0x00DD}, 488 | {0x00E2, 0x00E5}, {0x00E7, 0x00E7}, {0x00EB, 0x00EB}, 489 | {0x00EE, 0x00EF}, {0x00F1, 0x00F1}, {0x00F4, 0x00F6}, 490 | {0x00FB, 0x00FB}, {0x00FD, 0x00FD}, {0x00FF, 0x00FF}, 491 | {0x0100, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112}, 492 | {0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A}, 493 | {0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E}, 494 | {0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C}, 495 | {0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A}, 496 | {0x016C, 0x017F}, {0x0180, 0x01BA}, {0x01BB, 0x01BB}, 497 | {0x01BC, 0x01BF}, {0x01C0, 0x01C3}, {0x01C4, 0x01CD}, 498 | {0x01CF, 0x01CF}, {0x01D1, 0x01D1}, {0x01D3, 0x01D3}, 499 | {0x01D5, 0x01D5}, {0x01D7, 0x01D7}, {0x01D9, 0x01D9}, 500 | {0x01DB, 0x01DB}, {0x01DD, 0x024F}, {0x0250, 0x0250}, 501 | {0x0252, 0x0260}, {0x0262, 0x0293}, {0x0294, 0x0294}, 502 | {0x0295, 0x02AF}, {0x02B0, 0x02C1}, {0x02C2, 0x02C3}, 503 | {0x02C5, 0x02C5}, {0x02C6, 0x02C6}, {0x02C8, 0x02C8}, 504 | {0x02CC, 0x02CC}, {0x02CE, 0x02CF}, {0x02D1, 0x02D1}, 505 | {0x02D2, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE}, 506 | {0x02E0, 0x02E4}, {0x02E5, 0x02EB}, {0x02EC, 0x02EC}, 507 | {0x02ED, 0x02ED}, {0x02EE, 0x02EE}, {0x02EF, 0x02FF}, 508 | {0x0370, 0x0373}, {0x0374, 0x0374}, {0x0375, 0x0375}, 509 | {0x0376, 0x0377}, {0x037A, 0x037A}, {0x037B, 0x037D}, 510 | {0x037E, 0x037E}, {0x037F, 0x037F}, {0x0384, 0x0385}, 511 | {0x0386, 0x0386}, {0x0387, 0x0387}, {0x0388, 0x038A}, 512 | {0x038C, 0x038C}, {0x038E, 0x0390}, {0x03AA, 0x03B0}, 513 | {0x03C2, 0x03C2}, {0x03CA, 0x03F5}, {0x03F6, 0x03F6}, 514 | {0x03F7, 0x03FF}, {0x0400, 0x0400}, {0x0402, 0x040F}, 515 | {0x0450, 0x0450}, {0x0452, 0x0481}, {0x0482, 0x0482}, 516 | {0x0483, 0x0487}, {0x0488, 0x0489}, {0x048A, 0x04FF}, 517 | {0x0500, 0x052F}, {0x0531, 0x0556}, {0x0559, 0x0559}, 518 | {0x055A, 0x055F}, {0x0561, 0x0587}, {0x0589, 0x0589}, 519 | {0x058A, 0x058A}, {0x058D, 0x058E}, {0x058F, 0x058F}, 520 | {0x0591, 0x05BD}, {0x05BE, 0x05BE}, {0x05BF, 0x05BF}, 521 | {0x05C0, 0x05C0}, {0x05C1, 0x05C2}, {0x05C3, 0x05C3}, 522 | {0x05C4, 0x05C5}, {0x05C6, 0x05C6}, {0x05C7, 0x05C7}, 523 | {0x05D0, 0x05EA}, {0x05F0, 0x05F2}, {0x05F3, 0x05F4}, 524 | {0x0600, 0x0605}, {0x0606, 0x0608}, {0x0609, 0x060A}, 525 | {0x060B, 0x060B}, {0x060C, 0x060D}, {0x060E, 0x060F}, 526 | {0x0610, 0x061A}, {0x061B, 0x061B}, {0x061C, 0x061C}, 527 | {0x061E, 0x061F}, {0x0620, 0x063F}, {0x0640, 0x0640}, 528 | {0x0641, 0x064A}, {0x064B, 0x065F}, {0x0660, 0x0669}, 529 | {0x066A, 0x066D}, {0x066E, 0x066F}, {0x0670, 0x0670}, 530 | {0x0671, 0x06D3}, {0x06D4, 0x06D4}, {0x06D5, 0x06D5}, 531 | {0x06D6, 0x06DC}, {0x06DD, 0x06DD}, {0x06DE, 0x06DE}, 532 | {0x06DF, 0x06E4}, {0x06E5, 0x06E6}, {0x06E7, 0x06E8}, 533 | {0x06E9, 0x06E9}, {0x06EA, 0x06ED}, {0x06EE, 0x06EF}, 534 | {0x06F0, 0x06F9}, {0x06FA, 0x06FC}, {0x06FD, 0x06FE}, 535 | {0x06FF, 0x06FF}, {0x0700, 0x070D}, {0x070F, 0x070F}, 536 | {0x0710, 0x0710}, {0x0711, 0x0711}, {0x0712, 0x072F}, 537 | {0x0730, 0x074A}, {0x074D, 0x074F}, {0x0750, 0x077F}, 538 | {0x0780, 0x07A5}, {0x07A6, 0x07B0}, {0x07B1, 0x07B1}, 539 | {0x07C0, 0x07C9}, {0x07CA, 0x07EA}, {0x07EB, 0x07F3}, 540 | {0x07F4, 0x07F5}, {0x07F6, 0x07F6}, {0x07F7, 0x07F9}, 541 | {0x07FA, 0x07FA}, {0x0800, 0x0815}, {0x0816, 0x0819}, 542 | {0x081A, 0x081A}, {0x081B, 0x0823}, {0x0824, 0x0824}, 543 | {0x0825, 0x0827}, {0x0828, 0x0828}, {0x0829, 0x082D}, 544 | {0x0830, 0x083E}, {0x0840, 0x0858}, {0x0859, 0x085B}, 545 | {0x085E, 0x085E}, {0x08A0, 0x08B4}, {0x08B6, 0x08BD}, 546 | {0x08D4, 0x08E1}, {0x08E2, 0x08E2}, {0x08E3, 0x08FF}, 547 | {0x0900, 0x0902}, {0x0903, 0x0903}, {0x0904, 0x0939}, 548 | {0x093A, 0x093A}, {0x093B, 0x093B}, {0x093C, 0x093C}, 549 | {0x093D, 0x093D}, {0x093E, 0x0940}, {0x0941, 0x0948}, 550 | {0x0949, 0x094C}, {0x094D, 0x094D}, {0x094E, 0x094F}, 551 | {0x0950, 0x0950}, {0x0951, 0x0957}, {0x0958, 0x0961}, 552 | {0x0962, 0x0963}, {0x0964, 0x0965}, {0x0966, 0x096F}, 553 | {0x0970, 0x0970}, {0x0971, 0x0971}, {0x0972, 0x097F}, 554 | {0x0980, 0x0980}, {0x0981, 0x0981}, {0x0982, 0x0983}, 555 | {0x0985, 0x098C}, {0x098F, 0x0990}, {0x0993, 0x09A8}, 556 | {0x09AA, 0x09B0}, {0x09B2, 0x09B2}, {0x09B6, 0x09B9}, 557 | {0x09BC, 0x09BC}, {0x09BD, 0x09BD}, {0x09BE, 0x09C0}, 558 | {0x09C1, 0x09C4}, {0x09C7, 0x09C8}, {0x09CB, 0x09CC}, 559 | {0x09CD, 0x09CD}, {0x09CE, 0x09CE}, {0x09D7, 0x09D7}, 560 | {0x09DC, 0x09DD}, {0x09DF, 0x09E1}, {0x09E2, 0x09E3}, 561 | {0x09E6, 0x09EF}, {0x09F0, 0x09F1}, {0x09F2, 0x09F3}, 562 | {0x09F4, 0x09F9}, {0x09FA, 0x09FA}, {0x09FB, 0x09FB}, 563 | {0x0A01, 0x0A02}, {0x0A03, 0x0A03}, {0x0A05, 0x0A0A}, 564 | {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30}, 565 | {0x0A32, 0x0A33}, {0x0A35, 0x0A36}, {0x0A38, 0x0A39}, 566 | {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A40}, {0x0A41, 0x0A42}, 567 | {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51}, 568 | {0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E}, {0x0A66, 0x0A6F}, 569 | {0x0A70, 0x0A71}, {0x0A72, 0x0A74}, {0x0A75, 0x0A75}, 570 | {0x0A81, 0x0A82}, {0x0A83, 0x0A83}, {0x0A85, 0x0A8D}, 571 | {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0}, 572 | {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0ABC, 0x0ABC}, 573 | {0x0ABD, 0x0ABD}, {0x0ABE, 0x0AC0}, {0x0AC1, 0x0AC5}, 574 | {0x0AC7, 0x0AC8}, {0x0AC9, 0x0AC9}, {0x0ACB, 0x0ACC}, 575 | {0x0ACD, 0x0ACD}, {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE1}, 576 | {0x0AE2, 0x0AE3}, {0x0AE6, 0x0AEF}, {0x0AF0, 0x0AF0}, 577 | {0x0AF1, 0x0AF1}, {0x0AF9, 0x0AF9}, {0x0B01, 0x0B01}, 578 | {0x0B02, 0x0B03}, {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, 579 | {0x0B13, 0x0B28}, {0x0B2A, 0x0B30}, {0x0B32, 0x0B33}, 580 | {0x0B35, 0x0B39}, {0x0B3C, 0x0B3C}, {0x0B3D, 0x0B3D}, 581 | {0x0B3E, 0x0B3E}, {0x0B3F, 0x0B3F}, {0x0B40, 0x0B40}, 582 | {0x0B41, 0x0B44}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4C}, 583 | {0x0B4D, 0x0B4D}, {0x0B56, 0x0B56}, {0x0B57, 0x0B57}, 584 | {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B61}, {0x0B62, 0x0B63}, 585 | {0x0B66, 0x0B6F}, {0x0B70, 0x0B70}, {0x0B71, 0x0B71}, 586 | {0x0B72, 0x0B77}, {0x0B82, 0x0B82}, {0x0B83, 0x0B83}, 587 | {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, 588 | {0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F}, 589 | {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9}, 590 | {0x0BBE, 0x0BBF}, {0x0BC0, 0x0BC0}, {0x0BC1, 0x0BC2}, 591 | {0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCC}, {0x0BCD, 0x0BCD}, 592 | {0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7}, {0x0BE6, 0x0BEF}, 593 | {0x0BF0, 0x0BF2}, {0x0BF3, 0x0BF8}, {0x0BF9, 0x0BF9}, 594 | {0x0BFA, 0x0BFA}, {0x0C00, 0x0C00}, {0x0C01, 0x0C03}, 595 | {0x0C05, 0x0C0C}, {0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, 596 | {0x0C2A, 0x0C39}, {0x0C3D, 0x0C3D}, {0x0C3E, 0x0C40}, 597 | {0x0C41, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, 598 | {0x0C55, 0x0C56}, {0x0C58, 0x0C5A}, {0x0C60, 0x0C61}, 599 | {0x0C62, 0x0C63}, {0x0C66, 0x0C6F}, {0x0C78, 0x0C7E}, 600 | {0x0C7F, 0x0C7F}, {0x0C80, 0x0C80}, {0x0C81, 0x0C81}, 601 | {0x0C82, 0x0C83}, {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90}, 602 | {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9}, 603 | {0x0CBC, 0x0CBC}, {0x0CBD, 0x0CBD}, {0x0CBE, 0x0CBE}, 604 | {0x0CBF, 0x0CBF}, {0x0CC0, 0x0CC4}, {0x0CC6, 0x0CC6}, 605 | {0x0CC7, 0x0CC8}, {0x0CCA, 0x0CCB}, {0x0CCC, 0x0CCD}, 606 | {0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE1}, 607 | {0x0CE2, 0x0CE3}, {0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2}, 608 | {0x0D01, 0x0D01}, {0x0D02, 0x0D03}, {0x0D05, 0x0D0C}, 609 | {0x0D0E, 0x0D10}, {0x0D12, 0x0D3A}, {0x0D3D, 0x0D3D}, 610 | {0x0D3E, 0x0D40}, {0x0D41, 0x0D44}, {0x0D46, 0x0D48}, 611 | {0x0D4A, 0x0D4C}, {0x0D4D, 0x0D4D}, {0x0D4E, 0x0D4E}, 612 | {0x0D4F, 0x0D4F}, {0x0D54, 0x0D56}, {0x0D57, 0x0D57}, 613 | {0x0D58, 0x0D5E}, {0x0D5F, 0x0D61}, {0x0D62, 0x0D63}, 614 | {0x0D66, 0x0D6F}, {0x0D70, 0x0D78}, {0x0D79, 0x0D79}, 615 | {0x0D7A, 0x0D7F}, {0x0D82, 0x0D83}, {0x0D85, 0x0D96}, 616 | {0x0D9A, 0x0DB1}, {0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD}, 617 | {0x0DC0, 0x0DC6}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD1}, 618 | {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, 619 | {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF3}, {0x0DF4, 0x0DF4}, 620 | {0x0E01, 0x0E30}, {0x0E31, 0x0E31}, {0x0E32, 0x0E33}, 621 | {0x0E34, 0x0E3A}, {0x0E3F, 0x0E3F}, {0x0E40, 0x0E45}, 622 | {0x0E46, 0x0E46}, {0x0E47, 0x0E4E}, {0x0E4F, 0x0E4F}, 623 | {0x0E50, 0x0E59}, {0x0E5A, 0x0E5B}, {0x0E81, 0x0E82}, 624 | {0x0E84, 0x0E84}, {0x0E87, 0x0E88}, {0x0E8A, 0x0E8A}, 625 | {0x0E8D, 0x0E8D}, {0x0E94, 0x0E97}, {0x0E99, 0x0E9F}, 626 | {0x0EA1, 0x0EA3}, {0x0EA5, 0x0EA5}, {0x0EA7, 0x0EA7}, 627 | {0x0EAA, 0x0EAB}, {0x0EAD, 0x0EB0}, {0x0EB1, 0x0EB1}, 628 | {0x0EB2, 0x0EB3}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, 629 | {0x0EBD, 0x0EBD}, {0x0EC0, 0x0EC4}, {0x0EC6, 0x0EC6}, 630 | {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9}, {0x0EDC, 0x0EDF}, 631 | {0x0F00, 0x0F00}, {0x0F01, 0x0F03}, {0x0F04, 0x0F12}, 632 | {0x0F13, 0x0F13}, {0x0F14, 0x0F14}, {0x0F15, 0x0F17}, 633 | {0x0F18, 0x0F19}, {0x0F1A, 0x0F1F}, {0x0F20, 0x0F29}, 634 | {0x0F2A, 0x0F33}, {0x0F34, 0x0F34}, {0x0F35, 0x0F35}, 635 | {0x0F36, 0x0F36}, {0x0F37, 0x0F37}, {0x0F38, 0x0F38}, 636 | {0x0F39, 0x0F39}, {0x0F3A, 0x0F3A}, {0x0F3B, 0x0F3B}, 637 | {0x0F3C, 0x0F3C}, {0x0F3D, 0x0F3D}, {0x0F3E, 0x0F3F}, 638 | {0x0F40, 0x0F47}, {0x0F49, 0x0F6C}, {0x0F71, 0x0F7E}, 639 | {0x0F7F, 0x0F7F}, {0x0F80, 0x0F84}, {0x0F85, 0x0F85}, 640 | {0x0F86, 0x0F87}, {0x0F88, 0x0F8C}, {0x0F8D, 0x0F97}, 641 | {0x0F99, 0x0FBC}, {0x0FBE, 0x0FC5}, {0x0FC6, 0x0FC6}, 642 | {0x0FC7, 0x0FCC}, {0x0FCE, 0x0FCF}, {0x0FD0, 0x0FD4}, 643 | {0x0FD5, 0x0FD8}, {0x0FD9, 0x0FDA}, {0x1000, 0x102A}, 644 | {0x102B, 0x102C}, {0x102D, 0x1030}, {0x1031, 0x1031}, 645 | {0x1032, 0x1037}, {0x1038, 0x1038}, {0x1039, 0x103A}, 646 | {0x103B, 0x103C}, {0x103D, 0x103E}, {0x103F, 0x103F}, 647 | {0x1040, 0x1049}, {0x104A, 0x104F}, {0x1050, 0x1055}, 648 | {0x1056, 0x1057}, {0x1058, 0x1059}, {0x105A, 0x105D}, 649 | {0x105E, 0x1060}, {0x1061, 0x1061}, {0x1062, 0x1064}, 650 | {0x1065, 0x1066}, {0x1067, 0x106D}, {0x106E, 0x1070}, 651 | {0x1071, 0x1074}, {0x1075, 0x1081}, {0x1082, 0x1082}, 652 | {0x1083, 0x1084}, {0x1085, 0x1086}, {0x1087, 0x108C}, 653 | {0x108D, 0x108D}, {0x108E, 0x108E}, {0x108F, 0x108F}, 654 | {0x1090, 0x1099}, {0x109A, 0x109C}, {0x109D, 0x109D}, 655 | {0x109E, 0x109F}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, 656 | {0x10CD, 0x10CD}, {0x10D0, 0x10FA}, {0x10FB, 0x10FB}, 657 | {0x10FC, 0x10FC}, {0x10FD, 0x10FF}, {0x1160, 0x11FF}, 658 | {0x1200, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256}, 659 | {0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288}, 660 | {0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5}, 661 | {0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, 662 | {0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315}, 663 | {0x1318, 0x135A}, {0x135D, 0x135F}, {0x1360, 0x1368}, 664 | {0x1369, 0x137C}, {0x1380, 0x138F}, {0x1390, 0x1399}, 665 | {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1400, 0x1400}, 666 | {0x1401, 0x166C}, {0x166D, 0x166E}, {0x166F, 0x167F}, 667 | {0x1680, 0x1680}, {0x1681, 0x169A}, {0x169B, 0x169B}, 668 | {0x169C, 0x169C}, {0x16A0, 0x16EA}, {0x16EB, 0x16ED}, 669 | {0x16EE, 0x16F0}, {0x16F1, 0x16F8}, {0x1700, 0x170C}, 670 | {0x170E, 0x1711}, {0x1712, 0x1714}, {0x1720, 0x1731}, 671 | {0x1732, 0x1734}, {0x1735, 0x1736}, {0x1740, 0x1751}, 672 | {0x1752, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770}, 673 | {0x1772, 0x1773}, {0x1780, 0x17B3}, {0x17B4, 0x17B5}, 674 | {0x17B6, 0x17B6}, {0x17B7, 0x17BD}, {0x17BE, 0x17C5}, 675 | {0x17C6, 0x17C6}, {0x17C7, 0x17C8}, {0x17C9, 0x17D3}, 676 | {0x17D4, 0x17D6}, {0x17D7, 0x17D7}, {0x17D8, 0x17DA}, 677 | {0x17DB, 0x17DB}, {0x17DC, 0x17DC}, {0x17DD, 0x17DD}, 678 | {0x17E0, 0x17E9}, {0x17F0, 0x17F9}, {0x1800, 0x1805}, 679 | {0x1806, 0x1806}, {0x1807, 0x180A}, {0x180B, 0x180D}, 680 | {0x180E, 0x180E}, {0x1810, 0x1819}, {0x1820, 0x1842}, 681 | {0x1843, 0x1843}, {0x1844, 0x1877}, {0x1880, 0x1884}, 682 | {0x1885, 0x1886}, {0x1887, 0x18A8}, {0x18A9, 0x18A9}, 683 | {0x18AA, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E}, 684 | {0x1920, 0x1922}, {0x1923, 0x1926}, {0x1927, 0x1928}, 685 | {0x1929, 0x192B}, {0x1930, 0x1931}, {0x1932, 0x1932}, 686 | {0x1933, 0x1938}, {0x1939, 0x193B}, {0x1940, 0x1940}, 687 | {0x1944, 0x1945}, {0x1946, 0x194F}, {0x1950, 0x196D}, 688 | {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, 689 | {0x19D0, 0x19D9}, {0x19DA, 0x19DA}, {0x19DE, 0x19DF}, 690 | {0x19E0, 0x19FF}, {0x1A00, 0x1A16}, {0x1A17, 0x1A18}, 691 | {0x1A19, 0x1A1A}, {0x1A1B, 0x1A1B}, {0x1A1E, 0x1A1F}, 692 | {0x1A20, 0x1A54}, {0x1A55, 0x1A55}, {0x1A56, 0x1A56}, 693 | {0x1A57, 0x1A57}, {0x1A58, 0x1A5E}, {0x1A60, 0x1A60}, 694 | {0x1A61, 0x1A61}, {0x1A62, 0x1A62}, {0x1A63, 0x1A64}, 695 | {0x1A65, 0x1A6C}, {0x1A6D, 0x1A72}, {0x1A73, 0x1A7C}, 696 | {0x1A7F, 0x1A7F}, {0x1A80, 0x1A89}, {0x1A90, 0x1A99}, 697 | {0x1AA0, 0x1AA6}, {0x1AA7, 0x1AA7}, {0x1AA8, 0x1AAD}, 698 | {0x1AB0, 0x1ABD}, {0x1ABE, 0x1ABE}, {0x1B00, 0x1B03}, 699 | {0x1B04, 0x1B04}, {0x1B05, 0x1B33}, {0x1B34, 0x1B34}, 700 | {0x1B35, 0x1B35}, {0x1B36, 0x1B3A}, {0x1B3B, 0x1B3B}, 701 | {0x1B3C, 0x1B3C}, {0x1B3D, 0x1B41}, {0x1B42, 0x1B42}, 702 | {0x1B43, 0x1B44}, {0x1B45, 0x1B4B}, {0x1B50, 0x1B59}, 703 | {0x1B5A, 0x1B60}, {0x1B61, 0x1B6A}, {0x1B6B, 0x1B73}, 704 | {0x1B74, 0x1B7C}, {0x1B80, 0x1B81}, {0x1B82, 0x1B82}, 705 | {0x1B83, 0x1BA0}, {0x1BA1, 0x1BA1}, {0x1BA2, 0x1BA5}, 706 | {0x1BA6, 0x1BA7}, {0x1BA8, 0x1BA9}, {0x1BAA, 0x1BAA}, 707 | {0x1BAB, 0x1BAD}, {0x1BAE, 0x1BAF}, {0x1BB0, 0x1BB9}, 708 | {0x1BBA, 0x1BBF}, {0x1BC0, 0x1BE5}, {0x1BE6, 0x1BE6}, 709 | {0x1BE7, 0x1BE7}, {0x1BE8, 0x1BE9}, {0x1BEA, 0x1BEC}, 710 | {0x1BED, 0x1BED}, {0x1BEE, 0x1BEE}, {0x1BEF, 0x1BF1}, 711 | {0x1BF2, 0x1BF3}, {0x1BFC, 0x1BFF}, {0x1C00, 0x1C23}, 712 | {0x1C24, 0x1C2B}, {0x1C2C, 0x1C33}, {0x1C34, 0x1C35}, 713 | {0x1C36, 0x1C37}, {0x1C3B, 0x1C3F}, {0x1C40, 0x1C49}, 714 | {0x1C4D, 0x1C4F}, {0x1C50, 0x1C59}, {0x1C5A, 0x1C77}, 715 | {0x1C78, 0x1C7D}, {0x1C7E, 0x1C7F}, {0x1C80, 0x1C88}, 716 | {0x1CC0, 0x1CC7}, {0x1CD0, 0x1CD2}, {0x1CD3, 0x1CD3}, 717 | {0x1CD4, 0x1CE0}, {0x1CE1, 0x1CE1}, {0x1CE2, 0x1CE8}, 718 | {0x1CE9, 0x1CEC}, {0x1CED, 0x1CED}, {0x1CEE, 0x1CF1}, 719 | {0x1CF2, 0x1CF3}, {0x1CF4, 0x1CF4}, {0x1CF5, 0x1CF6}, 720 | {0x1CF8, 0x1CF9}, {0x1D00, 0x1D2B}, {0x1D2C, 0x1D6A}, 721 | {0x1D6B, 0x1D77}, {0x1D78, 0x1D78}, {0x1D79, 0x1D7F}, 722 | {0x1D80, 0x1D9A}, {0x1D9B, 0x1DBF}, {0x1DC0, 0x1DF5}, 723 | {0x1DFB, 0x1DFF}, {0x1E00, 0x1EFF}, {0x1F00, 0x1F15}, 724 | {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, 725 | {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, 726 | {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, 727 | {0x1FB6, 0x1FBC}, {0x1FBD, 0x1FBD}, {0x1FBE, 0x1FBE}, 728 | {0x1FBF, 0x1FC1}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, 729 | {0x1FCD, 0x1FCF}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB}, 730 | {0x1FDD, 0x1FDF}, {0x1FE0, 0x1FEC}, {0x1FED, 0x1FEF}, 731 | {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x1FFD, 0x1FFE}, 732 | {0x2000, 0x200A}, {0x200B, 0x200F}, {0x2011, 0x2012}, 733 | {0x2017, 0x2017}, {0x201A, 0x201A}, {0x201B, 0x201B}, 734 | {0x201E, 0x201E}, {0x201F, 0x201F}, {0x2023, 0x2023}, 735 | {0x2028, 0x2028}, {0x2029, 0x2029}, {0x202A, 0x202E}, 736 | {0x202F, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034}, 737 | {0x2036, 0x2038}, {0x2039, 0x2039}, {0x203A, 0x203A}, 738 | {0x203C, 0x203D}, {0x203F, 0x2040}, {0x2041, 0x2043}, 739 | {0x2044, 0x2044}, {0x2045, 0x2045}, {0x2046, 0x2046}, 740 | {0x2047, 0x2051}, {0x2052, 0x2052}, {0x2053, 0x2053}, 741 | {0x2054, 0x2054}, {0x2055, 0x205E}, {0x205F, 0x205F}, 742 | {0x2060, 0x2064}, {0x2066, 0x206F}, {0x2070, 0x2070}, 743 | {0x2071, 0x2071}, {0x2075, 0x2079}, {0x207A, 0x207C}, 744 | {0x207D, 0x207D}, {0x207E, 0x207E}, {0x2080, 0x2080}, 745 | {0x2085, 0x2089}, {0x208A, 0x208C}, {0x208D, 0x208D}, 746 | {0x208E, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8}, 747 | {0x20AA, 0x20AB}, {0x20AD, 0x20BE}, {0x20D0, 0x20DC}, 748 | {0x20DD, 0x20E0}, {0x20E1, 0x20E1}, {0x20E2, 0x20E4}, 749 | {0x20E5, 0x20F0}, {0x2100, 0x2101}, {0x2102, 0x2102}, 750 | {0x2104, 0x2104}, {0x2106, 0x2106}, {0x2107, 0x2107}, 751 | {0x2108, 0x2108}, {0x210A, 0x2112}, {0x2114, 0x2114}, 752 | {0x2115, 0x2115}, {0x2117, 0x2117}, {0x2118, 0x2118}, 753 | {0x2119, 0x211D}, {0x211E, 0x2120}, {0x2123, 0x2123}, 754 | {0x2124, 0x2124}, {0x2125, 0x2125}, {0x2127, 0x2127}, 755 | {0x2128, 0x2128}, {0x2129, 0x2129}, {0x212A, 0x212A}, 756 | {0x212C, 0x212D}, {0x212E, 0x212E}, {0x212F, 0x2134}, 757 | {0x2135, 0x2138}, {0x2139, 0x2139}, {0x213A, 0x213B}, 758 | {0x213C, 0x213F}, {0x2140, 0x2144}, {0x2145, 0x2149}, 759 | {0x214A, 0x214A}, {0x214B, 0x214B}, {0x214C, 0x214D}, 760 | {0x214E, 0x214E}, {0x214F, 0x214F}, {0x2150, 0x2152}, 761 | {0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F}, 762 | {0x217A, 0x2182}, {0x2183, 0x2184}, {0x2185, 0x2188}, 763 | {0x218A, 0x218B}, {0x219A, 0x219B}, {0x219C, 0x219F}, 764 | {0x21A0, 0x21A0}, {0x21A1, 0x21A2}, {0x21A3, 0x21A3}, 765 | {0x21A4, 0x21A5}, {0x21A6, 0x21A6}, {0x21A7, 0x21AD}, 766 | {0x21AE, 0x21AE}, {0x21AF, 0x21B7}, {0x21BA, 0x21CD}, 767 | {0x21CE, 0x21CF}, {0x21D0, 0x21D1}, {0x21D3, 0x21D3}, 768 | {0x21D5, 0x21E6}, {0x21E8, 0x21F3}, {0x21F4, 0x21FF}, 769 | {0x2201, 0x2201}, {0x2204, 0x2206}, {0x2209, 0x220A}, 770 | {0x220C, 0x220E}, {0x2210, 0x2210}, {0x2212, 0x2214}, 771 | {0x2216, 0x2219}, {0x221B, 0x221C}, {0x2221, 0x2222}, 772 | {0x2224, 0x2224}, {0x2226, 0x2226}, {0x222D, 0x222D}, 773 | {0x222F, 0x2233}, {0x2238, 0x223B}, {0x223E, 0x2247}, 774 | {0x2249, 0x224B}, {0x224D, 0x2251}, {0x2253, 0x225F}, 775 | {0x2262, 0x2263}, {0x2268, 0x2269}, {0x226C, 0x226D}, 776 | {0x2270, 0x2281}, {0x2284, 0x2285}, {0x2288, 0x2294}, 777 | {0x2296, 0x2298}, {0x229A, 0x22A4}, {0x22A6, 0x22BE}, 778 | {0x22C0, 0x22FF}, {0x2300, 0x2307}, {0x2308, 0x2308}, 779 | {0x2309, 0x2309}, {0x230A, 0x230A}, {0x230B, 0x230B}, 780 | {0x230C, 0x2311}, {0x2313, 0x2319}, {0x231C, 0x231F}, 781 | {0x2320, 0x2321}, {0x2322, 0x2328}, {0x232B, 0x237B}, 782 | {0x237C, 0x237C}, {0x237D, 0x239A}, {0x239B, 0x23B3}, 783 | {0x23B4, 0x23DB}, {0x23DC, 0x23E1}, {0x23E2, 0x23E8}, 784 | {0x23ED, 0x23EF}, {0x23F1, 0x23F2}, {0x23F4, 0x23FE}, 785 | {0x2400, 0x2426}, {0x2440, 0x244A}, {0x24EA, 0x24EA}, 786 | {0x254C, 0x254F}, {0x2574, 0x257F}, {0x2590, 0x2591}, 787 | {0x2596, 0x259F}, {0x25A2, 0x25A2}, {0x25AA, 0x25B1}, 788 | {0x25B4, 0x25B5}, {0x25B8, 0x25BB}, {0x25BE, 0x25BF}, 789 | {0x25C2, 0x25C5}, {0x25C9, 0x25CA}, {0x25CC, 0x25CD}, 790 | {0x25D2, 0x25E1}, {0x25E6, 0x25EE}, {0x25F0, 0x25F7}, 791 | {0x25F8, 0x25FC}, {0x25FF, 0x25FF}, {0x2600, 0x2604}, 792 | {0x2607, 0x2608}, {0x260A, 0x260D}, {0x2610, 0x2613}, 793 | {0x2616, 0x261B}, {0x261D, 0x261D}, {0x261F, 0x263F}, 794 | {0x2641, 0x2641}, {0x2643, 0x2647}, {0x2654, 0x265F}, 795 | {0x2662, 0x2662}, {0x2666, 0x2666}, {0x266B, 0x266B}, 796 | {0x266E, 0x266E}, {0x2670, 0x267E}, {0x2680, 0x2692}, 797 | {0x2694, 0x269D}, {0x26A0, 0x26A0}, {0x26A2, 0x26A9}, 798 | {0x26AC, 0x26BC}, {0x26C0, 0x26C3}, {0x26E2, 0x26E2}, 799 | {0x26E4, 0x26E7}, {0x2700, 0x2704}, {0x2706, 0x2709}, 800 | {0x270C, 0x2727}, {0x2729, 0x273C}, {0x273E, 0x274B}, 801 | {0x274D, 0x274D}, {0x274F, 0x2752}, {0x2756, 0x2756}, 802 | {0x2758, 0x2767}, {0x2768, 0x2768}, {0x2769, 0x2769}, 803 | {0x276A, 0x276A}, {0x276B, 0x276B}, {0x276C, 0x276C}, 804 | {0x276D, 0x276D}, {0x276E, 0x276E}, {0x276F, 0x276F}, 805 | {0x2770, 0x2770}, {0x2771, 0x2771}, {0x2772, 0x2772}, 806 | {0x2773, 0x2773}, {0x2774, 0x2774}, {0x2775, 0x2775}, 807 | {0x2780, 0x2793}, {0x2794, 0x2794}, {0x2798, 0x27AF}, 808 | {0x27B1, 0x27BE}, {0x27C0, 0x27C4}, {0x27C5, 0x27C5}, 809 | {0x27C6, 0x27C6}, {0x27C7, 0x27E5}, {0x27EE, 0x27EE}, 810 | {0x27EF, 0x27EF}, {0x27F0, 0x27FF}, {0x2800, 0x28FF}, 811 | {0x2900, 0x297F}, {0x2980, 0x2982}, {0x2983, 0x2983}, 812 | {0x2984, 0x2984}, {0x2987, 0x2987}, {0x2988, 0x2988}, 813 | {0x2989, 0x2989}, {0x298A, 0x298A}, {0x298B, 0x298B}, 814 | {0x298C, 0x298C}, {0x298D, 0x298D}, {0x298E, 0x298E}, 815 | {0x298F, 0x298F}, {0x2990, 0x2990}, {0x2991, 0x2991}, 816 | {0x2992, 0x2992}, {0x2993, 0x2993}, {0x2994, 0x2994}, 817 | {0x2995, 0x2995}, {0x2996, 0x2996}, {0x2997, 0x2997}, 818 | {0x2998, 0x2998}, {0x2999, 0x29D7}, {0x29D8, 0x29D8}, 819 | {0x29D9, 0x29D9}, {0x29DA, 0x29DA}, {0x29DB, 0x29DB}, 820 | {0x29DC, 0x29FB}, {0x29FC, 0x29FC}, {0x29FD, 0x29FD}, 821 | {0x29FE, 0x29FF}, {0x2A00, 0x2AFF}, {0x2B00, 0x2B1A}, 822 | {0x2B1D, 0x2B2F}, {0x2B30, 0x2B44}, {0x2B45, 0x2B46}, 823 | {0x2B47, 0x2B4C}, {0x2B4D, 0x2B4F}, {0x2B51, 0x2B54}, 824 | {0x2B5A, 0x2B73}, {0x2B76, 0x2B95}, {0x2B98, 0x2BB9}, 825 | {0x2BBD, 0x2BC8}, {0x2BCA, 0x2BD1}, {0x2BEC, 0x2BEF}, 826 | {0x2C00, 0x2C2E}, {0x2C30, 0x2C5E}, {0x2C60, 0x2C7B}, 827 | {0x2C7C, 0x2C7D}, {0x2C7E, 0x2C7F}, {0x2C80, 0x2CE4}, 828 | {0x2CE5, 0x2CEA}, {0x2CEB, 0x2CEE}, {0x2CEF, 0x2CF1}, 829 | {0x2CF2, 0x2CF3}, {0x2CF9, 0x2CFC}, {0x2CFD, 0x2CFD}, 830 | {0x2CFE, 0x2CFF}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, 831 | {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D6F}, 832 | {0x2D70, 0x2D70}, {0x2D7F, 0x2D7F}, {0x2D80, 0x2D96}, 833 | {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, 834 | {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, 835 | {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2DFF}, 836 | {0x2E00, 0x2E01}, {0x2E02, 0x2E02}, {0x2E03, 0x2E03}, 837 | {0x2E04, 0x2E04}, {0x2E05, 0x2E05}, {0x2E06, 0x2E08}, 838 | {0x2E09, 0x2E09}, {0x2E0A, 0x2E0A}, {0x2E0B, 0x2E0B}, 839 | {0x2E0C, 0x2E0C}, {0x2E0D, 0x2E0D}, {0x2E0E, 0x2E16}, 840 | {0x2E17, 0x2E17}, {0x2E18, 0x2E19}, {0x2E1A, 0x2E1A}, 841 | {0x2E1B, 0x2E1B}, {0x2E1C, 0x2E1C}, {0x2E1D, 0x2E1D}, 842 | {0x2E1E, 0x2E1F}, {0x2E20, 0x2E20}, {0x2E21, 0x2E21}, 843 | {0x2E22, 0x2E22}, {0x2E23, 0x2E23}, {0x2E24, 0x2E24}, 844 | {0x2E25, 0x2E25}, {0x2E26, 0x2E26}, {0x2E27, 0x2E27}, 845 | {0x2E28, 0x2E28}, {0x2E29, 0x2E29}, {0x2E2A, 0x2E2E}, 846 | {0x2E2F, 0x2E2F}, {0x2E30, 0x2E39}, {0x2E3A, 0x2E3B}, 847 | {0x2E3C, 0x2E3F}, {0x2E40, 0x2E40}, {0x2E41, 0x2E41}, 848 | {0x2E42, 0x2E42}, {0x2E43, 0x2E44}, {0x303F, 0x303F}, 849 | {0x4DC0, 0x4DFF}, {0xA4D0, 0xA4F7}, {0xA4F8, 0xA4FD}, 850 | {0xA4FE, 0xA4FF}, {0xA500, 0xA60B}, {0xA60C, 0xA60C}, 851 | {0xA60D, 0xA60F}, {0xA610, 0xA61F}, {0xA620, 0xA629}, 852 | {0xA62A, 0xA62B}, {0xA640, 0xA66D}, {0xA66E, 0xA66E}, 853 | {0xA66F, 0xA66F}, {0xA670, 0xA672}, {0xA673, 0xA673}, 854 | {0xA674, 0xA67D}, {0xA67E, 0xA67E}, {0xA67F, 0xA67F}, 855 | {0xA680, 0xA69B}, {0xA69C, 0xA69D}, {0xA69E, 0xA69F}, 856 | {0xA6A0, 0xA6E5}, {0xA6E6, 0xA6EF}, {0xA6F0, 0xA6F1}, 857 | {0xA6F2, 0xA6F7}, {0xA700, 0xA716}, {0xA717, 0xA71F}, 858 | {0xA720, 0xA721}, {0xA722, 0xA76F}, {0xA770, 0xA770}, 859 | {0xA771, 0xA787}, {0xA788, 0xA788}, {0xA789, 0xA78A}, 860 | {0xA78B, 0xA78E}, {0xA78F, 0xA78F}, {0xA790, 0xA7AE}, 861 | {0xA7B0, 0xA7B7}, {0xA7F7, 0xA7F7}, {0xA7F8, 0xA7F9}, 862 | {0xA7FA, 0xA7FA}, {0xA7FB, 0xA7FF}, {0xA800, 0xA801}, 863 | {0xA802, 0xA802}, {0xA803, 0xA805}, {0xA806, 0xA806}, 864 | {0xA807, 0xA80A}, {0xA80B, 0xA80B}, {0xA80C, 0xA822}, 865 | {0xA823, 0xA824}, {0xA825, 0xA826}, {0xA827, 0xA827}, 866 | {0xA828, 0xA82B}, {0xA830, 0xA835}, {0xA836, 0xA837}, 867 | {0xA838, 0xA838}, {0xA839, 0xA839}, {0xA840, 0xA873}, 868 | {0xA874, 0xA877}, {0xA880, 0xA881}, {0xA882, 0xA8B3}, 869 | {0xA8B4, 0xA8C3}, {0xA8C4, 0xA8C5}, {0xA8CE, 0xA8CF}, 870 | {0xA8D0, 0xA8D9}, {0xA8E0, 0xA8F1}, {0xA8F2, 0xA8F7}, 871 | {0xA8F8, 0xA8FA}, {0xA8FB, 0xA8FB}, {0xA8FC, 0xA8FC}, 872 | {0xA8FD, 0xA8FD}, {0xA900, 0xA909}, {0xA90A, 0xA925}, 873 | {0xA926, 0xA92D}, {0xA92E, 0xA92F}, {0xA930, 0xA946}, 874 | {0xA947, 0xA951}, {0xA952, 0xA953}, {0xA95F, 0xA95F}, 875 | {0xA980, 0xA982}, {0xA983, 0xA983}, {0xA984, 0xA9B2}, 876 | {0xA9B3, 0xA9B3}, {0xA9B4, 0xA9B5}, {0xA9B6, 0xA9B9}, 877 | {0xA9BA, 0xA9BB}, {0xA9BC, 0xA9BC}, {0xA9BD, 0xA9C0}, 878 | {0xA9C1, 0xA9CD}, {0xA9CF, 0xA9CF}, {0xA9D0, 0xA9D9}, 879 | {0xA9DE, 0xA9DF}, {0xA9E0, 0xA9E4}, {0xA9E5, 0xA9E5}, 880 | {0xA9E6, 0xA9E6}, {0xA9E7, 0xA9EF}, {0xA9F0, 0xA9F9}, 881 | {0xA9FA, 0xA9FE}, {0xAA00, 0xAA28}, {0xAA29, 0xAA2E}, 882 | {0xAA2F, 0xAA30}, {0xAA31, 0xAA32}, {0xAA33, 0xAA34}, 883 | {0xAA35, 0xAA36}, {0xAA40, 0xAA42}, {0xAA43, 0xAA43}, 884 | {0xAA44, 0xAA4B}, {0xAA4C, 0xAA4C}, {0xAA4D, 0xAA4D}, 885 | {0xAA50, 0xAA59}, {0xAA5C, 0xAA5F}, {0xAA60, 0xAA6F}, 886 | {0xAA70, 0xAA70}, {0xAA71, 0xAA76}, {0xAA77, 0xAA79}, 887 | {0xAA7A, 0xAA7A}, {0xAA7B, 0xAA7B}, {0xAA7C, 0xAA7C}, 888 | {0xAA7D, 0xAA7D}, {0xAA7E, 0xAA7F}, {0xAA80, 0xAAAF}, 889 | {0xAAB0, 0xAAB0}, {0xAAB1, 0xAAB1}, {0xAAB2, 0xAAB4}, 890 | {0xAAB5, 0xAAB6}, {0xAAB7, 0xAAB8}, {0xAAB9, 0xAABD}, 891 | {0xAABE, 0xAABF}, {0xAAC0, 0xAAC0}, {0xAAC1, 0xAAC1}, 892 | {0xAAC2, 0xAAC2}, {0xAADB, 0xAADC}, {0xAADD, 0xAADD}, 893 | {0xAADE, 0xAADF}, {0xAAE0, 0xAAEA}, {0xAAEB, 0xAAEB}, 894 | {0xAAEC, 0xAAED}, {0xAAEE, 0xAAEF}, {0xAAF0, 0xAAF1}, 895 | {0xAAF2, 0xAAF2}, {0xAAF3, 0xAAF4}, {0xAAF5, 0xAAF5}, 896 | {0xAAF6, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, 897 | {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, 898 | {0xAB30, 0xAB5A}, {0xAB5B, 0xAB5B}, {0xAB5C, 0xAB5F}, 899 | {0xAB60, 0xAB65}, {0xAB70, 0xABBF}, {0xABC0, 0xABE2}, 900 | {0xABE3, 0xABE4}, {0xABE5, 0xABE5}, {0xABE6, 0xABE7}, 901 | {0xABE8, 0xABE8}, {0xABE9, 0xABEA}, {0xABEB, 0xABEB}, 902 | {0xABEC, 0xABEC}, {0xABED, 0xABED}, {0xABF0, 0xABF9}, 903 | {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDB7F}, 904 | {0xDB80, 0xDBFF}, {0xDC00, 0xDFFF}, {0xFB00, 0xFB06}, 905 | {0xFB13, 0xFB17}, {0xFB1D, 0xFB1D}, {0xFB1E, 0xFB1E}, 906 | {0xFB1F, 0xFB28}, {0xFB29, 0xFB29}, {0xFB2A, 0xFB36}, 907 | {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, 908 | {0xFB43, 0xFB44}, {0xFB46, 0xFB4F}, {0xFB50, 0xFBB1}, 909 | {0xFBB2, 0xFBC1}, {0xFBD3, 0xFD3D}, {0xFD3E, 0xFD3E}, 910 | {0xFD3F, 0xFD3F}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, 911 | {0xFDF0, 0xFDFB}, {0xFDFC, 0xFDFC}, {0xFDFD, 0xFDFD}, 912 | {0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, 913 | {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFC, 0xFFFC}, 914 | {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A}, 915 | {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D}, 916 | {0x10080, 0x100FA}, {0x10100, 0x10102}, {0x10107, 0x10133}, 917 | {0x10137, 0x1013F}, {0x10140, 0x10174}, {0x10175, 0x10178}, 918 | {0x10179, 0x10189}, {0x1018A, 0x1018B}, {0x1018C, 0x1018E}, 919 | {0x10190, 0x1019B}, {0x101A0, 0x101A0}, {0x101D0, 0x101FC}, 920 | {0x101FD, 0x101FD}, {0x10280, 0x1029C}, {0x102A0, 0x102D0}, 921 | {0x102E0, 0x102E0}, {0x102E1, 0x102FB}, {0x10300, 0x1031F}, 922 | {0x10320, 0x10323}, {0x10330, 0x10340}, {0x10341, 0x10341}, 923 | {0x10342, 0x10349}, {0x1034A, 0x1034A}, {0x10350, 0x10375}, 924 | {0x10376, 0x1037A}, {0x10380, 0x1039D}, {0x1039F, 0x1039F}, 925 | {0x103A0, 0x103C3}, {0x103C8, 0x103CF}, {0x103D0, 0x103D0}, 926 | {0x103D1, 0x103D5}, {0x10400, 0x1044F}, {0x10450, 0x1047F}, 927 | {0x10480, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, 928 | {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, 929 | {0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755}, 930 | {0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808}, 931 | {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, 932 | {0x1083F, 0x1083F}, {0x10840, 0x10855}, {0x10857, 0x10857}, 933 | {0x10858, 0x1085F}, {0x10860, 0x10876}, {0x10877, 0x10878}, 934 | {0x10879, 0x1087F}, {0x10880, 0x1089E}, {0x108A7, 0x108AF}, 935 | {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x108FF}, 936 | {0x10900, 0x10915}, {0x10916, 0x1091B}, {0x1091F, 0x1091F}, 937 | {0x10920, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x1099F}, 938 | {0x109A0, 0x109B7}, {0x109BC, 0x109BD}, {0x109BE, 0x109BF}, 939 | {0x109C0, 0x109CF}, {0x109D2, 0x109FF}, {0x10A00, 0x10A00}, 940 | {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, 941 | {0x10A10, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A33}, 942 | {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x10A40, 0x10A47}, 943 | {0x10A50, 0x10A58}, {0x10A60, 0x10A7C}, {0x10A7D, 0x10A7E}, 944 | {0x10A7F, 0x10A7F}, {0x10A80, 0x10A9C}, {0x10A9D, 0x10A9F}, 945 | {0x10AC0, 0x10AC7}, {0x10AC8, 0x10AC8}, {0x10AC9, 0x10AE4}, 946 | {0x10AE5, 0x10AE6}, {0x10AEB, 0x10AEF}, {0x10AF0, 0x10AF6}, 947 | {0x10B00, 0x10B35}, {0x10B39, 0x10B3F}, {0x10B40, 0x10B55}, 948 | {0x10B58, 0x10B5F}, {0x10B60, 0x10B72}, {0x10B78, 0x10B7F}, 949 | {0x10B80, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF}, 950 | {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, 951 | {0x10CFA, 0x10CFF}, {0x10E60, 0x10E7E}, {0x11000, 0x11000}, 952 | {0x11001, 0x11001}, {0x11002, 0x11002}, {0x11003, 0x11037}, 953 | {0x11038, 0x11046}, {0x11047, 0x1104D}, {0x11052, 0x11065}, 954 | {0x11066, 0x1106F}, {0x1107F, 0x1107F}, {0x11080, 0x11081}, 955 | {0x11082, 0x11082}, {0x11083, 0x110AF}, {0x110B0, 0x110B2}, 956 | {0x110B3, 0x110B6}, {0x110B7, 0x110B8}, {0x110B9, 0x110BA}, 957 | {0x110BB, 0x110BC}, {0x110BD, 0x110BD}, {0x110BE, 0x110C1}, 958 | {0x110D0, 0x110E8}, {0x110F0, 0x110F9}, {0x11100, 0x11102}, 959 | {0x11103, 0x11126}, {0x11127, 0x1112B}, {0x1112C, 0x1112C}, 960 | {0x1112D, 0x11134}, {0x11136, 0x1113F}, {0x11140, 0x11143}, 961 | {0x11150, 0x11172}, {0x11173, 0x11173}, {0x11174, 0x11175}, 962 | {0x11176, 0x11176}, {0x11180, 0x11181}, {0x11182, 0x11182}, 963 | {0x11183, 0x111B2}, {0x111B3, 0x111B5}, {0x111B6, 0x111BE}, 964 | {0x111BF, 0x111C0}, {0x111C1, 0x111C4}, {0x111C5, 0x111C9}, 965 | {0x111CA, 0x111CC}, {0x111CD, 0x111CD}, {0x111D0, 0x111D9}, 966 | {0x111DA, 0x111DA}, {0x111DB, 0x111DB}, {0x111DC, 0x111DC}, 967 | {0x111DD, 0x111DF}, {0x111E1, 0x111F4}, {0x11200, 0x11211}, 968 | {0x11213, 0x1122B}, {0x1122C, 0x1122E}, {0x1122F, 0x11231}, 969 | {0x11232, 0x11233}, {0x11234, 0x11234}, {0x11235, 0x11235}, 970 | {0x11236, 0x11237}, {0x11238, 0x1123D}, {0x1123E, 0x1123E}, 971 | {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D}, 972 | {0x1128F, 0x1129D}, {0x1129F, 0x112A8}, {0x112A9, 0x112A9}, 973 | {0x112B0, 0x112DE}, {0x112DF, 0x112DF}, {0x112E0, 0x112E2}, 974 | {0x112E3, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11301}, 975 | {0x11302, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, 976 | {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, 977 | {0x11335, 0x11339}, {0x1133C, 0x1133C}, {0x1133D, 0x1133D}, 978 | {0x1133E, 0x1133F}, {0x11340, 0x11340}, {0x11341, 0x11344}, 979 | {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11350, 0x11350}, 980 | {0x11357, 0x11357}, {0x1135D, 0x11361}, {0x11362, 0x11363}, 981 | {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11400, 0x11434}, 982 | {0x11435, 0x11437}, {0x11438, 0x1143F}, {0x11440, 0x11441}, 983 | {0x11442, 0x11444}, {0x11445, 0x11445}, {0x11446, 0x11446}, 984 | {0x11447, 0x1144A}, {0x1144B, 0x1144F}, {0x11450, 0x11459}, 985 | {0x1145B, 0x1145B}, {0x1145D, 0x1145D}, {0x11480, 0x114AF}, 986 | {0x114B0, 0x114B2}, {0x114B3, 0x114B8}, {0x114B9, 0x114B9}, 987 | {0x114BA, 0x114BA}, {0x114BB, 0x114BE}, {0x114BF, 0x114C0}, 988 | {0x114C1, 0x114C1}, {0x114C2, 0x114C3}, {0x114C4, 0x114C5}, 989 | {0x114C6, 0x114C6}, {0x114C7, 0x114C7}, {0x114D0, 0x114D9}, 990 | {0x11580, 0x115AE}, {0x115AF, 0x115B1}, {0x115B2, 0x115B5}, 991 | {0x115B8, 0x115BB}, {0x115BC, 0x115BD}, {0x115BE, 0x115BE}, 992 | {0x115BF, 0x115C0}, {0x115C1, 0x115D7}, {0x115D8, 0x115DB}, 993 | {0x115DC, 0x115DD}, {0x11600, 0x1162F}, {0x11630, 0x11632}, 994 | {0x11633, 0x1163A}, {0x1163B, 0x1163C}, {0x1163D, 0x1163D}, 995 | {0x1163E, 0x1163E}, {0x1163F, 0x11640}, {0x11641, 0x11643}, 996 | {0x11644, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C}, 997 | {0x11680, 0x116AA}, {0x116AB, 0x116AB}, {0x116AC, 0x116AC}, 998 | {0x116AD, 0x116AD}, {0x116AE, 0x116AF}, {0x116B0, 0x116B5}, 999 | {0x116B6, 0x116B6}, {0x116B7, 0x116B7}, {0x116C0, 0x116C9}, 1000 | {0x11700, 0x11719}, {0x1171D, 0x1171F}, {0x11720, 0x11721}, 1001 | {0x11722, 0x11725}, {0x11726, 0x11726}, {0x11727, 0x1172B}, 1002 | {0x11730, 0x11739}, {0x1173A, 0x1173B}, {0x1173C, 0x1173E}, 1003 | {0x1173F, 0x1173F}, {0x118A0, 0x118DF}, {0x118E0, 0x118E9}, 1004 | {0x118EA, 0x118F2}, {0x118FF, 0x118FF}, {0x11AC0, 0x11AF8}, 1005 | {0x11C00, 0x11C08}, {0x11C0A, 0x11C2E}, {0x11C2F, 0x11C2F}, 1006 | {0x11C30, 0x11C36}, {0x11C38, 0x11C3D}, {0x11C3E, 0x11C3E}, 1007 | {0x11C3F, 0x11C3F}, {0x11C40, 0x11C40}, {0x11C41, 0x11C45}, 1008 | {0x11C50, 0x11C59}, {0x11C5A, 0x11C6C}, {0x11C70, 0x11C71}, 1009 | {0x11C72, 0x11C8F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CA9}, 1010 | {0x11CAA, 0x11CB0}, {0x11CB1, 0x11CB1}, {0x11CB2, 0x11CB3}, 1011 | {0x11CB4, 0x11CB4}, {0x11CB5, 0x11CB6}, {0x12000, 0x12399}, 1012 | {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543}, 1013 | {0x13000, 0x1342E}, {0x14400, 0x14646}, {0x16800, 0x16A38}, 1014 | {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16A6F}, 1015 | {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF4}, {0x16AF5, 0x16AF5}, 1016 | {0x16B00, 0x16B2F}, {0x16B30, 0x16B36}, {0x16B37, 0x16B3B}, 1017 | {0x16B3C, 0x16B3F}, {0x16B40, 0x16B43}, {0x16B44, 0x16B44}, 1018 | {0x16B45, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, 1019 | {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16F00, 0x16F44}, 1020 | {0x16F50, 0x16F50}, {0x16F51, 0x16F7E}, {0x16F8F, 0x16F92}, 1021 | {0x16F93, 0x16F9F}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, 1022 | {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BC9C}, 1023 | {0x1BC9D, 0x1BC9E}, {0x1BC9F, 0x1BC9F}, {0x1BCA0, 0x1BCA3}, 1024 | {0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D164}, 1025 | {0x1D165, 0x1D166}, {0x1D167, 0x1D169}, {0x1D16A, 0x1D16C}, 1026 | {0x1D16D, 0x1D172}, {0x1D173, 0x1D17A}, {0x1D17B, 0x1D182}, 1027 | {0x1D183, 0x1D184}, {0x1D185, 0x1D18B}, {0x1D18C, 0x1D1A9}, 1028 | {0x1D1AA, 0x1D1AD}, {0x1D1AE, 0x1D1E8}, {0x1D200, 0x1D241}, 1029 | {0x1D242, 0x1D244}, {0x1D245, 0x1D245}, {0x1D300, 0x1D356}, 1030 | {0x1D360, 0x1D371}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, 1031 | {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, 1032 | {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, 1033 | {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, 1034 | {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, 1035 | {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, 1036 | {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0}, 1037 | {0x1D6C1, 0x1D6C1}, {0x1D6C2, 0x1D6DA}, {0x1D6DB, 0x1D6DB}, 1038 | {0x1D6DC, 0x1D6FA}, {0x1D6FB, 0x1D6FB}, {0x1D6FC, 0x1D714}, 1039 | {0x1D715, 0x1D715}, {0x1D716, 0x1D734}, {0x1D735, 0x1D735}, 1040 | {0x1D736, 0x1D74E}, {0x1D74F, 0x1D74F}, {0x1D750, 0x1D76E}, 1041 | {0x1D76F, 0x1D76F}, {0x1D770, 0x1D788}, {0x1D789, 0x1D789}, 1042 | {0x1D78A, 0x1D7A8}, {0x1D7A9, 0x1D7A9}, {0x1D7AA, 0x1D7C2}, 1043 | {0x1D7C3, 0x1D7C3}, {0x1D7C4, 0x1D7CB}, {0x1D7CE, 0x1D7FF}, 1044 | {0x1D800, 0x1D9FF}, {0x1DA00, 0x1DA36}, {0x1DA37, 0x1DA3A}, 1045 | {0x1DA3B, 0x1DA6C}, {0x1DA6D, 0x1DA74}, {0x1DA75, 0x1DA75}, 1046 | {0x1DA76, 0x1DA83}, {0x1DA84, 0x1DA84}, {0x1DA85, 0x1DA86}, 1047 | {0x1DA87, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, 1048 | {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, 1049 | {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E800, 0x1E8C4}, 1050 | {0x1E8C7, 0x1E8CF}, {0x1E8D0, 0x1E8D6}, {0x1E900, 0x1E943}, 1051 | {0x1E944, 0x1E94A}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F}, 1052 | {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, 1053 | {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, 1054 | {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, 1055 | {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, 1056 | {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, 1057 | {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, 1058 | {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, 1059 | {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, 1060 | {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, 1061 | {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, 1062 | {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, 1063 | {0x1EEF0, 0x1EEF1}, {0x1F000, 0x1F003}, {0x1F005, 0x1F02B}, 1064 | {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, 1065 | {0x1F0C1, 0x1F0CE}, {0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10C}, 1066 | {0x1F12E, 0x1F12E}, {0x1F16A, 0x1F16B}, {0x1F1E6, 0x1F1FF}, 1067 | {0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, 1068 | {0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF}, 1069 | {0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F}, 1070 | {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A}, 1071 | {0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594}, 1072 | {0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F}, 1073 | {0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6E0, 0x1F6EA}, 1074 | {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F773}, {0x1F780, 0x1F7D4}, 1075 | {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, {0x1F850, 0x1F859}, 1076 | {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, {0xE0001, 0xE0001}, 1077 | {0xE0020, 0xE007F}, 1078 | } 1079 | 1080 | // Condition have flag EastAsianWidth whether the current locale is CJK or not. 1081 | type Condition struct { 1082 | EastAsianWidth bool 1083 | } 1084 | 1085 | // NewCondition return new instance of Condition which is current locale. 1086 | func NewCondition() *Condition { 1087 | return &Condition{EastAsianWidth} 1088 | } 1089 | 1090 | // RuneWidth returns the number of cells in r. 1091 | // See http://www.unicode.org/reports/tr11/ 1092 | func (c *Condition) RuneWidth(r rune) int { 1093 | switch { 1094 | case r < 0 || r > 0x10FFFF || 1095 | inTables(r, nonprint, combining, notassigned): 1096 | return 0 1097 | case (c.EastAsianWidth && IsAmbiguousWidth(r)) || 1098 | inTables(r, doublewidth, emoji): 1099 | return 2 1100 | default: 1101 | return 1 1102 | } 1103 | } 1104 | 1105 | // StringWidth return width as you can see 1106 | func (c *Condition) StringWidth(s string) (width int) { 1107 | for _, r := range []rune(s) { 1108 | width += c.RuneWidth(r) 1109 | } 1110 | return width 1111 | } 1112 | 1113 | // Truncate return string truncated with w cells 1114 | func (c *Condition) Truncate(s string, w int, tail string) string { 1115 | if c.StringWidth(s) <= w { 1116 | return s 1117 | } 1118 | r := []rune(s) 1119 | tw := c.StringWidth(tail) 1120 | w -= tw 1121 | width := 0 1122 | i := 0 1123 | for ; i < len(r); i++ { 1124 | cw := c.RuneWidth(r[i]) 1125 | if width+cw > w { 1126 | break 1127 | } 1128 | width += cw 1129 | } 1130 | return string(r[0:i]) + tail 1131 | } 1132 | 1133 | // Wrap return string wrapped with w cells 1134 | func (c *Condition) Wrap(s string, w int) string { 1135 | width := 0 1136 | out := "" 1137 | for _, r := range []rune(s) { 1138 | cw := RuneWidth(r) 1139 | if r == '\n' { 1140 | out += string(r) 1141 | width = 0 1142 | continue 1143 | } else if width+cw > w { 1144 | out += "\n" 1145 | width = 0 1146 | out += string(r) 1147 | width += cw 1148 | continue 1149 | } 1150 | out += string(r) 1151 | width += cw 1152 | } 1153 | return out 1154 | } 1155 | 1156 | // FillLeft return string filled in left by spaces in w cells 1157 | func (c *Condition) FillLeft(s string, w int) string { 1158 | width := c.StringWidth(s) 1159 | count := w - width 1160 | if count > 0 { 1161 | b := make([]byte, count) 1162 | for i := range b { 1163 | b[i] = ' ' 1164 | } 1165 | return string(b) + s 1166 | } 1167 | return s 1168 | } 1169 | 1170 | // FillRight return string filled in left by spaces in w cells 1171 | func (c *Condition) FillRight(s string, w int) string { 1172 | width := c.StringWidth(s) 1173 | count := w - width 1174 | if count > 0 { 1175 | b := make([]byte, count) 1176 | for i := range b { 1177 | b[i] = ' ' 1178 | } 1179 | return s + string(b) 1180 | } 1181 | return s 1182 | } 1183 | 1184 | // RuneWidth returns the number of cells in r. 1185 | // See http://www.unicode.org/reports/tr11/ 1186 | func RuneWidth(r rune) int { 1187 | return DefaultCondition.RuneWidth(r) 1188 | } 1189 | 1190 | // IsAmbiguousWidth returns whether is ambiguous width or not. 1191 | func IsAmbiguousWidth(r rune) bool { 1192 | return inTables(r, private, ambiguous) 1193 | } 1194 | 1195 | // IsNeutralWidth returns whether is neutral width or not. 1196 | func IsNeutralWidth(r rune) bool { 1197 | return inTable(r, neutral) 1198 | } 1199 | 1200 | // StringWidth return width as you can see 1201 | func StringWidth(s string) (width int) { 1202 | return DefaultCondition.StringWidth(s) 1203 | } 1204 | 1205 | // Truncate return string truncated with w cells 1206 | func Truncate(s string, w int, tail string) string { 1207 | return DefaultCondition.Truncate(s, w, tail) 1208 | } 1209 | 1210 | // Wrap return string wrapped with w cells 1211 | func Wrap(s string, w int) string { 1212 | return DefaultCondition.Wrap(s, w) 1213 | } 1214 | 1215 | // FillLeft return string filled in left by spaces in w cells 1216 | func FillLeft(s string, w int) string { 1217 | return DefaultCondition.FillLeft(s, w) 1218 | } 1219 | 1220 | // FillRight return string filled in left by spaces in w cells 1221 | func FillRight(s string, w int) string { 1222 | return DefaultCondition.FillRight(s, w) 1223 | } 1224 | --------------------------------------------------------------------------------