diff --git a/vendor/golang.org/x/text/internal/gen/code.go b/vendor/golang.org/x/text/internal/gen/code.go
new file mode 100644
index 0000000..0389509
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/gen/code.go
@@ -0,0 +1,369 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gen
+
+import (
+	"bytes"
+	"encoding/gob"
+	"fmt"
+	"hash"
+	"hash/fnv"
+	"io"
+	"log"
+	"os"
+	"reflect"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+)
+
+// This file contains utilities for generating code.
+
+// TODO: other write methods like:
+// - slices, maps, types, etc.
+
+// CodeWriter is a utility for writing structured code. It computes the content
+// hash and size of written content. It ensures there are newlines between
+// written code blocks.
+type CodeWriter struct {
+	buf  bytes.Buffer
+	Size int
+	Hash hash.Hash32 // content hash
+	gob  *gob.Encoder
+	// For comments we skip the usual one-line separator if they are followed by
+	// a code block.
+	skipSep bool
+}
+
+func (w *CodeWriter) Write(p []byte) (n int, err error) {
+	return w.buf.Write(p)
+}
+
+// NewCodeWriter returns a new CodeWriter.
+func NewCodeWriter() *CodeWriter {
+	h := fnv.New32()
+	return &CodeWriter{Hash: h, gob: gob.NewEncoder(h)}
+}
+
+// WriteGoFile appends the buffer with the total size of all created structures
+// and writes it as a Go file to the the given file with the given package name.
+func (w *CodeWriter) WriteGoFile(filename, pkg string) {
+	f, err := os.Create(filename)
+	if err != nil {
+		log.Fatalf("Could not create file %s: %v", filename, err)
+	}
+	defer f.Close()
+	if _, err = w.WriteGo(f, pkg, ""); err != nil {
+		log.Fatalf("Error writing file %s: %v", filename, err)
+	}
+}
+
+// WriteVersionedGoFile appends the buffer with the total size of all created
+// structures and writes it as a Go file to the the given file with the given
+// package name and build tags for the current Unicode version,
+func (w *CodeWriter) WriteVersionedGoFile(filename, pkg string) {
+	tags := buildTags()
+	if tags != "" {
+		filename = insertVersion(filename, UnicodeVersion())
+	}
+	f, err := os.Create(filename)
+	if err != nil {
+		log.Fatalf("Could not create file %s: %v", filename, err)
+	}
+	defer f.Close()
+	if _, err = w.WriteGo(f, pkg, tags); err != nil {
+		log.Fatalf("Error writing file %s: %v", filename, err)
+	}
+}
+
+// WriteGo appends the buffer with the total size of all created structures and
+// writes it as a Go file to the the given writer with the given package name.
+func (w *CodeWriter) WriteGo(out io.Writer, pkg, tags string) (n int, err error) {
+	sz := w.Size
+	w.WriteComment("Total table size %d bytes (%dKiB); checksum: %X\n", sz, sz/1024, w.Hash.Sum32())
+	defer w.buf.Reset()
+	return WriteGo(out, pkg, tags, w.buf.Bytes())
+}
+
+func (w *CodeWriter) printf(f string, x ...interface{}) {
+	fmt.Fprintf(w, f, x...)
+}
+
+func (w *CodeWriter) insertSep() {
+	if w.skipSep {
+		w.skipSep = false
+		return
+	}
+	// Use at least two newlines to ensure a blank space between the previous
+	// block. WriteGoFile will remove extraneous newlines.
+	w.printf("\n\n")
+}
+
+// WriteComment writes a comment block. All line starts are prefixed with "//".
+// Initial empty lines are gobbled. The indentation for the first line is
+// stripped from consecutive lines.
+func (w *CodeWriter) WriteComment(comment string, args ...interface{}) {
+	s := fmt.Sprintf(comment, args...)
+	s = strings.Trim(s, "\n")
+
+	// Use at least two newlines to ensure a blank space between the previous
+	// block. WriteGoFile will remove extraneous newlines.
+	w.printf("\n\n// ")
+	w.skipSep = true
+
+	// strip first indent level.
+	sep := "\n"
+	for ; len(s) > 0 && (s[0] == '\t' || s[0] == ' '); s = s[1:] {
+		sep += s[:1]
+	}
+
+	strings.NewReplacer(sep, "\n// ", "\n", "\n// ").WriteString(w, s)
+
+	w.printf("\n")
+}
+
+func (w *CodeWriter) writeSizeInfo(size int) {
+	w.printf("// Size: %d bytes\n", size)
+}
+
+// WriteConst writes a constant of the given name and value.
+func (w *CodeWriter) WriteConst(name string, x interface{}) {
+	w.insertSep()
+	v := reflect.ValueOf(x)
+
+	switch v.Type().Kind() {
+	case reflect.String:
+		w.printf("const %s %s = ", name, typeName(x))
+		w.WriteString(v.String())
+		w.printf("\n")
+	default:
+		w.printf("const %s = %#v\n", name, x)
+	}
+}
+
+// WriteVar writes a variable of the given name and value.
+func (w *CodeWriter) WriteVar(name string, x interface{}) {
+	w.insertSep()
+	v := reflect.ValueOf(x)
+	oldSize := w.Size
+	sz := int(v.Type().Size())
+	w.Size += sz
+
+	switch v.Type().Kind() {
+	case reflect.String:
+		w.printf("var %s %s = ", name, typeName(x))
+		w.WriteString(v.String())
+	case reflect.Struct:
+		w.gob.Encode(x)
+		fallthrough
+	case reflect.Slice, reflect.Array:
+		w.printf("var %s = ", name)
+		w.writeValue(v)
+		w.writeSizeInfo(w.Size - oldSize)
+	default:
+		w.printf("var %s %s = ", name, typeName(x))
+		w.gob.Encode(x)
+		w.writeValue(v)
+		w.writeSizeInfo(w.Size - oldSize)
+	}
+	w.printf("\n")
+}
+
+func (w *CodeWriter) writeValue(v reflect.Value) {
+	x := v.Interface()
+	switch v.Kind() {
+	case reflect.String:
+		w.WriteString(v.String())
+	case reflect.Array:
+		// Don't double count: callers of WriteArray count on the size being
+		// added, so we need to discount it here.
+		w.Size -= int(v.Type().Size())
+		w.writeSlice(x, true)
+	case reflect.Slice:
+		w.writeSlice(x, false)
+	case reflect.Struct:
+		w.printf("%s{\n", typeName(v.Interface()))
+		t := v.Type()
+		for i := 0; i < v.NumField(); i++ {
+			w.printf("%s: ", t.Field(i).Name)
+			w.writeValue(v.Field(i))
+			w.printf(",\n")
+		}
+		w.printf("}")
+	default:
+		w.printf("%#v", x)
+	}
+}
+
+// WriteString writes a string literal.
+func (w *CodeWriter) WriteString(s string) {
+	s = strings.Replace(s, `\`, `\\`, -1)
+	io.WriteString(w.Hash, s) // content hash
+	w.Size += len(s)
+
+	const maxInline = 40
+	if len(s) <= maxInline {
+		w.printf("%q", s)
+		return
+	}
+
+	// We will render the string as a multi-line string.
+	const maxWidth = 80 - 4 - len(`"`) - len(`" +`)
+
+	// When starting on its own line, go fmt indents line 2+ an extra level.
+	n, max := maxWidth, maxWidth-4
+
+	// As per https://golang.org/issue/18078, the compiler has trouble
+	// compiling the concatenation of many strings, s0 + s1 + s2 + ... + sN,
+	// for large N. We insert redundant, explicit parentheses to work around
+	// that, lowering the N at any given step: (s0 + s1 + ... + s63) + (s64 +
+	// ... + s127) + etc + (etc + ... + sN).
+	explicitParens, extraComment := len(s) > 128*1024, ""
+	if explicitParens {
+		w.printf(`(`)
+		extraComment = "; the redundant, explicit parens are for https://golang.org/issue/18078"
+	}
+
+	// Print "" +\n, if a string does not start on its own line.
+	b := w.buf.Bytes()
+	if p := len(bytes.TrimRight(b, " \t")); p > 0 && b[p-1] != '\n' {
+		w.printf("\"\" + // Size: %d bytes%s\n", len(s), extraComment)
+		n, max = maxWidth, maxWidth
+	}
+
+	w.printf(`"`)
+
+	for sz, p, nLines := 0, 0, 0; p < len(s); {
+		var r rune
+		r, sz = utf8.DecodeRuneInString(s[p:])
+		out := s[p : p+sz]
+		chars := 1
+		if !unicode.IsPrint(r) || r == utf8.RuneError || r == '"' {
+			switch sz {
+			case 1:
+				out = fmt.Sprintf("\\x%02x", s[p])
+			case 2, 3:
+				out = fmt.Sprintf("\\u%04x", r)
+			case 4:
+				out = fmt.Sprintf("\\U%08x", r)
+			}
+			chars = len(out)
+		}
+		if n -= chars; n < 0 {
+			nLines++
+			if explicitParens && nLines&63 == 63 {
+				w.printf("\") + (\"")
+			}
+			w.printf("\" +\n\"")
+			n = max - len(out)
+		}
+		w.printf("%s", out)
+		p += sz
+	}
+	w.printf(`"`)
+	if explicitParens {
+		w.printf(`)`)
+	}
+}
+
+// WriteSlice writes a slice value.
+func (w *CodeWriter) WriteSlice(x interface{}) {
+	w.writeSlice(x, false)
+}
+
+// WriteArray writes an array value.
+func (w *CodeWriter) WriteArray(x interface{}) {
+	w.writeSlice(x, true)
+}
+
+func (w *CodeWriter) writeSlice(x interface{}, isArray bool) {
+	v := reflect.ValueOf(x)
+	w.gob.Encode(v.Len())
+	w.Size += v.Len() * int(v.Type().Elem().Size())
+	name := typeName(x)
+	if isArray {
+		name = fmt.Sprintf("[%d]%s", v.Len(), name[strings.Index(name, "]")+1:])
+	}
+	if isArray {
+		w.printf("%s{\n", name)
+	} else {
+		w.printf("%s{ // %d elements\n", name, v.Len())
+	}
+
+	switch kind := v.Type().Elem().Kind(); kind {
+	case reflect.String:
+		for _, s := range x.([]string) {
+			w.WriteString(s)
+			w.printf(",\n")
+		}
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		// nLine and nBlock are the number of elements per line and block.
+		nLine, nBlock, format := 8, 64, "%d,"
+		switch kind {
+		case reflect.Uint8:
+			format = "%#02x,"
+		case reflect.Uint16:
+			format = "%#04x,"
+		case reflect.Uint32:
+			nLine, nBlock, format = 4, 32, "%#08x,"
+		case reflect.Uint, reflect.Uint64:
+			nLine, nBlock, format = 4, 32, "%#016x,"
+		case reflect.Int8:
+			nLine = 16
+		}
+		n := nLine
+		for i := 0; i < v.Len(); i++ {
+			if i%nBlock == 0 && v.Len() > nBlock {
+				w.printf("// Entry %X - %X\n", i, i+nBlock-1)
+			}
+			x := v.Index(i).Interface()
+			w.gob.Encode(x)
+			w.printf(format, x)
+			if n--; n == 0 {
+				n = nLine
+				w.printf("\n")
+			}
+		}
+		w.printf("\n")
+	case reflect.Struct:
+		zero := reflect.Zero(v.Type().Elem()).Interface()
+		for i := 0; i < v.Len(); i++ {
+			x := v.Index(i).Interface()
+			w.gob.EncodeValue(v)
+			if !reflect.DeepEqual(zero, x) {
+				line := fmt.Sprintf("%#v,\n", x)
+				line = line[strings.IndexByte(line, '{'):]
+				w.printf("%d: ", i)
+				w.printf(line)
+			}
+		}
+	case reflect.Array:
+		for i := 0; i < v.Len(); i++ {
+			w.printf("%d: %#v,\n", i, v.Index(i).Interface())
+		}
+	default:
+		panic("gen: slice elem type not supported")
+	}
+	w.printf("}")
+}
+
+// WriteType writes a definition of the type of the given value and returns the
+// type name.
+func (w *CodeWriter) WriteType(x interface{}) string {
+	t := reflect.TypeOf(x)
+	w.printf("type %s struct {\n", t.Name())
+	for i := 0; i < t.NumField(); i++ {
+		w.printf("\t%s %s\n", t.Field(i).Name, t.Field(i).Type)
+	}
+	w.printf("}\n")
+	return t.Name()
+}
+
+// typeName returns the name of the go type of x.
+func typeName(x interface{}) string {
+	t := reflect.ValueOf(x).Type()
+	return strings.Replace(fmt.Sprint(t), "main.", "", 1)
+}
diff --git a/vendor/golang.org/x/text/internal/gen/gen.go b/vendor/golang.org/x/text/internal/gen/gen.go
new file mode 100644
index 0000000..4c3f760
--- /dev/null
+++ b/vendor/golang.org/x/text/internal/gen/gen.go
@@ -0,0 +1,333 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package gen contains common code for the various code generation tools in the
+// text repository. Its usage ensures consistency between tools.
+//
+// This package defines command line flags that are common to most generation
+// tools. The flags allow for specifying specific Unicode and CLDR versions
+// in the public Unicode data repository (http://www.unicode.org/Public).
+//
+// A local Unicode data mirror can be set through the flag -local or the
+// environment variable UNICODE_DIR. The former takes precedence. The local
+// directory should follow the same structure as the public repository.
+//
+// IANA data can also optionally be mirrored by putting it in the iana directory
+// rooted at the top of the local mirror. Beware, though, that IANA data is not
+// versioned. So it is up to the developer to use the right version.
+package gen // import "golang.org/x/text/internal/gen"
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/build"
+	"go/format"
+	"io"
+	"io/ioutil"
+	"log"
+	"net/http"
+	"os"
+	"path"
+	"path/filepath"
+	"strings"
+	"sync"
+	"unicode"
+
+	"golang.org/x/text/unicode/cldr"
+)
+
+var (
+	url = flag.String("url",
+		"http://www.unicode.org/Public",
+		"URL of Unicode database directory")
+	iana = flag.String("iana",
+		"http://www.iana.org",
+		"URL of the IANA repository")
+	unicodeVersion = flag.String("unicode",
+		getEnv("UNICODE_VERSION", unicode.Version),
+		"unicode version to use")
+	cldrVersion = flag.String("cldr",
+		getEnv("CLDR_VERSION", cldr.Version),
+		"cldr version to use")
+)
+
+func getEnv(name, def string) string {
+	if v := os.Getenv(name); v != "" {
+		return v
+	}
+	return def
+}
+
+// Init performs common initialization for a gen command. It parses the flags
+// and sets up the standard logging parameters.
+func Init() {
+	log.SetPrefix("")
+	log.SetFlags(log.Lshortfile)
+	flag.Parse()
+}
+
+const header = `// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+`
+
+// UnicodeVersion reports the requested Unicode version.
+func UnicodeVersion() string {
+	return *unicodeVersion
+}
+
+// CLDRVersion reports the requested CLDR version.
+func CLDRVersion() string {
+	return *cldrVersion
+}
+
+var tags = []struct{ version, buildTags string }{
+	{"10.0.0", "go1.10"},
+	{"", "!go1.10"},
+}
+
+// buildTags reports the build tags used for the current Unicode version.
+func buildTags() string {
+	v := UnicodeVersion()
+	for _, x := range tags {
+		// We should do a numeric comparison, but including the collate package
+		// would create an import cycle. We approximate it by assuming that
+		// longer version strings are later.
+		if len(x.version) <= len(v) {
+			return x.buildTags
+		}
+		if len(x.version) == len(v) && x.version <= v {
+			return x.buildTags
+		}
+	}
+	return tags[0].buildTags
+}
+
+// IsLocal reports whether data files are available locally.
+func IsLocal() bool {
+	dir, err := localReadmeFile()
+	if err != nil {
+		return false
+	}
+	if _, err = os.Stat(dir); err != nil {
+		return false
+	}
+	return true
+}
+
+// OpenUCDFile opens the requested UCD file. The file is specified relative to
+// the public Unicode root directory. It will call log.Fatal if there are any
+// errors.
+func OpenUCDFile(file string) io.ReadCloser {
+	return openUnicode(path.Join(*unicodeVersion, "ucd", file))
+}
+
+// OpenCLDRCoreZip opens the CLDR core zip file. It will call log.Fatal if there
+// are any errors.
+func OpenCLDRCoreZip() io.ReadCloser {
+	return OpenUnicodeFile("cldr", *cldrVersion, "core.zip")
+}
+
+// OpenUnicodeFile opens the requested file of the requested category from the
+// root of the Unicode data archive. The file is specified relative to the
+// public Unicode root directory. If version is "", it will use the default
+// Unicode version. It will call log.Fatal if there are any errors.
+func OpenUnicodeFile(category, version, file string) io.ReadCloser {
+	if version == "" {
+		version = UnicodeVersion()
+	}
+	return openUnicode(path.Join(category, version, file))
+}
+
+// OpenIANAFile opens the requested IANA file. The file is specified relative
+// to the IANA root, which is typically either http://www.iana.org or the
+// iana directory in the local mirror. It will call log.Fatal if there are any
+// errors.
+func OpenIANAFile(path string) io.ReadCloser {
+	return Open(*iana, "iana", path)
+}
+
+var (
+	dirMutex sync.Mutex
+	localDir string
+)
+
+const permissions = 0755
+
+func localReadmeFile() (string, error) {
+	p, err := build.Import("golang.org/x/text", "", build.FindOnly)
+	if err != nil {
+		return "", fmt.Errorf("Could not locate package: %v", err)
+	}
+	return filepath.Join(p.Dir, "DATA", "README"), nil
+}
+
+func getLocalDir() string {
+	dirMutex.Lock()
+	defer dirMutex.Unlock()
+
+	readme, err := localReadmeFile()
+	if err != nil {
+		log.Fatal(err)
+	}
+	dir := filepath.Dir(readme)
+	if _, err := os.Stat(readme); err != nil {
+		if err := os.MkdirAll(dir, permissions); err != nil {
+			log.Fatalf("Could not create directory: %v", err)
+		}
+		ioutil.WriteFile(readme, []byte(readmeTxt), permissions)
+	}
+	return dir
+}
+
+const readmeTxt = `Generated by golang.org/x/text/internal/gen. DO NOT EDIT.
+
+This directory contains downloaded files used to generate the various tables
+in the golang.org/x/text subrepo.
+
+Note that the language subtag repo (iana/assignments/language-subtag-registry)
+and all other times in the iana subdirectory are not versioned and will need
+to be periodically manually updated. The easiest way to do this is to remove
+the entire iana directory. This is mostly of concern when updating the language
+package.
+`
+
+// Open opens subdir/path if a local directory is specified and the file exists,
+// where subdir is a directory relative to the local root, or fetches it from
+// urlRoot/path otherwise. It will call log.Fatal if there are any errors.
+func Open(urlRoot, subdir, path string) io.ReadCloser {
+	file := filepath.Join(getLocalDir(), subdir, filepath.FromSlash(path))
+	return open(file, urlRoot, path)
+}
+
+func openUnicode(path string) io.ReadCloser {
+	file := filepath.Join(getLocalDir(), filepath.FromSlash(path))
+	return open(file, *url, path)
+}
+
+// TODO: automatically periodically update non-versioned files.
+
+func open(file, urlRoot, path string) io.ReadCloser {
+	if f, err := os.Open(file); err == nil {
+		return f
+	}
+	r := get(urlRoot, path)
+	defer r.Close()
+	b, err := ioutil.ReadAll(r)
+	if err != nil {
+		log.Fatalf("Could not download file: %v", err)
+	}
+	os.MkdirAll(filepath.Dir(file), permissions)
+	if err := ioutil.WriteFile(file, b, permissions); err != nil {
+		log.Fatalf("Could not create file: %v", err)
+	}
+	return ioutil.NopCloser(bytes.NewReader(b))
+}
+
+func get(root, path string) io.ReadCloser {
+	url := root + "/" + path
+	fmt.Printf("Fetching %s...", url)
+	defer fmt.Println(" done.")
+	resp, err := http.Get(url)
+	if err != nil {
+		log.Fatalf("HTTP GET: %v", err)
+	}
+	if resp.StatusCode != 200 {
+		log.Fatalf("Bad GET status for %q: %q", url, resp.Status)
+	}
+	return resp.Body
+}
+
+// TODO: use Write*Version in all applicable packages.
+
+// WriteUnicodeVersion writes a constant for the Unicode version from which the
+// tables are generated.
+func WriteUnicodeVersion(w io.Writer) {
+	fmt.Fprintf(w, "// UnicodeVersion is the Unicode version from which the tables in this package are derived.\n")
+	fmt.Fprintf(w, "const UnicodeVersion = %q\n\n", UnicodeVersion())
+}
+
+// WriteCLDRVersion writes a constant for the CLDR version from which the
+// tables are generated.
+func WriteCLDRVersion(w io.Writer) {
+	fmt.Fprintf(w, "// CLDRVersion is the CLDR version from which the tables in this package are derived.\n")
+	fmt.Fprintf(w, "const CLDRVersion = %q\n\n", CLDRVersion())
+}
+
+// WriteGoFile prepends a standard file comment and package statement to the
+// given bytes, applies gofmt, and writes them to a file with the given name.
+// It will call log.Fatal if there are any errors.
+func WriteGoFile(filename, pkg string, b []byte) {
+	w, err := os.Create(filename)
+	if err != nil {
+		log.Fatalf("Could not create file %s: %v", filename, err)
+	}
+	defer w.Close()
+	if _, err = WriteGo(w, pkg, "", b); err != nil {
+		log.Fatalf("Error writing file %s: %v", filename, err)
+	}
+}
+
+func insertVersion(filename, version string) string {
+	suffix := ".go"
+	if strings.HasSuffix(filename, "_test.go") {
+		suffix = "_test.go"
+	}
+	return fmt.Sprint(filename[:len(filename)-len(suffix)], version, suffix)
+}
+
+// WriteVersionedGoFile prepends a standard file comment, adds build tags to
+// version the file for the current Unicode version, and package statement to
+// the given bytes, applies gofmt, and writes them to a file with the given
+// name. It will call log.Fatal if there are any errors.
+func WriteVersionedGoFile(filename, pkg string, b []byte) {
+	tags := buildTags()
+	if tags != "" {
+		filename = insertVersion(filename, UnicodeVersion())
+	}
+	w, err := os.Create(filename)
+	if err != nil {
+		log.Fatalf("Could not create file %s: %v", filename, err)
+	}
+	defer w.Close()
+	if _, err = WriteGo(w, pkg, tags, b); err != nil {
+		log.Fatalf("Error writing file %s: %v", filename, err)
+	}
+}
+
+// WriteGo prepends a standard file comment and package statement to the given
+// bytes, applies gofmt, and writes them to w.
+func WriteGo(w io.Writer, pkg, tags string, b []byte) (n int, err error) {
+	src := []byte(header)
+	if tags != "" {
+		src = append(src, fmt.Sprintf("// +build %s\n\n", tags)...)
+	}
+	src = append(src, fmt.Sprintf("package %s\n\n", pkg)...)
+	src = append(src, b...)
+	formatted, err := format.Source(src)
+	if err != nil {
+		// Print the generated code even in case of an error so that the
+		// returned error can be meaningfully interpreted.
+		n, _ = w.Write(src)
+		return n, err
+	}
+	return w.Write(formatted)
+}
+
+// Repackage rewrites a Go file from belonging to package main to belonging to
+// the given package.
+func Repackage(inFile, outFile, pkg string) {
+	src, err := ioutil.ReadFile(inFile)
+	if err != nil {
+		log.Fatalf("reading %s: %v", inFile, err)
+	}
+	const toDelete = "package main\n\n"
+	i := bytes.Index(src, []byte(toDelete))
+	if i < 0 {
+		log.Fatalf("Could not find %q in %s.", toDelete, inFile)
+	}
+	w := &bytes.Buffer{}
+	w.Write(src[i+len(toDelete):])
+	WriteGoFile(outFile, pkg, w.Bytes())
+}
