aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gopkg.lock20
-rw-r--r--vendor/github.com/jroimartin/gocui/.gitignore1
-rw-r--r--vendor/github.com/jroimartin/gocui/AUTHORS24
-rw-r--r--vendor/github.com/jroimartin/gocui/LICENSE23
-rw-r--r--vendor/github.com/jroimartin/gocui/README.md91
-rw-r--r--vendor/github.com/jroimartin/gocui/attribute.go32
-rw-r--r--vendor/github.com/jroimartin/gocui/doc.go116
-rw-r--r--vendor/github.com/jroimartin/gocui/edit.go341
-rw-r--r--vendor/github.com/jroimartin/gocui/escape.go168
-rw-r--r--vendor/github.com/jroimartin/gocui/gui.go646
-rw-r--r--vendor/github.com/jroimartin/gocui/keybinding.go141
-rw-r--r--vendor/github.com/jroimartin/gocui/view.go474
-rw-r--r--vendor/github.com/mattn/go-runewidth/.travis.yml8
-rw-r--r--vendor/github.com/mattn/go-runewidth/LICENSE21
-rw-r--r--vendor/github.com/mattn/go-runewidth/README.mkd27
-rw-r--r--vendor/github.com/mattn/go-runewidth/runewidth.go1223
-rw-r--r--vendor/github.com/mattn/go-runewidth/runewidth_js.go8
-rw-r--r--vendor/github.com/mattn/go-runewidth/runewidth_posix.go77
-rw-r--r--vendor/github.com/mattn/go-runewidth/runewidth_windows.go25
-rw-r--r--vendor/github.com/nsf/termbox-go/AUTHORS4
-rw-r--r--vendor/github.com/nsf/termbox-go/LICENSE19
-rw-r--r--vendor/github.com/nsf/termbox-go/README.md43
-rw-r--r--vendor/github.com/nsf/termbox-go/api.go489
-rw-r--r--vendor/github.com/nsf/termbox-go/api_common.go187
-rw-r--r--vendor/github.com/nsf/termbox-go/api_windows.go239
-rwxr-xr-xvendor/github.com/nsf/termbox-go/collect_terminfo.py110
-rw-r--r--vendor/github.com/nsf/termbox-go/escwait.go11
-rw-r--r--vendor/github.com/nsf/termbox-go/escwait_darwin.go9
-rw-r--r--vendor/github.com/nsf/termbox-go/syscalls.go39
-rw-r--r--vendor/github.com/nsf/termbox-go/syscalls_darwin.go41
-rw-r--r--vendor/github.com/nsf/termbox-go/syscalls_darwin_amd64.go40
-rw-r--r--vendor/github.com/nsf/termbox-go/syscalls_dragonfly.go39
-rw-r--r--vendor/github.com/nsf/termbox-go/syscalls_freebsd.go39
-rw-r--r--vendor/github.com/nsf/termbox-go/syscalls_linux.go33
-rw-r--r--vendor/github.com/nsf/termbox-go/syscalls_netbsd.go39
-rw-r--r--vendor/github.com/nsf/termbox-go/syscalls_openbsd.go39
-rw-r--r--vendor/github.com/nsf/termbox-go/syscalls_windows.go61
-rw-r--r--vendor/github.com/nsf/termbox-go/termbox.go529
-rw-r--r--vendor/github.com/nsf/termbox-go/termbox_common.go59
-rw-r--r--vendor/github.com/nsf/termbox-go/termbox_windows.go915
-rw-r--r--vendor/github.com/nsf/termbox-go/terminfo.go232
-rw-r--r--vendor/github.com/nsf/termbox-go/terminfo_builtin.go64
42 files changed, 6745 insertions, 1 deletions
diff --git a/Gopkg.lock b/Gopkg.lock
index abc824eb..51f38806 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -50,6 +50,12 @@
version = "v1.0"
[[projects]]
+ name = "github.com/jroimartin/gocui"
+ packages = ["."]
+ revision = "4e9ce9a8e26f2ef33dfe297dbdfca148733b6b9b"
+ version = "v0.3.0"
+
+[[projects]]
name = "github.com/mattn/go-colorable"
packages = ["."]
revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
@@ -62,6 +68,18 @@
version = "v0.0.3"
[[projects]]
+ name = "github.com/mattn/go-runewidth"
+ packages = ["."]
+ revision = "9e777a8366cce605130a531d2cd6363d07ad7317"
+ version = "v0.0.2"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/nsf/termbox-go"
+ packages = ["."]
+ revision = "5c94acc5e6eb520f1bcd183974e01171cc4c23b3"
+
+[[projects]]
name = "github.com/phayes/freeport"
packages = ["."]
revision = "b8543db493a5ed890c5499e935e2cad7504f3a04"
@@ -136,6 +154,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
- inputs-digest = "8eef4e36cf2c25bf253e53fb2a2a276a39715a847a6a05bb329870fe39af15a7"
+ inputs-digest = "793e41ab4418f9961ea3328a0233107af12a470e5237888891a7d52bd125c001"
solver-name = "gps-cdcl"
solver-version = 1
diff --git a/vendor/github.com/jroimartin/gocui/.gitignore b/vendor/github.com/jroimartin/gocui/.gitignore
new file mode 100644
index 00000000..1377554e
--- /dev/null
+++ b/vendor/github.com/jroimartin/gocui/.gitignore
@@ -0,0 +1 @@
+*.swp
diff --git a/vendor/github.com/jroimartin/gocui/AUTHORS b/vendor/github.com/jroimartin/gocui/AUTHORS
new file mode 100644
index 00000000..acf97f47
--- /dev/null
+++ b/vendor/github.com/jroimartin/gocui/AUTHORS
@@ -0,0 +1,24 @@
+# This is the official list of gocui authors for copyright purposes.
+
+# Names should be added to this file as
+# Name or Organization <email address> contribution
+# Contribution
+# The email address is not required for organizations.
+
+Roi Martin <jroi.martin@gmail.com>
+ Main developer
+
+Ryan Sullivan <kayoticsully@gmail.com>
+ Toggleable view frames
+
+Matthieu Rakotojaona <matthieu.rakotojaona@gmail.com>
+ Wrapped views
+
+Harry Lawrence <hazbo@gmx.com>
+ Basic mouse support
+
+Danny Tylman <dtylman@gmail.com>
+ Masked views
+
+Frederik Deweerdt <frederik.deweerdt@gmail.com>
+ Colored fonts
diff --git a/vendor/github.com/jroimartin/gocui/LICENSE b/vendor/github.com/jroimartin/gocui/LICENSE
new file mode 100644
index 00000000..8cb28215
--- /dev/null
+++ b/vendor/github.com/jroimartin/gocui/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2014 The gocui Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the gocui Authors nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/jroimartin/gocui/README.md b/vendor/github.com/jroimartin/gocui/README.md
new file mode 100644
index 00000000..d2e5065f
--- /dev/null
+++ b/vendor/github.com/jroimartin/gocui/README.md
@@ -0,0 +1,91 @@
+# GOCUI - Go Console User Interface
+
+[![GoDoc](https://godoc.org/github.com/jroimartin/gocui?status.svg)](https://godoc.org/github.com/jroimartin/gocui)
+
+Minimalist Go package aimed at creating Console User Interfaces.
+
+## Features
+
+* Minimalist API.
+* Views (the "windows" in the GUI) implement the interface io.ReadWriter.
+* Support for overlapping views.
+* The GUI can be modified at runtime (concurrent-safe).
+* Global and view-level keybindings.
+* Mouse support.
+* Colored text.
+* Customizable edition mode.
+
+## Installation
+
+Execute:
+
+```
+$ go get github.com/jroimartin/gocui
+```
+
+## Documentation
+
+Execute:
+
+```
+$ go doc github.com/jroimartin/gocui
+```
+
+Or visit [godoc.org](https://godoc.org/github.com/jroimartin/gocui) to read it
+online.
+
+## Example
+
+```go
+package main
+
+import (
+ "fmt"
+ "log"
+
+ "github.com/jroimartin/gocui"
+)
+
+func main() {
+ g := gocui.NewGui()
+ if err := g.Init(); err != nil {
+ log.Panicln(err)
+ }
+ defer g.Close()
+
+ g.SetLayout(layout)
+
+ if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
+ log.Panicln(err)
+ }
+
+ if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
+ log.Panicln(err)
+ }
+}
+
+func layout(g *gocui.Gui) error {
+ maxX, maxY := g.Size()
+ if v, err := g.SetView("hello", maxX/2-7, maxY/2, maxX/2+7, maxY/2+2); err != nil {
+ if err != gocui.ErrUnknownView {
+ return err
+ }
+ fmt.Fprintln(v, "Hello world!")
+ }
+ return nil
+}
+
+func quit(g *gocui.Gui, v *gocui.View) error {
+ return gocui.ErrQuit
+}
+```
+
+## Screenshots
+
+_examples/demo.go:
+
+![_examples/demo.go](https://cloud.githubusercontent.com/assets/1223476/5992750/720b84f0-aa36-11e4-88ec-296fa3247b52.png)
+
+_examples/dynamic.go:
+
+![_examples/dynamic.go](https://cloud.githubusercontent.com/assets/1223476/5992751/76ad5cc2-aa36-11e4-8204-6a90269db827.png)
diff --git a/vendor/github.com/jroimartin/gocui/attribute.go b/vendor/github.com/jroimartin/gocui/attribute.go
new file mode 100644
index 00000000..bad758a1
--- /dev/null
+++ b/vendor/github.com/jroimartin/gocui/attribute.go
@@ -0,0 +1,32 @@
+// Copyright 2014 The gocui Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocui
+
+import "github.com/nsf/termbox-go"
+
+// Attribute represents a terminal attribute, like color, font style, etc. They
+// can be combined using bitwise OR (|). Note that it is not possible to
+// combine multiple color attributes.
+type Attribute termbox.Attribute
+
+// Color attributes.
+const (
+ ColorDefault Attribute = Attribute(termbox.ColorDefault)
+ ColorBlack = Attribute(termbox.ColorBlack)
+ ColorRed = Attribute(termbox.ColorRed)
+ ColorGreen = Attribute(termbox.ColorGreen)
+ ColorYellow = Attribute(termbox.ColorYellow)
+ ColorBlue = Attribute(termbox.ColorBlue)
+ ColorMagenta = Attribute(termbox.ColorMagenta)
+ ColorCyan = Attribute(termbox.ColorCyan)
+ ColorWhite = Attribute(termbox.ColorWhite)
+)
+
+// Text style attributes.
+const (
+ AttrBold Attribute = Attribute(termbox.AttrBold)
+ AttrUnderline = Attribute(termbox.AttrUnderline)
+ AttrReverse = Attribute(termbox.AttrReverse)
+)
diff --git a/vendor/github.com/jroimartin/gocui/doc.go b/vendor/github.com/jroimartin/gocui/doc.go
new file mode 100644
index 00000000..2c753c99
--- /dev/null
+++ b/vendor/github.com/jroimartin/gocui/doc.go
@@ -0,0 +1,116 @@
+// Copyright 2014 The gocui Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package gocui allows to create console user interfaces.
+
+Create a new GUI:
+
+ g := gocui.NewGui()
+ if err := g.Init(); err != nil {
+ // handle error
+ }
+ defer g.Close()
+
+ // Set layout and key bindings
+ // ...
+
+ if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
+ // handle error
+ }
+
+Set the layout function:
+
+ g.SetLayout(fcn)
+
+On each iteration of the GUI's main loop, the "layout function" is executed.
+These layout functions can be used to set-up and update the application's main
+views, being possible to freely switch between them. Also, it is important to
+mention that a main loop iteration is executed on each reported event
+(key-press, mouse event, window resize, etc).
+
+GUIs are composed by Views, you can think of it as buffers. Views implement the
+io.ReadWriter interface, so you can just write to them if you want to modify
+their content. The same is valid for reading.
+
+Create and initialize a view with absolute coordinates:
+
+ if v, err := g.SetView("viewname", 2, 2, 22, 7); err != nil {
+ if err != gocui.ErrUnknownView {
+ // handle error
+ }
+ fmt.Fprintln(v, "This is a new view")
+ // ...
+ }
+
+Views can also be created using relative coordinates:
+
+ maxX, maxY := g.Size()
+ if v, err := g.SetView("viewname", maxX/2-30, maxY/2, maxX/2+30, maxY/2+2); err != nil {
+ // ...
+ }
+
+Configure keybindings:
+
+ if err := g.SetKeybinding("viewname", gocui.KeyEnter, gocui.ModNone, fcn); err != nil {
+ // handle error
+ }
+
+gocui implements full mouse support that can be enabled with:
+
+ g.Mouse = true
+
+Mouse events are handled like any other keybinding:
+
+ if err := g.SetKeybinding("viewname", gocui.MouseLeft, gocui.ModNone, fcn); err != nil {
+ // handle error
+ }
+
+IMPORTANT: Views can only be created, destroyed or updated in three ways: from
+layout functions, from keybinding callbacks or via *Gui.Execute(). The reason
+for this is that it allows gocui to be conccurent-safe. So, if you want to
+update your GUI from a goroutine, you must use *Gui.Execute(). For example:
+
+ g.Execute(func(g *gocui.Gui) error {
+ v, err := g.View("viewname")
+ if err != nil {
+ // handle error
+ }
+ v.Clear()
+ fmt.Fprintln(v, "Writing from different goroutines")
+ return nil
+ })
+
+By default, gocui provides a basic edition mode. This mode can be extended
+and customized creating a new Editor and assigning it to *Gui.Editor:
+
+ type Editor interface {
+ Edit(v *View, key Key, ch rune, mod Modifier)
+ }
+
+DefaultEditor can be taken as example to create your own custom Editor:
+
+ var DefaultEditor Editor = EditorFunc(simpleEditor)
+
+ func simpleEditor(v *View, key Key, ch rune, mod Modifier) {
+ switch {
+ case ch != 0 && mod == 0:
+ v.EditWrite(ch)
+ case key == KeySpace:
+ v.EditWrite(' ')
+ case key == KeyBackspace || key == KeyBackspace2:
+ v.EditDelete(true)
+ // ...
+ }
+ }
+
+Colored text:
+
+Views allow to add colored text using ANSI colors. For example:
+
+ fmt.Fprintln(v, "\x1b[0;31mHello world")
+
+For more information, see the examples in folder "_examples/".
+*/
+package gocui
diff --git a/vendor/github.com/jroimartin/gocui/edit.go b/vendor/github.com/jroimartin/gocui/edit.go
new file mode 100644
index 00000000..66d84c8d
--- /dev/null
+++ b/vendor/github.com/jroimartin/gocui/edit.go
@@ -0,0 +1,341 @@
+// Copyright 2014 The gocui Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocui
+
+import "errors"
+
+const maxInt = int(^uint(0) >> 1)
+
+// Editor interface must be satisfied by gocui editors.
+type Editor interface {
+ Edit(v *View, key Key, ch rune, mod Modifier)
+}
+
+// The EditorFunc type is an adapter to allow the use of ordinary functions as
+// Editors. If f is a function with the appropriate signature, EditorFunc(f)
+// is an Editor object that calls f.
+type EditorFunc func(v *View, key Key, ch rune, mod Modifier)
+
+// Edit calls f(v, key, ch, mod)
+func (f EditorFunc) Edit(v *View, key Key, ch rune, mod Modifier) {
+ f(v, key, ch, mod)
+}
+
+// DefaultEditor is the default editor.
+var DefaultEditor Editor = EditorFunc(simpleEditor)
+
+// simpleEditor is used as the default gocui editor.
+func simpleEditor(v *View, key Key, ch rune, mod Modifier) {
+ switch {
+ case ch != 0 && mod == 0:
+ v.EditWrite(ch)
+ case key == KeySpace:
+ v.EditWrite(' ')
+ case key == KeyBackspace || key == KeyBackspace2:
+ v.EditDelete(true)
+ case key == KeyDelete:
+ v.EditDelete(false)
+ case key == KeyInsert:
+ v.Overwrite = !v.Overwrite
+ case key == KeyEnter:
+ v.EditNewLine()
+ case key == KeyArrowDown:
+ v.MoveCursor(0, 1, false)
+ case key == KeyArrowUp:
+ v.MoveCursor(0, -1, false)
+ case key == KeyArrowLeft:
+ v.MoveCursor(-1, 0, false)
+ case key == KeyArrowRight:
+ v.MoveCursor(1, 0, false)
+ }
+}
+
+// EditWrite writes a rune at the cursor position.
+func (v *View) EditWrite(ch rune) {
+ v.writeRune(v.cx, v.cy, ch)
+ v.MoveCursor(1, 0, true)
+}
+
+// EditDelete deletes a rune at the cursor position. back determines the
+// direction.
+func (v *View) EditDelete(back bool) {
+ x, y := v.ox+v.cx, v.oy+v.cy
+ if y < 0 {
+ return
+ } else if y >= len(v.viewLines) {
+ v.MoveCursor(-1, 0, true)
+ return
+ }
+
+ maxX, _ := v.Size()
+ if back {
+ if x == 0 { // start of the line
+ if y < 1 {
+ return
+ }
+
+ var maxPrevWidth int
+ if v.Wrap {
+ maxPrevWidth = maxX
+ } else {
+ maxPrevWidth = maxInt
+ }
+
+ if v.viewLines[y].linesX == 0 { // regular line
+ v.mergeLines(v.cy - 1)
+ if len(v.viewLines[y-1].line) < maxPrevWidth {
+ v.MoveCursor(-1, 0, true)
+ }
+ } else { // wrapped line
+ v.deleteRune(len(v.viewLines[y-1].line)-1, v.cy-1)
+ v.MoveCursor(-1, 0, true)
+ }
+ } else { // middle/end of the line
+ v.deleteRune(v.cx-1, v.cy)
+ v.MoveCursor(-1, 0, true)
+ }
+ } else {
+ if x == len(v.viewLines[y].line) { // end of the line
+ v.mergeLines(v.cy)
+ } else { // start/middle of the line
+ v.deleteRune(v.cx, v.cy)
+ }
+ }
+}
+
+// EditNewLine inserts a new line under the cursor.
+func (v *View) EditNewLine() {
+ v.breakLine(v.cx, v.cy)
+
+ y := v.oy + v.cy
+ if y >= len(v.viewLines) || (y >= 0 && y < len(v.viewLines) &&
+ !(v.Wrap && v.cx == 0 && v.viewLines[y].linesX > 0)) {
+ // new line at the end of the buffer or
+ // cursor is not at the beginning of a wrapped line
+ v.ox = 0
+ v.cx = 0
+ v.MoveCursor(0, 1, true)
+ }
+}
+
+// MoveCursor moves the cursor taking into account the width of the line/view,
+// displacing the origin if necessary.
+func (v *View) MoveCursor(dx, dy int, writeMode bool) {
+ maxX, maxY := v.Size()
+ cx, cy := v.cx+dx, v.cy+dy
+ x, y := v.ox+cx, v.oy+cy
+
+ var curLineWidth, prevLineWidth int
+ // get the width of the current line
+ if writeMode {
+ if v.Wrap {
+ curLineWidth = maxX - 1
+ } else {
+ curLineWidth = maxInt
+ }
+ } else {
+ if y >= 0 && y < len(v.viewLines) {
+ curLineWidth = len(v.viewLines[y].line)
+ if v.Wrap && curLineWidth >= maxX {
+ curLineWidth = maxX - 1
+ }
+ } else {
+ curLineWidth = 0
+ }
+ }
+ // get the width of the previous line
+ if y-1 >= 0 && y-1 < len(v.viewLines) {
+ prevLineWidth = len(v.viewLines[y-1].line)
+ } else {
+ prevLineWidth = 0
+ }
+
+ // adjust cursor's x position and view's x origin
+ if x > curLineWidth { // move to next line
+ if dx > 0 { // horizontal movement
+ if !v.Wrap {
+ v.ox = 0
+ }
+ v.cx = 0
+ cy++
+ } else { // vertical movement
+ if curLineWidth > 0 { // move cursor to the EOL
+ if v.Wrap {
+ v.cx = curLineWidth
+ } else {
+ ncx := curLineWidth - v.ox
+ if ncx < 0 {
+ v.ox += ncx
+ if v.ox < 0 {
+ v.ox = 0
+ }
+ v.cx = 0
+ } else {
+ v.cx = ncx
+ }
+ }
+ } else {
+ if !v.Wrap {
+ v.ox = 0
+ }
+ v.cx = 0
+ }
+ }
+ } else if cx < 0 {
+ if !v.Wrap && v.ox > 0 { // move origin to the left
+ v.ox--
+ } else { // move to previous line
+ if prevLineWidth > 0 {
+ if !v.Wrap { // set origin so the EOL is visible
+ nox := prevLineWidth - maxX + 1
+ if nox < 0 {
+ v.ox = 0
+ } else {
+ v.ox = nox
+ }
+ }
+ v.cx = prevLineWidth
+ } else {
+ if !v.Wrap {
+ v.ox = 0
+ }
+ v.cx = 0
+ }
+ cy--
+ }
+ } else { // stay on the same line
+ if v.Wrap {
+ v.cx = cx
+ } else {
+ if cx >= maxX {
+ v.ox++
+ } else {
+ v.cx = cx
+ }
+ }
+ }
+
+ // adjust cursor's y position and view's y origin
+ if cy >= maxY {
+ v.oy++
+ } else if cy < 0 {
+ if v.oy > 0 {
+ v.oy--
+ }
+ } else {
+ v.cy = cy
+ }
+}
+
+// writeRune writes a rune into the view's internal buffer, at the
+// position corresponding to the point (x, y). The length of the internal
+// buffer is increased if the point is out of bounds. Overwrite mode is
+// governed by the value of View.overwrite.
+func (v *View) writeRune(x, y int, ch rune) error {
+ v.tainted = true
+
+ x, y, err := v.realPosition(x, y)
+ if err != nil {
+ return err
+ }
+
+ if x < 0 || y < 0 {
+ return errors.New("invalid point")
+ }
+
+ if y >= len(v.lines) {
+ s := make([][]cell, y-len(v.lines)+1)
+ v.lines = append(v.lines, s...)
+ }
+
+ olen := len(v.lines[y])
+ if x >= len(v.lines[y]) {
+ s := make([]cell, x-len(v.lines[y])+1)
+ v.lines[y] = append(v.lines[y], s...)
+ }
+
+ c := cell{
+ fgColor: v.FgColor,
+ bgColor: v.BgColor,
+ }
+ if !v.Overwrite || (v.Overwrite && x >= olen-1) {
+ c.chr = '\x00'
+ v.lines[y] = append(v.lines[y], c)
+ copy(v.lines[y][x+1:], v.lines[y][x:])
+ }
+ c.chr = ch
+ v.lines[y][x] = c
+ return nil
+}
+
+// deleteRune removes a rune from the view's internal buffer, at the
+// position corresponding to the point (x, y).
+func (v *View) deleteRune(x, y int) error {
+ v.tainted = true
+
+ x, y, err := v.realPosition(x, y)
+ if err != nil {
+ return err
+ }
+
+ if x < 0 || y < 0 || y >= len(v.lines) || x >= len(v.lines[y]) {
+ return errors.New("invalid point")
+ }
+ v.lines[y] = append(v.lines[y][:x], v.lines[y][x+1:]...)
+ return nil
+}
+
+// mergeLines merges the lines "y" and "y+1" if possible.
+func (v *View) mergeLines(y int) error {
+ v.tainted = true
+
+ _, y, err := v.realPosition(0, y)
+ if err != nil {
+ return err
+ }
+
+ if y < 0 || y >= len(v.lines) {
+ return errors.New("invalid point")
+ }
+
+ if y < len(v.lines)-1 { // otherwise we don't need to merge anything
+ v.lines[y] = append(v.lines[y], v.lines[y+1]...)
+ v.lines = append(v.lines[:y+1], v.lines[y+2:]...)
+ }
+ return nil
+}
+
+// breakLine breaks a line of the internal buffer at the position corresponding
+// to the point (x, y).
+func (v *View) breakLine(x, y int) error {
+ v.tainted = true
+
+ x, y, err := v.realPosition(x, y)
+ if err != nil {
+ return err
+ }
+
+ if y < 0 || y >= len(v.lines) {
+ return errors.New("invalid point")
+ }
+
+ var left, right []cell
+ if x < len(v.lines[y]) { // break line
+ left = make([]cell, len(v.lines[y][:x]))
+ copy(left, v.lines[y][:x])
+ right = make([]cell, len(v.lines[y][x:]))
+ copy(right, v.lines[y][x:])
+ } else { // new empty line
+ left = v.lines[y]
+ }
+
+ lines := make([][]cell, len(v.lines)+1)
+ lines[y] = left
+ lines[y+1] = right
+ copy(lines, v.lines[:y])
+ copy(lines[y+2:], v.lines[y+1:])
+ v.lines = lines
+ return nil
+}
diff --git a/vendor/github.com/jroimartin/gocui/escape.go b/vendor/github.com/jroimartin/gocui/escape.go
new file mode 100644
index 00000000..07871d52
--- /dev/null
+++ b/vendor/github.com/jroimartin/gocui/escape.go
@@ -0,0 +1,168 @@
+// Copyright 2014 The gocui Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocui
+
+import (
+ "errors"
+ "strconv"
+)
+
+type escapeInterpreter struct {
+ state escapeState
+ curch rune
+ csiParam []string
+ curFgColor, curBgColor Attribute
+}
+
+type escapeState int
+
+const (
+ stateNone escapeState = iota
+ stateEscape
+ stateCSI
+ stateParams
+)
+
+var (
+ errNotCSI = errors.New("Not a CSI escape sequence")
+ errCSINotANumber = errors.New("CSI escape sequence was expecting a number or a ;")
+ errCSIParseError = errors.New("CSI escape sequence parsing error")
+ errCSITooLong = errors.New("CSI escape sequence is too long")
+)
+
+// runes in case of error will output the non-parsed runes as a string.
+func (ei *escapeInterpreter) runes() []rune {
+ switch ei.state {
+ case stateNone:
+ return []rune{0x1b}
+ case stateEscape:
+ return []rune{0x1b, ei.curch}
+ case stateCSI:
+ return []rune{0x1b, '[', ei.curch}
+ case stateParams:
+ ret := []rune{0x1b, '['}
+ for _, s := range ei.csiParam {
+ ret = append(ret, []rune(s)...)
+ ret = append(ret, ';')
+ }
+ return append(ret, ei.curch)
+ }
+ return nil
+}
+
+// newEscapeInterpreter returns an escapeInterpreter that will be able to parse
+// terminal escape sequences.
+func newEscapeInterpreter() *escapeInterpreter {
+ ei := &escapeInterpreter{
+ state: stateNone,
+ curFgColor: ColorDefault,
+ curBgColor: ColorDefault,
+ }
+ return ei
+}
+
+// reset sets the escapeInterpreter in initial state.
+func (ei *escapeInterpreter) reset() {
+ ei.state = stateNone
+ ei.curFgColor = ColorDefault
+ ei.curBgColor = ColorDefault
+ ei.csiParam = nil
+}
+
+// paramToColor returns an attribute given a terminfo coloring.
+func paramToColor(p int) Attribute {
+ switch p {
+ case 0:
+ return ColorBlack
+ case 1:
+ return ColorRed
+ case 2:
+ return ColorGreen
+ case 3:
+ return ColorYellow
+ case 4:
+ return ColorBlue
+ case 5:
+ return ColorMagenta
+ case 6:
+ return ColorCyan
+ case 7:
+ return ColorWhite
+ }
+ return ColorDefault
+}
+
+// parseOne parses a rune. If isEscape is true, it means that the rune is part
+// of an escape sequence, and as such should not be printed verbatim. Otherwise,
+// it's not an escape sequence.
+func (ei *escapeInterpreter) parseOne(ch rune) (isEscape bool, err error) {
+ // Sanity checks to make sure we're not parsing something totally bogus.
+ if len(ei.csiParam) > 20 {
+ return false, errCSITooLong
+ }
+ if len(ei.csiParam) > 0 && len(ei.csiParam[len(ei.csiParam)-1]) > 255 {
+ return false, errCSITooLong
+ }
+ ei.curch = ch
+ switch ei.state {
+ case stateNone:
+ if ch == 0x1b {
+ ei.state = stateEscape
+ return true, nil
+ }
+ return false, nil
+ case stateEscape:
+ if ch == '[' {
+ ei.state = stateCSI
+ return true, nil
+ }
+ return false, errNotCSI
+ case stateCSI:
+ if ch >= '0' && ch <= '9' {
+ ei.state = stateParams
+ ei.csiParam = append(ei.csiParam, string(ch))
+ return true, nil
+ }
+ return false, errCSINotANumber
+ case stateParams:
+ switch {
+ case ch >= '0' && ch <= '9':
+ ei.csiParam[len(ei.csiParam)-1] += string(ch)
+ return true, nil
+ case ch == ';':
+ ei.csiParam = append(ei.csiParam, "")
+ return true, nil
+ case ch == 'm':
+ if len(ei.csiParam) < 1 {
+ return false, errCSIParseError
+ }
+ for _, param := range ei.csiParam {
+ p, err := strconv.Atoi(param)
+ if err != nil {
+ return false, errCSIParseError
+ }
+ switch {
+ case p >= 30 && p <= 37:
+ ei.curFgColor = paramToColor(p - 30)
+ case p >= 40 && p <= 47:
+ ei.curBgColor = paramToColor(p - 40)
+ case p == 1:
+ ei.curFgColor |= AttrBold
+ case p == 4:
+ ei.curFgColor |= AttrUnderline
+ case p == 7:
+ ei.curFgColor |= AttrReverse
+ case p == 0 || p == 39:
+ ei.curFgColor = ColorDefault
+ ei.curBgColor = ColorDefault
+ }
+ }
+ ei.state = stateNone
+ ei.csiParam = nil
+ return true, nil
+ }
+ }
+ return false, nil
+}
diff --git a/vendor/github.com/jroimartin/gocui/gui.go b/vendor/github.com/jroimartin/gocui/gui.go
new file mode 100644
index 00000000..39579dc4
--- /dev/null
+++ b/vendor/github.com/jroimartin/gocui/gui.go
@@ -0,0 +1,646 @@
+// Copyright 2014 The gocui Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocui
+
+import (
+ "errors"
+
+ "github.com/nsf/termbox-go"
+)
+
+// Handler represents a handler that can be used to update or modify the GUI.
+type Handler func(*Gui) error
+
+// userEvent represents an event triggered by the user.
+type userEvent struct {
+ h Handler
+}
+
+var (
+ // ErrQuit is used to decide if the MainLoop finished successfully.
+ ErrQuit = errors.New("quit")
+
+ // ErrUnknownView allows to assert if a View must be initialized.
+ ErrUnknownView = errors.New("unknown view")
+)
+
+// Gui represents the whole User Interface, including the views, layouts
+// and keybindings.
+type Gui struct {
+ tbEvents chan termbox.Event
+ userEvents chan userEvent
+ views []*View
+ currentView *View
+ layout Handler
+ keybindings []*keybinding
+ maxX, maxY int
+
+ // BgColor and FgColor allow to configure the background and foreground
+ // colors of the GUI.
+ BgColor, FgColor Attribute
+
+ // SelBgColor and SelFgColor are used to configure the background and
+ // foreground colors of the selected line, when it is highlighted.
+ SelBgColor, SelFgColor Attribute
+
+ // If Cursor is true then the cursor is enabled.
+ Cursor bool
+
+ // If Mouse is true then mouse events will be enabled.
+ Mouse bool
+
+ // If InputEsc is true, when ESC sequence is in the buffer and it doesn't
+ // match any known sequence, ESC means KeyEsc.
+ InputEsc bool
+
+ // Editor allows to define the editor that manages the edition mode,
+ // including keybindings or cursor behaviour. DefaultEditor is used by
+ // default.
+ Editor Editor
+}
+
+// NewGui returns a new Gui object.
+func NewGui() *Gui {
+ return &Gui{}
+}
+
+// Init initializes the library. This function must be called before
+// any other functions.
+func (g *Gui) Init() error {
+ if err := termbox.Init(); err != nil {
+ return err
+ }
+ g.tbEvents = make(chan termbox.Event, 20)
+ g.userEvents = make(chan userEvent, 20)
+ g.maxX, g.maxY = termbox.Size()
+ g.BgColor = ColorBlack
+ g.FgColor = ColorWhite
+ g.Editor = DefaultEditor
+ return nil
+}
+
+// Close finalizes the library. It should be called after a successful
+// initialization and when gocui is not needed anymore.
+func (g *Gui) Close() {
+ termbox.Close()
+}
+
+// Size returns the terminal's size.
+func (g *Gui) Size() (x, y int) {
+ return g.maxX, g.maxY
+}
+
+// SetRune writes a rune at the given point, relative to the top-left
+// corner of the terminal. It checks if the position is valid and applies
+// the gui's colors.
+func (g *Gui) SetRune(x, y int, ch rune) error {
+ if x < 0 || y < 0 || x >= g.maxX || y >= g.maxY {
+ return errors.New("invalid point")
+ }
+ termbox.SetCell(x, y, ch, termbox.Attribute(g.FgColor), termbox.Attribute(g.BgColor))
+ return nil
+}
+
+// Rune returns the rune contained in the cell at the given position.
+// It checks if the position is valid.
+func (g *Gui) Rune(x, y int) (rune, error) {
+ if x < 0 || y < 0 || x >= g.maxX || y >= g.maxY {
+ return ' ', errors.New("invalid point")
+ }
+ c := termbox.CellBuffer()[y*g.maxX+x]
+ return c.Ch, nil
+}
+
+// SetView creates a new view with its top-left corner at (x0, y0)
+// and the bottom-right one at (x1, y1). If a view with the same name
+// already exists, its dimensions are updated; otherwise, the error
+// ErrUnknownView is returned, which allows to assert if the View must
+// be initialized. It checks if the position is valid.
+func (g *Gui) SetView(name string, x0, y0, x1, y1 int) (*View, error) {
+ if x0 >= x1 || y0 >= y1 {
+ return nil, errors.New("invalid dimensions")
+ }
+ if name == "" {
+ return nil, errors.New("invalid name")
+ }
+
+ if v, err := g.View(name); err == nil {
+ v.x0 = x0
+ v.y0 = y0
+ v.x1 = x1
+ v.y1 = y1
+ v.tainted = true
+ return v, nil
+ }
+
+ v := newView(name, x0, y0, x1, y1)
+ v.BgColor, v.FgColor = g.BgColor, g.FgColor
+ v.SelBgColor, v.SelFgColor = g.SelBgColor, g.SelFgColor
+ g.views = append(g.views, v)
+ return v, ErrUnknownView
+}
+
+// SetViewOnTop sets the given view on top of the existing ones.
+func (g *Gui) SetViewOnTop(name string) (*View, error) {
+ for i, v := range g.views {
+ if v.name == name {
+ s := append(g.views[:i], g.views[i+1:]...)
+ g.views = append(s, v)
+ return v, nil
+ }
+ }
+ return nil, ErrUnknownView
+}
+
+// View returns a pointer to the view with the given name, or error
+// ErrUnknownView if a view with that name does not exist.
+func (g *Gui) View(name string) (*View, error) {
+ for _, v := range g.views {
+ if v.name == name {
+ return v, nil
+ }
+ }
+ return nil, ErrUnknownView
+}
+
+// ViewByPosition returns a pointer to a view matching the given position, or
+// error ErrUnknownView if a view in that position does not exist.
+func (g *Gui) ViewByPosition(x, y int) (*View, error) {
+ for _, v := range g.views {
+ if x > v.x0 && x < v.x1 && y > v.y0 && y < v.y1 {
+ return v, nil
+ }
+ }
+ return nil, ErrUnknownView
+}
+
+// ViewPosition returns the coordinates of the view with the given name, or
+// error ErrUnknownView if a view with that name does not exist.
+func (g *Gui) ViewPosition(name string) (x0, y0, x1, y1 int, err error) {
+ for _, v := range g.views {
+ if v.name == name {
+ return v.x0, v.y0, v.x1, v.y1, nil
+ }
+ }
+ return 0, 0, 0, 0, ErrUnknownView
+}
+
+// DeleteView deletes a view by name.
+func (g *Gui) DeleteView(name string) error {
+ for i, v := range g.views {
+ if v.name == name {
+ g.views = append(g.views[:i], g.views[i+1:]...)
+ return nil
+ }
+ }
+ return ErrUnknownView
+}
+
+// SetCurrentView gives the focus to a given view.
+func (g *Gui) SetCurrentView(name string) error {
+ for _, v := range g.views {
+ if v.name == name {
+ g.currentView = v
+ return nil
+ }
+ }
+ return ErrUnknownView
+}
+
+// CurrentView returns the currently focused view, or nil if no view
+// owns the focus.
+func (g *Gui) CurrentView() *View {
+ return g.currentView
+}
+
+// SetKeybinding creates a new keybinding. If viewname equals to ""
+// (empty string) then the keybinding will apply to all views. key must
+// be a rune or a Key.
+func (g *Gui) SetKeybinding(viewname string, key interface{}, mod Modifier, h KeybindingHandler) error {
+ var kb *keybinding
+
+ k, ch, err := getKey(key)
+ if err != nil {
+ return err
+ }
+ kb = newKeybinding(viewname, k, ch, mod, h)
+ g.keybindings = append(g.keybindings, kb)
+ return nil
+}
+
+// DeleteKeybinding deletes a keybinding.
+func (g *Gui) DeleteKeybinding(viewname string, key interface{}, mod Modifier) error {
+ k, ch, err := getKey(key)
+ if err != nil {
+ return err
+ }
+
+ for i, kb := range g.keybindings {
+ if kb.viewName == viewname && kb.ch == ch && kb.key == k && kb.mod == mod {
+ g.keybindings = append(g.keybindings[:i], g.keybindings[i+1:]...)
+ return nil
+ }
+ }
+ return errors.New("keybinding not found")
+}
+
+// DeleteKeybindings deletes all keybindings of view.
+func (g *Gui) DeleteKeybindings(viewname string) {
+ var s []*keybinding
+ for _, kb := range g.keybindings {
+ if kb.viewName != viewname {
+ s = append(s, kb)
+ }
+ }
+ g.keybindings = s
+}
+
+// getKey takes an empty interface with a key and returns the corresponding
+// typed Key or rune.
+func getKey(key interface{}) (Key, rune, error) {
+ switch t := key.(type) {
+ case Key:
+ return t, 0, nil
+ case rune:
+ return 0, t, nil
+ default:
+ return 0, 0, errors.New("unknown type")
+ }
+}
+
+// Execute executes the given handler. This function can be called safely from
+// a goroutine in order to update the GUI. It is important to note that it
+// won't be executed immediately, instead it will be added to the user events
+// queue.
+func (g *Gui) Execute(h Handler) {
+ go func() { g.userEvents <- userEvent{h: h} }()
+}
+
+// SetLayout sets the current layout. A layout is a function that
+// will be called every time the gui is redrawn, it must contain
+// the base views and its initializations.
+func (g *Gui) SetLayout(layout Handler) {
+ g.layout = layout
+ g.currentView = nil
+ g.views = nil
+ go func() { g.tbEvents <- termbox.Event{Type: termbox.EventResize} }()
+}
+
+// MainLoop runs the main loop until an error is returned. A successful
+// finish should return ErrQuit.
+func (g *Gui) MainLoop() error {
+ go func() {
+ for {
+ g.tbEvents <- termbox.PollEvent()
+ }
+ }()
+
+ inputMode := termbox.InputAlt
+ if g.InputEsc {
+ inputMode = termbox.InputEsc
+ }
+ if g.Mouse {
+ inputMode |= termbox.InputMouse
+ }
+ termbox.SetInputMode(inputMode)
+
+ if err := g.flush(); err != nil {
+ return err
+ }
+ for {
+ select {
+ case ev := <-g.tbEvents:
+ if err := g.handleEvent(&ev); err != nil {
+ return err
+ }
+ case ev := <-g.userEvents:
+ if err := ev.h(g); err != nil {
+ return err
+ }
+ }
+ if err := g.consumeevents(); err != nil {
+ return err
+ }
+ if err := g.flush(); err != nil {
+ return err
+ }
+ }
+}
+
+// consumeevents handles the remaining events in the events pool.
+func (g *Gui) consumeevents() error {
+ for {
+ select {
+ case ev := <-g.tbEvents:
+ if err := g.handleEvent(&ev); err != nil {
+ return err
+ }
+ case ev := <-g.userEvents:
+ if err := ev.h(g); err != nil {
+ return err
+ }
+ default:
+ return nil
+ }
+ }
+}
+
+// handleEvent handles an event, based on its type (key-press, error,
+// etc.)
+func (g *Gui) handleEvent(ev *termbox.Event) error {
+ switch ev.Type {
+ case termbox.EventKey, termbox.EventMouse:
+ return g.onKey(ev)
+ case termbox.EventError:
+ return ev.Err
+ default:
+ return nil
+ }
+}
+
+// flush updates the gui, re-drawing frames and buffers.
+func (g *Gui) flush() error {
+ if g.layout == nil {
+ return errors.New("Null layout")
+ }
+
+ termbox.Clear(termbox.Attribute(g.FgColor), termbox.Attribute(g.BgColor))
+
+ maxX, maxY := termbox.Size()
+ // if GUI's size has changed, we need to redraw all views
+ if maxX != g.maxX || maxY != g.maxY {
+ for _, v := range g.views {
+ v.tainted = true
+ }
+ }
+ g.maxX, g.maxY = maxX, maxY
+
+ if err := g.layout(g); err != nil {
+ return err
+ }
+ for _, v := range g.views {
+ if v.Frame {
+ if err := g.drawFrame(v); err != nil {
+ return err
+ }
+ if err := g.drawCorners(v); err != nil {
+ return err
+ }
+ if v.Title != "" {
+ if err := g.drawTitle(v); err != nil {
+ return err
+ }
+ }
+ }
+
+ if err := g.draw(v); err != nil {
+ return err
+ }
+ }
+ if err := g.drawIntersections(); err != nil {
+ return err
+ }
+ termbox.Flush()
+ return nil
+
+}
+
+// drawFrame draws the horizontal and vertical edges of a view.
+func (g *Gui) drawFrame(v *View) error {
+ for x := v.x0 + 1; x < v.x1 && x < g.maxX; x++ {
+ if x < 0 {
+ continue
+ }
+ if v.y0 > -1 && v.y0 < g.maxY {
+ if err := g.SetRune(x, v.y0, '─'); err != nil {
+ return err
+ }
+ }
+ if v.y1 > -1 && v.y1 < g.maxY {
+ if err := g.SetRune(x, v.y1, '─'); err != nil {
+ return err
+ }
+ }
+ }
+ for y := v.y0 + 1; y < v.y1 && y < g.maxY; y++ {
+ if y < 0 {
+ continue
+ }
+ if v.x0 > -1 && v.x0 < g.maxX {
+ if err := g.SetRune(v.x0, y, '│'); err != nil {
+ return err
+ }
+ }
+ if v.x1 > -1 && v.x1 < g.maxX {
+ if err := g.SetRune(v.x1, y, '│'); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+// drawCorners draws the corners of the view.
+func (g *Gui) drawCorners(v *View) error {
+ if v.x0 >= 0 && v.y0 >= 0 && v.x0 < g.maxX && v.y0 < g.maxY {
+ if err := g.SetRune(v.x0, v.y0, '┌'); err != nil {
+ return err
+ }
+ }
+ if v.x1 >= 0 && v.y0 >= 0 && v.x1 < g.maxX && v.y0 < g.maxY {
+ if err := g.SetRune(v.x1, v.y0, '┐'); err != nil {
+ return err
+ }
+ }
+ if v.x0 >= 0 && v.y1 >= 0 && v.x0 < g.maxX && v.y1 < g.maxY {
+ if err := g.SetRune(v.x0, v.y1, '└'); err != nil {
+ return err
+ }
+ }
+ if v.x1 >= 0 && v.y1 >= 0 && v.x1 < g.maxX && v.y1 < g.maxY {
+ if err := g.SetRune(v.x1, v.y1, '┘'); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// drawTitle draws the title of the view.
+func (g *Gui) drawTitle(v *View) error {
+ if v.y0 < 0 || v.y0 >= g.maxY {
+ return nil
+ }
+
+ for i, ch := range v.Title {
+ x := v.x0 + i + 2
+ if x < 0 {
+ continue
+ } else if x > v.x1-2 || x >= g.maxX {
+ break
+ }
+ if err := g.SetRune(x, v.y0, ch); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// draw manages the cursor and calls the draw function of a view.
+func (g *Gui) draw(v *View) error {
+ if g.Cursor {
+ if v := g.currentView; v != nil {
+ vMaxX, vMaxY := v.Size()
+ if v.cx < 0 {
+ v.cx = 0
+ } else if v.cx >= vMaxX {
+ v.cx = vMaxX - 1
+ }
+ if v.cy < 0 {
+ v.cy = 0
+ } else if v.cy >= vMaxY {
+ v.cy = vMaxY - 1
+ }
+
+ gMaxX, gMaxY := g.Size()
+ cx, cy := v.x0+v.cx+1, v.y0+v.cy+1
+ if cx >= 0 && cx < gMaxX && cy >= 0 && cy < gMaxY {
+ termbox.SetCursor(cx, cy)
+ } else {
+ termbox.HideCursor()
+ }
+ }
+ } else {
+ termbox.HideCursor()
+ }
+
+ v.clearRunes()
+ if err := v.draw(); err != nil {
+ return err
+ }
+ return nil
+}
+
+// drawIntersections draws the corners of each view, based on the type
+// of the edges that converge at these points.
+func (g *Gui) drawIntersections() error {
+ for _, v := range g.views {
+ if ch, ok := g.intersectionRune(v.x0, v.y0); ok {
+ if err := g.SetRune(v.x0, v.y0, ch); err != nil {
+ return err
+ }
+ }
+ if ch, ok := g.intersectionRune(v.x0, v.y1); ok {
+ if err := g.SetRune(v.x0, v.y1, ch); err != nil {
+ return err
+ }
+ }
+ if ch, ok := g.intersectionRune(v.x1, v.y0); ok {
+ if err := g.SetRune(v.x1, v.y0, ch); err != nil {
+ return err
+ }
+ }
+ if ch, ok := g.intersectionRune(v.x1, v.y1); ok {
+ if err := g.SetRune(v.x1, v.y1, ch); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+// intersectionRune returns the correct intersection rune at a given
+// point.
+func (g *Gui) intersectionRune(x, y int) (rune, bool) {
+ if x < 0 || y < 0 || x >= g.maxX || y >= g.maxY {
+ return ' ', false
+ }
+
+ chTop, _ := g.Rune(x, y-1)
+ top := verticalRune(chTop)
+ chBottom, _ := g.Rune(x, y+1)
+ bottom := verticalRune(chBottom)
+ chLeft, _ := g.Rune(x-1, y)
+ left := horizontalRune(chLeft)
+ chRight, _ := g.Rune(x+1, y)
+ right := horizontalRune(chRight)
+
+ var ch rune
+ switch {
+ case top && bottom && left && right:
+ ch = '┼'
+ case top && bottom && !left && right:
+ ch = '├'
+ case top && bottom && left && !right:
+ ch = '┤'
+ case !top && bottom && left && right:
+ ch = '┬'
+ case top && !bottom && left && right:
+ ch = '┴'
+ default:
+ return ' ', false
+ }
+ return ch, true
+}
+
+// verticalRune returns if the given character is a vertical rune.
+func verticalRune(ch rune) bool {
+ if ch == '│' || ch == '┼' || ch == '├' || ch == '┤' {
+ return true
+ }
+ return false
+}
+
+// verticalRune returns if the given character is a horizontal rune.
+func horizontalRune(ch rune) bool {
+ if ch == '─' || ch == '┼' || ch == '┬' || ch == '┴' {
+ return true
+ }
+ return false
+}
+
+// onKey manages key-press events. A keybinding handler is called when
+// a key-press or mouse event satisfies a configured keybinding. Furthermore,
+// currentView's internal buffer is modified if currentView.Editable is true.
+func (g *Gui) onKey(ev *termbox.Event) error {
+ switch ev.Type {
+ case termbox.EventKey:
+ if err := g.execKeybindings(g.currentView, ev); err != nil {
+ return err
+ }
+ if g.currentView != nil && g.currentView.Editable && g.Editor != nil {
+ g.Editor.Edit(g.currentView, Key(ev.Key), ev.Ch, Modifier(ev.Mod))
+ }
+ case termbox.EventMouse:
+ mx, my := ev.MouseX, ev.MouseY
+ v, err := g.ViewByPosition(mx, my)
+ if err != nil {
+ break
+ }
+ if err := v.SetCursor(mx-v.x0-1, my-v.y0-1); err != nil {
+ return err
+ }
+ if err := g.execKeybindings(v, ev); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// execKeybindings executes the keybinding handlers that match the passed view
+// and event.
+func (g *Gui) execKeybindings(v *View, ev *termbox.Event) error {
+ for _, kb := range g.keybindings {
+ if kb.h == nil {
+ continue
+ }
+ if kb.matchKeypress(Key(ev.Key), ev.Ch, Modifier(ev.Mod)) && kb.matchView(v) {
+ if err := kb.h(g, v); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/jroimartin/gocui/keybinding.go b/vendor/github.com/jroimartin/gocui/keybinding.go
new file mode 100644
index 00000000..61516821
--- /dev/null
+++ b/vendor/github.com/jroimartin/gocui/keybinding.go
@@ -0,0 +1,141 @@
+// Copyright 2014 The gocui Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocui
+
+import "github.com/nsf/termbox-go"
+
+type (
+ // Key represents special keys or keys combinations.
+ Key termbox.Key
+
+ // Modifier allows to define special keys combinations. They can be used
+ // in combination with Keys or Runes when a new keybinding is defined.
+ Modifier termbox.Modifier
+
+ // KeybindingHandler represents the handler linked to a specific
+ // keybindings. The handler is called when a key-press event satisfies a
+ // configured keybinding.
+ KeybindingHandler func(*Gui, *View) error
+)
+
+// Special keys.
+const (
+ KeyF1 Key = Key(termbox.KeyF1)
+ KeyF2 = Key(termbox.KeyF2)
+ KeyF3 = Key(termbox.KeyF3)
+ KeyF4 = Key(termbox.KeyF4)
+ KeyF5 = Key(termbox.KeyF5)
+ KeyF6 = Key(termbox.KeyF6)
+ KeyF7 = Key(termbox.KeyF7)
+ KeyF8 = Key(termbox.KeyF8)
+ KeyF9 = Key(termbox.KeyF9)
+ KeyF10 = Key(termbox.KeyF10)
+ KeyF11 = Key(termbox.KeyF11)
+ KeyF12 = Key(termbox.KeyF12)
+ KeyInsert = Key(termbox.KeyInsert)
+ KeyDelete = Key(termbox.KeyDelete)
+ KeyHome = Key(termbox.KeyHome)
+ KeyEnd = Key(termbox.KeyEnd)
+ KeyPgup = Key(termbox.KeyPgup)
+ KeyPgdn = Key(termbox.KeyPgdn)
+ KeyArrowUp = Key(termbox.KeyArrowUp)
+ KeyArrowDown = Key(termbox.KeyArrowDown)
+ KeyArrowLeft = Key(termbox.KeyArrowLeft)
+ KeyArrowRight = Key(termbox.KeyArrowRight)
+
+ MouseLeft = Key(termbox.MouseLeft)
+ MouseMiddle = Key(termbox.MouseMiddle)
+ MouseRight = Key(termbox.MouseRight)
+)
+
+// Keys combinations.
+const (
+ KeyCtrlTilde Key = Key(termbox.KeyCtrlTilde)
+ KeyCtrl2 = Key(termbox.KeyCtrl2)
+ KeyCtrlSpace = Key(termbox.KeyCtrlSpace)
+ KeyCtrlA = Key(termbox.KeyCtrlA)
+ KeyCtrlB = Key(termbox.KeyCtrlB)
+ KeyCtrlC = Key(termbox.KeyCtrlC)
+ KeyCtrlD = Key(termbox.KeyCtrlD)
+ KeyCtrlE = Key(termbox.KeyCtrlE)
+ KeyCtrlF = Key(termbox.KeyCtrlF)
+ KeyCtrlG = Key(termbox.KeyCtrlG)
+ KeyBackspace = Key(termbox.KeyBackspace)
+ KeyCtrlH = Key(termbox.KeyCtrlH)
+ KeyTab = Key(termbox.KeyTab)
+ KeyCtrlI = Key(termbox.KeyCtrlI)
+ KeyCtrlJ = Key(termbox.KeyCtrlJ)
+ KeyCtrlK = Key(termbox.KeyCtrlK)
+ KeyCtrlL = Key(termbox.KeyCtrlL)
+ KeyEnter = Key(termbox.KeyEnter)
+ KeyCtrlM = Key(termbox.KeyCtrlM)
+ KeyCtrlN = Key(termbox.KeyCtrlN)
+ KeyCtrlO = Key(termbox.KeyCtrlO)
+ KeyCtrlP = Key(termbox.KeyCtrlP)
+ KeyCtrlQ = Key(termbox.KeyCtrlQ)
+ KeyCtrlR = Key(termbox.KeyCtrlR)
+ KeyCtrlS = Key(termbox.KeyCtrlS)
+ KeyCtrlT = Key(termbox.KeyCtrlT)
+ KeyCtrlU = Key(termbox.KeyCtrlU)
+ KeyCtrlV = Key(termbox.KeyCtrlV)
+ KeyCtrlW = Key(termbox.KeyCtrlW)
+ KeyCtrlX = Key(termbox.KeyCtrlX)
+ KeyCtrlY = Key(termbox.KeyCtrlY)
+ KeyCtrlZ = Key(termbox.KeyCtrlZ)
+ KeyEsc = Key(termbox.KeyEsc)
+ KeyCtrlLsqBracket = Key(termbox.KeyCtrlLsqBracket)
+ KeyCtrl3 = Key(termbox.KeyCtrl3)
+ KeyCtrl4 = Key(termbox.KeyCtrl4)
+ KeyCtrlBackslash = Key(termbox.KeyCtrlBackslash)
+ KeyCtrl5 = Key(termbox.KeyCtrl5)
+ KeyCtrlRsqBracket = Key(termbox.KeyCtrlRsqBracket)
+ KeyCtrl6 = Key(termbox.KeyCtrl6)
+ KeyCtrl7 = Key(termbox.KeyCtrl7)
+ KeyCtrlSlash = Key(termbox.KeyCtrlSlash)
+ KeyCtrlUnderscore = Key(termbox.KeyCtrlUnderscore)
+ KeySpace = Key(termbox.KeySpace)
+ KeyBackspace2 = Key(termbox.KeyBackspace2)
+ KeyCtrl8 = Key(termbox.KeyCtrl8)
+)
+
+// Modifiers.
+const (
+ ModNone Modifier = Modifier(0)
+ ModAlt = Modifier(termbox.ModAlt)
+)
+
+// Keybidings are used to link a given key-press event with a handler.
+type keybinding struct {
+ viewName string
+ key Key
+ ch rune
+ mod Modifier
+ h KeybindingHandler
+}
+
+// newKeybinding returns a new Keybinding object.
+func newKeybinding(viewname string, key Key, ch rune, mod Modifier, h KeybindingHandler) (kb *keybinding) {
+ kb = &keybinding{
+ viewName: viewname,
+ key: key,
+ ch: ch,
+ mod: mod,
+ h: h,
+ }
+ return kb
+}
+
+// matchKeypress returns if the keybinding matches the keypress.
+func (kb *keybinding) matchKeypress(key Key, ch rune, mod Modifier) bool {
+ return kb.key == key && kb.ch == ch && kb.mod == mod
+}
+
+// matchView returns if the keybinding matches the current view.
+func (kb *keybinding) matchView(v *View) bool {
+ if kb.viewName == "" {
+ return true
+ }
+ return v != nil && kb.viewName == v.name
+}
diff --git a/vendor/github.com/jroimartin/gocui/view.go b/vendor/github.com/jroimartin/gocui/view.go
new file mode 100644
index 00000000..f8d86940
--- /dev/null
+++ b/vendor/github.com/jroimartin/gocui/view.go
@@ -0,0 +1,474 @@
+// Copyright 2014 The gocui Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocui
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "strings"
+
+ "github.com/nsf/termbox-go"
+)
+
+// A View is a window. It maintains its own internal buffer and cursor
+// position.
+type View struct {
+ name string
+ x0, y0, x1, y1 int
+ ox, oy int
+ cx, cy int
+ lines [][]cell
+ readOffset int
+ readCache string
+
+ tainted bool // marks if the viewBuffer must be updated
+ viewLines []viewLine // internal representation of the view's buffer
+
+ ei *escapeInterpreter // used to decode ESC sequences on Write
+
+ // BgColor and FgColor allow to configure the background and foreground
+ // colors of the View.
+ BgColor, FgColor Attribute
+
+ // SelBgColor and SelFgColor are used to configure the background and
+ // foreground colors of the selected line, when it is highlighted.
+ SelBgColor, SelFgColor Attribute
+
+ // If Editable is true, keystrokes will be added to the view's internal
+ // buffer at the cursor position.
+ Editable bool
+
+ // Overwrite enables or disables the overwrite mode of the view.
+ Overwrite bool
+
+ // If Highlight is true, Sel{Bg,Fg}Colors will be used
+ // for the line under the cursor position.
+ Highlight bool
+
+ // If Frame is true, a border will be drawn around the view.
+ Frame bool
+
+ // If Wrap is true, the content that is written to this View is
+ // automatically wrapped when it is longer than its width. If true the
+ // view's x-origin will be ignored.
+ Wrap bool
+
+ // If Autoscroll is true, the View will automatically scroll down when the
+ // text overflows. If true the view's y-origin will be ignored.
+ Autoscroll bool
+
+ // If Frame is true, Title allows to configure a title for the view.
+ Title string
+
+ // If Mask is true, the View will display the mask instead of the real
+ // content
+ Mask rune
+}
+
+type viewLine struct {
+ linesX, linesY int // coordinates relative to v.lines
+ line []cell
+}
+
+type cell struct {
+ chr rune
+ bgColor, fgColor Attribute
+}
+
+type lineType []cell
+
+// String returns a string from a given cell slice.
+func (l lineType) String() string {
+ str := ""
+ for _, c := range l {
+ str += string(c.chr)
+ }
+ return str
+}
+
+// newView returns a new View object.
+func newView(name string, x0, y0, x1, y1 int) *View {
+ v := &View{
+ name: name,
+ x0: x0,
+ y0: y0,
+ x1: x1,
+ y1: y1,
+ Frame: true,
+ tainted: true,
+ ei: newEscapeInterpreter(),
+ }
+ return v
+}
+
+// Size returns the number of visible columns and rows in the View.
+func (v *View) Size() (x, y int) {
+ return v.x1 - v.x0 - 1, v.y1 - v.y0 - 1
+}
+
+// Name returns the name of the view.
+func (v *View) Name() string {
+ return v.name
+}
+
+// setRune sets a rune at the given point relative to the view. It applies the
+// specified colors, taking into account if the cell must be highlighted. Also,
+// it checks if the position is valid.
+func (v *View) setRune(x, y int, ch rune, fgColor, bgColor Attribute) error {
+ maxX, maxY := v.Size()
+ if x < 0 || x >= maxX || y < 0 || y >= maxY {
+ return errors.New("invalid point")
+ }
+
+ var (
+ ry, rcy int
+ err error
+ )
+ if v.Highlight {
+ _, ry, err = v.realPosition(x, y)
+ if err != nil {
+ return err
+ }
+ _, rcy, err = v.realPosition(v.cx, v.cy)
+ if err != nil {
+ return err
+ }
+ }
+
+ if v.Mask != 0 {
+ fgColor = v.FgColor
+ bgColor = v.BgColor
+ ch = v.Mask
+ } else if v.Highlight && ry == rcy {
+ fgColor = v.SelFgColor
+ bgColor = v.SelBgColor
+ }
+
+ termbox.SetCell(v.x0+x+1, v.y0+y+1, ch,
+ termbox.Attribute(fgColor), termbox.Attribute(bgColor))
+
+ return nil
+}
+
+// SetCursor sets the cursor position of the view at the given point,
+// relative to the view. It checks if the position is valid.
+func (v *View) SetCursor(x, y int) error {
+ maxX, maxY := v.Size()
+ if x < 0 || x >= maxX || y < 0 || y >= maxY {
+ return errors.New("invalid point")
+ }
+ v.cx = x
+ v.cy = y
+ return nil
+}
+
+// Cursor returns the cursor position of the view.
+func (v *View) Cursor() (x, y int) {
+ return v.cx, v.cy
+}
+
+// SetOrigin sets the origin position of the view's internal buffer,
+// so the buffer starts to be printed from this point, which means that
+// it is linked with the origin point of view. It can be used to
+// implement Horizontal and Vertical scrolling with just incrementing
+// or decrementing ox and oy.
+func (v *View) SetOrigin(x, y int) error {
+ if x < 0 || y < 0 {
+ return errors.New("invalid point")
+ }
+ v.ox = x
+ v.oy = y
+ return nil
+}
+
+// Origin returns the origin position of the view.
+func (v *View) Origin() (x, y int) {
+ return v.ox, v.oy
+}
+
+// Write appends a byte slice into the view's internal buffer. Because
+// View implements the io.Writer interface, it can be passed as parameter
+// of functions like fmt.Fprintf, fmt.Fprintln, io.Copy, etc. Clear must
+// be called to clear the view's buffer.
+func (v *View) Write(p []byte) (n int, err error) {
+ v.tainted = true
+
+ for _, ch := range bytes.Runes(p) {
+ switch ch {
+ case '\n':
+ v.lines = append(v.lines, nil)
+ case '\r':
+ nl := len(v.lines)
+ if nl > 0 {
+ v.lines[nl-1] = nil
+ } else {
+ v.lines = make([][]cell, 1)
+ }
+ default:
+ cells := v.parseInput(ch)
+ if cells == nil {
+ continue
+ }
+
+ nl := len(v.lines)
+ if nl > 0 {
+ v.lines[nl-1] = append(v.lines[nl-1], cells...)
+ } else {
+ v.lines = append(v.lines, cells)
+ }
+ }
+ }
+ return len(p), nil
+}
+
+// parseInput parses char by char the input written to the View. It returns nil
+// while processing ESC sequences. Otherwise, it returns a cell slice that
+// contains the processed data.
+func (v *View) parseInput(ch rune) []cell {
+ cells := []cell{}
+
+ isEscape, err := v.ei.parseOne(ch)
+ if err != nil {
+ for _, r := range v.ei.runes() {
+ c := cell{
+ fgColor: v.FgColor,
+ bgColor: v.BgColor,
+ chr: r,
+ }
+ cells = append(cells, c)
+ }
+ v.ei.reset()
+ } else {
+ if isEscape {
+ return nil
+ }
+ c := cell{
+ fgColor: v.ei.curFgColor,
+ bgColor: v.ei.curBgColor,
+ chr: ch,
+ }
+ cells = append(cells, c)
+ }
+
+ return cells
+}
+
+// Read reads data into p. It returns the number of bytes read into p.
+// At EOF, err will be io.EOF. Calling Read() after Rewind() makes the
+// cache to be refreshed with the contents of the view.
+func (v *View) Read(p []byte) (n int, err error) {
+ if v.readOffset == 0 {
+ v.readCache = v.Buffer()
+ }
+ if v.readOffset < len(v.readCache) {
+ n = copy(p, v.readCache[v.readOffset:])
+ v.readOffset += n
+ } else {
+ err = io.EOF
+ }
+ return
+}
+
+// Rewind sets the offset for the next Read to 0, which also refresh the
+// read cache.
+func (v *View) Rewind() {
+ v.readOffset = 0
+}
+
+// draw re-draws the view's contents.
+func (v *View) draw() error {
+ maxX, maxY := v.Size()
+
+ if v.Wrap {
+ if maxX == 0 {
+ return errors.New("X size of the view cannot be 0")
+ }
+ v.ox = 0
+ }
+ if v.tainted {
+ v.viewLines = nil
+ for i, line := range v.lines {
+ if v.Wrap {
+ if len(line) <= maxX {
+ vline := viewLine{linesX: 0, linesY: i, line: line}
+ v.viewLines = append(v.viewLines, vline)
+ continue
+ } else {
+ vline := viewLine{linesX: 0, linesY: i, line: line[:maxX]}
+ v.viewLines = append(v.viewLines, vline)
+ }
+ // Append remaining lines
+ for n := maxX; n < len(line); n += maxX {
+ if len(line[n:]) <= maxX {
+ vline := viewLine{linesX: n, linesY: i, line: line[n:]}
+ v.viewLines = append(v.viewLines, vline)
+ } else {
+ vline := viewLine{linesX: n, linesY: i, line: line[n : n+maxX]}
+ v.viewLines = append(v.viewLines, vline)
+ }
+ }
+ } else {
+ vline := viewLine{linesX: 0, linesY: i, line: line}
+ v.viewLines = append(v.viewLines, vline)
+ }
+ }
+ v.tainted = false
+ }
+
+ if v.Autoscroll && len(v.viewLines) > maxY {
+ v.oy = len(v.viewLines) - maxY
+ }
+ y := 0
+ for i, vline := range v.viewLines {
+ if i < v.oy {
+ continue
+ }
+ if y >= maxY {
+ break
+ }
+ x := 0
+ for j, c := range vline.line {
+ if j < v.ox {
+ continue
+ }
+ if x >= maxX {
+ break
+ }
+
+ fgColor := c.fgColor
+ if fgColor == ColorDefault {
+ fgColor = v.FgColor
+ }
+ bgColor := c.bgColor
+ if bgColor == ColorDefault {
+ bgColor = v.BgColor
+ }
+
+ if err := v.setRune(x, y, c.chr, fgColor, bgColor); err != nil {
+ return err
+ }
+ x++
+ }
+ y++
+ }
+ return nil
+}
+
+// realPosition returns the position in the internal buffer corresponding to the
+// point (x, y) of the view.
+func (v *View) realPosition(vx, vy int) (x, y int, err error) {
+ vx = v.ox + vx
+ vy = v.oy + vy
+
+ if vx < 0 || vy < 0 {
+ return 0, 0, errors.New("invalid point")
+ }
+
+ if len(v.viewLines) == 0 {
+ return vx, vy, nil
+ }
+
+ if vy < len(v.viewLines) {
+ vline := v.viewLines[vy]
+ x = vline.linesX + vx
+ y = vline.linesY
+ } else {
+ vline := v.viewLines[len(v.viewLines)-1]
+ x = vx
+ y = vline.linesY + vy - len(v.viewLines) + 1
+ }
+
+ return x, y, nil
+}
+
+// Clear empties the view's internal buffer.
+func (v *View) Clear() {
+ v.tainted = true
+
+ v.lines = nil
+ v.clearRunes()
+}
+
+// clearRunes erases all the cells in the view.
+func (v *View) clearRunes() {
+ maxX, maxY := v.Size()
+ for x := 0; x < maxX; x++ {
+ for y := 0; y < maxY; y++ {
+ termbox.SetCell(v.x0+x+1, v.y0+y+1, ' ',
+ termbox.Attribute(v.FgColor), termbox.Attribute(v.BgColor))
+ }
+ }
+}
+
+// Buffer returns a string with the contents of the view's internal
+// buffer.
+func (v *View) Buffer() string {
+ str := ""
+ for _, l := range v.lines {
+ str += lineType(l).String() + "\n"
+ }
+ return strings.Replace(str, "\x00", " ", -1)
+}
+
+// ViewBuffer returns a string with the contents of the view's buffer that is
+// shown to the user.
+func (v *View) ViewBuffer() string {
+ str := ""
+ for _, l := range v.viewLines {
+ str += lineType(l.line).String() + "\n"
+ }
+ return strings.Replace(str, "\x00", " ", -1)
+}
+
+// Line returns a string with the line of the view's internal buffer
+// at the position corresponding to the point (x, y).
+func (v *View) Line(y int) (string, error) {
+ _, y, err := v.realPosition(0, y)
+ if err != nil {
+ return "", err
+ }
+
+ if y < 0 || y >= len(v.lines) {
+ return "", errors.New("invalid point")
+ }
+
+ return lineType(v.lines[y]).String(), nil
+}
+
+// Word returns a string with the word of the view's internal buffer
+// at the position corresponding to the point (x, y).
+func (v *View) Word(x, y int) (string, error) {
+ x, y, err := v.realPosition(x, y)
+ if err != nil {
+ return "", err
+ }
+
+ if x < 0 || y < 0 || y >= len(v.lines) || x >= len(v.lines[y]) {
+ return "", errors.New("invalid point")
+ }
+
+ str := lineType(v.lines[y]).String()
+
+ nl := strings.LastIndexFunc(str[:x], indexFunc)
+ if nl == -1 {
+ nl = 0
+ } else {
+ nl = nl + 1
+ }
+ nr := strings.IndexFunc(str[x:], indexFunc)
+ if nr == -1 {
+ nr = len(str)
+ } else {
+ nr = nr + x
+ }
+ return string(str[nl:nr]), nil
+}
+
+// indexFunc allows to split lines by words taking into account spaces
+// and 0.
+func indexFunc(r rune) bool {
+ return r == ' ' || r == 0
+}
diff --git a/vendor/github.com/mattn/go-runewidth/.travis.yml b/vendor/github.com/mattn/go-runewidth/.travis.yml
new file mode 100644
index 00000000..5c9c2a30
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/.travis.yml
@@ -0,0 +1,8 @@
+language: go
+go:
+ - tip
+before_install:
+ - go get github.com/mattn/goveralls
+ - go get golang.org/x/tools/cmd/cover
+script:
+ - $HOME/gopath/bin/goveralls -repotoken lAKAWPzcGsD3A8yBX3BGGtRUdJ6CaGERL
diff --git a/vendor/github.com/mattn/go-runewidth/LICENSE b/vendor/github.com/mattn/go-runewidth/LICENSE
new file mode 100644
index 00000000..91b5cef3
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Yasuhiro Matsumoto
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/mattn/go-runewidth/README.mkd b/vendor/github.com/mattn/go-runewidth/README.mkd
new file mode 100644
index 00000000..66663a94
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/README.mkd
@@ -0,0 +1,27 @@
+go-runewidth
+============
+
+[![Build Status](https://travis-ci.org/mattn/go-runewidth.png?branch=master)](https://travis-ci.org/mattn/go-runewidth)
+[![Coverage Status](https://coveralls.io/repos/mattn/go-runewidth/badge.png?branch=HEAD)](https://coveralls.io/r/mattn/go-runewidth?branch=HEAD)
+[![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth)
+[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-runewidth)](https://goreportcard.com/report/github.com/mattn/go-runewidth)
+
+Provides functions to get fixed width of the character or string.
+
+Usage
+-----
+
+```go
+runewidth.StringWidth("つのだ☆HIRO") == 12
+```
+
+
+Author
+------
+
+Yasuhiro Matsumoto
+
+License
+-------
+
+under the MIT License: http://mattn.mit-license.org/2013
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth.go b/vendor/github.com/mattn/go-runewidth/runewidth.go
new file mode 100644
index 00000000..2164497a
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/runewidth.go
@@ -0,0 +1,1223 @@
+package runewidth
+
+var (
+ // EastAsianWidth will be set true if the current locale is CJK
+ EastAsianWidth = IsEastAsian()
+
+ // DefaultCondition is a condition in current locale
+ DefaultCondition = &Condition{EastAsianWidth}
+)
+
+type interval struct {
+ first rune
+ last rune
+}
+
+type table []interval
+
+func inTables(r rune, ts ...table) bool {
+ for _, t := range ts {
+ if inTable(r, t) {
+ return true
+ }
+ }
+ return false
+}
+
+func inTable(r rune, t table) bool {
+ // func (t table) IncludesRune(r rune) bool {
+ if r < t[0].first {
+ return false
+ }
+
+ bot := 0
+ top := len(t) - 1
+ for top >= bot {
+ mid := (bot + top) / 2
+
+ switch {
+ case t[mid].last < r:
+ bot = mid + 1
+ case t[mid].first > r:
+ top = mid - 1
+ default:
+ return true
+ }
+ }
+
+ return false
+}
+
+var private = table{
+ {0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD},
+}
+
+var nonprint = table{
+ {0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD},
+ {0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F},
+ {0x202A, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF},
+ {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF},
+}
+
+var combining = table{
+ {0x0300, 0x036F}, {0x0483, 0x0489}, {0x0591, 0x05BD},
+ {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, {0x05C4, 0x05C5},
+ {0x05C7, 0x05C7}, {0x0610, 0x061A}, {0x064B, 0x065F},
+ {0x0670, 0x0670}, {0x06D6, 0x06DC}, {0x06DF, 0x06E4},
+ {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, {0x0711, 0x0711},
+ {0x0730, 0x074A}, {0x07A6, 0x07B0}, {0x07EB, 0x07F3},
+ {0x0816, 0x0819}, {0x081B, 0x0823}, {0x0825, 0x0827},
+ {0x0829, 0x082D}, {0x0859, 0x085B}, {0x08D4, 0x08E1},
+ {0x08E3, 0x0903}, {0x093A, 0x093C}, {0x093E, 0x094F},
+ {0x0951, 0x0957}, {0x0962, 0x0963}, {0x0981, 0x0983},
+ {0x09BC, 0x09BC}, {0x09BE, 0x09C4}, {0x09C7, 0x09C8},
+ {0x09CB, 0x09CD}, {0x09D7, 0x09D7}, {0x09E2, 0x09E3},
+ {0x0A01, 0x0A03}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42},
+ {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51},
+ {0x0A70, 0x0A71}, {0x0A75, 0x0A75}, {0x0A81, 0x0A83},
+ {0x0ABC, 0x0ABC}, {0x0ABE, 0x0AC5}, {0x0AC7, 0x0AC9},
+ {0x0ACB, 0x0ACD}, {0x0AE2, 0x0AE3}, {0x0B01, 0x0B03},
+ {0x0B3C, 0x0B3C}, {0x0B3E, 0x0B44}, {0x0B47, 0x0B48},
+ {0x0B4B, 0x0B4D}, {0x0B56, 0x0B57}, {0x0B62, 0x0B63},
+ {0x0B82, 0x0B82}, {0x0BBE, 0x0BC2}, {0x0BC6, 0x0BC8},
+ {0x0BCA, 0x0BCD}, {0x0BD7, 0x0BD7}, {0x0C00, 0x0C03},
+ {0x0C3E, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D},
+ {0x0C55, 0x0C56}, {0x0C62, 0x0C63}, {0x0C81, 0x0C83},
+ {0x0CBC, 0x0CBC}, {0x0CBE, 0x0CC4}, {0x0CC6, 0x0CC8},
+ {0x0CCA, 0x0CCD}, {0x0CD5, 0x0CD6}, {0x0CE2, 0x0CE3},
+ {0x0D01, 0x0D03}, {0x0D3E, 0x0D44}, {0x0D46, 0x0D48},
+ {0x0D4A, 0x0D4D}, {0x0D57, 0x0D57}, {0x0D62, 0x0D63},
+ {0x0D82, 0x0D83}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4},
+ {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF}, {0x0DF2, 0x0DF3},
+ {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E},
+ {0x0EB1, 0x0EB1}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC},
+ {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, {0x0F35, 0x0F35},
+ {0x0F37, 0x0F37}, {0x0F39, 0x0F39}, {0x0F3E, 0x0F3F},
+ {0x0F71, 0x0F84}, {0x0F86, 0x0F87}, {0x0F8D, 0x0F97},
+ {0x0F99, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102B, 0x103E},
+ {0x1056, 0x1059}, {0x105E, 0x1060}, {0x1062, 0x1064},
+ {0x1067, 0x106D}, {0x1071, 0x1074}, {0x1082, 0x108D},
+ {0x108F, 0x108F}, {0x109A, 0x109D}, {0x135D, 0x135F},
+ {0x1712, 0x1714}, {0x1732, 0x1734}, {0x1752, 0x1753},
+ {0x1772, 0x1773}, {0x17B4, 0x17D3}, {0x17DD, 0x17DD},
+ {0x180B, 0x180D}, {0x1885, 0x1886}, {0x18A9, 0x18A9},
+ {0x1920, 0x192B}, {0x1930, 0x193B}, {0x1A17, 0x1A1B},
+ {0x1A55, 0x1A5E}, {0x1A60, 0x1A7C}, {0x1A7F, 0x1A7F},
+ {0x1AB0, 0x1ABE}, {0x1B00, 0x1B04}, {0x1B34, 0x1B44},
+ {0x1B6B, 0x1B73}, {0x1B80, 0x1B82}, {0x1BA1, 0x1BAD},
+ {0x1BE6, 0x1BF3}, {0x1C24, 0x1C37}, {0x1CD0, 0x1CD2},
+ {0x1CD4, 0x1CE8}, {0x1CED, 0x1CED}, {0x1CF2, 0x1CF4},
+ {0x1CF8, 0x1CF9}, {0x1DC0, 0x1DF5}, {0x1DFB, 0x1DFF},
+ {0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2D7F, 0x2D7F},
+ {0x2DE0, 0x2DFF}, {0x302A, 0x302F}, {0x3099, 0x309A},
+ {0xA66F, 0xA672}, {0xA674, 0xA67D}, {0xA69E, 0xA69F},
+ {0xA6F0, 0xA6F1}, {0xA802, 0xA802}, {0xA806, 0xA806},
+ {0xA80B, 0xA80B}, {0xA823, 0xA827}, {0xA880, 0xA881},
+ {0xA8B4, 0xA8C5}, {0xA8E0, 0xA8F1}, {0xA926, 0xA92D},
+ {0xA947, 0xA953}, {0xA980, 0xA983}, {0xA9B3, 0xA9C0},
+ {0xA9E5, 0xA9E5}, {0xAA29, 0xAA36}, {0xAA43, 0xAA43},
+ {0xAA4C, 0xAA4D}, {0xAA7B, 0xAA7D}, {0xAAB0, 0xAAB0},
+ {0xAAB2, 0xAAB4}, {0xAAB7, 0xAAB8}, {0xAABE, 0xAABF},
+ {0xAAC1, 0xAAC1}, {0xAAEB, 0xAAEF}, {0xAAF5, 0xAAF6},
+ {0xABE3, 0xABEA}, {0xABEC, 0xABED}, {0xFB1E, 0xFB1E},
+ {0xFE00, 0xFE0F}, {0xFE20, 0xFE2F}, {0x101FD, 0x101FD},
+ {0x102E0, 0x102E0}, {0x10376, 0x1037A}, {0x10A01, 0x10A03},
+ {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, {0x10A38, 0x10A3A},
+ {0x10A3F, 0x10A3F}, {0x10AE5, 0x10AE6}, {0x11000, 0x11002},
+ {0x11038, 0x11046}, {0x1107F, 0x11082}, {0x110B0, 0x110BA},
+ {0x11100, 0x11102}, {0x11127, 0x11134}, {0x11173, 0x11173},
+ {0x11180, 0x11182}, {0x111B3, 0x111C0}, {0x111CA, 0x111CC},
+ {0x1122C, 0x11237}, {0x1123E, 0x1123E}, {0x112DF, 0x112EA},
+ {0x11300, 0x11303}, {0x1133C, 0x1133C}, {0x1133E, 0x11344},
+ {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11357, 0x11357},
+ {0x11362, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374},
+ {0x11435, 0x11446}, {0x114B0, 0x114C3}, {0x115AF, 0x115B5},
+ {0x115B8, 0x115C0}, {0x115DC, 0x115DD}, {0x11630, 0x11640},
+ {0x116AB, 0x116B7}, {0x1171D, 0x1172B}, {0x11C2F, 0x11C36},
+ {0x11C38, 0x11C3F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6},
+ {0x16AF0, 0x16AF4}, {0x16B30, 0x16B36}, {0x16F51, 0x16F7E},
+ {0x16F8F, 0x16F92}, {0x1BC9D, 0x1BC9E}, {0x1D165, 0x1D169},
+ {0x1D16D, 0x1D172}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B},
+ {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0x1DA00, 0x1DA36},
+ {0x1DA3B, 0x1DA6C}, {0x1DA75, 0x1DA75}, {0x1DA84, 0x1DA84},
+ {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006},
+ {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024},
+ {0x1E026, 0x1E02A}, {0x1E8D0, 0x1E8D6}, {0x1E944, 0x1E94A},
+ {0xE0100, 0xE01EF},
+}
+
+var doublewidth = table{
+ {0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A},
+ {0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3},
+ {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653},
+ {0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1},
+ {0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5},
+ {0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA},
+ {0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA},
+ {0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B},
+ {0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E},
+ {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797},
+ {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C},
+ {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99},
+ {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB},
+ {0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF},
+ {0x3105, 0x312D}, {0x3131, 0x318E}, {0x3190, 0x31BA},
+ {0x31C0, 0x31E3}, {0x31F0, 0x321E}, {0x3220, 0x3247},
+ {0x3250, 0x32FE}, {0x3300, 0x4DBF}, {0x4E00, 0xA48C},
+ {0xA490, 0xA4C6}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3},
+ {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52},
+ {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60},
+ {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE0}, {0x17000, 0x187EC},
+ {0x18800, 0x18AF2}, {0x1B000, 0x1B001}, {0x1F004, 0x1F004},
+ {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A},
+ {0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248},
+ {0x1F250, 0x1F251}, {0x1F300, 0x1F320}, {0x1F32D, 0x1F335},
+ {0x1F337, 0x1F37C}, {0x1F37E, 0x1F393}, {0x1F3A0, 0x1F3CA},
+ {0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0}, {0x1F3F4, 0x1F3F4},
+ {0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440}, {0x1F442, 0x1F4FC},
+ {0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E}, {0x1F550, 0x1F567},
+ {0x1F57A, 0x1F57A}, {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A4},
+ {0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC},
+ {0x1F6D0, 0x1F6D2}, {0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6F6},
+ {0x1F910, 0x1F91E}, {0x1F920, 0x1F927}, {0x1F930, 0x1F930},
+ {0x1F933, 0x1F93E}, {0x1F940, 0x1F94B}, {0x1F950, 0x1F95E},
+ {0x1F980, 0x1F991}, {0x1F9C0, 0x1F9C0}, {0x20000, 0x2FFFD},
+ {0x30000, 0x3FFFD},
+}
+
+var ambiguous = table{
+ {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8},
+ {0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4},
+ {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6},
+ {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1},
+ {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED},
+ {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA},
+ {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101},
+ {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B},
+ {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133},
+ {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144},
+ {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153},
+ {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE},
+ {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4},
+ {0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA},
+ {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261},
+ {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB},
+ {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB},
+ {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F},
+ {0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1},
+ {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F},
+ {0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016},
+ {0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022},
+ {0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033},
+ {0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E},
+ {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084},
+ {0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105},
+ {0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116},
+ {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B},
+ {0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B},
+ {0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199},
+ {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4},
+ {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203},
+ {0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F},
+ {0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A},
+ {0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225},
+ {0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237},
+ {0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C},
+ {0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267},
+ {0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283},
+ {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299},
+ {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312},
+ {0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573},
+ {0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1},
+ {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7},
+ {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8},
+ {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5},
+ {0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609},
+ {0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E},
+ {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661},
+ {0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D},
+ {0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF},
+ {0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1},
+ {0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1},
+ {0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC},
+ {0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F},
+ {0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF},
+ {0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A},
+ {0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D},
+ {0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF},
+ {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD},
+}
+
+var emoji = table{
+ {0x1F1E6, 0x1F1FF}, {0x1F321, 0x1F321}, {0x1F324, 0x1F32C},
+ {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D}, {0x1F396, 0x1F397},
+ {0x1F399, 0x1F39B}, {0x1F39E, 0x1F39F}, {0x1F3CB, 0x1F3CE},
+ {0x1F3D4, 0x1F3DF}, {0x1F3F3, 0x1F3F5}, {0x1F3F7, 0x1F3F7},
+ {0x1F43F, 0x1F43F}, {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FD},
+ {0x1F549, 0x1F54A}, {0x1F56F, 0x1F570}, {0x1F573, 0x1F579},
+ {0x1F587, 0x1F587}, {0x1F58A, 0x1F58D}, {0x1F590, 0x1F590},
+ {0x1F5A5, 0x1F5A5}, {0x1F5A8, 0x1F5A8}, {0x1F5B1, 0x1F5B2},
+ {0x1F5BC, 0x1F5BC}, {0x1F5C2, 0x1F5C4}, {0x1F5D1, 0x1F5D3},
+ {0x1F5DC, 0x1F5DE}, {0x1F5E1, 0x1F5E1}, {0x1F5E3, 0x1F5E3},
+ {0x1F5E8, 0x1F5E8}, {0x1F5EF, 0x1F5EF}, {0x1F5F3, 0x1F5F3},
+ {0x1F5FA, 0x1F5FA}, {0x1F6CB, 0x1F6CF}, {0x1F6E0, 0x1F6E5},
+ {0x1F6E9, 0x1F6E9}, {0x1F6F0, 0x1F6F0}, {0x1F6F3, 0x1F6F3},
+}
+
+var notassigned = table{
+ {0x0378, 0x0379}, {0x0380, 0x0383}, {0x038B, 0x038B},
+ {0x038D, 0x038D}, {0x03A2, 0x03A2}, {0x0530, 0x0530},
+ {0x0557, 0x0558}, {0x0560, 0x0560}, {0x0588, 0x0588},
+ {0x058B, 0x058C}, {0x0590, 0x0590}, {0x05C8, 0x05CF},
+ {0x05EB, 0x05EF}, {0x05F5, 0x05FF}, {0x061D, 0x061D},
+ {0x070E, 0x070E}, {0x074B, 0x074C}, {0x07B2, 0x07BF},
+ {0x07FB, 0x07FF}, {0x082E, 0x082F}, {0x083F, 0x083F},
+ {0x085C, 0x085D}, {0x085F, 0x089F}, {0x08B5, 0x08B5},
+ {0x08BE, 0x08D3}, {0x0984, 0x0984}, {0x098D, 0x098E},
+ {0x0991, 0x0992}, {0x09A9, 0x09A9}, {0x09B1, 0x09B1},
+ {0x09B3, 0x09B5}, {0x09BA, 0x09BB}, {0x09C5, 0x09C6},
+ {0x09C9, 0x09CA}, {0x09CF, 0x09D6}, {0x09D8, 0x09DB},
+ {0x09DE, 0x09DE}, {0x09E4, 0x09E5}, {0x09FC, 0x0A00},
+ {0x0A04, 0x0A04}, {0x0A0B, 0x0A0E}, {0x0A11, 0x0A12},
+ {0x0A29, 0x0A29}, {0x0A31, 0x0A31}, {0x0A34, 0x0A34},
+ {0x0A37, 0x0A37}, {0x0A3A, 0x0A3B}, {0x0A3D, 0x0A3D},
+ {0x0A43, 0x0A46}, {0x0A49, 0x0A4A}, {0x0A4E, 0x0A50},
+ {0x0A52, 0x0A58}, {0x0A5D, 0x0A5D}, {0x0A5F, 0x0A65},
+ {0x0A76, 0x0A80}, {0x0A84, 0x0A84}, {0x0A8E, 0x0A8E},
+ {0x0A92, 0x0A92}, {0x0AA9, 0x0AA9}, {0x0AB1, 0x0AB1},
+ {0x0AB4, 0x0AB4}, {0x0ABA, 0x0ABB}, {0x0AC6, 0x0AC6},
+ {0x0ACA, 0x0ACA}, {0x0ACE, 0x0ACF}, {0x0AD1, 0x0ADF},
+ {0x0AE4, 0x0AE5}, {0x0AF2, 0x0AF8}, {0x0AFA, 0x0B00},
+ {0x0B04, 0x0B04}, {0x0B0D, 0x0B0E}, {0x0B11, 0x0B12},
+ {0x0B29, 0x0B29}, {0x0B31, 0x0B31}, {0x0B34, 0x0B34},
+ {0x0B3A, 0x0B3B}, {0x0B45, 0x0B46}, {0x0B49, 0x0B4A},
+ {0x0B4E, 0x0B55}, {0x0B58, 0x0B5B}, {0x0B5E, 0x0B5E},
+ {0x0B64, 0x0B65}, {0x0B78, 0x0B81}, {0x0B84, 0x0B84},
+ {0x0B8B, 0x0B8D}, {0x0B91, 0x0B91}, {0x0B96, 0x0B98},
+ {0x0B9B, 0x0B9B}, {0x0B9D, 0x0B9D}, {0x0BA0, 0x0BA2},
+ {0x0BA5, 0x0BA7}, {0x0BAB, 0x0BAD}, {0x0BBA, 0x0BBD},
+ {0x0BC3, 0x0BC5}, {0x0BC9, 0x0BC9}, {0x0BCE, 0x0BCF},
+ {0x0BD1, 0x0BD6}, {0x0BD8, 0x0BE5}, {0x0BFB, 0x0BFF},
+ {0x0C04, 0x0C04}, {0x0C0D, 0x0C0D}, {0x0C11, 0x0C11},
+ {0x0C29, 0x0C29}, {0x0C3A, 0x0C3C}, {0x0C45, 0x0C45},
+ {0x0C49, 0x0C49}, {0x0C4E, 0x0C54}, {0x0C57, 0x0C57},
+ {0x0C5B, 0x0C5F}, {0x0C64, 0x0C65}, {0x0C70, 0x0C77},
+ {0x0C84, 0x0C84}, {0x0C8D, 0x0C8D}, {0x0C91, 0x0C91},
+ {0x0CA9, 0x0CA9}, {0x0CB4, 0x0CB4}, {0x0CBA, 0x0CBB},
+ {0x0CC5, 0x0CC5}, {0x0CC9, 0x0CC9}, {0x0CCE, 0x0CD4},
+ {0x0CD7, 0x0CDD}, {0x0CDF, 0x0CDF}, {0x0CE4, 0x0CE5},
+ {0x0CF0, 0x0CF0}, {0x0CF3, 0x0D00}, {0x0D04, 0x0D04},
+ {0x0D0D, 0x0D0D}, {0x0D11, 0x0D11}, {0x0D3B, 0x0D3C},
+ {0x0D45, 0x0D45}, {0x0D49, 0x0D49}, {0x0D50, 0x0D53},
+ {0x0D64, 0x0D65}, {0x0D80, 0x0D81}, {0x0D84, 0x0D84},
+ {0x0D97, 0x0D99}, {0x0DB2, 0x0DB2}, {0x0DBC, 0x0DBC},
+ {0x0DBE, 0x0DBF}, {0x0DC7, 0x0DC9}, {0x0DCB, 0x0DCE},
+ {0x0DD5, 0x0DD5}, {0x0DD7, 0x0DD7}, {0x0DE0, 0x0DE5},
+ {0x0DF0, 0x0DF1}, {0x0DF5, 0x0E00}, {0x0E3B, 0x0E3E},
+ {0x0E5C, 0x0E80}, {0x0E83, 0x0E83}, {0x0E85, 0x0E86},
+ {0x0E89, 0x0E89}, {0x0E8B, 0x0E8C}, {0x0E8E, 0x0E93},
+ {0x0E98, 0x0E98}, {0x0EA0, 0x0EA0}, {0x0EA4, 0x0EA4},
+ {0x0EA6, 0x0EA6}, {0x0EA8, 0x0EA9}, {0x0EAC, 0x0EAC},
+ {0x0EBA, 0x0EBA}, {0x0EBE, 0x0EBF}, {0x0EC5, 0x0EC5},
+ {0x0EC7, 0x0EC7}, {0x0ECE, 0x0ECF}, {0x0EDA, 0x0EDB},
+ {0x0EE0, 0x0EFF}, {0x0F48, 0x0F48}, {0x0F6D, 0x0F70},
+ {0x0F98, 0x0F98}, {0x0FBD, 0x0FBD}, {0x0FCD, 0x0FCD},
+ {0x0FDB, 0x0FFF}, {0x10C6, 0x10C6}, {0x10C8, 0x10CC},
+ {0x10CE, 0x10CF}, {0x1249, 0x1249}, {0x124E, 0x124F},
+ {0x1257, 0x1257}, {0x1259, 0x1259}, {0x125E, 0x125F},
+ {0x1289, 0x1289}, {0x128E, 0x128F}, {0x12B1, 0x12B1},
+ {0x12B6, 0x12B7}, {0x12BF, 0x12BF}, {0x12C1, 0x12C1},
+ {0x12C6, 0x12C7}, {0x12D7, 0x12D7}, {0x1311, 0x1311},
+ {0x1316, 0x1317}, {0x135B, 0x135C}, {0x137D, 0x137F},
+ {0x139A, 0x139F}, {0x13F6, 0x13F7}, {0x13FE, 0x13FF},
+ {0x169D, 0x169F}, {0x16F9, 0x16FF}, {0x170D, 0x170D},
+ {0x1715, 0x171F}, {0x1737, 0x173F}, {0x1754, 0x175F},
+ {0x176D, 0x176D}, {0x1771, 0x1771}, {0x1774, 0x177F},
+ {0x17DE, 0x17DF}, {0x17EA, 0x17EF}, {0x17FA, 0x17FF},
+ {0x180F, 0x180F}, {0x181A, 0x181F}, {0x1878, 0x187F},
+ {0x18AB, 0x18AF}, {0x18F6, 0x18FF}, {0x191F, 0x191F},
+ {0x192C, 0x192F}, {0x193C, 0x193F}, {0x1941, 0x1943},
+ {0x196E, 0x196F}, {0x1975, 0x197F}, {0x19AC, 0x19AF},
+ {0x19CA, 0x19CF}, {0x19DB, 0x19DD}, {0x1A1C, 0x1A1D},
+ {0x1A5F, 0x1A5F}, {0x1A7D, 0x1A7E}, {0x1A8A, 0x1A8F},
+ {0x1A9A, 0x1A9F}, {0x1AAE, 0x1AAF}, {0x1ABF, 0x1AFF},
+ {0x1B4C, 0x1B4F}, {0x1B7D, 0x1B7F}, {0x1BF4, 0x1BFB},
+ {0x1C38, 0x1C3A}, {0x1C4A, 0x1C4C}, {0x1C89, 0x1CBF},
+ {0x1CC8, 0x1CCF}, {0x1CF7, 0x1CF7}, {0x1CFA, 0x1CFF},
+ {0x1DF6, 0x1DFA}, {0x1F16, 0x1F17}, {0x1F1E, 0x1F1F},
+ {0x1F46, 0x1F47}, {0x1F4E, 0x1F4F}, {0x1F58, 0x1F58},
+ {0x1F5A, 0x1F5A}, {0x1F5C, 0x1F5C}, {0x1F5E, 0x1F5E},
+ {0x1F7E, 0x1F7F}, {0x1FB5, 0x1FB5}, {0x1FC5, 0x1FC5},
+ {0x1FD4, 0x1FD5}, {0x1FDC, 0x1FDC}, {0x1FF0, 0x1FF1},
+ {0x1FF5, 0x1FF5}, {0x1FFF, 0x1FFF}, {0x2065, 0x2065},
+ {0x2072, 0x2073}, {0x208F, 0x208F}, {0x209D, 0x209F},
+ {0x20BF, 0x20CF}, {0x20F1, 0x20FF}, {0x218C, 0x218F},
+ {0x23FF, 0x23FF}, {0x2427, 0x243F}, {0x244B, 0x245F},
+ {0x2B74, 0x2B75}, {0x2B96, 0x2B97}, {0x2BBA, 0x2BBC},
+ {0x2BC9, 0x2BC9}, {0x2BD2, 0x2BEB}, {0x2BF0, 0x2BFF},
+ {0x2C2F, 0x2C2F}, {0x2C5F, 0x2C5F}, {0x2CF4, 0x2CF8},
+ {0x2D26, 0x2D26}, {0x2D28, 0x2D2C}, {0x2D2E, 0x2D2F},
+ {0x2D68, 0x2D6E}, {0x2D71, 0x2D7E}, {0x2D97, 0x2D9F},
+ {0x2DA7, 0x2DA7}, {0x2DAF, 0x2DAF}, {0x2DB7, 0x2DB7},
+ {0x2DBF, 0x2DBF}, {0x2DC7, 0x2DC7}, {0x2DCF, 0x2DCF},
+ {0x2DD7, 0x2DD7}, {0x2DDF, 0x2DDF}, {0x2E45, 0x2E7F},
+ {0x2E9A, 0x2E9A}, {0x2EF4, 0x2EFF}, {0x2FD6, 0x2FEF},
+ {0x2FFC, 0x2FFF}, {0x3040, 0x3040}, {0x3097, 0x3098},
+ {0x3100, 0x3104}, {0x312E, 0x3130}, {0x318F, 0x318F},
+ {0x31BB, 0x31BF}, {0x31E4, 0x31EF}, {0x321F, 0x321F},
+ {0x32FF, 0x32FF}, {0x4DB6, 0x4DBF}, {0x9FD6, 0x9FFF},
+ {0xA48D, 0xA48F}, {0xA4C7, 0xA4CF}, {0xA62C, 0xA63F},
+ {0xA6F8, 0xA6FF}, {0xA7AF, 0xA7AF}, {0xA7B8, 0xA7F6},
+ {0xA82C, 0xA82F}, {0xA83A, 0xA83F}, {0xA878, 0xA87F},
+ {0xA8C6, 0xA8CD}, {0xA8DA, 0xA8DF}, {0xA8FE, 0xA8FF},
+ {0xA954, 0xA95E}, {0xA97D, 0xA97F}, {0xA9CE, 0xA9CE},
+ {0xA9DA, 0xA9DD}, {0xA9FF, 0xA9FF}, {0xAA37, 0xAA3F},
+ {0xAA4E, 0xAA4F}, {0xAA5A, 0xAA5B}, {0xAAC3, 0xAADA},
+ {0xAAF7, 0xAB00}, {0xAB07, 0xAB08}, {0xAB0F, 0xAB10},
+ {0xAB17, 0xAB1F}, {0xAB27, 0xAB27}, {0xAB2F, 0xAB2F},
+ {0xAB66, 0xAB6F}, {0xABEE, 0xABEF}, {0xABFA, 0xABFF},
+ {0xD7A4, 0xD7AF}, {0xD7C7, 0xD7CA}, {0xD7FC, 0xD7FF},
+ {0xFA6E, 0xFA6F}, {0xFADA, 0xFAFF}, {0xFB07, 0xFB12},
+ {0xFB18, 0xFB1C}, {0xFB37, 0xFB37}, {0xFB3D, 0xFB3D},
+ {0xFB3F, 0xFB3F}, {0xFB42, 0xFB42}, {0xFB45, 0xFB45},
+ {0xFBC2, 0xFBD2}, {0xFD40, 0xFD4F}, {0xFD90, 0xFD91},
+ {0xFDC8, 0xFDEF}, {0xFDFE, 0xFDFF}, {0xFE1A, 0xFE1F},
+ {0xFE53, 0xFE53}, {0xFE67, 0xFE67}, {0xFE6C, 0xFE6F},
+ {0xFE75, 0xFE75}, {0xFEFD, 0xFEFE}, {0xFF00, 0xFF00},
+ {0xFFBF, 0xFFC1}, {0xFFC8, 0xFFC9}, {0xFFD0, 0xFFD1},
+ {0xFFD8, 0xFFD9}, {0xFFDD, 0xFFDF}, {0xFFE7, 0xFFE7},
+ {0xFFEF, 0xFFF8}, {0xFFFE, 0xFFFF}, {0x1000C, 0x1000C},
+ {0x10027, 0x10027}, {0x1003B, 0x1003B}, {0x1003E, 0x1003E},
+ {0x1004E, 0x1004F}, {0x1005E, 0x1007F}, {0x100FB, 0x100FF},
+ {0x10103, 0x10106}, {0x10134, 0x10136}, {0x1018F, 0x1018F},
+ {0x1019C, 0x1019F}, {0x101A1, 0x101CF}, {0x101FE, 0x1027F},
+ {0x1029D, 0x1029F}, {0x102D1, 0x102DF}, {0x102FC, 0x102FF},
+ {0x10324, 0x1032F}, {0x1034B, 0x1034F}, {0x1037B, 0x1037F},
+ {0x1039E, 0x1039E}, {0x103C4, 0x103C7}, {0x103D6, 0x103FF},
+ {0x1049E, 0x1049F}, {0x104AA, 0x104AF}, {0x104D4, 0x104D7},
+ {0x104FC, 0x104FF}, {0x10528, 0x1052F}, {0x10564, 0x1056E},
+ {0x10570, 0x105FF}, {0x10737, 0x1073F}, {0x10756, 0x1075F},
+ {0x10768, 0x107FF}, {0x10806, 0x10807}, {0x10809, 0x10809},
+ {0x10836, 0x10836}, {0x10839, 0x1083B}, {0x1083D, 0x1083E},
+ {0x10856, 0x10856}, {0x1089F, 0x108A6}, {0x108B0, 0x108DF},
+ {0x108F3, 0x108F3}, {0x108F6, 0x108FA}, {0x1091C, 0x1091E},
+ {0x1093A, 0x1093E}, {0x10940, 0x1097F}, {0x109B8, 0x109BB},
+ {0x109D0, 0x109D1}, {0x10A04, 0x10A04}, {0x10A07, 0x10A0B},
+ {0x10A14, 0x10A14}, {0x10A18, 0x10A18}, {0x10A34, 0x10A37},
+ {0x10A3B, 0x10A3E}, {0x10A48, 0x10A4F}, {0x10A59, 0x10A5F},
+ {0x10AA0, 0x10ABF}, {0x10AE7, 0x10AEA}, {0x10AF7, 0x10AFF},
+ {0x10B36, 0x10B38}, {0x10B56, 0x10B57}, {0x10B73, 0x10B77},
+ {0x10B92, 0x10B98}, {0x10B9D, 0x10BA8}, {0x10BB0, 0x10BFF},
+ {0x10C49, 0x10C7F}, {0x10CB3, 0x10CBF}, {0x10CF3, 0x10CF9},
+ {0x10D00, 0x10E5F}, {0x10E7F, 0x10FFF}, {0x1104E, 0x11051},
+ {0x11070, 0x1107E}, {0x110C2, 0x110CF}, {0x110E9, 0x110EF},
+ {0x110FA, 0x110FF}, {0x11135, 0x11135}, {0x11144, 0x1114F},
+ {0x11177, 0x1117F}, {0x111CE, 0x111CF}, {0x111E0, 0x111E0},
+ {0x111F5, 0x111FF}, {0x11212, 0x11212}, {0x1123F, 0x1127F},
+ {0x11287, 0x11287}, {0x11289, 0x11289}, {0x1128E, 0x1128E},
+ {0x1129E, 0x1129E}, {0x112AA, 0x112AF}, {0x112EB, 0x112EF},
+ {0x112FA, 0x112FF}, {0x11304, 0x11304}, {0x1130D, 0x1130E},
+ {0x11311, 0x11312}, {0x11329, 0x11329}, {0x11331, 0x11331},
+ {0x11334, 0x11334}, {0x1133A, 0x1133B}, {0x11345, 0x11346},
+ {0x11349, 0x1134A}, {0x1134E, 0x1134F}, {0x11351, 0x11356},
+ {0x11358, 0x1135C}, {0x11364, 0x11365}, {0x1136D, 0x1136F},
+ {0x11375, 0x113FF}, {0x1145A, 0x1145A}, {0x1145C, 0x1145C},
+ {0x1145E, 0x1147F}, {0x114C8, 0x114CF}, {0x114DA, 0x1157F},
+ {0x115B6, 0x115B7}, {0x115DE, 0x115FF}, {0x11645, 0x1164F},
+ {0x1165A, 0x1165F}, {0x1166D, 0x1167F}, {0x116B8, 0x116BF},
+ {0x116CA, 0x116FF}, {0x1171A, 0x1171C}, {0x1172C, 0x1172F},
+ {0x11740, 0x1189F}, {0x118F3, 0x118FE}, {0x11900, 0x11ABF},
+ {0x11AF9, 0x11BFF}, {0x11C09, 0x11C09}, {0x11C37, 0x11C37},
+ {0x11C46, 0x11C4F}, {0x11C6D, 0x11C6F}, {0x11C90, 0x11C91},
+ {0x11CA8, 0x11CA8}, {0x11CB7, 0x11FFF}, {0x1239A, 0x123FF},
+ {0x1246F, 0x1246F}, {0x12475, 0x1247F}, {0x12544, 0x12FFF},
+ {0x1342F, 0x143FF}, {0x14647, 0x167FF}, {0x16A39, 0x16A3F},
+ {0x16A5F, 0x16A5F}, {0x16A6A, 0x16A6D}, {0x16A70, 0x16ACF},
+ {0x16AEE, 0x16AEF}, {0x16AF6, 0x16AFF}, {0x16B46, 0x16B4F},
+ {0x16B5A, 0x16B5A}, {0x16B62, 0x16B62}, {0x16B78, 0x16B7C},
+ {0x16B90, 0x16EFF}, {0x16F45, 0x16F4F}, {0x16F7F, 0x16F8E},
+ {0x16FA0, 0x16FDF}, {0x16FE1, 0x16FFF}, {0x187ED, 0x187FF},
+ {0x18AF3, 0x1AFFF}, {0x1B002, 0x1BBFF}, {0x1BC6B, 0x1BC6F},
+ {0x1BC7D, 0x1BC7F}, {0x1BC89, 0x1BC8F}, {0x1BC9A, 0x1BC9B},
+ {0x1BCA4, 0x1CFFF}, {0x1D0F6, 0x1D0FF}, {0x1D127, 0x1D128},
+ {0x1D1E9, 0x1D1FF}, {0x1D246, 0x1D2FF}, {0x1D357, 0x1D35F},
+ {0x1D372, 0x1D3FF}, {0x1D455, 0x1D455}, {0x1D49D, 0x1D49D},
+ {0x1D4A0, 0x1D4A1}, {0x1D4A3, 0x1D4A4}, {0x1D4A7, 0x1D4A8},
+ {0x1D4AD, 0x1D4AD}, {0x1D4BA, 0x1D4BA}, {0x1D4BC, 0x1D4BC},
+ {0x1D4C4, 0x1D4C4}, {0x1D506, 0x1D506}, {0x1D50B, 0x1D50C},
+ {0x1D515, 0x1D515}, {0x1D51D, 0x1D51D}, {0x1D53A, 0x1D53A},
+ {0x1D53F, 0x1D53F}, {0x1D545, 0x1D545}, {0x1D547, 0x1D549},
+ {0x1D551, 0x1D551}, {0x1D6A6, 0x1D6A7}, {0x1D7CC, 0x1D7CD},
+ {0x1DA8C, 0x1DA9A}, {0x1DAA0, 0x1DAA0}, {0x1DAB0, 0x1DFFF},
+ {0x1E007, 0x1E007}, {0x1E019, 0x1E01A}, {0x1E022, 0x1E022},
+ {0x1E025, 0x1E025}, {0x1E02B, 0x1E7FF}, {0x1E8C5, 0x1E8C6},
+ {0x1E8D7, 0x1E8FF}, {0x1E94B, 0x1E94F}, {0x1E95A, 0x1E95D},
+ {0x1E960, 0x1EDFF}, {0x1EE04, 0x1EE04}, {0x1EE20, 0x1EE20},
+ {0x1EE23, 0x1EE23}, {0x1EE25, 0x1EE26}, {0x1EE28, 0x1EE28},
+ {0x1EE33, 0x1EE33}, {0x1EE38, 0x1EE38}, {0x1EE3A, 0x1EE3A},
+ {0x1EE3C, 0x1EE41}, {0x1EE43, 0x1EE46}, {0x1EE48, 0x1EE48},
+ {0x1EE4A, 0x1EE4A}, {0x1EE4C, 0x1EE4C}, {0x1EE50, 0x1EE50},
+ {0x1EE53, 0x1EE53}, {0x1EE55, 0x1EE56}, {0x1EE58, 0x1EE58},
+ {0x1EE5A, 0x1EE5A}, {0x1EE5C, 0x1EE5C}, {0x1EE5E, 0x1EE5E},
+ {0x1EE60, 0x1EE60}, {0x1EE63, 0x1EE63}, {0x1EE65, 0x1EE66},
+ {0x1EE6B, 0x1EE6B}, {0x1EE73, 0x1EE73}, {0x1EE78, 0x1EE78},
+ {0x1EE7D, 0x1EE7D}, {0x1EE7F, 0x1EE7F}, {0x1EE8A, 0x1EE8A},
+ {0x1EE9C, 0x1EEA0}, {0x1EEA4, 0x1EEA4}, {0x1EEAA, 0x1EEAA},
+ {0x1EEBC, 0x1EEEF}, {0x1EEF2, 0x1EFFF}, {0x1F02C, 0x1F02F},
+ {0x1F094, 0x1F09F}, {0x1F0AF, 0x1F0B0}, {0x1F0C0, 0x1F0C0},
+ {0x1F0D0, 0x1F0D0}, {0x1F0F6, 0x1F0FF}, {0x1F10D, 0x1F10F},
+ {0x1F12F, 0x1F12F}, {0x1F16C, 0x1F16F}, {0x1F1AD, 0x1F1E5},
+ {0x1F203, 0x1F20F}, {0x1F23C, 0x1F23F}, {0x1F249, 0x1F24F},
+ {0x1F252, 0x1F2FF}, {0x1F6D3, 0x1F6DF}, {0x1F6ED, 0x1F6EF},
+ {0x1F6F7, 0x1F6FF}, {0x1F774, 0x1F77F}, {0x1F7D5, 0x1F7FF},
+ {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F}, {0x1F85A, 0x1F85F},
+ {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F90F}, {0x1F91F, 0x1F91F},
+ {0x1F928, 0x1F92F}, {0x1F931, 0x1F932}, {0x1F93F, 0x1F93F},
+ {0x1F94C, 0x1F94F}, {0x1F95F, 0x1F97F}, {0x1F992, 0x1F9BF},
+ {0x1F9C1, 0x1FFFF}, {0x2A6D7, 0x2A6FF}, {0x2B735, 0x2B73F},
+ {0x2B81E, 0x2B81F}, {0x2CEA2, 0x2F7FF}, {0x2FA1E, 0xE0000},
+ {0xE0002, 0xE001F}, {0xE0080, 0xE00FF}, {0xE01F0, 0xEFFFF},
+ {0xFFFFE, 0xFFFFF},
+}
+
+var neutral = table{
+ {0x0000, 0x001F}, {0x007F, 0x007F}, {0x0080, 0x009F},
+ {0x00A0, 0x00A0}, {0x00A9, 0x00A9}, {0x00AB, 0x00AB},
+ {0x00B5, 0x00B5}, {0x00BB, 0x00BB}, {0x00C0, 0x00C5},
+ {0x00C7, 0x00CF}, {0x00D1, 0x00D6}, {0x00D9, 0x00DD},
+ {0x00E2, 0x00E5}, {0x00E7, 0x00E7}, {0x00EB, 0x00EB},
+ {0x00EE, 0x00EF}, {0x00F1, 0x00F1}, {0x00F4, 0x00F6},
+ {0x00FB, 0x00FB}, {0x00FD, 0x00FD}, {0x00FF, 0x00FF},
+ {0x0100, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112},
+ {0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A},
+ {0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E},
+ {0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C},
+ {0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A},
+ {0x016C, 0x017F}, {0x0180, 0x01BA}, {0x01BB, 0x01BB},
+ {0x01BC, 0x01BF}, {0x01C0, 0x01C3}, {0x01C4, 0x01CD},
+ {0x01CF, 0x01CF}, {0x01D1, 0x01D1}, {0x01D3, 0x01D3},
+ {0x01D5, 0x01D5}, {0x01D7, 0x01D7}, {0x01D9, 0x01D9},
+ {0x01DB, 0x01DB}, {0x01DD, 0x024F}, {0x0250, 0x0250},
+ {0x0252, 0x0260}, {0x0262, 0x0293}, {0x0294, 0x0294},
+ {0x0295, 0x02AF}, {0x02B0, 0x02C1}, {0x02C2, 0x02C3},
+ {0x02C5, 0x02C5}, {0x02C6, 0x02C6}, {0x02C8, 0x02C8},
+ {0x02CC, 0x02CC}, {0x02CE, 0x02CF}, {0x02D1, 0x02D1},
+ {0x02D2, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE},
+ {0x02E0, 0x02E4}, {0x02E5, 0x02EB}, {0x02EC, 0x02EC},
+ {0x02ED, 0x02ED}, {0x02EE, 0x02EE}, {0x02EF, 0x02FF},
+ {0x0370, 0x0373}, {0x0374, 0x0374}, {0x0375, 0x0375},
+ {0x0376, 0x0377}, {0x037A, 0x037A}, {0x037B, 0x037D},
+ {0x037E, 0x037E}, {0x037F, 0x037F}, {0x0384, 0x0385},
+ {0x0386, 0x0386}, {0x0387, 0x0387}, {0x0388, 0x038A},
+ {0x038C, 0x038C}, {0x038E, 0x0390}, {0x03AA, 0x03B0},
+ {0x03C2, 0x03C2}, {0x03CA, 0x03F5}, {0x03F6, 0x03F6},
+ {0x03F7, 0x03FF}, {0x0400, 0x0400}, {0x0402, 0x040F},
+ {0x0450, 0x0450}, {0x0452, 0x0481}, {0x0482, 0x0482},
+ {0x0483, 0x0487}, {0x0488, 0x0489}, {0x048A, 0x04FF},
+ {0x0500, 0x052F}, {0x0531, 0x0556}, {0x0559, 0x0559},
+ {0x055A, 0x055F}, {0x0561, 0x0587}, {0x0589, 0x0589},
+ {0x058A, 0x058A}, {0x058D, 0x058E}, {0x058F, 0x058F},
+ {0x0591, 0x05BD}, {0x05BE, 0x05BE}, {0x05BF, 0x05BF},
+ {0x05C0, 0x05C0}, {0x05C1, 0x05C2}, {0x05C3, 0x05C3},
+ {0x05C4, 0x05C5}, {0x05C6, 0x05C6}, {0x05C7, 0x05C7},
+ {0x05D0, 0x05EA}, {0x05F0, 0x05F2}, {0x05F3, 0x05F4},
+ {0x0600, 0x0605}, {0x0606, 0x0608}, {0x0609, 0x060A},
+ {0x060B, 0x060B}, {0x060C, 0x060D}, {0x060E, 0x060F},
+ {0x0610, 0x061A}, {0x061B, 0x061B}, {0x061C, 0x061C},
+ {0x061E, 0x061F}, {0x0620, 0x063F}, {0x0640, 0x0640},
+ {0x0641, 0x064A}, {0x064B, 0x065F}, {0x0660, 0x0669},
+ {0x066A, 0x066D}, {0x066E, 0x066F}, {0x0670, 0x0670},
+ {0x0671, 0x06D3}, {0x06D4, 0x06D4}, {0x06D5, 0x06D5},
+ {0x06D6, 0x06DC}, {0x06DD, 0x06DD}, {0x06DE, 0x06DE},
+ {0x06DF, 0x06E4}, {0x06E5, 0x06E6}, {0x06E7, 0x06E8},
+ {0x06E9, 0x06E9}, {0x06EA, 0x06ED}, {0x06EE, 0x06EF},
+ {0x06F0, 0x06F9}, {0x06FA, 0x06FC}, {0x06FD, 0x06FE},
+ {0x06FF, 0x06FF}, {0x0700, 0x070D}, {0x070F, 0x070F},
+ {0x0710, 0x0710}, {0x0711, 0x0711}, {0x0712, 0x072F},
+ {0x0730, 0x074A}, {0x074D, 0x074F}, {0x0750, 0x077F},
+ {0x0780, 0x07A5}, {0x07A6, 0x07B0}, {0x07B1, 0x07B1},
+ {0x07C0, 0x07C9}, {0x07CA, 0x07EA}, {0x07EB, 0x07F3},
+ {0x07F4, 0x07F5}, {0x07F6, 0x07F6}, {0x07F7, 0x07F9},
+ {0x07FA, 0x07FA}, {0x0800, 0x0815}, {0x0816, 0x0819},
+ {0x081A, 0x081A}, {0x081B, 0x0823}, {0x0824, 0x0824},
+ {0x0825, 0x0827}, {0x0828, 0x0828}, {0x0829, 0x082D},
+ {0x0830, 0x083E}, {0x0840, 0x0858}, {0x0859, 0x085B},
+ {0x085E, 0x085E}, {0x08A0, 0x08B4}, {0x08B6, 0x08BD},
+ {0x08D4, 0x08E1}, {0x08E2, 0x08E2}, {0x08E3, 0x08FF},
+ {0x0900, 0x0902}, {0x0903, 0x0903}, {0x0904, 0x0939},
+ {0x093A, 0x093A}, {0x093B, 0x093B}, {0x093C, 0x093C},
+ {0x093D, 0x093D}, {0x093E, 0x0940}, {0x0941, 0x0948},
+ {0x0949, 0x094C}, {0x094D, 0x094D}, {0x094E, 0x094F},
+ {0x0950, 0x0950}, {0x0951, 0x0957}, {0x0958, 0x0961},
+ {0x0962, 0x0963}, {0x0964, 0x0965}, {0x0966, 0x096F},
+ {0x0970, 0x0970}, {0x0971, 0x0971}, {0x0972, 0x097F},
+ {0x0980, 0x0980}, {0x0981, 0x0981}, {0x0982, 0x0983},
+ {0x0985, 0x098C}, {0x098F, 0x0990}, {0x0993, 0x09A8},
+ {0x09AA, 0x09B0}, {0x09B2, 0x09B2}, {0x09B6, 0x09B9},
+ {0x09BC, 0x09BC}, {0x09BD, 0x09BD}, {0x09BE, 0x09C0},
+ {0x09C1, 0x09C4}, {0x09C7, 0x09C8}, {0x09CB, 0x09CC},
+ {0x09CD, 0x09CD}, {0x09CE, 0x09CE}, {0x09D7, 0x09D7},
+ {0x09DC, 0x09DD}, {0x09DF, 0x09E1}, {0x09E2, 0x09E3},
+ {0x09E6, 0x09EF}, {0x09F0, 0x09F1}, {0x09F2, 0x09F3},
+ {0x09F4, 0x09F9}, {0x09FA, 0x09FA}, {0x09FB, 0x09FB},
+ {0x0A01, 0x0A02}, {0x0A03, 0x0A03}, {0x0A05, 0x0A0A},
+ {0x0A0F, 0x0A10}, {0x0A13, 0x0A28}, {0x0A2A, 0x0A30},
+ {0x0A32, 0x0A33}, {0x0A35, 0x0A36}, {0x0A38, 0x0A39},
+ {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A40}, {0x0A41, 0x0A42},
+ {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51},
+ {0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E}, {0x0A66, 0x0A6F},
+ {0x0A70, 0x0A71}, {0x0A72, 0x0A74}, {0x0A75, 0x0A75},
+ {0x0A81, 0x0A82}, {0x0A83, 0x0A83}, {0x0A85, 0x0A8D},
+ {0x0A8F, 0x0A91}, {0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0},
+ {0x0AB2, 0x0AB3}, {0x0AB5, 0x0AB9}, {0x0ABC, 0x0ABC},
+ {0x0ABD, 0x0ABD}, {0x0ABE, 0x0AC0}, {0x0AC1, 0x0AC5},
+ {0x0AC7, 0x0AC8}, {0x0AC9, 0x0AC9}, {0x0ACB, 0x0ACC},
+ {0x0ACD, 0x0ACD}, {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE1},
+ {0x0AE2, 0x0AE3}, {0x0AE6, 0x0AEF}, {0x0AF0, 0x0AF0},
+ {0x0AF1, 0x0AF1}, {0x0AF9, 0x0AF9}, {0x0B01, 0x0B01},
+ {0x0B02, 0x0B03}, {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10},
+ {0x0B13, 0x0B28}, {0x0B2A, 0x0B30}, {0x0B32, 0x0B33},
+ {0x0B35, 0x0B39}, {0x0B3C, 0x0B3C}, {0x0B3D, 0x0B3D},
+ {0x0B3E, 0x0B3E}, {0x0B3F, 0x0B3F}, {0x0B40, 0x0B40},
+ {0x0B41, 0x0B44}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4C},
+ {0x0B4D, 0x0B4D}, {0x0B56, 0x0B56}, {0x0B57, 0x0B57},
+ {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B61}, {0x0B62, 0x0B63},
+ {0x0B66, 0x0B6F}, {0x0B70, 0x0B70}, {0x0B71, 0x0B71},
+ {0x0B72, 0x0B77}, {0x0B82, 0x0B82}, {0x0B83, 0x0B83},
+ {0x0B85, 0x0B8A}, {0x0B8E, 0x0B90}, {0x0B92, 0x0B95},
+ {0x0B99, 0x0B9A}, {0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F},
+ {0x0BA3, 0x0BA4}, {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9},
+ {0x0BBE, 0x0BBF}, {0x0BC0, 0x0BC0}, {0x0BC1, 0x0BC2},
+ {0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCC}, {0x0BCD, 0x0BCD},
+ {0x0BD0, 0x0BD0}, {0x0BD7, 0x0BD7}, {0x0BE6, 0x0BEF},
+ {0x0BF0, 0x0BF2}, {0x0BF3, 0x0BF8}, {0x0BF9, 0x0BF9},
+ {0x0BFA, 0x0BFA}, {0x0C00, 0x0C00}, {0x0C01, 0x0C03},
+ {0x0C05, 0x0C0C}, {0x0C0E, 0x0C10}, {0x0C12, 0x0C28},
+ {0x0C2A, 0x0C39}, {0x0C3D, 0x0C3D}, {0x0C3E, 0x0C40},
+ {0x0C41, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D},
+ {0x0C55, 0x0C56}, {0x0C58, 0x0C5A}, {0x0C60, 0x0C61},
+ {0x0C62, 0x0C63}, {0x0C66, 0x0C6F}, {0x0C78, 0x0C7E},
+ {0x0C7F, 0x0C7F}, {0x0C80, 0x0C80}, {0x0C81, 0x0C81},
+ {0x0C82, 0x0C83}, {0x0C85, 0x0C8C}, {0x0C8E, 0x0C90},
+ {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9},
+ {0x0CBC, 0x0CBC}, {0x0CBD, 0x0CBD}, {0x0CBE, 0x0CBE},
+ {0x0CBF, 0x0CBF}, {0x0CC0, 0x0CC4}, {0x0CC6, 0x0CC6},
+ {0x0CC7, 0x0CC8}, {0x0CCA, 0x0CCB}, {0x0CCC, 0x0CCD},
+ {0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE1},
+ {0x0CE2, 0x0CE3}, {0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2},
+ {0x0D01, 0x0D01}, {0x0D02, 0x0D03}, {0x0D05, 0x0D0C},
+ {0x0D0E, 0x0D10}, {0x0D12, 0x0D3A}, {0x0D3D, 0x0D3D},
+ {0x0D3E, 0x0D40}, {0x0D41, 0x0D44}, {0x0D46, 0x0D48},
+ {0x0D4A, 0x0D4C}, {0x0D4D, 0x0D4D}, {0x0D4E, 0x0D4E},
+ {0x0D4F, 0x0D4F}, {0x0D54, 0x0D56}, {0x0D57, 0x0D57},
+ {0x0D58, 0x0D5E}, {0x0D5F, 0x0D61}, {0x0D62, 0x0D63},
+ {0x0D66, 0x0D6F}, {0x0D70, 0x0D78}, {0x0D79, 0x0D79},
+ {0x0D7A, 0x0D7F}, {0x0D82, 0x0D83}, {0x0D85, 0x0D96},
+ {0x0D9A, 0x0DB1}, {0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD},
+ {0x0DC0, 0x0DC6}, {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD1},
+ {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0DD8, 0x0DDF},
+ {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF3}, {0x0DF4, 0x0DF4},
+ {0x0E01, 0x0E30}, {0x0E31, 0x0E31}, {0x0E32, 0x0E33},
+ {0x0E34, 0x0E3A}, {0x0E3F, 0x0E3F}, {0x0E40, 0x0E45},
+ {0x0E46, 0x0E46}, {0x0E47, 0x0E4E}, {0x0E4F, 0x0E4F},
+ {0x0E50, 0x0E59}, {0x0E5A, 0x0E5B}, {0x0E81, 0x0E82},
+ {0x0E84, 0x0E84}, {0x0E87, 0x0E88}, {0x0E8A, 0x0E8A},
+ {0x0E8D, 0x0E8D}, {0x0E94, 0x0E97}, {0x0E99, 0x0E9F},
+ {0x0EA1, 0x0EA3}, {0x0EA5, 0x0EA5}, {0x0EA7, 0x0EA7},
+ {0x0EAA, 0x0EAB}, {0x0EAD, 0x0EB0}, {0x0EB1, 0x0EB1},
+ {0x0EB2, 0x0EB3}, {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC},
+ {0x0EBD, 0x0EBD}, {0x0EC0, 0x0EC4}, {0x0EC6, 0x0EC6},
+ {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9}, {0x0EDC, 0x0EDF},
+ {0x0F00, 0x0F00}, {0x0F01, 0x0F03}, {0x0F04, 0x0F12},
+ {0x0F13, 0x0F13}, {0x0F14, 0x0F14}, {0x0F15, 0x0F17},
+ {0x0F18, 0x0F19}, {0x0F1A, 0x0F1F}, {0x0F20, 0x0F29},
+ {0x0F2A, 0x0F33}, {0x0F34, 0x0F34}, {0x0F35, 0x0F35},
+ {0x0F36, 0x0F36}, {0x0F37, 0x0F37}, {0x0F38, 0x0F38},
+ {0x0F39, 0x0F39}, {0x0F3A, 0x0F3A}, {0x0F3B, 0x0F3B},
+ {0x0F3C, 0x0F3C}, {0x0F3D, 0x0F3D}, {0x0F3E, 0x0F3F},
+ {0x0F40, 0x0F47}, {0x0F49, 0x0F6C}, {0x0F71, 0x0F7E},
+ {0x0F7F, 0x0F7F}, {0x0F80, 0x0F84}, {0x0F85, 0x0F85},
+ {0x0F86, 0x0F87}, {0x0F88, 0x0F8C}, {0x0F8D, 0x0F97},
+ {0x0F99, 0x0FBC}, {0x0FBE, 0x0FC5}, {0x0FC6, 0x0FC6},
+ {0x0FC7, 0x0FCC}, {0x0FCE, 0x0FCF}, {0x0FD0, 0x0FD4},
+ {0x0FD5, 0x0FD8}, {0x0FD9, 0x0FDA}, {0x1000, 0x102A},
+ {0x102B, 0x102C}, {0x102D, 0x1030}, {0x1031, 0x1031},
+ {0x1032, 0x1037}, {0x1038, 0x1038}, {0x1039, 0x103A},
+ {0x103B, 0x103C}, {0x103D, 0x103E}, {0x103F, 0x103F},
+ {0x1040, 0x1049}, {0x104A, 0x104F}, {0x1050, 0x1055},
+ {0x1056, 0x1057}, {0x1058, 0x1059}, {0x105A, 0x105D},
+ {0x105E, 0x1060}, {0x1061, 0x1061}, {0x1062, 0x1064},
+ {0x1065, 0x1066}, {0x1067, 0x106D}, {0x106E, 0x1070},
+ {0x1071, 0x1074}, {0x1075, 0x1081}, {0x1082, 0x1082},
+ {0x1083, 0x1084}, {0x1085, 0x1086}, {0x1087, 0x108C},
+ {0x108D, 0x108D}, {0x108E, 0x108E}, {0x108F, 0x108F},
+ {0x1090, 0x1099}, {0x109A, 0x109C}, {0x109D, 0x109D},
+ {0x109E, 0x109F}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7},
+ {0x10CD, 0x10CD}, {0x10D0, 0x10FA}, {0x10FB, 0x10FB},
+ {0x10FC, 0x10FC}, {0x10FD, 0x10FF}, {0x1160, 0x11FF},
+ {0x1200, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256},
+ {0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288},
+ {0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5},
+ {0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5},
+ {0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315},
+ {0x1318, 0x135A}, {0x135D, 0x135F}, {0x1360, 0x1368},
+ {0x1369, 0x137C}, {0x1380, 0x138F}, {0x1390, 0x1399},
+ {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1400, 0x1400},
+ {0x1401, 0x166C}, {0x166D, 0x166E}, {0x166F, 0x167F},
+ {0x1680, 0x1680}, {0x1681, 0x169A}, {0x169B, 0x169B},
+ {0x169C, 0x169C}, {0x16A0, 0x16EA}, {0x16EB, 0x16ED},
+ {0x16EE, 0x16F0}, {0x16F1, 0x16F8}, {0x1700, 0x170C},
+ {0x170E, 0x1711}, {0x1712, 0x1714}, {0x1720, 0x1731},
+ {0x1732, 0x1734}, {0x1735, 0x1736}, {0x1740, 0x1751},
+ {0x1752, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770},
+ {0x1772, 0x1773}, {0x1780, 0x17B3}, {0x17B4, 0x17B5},
+ {0x17B6, 0x17B6}, {0x17B7, 0x17BD}, {0x17BE, 0x17C5},
+ {0x17C6, 0x17C6}, {0x17C7, 0x17C8}, {0x17C9, 0x17D3},
+ {0x17D4, 0x17D6}, {0x17D7, 0x17D7}, {0x17D8, 0x17DA},
+ {0x17DB, 0x17DB}, {0x17DC, 0x17DC}, {0x17DD, 0x17DD},
+ {0x17E0, 0x17E9}, {0x17F0, 0x17F9}, {0x1800, 0x1805},
+ {0x1806, 0x1806}, {0x1807, 0x180A}, {0x180B, 0x180D},
+ {0x180E, 0x180E}, {0x1810, 0x1819}, {0x1820, 0x1842},
+ {0x1843, 0x1843}, {0x1844, 0x1877}, {0x1880, 0x1884},
+ {0x1885, 0x1886}, {0x1887, 0x18A8}, {0x18A9, 0x18A9},
+ {0x18AA, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E},
+ {0x1920, 0x1922}, {0x1923, 0x1926}, {0x1927, 0x1928},
+ {0x1929, 0x192B}, {0x1930, 0x1931}, {0x1932, 0x1932},
+ {0x1933, 0x1938}, {0x1939, 0x193B}, {0x1940, 0x1940},
+ {0x1944, 0x1945}, {0x1946, 0x194F}, {0x1950, 0x196D},
+ {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9},
+ {0x19D0, 0x19D9}, {0x19DA, 0x19DA}, {0x19DE, 0x19DF},
+ {0x19E0, 0x19FF}, {0x1A00, 0x1A16}, {0x1A17, 0x1A18},
+ {0x1A19, 0x1A1A}, {0x1A1B, 0x1A1B}, {0x1A1E, 0x1A1F},
+ {0x1A20, 0x1A54}, {0x1A55, 0x1A55}, {0x1A56, 0x1A56},
+ {0x1A57, 0x1A57}, {0x1A58, 0x1A5E}, {0x1A60, 0x1A60},
+ {0x1A61, 0x1A61}, {0x1A62, 0x1A62}, {0x1A63, 0x1A64},
+ {0x1A65, 0x1A6C}, {0x1A6D, 0x1A72}, {0x1A73, 0x1A7C},
+ {0x1A7F, 0x1A7F}, {0x1A80, 0x1A89}, {0x1A90, 0x1A99},
+ {0x1AA0, 0x1AA6}, {0x1AA7, 0x1AA7}, {0x1AA8, 0x1AAD},
+ {0x1AB0, 0x1ABD}, {0x1ABE, 0x1ABE}, {0x1B00, 0x1B03},
+ {0x1B04, 0x1B04}, {0x1B05, 0x1B33}, {0x1B34, 0x1B34},
+ {0x1B35, 0x1B35}, {0x1B36, 0x1B3A}, {0x1B3B, 0x1B3B},
+ {0x1B3C, 0x1B3C}, {0x1B3D, 0x1B41}, {0x1B42, 0x1B42},
+ {0x1B43, 0x1B44}, {0x1B45, 0x1B4B}, {0x1B50, 0x1B59},
+ {0x1B5A, 0x1B60}, {0x1B61, 0x1B6A}, {0x1B6B, 0x1B73},
+ {0x1B74, 0x1B7C}, {0x1B80, 0x1B81}, {0x1B82, 0x1B82},
+ {0x1B83, 0x1BA0}, {0x1BA1, 0x1BA1}, {0x1BA2, 0x1BA5},
+ {0x1BA6, 0x1BA7}, {0x1BA8, 0x1BA9}, {0x1BAA, 0x1BAA},
+ {0x1BAB, 0x1BAD}, {0x1BAE, 0x1BAF}, {0x1BB0, 0x1BB9},
+ {0x1BBA, 0x1BBF}, {0x1BC0, 0x1BE5}, {0x1BE6, 0x1BE6},
+ {0x1BE7, 0x1BE7}, {0x1BE8, 0x1BE9}, {0x1BEA, 0x1BEC},
+ {0x1BED, 0x1BED}, {0x1BEE, 0x1BEE}, {0x1BEF, 0x1BF1},
+ {0x1BF2, 0x1BF3}, {0x1BFC, 0x1BFF}, {0x1C00, 0x1C23},
+ {0x1C24, 0x1C2B}, {0x1C2C, 0x1C33}, {0x1C34, 0x1C35},
+ {0x1C36, 0x1C37}, {0x1C3B, 0x1C3F}, {0x1C40, 0x1C49},
+ {0x1C4D, 0x1C4F}, {0x1C50, 0x1C59}, {0x1C5A, 0x1C77},
+ {0x1C78, 0x1C7D}, {0x1C7E, 0x1C7F}, {0x1C80, 0x1C88},
+ {0x1CC0, 0x1CC7}, {0x1CD0, 0x1CD2}, {0x1CD3, 0x1CD3},
+ {0x1CD4, 0x1CE0}, {0x1CE1, 0x1CE1}, {0x1CE2, 0x1CE8},
+ {0x1CE9, 0x1CEC}, {0x1CED, 0x1CED}, {0x1CEE, 0x1CF1},
+ {0x1CF2, 0x1CF3}, {0x1CF4, 0x1CF4}, {0x1CF5, 0x1CF6},
+ {0x1CF8, 0x1CF9}, {0x1D00, 0x1D2B}, {0x1D2C, 0x1D6A},
+ {0x1D6B, 0x1D77}, {0x1D78, 0x1D78}, {0x1D79, 0x1D7F},
+ {0x1D80, 0x1D9A}, {0x1D9B, 0x1DBF}, {0x1DC0, 0x1DF5},
+ {0x1DFB, 0x1DFF}, {0x1E00, 0x1EFF}, {0x1F00, 0x1F15},
+ {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D},
+ {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B},
+ {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4},
+ {0x1FB6, 0x1FBC}, {0x1FBD, 0x1FBD}, {0x1FBE, 0x1FBE},
+ {0x1FBF, 0x1FC1}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC},
+ {0x1FCD, 0x1FCF}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB},
+ {0x1FDD, 0x1FDF}, {0x1FE0, 0x1FEC}, {0x1FED, 0x1FEF},
+ {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x1FFD, 0x1FFE},
+ {0x2000, 0x200A}, {0x200B, 0x200F}, {0x2011, 0x2012},
+ {0x2017, 0x2017}, {0x201A, 0x201A}, {0x201B, 0x201B},
+ {0x201E, 0x201E}, {0x201F, 0x201F}, {0x2023, 0x2023},
+ {0x2028, 0x2028}, {0x2029, 0x2029}, {0x202A, 0x202E},
+ {0x202F, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034},
+ {0x2036, 0x2038}, {0x2039, 0x2039}, {0x203A, 0x203A},
+ {0x203C, 0x203D}, {0x203F, 0x2040}, {0x2041, 0x2043},
+ {0x2044, 0x2044}, {0x2045, 0x2045}, {0x2046, 0x2046},
+ {0x2047, 0x2051}, {0x2052, 0x2052}, {0x2053, 0x2053},
+ {0x2054, 0x2054}, {0x2055, 0x205E}, {0x205F, 0x205F},
+ {0x2060, 0x2064}, {0x2066, 0x206F}, {0x2070, 0x2070},
+ {0x2071, 0x2071}, {0x2075, 0x2079}, {0x207A, 0x207C},
+ {0x207D, 0x207D}, {0x207E, 0x207E}, {0x2080, 0x2080},
+ {0x2085, 0x2089}, {0x208A, 0x208C}, {0x208D, 0x208D},
+ {0x208E, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8},
+ {0x20AA, 0x20AB}, {0x20AD, 0x20BE}, {0x20D0, 0x20DC},
+ {0x20DD, 0x20E0}, {0x20E1, 0x20E1}, {0x20E2, 0x20E4},
+ {0x20E5, 0x20F0}, {0x2100, 0x2101}, {0x2102, 0x2102},
+ {0x2104, 0x2104}, {0x2106, 0x2106}, {0x2107, 0x2107},
+ {0x2108, 0x2108}, {0x210A, 0x2112}, {0x2114, 0x2114},
+ {0x2115, 0x2115}, {0x2117, 0x2117}, {0x2118, 0x2118},
+ {0x2119, 0x211D}, {0x211E, 0x2120}, {0x2123, 0x2123},
+ {0x2124, 0x2124}, {0x2125, 0x2125}, {0x2127, 0x2127},
+ {0x2128, 0x2128}, {0x2129, 0x2129}, {0x212A, 0x212A},
+ {0x212C, 0x212D}, {0x212E, 0x212E}, {0x212F, 0x2134},
+ {0x2135, 0x2138}, {0x2139, 0x2139}, {0x213A, 0x213B},
+ {0x213C, 0x213F}, {0x2140, 0x2144}, {0x2145, 0x2149},
+ {0x214A, 0x214A}, {0x214B, 0x214B}, {0x214C, 0x214D},
+ {0x214E, 0x214E}, {0x214F, 0x214F}, {0x2150, 0x2152},
+ {0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F},
+ {0x217A, 0x2182}, {0x2183, 0x2184}, {0x2185, 0x2188},
+ {0x218A, 0x218B}, {0x219A, 0x219B}, {0x219C, 0x219F},
+ {0x21A0, 0x21A0}, {0x21A1, 0x21A2}, {0x21A3, 0x21A3},
+ {0x21A4, 0x21A5}, {0x21A6, 0x21A6}, {0x21A7, 0x21AD},
+ {0x21AE, 0x21AE}, {0x21AF, 0x21B7}, {0x21BA, 0x21CD},
+ {0x21CE, 0x21CF}, {0x21D0, 0x21D1}, {0x21D3, 0x21D3},
+ {0x21D5, 0x21E6}, {0x21E8, 0x21F3}, {0x21F4, 0x21FF},
+ {0x2201, 0x2201}, {0x2204, 0x2206}, {0x2209, 0x220A},
+ {0x220C, 0x220E}, {0x2210, 0x2210}, {0x2212, 0x2214},
+ {0x2216, 0x2219}, {0x221B, 0x221C}, {0x2221, 0x2222},
+ {0x2224, 0x2224}, {0x2226, 0x2226}, {0x222D, 0x222D},
+ {0x222F, 0x2233}, {0x2238, 0x223B}, {0x223E, 0x2247},
+ {0x2249, 0x224B}, {0x224D, 0x2251}, {0x2253, 0x225F},
+ {0x2262, 0x2263}, {0x2268, 0x2269}, {0x226C, 0x226D},
+ {0x2270, 0x2281}, {0x2284, 0x2285}, {0x2288, 0x2294},
+ {0x2296, 0x2298}, {0x229A, 0x22A4}, {0x22A6, 0x22BE},
+ {0x22C0, 0x22FF}, {0x2300, 0x2307}, {0x2308, 0x2308},
+ {0x2309, 0x2309}, {0x230A, 0x230A}, {0x230B, 0x230B},
+ {0x230C, 0x2311}, {0x2313, 0x2319}, {0x231C, 0x231F},
+ {0x2320, 0x2321}, {0x2322, 0x2328}, {0x232B, 0x237B},
+ {0x237C, 0x237C}, {0x237D, 0x239A}, {0x239B, 0x23B3},
+ {0x23B4, 0x23DB}, {0x23DC, 0x23E1}, {0x23E2, 0x23E8},
+ {0x23ED, 0x23EF}, {0x23F1, 0x23F2}, {0x23F4, 0x23FE},
+ {0x2400, 0x2426}, {0x2440, 0x244A}, {0x24EA, 0x24EA},
+ {0x254C, 0x254F}, {0x2574, 0x257F}, {0x2590, 0x2591},
+ {0x2596, 0x259F}, {0x25A2, 0x25A2}, {0x25AA, 0x25B1},
+ {0x25B4, 0x25B5}, {0x25B8, 0x25BB}, {0x25BE, 0x25BF},
+ {0x25C2, 0x25C5}, {0x25C9, 0x25CA}, {0x25CC, 0x25CD},
+ {0x25D2, 0x25E1}, {0x25E6, 0x25EE}, {0x25F0, 0x25F7},
+ {0x25F8, 0x25FC}, {0x25FF, 0x25FF}, {0x2600, 0x2604},
+ {0x2607, 0x2608}, {0x260A, 0x260D}, {0x2610, 0x2613},
+ {0x2616, 0x261B}, {0x261D, 0x261D}, {0x261F, 0x263F},
+ {0x2641, 0x2641}, {0x2643, 0x2647}, {0x2654, 0x265F},
+ {0x2662, 0x2662}, {0x2666, 0x2666}, {0x266B, 0x266B},
+ {0x266E, 0x266E}, {0x2670, 0x267E}, {0x2680, 0x2692},
+ {0x2694, 0x269D}, {0x26A0, 0x26A0}, {0x26A2, 0x26A9},
+ {0x26AC, 0x26BC}, {0x26C0, 0x26C3}, {0x26E2, 0x26E2},
+ {0x26E4, 0x26E7}, {0x2700, 0x2704}, {0x2706, 0x2709},
+ {0x270C, 0x2727}, {0x2729, 0x273C}, {0x273E, 0x274B},
+ {0x274D, 0x274D}, {0x274F, 0x2752}, {0x2756, 0x2756},
+ {0x2758, 0x2767}, {0x2768, 0x2768}, {0x2769, 0x2769},
+ {0x276A, 0x276A}, {0x276B, 0x276B}, {0x276C, 0x276C},
+ {0x276D, 0x276D}, {0x276E, 0x276E}, {0x276F, 0x276F},
+ {0x2770, 0x2770}, {0x2771, 0x2771}, {0x2772, 0x2772},
+ {0x2773, 0x2773}, {0x2774, 0x2774}, {0x2775, 0x2775},
+ {0x2780, 0x2793}, {0x2794, 0x2794}, {0x2798, 0x27AF},
+ {0x27B1, 0x27BE}, {0x27C0, 0x27C4}, {0x27C5, 0x27C5},
+ {0x27C6, 0x27C6}, {0x27C7, 0x27E5}, {0x27EE, 0x27EE},
+ {0x27EF, 0x27EF}, {0x27F0, 0x27FF}, {0x2800, 0x28FF},
+ {0x2900, 0x297F}, {0x2980, 0x2982}, {0x2983, 0x2983},
+ {0x2984, 0x2984}, {0x2987, 0x2987}, {0x2988, 0x2988},
+ {0x2989, 0x2989}, {0x298A, 0x298A}, {0x298B, 0x298B},
+ {0x298C, 0x298C}, {0x298D, 0x298D}, {0x298E, 0x298E},
+ {0x298F, 0x298F}, {0x2990, 0x2990}, {0x2991, 0x2991},
+ {0x2992, 0x2992}, {0x2993, 0x2993}, {0x2994, 0x2994},
+ {0x2995, 0x2995}, {0x2996, 0x2996}, {0x2997, 0x2997},
+ {0x2998, 0x2998}, {0x2999, 0x29D7}, {0x29D8, 0x29D8},
+ {0x29D9, 0x29D9}, {0x29DA, 0x29DA}, {0x29DB, 0x29DB},
+ {0x29DC, 0x29FB}, {0x29FC, 0x29FC}, {0x29FD, 0x29FD},
+ {0x29FE, 0x29FF}, {0x2A00, 0x2AFF}, {0x2B00, 0x2B1A},
+ {0x2B1D, 0x2B2F}, {0x2B30, 0x2B44}, {0x2B45, 0x2B46},
+ {0x2B47, 0x2B4C}, {0x2B4D, 0x2B4F}, {0x2B51, 0x2B54},
+ {0x2B5A, 0x2B73}, {0x2B76, 0x2B95}, {0x2B98, 0x2BB9},
+ {0x2BBD, 0x2BC8}, {0x2BCA, 0x2BD1}, {0x2BEC, 0x2BEF},
+ {0x2C00, 0x2C2E}, {0x2C30, 0x2C5E}, {0x2C60, 0x2C7B},
+ {0x2C7C, 0x2C7D}, {0x2C7E, 0x2C7F}, {0x2C80, 0x2CE4},
+ {0x2CE5, 0x2CEA}, {0x2CEB, 0x2CEE}, {0x2CEF, 0x2CF1},
+ {0x2CF2, 0x2CF3}, {0x2CF9, 0x2CFC}, {0x2CFD, 0x2CFD},
+ {0x2CFE, 0x2CFF}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27},
+ {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D6F},
+ {0x2D70, 0x2D70}, {0x2D7F, 0x2D7F}, {0x2D80, 0x2D96},
+ {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6},
+ {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE},
+ {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2DFF},
+ {0x2E00, 0x2E01}, {0x2E02, 0x2E02}, {0x2E03, 0x2E03},
+ {0x2E04, 0x2E04}, {0x2E05, 0x2E05}, {0x2E06, 0x2E08},
+ {0x2E09, 0x2E09}, {0x2E0A, 0x2E0A}, {0x2E0B, 0x2E0B},
+ {0x2E0C, 0x2E0C}, {0x2E0D, 0x2E0D}, {0x2E0E, 0x2E16},
+ {0x2E17, 0x2E17}, {0x2E18, 0x2E19}, {0x2E1A, 0x2E1A},
+ {0x2E1B, 0x2E1B}, {0x2E1C, 0x2E1C}, {0x2E1D, 0x2E1D},
+ {0x2E1E, 0x2E1F}, {0x2E20, 0x2E20}, {0x2E21, 0x2E21},
+ {0x2E22, 0x2E22}, {0x2E23, 0x2E23}, {0x2E24, 0x2E24},
+ {0x2E25, 0x2E25}, {0x2E26, 0x2E26}, {0x2E27, 0x2E27},
+ {0x2E28, 0x2E28}, {0x2E29, 0x2E29}, {0x2E2A, 0x2E2E},
+ {0x2E2F, 0x2E2F}, {0x2E30, 0x2E39}, {0x2E3A, 0x2E3B},
+ {0x2E3C, 0x2E3F}, {0x2E40, 0x2E40}, {0x2E41, 0x2E41},
+ {0x2E42, 0x2E42}, {0x2E43, 0x2E44}, {0x303F, 0x303F},
+ {0x4DC0, 0x4DFF}, {0xA4D0, 0xA4F7}, {0xA4F8, 0xA4FD},
+ {0xA4FE, 0xA4FF}, {0xA500, 0xA60B}, {0xA60C, 0xA60C},
+ {0xA60D, 0xA60F}, {0xA610, 0xA61F}, {0xA620, 0xA629},
+ {0xA62A, 0xA62B}, {0xA640, 0xA66D}, {0xA66E, 0xA66E},
+ {0xA66F, 0xA66F}, {0xA670, 0xA672}, {0xA673, 0xA673},
+ {0xA674, 0xA67D}, {0xA67E, 0xA67E}, {0xA67F, 0xA67F},
+ {0xA680, 0xA69B}, {0xA69C, 0xA69D}, {0xA69E, 0xA69F},
+ {0xA6A0, 0xA6E5}, {0xA6E6, 0xA6EF}, {0xA6F0, 0xA6F1},
+ {0xA6F2, 0xA6F7}, {0xA700, 0xA716}, {0xA717, 0xA71F},
+ {0xA720, 0xA721}, {0xA722, 0xA76F}, {0xA770, 0xA770},
+ {0xA771, 0xA787}, {0xA788, 0xA788}, {0xA789, 0xA78A},
+ {0xA78B, 0xA78E}, {0xA78F, 0xA78F}, {0xA790, 0xA7AE},
+ {0xA7B0, 0xA7B7}, {0xA7F7, 0xA7F7}, {0xA7F8, 0xA7F9},
+ {0xA7FA, 0xA7FA}, {0xA7FB, 0xA7FF}, {0xA800, 0xA801},
+ {0xA802, 0xA802}, {0xA803, 0xA805}, {0xA806, 0xA806},
+ {0xA807, 0xA80A}, {0xA80B, 0xA80B}, {0xA80C, 0xA822},
+ {0xA823, 0xA824}, {0xA825, 0xA826}, {0xA827, 0xA827},
+ {0xA828, 0xA82B}, {0xA830, 0xA835}, {0xA836, 0xA837},
+ {0xA838, 0xA838}, {0xA839, 0xA839}, {0xA840, 0xA873},
+ {0xA874, 0xA877}, {0xA880, 0xA881}, {0xA882, 0xA8B3},
+ {0xA8B4, 0xA8C3}, {0xA8C4, 0xA8C5}, {0xA8CE, 0xA8CF},
+ {0xA8D0, 0xA8D9}, {0xA8E0, 0xA8F1}, {0xA8F2, 0xA8F7},
+ {0xA8F8, 0xA8FA}, {0xA8FB, 0xA8FB}, {0xA8FC, 0xA8FC},
+ {0xA8FD, 0xA8FD}, {0xA900, 0xA909}, {0xA90A, 0xA925},
+ {0xA926, 0xA92D}, {0xA92E, 0xA92F}, {0xA930, 0xA946},
+ {0xA947, 0xA951}, {0xA952, 0xA953}, {0xA95F, 0xA95F},
+ {0xA980, 0xA982}, {0xA983, 0xA983}, {0xA984, 0xA9B2},
+ {0xA9B3, 0xA9B3}, {0xA9B4, 0xA9B5}, {0xA9B6, 0xA9B9},
+ {0xA9BA, 0xA9BB}, {0xA9BC, 0xA9BC}, {0xA9BD, 0xA9C0},
+ {0xA9C1, 0xA9CD}, {0xA9CF, 0xA9CF}, {0xA9D0, 0xA9D9},
+ {0xA9DE, 0xA9DF}, {0xA9E0, 0xA9E4}, {0xA9E5, 0xA9E5},
+ {0xA9E6, 0xA9E6}, {0xA9E7, 0xA9EF}, {0xA9F0, 0xA9F9},
+ {0xA9FA, 0xA9FE}, {0xAA00, 0xAA28}, {0xAA29, 0xAA2E},
+ {0xAA2F, 0xAA30}, {0xAA31, 0xAA32}, {0xAA33, 0xAA34},
+ {0xAA35, 0xAA36}, {0xAA40, 0xAA42}, {0xAA43, 0xAA43},
+ {0xAA44, 0xAA4B}, {0xAA4C, 0xAA4C}, {0xAA4D, 0xAA4D},
+ {0xAA50, 0xAA59}, {0xAA5C, 0xAA5F}, {0xAA60, 0xAA6F},
+ {0xAA70, 0xAA70}, {0xAA71, 0xAA76}, {0xAA77, 0xAA79},
+ {0xAA7A, 0xAA7A}, {0xAA7B, 0xAA7B}, {0xAA7C, 0xAA7C},
+ {0xAA7D, 0xAA7D}, {0xAA7E, 0xAA7F}, {0xAA80, 0xAAAF},
+ {0xAAB0, 0xAAB0}, {0xAAB1, 0xAAB1}, {0xAAB2, 0xAAB4},
+ {0xAAB5, 0xAAB6}, {0xAAB7, 0xAAB8}, {0xAAB9, 0xAABD},
+ {0xAABE, 0xAABF}, {0xAAC0, 0xAAC0}, {0xAAC1, 0xAAC1},
+ {0xAAC2, 0xAAC2}, {0xAADB, 0xAADC}, {0xAADD, 0xAADD},
+ {0xAADE, 0xAADF}, {0xAAE0, 0xAAEA}, {0xAAEB, 0xAAEB},
+ {0xAAEC, 0xAAED}, {0xAAEE, 0xAAEF}, {0xAAF0, 0xAAF1},
+ {0xAAF2, 0xAAF2}, {0xAAF3, 0xAAF4}, {0xAAF5, 0xAAF5},
+ {0xAAF6, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E},
+ {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E},
+ {0xAB30, 0xAB5A}, {0xAB5B, 0xAB5B}, {0xAB5C, 0xAB5F},
+ {0xAB60, 0xAB65}, {0xAB70, 0xABBF}, {0xABC0, 0xABE2},
+ {0xABE3, 0xABE4}, {0xABE5, 0xABE5}, {0xABE6, 0xABE7},
+ {0xABE8, 0xABE8}, {0xABE9, 0xABEA}, {0xABEB, 0xABEB},
+ {0xABEC, 0xABEC}, {0xABED, 0xABED}, {0xABF0, 0xABF9},
+ {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDB7F},
+ {0xDB80, 0xDBFF}, {0xDC00, 0xDFFF}, {0xFB00, 0xFB06},
+ {0xFB13, 0xFB17}, {0xFB1D, 0xFB1D}, {0xFB1E, 0xFB1E},
+ {0xFB1F, 0xFB28}, {0xFB29, 0xFB29}, {0xFB2A, 0xFB36},
+ {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41},
+ {0xFB43, 0xFB44}, {0xFB46, 0xFB4F}, {0xFB50, 0xFBB1},
+ {0xFBB2, 0xFBC1}, {0xFBD3, 0xFD3D}, {0xFD3E, 0xFD3E},
+ {0xFD3F, 0xFD3F}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7},
+ {0xFDF0, 0xFDFB}, {0xFDFC, 0xFDFC}, {0xFDFD, 0xFDFD},
+ {0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC},
+ {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFC, 0xFFFC},
+ {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A},
+ {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D},
+ {0x10080, 0x100FA}, {0x10100, 0x10102}, {0x10107, 0x10133},
+ {0x10137, 0x1013F}, {0x10140, 0x10174}, {0x10175, 0x10178},
+ {0x10179, 0x10189}, {0x1018A, 0x1018B}, {0x1018C, 0x1018E},
+ {0x10190, 0x1019B}, {0x101A0, 0x101A0}, {0x101D0, 0x101FC},
+ {0x101FD, 0x101FD}, {0x10280, 0x1029C}, {0x102A0, 0x102D0},
+ {0x102E0, 0x102E0}, {0x102E1, 0x102FB}, {0x10300, 0x1031F},
+ {0x10320, 0x10323}, {0x10330, 0x10340}, {0x10341, 0x10341},
+ {0x10342, 0x10349}, {0x1034A, 0x1034A}, {0x10350, 0x10375},
+ {0x10376, 0x1037A}, {0x10380, 0x1039D}, {0x1039F, 0x1039F},
+ {0x103A0, 0x103C3}, {0x103C8, 0x103CF}, {0x103D0, 0x103D0},
+ {0x103D1, 0x103D5}, {0x10400, 0x1044F}, {0x10450, 0x1047F},
+ {0x10480, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3},
+ {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563},
+ {0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755},
+ {0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808},
+ {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C},
+ {0x1083F, 0x1083F}, {0x10840, 0x10855}, {0x10857, 0x10857},
+ {0x10858, 0x1085F}, {0x10860, 0x10876}, {0x10877, 0x10878},
+ {0x10879, 0x1087F}, {0x10880, 0x1089E}, {0x108A7, 0x108AF},
+ {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x108FF},
+ {0x10900, 0x10915}, {0x10916, 0x1091B}, {0x1091F, 0x1091F},
+ {0x10920, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x1099F},
+ {0x109A0, 0x109B7}, {0x109BC, 0x109BD}, {0x109BE, 0x109BF},
+ {0x109C0, 0x109CF}, {0x109D2, 0x109FF}, {0x10A00, 0x10A00},
+ {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F},
+ {0x10A10, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A33},
+ {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x10A40, 0x10A47},
+ {0x10A50, 0x10A58}, {0x10A60, 0x10A7C}, {0x10A7D, 0x10A7E},
+ {0x10A7F, 0x10A7F}, {0x10A80, 0x10A9C}, {0x10A9D, 0x10A9F},
+ {0x10AC0, 0x10AC7}, {0x10AC8, 0x10AC8}, {0x10AC9, 0x10AE4},
+ {0x10AE5, 0x10AE6}, {0x10AEB, 0x10AEF}, {0x10AF0, 0x10AF6},
+ {0x10B00, 0x10B35}, {0x10B39, 0x10B3F}, {0x10B40, 0x10B55},
+ {0x10B58, 0x10B5F}, {0x10B60, 0x10B72}, {0x10B78, 0x10B7F},
+ {0x10B80, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF},
+ {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2},
+ {0x10CFA, 0x10CFF}, {0x10E60, 0x10E7E}, {0x11000, 0x11000},
+ {0x11001, 0x11001}, {0x11002, 0x11002}, {0x11003, 0x11037},
+ {0x11038, 0x11046}, {0x11047, 0x1104D}, {0x11052, 0x11065},
+ {0x11066, 0x1106F}, {0x1107F, 0x1107F}, {0x11080, 0x11081},
+ {0x11082, 0x11082}, {0x11083, 0x110AF}, {0x110B0, 0x110B2},
+ {0x110B3, 0x110B6}, {0x110B7, 0x110B8}, {0x110B9, 0x110BA},
+ {0x110BB, 0x110BC}, {0x110BD, 0x110BD}, {0x110BE, 0x110C1},
+ {0x110D0, 0x110E8}, {0x110F0, 0x110F9}, {0x11100, 0x11102},
+ {0x11103, 0x11126}, {0x11127, 0x1112B}, {0x1112C, 0x1112C},
+ {0x1112D, 0x11134}, {0x11136, 0x1113F}, {0x11140, 0x11143},
+ {0x11150, 0x11172}, {0x11173, 0x11173}, {0x11174, 0x11175},
+ {0x11176, 0x11176}, {0x11180, 0x11181}, {0x11182, 0x11182},
+ {0x11183, 0x111B2}, {0x111B3, 0x111B5}, {0x111B6, 0x111BE},
+ {0x111BF, 0x111C0}, {0x111C1, 0x111C4}, {0x111C5, 0x111C9},
+ {0x111CA, 0x111CC}, {0x111CD, 0x111CD}, {0x111D0, 0x111D9},
+ {0x111DA, 0x111DA}, {0x111DB, 0x111DB}, {0x111DC, 0x111DC},
+ {0x111DD, 0x111DF}, {0x111E1, 0x111F4}, {0x11200, 0x11211},
+ {0x11213, 0x1122B}, {0x1122C, 0x1122E}, {0x1122F, 0x11231},
+ {0x11232, 0x11233}, {0x11234, 0x11234}, {0x11235, 0x11235},
+ {0x11236, 0x11237}, {0x11238, 0x1123D}, {0x1123E, 0x1123E},
+ {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D},
+ {0x1128F, 0x1129D}, {0x1129F, 0x112A8}, {0x112A9, 0x112A9},
+ {0x112B0, 0x112DE}, {0x112DF, 0x112DF}, {0x112E0, 0x112E2},
+ {0x112E3, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11301},
+ {0x11302, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310},
+ {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333},
+ {0x11335, 0x11339}, {0x1133C, 0x1133C}, {0x1133D, 0x1133D},
+ {0x1133E, 0x1133F}, {0x11340, 0x11340}, {0x11341, 0x11344},
+ {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11350, 0x11350},
+ {0x11357, 0x11357}, {0x1135D, 0x11361}, {0x11362, 0x11363},
+ {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11400, 0x11434},
+ {0x11435, 0x11437}, {0x11438, 0x1143F}, {0x11440, 0x11441},
+ {0x11442, 0x11444}, {0x11445, 0x11445}, {0x11446, 0x11446},
+ {0x11447, 0x1144A}, {0x1144B, 0x1144F}, {0x11450, 0x11459},
+ {0x1145B, 0x1145B}, {0x1145D, 0x1145D}, {0x11480, 0x114AF},
+ {0x114B0, 0x114B2}, {0x114B3, 0x114B8}, {0x114B9, 0x114B9},
+ {0x114BA, 0x114BA}, {0x114BB, 0x114BE}, {0x114BF, 0x114C0},
+ {0x114C1, 0x114C1}, {0x114C2, 0x114C3}, {0x114C4, 0x114C5},
+ {0x114C6, 0x114C6}, {0x114C7, 0x114C7}, {0x114D0, 0x114D9},
+ {0x11580, 0x115AE}, {0x115AF, 0x115B1}, {0x115B2, 0x115B5},
+ {0x115B8, 0x115BB}, {0x115BC, 0x115BD}, {0x115BE, 0x115BE},
+ {0x115BF, 0x115C0}, {0x115C1, 0x115D7}, {0x115D8, 0x115DB},
+ {0x115DC, 0x115DD}, {0x11600, 0x1162F}, {0x11630, 0x11632},
+ {0x11633, 0x1163A}, {0x1163B, 0x1163C}, {0x1163D, 0x1163D},
+ {0x1163E, 0x1163E}, {0x1163F, 0x11640}, {0x11641, 0x11643},
+ {0x11644, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C},
+ {0x11680, 0x116AA}, {0x116AB, 0x116AB}, {0x116AC, 0x116AC},
+ {0x116AD, 0x116AD}, {0x116AE, 0x116AF}, {0x116B0, 0x116B5},
+ {0x116B6, 0x116B6}, {0x116B7, 0x116B7}, {0x116C0, 0x116C9},
+ {0x11700, 0x11719}, {0x1171D, 0x1171F}, {0x11720, 0x11721},
+ {0x11722, 0x11725}, {0x11726, 0x11726}, {0x11727, 0x1172B},
+ {0x11730, 0x11739}, {0x1173A, 0x1173B}, {0x1173C, 0x1173E},
+ {0x1173F, 0x1173F}, {0x118A0, 0x118DF}, {0x118E0, 0x118E9},
+ {0x118EA, 0x118F2}, {0x118FF, 0x118FF}, {0x11AC0, 0x11AF8},
+ {0x11C00, 0x11C08}, {0x11C0A, 0x11C2E}, {0x11C2F, 0x11C2F},
+ {0x11C30, 0x11C36}, {0x11C38, 0x11C3D}, {0x11C3E, 0x11C3E},
+ {0x11C3F, 0x11C3F}, {0x11C40, 0x11C40}, {0x11C41, 0x11C45},
+ {0x11C50, 0x11C59}, {0x11C5A, 0x11C6C}, {0x11C70, 0x11C71},
+ {0x11C72, 0x11C8F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CA9},
+ {0x11CAA, 0x11CB0}, {0x11CB1, 0x11CB1}, {0x11CB2, 0x11CB3},
+ {0x11CB4, 0x11CB4}, {0x11CB5, 0x11CB6}, {0x12000, 0x12399},
+ {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543},
+ {0x13000, 0x1342E}, {0x14400, 0x14646}, {0x16800, 0x16A38},
+ {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16A6F},
+ {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF4}, {0x16AF5, 0x16AF5},
+ {0x16B00, 0x16B2F}, {0x16B30, 0x16B36}, {0x16B37, 0x16B3B},
+ {0x16B3C, 0x16B3F}, {0x16B40, 0x16B43}, {0x16B44, 0x16B44},
+ {0x16B45, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61},
+ {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16F00, 0x16F44},
+ {0x16F50, 0x16F50}, {0x16F51, 0x16F7E}, {0x16F8F, 0x16F92},
+ {0x16F93, 0x16F9F}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C},
+ {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BC9C},
+ {0x1BC9D, 0x1BC9E}, {0x1BC9F, 0x1BC9F}, {0x1BCA0, 0x1BCA3},
+ {0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D164},
+ {0x1D165, 0x1D166}, {0x1D167, 0x1D169}, {0x1D16A, 0x1D16C},
+ {0x1D16D, 0x1D172}, {0x1D173, 0x1D17A}, {0x1D17B, 0x1D182},
+ {0x1D183, 0x1D184}, {0x1D185, 0x1D18B}, {0x1D18C, 0x1D1A9},
+ {0x1D1AA, 0x1D1AD}, {0x1D1AE, 0x1D1E8}, {0x1D200, 0x1D241},
+ {0x1D242, 0x1D244}, {0x1D245, 0x1D245}, {0x1D300, 0x1D356},
+ {0x1D360, 0x1D371}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C},
+ {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6},
+ {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB},
+ {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A},
+ {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539},
+ {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546},
+ {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0},
+ {0x1D6C1, 0x1D6C1}, {0x1D6C2, 0x1D6DA}, {0x1D6DB, 0x1D6DB},
+ {0x1D6DC, 0x1D6FA}, {0x1D6FB, 0x1D6FB}, {0x1D6FC, 0x1D714},
+ {0x1D715, 0x1D715}, {0x1D716, 0x1D734}, {0x1D735, 0x1D735},
+ {0x1D736, 0x1D74E}, {0x1D74F, 0x1D74F}, {0x1D750, 0x1D76E},
+ {0x1D76F, 0x1D76F}, {0x1D770, 0x1D788}, {0x1D789, 0x1D789},
+ {0x1D78A, 0x1D7A8}, {0x1D7A9, 0x1D7A9}, {0x1D7AA, 0x1D7C2},
+ {0x1D7C3, 0x1D7C3}, {0x1D7C4, 0x1D7CB}, {0x1D7CE, 0x1D7FF},
+ {0x1D800, 0x1D9FF}, {0x1DA00, 0x1DA36}, {0x1DA37, 0x1DA3A},
+ {0x1DA3B, 0x1DA6C}, {0x1DA6D, 0x1DA74}, {0x1DA75, 0x1DA75},
+ {0x1DA76, 0x1DA83}, {0x1DA84, 0x1DA84}, {0x1DA85, 0x1DA86},
+ {0x1DA87, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF},
+ {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021},
+ {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E800, 0x1E8C4},
+ {0x1E8C7, 0x1E8CF}, {0x1E8D0, 0x1E8D6}, {0x1E900, 0x1E943},
+ {0x1E944, 0x1E94A}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F},
+ {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22},
+ {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32},
+ {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B},
+ {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49},
+ {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52},
+ {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59},
+ {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F},
+ {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A},
+ {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C},
+ {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B},
+ {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB},
+ {0x1EEF0, 0x1EEF1}, {0x1F000, 0x1F003}, {0x1F005, 0x1F02B},
+ {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF},
+ {0x1F0C1, 0x1F0CE}, {0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10C},
+ {0x1F12E, 0x1F12E}, {0x1F16A, 0x1F16B}, {0x1F1E6, 0x1F1FF},
+ {0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D},
+ {0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF},
+ {0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F},
+ {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A},
+ {0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594},
+ {0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F},
+ {0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6E0, 0x1F6EA},
+ {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F773}, {0x1F780, 0x1F7D4},
+ {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, {0x1F850, 0x1F859},
+ {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, {0xE0001, 0xE0001},
+ {0xE0020, 0xE007F},
+}
+
+// Condition have flag EastAsianWidth whether the current locale is CJK or not.
+type Condition struct {
+ EastAsianWidth bool
+}
+
+// NewCondition return new instance of Condition which is current locale.
+func NewCondition() *Condition {
+ return &Condition{EastAsianWidth}
+}
+
+// RuneWidth returns the number of cells in r.
+// See http://www.unicode.org/reports/tr11/
+func (c *Condition) RuneWidth(r rune) int {
+ switch {
+ case r < 0 || r > 0x10FFFF ||
+ inTables(r, nonprint, combining, notassigned):
+ return 0
+ case (c.EastAsianWidth && IsAmbiguousWidth(r)) ||
+ inTables(r, doublewidth, emoji):
+ return 2
+ default:
+ return 1
+ }
+}
+
+// StringWidth return width as you can see
+func (c *Condition) StringWidth(s string) (width int) {
+ for _, r := range []rune(s) {
+ width += c.RuneWidth(r)
+ }
+ return width
+}
+
+// Truncate return string truncated with w cells
+func (c *Condition) Truncate(s string, w int, tail string) string {
+ if c.StringWidth(s) <= w {
+ return s
+ }
+ r := []rune(s)
+ tw := c.StringWidth(tail)
+ w -= tw
+ width := 0
+ i := 0
+ for ; i < len(r); i++ {
+ cw := c.RuneWidth(r[i])
+ if width+cw > w {
+ break
+ }
+ width += cw
+ }
+ return string(r[0:i]) + tail
+}
+
+// Wrap return string wrapped with w cells
+func (c *Condition) Wrap(s string, w int) string {
+ width := 0
+ out := ""
+ for _, r := range []rune(s) {
+ cw := RuneWidth(r)
+ if r == '\n' {
+ out += string(r)
+ width = 0
+ continue
+ } else if width+cw > w {
+ out += "\n"
+ width = 0
+ out += string(r)
+ width += cw
+ continue
+ }
+ out += string(r)
+ width += cw
+ }
+ return out
+}
+
+// FillLeft return string filled in left by spaces in w cells
+func (c *Condition) FillLeft(s string, w int) string {
+ width := c.StringWidth(s)
+ count := w - width
+ if count > 0 {
+ b := make([]byte, count)
+ for i := range b {
+ b[i] = ' '
+ }
+ return string(b) + s
+ }
+ return s
+}
+
+// FillRight return string filled in left by spaces in w cells
+func (c *Condition) FillRight(s string, w int) string {
+ width := c.StringWidth(s)
+ count := w - width
+ if count > 0 {
+ b := make([]byte, count)
+ for i := range b {
+ b[i] = ' '
+ }
+ return s + string(b)
+ }
+ return s
+}
+
+// RuneWidth returns the number of cells in r.
+// See http://www.unicode.org/reports/tr11/
+func RuneWidth(r rune) int {
+ return DefaultCondition.RuneWidth(r)
+}
+
+// IsAmbiguousWidth returns whether is ambiguous width or not.
+func IsAmbiguousWidth(r rune) bool {
+ return inTables(r, private, ambiguous)
+}
+
+// IsNeutralWidth returns whether is neutral width or not.
+func IsNeutralWidth(r rune) bool {
+ return inTable(r, neutral)
+}
+
+// StringWidth return width as you can see
+func StringWidth(s string) (width int) {
+ return DefaultCondition.StringWidth(s)
+}
+
+// Truncate return string truncated with w cells
+func Truncate(s string, w int, tail string) string {
+ return DefaultCondition.Truncate(s, w, tail)
+}
+
+// Wrap return string wrapped with w cells
+func Wrap(s string, w int) string {
+ return DefaultCondition.Wrap(s, w)
+}
+
+// FillLeft return string filled in left by spaces in w cells
+func FillLeft(s string, w int) string {
+ return DefaultCondition.FillLeft(s, w)
+}
+
+// FillRight return string filled in left by spaces in w cells
+func FillRight(s string, w int) string {
+ return DefaultCondition.FillRight(s, w)
+}
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_js.go b/vendor/github.com/mattn/go-runewidth/runewidth_js.go
new file mode 100644
index 00000000..0ce32c5e
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/runewidth_js.go
@@ -0,0 +1,8 @@
+// +build js
+
+package runewidth
+
+func IsEastAsian() bool {
+ // TODO: Implement this for the web. Detect east asian in a compatible way, and return true.
+ return false
+}
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_posix.go b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go
new file mode 100644
index 00000000..c579e9a3
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go
@@ -0,0 +1,77 @@
+// +build !windows,!js
+
+package runewidth
+
+import (
+ "os"
+ "regexp"
+ "strings"
+)
+
+var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`)
+
+var mblenTable = map[string]int{
+ "utf-8": 6,
+ "utf8": 6,
+ "jis": 8,
+ "eucjp": 3,
+ "euckr": 2,
+ "euccn": 2,
+ "sjis": 2,
+ "cp932": 2,
+ "cp51932": 2,
+ "cp936": 2,
+ "cp949": 2,
+ "cp950": 2,
+ "big5": 2,
+ "gbk": 2,
+ "gb2312": 2,
+}
+
+func isEastAsian(locale string) bool {
+ charset := strings.ToLower(locale)
+ r := reLoc.FindStringSubmatch(locale)
+ if len(r) == 2 {
+ charset = strings.ToLower(r[1])
+ }
+
+ if strings.HasSuffix(charset, "@cjk_narrow") {
+ return false
+ }
+
+ for pos, b := range []byte(charset) {
+ if b == '@' {
+ charset = charset[:pos]
+ break
+ }
+ }
+ max := 1
+ if m, ok := mblenTable[charset]; ok {
+ max = m
+ }
+ if max > 1 && (charset[0] != 'u' ||
+ strings.HasPrefix(locale, "ja") ||
+ strings.HasPrefix(locale, "ko") ||
+ strings.HasPrefix(locale, "zh")) {
+ return true
+ }
+ return false
+}
+
+// IsEastAsian return true if the current locale is CJK
+func IsEastAsian() bool {
+ locale := os.Getenv("LC_CTYPE")
+ if locale == "" {
+ locale = os.Getenv("LANG")
+ }
+
+ // ignore C locale
+ if locale == "POSIX" || locale == "C" {
+ return false
+ }
+ if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') {
+ return false
+ }
+
+ return isEastAsian(locale)
+}
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_windows.go b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go
new file mode 100644
index 00000000..0258876b
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go
@@ -0,0 +1,25 @@
+package runewidth
+
+import (
+ "syscall"
+)
+
+var (
+ kernel32 = syscall.NewLazyDLL("kernel32")
+ procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP")
+)
+
+// IsEastAsian return true if the current locale is CJK
+func IsEastAsian() bool {
+ r1, _, _ := procGetConsoleOutputCP.Call()
+ if r1 == 0 {
+ return false
+ }
+
+ switch int(r1) {
+ case 932, 51932, 936, 949, 950:
+ return true
+ }
+
+ return false
+}
diff --git a/vendor/github.com/nsf/termbox-go/AUTHORS b/vendor/github.com/nsf/termbox-go/AUTHORS
new file mode 100644
index 00000000..fe26fb0f
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/AUTHORS
@@ -0,0 +1,4 @@
+# Please keep this file sorted.
+
+Georg Reinke <guelfey@googlemail.com>
+nsf <no.smile.face@gmail.com>
diff --git a/vendor/github.com/nsf/termbox-go/LICENSE b/vendor/github.com/nsf/termbox-go/LICENSE
new file mode 100644
index 00000000..d9bc068c
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2012 termbox-go authors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/github.com/nsf/termbox-go/README.md b/vendor/github.com/nsf/termbox-go/README.md
new file mode 100644
index 00000000..2ffe033e
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/README.md
@@ -0,0 +1,43 @@
+[![GoDoc](https://godoc.org/github.com/nsf/termbox-go?status.svg)](http://godoc.org/github.com/nsf/termbox-go)
+
+## Termbox
+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.
+
+### Installation
+Install and update this go package with `go get -u github.com/nsf/termbox-go`
+
+### Examples
+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`
+
+There are also some interesting projects using termbox-go:
+ - [godit](https://github.com/nsf/godit) is an emacsish lightweight text editor written using termbox.
+ - [gotetris](https://github.com/jjinux/gotetris) is an implementation of Tetris.
+ - [sokoban-go](https://github.com/rn2dy/sokoban-go) is an implementation of sokoban game.
+ - [hecate](https://github.com/evanmiller/hecate) is a hex editor designed by Satan.
+ - [httopd](https://github.com/verdverm/httopd) is top for httpd logs.
+ - [mop](https://github.com/mop-tracker/mop) is stock market tracker for hackers.
+ - [termui](https://github.com/gizak/termui) is a terminal dashboard.
+ - [termloop](https://github.com/JoelOtter/termloop) is a terminal game engine.
+ - [xterm-color-chart](https://github.com/kutuluk/xterm-color-chart) is a XTerm 256 color chart.
+ - [gocui](https://github.com/jroimartin/gocui) is a minimalist Go library aimed at creating console user interfaces.
+ - [dry](https://github.com/moncho/dry) is an interactive cli to manage Docker containers.
+ - [pxl](https://github.com/ichinaski/pxl) displays images in the terminal.
+ - [snake-game](https://github.com/DyegoCosta/snake-game) is an implementation of the Snake game.
+ - [gone](https://github.com/guillaumebreton/gone) is a CLI pomodoro® timer.
+ - [Spoof.go](https://github.com/sabey/spoofgo) controllable movement spoofing from the cli
+ - [lf](https://github.com/gokcehan/lf) is a terminal file manager
+ - [rat](https://github.com/ericfreese/rat) lets you compose shell commands to build terminal applications.
+ - [httplab](https://github.com/gchaincl/httplab) An interactive web server.
+ - [tetris](https://github.com/MichaelS11/tetris) Go Tetris with AI option
+ - [wot](https://github.com/kyu-suke/wot) Wait time during command is completed.
+ - [2048-go](https://github.com/1984weed/2048-go) is 2048 in Go
+ - [jv](https://github.com/maxzender/jv) helps you view JSON on the command-line.
+ - [pinger](https://github.com/hirose31/pinger) helps you to monitor numerous hosts using ICMP ECHO_REQUEST.
+ - [vixl44](https://github.com/sebashwa/vixl44) lets you create pixel art inside your terminal using vim movements
+ - [zterm](https://github.com/varunrau/zterm) is a typing game inspired by http://zty.pe/
+ - [gotypist](https://github.com/pb-/gotypist) is a fun touch-typing tutor following Steve Yegge's method.
+ - [cointop](https://github.com/miguelmota/cointop) is an interactive terminal based UI application for tracking cryptocurrencies.
+ - [pexpo](https://github.com/nnao45/pexpo) is a terminal sending ping tool written in Go.
+
+### API reference
+[godoc.org/github.com/nsf/termbox-go](http://godoc.org/github.com/nsf/termbox-go)
diff --git a/vendor/github.com/nsf/termbox-go/api.go b/vendor/github.com/nsf/termbox-go/api.go
new file mode 100644
index 00000000..d530ab5c
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/api.go
@@ -0,0 +1,489 @@
+// +build !windows
+
+package termbox
+
+import "github.com/mattn/go-runewidth"
+import "fmt"
+import "os"
+import "os/signal"
+import "syscall"
+import "runtime"
+import "time"
+
+// public API
+
+// Initializes termbox library. This function should be called before any other functions.
+// After successful initialization, the library must be finalized using 'Close' function.
+//
+// Example usage:
+// err := termbox.Init()
+// if err != nil {
+// panic(err)
+// }
+// defer termbox.Close()
+func Init() error {
+ var err error
+
+ out, err = os.OpenFile("/dev/tty", syscall.O_WRONLY, 0)
+ if err != nil {
+ return err
+ }
+ in, err = syscall.Open("/dev/tty", syscall.O_RDONLY, 0)
+ if err != nil {
+ return err
+ }
+
+ err = setup_term()
+ if err != nil {
+ return fmt.Errorf("termbox: error while reading terminfo data: %v", err)
+ }
+
+ signal.Notify(sigwinch, syscall.SIGWINCH)
+ signal.Notify(sigio, syscall.SIGIO)
+
+ _, err = fcntl(in, syscall.F_SETFL, syscall.O_ASYNC|syscall.O_NONBLOCK)
+ if err != nil {
+ return err
+ }
+ _, err = fcntl(in, syscall.F_SETOWN, syscall.Getpid())
+ if runtime.GOOS != "darwin" && err != nil {
+ return err
+ }
+ err = tcgetattr(out.Fd(), &orig_tios)
+ if err != nil {
+ return err
+ }
+
+ tios := orig_tios
+ tios.Iflag &^= syscall_IGNBRK | syscall_BRKINT | syscall_PARMRK |
+ syscall_ISTRIP | syscall_INLCR | syscall_IGNCR |
+ syscall_ICRNL | syscall_IXON
+ tios.Lflag &^= syscall_ECHO | syscall_ECHONL | syscall_ICANON |
+ syscall_ISIG | syscall_IEXTEN
+ tios.Cflag &^= syscall_CSIZE | syscall_PARENB
+ tios.Cflag |= syscall_CS8
+ tios.Cc[syscall_VMIN] = 1
+ tios.Cc[syscall_VTIME] = 0
+
+ err = tcsetattr(out.Fd(), &tios)
+ if err != nil {
+ return err
+ }
+
+ out.WriteString(funcs[t_enter_ca])
+ out.WriteString(funcs[t_enter_keypad])
+ out.WriteString(funcs[t_hide_cursor])
+ out.WriteString(funcs[t_clear_screen])
+
+ termw, termh = get_term_size(out.Fd())
+ back_buffer.init(termw, termh)
+ front_buffer.init(termw, termh)
+ back_buffer.clear()
+ front_buffer.clear()
+
+ go func() {
+ buf := make([]byte, 128)
+ for {
+ select {
+ case <-sigio:
+ for {
+ n, err := syscall.Read(in, buf)
+ if err == syscall.EAGAIN || err == syscall.EWOULDBLOCK {
+ break
+ }
+ select {
+ case input_comm <- input_event{buf[:n], err}:
+ ie := <-input_comm
+ buf = ie.data[:128]
+ case <-quit:
+ return
+ }
+ }
+ case <-quit:
+ return
+ }
+ }
+ }()
+
+ IsInit = true
+ return nil
+}
+
+// Interrupt an in-progress call to PollEvent by causing it to return
+// EventInterrupt. Note that this function will block until the PollEvent
+// function has successfully been interrupted.
+func Interrupt() {
+ interrupt_comm <- struct{}{}
+}
+
+// Finalizes termbox library, should be called after successful initialization
+// when termbox's functionality isn't required anymore.
+func Close() {
+ quit <- 1
+ out.WriteString(funcs[t_show_cursor])
+ out.WriteString(funcs[t_sgr0])
+ out.WriteString(funcs[t_clear_screen])
+ out.WriteString(funcs[t_exit_ca])
+ out.WriteString(funcs[t_exit_keypad])
+ out.WriteString(funcs[t_exit_mouse])
+ tcsetattr(out.Fd(), &orig_tios)
+
+ out.Close()
+ syscall.Close(in)
+
+ // reset the state, so that on next Init() it will work again
+ termw = 0
+ termh = 0
+ input_mode = InputEsc
+ out = nil
+ in = 0
+ lastfg = attr_invalid
+ lastbg = attr_invalid
+ lastx = coord_invalid
+ lasty = coord_invalid
+ cursor_x = cursor_hidden
+ cursor_y = cursor_hidden
+ foreground = ColorDefault
+ background = ColorDefault
+ IsInit = false
+}
+
+// Synchronizes the internal back buffer with the terminal.
+func Flush() error {
+ // invalidate cursor position
+ lastx = coord_invalid
+ lasty = coord_invalid
+
+ update_size_maybe()
+
+ for y := 0; y < front_buffer.height; y++ {
+ line_offset := y * front_buffer.width
+ for x := 0; x < front_buffer.width; {
+ cell_offset := line_offset + x
+ back := &back_buffer.cells[cell_offset]
+ front := &front_buffer.cells[cell_offset]
+ if back.Ch < ' ' {
+ back.Ch = ' '
+ }
+ w := runewidth.RuneWidth(back.Ch)
+ if w == 0 || w == 2 && runewidth.IsAmbiguousWidth(back.Ch) {
+ w = 1
+ }
+ if *back == *front {
+ x += w
+ continue
+ }
+ *front = *back
+ send_attr(back.Fg, back.Bg)
+
+ if w == 2 && x == front_buffer.width-1 {
+ // there's not enough space for 2-cells rune,
+ // let's just put a space in there
+ send_char(x, y, ' ')
+ } else {
+ send_char(x, y, back.Ch)
+ if w == 2 {
+ next := cell_offset + 1
+ front_buffer.cells[next] = Cell{
+ Ch: 0,
+ Fg: back.Fg,
+ Bg: back.Bg,
+ }
+ }
+ }
+ x += w
+ }
+ }
+ if !is_cursor_hidden(cursor_x, cursor_y) {
+ write_cursor(cursor_x, cursor_y)
+ }
+ return flush()
+}
+
+// Sets the position of the cursor. See also HideCursor().
+func SetCursor(x, y int) {
+ if is_cursor_hidden(cursor_x, cursor_y) && !is_cursor_hidden(x, y) {
+ outbuf.WriteString(funcs[t_show_cursor])
+ }
+
+ if !is_cursor_hidden(cursor_x, cursor_y) && is_cursor_hidden(x, y) {
+ outbuf.WriteString(funcs[t_hide_cursor])
+ }
+
+ cursor_x, cursor_y = x, y
+ if !is_cursor_hidden(cursor_x, cursor_y) {
+ write_cursor(cursor_x, cursor_y)
+ }
+}
+
+// The shortcut for SetCursor(-1, -1).
+func HideCursor() {
+ SetCursor(cursor_hidden, cursor_hidden)
+}
+
+// Changes cell's parameters in the internal back buffer at the specified
+// position.
+func SetCell(x, y int, ch rune, fg, bg Attribute) {
+ if x < 0 || x >= back_buffer.width {
+ return
+ }
+ if y < 0 || y >= back_buffer.height {
+ return
+ }
+
+ back_buffer.cells[y*back_buffer.width+x] = Cell{ch, fg, bg}
+}
+
+// Returns a slice into the termbox's back buffer. You can get its dimensions
+// using 'Size' function. The slice remains valid as long as no 'Clear' or
+// 'Flush' function calls were made after call to this function.
+func CellBuffer() []Cell {
+ return back_buffer.cells
+}
+
+// After getting a raw event from PollRawEvent function call, you can parse it
+// again into an ordinary one using termbox logic. That is parse an event as
+// termbox would do it. Returned event in addition to usual Event struct fields
+// sets N field to the amount of bytes used within 'data' slice. If the length
+// of 'data' slice is zero or event cannot be parsed for some other reason, the
+// function will return a special event type: EventNone.
+//
+// IMPORTANT: EventNone may contain a non-zero N, which means you should skip
+// these bytes, because termbox cannot recognize them.
+//
+// NOTE: This API is experimental and may change in future.
+func ParseEvent(data []byte) Event {
+ event := Event{Type: EventKey}
+ status := extract_event(data, &event, false)
+ if status != event_extracted {
+ return Event{Type: EventNone, N: event.N}
+ }
+ return event
+}
+
+// Wait for an event and return it. This is a blocking function call. Instead
+// of EventKey and EventMouse it returns EventRaw events. Raw event is written
+// into `data` slice and Event's N field is set to the amount of bytes written.
+// The minimum required length of the 'data' slice is 1. This requirement may
+// vary on different platforms.
+//
+// NOTE: This API is experimental and may change in future.
+func PollRawEvent(data []byte) Event {
+ if len(data) == 0 {
+ panic("len(data) >= 1 is a requirement")
+ }
+
+ var event Event
+ if extract_raw_event(data, &event) {
+ return event
+ }
+
+ for {
+ select {
+ case ev := <-input_comm:
+ if ev.err != nil {
+ return Event{Type: EventError, Err: ev.err}
+ }
+
+ inbuf = append(inbuf, ev.data...)
+ input_comm <- ev
+ if extract_raw_event(data, &event) {
+ return event
+ }
+ case <-interrupt_comm:
+ event.Type = EventInterrupt
+ return event
+
+ case <-sigwinch:
+ event.Type = EventResize
+ event.Width, event.Height = get_term_size(out.Fd())
+ return event
+ }
+ }
+}
+
+// Wait for an event and return it. This is a blocking function call.
+func PollEvent() Event {
+ // Constant governing macOS specific behavior. See https://github.com/nsf/termbox-go/issues/132
+ // This is an arbitrary delay which hopefully will be enough time for any lagging
+ // partial escape sequences to come through.
+ const esc_wait_delay = 100 * time.Millisecond
+
+ var event Event
+ var esc_wait_timer *time.Timer
+ var esc_timeout <-chan time.Time
+
+ // try to extract event from input buffer, return on success
+ event.Type = EventKey
+ status := extract_event(inbuf, &event, true)
+ if event.N != 0 {
+ copy(inbuf, inbuf[event.N:])
+ inbuf = inbuf[:len(inbuf)-event.N]
+ }
+ if status == event_extracted {
+ return event
+ } else if status == esc_wait {
+ esc_wait_timer = time.NewTimer(esc_wait_delay)
+ esc_timeout = esc_wait_timer.C
+ }
+
+ for {
+ select {
+ case ev := <-input_comm:
+ if esc_wait_timer != nil {
+ if !esc_wait_timer.Stop() {
+ <-esc_wait_timer.C
+ }
+ esc_wait_timer = nil
+ }
+
+ if ev.err != nil {
+ return Event{Type: EventError, Err: ev.err}
+ }
+
+ inbuf = append(inbuf, ev.data...)
+ input_comm <- ev
+ status := extract_event(inbuf, &event, true)
+ if event.N != 0 {
+ copy(inbuf, inbuf[event.N:])
+ inbuf = inbuf[:len(inbuf)-event.N]
+ }
+ if status == event_extracted {
+ return event
+ } else if status == esc_wait {
+ esc_wait_timer = time.NewTimer(esc_wait_delay)
+ esc_timeout = esc_wait_timer.C
+ }
+ case <-esc_timeout:
+ esc_wait_timer = nil
+
+ status := extract_event(inbuf, &event, false)
+ if event.N != 0 {
+ copy(inbuf, inbuf[event.N:])
+ inbuf = inbuf[:len(inbuf)-event.N]
+ }
+ if status == event_extracted {
+ return event
+ }
+ case <-interrupt_comm:
+ event.Type = EventInterrupt
+ return event
+
+ case <-sigwinch:
+ event.Type = EventResize
+ event.Width, event.Height = get_term_size(out.Fd())
+ return event
+ }
+ }
+}
+
+// Returns the size of the internal back buffer (which is mostly the same as
+// terminal's window size in characters). But it doesn't always match the size
+// of the terminal window, after the terminal size has changed, the internal
+// back buffer will get in sync only after Clear or Flush function calls.
+func Size() (width int, height int) {
+ return termw, termh
+}
+
+// Clears the internal back buffer.
+func Clear(fg, bg Attribute) error {
+ foreground, background = fg, bg
+ err := update_size_maybe()
+ back_buffer.clear()
+ return err
+}
+
+// Sets termbox input mode. Termbox has two input modes:
+//
+// 1. Esc input mode. When ESC sequence is in the buffer and it doesn't match
+// any known sequence. ESC means KeyEsc. This is the default input mode.
+//
+// 2. Alt input mode. When ESC sequence is in the buffer and it doesn't match
+// any known sequence. ESC enables ModAlt modifier for the next keyboard event.
+//
+// Both input modes can be OR'ed with Mouse mode. Setting Mouse mode bit up will
+// enable mouse button press/release and drag events.
+//
+// If 'mode' is InputCurrent, returns the current input mode. See also Input*
+// constants.
+func SetInputMode(mode InputMode) InputMode {
+ if mode == InputCurrent {
+ return input_mode
+ }
+ if mode&(InputEsc|InputAlt) == 0 {
+ mode |= InputEsc
+ }
+ if mode&(InputEsc|InputAlt) == InputEsc|InputAlt {
+ mode &^= InputAlt
+ }
+ if mode&InputMouse != 0 {
+ out.WriteString(funcs[t_enter_mouse])
+ } else {
+ out.WriteString(funcs[t_exit_mouse])
+ }
+
+ input_mode = mode
+ return input_mode
+}
+
+// Sets the termbox output mode. Termbox has four output options:
+//
+// 1. OutputNormal => [1..8]
+// This mode provides 8 different colors:
+// black, red, green, yellow, blue, magenta, cyan, white
+// Shortcut: ColorBlack, ColorRed, ...
+// Attributes: AttrBold, AttrUnderline, AttrReverse
+//
+// Example usage:
+// SetCell(x, y, '@', ColorBlack | AttrBold, ColorRed);
+//
+// 2. Output256 => [1..256]
+// In this mode you can leverage the 256 terminal mode:
+// 0x01 - 0x08: the 8 colors as in OutputNormal
+// 0x09 - 0x10: Color* | AttrBold
+// 0x11 - 0xe8: 216 different colors
+// 0xe9 - 0x1ff: 24 different shades of grey
+//
+// Example usage:
+// SetCell(x, y, '@', 184, 240);
+// SetCell(x, y, '@', 0xb8, 0xf0);
+//
+// 3. Output216 => [1..216]
+// This mode supports the 3rd range of the 256 mode only.
+// But you don't need to provide an offset.
+//
+// 4. OutputGrayscale => [1..26]
+// This mode supports the 4th range of the 256 mode
+// and black and white colors from 3th range of the 256 mode
+// But you don't need to provide an offset.
+//
+// In all modes, 0x00 represents the default color.
+//
+// `go run _demos/output.go` to see its impact on your terminal.
+//
+// If 'mode' is OutputCurrent, it returns the current output mode.
+//
+// Note that this may return a different OutputMode than the one requested,
+// as the requested mode may not be available on the target platform.
+func SetOutputMode(mode OutputMode) OutputMode {
+ if mode == OutputCurrent {
+ return output_mode
+ }
+
+ output_mode = mode
+ return output_mode
+}
+
+// Sync comes handy when something causes desync between termbox's understanding
+// of a terminal buffer and the reality. Such as a third party process. Sync
+// forces a complete resync between the termbox and a terminal, it may not be
+// visually pretty though.
+func Sync() error {
+ front_buffer.clear()
+ err := send_clear()
+ if err != nil {
+ return err
+ }
+
+ return Flush()
+}
diff --git a/vendor/github.com/nsf/termbox-go/api_common.go b/vendor/github.com/nsf/termbox-go/api_common.go
new file mode 100644
index 00000000..5ca1371a
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/api_common.go
@@ -0,0 +1,187 @@
+// termbox is a library for creating cross-platform text-based interfaces
+package termbox
+
+// public API, common OS agnostic part
+
+type (
+ InputMode int
+ OutputMode int
+ EventType uint8
+ Modifier uint8
+ Key uint16
+ Attribute uint16
+)
+
+// This type represents a termbox event. The 'Mod', 'Key' and 'Ch' fields are
+// valid if 'Type' is EventKey. The 'Width' and 'Height' fields are valid if
+// 'Type' is EventResize. The 'Err' field is valid if 'Type' is EventError.
+type Event struct {
+ Type EventType // one of Event* constants
+ Mod Modifier // one of Mod* constants or 0
+ Key Key // one of Key* constants, invalid if 'Ch' is not 0
+ Ch rune // a unicode character
+ Width int // width of the screen
+ Height int // height of the screen
+ Err error // error in case if input failed
+ MouseX int // x coord of mouse
+ MouseY int // y coord of mouse
+ N int // number of bytes written when getting a raw event
+}
+
+// A cell, single conceptual entity on the screen. The screen is basically a 2d
+// array of cells. 'Ch' is a unicode character, 'Fg' and 'Bg' are foreground
+// and background attributes respectively.
+type Cell struct {
+ Ch rune
+ Fg Attribute
+ Bg Attribute
+}
+
+// To know if termbox has been initialized or not
+var (
+ IsInit bool = false
+)
+
+// Key constants, see Event.Key field.
+const (
+ KeyF1 Key = 0xFFFF - iota
+ KeyF2
+ KeyF3
+ KeyF4
+ KeyF5
+ KeyF6
+ KeyF7
+ KeyF8
+ KeyF9
+ KeyF10
+ KeyF11
+ KeyF12
+ KeyInsert
+ KeyDelete
+ KeyHome
+ KeyEnd
+ KeyPgup
+ KeyPgdn
+ KeyArrowUp
+ KeyArrowDown
+ KeyArrowLeft
+ KeyArrowRight
+ key_min // see terminfo
+ MouseLeft
+ MouseMiddle
+ MouseRight
+ MouseRelease
+ MouseWheelUp
+ MouseWheelDown
+)
+
+const (
+ KeyCtrlTilde Key = 0x00
+ KeyCtrl2 Key = 0x00
+ KeyCtrlSpace Key = 0x00
+ KeyCtrlA Key = 0x01
+ KeyCtrlB Key = 0x02
+ KeyCtrlC Key = 0x03
+ KeyCtrlD Key = 0x04
+ KeyCtrlE Key = 0x05
+ KeyCtrlF Key = 0x06
+ KeyCtrlG Key = 0x07
+ KeyBackspace Key = 0x08
+ KeyCtrlH Key = 0x08
+ KeyTab Key = 0x09
+ KeyCtrlI Key = 0x09
+ KeyCtrlJ Key = 0x0A
+ KeyCtrlK Key = 0x0B
+ KeyCtrlL Key = 0x0C
+ KeyEnter Key = 0x0D
+ KeyCtrlM Key = 0x0D
+ KeyCtrlN Key = 0x0E
+ KeyCtrlO Key = 0x0F
+ KeyCtrlP Key = 0x10
+ KeyCtrlQ Key = 0x11
+ KeyCtrlR Key = 0x12
+ KeyCtrlS Key = 0x13
+ KeyCtrlT Key = 0x14
+ KeyCtrlU Key = 0x15
+ KeyCtrlV Key = 0x16
+ KeyCtrlW Key = 0x17
+ KeyCtrlX Key = 0x18
+ KeyCtrlY Key = 0x19
+ KeyCtrlZ Key = 0x1A
+ KeyEsc Key = 0x1B
+ KeyCtrlLsqBracket Key = 0x1B
+ KeyCtrl3 Key = 0x1B
+ KeyCtrl4 Key = 0x1C
+ KeyCtrlBackslash Key = 0x1C
+ KeyCtrl5 Key = 0x1D
+ KeyCtrlRsqBracket Key = 0x1D
+ KeyCtrl6 Key = 0x1E
+ KeyCtrl7 Key = 0x1F
+ KeyCtrlSlash Key = 0x1F
+ KeyCtrlUnderscore Key = 0x1F
+ KeySpace Key = 0x20
+ KeyBackspace2 Key = 0x7F
+ KeyCtrl8 Key = 0x7F
+)
+
+// Alt modifier constant, see Event.Mod field and SetInputMode function.
+const (
+ ModAlt Modifier = 1 << iota
+ ModMotion
+)
+
+// Cell colors, you can combine a color with multiple attributes using bitwise
+// OR ('|').
+const (
+ ColorDefault Attribute = iota
+ ColorBlack
+ ColorRed
+ ColorGreen
+ ColorYellow
+ ColorBlue
+ ColorMagenta
+ ColorCyan
+ ColorWhite
+)
+
+// Cell attributes, it is possible to use multiple attributes by combining them
+// using bitwise OR ('|'). Although, colors cannot be combined. But you can
+// combine attributes and a single color.
+//
+// It's worth mentioning that some platforms don't support certain attributes.
+// For example windows console doesn't support AttrUnderline. And on some
+// terminals applying AttrBold to background may result in blinking text. Use
+// them with caution and test your code on various terminals.
+const (
+ AttrBold Attribute = 1 << (iota + 9)
+ AttrUnderline
+ AttrReverse
+)
+
+// Input mode. See SetInputMode function.
+const (
+ InputEsc InputMode = 1 << iota
+ InputAlt
+ InputMouse
+ InputCurrent InputMode = 0
+)
+
+// Output mode. See SetOutputMode function.
+const (
+ OutputCurrent OutputMode = iota
+ OutputNormal
+ Output256
+ Output216
+ OutputGrayscale
+)
+
+// Event type. See Event.Type field.
+const (
+ EventKey EventType = iota
+ EventResize
+ EventMouse
+ EventError
+ EventInterrupt
+ EventRaw
+ EventNone
+)
diff --git a/vendor/github.com/nsf/termbox-go/api_windows.go b/vendor/github.com/nsf/termbox-go/api_windows.go
new file mode 100644
index 00000000..7def30a6
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/api_windows.go
@@ -0,0 +1,239 @@
+package termbox
+
+import (
+ "syscall"
+)
+
+// public API
+
+// Initializes termbox library. This function should be called before any other functions.
+// After successful initialization, the library must be finalized using 'Close' function.
+//
+// Example usage:
+// err := termbox.Init()
+// if err != nil {
+// panic(err)
+// }
+// defer termbox.Close()
+func Init() error {
+ var err error
+
+ interrupt, err = create_event()
+ if err != nil {
+ return err
+ }
+
+ in, err = syscall.Open("CONIN$", syscall.O_RDWR, 0)
+ if err != nil {
+ return err
+ }
+ out, err = syscall.Open("CONOUT$", syscall.O_RDWR, 0)
+ if err != nil {
+ return err
+ }
+
+ err = get_console_mode(in, &orig_mode)
+ if err != nil {
+ return err
+ }
+
+ err = set_console_mode(in, enable_window_input)
+ if err != nil {
+ return err
+ }
+
+ orig_size = get_term_size(out)
+ win_size := get_win_size(out)
+
+ err = set_console_screen_buffer_size(out, win_size)
+ if err != nil {
+ return err
+ }
+
+ err = get_console_cursor_info(out, &orig_cursor_info)
+ if err != nil {
+ return err
+ }
+
+ show_cursor(false)
+ term_size = get_term_size(out)
+ back_buffer.init(int(term_size.x), int(term_size.y))
+ front_buffer.init(int(term_size.x), int(term_size.y))
+ back_buffer.clear()
+ front_buffer.clear()
+ clear()
+
+ diffbuf = make([]diff_msg, 0, 32)
+
+ go input_event_producer()
+ IsInit = true
+ return nil
+}
+
+// Finalizes termbox library, should be called after successful initialization
+// when termbox's functionality isn't required anymore.
+func Close() {
+ // we ignore errors here, because we can't really do anything about them
+ Clear(0, 0)
+ Flush()
+
+ // stop event producer
+ cancel_comm <- true
+ set_event(interrupt)
+ select {
+ case <-input_comm:
+ default:
+ }
+ <-cancel_done_comm
+
+ set_console_cursor_info(out, &orig_cursor_info)
+ set_console_cursor_position(out, coord{})
+ set_console_screen_buffer_size(out, orig_size)
+ set_console_mode(in, orig_mode)
+ syscall.Close(in)
+ syscall.Close(out)
+ syscall.Close(interrupt)
+ IsInit = false
+}
+
+// Interrupt an in-progress call to PollEvent by causing it to return
+// EventInterrupt. Note that this function will block until the PollEvent
+// function has successfully been interrupted.
+func Interrupt() {
+ interrupt_comm <- struct{}{}
+}
+
+// Synchronizes the internal back buffer with the terminal.
+func Flush() error {
+ update_size_maybe()
+ prepare_diff_messages()
+ for _, diff := range diffbuf {
+ r := small_rect{
+ left: 0,
+ top: diff.pos,
+ right: term_size.x - 1,
+ bottom: diff.pos + diff.lines - 1,
+ }
+ write_console_output(out, diff.chars, r)
+ }
+ if !is_cursor_hidden(cursor_x, cursor_y) {
+ move_cursor(cursor_x, cursor_y)
+ }
+ return nil
+}
+
+// Sets the position of the cursor. See also HideCursor().
+func SetCursor(x, y int) {
+ if is_cursor_hidden(cursor_x, cursor_y) && !is_cursor_hidden(x, y) {
+ show_cursor(true)
+ }
+
+ if !is_cursor_hidden(cursor_x, cursor_y) && is_cursor_hidden(x, y) {
+ show_cursor(false)
+ }
+
+ cursor_x, cursor_y = x, y
+ if !is_cursor_hidden(cursor_x, cursor_y) {
+ move_cursor(cursor_x, cursor_y)
+ }
+}
+
+// The shortcut for SetCursor(-1, -1).
+func HideCursor() {
+ SetCursor(cursor_hidden, cursor_hidden)
+}
+
+// Changes cell's parameters in the internal back buffer at the specified
+// position.
+func SetCell(x, y int, ch rune, fg, bg Attribute) {
+ if x < 0 || x >= back_buffer.width {
+ return
+ }
+ if y < 0 || y >= back_buffer.height {
+ return
+ }
+
+ back_buffer.cells[y*back_buffer.width+x] = Cell{ch, fg, bg}
+}
+
+// Returns a slice into the termbox's back buffer. You can get its dimensions
+// using 'Size' function. The slice remains valid as long as no 'Clear' or
+// 'Flush' function calls were made after call to this function.
+func CellBuffer() []Cell {
+ return back_buffer.cells
+}
+
+// Wait for an event and return it. This is a blocking function call.
+func PollEvent() Event {
+ select {
+ case ev := <-input_comm:
+ return ev
+ case <-interrupt_comm:
+ return Event{Type: EventInterrupt}
+ }
+}
+
+// Returns the size of the internal back buffer (which is mostly the same as
+// console's window size in characters). But it doesn't always match the size
+// of the console window, after the console size has changed, the internal back
+// buffer will get in sync only after Clear or Flush function calls.
+func Size() (int, int) {
+ return int(term_size.x), int(term_size.y)
+}
+
+// Clears the internal back buffer.
+func Clear(fg, bg Attribute) error {
+ foreground, background = fg, bg
+ update_size_maybe()
+ back_buffer.clear()
+ return nil
+}
+
+// Sets termbox input mode. Termbox has two input modes:
+//
+// 1. Esc input mode. When ESC sequence is in the buffer and it doesn't match
+// any known sequence. ESC means KeyEsc. This is the default input mode.
+//
+// 2. Alt input mode. When ESC sequence is in the buffer and it doesn't match
+// any known sequence. ESC enables ModAlt modifier for the next keyboard event.
+//
+// Both input modes can be OR'ed with Mouse mode. Setting Mouse mode bit up will
+// enable mouse button press/release and drag events.
+//
+// If 'mode' is InputCurrent, returns the current input mode. See also Input*
+// constants.
+func SetInputMode(mode InputMode) InputMode {
+ if mode == InputCurrent {
+ return input_mode
+ }
+ if mode&InputMouse != 0 {
+ err := set_console_mode(in, enable_window_input|enable_mouse_input|enable_extended_flags)
+ if err != nil {
+ panic(err)
+ }
+ } else {
+ err := set_console_mode(in, enable_window_input)
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ input_mode = mode
+ return input_mode
+}
+
+// Sets the termbox output mode.
+//
+// Windows console does not support extra colour modes,
+// so this will always set and return OutputNormal.
+func SetOutputMode(mode OutputMode) OutputMode {
+ return OutputNormal
+}
+
+// Sync comes handy when something causes desync between termbox's understanding
+// of a terminal buffer and the reality. Such as a third party process. Sync
+// forces a complete resync between the termbox and a terminal, it may not be
+// visually pretty though. At the moment on Windows it does nothing.
+func Sync() error {
+ return nil
+}
diff --git a/vendor/github.com/nsf/termbox-go/collect_terminfo.py b/vendor/github.com/nsf/termbox-go/collect_terminfo.py
new file mode 100755
index 00000000..5e50975e
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/collect_terminfo.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+
+import sys, os, subprocess
+
+def escaped(s):
+ return repr(s)[1:-1]
+
+def tput(term, name):
+ try:
+ return subprocess.check_output(['tput', '-T%s' % term, name]).decode()
+ except subprocess.CalledProcessError as e:
+ return e.output.decode()
+
+
+def w(s):
+ if s == None:
+ return
+ sys.stdout.write(s)
+
+terminals = {
+ 'xterm' : 'xterm',
+ 'rxvt-256color' : 'rxvt_256color',
+ 'rxvt-unicode' : 'rxvt_unicode',
+ 'linux' : 'linux',
+ 'Eterm' : 'eterm',
+ 'screen' : 'screen'
+}
+
+keys = [
+ "F1", "kf1",
+ "F2", "kf2",
+ "F3", "kf3",
+ "F4", "kf4",
+ "F5", "kf5",
+ "F6", "kf6",
+ "F7", "kf7",
+ "F8", "kf8",
+ "F9", "kf9",
+ "F10", "kf10",
+ "F11", "kf11",
+ "F12", "kf12",
+ "INSERT", "kich1",
+ "DELETE", "kdch1",
+ "HOME", "khome",
+ "END", "kend",
+ "PGUP", "kpp",
+ "PGDN", "knp",
+ "KEY_UP", "kcuu1",
+ "KEY_DOWN", "kcud1",
+ "KEY_LEFT", "kcub1",
+ "KEY_RIGHT", "kcuf1"
+]
+
+funcs = [
+ "T_ENTER_CA", "smcup",
+ "T_EXIT_CA", "rmcup",
+ "T_SHOW_CURSOR", "cnorm",
+ "T_HIDE_CURSOR", "civis",
+ "T_CLEAR_SCREEN", "clear",
+ "T_SGR0", "sgr0",
+ "T_UNDERLINE", "smul",
+ "T_BOLD", "bold",
+ "T_BLINK", "blink",
+ "T_REVERSE", "rev",
+ "T_ENTER_KEYPAD", "smkx",
+ "T_EXIT_KEYPAD", "rmkx"
+]
+
+def iter_pairs(iterable):
+ iterable = iter(iterable)
+ while True:
+ yield (next(iterable), next(iterable))
+
+def do_term(term, nick):
+ w("// %s\n" % term)
+ w("var %s_keys = []string{\n\t" % nick)
+ for k, v in iter_pairs(keys):
+ w('"')
+ w(escaped(tput(term, v)))
+ w('",')
+ w("\n}\n")
+ w("var %s_funcs = []string{\n\t" % nick)
+ for k,v in iter_pairs(funcs):
+ w('"')
+ if v == "sgr":
+ w("\\033[3%d;4%dm")
+ elif v == "cup":
+ w("\\033[%d;%dH")
+ else:
+ w(escaped(tput(term, v)))
+ w('", ')
+ w("\n}\n\n")
+
+def do_terms(d):
+ w("var terms = []struct {\n")
+ w("\tname string\n")
+ w("\tkeys []string\n")
+ w("\tfuncs []string\n")
+ w("}{\n")
+ for k, v in d.items():
+ w('\t{"%s", %s_keys, %s_funcs},\n' % (k, v, v))
+ w("}\n\n")
+
+w("// +build !windows\n\npackage termbox\n\n")
+
+for k,v in terminals.items():
+ do_term(k, v)
+
+do_terms(terminals)
+
diff --git a/vendor/github.com/nsf/termbox-go/escwait.go b/vendor/github.com/nsf/termbox-go/escwait.go
new file mode 100644
index 00000000..b7bbb891
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/escwait.go
@@ -0,0 +1,11 @@
+// +build !darwin
+
+package termbox
+
+// On all systems other than macOS, disable behavior which will wait before
+// deciding that the escape key was pressed, to account for partially send
+// escape sequences, especially with regard to lengthy mouse sequences.
+// See https://github.com/nsf/termbox-go/issues/132
+func enable_wait_for_escape_sequence() bool {
+ return false
+}
diff --git a/vendor/github.com/nsf/termbox-go/escwait_darwin.go b/vendor/github.com/nsf/termbox-go/escwait_darwin.go
new file mode 100644
index 00000000..dde69b6c
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/escwait_darwin.go
@@ -0,0 +1,9 @@
+package termbox
+
+// On macOS, enable behavior which will wait before deciding that the escape
+// key was pressed, to account for partially send escape sequences, especially
+// with regard to lengthy mouse sequences.
+// See https://github.com/nsf/termbox-go/issues/132
+func enable_wait_for_escape_sequence() bool {
+ return true
+}
diff --git a/vendor/github.com/nsf/termbox-go/syscalls.go b/vendor/github.com/nsf/termbox-go/syscalls.go
new file mode 100644
index 00000000..4f52bb9a
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/syscalls.go
@@ -0,0 +1,39 @@
+// +build ignore
+
+package termbox
+
+/*
+#include <termios.h>
+#include <sys/ioctl.h>
+*/
+import "C"
+
+type syscall_Termios C.struct_termios
+
+const (
+ syscall_IGNBRK = C.IGNBRK
+ syscall_BRKINT = C.BRKINT
+ syscall_PARMRK = C.PARMRK
+ syscall_ISTRIP = C.ISTRIP
+ syscall_INLCR = C.INLCR
+ syscall_IGNCR = C.IGNCR
+ syscall_ICRNL = C.ICRNL
+ syscall_IXON = C.IXON
+ syscall_OPOST = C.OPOST
+ syscall_ECHO = C.ECHO
+ syscall_ECHONL = C.ECHONL
+ syscall_ICANON = C.ICANON
+ syscall_ISIG = C.ISIG
+ syscall_IEXTEN = C.IEXTEN
+ syscall_CSIZE = C.CSIZE
+ syscall_PARENB = C.PARENB
+ syscall_CS8 = C.CS8
+ syscall_VMIN = C.VMIN
+ syscall_VTIME = C.VTIME
+
+ // on darwin change these to (on *bsd too?):
+ // C.TIOCGETA
+ // C.TIOCSETA
+ syscall_TCGETS = C.TCGETS
+ syscall_TCSETS = C.TCSETS
+)
diff --git a/vendor/github.com/nsf/termbox-go/syscalls_darwin.go b/vendor/github.com/nsf/termbox-go/syscalls_darwin.go
new file mode 100644
index 00000000..25b78f7a
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/syscalls_darwin.go
@@ -0,0 +1,41 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs syscalls.go
+
+// +build !amd64
+
+package termbox
+
+type syscall_Termios struct {
+ Iflag uint32
+ Oflag uint32
+ Cflag uint32
+ Lflag uint32
+ Cc [20]uint8
+ Ispeed uint32
+ Ospeed uint32
+}
+
+const (
+ syscall_IGNBRK = 0x1
+ syscall_BRKINT = 0x2
+ syscall_PARMRK = 0x8
+ syscall_ISTRIP = 0x20
+ syscall_INLCR = 0x40
+ syscall_IGNCR = 0x80
+ syscall_ICRNL = 0x100
+ syscall_IXON = 0x200
+ syscall_OPOST = 0x1
+ syscall_ECHO = 0x8
+ syscall_ECHONL = 0x10
+ syscall_ICANON = 0x100
+ syscall_ISIG = 0x80
+ syscall_IEXTEN = 0x400
+ syscall_CSIZE = 0x300
+ syscall_PARENB = 0x1000
+ syscall_CS8 = 0x300
+ syscall_VMIN = 0x10
+ syscall_VTIME = 0x11
+
+ syscall_TCGETS = 0x402c7413
+ syscall_TCSETS = 0x802c7414
+)
diff --git a/vendor/github.com/nsf/termbox-go/syscalls_darwin_amd64.go b/vendor/github.com/nsf/termbox-go/syscalls_darwin_amd64.go
new file mode 100644
index 00000000..11f25be7
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/syscalls_darwin_amd64.go
@@ -0,0 +1,40 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs syscalls.go
+
+package termbox
+
+type syscall_Termios struct {
+ Iflag uint64
+ Oflag uint64
+ Cflag uint64
+ Lflag uint64
+ Cc [20]uint8
+ Pad_cgo_0 [4]byte
+ Ispeed uint64
+ Ospeed uint64
+}
+
+const (
+ syscall_IGNBRK = 0x1
+ syscall_BRKINT = 0x2
+ syscall_PARMRK = 0x8
+ syscall_ISTRIP = 0x20
+ syscall_INLCR = 0x40
+ syscall_IGNCR = 0x80
+ syscall_ICRNL = 0x100
+ syscall_IXON = 0x200
+ syscall_OPOST = 0x1
+ syscall_ECHO = 0x8
+ syscall_ECHONL = 0x10
+ syscall_ICANON = 0x100
+ syscall_ISIG = 0x80
+ syscall_IEXTEN = 0x400
+ syscall_CSIZE = 0x300
+ syscall_PARENB = 0x1000
+ syscall_CS8 = 0x300
+ syscall_VMIN = 0x10
+ syscall_VTIME = 0x11
+
+ syscall_TCGETS = 0x40487413
+ syscall_TCSETS = 0x80487414
+)
diff --git a/vendor/github.com/nsf/termbox-go/syscalls_dragonfly.go b/vendor/github.com/nsf/termbox-go/syscalls_dragonfly.go
new file mode 100644
index 00000000..e03624eb
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/syscalls_dragonfly.go
@@ -0,0 +1,39 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs syscalls.go
+
+package termbox
+
+type syscall_Termios struct {
+ Iflag uint32
+ Oflag uint32
+ Cflag uint32
+ Lflag uint32
+ Cc [20]uint8
+ Ispeed uint32
+ Ospeed uint32
+}
+
+const (
+ syscall_IGNBRK = 0x1
+ syscall_BRKINT = 0x2
+ syscall_PARMRK = 0x8
+ syscall_ISTRIP = 0x20
+ syscall_INLCR = 0x40
+ syscall_IGNCR = 0x80
+ syscall_ICRNL = 0x100
+ syscall_IXON = 0x200
+ syscall_OPOST = 0x1
+ syscall_ECHO = 0x8
+ syscall_ECHONL = 0x10
+ syscall_ICANON = 0x100
+ syscall_ISIG = 0x80
+ syscall_IEXTEN = 0x400
+ syscall_CSIZE = 0x300
+ syscall_PARENB = 0x1000
+ syscall_CS8 = 0x300
+ syscall_VMIN = 0x10
+ syscall_VTIME = 0x11
+
+ syscall_TCGETS = 0x402c7413
+ syscall_TCSETS = 0x802c7414
+)
diff --git a/vendor/github.com/nsf/termbox-go/syscalls_freebsd.go b/vendor/github.com/nsf/termbox-go/syscalls_freebsd.go
new file mode 100644
index 00000000..e03624eb
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/syscalls_freebsd.go
@@ -0,0 +1,39 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs syscalls.go
+
+package termbox
+
+type syscall_Termios struct {
+ Iflag uint32
+ Oflag uint32
+ Cflag uint32
+ Lflag uint32
+ Cc [20]uint8
+ Ispeed uint32
+ Ospeed uint32
+}
+
+const (
+ syscall_IGNBRK = 0x1
+ syscall_BRKINT = 0x2
+ syscall_PARMRK = 0x8
+ syscall_ISTRIP = 0x20
+ syscall_INLCR = 0x40
+ syscall_IGNCR = 0x80
+ syscall_ICRNL = 0x100
+ syscall_IXON = 0x200
+ syscall_OPOST = 0x1
+ syscall_ECHO = 0x8
+ syscall_ECHONL = 0x10
+ syscall_ICANON = 0x100
+ syscall_ISIG = 0x80
+ syscall_IEXTEN = 0x400
+ syscall_CSIZE = 0x300
+ syscall_PARENB = 0x1000
+ syscall_CS8 = 0x300
+ syscall_VMIN = 0x10
+ syscall_VTIME = 0x11
+
+ syscall_TCGETS = 0x402c7413
+ syscall_TCSETS = 0x802c7414
+)
diff --git a/vendor/github.com/nsf/termbox-go/syscalls_linux.go b/vendor/github.com/nsf/termbox-go/syscalls_linux.go
new file mode 100644
index 00000000..b88960de
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/syscalls_linux.go
@@ -0,0 +1,33 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs syscalls.go
+
+package termbox
+
+import "syscall"
+
+type syscall_Termios syscall.Termios
+
+const (
+ syscall_IGNBRK = syscall.IGNBRK
+ syscall_BRKINT = syscall.BRKINT
+ syscall_PARMRK = syscall.PARMRK
+ syscall_ISTRIP = syscall.ISTRIP
+ syscall_INLCR = syscall.INLCR
+ syscall_IGNCR = syscall.IGNCR
+ syscall_ICRNL = syscall.ICRNL
+ syscall_IXON = syscall.IXON
+ syscall_OPOST = syscall.OPOST
+ syscall_ECHO = syscall.ECHO
+ syscall_ECHONL = syscall.ECHONL
+ syscall_ICANON = syscall.ICANON
+ syscall_ISIG = syscall.ISIG
+ syscall_IEXTEN = syscall.IEXTEN
+ syscall_CSIZE = syscall.CSIZE
+ syscall_PARENB = syscall.PARENB
+ syscall_CS8 = syscall.CS8
+ syscall_VMIN = syscall.VMIN
+ syscall_VTIME = syscall.VTIME
+
+ syscall_TCGETS = syscall.TCGETS
+ syscall_TCSETS = syscall.TCSETS
+)
diff --git a/vendor/github.com/nsf/termbox-go/syscalls_netbsd.go b/vendor/github.com/nsf/termbox-go/syscalls_netbsd.go
new file mode 100644
index 00000000..49a3355b
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/syscalls_netbsd.go
@@ -0,0 +1,39 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs syscalls.go
+
+package termbox
+
+type syscall_Termios struct {
+ Iflag uint32
+ Oflag uint32
+ Cflag uint32
+ Lflag uint32
+ Cc [20]uint8
+ Ispeed int32
+ Ospeed int32
+}
+
+const (
+ syscall_IGNBRK = 0x1
+ syscall_BRKINT = 0x2
+ syscall_PARMRK = 0x8
+ syscall_ISTRIP = 0x20
+ syscall_INLCR = 0x40
+ syscall_IGNCR = 0x80
+ syscall_ICRNL = 0x100
+ syscall_IXON = 0x200
+ syscall_OPOST = 0x1
+ syscall_ECHO = 0x8
+ syscall_ECHONL = 0x10
+ syscall_ICANON = 0x100
+ syscall_ISIG = 0x80
+ syscall_IEXTEN = 0x400
+ syscall_CSIZE = 0x300
+ syscall_PARENB = 0x1000
+ syscall_CS8 = 0x300
+ syscall_VMIN = 0x10
+ syscall_VTIME = 0x11
+
+ syscall_TCGETS = 0x402c7413
+ syscall_TCSETS = 0x802c7414
+)
diff --git a/vendor/github.com/nsf/termbox-go/syscalls_openbsd.go b/vendor/github.com/nsf/termbox-go/syscalls_openbsd.go
new file mode 100644
index 00000000..49a3355b
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/syscalls_openbsd.go
@@ -0,0 +1,39 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs syscalls.go
+
+package termbox
+
+type syscall_Termios struct {
+ Iflag uint32
+ Oflag uint32
+ Cflag uint32
+ Lflag uint32
+ Cc [20]uint8
+ Ispeed int32
+ Ospeed int32
+}
+
+const (
+ syscall_IGNBRK = 0x1
+ syscall_BRKINT = 0x2
+ syscall_PARMRK = 0x8
+ syscall_ISTRIP = 0x20
+ syscall_INLCR = 0x40
+ syscall_IGNCR = 0x80
+ syscall_ICRNL = 0x100
+ syscall_IXON = 0x200
+ syscall_OPOST = 0x1
+ syscall_ECHO = 0x8
+ syscall_ECHONL = 0x10
+ syscall_ICANON = 0x100
+ syscall_ISIG = 0x80
+ syscall_IEXTEN = 0x400
+ syscall_CSIZE = 0x300
+ syscall_PARENB = 0x1000
+ syscall_CS8 = 0x300
+ syscall_VMIN = 0x10
+ syscall_VTIME = 0x11
+
+ syscall_TCGETS = 0x402c7413
+ syscall_TCSETS = 0x802c7414
+)
diff --git a/vendor/github.com/nsf/termbox-go/syscalls_windows.go b/vendor/github.com/nsf/termbox-go/syscalls_windows.go
new file mode 100644
index 00000000..472d002a
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/syscalls_windows.go
@@ -0,0 +1,61 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs -- -DUNICODE syscalls.go
+
+package termbox
+
+const (
+ foreground_blue = 0x1
+ foreground_green = 0x2
+ foreground_red = 0x4
+ foreground_intensity = 0x8
+ background_blue = 0x10
+ background_green = 0x20
+ background_red = 0x40
+ background_intensity = 0x80
+ std_input_handle = -0xa
+ std_output_handle = -0xb
+ key_event = 0x1
+ mouse_event = 0x2
+ window_buffer_size_event = 0x4
+ enable_window_input = 0x8
+ enable_mouse_input = 0x10
+ enable_extended_flags = 0x80
+
+ vk_f1 = 0x70
+ vk_f2 = 0x71
+ vk_f3 = 0x72
+ vk_f4 = 0x73
+ vk_f5 = 0x74
+ vk_f6 = 0x75
+ vk_f7 = 0x76
+ vk_f8 = 0x77
+ vk_f9 = 0x78
+ vk_f10 = 0x79
+ vk_f11 = 0x7a
+ vk_f12 = 0x7b
+ vk_insert = 0x2d
+ vk_delete = 0x2e
+ vk_home = 0x24
+ vk_end = 0x23
+ vk_pgup = 0x21
+ vk_pgdn = 0x22
+ vk_arrow_up = 0x26
+ vk_arrow_down = 0x28
+ vk_arrow_left = 0x25
+ vk_arrow_right = 0x27
+ vk_backspace = 0x8
+ vk_tab = 0x9
+ vk_enter = 0xd
+ vk_esc = 0x1b
+ vk_space = 0x20
+
+ left_alt_pressed = 0x2
+ left_ctrl_pressed = 0x8
+ right_alt_pressed = 0x1
+ right_ctrl_pressed = 0x4
+ shift_pressed = 0x10
+
+ generic_read = 0x80000000
+ generic_write = 0x40000000
+ console_textmode_buffer = 0x1
+)
diff --git a/vendor/github.com/nsf/termbox-go/termbox.go b/vendor/github.com/nsf/termbox-go/termbox.go
new file mode 100644
index 00000000..fbe4c3de
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/termbox.go
@@ -0,0 +1,529 @@
+// +build !windows
+
+package termbox
+
+import "unicode/utf8"
+import "bytes"
+import "syscall"
+import "unsafe"
+import "strings"
+import "strconv"
+import "os"
+import "io"
+
+// private API
+
+const (
+ t_enter_ca = iota
+ t_exit_ca
+ t_show_cursor
+ t_hide_cursor
+ t_clear_screen
+ t_sgr0
+ t_underline
+ t_bold
+ t_blink
+ t_reverse
+ t_enter_keypad
+ t_exit_keypad
+ t_enter_mouse
+ t_exit_mouse
+ t_max_funcs
+)
+
+const (
+ coord_invalid = -2
+ attr_invalid = Attribute(0xFFFF)
+)
+
+type input_event struct {
+ data []byte
+ err error
+}
+
+type extract_event_res int
+
+const (
+ event_not_extracted extract_event_res = iota
+ event_extracted
+ esc_wait
+)
+
+var (
+ // term specific sequences
+ keys []string
+ funcs []string
+
+ // termbox inner state
+ orig_tios syscall_Termios
+ back_buffer cellbuf
+ front_buffer cellbuf
+ termw int
+ termh int
+ input_mode = InputEsc
+ output_mode = OutputNormal
+ out *os.File
+ in int
+ lastfg = attr_invalid
+ lastbg = attr_invalid
+ lastx = coord_invalid
+ lasty = coord_invalid
+ cursor_x = cursor_hidden
+ cursor_y = cursor_hidden
+ foreground = ColorDefault
+ background = ColorDefault
+ inbuf = make([]byte, 0, 64)
+ outbuf bytes.Buffer
+ sigwinch = make(chan os.Signal, 1)
+ sigio = make(chan os.Signal, 1)
+ quit = make(chan int)
+ input_comm = make(chan input_event)
+ interrupt_comm = make(chan struct{})
+ intbuf = make([]byte, 0, 16)
+
+ // grayscale indexes
+ grayscale = []Attribute{
+ 0, 17, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,
+ 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 232,
+ }
+)
+
+func write_cursor(x, y int) {
+ outbuf.WriteString("\033[")
+ outbuf.Write(strconv.AppendUint(intbuf, uint64(y+1), 10))
+ outbuf.WriteString(";")
+ outbuf.Write(strconv.AppendUint(intbuf, uint64(x+1), 10))
+ outbuf.WriteString("H")
+}
+
+func write_sgr_fg(a Attribute) {
+ switch output_mode {
+ case Output256, Output216, OutputGrayscale:
+ outbuf.WriteString("\033[38;5;")
+ outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10))
+ outbuf.WriteString("m")
+ default:
+ outbuf.WriteString("\033[3")
+ outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10))
+ outbuf.WriteString("m")
+ }
+}
+
+func write_sgr_bg(a Attribute) {
+ switch output_mode {
+ case Output256, Output216, OutputGrayscale:
+ outbuf.WriteString("\033[48;5;")
+ outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10))
+ outbuf.WriteString("m")
+ default:
+ outbuf.WriteString("\033[4")
+ outbuf.Write(strconv.AppendUint(intbuf, uint64(a-1), 10))
+ outbuf.WriteString("m")
+ }
+}
+
+func write_sgr(fg, bg Attribute) {
+ switch output_mode {
+ case Output256, Output216, OutputGrayscale:
+ outbuf.WriteString("\033[38;5;")
+ outbuf.Write(strconv.AppendUint(intbuf, uint64(fg-1), 10))
+ outbuf.WriteString("m")
+ outbuf.WriteString("\033[48;5;")
+ outbuf.Write(strconv.AppendUint(intbuf, uint64(bg-1), 10))
+ outbuf.WriteString("m")
+ default:
+ outbuf.WriteString("\033[3")
+ outbuf.Write(strconv.AppendUint(intbuf, uint64(fg-1), 10))
+ outbuf.WriteString(";4")
+ outbuf.Write(strconv.AppendUint(intbuf, uint64(bg-1), 10))
+ outbuf.WriteString("m")
+ }
+}
+
+type winsize struct {
+ rows uint16
+ cols uint16
+ xpixels uint16
+ ypixels uint16
+}
+
+func get_term_size(fd uintptr) (int, int) {
+ var sz winsize
+ _, _, _ = syscall.Syscall(syscall.SYS_IOCTL,
+ fd, uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&sz)))
+ return int(sz.cols), int(sz.rows)
+}
+
+func send_attr(fg, bg Attribute) {
+ if fg == lastfg && bg == lastbg {
+ return
+ }
+
+ outbuf.WriteString(funcs[t_sgr0])
+
+ var fgcol, bgcol Attribute
+
+ switch output_mode {
+ case Output256:
+ fgcol = fg & 0x1FF
+ bgcol = bg & 0x1FF
+ case Output216:
+ fgcol = fg & 0xFF
+ bgcol = bg & 0xFF
+ if fgcol > 216 {
+ fgcol = ColorDefault
+ }
+ if bgcol > 216 {
+ bgcol = ColorDefault
+ }
+ if fgcol != ColorDefault {
+ fgcol += 0x10
+ }
+ if bgcol != ColorDefault {
+ bgcol += 0x10
+ }
+ case OutputGrayscale:
+ fgcol = fg & 0x1F
+ bgcol = bg & 0x1F
+ if fgcol > 26 {
+ fgcol = ColorDefault
+ }
+ if bgcol > 26 {
+ bgcol = ColorDefault
+ }
+ if fgcol != ColorDefault {
+ fgcol = grayscale[fgcol]
+ }
+ if bgcol != ColorDefault {
+ bgcol = grayscale[bgcol]
+ }
+ default:
+ fgcol = fg & 0x0F
+ bgcol = bg & 0x0F
+ }
+
+ if fgcol != ColorDefault {
+ if bgcol != ColorDefault {
+ write_sgr(fgcol, bgcol)
+ } else {
+ write_sgr_fg(fgcol)
+ }
+ } else if bgcol != ColorDefault {
+ write_sgr_bg(bgcol)
+ }
+
+ if fg&AttrBold != 0 {
+ outbuf.WriteString(funcs[t_bold])
+ }
+ if bg&AttrBold != 0 {
+ outbuf.WriteString(funcs[t_blink])
+ }
+ if fg&AttrUnderline != 0 {
+ outbuf.WriteString(funcs[t_underline])
+ }
+ if fg&AttrReverse|bg&AttrReverse != 0 {
+ outbuf.WriteString(funcs[t_reverse])
+ }
+
+ lastfg, lastbg = fg, bg
+}
+
+func send_char(x, y int, ch rune) {
+ var buf [8]byte
+ n := utf8.EncodeRune(buf[:], ch)
+ if x-1 != lastx || y != lasty {
+ write_cursor(x, y)
+ }
+ lastx, lasty = x, y
+ outbuf.Write(buf[:n])
+}
+
+func flush() error {
+ _, err := io.Copy(out, &outbuf)
+ outbuf.Reset()
+ return err
+}
+
+func send_clear() error {
+ send_attr(foreground, background)
+ outbuf.WriteString(funcs[t_clear_screen])
+ if !is_cursor_hidden(cursor_x, cursor_y) {
+ write_cursor(cursor_x, cursor_y)
+ }
+
+ // we need to invalidate cursor position too and these two vars are
+ // used only for simple cursor positioning optimization, cursor
+ // actually may be in the correct place, but we simply discard
+ // optimization once and it gives us simple solution for the case when
+ // cursor moved
+ lastx = coord_invalid
+ lasty = coord_invalid
+
+ return flush()
+}
+
+func update_size_maybe() error {
+ w, h := get_term_size(out.Fd())
+ if w != termw || h != termh {
+ termw, termh = w, h
+ back_buffer.resize(termw, termh)
+ front_buffer.resize(termw, termh)
+ front_buffer.clear()
+ return send_clear()
+ }
+ return nil
+}
+
+func tcsetattr(fd uintptr, termios *syscall_Termios) error {
+ r, _, e := syscall.Syscall(syscall.SYS_IOCTL,
+ fd, uintptr(syscall_TCSETS), uintptr(unsafe.Pointer(termios)))
+ if r != 0 {
+ return os.NewSyscallError("SYS_IOCTL", e)
+ }
+ return nil
+}
+
+func tcgetattr(fd uintptr, termios *syscall_Termios) error {
+ r, _, e := syscall.Syscall(syscall.SYS_IOCTL,
+ fd, uintptr(syscall_TCGETS), uintptr(unsafe.Pointer(termios)))
+ if r != 0 {
+ return os.NewSyscallError("SYS_IOCTL", e)
+ }
+ return nil
+}
+
+func parse_mouse_event(event *Event, buf string) (int, bool) {
+ if strings.HasPrefix(buf, "\033[M") && len(buf) >= 6 {
+ // X10 mouse encoding, the simplest one
+ // \033 [ M Cb Cx Cy
+ b := buf[3] - 32
+ switch b & 3 {
+ case 0:
+ if b&64 != 0 {
+ event.Key = MouseWheelUp
+ } else {
+ event.Key = MouseLeft
+ }
+ case 1:
+ if b&64 != 0 {
+ event.Key = MouseWheelDown
+ } else {
+ event.Key = MouseMiddle
+ }
+ case 2:
+ event.Key = MouseRight
+ case 3:
+ event.Key = MouseRelease
+ default:
+ return 6, false
+ }
+ event.Type = EventMouse // KeyEvent by default
+ if b&32 != 0 {
+ event.Mod |= ModMotion
+ }
+
+ // the coord is 1,1 for upper left
+ event.MouseX = int(buf[4]) - 1 - 32
+ event.MouseY = int(buf[5]) - 1 - 32
+ return 6, true
+ } else if strings.HasPrefix(buf, "\033[<") || strings.HasPrefix(buf, "\033[") {
+ // xterm 1006 extended mode or urxvt 1015 extended mode
+ // xterm: \033 [ < Cb ; Cx ; Cy (M or m)
+ // urxvt: \033 [ Cb ; Cx ; Cy M
+
+ // find the first M or m, that's where we stop
+ mi := strings.IndexAny(buf, "Mm")
+ if mi == -1 {
+ return 0, false
+ }
+
+ // whether it's a capital M or not
+ isM := buf[mi] == 'M'
+
+ // whether it's urxvt or not
+ isU := false
+
+ // buf[2] is safe here, because having M or m found means we have at
+ // least 3 bytes in a string
+ if buf[2] == '<' {
+ buf = buf[3:mi]
+ } else {
+ isU = true
+ buf = buf[2:mi]
+ }
+
+ s1 := strings.Index(buf, ";")
+ s2 := strings.LastIndex(buf, ";")
+ // not found or only one ';'
+ if s1 == -1 || s2 == -1 || s1 == s2 {
+ return 0, false
+ }
+
+ n1, err := strconv.ParseInt(buf[0:s1], 10, 64)
+ if err != nil {
+ return 0, false
+ }
+ n2, err := strconv.ParseInt(buf[s1+1:s2], 10, 64)
+ if err != nil {
+ return 0, false
+ }
+ n3, err := strconv.ParseInt(buf[s2+1:], 10, 64)
+ if err != nil {
+ return 0, false
+ }
+
+ // on urxvt, first number is encoded exactly as in X10, but we need to
+ // make it zero-based, on xterm it is zero-based already
+ if isU {
+ n1 -= 32
+ }
+ switch n1 & 3 {
+ case 0:
+ if n1&64 != 0 {
+ event.Key = MouseWheelUp
+ } else {
+ event.Key = MouseLeft
+ }
+ case 1:
+ if n1&64 != 0 {
+ event.Key = MouseWheelDown
+ } else {
+ event.Key = MouseMiddle
+ }
+ case 2:
+ event.Key = MouseRight
+ case 3:
+ event.Key = MouseRelease
+ default:
+ return mi + 1, false
+ }
+ if !isM {
+ // on xterm mouse release is signaled by lowercase m
+ event.Key = MouseRelease
+ }
+
+ event.Type = EventMouse // KeyEvent by default
+ if n1&32 != 0 {
+ event.Mod |= ModMotion
+ }
+
+ event.MouseX = int(n2) - 1
+ event.MouseY = int(n3) - 1
+ return mi + 1, true
+ }
+
+ return 0, false
+}
+
+func parse_escape_sequence(event *Event, buf []byte) (int, bool) {
+ bufstr := string(buf)
+ for i, key := range keys {
+ if strings.HasPrefix(bufstr, key) {
+ event.Ch = 0
+ event.Key = Key(0xFFFF - i)
+ return len(key), true
+ }
+ }
+
+ // if none of the keys match, let's try mouse sequences
+ return parse_mouse_event(event, bufstr)
+}
+
+func extract_raw_event(data []byte, event *Event) bool {
+ if len(inbuf) == 0 {
+ return false
+ }
+
+ n := len(data)
+ if n == 0 {
+ return false
+ }
+
+ n = copy(data, inbuf)
+ copy(inbuf, inbuf[n:])
+ inbuf = inbuf[:len(inbuf)-n]
+
+ event.N = n
+ event.Type = EventRaw
+ return true
+}
+
+func extract_event(inbuf []byte, event *Event, allow_esc_wait bool) extract_event_res {
+ if len(inbuf) == 0 {
+ event.N = 0
+ return event_not_extracted
+ }
+
+ if inbuf[0] == '\033' {
+ // possible escape sequence
+ if n, ok := parse_escape_sequence(event, inbuf); n != 0 {
+ event.N = n
+ if ok {
+ return event_extracted
+ } else {
+ return event_not_extracted
+ }
+ }
+
+ // possible partially read escape sequence; trigger a wait if appropriate
+ if enable_wait_for_escape_sequence() && allow_esc_wait {
+ event.N = 0
+ return esc_wait
+ }
+
+ // it's not escape sequence, then it's Alt or Esc, check input_mode
+ switch {
+ case input_mode&InputEsc != 0:
+ // if we're in escape mode, fill Esc event, pop buffer, return success
+ event.Ch = 0
+ event.Key = KeyEsc
+ event.Mod = 0
+ event.N = 1
+ return event_extracted
+ case input_mode&InputAlt != 0:
+ // if we're in alt mode, set Alt modifier to event and redo parsing
+ event.Mod = ModAlt
+ status := extract_event(inbuf[1:], event, false)
+ if status == event_extracted {
+ event.N++
+ } else {
+ event.N = 0
+ }
+ return status
+ default:
+ panic("unreachable")
+ }
+ }
+
+ // if we're here, this is not an escape sequence and not an alt sequence
+ // so, it's a FUNCTIONAL KEY or a UNICODE character
+
+ // first of all check if it's a functional key
+ if Key(inbuf[0]) <= KeySpace || Key(inbuf[0]) == KeyBackspace2 {
+ // fill event, pop buffer, return success
+ event.Ch = 0
+ event.Key = Key(inbuf[0])
+ event.N = 1
+ return event_extracted
+ }
+
+ // the only possible option is utf8 rune
+ if r, n := utf8.DecodeRune(inbuf); r != utf8.RuneError {
+ event.Ch = r
+ event.Key = 0
+ event.N = n
+ return event_extracted
+ }
+
+ return event_not_extracted
+}
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+ r, _, e := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), uintptr(cmd),
+ uintptr(arg))
+ val = int(r)
+ if e != 0 {
+ err = e
+ }
+ return
+}
diff --git a/vendor/github.com/nsf/termbox-go/termbox_common.go b/vendor/github.com/nsf/termbox-go/termbox_common.go
new file mode 100644
index 00000000..c3355cc2
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/termbox_common.go
@@ -0,0 +1,59 @@
+package termbox
+
+// private API, common OS agnostic part
+
+type cellbuf struct {
+ width int
+ height int
+ cells []Cell
+}
+
+func (this *cellbuf) init(width, height int) {
+ this.width = width
+ this.height = height
+ this.cells = make([]Cell, width*height)
+}
+
+func (this *cellbuf) resize(width, height int) {
+ if this.width == width && this.height == height {
+ return
+ }
+
+ oldw := this.width
+ oldh := this.height
+ oldcells := this.cells
+
+ this.init(width, height)
+ this.clear()
+
+ minw, minh := oldw, oldh
+
+ if width < minw {
+ minw = width
+ }
+ if height < minh {
+ minh = height
+ }
+
+ for i := 0; i < minh; i++ {
+ srco, dsto := i*oldw, i*width
+ src := oldcells[srco : srco+minw]
+ dst := this.cells[dsto : dsto+minw]
+ copy(dst, src)
+ }
+}
+
+func (this *cellbuf) clear() {
+ for i := range this.cells {
+ c := &this.cells[i]
+ c.Ch = ' '
+ c.Fg = foreground
+ c.Bg = background
+ }
+}
+
+const cursor_hidden = -1
+
+func is_cursor_hidden(x, y int) bool {
+ return x == cursor_hidden || y == cursor_hidden
+}
diff --git a/vendor/github.com/nsf/termbox-go/termbox_windows.go b/vendor/github.com/nsf/termbox-go/termbox_windows.go
new file mode 100644
index 00000000..7752a175
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/termbox_windows.go
@@ -0,0 +1,915 @@
+package termbox
+
+import "math"
+import "syscall"
+import "unsafe"
+import "unicode/utf16"
+import "github.com/mattn/go-runewidth"
+
+type (
+ wchar uint16
+ short int16
+ dword uint32
+ word uint16
+ char_info struct {
+ char wchar
+ attr word
+ }
+ coord struct {
+ x short
+ y short
+ }
+ small_rect struct {
+ left short
+ top short
+ right short
+ bottom short
+ }
+ console_screen_buffer_info struct {
+ size coord
+ cursor_position coord
+ attributes word
+ window small_rect
+ maximum_window_size coord
+ }
+ console_cursor_info struct {
+ size dword
+ visible int32
+ }
+ input_record struct {
+ event_type word
+ _ [2]byte
+ event [16]byte
+ }
+ key_event_record struct {
+ key_down int32
+ repeat_count word
+ virtual_key_code word
+ virtual_scan_code word
+ unicode_char wchar
+ control_key_state dword
+ }
+ window_buffer_size_record struct {
+ size coord
+ }
+ mouse_event_record struct {
+ mouse_pos coord
+ button_state dword
+ control_key_state dword
+ event_flags dword
+ }
+ console_font_info struct {
+ font uint32
+ font_size coord
+ }
+)
+
+const (
+ mouse_lmb = 0x1
+ mouse_rmb = 0x2
+ mouse_mmb = 0x4 | 0x8 | 0x10
+ SM_CXMIN = 28
+ SM_CYMIN = 29
+)
+
+func (this coord) uintptr() uintptr {
+ return uintptr(*(*int32)(unsafe.Pointer(&this)))
+}
+
+var kernel32 = syscall.NewLazyDLL("kernel32.dll")
+var moduser32 = syscall.NewLazyDLL("user32.dll")
+var is_cjk = runewidth.IsEastAsian()
+
+var (
+ proc_set_console_active_screen_buffer = kernel32.NewProc("SetConsoleActiveScreenBuffer")
+ proc_set_console_screen_buffer_size = kernel32.NewProc("SetConsoleScreenBufferSize")
+ proc_create_console_screen_buffer = kernel32.NewProc("CreateConsoleScreenBuffer")
+ proc_get_console_screen_buffer_info = kernel32.NewProc("GetConsoleScreenBufferInfo")
+ proc_write_console_output = kernel32.NewProc("WriteConsoleOutputW")
+ proc_write_console_output_character = kernel32.NewProc("WriteConsoleOutputCharacterW")
+ proc_write_console_output_attribute = kernel32.NewProc("WriteConsoleOutputAttribute")
+ proc_set_console_cursor_info = kernel32.NewProc("SetConsoleCursorInfo")
+ proc_set_console_cursor_position = kernel32.NewProc("SetConsoleCursorPosition")
+ proc_get_console_cursor_info = kernel32.NewProc("GetConsoleCursorInfo")
+ proc_read_console_input = kernel32.NewProc("ReadConsoleInputW")
+ proc_get_console_mode = kernel32.NewProc("GetConsoleMode")
+ proc_set_console_mode = kernel32.NewProc("SetConsoleMode")
+ proc_fill_console_output_character = kernel32.NewProc("FillConsoleOutputCharacterW")
+ proc_fill_console_output_attribute = kernel32.NewProc("FillConsoleOutputAttribute")
+ proc_create_event = kernel32.NewProc("CreateEventW")
+ proc_wait_for_multiple_objects = kernel32.NewProc("WaitForMultipleObjects")
+ proc_set_event = kernel32.NewProc("SetEvent")
+ proc_get_current_console_font = kernel32.NewProc("GetCurrentConsoleFont")
+ get_system_metrics = moduser32.NewProc("GetSystemMetrics")
+)
+
+func set_console_active_screen_buffer(h syscall.Handle) (err error) {
+ r0, _, e1 := syscall.Syscall(proc_set_console_active_screen_buffer.Addr(),
+ 1, uintptr(h), 0, 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func set_console_screen_buffer_size(h syscall.Handle, size coord) (err error) {
+ r0, _, e1 := syscall.Syscall(proc_set_console_screen_buffer_size.Addr(),
+ 2, uintptr(h), size.uintptr(), 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func create_console_screen_buffer() (h syscall.Handle, err error) {
+ r0, _, e1 := syscall.Syscall6(proc_create_console_screen_buffer.Addr(),
+ 5, uintptr(generic_read|generic_write), 0, 0, console_textmode_buffer, 0, 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return syscall.Handle(r0), err
+}
+
+func get_console_screen_buffer_info(h syscall.Handle, info *console_screen_buffer_info) (err error) {
+ r0, _, e1 := syscall.Syscall(proc_get_console_screen_buffer_info.Addr(),
+ 2, uintptr(h), uintptr(unsafe.Pointer(info)), 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func write_console_output(h syscall.Handle, chars []char_info, dst small_rect) (err error) {
+ tmp_coord = coord{dst.right - dst.left + 1, dst.bottom - dst.top + 1}
+ tmp_rect = dst
+ r0, _, e1 := syscall.Syscall6(proc_write_console_output.Addr(),
+ 5, uintptr(h), uintptr(unsafe.Pointer(&chars[0])), tmp_coord.uintptr(),
+ tmp_coord0.uintptr(), uintptr(unsafe.Pointer(&tmp_rect)), 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func write_console_output_character(h syscall.Handle, chars []wchar, pos coord) (err error) {
+ r0, _, e1 := syscall.Syscall6(proc_write_console_output_character.Addr(),
+ 5, uintptr(h), uintptr(unsafe.Pointer(&chars[0])), uintptr(len(chars)),
+ pos.uintptr(), uintptr(unsafe.Pointer(&tmp_arg)), 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func write_console_output_attribute(h syscall.Handle, attrs []word, pos coord) (err error) {
+ r0, _, e1 := syscall.Syscall6(proc_write_console_output_attribute.Addr(),
+ 5, uintptr(h), uintptr(unsafe.Pointer(&attrs[0])), uintptr(len(attrs)),
+ pos.uintptr(), uintptr(unsafe.Pointer(&tmp_arg)), 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func set_console_cursor_info(h syscall.Handle, info *console_cursor_info) (err error) {
+ r0, _, e1 := syscall.Syscall(proc_set_console_cursor_info.Addr(),
+ 2, uintptr(h), uintptr(unsafe.Pointer(info)), 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func get_console_cursor_info(h syscall.Handle, info *console_cursor_info) (err error) {
+ r0, _, e1 := syscall.Syscall(proc_get_console_cursor_info.Addr(),
+ 2, uintptr(h), uintptr(unsafe.Pointer(info)), 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func set_console_cursor_position(h syscall.Handle, pos coord) (err error) {
+ r0, _, e1 := syscall.Syscall(proc_set_console_cursor_position.Addr(),
+ 2, uintptr(h), pos.uintptr(), 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func read_console_input(h syscall.Handle, record *input_record) (err error) {
+ r0, _, e1 := syscall.Syscall6(proc_read_console_input.Addr(),
+ 4, uintptr(h), uintptr(unsafe.Pointer(record)), 1, uintptr(unsafe.Pointer(&tmp_arg)), 0, 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func get_console_mode(h syscall.Handle, mode *dword) (err error) {
+ r0, _, e1 := syscall.Syscall(proc_get_console_mode.Addr(),
+ 2, uintptr(h), uintptr(unsafe.Pointer(mode)), 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func set_console_mode(h syscall.Handle, mode dword) (err error) {
+ r0, _, e1 := syscall.Syscall(proc_set_console_mode.Addr(),
+ 2, uintptr(h), uintptr(mode), 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func fill_console_output_character(h syscall.Handle, char wchar, n int) (err error) {
+ r0, _, e1 := syscall.Syscall6(proc_fill_console_output_character.Addr(),
+ 5, uintptr(h), uintptr(char), uintptr(n), tmp_coord.uintptr(),
+ uintptr(unsafe.Pointer(&tmp_arg)), 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func fill_console_output_attribute(h syscall.Handle, attr word, n int) (err error) {
+ r0, _, e1 := syscall.Syscall6(proc_fill_console_output_attribute.Addr(),
+ 5, uintptr(h), uintptr(attr), uintptr(n), tmp_coord.uintptr(),
+ uintptr(unsafe.Pointer(&tmp_arg)), 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func create_event() (out syscall.Handle, err error) {
+ r0, _, e1 := syscall.Syscall6(proc_create_event.Addr(),
+ 4, 0, 0, 0, 0, 0, 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return syscall.Handle(r0), err
+}
+
+func wait_for_multiple_objects(objects []syscall.Handle) (err error) {
+ r0, _, e1 := syscall.Syscall6(proc_wait_for_multiple_objects.Addr(),
+ 4, uintptr(len(objects)), uintptr(unsafe.Pointer(&objects[0])),
+ 0, 0xFFFFFFFF, 0, 0)
+ if uint32(r0) == 0xFFFFFFFF {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func set_event(ev syscall.Handle) (err error) {
+ r0, _, e1 := syscall.Syscall(proc_set_event.Addr(),
+ 1, uintptr(ev), 0, 0)
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func get_current_console_font(h syscall.Handle, info *console_font_info) (err error) {
+ r0, _, e1 := syscall.Syscall(proc_get_current_console_font.Addr(),
+ 3, uintptr(h), 0, uintptr(unsafe.Pointer(info)))
+ if int(r0) == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+type diff_msg struct {
+ pos short
+ lines short
+ chars []char_info
+}
+
+type input_event struct {
+ event Event
+ err error
+}
+
+var (
+ orig_cursor_info console_cursor_info
+ orig_size coord
+ orig_mode dword
+ orig_screen syscall.Handle
+ back_buffer cellbuf
+ front_buffer cellbuf
+ term_size coord
+ input_mode = InputEsc
+ cursor_x = cursor_hidden
+ cursor_y = cursor_hidden
+ foreground = ColorDefault
+ background = ColorDefault
+ in syscall.Handle
+ out syscall.Handle
+ interrupt syscall.Handle
+ charbuf []char_info
+ diffbuf []diff_msg
+ beg_x = -1
+ beg_y = -1
+ beg_i = -1
+ input_comm = make(chan Event)
+ interrupt_comm = make(chan struct{})
+ cancel_comm = make(chan bool, 1)
+ cancel_done_comm = make(chan bool)
+ alt_mode_esc = false
+
+ // these ones just to prevent heap allocs at all costs
+ tmp_info console_screen_buffer_info
+ tmp_arg dword
+ tmp_coord0 = coord{0, 0}
+ tmp_coord = coord{0, 0}
+ tmp_rect = small_rect{0, 0, 0, 0}
+ tmp_finfo console_font_info
+)
+
+func get_cursor_position(out syscall.Handle) coord {
+ err := get_console_screen_buffer_info(out, &tmp_info)
+ if err != nil {
+ panic(err)
+ }
+ return tmp_info.cursor_position
+}
+
+func get_term_size(out syscall.Handle) coord {
+ err := get_console_screen_buffer_info(out, &tmp_info)
+ if err != nil {
+ panic(err)
+ }
+ return tmp_info.size
+}
+
+func get_win_min_size(out syscall.Handle) coord {
+ x, _, err := get_system_metrics.Call(SM_CXMIN)
+ y, _, err := get_system_metrics.Call(SM_CYMIN)
+
+ if x == 0 || y == 0 {
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ err1 := get_current_console_font(out, &tmp_finfo)
+ if err1 != nil {
+ panic(err1)
+ }
+
+ return coord{
+ x: short(math.Ceil(float64(x) / float64(tmp_finfo.font_size.x))),
+ y: short(math.Ceil(float64(y) / float64(tmp_finfo.font_size.y))),
+ }
+}
+
+func get_win_size(out syscall.Handle) coord {
+ err := get_console_screen_buffer_info(out, &tmp_info)
+ if err != nil {
+ panic(err)
+ }
+
+ min_size := get_win_min_size(out)
+
+ size := coord{
+ x: tmp_info.window.right - tmp_info.window.left + 1,
+ y: tmp_info.window.bottom - tmp_info.window.top + 1,
+ }
+
+ if size.x < min_size.x {
+ size.x = min_size.x
+ }
+
+ if size.y < min_size.y {
+ size.y = min_size.y
+ }
+
+ return size
+}
+
+func update_size_maybe() {
+ size := get_win_size(out)
+ if size.x != term_size.x || size.y != term_size.y {
+ set_console_screen_buffer_size(out, size)
+ term_size = size
+ back_buffer.resize(int(size.x), int(size.y))
+ front_buffer.resize(int(size.x), int(size.y))
+ front_buffer.clear()
+ clear()
+
+ area := int(size.x) * int(size.y)
+ if cap(charbuf) < area {
+ charbuf = make([]char_info, 0, area)
+ }
+ }
+}
+
+var color_table_bg = []word{
+ 0, // default (black)
+ 0, // black
+ background_red,
+ background_green,
+ background_red | background_green, // yellow
+ background_blue,
+ background_red | background_blue, // magenta
+ background_green | background_blue, // cyan
+ background_red | background_blue | background_green, // white
+}
+
+var color_table_fg = []word{
+ foreground_red | foreground_blue | foreground_green, // default (white)
+ 0,
+ foreground_red,
+ foreground_green,
+ foreground_red | foreground_green, // yellow
+ foreground_blue,
+ foreground_red | foreground_blue, // magenta
+ foreground_green | foreground_blue, // cyan
+ foreground_red | foreground_blue | foreground_green, // white
+}
+
+const (
+ replacement_char = '\uFFFD'
+ max_rune = '\U0010FFFF'
+ surr1 = 0xd800
+ surr2 = 0xdc00
+ surr3 = 0xe000
+ surr_self = 0x10000
+)
+
+func append_diff_line(y int) int {
+ n := 0
+ for x := 0; x < front_buffer.width; {
+ cell_offset := y*front_buffer.width + x
+ back := &back_buffer.cells[cell_offset]
+ front := &front_buffer.cells[cell_offset]
+ attr, char := cell_to_char_info(*back)
+ charbuf = append(charbuf, char_info{attr: attr, char: char[0]})
+ *front = *back
+ n++
+ w := runewidth.RuneWidth(back.Ch)
+ if w == 0 || w == 2 && runewidth.IsAmbiguousWidth(back.Ch) {
+ w = 1
+ }
+ x += w
+ // If not CJK, fill trailing space with whitespace
+ if !is_cjk && w == 2 {
+ charbuf = append(charbuf, char_info{attr: attr, char: ' '})
+ }
+ }
+ return n
+}
+
+// compares 'back_buffer' with 'front_buffer' and prepares all changes in the form of
+// 'diff_msg's in the 'diff_buf'
+func prepare_diff_messages() {
+ // clear buffers
+ diffbuf = diffbuf[:0]
+ charbuf = charbuf[:0]
+
+ var diff diff_msg
+ gbeg := 0
+ for y := 0; y < front_buffer.height; y++ {
+ same := true
+ line_offset := y * front_buffer.width
+ for x := 0; x < front_buffer.width; x++ {
+ cell_offset := line_offset + x
+ back := &back_buffer.cells[cell_offset]
+ front := &front_buffer.cells[cell_offset]
+ if *back != *front {
+ same = false
+ break
+ }
+ }
+ if same && diff.lines > 0 {
+ diffbuf = append(diffbuf, diff)
+ diff = diff_msg{}
+ }
+ if !same {
+ beg := len(charbuf)
+ end := beg + append_diff_line(y)
+ if diff.lines == 0 {
+ diff.pos = short(y)
+ gbeg = beg
+ }
+ diff.lines++
+ diff.chars = charbuf[gbeg:end]
+ }
+ }
+ if diff.lines > 0 {
+ diffbuf = append(diffbuf, diff)
+ diff = diff_msg{}
+ }
+}
+
+func get_ct(table []word, idx int) word {
+ idx = idx & 0x0F
+ if idx >= len(table) {
+ idx = len(table) - 1
+ }
+ return table[idx]
+}
+
+func cell_to_char_info(c Cell) (attr word, wc [2]wchar) {
+ attr = get_ct(color_table_fg, int(c.Fg)) | get_ct(color_table_bg, int(c.Bg))
+ if c.Fg&AttrReverse|c.Bg&AttrReverse != 0 {
+ attr = (attr&0xF0)>>4 | (attr&0x0F)<<4
+ }
+ if c.Fg&AttrBold != 0 {
+ attr |= foreground_intensity
+ }
+ if c.Bg&AttrBold != 0 {
+ attr |= background_intensity
+ }
+
+ r0, r1 := utf16.EncodeRune(c.Ch)
+ if r0 == 0xFFFD {
+ wc[0] = wchar(c.Ch)
+ wc[1] = ' '
+ } else {
+ wc[0] = wchar(r0)
+ wc[1] = wchar(r1)
+ }
+ return
+}
+
+func move_cursor(x, y int) {
+ err := set_console_cursor_position(out, coord{short(x), short(y)})
+ if err != nil {
+ panic(err)
+ }
+}
+
+func show_cursor(visible bool) {
+ var v int32
+ if visible {
+ v = 1
+ }
+
+ var info console_cursor_info
+ info.size = 100
+ info.visible = v
+ err := set_console_cursor_info(out, &info)
+ if err != nil {
+ panic(err)
+ }
+}
+
+func clear() {
+ var err error
+ attr, char := cell_to_char_info(Cell{
+ ' ',
+ foreground,
+ background,
+ })
+
+ area := int(term_size.x) * int(term_size.y)
+ err = fill_console_output_attribute(out, attr, area)
+ if err != nil {
+ panic(err)
+ }
+ err = fill_console_output_character(out, char[0], area)
+ if err != nil {
+ panic(err)
+ }
+ if !is_cursor_hidden(cursor_x, cursor_y) {
+ move_cursor(cursor_x, cursor_y)
+ }
+}
+
+func key_event_record_to_event(r *key_event_record) (Event, bool) {
+ if r.key_down == 0 {
+ return Event{}, false
+ }
+
+ e := Event{Type: EventKey}
+ if input_mode&InputAlt != 0 {
+ if alt_mode_esc {
+ e.Mod = ModAlt
+ alt_mode_esc = false
+ }
+ if r.control_key_state&(left_alt_pressed|right_alt_pressed) != 0 {
+ e.Mod = ModAlt
+ }
+ }
+
+ ctrlpressed := r.control_key_state&(left_ctrl_pressed|right_ctrl_pressed) != 0
+
+ if r.virtual_key_code >= vk_f1 && r.virtual_key_code <= vk_f12 {
+ switch r.virtual_key_code {
+ case vk_f1:
+ e.Key = KeyF1
+ case vk_f2:
+ e.Key = KeyF2
+ case vk_f3:
+ e.Key = KeyF3
+ case vk_f4:
+ e.Key = KeyF4
+ case vk_f5:
+ e.Key = KeyF5
+ case vk_f6:
+ e.Key = KeyF6
+ case vk_f7:
+ e.Key = KeyF7
+ case vk_f8:
+ e.Key = KeyF8
+ case vk_f9:
+ e.Key = KeyF9
+ case vk_f10:
+ e.Key = KeyF10
+ case vk_f11:
+ e.Key = KeyF11
+ case vk_f12:
+ e.Key = KeyF12
+ default:
+ panic("unreachable")
+ }
+
+ return e, true
+ }
+
+ if r.virtual_key_code <= vk_delete {
+ switch r.virtual_key_code {
+ case vk_insert:
+ e.Key = KeyInsert
+ case vk_delete:
+ e.Key = KeyDelete
+ case vk_home:
+ e.Key = KeyHome
+ case vk_end:
+ e.Key = KeyEnd
+ case vk_pgup:
+ e.Key = KeyPgup
+ case vk_pgdn:
+ e.Key = KeyPgdn
+ case vk_arrow_up:
+ e.Key = KeyArrowUp
+ case vk_arrow_down:
+ e.Key = KeyArrowDown
+ case vk_arrow_left:
+ e.Key = KeyArrowLeft
+ case vk_arrow_right:
+ e.Key = KeyArrowRight
+ case vk_backspace:
+ if ctrlpressed {
+ e.Key = KeyBackspace2
+ } else {
+ e.Key = KeyBackspace
+ }
+ case vk_tab:
+ e.Key = KeyTab
+ case vk_enter:
+ e.Key = KeyEnter
+ case vk_esc:
+ switch {
+ case input_mode&InputEsc != 0:
+ e.Key = KeyEsc
+ case input_mode&InputAlt != 0:
+ alt_mode_esc = true
+ return Event{}, false
+ }
+ case vk_space:
+ if ctrlpressed {
+ // manual return here, because KeyCtrlSpace is zero
+ e.Key = KeyCtrlSpace
+ return e, true
+ } else {
+ e.Key = KeySpace
+ }
+ }
+
+ if e.Key != 0 {
+ return e, true
+ }
+ }
+
+ if ctrlpressed {
+ if Key(r.unicode_char) >= KeyCtrlA && Key(r.unicode_char) <= KeyCtrlRsqBracket {
+ e.Key = Key(r.unicode_char)
+ if input_mode&InputAlt != 0 && e.Key == KeyEsc {
+ alt_mode_esc = true
+ return Event{}, false
+ }
+ return e, true
+ }
+ switch r.virtual_key_code {
+ case 192, 50:
+ // manual return here, because KeyCtrl2 is zero
+ e.Key = KeyCtrl2
+ return e, true
+ case 51:
+ if input_mode&InputAlt != 0 {
+ alt_mode_esc = true
+ return Event{}, false
+ }
+ e.Key = KeyCtrl3
+ case 52:
+ e.Key = KeyCtrl4
+ case 53:
+ e.Key = KeyCtrl5
+ case 54:
+ e.Key = KeyCtrl6
+ case 189, 191, 55:
+ e.Key = KeyCtrl7
+ case 8, 56:
+ e.Key = KeyCtrl8
+ }
+
+ if e.Key != 0 {
+ return e, true
+ }
+ }
+
+ if r.unicode_char != 0 {
+ e.Ch = rune(r.unicode_char)
+ return e, true
+ }
+
+ return Event{}, false
+}
+
+func input_event_producer() {
+ var r input_record
+ var err error
+ var last_button Key
+ var last_button_pressed Key
+ var last_state = dword(0)
+ var last_x, last_y = -1, -1
+ handles := []syscall.Handle{in, interrupt}
+ for {
+ err = wait_for_multiple_objects(handles)
+ if err != nil {
+ input_comm <- Event{Type: EventError, Err: err}
+ }
+
+ select {
+ case <-cancel_comm:
+ cancel_done_comm <- true
+ return
+ default:
+ }
+
+ err = read_console_input(in, &r)
+ if err != nil {
+ input_comm <- Event{Type: EventError, Err: err}
+ }
+
+ switch r.event_type {
+ case key_event:
+ kr := (*key_event_record)(unsafe.Pointer(&r.event))
+ ev, ok := key_event_record_to_event(kr)
+ if ok {
+ for i := 0; i < int(kr.repeat_count); i++ {
+ input_comm <- ev
+ }
+ }
+ case window_buffer_size_event:
+ sr := *(*window_buffer_size_record)(unsafe.Pointer(&r.event))
+ input_comm <- Event{
+ Type: EventResize,
+ Width: int(sr.size.x),
+ Height: int(sr.size.y),
+ }
+ case mouse_event:
+ mr := *(*mouse_event_record)(unsafe.Pointer(&r.event))
+ ev := Event{Type: EventMouse}
+ switch mr.event_flags {
+ case 0, 2:
+ // single or double click
+ cur_state := mr.button_state
+ switch {
+ case last_state&mouse_lmb == 0 && cur_state&mouse_lmb != 0:
+ last_button = MouseLeft
+ last_button_pressed = last_button
+ case last_state&mouse_rmb == 0 && cur_state&mouse_rmb != 0:
+ last_button = MouseRight
+ last_button_pressed = last_button
+ case last_state&mouse_mmb == 0 && cur_state&mouse_mmb != 0:
+ last_button = MouseMiddle
+ last_button_pressed = last_button
+ case last_state&mouse_lmb != 0 && cur_state&mouse_lmb == 0:
+ last_button = MouseRelease
+ case last_state&mouse_rmb != 0 && cur_state&mouse_rmb == 0:
+ last_button = MouseRelease
+ case last_state&mouse_mmb != 0 && cur_state&mouse_mmb == 0:
+ last_button = MouseRelease
+ default:
+ last_state = cur_state
+ continue
+ }
+ last_state = cur_state
+ ev.Key = last_button
+ last_x, last_y = int(mr.mouse_pos.x), int(mr.mouse_pos.y)
+ ev.MouseX = last_x
+ ev.MouseY = last_y
+ case 1:
+ // mouse motion
+ x, y := int(mr.mouse_pos.x), int(mr.mouse_pos.y)
+ if last_state != 0 && (last_x != x || last_y != y) {
+ ev.Key = last_button_pressed
+ ev.Mod = ModMotion
+ ev.MouseX = x
+ ev.MouseY = y
+ last_x, last_y = x, y
+ } else {
+ ev.Type = EventNone
+ }
+ case 4:
+ // mouse wheel
+ n := int16(mr.button_state >> 16)
+ if n > 0 {
+ ev.Key = MouseWheelUp
+ } else {
+ ev.Key = MouseWheelDown
+ }
+ last_x, last_y = int(mr.mouse_pos.x), int(mr.mouse_pos.y)
+ ev.MouseX = last_x
+ ev.MouseY = last_y
+ default:
+ ev.Type = EventNone
+ }
+ if ev.Type != EventNone {
+ input_comm <- ev
+ }
+ }
+ }
+}
diff --git a/vendor/github.com/nsf/termbox-go/terminfo.go b/vendor/github.com/nsf/termbox-go/terminfo.go
new file mode 100644
index 00000000..ab2e7a19
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/terminfo.go
@@ -0,0 +1,232 @@
+// +build !windows
+// This file contains a simple and incomplete implementation of the terminfo
+// database. Information was taken from the ncurses manpages term(5) and
+// terminfo(5). Currently, only the string capabilities for special keys and for
+// functions without parameters are actually used. Colors are still done with
+// ANSI escape sequences. Other special features that are not (yet?) supported
+// are reading from ~/.terminfo, the TERMINFO_DIRS variable, Berkeley database
+// format and extended capabilities.
+
+package termbox
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/hex"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "strings"
+)
+
+const (
+ ti_magic = 0432
+ ti_header_length = 12
+ ti_mouse_enter = "\x1b[?1000h\x1b[?1002h\x1b[?1015h\x1b[?1006h"
+ ti_mouse_leave = "\x1b[?1006l\x1b[?1015l\x1b[?1002l\x1b[?1000l"
+)
+
+func load_terminfo() ([]byte, error) {
+ var data []byte
+ var err error
+
+ term := os.Getenv("TERM")
+ if term == "" {
+ return nil, fmt.Errorf("termbox: TERM not set")
+ }
+
+ // The following behaviour follows the one described in terminfo(5) as
+ // distributed by ncurses.
+
+ terminfo := os.Getenv("TERMINFO")
+ if terminfo != "" {
+ // if TERMINFO is set, no other directory should be searched
+ return ti_try_path(terminfo)
+ }
+
+ // next, consider ~/.terminfo
+ home := os.Getenv("HOME")
+ if home != "" {
+ data, err = ti_try_path(home + "/.terminfo")
+ if err == nil {
+ return data, nil
+ }
+ }
+
+ // next, TERMINFO_DIRS
+ dirs := os.Getenv("TERMINFO_DIRS")
+ if dirs != "" {
+ for _, dir := range strings.Split(dirs, ":") {
+ if dir == "" {
+ // "" -> "/usr/share/terminfo"
+ dir = "/usr/share/terminfo"
+ }
+ data, err = ti_try_path(dir)
+ if err == nil {
+ return data, nil
+ }
+ }
+ }
+
+ // next, /lib/terminfo
+ data, err = ti_try_path("/lib/terminfo")
+ if err == nil {
+ return data, nil
+ }
+
+ // fall back to /usr/share/terminfo
+ return ti_try_path("/usr/share/terminfo")
+}
+
+func ti_try_path(path string) (data []byte, err error) {
+ // load_terminfo already made sure it is set
+ term := os.Getenv("TERM")
+
+ // first try, the typical *nix path
+ terminfo := path + "/" + term[0:1] + "/" + term
+ data, err = ioutil.ReadFile(terminfo)
+ if err == nil {
+ return
+ }
+
+ // fallback to darwin specific dirs structure
+ terminfo = path + "/" + hex.EncodeToString([]byte(term[:1])) + "/" + term
+ data, err = ioutil.ReadFile(terminfo)
+ return
+}
+
+func setup_term_builtin() error {
+ name := os.Getenv("TERM")
+ if name == "" {
+ return errors.New("termbox: TERM environment variable not set")
+ }
+
+ for _, t := range terms {
+ if t.name == name {
+ keys = t.keys
+ funcs = t.funcs
+ return nil
+ }
+ }
+
+ compat_table := []struct {
+ partial string
+ keys []string
+ funcs []string
+ }{
+ {"xterm", xterm_keys, xterm_funcs},
+ {"rxvt", rxvt_unicode_keys, rxvt_unicode_funcs},
+ {"linux", linux_keys, linux_funcs},
+ {"Eterm", eterm_keys, eterm_funcs},
+ {"screen", screen_keys, screen_funcs},
+ // let's assume that 'cygwin' is xterm compatible
+ {"cygwin", xterm_keys, xterm_funcs},
+ {"st", xterm_keys, xterm_funcs},
+ }
+
+ // try compatibility variants
+ for _, it := range compat_table {
+ if strings.Contains(name, it.partial) {
+ keys = it.keys
+ funcs = it.funcs
+ return nil
+ }
+ }
+
+ return errors.New("termbox: unsupported terminal")
+}
+
+func setup_term() (err error) {
+ var data []byte
+ var header [6]int16
+ var str_offset, table_offset int16
+
+ data, err = load_terminfo()
+ if err != nil {
+ return setup_term_builtin()
+ }
+
+ rd := bytes.NewReader(data)
+ // 0: magic number, 1: size of names section, 2: size of boolean section, 3:
+ // size of numbers section (in integers), 4: size of the strings section (in
+ // integers), 5: size of the string table
+
+ err = binary.Read(rd, binary.LittleEndian, header[:])
+ if err != nil {
+ return
+ }
+
+ number_sec_len := int16(2)
+ if header[0] == 542 { // doc says it should be octal 0542, but what I see it terminfo files is 542, learn to program please... thank you..
+ number_sec_len = 4
+ }
+
+ if (header[1]+header[2])%2 != 0 {
+ // old quirk to align everything on word boundaries
+ header[2] += 1
+ }
+ str_offset = ti_header_length + header[1] + header[2] + number_sec_len*header[3]
+ table_offset = str_offset + 2*header[4]
+
+ keys = make([]string, 0xFFFF-key_min)
+ for i, _ := range keys {
+ keys[i], err = ti_read_string(rd, str_offset+2*ti_keys[i], table_offset)
+ if err != nil {
+ return
+ }
+ }
+ funcs = make([]string, t_max_funcs)
+ // the last two entries are reserved for mouse. because the table offset is
+ // not there, the two entries have to fill in manually
+ for i, _ := range funcs[:len(funcs)-2] {
+ funcs[i], err = ti_read_string(rd, str_offset+2*ti_funcs[i], table_offset)
+ if err != nil {
+ return
+ }
+ }
+ funcs[t_max_funcs-2] = ti_mouse_enter
+ funcs[t_max_funcs-1] = ti_mouse_leave
+ return nil
+}
+
+func ti_read_string(rd *bytes.Reader, str_off, table int16) (string, error) {
+ var off int16
+
+ _, err := rd.Seek(int64(str_off), 0)
+ if err != nil {
+ return "", err
+ }
+ err = binary.Read(rd, binary.LittleEndian, &off)
+ if err != nil {
+ return "", err
+ }
+ _, err = rd.Seek(int64(table+off), 0)
+ if err != nil {
+ return "", err
+ }
+ var bs []byte
+ for {
+ b, err := rd.ReadByte()
+ if err != nil {
+ return "", err
+ }
+ if b == byte(0x00) {
+ break
+ }
+ bs = append(bs, b)
+ }
+ return string(bs), nil
+}
+
+// "Maps" the function constants from termbox.go to the number of the respective
+// string capability in the terminfo file. Taken from (ncurses) term.h.
+var ti_funcs = []int16{
+ 28, 40, 16, 13, 5, 39, 36, 27, 26, 34, 89, 88,
+}
+
+// Same as above for the special keys.
+var ti_keys = []int16{
+ 66, 68 /* apparently not a typo; 67 is F10 for whatever reason */, 69, 70,
+ 71, 72, 73, 74, 75, 67, 216, 217, 77, 59, 76, 164, 82, 81, 87, 61, 79, 83,
+}
diff --git a/vendor/github.com/nsf/termbox-go/terminfo_builtin.go b/vendor/github.com/nsf/termbox-go/terminfo_builtin.go
new file mode 100644
index 00000000..a9486606
--- /dev/null
+++ b/vendor/github.com/nsf/termbox-go/terminfo_builtin.go
@@ -0,0 +1,64 @@
+// +build !windows
+
+package termbox
+
+// Eterm
+var eterm_keys = []string{
+ "\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",
+}
+var eterm_funcs = []string{
+ "\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", "", "", "", "",
+}
+
+// screen
+var screen_keys = []string{
+ "\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",
+}
+var screen_funcs = []string{
+ "\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,
+}
+
+// xterm
+var xterm_keys = []string{
+ "\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",
+}
+var xterm_funcs = []string{
+ "\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,
+}
+
+// rxvt-unicode
+var rxvt_unicode_keys = []string{
+ "\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",
+}
+var rxvt_unicode_funcs = []string{
+ "\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,
+}
+
+// linux
+var linux_keys = []string{
+ "\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",
+}
+var linux_funcs = []string{
+ "", "", "\x1b[?25h\x1b[?0c", "\x1b[?25l\x1b[?1c", "\x1b[H\x1b[J", "\x1b[0;10m", "\x1b[4m", "\x1b[1m", "\x1b[5m", "\x1b[7m", "", "", "", "",
+}
+
+// rxvt-256color
+var rxvt_256color_keys = []string{
+ "\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",
+}
+var rxvt_256color_funcs = []string{
+ "\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,
+}
+
+var terms = []struct {
+ name string
+ keys []string
+ funcs []string
+}{
+ {"Eterm", eterm_keys, eterm_funcs},
+ {"screen", screen_keys, screen_funcs},
+ {"xterm", xterm_keys, xterm_funcs},
+ {"rxvt-unicode", rxvt_unicode_keys, rxvt_unicode_funcs},
+ {"linux", linux_keys, linux_funcs},
+ {"rxvt-256color", rxvt_256color_keys, rxvt_256color_funcs},
+}