Full Code of mailhog/MailHog for AI

master e6fa06877ef6 cached
273 files
3.3 MB
881.7k tokens
2660 symbols
1 requests
Download .txt
Showing preview only (3,522K chars total). Download the full file or copy to clipboard to get everything.
Repository: mailhog/MailHog
Branch: master
Commit: e6fa06877ef6
Files: 273
Total size: 3.3 MB

Directory structure:
gitextract_kj7nbxlu/

├── .dockerignore
├── .gitignore
├── .travis.yml
├── Dockerfile
├── LICENSE.md
├── Makefile
├── README.md
├── config/
│   └── config.go
├── docs/
│   ├── APIv1.md
│   ├── APIv2/
│   │   ├── swagger-2.0.json
│   │   └── swagger-2.0.yaml
│   ├── APIv2.md
│   ├── Auth.md
│   ├── BUILD.md
│   ├── CONFIG.md
│   ├── DEPLOY.md
│   ├── JIM.md
│   ├── LIBRARIES.md
│   ├── RELEASES.md
│   └── example-auth
├── main.go
├── snapcraft.yaml
└── vendor/
    ├── github.com/
    │   ├── gorilla/
    │   │   ├── context/
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── context.go
    │   │   │   └── doc.go
    │   │   ├── mux/
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── context_gorilla.go
    │   │   │   ├── context_native.go
    │   │   │   ├── doc.go
    │   │   │   ├── mux.go
    │   │   │   ├── regexp.go
    │   │   │   └── route.go
    │   │   ├── pat/
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── doc.go
    │   │   │   └── pat.go
    │   │   └── websocket/
    │   │       ├── AUTHORS
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── client.go
    │   │       ├── client_clone.go
    │   │       ├── client_clone_legacy.go
    │   │       ├── compression.go
    │   │       ├── conn.go
    │   │       ├── conn_read.go
    │   │       ├── conn_read_legacy.go
    │   │       ├── doc.go
    │   │       ├── json.go
    │   │       ├── mask.go
    │   │       ├── mask_safe.go
    │   │       ├── prepared.go
    │   │       ├── server.go
    │   │       └── util.go
    │   ├── ian-kent/
    │   │   ├── envconf/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── README.md
    │   │   │   └── envconf.go
    │   │   ├── go-log/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── appenders/
    │   │   │   │   ├── appender.go
    │   │   │   │   ├── console.go
    │   │   │   │   ├── fluentd.go
    │   │   │   │   ├── multiple_appender.go
    │   │   │   │   ├── rollingfile.go
    │   │   │   │   ├── rollingfile_test.log
    │   │   │   │   └── rollingfile_test.log.1
    │   │   │   ├── layout/
    │   │   │   │   ├── basic.go
    │   │   │   │   ├── layout.go
    │   │   │   │   └── pattern.go
    │   │   │   ├── levels/
    │   │   │   │   └── levels.go
    │   │   │   ├── log/
    │   │   │   │   └── log.go
    │   │   │   └── logger/
    │   │   │       └── logger.go
    │   │   ├── goose/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── README.md
    │   │   │   └── goose.go
    │   │   └── linkio/
    │   │       ├── README.md
    │   │       └── linkio.go
    │   ├── jtolds/
    │   │   └── gls/
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── context.go
    │   │       ├── gen_sym.go
    │   │       ├── gid.go
    │   │       ├── id_pool.go
    │   │       ├── stack_tags.go
    │   │       ├── stack_tags_js.go
    │   │       └── stack_tags_main.go
    │   ├── mailhog/
    │   │   ├── MailHog-Server/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── Makefile
    │   │   │   ├── README.md
    │   │   │   ├── api/
    │   │   │   │   ├── api.go
    │   │   │   │   ├── v1.go
    │   │   │   │   └── v2.go
    │   │   │   ├── config/
    │   │   │   │   └── config.go
    │   │   │   ├── main.go
    │   │   │   ├── monkey/
    │   │   │   │   ├── jim.go
    │   │   │   │   └── monkey.go
    │   │   │   ├── smtp/
    │   │   │   │   ├── session.go
    │   │   │   │   ├── session_test.go
    │   │   │   │   └── smtp.go
    │   │   │   └── websockets/
    │   │   │       ├── connection.go
    │   │   │       └── hub.go
    │   │   ├── MailHog-UI/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── Makefile
    │   │   │   ├── README.md
    │   │   │   ├── assets/
    │   │   │   │   └── assets.go
    │   │   │   ├── config/
    │   │   │   │   └── config.go
    │   │   │   ├── main.go
    │   │   │   └── web/
    │   │   │       └── web.go
    │   │   ├── data/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── README.md
    │   │   │   └── message.go
    │   │   ├── http/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── README.md
    │   │   │   └── server.go
    │   │   ├── mhsendmail/
    │   │   │   ├── LICENSE.md
    │   │   │   └── cmd/
    │   │   │       └── cmd.go
    │   │   ├── smtp/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── README.md
    │   │   │   ├── protocol.go
    │   │   │   ├── reply.go
    │   │   │   └── state.go
    │   │   └── storage/
    │   │       ├── LICENSE.md
    │   │       ├── README.md
    │   │       ├── maildir.go
    │   │       ├── memory.go
    │   │       ├── mongodb.go
    │   │       └── storage.go
    │   ├── philhofer/
    │   │   └── fwd/
    │   │       ├── LICENSE.md
    │   │       ├── README.md
    │   │       ├── reader.go
    │   │       ├── writer.go
    │   │       ├── writer_appengine.go
    │   │       └── writer_unsafe.go
    │   ├── smartystreets/
    │   │   ├── assertions/
    │   │   │   ├── CONTRIBUTING.md
    │   │   │   ├── LICENSE.md
    │   │   │   ├── README.md
    │   │   │   ├── collections.go
    │   │   │   ├── doc.go
    │   │   │   ├── equality.go
    │   │   │   ├── filter.go
    │   │   │   ├── internal/
    │   │   │   │   ├── go-render/
    │   │   │   │   │   ├── LICENSE
    │   │   │   │   │   └── render/
    │   │   │   │   │       └── render.go
    │   │   │   │   └── oglematchers/
    │   │   │   │       ├── LICENSE
    │   │   │   │       ├── README.md
    │   │   │   │       ├── any_of.go
    │   │   │   │       ├── contains.go
    │   │   │   │       ├── deep_equals.go
    │   │   │   │       ├── equals.go
    │   │   │   │       ├── greater_or_equal.go
    │   │   │   │       ├── greater_than.go
    │   │   │   │       ├── less_or_equal.go
    │   │   │   │       ├── less_than.go
    │   │   │   │       ├── matcher.go
    │   │   │   │       ├── not.go
    │   │   │   │       └── transform_description.go
    │   │   │   ├── messages.go
    │   │   │   ├── panic.go
    │   │   │   ├── quantity.go
    │   │   │   ├── serializer.go
    │   │   │   ├── strings.go
    │   │   │   ├── time.go
    │   │   │   └── type.go
    │   │   └── goconvey/
    │   │       ├── LICENSE.md
    │   │       └── convey/
    │   │           ├── assertions.go
    │   │           ├── context.go
    │   │           ├── convey.goconvey
    │   │           ├── discovery.go
    │   │           ├── doc.go
    │   │           ├── gotest/
    │   │           │   └── utils.go
    │   │           ├── init.go
    │   │           ├── nilReporter.go
    │   │           └── reporting/
    │   │               ├── console.go
    │   │               ├── doc.go
    │   │               ├── dot.go
    │   │               ├── gotest.go
    │   │               ├── init.go
    │   │               ├── json.go
    │   │               ├── printer.go
    │   │               ├── problems.go
    │   │               ├── reporter.go
    │   │               ├── reporting.goconvey
    │   │               ├── reports.go
    │   │               ├── statistics.go
    │   │               └── story.go
    │   ├── spf13/
    │   │   └── pflag/
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── bool.go
    │   │       ├── count.go
    │   │       ├── duration.go
    │   │       ├── flag.go
    │   │       ├── float32.go
    │   │       ├── float64.go
    │   │       ├── golangflag.go
    │   │       ├── int.go
    │   │       ├── int32.go
    │   │       ├── int64.go
    │   │       ├── int8.go
    │   │       ├── int_slice.go
    │   │       ├── ip.go
    │   │       ├── ipmask.go
    │   │       ├── ipnet.go
    │   │       ├── string.go
    │   │       ├── string_slice.go
    │   │       ├── uint.go
    │   │       ├── uint16.go
    │   │       ├── uint32.go
    │   │       ├── uint64.go
    │   │       └── uint8.go
    │   ├── t-k/
    │   │   └── fluent-logger-golang/
    │   │       ├── LICENSE
    │   │       └── fluent/
    │   │           ├── fluent.go
    │   │           ├── proto.go
    │   │           ├── proto_gen.go
    │   │           └── version.go
    │   └── tinylib/
    │       └── msgp/
    │           ├── LICENSE
    │           └── msgp/
    │               ├── advise_linux.go
    │               ├── advise_other.go
    │               ├── appengine.go
    │               ├── circular.go
    │               ├── defs.go
    │               ├── edit.go
    │               ├── elsize.go
    │               ├── errors.go
    │               ├── extension.go
    │               ├── file.go
    │               ├── file_port.go
    │               ├── integers.go
    │               ├── json.go
    │               ├── json_bytes.go
    │               ├── number.go
    │               ├── read.go
    │               ├── read_bytes.go
    │               ├── size.go
    │               ├── unsafe.go
    │               ├── write.go
    │               └── write_bytes.go
    ├── golang.org/
    │   └── x/
    │       └── crypto/
    │           ├── LICENSE
    │           ├── PATENTS
    │           ├── bcrypt/
    │           │   ├── base64.go
    │           │   └── bcrypt.go
    │           └── blowfish/
    │               ├── block.go
    │               ├── cipher.go
    │               └── const.go
    ├── gopkg.in/
    │   └── mgo.v2/
    │       ├── LICENSE
    │       ├── Makefile
    │       ├── README.md
    │       ├── auth.go
    │       ├── bson/
    │       │   ├── LICENSE
    │       │   ├── bson.go
    │       │   ├── decode.go
    │       │   └── encode.go
    │       ├── bulk.go
    │       ├── cluster.go
    │       ├── doc.go
    │       ├── gridfs.go
    │       ├── internal/
    │       │   ├── sasl/
    │       │   │   ├── sasl.c
    │       │   │   ├── sasl.go
    │       │   │   ├── sasl_windows.c
    │       │   │   ├── sasl_windows.go
    │       │   │   ├── sasl_windows.h
    │       │   │   ├── sspi_windows.c
    │       │   │   └── sspi_windows.h
    │       │   └── scram/
    │       │       └── scram.go
    │       ├── log.go
    │       ├── queue.go
    │       ├── raceoff.go
    │       ├── raceon.go
    │       ├── saslimpl.go
    │       ├── saslstub.go
    │       ├── server.go
    │       ├── session.go
    │       ├── socket.go
    │       └── stats.go
    └── vendor.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
*


================================================
FILE: .gitignore
================================================
build/


================================================
FILE: .travis.yml
================================================
language: go
go:
 - 1.6
 - tip


================================================
FILE: Dockerfile
================================================
#
# MailHog Dockerfile
#

FROM golang:1.18-alpine as builder

# Install MailHog:
RUN apk --no-cache add --virtual build-dependencies \
    git \
  && mkdir -p /root/gocode \
  && export GOPATH=/root/gocode \
  && go install github.com/mailhog/MailHog@latest

FROM alpine:3
# Add mailhog user/group with uid/gid 1000.
# This is a workaround for boot2docker issue #581, see
# https://github.com/boot2docker/boot2docker/issues/581
RUN adduser -D -u 1000 mailhog

COPY --from=builder /root/gocode/bin/MailHog /usr/local/bin/

USER mailhog

WORKDIR /home/mailhog

ENTRYPOINT ["MailHog"]

# Expose the SMTP and HTTP ports:
EXPOSE 1025 8025


================================================
FILE: LICENSE.md
================================================
The MIT License (MIT)

Copyright (c) 2014 - 2016 Ian Kent

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.


================================================
FILE: Makefile
================================================
VERSION=1.0.0

all: fmt combined

combined:
	go install .

release: tag release-deps 
	gox -ldflags "-X main.version=${VERSION}" -output="build/{{.Dir}}_{{.OS}}_{{.Arch}}" .

fmt:
	go fmt ./...

release-deps:
	go get github.com/mitchellh/gox

pull:
	git pull
	cd ../data; git pull
	cd ../http; git pull
	cd ../MailHog-Server; git pull
	cd ../MailHog-UI; git pull
	cd ../smtp; git pull
	cd ../storage; git pull

tag:
	git tag -a -m 'v${VERSION}' v${VERSION} && git push origin v${VERSION}
	cd ../data; git tag -a -m 'v${VERSION}' v${VERSION} && git push origin v${VERSION}
	cd ../http; git tag -a -m 'v${VERSION}' v${VERSION} && git push origin v${VERSION}
	cd ../MailHog-Server; git tag -a -m 'v${VERSION}' v${VERSION} && git push origin v${VERSION}
	cd ../MailHog-UI; git tag -a -m 'v${VERSION}' v${VERSION} && git push origin v${VERSION}
	cd ../smtp; git tag -a -m 'v${VERSION}' v${VERSION} && git push origin v${VERSION}
	cd ../storage; git tag -a -m 'v${VERSION}' v${VERSION} && git push origin v${VERSION}

.PHONY: all combined release fmt release-deps pull tag


================================================
FILE: README.md
================================================
MailHog [ ![Download](https://img.shields.io/github/release/mailhog/MailHog.svg) ](https://github.com/mailhog/MailHog/releases/tag/v1.0.0) [![GoDoc](https://godoc.org/github.com/mailhog/MailHog?status.svg)](https://godoc.org/github.com/mailhog/MailHog) [![Build Status](https://travis-ci.org/mailhog/MailHog.svg?branch=master)](https://travis-ci.org/mailhog/MailHog)
=========

Inspired by [MailCatcher](https://mailcatcher.me/), easier to install.

* Download and run MailHog
* Configure your outgoing SMTP server
* View your outgoing email in a web UI
* Release it to a real mail server

Built with Go - MailHog runs without installation on multiple platforms.

### Overview

MailHog is an email testing tool for developers:

* Configure your application to use MailHog for SMTP delivery
* View messages in the web UI, or retrieve them with the JSON API
* Optionally release messages to real SMTP servers for delivery

### Installation

#### Manual installation
[Download the latest release for your platform](/docs/RELEASES.md). Then
[read the deployment guide](/docs/DEPLOY.md) for deployment options.

#### MacOS
```bash
brew update && brew install mailhog
```

Then, start MailHog by running `mailhog` in the command line.

#### Debian / Ubuntu Go < v1.18
```bash
sudo apt-get -y install golang-go
go get github.com/mailhog/MailHog
```

#### Go >= v1.17 (Debian Bookworm) 
```bash
sudo apt-get -y install golang-go
go install github.com/mailhog/MailHog@latest
```

Then, start MailHog by running `/path/to/MailHog` in the command line.

E.g. the path to Go's bin files on Ubuntu is `~/go/bin/`, so to start the MailHog run:

```bash
~/go/bin/MailHog
```

#### FreeBSD
```bash
pkg install mailhog
sysrc mailhog_enable="YES"
service mailhog start
```

#### Docker
[Run it from Docker Hub](https://registry.hub.docker.com/r/mailhog/mailhog/) or using the provided [Dockerfile](Dockerfile)

### Configuration

Check out how to [configure MailHog](/docs/CONFIG.md), or use the default settings:
  * the SMTP server starts on port 1025
  * the HTTP server starts on port 8025
  * in-memory message storage

### Features

See [MailHog libraries](docs/LIBRARIES.md) for a list of MailHog client libraries.

* ESMTP server implementing RFC5321
* Support for SMTP AUTH (RFC4954) and PIPELINING (RFC2920)
* Web interface to view messages (plain text, HTML or source)
  * Supports RFC2047 encoded headers
* Real-time updates using EventSource
* Release messages to real SMTP servers
* Chaos Monkey for failure testing
  * See [Introduction to Jim](/docs/JIM.md) for more information
* HTTP API to list, retrieve and delete messages
  * See [APIv1](/docs/APIv1.md) and [APIv2](/docs/APIv2.md) documentation for more information
* [HTTP basic authentication](docs/Auth.md) for MailHog UI and API
* Multipart MIME support
* Download individual MIME parts
* In-memory message storage
* MongoDB and file based storage for message persistence
* Lightweight and portable
* No installation required

#### sendmail

[mhsendmail](https://github.com/mailhog/mhsendmail) is a sendmail replacement for MailHog.

It redirects mail to MailHog using SMTP.

You can also use `MailHog sendmail ...` instead of the separate mhsendmail binary.

Alternatively, you can use your native `sendmail` command by providing `-S`, for example:

```bash
/usr/sbin/sendmail -S mail:1025
```

For example, in PHP you could add either of these lines to `php.ini`:

```
sendmail_path = /usr/local/bin/mhsendmail
sendmail_path = /usr/sbin/sendmail -S mail:1025
```

#### Web UI

![Screenshot of MailHog web interface](/docs/MailHog.png "MailHog web interface")

### Contributing

MailHog is a rewritten version of [MailHog](https://github.com/ian-kent/MailHog), which was born out of [M3MTA](https://github.com/ian-kent/M3MTA).

Clone this repository to ```$GOPATH/src/github.com/mailhog/MailHog``` and type ```make deps```.

See the [Building MailHog](/docs/BUILD.md) guide.

Requires Go 1.4+ to build.

Run tests using ```make test``` or ```goconvey```.

If you make any changes, run ```go fmt ./...``` before submitting a pull request.

### Licence

Copyright ©‎ 2014 - 2017, Ian Kent (http://iankent.uk)

Released under MIT license, see [LICENSE](LICENSE.md) for details.


================================================
FILE: config/config.go
================================================
package config

import (
	"flag"

	"github.com/ian-kent/envconf"
)

func DefaultConfig() *Config {
	return &Config{
		AuthFile: "",
	}
}

type Config struct {
	AuthFile string
	WebPath  string
}

var cfg = DefaultConfig()

func Configure() *Config {

	//sanitize webpath
	//add a leading slash
	if cfg.WebPath != "" && !(cfg.WebPath[0] == '/') {
		cfg.WebPath = "/" + cfg.WebPath
	}

	return cfg
}

func RegisterFlags() {
	flag.StringVar(&cfg.AuthFile, "auth-file", envconf.FromEnvP("MH_AUTH_FILE", "").(string), "A username:bcryptpw mapping file")
	flag.StringVar(&cfg.WebPath, "ui-web-path", envconf.FromEnvP("MH_UI_WEB_PATH", "").(string), "WebPath under which the UI is served (without leading or trailing slashes), e.g. 'mailhog'. Value defaults to ''")
}


================================================
FILE: docs/APIv1.md
================================================
MailHog API v1
==============

The v1 API is a RESTful HTTP JSON API.

### GET /api/v1/events

Streams new messages using EventSource and chunked encoding

### GET /api/v1/messages

Lists all messages excluding message content

### DELETE /api/v1/messages

Deletes all messages

Returns a ```200``` response code if message deletion was successful.

### GET /api/v1/messages/{ message_id }

Returns an individual message including message content

### DELETE /api/v1/messages/{ message_id }

Delete an individual message

Returns a ```200``` response code if message deletion was successful.

### GET /api/v1/messages/{ message_id }/download

Download the complete message

### GET /api/v1/messages/{ message_id }/mime/part/{ part_index }/download

Download a MIME part

### POST /api/v1/messages/{ message_id }/release

Release the message to an SMTP server

Send a JSON body specifying the recipient, SMTP hostname and port number:

```json
{
	"Host": "mail.example.com",
	"Post": "25",
	"Email": "someone@example.com"
}
```

Returns a ```200``` response code if message delivery was successful.


================================================
FILE: docs/APIv2/swagger-2.0.json
================================================
{
    "swagger": "2.0",
    "info": {
        "version": "2.0.0",
        "title": "MailHog API"
    },
    "paths": {
        "/api/v2/messages": {
            "get": {
                "description": "Retrieve a list of messages\n",
                "parameters": [
                    {
                        "name": "start",
                        "in": "query",
                        "description": "Start index",
                        "required": false,
                        "type": "number",
                        "format": "int64",
                        "default": 0
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "Number of messages",
                        "required": false,
                        "type": "number",
                        "format": "int64",
                        "default": 50
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful response",
                        "schema": {
                            "title": "Messages",
                            "type": "object",
                            "properties": {
                                "total": {
                                    "type": "number",
                                    "format": "int64",
                                    "description": "Total number of stored messages"
                                },
                                "start": {
                                    "type": "number",
                                    "format": "int64",
                                    "description": "Start index of first returned message"
                                },
                                "count": {
                                    "type": "number",
                                    "format": "int64",
                                    "description": "Number of returned messages"
                                },
                                "messages": {
                                    "type": "array",
                                    "items": {
                                        "title": "Message",
                                        "type": "object",
                                        "properties": {
                                            "id": {
                                                "type": "string"
                                            },
                                            "from": {
                                                "title": "Path",
                                                "type": "object",
                                                "properties": {
                                                    "relays": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "string"
                                                        }
                                                    },
                                                    "mailbox": {
                                                        "type": "string"
                                                    },
                                                    "domain": {
                                                        "type": "string"
                                                    },
                                                    "params": {
                                                        "type": "string"
                                                    }
                                                }
                                            },
                                            "to": {
                                                "type": "array",
                                                "items": {
                                                    "title": "Path",
                                                    "type": "object",
                                                    "properties": {
                                                        "relays": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string"
                                                            }
                                                        },
                                                        "mailbox": {
                                                            "type": "string"
                                                        },
                                                        "domain": {
                                                            "type": "string"
                                                        },
                                                        "params": {
                                                            "type": "string"
                                                        }
                                                    }
                                                }
                                            },
                                            "headers": {
                                                "type": "object"
                                            },
                                            "size": {
                                                "type": "number",
                                                "format": "int64"
                                            },
                                            "created": {
                                                "type": "string",
                                                "format": "date-time"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v2/search": {
            "get": {
                "description": "Search messages\n",
                "parameters": [
                    {
                        "name": "kind",
                        "in": "query",
                        "description": "Kind of search",
                        "required": true,
                        "type": "string",
                        "enum": [
                            "from",
                            "to",
                            "containing"
                        ]
                    },
                    {
                        "name": "query",
                        "in": "query",
                        "description": "Search parameter",
                        "required": true,
                        "type": "string"
                    },
                    {
                        "name": "start",
                        "in": "query",
                        "description": "Start index",
                        "required": false,
                        "type": "number",
                        "format": "int64",
                        "default": 0
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "description": "Number of messages",
                        "required": false,
                        "type": "number",
                        "format": "int64",
                        "default": 50
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful response",
                        "schema": {
                            "title": "Messages",
                            "type": "object",
                            "properties": {
                                "total": {
                                    "type": "number",
                                    "format": "int64",
                                    "description": "Total number of stored messages"
                                },
                                "start": {
                                    "type": "number",
                                    "format": "int64",
                                    "description": "Start index of first returned message"
                                },
                                "count": {
                                    "type": "number",
                                    "format": "int64",
                                    "description": "Number of returned messages"
                                },
                                "messages": {
                                    "type": "array",
                                    "items": {
                                        "title": "Message",
                                        "type": "object",
                                        "properties": {
                                            "id": {
                                                "type": "string"
                                            },
                                            "from": {
                                                "title": "Path",
                                                "type": "object",
                                                "properties": {
                                                    "relays": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "string"
                                                        }
                                                    },
                                                    "mailbox": {
                                                        "type": "string"
                                                    },
                                                    "domain": {
                                                        "type": "string"
                                                    },
                                                    "params": {
                                                        "type": "string"
                                                    }
                                                }
                                            },
                                            "to": {
                                                "type": "array",
                                                "items": {
                                                    "title": "Path",
                                                    "type": "object",
                                                    "properties": {
                                                        "relays": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string"
                                                            }
                                                        },
                                                        "mailbox": {
                                                            "type": "string"
                                                        },
                                                        "domain": {
                                                            "type": "string"
                                                        },
                                                        "params": {
                                                            "type": "string"
                                                        }
                                                    }
                                                }
                                            },
                                            "headers": {
                                                "type": "object"
                                            },
                                            "size": {
                                                "type": "number",
                                                "format": "int64"
                                            },
                                            "created": {
                                                "type": "string",
                                                "format": "date-time"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}


================================================
FILE: docs/APIv2/swagger-2.0.yaml
================================================
swagger: '2.0'

info:
  version: "2.0.0"
  title: MailHog API

paths:
  /api/v2/messages:
    get:
      description: |
        Retrieve a list of messages
      parameters:
        -
          name: start
          in: query
          description: Start index
          required: false
          type: number
          format: int64
          default: 0
        -
          name: limit
          in: query
          description: Number of messages
          required: false
          type: number
          format: int64
          default: 50
      responses:
        200:
          description: Successful response
          schema:
            title: Messages
            type: object
            properties:
              total:
                type: number
                format: int64
                description: Total number of stored messages
              start:
                type: number
                format: int64
                description: Start index of first returned message
              count:
                type: number
                format: int64
                description: Number of returned messages
              messages:
                type: array
                items:
                  title: Message
                  type: object
                  properties:
                    id:
                      type: string
                    from:
                      title: Path
                      type: object
                      properties:
                        relays:
                          type: array
                          items:
                            type: string
                        mailbox:
                          type: string
                        domain:
                          type: string
                        params:
                          type: string
                    to:
                      type: array
                      items:
                        title: Path
                        type: object
                        properties:
                          relays:
                            type: array
                            items:
                              type: string
                          mailbox:
                            type: string
                          domain:
                            type: string
                          params:
                            type: string
                    headers:
                      type: object
                    size:
                      type: number
                      format: int64
                    created:
                      type: string
                      format: date-time
  /api/v2/search:
    get:
      description: |
        Search messages
      parameters:
        -
          name: kind
          in: query
          description: Kind of search
          required: true
          type: string
          enum: [ from, to, containing ]
        -
          name: query
          in: query
          description: Search parameter
          required: true
          type: string
        -
          name: start
          in: query
          description: Start index
          required: false
          type: number
          format: int64
          default: 0
        -
          name: limit
          in: query
          description: Number of messages
          required: false
          type: number
          format: int64
          default: 50
      responses:
        200:
          description: Successful response
          schema:
            title: Messages
            type: object
            properties:
              total:
                type: number
                format: int64
                description: Total number of stored messages
              start:
                type: number
                format: int64
                description: Start index of first returned message
              count:
                type: number
                format: int64
                description: Number of returned messages
              messages:
                type: array
                items:
                  title: Message
                  type: object
                  properties:
                    id:
                      type: string
                    from:
                      title: Path
                      type: object
                      properties:
                        relays:
                          type: array
                          items:
                            type: string
                        mailbox:
                          type: string
                        domain:
                          type: string
                        params:
                          type: string
                    to:
                      type: array
                      items:
                        title: Path
                        type: object
                        properties:
                          relays:
                            type: array
                            items:
                              type: string
                          mailbox:
                            type: string
                          domain:
                            type: string
                          params:
                            type: string
                    headers:
                      type: object
                    size:
                      type: number
                      format: int64
                    created:
                      type: string
                      format: date-time


================================================
FILE: docs/APIv2.md
================================================
MailHog API v2
==============

The v2 API is hopefully less of a mess than v1.

The specification is written in [Swagger 2.0](http://swagger.io/).

See the YAML and JSON specifications in the [APIv2](./APIv2) directory.


================================================
FILE: docs/Auth.md
================================================
Authentication
==============

HTTP basic authentication is supported using a password file.

See [example-auth](example-auth) for an example (the password is `test`).

Authentication applies to all HTTP requests, including static content
and API endpoints.

### Password file format

The password file format is:

* One user per line
* `username:password`
* Password is bcrypted

By default, a bcrypt difficulty of 4 is used to reduce page load times.

### Generating a bcrypted password

You can use a MailHog shortcut to generate a bcrypted password:

    MailHog bcrypt <password>

### Enabling HTTP authentication

To enable authentication, pass an `-auth-file` flag to MailHog:

    MailHog -auth-file=docs/example-auth

This also works if you're running MailHog-UI and MailHog-Server separately:

    MailHog-Server -auth-file=docs/example-auth
    MailHog-UI -auth-file=docs/example-auth

## Future compatibility

Authentication has been a bit of an experiment.

The exact implementation may change over time, e.g. using sessions in the UI
and tokens for the API to avoid frequently bcrypting passwords.


================================================
FILE: docs/BUILD.md
================================================
Building MailHog
================

MailHog is built using `make`, and using [this Makefile](../Makefile).

If you aren't making any code changes, you can install MailHog using
`go get github.com/mailhog/MailHog`, since [mailhog/MailHog-UI/assets/assets.go](https://github.com/mailhog/MailHog-UI/blob/master/assets/assets.go)
is already pre-compiled and committed to this repository.

### Why do I need a Makefile?

MailHog has HTML, CSS and Javascript assets which need to be converted
to a go source file using [go-bindata](https://github.com/jteeuwen/go-bindata).

This must happen before running `go build` or `go install` to avoid compilation
errors (e.g., `no buildable Go source files in MailHog-UI/assets`).

### go generate

The build should be updated to use `go generate` (added in Go 1.4) to
preprocess static assets into go source files.

However, this will break backwards compatibility with Go 1.2/1.3.

### Building a release

Releases are built using [gox](https://github.com/mitchellh/gox).

Run `make release` to cross-compile for all available platforms.


================================================
FILE: docs/CONFIG.md
================================================
Configuring MailHog
===================

You can configure MailHog using command line options or environment variables:

| Environment         | Command line    | Default         | Description
| ------------------- | --------------- | --------------- | -----------
| MH_CORS_ORIGIN      | -cors-origin    |                 | If set, an Access-Control-Allow-Origin header is returned for API endpoints
| MH_HOSTNAME         | -hostname       | mailhog.example | Hostname to use for EHLO/HELO and message IDs
| MH_API_BIND_ADDR    | -api-bind-addr  | 0.0.0.0:8025    | Interface and port for HTTP API server to bind to
| MH_UI_BIND_ADDR     | -ui-bind-addr   | 0.0.0.0:8025    | Interface and port for HTTP UI server to bind to
| MH_MAILDIR_PATH     | -maildir-path   |                 | Maildir path (for maildir storage backend)
| MH_MONGO_COLLECTION | -mongo-coll     | messages        | MongoDB collection name for message storage
| MH_MONGO_DB         | -mongo-db       | mailhog         | MongoDB database name for message storage
| MH_MONGO_URI        | -mongo-uri      | 127.0.0.1:27017 | MongoDB host and port
| MH_SMTP_BIND_ADDR   | -smtp-bind-addr | 0.0.0.0:1025    | Interface and port for SMTP server to bind to
| MH_STORAGE          | -storage        | memory          | Set message storage: memory / mongodb / maildir
| MH_OUTGOING_SMTP    | -outgoing-smtp  |                 | JSON file defining outgoing SMTP servers
| MH_UI_WEB_PATH      | -ui-web-path    |                 | WebPath under which the UI is served (without leading or trailing slashes), e.g. 'mailhog'
| MH_AUTH_FILE        | -auth-file      |                 | A username:bcryptpw mapping file

#### Note on HTTP bind addresses

If `api-bind-addr` and `ui-bind-addr` are identical, a single listener will
be used allowing both to co-exist on one port.

The values must match in a string comparison. Resolving to the same host and
port combination isn't enough.

### Outgoing SMTP configuration

Outgoing SMTP servers can be set in web UI when releasing a message, and can
be temporarily persisted for later use in the same session.

To make outgoing SMTP servers permanently available, create a JSON file with
the following structure, and set `MH_OUTGOING_SMTP` or `-outgoing-smtp`.

```json
{
    "server name": {
        "name": "server name",
        "host": "...",
        "port": "587",
        "email": "...",
        "username": "...",
        "password": "...",
        "mechanism": "PLAIN"
    }
}
```

Only `name`, `host` and `port` are required.

`mechanism` can be `PLAIN` or `CRAM-MD5`.

### Firewalls and proxies

If you have MailHog behind a firewall, you'll need ports `8025` and `1025` by default.

You can override this using `-api-bind-addr`, `-ui-bind-addr` and `-smtp-bind-addr` configuration options.

If you're using MailHog behind a reverse proxy, e.g. nginx, make sure WebSocket connections
are also supported and configured - see [this issue](https://github.com/mailhog/MailHog/issues/117) for information.


================================================
FILE: docs/DEPLOY.md
================================================
Deploying MailHog
=================

### Command line

You can run MailHog locally from the command line.

    go get github.com/mailhog/MailHog
    MailHog -h

To configure MailHog, use the environment variables or command line flags
described in the [CONFIG](CONFIG.md).

### Using supervisord/upstart/etc

MailHog can be started as a daemon using supervisord/upstart/etc.

See [this example init script](https://github.com/geerlingguy/ansible-role-mailhog/blob/master/templates/mailhog.init.j2)
and [this Ansible role](https://github.com/geerlingguy/ansible-role-mailhog) by [geerlingguy](https://github.com/geerlingguy).

If installed with Homebrew on OSX you can have launchd start mailhog now and restart at login:
    brew services start mailhog

### Docker

The example [Dockerfile](../Dockerfile) can be used to run MailHog in a [Docker](https://www.docker.com/) container.

You can run it directly from Docker Hub (thanks [humboldtux](https://github.com/humboldtux))

    docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog

To mount the Maildir to the local filesystem, you can use a volume:

    docker run -d -e "MH_STORAGE=maildir" -v $PWD/maildir:/maildir -p 1025:1025 -p 8025:8025 mailhog/mailhog

### Elastic Beanstalk

You can deploy MailHog using [AWS Elastic Beanstalk](http://aws.amazon.com/elasticbeanstalk/).

1. Open the Elastic Beanstalk console
2. Create a zip file containing the Dockerfile and MailHog binary
3. Create a new Elastic Beanstalk application
4. Launch a new environment and upload the zip file

**Note** You'll need to reconfigure nginx in Elastic Beanstalk to expose both
ports as TCP, since by default it proxies the first exposed port to port 80 as HTTP.

If you're using in-memory storage, you can only use a single instance of
MailHog. To use a load balanced EB application, use MongoDB backed storage.

To configure your Elastic Beanstalk MailHog instance, either:

* Set environment variables using the Elastic Beanstalk console
* Edit the Dockerfile to pass in command line arguments

You may face restrictions on outbound SMTP from EC2, for example if you are
releasing messages to real SMTP servers.

### SaltStack

For deploying MailHog using [SaltStack](https://github.com/saltstack/salt), there's a
[SaltStack Formula](https://docs.saltstack.com/en/latest/topics/development/conventions/formulas.html)
available in [github.com/ssc-services/salt-formulas-public](https://github.com/ssc-services/salt-formulas-public/tree/master/mailhog).


================================================
FILE: docs/JIM.md
================================================
Introduction to Jim
===================

Jim is the MailHog Chaos Monkey, inspired by Netflix.

You can invite Jim to the party using the `invite-jim` flag:

    MailHog -invite-jim

With Jim around, things aren't going to work how you expect.

### What can Jim do?

* Reject connections
* Rate limit connections
* Reject authentication
* Reject senders
* Reject recipients

It does this randomly, but within defined parameters.

You can control these using the following command line flags:

| Flag                  | Default | Description
| --------------------- | ------- | ----
| -invite-jim           | false   | Set to true to invite Jim
| -jim-disconnect       | 0.005   | Chance of randomly disconnecting a session
| -jim-accept           | 0.99    | Chance of accepting an incoming connection
| -jim-linkspeed-affect | 0.1     | Chance of applying a rate limit
| -jim-linkspeed-min    | 1024    | Minimum link speed (in bytes per second)
| -jim-linkspeed-max    | 10240   | Maximum link speed (in bytes per second)
| -jim-reject-sender    | 0.05    | Chance of rejecting a MAIL FROM command
| -jim-reject-recipient | 0.05    | Chance of rejecting a RCPT TO command
| -jim-reject-auth      | 0.05    | Chance of rejecting an AUTH command

If you enable Jim, you enable all parts. To disable individual parts, set the chance
of it happening to 0, e.g. to disable connection rate limiting:

    MailHog -invite-jim -jim-linkspeed-affect=0

### Examples

Always rate limit to 1 byte per second:

    MailHog -invite-jim -jim-linkspeed-affect=1 -jim-linkspeed-max=1 -jim-linkspeed-min=1

Disconnect clients after approximately 5 commands:

    MailHog -invite-jim -jim-disconnect=0.2

Simulate a mobile connection (at 10-100kbps) for 10% of clients:

    MailHog -invite-jim -jim-linkspeed-affect=0.1 -jim-linkspeed-min=1250 -jim-linkspeed-max=12500


================================================
FILE: docs/LIBRARIES.md
================================================
MailHog libraries
=================

If you've created a MailHog client library, open a pull request and add it!

* [APIv2 library for NodeJS](https://github.com/blueimp/mailhog-node)
* [APIv1/APIv2 library for PHP](https://github.com/rpkamp/mailhog-client)


================================================
FILE: docs/RELEASES.md
================================================
MailHog Releases
================

### [v1.0.0](https://github.com/mailhog/MailHog/releases/v1.0.0)

There's still outstanding PRs and issues which haven't been addressed in this release.

This is to get the updated release out with the latest code, since 0.2.1 is getting very stale!

- Bump release to 1.0.0
- updated mgo dependency
- temporarily remove vendor directory, because of some build issues
- Fix #117 - add info about proxies
- Fix #146 - keep tags on docker hub
- Fix #148 and mailhog/storage#7 - leading \r\n in maildir storage
- #113 - better support RFC support for headers
- #118 - optimise Dockerfile for automated builds, thanks @blueimp
- #122 - add -version flag, thanks @swordbeta
- #123 - add .gitignore, thanks @swordbeta
- #136 - update MailHog-UI assets, thanks @sdurrheimer
- #145 - fix a link in DEPLOY.md, thanks @nnmer
- mailhog/MailHog-UI#22 and #104 - support TLS websockets in HTTPS mode, thanks @blueimp
- mailhog/MailHog-UI#23 and mailhog/MailHog-UI#24 - support multiple instances of CID, thanks @kieran and @jerbob92
- more things I've forgotten/can't find!

### [v0.2.1](https://github.com/mailhog/MailHog/releases/v0.2.1)
- Update .travis.yml to Go 1.6 and tip
- Fix builds broken by out of date mgo import path
- #82 - fix configuration documentation, thanks @riking
- #83 - add search query parameter to Swagger JSON, thanks @kkrauth
- #86 - vendor all dependencies
- #89 - add missing iso88591_map.js and sjis_map.js
- #90 - update broken link in documentation, thanks @espen
- #91 - add assets/js/filesize-3.1.2.min.js
- #93 - starting MailHog as a service using brew, thanks @espen
- #95 - fix UTF-8 encoding bug in attachment names
- #97 - fix header case sensitivity bug
- #102 - merge multiple PRs adding WebSocket support, thanks @GREsau
- mailhog/smtp#2 - use file modification time for Created field, thanks @esiqveland

### [v0.2.0](https://github.com/mailhog/MailHog/releases/v0.2.0)
- mailhog/storage#1 - fix MongoDB storage bug, and implement search, thanks @HokieTT
- #13 - implement file based storage backend (currently without search)

### [v0.1.9](https://github.com/mailhog/MailHog/releases/v0.1.9)
- #76 - optimise docker image size, thanks @missedone
- #77 - fix ci by removing go-uuid, thanks @missedone
- #80, mailhog/MailHog-UI#15, mailhog/MailHog-Server#2 - add webpath, thanks @oers
- mailhog/MailHog-UI#13 - create hyperlinks for URLs in plain text, thanks @GREsau
- mailhog/MailHog-UI#14 - add no-referrer referrer policy, thanks @djmattyg007

### [v0.1.8](https://github.com/mailhog/MailHog/releases/v0.1.8)
- Add `MailHog sendmail` shortcut to `mhsendmail`
- Add #40 - HTTP basic authentication
- Add #63 - message size in UI
- Fix mailhog/MailHog-UI#10 - fix delete for in-memory storage
- Merge mailhog/MailHog-UI#8 - fix styles for .content positioning, thanks @thejameskyle
- Merge mailhog/MailHog-UI#9 - fix content types, thanks @danielwhite
- Merge mailhog/data#4 - factor out use of log package, thanks @ishbir

### [v0.1.7](https://github.com/mailhog/MailHog/releases/v0.1.7)
- Add [mhsendmail](https://github.com/mailhog/mhsendmail) sendmail replacement
- Fix #42 - panic when setting UI bind address
- Fix #46 - utf8 error in e-mail subject
- Fix #41 and #50 - underscores replaced with spaces in UI
- Fix mailhog/MailHog-UI#6 - user defined pagination
- Merge #43 and #44 - fix documentation, thanks @eirc
- Merge #48 - fix documentation, thanks @zhubert
- Merge mailhog/MailHog-Server#1 - avoid duplicate headers, thanks @wienczny

### [v0.1.6](https://github.com/mailhog/MailHog/releases/v0.1.6)
- Fix #24 - base64 attachments/mime part downloads
- Fix #28 - embed js/css/font assets for offline use
- Fix #29 - overview of MailHog for readme
- Fix #34 - message list scrolling
- Fix #35 - message list sorting
- Fix #36 - document outgoing SMTP server configuration and APIv2
- Merge mailhog/MailHog-UI#4 - support base64 content transfer encoding, thanks @stekershaw
- Merge mailhog/Mailhog-UI#5 - single part encoded text/plain, thanks @naoina

### [v0.1.5](https://github.com/mailhog/MailHog/releases/v0.1.5)
- Fix mailhog/MailHog-UI#3 - squashed subject line

### [v0.1.4](https://github.com/mailhog/MailHog/releases/v0.1.4)
- Merge mailhog/data#2 - MIME boundary fixes, thanks @nvcnvn
- Merge mailhog/MailHog-UI#2 - UI overhaul, thanks @omegahm
- Fix #31 - updated this file :smile:

### [v0.1.3](https://github.com/mailhog/MailHog/releases/v0.1.3)
- Fix #22 - render non-multipart messages with HTML content type
- Fix #25 - make web UI resource paths relative

### [v0.1.2](https://github.com/mailhog/MailHog/releases/v0.1.2)
- Hopefully fix #22 - broken rendering of HTML email
- Partially implement #15 - authentication for SMTP release
  - Load outgoing SMTP servers from file
  - Save outgoing SMTP server when releasing message in UI
  - Select outgoing SMTP server when release message in UI
- Make Jim (Chaos Monkey) available via APIv2
- Add Jim overview and on/off switch to web UI

### [v0.1.1](https://github.com/mailhog/MailHog/releases/v0.1.1)
- Fix #23 - switch to iframe to fix CSS bug
- Update to latest AngularJS
- Update Dockerfile - thanks @humboldtux
- Fix SMTP AUTH bug (missing from EHLO)
- Fix SMTP new line parsing

### [v0.1.0](https://github.com/mailhog/MailHog/releases/v0.1.0)

- Switch to semantic versioning
- Rewrite web user interface
- Deprecate APIv1
- Rewrite messages endpoint for APIv2
- Add search to APIv2

### [v0.09](https://github.com/mailhog/MailHog/releases/0.08)

- Fix #8 - add Chaos Monkey ([Jim](JIM.md)) to support failure testing

### [v0.08](https://github.com/mailhog/MailHog/releases/0.08)

- Extract SMTP protocol into isolated library
- Better protocol tests
- Add hooks for manipulating protocol behaviour
- Merge #14 - fix display of multipart messges, thanks @derwassi
- Merge #17 - fix API v1 docs, thanks @geerlingguy
- Fix #11 - add build documentation
- Fix #12 - support broken MAIL/RCPT syntax
- Fix #16 - add deployment documentation
- Fix #18 - better server-sent event support using [goose](https://github.com/ian-kent/goose)

### [v0.07](https://github.com/mailhog/MailHog/releases/tag/0.07)

- Fix #6 - Make SMTP verbs case-insensitive

### [v0.06](https://github.com/mailhog/MailHog/releases/tag/0.06)

- Fix #5 - Support leading tab in multiline headers

### [v0.05](https://github.com/mailhog/MailHog/releases/tag/0.05)

- Add #4 - UI support for RFC2047 encoded headers

### [v0.04](https://github.com/mailhog/MailHog/releases/tag/0.04)

* Configure from environment
* Include example Dockerfile
* Fix #1 - mismatched import path and repository name
* Fix #2 - possible panic with some MIME content
* Fix #3 - incorrect handling of RSET


### [v0.03](https://github.com/mailhog/MailHog/releases/tag/0.03)

* Download message in .eml format
* Cleaned up v1 API
* Web UI and API improvements
  * Fixed UI rendering bugs
  * Message search and matched/total message count
  * Message list resizing and scrolling  
  * EventSource support for message streaming
  * Better error handling and reporting
  * View/download individual MIME parts
  * Release messages to real SMTP servers
* Switch to [go-bindata](https://github.com/jteeuwen/go-bindata) for asset embedding

### [v0.02](https://github.com/mailhog/MailHog/releases/tag/0.02)

* Better support for ESMTP (RFC5321)
* Support for SMTP AUTH (RFC4954) and PIPELINING (RFC2920)
* Improved AJAX web interface to view messages (plain text, HTML or source)
* Improved HTTP API to list, retrieve and delete messages
* Multipart MIME support
* In-memory message storage
* MongoDB storage for message persistence

### [v0.01](https://github.com/mailhog/MailHog/releases/tag/0.01)

* Basic support for SMTP and HTTP servers
* Accepts SMTP messages
* Stores parsed messages in MongoDB
* Makes messages available via API
* has Bootstrap/AngularJS UI for viewing/deleting messages


================================================
FILE: docs/example-auth
================================================
test:$2a$04$qxRo.ftFoNep7ld/5jfKtuBTnGqff/fZVyj53mUC5sVf9dtDLAi/S


================================================
FILE: main.go
================================================
package main

import (
	"flag"
	"fmt"
	"os"

	gohttp "net/http"

	"github.com/gorilla/pat"
	"github.com/ian-kent/go-log/log"
	"github.com/mailhog/MailHog-Server/api"
	cfgapi "github.com/mailhog/MailHog-Server/config"
	"github.com/mailhog/MailHog-Server/smtp"
	"github.com/mailhog/MailHog-UI/assets"
	cfgui "github.com/mailhog/MailHog-UI/config"
	"github.com/mailhog/MailHog-UI/web"
	cfgcom "github.com/mailhog/MailHog/config"
	"github.com/mailhog/http"
	"github.com/mailhog/mhsendmail/cmd"
	"golang.org/x/crypto/bcrypt"
)

var apiconf *cfgapi.Config
var uiconf *cfgui.Config
var comconf *cfgcom.Config
var exitCh chan int
var version string

func configure() {
	cfgcom.RegisterFlags()
	cfgapi.RegisterFlags()
	cfgui.RegisterFlags()
	flag.Parse()
	apiconf = cfgapi.Configure()
	uiconf = cfgui.Configure()
	comconf = cfgcom.Configure()

	apiconf.WebPath = comconf.WebPath
	uiconf.WebPath = comconf.WebPath
}

func main() {
	if len(os.Args) > 1 && (os.Args[1] == "-version" || os.Args[1] == "--version") {
		fmt.Println("MailHog version: " + version)
		os.Exit(0)
	}

	if len(os.Args) > 1 && os.Args[1] == "sendmail" {
		args := os.Args
		os.Args = []string{args[0]}
		if len(args) > 2 {
			os.Args = append(os.Args, args[2:]...)
		}
		cmd.Go()
		return
	}

	if len(os.Args) > 1 && os.Args[1] == "bcrypt" {
		var pw string
		if len(os.Args) > 2 {
			pw = os.Args[2]
		} else {
			// TODO: read from stdin
		}
		b, err := bcrypt.GenerateFromPassword([]byte(pw), 4)
		if err != nil {
			log.Fatalf("error bcrypting password: %s", err)
			os.Exit(1)
		}
		fmt.Println(string(b))
		os.Exit(0)
	}

	configure()

	if comconf.AuthFile != "" {
		http.AuthFile(comconf.AuthFile)
	}

	exitCh = make(chan int)
	if uiconf.UIBindAddr == apiconf.APIBindAddr {
		cb := func(r gohttp.Handler) {
			web.CreateWeb(uiconf, r.(*pat.Router), assets.Asset)
			api.CreateAPI(apiconf, r.(*pat.Router))
		}
		go http.Listen(uiconf.UIBindAddr, assets.Asset, exitCh, cb)
	} else {
		cb1 := func(r gohttp.Handler) {
			api.CreateAPI(apiconf, r.(*pat.Router))
		}
		cb2 := func(r gohttp.Handler) {
			web.CreateWeb(uiconf, r.(*pat.Router), assets.Asset)
		}
		go http.Listen(apiconf.APIBindAddr, assets.Asset, exitCh, cb1)
		go http.Listen(uiconf.UIBindAddr, assets.Asset, exitCh, cb2)
	}
	go smtp.Listen(apiconf, exitCh)

	<-exitCh
	log.Printf("Received exit signal")
}

/*

Add some random content to the end of this file, hopefully tricking GitHub
into recognising this as a Go repo instead of Makefile.

A gopher, ASCII art style - borrowed from
https://gist.github.com/belbomemo/b5e7dad10fa567a5fe8a

          ,_---~~~~~----._
   _,,_,*^____      _____``*g*\"*,
  / __/ /'     ^.  /      \ ^@q   f
 [  @f | @))    |  | @))   l  0 _/
  \`/   \~____ / __ \_____/    \
   |           _l__l_           I
   }          [______]           I
   ]            | | |            |
   ]             ~ ~             |
   |                            |
    |                           |

*/


================================================
FILE: snapcraft.yaml
================================================
name: mailhog
summary: Web and API based SMTP testing
description: |
 MailHog is an email testing tool for developers:
 * Configure your application to use MailHog for SMTP delivery
 * View messages in the web UI, or retrieve them with the JSON API
 * Optionally release messages to real SMTP servers for delivery
version: "master"
confinement: strict
grade: stable
apps:
  mailhog:
    command: MailHog
    plugs: [network-bind]
    daemon: simple
parts:
  mailhog:
    plugin: go
    go-packages:
      - github.com/mailhog/MailHog
    build-packages:
      - git


================================================
FILE: vendor/github.com/gorilla/context/LICENSE
================================================
Copyright (c) 2012 Rodrigo Moraes. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

	 * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
	 * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
	 * Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: vendor/github.com/gorilla/context/README.md
================================================
context
=======
[![Build Status](https://travis-ci.org/gorilla/context.png?branch=master)](https://travis-ci.org/gorilla/context)

gorilla/context is a general purpose registry for global request variables.

> Note: gorilla/context, having been born well before `context.Context` existed, does not play well
> with the shallow copying of the request that [`http.Request.WithContext`](https://golang.org/pkg/net/http/#Request.WithContext) (added to net/http Go 1.7 onwards) performs. You should either use *just* gorilla/context, or moving forward, the new `http.Request.Context()`.

Read the full documentation here: http://www.gorillatoolkit.org/pkg/context


================================================
FILE: vendor/github.com/gorilla/context/context.go
================================================
// Copyright 2012 The Gorilla 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 context

import (
	"net/http"
	"sync"
	"time"
)

var (
	mutex sync.RWMutex
	data  = make(map[*http.Request]map[interface{}]interface{})
	datat = make(map[*http.Request]int64)
)

// Set stores a value for a given key in a given request.
func Set(r *http.Request, key, val interface{}) {
	mutex.Lock()
	if data[r] == nil {
		data[r] = make(map[interface{}]interface{})
		datat[r] = time.Now().Unix()
	}
	data[r][key] = val
	mutex.Unlock()
}

// Get returns a value stored for a given key in a given request.
func Get(r *http.Request, key interface{}) interface{} {
	mutex.RLock()
	if ctx := data[r]; ctx != nil {
		value := ctx[key]
		mutex.RUnlock()
		return value
	}
	mutex.RUnlock()
	return nil
}

// GetOk returns stored value and presence state like multi-value return of map access.
func GetOk(r *http.Request, key interface{}) (interface{}, bool) {
	mutex.RLock()
	if _, ok := data[r]; ok {
		value, ok := data[r][key]
		mutex.RUnlock()
		return value, ok
	}
	mutex.RUnlock()
	return nil, false
}

// GetAll returns all stored values for the request as a map. Nil is returned for invalid requests.
func GetAll(r *http.Request) map[interface{}]interface{} {
	mutex.RLock()
	if context, ok := data[r]; ok {
		result := make(map[interface{}]interface{}, len(context))
		for k, v := range context {
			result[k] = v
		}
		mutex.RUnlock()
		return result
	}
	mutex.RUnlock()
	return nil
}

// GetAllOk returns all stored values for the request as a map and a boolean value that indicates if
// the request was registered.
func GetAllOk(r *http.Request) (map[interface{}]interface{}, bool) {
	mutex.RLock()
	context, ok := data[r]
	result := make(map[interface{}]interface{}, len(context))
	for k, v := range context {
		result[k] = v
	}
	mutex.RUnlock()
	return result, ok
}

// Delete removes a value stored for a given key in a given request.
func Delete(r *http.Request, key interface{}) {
	mutex.Lock()
	if data[r] != nil {
		delete(data[r], key)
	}
	mutex.Unlock()
}

// Clear removes all values stored for a given request.
//
// This is usually called by a handler wrapper to clean up request
// variables at the end of a request lifetime. See ClearHandler().
func Clear(r *http.Request) {
	mutex.Lock()
	clear(r)
	mutex.Unlock()
}

// clear is Clear without the lock.
func clear(r *http.Request) {
	delete(data, r)
	delete(datat, r)
}

// Purge removes request data stored for longer than maxAge, in seconds.
// It returns the amount of requests removed.
//
// If maxAge <= 0, all request data is removed.
//
// This is only used for sanity check: in case context cleaning was not
// properly set some request data can be kept forever, consuming an increasing
// amount of memory. In case this is detected, Purge() must be called
// periodically until the problem is fixed.
func Purge(maxAge int) int {
	mutex.Lock()
	count := 0
	if maxAge <= 0 {
		count = len(data)
		data = make(map[*http.Request]map[interface{}]interface{})
		datat = make(map[*http.Request]int64)
	} else {
		min := time.Now().Unix() - int64(maxAge)
		for r := range data {
			if datat[r] < min {
				clear(r)
				count++
			}
		}
	}
	mutex.Unlock()
	return count
}

// ClearHandler wraps an http.Handler and clears request values at the end
// of a request lifetime.
func ClearHandler(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		defer Clear(r)
		h.ServeHTTP(w, r)
	})
}


================================================
FILE: vendor/github.com/gorilla/context/doc.go
================================================
// Copyright 2012 The Gorilla 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 context stores values shared during a request lifetime.

Note: gorilla/context, having been born well before `context.Context` existed,
does not play well > with the shallow copying of the request that
[`http.Request.WithContext`](https://golang.org/pkg/net/http/#Request.WithContext)
(added to net/http Go 1.7 onwards) performs. You should either use *just*
gorilla/context, or moving forward, the new `http.Request.Context()`.

For example, a router can set variables extracted from the URL and later
application handlers can access those values, or it can be used to store
sessions values to be saved at the end of a request. There are several
others common uses.

The idea was posted by Brad Fitzpatrick to the go-nuts mailing list:

	http://groups.google.com/group/golang-nuts/msg/e2d679d303aa5d53

Here's the basic usage: first define the keys that you will need. The key
type is interface{} so a key can be of any type that supports equality.
Here we define a key using a custom int type to avoid name collisions:

	package foo

	import (
		"github.com/gorilla/context"
	)

	type key int

	const MyKey key = 0

Then set a variable. Variables are bound to an http.Request object, so you
need a request instance to set a value:

	context.Set(r, MyKey, "bar")

The application can later access the variable using the same key you provided:

	func MyHandler(w http.ResponseWriter, r *http.Request) {
		// val is "bar".
		val := context.Get(r, foo.MyKey)

		// returns ("bar", true)
		val, ok := context.GetOk(r, foo.MyKey)
		// ...
	}

And that's all about the basic usage. We discuss some other ideas below.

Any type can be stored in the context. To enforce a given type, make the key
private and wrap Get() and Set() to accept and return values of a specific
type:

	type key int

	const mykey key = 0

	// GetMyKey returns a value for this package from the request values.
	func GetMyKey(r *http.Request) SomeType {
		if rv := context.Get(r, mykey); rv != nil {
			return rv.(SomeType)
		}
		return nil
	}

	// SetMyKey sets a value for this package in the request values.
	func SetMyKey(r *http.Request, val SomeType) {
		context.Set(r, mykey, val)
	}

Variables must be cleared at the end of a request, to remove all values
that were stored. This can be done in an http.Handler, after a request was
served. Just call Clear() passing the request:

	context.Clear(r)

...or use ClearHandler(), which conveniently wraps an http.Handler to clear
variables at the end of a request lifetime.

The Routers from the packages gorilla/mux and gorilla/pat call Clear()
so if you are using either of them you don't need to clear the context manually.
*/
package context


================================================
FILE: vendor/github.com/gorilla/mux/LICENSE
================================================
Copyright (c) 2012 Rodrigo Moraes. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

	 * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
	 * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
	 * Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: vendor/github.com/gorilla/mux/README.md
================================================
gorilla/mux
===
[![GoDoc](https://godoc.org/github.com/gorilla/mux?status.svg)](https://godoc.org/github.com/gorilla/mux)
[![Build Status](https://travis-ci.org/gorilla/mux.svg?branch=master)](https://travis-ci.org/gorilla/mux)
[![Sourcegraph](https://sourcegraph.com/github.com/gorilla/mux/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/mux?badge)

![Gorilla Logo](http://www.gorillatoolkit.org/static/images/gorilla-icon-64.png)

http://www.gorillatoolkit.org/pkg/mux

Package `gorilla/mux` implements a request router and dispatcher for matching incoming requests to
their respective handler.

The name mux stands for "HTTP request multiplexer". Like the standard `http.ServeMux`, `mux.Router` matches incoming requests against a list of registered routes and calls a handler for the route that matches the URL or other conditions. The main features are:

* It implements the `http.Handler` interface so it is compatible with the standard `http.ServeMux`.
* Requests can be matched based on URL host, path, path prefix, schemes, header and query values, HTTP methods or using custom matchers.
* URL hosts and paths can have variables with an optional regular expression.
* Registered URLs can be built, or "reversed", which helps maintaining references to resources.
* Routes can be used as subrouters: nested routes are only tested if the parent route matches. This is useful to define groups of routes that share common conditions like a host, a path prefix or other repeated attributes. As a bonus, this optimizes request matching.

---

* [Install](#install)
* [Examples](#examples)
* [Matching Routes](#matching-routes)
* [Listing Routes](#listing-routes)
* [Static Files](#static-files)
* [Registered URLs](#registered-urls)
* [Full Example](#full-example)

---

## Install

With a [correctly configured](https://golang.org/doc/install#testing) Go toolchain:

```sh
go get -u github.com/gorilla/mux
```

## Examples

Let's start registering a couple of URL paths and handlers:

```go
func main() {
	r := mux.NewRouter()
	r.HandleFunc("/", HomeHandler)
	r.HandleFunc("/products", ProductsHandler)
	r.HandleFunc("/articles", ArticlesHandler)
	http.Handle("/", r)
}
```

Here we register three routes mapping URL paths to handlers. This is equivalent to how `http.HandleFunc()` works: if an incoming request URL matches one of the paths, the corresponding handler is called passing (`http.ResponseWriter`, `*http.Request`) as parameters.

Paths can have variables. They are defined using the format `{name}` or `{name:pattern}`. If a regular expression pattern is not defined, the matched variable will be anything until the next slash. For example:

```go
r := mux.NewRouter()
r.HandleFunc("/products/{key}", ProductHandler)
r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
```

The names are used to create a map of route variables which can be retrieved calling `mux.Vars()`:

```go
func ArticlesCategoryHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	w.WriteHeader(http.StatusOK)
	fmt.Fprintf(w, "Category: %v\n", vars["category"])
}
```

And this is all you need to know about the basic usage. More advanced options are explained below.

### Matching Routes

Routes can also be restricted to a domain or subdomain. Just define a host pattern to be matched. They can also have variables:

```go
r := mux.NewRouter()
// Only matches if domain is "www.example.com".
r.Host("www.example.com")
// Matches a dynamic subdomain.
r.Host("{subdomain:[a-z]+}.domain.com")
```

There are several other matchers that can be added. To match path prefixes:

```go
r.PathPrefix("/products/")
```

...or HTTP methods:

```go
r.Methods("GET", "POST")
```

...or URL schemes:

```go
r.Schemes("https")
```

...or header values:

```go
r.Headers("X-Requested-With", "XMLHttpRequest")
```

...or query values:

```go
r.Queries("key", "value")
```

...or to use a custom matcher function:

```go
r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool {
	return r.ProtoMajor == 0
})
```

...and finally, it is possible to combine several matchers in a single route:

```go
r.HandleFunc("/products", ProductsHandler).
  Host("www.example.com").
  Methods("GET").
  Schemes("http")
```

Setting the same matching conditions again and again can be boring, so we have a way to group several routes that share the same requirements. We call it "subrouting".

For example, let's say we have several URLs that should only match when the host is `www.example.com`. Create a route for that host and get a "subrouter" from it:

```go
r := mux.NewRouter()
s := r.Host("www.example.com").Subrouter()
```

Then register routes in the subrouter:

```go
s.HandleFunc("/products/", ProductsHandler)
s.HandleFunc("/products/{key}", ProductHandler)
s.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
```

The three URL paths we registered above will only be tested if the domain is `www.example.com`, because the subrouter is tested first. This is not only convenient, but also optimizes request matching. You can create subrouters combining any attribute matchers accepted by a route.

Subrouters can be used to create domain or path "namespaces": you define subrouters in a central place and then parts of the app can register its paths relatively to a given subrouter.

There's one more thing about subroutes. When a subrouter has a path prefix, the inner routes use it as base for their paths:

```go
r := mux.NewRouter()
s := r.PathPrefix("/products").Subrouter()
// "/products/"
s.HandleFunc("/", ProductsHandler)
// "/products/{key}/"
s.HandleFunc("/{key}/", ProductHandler)
// "/products/{key}/details"
s.HandleFunc("/{key}/details", ProductDetailsHandler)
```

### Listing Routes

Routes on a mux can be listed using the Router.Walk method—useful for generating documentation:

```go
package main

import (
    "fmt"
    "net/http"

    "github.com/gorilla/mux"
)

func handler(w http.ResponseWriter, r *http.Request) {
    return
}

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/", handler)
    r.HandleFunc("/products", handler)
    r.HandleFunc("/articles", handler)
    r.HandleFunc("/articles/{id}", handler)
    r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
        t, err := route.GetPathTemplate()
        if err != nil {
            return err
        }
        fmt.Println(t)
        return nil
    })
    http.Handle("/", r)
}
```

### Static Files

Note that the path provided to `PathPrefix()` represents a "wildcard": calling
`PathPrefix("/static/").Handler(...)` means that the handler will be passed any
request that matches "/static/*". This makes it easy to serve static files with mux:

```go
func main() {
	var dir string

	flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir")
	flag.Parse()
	r := mux.NewRouter()

	// This will serve files under http://localhost:8000/static/<filename>
	r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir))))

	srv := &http.Server{
		Handler:      r,
		Addr:         "127.0.0.1:8000",
		// Good practice: enforce timeouts for servers you create!
		WriteTimeout: 15 * time.Second,
		ReadTimeout:  15 * time.Second,
	}

	log.Fatal(srv.ListenAndServe())
}
```

### Registered URLs

Now let's see how to build registered URLs.

Routes can be named. All routes that define a name can have their URLs built, or "reversed". We define a name calling `Name()` on a route. For example:

```go
r := mux.NewRouter()
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
  Name("article")
```

To build a URL, get the route and call the `URL()` method, passing a sequence of key/value pairs for the route variables. For the previous route, we would do:

```go
url, err := r.Get("article").URL("category", "technology", "id", "42")
```

...and the result will be a `url.URL` with the following path:

```
"/articles/technology/42"
```

This also works for host variables:

```go
r := mux.NewRouter()
r.Host("{subdomain}.domain.com").
  Path("/articles/{category}/{id:[0-9]+}").
  HandlerFunc(ArticleHandler).
  Name("article")

// url.String() will be "http://news.domain.com/articles/technology/42"
url, err := r.Get("article").URL("subdomain", "news",
                                 "category", "technology",
                                 "id", "42")
```

All variables defined in the route are required, and their values must conform to the corresponding patterns. These requirements guarantee that a generated URL will always match a registered route -- the only exception is for explicitly defined "build-only" routes which never match.

Regex support also exists for matching Headers within a route. For example, we could do:

```go
r.HeadersRegexp("Content-Type", "application/(text|json)")
```

...and the route will match both requests with a Content-Type of `application/json` as well as `application/text`

There's also a way to build only the URL host or path for a route: use the methods `URLHost()` or `URLPath()` instead. For the previous route, we would do:

```go
// "http://news.domain.com/"
host, err := r.Get("article").URLHost("subdomain", "news")

// "/articles/technology/42"
path, err := r.Get("article").URLPath("category", "technology", "id", "42")
```

And if you use subrouters, host and path defined separately can be built as well:

```go
r := mux.NewRouter()
s := r.Host("{subdomain}.domain.com").Subrouter()
s.Path("/articles/{category}/{id:[0-9]+}").
  HandlerFunc(ArticleHandler).
  Name("article")

// "http://news.domain.com/articles/technology/42"
url, err := r.Get("article").URL("subdomain", "news",
                                 "category", "technology",
                                 "id", "42")
```

## Full Example

Here's a complete, runnable example of a small `mux` based server:

```go
package main

import (
	"net/http"
	"log"
	"github.com/gorilla/mux"
)

func YourHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Gorilla!\n"))
}

func main() {
	r := mux.NewRouter()
	// Routes consist of a path and a handler function.
	r.HandleFunc("/", YourHandler)

	// Bind to a port and pass our router in
	log.Fatal(http.ListenAndServe(":8000", r))
}
```

## License

BSD licensed. See the LICENSE file for details.


================================================
FILE: vendor/github.com/gorilla/mux/context_gorilla.go
================================================
// +build !go1.7

package mux

import (
	"net/http"

	"github.com/gorilla/context"
)

func contextGet(r *http.Request, key interface{}) interface{} {
	return context.Get(r, key)
}

func contextSet(r *http.Request, key, val interface{}) *http.Request {
	if val == nil {
		return r
	}

	context.Set(r, key, val)
	return r
}

func contextClear(r *http.Request) {
	context.Clear(r)
}


================================================
FILE: vendor/github.com/gorilla/mux/context_native.go
================================================
// +build go1.7

package mux

import (
	"context"
	"net/http"
)

func contextGet(r *http.Request, key interface{}) interface{} {
	return r.Context().Value(key)
}

func contextSet(r *http.Request, key, val interface{}) *http.Request {
	if val == nil {
		return r
	}

	return r.WithContext(context.WithValue(r.Context(), key, val))
}

func contextClear(r *http.Request) {
	return
}


================================================
FILE: vendor/github.com/gorilla/mux/doc.go
================================================
// Copyright 2012 The Gorilla 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 mux implements a request router and dispatcher.

The name mux stands for "HTTP request multiplexer". Like the standard
http.ServeMux, mux.Router matches incoming requests against a list of
registered routes and calls a handler for the route that matches the URL
or other conditions. The main features are:

	* Requests can be matched based on URL host, path, path prefix, schemes,
	  header and query values, HTTP methods or using custom matchers.
	* URL hosts and paths can have variables with an optional regular
	  expression.
	* Registered URLs can be built, or "reversed", which helps maintaining
	  references to resources.
	* Routes can be used as subrouters: nested routes are only tested if the
	  parent route matches. This is useful to define groups of routes that
	  share common conditions like a host, a path prefix or other repeated
	  attributes. As a bonus, this optimizes request matching.
	* It implements the http.Handler interface so it is compatible with the
	  standard http.ServeMux.

Let's start registering a couple of URL paths and handlers:

	func main() {
		r := mux.NewRouter()
		r.HandleFunc("/", HomeHandler)
		r.HandleFunc("/products", ProductsHandler)
		r.HandleFunc("/articles", ArticlesHandler)
		http.Handle("/", r)
	}

Here we register three routes mapping URL paths to handlers. This is
equivalent to how http.HandleFunc() works: if an incoming request URL matches
one of the paths, the corresponding handler is called passing
(http.ResponseWriter, *http.Request) as parameters.

Paths can have variables. They are defined using the format {name} or
{name:pattern}. If a regular expression pattern is not defined, the matched
variable will be anything until the next slash. For example:

	r := mux.NewRouter()
	r.HandleFunc("/products/{key}", ProductHandler)
	r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
	r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)

Groups can be used inside patterns, as long as they are non-capturing (?:re). For example:

	r.HandleFunc("/articles/{category}/{sort:(?:asc|desc|new)}", ArticlesCategoryHandler)

The names are used to create a map of route variables which can be retrieved
calling mux.Vars():

	vars := mux.Vars(request)
	category := vars["category"]

Note that if any capturing groups are present, mux will panic() during parsing. To prevent
this, convert any capturing groups to non-capturing, e.g. change "/{sort:(asc|desc)}" to
"/{sort:(?:asc|desc)}". This is a change from prior versions which behaved unpredictably
when capturing groups were present.

And this is all you need to know about the basic usage. More advanced options
are explained below.

Routes can also be restricted to a domain or subdomain. Just define a host
pattern to be matched. They can also have variables:

	r := mux.NewRouter()
	// Only matches if domain is "www.example.com".
	r.Host("www.example.com")
	// Matches a dynamic subdomain.
	r.Host("{subdomain:[a-z]+}.domain.com")

There are several other matchers that can be added. To match path prefixes:

	r.PathPrefix("/products/")

...or HTTP methods:

	r.Methods("GET", "POST")

...or URL schemes:

	r.Schemes("https")

...or header values:

	r.Headers("X-Requested-With", "XMLHttpRequest")

...or query values:

	r.Queries("key", "value")

...or to use a custom matcher function:

	r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool {
		return r.ProtoMajor == 0
	})

...and finally, it is possible to combine several matchers in a single route:

	r.HandleFunc("/products", ProductsHandler).
	  Host("www.example.com").
	  Methods("GET").
	  Schemes("http")

Setting the same matching conditions again and again can be boring, so we have
a way to group several routes that share the same requirements.
We call it "subrouting".

For example, let's say we have several URLs that should only match when the
host is "www.example.com". Create a route for that host and get a "subrouter"
from it:

	r := mux.NewRouter()
	s := r.Host("www.example.com").Subrouter()

Then register routes in the subrouter:

	s.HandleFunc("/products/", ProductsHandler)
	s.HandleFunc("/products/{key}", ProductHandler)
	s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler)

The three URL paths we registered above will only be tested if the domain is
"www.example.com", because the subrouter is tested first. This is not
only convenient, but also optimizes request matching. You can create
subrouters combining any attribute matchers accepted by a route.

Subrouters can be used to create domain or path "namespaces": you define
subrouters in a central place and then parts of the app can register its
paths relatively to a given subrouter.

There's one more thing about subroutes. When a subrouter has a path prefix,
the inner routes use it as base for their paths:

	r := mux.NewRouter()
	s := r.PathPrefix("/products").Subrouter()
	// "/products/"
	s.HandleFunc("/", ProductsHandler)
	// "/products/{key}/"
	s.HandleFunc("/{key}/", ProductHandler)
	// "/products/{key}/details"
	s.HandleFunc("/{key}/details", ProductDetailsHandler)

Note that the path provided to PathPrefix() represents a "wildcard": calling
PathPrefix("/static/").Handler(...) means that the handler will be passed any
request that matches "/static/*". This makes it easy to serve static files with mux:

	func main() {
		var dir string

		flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir")
		flag.Parse()
		r := mux.NewRouter()

		// This will serve files under http://localhost:8000/static/<filename>
		r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir))))

		srv := &http.Server{
			Handler:      r,
			Addr:         "127.0.0.1:8000",
			// Good practice: enforce timeouts for servers you create!
			WriteTimeout: 15 * time.Second,
			ReadTimeout:  15 * time.Second,
		}

		log.Fatal(srv.ListenAndServe())
	}

Now let's see how to build registered URLs.

Routes can be named. All routes that define a name can have their URLs built,
or "reversed". We define a name calling Name() on a route. For example:

	r := mux.NewRouter()
	r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
	  Name("article")

To build a URL, get the route and call the URL() method, passing a sequence of
key/value pairs for the route variables. For the previous route, we would do:

	url, err := r.Get("article").URL("category", "technology", "id", "42")

...and the result will be a url.URL with the following path:

	"/articles/technology/42"

This also works for host variables:

	r := mux.NewRouter()
	r.Host("{subdomain}.domain.com").
	  Path("/articles/{category}/{id:[0-9]+}").
	  HandlerFunc(ArticleHandler).
	  Name("article")

	// url.String() will be "http://news.domain.com/articles/technology/42"
	url, err := r.Get("article").URL("subdomain", "news",
	                                 "category", "technology",
	                                 "id", "42")

All variables defined in the route are required, and their values must
conform to the corresponding patterns. These requirements guarantee that a
generated URL will always match a registered route -- the only exception is
for explicitly defined "build-only" routes which never match.

Regex support also exists for matching Headers within a route. For example, we could do:

	r.HeadersRegexp("Content-Type", "application/(text|json)")

...and the route will match both requests with a Content-Type of `application/json` as well as
`application/text`

There's also a way to build only the URL host or path for a route:
use the methods URLHost() or URLPath() instead. For the previous route,
we would do:

	// "http://news.domain.com/"
	host, err := r.Get("article").URLHost("subdomain", "news")

	// "/articles/technology/42"
	path, err := r.Get("article").URLPath("category", "technology", "id", "42")

And if you use subrouters, host and path defined separately can be built
as well:

	r := mux.NewRouter()
	s := r.Host("{subdomain}.domain.com").Subrouter()
	s.Path("/articles/{category}/{id:[0-9]+}").
	  HandlerFunc(ArticleHandler).
	  Name("article")

	// "http://news.domain.com/articles/technology/42"
	url, err := r.Get("article").URL("subdomain", "news",
	                                 "category", "technology",
	                                 "id", "42")
*/
package mux


================================================
FILE: vendor/github.com/gorilla/mux/mux.go
================================================
// Copyright 2012 The Gorilla 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 mux

import (
	"errors"
	"fmt"
	"net/http"
	"path"
	"regexp"
	"strings"
)

// NewRouter returns a new router instance.
func NewRouter() *Router {
	return &Router{namedRoutes: make(map[string]*Route), KeepContext: false}
}

// Router registers routes to be matched and dispatches a handler.
//
// It implements the http.Handler interface, so it can be registered to serve
// requests:
//
//     var router = mux.NewRouter()
//
//     func main() {
//         http.Handle("/", router)
//     }
//
// Or, for Google App Engine, register it in a init() function:
//
//     func init() {
//         http.Handle("/", router)
//     }
//
// This will send all incoming requests to the router.
type Router struct {
	// Configurable Handler to be used when no route matches.
	NotFoundHandler http.Handler
	// Parent route, if this is a subrouter.
	parent parentRoute
	// Routes to be matched, in order.
	routes []*Route
	// Routes by name for URL building.
	namedRoutes map[string]*Route
	// See Router.StrictSlash(). This defines the flag for new routes.
	strictSlash bool
	// See Router.SkipClean(). This defines the flag for new routes.
	skipClean bool
	// If true, do not clear the request context after handling the request.
	// This has no effect when go1.7+ is used, since the context is stored
	// on the request itself.
	KeepContext bool
	// see Router.UseEncodedPath(). This defines a flag for all routes.
	useEncodedPath bool
}

// Match matches registered routes against the request.
func (r *Router) Match(req *http.Request, match *RouteMatch) bool {
	for _, route := range r.routes {
		if route.Match(req, match) {
			return true
		}
	}

	// Closest match for a router (includes sub-routers)
	if r.NotFoundHandler != nil {
		match.Handler = r.NotFoundHandler
		return true
	}
	return false
}

// ServeHTTP dispatches the handler registered in the matched route.
//
// When there is a match, the route variables can be retrieved calling
// mux.Vars(request).
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if !r.skipClean {
		path := req.URL.Path
		if r.useEncodedPath {
			path = getPath(req)
		}
		// Clean path to canonical form and redirect.
		if p := cleanPath(path); p != path {

			// Added 3 lines (Philip Schlump) - It was dropping the query string and #whatever from query.
			// This matches with fix in go 1.2 r.c. 4 for same problem.  Go Issue:
			// http://code.google.com/p/go/issues/detail?id=5252
			url := *req.URL
			url.Path = p
			p = url.String()

			w.Header().Set("Location", p)
			w.WriteHeader(http.StatusMovedPermanently)
			return
		}
	}
	var match RouteMatch
	var handler http.Handler
	if r.Match(req, &match) {
		handler = match.Handler
		req = setVars(req, match.Vars)
		req = setCurrentRoute(req, match.Route)
	}
	if handler == nil {
		handler = http.NotFoundHandler()
	}
	if !r.KeepContext {
		defer contextClear(req)
	}
	handler.ServeHTTP(w, req)
}

// Get returns a route registered with the given name.
func (r *Router) Get(name string) *Route {
	return r.getNamedRoutes()[name]
}

// GetRoute returns a route registered with the given name. This method
// was renamed to Get() and remains here for backwards compatibility.
func (r *Router) GetRoute(name string) *Route {
	return r.getNamedRoutes()[name]
}

// StrictSlash defines the trailing slash behavior for new routes. The initial
// value is false.
//
// When true, if the route path is "/path/", accessing "/path" will redirect
// to the former and vice versa. In other words, your application will always
// see the path as specified in the route.
//
// When false, if the route path is "/path", accessing "/path/" will not match
// this route and vice versa.
//
// Special case: when a route sets a path prefix using the PathPrefix() method,
// strict slash is ignored for that route because the redirect behavior can't
// be determined from a prefix alone. However, any subrouters created from that
// route inherit the original StrictSlash setting.
func (r *Router) StrictSlash(value bool) *Router {
	r.strictSlash = value
	return r
}

// SkipClean defines the path cleaning behaviour for new routes. The initial
// value is false. Users should be careful about which routes are not cleaned
//
// When true, if the route path is "/path//to", it will remain with the double
// slash. This is helpful if you have a route like: /fetch/http://xkcd.com/534/
//
// When false, the path will be cleaned, so /fetch/http://xkcd.com/534/ will
// become /fetch/http/xkcd.com/534
func (r *Router) SkipClean(value bool) *Router {
	r.skipClean = value
	return r
}

// UseEncodedPath tells the router to match the encoded original path
// to the routes.
// For eg. "/path/foo%2Fbar/to" will match the path "/path/{var}/to".
// This behavior has the drawback of needing to match routes against
// r.RequestURI instead of r.URL.Path. Any modifications (such as http.StripPrefix)
// to r.URL.Path will not affect routing when this flag is on and thus may
// induce unintended behavior.
//
// If not called, the router will match the unencoded path to the routes.
// For eg. "/path/foo%2Fbar/to" will match the path "/path/foo/bar/to"
func (r *Router) UseEncodedPath() *Router {
	r.useEncodedPath = true
	return r
}

// ----------------------------------------------------------------------------
// parentRoute
// ----------------------------------------------------------------------------

// getNamedRoutes returns the map where named routes are registered.
func (r *Router) getNamedRoutes() map[string]*Route {
	if r.namedRoutes == nil {
		if r.parent != nil {
			r.namedRoutes = r.parent.getNamedRoutes()
		} else {
			r.namedRoutes = make(map[string]*Route)
		}
	}
	return r.namedRoutes
}

// getRegexpGroup returns regexp definitions from the parent route, if any.
func (r *Router) getRegexpGroup() *routeRegexpGroup {
	if r.parent != nil {
		return r.parent.getRegexpGroup()
	}
	return nil
}

func (r *Router) buildVars(m map[string]string) map[string]string {
	if r.parent != nil {
		m = r.parent.buildVars(m)
	}
	return m
}

// ----------------------------------------------------------------------------
// Route factories
// ----------------------------------------------------------------------------

// NewRoute registers an empty route.
func (r *Router) NewRoute() *Route {
	route := &Route{parent: r, strictSlash: r.strictSlash, skipClean: r.skipClean, useEncodedPath: r.useEncodedPath}
	r.routes = append(r.routes, route)
	return route
}

// Handle registers a new route with a matcher for the URL path.
// See Route.Path() and Route.Handler().
func (r *Router) Handle(path string, handler http.Handler) *Route {
	return r.NewRoute().Path(path).Handler(handler)
}

// HandleFunc registers a new route with a matcher for the URL path.
// See Route.Path() and Route.HandlerFunc().
func (r *Router) HandleFunc(path string, f func(http.ResponseWriter,
	*http.Request)) *Route {
	return r.NewRoute().Path(path).HandlerFunc(f)
}

// Headers registers a new route with a matcher for request header values.
// See Route.Headers().
func (r *Router) Headers(pairs ...string) *Route {
	return r.NewRoute().Headers(pairs...)
}

// Host registers a new route with a matcher for the URL host.
// See Route.Host().
func (r *Router) Host(tpl string) *Route {
	return r.NewRoute().Host(tpl)
}

// MatcherFunc registers a new route with a custom matcher function.
// See Route.MatcherFunc().
func (r *Router) MatcherFunc(f MatcherFunc) *Route {
	return r.NewRoute().MatcherFunc(f)
}

// Methods registers a new route with a matcher for HTTP methods.
// See Route.Methods().
func (r *Router) Methods(methods ...string) *Route {
	return r.NewRoute().Methods(methods...)
}

// Path registers a new route with a matcher for the URL path.
// See Route.Path().
func (r *Router) Path(tpl string) *Route {
	return r.NewRoute().Path(tpl)
}

// PathPrefix registers a new route with a matcher for the URL path prefix.
// See Route.PathPrefix().
func (r *Router) PathPrefix(tpl string) *Route {
	return r.NewRoute().PathPrefix(tpl)
}

// Queries registers a new route with a matcher for URL query values.
// See Route.Queries().
func (r *Router) Queries(pairs ...string) *Route {
	return r.NewRoute().Queries(pairs...)
}

// Schemes registers a new route with a matcher for URL schemes.
// See Route.Schemes().
func (r *Router) Schemes(schemes ...string) *Route {
	return r.NewRoute().Schemes(schemes...)
}

// BuildVarsFunc registers a new route with a custom function for modifying
// route variables before building a URL.
func (r *Router) BuildVarsFunc(f BuildVarsFunc) *Route {
	return r.NewRoute().BuildVarsFunc(f)
}

// Walk walks the router and all its sub-routers, calling walkFn for each route
// in the tree. The routes are walked in the order they were added. Sub-routers
// are explored depth-first.
func (r *Router) Walk(walkFn WalkFunc) error {
	return r.walk(walkFn, []*Route{})
}

// SkipRouter is used as a return value from WalkFuncs to indicate that the
// router that walk is about to descend down to should be skipped.
var SkipRouter = errors.New("skip this router")

// WalkFunc is the type of the function called for each route visited by Walk.
// At every invocation, it is given the current route, and the current router,
// and a list of ancestor routes that lead to the current route.
type WalkFunc func(route *Route, router *Router, ancestors []*Route) error

func (r *Router) walk(walkFn WalkFunc, ancestors []*Route) error {
	for _, t := range r.routes {
		if t.regexp == nil || t.regexp.path == nil || t.regexp.path.template == "" {
			continue
		}

		err := walkFn(t, r, ancestors)
		if err == SkipRouter {
			continue
		}
		if err != nil {
			return err
		}
		for _, sr := range t.matchers {
			if h, ok := sr.(*Router); ok {
				err := h.walk(walkFn, ancestors)
				if err != nil {
					return err
				}
			}
		}
		if h, ok := t.handler.(*Router); ok {
			ancestors = append(ancestors, t)
			err := h.walk(walkFn, ancestors)
			if err != nil {
				return err
			}
			ancestors = ancestors[:len(ancestors)-1]
		}
	}
	return nil
}

// ----------------------------------------------------------------------------
// Context
// ----------------------------------------------------------------------------

// RouteMatch stores information about a matched route.
type RouteMatch struct {
	Route   *Route
	Handler http.Handler
	Vars    map[string]string
}

type contextKey int

const (
	varsKey contextKey = iota
	routeKey
)

// Vars returns the route variables for the current request, if any.
func Vars(r *http.Request) map[string]string {
	if rv := contextGet(r, varsKey); rv != nil {
		return rv.(map[string]string)
	}
	return nil
}

// CurrentRoute returns the matched route for the current request, if any.
// This only works when called inside the handler of the matched route
// because the matched route is stored in the request context which is cleared
// after the handler returns, unless the KeepContext option is set on the
// Router.
func CurrentRoute(r *http.Request) *Route {
	if rv := contextGet(r, routeKey); rv != nil {
		return rv.(*Route)
	}
	return nil
}

func setVars(r *http.Request, val interface{}) *http.Request {
	return contextSet(r, varsKey, val)
}

func setCurrentRoute(r *http.Request, val interface{}) *http.Request {
	return contextSet(r, routeKey, val)
}

// ----------------------------------------------------------------------------
// Helpers
// ----------------------------------------------------------------------------

// getPath returns the escaped path if possible; doing what URL.EscapedPath()
// which was added in go1.5 does
func getPath(req *http.Request) string {
	if req.RequestURI != "" {
		// Extract the path from RequestURI (which is escaped unlike URL.Path)
		// as detailed here as detailed in https://golang.org/pkg/net/url/#URL
		// for < 1.5 server side workaround
		// http://localhost/path/here?v=1 -> /path/here
		path := req.RequestURI
		path = strings.TrimPrefix(path, req.URL.Scheme+`://`)
		path = strings.TrimPrefix(path, req.URL.Host)
		if i := strings.LastIndex(path, "?"); i > -1 {
			path = path[:i]
		}
		if i := strings.LastIndex(path, "#"); i > -1 {
			path = path[:i]
		}
		return path
	}
	return req.URL.Path
}

// cleanPath returns the canonical path for p, eliminating . and .. elements.
// Borrowed from the net/http package.
func cleanPath(p string) string {
	if p == "" {
		return "/"
	}
	if p[0] != '/' {
		p = "/" + p
	}
	np := path.Clean(p)
	// path.Clean removes trailing slash except for root;
	// put the trailing slash back if necessary.
	if p[len(p)-1] == '/' && np != "/" {
		np += "/"
	}

	return np
}

// uniqueVars returns an error if two slices contain duplicated strings.
func uniqueVars(s1, s2 []string) error {
	for _, v1 := range s1 {
		for _, v2 := range s2 {
			if v1 == v2 {
				return fmt.Errorf("mux: duplicated route variable %q", v2)
			}
		}
	}
	return nil
}

// checkPairs returns the count of strings passed in, and an error if
// the count is not an even number.
func checkPairs(pairs ...string) (int, error) {
	length := len(pairs)
	if length%2 != 0 {
		return length, fmt.Errorf(
			"mux: number of parameters must be multiple of 2, got %v", pairs)
	}
	return length, nil
}

// mapFromPairsToString converts variadic string parameters to a
// string to string map.
func mapFromPairsToString(pairs ...string) (map[string]string, error) {
	length, err := checkPairs(pairs...)
	if err != nil {
		return nil, err
	}
	m := make(map[string]string, length/2)
	for i := 0; i < length; i += 2 {
		m[pairs[i]] = pairs[i+1]
	}
	return m, nil
}

// mapFromPairsToRegex converts variadic string paramers to a
// string to regex map.
func mapFromPairsToRegex(pairs ...string) (map[string]*regexp.Regexp, error) {
	length, err := checkPairs(pairs...)
	if err != nil {
		return nil, err
	}
	m := make(map[string]*regexp.Regexp, length/2)
	for i := 0; i < length; i += 2 {
		regex, err := regexp.Compile(pairs[i+1])
		if err != nil {
			return nil, err
		}
		m[pairs[i]] = regex
	}
	return m, nil
}

// matchInArray returns true if the given string value is in the array.
func matchInArray(arr []string, value string) bool {
	for _, v := range arr {
		if v == value {
			return true
		}
	}
	return false
}

// matchMapWithString returns true if the given key/value pairs exist in a given map.
func matchMapWithString(toCheck map[string]string, toMatch map[string][]string, canonicalKey bool) bool {
	for k, v := range toCheck {
		// Check if key exists.
		if canonicalKey {
			k = http.CanonicalHeaderKey(k)
		}
		if values := toMatch[k]; values == nil {
			return false
		} else if v != "" {
			// If value was defined as an empty string we only check that the
			// key exists. Otherwise we also check for equality.
			valueExists := false
			for _, value := range values {
				if v == value {
					valueExists = true
					break
				}
			}
			if !valueExists {
				return false
			}
		}
	}
	return true
}

// matchMapWithRegex returns true if the given key/value pairs exist in a given map compiled against
// the given regex
func matchMapWithRegex(toCheck map[string]*regexp.Regexp, toMatch map[string][]string, canonicalKey bool) bool {
	for k, v := range toCheck {
		// Check if key exists.
		if canonicalKey {
			k = http.CanonicalHeaderKey(k)
		}
		if values := toMatch[k]; values == nil {
			return false
		} else if v != nil {
			// If value was defined as an empty string we only check that the
			// key exists. Otherwise we also check for equality.
			valueExists := false
			for _, value := range values {
				if v.MatchString(value) {
					valueExists = true
					break
				}
			}
			if !valueExists {
				return false
			}
		}
	}
	return true
}


================================================
FILE: vendor/github.com/gorilla/mux/regexp.go
================================================
// Copyright 2012 The Gorilla 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 mux

import (
	"bytes"
	"fmt"
	"net/http"
	"net/url"
	"regexp"
	"strconv"
	"strings"
)

// newRouteRegexp parses a route template and returns a routeRegexp,
// used to match a host, a path or a query string.
//
// It will extract named variables, assemble a regexp to be matched, create
// a "reverse" template to build URLs and compile regexps to validate variable
// values used in URL building.
//
// Previously we accepted only Python-like identifiers for variable
// names ([a-zA-Z_][a-zA-Z0-9_]*), but currently the only restriction is that
// name and pattern can't be empty, and names can't contain a colon.
func newRouteRegexp(tpl string, matchHost, matchPrefix, matchQuery, strictSlash, useEncodedPath bool) (*routeRegexp, error) {
	// Check if it is well-formed.
	idxs, errBraces := braceIndices(tpl)
	if errBraces != nil {
		return nil, errBraces
	}
	// Backup the original.
	template := tpl
	// Now let's parse it.
	defaultPattern := "[^/]+"
	if matchQuery {
		defaultPattern = "[^?&]*"
	} else if matchHost {
		defaultPattern = "[^.]+"
		matchPrefix = false
	}
	// Only match strict slash if not matching
	if matchPrefix || matchHost || matchQuery {
		strictSlash = false
	}
	// Set a flag for strictSlash.
	endSlash := false
	if strictSlash && strings.HasSuffix(tpl, "/") {
		tpl = tpl[:len(tpl)-1]
		endSlash = true
	}
	varsN := make([]string, len(idxs)/2)
	varsR := make([]*regexp.Regexp, len(idxs)/2)
	pattern := bytes.NewBufferString("")
	pattern.WriteByte('^')
	reverse := bytes.NewBufferString("")
	var end int
	var err error
	for i := 0; i < len(idxs); i += 2 {
		// Set all values we are interested in.
		raw := tpl[end:idxs[i]]
		end = idxs[i+1]
		parts := strings.SplitN(tpl[idxs[i]+1:end-1], ":", 2)
		name := parts[0]
		patt := defaultPattern
		if len(parts) == 2 {
			patt = parts[1]
		}
		// Name or pattern can't be empty.
		if name == "" || patt == "" {
			return nil, fmt.Errorf("mux: missing name or pattern in %q",
				tpl[idxs[i]:end])
		}
		// Build the regexp pattern.
		fmt.Fprintf(pattern, "%s(?P<%s>%s)", regexp.QuoteMeta(raw), varGroupName(i/2), patt)

		// Build the reverse template.
		fmt.Fprintf(reverse, "%s%%s", raw)

		// Append variable name and compiled pattern.
		varsN[i/2] = name
		varsR[i/2], err = regexp.Compile(fmt.Sprintf("^%s$", patt))
		if err != nil {
			return nil, err
		}
	}
	// Add the remaining.
	raw := tpl[end:]
	pattern.WriteString(regexp.QuoteMeta(raw))
	if strictSlash {
		pattern.WriteString("[/]?")
	}
	if matchQuery {
		// Add the default pattern if the query value is empty
		if queryVal := strings.SplitN(template, "=", 2)[1]; queryVal == "" {
			pattern.WriteString(defaultPattern)
		}
	}
	if !matchPrefix {
		pattern.WriteByte('$')
	}
	reverse.WriteString(raw)
	if endSlash {
		reverse.WriteByte('/')
	}
	// Compile full regexp.
	reg, errCompile := regexp.Compile(pattern.String())
	if errCompile != nil {
		return nil, errCompile
	}

	// Check for capturing groups which used to work in older versions
	if reg.NumSubexp() != len(idxs)/2 {
		panic(fmt.Sprintf("route %s contains capture groups in its regexp. ", template) +
			"Only non-capturing groups are accepted: e.g. (?:pattern) instead of (pattern)")
	}

	// Done!
	return &routeRegexp{
		template:       template,
		matchHost:      matchHost,
		matchQuery:     matchQuery,
		strictSlash:    strictSlash,
		useEncodedPath: useEncodedPath,
		regexp:         reg,
		reverse:        reverse.String(),
		varsN:          varsN,
		varsR:          varsR,
	}, nil
}

// routeRegexp stores a regexp to match a host or path and information to
// collect and validate route variables.
type routeRegexp struct {
	// The unmodified template.
	template string
	// True for host match, false for path or query string match.
	matchHost bool
	// True for query string match, false for path and host match.
	matchQuery bool
	// The strictSlash value defined on the route, but disabled if PathPrefix was used.
	strictSlash bool
	// Determines whether to use encoded path from getPath function or unencoded
	// req.URL.Path for path matching
	useEncodedPath bool
	// Expanded regexp.
	regexp *regexp.Regexp
	// Reverse template.
	reverse string
	// Variable names.
	varsN []string
	// Variable regexps (validators).
	varsR []*regexp.Regexp
}

// Match matches the regexp against the URL host or path.
func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool {
	if !r.matchHost {
		if r.matchQuery {
			return r.matchQueryString(req)
		}
		path := req.URL.Path
		if r.useEncodedPath {
			path = getPath(req)
		}
		return r.regexp.MatchString(path)
	}

	return r.regexp.MatchString(getHost(req))
}

// url builds a URL part using the given values.
func (r *routeRegexp) url(values map[string]string) (string, error) {
	urlValues := make([]interface{}, len(r.varsN))
	for k, v := range r.varsN {
		value, ok := values[v]
		if !ok {
			return "", fmt.Errorf("mux: missing route variable %q", v)
		}
		urlValues[k] = value
	}
	rv := fmt.Sprintf(r.reverse, urlValues...)
	if !r.regexp.MatchString(rv) {
		// The URL is checked against the full regexp, instead of checking
		// individual variables. This is faster but to provide a good error
		// message, we check individual regexps if the URL doesn't match.
		for k, v := range r.varsN {
			if !r.varsR[k].MatchString(values[v]) {
				return "", fmt.Errorf(
					"mux: variable %q doesn't match, expected %q", values[v],
					r.varsR[k].String())
			}
		}
	}
	return rv, nil
}

// getURLQuery returns a single query parameter from a request URL.
// For a URL with foo=bar&baz=ding, we return only the relevant key
// value pair for the routeRegexp.
func (r *routeRegexp) getURLQuery(req *http.Request) string {
	if !r.matchQuery {
		return ""
	}
	templateKey := strings.SplitN(r.template, "=", 2)[0]
	for key, vals := range req.URL.Query() {
		if key == templateKey && len(vals) > 0 {
			return key + "=" + vals[0]
		}
	}
	return ""
}

func (r *routeRegexp) matchQueryString(req *http.Request) bool {
	return r.regexp.MatchString(r.getURLQuery(req))
}

// braceIndices returns the first level curly brace indices from a string.
// It returns an error in case of unbalanced braces.
func braceIndices(s string) ([]int, error) {
	var level, idx int
	var idxs []int
	for i := 0; i < len(s); i++ {
		switch s[i] {
		case '{':
			if level++; level == 1 {
				idx = i
			}
		case '}':
			if level--; level == 0 {
				idxs = append(idxs, idx, i+1)
			} else if level < 0 {
				return nil, fmt.Errorf("mux: unbalanced braces in %q", s)
			}
		}
	}
	if level != 0 {
		return nil, fmt.Errorf("mux: unbalanced braces in %q", s)
	}
	return idxs, nil
}

// varGroupName builds a capturing group name for the indexed variable.
func varGroupName(idx int) string {
	return "v" + strconv.Itoa(idx)
}

// ----------------------------------------------------------------------------
// routeRegexpGroup
// ----------------------------------------------------------------------------

// routeRegexpGroup groups the route matchers that carry variables.
type routeRegexpGroup struct {
	host    *routeRegexp
	path    *routeRegexp
	queries []*routeRegexp
}

// setMatch extracts the variables from the URL once a route matches.
func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route) {
	// Store host variables.
	if v.host != nil {
		host := getHost(req)
		matches := v.host.regexp.FindStringSubmatchIndex(host)
		if len(matches) > 0 {
			extractVars(host, matches, v.host.varsN, m.Vars)
		}
	}
	path := req.URL.Path
	if r.useEncodedPath {
		path = getPath(req)
	}
	// Store path variables.
	if v.path != nil {
		matches := v.path.regexp.FindStringSubmatchIndex(path)
		if len(matches) > 0 {
			extractVars(path, matches, v.path.varsN, m.Vars)
			// Check if we should redirect.
			if v.path.strictSlash {
				p1 := strings.HasSuffix(path, "/")
				p2 := strings.HasSuffix(v.path.template, "/")
				if p1 != p2 {
					u, _ := url.Parse(req.URL.String())
					if p1 {
						u.Path = u.Path[:len(u.Path)-1]
					} else {
						u.Path += "/"
					}
					m.Handler = http.RedirectHandler(u.String(), 301)
				}
			}
		}
	}
	// Store query string variables.
	for _, q := range v.queries {
		queryURL := q.getURLQuery(req)
		matches := q.regexp.FindStringSubmatchIndex(queryURL)
		if len(matches) > 0 {
			extractVars(queryURL, matches, q.varsN, m.Vars)
		}
	}
}

// getHost tries its best to return the request host.
func getHost(r *http.Request) string {
	if r.URL.IsAbs() {
		return r.URL.Host
	}
	host := r.Host
	// Slice off any port information.
	if i := strings.Index(host, ":"); i != -1 {
		host = host[:i]
	}
	return host

}

func extractVars(input string, matches []int, names []string, output map[string]string) {
	for i, name := range names {
		output[name] = input[matches[2*i+2]:matches[2*i+3]]
	}
}


================================================
FILE: vendor/github.com/gorilla/mux/route.go
================================================
// Copyright 2012 The Gorilla 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 mux

import (
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"regexp"
	"strings"
)

// Route stores information to match a request and build URLs.
type Route struct {
	// Parent where the route was registered (a Router).
	parent parentRoute
	// Request handler for the route.
	handler http.Handler
	// List of matchers.
	matchers []matcher
	// Manager for the variables from host and path.
	regexp *routeRegexpGroup
	// If true, when the path pattern is "/path/", accessing "/path" will
	// redirect to the former and vice versa.
	strictSlash bool
	// If true, when the path pattern is "/path//to", accessing "/path//to"
	// will not redirect
	skipClean bool
	// If true, "/path/foo%2Fbar/to" will match the path "/path/{var}/to"
	useEncodedPath bool
	// If true, this route never matches: it is only used to build URLs.
	buildOnly bool
	// The name used to build URLs.
	name string
	// Error resulted from building a route.
	err error

	buildVarsFunc BuildVarsFunc
}

func (r *Route) SkipClean() bool {
	return r.skipClean
}

// Match matches the route against the request.
func (r *Route) Match(req *http.Request, match *RouteMatch) bool {
	if r.buildOnly || r.err != nil {
		return false
	}
	// Match everything.
	for _, m := range r.matchers {
		if matched := m.Match(req, match); !matched {
			return false
		}
	}
	// Yay, we have a match. Let's collect some info about it.
	if match.Route == nil {
		match.Route = r
	}
	if match.Handler == nil {
		match.Handler = r.handler
	}
	if match.Vars == nil {
		match.Vars = make(map[string]string)
	}
	// Set variables.
	if r.regexp != nil {
		r.regexp.setMatch(req, match, r)
	}
	return true
}

// ----------------------------------------------------------------------------
// Route attributes
// ----------------------------------------------------------------------------

// GetError returns an error resulted from building the route, if any.
func (r *Route) GetError() error {
	return r.err
}

// BuildOnly sets the route to never match: it is only used to build URLs.
func (r *Route) BuildOnly() *Route {
	r.buildOnly = true
	return r
}

// Handler --------------------------------------------------------------------

// Handler sets a handler for the route.
func (r *Route) Handler(handler http.Handler) *Route {
	if r.err == nil {
		r.handler = handler
	}
	return r
}

// HandlerFunc sets a handler function for the route.
func (r *Route) HandlerFunc(f func(http.ResponseWriter, *http.Request)) *Route {
	return r.Handler(http.HandlerFunc(f))
}

// GetHandler returns the handler for the route, if any.
func (r *Route) GetHandler() http.Handler {
	return r.handler
}

// Name -----------------------------------------------------------------------

// Name sets the name for the route, used to build URLs.
// If the name was registered already it will be overwritten.
func (r *Route) Name(name string) *Route {
	if r.name != "" {
		r.err = fmt.Errorf("mux: route already has name %q, can't set %q",
			r.name, name)
	}
	if r.err == nil {
		r.name = name
		r.getNamedRoutes()[name] = r
	}
	return r
}

// GetName returns the name for the route, if any.
func (r *Route) GetName() string {
	return r.name
}

// ----------------------------------------------------------------------------
// Matchers
// ----------------------------------------------------------------------------

// matcher types try to match a request.
type matcher interface {
	Match(*http.Request, *RouteMatch) bool
}

// addMatcher adds a matcher to the route.
func (r *Route) addMatcher(m matcher) *Route {
	if r.err == nil {
		r.matchers = append(r.matchers, m)
	}
	return r
}

// addRegexpMatcher adds a host or path matcher and builder to a route.
func (r *Route) addRegexpMatcher(tpl string, matchHost, matchPrefix, matchQuery bool) error {
	if r.err != nil {
		return r.err
	}
	r.regexp = r.getRegexpGroup()
	if !matchHost && !matchQuery {
		if len(tpl) > 0 && tpl[0] != '/' {
			return fmt.Errorf("mux: path must start with a slash, got %q", tpl)
		}
		if r.regexp.path != nil {
			tpl = strings.TrimRight(r.regexp.path.template, "/") + tpl
		}
	}
	rr, err := newRouteRegexp(tpl, matchHost, matchPrefix, matchQuery, r.strictSlash, r.useEncodedPath)
	if err != nil {
		return err
	}
	for _, q := range r.regexp.queries {
		if err = uniqueVars(rr.varsN, q.varsN); err != nil {
			return err
		}
	}
	if matchHost {
		if r.regexp.path != nil {
			if err = uniqueVars(rr.varsN, r.regexp.path.varsN); err != nil {
				return err
			}
		}
		r.regexp.host = rr
	} else {
		if r.regexp.host != nil {
			if err = uniqueVars(rr.varsN, r.regexp.host.varsN); err != nil {
				return err
			}
		}
		if matchQuery {
			r.regexp.queries = append(r.regexp.queries, rr)
		} else {
			r.regexp.path = rr
		}
	}
	r.addMatcher(rr)
	return nil
}

// Headers --------------------------------------------------------------------

// headerMatcher matches the request against header values.
type headerMatcher map[string]string

func (m headerMatcher) Match(r *http.Request, match *RouteMatch) bool {
	return matchMapWithString(m, r.Header, true)
}

// Headers adds a matcher for request header values.
// It accepts a sequence of key/value pairs to be matched. For example:
//
//     r := mux.NewRouter()
//     r.Headers("Content-Type", "application/json",
//               "X-Requested-With", "XMLHttpRequest")
//
// The above route will only match if both request header values match.
// If the value is an empty string, it will match any value if the key is set.
func (r *Route) Headers(pairs ...string) *Route {
	if r.err == nil {
		var headers map[string]string
		headers, r.err = mapFromPairsToString(pairs...)
		return r.addMatcher(headerMatcher(headers))
	}
	return r
}

// headerRegexMatcher matches the request against the route given a regex for the header
type headerRegexMatcher map[string]*regexp.Regexp

func (m headerRegexMatcher) Match(r *http.Request, match *RouteMatch) bool {
	return matchMapWithRegex(m, r.Header, true)
}

// HeadersRegexp accepts a sequence of key/value pairs, where the value has regex
// support. For example:
//
//     r := mux.NewRouter()
//     r.HeadersRegexp("Content-Type", "application/(text|json)",
//               "X-Requested-With", "XMLHttpRequest")
//
// The above route will only match if both the request header matches both regular expressions.
// It the value is an empty string, it will match any value if the key is set.
func (r *Route) HeadersRegexp(pairs ...string) *Route {
	if r.err == nil {
		var headers map[string]*regexp.Regexp
		headers, r.err = mapFromPairsToRegex(pairs...)
		return r.addMatcher(headerRegexMatcher(headers))
	}
	return r
}

// Host -----------------------------------------------------------------------

// Host adds a matcher for the URL host.
// It accepts a template with zero or more URL variables enclosed by {}.
// Variables can define an optional regexp pattern to be matched:
//
// - {name} matches anything until the next dot.
//
// - {name:pattern} matches the given regexp pattern.
//
// For example:
//
//     r := mux.NewRouter()
//     r.Host("www.example.com")
//     r.Host("{subdomain}.domain.com")
//     r.Host("{subdomain:[a-z]+}.domain.com")
//
// Variable names must be unique in a given route. They can be retrieved
// calling mux.Vars(request).
func (r *Route) Host(tpl string) *Route {
	r.err = r.addRegexpMatcher(tpl, true, false, false)
	return r
}

// MatcherFunc ----------------------------------------------------------------

// MatcherFunc is the function signature used by custom matchers.
type MatcherFunc func(*http.Request, *RouteMatch) bool

// Match returns the match for a given request.
func (m MatcherFunc) Match(r *http.Request, match *RouteMatch) bool {
	return m(r, match)
}

// MatcherFunc adds a custom function to be used as request matcher.
func (r *Route) MatcherFunc(f MatcherFunc) *Route {
	return r.addMatcher(f)
}

// Methods --------------------------------------------------------------------

// methodMatcher matches the request against HTTP methods.
type methodMatcher []string

func (m methodMatcher) Match(r *http.Request, match *RouteMatch) bool {
	return matchInArray(m, r.Method)
}

// Methods adds a matcher for HTTP methods.
// It accepts a sequence of one or more methods to be matched, e.g.:
// "GET", "POST", "PUT".
func (r *Route) Methods(methods ...string) *Route {
	for k, v := range methods {
		methods[k] = strings.ToUpper(v)
	}
	return r.addMatcher(methodMatcher(methods))
}

// Path -----------------------------------------------------------------------

// Path adds a matcher for the URL path.
// It accepts a template with zero or more URL variables enclosed by {}. The
// template must start with a "/".
// Variables can define an optional regexp pattern to be matched:
//
// - {name} matches anything until the next slash.
//
// - {name:pattern} matches the given regexp pattern.
//
// For example:
//
//     r := mux.NewRouter()
//     r.Path("/products/").Handler(ProductsHandler)
//     r.Path("/products/{key}").Handler(ProductsHandler)
//     r.Path("/articles/{category}/{id:[0-9]+}").
//       Handler(ArticleHandler)
//
// Variable names must be unique in a given route. They can be retrieved
// calling mux.Vars(request).
func (r *Route) Path(tpl string) *Route {
	r.err = r.addRegexpMatcher(tpl, false, false, false)
	return r
}

// PathPrefix -----------------------------------------------------------------

// PathPrefix adds a matcher for the URL path prefix. This matches if the given
// template is a prefix of the full URL path. See Route.Path() for details on
// the tpl argument.
//
// Note that it does not treat slashes specially ("/foobar/" will be matched by
// the prefix "/foo") so you may want to use a trailing slash here.
//
// Also note that the setting of Router.StrictSlash() has no effect on routes
// with a PathPrefix matcher.
func (r *Route) PathPrefix(tpl string) *Route {
	r.err = r.addRegexpMatcher(tpl, false, true, false)
	return r
}

// Query ----------------------------------------------------------------------

// Queries adds a matcher for URL query values.
// It accepts a sequence of key/value pairs. Values may define variables.
// For example:
//
//     r := mux.NewRouter()
//     r.Queries("foo", "bar", "id", "{id:[0-9]+}")
//
// The above route will only match if the URL contains the defined queries
// values, e.g.: ?foo=bar&id=42.
//
// It the value is an empty string, it will match any value if the key is set.
//
// Variables can define an optional regexp pattern to be matched:
//
// - {name} matches anything until the next slash.
//
// - {name:pattern} matches the given regexp pattern.
func (r *Route) Queries(pairs ...string) *Route {
	length := len(pairs)
	if length%2 != 0 {
		r.err = fmt.Errorf(
			"mux: number of parameters must be multiple of 2, got %v", pairs)
		return nil
	}
	for i := 0; i < length; i += 2 {
		if r.err = r.addRegexpMatcher(pairs[i]+"="+pairs[i+1], false, false, true); r.err != nil {
			return r
		}
	}

	return r
}

// Schemes --------------------------------------------------------------------

// schemeMatcher matches the request against URL schemes.
type schemeMatcher []string

func (m schemeMatcher) Match(r *http.Request, match *RouteMatch) bool {
	return matchInArray(m, r.URL.Scheme)
}

// Schemes adds a matcher for URL schemes.
// It accepts a sequence of schemes to be matched, e.g.: "http", "https".
func (r *Route) Schemes(schemes ...string) *Route {
	for k, v := range schemes {
		schemes[k] = strings.ToLower(v)
	}
	return r.addMatcher(schemeMatcher(schemes))
}

// BuildVarsFunc --------------------------------------------------------------

// BuildVarsFunc is the function signature used by custom build variable
// functions (which can modify route variables before a route's URL is built).
type BuildVarsFunc func(map[string]string) map[string]string

// BuildVarsFunc adds a custom function to be used to modify build variables
// before a route's URL is built.
func (r *Route) BuildVarsFunc(f BuildVarsFunc) *Route {
	r.buildVarsFunc = f
	return r
}

// Subrouter ------------------------------------------------------------------

// Subrouter creates a subrouter for the route.
//
// It will test the inner routes only if the parent route matched. For example:
//
//     r := mux.NewRouter()
//     s := r.Host("www.example.com").Subrouter()
//     s.HandleFunc("/products/", ProductsHandler)
//     s.HandleFunc("/products/{key}", ProductHandler)
//     s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler)
//
// Here, the routes registered in the subrouter won't be tested if the host
// doesn't match.
func (r *Route) Subrouter() *Router {
	router := &Router{parent: r, strictSlash: r.strictSlash}
	r.addMatcher(router)
	return router
}

// ----------------------------------------------------------------------------
// URL building
// ----------------------------------------------------------------------------

// URL builds a URL for the route.
//
// It accepts a sequence of key/value pairs for the route variables. For
// example, given this route:
//
//     r := mux.NewRouter()
//     r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
//       Name("article")
//
// ...a URL for it can be built using:
//
//     url, err := r.Get("article").URL("category", "technology", "id", "42")
//
// ...which will return an url.URL with the following path:
//
//     "/articles/technology/42"
//
// This also works for host variables:
//
//     r := mux.NewRouter()
//     r.Host("{subdomain}.domain.com").
//       HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
//       Name("article")
//
//     // url.String() will be "http://news.domain.com/articles/technology/42"
//     url, err := r.Get("article").URL("subdomain", "news",
//                                      "category", "technology",
//                                      "id", "42")
//
// All variables defined in the route are required, and their values must
// conform to the corresponding patterns.
func (r *Route) URL(pairs ...string) (*url.URL, error) {
	if r.err != nil {
		return nil, r.err
	}
	if r.regexp == nil {
		return nil, errors.New("mux: route doesn't have a host or path")
	}
	values, err := r.prepareVars(pairs...)
	if err != nil {
		return nil, err
	}
	var scheme, host, path string
	if r.regexp.host != nil {
		// Set a default scheme.
		scheme = "http"
		if host, err = r.regexp.host.url(values); err != nil {
			return nil, err
		}
	}
	if r.regexp.path != nil {
		if path, err = r.regexp.path.url(values); err != nil {
			return nil, err
		}
	}
	return &url.URL{
		Scheme: scheme,
		Host:   host,
		Path:   path,
	}, nil
}

// URLHost builds the host part of the URL for a route. See Route.URL().
//
// The route must have a host defined.
func (r *Route) URLHost(pairs ...string) (*url.URL, error) {
	if r.err != nil {
		return nil, r.err
	}
	if r.regexp == nil || r.regexp.host == nil {
		return nil, errors.New("mux: route doesn't have a host")
	}
	values, err := r.prepareVars(pairs...)
	if err != nil {
		return nil, err
	}
	host, err := r.regexp.host.url(values)
	if err != nil {
		return nil, err
	}
	return &url.URL{
		Scheme: "http",
		Host:   host,
	}, nil
}

// URLPath builds the path part of the URL for a route. See Route.URL().
//
// The route must have a path defined.
func (r *Route) URLPath(pairs ...string) (*url.URL, error) {
	if r.err != nil {
		return nil, r.err
	}
	if r.regexp == nil || r.regexp.path == nil {
		return nil, errors.New("mux: route doesn't have a path")
	}
	values, err := r.prepareVars(pairs...)
	if err != nil {
		return nil, err
	}
	path, err := r.regexp.path.url(values)
	if err != nil {
		return nil, err
	}
	return &url.URL{
		Path: path,
	}, nil
}

// GetPathTemplate returns the template used to build the
// route match.
// This is useful for building simple REST API documentation and for instrumentation
// against third-party services.
// An error will be returned if the route does not define a path.
func (r *Route) GetPathTemplate() (string, error) {
	if r.err != nil {
		return "", r.err
	}
	if r.regexp == nil || r.regexp.path == nil {
		return "", errors.New("mux: route doesn't have a path")
	}
	return r.regexp.path.template, nil
}

// GetHostTemplate returns the template used to build the
// route match.
// This is useful for building simple REST API documentation and for instrumentation
// against third-party services.
// An error will be returned if the route does not define a host.
func (r *Route) GetHostTemplate() (string, error) {
	if r.err != nil {
		return "", r.err
	}
	if r.regexp == nil || r.regexp.host == nil {
		return "", errors.New("mux: route doesn't have a host")
	}
	return r.regexp.host.template, nil
}

// prepareVars converts the route variable pairs into a map. If the route has a
// BuildVarsFunc, it is invoked.
func (r *Route) prepareVars(pairs ...string) (map[string]string, error) {
	m, err := mapFromPairsToString(pairs...)
	if err != nil {
		return nil, err
	}
	return r.buildVars(m), nil
}

func (r *Route) buildVars(m map[string]string) map[string]string {
	if r.parent != nil {
		m = r.parent.buildVars(m)
	}
	if r.buildVarsFunc != nil {
		m = r.buildVarsFunc(m)
	}
	return m
}

// ----------------------------------------------------------------------------
// parentRoute
// ----------------------------------------------------------------------------

// parentRoute allows routes to know about parent host and path definitions.
type parentRoute interface {
	getNamedRoutes() map[string]*Route
	getRegexpGroup() *routeRegexpGroup
	buildVars(map[string]string) map[string]string
}

// getNamedRoutes returns the map where named routes are registered.
func (r *Route) getNamedRoutes() map[string]*Route {
	if r.parent == nil {
		// During tests router is not always set.
		r.parent = NewRouter()
	}
	return r.parent.getNamedRoutes()
}

// getRegexpGroup returns regexp definitions from this route.
func (r *Route) getRegexpGroup() *routeRegexpGroup {
	if r.regexp == nil {
		if r.parent == nil {
			// During tests router is not always set.
			r.parent = NewRouter()
		}
		regexp := r.parent.getRegexpGroup()
		if regexp == nil {
			r.regexp = new(routeRegexpGroup)
		} else {
			// Copy.
			r.regexp = &routeRegexpGroup{
				host:    regexp.host,
				path:    regexp.path,
				queries: regexp.queries,
			}
		}
	}
	return r.regexp
}


================================================
FILE: vendor/github.com/gorilla/pat/LICENSE
================================================
Copyright (c) 2012 Rodrigo Moraes. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

	 * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
	 * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
	 * Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: vendor/github.com/gorilla/pat/README.md
================================================
pat
===
[![GoDoc](https://godoc.org/github.com/gorilla/pat?status.svg)](https://godoc.org/github.com/gorilla/pat)
[![Build Status](https://travis-ci.org/gorilla/pat.svg?branch=master)](https://travis-ci.org/gorilla/pat)

### How to use?

pat is pretty simple. The documentation lives [here](http://www.gorillatoolkit.org/pkg/pat).

### Install
With a properly configured Go toolchain:
```sh
go get github.com/gorilla/pat
```

### Example

Here's an example of a RESTful api:

```go
package main

import (
	"log"
	"net/http"

	"github.com/gorilla/pat"
)

func homeHandler(wr http.ResponseWriter, req *http.Request) {
	wr.WriteHeader(http.StatusOK)
	wr.Write([]byte("Yay! We're home, Jim!"))
}

func getAllTheThings(wr http.ResponseWriter, req *http.Request) {
	wr.WriteHeader(http.StatusOK)
	wr.Write([]byte("Look, Jim! Get all the things!"))
}

func putOneThing(wr http.ResponseWriter, req *http.Request) {
	wr.WriteHeader(http.StatusOK)
	wr.Write([]byte("Look, Jim! Put one thing!"))
}

func deleteOneThing(wr http.ResponseWriter, req *http.Request) {
	wr.WriteHeader(http.StatusOK)
	wr.Write([]byte("Look, Jim! Delete one thing!"))
}

func main() {
    router := pat.New()

	router.Get("/things", getAllTheThings)

    router.Put("/things/{id}", putOneThing)
    router.Delete("/things/{id}", deleteOneThing)

	router.Get("/", homeHandler)

	http.Handle("/", router)

	log.Print("Listening on 127.0.0.1:8000...")
	log.Fatal(http.ListenAndServe(":8000", nil))
}
```
Notice how the routes descend? That's because Pat will take the first route
that matches. For your own testing, take the line ```router.Get("/",
homeHandler)``` and put it above the other routes and run the example. When you
try to curl any of the routes, you'll only get what the homeHandler returns.
Design your routes carefully.


================================================
FILE: vendor/github.com/gorilla/pat/doc.go
================================================
// Copyright 2012 The Gorilla 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 gorilla/pat is a request router and dispatcher with a pat-like
interface. It is an alternative to gorilla/mux that showcases how it can
be used as a base for different API flavors. Package pat is documented at:

	http://godoc.org/github.com/bmizerany/pat

Let's start registering a couple of URL paths and handlers:

	func main() {
		r := pat.New()
		r.Get("/products", ProductsHandler)
		r.Get("/articles", ArticlesHandler)
		r.Get("/", HomeHandler)
		http.Handle("/", r)
	}

Here we register three routes mapping URL paths to handlers. This is
equivalent to how http.HandleFunc() works: if an incoming GET request matches
one of the paths, the corresponding handler is called passing
(http.ResponseWriter, *http.Request) as parameters.

Note: gorilla/pat matches path prefixes, so you must register the most
specific paths first.

Note: differently from pat, these methods accept a handler function, and not an
http.Handler. We think this is shorter and more convenient. To set an
http.Handler, use the Add() method.

Paths can have variables. They are defined using the format {name} or
{name:pattern}. If a regular expression pattern is not defined, the matched
variable will be anything until the next slash. For example:

	r := pat.New()
	r.Get("/articles/{category}/{id:[0-9]+}", ArticleHandler)
	r.Get("/articles/{category}/", ArticlesCategoryHandler)
	r.Get("/products/{key}", ProductHandler)

The names are used to create a map of route variables which are stored in the
URL query, prefixed by a colon:

	category := req.URL.Query().Get(":category")

As in the gorilla/mux package, other matchers can be added to the registered
routes and URLs can be reversed as well. To build a URL for a route, first
add a name to it:

	r.Get("/products/{key}", ProductHandler).Name("product")

Then you can get it using the name and generate a URL:

	url, err := r.GetRoute("product").URL("key", "transmogrifier")

...and the result will be a url.URL with the following path:

	"/products/transmogrifier"

Check the mux documentation for more details about URL building and extra
matchers:

	http://gorilla-web.appspot.com/pkg/mux/
*/
package pat


================================================
FILE: vendor/github.com/gorilla/pat/pat.go
================================================
// Copyright 2012 The Gorilla 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 pat

import (
	"net/http"
	"net/url"
	"path"
	"strings"

	"github.com/gorilla/context"
	"github.com/gorilla/mux"
)

// New returns a new router.
func New() *Router {
	return &Router{}
}

// Router is a request router that implements a pat-like API.
//
// pat docs: http://godoc.org/github.com/bmizerany/pat
type Router struct {
	mux.Router
}

// Add registers a pattern with a handler for the given request method.
func (r *Router) Add(meth, pat string, h http.Handler) *mux.Route {
	return r.NewRoute().PathPrefix(pat).Handler(h).Methods(meth)
}

// Options registers a pattern with a handler for OPTIONS requests.
func (r *Router) Options(pat string, h http.HandlerFunc) *mux.Route {
	return r.Add("OPTIONS", pat, h)
}

// Delete registers a pattern with a handler for DELETE requests.
func (r *Router) Delete(pat string, h http.HandlerFunc) *mux.Route {
	return r.Add("DELETE", pat, h)
}

// Head registers a pattern with a handler for HEAD requests.
func (r *Router) Head(pat string, h http.HandlerFunc) *mux.Route {
	return r.Add("HEAD", pat, h)
}

// Get registers a pattern with a handler for GET requests.
func (r *Router) Get(pat string, h http.HandlerFunc) *mux.Route {
	return r.Add("GET", pat, h)
}

// Post registers a pattern with a handler for POST requests.
func (r *Router) Post(pat string, h http.HandlerFunc) *mux.Route {
	return r.Add("POST", pat, h)
}

// Put registers a pattern with a handler for PUT requests.
func (r *Router) Put(pat string, h http.HandlerFunc) *mux.Route {
	return r.Add("PUT", pat, h)
}

// Patch registers a pattern with a handler for PATCH requests.
func (r *Router) Patch(pat string, h http.HandlerFunc) *mux.Route {
	return r.Add("PATCH", pat, h)
}

// ServeHTTP dispatches the handler registered in the matched route.
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	// Clean path to canonical form and redirect.
	if p := cleanPath(req.URL.Path); p != req.URL.Path {
		w.Header().Set("Location", p)
		w.WriteHeader(http.StatusMovedPermanently)
		return
	}
	var match mux.RouteMatch
	var handler http.Handler
	if matched := r.Match(req, &match); matched {
		handler = match.Handler
		registerVars(req, match.Vars)
	}
	if handler == nil {
		if r.NotFoundHandler == nil {
			r.NotFoundHandler = http.NotFoundHandler()
		}
		handler = r.NotFoundHandler
	}
	if !r.KeepContext {
		defer context.Clear(req)
	}
	handler.ServeHTTP(w, req)
}

// registerVars adds the matched route variables to the URL query.
func registerVars(r *http.Request, vars map[string]string) {
	parts, i := make([]string, len(vars)), 0
	for key, value := range vars {
		parts[i] = url.QueryEscape(":"+key) + "=" + url.QueryEscape(value)
		i++
	}
	q := strings.Join(parts, "&")
	if r.URL.RawQuery == "" {
		r.URL.RawQuery = q
	} else {
		r.URL.RawQuery += "&" + q
	}
}

// cleanPath returns the canonical path for p, eliminating . and .. elements.
// Borrowed from the net/http package.
func cleanPath(p string) string {
	if p == "" {
		return "/"
	}
	if p[0] != '/' {
		p = "/" + p
	}
	np := path.Clean(p)
	// path.Clean removes trailing slash except for root;
	// put the trailing slash back if necessary.
	if p[len(p)-1] == '/' && np != "/" {
		np += "/"
	}
	return np
}


================================================
FILE: vendor/github.com/gorilla/websocket/AUTHORS
================================================
# This is the official list of Gorilla WebSocket authors for copyright
# purposes.
#
# Please keep the list sorted.

Gary Burd <gary@beagledreams.com>
Joachim Bauch <mail@joachim-bauch.de>



================================================
FILE: vendor/github.com/gorilla/websocket/LICENSE
================================================
Copyright (c) 2013 The Gorilla WebSocket 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.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: vendor/github.com/gorilla/websocket/README.md
================================================
# Gorilla WebSocket

Gorilla WebSocket is a [Go](http://golang.org/) implementation of the
[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol.

[![Build Status](https://travis-ci.org/gorilla/websocket.svg?branch=master)](https://travis-ci.org/gorilla/websocket)
[![GoDoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket)

### Documentation

* [API Reference](http://godoc.org/github.com/gorilla/websocket)
* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat)
* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command)
* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo)
* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch)

### Status

The Gorilla WebSocket package provides a complete and tested implementation of
the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The
package API is stable.

### Installation

    go get github.com/gorilla/websocket

### Protocol Compliance

The Gorilla WebSocket package passes the server tests in the [Autobahn Test
Suite](http://autobahn.ws/testsuite) using the application in the [examples/autobahn
subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn).

### Gorilla WebSocket compared with other packages

<table>
<tr>
<th></th>
<th><a href="http://godoc.org/github.com/gorilla/websocket">github.com/gorilla</a></th>
<th><a href="http://godoc.org/golang.org/x/net/websocket">golang.org/x/net</a></th>
</tr>
<tr>
<tr><td colspan="3"><a href="http://tools.ietf.org/html/rfc6455">RFC 6455</a> Features</td></tr>
<tr><td>Passes <a href="http://autobahn.ws/testsuite/">Autobahn Test Suite</a></td><td><a href="https://github.com/gorilla/websocket/tree/master/examples/autobahn">Yes</a></td><td>No</td></tr>
<tr><td>Receive <a href="https://tools.ietf.org/html/rfc6455#section-5.4">fragmented</a> message<td>Yes</td><td><a href="https://code.google.com/p/go/issues/detail?id=7632">No</a>, see note 1</td></tr>
<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close</a> message</td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td><a href="https://code.google.com/p/go/issues/detail?id=4588">No</a></td></tr>
<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">pings</a> and receive <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pongs</a></td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td>No</td></tr>
<tr><td>Get the <a href="https://tools.ietf.org/html/rfc6455#section-5.6">type</a> of a received data message</td><td>Yes</td><td>Yes, see note 2</td></tr>
<tr><td colspan="3">Other Features</tr></td>
<tr><td><a href="https://tools.ietf.org/html/rfc7692">Compression Extensions</a></td><td>Experimental</td><td>No</td></tr>
<tr><td>Read message using io.Reader</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextReader">Yes</a></td><td>No, see note 3</td></tr>
<tr><td>Write message using io.WriteCloser</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextWriter">Yes</a></td><td>No, see note 3</td></tr>
</table>

Notes: 

1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html).
2. The application can get the type of a received data message by implementing
   a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal)
   function.
3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries.
  Read returns when the input buffer is full or a frame boundary is
  encountered. Each call to Write sends a single frame message. The Gorilla
  io.Reader and io.WriteCloser operate on a single WebSocket message.



================================================
FILE: vendor/github.com/gorilla/websocket/client.go
================================================
// Copyright 2013 The Gorilla WebSocket 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 websocket

import (
	"bufio"
	"bytes"
	"crypto/tls"
	"encoding/base64"
	"errors"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"strings"
	"time"
)

// ErrBadHandshake is returned when the server response to opening handshake is
// invalid.
var ErrBadHandshake = errors.New("websocket: bad handshake")

var errInvalidCompression = errors.New("websocket: invalid compression negotiation")

// NewClient creates a new client connection using the given net connection.
// The URL u specifies the host and request URI. Use requestHeader to specify
// the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies
// (Cookie). Use the response.Header to get the selected subprotocol
// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).
//
// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
// non-nil *http.Response so that callers can handle redirects, authentication,
// etc.
//
// Deprecated: Use Dialer instead.
func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) {
	d := Dialer{
		ReadBufferSize:  readBufSize,
		WriteBufferSize: writeBufSize,
		NetDial: func(net, addr string) (net.Conn, error) {
			return netConn, nil
		},
	}
	return d.Dial(u.String(), requestHeader)
}

// A Dialer contains options for connecting to WebSocket server.
type Dialer struct {
	// NetDial specifies the dial function for creating TCP connections. If
	// NetDial is nil, net.Dial is used.
	NetDial func(network, addr string) (net.Conn, error)

	// Proxy specifies a function to return a proxy for a given
	// Request. If the function returns a non-nil error, the
	// request is aborted with the provided error.
	// If Proxy is nil or returns a nil *URL, no proxy is used.
	Proxy func(*http.Request) (*url.URL, error)

	// TLSClientConfig specifies the TLS configuration to use with tls.Client.
	// If nil, the default configuration is used.
	TLSClientConfig *tls.Config

	// HandshakeTimeout specifies the duration for the handshake to complete.
	HandshakeTimeout time.Duration

	// ReadBufferSize and WriteBufferSize specify I/O buffer sizes. If a buffer
	// size is zero, then a useful default size is used. The I/O buffer sizes
	// do not limit the size of the messages that can be sent or received.
	ReadBufferSize, WriteBufferSize int

	// Subprotocols specifies the client's requested subprotocols.
	Subprotocols []string

	// EnableCompression specifies if the client should attempt to negotiate
	// per message compression (RFC 7692). Setting this value to true does not
	// guarantee that compression will be supported. Currently only "no context
	// takeover" modes are supported.
	EnableCompression bool

	// Jar specifies the cookie jar.
	// If Jar is nil, cookies are not sent in requests and ignored
	// in responses.
	Jar http.CookieJar
}

var errMalformedURL = errors.New("malformed ws or wss URL")

// parseURL parses the URL.
//
// This function is a replacement for the standard library url.Parse function.
// In Go 1.4 and earlier, url.Parse loses information from the path.
func parseURL(s string) (*url.URL, error) {
	// From the RFC:
	//
	// ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
	// wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]
	var u url.URL
	switch {
	case strings.HasPrefix(s, "ws://"):
		u.Scheme = "ws"
		s = s[len("ws://"):]
	case strings.HasPrefix(s, "wss://"):
		u.Scheme = "wss"
		s = s[len("wss://"):]
	default:
		return nil, errMalformedURL
	}

	if i := strings.Index(s, "?"); i >= 0 {
		u.RawQuery = s[i+1:]
		s = s[:i]
	}

	if i := strings.Index(s, "/"); i >= 0 {
		u.Opaque = s[i:]
		s = s[:i]
	} else {
		u.Opaque = "/"
	}

	u.Host = s

	if strings.Contains(u.Host, "@") {
		// Don't bother parsing user information because user information is
		// not allowed in websocket URIs.
		return nil, errMalformedURL
	}

	return &u, nil
}

func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) {
	hostPort = u.Host
	hostNoPort = u.Host
	if i := strings.LastIndex(u.Host, ":"); i > strings.LastIndex(u.Host, "]") {
		hostNoPort = hostNoPort[:i]
	} else {
		switch u.Scheme {
		case "wss":
			hostPort += ":443"
		case "https":
			hostPort += ":443"
		default:
			hostPort += ":80"
		}
	}
	return hostPort, hostNoPort
}

// DefaultDialer is a dialer with all fields set to the default zero values.
var DefaultDialer = &Dialer{
	Proxy: http.ProxyFromEnvironment,
}

// Dial creates a new client connection. Use requestHeader to specify the
// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie).
// Use the response.Header to get the selected subprotocol
// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).
//
// If the WebSocket handshake fails, ErrBadHandshake is returned along with a
// non-nil *http.Response so that callers can handle redirects, authentication,
// etcetera. The response body may not contain the entire response and does not
// need to be closed by the application.
func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {

	if d == nil {
		d = &Dialer{
			Proxy: http.ProxyFromEnvironment,
		}
	}

	challengeKey, err := generateChallengeKey()
	if err != nil {
		return nil, nil, err
	}

	u, err := parseURL(urlStr)
	if err != nil {
		return nil, nil, err
	}

	switch u.Scheme {
	case "ws":
		u.Scheme = "http"
	case "wss":
		u.Scheme = "https"
	default:
		return nil, nil, errMalformedURL
	}

	if u.User != nil {
		// User name and password are not allowed in websocket URIs.
		return nil, nil, errMalformedURL
	}

	req := &http.Request{
		Method:     "GET",
		URL:        u,
		Proto:      "HTTP/1.1",
		ProtoMajor: 1,
		ProtoMinor: 1,
		Header:     make(http.Header),
		Host:       u.Host,
	}

	// Set the cookies present in the cookie jar of the dialer
	if d.Jar != nil {
		for _, cookie := range d.Jar.Cookies(u) {
			req.AddCookie(cookie)
		}
	}

	// Set the request headers using the capitalization for names and values in
	// RFC examples. Although the capitalization shouldn't matter, there are
	// servers that depend on it. The Header.Set method is not used because the
	// method canonicalizes the header names.
	req.Header["Upgrade"] = []string{"websocket"}
	req.Header["Connection"] = []string{"Upgrade"}
	req.Header["Sec-WebSocket-Key"] = []string{challengeKey}
	req.Header["Sec-WebSocket-Version"] = []string{"13"}
	if len(d.Subprotocols) > 0 {
		req.Header["Sec-WebSocket-Protocol"] = []string{strings.Join(d.Subprotocols, ", ")}
	}
	for k, vs := range requestHeader {
		switch {
		case k == "Host":
			if len(vs) > 0 {
				req.Host = vs[0]
			}
		case k == "Upgrade" ||
			k == "Connection" ||
			k == "Sec-Websocket-Key" ||
			k == "Sec-Websocket-Version" ||
			k == "Sec-Websocket-Extensions" ||
			(k == "Sec-Websocket-Protocol" && len(d.Subprotocols) > 0):
			return nil, nil, errors.New("websocket: duplicate header not allowed: " + k)
		default:
			req.Header[k] = vs
		}
	}

	if d.EnableCompression {
		req.Header.Set("Sec-Websocket-Extensions", "permessage-deflate; server_no_context_takeover; client_no_context_takeover")
	}

	hostPort, hostNoPort := hostPortNoPort(u)

	var proxyURL *url.URL
	// Check wether the proxy method has been configured
	if d.Proxy != nil {
		proxyURL, err = d.Proxy(req)
	}
	if err != nil {
		return nil, nil, err
	}

	var targetHostPort string
	if proxyURL != nil {
		targetHostPort, _ = hostPortNoPort(proxyURL)
	} else {
		targetHostPort = hostPort
	}

	var deadline time.Time
	if d.HandshakeTimeout != 0 {
		deadline = time.Now().Add(d.HandshakeTimeout)
	}

	netDial := d.NetDial
	if netDial == nil {
		netDialer := &net.Dialer{Deadline: deadline}
		netDial = netDialer.Dial
	}

	netConn, err := netDial("tcp", targetHostPort)
	if err != nil {
		return nil, nil, err
	}

	defer func() {
		if netConn != nil {
			netConn.Close()
		}
	}()

	if err := netConn.SetDeadline(deadline); err != nil {
		return nil, nil, err
	}

	if proxyURL != nil {
		connectHeader := make(http.Header)
		if user := proxyURL.User; user != nil {
			proxyUser := user.Username()
			if proxyPassword, passwordSet := user.Password(); passwordSet {
				credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword))
				connectHeader.Set("Proxy-Authorization", "Basic "+credential)
			}
		}
		connectReq := &http.Request{
			Method: "CONNECT",
			URL:    &url.URL{Opaque: hostPort},
			Host:   hostPort,
			Header: connectHeader,
		}

		connectReq.Write(netConn)

		// Read response.
		// Okay to use and discard buffered reader here, because
		// TLS server will not speak until spoken to.
		br := bufio.NewReader(netConn)
		resp, err := http.ReadResponse(br, connectReq)
		if err != nil {
			return nil, nil, err
		}
		if resp.StatusCode != 200 {
			f := strings.SplitN(resp.Status, " ", 2)
			return nil, nil, errors.New(f[1])
		}
	}

	if u.Scheme == "https" {
		cfg := cloneTLSConfig(d.TLSClientConfig)
		if cfg.ServerName == "" {
			cfg.ServerName = hostNoPort
		}
		tlsConn := tls.Client(netConn, cfg)
		netConn = tlsConn
		if err := tlsConn.Handshake(); err != nil {
			return nil, nil, err
		}
		if !cfg.InsecureSkipVerify {
			if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
				return nil, nil, err
			}
		}
	}

	conn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize)

	if err := req.Write(netConn); err != nil {
		return nil, nil, err
	}

	resp, err := http.ReadResponse(conn.br, req)
	if err != nil {
		return nil, nil, err
	}

	if d.Jar != nil {
		if rc := resp.Cookies(); len(rc) > 0 {
			d.Jar.SetCookies(u, rc)
		}
	}

	if resp.StatusCode != 101 ||
		!strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") ||
		!strings.EqualFold(resp.Header.Get("Connection"), "upgrade") ||
		resp.Header.Get("Sec-Websocket-Accept") != computeAcceptKey(challengeKey) {
		// Before closing the network connection on return from this
		// function, slurp up some of the response to aid application
		// debugging.
		buf := make([]byte, 1024)
		n, _ := io.ReadFull(resp.Body, buf)
		resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n]))
		return nil, resp, ErrBadHandshake
	}

	for _, ext := range parseExtensions(resp.Header) {
		if ext[""] != "permessage-deflate" {
			continue
		}
		_, snct := ext["server_no_context_takeover"]
		_, cnct := ext["client_no_context_takeover"]
		if !snct || !cnct {
			return nil, resp, errInvalidCompression
		}
		conn.newCompressionWriter = compressNoContextTakeover
		conn.newDecompressionReader = decompressNoContextTakeover
		break
	}

	resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
	conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol")

	netConn.SetDeadline(time.Time{})
	netConn = nil // to avoid close in defer.
	return conn, resp, nil
}


================================================
FILE: vendor/github.com/gorilla/websocket/client_clone.go
================================================
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build go1.8

package websocket

import "crypto/tls"

func cloneTLSConfig(cfg *tls.Config) *tls.Config {
	if cfg == nil {
		return &tls.Config{}
	}
	return cfg.Clone()
}


================================================
FILE: vendor/github.com/gorilla/websocket/client_clone_legacy.go
================================================
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !go1.8

package websocket

import "crypto/tls"

// cloneTLSConfig clones all public fields except the fields
// SessionTicketsDisabled and SessionTicketKey. This avoids copying the
// sync.Mutex in the sync.Once and makes it safe to call cloneTLSConfig on a
// config in active use.
func cloneTLSConfig(cfg *tls.Config) *tls.Config {
	if cfg == nil {
		return &tls.Config{}
	}
	return &tls.Config{
		Rand:                     cfg.Rand,
		Time:                     cfg.Time,
		Certificates:             cfg.Certificates,
		NameToCertificate:        cfg.NameToCertificate,
		GetCertificate:           cfg.GetCertificate,
		RootCAs:                  cfg.RootCAs,
		NextProtos:               cfg.NextProtos,
		ServerName:               cfg.ServerName,
		ClientAuth:               cfg.ClientAuth,
		ClientCAs:                cfg.ClientCAs,
		InsecureSkipVerify:       cfg.InsecureSkipVerify,
		CipherSuites:             cfg.CipherSuites,
		PreferServerCipherSuites: cfg.PreferServerCipherSuites,
		ClientSessionCache:       cfg.ClientSessionCache,
		MinVersion:               cfg.MinVersion,
		MaxVersion:               cfg.MaxVersion,
		CurvePreferences:         cfg.CurvePreferences,
	}
}


================================================
FILE: vendor/github.com/gorilla/websocket/compression.go
================================================
// Copyright 2017 The Gorilla WebSocket 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 websocket

import (
	"compress/flate"
	"errors"
	"io"
	"strings"
	"sync"
)

const (
	minCompressionLevel     = -2 // flate.HuffmanOnly not defined in Go < 1.6
	maxCompressionLevel     = flate.BestCompression
	defaultCompressionLevel = 1
)

var (
	flateWriterPools [maxCompressionLevel - minCompressionLevel + 1]sync.Pool
	flateReaderPool  = sync.Pool{New: func() interface{} {
		return flate.NewReader(nil)
	}}
)

func decompressNoContextTakeover(r io.Reader) io.ReadCloser {
	const tail =
	// Add four bytes as specified in RFC
	"\x00\x00\xff\xff" +
		// Add final block to squelch unexpected EOF error from flate reader.
		"\x01\x00\x00\xff\xff"

	fr, _ := flateReaderPool.Get().(io.ReadCloser)
	fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil)
	return &flateReadWrapper{fr}
}

func isValidCompressionLevel(level int) bool {
	return minCompressionLevel <= level && level <= maxCompressionLevel
}

func compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser {
	p := &flateWriterPools[level-minCompressionLevel]
	tw := &truncWriter{w: w}
	fw, _ := p.Get().(*flate.Writer)
	if fw == nil {
		fw, _ = flate.NewWriter(tw, level)
	} else {
		fw.Reset(tw)
	}
	return &flateWriteWrapper{fw: fw, tw: tw, p: p}
}

// truncWriter is an io.Writer that writes all but the last four bytes of the
// stream to another io.Writer.
type truncWriter struct {
	w io.WriteCloser
	n int
	p [4]byte
}

func (w *truncWriter) Write(p []byte) (int, error) {
	n := 0

	// fill buffer first for simplicity.
	if w.n < len(w.p) {
		n = copy(w.p[w.n:], p)
		p = p[n:]
		w.n += n
		if len(p) == 0 {
			return n, nil
		}
	}

	m := len(p)
	if m > len(w.p) {
		m = len(w.p)
	}

	if nn, err := w.w.Write(w.p[:m]); err != nil {
		return n + nn, err
	}

	copy(w.p[:], w.p[m:])
	copy(w.p[len(w.p)-m:], p[len(p)-m:])
	nn, err := w.w.Write(p[:len(p)-m])
	return n + nn, err
}

type flateWriteWrapper struct {
	fw *flate.Writer
	tw *truncWriter
	p  *sync.Pool
}

func (w *flateWriteWrapper) Write(p []byte) (int, error) {
	if w.fw == nil {
		return 0, errWriteClosed
	}
	return w.fw.Write(p)
}

func (w *flateWriteWrapper) Close() error {
	if w.fw == nil {
		return errWriteClosed
	}
	err1 := w.fw.Flush()
	w.p.Put(w.fw)
	w.fw = nil
	if w.tw.p != [4]byte{0, 0, 0xff, 0xff} {
		return errors.New("websocket: internal error, unexpected bytes at end of flate stream")
	}
	err2 := w.tw.w.Close()
	if err1 != nil {
		return err1
	}
	return err2
}

type flateReadWrapper struct {
	fr io.ReadCloser
}

func (r *flateReadWrapper) Read(p []byte) (int, error) {
	if r.fr == nil {
		return 0, io.ErrClosedPipe
	}
	n, err := r.fr.Read(p)
	if err == io.EOF {
		// Preemptively place the reader back in the pool. This helps with
		// scenarios where the application does not call NextReader() soon after
		// this final read.
		r.Close()
	}
	return n, err
}

func (r *flateReadWrapper) Close() error {
	if r.fr == nil {
		return io.ErrClosedPipe
	}
	err := r.fr.Close()
	flateReaderPool.Put(r.fr)
	r.fr = nil
	return err
}


================================================
FILE: vendor/github.com/gorilla/websocket/conn.go
================================================
// Copyright 2013 The Gorilla WebSocket 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 websocket

import (
	"bufio"
	"encoding/binary"
	"errors"
	"io"
	"io/ioutil"
	"math/rand"
	"net"
	"strconv"
	"sync"
	"time"
	"unicode/utf8"
)

const (
	// Frame header byte 0 bits from Section 5.2 of RFC 6455
	finalBit = 1 << 7
	rsv1Bit  = 1 << 6
	rsv2Bit  = 1 << 5
	rsv3Bit  = 1 << 4

	// Frame header byte 1 bits from Section 5.2 of RFC 6455
	maskBit = 1 << 7

	maxFrameHeaderSize         = 2 + 8 + 4 // Fixed header + length + mask
	maxControlFramePayloadSize = 125

	writeWait = time.Second

	defaultReadBufferSize  = 4096
	defaultWriteBufferSize = 4096

	continuationFrame = 0
	noFrame           = -1
)

// Close codes defined in RFC 6455, section 11.7.
const (
	CloseNormalClosure           = 1000
	CloseGoingAway               = 1001
	CloseProtocolError           = 1002
	CloseUnsupportedData         = 1003
	CloseNoStatusReceived        = 1005
	CloseAbnormalClosure         = 1006
	CloseInvalidFramePayloadData = 1007
	ClosePolicyViolation         = 1008
	CloseMessageTooBig           = 1009
	CloseMandatoryExtension      = 1010
	CloseInternalServerErr       = 1011
	CloseServiceRestart          = 1012
	CloseTryAgainLater           = 1013
	CloseTLSHandshake            = 1015
)

// The message types are defined in RFC 6455, section 11.8.
const (
	// TextMessage denotes a text data message. The text message payload is
	// interpreted as UTF-8 encoded text data.
	TextMessage = 1

	// BinaryMessage denotes a binary data message.
	BinaryMessage = 2

	// CloseMessage denotes a close control message. The optional message
	// payload contains a numeric code and text. Use the FormatCloseMessage
	// function to format a close message payload.
	CloseMessage = 8

	// PingMessage denotes a ping control message. The optional message payload
	// is UTF-8 encoded text.
	PingMessage = 9

	// PongMessage denotes a ping control message. The optional message payload
	// is UTF-8 encoded text.
	PongMessage = 10
)

// ErrCloseSent is returned when the application writes a message to the
// connection after sending a close message.
var ErrCloseSent = errors.New("websocket: close sent")

// ErrReadLimit is returned when reading a message that is larger than the
// read limit set for the connection.
var ErrReadLimit = errors.New("websocket: read limit exceeded")

// netError satisfies the net Error interface.
type netError struct {
	msg       string
	temporary bool
	timeout   bool
}

func (e *netError) Error() string   { return e.msg }
func (e *netError) Temporary() bool { return e.temporary }
func (e *netError) Timeout() bool   { return e.timeout }

// CloseError represents close frame.
type CloseError struct {

	// Code is defined in RFC 6455, section 11.7.
	Code int

	// Text is the optional text payload.
	Text string
}

func (e *CloseError) Error() string {
	s := []byte("websocket: close ")
	s = strconv.AppendInt(s, int64(e.Code), 10)
	switch e.Code {
	case CloseNormalClosure:
		s = append(s, " (normal)"...)
	case CloseGoingAway:
		s = append(s, " (going away)"...)
	case CloseProtocolError:
		s = append(s, " (protocol error)"...)
	case CloseUnsupportedData:
		s = append(s, " (unsupported data)"...)
	case CloseNoStatusReceived:
		s = append(s, " (no status)"...)
	case CloseAbnormalClosure:
		s = append(s, " (abnormal closure)"...)
	case CloseInvalidFramePayloadData:
		s = append(s, " (invalid payload data)"...)
	case ClosePolicyViolation:
		s = append(s, " (policy violation)"...)
	case CloseMessageTooBig:
		s = append(s, " (message too big)"...)
	case CloseMandatoryExtension:
		s = append(s, " (mandatory extension missing)"...)
	case CloseInternalServerErr:
		s = append(s, " (internal server error)"...)
	case CloseTLSHandshake:
		s = append(s, " (TLS handshake error)"...)
	}
	if e.Text != "" {
		s = append(s, ": "...)
		s = append(s, e.Text...)
	}
	return string(s)
}

// IsCloseError returns boolean indicating whether the error is a *CloseError
// with one of the specified codes.
func IsCloseError(err error, codes ...int) bool {
	if e, ok := err.(*CloseError); ok {
		for _, code := range codes {
			if e.Code == code {
				return true
			}
		}
	}
	return false
}

// IsUnexpectedCloseError returns boolean indicating whether the error is a
// *CloseError with a code not in the list of expected codes.
func IsUnexpectedCloseError(err error, expectedCodes ...int) bool {
	if e, ok := err.(*CloseError); ok {
		for _, code := range expectedCodes {
			if e.Code == code {
				return false
			}
		}
		return true
	}
	return false
}

var (
	errWriteTimeout        = &netError{msg: "websocket: write timeout", timeout: true, temporary: true}
	errUnexpectedEOF       = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()}
	errBadWriteOpCode      = errors.New("websocket: bad write message type")
	errWriteClosed         = errors.New("websocket: write closed")
	errInvalidControlFrame = errors.New("websocket: invalid control frame")
)

func newMaskKey() [4]byte {
	n := rand.Uint32()
	return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)}
}

func hideTempErr(err error) error {
	if e, ok := err.(net.Error); ok && e.Temporary() {
		err = &netError{msg: e.Error(), timeout: e.Timeout()}
	}
	return err
}

func isControl(frameType int) bool {
	return frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage
}

func isData(frameType int) bool {
	return frameType == TextMessage || frameType == BinaryMessage
}

var validReceivedCloseCodes = map[int]bool{
	// see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number

	CloseNormalClosure:           true,
	CloseGoingAway:               true,
	CloseProtocolError:           true,
	CloseUnsupportedData:         true,
	CloseNoStatusReceived:        false,
	CloseAbnormalClosure:         false,
	CloseInvalidFramePayloadData: true,
	ClosePolicyViolation:         true,
	CloseMessageTooBig:           true,
	CloseMandatoryExtension:      true,
	CloseInternalServerErr:       true,
	CloseServiceRestart:          true,
	CloseTryAgainLater:           true,
	CloseTLSHandshake:            false,
}

func isValidReceivedCloseCode(code int) bool {
	return validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999)
}

// The Conn type represents a WebSocket connection.
type Conn struct {
	conn        net.Conn
	isServer    bool
	subprotocol string

	// Write fields
	mu            chan bool // used as mutex to protect write to conn
	writeBuf      []byte    // frame is constructed in this buffer.
	writeDeadline time.Time
	writer        io.WriteCloser // the current writer returned to the application
	isWriting     bool           // for best-effort concurrent write detection

	writeErrMu sync.Mutex
	writeErr   error

	enableWriteCompression bool
	compressionLevel       int
	newCompressionWriter   func(io.WriteCloser, int) io.WriteCloser

	// Read fields
	reader        io.ReadCloser // the current reader returned to the application
	readErr       error
	br            *bufio.Reader
	readRemaining int64 // bytes remaining in current frame.
	readFinal     bool  // true the current message has more frames.
	readLength    int64 // Message size.
	readLimit     int64 // Maximum message size.
	readMaskPos   int
	readMaskKey   [4]byte
	handlePong    func(string) error
	handlePing    func(string) error
	handleClose   func(int, string) error
	readErrCount  int
	messageReader *messageReader // the current low-level reader

	readDecompress         bool // whether last read frame had RSV1 set
	newDecompressionReader func(io.Reader) io.ReadCloser
}

func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int) *Conn {
	return newConnBRW(conn, isServer, readBufferSize, writeBufferSize, nil)
}

type writeHook struct {
	p []byte
}

func (wh *writeHook) Write(p []byte) (int, error) {
	wh.p = p
	return len(p), nil
}

func newConnBRW(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, brw *bufio.ReadWriter) *Conn {
	mu := make(chan bool, 1)
	mu <- true

	var br *bufio.Reader
	if readBufferSize == 0 && brw != nil && brw.Reader != nil {
		// Reuse the supplied bufio.Reader if the buffer has a useful size.
		// This code assumes that peek on a reader returns
		// bufio.Reader.buf[:0].
		brw.Reader.Reset(conn)
		if p, err := brw.Reader.Peek(0); err == nil && cap(p) >= 256 {
			br = brw.Reader
		}
	}
	if br == nil {
		if readBufferSize == 0 {
			readBufferSize = defaultReadBufferSize
		}
		if readBufferSize < maxControlFramePayloadSize {
			readBufferSize = maxControlFramePayloadSize
		}
		br = bufio.NewReaderSize(conn, readBufferSize)
	}

	var writeBuf []byte
	if writeBufferSize == 0 && brw != nil && brw.Writer != nil {
		// Use the bufio.Writer's buffer if the buffer has a useful size. This
		// code assumes that bufio.Writer.buf[:1] is passed to the
		// bufio.Writer's underlying writer.
		var wh writeHook
		brw.Writer.Reset(&wh)
		brw.Writer.WriteByte(0)
		brw.Flush()
		if cap(wh.p) >= maxFrameHeaderSize+256 {
			writeBuf = wh.p[:cap(wh.p)]
		}
	}

	if writeBuf == nil {
		if writeBufferSize == 0 {
			writeBufferSize = defaultWriteBufferSize
		}
		writeBuf = make([]byte, writeBufferSize+maxFrameHeaderSize)
	}

	c := &Conn{
		isServer:               isServer,
		br:                     br,
		conn:                   conn,
		mu:                     mu,
		readFinal:              true,
		writeBuf:               writeBuf,
		enableWriteCompression: true,
		compressionLevel:       defaultCompressionLevel,
	}
	c.SetCloseHandler(nil)
	c.SetPingHandler(nil)
	c.SetPongHandler(nil)
	return c
}

// Subprotocol returns the negotiated protocol for the connection.
func (c *Conn) Subprotocol() string {
	return c.subprotocol
}

// Close closes the underlying network connection without sending or waiting for a close frame.
func (c *Conn) Close() error {
	return c.conn.Close()
}

// LocalAddr returns the local network address.
func (c *Conn) LocalAddr() net.Addr {
	return c.conn.LocalAddr()
}

// RemoteAddr returns the remote network address.
func (c *Conn) RemoteAddr() net.Addr {
	return c.conn.RemoteAddr()
}

// Write methods

func (c *Conn) writeFatal(err error) error {
	err = hideTempErr(err)
	c.writeErrMu.Lock()
	if c.writeErr == nil {
		c.writeErr = err
	}
	c.writeErrMu.Unlock()
	return err
}

func (c *Conn) write(frameType int, deadline time.Time, bufs ...[]byte) error {
	<-c.mu
	defer func() { c.mu <- true }()

	c.writeErrMu.Lock()
	err := c.writeErr
	c.writeErrMu.Unlock()
	if err != nil {
		return err
	}

	c.conn.SetWriteDeadline(deadline)
	for _, buf := range bufs {
		if len(buf) > 0 {
			_, err := c.conn.Write(buf)
			if err != nil {
				return c.writeFatal(err)
			}
		}
	}

	if frameType == CloseMessage {
		c.writeFatal(ErrCloseSent)
	}
	return nil
}

// WriteControl writes a control message with the given deadline. The allowed
// message types are CloseMessage, PingMessage and PongMessage.
func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error {
	if !isControl(messageType) {
		return errBadWriteOpCode
	}
	if len(data) > maxControlFramePayloadSize {
		return errInvalidControlFrame
	}

	b0 := byte(messageType) | finalBit
	b1 := byte(len(data))
	if !c.isServer {
		b1 |= maskBit
	}

	buf := make([]byte, 0, maxFrameHeaderSize+maxControlFramePayloadSize)
	buf = append(buf, b0, b1)

	if c.isServer {
		buf = append(buf, data...)
	} else {
		key := newMaskKey()
		buf = append(buf, key[:]...)
		buf = append(buf, data...)
		maskBytes(key, 0, buf[6:])
	}

	d := time.Hour * 1000
	if !deadline.IsZero() {
		d = deadline.Sub(time.Now())
		if d < 0 {
			return errWriteTimeout
		}
	}

	timer := time.NewTimer(d)
	select {
	case <-c.mu:
		timer.Stop()
	case <-timer.C:
		return errWriteTimeout
	}
	defer func() { c.mu <- true }()

	c.writeErrMu.Lock()
	err := c.writeErr
	c.writeErrMu.Unlock()
	if err != nil {
		return err
	}

	c.conn.SetWriteDeadline(deadline)
	_, err = c.conn.Write(buf)
	if err != nil {
		return c.writeFatal(err)
	}
	if messageType == CloseMessage {
		c.writeFatal(ErrCloseSent)
	}
	return err
}

func (c *Conn) prepWrite(messageType int) error {
	// Close previous writer if not already closed by the application. It's
	// probably better to return an error in this situation, but we cannot
	// change this without breaking existing applications.
	if c.writer != nil {
		c.writer.Close()
		c.writer = nil
	}

	if !isControl(messageType) && !isData(messageType) {
		return errBadWriteOpCode
	}

	c.writeErrMu.Lock()
	err := c.writeErr
	c.writeErrMu.Unlock()
	return err
}

// NextWriter returns a writer for the next message to send. The writer's Close
// method flushes the complete message to the network.
//
// There can be at most one open writer on a connection. NextWriter closes the
// previous writer if the application has not already done so.
func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) {
	if err := c.prepWrite(messageType); err != nil {
		return nil, err
	}

	mw := &messageWriter{
		c:         c,
		frameType: messageType,
		pos:       maxFrameHeaderSize,
	}
	c.writer = mw
	if c.newCompressionWriter != nil && c.enableWriteCompression && isData(messageType) {
		w := c.newCompressionWriter(c.writer, c.compressionLevel)
		mw.compress = true
		c.writer = w
	}
	return c.writer, nil
}

type messageWriter struct {
	c         *Conn
	compress  bool // whether next call to flushFrame should set RSV1
	pos       int  // end of data in writeBuf.
	frameType int  // type of the current frame.
	err       error
}

func (w *messageWriter) fatal(err error) error {
	if w.err != nil {
		w.err = err
		w.c.writer = nil
	}
	return err
}

// flushFrame writes buffered data and extra as a frame to the network. The
// final argument indicates that this is the last frame in the message.
func (w *messageWriter) flushFrame(final bool, extra []byte) error {
	c := w.c
	length := w.pos - maxFrameHeaderSize + len(extra)

	// Check for invalid control frames.
	if isControl(w.frameType) &&
		(!final || length > maxControlFramePayloadSize) {
		return w.fatal(errInvalidControlFrame)
	}

	b0 := byte(w.frameType)
	if final {
		b0 |= finalBit
	}
	if w.compress {
		b0 |= rsv1Bit
	}
	w.compress = false

	b1 := byte(0)
	if !c.isServer {
		b1 |= maskBit
	}

	// Assume that the frame starts at beginning of c.writeBuf.
	framePos := 0
	if c.isServer {
		// Adjust up if mask not included in the header.
		framePos = 4
	}

	switch {
	case length >= 65536:
		c.writeBuf[framePos] = b0
		c.writeBuf[framePos+1] = b1 | 127
		binary.BigEndian.PutUint64(c.writeBuf[framePos+2:], uint64(length))
	case length > 125:
		framePos += 6
		c.writeBuf[framePos] = b0
		c.writeBuf[framePos+1] = b1 | 126
		binary.BigEndian.PutUint16(c.writeBuf[framePos+2:], uint16(length))
	default:
		framePos += 8
		c.writeBuf[framePos] = b0
		c.writeBuf[framePos+1] = b1 | byte(length)
	}

	if !c.isServer {
		key := newMaskKey()
		copy(c.writeBuf[maxFrameHeaderSize-4:], key[:])
		maskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:w.pos])
		if len(extra) > 0 {
			return c.writeFatal(errors.New("websocket: internal error, extra used in client mode"))
		}
	}

	// Write the buffers to the connection with best-effort detection of
	// concurrent writes. See the concurrency section in the package
	// documentation for more info.

	if c.isWriting {
		panic("concurrent write to websocket connection")
	}
	c.isWriting = true

	err := c.write(w.frameType, c.writeDeadline, c.writeBuf[framePos:w.pos], extra)

	if !c.isWriting {
		panic("concurrent write to websocket connection")
	}
	c.isWriting = false

	if err != nil {
		return w.fatal(err)
	}

	if final {
		c.writer = nil
		return nil
	}

	// Setup for next frame.
	w.pos = maxFrameHeaderSize
	w.frameType = continuationFrame
	return nil
}

func (w *messageWriter) ncopy(max int) (int, error) {
	n := len(w.c.writeBuf) - w.pos
	if n <= 0 {
		if err := w.flushFrame(false, nil); err != nil {
			return 0, err
		}
		n = len(w.c.writeBuf) - w.pos
	}
	if n > max {
		n = max
	}
	return n, nil
}

func (w *messageWriter) Write(p []byte) (int, error) {
	if w.err != nil {
		return 0, w.err
	}

	if len(p) > 2*len(w.c.writeBuf) && w.c.isServer {
		// Don't buffer large messages.
		err := w.flushFrame(false, p)
		if err != nil {
			return 0, err
		}
		return len(p), nil
	}

	nn := len(p)
	for len(p) > 0 {
		n, err := w.ncopy(len(p))
		if err != nil {
			return 0, err
		}
		copy(w.c.writeBuf[w.pos:], p[:n])
		w.pos += n
		p = p[n:]
	}
	return nn, nil
}

func (w *messageWriter) WriteString(p string) (int, error) {
	if w.err != nil {
		return 0, w.err
	}

	nn := len(p)
	for len(p) > 0 {
		n, err := w.ncopy(len(p))
		if err != nil {
			return 0, err
		}
		copy(w.c.writeBuf[w.pos:], p[:n])
		w.pos += n
		p = p[n:]
	}
	return nn, nil
}

func (w *messageWriter) ReadFrom(r io.Reader) (nn int64, err error) {
	if w.err != nil {
		return 0, w.err
	}
	for {
		if w.pos == len(w.c.writeBuf) {
			err = w.flushFrame(false, nil)
			if err != nil {
				break
			}
		}
		var n int
		n, err = r.Read(w.c.writeBuf[w.pos:])
		w.pos += n
		nn += int64(n)
		if err != nil {
			if err == io.EOF {
				err = nil
			}
			break
		}
	}
	return nn, err
}

func (w *messageWriter) Close() error {
	if w.err != nil {
		return w.err
	}
	if err := w.flushFrame(true, nil); err != nil {
		return err
	}
	w.err = errWriteClosed
	return nil
}

// WritePreparedMessage writes prepared message into connection.
func (c *Conn) WritePreparedMessage(pm *PreparedMessage) error {
	frameType, frameData, err := pm.frame(prepareKey{
		isServer:         c.isServer,
		compress:         c.newCompressionWriter != nil && c.enableWriteCompression && isData(pm.messageType),
		compressionLevel: c.compressionLevel,
	})
	if err != nil {
		return err
	}
	if c.isWriting {
		panic("concurrent write to websocket connection")
	}
	c.isWriting = true
	err = c.write(frameType, c.writeDeadline, frameData, nil)
	if !c.isWriting {
		panic("concurrent write to websocket connection")
	}
	c.isWriting = false
	return err
}

// WriteMessage is a helper method for getting a writer using NextWriter,
// writing the message and closing the writer.
func (c *Conn) WriteMessage(messageType int, data []byte) error {

	if c.isServer && (c.newCompressionWriter == nil || !c.enableWriteCompression) {
		// Fast path with no allocations and single frame.

		if err := c.prepWrite(messageType); err != nil {
			return err
		}
		mw := messageWriter{c: c, frameType: messageType, pos: maxFrameHeaderSize}
		n := copy(c.writeBuf[mw.pos:], data)
		mw.pos += n
		data = data[n:]
		return mw.flushFrame(true, data)
	}

	w, err := c.NextWriter(messageType)
	if err != nil {
		return err
	}
	if _, err = w.Write(data); err != nil {
		return err
	}
	return w.Close()
}

// SetWriteDeadline sets the write deadline on the underlying network
// connection. After a write has timed out, the websocket state is corrupt and
// all future writes will return an error. A zero value for t means writes will
// not time out.
func (c *Conn) SetWriteDeadline(t time.Time) error {
	c.writeDeadline = t
	return nil
}

// Read methods

func (c *Conn) advanceFrame() (int, error) {

	// 1. Skip remainder of previous frame.

	if c.readRemaining > 0 {
		if _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil {
			return noFrame, err
		}
	}

	// 2. Read and parse first two bytes of frame header.

	p, err := c.read(2)
	if err != nil {
		return noFrame, err
	}

	final := p[0]&finalBit != 0
	frameType := int(p[0] & 0xf)
	mask := p[1]&maskBit != 0
	c.readRemaining = int64(p[1] & 0x7f)

	c.readDecompress = false
	if c.newDecompressionReader != nil && (p[0]&rsv1Bit) != 0 {
		c.readDecompress = true
		p[0] &^= rsv1Bit
	}

	if rsv := p[0] & (rsv1Bit | rsv2Bit | rsv3Bit); rsv != 0 {
		return noFrame, c.handleProtocolError("unexpected reserved bits 0x" + strconv.FormatInt(int64(rsv), 16))
	}

	switch frameType {
	case CloseMessage, PingMessage, PongMessage:
		if c.readRemaining > maxControlFramePayloadSize {
			return noFrame, c.handleProtocolError("control frame length > 125")
		}
		if !final {
			return noFrame, c.handleProtocolError("control frame not final")
		}
	case TextMessage, BinaryMessage:
		if !c.readFinal {
			return noFrame, c.handleProtocolError("message start before final message frame")
		}
		c.readFinal = final
	case continuationFrame:
		if c.readFinal {
			return noFrame, c.handleProtocolError("continuation after final message frame")
		}
		c.readFinal = final
	default:
		return noFrame, c.handleProtocolError("unknown opcode " + strconv.Itoa(frameType))
	}

	// 3. Read and parse frame length.

	switch c.readRemaining {
	case 126:
		p, err := c.read(2)
		if err != nil {
			return noFrame, err
		}
		c.readRemaining = int64(binary.BigEndian.Uint16(p))
	case 127:
		p, err := c.read(8)
		if err != nil {
			return noFrame, err
		}
		c.readRemaining = int64(binary.BigEndian.Uint64(p))
	}

	// 4. Handle frame masking.

	if mask != c.isServer {
		return noFrame, c.handleProtocolError("incorrect mask flag")
	}

	if mask {
		c.readMaskPos = 0
		p, err := c.read(len(c.readMaskKey))
		if err != nil {
			return noFrame, err
		}
		copy(c.readMaskKey[:], p)
	}

	// 5. For text and binary messages, enforce read limit and return.

	if frameType == continuationFrame || frameType == TextMessage || frameType == BinaryMessage {

		c.readLength += c.readRemaining
		if c.readLimit > 0 && c.readLength > c.readLimit {
			c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait))
			return noFrame, ErrReadLimit
		}

		return frameType, nil
	}

	// 6. Read control frame payload.

	var payload []byte
	if c.readRemaining > 0 {
		payload, err = c.read(int(c.readRemaining))
		c.readRemaining = 0
		if err != nil {
			return noFrame, err
		}
		if c.isServer {
			maskBytes(c.readMaskKey, 0, payload)
		}
	}

	// 7. Process control frame payload.

	switch frameType {
	case PongMessage:
		if err := c.handlePong(string(payload)); err != nil {
			return noFrame, err
		}
	case PingMessage:
		if err := c.handlePing(string(payload)); err != nil {
			return noFrame, err
		}
	case CloseMessage:
		closeCode := CloseNoStatusReceived
		closeText := ""
		if len(payload) >= 2 {
			closeCode = int(binary.BigEndian.Uint16(payload))
			if !isValidReceivedCloseCode(closeCode) {
				return noFrame, c.handleProtocolError("invalid close code")
			}
			closeText = string(payload[2:])
			if !utf8.ValidString(closeText) {
				return noFrame, c.handleProtocolError("invalid utf8 payload in close frame")
			}
		}
		if err := c.handleClose(closeCode, closeText); err != nil {
			return noFrame, err
		}
		return noFrame, &CloseError{Code: closeCode, Text: closeText}
	}

	return frameType, nil
}

func (c *Conn) handleProtocolError(message string) error {
	c.WriteControl(CloseMessage, FormatCloseMessage(CloseProtocolError, message), time.Now().Add(writeWait))
	return errors.New("websocket: " + message)
}

// NextReader returns the next data message received from the peer. The
// returned messageType is either TextMessage or BinaryMessage.
//
// There can be at most one open reader on a connection. NextReader discards
// the previous message if the application has not already consumed it.
//
// Applications must break out of the application's read loop when this method
// returns a non-nil error value. Errors returned from this method are
// permanent. Once this method returns a non-nil error, all subsequent calls to
// this method return the same error.
func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {
	// Close previous reader, only relevant for decompression.
	if c.reader != nil {
		c.reader.Close()
		c.reader = nil
	}

	c.messageReader = nil
	c.readLength = 0

	for c.readErr == nil {
		frameType, err := c.advanceFrame()
		if err != nil {
			c.readErr = hideTempErr(err)
			break
		}
		if frameType == TextMessage || frameType == BinaryMessage {
			c.messageReader = &messageReader{c}
			c.reader = c.messageReader
			if c.readDecompress {
				c.reader = c.newDecompressionReader(c.reader)
			}
			return frameType, c.reader, nil
		}
	}

	// Applications that do handle the error returned from this method spin in
	// tight loop on connection failure. To help application developers detect
	// this error, panic on repeated reads to the failed connection.
	c.readErrCount++
	if c.readErrCount >= 1000 {
		panic("repeated read on failed websocket connection")
	}

	return noFrame, nil, c.readErr
}

type messageReader struct{ c *Conn }

func (r *messageReader) Read(b []byte) (int, error) {
	c := r.c
	if c.messageReader != r {
		return 0, io.EOF
	}

	for c.readErr == nil {

		if c.readRemaining > 0 {
			if int64(len(b)) > c.readRemaining {
				b = b[:c.readRemaining]
			}
			n, err := c.br.Read(b)
			c.readErr = hideTempErr(err)
			if c.isServer {
				c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n])
			}
			c.readRemaining -= int64(n)
			if c.readRemaining > 0 && c.readErr == io.EOF {
				c.readErr = errUnexpectedEOF
			}
			return n, c.readErr
		}

		if c.readFinal {
			c.messageReader = nil
			return 0, io.EOF
		}

		frameType, err := c.advanceFrame()
		switch {
		case err != nil:
			c.readErr = hideTempErr(err)
		case frameType == TextMessage || frameType == BinaryMessage:
			c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader")
		}
	}

	err := c.readErr
	if err == io.EOF && c.messageReader == r {
		err = errUnexpectedEOF
	}
	return 0, err
}

func (r *messageReader) Close() error {
	return nil
}

// ReadMessage is a helper method for getting a reader using NextReader and
// reading from that reader to a buffer.
func (c *Conn) ReadMessage() (messageType int, p []byte, err error) {
	var r io.Reader
	messageType, r, err = c.NextReader()
	if err != nil {
		return messageType, nil, err
	}
	p, err = ioutil.ReadAll(r)
	return messageType, p, err
}

// SetReadDeadline sets the read deadline on the underlying network connection.
// After a read has timed out, the websocket connection state is corrupt and
// all future reads will return an error. A zero value for t means reads will
// not time out.
func (c *Conn) SetReadDeadline(t time.Time) error {
	return c.conn.SetReadDeadline(t)
}

// SetReadLimit sets the maximum size for a message read from the peer. If a
// message exceeds the limit, the connection sends a close frame to the peer
// and returns ErrReadLimit to the application.
func (c *Conn) SetReadLimit(limit int64) {
	c.readLimit = limit
}

// CloseHandler returns the current close handler
func (c *Conn) CloseHandler() func(code int, text string) error {
	return c.handleClose
}

// SetCloseHandler sets the handler for close messages received from the peer.
// The code argument to h is the received close code or CloseNoStatusReceived
// if the close message is empty. The default close handler sends a close frame
// back to the peer.
//
// The application must read the connection to process close messages as
// described in the section on Control Frames above.
//
// The connection read methods return a CloseError when a close frame is
// received. Most applications should handle close messages as part of their
// normal error handling. Applications should only set a close handler when the
// application must perform some action before sending a close frame back to
// the peer.
func (c *Conn) SetCloseHandler(h func(code int, text string) error) {
	if h == nil {
		h = func(code int, text string) error {
			message := []byte{}
			if code != CloseNoStatusReceived {
				message = FormatCloseMessage(code, "")
			}
			c.WriteControl(CloseMessage, message, time.Now().Add(writeWait))
			return nil
		}
	}
	c.handleClose = h
}

// PingHandler returns the current ping handler
func (c *Conn) PingHandler() func(appData string) error {
	return c.handlePing
}

// SetPingHandler sets the handler for ping messages received from the peer.
// The appData argument to h is the PING frame application data. The default
// ping handler sends a pong to the peer.
//
// The application must read the connection to process ping messages as
// described in the section on Control Frames above.
func (c *Conn) SetPingHandler(h func(appData string) error) {
	if h == nil {
		h = func(message string) error {
			err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait))
			if err == ErrCloseSent {
				return nil
			} else if e, ok := err.(net.Error); ok && e.Temporary() {
				return nil
			}
			return err
		}
	}
	c.handlePing = h
}

// PongHandler returns the current pong handler
func (c *Conn) PongHandler() func(appData string) error {
	return c.handlePong
}

// SetPongHandler sets the handler for pong messages received from the peer.
// The appData argument to h is the PONG frame application data. The default
// pong handler does nothing.
//
// The application must read the connection to process ping messages as
// described in the section on Control Frames above.
func (c *Conn) SetPongHandler(h func(appData string) error) {
	if h == nil {
		h = func(string) error { return nil }
	}
	c.handlePong = h
}

// UnderlyingConn returns the internal net.Conn. This can be used to further
// modifications to connection specific flags.
func (c *Conn) UnderlyingConn() net.Conn {
	return c.conn
}

// EnableWriteCompression enables and disables write compression of
// subsequent text and binary messages. This function is a noop if
// compression was not negotiated with the peer.
func (c *Conn) EnableWriteCompression(enable bool) {
	c.enableWriteCompression = enable
}

// SetCompressionLevel sets the flate compression level for subsequent text and
// binary messages. This function is a noop if compression was not negotiated
// with the peer. See the compress/flate package for a description of
// compression levels.
func (c *Conn) SetCompressionLevel(level int) error {
	if !isValidCompressionLevel(level) {
		return errors.New("websocket: invalid compression level")
	}
	c.compressionLevel = level
	return nil
}

// FormatCloseMessage formats closeCode and text as a WebSocket close message.
func FormatCloseMessage(closeCode int, text string) []byte {
	buf := make([]byte, 2+len(text))
	binary.BigEndian.PutUint16(buf, uint16(closeCode))
	copy(buf[2:], text)
	return buf
}


================================================
FILE: vendor/github.com/gorilla/websocket/conn_read.go
================================================
// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build go1.5

package websocket

import "io"

func (c *Conn) read(n int) ([]byte, error) {
	p, err := c.br.Peek(n)
	if err == io.EOF {
		err = errUnexpectedEOF
	}
	c.br.Discard(len(p))
	return p, err
}


================================================
FILE: vendor/github.com/gorilla/websocket/conn_read_legacy.go
================================================
// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !go1.5

package websocket

import "io"

func (c *Conn) read(n int) ([]byte, error) {
	p, err := c.br.Peek(n)
	if err == io.EOF {
		err = errUnexpectedEOF
	}
	if len(p) > 0 {
		// advance over the bytes just read
		io.ReadFull(c.br, p)
	}
	return p, err
}


================================================
FILE: vendor/github.com/gorilla/websocket/doc.go
================================================
// Copyright 2013 The Gorilla WebSocket 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 websocket implements the WebSocket protocol defined in RFC 6455.
//
// Overview
//
// The Conn type represents a WebSocket connection. A server application uses
// the Upgrade function from an Upgrader object with a HTTP request handler
// to get a pointer to a Conn:
//
//  var upgrader = websocket.Upgrader{
//      ReadBufferSize:  1024,
//      WriteBufferSize: 1024,
//  }
//
//  func handler(w http.ResponseWriter, r *http.Request) {
//      conn, err := upgrader.Upgrade(w, r, nil)
//      if err != nil {
//          log.Println(err)
//          return
//      }
//      ... Use conn to send and receive messages.
//  }
//
// Call the connection's WriteMessage and ReadMessage methods to send and
// receive messages as a slice of bytes. This snippet of code shows how to echo
// messages using these methods:
//
//  for {
//      messageType, p, err := conn.ReadMessage()
//      if err != nil {
//          return
//      }
//      if err = conn.WriteMessage(messageType, p); err != nil {
//          return err
//      }
//  }
//
// In above snippet of code, p is a []byte and messageType is an int with value
// websocket.BinaryMessage or websocket.TextMessage.
//
// An application can also send and receive messages using the io.WriteCloser
// and io.Reader interfaces. To send a message, call the connection NextWriter
// method to get an io.WriteCloser, write the message to the writer and close
// the writer when done. To receive a message, call the connection NextReader
// method to get an io.Reader and read until io.EOF is returned. This snippet
// shows how to echo messages using the NextWriter and NextReader methods:
//
//  for {
//      messageType, r, err := conn.NextReader()
//      if err != nil {
//          return
//      }
//      w, err := conn.NextWriter(messageType)
//      if err != nil {
//          return err
//      }
//      if _, err := io.Copy(w, r); err != nil {
//          return err
//      }
//      if err := w.Close(); err != nil {
//          return err
//      }
//  }
//
// Data Messages
//
// The WebSocket protocol distinguishes between text and binary data messages.
// Text messages are interpreted as UTF-8 encoded text. The interpretation of
// binary messages is left to the application.
//
// This package uses the TextMessage and BinaryMessage integer constants to
// identify the two data message types. The ReadMessage and NextReader methods
// return the type of the received message. The messageType argument to the
// WriteMessage and NextWriter methods specifies the type of a sent message.
//
// It is the application's responsibility to ensure that text messages are
// valid UTF-8 encoded text.
//
// Control Messages
//
// The WebSocket protocol defines three types of control messages: close, ping
// and pong. Call the connection WriteControl, WriteMessage or NextWriter
// methods to send a control message to the peer.
//
// Connections handle received close messages by sending a close message to the
// peer and returning a *CloseError from the the NextReader, ReadMessage or the
// message Read method.
//
// Connections handle received ping and pong messages by invoking callback
// functions set with SetPingHandler and SetPongHandler methods. The callback
// functions are called from the NextReader, ReadMessage and the message Read
// methods.
//
// The default ping handler sends a pong to the peer. The application's reading
// goroutine can block for a short time while the handler writes the pong data
// to the connection.
//
// The application must read the connection to process ping, pong and close
// messages sent from the peer. If the application is not otherwise interested
// in messages from the peer, then the application should start a goroutine to
// read and discard messages from the peer. A simple example is:
//
//  func readLoop(c *websocket.Conn) {
//      for {
//          if _, _, err := c.NextReader(); err != nil {
//              c.Close()
//              break
//          }
//      }
//  }
//
// Concurrency
//
// Connections support one concurrent reader and one concurrent writer.
//
// Applications are responsible for ensuring that no more than one goroutine
// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage,
// WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and
// that no more than one goroutine calls the read methods (NextReader,
// SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler)
// concurrently.
//
// The Close and WriteControl methods can be called concurrently with all other
// methods.
//
// Origin Considerations
//
// Web browsers allow Javascript applications to open a WebSocket connection to
// any host. It's up to the server to enforce an origin policy using the Origin
// request header sent by the browser.
//
// The Upgrader calls the function specified in the CheckOrigin field to check
// the origin. If the CheckOrigin function returns false, then the Upgrade
// method fails the WebSocket handshake with HTTP status 403.
//
// If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail
// the handshake if the Origin request header is present and not equal to the
// Host request header.
//
// An application can allow connections from any origin by specifying a
// function that always returns true:
//
//  var upgrader = websocket.Upgrader{
//      CheckOrigin: func(r *http.Request) bool { return true },
//  }
//
// The deprecated Upgrade function does not enforce an origin policy. It's the
// application's responsibility to check the Origin header before calling
// Upgrade.
//
// Compression EXPERIMENTAL
//
// Per message compression extensions (RFC 7692) are experimentally supported
// by this package in a limited capacity. Setting the EnableCompression option
// to true in Dialer or Upgrader will attempt to negotiate per message deflate
// support.
//
//  var upgrader = websocket.Upgrader{
//      EnableCompression: true,
//  }
//
// If compression was successfully negotiated with the connection's peer, any
// message received in compressed form will be automatically decompressed.
// All Read methods will return uncompressed bytes.
//
// Per message compression of messages written to a connection can be enabled
// or disabled by calling the corresponding Conn method:
//
//  conn.EnableWriteCompression(false)
//
// Currently this package does not support compression with "context takeover".
// This means that messages must be compressed and decompressed in isolation,
// without retaining sliding window or dictionary state across messages. For
// more details refer to RFC 7692.
//
// Use of compression is experimental and may result in decreased performance.
package websocket


================================================
FILE: vendor/github.com/gorilla/websocket/json.go
================================================
// Copyright 2013 The Gorilla WebSocket 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 websocket

import (
	"encoding/json"
	"io"
)

// WriteJSON is deprecated, use c.WriteJSON instead.
func WriteJSON(c *Conn, v interface{}) error {
	return c.WriteJSON(v)
}

// WriteJSON writes the JSON encoding of v to the connection.
//
// See the documentation for encoding/json Marshal for details about the
// conversion of Go values to JSON.
func (c *Conn) WriteJSON(v interface{}) error {
	w, err := c.NextWriter(TextMessage)
	if err != nil {
		return err
	}
	err1 := json.NewEncoder(w).Encode(v)
	err2 := w.Close()
	if err1 != nil {
		return err1
	}
	return err2
}

// ReadJSON is deprecated, use c.ReadJSON instead.
func ReadJSON(c *Conn, v interface{}) error {
	return c.ReadJSON(v)
}

// ReadJSON reads the next JSON-encoded message from the connection and stores
// it in the value pointed to by v.
//
// See the documentation for the encoding/json Unmarshal function for details
// about the conversion of JSON to a Go value.
func (c *Conn) ReadJSON(v interface{}) error {
	_, r, err := c.NextReader()
	if err != nil {
		return err
	}
	err = json.NewDecoder(r).Decode(v)
	if err == io.EOF {
		// One value is expected in the message.
		err = io.ErrUnexpectedEOF
	}
	return err
}


================================================
FILE: vendor/github.com/gorilla/websocket/mask.go
================================================
// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.  Use of
// this source code is governed by a BSD-style license that can be found in the
// LICENSE file.

// +build !appengine

package websocket

import "unsafe"

const wordSize = int(unsafe.Sizeof(uintptr(0)))

func maskBytes(key [4]byte, pos int, b []byte) int {

	// Mask one byte at a time for small buffers.
	if len(b) < 2*wordSize {
		for i := range b {
			b[i] ^= key[pos&3]
			pos++
		}
		return pos & 3
	}

	// Mask one byte at a time to word boundary.
	if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 {
		n = wordSize - n
		for i := range b[:n] {
			b[i] ^= key[pos&3]
			pos++
		}
		b = b[n:]
	}

	// Create aligned word size key.
	var k [wordSize]byte
	for i := range k {
		k[i] = key[(pos+i)&3]
	}
	kw := *(*uintptr)(unsafe.Pointer(&k))

	// Mask one word at a time.
	n := (len(b) / wordSize) * wordSize
	for i := 0; i < n; i += wordSize {
		*(*uintptr)(
Download .txt
gitextract_kj7nbxlu/

├── .dockerignore
├── .gitignore
├── .travis.yml
├── Dockerfile
├── LICENSE.md
├── Makefile
├── README.md
├── config/
│   └── config.go
├── docs/
│   ├── APIv1.md
│   ├── APIv2/
│   │   ├── swagger-2.0.json
│   │   └── swagger-2.0.yaml
│   ├── APIv2.md
│   ├── Auth.md
│   ├── BUILD.md
│   ├── CONFIG.md
│   ├── DEPLOY.md
│   ├── JIM.md
│   ├── LIBRARIES.md
│   ├── RELEASES.md
│   └── example-auth
├── main.go
├── snapcraft.yaml
└── vendor/
    ├── github.com/
    │   ├── gorilla/
    │   │   ├── context/
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── context.go
    │   │   │   └── doc.go
    │   │   ├── mux/
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── context_gorilla.go
    │   │   │   ├── context_native.go
    │   │   │   ├── doc.go
    │   │   │   ├── mux.go
    │   │   │   ├── regexp.go
    │   │   │   └── route.go
    │   │   ├── pat/
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── doc.go
    │   │   │   └── pat.go
    │   │   └── websocket/
    │   │       ├── AUTHORS
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── client.go
    │   │       ├── client_clone.go
    │   │       ├── client_clone_legacy.go
    │   │       ├── compression.go
    │   │       ├── conn.go
    │   │       ├── conn_read.go
    │   │       ├── conn_read_legacy.go
    │   │       ├── doc.go
    │   │       ├── json.go
    │   │       ├── mask.go
    │   │       ├── mask_safe.go
    │   │       ├── prepared.go
    │   │       ├── server.go
    │   │       └── util.go
    │   ├── ian-kent/
    │   │   ├── envconf/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── README.md
    │   │   │   └── envconf.go
    │   │   ├── go-log/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── appenders/
    │   │   │   │   ├── appender.go
    │   │   │   │   ├── console.go
    │   │   │   │   ├── fluentd.go
    │   │   │   │   ├── multiple_appender.go
    │   │   │   │   ├── rollingfile.go
    │   │   │   │   ├── rollingfile_test.log
    │   │   │   │   └── rollingfile_test.log.1
    │   │   │   ├── layout/
    │   │   │   │   ├── basic.go
    │   │   │   │   ├── layout.go
    │   │   │   │   └── pattern.go
    │   │   │   ├── levels/
    │   │   │   │   └── levels.go
    │   │   │   ├── log/
    │   │   │   │   └── log.go
    │   │   │   └── logger/
    │   │   │       └── logger.go
    │   │   ├── goose/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── README.md
    │   │   │   └── goose.go
    │   │   └── linkio/
    │   │       ├── README.md
    │   │       └── linkio.go
    │   ├── jtolds/
    │   │   └── gls/
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── context.go
    │   │       ├── gen_sym.go
    │   │       ├── gid.go
    │   │       ├── id_pool.go
    │   │       ├── stack_tags.go
    │   │       ├── stack_tags_js.go
    │   │       └── stack_tags_main.go
    │   ├── mailhog/
    │   │   ├── MailHog-Server/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── Makefile
    │   │   │   ├── README.md
    │   │   │   ├── api/
    │   │   │   │   ├── api.go
    │   │   │   │   ├── v1.go
    │   │   │   │   └── v2.go
    │   │   │   ├── config/
    │   │   │   │   └── config.go
    │   │   │   ├── main.go
    │   │   │   ├── monkey/
    │   │   │   │   ├── jim.go
    │   │   │   │   └── monkey.go
    │   │   │   ├── smtp/
    │   │   │   │   ├── session.go
    │   │   │   │   ├── session_test.go
    │   │   │   │   └── smtp.go
    │   │   │   └── websockets/
    │   │   │       ├── connection.go
    │   │   │       └── hub.go
    │   │   ├── MailHog-UI/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── Makefile
    │   │   │   ├── README.md
    │   │   │   ├── assets/
    │   │   │   │   └── assets.go
    │   │   │   ├── config/
    │   │   │   │   └── config.go
    │   │   │   ├── main.go
    │   │   │   └── web/
    │   │   │       └── web.go
    │   │   ├── data/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── README.md
    │   │   │   └── message.go
    │   │   ├── http/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── README.md
    │   │   │   └── server.go
    │   │   ├── mhsendmail/
    │   │   │   ├── LICENSE.md
    │   │   │   └── cmd/
    │   │   │       └── cmd.go
    │   │   ├── smtp/
    │   │   │   ├── LICENSE.md
    │   │   │   ├── README.md
    │   │   │   ├── protocol.go
    │   │   │   ├── reply.go
    │   │   │   └── state.go
    │   │   └── storage/
    │   │       ├── LICENSE.md
    │   │       ├── README.md
    │   │       ├── maildir.go
    │   │       ├── memory.go
    │   │       ├── mongodb.go
    │   │       └── storage.go
    │   ├── philhofer/
    │   │   └── fwd/
    │   │       ├── LICENSE.md
    │   │       ├── README.md
    │   │       ├── reader.go
    │   │       ├── writer.go
    │   │       ├── writer_appengine.go
    │   │       └── writer_unsafe.go
    │   ├── smartystreets/
    │   │   ├── assertions/
    │   │   │   ├── CONTRIBUTING.md
    │   │   │   ├── LICENSE.md
    │   │   │   ├── README.md
    │   │   │   ├── collections.go
    │   │   │   ├── doc.go
    │   │   │   ├── equality.go
    │   │   │   ├── filter.go
    │   │   │   ├── internal/
    │   │   │   │   ├── go-render/
    │   │   │   │   │   ├── LICENSE
    │   │   │   │   │   └── render/
    │   │   │   │   │       └── render.go
    │   │   │   │   └── oglematchers/
    │   │   │   │       ├── LICENSE
    │   │   │   │       ├── README.md
    │   │   │   │       ├── any_of.go
    │   │   │   │       ├── contains.go
    │   │   │   │       ├── deep_equals.go
    │   │   │   │       ├── equals.go
    │   │   │   │       ├── greater_or_equal.go
    │   │   │   │       ├── greater_than.go
    │   │   │   │       ├── less_or_equal.go
    │   │   │   │       ├── less_than.go
    │   │   │   │       ├── matcher.go
    │   │   │   │       ├── not.go
    │   │   │   │       └── transform_description.go
    │   │   │   ├── messages.go
    │   │   │   ├── panic.go
    │   │   │   ├── quantity.go
    │   │   │   ├── serializer.go
    │   │   │   ├── strings.go
    │   │   │   ├── time.go
    │   │   │   └── type.go
    │   │   └── goconvey/
    │   │       ├── LICENSE.md
    │   │       └── convey/
    │   │           ├── assertions.go
    │   │           ├── context.go
    │   │           ├── convey.goconvey
    │   │           ├── discovery.go
    │   │           ├── doc.go
    │   │           ├── gotest/
    │   │           │   └── utils.go
    │   │           ├── init.go
    │   │           ├── nilReporter.go
    │   │           └── reporting/
    │   │               ├── console.go
    │   │               ├── doc.go
    │   │               ├── dot.go
    │   │               ├── gotest.go
    │   │               ├── init.go
    │   │               ├── json.go
    │   │               ├── printer.go
    │   │               ├── problems.go
    │   │               ├── reporter.go
    │   │               ├── reporting.goconvey
    │   │               ├── reports.go
    │   │               ├── statistics.go
    │   │               └── story.go
    │   ├── spf13/
    │   │   └── pflag/
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── bool.go
    │   │       ├── count.go
    │   │       ├── duration.go
    │   │       ├── flag.go
    │   │       ├── float32.go
    │   │       ├── float64.go
    │   │       ├── golangflag.go
    │   │       ├── int.go
    │   │       ├── int32.go
    │   │       ├── int64.go
    │   │       ├── int8.go
    │   │       ├── int_slice.go
    │   │       ├── ip.go
    │   │       ├── ipmask.go
    │   │       ├── ipnet.go
    │   │       ├── string.go
    │   │       ├── string_slice.go
    │   │       ├── uint.go
    │   │       ├── uint16.go
    │   │       ├── uint32.go
    │   │       ├── uint64.go
    │   │       └── uint8.go
    │   ├── t-k/
    │   │   └── fluent-logger-golang/
    │   │       ├── LICENSE
    │   │       └── fluent/
    │   │           ├── fluent.go
    │   │           ├── proto.go
    │   │           ├── proto_gen.go
    │   │           └── version.go
    │   └── tinylib/
    │       └── msgp/
    │           ├── LICENSE
    │           └── msgp/
    │               ├── advise_linux.go
    │               ├── advise_other.go
    │               ├── appengine.go
    │               ├── circular.go
    │               ├── defs.go
    │               ├── edit.go
    │               ├── elsize.go
    │               ├── errors.go
    │               ├── extension.go
    │               ├── file.go
    │               ├── file_port.go
    │               ├── integers.go
    │               ├── json.go
    │               ├── json_bytes.go
    │               ├── number.go
    │               ├── read.go
    │               ├── read_bytes.go
    │               ├── size.go
    │               ├── unsafe.go
    │               ├── write.go
    │               └── write_bytes.go
    ├── golang.org/
    │   └── x/
    │       └── crypto/
    │           ├── LICENSE
    │           ├── PATENTS
    │           ├── bcrypt/
    │           │   ├── base64.go
    │           │   └── bcrypt.go
    │           └── blowfish/
    │               ├── block.go
    │               ├── cipher.go
    │               └── const.go
    ├── gopkg.in/
    │   └── mgo.v2/
    │       ├── LICENSE
    │       ├── Makefile
    │       ├── README.md
    │       ├── auth.go
    │       ├── bson/
    │       │   ├── LICENSE
    │       │   ├── bson.go
    │       │   ├── decode.go
    │       │   └── encode.go
    │       ├── bulk.go
    │       ├── cluster.go
    │       ├── doc.go
    │       ├── gridfs.go
    │       ├── internal/
    │       │   ├── sasl/
    │       │   │   ├── sasl.c
    │       │   │   ├── sasl.go
    │       │   │   ├── sasl_windows.c
    │       │   │   ├── sasl_windows.go
    │       │   │   ├── sasl_windows.h
    │       │   │   ├── sspi_windows.c
    │       │   │   └── sspi_windows.h
    │       │   └── scram/
    │       │       └── scram.go
    │       ├── log.go
    │       ├── queue.go
    │       ├── raceoff.go
    │       ├── raceon.go
    │       ├── saslimpl.go
    │       ├── saslstub.go
    │       ├── server.go
    │       ├── session.go
    │       ├── socket.go
    │       └── stats.go
    └── vendor.json
Download .txt
Showing preview only (229K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2660 symbols across 187 files)

FILE: config/config.go
  function DefaultConfig (line 9) | func DefaultConfig() *Config {
  type Config (line 15) | type Config struct
  function Configure (line 22) | func Configure() *Config {
  function RegisterFlags (line 33) | func RegisterFlags() {

FILE: main.go
  function configure (line 30) | func configure() {
  function main (line 43) | func main() {

FILE: vendor/github.com/gorilla/context/context.go
  function Set (line 20) | func Set(r *http.Request, key, val interface{}) {
  function Get (line 31) | func Get(r *http.Request, key interface{}) interface{} {
  function GetOk (line 43) | func GetOk(r *http.Request, key interface{}) (interface{}, bool) {
  function GetAll (line 55) | func GetAll(r *http.Request) map[interface{}]interface{} {
  function GetAllOk (line 71) | func GetAllOk(r *http.Request) (map[interface{}]interface{}, bool) {
  function Delete (line 83) | func Delete(r *http.Request, key interface{}) {
  function Clear (line 95) | func Clear(r *http.Request) {
  function clear (line 102) | func clear(r *http.Request) {
  function Purge (line 116) | func Purge(maxAge int) int {
  function ClearHandler (line 138) | func ClearHandler(h http.Handler) http.Handler {

FILE: vendor/github.com/gorilla/mux/context_gorilla.go
  function contextGet (line 11) | func contextGet(r *http.Request, key interface{}) interface{} {
  function contextSet (line 15) | func contextSet(r *http.Request, key, val interface{}) *http.Request {
  function contextClear (line 24) | func contextClear(r *http.Request) {

FILE: vendor/github.com/gorilla/mux/context_native.go
  function contextGet (line 10) | func contextGet(r *http.Request, key interface{}) interface{} {
  function contextSet (line 14) | func contextSet(r *http.Request, key, val interface{}) *http.Request {
  function contextClear (line 22) | func contextClear(r *http.Request) {

FILE: vendor/github.com/gorilla/mux/mux.go
  function NewRouter (line 17) | func NewRouter() *Router {
  type Router (line 39) | type Router struct
    method Match (line 61) | func (r *Router) Match(req *http.Request, match *RouteMatch) bool {
    method ServeHTTP (line 80) | func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
    method Get (line 118) | func (r *Router) Get(name string) *Route {
    method GetRoute (line 124) | func (r *Router) GetRoute(name string) *Route {
    method StrictSlash (line 142) | func (r *Router) StrictSlash(value bool) *Router {
    method SkipClean (line 155) | func (r *Router) SkipClean(value bool) *Router {
    method UseEncodedPath (line 170) | func (r *Router) UseEncodedPath() *Router {
    method getNamedRoutes (line 180) | func (r *Router) getNamedRoutes() map[string]*Route {
    method getRegexpGroup (line 192) | func (r *Router) getRegexpGroup() *routeRegexpGroup {
    method buildVars (line 199) | func (r *Router) buildVars(m map[string]string) map[string]string {
    method NewRoute (line 211) | func (r *Router) NewRoute() *Route {
    method Handle (line 219) | func (r *Router) Handle(path string, handler http.Handler) *Route {
    method HandleFunc (line 225) | func (r *Router) HandleFunc(path string, f func(http.ResponseWriter,
    method Headers (line 232) | func (r *Router) Headers(pairs ...string) *Route {
    method Host (line 238) | func (r *Router) Host(tpl string) *Route {
    method MatcherFunc (line 244) | func (r *Router) MatcherFunc(f MatcherFunc) *Route {
    method Methods (line 250) | func (r *Router) Methods(methods ...string) *Route {
    method Path (line 256) | func (r *Router) Path(tpl string) *Route {
    method PathPrefix (line 262) | func (r *Router) PathPrefix(tpl string) *Route {
    method Queries (line 268) | func (r *Router) Queries(pairs ...string) *Route {
    method Schemes (line 274) | func (r *Router) Schemes(schemes ...string) *Route {
    method BuildVarsFunc (line 280) | func (r *Router) BuildVarsFunc(f BuildVarsFunc) *Route {
    method Walk (line 287) | func (r *Router) Walk(walkFn WalkFunc) error {
    method walk (line 300) | func (r *Router) walk(walkFn WalkFunc, ancestors []*Route) error {
  type WalkFunc (line 298) | type WalkFunc
  type RouteMatch (line 338) | type RouteMatch struct
  type contextKey (line 344) | type contextKey
  constant varsKey (line 347) | varsKey contextKey = iota
  constant routeKey (line 348) | routeKey
  function Vars (line 352) | func Vars(r *http.Request) map[string]string {
  function CurrentRoute (line 364) | func CurrentRoute(r *http.Request) *Route {
  function setVars (line 371) | func setVars(r *http.Request, val interface{}) *http.Request {
  function setCurrentRoute (line 375) | func setCurrentRoute(r *http.Request, val interface{}) *http.Request {
  function getPath (line 385) | func getPath(req *http.Request) string {
  function cleanPath (line 407) | func cleanPath(p string) string {
  function uniqueVars (line 425) | func uniqueVars(s1, s2 []string) error {
  function checkPairs (line 438) | func checkPairs(pairs ...string) (int, error) {
  function mapFromPairsToString (line 449) | func mapFromPairsToString(pairs ...string) (map[string]string, error) {
  function mapFromPairsToRegex (line 463) | func mapFromPairsToRegex(pairs ...string) (map[string]*regexp.Regexp, er...
  function matchInArray (line 480) | func matchInArray(arr []string, value string) bool {
  function matchMapWithString (line 490) | func matchMapWithString(toCheck map[string]string, toMatch map[string][]...
  function matchMapWithRegex (line 518) | func matchMapWithRegex(toCheck map[string]*regexp.Regexp, toMatch map[st...

FILE: vendor/github.com/gorilla/mux/regexp.go
  function newRouteRegexp (line 27) | func newRouteRegexp(tpl string, matchHost, matchPrefix, matchQuery, stri...
  type routeRegexp (line 135) | type routeRegexp struct
    method Match (line 158) | func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool {
    method url (line 174) | func (r *routeRegexp) url(values map[string]string) (string, error) {
    method getURLQuery (line 202) | func (r *routeRegexp) getURLQuery(req *http.Request) string {
    method matchQueryString (line 215) | func (r *routeRegexp) matchQueryString(req *http.Request) bool {
  function braceIndices (line 221) | func braceIndices(s string) ([]int, error) {
  function varGroupName (line 245) | func varGroupName(idx int) string {
  type routeRegexpGroup (line 254) | type routeRegexpGroup struct
    method setMatch (line 261) | func (v *routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, ...
  function getHost (line 306) | func getHost(r *http.Request) string {
  function extractVars (line 319) | func extractVars(input string, matches []int, names []string, output map...

FILE: vendor/github.com/gorilla/mux/route.go
  type Route (line 17) | type Route struct
    method SkipClean (line 44) | func (r *Route) SkipClean() bool {
    method Match (line 49) | func (r *Route) Match(req *http.Request, match *RouteMatch) bool {
    method GetError (line 81) | func (r *Route) GetError() error {
    method BuildOnly (line 86) | func (r *Route) BuildOnly() *Route {
    method Handler (line 94) | func (r *Route) Handler(handler http.Handler) *Route {
    method HandlerFunc (line 102) | func (r *Route) HandlerFunc(f func(http.ResponseWriter, *http.Request)...
    method GetHandler (line 107) | func (r *Route) GetHandler() http.Handler {
    method Name (line 115) | func (r *Route) Name(name string) *Route {
    method GetName (line 128) | func (r *Route) GetName() string {
    method addMatcher (line 142) | func (r *Route) addMatcher(m matcher) *Route {
    method addRegexpMatcher (line 150) | func (r *Route) addRegexpMatcher(tpl string, matchHost, matchPrefix, m...
    method Headers (line 213) | func (r *Route) Headers(pairs ...string) *Route {
    method HeadersRegexp (line 238) | func (r *Route) HeadersRegexp(pairs ...string) *Route {
    method Host (line 266) | func (r *Route) Host(tpl string) *Route {
    method MatcherFunc (line 282) | func (r *Route) MatcherFunc(f MatcherFunc) *Route {
    method Methods (line 298) | func (r *Route) Methods(methods ...string) *Route {
    method Path (line 326) | func (r *Route) Path(tpl string) *Route {
    method PathPrefix (line 342) | func (r *Route) PathPrefix(tpl string) *Route {
    method Queries (line 366) | func (r *Route) Queries(pairs ...string) *Route {
    method Schemes (line 393) | func (r *Route) Schemes(schemes ...string) *Route {
    method BuildVarsFunc (line 408) | func (r *Route) BuildVarsFunc(f BuildVarsFunc) *Route {
    method Subrouter (line 427) | func (r *Route) Subrouter() *Router {
    method URL (line 468) | func (r *Route) URL(pairs ...string) (*url.URL, error) {
    method URLHost (line 502) | func (r *Route) URLHost(pairs ...string) (*url.URL, error) {
    method URLPath (line 526) | func (r *Route) URLPath(pairs ...string) (*url.URL, error) {
    method GetPathTemplate (line 551) | func (r *Route) GetPathTemplate() (string, error) {
    method GetHostTemplate (line 566) | func (r *Route) GetHostTemplate() (string, error) {
    method prepareVars (line 578) | func (r *Route) prepareVars(pairs ...string) (map[string]string, error) {
    method buildVars (line 586) | func (r *Route) buildVars(m map[string]string) map[string]string {
    method getNamedRoutes (line 608) | func (r *Route) getNamedRoutes() map[string]*Route {
    method getRegexpGroup (line 617) | func (r *Route) getRegexpGroup() *routeRegexpGroup {
  type matcher (line 137) | type matcher interface
  type headerMatcher (line 198) | type headerMatcher
    method Match (line 200) | func (m headerMatcher) Match(r *http.Request, match *RouteMatch) bool {
  type headerRegexMatcher (line 223) | type headerRegexMatcher
    method Match (line 225) | func (m headerRegexMatcher) Match(r *http.Request, match *RouteMatch) ...
  type MatcherFunc (line 274) | type MatcherFunc
    method Match (line 277) | func (m MatcherFunc) Match(r *http.Request, match *RouteMatch) bool {
  type methodMatcher (line 289) | type methodMatcher
    method Match (line 291) | func (m methodMatcher) Match(r *http.Request, match *RouteMatch) bool {
  type schemeMatcher (line 385) | type schemeMatcher
    method Match (line 387) | func (m schemeMatcher) Match(r *http.Request, match *RouteMatch) bool {
  type BuildVarsFunc (line 404) | type BuildVarsFunc
  type parentRoute (line 601) | type parentRoute interface

FILE: vendor/github.com/gorilla/pat/pat.go
  function New (line 18) | func New() *Router {
  type Router (line 25) | type Router struct
    method Add (line 30) | func (r *Router) Add(meth, pat string, h http.Handler) *mux.Route {
    method Options (line 35) | func (r *Router) Options(pat string, h http.HandlerFunc) *mux.Route {
    method Delete (line 40) | func (r *Router) Delete(pat string, h http.HandlerFunc) *mux.Route {
    method Head (line 45) | func (r *Router) Head(pat string, h http.HandlerFunc) *mux.Route {
    method Get (line 50) | func (r *Router) Get(pat string, h http.HandlerFunc) *mux.Route {
    method Post (line 55) | func (r *Router) Post(pat string, h http.HandlerFunc) *mux.Route {
    method Put (line 60) | func (r *Router) Put(pat string, h http.HandlerFunc) *mux.Route {
    method Patch (line 65) | func (r *Router) Patch(pat string, h http.HandlerFunc) *mux.Route {
    method ServeHTTP (line 70) | func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
  function registerVars (line 96) | func registerVars(r *http.Request, vars map[string]string) {
  function cleanPath (line 112) | func cleanPath(p string) string {

FILE: vendor/github.com/gorilla/websocket/client.go
  function NewClient (line 39) | func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, ...
  type Dialer (line 51) | type Dialer struct
    method Dial (line 167) | func (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn...
  function parseURL (line 95) | func parseURL(s string) (*url.URL, error) {
  function hostPortNoPort (line 135) | func hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) {

FILE: vendor/github.com/gorilla/websocket/client_clone.go
  function cloneTLSConfig (line 11) | func cloneTLSConfig(cfg *tls.Config) *tls.Config {

FILE: vendor/github.com/gorilla/websocket/client_clone_legacy.go
  function cloneTLSConfig (line 15) | func cloneTLSConfig(cfg *tls.Config) *tls.Config {

FILE: vendor/github.com/gorilla/websocket/compression.go
  constant minCompressionLevel (line 16) | minCompressionLevel     = -2
  constant maxCompressionLevel (line 17) | maxCompressionLevel     = flate.BestCompression
  constant defaultCompressionLevel (line 18) | defaultCompressionLevel = 1
  function decompressNoContextTakeover (line 28) | func decompressNoContextTakeover(r io.Reader) io.ReadCloser {
  function isValidCompressionLevel (line 40) | func isValidCompressionLevel(level int) bool {
  function compressNoContextTakeover (line 44) | func compressNoContextTakeover(w io.WriteCloser, level int) io.WriteClos...
  type truncWriter (line 58) | type truncWriter struct
    method Write (line 64) | func (w *truncWriter) Write(p []byte) (int, error) {
  type flateWriteWrapper (line 92) | type flateWriteWrapper struct
    method Write (line 98) | func (w *flateWriteWrapper) Write(p []byte) (int, error) {
    method Close (line 105) | func (w *flateWriteWrapper) Close() error {
  type flateReadWrapper (line 122) | type flateReadWrapper struct
    method Read (line 126) | func (r *flateReadWrapper) Read(p []byte) (int, error) {
    method Close (line 140) | func (r *flateReadWrapper) Close() error {

FILE: vendor/github.com/gorilla/websocket/conn.go
  constant finalBit (line 23) | finalBit = 1 << 7
  constant rsv1Bit (line 24) | rsv1Bit  = 1 << 6
  constant rsv2Bit (line 25) | rsv2Bit  = 1 << 5
  constant rsv3Bit (line 26) | rsv3Bit  = 1 << 4
  constant maskBit (line 29) | maskBit = 1 << 7
  constant maxFrameHeaderSize (line 31) | maxFrameHeaderSize         = 2 + 8 + 4
  constant maxControlFramePayloadSize (line 32) | maxControlFramePayloadSize = 125
  constant writeWait (line 34) | writeWait = time.Second
  constant defaultReadBufferSize (line 36) | defaultReadBufferSize  = 4096
  constant defaultWriteBufferSize (line 37) | defaultWriteBufferSize = 4096
  constant continuationFrame (line 39) | continuationFrame = 0
  constant noFrame (line 40) | noFrame           = -1
  constant CloseNormalClosure (line 45) | CloseNormalClosure           = 1000
  constant CloseGoingAway (line 46) | CloseGoingAway               = 1001
  constant CloseProtocolError (line 47) | CloseProtocolError           = 1002
  constant CloseUnsupportedData (line 48) | CloseUnsupportedData         = 1003
  constant CloseNoStatusReceived (line 49) | CloseNoStatusReceived        = 1005
  constant CloseAbnormalClosure (line 50) | CloseAbnormalClosure         = 1006
  constant CloseInvalidFramePayloadData (line 51) | CloseInvalidFramePayloadData = 1007
  constant ClosePolicyViolation (line 52) | ClosePolicyViolation         = 1008
  constant CloseMessageTooBig (line 53) | CloseMessageTooBig           = 1009
  constant CloseMandatoryExtension (line 54) | CloseMandatoryExtension      = 1010
  constant CloseInternalServerErr (line 55) | CloseInternalServerErr       = 1011
  constant CloseServiceRestart (line 56) | CloseServiceRestart          = 1012
  constant CloseTryAgainLater (line 57) | CloseTryAgainLater           = 1013
  constant CloseTLSHandshake (line 58) | CloseTLSHandshake            = 1015
  constant TextMessage (line 65) | TextMessage = 1
  constant BinaryMessage (line 68) | BinaryMessage = 2
  constant CloseMessage (line 73) | CloseMessage = 8
  constant PingMessage (line 77) | PingMessage = 9
  constant PongMessage (line 81) | PongMessage = 10
  type netError (line 93) | type netError struct
    method Error (line 99) | func (e *netError) Error() string   { return e.msg }
    method Temporary (line 100) | func (e *netError) Temporary() bool { return e.temporary }
    method Timeout (line 101) | func (e *netError) Timeout() bool   { return e.timeout }
  type CloseError (line 104) | type CloseError struct
    method Error (line 113) | func (e *CloseError) Error() string {
  function IsCloseError (line 151) | func IsCloseError(err error, codes ...int) bool {
  function IsUnexpectedCloseError (line 164) | func IsUnexpectedCloseError(err error, expectedCodes ...int) bool {
  function newMaskKey (line 184) | func newMaskKey() [4]byte {
  function hideTempErr (line 189) | func hideTempErr(err error) error {
  function isControl (line 196) | func isControl(frameType int) bool {
  function isData (line 200) | func isData(frameType int) bool {
  function isValidReceivedCloseCode (line 223) | func isValidReceivedCloseCode(code int) bool {
  type Conn (line 228) | type Conn struct
    method Subprotocol (line 342) | func (c *Conn) Subprotocol() string {
    method Close (line 347) | func (c *Conn) Close() error {
    method LocalAddr (line 352) | func (c *Conn) LocalAddr() net.Addr {
    method RemoteAddr (line 357) | func (c *Conn) RemoteAddr() net.Addr {
    method writeFatal (line 363) | func (c *Conn) writeFatal(err error) error {
    method write (line 373) | func (c *Conn) write(frameType int, deadline time.Time, bufs ...[]byte...
    method WriteControl (line 402) | func (c *Conn) WriteControl(messageType int, data []byte, deadline tim...
    method prepWrite (line 463) | func (c *Conn) prepWrite(messageType int) error {
    method NextWriter (line 487) | func (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) {
    method WritePreparedMessage (line 707) | func (c *Conn) WritePreparedMessage(pm *PreparedMessage) error {
    method WriteMessage (line 730) | func (c *Conn) WriteMessage(messageType int, data []byte) error {
    method SetWriteDeadline (line 759) | func (c *Conn) SetWriteDeadline(t time.Time) error {
    method advanceFrame (line 766) | func (c *Conn) advanceFrame() (int, error) {
    method handleProtocolError (line 912) | func (c *Conn) handleProtocolError(message string) error {
    method NextReader (line 927) | func (c *Conn) NextReader() (messageType int, r io.Reader, err error) {
    method ReadMessage (line 1017) | func (c *Conn) ReadMessage() (messageType int, p []byte, err error) {
    method SetReadDeadline (line 1031) | func (c *Conn) SetReadDeadline(t time.Time) error {
    method SetReadLimit (line 1038) | func (c *Conn) SetReadLimit(limit int64) {
    method CloseHandler (line 1043) | func (c *Conn) CloseHandler() func(code int, text string) error {
    method SetCloseHandler (line 1060) | func (c *Conn) SetCloseHandler(h func(code int, text string) error) {
    method PingHandler (line 1075) | func (c *Conn) PingHandler() func(appData string) error {
    method SetPingHandler (line 1085) | func (c *Conn) SetPingHandler(h func(appData string) error) {
    method PongHandler (line 1101) | func (c *Conn) PongHandler() func(appData string) error {
    method SetPongHandler (line 1111) | func (c *Conn) SetPongHandler(h func(appData string) error) {
    method UnderlyingConn (line 1120) | func (c *Conn) UnderlyingConn() net.Conn {
    method EnableWriteCompression (line 1127) | func (c *Conn) EnableWriteCompression(enable bool) {
    method SetCompressionLevel (line 1135) | func (c *Conn) SetCompressionLevel(level int) error {
  function newConn (line 267) | func newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSi...
  type writeHook (line 271) | type writeHook struct
    method Write (line 275) | func (wh *writeHook) Write(p []byte) (int, error) {
  function newConnBRW (line 280) | func newConnBRW(conn net.Conn, isServer bool, readBufferSize, writeBuffe...
  type messageWriter (line 506) | type messageWriter struct
    method fatal (line 514) | func (w *messageWriter) fatal(err error) error {
    method flushFrame (line 524) | func (w *messageWriter) flushFrame(final bool, extra []byte) error {
    method ncopy (line 611) | func (w *messageWriter) ncopy(max int) (int, error) {
    method Write (line 625) | func (w *messageWriter) Write(p []byte) (int, error) {
    method WriteString (line 652) | func (w *messageWriter) WriteString(p string) (int, error) {
    method ReadFrom (line 670) | func (w *messageWriter) ReadFrom(r io.Reader) (nn int64, err error) {
    method Close (line 695) | func (w *messageWriter) Close() error {
  type messageReader (line 964) | type messageReader struct
    method Read (line 966) | func (r *messageReader) Read(b []byte) (int, error) {
    method Close (line 1011) | func (r *messageReader) Close() error {
  function FormatCloseMessage (line 1144) | func FormatCloseMessage(closeCode int, text string) []byte {

FILE: vendor/github.com/gorilla/websocket/conn_read.go
  method read (line 11) | func (c *Conn) read(n int) ([]byte, error) {

FILE: vendor/github.com/gorilla/websocket/conn_read_legacy.go
  method read (line 11) | func (c *Conn) read(n int) ([]byte, error) {

FILE: vendor/github.com/gorilla/websocket/json.go
  function WriteJSON (line 13) | func WriteJSON(c *Conn, v interface{}) error {
  method WriteJSON (line 21) | func (c *Conn) WriteJSON(v interface{}) error {
  function ReadJSON (line 35) | func ReadJSON(c *Conn, v interface{}) error {
  method ReadJSON (line 44) | func (c *Conn) ReadJSON(v interface{}) error {

FILE: vendor/github.com/gorilla/websocket/mask.go
  constant wordSize (line 11) | wordSize = int(unsafe.Sizeof(uintptr(0)))
  function maskBytes (line 13) | func maskBytes(key [4]byte, pos int, b []byte) int {

FILE: vendor/github.com/gorilla/websocket/mask_safe.go
  function maskBytes (line 9) | func maskBytes(key [4]byte, pos int, b []byte) int {

FILE: vendor/github.com/gorilla/websocket/prepared.go
  type PreparedMessage (line 19) | type PreparedMessage struct
    method frame (line 63) | func (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) {
  type prepareKey (line 28) | type prepareKey struct
  type preparedFrame (line 35) | type preparedFrame struct
  function NewPreparedMessage (line 44) | func NewPreparedMessage(messageType int, data []byte) (*PreparedMessage,...
  type prepareConn (line 97) | type prepareConn struct
    method Write (line 102) | func (pc *prepareConn) Write(p []byte) (int, error)        { return pc...
    method SetWriteDeadline (line 103) | func (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil }

FILE: vendor/github.com/gorilla/websocket/server.go
  type HandshakeError (line 18) | type HandshakeError struct
    method Error (line 22) | func (e HandshakeError) Error() string { return e.message }
  type Upgrader (line 26) | type Upgrader struct
    method returnError (line 58) | func (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request,...
    method selectSubprotocol (line 82) | func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader h...
    method Upgrade (line 106) | func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, res...
  function checkSameOrigin (line 70) | func checkSameOrigin(r *http.Request) bool {
  function Upgrade (line 260) | func Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http...
  function Subprotocols (line 274) | func Subprotocols(r *http.Request) []string {
  function IsWebSocketUpgrade (line 288) | func IsWebSocketUpgrade(r *http.Request) bool {

FILE: vendor/github.com/gorilla/websocket/util.go
  function computeAcceptKey (line 18) | func computeAcceptKey(challengeKey string) string {
  function generateChallengeKey (line 25) | func generateChallengeKey() (string, error) {
  constant isTokenOctet (line 37) | isTokenOctet = 1 << iota
  constant isSpaceOctet (line 38) | isSpaceOctet
  function init (line 41) | func init() {
  function skipSpace (line 75) | func skipSpace(s string) (rest string) {
  function nextToken (line 85) | func nextToken(s string) (token, rest string) {
  function nextTokenOrQuoted (line 95) | func nextTokenOrQuoted(s string) (value string, rest string) {
  function tokenListContainsValue (line 132) | func tokenListContainsValue(header http.Header, name string, value strin...
  function parseExtensions (line 158) | func parseExtensions(header http.Header) []map[string]string {

FILE: vendor/github.com/ian-kent/envconf/envconf.go
  function FromEnvP (line 16) | func FromEnvP(env string, value interface{}) interface{} {
  function FromEnv (line 26) | func FromEnv(env string, value interface{}) (interface{}, error) {

FILE: vendor/github.com/ian-kent/go-log/appenders/appender.go
  type Appender (line 18) | type Appender interface

FILE: vendor/github.com/ian-kent/go-log/appenders/console.go
  type consoleAppender (line 9) | type consoleAppender struct
    method Write (line 21) | func (a *consoleAppender) Write(level levels.LogLevel, message string,...
    method Layout (line 25) | func (a *consoleAppender) Layout() layout.Layout {
    method SetLayout (line 29) | func (a *consoleAppender) SetLayout(layout layout.Layout) {
  function Console (line 14) | func Console() *consoleAppender {

FILE: vendor/github.com/ian-kent/go-log/appenders/fluentd.go
  type fluentdAppender (line 11) | type fluentdAppender struct
    method Close (line 34) | func (a *fluentdAppender) Close() {
    method Open (line 39) | func (a *fluentdAppender) Open() error {
    method Write (line 48) | func (a *fluentdAppender) Write(level levels.LogLevel, message string,...
    method Layout (line 58) | func (a *fluentdAppender) Layout() layout.Layout {
    method SetLayout (line 62) | func (a *fluentdAppender) SetLayout(layout layout.Layout) {
  function SafeFluentd (line 18) | func SafeFluentd(config fluent.Config) (*fluentdAppender, error) {
  function Fluentd (line 29) | func Fluentd(config fluent.Config) *fluentdAppender {

FILE: vendor/github.com/ian-kent/go-log/appenders/multiple_appender.go
  type multipleAppender (line 8) | type multipleAppender struct
    method Layout (line 20) | func (this *multipleAppender) Layout() layout.Layout {
    method SetLayout (line 24) | func (this *multipleAppender) SetLayout(l layout.Layout) {
    method Write (line 28) | func (this *multipleAppender) Write(level levels.LogLevel, message str...
  function Multiple (line 13) | func Multiple(layout layout.Layout, appenders ...Appender) Appender {

FILE: vendor/github.com/ian-kent/go-log/appenders/rollingfile.go
  type rollingFileAppender (line 13) | type rollingFileAppender struct
    method Close (line 43) | func (a *rollingFileAppender) Close() {
    method Write (line 50) | func (a *rollingFileAppender) Write(level levels.LogLevel, message str...
    method Layout (line 68) | func (a *rollingFileAppender) Layout() layout.Layout {
    method SetLayout (line 72) | func (a *rollingFileAppender) SetLayout(layout layout.Layout) {
    method Filename (line 76) | func (a *rollingFileAppender) Filename() string {
    method SetFilename (line 80) | func (a *rollingFileAppender) SetFilename(filename string) error {
    method rotateFile (line 90) | func (a *rollingFileAppender) rotateFile() {
    method closeFile (line 108) | func (a *rollingFileAppender) closeFile() {
    method openFile (line 114) | func (a *rollingFileAppender) openFile() error {
  function RollingFile (line 27) | func RollingFile(filename string, append bool) *rollingFileAppender {

FILE: vendor/github.com/ian-kent/go-log/layout/basic.go
  type basicLayout (line 8) | type basicLayout struct
    method Format (line 16) | func (a *basicLayout) Format(level levels.LogLevel, message string, ar...
  function Basic (line 12) | func Basic() *basicLayout {

FILE: vendor/github.com/ian-kent/go-log/layout/layout.go
  type Layout (line 18) | type Layout interface
  function Default (line 22) | func Default() Layout {

FILE: vendor/github.com/ian-kent/go-log/layout/pattern.go
  type patternLayout (line 24) | type patternLayout struct
    method Format (line 63) | func (a *patternLayout) Format(level levels.LogLevel, message string, ...
  type caller (line 31) | type caller struct
  function Pattern (line 41) | func Pattern(pattern string) *patternLayout {
  function getCaller (line 49) | func getCaller() *caller {

FILE: vendor/github.com/ian-kent/go-log/levels/levels.go
  type LogLevel (line 3) | type LogLevel
  constant FATAL (line 6) | FATAL LogLevel = iota
  constant ERROR (line 7) | ERROR
  constant INFO (line 8) | INFO
  constant WARN (line 9) | WARN
  constant DEBUG (line 10) | DEBUG
  constant TRACE (line 11) | TRACE
  constant INHERIT (line 12) | INHERIT

FILE: vendor/github.com/ian-kent/go-log/log/log.go
  function Stol (line 12) | func Stol(level string) levels.LogLevel {
  function Logger (line 23) | func Logger(args ...string) logger.Logger {
  function Log (line 41) | func Log(level levels.LogLevel, params ...interface{}) {
  function Level (line 45) | func Level(level levels.LogLevel)   { Logger().Level() }
  function Debug (line 46) | func Debug(params ...interface{})   { Log(levels.DEBUG, params...) }
  function Info (line 47) | func Info(params ...interface{})    { Log(levels.INFO, params...) }
  function Warn (line 48) | func Warn(params ...interface{})    { Log(levels.WARN, params...) }
  function Error (line 49) | func Error(params ...interface{})   { Log(levels.ERROR, params...) }
  function Trace (line 50) | func Trace(params ...interface{})   { Log(levels.TRACE, params...) }
  function Fatal (line 51) | func Fatal(params ...interface{})   { Log(levels.FATAL, params...) }
  function Printf (line 52) | func Printf(params ...interface{})  { Log(levels.INFO, params...) }
  function Println (line 53) | func Println(params ...interface{}) { Log(levels.INFO, params...) }
  function Fatalf (line 54) | func Fatalf(params ...interface{})  { Log(levels.FATAL, params...) }

FILE: vendor/github.com/ian-kent/go-log/logger/logger.go
  type Logger (line 14) | type Logger interface
  type logger (line 38) | type logger struct
    method New (line 85) | func (l *logger) New(name string) Logger {
    method GetLogger (line 98) | func (l *logger) GetLogger(name string) Logger {
    method write (line 125) | func (l *logger) write(level levels.LogLevel, params ...interface{}) {
    method Appender (line 138) | func (l *logger) Appender() Appender {
    method Log (line 150) | func (l *logger) Log(level levels.LogLevel, params ...interface{}) {
    method Level (line 161) | func (l *logger) Level() levels.LogLevel {
    method Enabled (line 168) | func (l *logger) Enabled() map[levels.LogLevel]bool {
    method Name (line 175) | func (l *logger) Name() string {
    method FullName (line 179) | func (l *logger) FullName() string {
    method Children (line 190) | func (l *logger) Children() []Logger {
    method Parent (line 194) | func (l *logger) Parent() Logger {
    method SetLevel (line 198) | func (l *logger) SetLevel(level levels.LogLevel) {
    method SetAppender (line 209) | func (l *logger) SetAppender(appender Appender) {
    method Debug (line 213) | func (l *logger) Debug(params ...interface{})   { l.Log(levels.DEBUG, ...
    method Info (line 214) | func (l *logger) Info(params ...interface{})    { l.Log(levels.INFO, p...
    method Warn (line 215) | func (l *logger) Warn(params ...interface{})    { l.Log(levels.WARN, p...
    method Error (line 216) | func (l *logger) Error(params ...interface{})   { l.Log(levels.ERROR, ...
    method Trace (line 217) | func (l *logger) Trace(params ...interface{})   { l.Log(levels.TRACE, ...
    method Printf (line 218) | func (l *logger) Printf(params ...interface{})  { l.Log(levels.INFO, p...
    method Println (line 219) | func (l *logger) Println(params ...interface{}) { l.Log(levels.INFO, p...
    method Fatal (line 220) | func (l *logger) Fatal(params ...interface{})   { l.Log(levels.FATAL, ...
    method Fatalf (line 221) | func (l *logger) Fatalf(params ...interface{})  { l.Log(levels.FATAL, ...
  type Appender (line 49) | type Appender interface
  function New (line 56) | func New(name string) Logger {
  function unwrap (line 70) | func unwrap(args ...interface{}) []interface{} {
  type stringer (line 121) | type stringer interface

FILE: vendor/github.com/ian-kent/goose/goose.go
  type EventStream (line 20) | type EventStream struct
    method Notify (line 41) | func (es *EventStream) Notify(event string, bytes []byte) {
    method AddReceiver (line 98) | func (es *EventStream) AddReceiver(w http.ResponseWriter) (*EventRecei...
  function NewEventStream (line 26) | func NewEventStream() *EventStream {
  type EventReceiver (line 34) | type EventReceiver struct
    method send (line 59) | func (er *EventReceiver) send(size, data string) {
    method write (line 75) | func (er *EventReceiver) write(bytes []byte) (int, error) {

FILE: vendor/github.com/ian-kent/linkio/linkio.go
  type Throughput (line 17) | type Throughput
  constant BitPerSecond (line 30) | BitPerSecond      Throughput = 1
  constant BytePerSecond (line 31) | BytePerSecond                = 8 * BitPerSecond
  constant KilobitPerSecond (line 32) | KilobitPerSecond             = 1024 * BitPerSecond
  constant KilobytePerSecond (line 33) | KilobytePerSecond            = 1024 * BytePerSecond
  constant MegabitPerSecond (line 34) | MegabitPerSecond             = 1024 * KilobitPerSecond
  constant MegabytePerSecond (line 35) | MegabytePerSecond            = 1024 * KilobytePerSecond
  constant GigabitPerSecond (line 36) | GigabitPerSecond             = 1024 * MegabitPerSecond
  constant GigabytePerSecond (line 37) | GigabytePerSecond            = 1024 * MegabytePerSecond
  type LinkReader (line 42) | type LinkReader struct
    method Read (line 132) | func (l *LinkReader) Read(buf []byte) (n int, err error) {
  type LinkWriter (line 49) | type LinkWriter struct
    method Write (line 152) | func (l *LinkWriter) Write(buf []byte) (n int, err error) {
  type Link (line 59) | type Link struct
    method NewLinkReader (line 74) | func (link *Link) NewLinkReader(r io.Reader) (s *LinkReader) {
    method NewLinkWriter (line 81) | func (link *Link) NewLinkWriter(w io.Writer) (s *LinkWriter) {
    method SetThroughput (line 118) | func (link *Link) SetThroughput(throughput Throughput) {
  type linkRequest (line 67) | type linkRequest struct
  function NewLink (line 87) | func NewLink(throughput Throughput) (l *Link) {
  function min (line 124) | func min(a, b int) int {

FILE: vendor/github.com/jtolds/gls/context.go
  type Values (line 15) | type Values
  type ContextManager (line 22) | type ContextManager struct
    method Unregister (line 41) | func (m *ContextManager) Unregister() {
    method SetValues (line 54) | func (m *ContextManager) SetValues(new_values Values, context_call fun...
    method GetValue (line 104) | func (m *ContextManager) GetValue(key interface{}) (
    method getValues (line 122) | func (m *ContextManager) getValues() Values {
  function NewContextManager (line 30) | func NewContextManager() *ContextManager {
  function Go (line 139) | func Go(cb func()) {

FILE: vendor/github.com/jtolds/gls/gen_sym.go
  type ContextKey (line 13) | type ContextKey struct
  function GenSym (line 16) | func GenSym() ContextKey {

FILE: vendor/github.com/jtolds/gls/gid.go
  function GetGoroutineId (line 10) | func GetGoroutineId() (gid uint, ok bool) {
  function EnsureGoroutineId (line 17) | func EnsureGoroutineId(cb func(gid uint)) {

FILE: vendor/github.com/jtolds/gls/id_pool.go
  type idPool (line 11) | type idPool struct
    method Acquire (line 17) | func (p *idPool) Acquire() (id uint) {
    method Release (line 30) | func (p *idPool) Release(id uint) {

FILE: vendor/github.com/jtolds/gls/stack_tags.go
  constant bitWidth (line 6) | bitWidth       = 4
  constant stackBatchSize (line 7) | stackBatchSize = 16
  function init (line 15) | func init() {
  function addStackTag (line 45) | func addStackTag(tag uint, context_call func()) {
  function github_com_jtolds_gls_markS (line 54) | func github_com_jtolds_gls_markS(tag uint, cb func()) { _m(tag, cb) }
  function github_com_jtolds_gls_mark0 (line 55) | func github_com_jtolds_gls_mark0(tag uint, cb func()) { _m(tag, cb) }
  function github_com_jtolds_gls_mark1 (line 56) | func github_com_jtolds_gls_mark1(tag uint, cb func()) { _m(tag, cb) }
  function github_com_jtolds_gls_mark2 (line 57) | func github_com_jtolds_gls_mark2(tag uint, cb func()) { _m(tag, cb) }
  function github_com_jtolds_gls_mark3 (line 58) | func github_com_jtolds_gls_mark3(tag uint, cb func()) { _m(tag, cb) }
  function github_com_jtolds_gls_mark4 (line 59) | func github_com_jtolds_gls_mark4(tag uint, cb func()) { _m(tag, cb) }
  function github_com_jtolds_gls_mark5 (line 60) | func github_com_jtolds_gls_mark5(tag uint, cb func()) { _m(tag, cb) }
  function github_com_jtolds_gls_mark6 (line 61) | func github_com_jtolds_gls_mark6(tag uint, cb func()) { _m(tag, cb) }
  function github_com_jtolds_gls_mark7 (line 62) | func github_com_jtolds_gls_mark7(tag uint, cb func()) { _m(tag, cb) }
  function github_com_jtolds_gls_mark8 (line 63) | func github_com_jtolds_gls_mark8(tag uint, cb func()) { _m(tag, cb) }
  function github_com_jtolds_gls_mark9 (line 64) | func github_com_jtolds_gls_mark9(tag uint, cb func()) { _m(tag, cb) }
  function github_com_jtolds_gls_markA (line 65) | func github_com_jtolds_gls_markA(tag uint, cb func()) { _m(tag, cb) }
  function github_com_jtolds_gls_markB (line 66) | func github_com_jtolds_gls_markB(tag uint, cb func()) { _m(tag, cb) }
  function github_com_jtolds_gls_markC (line 67) | func github_com_jtolds_gls_markC(tag uint, cb func()) { _m(tag, cb) }
  function github_com_jtolds_gls_markD (line 68) | func github_com_jtolds_gls_markD(tag uint, cb func()) { _m(tag, cb) }
  function github_com_jtolds_gls_markE (line 69) | func github_com_jtolds_gls_markE(tag uint, cb func()) { _m(tag, cb) }
  function github_com_jtolds_gls_markF (line 70) | func github_com_jtolds_gls_markF(tag uint, cb func()) { _m(tag, cb) }
  function _m (line 72) | func _m(tag_remainder uint, cb func()) {
  function readStackTag (line 80) | func readStackTag() (tag uint, ok bool) {

FILE: vendor/github.com/jtolds/gls/stack_tags_js.go
  constant jsFuncNamePrefix (line 16) | jsFuncNamePrefix = "github_com_jtolds_gls_mark"
  function jsMarkStack (line 19) | func jsMarkStack() (f []uintptr) {
  function findPtr (line 62) | func findPtr() uintptr {
  function getStack (line 70) | func getStack(offset, amount int) []uintptr {

FILE: vendor/github.com/jtolds/gls/stack_tags_main.go
  function getStack (line 12) | func getStack(offset, amount int) []uintptr {
  function findPtr (line 17) | func findPtr() uintptr {

FILE: vendor/github.com/mailhog/MailHog-Server/api/api.go
  function CreateAPI (line 10) | func CreateAPI(conf *config.Config, r gohttp.Handler) {

FILE: vendor/github.com/mailhog/MailHog-Server/api/v1.go
  type APIv1 (line 27) | type APIv1 struct
    method defaultOptions (line 86) | func (apiv1 *APIv1) defaultOptions(w http.ResponseWriter, req *http.Re...
    method broadcast (line 94) | func (apiv1 *APIv1) broadcast(json string) {
    method keepalive (line 105) | func (apiv1 *APIv1) keepalive() {
    method eventstream (line 110) | func (apiv1 *APIv1) eventstream(w http.ResponseWriter, req *http.Reque...
    method messages (line 122) | func (apiv1 *APIv1) messages(w http.ResponseWriter, req *http.Request) {
    method message (line 144) | func (apiv1 *APIv1) message(w http.ResponseWriter, req *http.Request) {
    method download (line 168) | func (apiv1 *APIv1) download(w http.ResponseWriter, req *http.Request) {
    method download_part (line 199) | func (apiv1 *APIv1) download_part(w http.ResponseWriter, req *http.Req...
    method delete_all (line 239) | func (apiv1 *APIv1) delete_all(w http.ResponseWriter, req *http.Reques...
    method release_one (line 256) | func (apiv1 *APIv1) release_one(w http.ResponseWriter, req *http.Reque...
    method delete_one (line 344) | func (apiv1 *APIv1) delete_one(w http.ResponseWriter, req *http.Reques...
  type ReleaseConfig (line 36) | type ReleaseConfig
  function createAPIv1 (line 38) | func createAPIv1(conf *config.Config, r *pat.Router) *APIv1 {

FILE: vendor/github.com/mailhog/MailHog-Server/api/v2.go
  type APIv2 (line 20) | type APIv2 struct
    method defaultOptions (line 64) | func (apiv2 *APIv2) defaultOptions(w http.ResponseWriter, req *http.Re...
    method getStartLimit (line 79) | func (apiv2 *APIv2) getStartLimit(w http.ResponseWriter, req *http.Req...
    method messages (line 99) | func (apiv2 *APIv2) messages(w http.ResponseWriter, req *http.Request) {
    method search (line 123) | func (apiv2 *APIv2) search(w http.ResponseWriter, req *http.Request) {
    method jim (line 156) | func (apiv2 *APIv2) jim(w http.ResponseWriter, req *http.Request) {
    method deleteJim (line 171) | func (apiv2 *APIv2) deleteJim(w http.ResponseWriter, req *http.Request) {
    method createJim (line 184) | func (apiv2 *APIv2) createJim(w http.ResponseWriter, req *http.Request) {
    method newJimFromBody (line 204) | func (apiv2 *APIv2) newJimFromBody(w http.ResponseWriter, req *http.Re...
    method updateJim (line 222) | func (apiv2 *APIv2) updateJim(w http.ResponseWriter, req *http.Request) {
    method listOutgoingSMTP (line 238) | func (apiv2 *APIv2) listOutgoingSMTP(w http.ResponseWriter, req *http....
    method websocket (line 248) | func (apiv2 *APIv2) websocket(w http.ResponseWriter, req *http.Request) {
    method broadcast (line 254) | func (apiv2 *APIv2) broadcast(msg *data.Message) {
  function createAPIv2 (line 26) | func createAPIv2(conf *config.Config, r *pat.Router) *APIv2 {
  type messagesResult (line 72) | type messagesResult struct

FILE: vendor/github.com/mailhog/MailHog-Server/config/config.go
  function DefaultConfig (line 16) | func DefaultConfig() *Config {
  type Config (line 34) | type Config struct
  type OutgoingSMTP (line 55) | type OutgoingSMTP struct
  function Configure (line 72) | func Configure() *Config {
  function RegisterFlags (line 119) | func RegisterFlags() {

FILE: vendor/github.com/mailhog/MailHog-Server/main.go
  function configure (line 22) | func configure() {
  function main (line 30) | func main() {

FILE: vendor/github.com/mailhog/MailHog-Server/monkey/jim.go
  type Jim (line 13) | type Jim struct
    method RegisterFlags (line 26) | func (j *Jim) RegisterFlags() {
    method Configure (line 38) | func (j *Jim) Configure(logf func(string, ...interface{})) {
    method ConfigureFrom (line 45) | func (j *Jim) ConfigureFrom(j2 *Jim) {
    method Accept (line 50) | func (j *Jim) Accept(conn net.Conn) bool {
    method LinkSpeed (line 60) | func (j *Jim) LinkSpeed() *linkio.Throughput {
    method ValidRCPT (line 74) | func (j *Jim) ValidRCPT(rcpt string) bool {
    method ValidMAIL (line 84) | func (j *Jim) ValidMAIL(mail string) bool {
    method ValidAUTH (line 94) | func (j *Jim) ValidAUTH(mechanism string, args ...string) bool {
    method Disconnect (line 104) | func (j *Jim) Disconnect() bool {

FILE: vendor/github.com/mailhog/MailHog-Server/monkey/monkey.go
  type ChaosMonkey (line 10) | type ChaosMonkey interface

FILE: vendor/github.com/mailhog/MailHog-Server/smtp/session.go
  type Session (line 18) | type Session struct
    method validateAuthentication (line 70) | func (c *Session) validateAuthentication(mechanism string, args ...str...
    method validateRecipient (line 81) | func (c *Session) validateRecipient(to string) bool {
    method validateSender (line 91) | func (c *Session) validateSender(from string) bool {
    method acceptMessage (line 101) | func (c *Session) acceptMessage(msg *data.SMTPMessage) (id string, err...
    method logf (line 109) | func (c *Session) logf(message string, args ...interface{}) {
    method Read (line 116) | func (c *Session) Read() bool {
    method Write (line 155) | func (c *Session) Write(reply *smtp.Reply) {
  function Accept (line 34) | func Accept(remoteAddress string, conn io.ReadWriteCloser, storage stora...

FILE: vendor/github.com/mailhog/MailHog-Server/smtp/session_test.go
  type fakeRw (line 14) | type fakeRw struct
    method Read (line 20) | func (rw *fakeRw) Read(p []byte) (n int, err error) {
    method Close (line 26) | func (rw *fakeRw) Close() error {
    method Write (line 32) | func (rw *fakeRw) Write(p []byte) (n int, err error) {
  function TestAccept (line 39) | func TestAccept(t *testing.T) {
  function TestSocketError (line 47) | func TestSocketError(t *testing.T) {
  function TestAcceptMessage (line 59) | func TestAcceptMessage(t *testing.T) {
  function TestValidateAuthentication (line 107) | func TestValidateAuthentication(t *testing.T) {
  function TestValidateRecipient (line 125) | func TestValidateRecipient(t *testing.T) {
  function TestValidateSender (line 134) | func TestValidateSender(t *testing.T) {

FILE: vendor/github.com/mailhog/MailHog-Server/smtp/smtp.go
  function Listen (line 11) | func Listen(cfg *config.Config, exitCh chan int) *net.TCPListener {

FILE: vendor/github.com/mailhog/MailHog-Server/websockets/connection.go
  constant writeWait (line 11) | writeWait = 10 * time.Second
  constant pongWait (line 13) | pongWait = 60 * time.Second
  constant pingPeriod (line 15) | pingPeriod = (pongWait * 9) / 10
  constant maxMessageSize (line 17) | maxMessageSize = 1
  type connection (line 20) | type connection struct
    method readLoop (line 26) | func (c *connection) readLoop() {
    method writeLoop (line 41) | func (c *connection) writeLoop() {
    method writeJSON (line 65) | func (c *connection) writeJSON(message interface{}) error {
    method writeControl (line 70) | func (c *connection) writeControl(messageType int) error {

FILE: vendor/github.com/mailhog/MailHog-Server/websockets/hub.go
  type Hub (line 10) | type Hub struct
    method run (line 36) | func (h *Hub) run() {
    method unregister (line 55) | func (h *Hub) unregister(c *connection) {
    method Serve (line 62) | func (h *Hub) Serve(w http.ResponseWriter, r *http.Request) {
    method Broadcast (line 74) | func (h *Hub) Broadcast(data interface{}) {
  function NewHub (line 18) | func NewHub() *Hub {

FILE: vendor/github.com/mailhog/MailHog-UI/assets/assets.go
  function bindataRead (line 42) | func bindataRead(data []byte, name string) ([]byte, error) {
  type asset (line 62) | type asset struct
  type bindataFileInfo (line 67) | type bindataFileInfo struct
    method Name (line 74) | func (fi bindataFileInfo) Name() string {
    method Size (line 77) | func (fi bindataFileInfo) Size() int64 {
    method Mode (line 80) | func (fi bindataFileInfo) Mode() os.FileMode {
    method ModTime (line 83) | func (fi bindataFileInfo) ModTime() time.Time {
    method IsDir (line 86) | func (fi bindataFileInfo) IsDir() bool {
    method Sys (line 89) | func (fi bindataFileInfo) Sys() interface{} {
  function assetsCssBootstrap332MinCssBytes (line 95) | func assetsCssBootstrap332MinCssBytes() ([]byte, error) {
  function assetsCssBootstrap332MinCss (line 102) | func assetsCssBootstrap332MinCss() (*asset, error) {
  function assetsCssJqueryUi1104SmoothnessCssBytes (line 115) | func assetsCssJqueryUi1104SmoothnessCssBytes() ([]byte, error) {
  function assetsCssJqueryUi1104SmoothnessCss (line 122) | func assetsCssJqueryUi1104SmoothnessCss() (*asset, error) {
  function assetsCssStyleCssBytes (line 135) | func assetsCssStyleCssBytes() ([]byte, error) {
  function assetsCssStyleCss (line 142) | func assetsCssStyleCss() (*asset, error) {
  function assetsFontsGlyphiconsHalflingsRegularEotBytes (line 155) | func assetsFontsGlyphiconsHalflingsRegularEotBytes() ([]byte, error) {
  function assetsFontsGlyphiconsHalflingsRegularEot (line 162) | func assetsFontsGlyphiconsHalflingsRegularEot() (*asset, error) {
  function assetsFontsGlyphiconsHalflingsRegularSvgBytes (line 175) | func assetsFontsGlyphiconsHalflingsRegularSvgBytes() ([]byte, error) {
  function assetsFontsGlyphiconsHalflingsRegularSvg (line 182) | func assetsFontsGlyphiconsHalflingsRegularSvg() (*asset, error) {
  function assetsFontsGlyphiconsHalflingsRegularTtfBytes (line 195) | func assetsFontsGlyphiconsHalflingsRegularTtfBytes() ([]byte, error) {
  function assetsFontsGlyphiconsHalflingsRegularTtf (line 202) | func assetsFontsGlyphiconsHalflingsRegularTtf() (*asset, error) {
  function assetsFontsGlyphiconsHalflingsRegularWoffBytes (line 215) | func assetsFontsGlyphiconsHalflingsRegularWoffBytes() ([]byte, error) {
  function assetsFontsGlyphiconsHalflingsRegularWoff (line 222) | func assetsFontsGlyphiconsHalflingsRegularWoff() (*asset, error) {
  function assetsFontsGlyphiconsHalflingsRegularWoff2Bytes (line 235) | func assetsFontsGlyphiconsHalflingsRegularWoff2Bytes() ([]byte, error) {
  function assetsFontsGlyphiconsHalflingsRegularWoff2 (line 242) | func assetsFontsGlyphiconsHalflingsRegularWoff2() (*asset, error) {
  function assetsImagesGithubPngBytes (line 255) | func assetsImagesGithubPngBytes() ([]byte, error) {
  function assetsImagesGithubPng (line 262) | func assetsImagesGithubPng() (*asset, error) {
  function assetsImagesHogPngBytes (line 275) | func assetsImagesHogPngBytes() ([]byte, error) {
  function assetsImagesHogPng (line 282) | func assetsImagesHogPng() (*asset, error) {
  function assetsJsAngular138JsBytes (line 295) | func assetsJsAngular138JsBytes() ([]byte, error) {
  function assetsJsAngular138Js (line 302) | func assetsJsAngular138Js() (*asset, error) {
  function assetsJsBootstrap332MinJsBytes (line 315) | func assetsJsBootstrap332MinJsBytes() ([]byte, error) {
  function assetsJsBootstrap332MinJs (line 322) | func assetsJsBootstrap332MinJs() (*asset, error) {
  function assetsJsControllersJsBytes (line 335) | func assetsJsControllersJsBytes() ([]byte, error) {
  function assetsJsControllersJs (line 342) | func assetsJsControllersJs() (*asset, error) {
  function assetsJsFilesize312MinJsBytes (line 355) | func assetsJsFilesize312MinJsBytes() ([]byte, error) {
  function assetsJsFilesize312MinJs (line 362) | func assetsJsFilesize312MinJs() (*asset, error) {
  function assetsJsIso88591_mapJsBytes (line 375) | func assetsJsIso88591_mapJsBytes() ([]byte, error) {
  function assetsJsIso88591_mapJs (line 382) | func assetsJsIso88591_mapJs() (*asset, error) {
  function assetsJsJquery1110MinJsBytes (line 395) | func assetsJsJquery1110MinJsBytes() ([]byte, error) {
  function assetsJsJquery1110MinJs (line 402) | func assetsJsJquery1110MinJs() (*asset, error) {
  function assetsJsJqueryUi1104MinJsBytes (line 415) | func assetsJsJqueryUi1104MinJsBytes() ([]byte, error) {
  function assetsJsJqueryUi1104MinJs (line 422) | func assetsJsJqueryUi1104MinJs() (*asset, error) {
  function assetsJsMoment284JsBytes (line 435) | func assetsJsMoment284JsBytes() ([]byte, error) {
  function assetsJsMoment284Js (line 442) | func assetsJsMoment284Js() (*asset, error) {
  function assetsJsPunycodeJsBytes (line 455) | func assetsJsPunycodeJsBytes() ([]byte, error) {
  function assetsJsPunycodeJs (line 462) | func assetsJsPunycodeJs() (*asset, error) {
  function assetsJsSjis_mapJsBytes (line 475) | func assetsJsSjis_mapJsBytes() ([]byte, error) {
  function assetsJsSjis_mapJs (line 482) | func assetsJsSjis_mapJs() (*asset, error) {
  function assetsJsStrutilJsBytes (line 495) | func assetsJsStrutilJsBytes() ([]byte, error) {
  function assetsJsStrutilJs (line 502) | func assetsJsStrutilJs() (*asset, error) {
  function assetsTemplatesIndexHtmlBytes (line 515) | func assetsTemplatesIndexHtmlBytes() ([]byte, error) {
  function assetsTemplatesIndexHtml (line 522) | func assetsTemplatesIndexHtml() (*asset, error) {
  function assetsTemplatesLayoutHtmlBytes (line 535) | func assetsTemplatesLayoutHtmlBytes() ([]byte, error) {
  function assetsTemplatesLayoutHtml (line 542) | func assetsTemplatesLayoutHtml() (*asset, error) {
  function Asset (line 556) | func Asset(name string) ([]byte, error) {
  function MustAsset (line 570) | func MustAsset(name string) []byte {
  function AssetInfo (line 582) | func AssetInfo(name string) (os.FileInfo, error) {
  function AssetNames (line 595) | func AssetNames() []string {
  function AssetDir (line 643) | func AssetDir(name string) ([]string, error) {
  type bintree (line 665) | type bintree struct
  function RestoreAsset (line 709) | func RestoreAsset(dir, name string) error {
  function RestoreAssets (line 734) | func RestoreAssets(dir, name string) error {
  function _filePath (line 750) | func _filePath(dir, name string) string {

FILE: vendor/github.com/mailhog/MailHog-UI/config/config.go
  function DefaultConfig (line 9) | func DefaultConfig() *Config {
  type Config (line 17) | type Config struct
  function Configure (line 25) | func Configure() *Config {
  function RegisterFlags (line 29) | func RegisterFlags() {

FILE: vendor/github.com/mailhog/MailHog-UI/main.go
  function configure (line 22) | func configure() {
  function main (line 32) | func main() {

FILE: vendor/github.com/mailhog/MailHog-UI/web/web.go
  type Web (line 19) | type Web struct
    method Static (line 45) | func (web Web) Static(pattern string) func(http.ResponseWriter, *http....
    method Index (line 61) | func (web Web) Index() func(http.ResponseWriter, *http.Request) {
  function CreateWeb (line 24) | func CreateWeb(cfg *config.Config, r http.Handler, asset func(string) ([...

FILE: vendor/github.com/mailhog/data/message.go
  function logf (line 18) | func logf(message string, args ...interface{}) {
  type MessageID (line 27) | type MessageID
  function NewMessageID (line 30) | func NewMessageID(hostname string) (MessageID, error) {
  type Messages (line 47) | type Messages
  type Message (line 50) | type Message struct
    method Bytes (line 200) | func (m *Message) Bytes() io.Reader {
  type Path (line 61) | type Path struct
  type Content (line 69) | type Content struct
    method IsMIME (line 216) | func (content *Content) IsMIME() bool {
    method ParseMIMEBody (line 225) | func (content *Content) ParseMIMEBody() *MIMEBody {
  type SMTPMessage (line 77) | type SMTPMessage struct
    method Parse (line 90) | func (m *SMTPMessage) Parse(hostname string) *Message {
    method Bytes (line 151) | func (m *SMTPMessage) Bytes() io.Reader {
  type MIMEBody (line 85) | type MIMEBody struct
  function FromBytes (line 166) | func FromBytes(b []byte) *SMTPMessage {
  function PathFromString (line 258) | func PathFromString(path string) *Path {
  function ContentFromString (line 284) | func ContentFromString(data string) *Content {
  function extractBoundary (line 324) | func extractBoundary(contentType string) string {

FILE: vendor/github.com/mailhog/http/server.go
  function AuthFile (line 21) | func AuthFile(file string) {
  function BasicAuthHandler (line 79) | func BasicAuthHandler(h http.Handler) http.Handler {
  function Listen (line 99) | func Listen(httpBindAddr string, Asset func(string) ([]byte, error), exi...

FILE: vendor/github.com/mailhog/mhsendmail/cmd/cmd.go
  function Go (line 17) | func Go() {

FILE: vendor/github.com/mailhog/smtp/protocol.go
  type Command (line 16) | type Command struct
  function ParseCommand (line 23) | func ParseCommand(line string) *Command {
  type Protocol (line 36) | type Protocol struct
    method resetState (line 114) | func (proto *Protocol) resetState() {
    method logf (line 118) | func (proto *Protocol) logf(message string, args ...interface{}) {
    method Start (line 131) | func (proto *Protocol) Start() *Reply {
    method Parse (line 142) | func (proto *Protocol) Parse(line string) (string, *Reply) {
    method ProcessData (line 170) | func (proto *Protocol) ProcessData(line string) (reply *Reply) {
    method ProcessCommand (line 199) | func (proto *Protocol) ProcessCommand(line string) (reply *Reply) {
    method Command (line 213) | func (proto *Protocol) Command(command *Command) (reply *Reply) {
    method HELO (line 411) | func (proto *Protocol) HELO(args string) (reply *Reply) {
    method EHLO (line 419) | func (proto *Protocol) EHLO(args string) (reply *Reply) {
    method STARTTLS (line 441) | func (proto *Protocol) STARTTLS(args string) (reply *Reply) {
    method ParseMAIL (line 475) | func (proto *Protocol) ParseMAIL(mail string) (string, error) {
    method ParseRCPT (line 493) | func (proto *Protocol) ParseRCPT(rcpt string) (string, error) {
  function NewProtocol (line 102) | func NewProtocol() *Protocol {

FILE: vendor/github.com/mailhog/smtp/reply.go
  type Reply (line 8) | type Reply struct
    method Lines (line 15) | func (r Reply) Lines() []string {
  function ReplyIdent (line 38) | func ReplyIdent(ident string) *Reply { return &Reply{220, []string{ident...
  function ReplyReadyToStartTLS (line 41) | func ReplyReadyToStartTLS(callback func()) *Reply {
  function ReplyBye (line 46) | func ReplyBye() *Reply { return &Reply{221, []string{"Bye"}, nil} }
  function ReplyAuthOk (line 49) | func ReplyAuthOk() *Reply { return &Reply{235, []string{"Authentication ...
  function ReplyOk (line 52) | func ReplyOk(message ...string) *Reply {
  function ReplySenderOk (line 60) | func ReplySenderOk(sender string) *Reply {
  function ReplyRecipientOk (line 65) | func ReplyRecipientOk(recipient string) *Reply {
  function ReplyAuthResponse (line 70) | func ReplyAuthResponse(response string) *Reply { return &Reply{334, []st...
  function ReplyDataResponse (line 73) | func ReplyDataResponse() *Reply { return &Reply{354, []string{"End data ...
  function ReplyStorageFailed (line 76) | func ReplyStorageFailed(reason string) *Reply { return &Reply{452, []str...
  function ReplyUnrecognisedCommand (line 79) | func ReplyUnrecognisedCommand() *Reply { return &Reply{500, []string{"Un...
  function ReplyLineTooLong (line 82) | func ReplyLineTooLong() *Reply { return &Reply{500, []string{"Line too l...
  function ReplySyntaxError (line 85) | func ReplySyntaxError(response string) *Reply {
  function ReplyUnsupportedAuth (line 93) | func ReplyUnsupportedAuth() *Reply {
  function ReplyMustIssueSTARTTLSFirst (line 98) | func ReplyMustIssueSTARTTLSFirst() *Reply {
  function ReplyInvalidAuth (line 103) | func ReplyInvalidAuth() *Reply {
  function ReplyError (line 108) | func ReplyError(err error) *Reply { return &Reply{550, []string{err.Erro...
  function ReplyTooManyRecipients (line 111) | func ReplyTooManyRecipients() *Reply { return &Reply{552, []string{"Too ...

FILE: vendor/github.com/mailhog/smtp/state.go
  type State (line 4) | type State
  constant INVALID (line 8) | INVALID   = State(-1)
  constant ESTABLISH (line 9) | ESTABLISH = State(iota)
  constant AUTHPLAIN (line 10) | AUTHPLAIN
  constant AUTHLOGIN (line 11) | AUTHLOGIN
  constant AUTHLOGIN2 (line 12) | AUTHLOGIN2
  constant AUTHCRAMMD5 (line 13) | AUTHCRAMMD5
  constant MAIL (line 14) | MAIL
  constant RCPT (line 15) | RCPT
  constant DATA (line 16) | DATA
  constant DONE (line 17) | DONE

FILE: vendor/github.com/mailhog/storage/maildir.go
  type Maildir (line 15) | type Maildir struct
    method Store (line 41) | func (maildir *Maildir) Store(m *data.Message) (string, error) {
    method Count (line 51) | func (maildir *Maildir) Count() int {
    method Search (line 64) | func (maildir *Maildir) Search(kind, query string, start, limit int) (...
    method List (line 127) | func (maildir *Maildir) List(start, limit int) (*data.Messages, error) {
    method DeleteOne (line 161) | func (maildir *Maildir) DeleteOne(id string) error {
    method DeleteAll (line 166) | func (maildir *Maildir) DeleteAll() error {
    method Load (line 175) | func (maildir *Maildir) Load(id string) (*data.Message, error) {
  function CreateMaildir (line 20) | func CreateMaildir(path string) *Maildir {

FILE: vendor/github.com/mailhog/storage/memory.go
  type InMemory (line 12) | type InMemory struct
    method Store (line 27) | func (memory *InMemory) Store(m *data.Message) (string, error) {
    method Count (line 36) | func (memory *InMemory) Count() int {
    method Search (line 41) | func (memory *InMemory) Search(kind, query string, start, limit int) (...
    method List (line 131) | func (memory *InMemory) List(start int, limit int) (*data.Messages, er...
    method DeleteOne (line 163) | func (memory *InMemory) DeleteOne(id string) error {
    method DeleteAll (line 185) | func (memory *InMemory) DeleteAll() error {
    method Load (line 194) | func (memory *InMemory) Load(id string) (*data.Message, error) {
  function CreateInMemory (line 19) | func CreateInMemory() *InMemory {

FILE: vendor/github.com/mailhog/storage/mongodb.go
  type MongoDB (line 11) | type MongoDB struct
    method Store (line 36) | func (mongo *MongoDB) Store(m *data.Message) (string, error) {
    method Count (line 46) | func (mongo *MongoDB) Count() int {
    method Search (line 52) | func (mongo *MongoDB) Search(kind, query string, start, limit int) (*d...
    method List (line 82) | func (mongo *MongoDB) List(start int, limit int) (*data.Messages, erro...
    method DeleteOne (line 102) | func (mongo *MongoDB) DeleteOne(id string) error {
    method DeleteAll (line 108) | func (mongo *MongoDB) DeleteAll() error {
    method Load (line 114) | func (mongo *MongoDB) Load(id string) (*data.Message, error) {
  function CreateMongoDB (line 17) | func CreateMongoDB(uri, db, coll string) *MongoDB {

FILE: vendor/github.com/mailhog/storage/storage.go
  type Storage (line 6) | type Storage interface

FILE: vendor/github.com/philhofer/fwd/reader.go
  constant DefaultReaderSize (line 41) | DefaultReaderSize = 2048
  constant minReaderSize (line 44) | minReaderSize = 16
  function NewReader (line 48) | func NewReader(r io.Reader) *Reader {
  function NewReaderSize (line 54) | func NewReaderSize(r io.Reader, n int) *Reader {
  type Reader (line 66) | type Reader struct
    method Reset (line 81) | func (r *Reader) Reset(rd io.Reader) {
    method more (line 94) | func (r *Reader) more() {
    method err (line 117) | func (r *Reader) err() (e error) {
    method noEOF (line 123) | func (r *Reader) noEOF() (e error) {
    method buffered (line 132) | func (r *Reader) buffered() int { return len(r.data) - r.n }
    method Buffered (line 135) | func (r *Reader) Buffered() int { return len(r.data) - r.n }
    method BufferSize (line 138) | func (r *Reader) BufferSize() int { return cap(r.data) }
    method Peek (line 146) | func (r *Reader) Peek(n int) ([]byte, error) {
    method Skip (line 186) | func (r *Reader) Skip(n int) (int, error) {
    method Next (line 225) | func (r *Reader) Next(n int) ([]byte, error) {
    method skipSeek (line 250) | func (r *Reader) skipSeek(n int) (int, error) {
    method Read (line 263) | func (r *Reader) Read(b []byte) (int, error) {
    method ReadFull (line 292) | func (r *Reader) ReadFull(b []byte) (int, error) {
    method ReadByte (line 318) | func (r *Reader) ReadByte() (byte, error) {
    method WriteTo (line 331) | func (r *Reader) WriteTo(w io.Writer) (int64, error) {
  function min (line 367) | func min(a int, b int) int {
  function max (line 374) | func max(a int, b int) int {

FILE: vendor/github.com/philhofer/fwd/writer.go
  constant DefaultWriterSize (line 8) | DefaultWriterSize = 2048
  constant minWriterSize (line 10) | minWriterSize = minReaderSize
  type Writer (line 14) | type Writer struct
    method Buffered (line 47) | func (w *Writer) Buffered() int { return len(w.buf) }
    method BufferSize (line 50) | func (w *Writer) BufferSize() int { return cap(w.buf) }
    method Flush (line 54) | func (w *Writer) Flush() error {
    method Write (line 79) | func (w *Writer) Write(p []byte) (int, error) {
    method WriteString (line 102) | func (w *Writer) WriteString(s string) (int, error) {
    method WriteByte (line 137) | func (w *Writer) WriteByte(b byte) error {
    method Next (line 153) | func (w *Writer) Next(n int) ([]byte, error) {
    method pushback (line 172) | func (w *Writer) pushback(n int) {
    method ReadFrom (line 177) | func (w *Writer) ReadFrom(r io.Reader) (int64, error) {
  function NewWriter (line 22) | func NewWriter(w io.Writer) *Writer {
  function NewWriterSize (line 35) | func NewWriterSize(w io.Writer, size int) *Writer {

FILE: vendor/github.com/philhofer/fwd/writer_appengine.go
  function unsafestr (line 5) | func unsafestr(s string) []byte { return []byte(s) }

FILE: vendor/github.com/philhofer/fwd/writer_unsafe.go
  function unsafestr (line 11) | func unsafestr(b string) []byte {

FILE: vendor/github.com/smartystreets/assertions/collections.go
  function ShouldContain (line 12) | func ShouldContain(actual interface{}, expected ...interface{}) string {
  function ShouldNotContain (line 30) | func ShouldNotContain(actual interface{}, expected ...interface{}) string {
  function ShouldContainKey (line 47) | func ShouldContainKey(actual interface{}, expected ...interface{}) string {
  function ShouldNotContainKey (line 66) | func ShouldNotContainKey(actual interface{}, expected ...interface{}) st...
  function mapKeys (line 83) | func mapKeys(m interface{}) ([]reflect.Value, bool) {
  function keyFound (line 90) | func keyFound(keys []reflect.Value, expectedKey interface{}) bool {
  function ShouldBeIn (line 104) | func ShouldBeIn(actual interface{}, expected ...interface{}) string {
  function shouldBeIn (line 114) | func shouldBeIn(actual interface{}, expected interface{}) string {
  function ShouldNotBeIn (line 125) | func ShouldNotBeIn(actual interface{}, expected ...interface{}) string {
  function shouldNotBeIn (line 135) | func shouldNotBeIn(actual interface{}, expected interface{}) string {
  function ShouldBeEmpty (line 145) | func ShouldBeEmpty(actual interface{}, expected ...interface{}) string {
  function ShouldNotBeEmpty (line 186) | func ShouldNotBeEmpty(actual interface{}, expected ...interface{}) string {
  function ShouldHaveLength (line 201) | func ShouldHaveLength(actual interface{}, expected ...interface{}) string {

FILE: vendor/github.com/smartystreets/assertions/doc.go
  function GoConveyMode (line 30) | func GoConveyMode(yes bool) {
  type testingT (line 38) | type testingT interface
  type Assertion (line 42) | type Assertion struct
    method Failed (line 54) | func (this *Assertion) Failed() bool {
    method So (line 59) | func (this *Assertion) So(actual interface{}, assert assertion, expect...
  function New (line 49) | func New(t testingT) *Assertion {
  function So (line 85) | func So(actual interface{}, assert assertion, expected ...interface{}) (...
  function so (line 95) | func so(actual interface{}, assert func(interface{}, ...interface{}) str...
  type assertion (line 103) | type assertion

FILE: vendor/github.com/smartystreets/assertions/equality.go
  constant defaultDelta (line 15) | defaultDelta = 0.0000000001
  function ShouldEqual (line 18) | func ShouldEqual(actual interface{}, expected ...interface{}) string {
  function shouldEqual (line 24) | func shouldEqual(actual, expected interface{}) (message string) {
  function ShouldNotEqual (line 48) | func ShouldNotEqual(actual interface{}, expected ...interface{}) string {
  function ShouldAlmostEqual (line 60) | func ShouldAlmostEqual(actual interface{}, expected ...interface{}) stri...
  function ShouldNotAlmostEqual (line 75) | func ShouldNotAlmostEqual(actual interface{}, expected ...interface{}) s...
  function cleanAlmostEqualInput (line 89) | func cleanAlmostEqualInput(actual interface{}, expected ...interface{}) ...
  function getFloat (line 122) | func getFloat(num interface{}) (float64, error) {
  function ShouldResemble (line 147) | func ShouldResemble(actual interface{}, expected ...interface{}) string {
  function ShouldNotResemble (line 161) | func ShouldNotResemble(actual interface{}, expected ...interface{}) stri...
  function ShouldPointTo (line 171) | func ShouldPointTo(actual interface{}, expected ...interface{}) string {
  function shouldPointTo (line 178) | func shouldPointTo(actual, expected interface{}) string {
  function ShouldNotPointTo (line 201) | func ShouldNotPointTo(actual interface{}, expected ...interface{}) string {
  function ShouldBeNil (line 215) | func ShouldBeNil(actual interface{}, expected ...interface{}) string {
  function interfaceHasNilValue (line 225) | func interfaceHasNilValue(actual interface{}) bool {
  function ShouldNotBeNil (line 240) | func ShouldNotBeNil(actual interface{}, expected ...interface{}) string {
  function ShouldBeTrue (line 250) | func ShouldBeTrue(actual interface{}, expected ...interface{}) string {
  function ShouldBeFalse (line 260) | func ShouldBeFalse(actual interface{}, expected ...interface{}) string {
  function ShouldBeZeroValue (line 271) | func ShouldBeZeroValue(actual interface{}, expected ...interface{}) stri...

FILE: vendor/github.com/smartystreets/assertions/filter.go
  constant success (line 6) | success                = ""
  constant needExactValues (line 7) | needExactValues        = "This assertion requires exactly %d comparison ...
  constant needNonEmptyCollection (line 8) | needNonEmptyCollection = "This assertion requires at least 1 comparison ...
  function need (line 11) | func need(needed int, expected []interface{}) string {
  function atLeast (line 18) | func atLeast(minimum int, expected []interface{}) string {

FILE: vendor/github.com/smartystreets/assertions/internal/go-render/render/render.go
  function init (line 37) | func init() {
  function Render (line 51) | func Render(v interface{}) string {
  type traverseState (line 70) | type traverseState struct
    method forkFor (line 75) | func (s *traverseState) forkFor(ptr uintptr) *traverseState {
    method render (line 89) | func (s *traverseState) render(buf *bytes.Buffer, ptrs int, v reflect....
  function writeType (line 267) | func writeType(buf *bytes.Buffer, ptrs int, t reflect.Type) {
  type cmpFn (line 333) | type cmpFn
  type sortableValueSlice (line 335) | type sortableValueSlice struct
    method Len (line 340) | func (s sortableValueSlice) Len() int {
    method Less (line 344) | func (s sortableValueSlice) Less(i, j int) bool {
    method Swap (line 348) | func (s sortableValueSlice) Swap(i, j int) {
  function cmpForType (line 354) | func cmpForType(t reflect.Type) cmpFn {
  function tryAndSortMapKeys (line 473) | func tryAndSortMapKeys(mt reflect.Type, k []reflect.Value) {

FILE: vendor/github.com/smartystreets/assertions/internal/oglematchers/any_of.go
  function AnyOf (line 41) | func AnyOf(vals ...interface{}) Matcher {
  type anyOfMatcher (line 61) | type anyOfMatcher struct
    method Description (line 65) | func (m *anyOfMatcher) Description() string {
    method Matches (line 74) | func (m *anyOfMatcher) Matches(c interface{}) (err error) {

FILE: vendor/github.com/smartystreets/assertions/internal/oglematchers/contains.go
  function Contains (line 26) | func Contains(x interface{}) Matcher {
  type containsMatcher (line 37) | type containsMatcher struct
    method Description (line 41) | func (m *containsMatcher) Description() string {
    method Matches (line 45) | func (m *containsMatcher) Matches(candidate interface{}) error {

FILE: vendor/github.com/smartystreets/assertions/internal/oglematchers/deep_equals.go
  function DeepEquals (line 30) | func DeepEquals(x interface{}) Matcher {
  type deepEqualsMatcher (line 34) | type deepEqualsMatcher struct
    method Description (line 38) | func (m *deepEqualsMatcher) Description() string {
    method Matches (line 52) | func (m *deepEqualsMatcher) Matches(c interface{}) error {

FILE: vendor/github.com/smartystreets/assertions/internal/oglematchers/equals.go
  function Equals (line 58) | func Equals(x interface{}) Matcher {
  type equalsMatcher (line 74) | type equalsMatcher struct
    method Matches (line 476) | func (m *equalsMatcher) Matches(candidate interface{}) error {
    method Description (line 534) | func (m *equalsMatcher) Description() string {
  function isSignedInteger (line 82) | func isSignedInteger(v reflect.Value) bool {
  function isUnsignedInteger (line 87) | func isUnsignedInteger(v reflect.Value) bool {
  function isInteger (line 92) | func isInteger(v reflect.Value) bool {
  function isFloat (line 96) | func isFloat(v reflect.Value) bool {
  function isComplex (line 101) | func isComplex(v reflect.Value) bool {
  function checkAgainstInt64 (line 106) | func checkAgainstInt64(e int64, c reflect.Value) (err error) {
  function checkAgainstUint64 (line 133) | func checkAgainstUint64(e uint64, c reflect.Value) (err error) {
  function checkAgainstFloat32 (line 160) | func checkAgainstFloat32(e float32, c reflect.Value) (err error) {
  function checkAgainstFloat64 (line 199) | func checkAgainstFloat64(e float64, c reflect.Value) (err error) {
  function checkAgainstComplex64 (line 243) | func checkAgainstComplex64(e complex64, c reflect.Value) (err error) {
  function checkAgainstComplex128 (line 272) | func checkAgainstComplex128(e complex128, c reflect.Value) (err error) {
  function checkAgainstBool (line 303) | func checkAgainstBool(e bool, c reflect.Value) (err error) {
  function checkAgainstChan (line 316) | func checkAgainstChan(e reflect.Value, c reflect.Value) (err error) {
  function checkAgainstFunc (line 335) | func checkAgainstFunc(e reflect.Value, c reflect.Value) (err error) {
  function checkAgainstMap (line 349) | func checkAgainstMap(e reflect.Value, c reflect.Value) (err error) {
  function checkAgainstPtr (line 363) | func checkAgainstPtr(e reflect.Value, c reflect.Value) (err error) {
  function checkAgainstSlice (line 381) | func checkAgainstSlice(e reflect.Value, c reflect.Value) (err error) {
  function checkAgainstString (line 399) | func checkAgainstString(e reflect.Value, c reflect.Value) (err error) {
  function checkAgainstArray (line 413) | func checkAgainstArray(e reflect.Value, c reflect.Value) (err error) {
  function checkAgainstUnsafePointer (line 432) | func checkAgainstUnsafePointer(e reflect.Value, c reflect.Value) (err er...
  function checkForNil (line 446) | func checkForNil(c reflect.Value) (err error) {

FILE: vendor/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal.go
  function GreaterOrEqual (line 30) | func GreaterOrEqual(x interface{}) Matcher {

FILE: vendor/github.com/smartystreets/assertions/internal/oglematchers/greater_than.go
  function GreaterThan (line 30) | func GreaterThan(x interface{}) Matcher {

FILE: vendor/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal.go
  function LessOrEqual (line 30) | func LessOrEqual(x interface{}) Matcher {

FILE: vendor/github.com/smartystreets/assertions/internal/oglematchers/less_than.go
  function LessThan (line 31) | func LessThan(x interface{}) Matcher {
  type lessThanMatcher (line 47) | type lessThanMatcher struct
    method Description (line 51) | func (m *lessThanMatcher) Description() string {
    method Matches (line 107) | func (m *lessThanMatcher) Matches(c interface{}) (err error) {
  function compareIntegers (line 60) | func compareIntegers(v1, v2 reflect.Value) (err error) {
  function getFloat (line 92) | func getFloat(v reflect.Value) float64 {

FILE: vendor/github.com/smartystreets/assertions/internal/oglematchers/matcher.go
  type Matcher (line 33) | type Matcher interface
  type FatalError (line 75) | type FatalError struct
    method Error (line 84) | func (e *FatalError) Error() string {
  function NewFatalError (line 80) | func NewFatalError(s string) *FatalError {

FILE: vendor/github.com/smartystreets/assertions/internal/oglematchers/not.go
  function Not (line 26) | func Not(m Matcher) Matcher {
  type notMatcher (line 30) | type notMatcher struct
    method Matches (line 34) | func (m *notMatcher) Matches(c interface{}) (err error) {
    method Description (line 51) | func (m *notMatcher) Description() string {

FILE: vendor/github.com/smartystreets/assertions/internal/oglematchers/transform_description.go
  function transformDescription (line 21) | func transformDescription(m Matcher, newDesc string) Matcher {
  type transformDescriptionMatcher (line 25) | type transformDescriptionMatcher struct
    method Description (line 30) | func (m *transformDescriptionMatcher) Description() string {
    method Matches (line 34) | func (m *transformDescriptionMatcher) Matches(c interface{}) error {

FILE: vendor/github.com/smartystreets/assertions/messages.go
  constant shouldHaveBeenEqual (line 4) | shouldHaveBeenEqual             = "Expected: '%v'\nActual:   '%v'\n(Shou...
  constant shouldNotHaveBeenEqual (line 5) | shouldNotHaveBeenEqual          = "Expected     '%v'\nto NOT equal '%v'\...
  constant shouldHaveBeenEqualTypeMismatch (line 6) | shouldHaveBeenEqualTypeMismatch = "Expected: '%v' (%T)\nActual:   '%v' (...
  constant shouldHaveBeenAlmostEqual (line 7) | shouldHaveBeenAlmostEqual       = "Expected '%v' to almost equal '%v' (b...
  constant shouldHaveNotBeenAlmostEqual (line 8) | shouldHaveNotBeenAlmostEqual    = "Expected '%v' to NOT almost equal '%v...
  constant shouldHaveResembled (line 9) | shouldHaveResembled             = "Expected: '%s'\nActual:   '%s'\n(Shou...
  constant shouldNotHaveResembled (line 10) | shouldNotHaveResembled          = "Expected        '%#v'\nto NOT resembl...
  constant shouldBePointers (line 11) | shouldBePointers                = "Both arguments should be pointers "
  constant shouldHaveBeenNonNilPointer (line 12) | shouldHaveBeenNonNilPointer     = shouldBePointers + "(the %s was %s)!"
  constant shouldHavePointedTo (line 13) | shouldHavePointedTo             = "Expected '%+v' (address: '%v') and '%...
  constant shouldNotHavePointedTo (line 14) | shouldNotHavePointedTo          = "Expected '%+v' and '%+v' to be differ...
  constant shouldHaveBeenNil (line 15) | shouldHaveBeenNil               = "Expected: nil\nActual:   '%v'"
  constant shouldNotHaveBeenNil (line 16) | shouldNotHaveBeenNil            = "Expected '%+v' to NOT be nil (but it ...
  constant shouldHaveBeenTrue (line 17) | shouldHaveBeenTrue              = "Expected: true\nActual:   %v"
  constant shouldHaveBeenFalse (line 18) | shouldHaveBeenFalse             = "Expected: false\nActual:   %v"
  constant shouldHaveBeenZeroValue (line 19) | shouldHaveBeenZeroValue         = "'%+v' should have been the zero value"
  constant shouldHaveBeenGreater (line 23) | shouldHaveBeenGreater            = "Expected '%v' to be greater than '%v...
  constant shouldHaveBeenGreaterOrEqual (line 24) | shouldHaveBeenGreaterOrEqual     = "Expected '%v' to be greater than or ...
  constant shouldHaveBeenLess (line 25) | shouldHaveBeenLess               = "Expected '%v' to be less than '%v' (...
  constant shouldHaveBeenLessOrEqual (line 26) | shouldHaveBeenLessOrEqual        = "Expected '%v' to be less than or equ...
  constant shouldHaveBeenBetween (line 27) | shouldHaveBeenBetween            = "Expected '%v' to be between '%v' and...
  constant shouldNotHaveBeenBetween (line 28) | shouldNotHaveBeenBetween         = "Expected '%v' NOT to be between '%v'...
  constant shouldHaveDifferentUpperAndLower (line 29) | shouldHaveDifferentUpperAndLower = "The lower and upper bounds must be d...
  constant shouldHaveBeenBetweenOrEqual (line 30) | shouldHaveBeenBetweenOrEqual     = "Expected '%v' to be between '%v' and...
  constant shouldNotHaveBeenBetweenOrEqual (line 31) | shouldNotHaveBeenBetweenOrEqual  = "Expected '%v' NOT to be between '%v'...
  constant shouldHaveContained (line 35) | shouldHaveContained            = "Expected the container (%v) to contain...
  constant shouldNotHaveContained (line 36) | shouldNotHaveContained         = "Expected the container (%v) NOT to con...
  constant shouldHaveContainedKey (line 37) | shouldHaveContainedKey         = "Expected the %v to contain the key: %v...
  constant shouldNotHaveContainedKey (line 38) | shouldNotHaveContainedKey      = "Expected the %v NOT to contain the key...
  constant shouldHaveBeenIn (line 39) | shouldHaveBeenIn               = "Expected '%v' to be in the container (...
  constant shouldNotHaveBeenIn (line 40) | shouldNotHaveBeenIn            = "Expected '%v' NOT to be in the contain...
  constant shouldHaveBeenAValidCollection (line 41) | shouldHaveBeenAValidCollection = "You must provide a valid container (wa...
  constant shouldHaveBeenAValidMap (line 42) | shouldHaveBeenAValidMap        = "You must provide a valid map type (was...
  constant shouldHaveBeenEmpty (line 43) | shouldHaveBeenEmpty            = "Expected %+v to be empty (but it wasn'...
  constant shouldNotHaveBeenEmpty (line 44) | shouldNotHaveBeenEmpty         = "Expected %+v to NOT be empty (but it w...
  constant shouldHaveBeenAValidInteger (line 45) | shouldHaveBeenAValidInteger    = "You must provide a valid integer (was ...
  constant shouldHaveBeenAValidLength (line 46) | shouldHaveBeenAValidLength     = "You must provide a valid positive inte...
  constant shouldHaveHadLength (line 47) | shouldHaveHadLength            = "Expected %+v (length: %v) to have leng...
  constant shouldHaveStartedWith (line 51) | shouldHaveStartedWith           = "Expected      '%v'\nto start with '%v...
  constant shouldNotHaveStartedWith (line 52) | shouldNotHaveStartedWith        = "Expected          '%v'\nNOT to start ...
  constant shouldHaveEndedWith (line 53) | shouldHaveEndedWith             = "Expected    '%v'\nto end with '%v'\n(...
  constant shouldNotHaveEndedWith (line 54) | shouldNotHaveEndedWith          = "Expected        '%v'\nNOT to end with...
  constant shouldAllBeStrings (line 55) | shouldAllBeStrings              = "All arguments to this assertion must ...
  constant shouldBothBeStrings (line 56) | shouldBothBeStrings             = "Both arguments to this assertion must...
  constant shouldBeString (line 57) | shouldBeString                  = "The argument to this assertion must b...
  constant shouldHaveContainedSubstring (line 58) | shouldHaveContainedSubstring    = "Expected '%s' to contain substring '%...
  constant shouldNotHaveContainedSubstring (line 59) | shouldNotHaveContainedSubstring = "Expected '%s' NOT to contain substrin...
  constant shouldHaveBeenBlank (line 60) | shouldHaveBeenBlank             = "Expected '%s' to be blank (but it was...
  constant shouldNotHaveBeenBlank (line 61) | shouldNotHaveBeenBlank          = "Expected value to NOT be blank (but i...
  constant shouldUseVoidNiladicFunction (line 65) | shouldUseVoidNiladicFunction = "You must provide a void, niladic functio...
  constant shouldHavePanickedWith (line 66) | shouldHavePanickedWith       = "Expected func() to panic with '%v' (but ...
  constant shouldHavePanicked (line 67) | shouldHavePanicked           = "Expected func() to panic (but it didn't)!"
  constant shouldNotHavePanicked (line 68) | shouldNotHavePanicked        = "Expected func() NOT to panic (error: '%+...
  constant shouldNotHavePanickedWith (line 69) | shouldNotHavePanickedWith    = "Expected func() NOT to panic with '%v' (...
  constant shouldHaveBeenA (line 73) | shouldHaveBeenA    = "Expected '%v' to be: '%v' (but was: '%v')!"
  constant shouldNotHaveBeenA (line 74) | shouldNotHaveBeenA = "Expected '%v' to NOT be: '%v' (but it was)!"
  constant shouldHaveImplemented (line 76) | shouldHaveImplemented             = "Expected: '%v interface support'\nA...
  constant shouldNotHaveImplemented (line 77) | shouldNotHaveImplemented          = "Expected         '%v'\nto NOT imple...
  constant shouldCompareWithInterfacePointer (line 78) | shouldCompareWithInterfacePointer = "The expected value must be a pointe...
  constant shouldNotBeNilActual (line 79) | shouldNotBeNilActual              = "The actual value was 'nil' and shou...
  constant shouldUseTimes (line 83) | shouldUseTimes                   = "You must provide time instances as a...
  constant shouldUseTimeSlice (line 84) | shouldUseTimeSlice               = "You must provide a slice of time ins...
  constant shouldUseDurationAndTime (line 85) | shouldUseDurationAndTime         = "You must provide a duration and a ti...
  constant shouldHaveHappenedBefore (line 86) | shouldHaveHappenedBefore         = "Expected '%v' to happen before '%v' ...
  constant shouldHaveHappenedAfter (line 87) | shouldHaveHappenedAfter          = "Expected '%v' to happen after '%v' (...
  constant shouldHaveHappenedBetween (line 88) | shouldHaveHappenedBetween        = "Expected '%v' to happen between '%v'...
  constant shouldNotHaveHappenedOnOrBetween (line 89) | shouldNotHaveHappenedOnOrBetween = "Expected '%v' to NOT happen on or be...
  constant shouldHaveBeenChronological (line 92) | shouldHaveBeenChronological = "The 'Time' at index [%d] should have happ...

FILE: vendor/github.com/smartystreets/assertions/panic.go
  function ShouldPanic (line 6) | func ShouldPanic(actual interface{}, expected ...interface{}) (message s...
  function ShouldNotPanic (line 32) | func ShouldNotPanic(actual interface{}, expected ...interface{}) (messag...
  function ShouldPanicWith (line 58) | func ShouldPanicWith(actual interface{}, expected ...interface{}) (messa...
  function ShouldNotPanicWith (line 88) | func ShouldNotPanicWith(actual interface{}, expected ...interface{}) (me...

FILE: vendor/github.com/smartystreets/assertions/quantity.go
  function ShouldBeGreaterThan (line 10) | func ShouldBeGreaterThan(actual interface{}, expected ...interface{}) st...
  function ShouldBeGreaterThanOrEqualTo (line 22) | func ShouldBeGreaterThanOrEqualTo(actual interface{}, expected ...interf...
  function ShouldBeLessThan (line 32) | func ShouldBeLessThan(actual interface{}, expected ...interface{}) string {
  function ShouldBeLessThanOrEqualTo (line 42) | func ShouldBeLessThanOrEqualTo(actual interface{}, expected ...interface...
  function ShouldBeBetween (line 53) | func ShouldBeBetween(actual interface{}, expected ...interface{}) string {
  function ShouldNotBeBetween (line 69) | func ShouldNotBeBetween(actual interface{}, expected ...interface{}) str...
  function deriveBounds (line 82) | func deriveBounds(values []interface{}) (lower interface{}, upper interf...
  function isBetween (line 93) | func isBetween(value, lower, upper interface{}) bool {
  function ShouldBeBetweenOrEqual (line 104) | func ShouldBeBetweenOrEqual(actual interface{}, expected ...interface{})...
  function ShouldNotBeBetweenOrEqual (line 120) | func ShouldNotBeBetweenOrEqual(actual interface{}, expected ...interface...
  function isBetweenOrEqual (line 134) | func isBetweenOrEqual(value, lower, upper interface{}) bool {

FILE: vendor/github.com/smartystreets/assertions/serializer.go
  type Serializer (line 10) | type Serializer interface
  type failureSerializer (line 15) | type failureSerializer struct
    method serializeDetailed (line 17) | func (self *failureSerializer) serializeDetailed(expected, actual inte...
    method serialize (line 30) | func (self *failureSerializer) serialize(expected, actual interface{},...
  function newSerializer (line 43) | func newSerializer() *failureSerializer {
  type FailureView (line 51) | type FailureView struct
  type noopSerializer (line 62) | type noopSerializer struct
    method serialize (line 64) | func (self *noopSerializer) serialize(expected, actual interface{}, me...
    method serializeDetailed (line 67) | func (self *noopSerializer) serializeDetailed(expected, actual interfa...

FILE: vendor/github.com/smartystreets/assertions/strings.go
  function ShouldStartWith (line 10) | func ShouldStartWith(actual interface{}, expected ...interface{}) string {
  function shouldStartWith (line 24) | func shouldStartWith(value, prefix string) string {
  function ShouldNotStartWith (line 36) | func ShouldNotStartWith(actual interface{}, expected ...interface{}) str...
  function shouldNotStartWith (line 50) | func shouldNotStartWith(value, prefix string) string {
  function ShouldEndWith (line 64) | func ShouldEndWith(actual interface{}, expected ...interface{}) string {
  function shouldEndWith (line 78) | func shouldEndWith(value, suffix string) string {
  function ShouldNotEndWith (line 90) | func ShouldNotEndWith(actual interface{}, expected ...interface{}) string {
  function shouldNotEndWith (line 104) | func shouldNotEndWith(value, suffix string) string {
  function ShouldContainSubstring (line 118) | func ShouldContainSubstring(actual interface{}, expected ...interface{})...
  function ShouldNotContainSubstring (line 137) | func ShouldNotContainSubstring(actual interface{}, expected ...interface...
  function ShouldBeBlank (line 156) | func ShouldBeBlank(actual interface{}, expected ...interface{}) string {
  function ShouldNotBeBlank (line 171) | func ShouldNotBeBlank(actual interface{}, expected ...interface{}) string {
  function ShouldEqualWithout (line 187) | func ShouldEqualWithout(actual interface{}, expected ...interface{}) str...
  function ShouldEqualTrimSpace (line 213) | func ShouldEqualTrimSpace(actual interface{}, expected ...interface{}) s...

FILE: vendor/github.com/smartystreets/assertions/time.go
  function ShouldHappenBefore (line 9) | func ShouldHappenBefore(actual interface{}, expected ...interface{}) str...
  function ShouldHappenOnOrBefore (line 28) | func ShouldHappenOnOrBefore(actual interface{}, expected ...interface{})...
  function ShouldHappenAfter (line 46) | func ShouldHappenAfter(actual interface{}, expected ...interface{}) stri...
  function ShouldHappenOnOrAfter (line 63) | func ShouldHappenOnOrAfter(actual interface{}, expected ...interface{}) ...
  function ShouldHappenBetween (line 80) | func ShouldHappenBetween(actual interface{}, expected ...interface{}) st...
  function ShouldHappenOnOrBetween (line 102) | func ShouldHappenOnOrBetween(actual interface{}, expected ...interface{}...
  function ShouldNotHappenOnOrBetween (line 121) | func ShouldNotHappenOnOrBetween(actual interface{}, expected ...interfac...
  function ShouldHappenWithin (line 144) | func ShouldHappenWithin(actual interface{}, expected ...interface{}) str...
  function ShouldNotHappenWithin (line 164) | func ShouldNotHappenWithin(actual interface{}, expected ...interface{}) ...
  function ShouldBeChronological (line 183) | func ShouldBeChronological(actual interface{}, expected ...interface{}) ...

FILE: vendor/github.com/smartystreets/assertions/type.go
  function ShouldHaveSameTypeAs (line 9) | func ShouldHaveSameTypeAs(actual interface{}, expected ...interface{}) s...
  function ShouldNotHaveSameTypeAs (line 24) | func ShouldNotHaveSameTypeAs(actual interface{}, expected ...interface{}...
  function ShouldImplement (line 40) | func ShouldImplement(actual interface{}, expectedList ...interface{}) st...
  function ShouldNotImplement (line 80) | func ShouldNotImplement(actual interface{}, expectedList ...interface{})...

FILE: vendor/github.com/smartystreets/goconvey/convey/context.go
  type conveyErr (line 10) | type conveyErr struct
    method Error (line 15) | func (e *conveyErr) Error() string {
  function conveyPanic (line 19) | func conveyPanic(fmt string, params ...interface{}) {
  constant missingGoTest (line 24) | missingGoTest = `Top-level calls to Convey(...) need a reference to the ...
  constant extraGoTest (line 26) | extraGoTest    = `Only the top-level call to Convey(...) needs a referen...
  constant noStackContext (line 27) | noStackContext = "Convey operation made without context on goroutine sta...
  constant differentConveySituations (line 29) | differentConveySituations = "Different set of Convey statements on subse...
  constant multipleIdenticalConvey (line 30) | multipleIdenticalConvey   = "Multiple convey suites with identical names...
  constant failureHalt (line 34) | failureHalt = "___FAILURE_HALT___"
  constant nodeKey (line 36) | nodeKey = "node"
  function getCurrentContext (line 41) | func getCurrentContext() *context {
  function mustGetCurrentContext (line 49) | func mustGetCurrentContext() *context {
  type context (line 69) | type context struct
    method SkipConvey (line 118) | func (ctx *context) SkipConvey(items ...interface{}) {
    method FocusConvey (line 122) | func (ctx *context) FocusConvey(items ...interface{}) {
    method Convey (line 126) | func (ctx *context) Convey(items ...interface{}) {
    method SkipSo (line 168) | func (ctx *context) SkipSo(stuff ...interface{}) {
    method So (line 172) | func (ctx *context) So(actual interface{}, assert assertion, expected ...
    method Reset (line 180) | func (ctx *context) Reset(action func()) {
    method Print (line 185) | func (ctx *context) Print(items ...interface{}) (int, error) {
    method Println (line 190) | func (ctx *context) Println(items ...interface{}) (int, error) {
    method Printf (line 195) | func (ctx *context) Printf(format string, items ...interface{}) (int, ...
    method shouldVisit (line 205) | func (c *context) shouldVisit() bool {
    method conveyInner (line 212) | func (ctx *context) conveyInner(situation string, f func(C)) {
    method assertionReport (line 267) | func (ctx *context) assertionReport(r *reporting.AssertionResult) {
  function rootConvey (line 87) | func rootConvey(items ...interface{}) {

FILE: vendor/github.com/smartystreets/goconvey/convey/discovery.go
  type actionSpecifier (line 3) | type actionSpecifier
  constant noSpecifier (line 6) | noSpecifier actionSpecifier = iota
  constant skipConvey (line 7) | skipConvey
  constant focusConvey (line 8) | focusConvey
  type suite (line 11) | type suite struct
  function newSuite (line 19) | func newSuite(situation string, failureMode FailureMode, f func(C), test...
  function discover (line 35) | func discover(items []interface{}) *suite {
  function item (line 48) | func item(items []interface{}) interface{} {
  function parseName (line 54) | func parseName(items []interface{}) (string, []interface{}) {
  function parseGoTest (line 61) | func parseGoTest(items []interface{}) (t, []interface{}) {
  function parseFailureMode (line 67) | func parseFailureMode(items []interface{}) (FailureMode, []interface{}) {
  function parseAction (line 73) | func parseAction(items []interface{}) (func(C), []interface{}) {
  function parseSpecifier (line 85) | func parseSpecifier(items []interface{}) (actionSpecifier, []interface{}) {
  type t (line 99) | type t interface
  constant parseError (line 103) | parseError = "You must provide a name (string), then a *testing.T (if in...

FILE: vendor/github.com/smartystreets/goconvey/convey/doc.go
  type C (line 21) | type C interface
  function Convey (line 73) | func Convey(items ...interface{}) {
  function SkipConvey (line 84) | func SkipConvey(items ...interface{}) {
  function FocusConvey (line 95) | func FocusConvey(items ...interface{}) {
  function Reset (line 101) | func Reset(action func()) {
  type assertion (line 111) | type assertion
  constant assertionSuccess (line 113) | assertionSuccess = ""
  function So (line 124) | func So(actual interface{}, assert assertion, expected ...interface{}) {
  function SkipSo (line 130) | func SkipSo(stuff ...interface{}) {
  type FailureMode (line 136) | type FailureMode
    method combine (line 156) | func (f FailureMode) combine(other FailureMode) FailureMode {
  constant FailureContinues (line 143) | FailureContinues FailureMode = "continue"
  constant FailureHalts (line 148) | FailureHalts FailureMode = "halt"
  constant FailureInherits (line 153) | FailureInherits FailureMode = "inherits"
  function SetDefaultFailureMode (line 169) | func SetDefaultFailureMode(mode FailureMode) {
  function Print (line 181) | func Print(items ...interface{}) (written int, err error) {
  function Println (line 187) | func Println(items ...interface{}) (written int, err error) {
  function Printf (line 193) | func Printf(format string, items ...interface{}) (written int, err error) {
  function SuppressConsoleStatistics (line 201) | func SuppressConsoleStatistics() {
  function PrintConsoleStatistics (line 216) | func PrintConsoleStatistics() {

FILE: vendor/github.com/smartystreets/goconvey/convey/gotest/utils.go
  function ResolveExternalCaller (line 11) | func ResolveExternalCaller() (file string, line int, name string) {
  constant maxStackDepth (line 26) | maxStackDepth = 100

FILE: vendor/github.com/smartystreets/goconvey/convey/init.go
  function init (line 12) | func init() {
  function declareFlags (line 20) | func declareFlags() {
  function noStoryFlagProvided (line 32) | func noStoryFlagProvided() bool {
  function buildReporter (line 36) | func buildReporter() reporting.Reporter {
  function flagFound (line 74) | func flagFound(flagValue string) bool {

FILE: vendor/github.com/smartystreets/goconvey/convey/nilReporter.go
  type nilReporter (line 7) | type nilReporter struct
    method BeginStory (line 9) | func (self *nilReporter) BeginStory(story *reporting.StoryReport)  {}
    method Enter (line 10) | func (self *nilReporter) Enter(scope *reporting.ScopeReport)       {}
    method Report (line 11) | func (self *nilReporter) Report(report *reporting.AssertionResult) {}
    method Exit (line 12) | func (self *nilReporter) Exit()                                    {}
    method EndStory (line 13) | func (self *nilReporter) EndStory()                                {}
    method Write (line 14) | func (self *nilReporter) Write(p []byte) (int, error)              { r...
  function newNilReporter (line 15) | func newNilReporter() *nilReporter                                 { ret...

FILE: vendor/github.com/smartystreets/goconvey/convey/reporting/console.go
  type console (line 8) | type console struct
    method Write (line 10) | func (self *console) Write(p []byte) (n int, err error) {
  function NewConsole (line 14) | func NewConsole() io.Writer {

FILE: vendor/github.com/smartystreets/goconvey/convey/reporting/dot.go
  type dot (line 5) | type dot struct
    method BeginStory (line 7) | func (self *dot) BeginStory(story *StoryReport) {}
    method Enter (line 9) | func (self *dot) Enter(scope *ScopeReport) {}
    method Report (line 11) | func (self *dot) Report(report *AssertionResult) {
    method Exit (line 28) | func (self *dot) Exit() {}
    method EndStory (line 30) | func (self *dot) EndStory() {}
    method Write (line 32) | func (self *dot) Write(content []byte) (written int, err error) {
  function NewDotReporter (line 36) | func NewDotReporter(out *Printer) *dot {

FILE: vendor/github.com/smartystreets/goconvey/convey/reporting/gotest.go
  type gotestReporter (line 3) | type gotestReporter struct
    method BeginStory (line 5) | func (self *gotestReporter) BeginStory(story *StoryReport) {
    method Enter (line 9) | func (self *gotestReporter) Enter(scope *ScopeReport) {}
    method Report (line 11) | func (self *gotestReporter) Report(r *AssertionResult) {
    method Exit (line 17) | func (self *gotestReporter) Exit() {}
    method EndStory (line 19) | func (self *gotestReporter) EndStory() {
    method Write (line 23) | func (self *gotestReporter) Write(content []byte) (written int, err er...
  function NewGoTestReporter (line 27) | func NewGoTestReporter() *gotestReporter {
  function passed (line 31) | func passed(r *AssertionResult) bool {

FILE: vendor/github.com/smartystreets/goconvey/convey/reporting/init.go
  function init (line 9) | func init() {
  function BuildJsonReporter (line 19) | func BuildJsonReporter() Reporter {
  function BuildDotReporter (line 25) | func BuildDotReporter() Reporter {
  function BuildStoryReporter (line 33) | func BuildStoryReporter() Reporter {
  function BuildSilentReporter (line 41) | func BuildSilentReporter() Reporter {
  function SuppressConsoleStatistics (line 71) | func SuppressConsoleStatistics() { consoleStatistics.Suppress() }
  function PrintConsoleStatistics (line 72) | func PrintConsoleStatistics()    { consoleStatistics.PrintSummary() }
  function QuietMode (line 77) | func QuietMode() {
  function monochrome (line 81) | func monochrome() {
  function isColorableTerminal (line 85) | func isColorableTerminal() bool {
  type T (line 92) | type T interface

FILE: vendor/github.com/smartystreets/goconvey/convey/reporting/json.go
  type JsonReporter (line 12) | type JsonReporter struct
    method depth (line 20) | func (self *JsonReporter) depth() int { return len(self.currentKey) }
    method BeginStory (line 22) | func (self *JsonReporter) BeginStory(story *StoryReport) {}
    method Enter (line 24) | func (self *JsonReporter) Enter(scope *ScopeReport) {
    method Report (line 35) | func (self *JsonReporter) Report(report *AssertionResult) {
    method Exit (line 39) | func (self *JsonReporter) Exit() {
    method EndStory (line 43) | func (self *JsonReporter) EndStory() {
    method report (line 47) | func (self *JsonReporter) report() {
    method reset (line 61) | func (self *JsonReporter) reset() {
    method Write (line 67) | func (self *JsonReporter) Write(content []byte) (written int, err erro...
  function NewJsonReporter (line 72) | func NewJsonReporter(out *Printer) *JsonReporter {
  constant OpenJson (line 79) | OpenJson = ">->->OPEN-JSON->->->"
  constant CloseJson (line 80) | CloseJson = "<-<-<-CLOSE-JSON<-<-<"
  constant jsonMarshalFailure (line 81) | jsonMarshalFailure = `

FILE: vendor/github.com/smartystreets/goconvey/convey/reporting/printer.go
  type Printer (line 9) | type Printer struct
    method Println (line 14) | func (self *Printer) Println(message string, values ...interface{}) {
    method Print (line 19) | func (self *Printer) Print(message string, values ...interface{}) {
    method Insert (line 24) | func (self *Printer) Insert(text string) {
    method format (line 28) | func (self *Printer) format(message string, values ...interface{}) str...
    method Indent (line 39) | func (self *Printer) Indent() {
    method Dedent (line 43) | func (self *Printer) Dedent() {
  function NewPrinter (line 49) | func NewPrinter(out io.Writer) *Printer {
  constant space (line 55) | space = " "
  constant pad (line 56) | pad = space + space
  constant padLength (line 57) | padLength = len(pad)

FILE: vendor/github.com/smartystreets/goconvey/convey/reporting/problems.go
  type problem (line 5) | type problem struct
    method BeginStory (line 12) | func (self *problem) BeginStory(story *StoryReport) {}
    method Enter (line 14) | func (self *problem) Enter(scope *ScopeReport) {}
    method Report (line 16) | func (self *problem) Report(report *AssertionResult) {
    method Exit (line 24) | func (self *problem) Exit() {}
    method EndStory (line 26) | func (self *problem) EndStory() {
    method show (line 31) | func (self *problem) show(display func(), color string) {
    method showErrors (line 41) | func (self *problem) showErrors() {
    method showFailures (line 50) | func (self *problem) showFailures() {
    method Write (line 60) | func (self *problem) Write(content []byte) (written int, err error) {
    method prepareForNextStory (line 77) | func (self *problem) prepareForNextStory() {
  function NewProblemReporter (line 64) | func NewProblemReporter(out *Printer) *problem {
  function NewSilentProblemReporter (line 71) | func NewSilentProblemReporter(out *Printer) *problem {

FILE: vendor/github.com/smartystreets/goconvey/convey/reporting/reporter.go
  type Reporter (line 5) | type Reporter interface
  type reporters (line 14) | type reporters struct
    method BeginStory (line 16) | func (self *reporters) BeginStory(s *StoryReport) { self.foreach(func(...
    method Enter (line 17) | func (self *reporters) Enter(s *ScopeReport)      { self.foreach(func(...
    method Report (line 18) | func (self *reporters) Report(a *AssertionResult) { self.foreach(func(...
    method Exit (line 19) | func (self *reporters) Exit()                     { self.foreach(func(...
    method EndStory (line 20) | func (self *reporters) EndStory()                 { self.foreach(func(...
    method Write (line 22) | func (self *reporters) Write(contents []byte) (written int, err error) {
    method foreach (line 29) | func (self *reporters) foreach(action func(Reporter)) {
  function NewReporters (line 35) | func NewReporters(collection ...Reporter) *reporters {

FILE: vendor/github.com/smartystreets/goconvey/convey/reporting/reports.go
  type ScopeReport (line 14) | type ScopeReport struct
  function NewScopeReport (line 20) | func NewScopeReport(title string) *ScopeReport {
  type ScopeResult (line 31) | type ScopeResult struct
  function newScopeResult (line 40) | func newScopeResult(title string, depth int, file string, line int) *Sco...
  type StoryReport (line 52) | type StoryReport struct
  function NewStoryReport (line 59) | func NewStoryReport(test T) *StoryReport {
  function removePackagePath (line 72) | func removePackagePath(name string) string {
  type FailureView (line 81) | type FailureView struct
  type AssertionResult (line 89) | type AssertionResult struct
  function NewFailureReport (line 100) | func NewFailureReport(failure string) *AssertionResult {
  function parseFailure (line 107) | func parseFailure(failure string, report *AssertionResult) {
  function NewErrorReport (line 118) | func NewErrorReport(err interface{}) *AssertionResult {
  function NewSuccessReport (line 125) | func NewSuccessReport() *AssertionResult {
  function NewSkipReport (line 128) | func NewSkipReport() *AssertionResult {
  function caller (line 136) | func caller() (file string, line int) {
  function stackTrace (line 141) | func stackTrace() string {
  function fullStackTrace (line 146) | func fullStackTrace() string {
  function removeInternalEntries (line 151) | func removeInternalEntries(stack string) string {
  function isExternal (line 161) | func isExternal(line string) bool {

FILE: vendor/github.com/smartystreets/goconvey/convey/reporting/statistics.go
  function NewStatisticsReporter (line 86) | func NewStatisticsReporter(out *Printer) *statistics {
  type statistics (line 92) | type statistics struct
    method BeginStory (line 8) | func (self *statistics) BeginStory(story *StoryReport) {}
    method Enter (line 10) | func (self *statistics) Enter(scope *ScopeReport) {}
    method Report (line 12) | func (self *statistics) Report(report *AssertionResult) {
    method Exit (line 29) | func (self *statistics) Exit() {}
    method EndStory (line 31) | func (self *statistics) EndStory() {
    method Suppress (line 40) | func (self *statistics) Suppress() {
    method PrintSummary (line 46) | func (self *statistics) PrintSummary() {
    method printSummaryLocked (line 52) | func (self *statistics) printSummaryLocked() {
    method reportAssertionsLocked (line 57) | func (self *statistics) reportAssertionsLocked() {
    method decideColorLocked (line 61) | func (self *statistics) decideColorLocked() {
    method reportSkippedSectionsLocked (line 70) | func (self *statistics) reportSkippedSectionsLocked() {
    method completeReportLocked (line 76) | func (self *statistics) completeReportLocked() {
    method Write (line 82) | func (self *statistics) Write(content []byte) (written int, err error) {
  function plural (line 103) | func plural(word string, count int) string {

FILE: vendor/github.com/smartystreets/goconvey/convey/reporting/story.go
  type story (line 15) | type story struct
    method BeginStory (line 21) | func (self *story) BeginStory(story *StoryReport) {}
    method Enter (line 23) | func (self *story) Enter(scope *ScopeReport) {
    method Report (line 37) | func (self *story) Report(report *AssertionResult) {
    method Exit (line 54) | func (self *story) Exit() {
    method EndStory (line 59) | func (self *story) EndStory() {
    method Write (line 64) | func (self *story) Write(content []byte) (written int, err error) {
  function NewStoryReporter (line 68) | func NewStoryReporter(out *Printer) *story {

FILE: vendor/github.com/spf13/pflag/bool.go
  type boolFlag (line 10) | type boolFlag interface
  type boolValue (line 16) | type boolValue
    method Set (line 23) | func (b *boolValue) Set(s string) error {
    method Type (line 29) | func (b *boolValue) Type() string {
    method String (line 33) | func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) }
    method IsBoolFlag (line 35) | func (b *boolValue) IsBoolFlag() bool { return true }
  function newBoolValue (line 18) | func newBoolValue(val bool, p *bool) *boolValue {
  function boolConv (line 37) | func boolConv(sval string) (interface{}, error) {
  method GetBool (line 42) | func (f *FlagSet) GetBool(name string) (bool, error) {
  method BoolVar (line 52) | func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
  method BoolVarP (line 57) | func (f *FlagSet) BoolVarP(p *bool, name, shorthand string, value bool, ...
  function BoolVar (line 64) | func BoolVar(p *bool, name string, value bool, usage string) {
  function BoolVarP (line 69) | func BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
  method Bool (line 76) | func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
  method BoolP (line 81) | func (f *FlagSet) BoolP(name, shorthand string, value bool, usage string...
  function Bool (line 89) | func Bool(name string, value bool, usage string) *bool {
  function BoolP (line 94) | func BoolP(name, shorthand string, value bool, usage string) *bool {

FILE: vendor/github.com/spf13/pflag/count.go
  type countValue (line 9) | type countValue
    method Set (line 16) | func (i *countValue) Set(s string) error {
    method Type (line 27) | func (i *countValue) Type() string {
    method String (line 31) | func (i *countValue) String() string { return fmt.Sprintf("%v", *i) }
  function newCountValue (line 11) | func newCountValue(val int, p *int) *countValue {
  function countConv (line 33) | func countConv(sval string) (interface{}, error) {
  method GetCount (line 42) | func (f *FlagSet) GetCount(name string) (int, error) {
  method CountVar (line 53) | func (f *FlagSet) CountVar(p *int, name string, usage string) {
  method CountVarP (line 58) | func (f *FlagSet) CountVarP(p *int, name, shorthand string, usage string) {
  function CountVar (line 64) | func CountVar(p *int, name string, usage string) {
  function CountVarP (line 69) | func CountVarP(p *int, name, shorthand string, usage string) {
  method Count (line 76) | func (f *FlagSet) Count(name string, usage string) *int {
  method CountP (line 83) | func (f *FlagSet) CountP(name, shorthand string, usage string) *int {
  function Count (line 90) | func Count(name string, usage string) *int {
  function CountP (line 95) | func CountP(name, shorthand string, usage string) *int {

FILE: vendor/github.com/spf13/pflag/duration.go
  type durationValue (line 8) | type durationValue
    method Set (line 15) | func (d *durationValue) Set(s string) error {
    method Type (line 21) | func (d *durationValue) Type() string {
    method String (line 25) | func (d *durationValue) String() string { return (*time.Duration)(d).S...
  function newDurationValue (line 10) | func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
  function durationConv (line 27) | func durationConv(sval string) (interface{}, error) {
  method GetDuration (line 32) | func (f *FlagSet) GetDuration(name string) (time.Duration, error) {
  method DurationVar (line 42) | func (f *FlagSet) DurationVar(p *time.Duration, name string, value time....
  method DurationVarP (line 47) | func (f *FlagSet) DurationVarP(p *time.Duration, name, shorthand string,...
  function DurationVar (line 53) | func DurationVar(p *time.Duration, name string, value time.Duration, usa...
  function DurationVarP (line 58) | func DurationVarP(p *time.Duration, name, shorthand string, value time.D...
  method Duration (line 64) | func (f *FlagSet) Duration(name string, value time.Duration, usage strin...
  method DurationP (line 71) | func (f *FlagSet) DurationP(name, shorthand string, value time.Duration,...
  function Duration (line 79) | func Duration(name string, value time.Duration, usage string) *time.Dura...
  function DurationP (line 84) | func DurationP(name, shorthand string, value time.Duration, usage string...

FILE: vendor/github.com/spf13/pflag/flag.go
  type ErrorHandling (line 115) | type ErrorHandling
  constant ContinueOnError (line 119) | ContinueOnError ErrorHandling = iota
  constant ExitOnError (line 121) | ExitOnError
  constant PanicOnError (line 123) | PanicOnError
  type NormalizedName (line 128) | type NormalizedName
  type FlagSet (line 131) | type FlagSet struct
    method SetNormalizeFunc (line 195) | func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) Nor...
    method GetNormalizeFunc (line 207) | func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) Nor...
    method normalizeFlagName (line 214) | func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
    method out (line 219) | func (f *FlagSet) out() io.Writer {
    method SetOutput (line 228) | func (f *FlagSet) SetOutput(output io.Writer) {
    method VisitAll (line 234) | func (f *FlagSet) VisitAll(fn func(*Flag)) {
    method HasFlags (line 241) | func (f *FlagSet) HasFlags() bool {
    method HasAvailableFlags (line 247) | func (f *FlagSet) HasAvailableFlags() bool {
    method Visit (line 264) | func (f *FlagSet) Visit(fn func(*Flag)) {
    method Lookup (line 277) | func (f *FlagSet) Lookup(name string) *Flag {
    method lookup (line 282) | func (f *FlagSet) lookup(name NormalizedName) *Flag {
    method getFlagType (line 287) | func (f *FlagSet) getFlagType(name string, ftype string, convFunc func...
    method ArgsLenAtDash (line 310) | func (f *FlagSet) ArgsLenAtDash() int {
    method MarkDeprecated (line 317) | func (f *FlagSet) MarkDeprecated(name string, usageMessage string) err...
    method MarkShorthandDeprecated (line 332) | func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage st...
    method MarkHidden (line 346) | func (f *FlagSet) MarkHidden(name string) error {
    method Set (line 362) | func (f *FlagSet) Set(name, value string) error {
    method SetAnnotation (line 386) | func (f *FlagSet) SetAnnotation(name, key string, values []string) err...
    method Changed (line 401) | func (f *FlagSet) Changed(name string) bool {
    method PrintDefaults (line 417) | func (f *FlagSet) PrintDefaults() {
    method FlagUsages (line 479) | func (f *FlagSet) FlagUsages() string {
    method NFlag (line 567) | func (f *FlagSet) NFlag() int { return len(f.actual) }
    method Arg (line 574) | func (f *FlagSet) Arg(i int) string {
    method NArg (line 588) | func (f *FlagSet) NArg() int { return len(f.args) }
    method Args (line 594) | func (f *FlagSet) Args() []string { return f.args }
    method Var (line 605) | func (f *FlagSet) Var(value Value, name string, usage string) {
    method VarPF (line 610) | func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *F...
    method VarP (line 624) | func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
    method AddFlag (line 629) | func (f *FlagSet) AddFlag(flag *Flag) {
    method AddFlagSet (line 667) | func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
    method failf (line 695) | func (f *FlagSet) failf(format string, a ...interface{}) error {
    method usage (line 704) | func (f *FlagSet) usage() {
    method setFlag (line 714) | func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) er...
    method parseLongArg (line 742) | func (f *FlagSet) parseLongArg(s string, args []string) (a []string, e...
    method parseSingleShortArg (line 780) | func (f *FlagSet) parseSingleShortArg(shorthands string, args []string...
    method parseShortArg (line 819) | func (f *FlagSet) parseShortArg(s string, args []string) (a []string, ...
    method parseArgs (line 833) | func (f *FlagSet) parseArgs(args []string) (err error) {
    method Parse (line 868) | func (f *FlagSet) Parse(arguments []string) error {
    method Parsed (line 886) | func (f *FlagSet) Parsed() bool {
    method SetInterspersed (line 923) | func (f *FlagSet) SetInterspersed(interspersed bool) {
    method Init (line 930) | func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
  type Flag (line 152) | type Flag struct
  type Value (line 168) | type Value interface
  function sortFlags (line 175) | func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
  function VisitAll (line 258) | func VisitAll(fn func(*Flag)) {
  function Visit (line 272) | func Visit(fn func(*Flag)) {
  function Lookup (line 357) | func Lookup(name string) *Flag {
  function Set (line 411) | func Set(name, value string) error {
  function isZeroValue (line 424) | func isZeroValue(value string) bool {
  function UnquoteUsage (line 443) | func UnquoteUsage(flag *Flag) (name string, usage string) {
  function PrintDefaults (line 543) | func PrintDefaults() {
  function defaultUsage (line 548) | func defaultUsage(f *FlagSet) {
  function NFlag (line 570) | func NFlag() int { return len(CommandLine.actual) }
  function Arg (line 583) | func Arg(i int) string {
  function NArg (line 591) | func NArg() int { return len(CommandLine.args) }
  function Args (line 597) | func Args() []string { return CommandLine.args }
  function Var (line 684) | func Var(value Value, name string, usage string) {
  function VarP (line 689) | func VarP(value Value, name, shorthand, usage string) {
  function containsShorthand (line 733) | func containsShorthand(arg, shorthand string) bool {
  function Parse (line 892) | func Parse() {
  function SetInterspersed (line 898) | func SetInterspersed(interspersed bool) {
  function Parsed (line 903) | func Parsed() bool {
  function NewFlagSet (line 912) | func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {

FILE: vendor/github.com/spf13/pflag/float32.go
  type float32Value (line 9) | type float32Value
    method Set (line 16) | func (f *float32Value) Set(s string) error {
    method Type (line 22) | func (f *float32Value) Type() string {
    method String (line 26) | func (f *float32Value) String() string { return fmt.Sprintf("%v", *f) }
  function newFloat32Value (line 11) | func newFloat32Value(val float32, p *float32) *float32Value {
  function float32Conv (line 28) | func float32Conv(sval string) (interface{}, error) {
  method GetFloat32 (line 37) | func (f *FlagSet) GetFloat32(name string) (float32, error) {
  method Float32Var (line 47) | func (f *FlagSet) Float32Var(p *float32, name string, value float32, usa...
  method Float32VarP (line 52) | func (f *FlagSet) Float32VarP(p *float32, name, shorthand string, value ...
  function Float32Var (line 58) | func Float32Var(p *float32, name string, value float32, usage string) {
  function Float32VarP (line 63) | func Float32VarP(p *float32, name, shorthand string, value float32, usag...
  method Float32 (line 69) | func (f *FlagSet) Float32(name string, value float32, usage string) *flo...
  method Float32P (line 76) | func (f *FlagSet) Float32P(name, shorthand string, value float32, usage ...
  function Float32 (line 84) | func Float32(name string, value float32, usage string) *float32 {
  function Float32P (line 89) | func Float32P(name, shorthand string, value float32, usage string) *floa...

FILE: vendor/github.com/spf13/pflag/float64.go
  type float64Value (line 9) | type float64Value
    method Set (line 16) | func (f *float64Value) Set(s string) error {
    method Type (line 22) | func (f *float64Value) Type() string {
    method String (line 26) | func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
  function newFloat64Value (line 11) | func newFloat64Value(val float64, p *float64) *float64Value {
  function float64Conv (line 28) | func float64Conv(sval string) (interface{}, error) {
  method GetFloat64 (line 33) | func (f *FlagSet) GetFloat64(name string) (float64, error) {
  method Float64Var (line 43) | func (f *FlagSet) Float64Var(p *float64, name string, value float64, usa...
  method Float64VarP (line 48) | func (f *FlagSet) Float64VarP(p *float64, name, shorthand string, value ...
  function Float64Var (line 54) | func Float64Var(p *float64, name string, value float64, usage string) {
  function Float64VarP (line 59) | func Float64VarP(p *float64, name, shorthand string, value float64, usag...
  method Float64 (line 65) | func (f *FlagSet) Float64(name string, value float64, usage string) *flo...
  method Float64P (line 72) | func (f *FlagSet) Float64P(name, shorthand string, value float64, usage ...
  function Float64 (line 80) | func Float64(name string, value float64, usage string) *float64 {
  function Float64P (line 85) | func Float64P(name, shorthand string, value float64, usage string) *floa...

FILE: vendor/github.com/spf13/pflag/golangflag.go
  type flagValueWrapper (line 20) | type flagValueWrapper struct
    method String (line 51) | func (v *flagValueWrapper) String() string {
    method Set (line 55) | func (v *flagValueWrapper) Set(s string) error {
    method Type (line 59) | func (v *flagValueWrapper) Type() string {
  type goBoolFlag (line 27) | type goBoolFlag interface
  function wrapFlagValue (line 32) | func wrapFlagValue(v goflag.Value) Value {
  function PFlagFromGoFlag (line 67) | func PFlagFromGoFlag(goflag *goflag.Flag) *Flag {
  method AddGoFlag (line 88) | func (f *FlagSet) AddGoFlag(goflag *goflag.Flag) {
  method AddGoFlagSet (line 97) | func (f *FlagSet) AddGoFlagSet(newSet *goflag.FlagSet) {

FILE: vendor/github.com/spf13/pflag/int.go
  type intValue (line 9) | type intValue
    method Set (line 16) | func (i *intValue) Set(s string) error {
    method Type (line 22) | func (i *intValue) Type() string {
    method String (line 26) | func (i *intValue) String() string { return fmt.Sprintf("%v", *i) }
  function newIntValue (line 11) | func newIntValue(val int, p *int) *intValue {
  function intConv (line 28) | func intConv(sval string) (interface{}, error) {
  method GetInt (line 33) | func (f *FlagSet) GetInt(name string) (int, error) {
  method IntVar (line 43) | func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
  method IntVarP (line 48) | func (f *FlagSet) IntVarP(p *int, name, shorthand string, value int, usa...
  function IntVar (line 54) | func IntVar(p *int, name string, value int, usage string) {
  function IntVarP (line 59) | func IntVarP(p *int, name, shorthand string, value int, usage string) {
  method Int (line 65) | func (f *FlagSet) Int(name string, value int, usage string) *int {
  method IntP (line 72) | func (f *FlagSet) IntP(name, shorthand string, value int, usage string) ...
  function Int (line 80) | func Int(name string, value int, usage string) *int {
  function IntP (line 85) | func IntP(name, shorthand string, value int, usage string) *int {

FILE: vendor/github.com/spf13/pflag/int32.go
  type int32Value (line 9) | type int32Value
    method Set (line 16) | func (i *int32Value) Set(s string) error {
    method Type (line 22) | func (i *int32Value) Type() string {
    method String (line 26) | func (i *int32Value) String() string { return fmt.Sprintf("%v", *i) }
  function newInt32Value (line 11) | func newInt32Value(val int32, p *int32) *int32Value {
  function int32Conv (line 28) | func int32Conv(sval string) (interface{}, error) {
  method GetInt32 (line 37) | func (f *FlagSet) GetInt32(name string) (int32, error) {
  method Int32Var (line 47) | func (f *FlagSet) Int32Var(p *int32, name string, value int32, usage str...
  method Int32VarP (line 52) | func (f *FlagSet) Int32VarP(p *int32, name, shorthand string, value int3...
  function Int32Var (line 58) | func Int32Var(p *int32, name string, value int32, usage string) {
  function Int32VarP (line 63) | func Int32VarP(p *int32, name, shorthand string, value int32, usage stri...
  method Int32 (line 69) | func (f *FlagSet) Int32(name string, value int32, usage string) *int32 {
  method Int32P (line 76) | func (f *FlagSet) Int32P(name, shorthand string, value int32, usage stri...
  function Int32 (line 84) | func Int32(name string, value int32, usage string) *int32 {
  function Int32P (line 89) | func Int32P(name, shorthand string, value int32, usage string) *int32 {

FILE: vendor/github.com/spf13/pflag/int64.go
  type int64Value (line 9) | type int64Value
    method Set (line 16) | func (i *int64Value) Set(s string) error {
    method Type (line 22) | func (i *int64Value) Type() string {
    method String (line 26) | func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) }
  function newInt64Value (line 11) | func newInt64Value(val int64, p *int64) *int64Value {
  function int64Conv (line 28) | func int64Conv(sval string) (interface{}, error) {
  method GetInt64 (line 33) | func (f *FlagSet) GetInt64(name string) (int64, error) {
  method Int64Var (line 43) | func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage str...
  method Int64VarP (line 48) | func (f *FlagSet) Int64VarP(p *int64, name, shorthand string, value int6...
  function Int64Var (line 54) | func Int64Var(p *int64, name string, value int64, usage string) {
  function Int64VarP (line 59) | func Int64VarP(p *int64, name, shorthand string, value int64, usage stri...
  method Int64 (line 65) | func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
  method Int64P (line 72) | func (f *FlagSet) Int64P(name, shorthand string, value int64, usage stri...
  function Int64 (line 80) | func Int64(name string, value int64, usage string) *int64 {
  function Int64P (line 85) | func Int64P(name, shorthand string, value int64, usage string) *int64 {

FILE: vendor/github.com/spf13/pflag/int8.go
  type int8Value (line 9) | type int8Value
    method Set (line 16) | func (i *int8Value) Set(s string) error {
    method Type (line 22) | func (i *int8Value) Type() string {
    method String (line 26) | func (i *int8Value) String() string { return fmt.Sprintf("%v", *i) }
  function newInt8Value (line 11) | func newInt8Value(val int8, p *int8) *int8Value {
  function int8Conv (line 28) | func int8Conv(sval string) (interface{}, error) {
  method GetInt8 (line 37) | func (f *FlagSet) GetInt8(name string) (int8, error) {
  method Int8Var (line 47) | func (f *FlagSet) Int8Var(p *int8, name string, value int8, usage string) {
  method Int8VarP (line 52) | func (f *FlagSet) Int8VarP(p *int8, name, shorthand string, value int8, ...
  function Int8Var (line 58) | func Int8Var(p *int8, name string, value int8, usage string) {
  function Int8VarP (line 63) | func Int8VarP(p *int8, name, shorthand string, value int8, usage string) {
  method Int8 (line 69) | func (f *FlagSet) Int8(name string, value int8, usage string) *int8 {
  method Int8P (line 76) | func (f *FlagSet) Int8P(name, shorthand string, value int8, usage string...
  function Int8 (line 84) | func Int8(name string, value int8, usage string) *int8 {
  function Int8P (line 89) | func Int8P(name, shorthand string, value int8, usage string) *int8 {

FILE: vendor/github.com/spf13/pflag/int_slice.go
  type intSliceValue (line 10) | type intSliceValue struct
    method Set (line 22) | func (s *intSliceValue) Set(val string) error {
    method Type (line 42) | func (s *intSliceValue) Type() string {
    method String (line 46) | func (s *intSliceValue) String() string {
  function newIntSliceValue (line 15) | func newIntSliceValue(val []int, p *[]int) *intSliceValue {
  function intSliceConv (line 54) | func intSliceConv(val string) (interface{}, error) {
  method GetIntSlice (line 74) | func (f *FlagSet) GetIntSlice(name string) ([]int, error) {
  method IntSliceVar (line 84) | func (f *FlagSet) IntSliceVar(p *[]int, name string, value []int, usage ...
  method IntSliceVarP (line 89) | func (f *FlagSet) IntSliceVarP(p *[]int, name, shorthand string, value [...
  function IntSliceVar (line 95) | func IntSliceVar(p *[]int, name string, value []int, usage string) {
  function IntSliceVarP (line 100) | func IntSliceVarP(p *[]int, name, shorthand string, value []int, usage s...
  method IntSlice (line 106) | func (f *FlagSet) IntSlice(name string, value []int, usage string) *[]int {
  method IntSliceP (line 113) | func (f *FlagSet) IntSliceP(name, shorthand string, value []int, usage s...
  function IntSlice (line 121) | func IntSlice(name string, value []int, usage string) *[]int {
  function IntSliceP (line 126) | func IntSliceP(name, shorthand string, value []int, usage string) *[]int {

FILE: vendor/github.com/spf13/pflag/ip.go
  type ipValue (line 12) | type ipValue
    method String (line 19) | func (i *ipValue) String() string { return net.IP(*i).String() }
    method Set (line 20) | func (i *ipValue) Set(s string) error {
    method Type (line 29) | func (i *ipValue) Type() string {
  function newIPValue (line 14) | func newIPValue(val net.IP, p *net.IP) *ipValue {
  function ipConv (line 33) | func ipConv(sval string) (interface{}, error) {
  method GetIP (line 42) | func (f *FlagSet) GetIP(name string) (net.IP, error) {
  method IPVar (line 52) | func (f *FlagSet) IPVar(p *net.IP, name string, value net.IP, usage stri...
  method IPVarP (line 57) | func (f *FlagSet) IPVarP(p *net.IP, name, shorthand string, value net.IP...
  function IPVar (line 63) | func IPVar(p *net.IP, name string, value net.IP, usage string) {
  function IPVarP (line 68) | func IPVarP(p *net.IP, name, shorthand string, value net.IP, usage strin...
  method IP (line 74) | func (f *FlagSet) IP(name string, value net.IP, usage string) *net.IP {
  method IPP (line 81) | func (f *FlagSet) IPP(name, shorthand string, value net.IP, usage string...
  function IP (line 89) | func IP(name string, value net.IP, usage string) *net.IP {
  function IPP (line 94) | func IPP(name, shorthand string, value net.IP, usage string) *net.IP {

FILE: vendor/github.com/spf13/pflag/ipmask.go
  type ipMaskValue (line 10) | type ipMaskValue
    method String (line 17) | func (i *ipMaskValue) String() string { return net.IPMask(*i).String() }
    method Set (line 18) | func (i *ipMaskValue) Set(s string) error {
    method Type (line 27) | func (i *ipMaskValue) Type() string {
  function newIPMaskValue (line 12) | func newIPMaskValue(val net.IPMask, p *net.IPMask) *ipMaskValue {
  function ParseIPv4Mask (line 33) | func ParseIPv4Mask(s string) net.IPMask {
  function parseIPv4Mask (line 59) | func parseIPv4Mask(sval string) (interface{}, error) {
  method GetIPv4Mask (line 68) | func (f *FlagSet) GetIPv4Mask(name string) (net.IPMask, error) {
  method IPMaskVar (line 78) | func (f *FlagSet) IPMaskVar(p *net.IPMask, name string, value net.IPMask...
  method IPMaskVarP (line 83) | func (f *FlagSet) IPMaskVarP(p *net.IPMask, name, shorthand string, valu...
  function IPMaskVar (line 89) | func IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage strin...
  function IPMaskVarP (line 94) | func IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask,...
  method IPMask (line 100) | func (f *FlagSet) IPMask(name string, value net.IPMask, usage string) *n...
  method IPMaskP (line 107) | func (f *FlagSet) IPMaskP(name, shorthand string, value net.IPMask, usag...
  function IPMask (line 115) | func IPMask(name string, value net.IPMask, usage string) *net.IPMask {
  function IPMaskP (line 120) | func IPMaskP(name, shorthand string, value net.IPMask, usage string) *ne...

FILE: vendor/github.com/spf13/pflag/ipnet.go
  type ipNetValue (line 10) | type ipNetValue
    method String (line 12) | func (ipnet ipNetValue) String() string {
    method Set (line 17) | func (ipnet *ipNetValue) Set(value string) error {
    method Type (line 26) | func (*ipNetValue) Type() string {
  function newIPNetValue (line 32) | func newIPNetValue(val net.IPNet, p *net.IPNet) *ipNetValue {
  function ipNetConv (line 37) | func ipNetConv(sval string) (interface{}, error) {
  method GetIPNet (line 46) | func (f *FlagSet) GetIPNet(name string) (net.IPNet, error) {
  method IPNetVar (line 56) | func (f *FlagSet) IPNetVar(p *net.IPNet, name string, value net.IPNet, u...
  method IPNetVarP (line 61) | func (f *FlagSet) IPNetVarP(p *net.IPNet, name, shorthand string, value ...
  function IPNetVar (line 67) | func IPNetVar(p *net.IPNet, name string, value net.IPNet, usage string) {
  function IPNetVarP (line 72) | func IPNetVarP(p *net.IPNet, name, shorthand string, value net.IPNet, us...
  method IPNet (line 78) | func (f *FlagSet) IPNet(name string, value net.IPNet, usage string) *net...
  method IPNetP (line 85) | func (f *FlagSet) IPNetP(name, shorthand string, value net.IPNet, usage ...
  function IPNet (line 93) | func IPNet(name string, value net.IPNet, usage string) *net.IPNet {
  function IPNetP (line 98) | func IPNetP(name, shorthand string, value net.IPNet, usage string) *net....

FILE: vendor/github.com/spf13/pflag/string.go
  type stringValue (line 6) | type stringValue
    method Set (line 13) | func (s *stringValue) Set(val string) error {
    method Type (line 17) | func (s *stringValue) Type() string {
    method String (line 21) | func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) }
  function newStringValue (line 8) | func newStringValue(val string, p *string) *stringValue {
  function stringConv (line 23) | func stringConv(sval string) (interface{}, error) {
  method GetString (line 28) | func (f *FlagSet) GetString(name string) (string, error) {
  method StringVar (line 38) | func (f *FlagSet) StringVar(p *string, name string, value string, usage ...
  method StringVarP (line 43) | func (f *FlagSet) StringVarP(p *string, name, shorthand string, value st...
  function StringVar (line 49) | func StringVar(p *string, name string, value string, usage string) {
  function StringVarP (line 54) | func StringVarP(p *string, name, shorthand string, value string, usage s...
  method String (line 60) | func (f *FlagSet) String(name string, value string, usage string) *string {
  method StringP (line 67) | func (f *FlagSet) StringP(name, shorthand string, value string, usage st...
  function String (line 75) | func String(name string, value string, usage string) *string {
  function StringP (line 80) | func StringP(name, shorthand string, value string, usage string) *string {

FILE: vendor/github.com/spf13/pflag/string_slice.go
  type stringSliceValue (line 12) | type stringSliceValue struct
    method Set (line 24) | func (s *stringSliceValue) Set(val string) error {
    method Type (line 40) | func (s *stringSliceValue) Type() string {
    method String (line 44) | func (s *stringSliceValue) String() string { return "[" + strings.Join...
  function newStringSliceValue (line 17) | func newStringSliceValue(val []string, p *[]string) *stringSliceValue {
  function stringSliceConv (line 46) | func stringSliceConv(sval string) (interface{}, error) {
  method GetStringSlice (line 57) | func (f *FlagSet) GetStringSlice(name string) ([]string, error) {
  method StringSliceVar (line 67) | func (f *FlagSet) StringSliceVar(p *[]string, name string, value []strin...
  method StringSliceVarP (line 72) | func (f *FlagSet) StringSliceVarP(p *[]string, name, shorthand string, v...
  function StringSliceVar (line 78) | func StringSliceVar(p *[]string, name string, value []string, usage stri...
  function StringSliceVarP (line 83) | func StringSliceVarP(p *[]string, name, shorthand string, value []string...
  method StringSlice (line 89) | func (f *FlagSet) StringSlice(name string, value []string, usage string)...
  method StringSliceP (line 96) | func (f *FlagSet) StringSliceP(name, shorthand string, value []string, u...
  function StringSlice (line 104) | func StringSlice(name string, value []string, usage string) *[]string {
  function StringSliceP (line 109) | func StringSliceP(name, shorthand string, value []string, usage string) ...

FILE: vendor/github.com/spf13/pflag/uint.go
  type uintValue (line 9) | type uintValue
    method Set (line 16) | func (i *uintValue) Set(s string) error {
    method Type (line 22) | func (i *uintValue) Type() string {
    method String (line 26) | func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
  function newUintValue (line 11) | func newUintValue(val uint, p *uint) *uintValue {
  function uintConv (line 28) | func uintConv(sval string) (interface{}, error) {
  method GetUint (line 37) | func (f *FlagSet) GetUint(name string) (uint, error) {
  method UintVar (line 47) | func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
  method UintVarP (line 52) | func (f *FlagSet) UintVarP(p *uint, name, shorthand string, value uint, ...
  function UintVar (line 58) | func UintVar(p *uint, name string, value uint, usage string) {
  function UintVarP (line 63) | func UintVarP(p *uint, name, shorthand string, value uint, usage string) {
  method Uint (line 69) | func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
  method UintP (line 76) | func (f *FlagSet) UintP(name, shorthand string, value uint, usage string...
  function Uint (line 84) | func Uint(name string, value uint, usage string) *uint {
  function UintP (line 89) | func UintP(name, shorthand string, value uint, usage string) *uint {

FILE: vendor/github.com/spf13/pflag/uint16.go
  type uint16Value (line 9) | type uint16Value
    method String (line 15) | func (i *uint16Value) String() string { return fmt.Sprintf("%d", *i) }
    method Set (line 16) | func (i *uint16Value) Set(s string) error {
    method Type (line 22) | func (i *uint16Value) Type() string {
  function newUint16Value (line 11) | func newUint16Value(val uint16, p *uint16) *uint16Value {
  function uint16Conv (line 26) | func uint16Conv(sval string) (interface{}, error) {
  method GetUint16 (line 35) | func (f *FlagSet) GetUint16(name string) (uint16, error) {
  method Uint16Var (line 45) | func (f *FlagSet) Uint16Var(p *uint16, name string, value uint16, usage ...
  method Uint16VarP (line 50) | func (f *FlagSet) Uint16VarP(p *uint16, name, shorthand string, value ui...
  function Uint16Var (line 56) | func Uint16Var(p *uint16, name string, value uint16, usage string) {
  function Uint16VarP (line 61) | func Uint16VarP(p *uint16, name, shorthand string, value uint16, usage s...
  method Uint16 (line 67) | func (f *FlagSet) Uint16(name string, value uint16, usage string) *uint16 {
  method Uint16P (line 74) | func (f *FlagSet) Uint16P(name, shorthand string, value uint16, usage st...
  function Uint16 (line 82) | func Uint16(name string, value uint16, usage string) *uint16 {
  function Uint16P (line 87) | func Uint16P(name, shorthand string, value uint16, usage string) *uint16 {

FILE: vendor/github.com/spf13/pflag/uint32.go
  type uint32Value (line 9) | type uint32Value
    method String (line 15) | func (i *uint32Value) String() string { return fmt.Sprintf("%d", *i) }
    method Set (line 16) | func (i *uint32Value) Set(s string) error {
    method Type (line 22) | func (i *uint32Value) Type() string {
  function newUint32Value (line 11) | func newUint32Value(val uint32, p *uint32) *uint32Value {
  function uint32Conv (line 26) | func uint32Conv(sval string) (interface{}, error) {
  method GetUint32 (line 35) | func (f *FlagSet) GetUint32(name string) (uint32, error) {
  method Uint32Var (line 45) | func (f *FlagSet) Uint32Var(p *uint32, name string, value uint32, usage ...
  method Uint32VarP (line 50) | func (f *FlagSet) Uint32VarP(p *uint32, name, shorthand string, value ui...
  function Uint32Var (line 56) | func Uint32Var(p *uint32, name string, value uint32, usage string) {
  function Uint32VarP (line 61) | func Uint32VarP(p *uint32, name, shorthand string, value uint32, usage s...
  method Uint32 (line 67) | func (f *FlagSet) Uint32(name string, value uint32, usage string) *uint32 {
  method Uint32P (line 74) | func (f *FlagSet) Uint32P(name, shorthand string, value uint32, usage st...
  function Uint32 (line 82) | func Uint32(name string, value uint32, usage string) *uint32 {
  function Uint32P (line 87) | func Uint32P(name, shorthand string, value uint32, usage string) *uint32 {

FILE: vendor/github.com/spf13/pflag/uint64.go
  type uint64Value (line 9) | type uint64Value
    method Set (line 16) | func (i *uint64Value) Set(s string) error {
    method Type (line 22) | func (i *uint64Value) Type() string {
    method String (line 26) | func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
  function newUint64Value (line 11) | func newUint64Value(val uint64, p *uint64) *uint64Value {
  function uint64Conv (line 28) | func uint64Conv(sval string) (interface{}, error) {
  method GetUint64 (line 37) | func (f *FlagSet) GetUint64(name string) (uint64, error) {
  method Uint64Var (line 47) | func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage ...
  method Uint64VarP (line 52) | func (f *FlagSet) Uint64VarP(p *uint64, name, shorthand string, value ui...
  function Uint64Var (line 58) | func Uint64Var(p *uint64, name string, value uint64, usage string) {
  function Uint64VarP (line 63) | func Uint64VarP(p *uint64, name, shorthand string, value uint64, usage s...
  method Uint64 (line 69) | func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
  method Uint64P (line 76) | func (f *FlagSet) Uint64P(name, shorthand string, value uint64, usage st...
  function Uint64 (line 84) | func Uint64(name string, value uint64, usage string) *uint64 {
  function Uint64P (line 89) | func Uint64P(name, shorthand string, value uint64, usage string) *uint64 {

FILE: vendor/github.com/spf13/pflag/uint8.go
  type uint8Value (line 9) | type uint8Value
    method Set (line 16) | func (i *uint8Value) Set(s string) error {
    method Type (line 22) | func (i *uint8Value) Type() string {
    method String (line 26) | func (i *uint8Value) String() string { return fmt.Sprintf("%v", *i) }
  function newUint8Value (line 11) | func newUint8Value(val uint8, p *uint8) *uint8Value {
  function uint8Conv (line 28) | func uint8Conv(sval string) (interface{}, error) {
  method GetUint8 (line 37) | func (f *FlagSet) GetUint8(name string) (uint8, error) {
  method Uint8Var (line 47) | func (f *FlagSet) Uint8Var(p *uint8, name string, value uint8, usage str...
  method Uint8VarP (line 52) | func (f *FlagSet) Uint8VarP(p *uint8, name, shorthand string, value uint...
  function Uint8Var (line 58) | func Uint8Var(p *uint8, name string, value uint8, usage string) {
  function Uint8VarP (line 63) | func Uint8VarP(p *uint8, name, shorthand string, value uint8, usage stri...
  method Uint8 (line 69) | func (f *FlagSet) Uint8(name string, value uint8, usage string) *uint8 {
  method Uint8P (line 76) | func (f *FlagSet) Uint8P(name, shorthand string, value uint8, usage stri...
  function Uint8 (line 84) | func Uint8(name string, value uint8, usage string) *uint8 {
  function Uint8P (line 89) | func Uint8P(name, shorthand string, value uint8, usage string) *uint8 {

FILE: vendor/github.com/t-k/fluent-logger-golang/fluent/fluent.go
  constant defaultHost (line 15) | defaultHost                   = "127.0.0.1"
  constant defaultPort (line 16) | defaultPort                   = 24224
  constant defaultTimeout (line 17) | defaultTimeout                = 3 * time.Second
  constant defaultBufferLimit (line 18) | defaultBufferLimit            = 8 * 1024 * 1024
  constant defaultRetryWait (line 19) | defaultRetryWait              = 500
  constant defaultMaxRetry (line 20) | defaultMaxRetry               = 13
  constant defaultReconnectWaitIncreRate (line 21) | defaultReconnectWaitIncreRate = 1.5
  type Config (line 24) | type Config struct
  type Fluent (line 34) | type Fluent struct
    method Post (line 95) | func (f *Fluent) Post(tag string, message interface{}) error {
    method PostWithTime (line 100) | func (f *Fluent) PostWithTime(tag string, tm time.Time, message interf...
    method EncodeAndPostData (line 139) | func (f *Fluent) EncodeAndPostData(tag string, tm time.Time, message i...
    method PostRawData (line 149) | func (f *Fluent) PostRawData(data []byte) {
    method EncodeData (line 163) | func (f *Fluent) EncodeData(tag string, tm time.Time, message interfac...
    method Close (line 171) | func (f *Fluent) Close() (err error) {
    method close (line 180) | func (f *Fluent) close() (err error) {
    method connect (line 195) | func (f *Fluent) connect() (err error) {
    method reconnect (line 204) | func (f *Fluent) reconnect() {
    method flushBuffer (line 224) | func (f *Fluent) flushBuffer() {
    method send (line 230) | func (f *Fluent) send() (err error) {
  function New (line 43) | func New(config Config) (f *Fluent, err error) {
  function e (line 200) | func e(x, y float64) int {

FILE: vendor/github.com/t-k/fluent-logger-golang/fluent/proto.go
  type Entry (line 6) | type Entry struct
  type Forward (line 12) | type Forward struct
  type Message (line 19) | type Message struct

FILE: vendor/github.com/t-k/fluent-logger-golang/fluent/proto_gen.go
  method DecodeMsg (line 12) | func (z *Entry) DecodeMsg(dc *msgp.Reader) (err error) {
  method EncodeMsg (line 34) | func (z Entry) EncodeMsg(en *msgp.Writer) (err error) {
  method MarshalMsg (line 51) | func (z Entry) MarshalMsg(b []byte) (o []byte, err error) {
  method UnmarshalMsg (line 63) | func (z *Entry) UnmarshalMsg(bts []byte) (o []byte, err error) {
  method Msgsize (line 87) | func (z Entry) Msgsize() (s int) {
  method DecodeMsg (line 93) | func (z *Forward) DecodeMsg(dc *msgp.Reader) (err error) {
  method EncodeMsg (line 144) | func (z *Forward) EncodeMsg(en *msgp.Writer) (err error) {
  method MarshalMsg (line 179) | func (z *Forward) MarshalMsg(b []byte) (o []byte, err error) {
  method UnmarshalMsg (line 200) | func (z *Forward) UnmarshalMsg(bts []byte) (o []byte, err error) {
  method Msgsize (line 255) | func (z *Forward) Msgsize() (s int) {
  method DecodeMsg (line 265) | func (z *Message) DecodeMsg(dc *msgp.Reader) (err error) {
  method EncodeMsg (line 295) | func (z *Message) EncodeMsg(en *msgp.Writer) (err error) {
  method MarshalMsg (line 320) | func (z *Message) MarshalMsg(b []byte) (o []byte, err error) {
  method UnmarshalMsg (line 337) | func (z *Message) UnmarshalMsg(bts []byte) (o []byte, err error) {
  method Msgsize (line 369) | func (z *Message) Msgsize() (s int) {

FILE: vendor/github.com/t-k/fluent-logger-golang/fluent/version.go
  constant Version (line 3) | Version = "0.5.1"

FILE: vendor/github.com/tinylib/msgp/msgp/advise_linux.go
  function adviseRead (line 10) | func adviseRead(mem []byte) {
  function adviseWrite (line 14) | func adviseWrite(mem []byte) {
  function fallocate (line 18) | func fallocate(f *os.File, sz int64) error {

FILE: vendor/github.com/tinylib/msgp/msgp/advise_other.go
  function adviseRead (line 11) | func adviseRead(mem []byte) {}
  function adviseWrite (line 13) | func adviseWrite(mem []byte) {}
  function fallocate (line 15) | func fallocate(f *os.File, sz int64) error {

FILE: vendor/github.com/tinylib/msgp/msgp/appengine.go
  constant smallint (line 7) | smallint = false
  function UnsafeString (line 9) | func UnsafeString(b []byte) string {
  function UnsafeBytes (line 13) | func UnsafeBytes(s string) []byte {

FILE: vendor/github.com/tinylib/msgp/msgp/circular.go
  type timer (line 3) | type timer interface
  type EndlessReader (line 11) | type EndlessReader struct
    method Read (line 26) | func (c *EndlessReader) Read(p []byte) (int, error) {
  function NewEndlessReader (line 18) | func NewEndlessReader(b []byte, tb timer) *EndlessReader {

FILE: vendor/github.com/tinylib/msgp/msgp/defs.go
  constant last4 (line 26) | last4 = 0x0f
  constant first4 (line 27) | first4 = 0xf0
  constant last5 (line 28) | last5 = 0x1f
  constant first3 (line 29) | first3 = 0xe0
  constant last7 (line 30) | last7 = 0x7f
  function isfixint (line 32) | func isfixint(b byte) bool {
  function isnfixint (line 36) | func isnfixint(b byte) bool {
  function isfixmap (line 40) | func isfixmap(b byte) bool {
  function isfixarray (line 44) | func isfixarray(b byte) bool {
  function isfixstr (line 48) | func isfixstr(b byte) bool {
  function wfixint (line 52) | func wfixint(u uint8) byte {
  function rfixint (line 56) | func rfixint(b byte) uint8 {
  function wnfixint (line 60) | func wnfixint(i int8) byte {
  function rnfixint (line 64) | func rnfixint(b byte) int8 {
  function rfixmap (line 68) | func rfixmap(b byte) uint8 {
  function wfixmap (line 72) | func wfixmap(u uint8) byte {
  function rfixstr (line 76) | func rfixstr(b byte) uint8 {
  function wfixstr (line 80) | func wfixstr(u uint8) byte {
  function rfixarray (line 84) | func rfixarray(b byte) uint8 {
  function wfixarray (line 88) | func wfixarray(u uint8) byte {
  constant mfixint (line 97) | mfixint uint8 = 0x00
  constant mnfixint (line 100) | mnfixint uint8 = 0xe0
  constant mfixmap (line 103) | mfixmap uint8 = 0x80
  constant mfixarray (line 106) | mfixarray uint8 = 0x90
  constant mfixstr (line 109) | mfixstr uint8 = 0xa0
  constant mnil (line 111) | mnil      uint8 = 0xc0
  constant mfalse (line 112) | mfalse    uint8 = 0xc2
  constant mtrue (line 113) | mtrue     uint8 = 0xc3
  constant mbin8 (line 114) | mbin8     uint8 = 0xc4
  constant mbin16 (line 115) | mbin16    uint8 = 0xc5
  constant mbin32 (line 116) | mbin32    uint8 = 0xc6
  constant mext8 (line 117) | mext8     uint8 = 0xc7
  constant mext16 (line 118) | mext16    uint8 = 0xc8
  constant mext32 (line 119) | mext32    uint8 = 0xc9
  constant mfloat32 (line 120) | mfloat32  uint8 = 0xca
  constant mfloat64 (line 121) | mfloat64  uint8 = 0xcb
  constant muint8 (line 122) | muint8    uint8 = 0xcc
  constant muint16 (line 123) | muint16   uint8 = 0xcd
  constant muint32 (line 124) | muint32   uint8 = 0xce
  constant muint64 (line 125) | muint64   uint8 = 0xcf
  constant mint8 (line 126) | mint8     uint8 = 0xd0
  constant mint16 (line 127) | mint16    uint8 = 0xd1
  constant mint32 (line 128) | mint32    uint8 = 0xd2
  constant mint64 (line 129) | mint64    uint8 = 0xd3
  constant mfixext1 (line 130) | mfixext1  uint8 = 0xd4
  constant mfixext2 (line 131) | mfixext2  uint8 = 0xd5
  constant mfixext4 (line 132) | mfixext4  uint8 = 0xd6
  constant mfixext8 (line 133) | mfixext8  uint8 = 0xd7
  constant mfixext16 (line 134) | mfixext16 uint8 = 0xd8
  constant mstr8 (line 135) | mstr8     uint8 = 0xd9
  constant mstr16 (line 136) | mstr16    uint8 = 0xda
  constant mstr32 (line 137) | mstr32    uint8 = 0xdb
  constant marray16 (line 138) | marray16  uint8 = 0xdc
  constant marray32 (line 139) | marray32  uint8 = 0xdd
  constant mmap16 (line 140) | mmap16    uint8 = 0xde
  constant mmap32 (line 141) | mmap32    uint8 = 0xdf

FILE: vendor/github.com/tinylib/msgp/msgp/edit.go
  function Locate (line 11) | func Locate(key string, raw []byte) []byte {
  function Replace (line 23) | func Replace(key string, raw []byte, val []byte) []byte {
  function CopyReplace (line 34) | func CopyReplace(key string, raw []byte, val []byte) []byte {
  function Remove (line 44) | func Remove(key string, raw []byte) []byte {
  function HasKey (line 55) | func HasKey(key string, raw []byte) bool {
  function replace (line 73) | func replace(raw []byte, start int, end int, val []byte, inplace bool) [...
  function locate (line 115) | func locate(raw []byte, key string) (start int, end int) {
  function locateKV (line 153) | func locateKV(raw []byte, key string) (start int, end int) {
  function resizeMap (line 189) | func resizeMap(raw []byte, delta int64) []byte {

FILE: vendor/github.com/tinylib/msgp/msgp/elsize.go
  function init (line 42) | func init() {
  type bytespec (line 75) | type bytespec struct
  type varmode (line 84) | type varmode
  constant constsize (line 87) | constsize varmode = 0
  constant extra8 (line 88) | extra8            = -1
  constant extra16 (line 89) | extra16           = -2
  constant extra32 (line 90) | extra32           = -3
  constant map16v (line 91) | map16v            = -4
  constant map32v (line 92) | map32v            = -5
  constant array16v (line 93) | array16v          = -6
  constant array32v (line 94) | array32v          = -7
  function getType (line 97) | func getType(v byte) Type {

FILE: vendor/github.com/tinylib/msgp/msgp/errors.go
  type Error (line 23) | type Error interface
  type errShort (line 33) | type errShort struct
    method Error (line 35) | func (e errShort) Error() string   { return "msgp: too few bytes left ...
    method Resumable (line 36) | func (e errShort) Resumable() bool { return false }
  type errFatal (line 38) | type errFatal struct
    method Error (line 40) | func (f errFatal) Error() string   { return "msgp: fatal decoding erro...
    method Resumable (line 41) | func (f errFatal) Resumable() bool { return false }
  type ArrayError (line 46) | type ArrayError struct
    method Error (line 52) | func (a ArrayError) Error() string {
    method Resumable (line 57) | func (a ArrayError) Resumable() bool { return true }
  type IntOverflow (line 62) | type IntOverflow struct
    method Error (line 68) | func (i IntOverflow) Error() string {
    method Resumable (line 73) | func (i IntOverflow) Resumable() bool { return true }
  type UintOverflow (line 78) | type UintOverflow struct
    method Error (line 84) | func (u UintOverflow) Error() string {
    method Resumable (line 89) | func (u UintOverflow) Resumable() bool { return true }
  type TypeError (line 94) | type TypeError struct
    method Error (line 100) | func (t TypeError) Error() string {
    method Resumable (line 105) | func (t TypeError) Resumable() bool { return true }
  function badPrefix (line 110) | func badPrefix(want Type, lead byte) error {
  type InvalidPrefixError (line 121) | type InvalidPrefixError
    method Error (line 124) | func (i InvalidPrefixError) Error() string {
    method Resumable (line 129) | func (i InvalidPrefixError) Resumable() bool { return false }
  type ErrUnsupportedType (line 134) | type ErrUnsupportedType struct
    method Error (line 139) | func (e *ErrUnsupportedType) Error() string { return fmt.Sprintf("msgp...
    method Resumable (line 142) | func (e *ErrUnsupportedType) Resumable() bool { return true }

FILE: vendor/github.com/tinylib/msgp/msgp/extension.go
  constant Complex64Extension (line 10) | Complex64Extension = 3
  constant Complex128Extension (line 13) | Complex128Extension = 4
  constant TimeExtension (line 16) | TimeExtension = 5
  function RegisterExtension (line 38) | func RegisterExtension(typ int8, f func() Extension) {
  type ExtensionTypeError (line 52) | type ExtensionTypeError struct
    method Error (line 58) | func (e ExtensionTypeError) Error() string {
    method Resumable (line 63) | func (e ExtensionTypeError) Resumable() bool { return true }
  function errExt (line 65) | func errExt(got int8, wanted int8) error {
  type Extension (line 72) | type Extension interface
  type RawExtension (line 93) | type RawExtension struct
    method ExtensionType (line 99) | func (r *RawExtension) ExtensionType() int8 { return r.Type }
    method Len (line 102) | func (r *RawExtension) Len() int { return len(r.Data) }
    method MarshalBinaryTo (line 106) | func (r *RawExtension) MarshalBinaryTo(d []byte) error {
    method UnmarshalBinary (line 113) | func (r *RawExtension) UnmarshalBinary(b []byte) error {
  method WriteExtension (line 124) | func (mw *Writer) WriteExtension(e Extension) error {
  method peekExtensionType (line 228) | func (m *Reader) peekExtensionType() (int8, error) {
  function peekExtension (line 250) | func peekExtension(b []byte) (int8, error) {
  method ReadExtension (line 274) | func (m *Reader) ReadExtension(e Extension) (err error) {
  function AppendExtension (line 412) | func AppendExtension(b []byte, e Extension) ([]byte, error) {
  function ReadExtensionBytes (line 480) | func ReadExtensionBytes(b []byte, e Extension) ([]byte, error) {

FILE: vendor/github.com/tinylib/msgp/msgp/file.go
  function ReadFile (line 23) | func ReadFile(dst Unmarshaler, file *os.File) error {
  type MarshalSizer (line 44) | type MarshalSizer interface
  function WriteFile (line 70) | func WriteFile(src MarshalSizer, file *os.File) error {

FILE: vendor/github.com/tinylib/msgp/msgp/file_port.go
  type MarshalSizer (line 13) | type MarshalSizer interface
  function ReadFile (line 18) | func ReadFile(dst Unmarshaler, file *os.File) error {
  function WriteFile (line 31) | func WriteFile(src MarshalSizer, file *os.File) error {

FILE: vendor/github.com/tinylib/msgp/msgp/integers.go
  function putMint64 (line 13) | func putMint64(b []byte, i int64) {
  function getMint64 (line 25) | func getMint64(b []byte) int64 {
  function putMint32 (line 32) | func putMint32(b []byte, i int32) {
  function getMint32 (line 40) | func getMint32(b []byte) int32 {
  function putMint16 (line 44) | func putMint16(b []byte, i int16) {
  function getMint16 (line 50) | func getMint16(b []byte) (i int16) {
  function putMint8 (line 54) | func putMint8(b []byte, i int8) {
  function getMint8 (line 59) | func getMint8(b []byte) (i int8) {
  function putMuint64 (line 63) | func putMuint64(b []byte, u uint64) {
  function getMuint64 (line 75) | func getMuint64(b []byte) uint64 {
  function putMuint32 (line 82) | func putMuint32(b []byte, u uint32) {
  function getMuint32 (line 90) | func getMuint32(b []byte) uint32 {
  function putMuint16 (line 94) | func putMuint16(b []byte, u uint16) {
  function getMuint16 (line 100) | func getMuint16(b []byte) uint16 {
  function putMuint8 (line 104) | func putMuint8(b []byte, u uint8) {
  function getMuint8 (line 109) | func getMuint8(b []byte) uint8 {
  function getUnix (line 113) | func getUnix(b []byte) (sec int64, nsec int32) {
  function putUnix (line 123) | func putUnix(b []byte, sec int64, nsec int32) {
  function prefixu8 (line 143) | func prefixu8(b []byte, pre byte, sz uint8) {
  function prefixu16 (line 149) | func prefixu16(b []byte, pre byte, sz uint16) {
  function prefixu32 (line 156) | func prefixu32(b []byte, pre byte, sz uint32) {
  function prefixu64 (line 164) | func prefixu64(b []byte, pre byte, sz uint64) {

FILE: vendor/github.com/tinylib/msgp/msgp/json.go
  function init (line 21) | func init() {
  type jsWriter (line 45) | type jsWriter interface
  function CopyToJSON (line 53) | func CopyToJSON(dst io.Writer, src io.Reader) (n int64, err error) {
  method WriteToJSON (line 63) | func (r *Reader) WriteToJSON(w io.Writer) (n int64, err error) {
  function rwNext (line 90) | func rwNext(w jsWriter, src *Reader) (int, error) {
  function rwMap (line 98) | func rwMap(dst jsWriter, src *Reader) (n int, err error) {
  function rwArray (line 160) | func rwArray(dst jsWriter, src *Reader) (n int, err error) {
  function rwNil (line 196) | func rwNil(dst jsWriter, src *Reader) (int, error) {
  function rwFloat32 (line 204) | func rwFloat32(dst jsWriter, src *Reader) (int, error) {
  function rwFloat64 (line 213) | func rwFloat64(dst jsWriter, src *Reader) (int, error) {
  function rwInt (line 222) | func rwInt(dst jsWriter, src *Reader) (int, error) {
  function rwUint (line 231) | func rwUint(dst jsWriter, src *Reader) (int, error) {
  function rwBool (line 240) | func rwBool(dst jsWriter, src *Reader) (int, error) {
  function rwTime (line 251) | func rwTime(dst jsWriter, src *Reader) (int, error) {
  function rwExtension (line 263) | func rwExtension(dst jsWriter, src *Reader) (n int, err error) {
  function rwString (line 334) | func rwString(dst jsWriter, src *Reader) (n int, err error) {
  function rwBytes (line 381) | func rwBytes(dst jsWriter, src *Reader) (n int, err error) {
  function rwquoted (line 414) | func rwquoted(dst jsWriter, s []byte) (n int, err error) {

FILE: vendor/github.com/tinylib/msgp/msgp/json_bytes.go
  function init (line 14) | func init() {
  function UnmarshalAsJSON (line 41) | func UnmarshalAsJSON(w io.Writer, msg []byte) ([]byte, error) {
  function writeNext (line 63) | func writeNext(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, ...
  function rwArrayBytes (line 83) | func rwArrayBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byt...
  function rwMapBytes (line 108) | func rwMapBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte,...
  function rwMapKeyBytes (line 141) | func rwMapKeyBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []by...
  function rwStringBytes (line 151) | func rwStringBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []by...
  function rwBytesBytes (line 160) | func rwBytesBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byt...
  function rwNullBytes (line 184) | func rwNullBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte...
  function rwBoolBytes (line 193) | func rwBoolBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte...
  function rwIntBytes (line 206) | func rwIntBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte,...
  function rwUintBytes (line 216) | func rwUintBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte...
  function rwFloatBytes (line 226) | func rwFloatBytes(w jsWriter, msg []byte, f64 bool, scratch []byte) ([]b...
  function rwFloat32Bytes (line 247) | func rwFloat32Bytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []b...
  function rwFloat64Bytes (line 259) | func rwFloat64Bytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []b...
  function rwTimeBytes (line 271) | func rwTimeBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte...
  function rwExtensionBytes (line 286) | func rwExtensionBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, [...
  function writeExt (line 336) | func writeExt(w jsWriter, r RawExtension, scratch []byte) ([]byte, error) {

FILE: vendor/github.com/tinylib/msgp/msgp/number.go
  type Number (line 21) | type Number struct
    method AsInt (line 31) | func (n *Number) AsInt(i int64) {
    method AsUint (line 48) | func (n *Number) AsUint(u uint64) {
    method AsFloat32 (line 55) | func (n *Number) AsFloat32(f float32) {
    method AsFloat64 (line 62) | func (n *Number) AsFloat64(f float64) {
    method Int (line 70) | func (n *Number) Int() (int64, bool) {
    method Uint (line 76) | func (n *Number) Uint() (uint64, bool) {
    method Float (line 83) | func (n *Number) Float() (float64, bool) {
    method Type (line 96) | func (n *Number) Type() Type {
    method DecodeMsg (line 104) | func (n *Number) DecodeMsg(r *Reader) error {
    method UnmarshalMsg (line 144) | func (n *Number) UnmarshalMsg(b []byte) ([]byte, error) {
    method MarshalMsg (line 181) | func (n *Number) MarshalMsg(b []byte) ([]byte, error) {
    method EncodeMsg (line 197) | func (n *Number) EncodeMsg(w *Writer) error {
    method Msgsize (line 213) | func (n *Number) Msgsize() int {
    method MarshalJSON (line 229) | func (n *Number) MarshalJSON() ([]byte, error) {
    method String (line 251) | func (n *Number) String() string {

FILE: vendor/github.com/tinylib/msgp/msgp/read.go
  type Type (line 18) | type Type
    method String (line 52) | func (t Type) String() string {
  constant InvalidType (line 25) | InvalidType Type = iota
  constant StrType (line 29) | StrType
  constant BinType (line 30) | BinType
  constant MapType (line 31) | MapType
  constant ArrayType (line 32) | ArrayType
  constant Float64Type (line 33) | Float64Type
  constant Float32Type (line 34) | Float32Type
  constant BoolType (line 35) | BoolType
  constant IntType (line 36) | IntType
  constant UintType (line 37) | UintType
  constant NilType (line 38) | NilType
  constant ExtensionType (line 39) | ExtensionType
  constant Complex64Type (line 44) | Complex64Type
  constant Complex128Type (line 45) | Complex128Type
  constant TimeType (line 46) | TimeType
  constant _maxtype (line 48) | _maxtype
  function freeR (line 81) | func freeR(m *Reader) {
  type Unmarshaler (line 91) | type Unmarshaler interface
  type Decodable (line 98) | type Decodable interface
  function Decode (line 103) | func Decode(r io.Reader, d Decodable) error {
  function NewReader (line 113) | func NewReader(r io.Reader) *Reader {
  function NewReaderSize (line 125) | func NewReaderSize(r io.Reader, sz int) *Reader {
  type Reader (line 132) | type Reader struct
    method Read (line 145) | func (m *Reader) Read(p []byte) (int, error) {
    method ReadFull (line 150) | func (m *Reader) ReadFull(p []byte) (int, error) {
    method Reset (line 155) | func (m *Reader) Reset(r io.Reader) { m.R.Reset(r) }
    method Buffered (line 158) | func (m *Reader) Buffered() int { return m.R.Buffered() }
    method BufferSize (line 161) | func (m *Reader) BufferSize() int { return m.R.BufferSize() }
    method NextType (line 164) | func (m *Reader) NextType() (Type, error) {
    method IsNil (line 192) | func (m *Reader) IsNil() bool {
    method Skip (line 243) | func (m *Reader) Skip() error {
    method ReadMapHeader (line 292) | func (m *Reader) ReadMapHeader() (sz uint32, err error) {
    method ReadMapKey (line 329) | func (m *Reader) ReadMapKey(scratch []byte) ([]byte, error) {
    method ReadMapKeyPtr (line 348) | func (m *Reader) ReadMapKeyPtr() ([]byte, error) {
    method ReadArrayHeader (line 392) | func (m *Reader) ReadArrayHeader() (sz uint32, err error) {
    method ReadNil (line 429) | func (m *Reader) ReadNil() error {
    method ReadFloat64 (line 444) | func (m *Reader) ReadFloat64() (f float64, err error) {
    method ReadFloat32 (line 471) | func (m *Reader) ReadFloat32() (f float32, err error) {
    method ReadBool (line 487) | func (m *Reader) ReadBool() (b bool, err error) {
    method ReadInt64 (line 506) | func (m *Reader) ReadInt64() (i int64, err error) {
    method ReadInt32 (line 565) | func (m *Reader) ReadInt32() (i int32, err error) {
    method ReadInt16 (line 577) | func (m *Reader) ReadInt16() (i int16, err error) {
    method ReadInt8 (line 589) | func (m *Reader) ReadInt8() (i int8, err error) {
    method ReadInt (line 601) | func (m *Reader) ReadInt() (i int, err error) {
    method ReadUint64 (line 615) | func (m *Reader) ReadUint64() (u uint64, err error) {
    method ReadUint32 (line 669) | func (m *Reader) ReadUint32() (u uint32, err error) {
    method ReadUint16 (line 681) | func (m *Reader) ReadUint16() (u uint16, err error) {
    method ReadUint8 (line 693) | func (m *Reader) ReadUint8() (u uint8, err error) {
    method ReadUint (line 705) | func (m *Reader) ReadUint() (u uint, err error) {
    method ReadByte (line 722) | func (m *Reader) ReadByte() (b byte, err error) {
    method ReadBytes (line 736) | func (m *Reader) ReadBytes(scratch []byte) (b []byte, err error) {
    method ReadBytesHeader (line 779) | func (m *Reader) ReadBytesHeader() (sz uint32, err error) {
    method ReadExactBytes (line 817) | func (m *Reader) ReadExactBytes(into []byte) error {
    method ReadStringAsBytes (line 857) | func (m *Reader) ReadStringAsBytes(scratch []byte) (b []byte, err erro...
    method ReadStringHeader (line 910) | func (m *Reader) ReadStringHeader() (sz uint32, err error) {
    method ReadString (line 951) | func (m *Reader) ReadString() (s string, err error) {
    method ReadComplex64 (line 1022) | func (m *Reader) ReadComplex64() (f complex64, err error) {
    method ReadComplex128 (line 1043) | func (m *Reader) ReadComplex128() (f complex128, err error) {
    method ReadMapStrIntf (line 1065) | func (m *Reader) ReadMapStrIntf(mp map[string]interface{}) (err error) {
    method ReadTime (line 1092) | func (m *Reader) ReadTime() (t time.Time, err error) {
    method ReadIntf (line 1116) | func (m *Reader) ReadIntf() (i interface{}, err error) {
  function getNextSize (line 202) | func getNextSize(r *fwd.Reader) (uintptr, uintptr, error) {

FILE: vendor/github.com/tinylib/msgp/msgp/read_bytes.go
  function NextType (line 16) | func NextType(b []byte) Type {
  function IsNil (line 46) | func IsNil(b []byte) bool {
  type Raw (line 56) | type Raw
    method MarshalMsg (line 62) | func (r Raw) MarshalMsg(b []byte) ([]byte, error) {
    method UnmarshalMsg (line 75) | func (r *Raw) UnmarshalMsg(b []byte) ([]byte, error) {
    method EncodeMsg (line 94) | func (r Raw) EncodeMsg(w *Writer) error {
    method DecodeMsg (line 105) | func (r *Raw) DecodeMsg(f *Reader) error {
    method Msgsize (line 111) | func (r Raw) Msgsize() int {
    method MarshalJSON (line 141) | func (r *Raw) MarshalJSON() ([]byte, error) {
  function appendNext (line 119) | func appendNext(f *Reader, d *[]byte) error {
  function ReadMapHeaderBytes (line 152) | func ReadMapHeaderBytes(b []byte) (sz uint32, o []byte, err error) {
  function ReadMapKeyZC (line 196) | func ReadMapKeyZC(b []byte) ([]byte, []byte, error) {
  function ReadArrayHeaderBytes (line 213) | func ReadArrayHeaderBytes(b []byte) (sz uint32, o []byte, err error) {
  function ReadNilBytes (line 255) | func ReadNilBytes(b []byte) ([]byte, error) {
  function ReadFloat64Bytes (line 270) | func ReadFloat64Bytes(b []byte) (f float64, o []byte, err error) {
  function ReadFloat32Bytes (line 303) | func ReadFloat32Bytes(b []byte) (f float32, o []byte, err error) {
  function ReadBoolBytes (line 324) | func ReadBoolBytes(b []byte) (bool, []byte, error) {
  function ReadInt64Bytes (line 343) | func ReadInt64Bytes(b []byte) (i int64, o []byte, err error) {
  function ReadInt32Bytes (line 410) | func ReadInt32Bytes(b []byte) (int32, []byte, error) {
  function ReadInt16Bytes (line 424) | func ReadInt16Bytes(b []byte) (int16, []byte, error) {
  function ReadInt8Bytes (line 438) | func ReadInt8Bytes(b []byte) (int8, []byte, error) {
  function ReadIntBytes (line 452) | func ReadIntBytes(b []byte) (int, []byte, error) {
  function ReadUint64Bytes (line 466) | func ReadUint64Bytes(b []byte) (u uint64, o []byte, err error) {
  function ReadUint32Bytes (line 528) | func ReadUint32Bytes(b []byte) (uint32, []byte, error) {
  function ReadUint16Bytes (line 542) | func ReadUint16Bytes(b []byte) (uint16, []byte, error) {
  function ReadUint8Bytes (line 556) | func ReadUint8Bytes(b []byte) (uint8, []byte, error) {
  function ReadUintBytes (line 570) | func ReadUintBytes(b []byte) (uint, []byte, error) {
  function ReadByteBytes (line 580) | func ReadByteBytes(b []byte) (byte, []byte, error) {
  function ReadBytesBytes (line 590) | func ReadBytesBytes(b []byte, scratch []byte) (v []byte, o []byte, err e...
  function readBytesBytes (line 594) | func readBytesBytes(b []byte, scratch []byte, zc bool) (v []byte, o []by...
  function ReadBytesZC (line 661) | func ReadBytesZC(b []byte) (v []byte, o []byte, err error) {
  function ReadExactBytes (line 665) | func ReadExactBytes(b []byte, into []byte) (o []byte, err error) {
  function ReadStringZC (line 721) | func ReadStringZC(b []byte) (v []byte, o []byte, err error) {
  function ReadStringBytes (line 782) | func ReadStringBytes(b []byte) (string, []byte, error) {
  function ReadStringAsBytes (line 796) | func ReadStringAsBytes(b []byte, scratch []byte) (v []byte, o []byte, er...
  function ReadComplex128Bytes (line 811) | func ReadComplex128Bytes(b []byte) (c complex128, o []byte, err error) {
  function ReadComplex64Bytes (line 837) | func ReadComplex64Bytes(b []byte) (c complex64, o []byte, err error) {
  function ReadTimeBytes (line 863) | func ReadTimeBytes(b []byte) (t time.Time, o []byte, err error) {
  function ReadMapStrIntfBytes (line 885) | func ReadMapStrIntfBytes(b []byte, old map[string]interface{}) (v map[st...
  function ReadIntfBytes (line 926) | func ReadIntfBytes(b []byte) (i interface{}, o []byte, err error) {
  function Skip (line 1034) | func Skip(b []byte) ([]byte, error) {
  function getSize (line 1054) | func getSize(b []byte) (uintptr, uintptr, error) {

FILE: vendor/github.com/tinylib/msgp/msgp/size.go
  constant Int64Size (line 12) | Int64Size      = 9
  constant IntSize (line 13) | IntSize        = Int64Size
  constant UintSize (line 14) | UintSize       = Int64Size
  constant Int8Size (line 15) | Int8Size       = 2
  constant Int16Size (line 16) | Int16Size      = 3
  constant Int32Size (line 17) | Int32Size      = 5
  constant Uint8Size (line 18) | Uint8Size      = 2
  constant ByteSize (line 19) | ByteSize       = Uint8Size
  constant Uint16Size (line 20) | Uint16Size     = 3
  constant Uint32Size (line 21) | Uint32Size     = 5
  constant Uint64Size (line 22) | Uint64Size     = Int64Size
  constant Float64Size (line 23) | Float64Size    = 9
  constant Float32Size (line 24) | Float32Size    = 5
  constant Complex64Size (line 25) | Complex64Size  = 10
  constant Complex128Size (line 26) | Complex128Size = 18
  constant TimeSize (line 28) | TimeSize = 15
  constant BoolSize (line 29) | BoolSize = 1
  constant NilSize (line 30) | NilSize  = 1
  constant MapHeaderSize (line 32) | MapHeaderSize   = 5
  constant ArrayHeaderSize (line 33) | ArrayHeaderSize = 5
  constant BytesPrefixSize (line 35) | BytesPrefixSize     = 5
  constant StringPrefixSize (line 36) | StringPrefixSize    = 5
  constant ExtensionPrefixSize (line 37) | ExtensionPrefixSize = 6

FILE: vendor/github.com/tinylib/msgp/msgp/unsafe.go
  constant smallint (line 19) | smallint = unsafe.Sizeof(int(0)) == 4
  function UnsafeString (line 26) | func UnsafeString(b []byte) string {
  function UnsafeBytes (line 34) | func UnsafeBytes(s string) []byte {

FILE: vendor/github.com/tinylib/msgp/msgp/write.go
  type Sizer (line 20) | type Sizer interface
  function popWriter (line 36) | func popWriter(w io.Writer) *Writer {
  function pushWriter (line 42) | func pushWriter(wr *Writer) {
  function freeW (line 53) | func freeW(w *Writer) { pushWriter(w) }
  function Require (line 56) | func Require(old []byte, extra int) []byte {
  type nwhere (line 80) | type nwhere struct
    method Write (line 82) | func (n nwhere) Write(p []byte) (int, error) { return len(p), nil }
  type Marshaler (line 90) | type Marshaler interface
  type Encodable (line 97) | type Encodable interface
  type Writer (line 107) | type Writer struct
    method flush (line 147) | func (mw *Writer) flush() error {
    method Flush (line 164) | func (mw *Writer) Flush() error { return mw.flush() }
    method Buffered (line 167) | func (mw *Writer) Buffered() int { return len(mw.buf) - mw.wloc }
    method avail (line 169) | func (mw *Writer) avail() int { return len(mw.buf) - mw.wloc }
    method bufsize (line 171) | func (mw *Writer) bufsize() int { return len(mw.buf) }
    method require (line 178) | func (mw *Writer) require(n int) (int, error) {
    method Append (line 191) | func (mw *Writer) Append(b ...byte) error {
    method push (line 205) | func (mw *Writer) push(b byte) error {
    method prefix8 (line 216) | func (mw *Writer) prefix8(b byte, u uint8) error {
    method prefix16 (line 228) | func (mw *Writer) prefix16(b byte, u uint16) error {
    method prefix32 (line 240) | func (mw *Writer) prefix32(b byte, u uint32) error {
    method prefix64 (line 252) | func (mw *Writer) prefix64(b byte, u uint64) error {
    method Write (line 266) | func (mw *Writer) Write(p []byte) (int, error) {
    method writeString (line 281) | func (mw *Writer) writeString(s string) error {
    method Reset (line 297) | func (mw *Writer) Reset(w io.Writer) {
    method WriteMapHeader (line 305) | func (mw *Writer) WriteMapHeader(sz uint32) error {
    method WriteArrayHeader (line 318) | func (mw *Writer) WriteArrayHeader(sz uint32) error {
    method WriteNil (line 330) | func (mw *Writer) WriteNil() error {
    method WriteFloat64 (line 335) | func (mw *Writer) WriteFloat64(f float64) error {
    method WriteFloat32 (line 340) | func (mw *Writer) WriteFloat32(f float32) error {
    method WriteInt64 (line 345) | func (mw *Writer) WriteInt64(i int64) error {
    method WriteInt8 (line 373) | func (mw *Writer) WriteInt8(i int8) error { return mw.WriteInt64(int64...
    method WriteInt16 (line 376) | func (mw *Writer) WriteInt16(i int16) error { return mw.WriteInt64(int...
    method WriteInt32 (line 379) | func (mw *Writer) WriteInt32(i int32) error { return mw.WriteInt64(int...
    method WriteInt (line 382) | func (mw *Writer) WriteInt(i int) error { return mw.WriteInt64(int64(i...
    method WriteUint64 (line 385) | func (mw *Writer) WriteUint64(u uint64) error {
    method WriteByte (line 401) | func (mw *Writer) WriteByte(u byte) error { return mw.WriteUint8(uint8...
    method WriteUint8 (line 404) | func (mw *Writer) WriteUint8(u uint8) error { return mw.WriteUint64(ui...
    method WriteUint16 (line 407) | func (mw *Writer) WriteUint16(u uint16) error { return mw.WriteUint64(...
    method WriteUint32 (line 410) | func (mw *Writer) WriteUint32(u uint32) error { return mw.WriteUint64(...
    method WriteUint (line 413) | func (mw *Writer) WriteUint(u uint) error { return mw.WriteUint64(uint...
    method WriteBytes (line 416) | func (mw *Writer) WriteBytes(b []byte) error {
    method WriteBytesHeader (line 437) | func (mw *Writer) WriteBytesHeader(sz uint32) error {
    method WriteBool (line 449) | func (mw *Writer) WriteBool(b bool) error {
    method WriteString (line 458) | func (mw *Writer) WriteString(s string) error {
    method WriteStringHeader (line 481) | func (mw *Writer) WriteStringHeader(sz uint32) error {
    method WriteStringFromBytes (line 496) | func (mw *Writer) WriteStringFromBytes(str []byte) error {
    method WriteComplex64 (line 517) | func (mw *Writer) WriteComplex64(f complex64) error {
    method WriteComplex128 (line 530) | func (mw *Writer) WriteComplex128(f complex128) error {
    method WriteMapStrStr (line 543) | func (mw *Writer) WriteMapStrStr(mp map[string]string) (err error) {
    method WriteMapStrIntf (line 562) | func (mw *Writer) WriteMapStrIntf(mp map[string]interface{}) (err erro...
    method WriteTime (line 594) | func (mw *Writer) WriteTime(t time.Time) error {
    method WriteIntf (line 615) | func (mw *Writer) WriteIntf(v interface{}) error {
    method writeMap (line 691) | func (mw *Writer) writeMap(v reflect.Value) (err error) {
    method writeSlice (line 714) | func (mw *Writer) writeSlice(v reflect.Value) (err error) {
    method writeStruct (line 734) | func (mw *Writer) writeStruct(v reflect.Value) error {
    method writeVal (line 741) | func (mw *Writer) writeVal(v reflect.Value) error {
  function NewWriter (line 114) | func NewWriter(w io.Writer) *Writer {
  function NewWriterSize (line 122) | func NewWriterSize(w io.Writer, sz int) *Writer {
  function Encode (line 137) | func Encode(w io.Writer, e Encodable) error {
  function isSupported (line 789) | func isSupported(k reflect.Kind) bool {
  function GuessSize (line 802) | func GuessSize(i interface{}) int {

FILE: vendor/github.com/tinylib/msgp/msgp/write_bytes.go
  function ensure (line 10) | func ensure(b []byte, sz int) ([]byte, int) {
  function AppendMapHeader (line 23) | func AppendMapHeader(b []byte, sz uint32) []byte {
  function AppendArrayHeader (line 42) | func AppendArrayHeader(b []byte, sz uint32) []byte {
  function AppendNil (line 60) | func AppendNil(b []byte) []byte { return append(b, mnil) }
  function AppendFloat64 (line 63) | func AppendFloat64(b []byte, f float64) []byte {
  function AppendFloat32 (line 70) | func AppendFloat32(b []byte, f float32) []byte {
  function AppendInt64 (line 77) | func AppendInt64(b []byte, i int64) []byte {
  function AppendInt (line 119) | func AppendInt(b []byte, i int) []byte { return AppendInt64(b, int64(i)) }
  function AppendInt8 (line 122) | func AppendInt8(b []byte, i int8) []byte { return AppendInt64(b, int64(i...
  function AppendInt16 (line 125) | func AppendInt16(b []byte, i int16) []byte { return AppendInt64(b, int64...
  function AppendInt32 (line 128) | func AppendInt32(b []byte, i int32) []byte { return AppendInt64(b, int64...
  function AppendUint64 (line 131) | func AppendUint64(b []byte, u uint64) []byte {
  function AppendUint (line 160) | func AppendUint(b []byte, u uint) []byte { return AppendUint64(b, uint64...
  function AppendUint8 (line 163) | func AppendUint8(b []byte, u uint8) []byte { return AppendUint64(b, uint...
  function AppendByte (line 166) | func AppendByte(b []byte, u byte) []byte { return AppendUint8(b, uint8(u...
  function AppendUint16 (line 169) | func AppendUint16(b []byte, u uint16) []byte { return AppendUint64(b, ui...
  function AppendUint32 (line 172) | func AppendUint32(b []byte, u uint32) []byte { return AppendUint64(b, ui...
  function AppendBytes (line 175) | func AppendBytes(b []byte, bts []byte) []byte {
  function AppendBool (line 197) | func AppendBool(b []byte, t bool) []byte {
  function AppendString (line 205) | func AppendString(b []byte, s string) []byte {
  function AppendStringFromBytes (line 232) | func AppendStringFromBytes(b []byte, str []byte) []byte {
  function AppendComplex64 (line 258) | func AppendComplex64(b []byte, c complex64) []byte {
  function AppendComplex128 (line 268) | func AppendComplex128(b []byte, c complex128) []byte {
  function AppendTime (line 278) | func AppendTime(b []byte, t time.Time) []byte {
  function AppendMapStrStr (line 290) | func AppendMapStrStr(b []byte, m map[string]string) []byte {
  function AppendMapStrIntf (line 302) | func AppendMapStrIntf(b []byte, m map[string]interface{}) ([]byte, error) {
  function AppendIntf (line 325) | func AppendIntf(b []byte, i interface{}) ([]byte, error) {

FILE: vendor/golang.org/x/crypto/bcrypt/base64.go
  constant alphabet (line 9) | alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345...
  function base64Encode (line 13) | func base64Encode(src []byte) []byte {
  function base64Decode (line 23) | func base64Decode(src []byte) ([]byte, error) {

FILE: vendor/golang.org/x/crypto/bcrypt/bcrypt.go
  constant MinCost (line 21) | MinCost     int = 4
  constant MaxCost (line 22) | MaxCost     int = 31
  constant DefaultCost (line 23) | DefaultCost int = 10
  type HashVersionTooNewError (line 36) | type HashVersionTooNewError
    method Error (line 38) | func (hv HashVersionTooNewError) Error() string {
  type InvalidHashPrefixError (line 43) | type InvalidHashPrefixError
    method Error (line 45) | func (ih InvalidHashPrefixError) Error() string {
  type InvalidCostError (line 49) | type InvalidCostError
    method Error (line 51) | func (ic InvalidCostError) Error() string {
  constant majorVersion (line 56) | majorVersion       = '2'
  constant minorVersion (line 57) | minorVersion       = 'a'
  constant maxSaltSize (line 58) | maxSaltSize        = 16
  constant maxCryptedHashSize (line 59) | maxCryptedHashSize = 23
  constant encodedSaltSize (line 60) | encodedSaltSize    = 22
  constant encodedHashSize (line 61) | encodedHashSize    = 31
  constant minHashSize (line 62) | minHashSize        = 59
  type hashed (line 76) | type hashed struct
    method Hash (line 233) | func (p *hashed) Hash() []byte {
    method decodeVersion (line 255) | func (p *hashed) decodeVersion(sbytes []byte) (int, error) {
    method decodeCost (line 272) | func (p *hashed) decodeCost(sbytes []byte) (int, error) {
    method String (line 285) | func (p *hashed) String() string {
  function GenerateFromPassword (line 88) | func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
  function CompareHashAndPassword (line 98) | func CompareHashAndPassword(hashedPassword, password []byte) error {
  function Cost (line 121) | func Cost(hashedPassword []byte) (int, error) {
  function newFromPassword (line 129) | func newFromPassword(password []byte, cost int) (*hashed, error) {
  function newFromHash (line 158) | func newFromHash(hashedSecret []byte) (*hashed, error) {
  function bcrypt (line 186) | func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
  function expensiveBlowfishSetup (line 207) | func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blow...
  function checkCost (line 289) | func checkCost(cost int) error {

FILE: vendor/golang.org/x/crypto/blowfish/block.go
  function getNextWord (line 9) | func getNextWord(b []byte, pos *int) uint32 {
  function ExpandKey (line 28) | func ExpandKey(key []byte, c *Cipher) {
  function expandKeyWithSalt (line 71) | func expandKeyWithSalt(key []byte, salt []byte, c *Cipher) {
  function encryptBlock (line 115) | func encryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {
  function decryptBlock (line 138) | func decryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {

FILE: vendor/golang.org/x/crypto/blowfish/cipher.go
  constant BlockSize (line 14) | BlockSize = 8
  type Cipher (line 17) | type Cipher struct
    method BlockSize (line 60) | func (c *Cipher) BlockSize() int { return BlockSize }
    method Encrypt (line 67) | func (c *Cipher) Encrypt(dst, src []byte) {
    method Decrypt (line 77) | func (c *Cipher) Decrypt(dst, src []byte) {
  type KeySizeError (line 22) | type KeySizeError
    method Error (line 24) | func (k KeySizeError) Error() string {
  function NewCipher (line 30) | func NewCipher(key []byte) (*Cipher, error) {
  function NewSaltedCipher (line 44) | func NewSaltedCipher(key, salt []byte) (*Cipher, error) {
  function initCipher (line 85) | func initCipher(c *Cipher) {

FILE: vendor/gopkg.in/mgo.v2/auth.go
  type authCmd (line 41) | type authCmd struct
  type startSaslCmd (line 49) | type startSaslCmd struct
  type authResult (line 53) | type authResult struct
  type getNonceCmd (line 58) | type getNonceCmd struct
  type getNonceResult (line 62) | type getNonceResult struct
  type logoutCmd (line 68) | type logoutCmd struct
  type saslCmd (line 72) | type saslCmd struct
  type saslResult (line 80) | type saslResult struct
  type saslStepper (line 90) | type saslStepper interface
  method getNonce (line 95) | func (socket *mongoSocket) getNonce() (nonce string, err error) {
  method resetNonce (line 115) | func (socket *mongoSocket) resetNonce() {
  method Login (line 161) | func (socket *mongoSocket) Login(cred Credential) error {
  method loginClassic (line 204) | func (socket *mongoSocket) loginClassic(cred Credential) error {
  type authX509Cmd (line 238) | type authX509Cmd struct
  method loginX509 (line 244) | func (socket *mongoSocket) loginX509(cred Credential) error {
  method loginPlain (line 259) | func (socket *mongoSocket) loginPlain(cred Credential) error {
  method loginSASL (line 274) | func (socket *mongoSocket) loginSASL(cred Credential) error {
  function saslNewScram (line 356) | func saslNewScram(cred Credential) *saslScram {
  type saslScram (line 363) | type saslScram struct
    method Close (line 368) | func (s *saslScram) Close() {}
    method Step (line 370) | func (s *saslScram) Step(serverData []byte) (clientData []byte, done b...
  method loginRun (line 375) | func (socket *mongoSocket) loginRun(db string, query, result interface{}...
  method Logout (line 410) | func (socket *mongoSocket) Logout(db string) {
  method LogoutAll (line 420) | func (socket *mongoSocket) LogoutAll() {
  method flushLogout (line 430) | func (socket *mongoSocket) flushLogout() (ops []interface{}) {
  method dropAuth (line 447) | func (socket *mongoSocket) dropAuth(db string) (cred Credential, found b...
  method dropLogout (line 458) | func (socket *mongoSocket) dropLogout(cred Credential) (found bool) {

FILE: vendor/gopkg.in/mgo.v2/bson/bson.go
  type Getter (line 62) | type Getter interface
  type Setter (line 93) | type Setter interface
  type M (line 110) | type M
  type D (line 119) | type D
    method Map (line 128) | func (d D) Map() (m M) {
  type DocElem (line 122) | type DocElem struct
  type Raw (line 145) | type Raw struct
    method Unmarshal (line 560) | func (raw Raw) Unmarshal(out interface{}) (err error) {
  type RawD (line 154) | type RawD
  type RawDocElem (line 157) | type RawDocElem struct
  type ObjectId (line 167) | type ObjectId
    method String (line 261) | func (id ObjectId) String() string {
    method Hex (line 266) | func (id ObjectId) Hex() string {
    method MarshalJSON (line 271) | func (id ObjectId) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 278) | func (id *ObjectId) UnmarshalJSON(data []byte) error {
    method MarshalText (line 296) | func (id ObjectId) MarshalText() ([]byte, error) {
    method UnmarshalText (line 301) | func (id *ObjectId) UnmarshalText(data []byte) error {
    method Valid (line 319) | func (id ObjectId) Valid() bool {
    method byteSlice (line 325) | func (id ObjectId) byteSlice(start, end int) []byte {
    method Time (line 334) | func (id ObjectId) Time() time.Time {
    method Machine (line 342) | func (id ObjectId) Machine() []byte {
    method Pid (line 348) | func (id ObjectId) Pid() uint16 {
    method Counter (line 354) | func (id ObjectId) Counter() int32 {
  function ObjectIdHex (line 172) | func ObjectIdHex(s string) ObjectId {
  function IsObjectIdHex (line 182) | func IsObjectIdHex(s string) bool {
  function readRandomUint32 (line 195) | func readRandomUint32() uint32 {
  function readMachineId (line 210) | func readMachineId() []byte {
  function NewObjectId (line 228) | func NewObjectId() ObjectId {
  function NewObjectIdWithTime (line 253) | func NewObjectIdWithTime(t time.Time) ObjectId {
  type Symbol (line 362) | type Symbol
  function Now (line 369) | func Now() time.Time {
  type MongoTimestamp (line 375) | type MongoTimestamp
  type orderKey (line 377) | type orderKey
  type undefined (line 387) | type undefined struct
  type Binary (line 402) | type Binary struct
  type RegEx (line 415) | type RegEx struct
  type JavaScript (line 423) | type JavaScript struct
  type DBPointer (line 432) | type DBPointer struct
  constant initialBufferSize (line 437) | initialBufferSize = 64
  function handleErr (line 439) | func handleErr(err *error) {
  function Marshal (line 491) | func Marshal(in interface{}) (out []byte, err error) {
  function Unmarshal (line 533) | func Unmarshal(in []byte, out interface{}) (err error) {
  type TypeError (line 581) | type TypeError struct
    method Error (line 586) | func (e *TypeError) Error() string {
  type structInfo (line 593) | type structInfo struct
  type fieldInfo (line 600) | type fieldInfo struct
  type externalPanic (line 611) | type externalPanic
    method String (line 613) | func (e externalPanic) String() string {
  function getStructInfo (line 617) | func getStructInfo(st reflect.Type) (*structInfo, error) {

FILE: vendor/gopkg.in/mgo.v2/bson/decode.go
  type decoder (line 40) | type decoder struct
    method readDocTo (line 128) | func (d *decoder) readDocTo(out reflect.Value) {
    method readArrayDocTo (line 290) | func (d *decoder) readArrayDocTo(out reflect.Value) {
    method readSliceDoc (line 325) | func (d *decoder) readSliceDoc(t reflect.Type) interface{} {
    method readDocElems (line 371) | func (d *decoder) readDocElems(typ reflect.Type) reflect.Value {
    method readRawDocElems (line 388) | func (d *decoder) readRawDocElems(typ reflect.Type) reflect.Value {
    method readDocWith (line 405) | func (d *decoder) readDocWith(f func(kind byte, name string)) {
    method dropElem (line 433) | func (d *decoder) dropElem(kind byte) {
    method readElemTo (line 440) | func (d *decoder) readElemTo(out reflect.Value, kind byte) (good bool) {
    method readRegEx (line 746) | func (d *decoder) readRegEx() RegEx {
    method readBinary (line 753) | func (d *decoder) readBinary() Binary {
    method readStr (line 765) | func (d *decoder) readStr() string {
    method readCStr (line 774) | func (d *decoder) readCStr() string {
    method readBool (line 790) | func (d *decoder) readBool() bool {
    method readFloat64 (line 801) | func (d *decoder) readFloat64() float64 {
    method readInt32 (line 805) | func (d *decoder) readInt32() int32 {
    method readInt64 (line 813) | func (d *decoder) readInt64() int64 {
    method readByte (line 825) | func (d *decoder) readByte() byte {
    method readBytes (line 834) | func (d *decoder) readBytes(length int32) []byte {
  function newDecoder (line 48) | func newDecoder(in []byte) *decoder {
  function corrupted (line 55) | func corrupted() {
  function settableValueOf (line 59) | func settableValueOf(i interface{}) reflect.Value {
  constant setterUnknown (line 70) | setterUnknown = iota
  constant setterNone (line 71) | setterNone
  constant setterType (line 72) | setterType
  constant setterAddr (line 73) | setterAddr
  function init (line 80) | func init() {
  function setterStyle (line 86) | func setterStyle(outt reflect.Type) int {
  function getSetter (line 105) | func getSetter(outt reflect.Type, out reflect.Value) Setter {
  function clearMap (line 121) | func clearMap(m reflect.Value) {

FILE: vendor/gopkg.in/mgo.v2/bson/encode.go
  constant itoaCacheSize (line 59) | itoaCacheSize = 32
  function init (line 63) | func init() {
  function itoa (line 70) | func itoa(i int) string {
  type encoder (line 80) | type encoder struct
    method addDoc (line 84) | func (e *encoder) addDoc(v reflect.Value) {
    method addMap (line 130) | func (e *encoder) addMap(v reflect.Value) {
    method addStruct (line 136) | func (e *encoder) addStruct(v reflect.Value) {
    method addSlice (line 203) | func (e *encoder) addSlice(v reflect.Value) {
    method addElemName (line 241) | func (e *encoder) addElemName(kind byte, name string) {
    method addElem (line 247) | func (e *encoder) addElem(name string, v reflect.Value, minSize bool) {
    method addBinary (line 456) | func (e *encoder) addBinary(subtype byte, v []byte) {
    method addStr (line 469) | func (e *encoder) addStr(v string) {
    method addCStr (line 474) | func (e *encoder) addCStr(v string) {
    method reserveInt32 (line 479) | func (e *encoder) reserveInt32() (pos int) {
    method setInt32 (line 485) | func (e *encoder) setInt32(pos int, v int32) {
    method addInt32 (line 492) | func (e *encoder) addInt32(v int32) {
    method addInt64 (line 497) | func (e *encoder) addInt64(v int64) {
    method addFloat64 (line 503) | func (e *encoder) addFloat64(v float64) {
    method addBytes (line 507) | func (e *encoder) addBytes(v ...byte) {
  function isZero (line 167) | func isZero(v reflect.Value) bool {

FILE: vendor/gopkg.in/mgo.v2/bulk.go
  type Bulk (line 24) | type Bulk struct
    method Unordered (line 131) | func (b *Bulk) Unordered() {
    method action (line 135) | func (b *Bulk) action(op bulkOp, opcount int) *bulkAction {
    method Insert (line 159) | func (b *Bulk) Insert(docs ...interface{}) {
    method Remove (line 166) | func (b *Bulk) Remove(selectors ...interface{}) {
    method RemoveAll (line 183) | func (b *Bulk) RemoveAll(selectors ...interface{}) {
    method Update (line 202) | func (b *Bulk) Update(pairs ...interface{}) {
    method UpdateAll (line 224) | func (b *Bulk) UpdateAll(pairs ...interface{}) {
    method Upsert (line 248) | func (b *Bulk) Upsert(pairs ...interface{}) {
    method Run (line 274) | func (b *Bulk) Run() (*BulkResult, error) {
    method runInsert (line 305) | func (b *Bulk) runInsert(action *bulkAction, result *BulkResult, berr ...
    method runUpdate (line 314) | func (b *Bulk) runUpdate(action *bulkAction, result *BulkResult, berr ...
    method runRemove (line 323) | func (b *Bulk) runRemove(action *bulkAction, result *BulkResult, berr ...
    method checkSuccess (line 332) | func (b *Bulk) checkSuccess(action *bulkAction, berr *BulkError, lerr ...
  type bulkOp (line 31) | type bulkOp
  constant bulkInsert (line 34) | bulkInsert bulkOp = iota + 1
  constant bulkUpdate (line 35) | bulkUpdate
  constant bulkUpdateAll (line 36) | bulkUpdateAll
  constant bulkRemove (line 37) | bulkRemove
  type bulkAction (line 40) | type bulkAction struct
  type bulkUpdateOp (line 46) | type bulkUpdateOp
  type bulkDeleteOp (line 47) | type bulkDeleteOp
  type BulkResult (line 50) | type BulkResult struct
  type BulkError (line 62) | type BulkError struct
    method Error (line 66) | func (e *BulkError) Error() string {
    method Cases (line 117) | func (e *BulkError) Cases() []BulkErrorCase {
  type bulkErrorCases (line 95) | type bulkErrorCases
    method Len (line 97) | func (slice bulkErrorCases) Len() int           { return len(slice) }
    method Less (line 98) | func (slice bulkErrorCases) Less(i, j int) bool { return slice[i].Inde...
    method Swap (line 99) | func (slice bulkErrorCases) Swap(i, j int)      { slice[i], slice[j] =...
  type BulkErrorCase (line 109) | type BulkErrorCase struct
  method Bulk (line 122) | func (c *Collection) Bulk() *Bulk {

FILE: vendor/gopkg.in/mgo.v2/cluster.go
  type mongoCluster (line 48) | type mongoCluster struct
    method Acquire (line 83) | func (cluster *mongoCluster) Acquire() {
    method Release (line 92) | func (cluster *mongoCluster) Release() {
    method LiveServers (line 110) | func (cluster *mongoCluster) LiveServers() (servers []string) {
    method removeServer (line 119) | func (cluster *mongoCluster) removeServer(server *mongoServer) {
    method isMaster (line 143) | func (cluster *mongoCluster) isMaster(socket *mongoSocket, result *isM...
    method syncServer (line 158) | func (cluster *mongoCluster) syncServer(server *mongoServer) (info *mo...
    method addServer (line 256) | func (cluster *mongoCluster) addServer(server *mongoServer, info *mong...
    method getKnownAddrs (line 293) | func (cluster *mongoCluster) getKnownAddrs() []string {
    method syncServers (line 322) | func (cluster *mongoCluster) syncServers() {
    method syncServersLoop (line 342) | func (cluster *mongoCluster) syncServersLoop() {
    method server (line 402) | func (cluster *mongoCluster) server(addr string, tcpaddr *net.TCPAddr)...
    method syncServersIteration (line 477) | func (cluster *mongoCluster) syncServersIteration(direct bool) {
    method AcquireSocket (line 581) | func (cluster *mongoCluster) AcquireSocket(mode Mode, slaveOk bool, sy...
    method CacheIndex (line 653) | func (cluster *mongoCluster) CacheIndex(cacheKey string, exists bool) {
    method HasCachedIndex (line 666) | func (cluster *mongoCluster) HasCachedIndex(cacheKey string) (result b...
    method ResetIndexCache (line 675) | func (cluster *mongoCluster) ResetIndexCache() {
  function newCluster (line 66) | func newCluster(userSeeds []string, direct, failFast bool, dial dialer, ...
  type isMasterResult (line 131) | type isMasterResult struct
  type possibleTimeout (line 152) | type possibleTimeout interface
  type syncKind (line 249) | type syncKind
  constant completeSync (line 252) | completeSync syncKind = true
  constant partialSync (line 253) | partialSync  syncKind = false
  constant syncServersDelay (line 331) | syncServersDelay = 30 * time.Second
  constant syncShortDelay (line 332) | syncShortDelay = 500 * time.Millisecond
  function resolveAddr (line 412) | func resolveAddr(addr string) (*net.TCPAddr, error) {
  type pendingAdd (line 472) | type pendingAdd struct

FILE: vendor/gopkg.in/mgo.v2/gridfs.go
  type GridFS (line 42) | type GridFS struct
    method newFile (line 104) | func (gfs *GridFS) newFile() *GridFile {
    method Create (line 153) | func (gfs *GridFS) Create(name string) (file *GridFile, err error) {
    method OpenId (line 197) | func (gfs *GridFS) OpenId(id interface{}) (file *GridFile, err error) {
    method Open (line 241) | func (gfs *GridFS) Open(name string) (file *GridFile, err error) {
    method OpenNext (line 280) | func (gfs *GridFS) OpenNext(iter *Iter, file **GridFile) bool {
    method Find (line 312) | func (gfs *GridFS) Find(query interface{}) *Query {
    method RemoveId (line 317) | func (gfs *GridFS) RemoveId(id interface{}) error {
    method Remove (line 331) | func (gfs *GridFS) Remove(name string) (err error) {
  type gfsFileMode (line 47) | type gfsFileMode
  constant gfsClosed (line 50) | gfsClosed  gfsFileMode = 0
  constant gfsReading (line 51) | gfsReading gfsFileMode = 1
  constant gfsWriting (line 52) | gfsWriting gfsFileMode = 2
  type GridFile (line 55) | type GridFile struct
    method assertMode (line 345) | func (file *GridFile) assertMode(mode gfsFileMode) {
    method SetChunkSize (line 366) | func (file *GridFile) SetChunkSize(bytes int) {
    method Id (line 375) | func (file *GridFile) Id() interface{} {
    method SetId (line 383) | func (file *GridFile) SetId(id interface{}) {
    method Name (line 392) | func (file *GridFile) Name() string {
    method SetName (line 401) | func (file *GridFile) SetName(name string) {
    method ContentType (line 410) | func (file *GridFile) ContentType() string {
    method SetC
Condensed preview — 273 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,143K chars).
[
  {
    "path": ".dockerignore",
    "chars": 2,
    "preview": "*\n"
  },
  {
    "path": ".gitignore",
    "chars": 7,
    "preview": "build/\n"
  },
  {
    "path": ".travis.yml",
    "chars": 31,
    "preview": "language: go\ngo:\n - 1.6\n - tip\n"
  },
  {
    "path": "Dockerfile",
    "chars": 634,
    "preview": "#\n# MailHog Dockerfile\n#\n\nFROM golang:1.18-alpine as builder\n\n# Install MailHog:\nRUN apk --no-cache add --virtual build-"
  },
  {
    "path": "LICENSE.md",
    "chars": 1082,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 - 2016 Ian Kent\n\nPermission is hereby granted, free of charge, to any person o"
  },
  {
    "path": "Makefile",
    "chars": 1067,
    "preview": "VERSION=1.0.0\n\nall: fmt combined\n\ncombined:\n\tgo install .\n\nrelease: tag release-deps \n\tgox -ldflags \"-X main.version=${V"
  },
  {
    "path": "README.md",
    "chars": 4235,
    "preview": "MailHog [ ![Download](https://img.shields.io/github/release/mailhog/MailHog.svg) ](https://github.com/mailhog/MailHog/re"
  },
  {
    "path": "config/config.go",
    "chars": 761,
    "preview": "package config\n\nimport (\n\t\"flag\"\n\n\t\"github.com/ian-kent/envconf\"\n)\n\nfunc DefaultConfig() *Config {\n\treturn &Config{\n\t\tAu"
  },
  {
    "path": "docs/APIv1.md",
    "chars": 1098,
    "preview": "MailHog API v1\n==============\n\nThe v1 API is a RESTful HTTP JSON API.\n\n### GET /api/v1/events\n\nStreams new messages usin"
  },
  {
    "path": "docs/APIv2/swagger-2.0.json",
    "chars": 13247,
    "preview": "{\n    \"swagger\": \"2.0\",\n    \"info\": {\n        \"version\": \"2.0.0\",\n        \"title\": \"MailHog API\"\n    },\n    \"paths\": {\n "
  },
  {
    "path": "docs/APIv2/swagger-2.0.yaml",
    "chars": 5616,
    "preview": "swagger: '2.0'\n\ninfo:\n  version: \"2.0.0\"\n  title: MailHog API\n\npaths:\n  /api/v2/messages:\n    get:\n      description: |\n"
  },
  {
    "path": "docs/APIv2.md",
    "chars": 220,
    "preview": "MailHog API v2\n==============\n\nThe v2 API is hopefully less of a mess than v1.\n\nThe specification is written in [Swagger"
  },
  {
    "path": "docs/Auth.md",
    "chars": 1112,
    "preview": "Authentication\n==============\n\nHTTP basic authentication is supported using a password file.\n\nSee [example-auth](example"
  },
  {
    "path": "docs/BUILD.md",
    "chars": 1074,
    "preview": "Building MailHog\n================\n\nMailHog is built using `make`, and using [this Makefile](../Makefile).\n\nIf you aren't"
  },
  {
    "path": "docs/CONFIG.md",
    "chars": 3015,
    "preview": "Configuring MailHog\n===================\n\nYou can configure MailHog using command line options or environment variables:\n"
  },
  {
    "path": "docs/DEPLOY.md",
    "chars": 2495,
    "preview": "Deploying MailHog\n=================\n\n### Command line\n\nYou can run MailHog locally from the command line.\n\n    go get gi"
  },
  {
    "path": "docs/JIM.md",
    "chars": 1854,
    "preview": "Introduction to Jim\n===================\n\nJim is the MailHog Chaos Monkey, inspired by Netflix.\n\nYou can invite Jim to th"
  },
  {
    "path": "docs/LIBRARIES.md",
    "chars": 258,
    "preview": "MailHog libraries\n=================\n\nIf you've created a MailHog client library, open a pull request and add it!\n\n* [API"
  },
  {
    "path": "docs/RELEASES.md",
    "chars": 7888,
    "preview": "MailHog Releases\n================\n\n### [v1.0.0](https://github.com/mailhog/MailHog/releases/v1.0.0)\n\nThere's still outst"
  },
  {
    "path": "docs/example-auth",
    "chars": 66,
    "preview": "test:$2a$04$qxRo.ftFoNep7ld/5jfKtuBTnGqff/fZVyj53mUC5sVf9dtDLAi/S\n"
  },
  {
    "path": "main.go",
    "chars": 2951,
    "preview": "package main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\n\tgohttp \"net/http\"\n\n\t\"github.com/gorilla/pat\"\n\t\"github.com/ian-kent/go-log/"
  },
  {
    "path": "snapcraft.yaml",
    "chars": 566,
    "preview": "name: mailhog\nsummary: Web and API based SMTP testing\ndescription: |\n MailHog is an email testing tool for developers:\n "
  },
  {
    "path": "vendor/github.com/gorilla/context/LICENSE",
    "chars": 1476,
    "preview": "Copyright (c) 2012 Rodrigo Moraes. All rights reserved.\n\nRedistribution and use in source and binary forms, with or with"
  },
  {
    "path": "vendor/github.com/gorilla/context/README.md",
    "chars": 659,
    "preview": "context\n=======\n[![Build Status](https://travis-ci.org/gorilla/context.png?branch=master)](https://travis-ci.org/gorilla"
  },
  {
    "path": "vendor/github.com/gorilla/context/context.go",
    "chars": 3583,
    "preview": "// Copyright 2012 The Gorilla Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// lic"
  },
  {
    "path": "vendor/github.com/gorilla/context/doc.go",
    "chars": 2843,
    "preview": "// Copyright 2012 The Gorilla Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// lic"
  },
  {
    "path": "vendor/github.com/gorilla/mux/LICENSE",
    "chars": 1476,
    "preview": "Copyright (c) 2012 Rodrigo Moraes. All rights reserved.\n\nRedistribution and use in source and binary forms, with or with"
  },
  {
    "path": "vendor/github.com/gorilla/mux/README.md",
    "chars": 10376,
    "preview": "gorilla/mux\n===\n[![GoDoc](https://godoc.org/github.com/gorilla/mux?status.svg)](https://godoc.org/github.com/gorilla/mux"
  },
  {
    "path": "vendor/github.com/gorilla/mux/context_gorilla.go",
    "chars": 380,
    "preview": "// +build !go1.7\n\npackage mux\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/gorilla/context\"\n)\n\nfunc contextGet(r *http.Request, k"
  },
  {
    "path": "vendor/github.com/gorilla/mux/context_native.go",
    "chars": 380,
    "preview": "// +build go1.7\n\npackage mux\n\nimport (\n\t\"context\"\n\t\"net/http\"\n)\n\nfunc contextGet(r *http.Request, key interface{}) inter"
  },
  {
    "path": "vendor/github.com/gorilla/mux/doc.go",
    "chars": 8528,
    "preview": "// Copyright 2012 The Gorilla Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// lic"
  },
  {
    "path": "vendor/github.com/gorilla/mux/mux.go",
    "chars": 15856,
    "preview": "// Copyright 2012 The Gorilla Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// lic"
  },
  {
    "path": "vendor/github.com/gorilla/mux/regexp.go",
    "chars": 8956,
    "preview": "// Copyright 2012 The Gorilla Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// lic"
  },
  {
    "path": "vendor/github.com/gorilla/mux/route.go",
    "chars": 18537,
    "preview": "// Copyright 2012 The Gorilla Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// lic"
  },
  {
    "path": "vendor/github.com/gorilla/pat/LICENSE",
    "chars": 1476,
    "preview": "Copyright (c) 2012 Rodrigo Moraes. All rights reserved.\n\nRedistribution and use in source and binary forms, with or with"
  },
  {
    "path": "vendor/github.com/gorilla/pat/README.md",
    "chars": 1799,
    "preview": "pat\n===\n[![GoDoc](https://godoc.org/github.com/gorilla/pat?status.svg)](https://godoc.org/github.com/gorilla/pat)\n[![Bui"
  },
  {
    "path": "vendor/github.com/gorilla/pat/doc.go",
    "chars": 2320,
    "preview": "// Copyright 2012 The Gorilla Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// lic"
  },
  {
    "path": "vendor/github.com/gorilla/pat/pat.go",
    "chars": 3385,
    "preview": "// Copyright 2012 The Gorilla Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// lic"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/AUTHORS",
    "chars": 190,
    "preview": "# This is the official list of Gorilla WebSocket authors for copyright\n# purposes.\n#\n# Please keep the list sorted.\n\nGar"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/LICENSE",
    "chars": 1312,
    "preview": "Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved.\n\nRedistribution and use in source and binary form"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/README.md",
    "chars": 3924,
    "preview": "# Gorilla WebSocket\n\nGorilla WebSocket is a [Go](http://golang.org/) implementation of the\n[WebSocket](http://www.rfc-ed"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/client.go",
    "chars": 10946,
    "preview": "// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.\n// Use of this source code is governed by a BSD-st"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/client_clone.go",
    "chars": 348,
    "preview": "// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.\n// Use of this source code is governed by a BSD-st"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/client_clone_legacy.go",
    "chars": 1371,
    "preview": "// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.\n// Use of this source code is governed by a BSD-st"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/compression.go",
    "chars": 3192,
    "preview": "// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.\n// Use of this source code is governed by a BSD-st"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/conn.go",
    "chars": 30334,
    "preview": "// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.\n// Use of this source code is governed by a BSD-st"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/conn_read.go",
    "chars": 380,
    "preview": "// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.\n// Use of this source code is governed by a BSD-st"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/conn_read_legacy.go",
    "chars": 440,
    "preview": "// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.\n// Use of this source code is governed by a BSD-st"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/doc.go",
    "chars": 6926,
    "preview": "// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.\n// Use of this source code is governed by a BSD-st"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/json.go",
    "chars": 1373,
    "preview": "// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.\n// Use of this source code is governed by a BSD-st"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/mask.go",
    "chars": 1155,
    "preview": "// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.  Use of\n// this source code is governed by a BSD-s"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/mask_safe.go",
    "chars": 339,
    "preview": "// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.  Use of\n// this source code is governed by a BSD-s"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/prepared.go",
    "chars": 2978,
    "preview": "// Copyright 2017 The Gorilla WebSocket Authors. All rights reserved.\n// Use of this source code is governed by a BSD-st"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/server.go",
    "chars": 9704,
    "preview": "// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.\n// Use of this source code is governed by a BSD-st"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/util.go",
    "chars": 4854,
    "preview": "// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.\n// Use of this source code is governed by a BSD-st"
  },
  {
    "path": "vendor/github.com/ian-kent/envconf/LICENSE.md",
    "chars": 1075,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 Ian Kent\n\nPermission is hereby granted, free of charge, to any person obtainin"
  },
  {
    "path": "vendor/github.com/ian-kent/envconf/README.md",
    "chars": 535,
    "preview": "envconf\n=======\n\nConfigure your Go application from the environment.\n\nSupports most basic Go types and works nicely with"
  },
  {
    "path": "vendor/github.com/ian-kent/envconf/envconf.go",
    "chars": 1796,
    "preview": "package envconf\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nvar (\n\t// ErrUnsupportedType is returned if the type "
  },
  {
    "path": "vendor/github.com/ian-kent/go-log/LICENSE.md",
    "chars": 1075,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 Ian Kent\n\nPermission is hereby granted, free of charge, to any person obtainin"
  },
  {
    "path": "vendor/github.com/ian-kent/go-log/appenders/appender.go",
    "chars": 451,
    "preview": "package appenders\n\n/*\n\nAppenders control the flow of data from a logger to an output.\n\nFor example, a Console appender o"
  },
  {
    "path": "vendor/github.com/ian-kent/go-log/appenders/console.go",
    "chars": 585,
    "preview": "package appenders\n\nimport (\n\t\"fmt\"\n\t\"github.com/ian-kent/go-log/layout\"\n\t\"github.com/ian-kent/go-log/levels\"\n)\n\ntype con"
  },
  {
    "path": "vendor/github.com/ian-kent/go-log/appenders/fluentd.go",
    "chars": 1283,
    "preview": "package appenders\n\n// TODO add tests\n\nimport (\n\t\"github.com/ian-kent/go-log/layout\"\n\t\"github.com/ian-kent/go-log/levels\""
  },
  {
    "path": "vendor/github.com/ian-kent/go-log/appenders/multiple_appender.go",
    "chars": 723,
    "preview": "package appenders\n\nimport (\n\t\"github.com/ian-kent/go-log/layout\"\n\t\"github.com/ian-kent/go-log/levels\"\n)\n\ntype multipleAp"
  },
  {
    "path": "vendor/github.com/ian-kent/go-log/appenders/rollingfile.go",
    "chars": 2379,
    "preview": "package appenders\n\nimport (\n\t\"fmt\"\n\t\"github.com/ian-kent/go-log/layout\"\n\t\"github.com/ian-kent/go-log/levels\"\n\t\"os\"\n\t\"str"
  },
  {
    "path": "vendor/github.com/ian-kent/go-log/appenders/rollingfile_test.log",
    "chars": 17,
    "preview": "Yet another test\n"
  },
  {
    "path": "vendor/github.com/ian-kent/go-log/appenders/rollingfile_test.log.1",
    "chars": 26,
    "preview": "Test message\nAnother test\n"
  },
  {
    "path": "vendor/github.com/ian-kent/go-log/layout/basic.go",
    "chars": 301,
    "preview": "package layout\n\nimport (\n\t\"fmt\"\n\t\"github.com/ian-kent/go-log/levels\"\n)\n\ntype basicLayout struct {\n\tLayout\n}\n\nfunc Basic("
  },
  {
    "path": "vendor/github.com/ian-kent/go-log/layout/layout.go",
    "chars": 439,
    "preview": "package layout\n\n/*\n\nLayouts control the formatting of data into a printable log string.\n\nFor example, the Basic layout p"
  },
  {
    "path": "vendor/github.com/ian-kent/go-log/layout/pattern.go",
    "chars": 2514,
    "preview": "package layout\n\nimport (\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/ian-ke"
  },
  {
    "path": "vendor/github.com/ian-kent/go-log/levels/levels.go",
    "chars": 472,
    "preview": "package levels\n\ntype LogLevel int\n\nconst (\n\tFATAL LogLevel = iota\n\tERROR\n\tINFO\n\tWARN\n\tDEBUG\n\tTRACE\n\tINHERIT\n)\n\nvar Strin"
  },
  {
    "path": "vendor/github.com/ian-kent/go-log/log/log.go",
    "chars": 1523,
    "preview": "package log\n\nimport (\n\t\"github.com/ian-kent/go-log/levels\"\n\t\"github.com/ian-kent/go-log/logger\"\n\t\"strings\"\n)\n\nvar global"
  },
  {
    "path": "vendor/github.com/ian-kent/go-log/logger/logger.go",
    "chars": 5040,
    "preview": "package logger\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/ian-kent/go-log/appenders\"\n\t\"github.com/ian-kent/go-log/l"
  },
  {
    "path": "vendor/github.com/ian-kent/goose/LICENSE.md",
    "chars": 1075,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 Ian Kent\n\nPermission is hereby granted, free of charge, to any person obtainin"
  },
  {
    "path": "vendor/github.com/ian-kent/goose/README.md",
    "chars": 389,
    "preview": "Goose - Go Server-Sent Events [![GoDoc](https://godoc.org/github.com/ian-kent/goose?status.svg)](https://godoc.org/githu"
  },
  {
    "path": "vendor/github.com/ian-kent/goose/goose.go",
    "chars": 2459,
    "preview": "package goose\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"strings\"\n\t\"sync\"\n)\n\nvar (\n\t// ErrUnableToHijackRe"
  },
  {
    "path": "vendor/github.com/ian-kent/linkio/README.md",
    "chars": 1539,
    "preview": "linkio [![GoDoc](https://godoc.org/github.com/ian-kent/linkio?status.svg)](https://godoc.org/github.com/ian-kent/linkio)"
  },
  {
    "path": "vendor/github.com/ian-kent/linkio/linkio.go",
    "chars": 4953,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/jtolds/gls/LICENSE",
    "chars": 1063,
    "preview": "Copyright (c) 2013, Space Monkey, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\n"
  },
  {
    "path": "vendor/github.com/jtolds/gls/README.md",
    "chars": 3565,
    "preview": "gls\n===\n\nGoroutine local storage\n\n### IMPORTANT NOTE ###\n\nIt is my duty to point you to https://blog.golang.org/context,"
  },
  {
    "path": "vendor/github.com/jtolds/gls/context.go",
    "chars": 4212,
    "preview": "// Package gls implements goroutine-local storage.\npackage gls\n\nimport (\n\t\"sync\"\n)\n\nvar (\n\tmgrRegistry    = make(map[*Co"
  },
  {
    "path": "vendor/github.com/jtolds/gls/gen_sym.go",
    "chars": 380,
    "preview": "package gls\n\nimport (\n\t\"sync\"\n)\n\nvar (\n\tkeyMtx     sync.Mutex\n\tkeyCounter uint64\n)\n\n// ContextKey is a throwaway value y"
  },
  {
    "path": "vendor/github.com/jtolds/gls/gid.go",
    "chars": 699,
    "preview": "package gls\n\nvar (\n\tstackTagPool = &idPool{}\n)\n\n// Will return this goroutine's identifier if set. If you always need a\n"
  },
  {
    "path": "vendor/github.com/jtolds/gls/id_pool.go",
    "chars": 633,
    "preview": "package gls\n\n// though this could probably be better at keeping ids smaller, the goal of\n// this class is to keep a regi"
  },
  {
    "path": "vendor/github.com/jtolds/gls/stack_tags.go",
    "chars": 3626,
    "preview": "package gls\n\n// so, basically, we're going to encode integer tags in base-16 on the stack\n\nconst (\n\tbitWidth       = 4\n\t"
  },
  {
    "path": "vendor/github.com/jtolds/gls/stack_tags_js.go",
    "chars": 1443,
    "preview": "// +build js\n\npackage gls\n\n// This file is used for GopherJS builds, which don't have normal runtime\n// stack trace supp"
  },
  {
    "path": "vendor/github.com/jtolds/gls/stack_tags_main.go",
    "chars": 399,
    "preview": "// +build !js\n\npackage gls\n\n// This file is used for standard Go builds, which have the expected runtime\n// support\n\nimp"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-Server/LICENSE.md",
    "chars": 1082,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 - 2016 Ian Kent\n\nPermission is hereby granted, free of charge, to any person o"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-Server/Makefile",
    "chars": 297,
    "preview": "DEPS = $(go list -f '{{range .TestImports}}{{.}} {{end}}' ./...)\n\nall: release-deps fmt combined\n\ncombined:\n\tgo install "
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-Server/README.md",
    "chars": 347,
    "preview": "MailHog Server [![Build Status](https://travis-ci.org/mailhog/MailHog-Server.svg?branch=master)](https://travis-ci.org/m"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-Server/api/api.go",
    "chars": 404,
    "preview": "package api\n\nimport (\n\tgohttp \"net/http\"\n\n\t\"github.com/gorilla/pat\"\n\t\"github.com/mailhog/MailHog-Server/config\"\n)\n\nfunc "
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-Server/api/v1.go",
    "chars": 10382,
    "preview": "package api\n\nimport (\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/smtp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"githu"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-Server/api/v2.go",
    "chars": 6412,
    "preview": "package api\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"strconv\"\n\n\t\"github.com/gorilla/pat\"\n\t\"github.com/ian-kent/go-log/lo"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-Server/config/config.go",
    "chars": 4444,
    "preview": "package config\n\nimport (\n\t\"encoding/json\"\n\t\"flag\"\n\t\"io/ioutil\"\n\t\"log\"\n\n\t\"github.com/ian-kent/envconf\"\n\t\"github.com/mailh"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-Server/main.go",
    "chars": 913,
    "preview": "package main\n\nimport (\n\t\"flag\"\n\t\"os\"\n\n\tgohttp \"net/http\"\n\n\t\"github.com/ian-kent/go-log/log\"\n\t\"github.com/mailhog/MailHog"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-Server/monkey/jim.go",
    "chars": 3482,
    "preview": "package monkey\n\nimport (\n\t\"flag\"\n\t\"math/rand\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/ian-kent/linkio\"\n)\n\n// Jim is a chaos monkey\n"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-Server/monkey/monkey.go",
    "chars": 922,
    "preview": "package monkey\n\nimport (\n\t\"net\"\n\n\t\"github.com/ian-kent/linkio\"\n)\n\n// ChaosMonkey should be implemented by chaos monkeys!"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-Server/smtp/session.go",
    "chars": 4113,
    "preview": "package smtp\n\n// http://www.rfc-editor.org/rfc/rfc5321.txt\n\nimport (\n\t\"io\"\n\t\"log\"\n\t\"strings\"\n\n\t\"github.com/ian-kent/link"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-Server/smtp/session_test.go",
    "chars": 3189,
    "preview": "package smtp\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\t\"testing\"\n\n\t. \"github.com/smartystreets/goconvey/convey\"\n\n\t\"github.com/mailhog"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-Server/smtp/smtp.go",
    "chars": 777,
    "preview": "package smtp\n\nimport (\n\t\"io\"\n\t\"log\"\n\t\"net\"\n\n\t\"github.com/mailhog/MailHog-Server/config\"\n)\n\nfunc Listen(cfg *config.Confi"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-Server/websockets/connection.go",
    "chars": 1681,
    "preview": "package websockets\n\nimport (\n\t\"time\"\n\n\t\"github.com/gorilla/websocket\"\n)\n\nconst (\n\t// Time allowed to write a message to "
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-Server/websockets/hub.go",
    "chars": 1468,
    "preview": "package websockets\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/gorilla/websocket\"\n\t\"github.com/ian-kent/go-log/log\"\n)\n\ntype Hub "
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-UI/LICENSE.md",
    "chars": 1082,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 - 2016 Ian Kent\n\nPermission is hereby granted, free of charge, to any person o"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-UI/Makefile",
    "chars": 258,
    "preview": "all: bindata fmt ui\n\nui:\n\tgo install .\n\nbindata: bindata-deps\n\t-rm assets/assets.go\n\tgo-bindata -o assets/assets.go -pkg"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-UI/README.md",
    "chars": 331,
    "preview": "MailHog UI [![Build Status](https://travis-ci.org/mailhog/MailHog-UI.svg?branch=master)](https://travis-ci.org/mailhog/M"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-UI/assets/assets.go",
    "chars": 2273729,
    "preview": "// Code generated by go-bindata.\n// sources:\n// assets/css/bootstrap-3.3.2.min.css\n// assets/css/jquery-ui-1.10.4-smooth"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-UI/config/config.go",
    "chars": 702,
    "preview": "package config\n\nimport (\n\t\"flag\"\n\n\t\"github.com/ian-kent/envconf\"\n)\n\nfunc DefaultConfig() *Config {\n\treturn &Config{\n\t\tAP"
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-UI/main.go",
    "chars": 975,
    "preview": "package main\n\nimport (\n\t\"flag\"\n\t\"os\"\n\n\tgohttp \"net/http\"\n\n\t\"github.com/gorilla/pat\"\n\t\"github.com/ian-kent/go-log/log\"\n\t\""
  },
  {
    "path": "vendor/github.com/mailhog/MailHog-UI/web/web.go",
    "chars": 2886,
    "preview": "package web\n\nimport (\n\t\"bytes\"\n\t\"html/template\"\n\t\"log\"\n\t\"mime\"\n\t\"net/http\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/gor"
  },
  {
    "path": "vendor/github.com/mailhog/data/LICENSE.md",
    "chars": 1075,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 Ian Kent\n\nPermission is hereby granted, free of charge, to any person obtainin"
  },
  {
    "path": "vendor/github.com/mailhog/data/README.md",
    "chars": 435,
    "preview": "MailHog data library [![GoDoc](https://godoc.org/github.com/mailhog/data?status.svg)](https://godoc.org/github.com/mailh"
  },
  {
    "path": "vendor/github.com/mailhog/data/message.go",
    "chars": 7713,
    "preview": "package data\n\nimport (\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"encoding/base64\"\n\t\"io\"\n\t\"log\"\n\t\"mime\"\n\t\"strings\"\n\t\"time\"\n)\n\n// LogHandl"
  },
  {
    "path": "vendor/github.com/mailhog/http/LICENSE.md",
    "chars": 1075,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2015 Ian Kent\n\nPermission is hereby granted, free of charge, to any person obtainin"
  },
  {
    "path": "vendor/github.com/mailhog/http/README.md",
    "chars": 474,
    "preview": "MailHog HTTP utilities [![GoDoc](https://godoc.org/github.com/mailhog/http?status.svg)](https://godoc.org/github.com/mai"
  },
  {
    "path": "vendor/github.com/mailhog/http/server.go",
    "chars": 2391,
    "preview": "package http\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/gorilla/pat\"\n\t\"github.com/"
  },
  {
    "path": "vendor/github.com/mailhog/mhsendmail/LICENSE.md",
    "chars": 1082,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2015 - 2016 Ian Kent\n\nPermission is hereby granted, free of charge, to any person o"
  },
  {
    "path": "vendor/github.com/mailhog/mhsendmail/cmd/cmd.go",
    "chars": 1935,
    "preview": "package cmd\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"net/mail\"\n\t\"net/smtp\"\n\t\"os\"\n\t\"os/user\"\n)\n\nimport flag \"githu"
  },
  {
    "path": "vendor/github.com/mailhog/smtp/LICENSE.md",
    "chars": 1075,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 Ian Kent\n\nPermission is hereby granted, free of charge, to any person obtainin"
  },
  {
    "path": "vendor/github.com/mailhog/smtp/README.md",
    "chars": 3689,
    "preview": "MailHog SMTP Protocol [![GoDoc](https://godoc.org/github.com/mailhog/smtp?status.svg)](https://godoc.org/github.com/mail"
  },
  {
    "path": "vendor/github.com/mailhog/smtp/protocol.go",
    "chars": 16176,
    "preview": "package smtp\n\n// http://www.rfc-editor.org/rfc/rfc5321.txt\n\nimport (\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"log\"\n\t\"regexp\"\n\t\"str"
  },
  {
    "path": "vendor/github.com/mailhog/smtp/reply.go",
    "chars": 3511,
    "preview": "package smtp\n\nimport \"strconv\"\n\n// http://www.rfc-editor.org/rfc/rfc5321.txt\n\n// Reply is a struct representing an SMTP "
  },
  {
    "path": "vendor/github.com/mailhog/smtp/state.go",
    "chars": 608,
    "preview": "package smtp\n\n// State represents the state of an SMTP conversation\ntype State int\n\n// SMTP message conversation states\n"
  },
  {
    "path": "vendor/github.com/mailhog/storage/LICENSE.md",
    "chars": 1082,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 - 2016 Ian Kent\n\nPermission is hereby granted, free of charge, to any person o"
  },
  {
    "path": "vendor/github.com/mailhog/storage/README.md",
    "chars": 581,
    "preview": "MailHog storage backends [![GoDoc](https://godoc.org/github.com/mailhog/storage?status.svg)](https://godoc.org/github.co"
  },
  {
    "path": "vendor/github.com/mailhog/storage/maildir.go",
    "chars": 4063,
    "preview": "package storage\n\nimport (\n\t\"errors\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/mailhog/data\"\n)\n"
  },
  {
    "path": "vendor/github.com/mailhog/storage/memory.go",
    "chars": 4592,
    "preview": "package storage\n\nimport (\n\t\"errors\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/mailhog/data\"\n)\n\n// InMemory is an in memory storag"
  },
  {
    "path": "vendor/github.com/mailhog/storage/mongodb.go",
    "chars": 3221,
    "preview": "package storage\n\nimport (\n\t\"github.com/mailhog/data\"\n\t\"gopkg.in/mgo.v2\"\n\t\"gopkg.in/mgo.v2/bson\"\n\t\"log\"\n)\n\n// MongoDB rep"
  },
  {
    "path": "vendor/github.com/mailhog/storage/storage.go",
    "chars": 381,
    "preview": "package storage\n\nimport \"github.com/mailhog/data\"\n\n// Storage represents a storage backend\ntype Storage interface {\n\tSto"
  },
  {
    "path": "vendor/github.com/philhofer/fwd/LICENSE.md",
    "chars": 1061,
    "preview": "Copyright (c) 2014-2015, Philip Hofer\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of t"
  },
  {
    "path": "vendor/github.com/philhofer/fwd/README.md",
    "chars": 6720,
    "preview": "\n# fwd\n    import \"github.com/philhofer/fwd\"\n\nThe `fwd` package provides a buffered reader\nand writer. Each has methods "
  },
  {
    "path": "vendor/github.com/philhofer/fwd/reader.go",
    "chars": 9296,
    "preview": "// The `fwd` package provides a buffered reader\n// and writer. Each has methods that help improve\n// the encoding/decodi"
  },
  {
    "path": "vendor/github.com/philhofer/fwd/writer.go",
    "chars": 4680,
    "preview": "package fwd\n\nimport \"io\"\n\nconst (\n\t// DefaultWriterSize is the\n\t// default write buffer size.\n\tDefaultWriterSize = 2048\n"
  },
  {
    "path": "vendor/github.com/philhofer/fwd/writer_appengine.go",
    "chars": 87,
    "preview": "// +build appengine\n\npackage fwd\n\nfunc unsafestr(s string) []byte { return []byte(s) }\n"
  },
  {
    "path": "vendor/github.com/philhofer/fwd/writer_unsafe.go",
    "chars": 290,
    "preview": "// +build !appengine\n\npackage fwd\n\nimport (\n\t\"reflect\"\n\t\"unsafe\"\n)\n\n// unsafe cast string as []byte\nfunc unsafestr(b str"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/CONTRIBUTING.md",
    "chars": 1948,
    "preview": "# Contributing\n\nIn general, the code posted to the [SmartyStreets github organization](https://github.com/smartystreets)"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/LICENSE.md",
    "chars": 1297,
    "preview": "Copyright (c) 2016 SmartyStreets, LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy \nof "
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/README.md",
    "chars": 17884,
    "preview": "# assertions\n--\n    import \"github.com/smartystreets/assertions\"\n\nPackage assertions contains the implementations for al"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/collections.go",
    "chars": 7562,
    "preview": "package assertions\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\n\t\"github.com/smartystreets/assertions/internal/oglematchers\"\n)\n\n// Shoul"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/doc.go",
    "chars": 4112,
    "preview": "// Package assertions contains the implementations for all assertions which\n// are referenced in goconvey's `convey` pac"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/equality.go",
    "chars": 9338,
    "preview": "package assertions\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/smartystreets/assertions/inter"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/filter.go",
    "chars": 576,
    "preview": "package assertions\n\nimport \"fmt\"\n\nconst (\n\tsuccess                = \"\"\n\tneedExactValues        = \"This assertion require"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/internal/go-render/LICENSE",
    "chars": 1563,
    "preview": "// Copyright (c) 2015 The Chromium Authors. All rights reserved.\n//\n// Redistribution and use in source and binary forms"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/internal/go-render/render/render.go",
    "chars": 10586,
    "preview": "// Copyright 2015 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style licen"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/internal/oglematchers/LICENSE",
    "chars": 11358,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/internal/oglematchers/README.md",
    "chars": 2027,
    "preview": "[![GoDoc](https://godoc.org/github.com/smartystreets/assertions/internal/oglematchers?status.svg)](https://godoc.org/git"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/internal/oglematchers/any_of.go",
    "chars": 2655,
    "preview": "// Copyright 2011 Aaron Jacobs. All Rights Reserved.\n// Author: aaronjjacobs@gmail.com (Aaron Jacobs)\n//\n// Licensed und"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/internal/oglematchers/contains.go",
    "chars": 1755,
    "preview": "// Copyright 2012 Aaron Jacobs. All Rights Reserved.\n// Author: aaronjjacobs@gmail.com (Aaron Jacobs)\n//\n// Licensed und"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/internal/oglematchers/deep_equals.go",
    "chars": 2384,
    "preview": "// Copyright 2012 Aaron Jacobs. All Rights Reserved.\n// Author: aaronjjacobs@gmail.com (Aaron Jacobs)\n//\n// Licensed und"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/internal/oglematchers/equals.go",
    "chars": 12751,
    "preview": "// Copyright 2011 Aaron Jacobs. All Rights Reserved.\n// Author: aaronjjacobs@gmail.com (Aaron Jacobs)\n//\n// Licensed und"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal.go",
    "chars": 1389,
    "preview": "// Copyright 2011 Aaron Jacobs. All Rights Reserved.\n// Author: aaronjjacobs@gmail.com (Aaron Jacobs)\n//\n// Licensed und"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/internal/oglematchers/greater_than.go",
    "chars": 1358,
    "preview": "// Copyright 2011 Aaron Jacobs. All Rights Reserved.\n// Author: aaronjjacobs@gmail.com (Aaron Jacobs)\n//\n// Licensed und"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal.go",
    "chars": 1478,
    "preview": "// Copyright 2011 Aaron Jacobs. All Rights Reserved.\n// Author: aaronjjacobs@gmail.com (Aaron Jacobs)\n//\n// Licensed und"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/internal/oglematchers/less_than.go",
    "chars": 3660,
    "preview": "// Copyright 2011 Aaron Jacobs. All Rights Reserved.\n// Author: aaronjjacobs@gmail.com (Aaron Jacobs)\n//\n// Licensed und"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/internal/oglematchers/matcher.go",
    "chars": 3693,
    "preview": "// Copyright 2011 Aaron Jacobs. All Rights Reserved.\n// Author: aaronjjacobs@gmail.com (Aaron Jacobs)\n//\n// Licensed und"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/internal/oglematchers/not.go",
    "chars": 1456,
    "preview": "// Copyright 2011 Aaron Jacobs. All Rights Reserved.\n// Author: aaronjjacobs@gmail.com (Aaron Jacobs)\n//\n// Licensed und"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/internal/oglematchers/transform_description.go",
    "chars": 1261,
    "preview": "// Copyright 2011 Aaron Jacobs. All Rights Reserved.\n// Author: aaronjjacobs@gmail.com (Aaron Jacobs)\n//\n// Licensed und"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/messages.go",
    "chars": 6865,
    "preview": "package assertions\n\nconst ( // equality\n\tshouldHaveBeenEqual             = \"Expected: '%v'\\nActual:   '%v'\\n(Should be e"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/panic.go",
    "chars": 2527,
    "preview": "package assertions\n\nimport \"fmt\"\n\n// ShouldPanic receives a void, niladic function and expects to recover a panic.\nfunc "
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/quantity.go",
    "chars": 4971,
    "preview": "package assertions\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/smartystreets/assertions/internal/oglematchers\"\n)\n\n// ShouldBeGreaterT"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/serializer.go",
    "chars": 1957,
    "preview": "package assertions\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/smartystreets/assertions/internal/go-render/render\"\n)"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/strings.go",
    "chars": 7021,
    "preview": "package assertions\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n)\n\n// ShouldStartWith receives exactly 2 string parameters and"
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/time.go",
    "chars": 6429,
    "preview": "package assertions\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\n// ShouldHappenBefore receives exactly 2 time.Time arguments and asserts "
  },
  {
    "path": "vendor/github.com/smartystreets/assertions/type.go",
    "chars": 3173,
    "preview": "package assertions\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\n// ShouldHaveSameTypeAs receives exactly two parameters and compares t"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/LICENSE.md",
    "chars": 1285,
    "preview": "Copyright (c) 2016 SmartyStreets, LLC\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof t"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/assertions.go",
    "chars": 3218,
    "preview": "package convey\n\nimport \"github.com/smartystreets/assertions\"\n\nvar (\n\tShouldEqual          = assertions.ShouldEqual\n\tShou"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/context.go",
    "chars": 7176,
    "preview": "package convey\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/jtolds/gls\"\n\t\"github.com/smartystreets/goconvey/convey/reporting\"\n)\n\ntype "
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/convey.goconvey",
    "chars": 188,
    "preview": "#ignore\n-timeout=1s\n#-covermode=count\n#-coverpkg=github.com/smartystreets/goconvey/convey,github.com/smartystreets/gocon"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/discovery.go",
    "chars": 2451,
    "preview": "package convey\n\ntype actionSpecifier uint8\n\nconst (\n\tnoSpecifier actionSpecifier = iota\n\tskipConvey\n\tfocusConvey\n)\n\ntype"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/doc.go",
    "chars": 8674,
    "preview": "// Package convey contains all of the public-facing entry points to this project.\n// This means that it should never be "
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/gotest/utils.go",
    "chars": 831,
    "preview": "// Package gotest contains internal functionality. Although this package\n// contains one or more exported names it is no"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/init.go",
    "chars": 1986,
    "preview": "package convey\n\nimport (\n\t\"flag\"\n\t\"os\"\n\n\t\"github.com/jtolds/gls\"\n\t\"github.com/smartystreets/assertions\"\n\t\"github.com/sma"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/nilReporter.go",
    "chars": 642,
    "preview": "package convey\n\nimport (\n\t\"github.com/smartystreets/goconvey/convey/reporting\"\n)\n\ntype nilReporter struct{}\n\nfunc (self "
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/reporting/console.go",
    "chars": 210,
    "preview": "package reporting\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\ntype console struct{}\n\nfunc (self *console) Write(p []byte) (n int, err erro"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/reporting/doc.go",
    "chars": 256,
    "preview": "// Package reporting contains internal functionality related\n// to console reporting and output. Although this package h"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/reporting/dot.go",
    "chars": 808,
    "preview": "package reporting\n\nimport \"fmt\"\n\ntype dot struct{ out *Printer }\n\nfunc (self *dot) BeginStory(story *StoryReport) {}\n\nfu"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/reporting/gotest.go",
    "chars": 674,
    "preview": "package reporting\n\ntype gotestReporter struct{ test T }\n\nfunc (self *gotestReporter) BeginStory(story *StoryReport) {\n\ts"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/reporting/init.go",
    "chars": 2213,
    "preview": "package reporting\n\nimport (\n\t\"os\"\n\t\"runtime\"\n\t\"strings\"\n)\n\nfunc init() {\n\tif !isColorableTerminal() {\n\t\tmonochrome()\n\t}\n"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/reporting/json.go",
    "chars": 2227,
    "preview": "// TODO: under unit test\n\npackage reporting\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype JsonReporter s"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/reporting/printer.go",
    "chars": 1208,
    "preview": "package reporting\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n)\n\ntype Printer struct {\n\tout    io.Writer\n\tprefix string\n}\n\nfunc (s"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/reporting/problems.go",
    "chars": 1747,
    "preview": "package reporting\n\nimport \"fmt\"\n\ntype problem struct {\n\tsilent   bool\n\tout      *Printer\n\terrors   []*AssertionResult\n\tf"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/reporting/reporter.go",
    "chars": 1138,
    "preview": "package reporting\n\nimport \"io\"\n\ntype Reporter interface {\n\tBeginStory(story *StoryReport)\n\tEnter(scope *ScopeReport)\n\tRe"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/reporting/reporting.goconvey",
    "chars": 20,
    "preview": "#ignore\n-timeout=1s\n"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/reporting/reports.go",
    "chars": 4235,
    "preview": "package reporting\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"runtime\"\n\t\"strings\"\n\n\t\"github.com/smartystreets/goconvey/convey/go"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/reporting/statistics.go",
    "chars": 2074,
    "preview": "package reporting\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n)\n\nfunc (self *statistics) BeginStory(story *StoryReport) {}\n\nfunc (self *sta"
  },
  {
    "path": "vendor/github.com/smartystreets/goconvey/convey/reporting/story.go",
    "chars": 1691,
    "preview": "// TODO: in order for this reporter to be completely honest\n// we need to retrofit to be more like the json reporter suc"
  },
  {
    "path": "vendor/github.com/spf13/pflag/LICENSE",
    "chars": 1531,
    "preview": "Copyright (c) 2012 Alex Ogier. All rights reserved.\nCopyright (c) 2012 The Go Authors. All rights reserved.\n\nRedistribut"
  },
  {
    "path": "vendor/github.com/spf13/pflag/README.md",
    "chars": 8440,
    "preview": "[![Build Status](https://travis-ci.org/spf13/pflag.svg?branch=master)](https://travis-ci.org/spf13/pflag)\n\n## Descriptio"
  },
  {
    "path": "vendor/github.com/spf13/pflag/bool.go",
    "chars": 3077,
    "preview": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n)\n\n// optional interface to indicate boolean flags that can be\n// supplied wit"
  },
  {
    "path": "vendor/github.com/spf13/pflag/count.go",
    "chars": 2804,
    "preview": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n)\n\n// -- count Value\ntype countValue int\n\nfunc newCountValue(val int, p *int) "
  },
  {
    "path": "vendor/github.com/spf13/pflag/duration.go",
    "chars": 3317,
    "preview": "package pflag\n\nimport (\n\t\"time\"\n)\n\n// -- time.Duration Value\ntype durationValue time.Duration\n\nfunc newDurationValue(val"
  },
  {
    "path": "vendor/github.com/spf13/pflag/flag.go",
    "chars": 28760,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/spf13/pflag/float32.go",
    "chars": 3156,
    "preview": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n)\n\n// -- float32 Value\ntype float32Value float32\n\nfunc newFloat32Value(val flo"
  },
  {
    "path": "vendor/github.com/spf13/pflag/float64.go",
    "chars": 3093,
    "preview": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n)\n\n// -- float64 Value\ntype float64Value float64\n\nfunc newFloat64Value(val flo"
  },
  {
    "path": "vendor/github.com/spf13/pflag/golangflag.go",
    "chars": 2701,
    "preview": "// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/spf13/pflag/int.go",
    "chars": 2792,
    "preview": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n)\n\n// -- int Value\ntype intValue int\n\nfunc newIntValue(val int, p *int) *intVa"
  },
  {
    "path": "vendor/github.com/spf13/pflag/int32.go",
    "chars": 3014,
    "preview": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n)\n\n// -- int32 Value\ntype int32Value int32\n\nfunc newInt32Value(val int32, p *i"
  },
  {
    "path": "vendor/github.com/spf13/pflag/int64.go",
    "chars": 2953,
    "preview": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n)\n\n// -- int64 Value\ntype int64Value int64\n\nfunc newInt64Value(val int64, p *i"
  },
  {
    "path": "vendor/github.com/spf13/pflag/int8.go",
    "chars": 2936,
    "preview": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n)\n\n// -- int8 Value\ntype int8Value int8\n\nfunc newInt8Value(val int8, p *int8) "
  },
  {
    "path": "vendor/github.com/spf13/pflag/int_slice.go",
    "chars": 3785,
    "preview": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// -- intSlice Value\ntype intSliceValue struct {\n\tvalue   *[]int"
  },
  {
    "path": "vendor/github.com/spf13/pflag/ip.go",
    "chars": 3070,
    "preview": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n)\n\nvar _ = strings.TrimSpace\n\n// -- net.IP value\ntype ipValue net.IP\n\nf"
  },
  {
    "path": "vendor/github.com/spf13/pflag/ipmask.go",
    "chars": 4052,
    "preview": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"strconv\"\n)\n\n// -- net.IPMask value\ntype ipMaskValue net.IPMask\n\nfunc newIPMaskVa"
  }
]

// ... and 73 more files (download for full content)

About this extraction

This page contains the full source code of the mailhog/MailHog GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 273 files (3.3 MB), approximately 881.7k tokens, and a symbol index with 2660 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!