Generate documentation from `zipkin-api` Thrift definitions
diff --git a/generate_docs_from_thrift.sh b/generate_docs_from_thrift.sh
new file mode 100755
index 0000000..5eb6ebb
--- /dev/null
+++ b/generate_docs_from_thrift.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+set -euo pipefail
+set -x
+
+target_root="$(pwd)/public"
+cd "$(mktemp -d)"
+git clone https://github.com/openzipkin/zipkin-api.git
+cd zipkin-api/thrift
+rm -fv wrapper.thrift
+for source in *.thrift; do
+    echo "include \"$source\"" >> wrapper.thrift
+done
+thrift --gen html wrapper.thrift
+mv gen-html "$target_root/thrift"
diff --git a/public/thrift/index.html b/public/thrift/index.html
new file mode 100644
index 0000000..0d38ff3
--- /dev/null
+++ b/public/thrift/index.html
@@ -0,0 +1,51 @@
+<html><head>
+<link href="style.css" rel="stylesheet" type="text/css"/>
+<title>All Thrift declarations</title></head><body>
+<div class="container-fluid">
+<h1>All Thrift declarations</h1>
+<table class="table-bordered table-striped table-condensed"><thead><th>Module</th><th>Services</th><th>Data types</th><th>Constants</th></thead>
+<tr>
+<td>wrapper</td><td></td>
+<td></td>
+<td></code></td>
+</tr><tr>
+<td>zipkinCore</td><td></td>
+<td><a href="zipkinCore.html#Struct_Annotation">Annotation</a><br/>
+<a href="zipkinCore.html#Enum_AnnotationType">AnnotationType</a><br/>
+<a href="zipkinCore.html#Struct_BinaryAnnotation">BinaryAnnotation</a><br/>
+<a href="zipkinCore.html#Struct_Endpoint">Endpoint</a><br/>
+<a href="zipkinCore.html#Struct_Span">Span</a><br/>
+</td>
+<td><code><a href="zipkinCore.html#Const_CLIENT_ADDR">CLIENT_ADDR</a></code><br/>
+<code><a href="zipkinCore.html#Const_CLIENT_RECV">CLIENT_RECV</a></code><br/>
+<code><a href="zipkinCore.html#Const_CLIENT_RECV_FRAGMENT">CLIENT_RECV_FRAGMENT</a></code><br/>
+<code><a href="zipkinCore.html#Const_CLIENT_SEND">CLIENT_SEND</a></code><br/>
+<code><a href="zipkinCore.html#Const_CLIENT_SEND_FRAGMENT">CLIENT_SEND_FRAGMENT</a></code><br/>
+<code><a href="zipkinCore.html#Const_ERROR">ERROR</a></code><br/>
+<code><a href="zipkinCore.html#Const_HTTP_HOST">HTTP_HOST</a></code><br/>
+<code><a href="zipkinCore.html#Const_HTTP_METHOD">HTTP_METHOD</a></code><br/>
+<code><a href="zipkinCore.html#Const_HTTP_PATH">HTTP_PATH</a></code><br/>
+<code><a href="zipkinCore.html#Const_HTTP_REQUEST_SIZE">HTTP_REQUEST_SIZE</a></code><br/>
+<code><a href="zipkinCore.html#Const_HTTP_RESPONSE_SIZE">HTTP_RESPONSE_SIZE</a></code><br/>
+<code><a href="zipkinCore.html#Const_HTTP_STATUS_CODE">HTTP_STATUS_CODE</a></code><br/>
+<code><a href="zipkinCore.html#Const_HTTP_URL">HTTP_URL</a></code><br/>
+<code><a href="zipkinCore.html#Const_LOCAL_COMPONENT">LOCAL_COMPONENT</a></code><br/>
+<code><a href="zipkinCore.html#Const_MESSAGE_ADDR">MESSAGE_ADDR</a></code><br/>
+<code><a href="zipkinCore.html#Const_MESSAGE_RECV">MESSAGE_RECV</a></code><br/>
+<code><a href="zipkinCore.html#Const_MESSAGE_SEND">MESSAGE_SEND</a></code><br/>
+<code><a href="zipkinCore.html#Const_SERVER_ADDR">SERVER_ADDR</a></code><br/>
+<code><a href="zipkinCore.html#Const_SERVER_RECV">SERVER_RECV</a></code><br/>
+<code><a href="zipkinCore.html#Const_SERVER_RECV_FRAGMENT">SERVER_RECV_FRAGMENT</a></code><br/>
+<code><a href="zipkinCore.html#Const_SERVER_SEND">SERVER_SEND</a></code><br/>
+<code><a href="zipkinCore.html#Const_SERVER_SEND_FRAGMENT">SERVER_SEND_FRAGMENT</a></code><br/>
+<code><a href="zipkinCore.html#Const_WIRE_RECV">WIRE_RECV</a></code><br/>
+<code><a href="zipkinCore.html#Const_WIRE_SEND">WIRE_SEND</a></code><br/>
+</code></td>
+</tr><tr>
+<td>zipkinDependencies</td><td></td>
+<td><a href="zipkinDependencies.html#Struct_Dependencies">Dependencies</a><br/>
+<a href="zipkinDependencies.html#Struct_DependencyLink">DependencyLink</a><br/>
+</td>
+<td></code></td>
+</tr></table>
+</div></body></html>
diff --git a/public/thrift/style.css b/public/thrift/style.css
new file mode 100644
index 0000000..34fd9d7
--- /dev/null
+++ b/public/thrift/style.css
@@ -0,0 +1,184 @@
+/*!
+ * Bootstrap v2.0.3
+ *
+ * Copyright 2012 Twitter, Inc
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
+ */
+.clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:"";}
+.clearfix:after{clear:both;}
+.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0;}
+.input-block-level{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;}
+article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block;}
+audio,canvas,video{display:inline-block;*display:inline;*zoom:1;}
+audio:not([controls]){display:none;}
+html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;}
+a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}
+a:hover,a:active{outline:0;}
+sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline;}
+sup{top:-0.5em;}
+sub{bottom:-0.25em;}
+img{max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic;}
+button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle;}
+button,input{*overflow:visible;line-height:normal;}
+button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0;}
+button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;}
+input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield;}
+input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none;}
+textarea{overflow:auto;vertical-align:top;}
+body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;color:#333333;background-color:#ffffff;}
+a{color:#0088cc;text-decoration:none;}
+a:hover{color:#005580;text-decoration:underline;}
+.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";}
+.row:after{clear:both;}
+[class*="span"]{float:left;margin-left:20px;}
+.container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;}
+.span12{width:940px;}
+.span11{width:860px;}
+.span10{width:780px;}
+.span9{width:700px;}
+.span8{width:620px;}
+.span7{width:540px;}
+.span6{width:460px;}
+.span5{width:380px;}
+.span4{width:300px;}
+.span3{width:220px;}
+.span2{width:140px;}
+.span1{width:60px;}
+.offset12{margin-left:980px;}
+.offset11{margin-left:900px;}
+.offset10{margin-left:820px;}
+.offset9{margin-left:740px;}
+.offset8{margin-left:660px;}
+.offset7{margin-left:580px;}
+.offset6{margin-left:500px;}
+.offset5{margin-left:420px;}
+.offset4{margin-left:340px;}
+.offset3{margin-left:260px;}
+.offset2{margin-left:180px;}
+.offset1{margin-left:100px;}
+.row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";}
+.row-fluid:after{clear:both;}
+.row-fluid [class*="span"]{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.127659574%;*margin-left:2.0744680846382977%;}
+.row-fluid [class*="span"]:first-child{margin-left:0;}
+.row-fluid .span12{width:99.99999998999999%;*width:99.94680850063828%;}
+.row-fluid .span11{width:91.489361693%;*width:91.4361702036383%;}
+.row-fluid .span10{width:82.97872339599999%;*width:82.92553190663828%;}
+.row-fluid .span9{width:74.468085099%;*width:74.4148936096383%;}
+.row-fluid .span8{width:65.95744680199999%;*width:65.90425531263828%;}
+.row-fluid .span7{width:57.446808505%;*width:57.3936170156383%;}
+.row-fluid .span6{width:48.93617020799999%;*width:48.88297871863829%;}
+.row-fluid .span5{width:40.425531911%;*width:40.3723404216383%;}
+.row-fluid .span4{width:31.914893614%;*width:31.8617021246383%;}
+.row-fluid .span3{width:23.404255317%;*width:23.3510638276383%;}
+.row-fluid .span2{width:14.89361702%;*width:14.8404255306383%;}
+.row-fluid .span1{width:6.382978723%;*width:6.329787233638298%;}
+.container{margin-right:auto;margin-left:auto;*zoom:1;}.container:before,.container:after{display:table;content:"";}
+.container:after{clear:both;}
+.container-fluid{padding-right:20px;padding-left:20px;*zoom:1;}.container-fluid:before,.container-fluid:after{display:table;content:"";}
+.container-fluid:after{clear:both;}
+p{margin:0 0 9px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;}p small{font-size:11px;color:#999999;}
+.lead{margin-bottom:18px;font-size:20px;font-weight:200;line-height:27px;}
+h1,h2,h3,h4,h5,h6{margin:0;font-family:inherit;font-weight:bold;color:inherit;text-rendering:optimizelegibility;}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;color:#999999;}
+h1{font-size:30px;line-height:36px;}h1 small{font-size:18px;}
+h2{font-size:24px;line-height:36px;}h2 small{font-size:18px;}
+h3{font-size:18px;line-height:27px;}h3 small{font-size:14px;}
+h4,h5,h6{line-height:18px;}
+h4{font-size:14px;}h4 small{font-size:12px;}
+h5{font-size:12px;}
+h6{font-size:11px;color:#999999;text-transform:uppercase;}
+.page-header{padding-bottom:17px;margin:18px 0;border-bottom:1px solid #eeeeee;}
+.page-header h1{line-height:1;}
+ul,ol{padding:0;margin:0 0 9px 25px;}
+ul ul,ul ol,ol ol,ol ul{margin-bottom:0;}
+ul{list-style:disc;}
+ol{list-style:decimal;}
+li{line-height:18px;}
+ul.unstyled,ol.unstyled{margin-left:0;list-style:none;}
+dl{margin-bottom:18px;}
+dt,dd{line-height:18px;}
+dt{font-weight:bold;line-height:17px;}
+dd{margin-left:9px;}
+.dl-horizontal dt{float:left;width:120px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
+.dl-horizontal dd{margin-left:130px;}
+hr{margin:18px 0;border:0;border-top:1px solid #eeeeee;border-bottom:1px solid #ffffff;}
+strong{font-weight:bold;}
+em{font-style:italic;}
+.muted{color:#999999;}
+abbr[title]{cursor:help;border-bottom:1px dotted #ddd;}
+abbr.initialism{font-size:90%;text-transform:uppercase;}
+blockquote{padding:0 0 0 15px;margin:0 0 18px;border-left:5px solid #eeeeee;}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:22.5px;}
+blockquote small{display:block;line-height:18px;color:#999999;}blockquote small:before{content:'\2014 \00A0';}
+blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eeeeee;border-left:0;}blockquote.pull-right p,blockquote.pull-right small{text-align:right;}
+q:before,q:after,blockquote:before,blockquote:after{content:"";}
+address{display:block;margin-bottom:18px;font-style:normal;line-height:18px;}
+small{font-size:100%;}
+cite{font-style:normal;}
+code,pre{padding:0 3px 2px;font-family:Menlo,Monaco,Consolas,"Courier New",monospace;font-size:12px;color:#333333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
+code{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;}
+pre{display:block;padding:8.5px;margin:0 0 9px;font-size:12.025px;line-height:18px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}pre.prettyprint{margin-bottom:18px;}
+pre code{padding:0;color:inherit;background-color:transparent;border:0;}
+.pre-scrollable{max-height:340px;overflow-y:scroll;}
+.label,.badge{font-size:10.998px;font-weight:bold;line-height:14px;color:#ffffff;vertical-align:baseline;white-space:nowrap;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#999999;}
+.label{padding:1px 4px 2px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
+.badge{padding:1px 9px 2px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px;}
+a.label:hover,a.badge:hover{color:#ffffff;text-decoration:none;cursor:pointer;}
+.label-important,.badge-important{background-color:#b94a48;}
+.label-important[href],.badge-important[href]{background-color:#953b39;}
+.label-warning,.badge-warning{background-color:#f89406;}
+.label-warning[href],.badge-warning[href]{background-color:#c67605;}
+.label-success,.badge-success{background-color:#468847;}
+.label-success[href],.badge-success[href]{background-color:#356635;}
+.label-info,.badge-info{background-color:#3a87ad;}
+.label-info[href],.badge-info[href]{background-color:#2d6987;}
+.label-inverse,.badge-inverse{background-color:#333333;}
+.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a;}
+table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0;}
+.table{width:100%;margin-bottom:18px;}.table th,.table td{padding:8px;line-height:18px;text-align:left;vertical-align:top;border-top:1px solid #dddddd;}
+.table th{font-weight:bold;}
+.table thead th{vertical-align:bottom;}
+.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0;}
+.table tbody+tbody{border-top:2px solid #dddddd;}
+.table-condensed th,.table-condensed td{padding:4px 5px;}
+.table-bordered{border:1px solid #dddddd;border-collapse:separate;*border-collapse:collapsed;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.table-bordered th,.table-bordered td{border-left:1px solid #dddddd;}
+.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0;}
+.table-bordered thead:first-child tr:first-child th:first-child,.table-bordered tbody:first-child tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px;}
+.table-bordered thead:first-child tr:first-child th:last-child,.table-bordered tbody:first-child tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px;}
+.table-bordered thead:last-child tr:last-child th:first-child,.table-bordered tbody:last-child tr:last-child td:first-child{-webkit-border-radius:0 0 0 4px;-moz-border-radius:0 0 0 4px;border-radius:0 0 0 4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;}
+.table-bordered thead:last-child tr:last-child th:last-child,.table-bordered tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;}
+.table-striped tbody tr:nth-child(odd) td,.table-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9;}
+.table tbody tr:hover td,.table tbody tr:hover th{background-color:#f5f5f5;}
+table .span1{float:none;width:44px;margin-left:0;}
+table .span2{float:none;width:124px;margin-left:0;}
+table .span3{float:none;width:204px;margin-left:0;}
+table .span4{float:none;width:284px;margin-left:0;}
+table .span5{float:none;width:364px;margin-left:0;}
+table .span6{float:none;width:444px;margin-left:0;}
+table .span7{float:none;width:524px;margin-left:0;}
+table .span8{float:none;width:604px;margin-left:0;}
+table .span9{float:none;width:684px;margin-left:0;}
+table .span10{float:none;width:764px;margin-left:0;}
+table .span11{float:none;width:844px;margin-left:0;}
+table .span12{float:none;width:924px;margin-left:0;}
+table .span13{float:none;width:1004px;margin-left:0;}
+table .span14{float:none;width:1084px;margin-left:0;}
+table .span15{float:none;width:1164px;margin-left:0;}
+table .span16{float:none;width:1244px;margin-left:0;}
+table .span17{float:none;width:1324px;margin-left:0;}
+table .span18{float:none;width:1404px;margin-left:0;}
+table .span19{float:none;width:1484px;margin-left:0;}
+table .span20{float:none;width:1564px;margin-left:0;}
+table .span21{float:none;width:1644px;margin-left:0;}
+table .span22{float:none;width:1724px;margin-left:0;}
+table .span23{float:none;width:1804px;margin-left:0;}
+table .span24{float:none;width:1884px;margin-left:0;}
+/* Auto-generated CSS for generated Thrift docs */
+h3, h4 { margin-bottom: 6px; }
+div.definition { border: 1px solid #CCC; margin-bottom: 10px; padding: 10px; }
+div.extends { margin: -0.5em 0 1em 5em }
+td { vertical-align: top; }
+table { empty-cells: show; }
+code { line-height: 20px; }
+.table-bordered th, .table-bordered td { border-bottom: 1px solid #DDDDDD; }
diff --git a/public/thrift/wrapper.html b/public/thrift/wrapper.html
new file mode 100644
index 0000000..ab26c3a
--- /dev/null
+++ b/public/thrift/wrapper.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+<link href="style.css" rel="stylesheet" type="text/css"/>
+<title>Thrift module: wrapper</title></head><body>
+<div class="container-fluid">
+<h1>Thrift module: wrapper</h1>
+<table class="table-bordered table-striped table-condensed"><thead><th>Module</th><th>Services</th><th>Data types</th><th>Constants</th></thead>
+<tr>
+<td>wrapper</td><td></td>
+<td></td>
+<td></code></td>
+</tr></table>
+</div></body></html>