~evanj/evanjon.es

b2569bb225045d9d1d9f58c51dbc8cb5a9f79f58 — Evan J 9 months ago 3d3bf1d
Feat(go1.16, embed, Nu Html Checker): Fixing HTML issues as reported by
https://validator.w3.org/nu/. Updating to go1.16 and ripping out custom
file embedder for standard library embed!
M go.mod => go.mod +2 -2
@@ 1,10 1,10 @@
module git.sr.ht/~evanj/evanjon.es

go 1.14
go 1.16

require (
	git.sr.ht/~evanj/embed v0.0.0-20200702023953-8a902e4e7e94
	github.com/google/uuid v1.1.1
	github.com/gorilla/feeds v1.1.1
	github.com/tdewolff/minify/v2 v2.7.3
	github.com/tdewolff/minify/v2 v2.9.11
)

M go.sum => go.sum +8 -8
@@ 3,7 3,7 @@ git.sr.ht/~evanj/embed v0.0.0-20200702023953-8a902e4e7e94/go.mod h1:o3sadZPJeN9s
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/feeds v1.1.1 h1:HwKXxqzcRNg9to+BbvJog4+f3s/xzvtZXICcQGutYfY=


@@ 14,11 14,11 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/tdewolff/minify/v2 v2.7.3 h1:ngzhF7SaunCtbsBjgm7WJzl9HdiKlA1gYC/Qyx9CVMo=
github.com/tdewolff/minify/v2 v2.7.3/go.mod h1:BkDSm8aMMT0ALGmpt7j3Ra7nLUgZL0qhyrAHXwxcy5w=
github.com/tdewolff/parse/v2 v2.4.2 h1:Bu2Qv6wepkc+Ou7iB/qHjAhEImlAP5vedzlQRUdj3BI=
github.com/tdewolff/parse/v2 v2.4.2/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/tdewolff/minify/v2 v2.9.11 h1:8o6hclGwxm6MNwTPHabvdND5SghhHs0bn+3/+uAf0yQ=
github.com/tdewolff/minify/v2 v2.9.11/go.mod h1:YZk0lGOc6CvQrqvm5f7V3ihaq3QUd9acS4HESdVDOaM=
github.com/tdewolff/parse/v2 v2.5.8 h1:vutkOO9Xi3DehIzCLHqvMM2hFXo54S0iDvIG/hYznnE=
github.com/tdewolff/parse/v2 v2.5.8/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=
github.com/tdewolff/test v1.0.6 h1:76mzYJQ83Op284kMT+63iCNCI7NEERsIN8dLM+RiKr4=
github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=


@@ 27,10 27,10 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20181031143558-9b800f95dbbc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20200301222351-066e0c02454c h1:FD7jysxM+EJqg5UYYy3XYDsAiUickFsn4UiaanJkf8c=
golang.org/x/tools v0.0.0-20200301222351-066e0c02454c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

M internal/s/tmpl/css/main.css => internal/s/tmpl/css/main.css +7 -0
@@ 58,6 58,7 @@ body {
  font-size: 22px;
  line-height: 1.4;
  background-image: url("data:image/gif;base64,R0lGODlhdABuAPcAAP//////zP//mf//Zv//M///AP/M///MzP/Mmf/MZv/MM//MAP+Z//+ZzP+Zmf+ZZv+ZM/+ZAP9m//9mzP9mmf9mZv9mM/9mAP8z//8zzP8zmf8zZv8zM/8zAP8A//8AzP8Amf8AZv8AM/8AAMz//8z/zMz/mcz/Zsz/M8z/AMzM/8zMzMzMmczMZszMM8zMAMyZ/8yZzMyZmcyZZsyZM8yZAMxm/8xmzMxmmcxmZsxmM8xmAMwz/8wzzMwzmcwzZswzM8wzAMwA/8wAzMwAmcwAZswAM8wAAJn//5n/zJn/mZn/Zpn/M5n/AJnM/5nMzJnMmZnMZpnMM5nMAJmZ/5mZzJmZmZmZZpmZM5mZAJlm/5lmzJlmmZlmZplmM5lmAJkz/5kzzJkzmZkzZpkzM5kzAJkA/5kAzJkAmZkAZpkAM5kAAGb//2b/zGb/mWb/Zmb/M2b/AGbM/2bMzGbMmWbMZmbMM2bMAGaZ/2aZzGaZmWaZZmaZM2aZAGZm/2ZmzGZmmWZmZmZmM2ZmAGYz/2YzzGYzmWYzZmYzM2YzAGYA/2YAzGYAmWYAZmYAM2YAADP//zP/zDP/mTP/ZjP/MzP/ADPM/zPMzDPMmTPMZjPMMzPMADOZ/zOZzDOZmTOZZjOZMzOZADNm/zNmzDNmmTNmZjNmMzNmADMz/zMzzDMzmTMzZjMzMzMzADMA/zMAzDMAmTMAZjMAMzMAAAD//wD/zAD/mQD/ZgD/MwD/AADM/wDMzADMmQDMZgDMMwDMAACZ/wCZzACZmQCZZgCZMwCZAABm/wBmzABmmQBmZgBmMwBmAAAz/wAzzAAzmQAzZgAzMwAzAAAA/wAAzAAAmQAAZgAAMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAdABuAAAI/wABCBxIsCBBEgYTKlyoECHDhxAHOoxIceHEihgPZtwo8CLHih4/RgwpkiHJkhZRglQ5kmVLlw9Pwuw402TNlDcNyqy5c2ZPlz+B5kwYVGVRo0N1JtW4VGJTp0+PopRakupHq1ef0oyqFQBWjl8zhhXbdexKrWbPNk1Lke3LtWXjckUrFy7du3bFktjLt6/fv4ADCx5MuLDhw4PB1l3qFmLjmHjzSk762GZkyoshi6zcMDPmuaAnD+Xc+fJoz6dDM0Z9kzRR1jxhx1b9mXZO10pN35btU/du37Nt/xadWnhw4sNXAz9eG3nr5b2hC5U+3Tnz5tizw7yIm6nx7V6ps/3s7l359+jW0aevvp699uTm48t/f714e6Ti8d/Xv78qWMQABijggAQmthF5UPXnX34Lngeeg+7Rp9589kk4oYURVojheLw9qOBmHXLIYIMUwrchfyU+B6GIK04VIosp1mfijDSq+GFWI+LYoos7khijhz6+lqNiQxJ5o5FHklXkgUsq2aOOSTr5I5BTwlillRpmWeOFWtp4JYon8vgklGGKGaVaZ6JZZpBdculYgXDGKeecSH7J5pZuyuilnSA2iRGC4fmpZpt56lnooVQSmqiiWDLa6J5r9plmWy+ayaekl5IZaZ2bcornop8+CqmjlnbK5JiehgomqaWqWlBAADs=");
  background-attachment: fixed;
  display: flex;
  min-height: calc(100vh - 3em);
  align-items: center;


@@ 125,6 126,9 @@ h1, h2, h3, h4, h5, h6, p, ul, ol, pre {
  margin-bottom: 0.5em; 
}

/* Same as H1. */
.site-title { font-size: 1.75em; margin-left: calc(1em * -6/6); }

aside ul li { 
  display: inline-block;
}


@@ 186,6 190,9 @@ body.list main h1 {
  h5 { margin-left: 0; }
  h6 { margin-left: 0; }

  /* Same as H1. */
  .site-title { margin-left: 0; }

  table td { 
    display: block;
    width: 100%;

M internal/s/tmpl/html/_aside.html => internal/s/tmpl/html/_aside.html +2 -1
@@ 3,7 3,7 @@
  <div>
    <div>
      <a href="/">
        <h1>{{.Val "string1"}}</h1>
        <h2 class='site-title'>{{.Val "string1"}}</h2>
      </a>
      <p>{{.Val "desc"}}</p>
      <nav>


@@ 15,6 15,7 @@
          {{end}}
        </ul>
      </nav>
    </div>
  </div>
</aside>
{{end}}

M internal/s/tmpl/html/_tracker.html => internal/s/tmpl/html/_tracker.html +1 -1
@@ 1,3 1,3 @@
{{if .A}}
<img style='position: fixed; bottom: 0; right: 0;' src="//evanjones.goatcounter.com/count?p={{.A.Path}}{{if .A.Referer}}&r={{.A.Referer}}{{end}}&rnd={{.A.RND}}">
<img alt='Tracker pixel... Sorry!' style='position: fixed; bottom: 0; right: 0;' src="//evanjones.goatcounter.com/count?p={{.A.Path}}{{if .A.Referer}}&r={{.A.Referer}}{{end}}&rnd={{.A.RND}}">
{{end}}

M internal/s/tmpl/html/item.html => internal/s/tmpl/html/item.html +2 -2
@@ 1,6 1,6 @@
{{with .Item.Must}}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html lang=en xmlns="http://www.w3.org/1999/xhtml">
<head>
  {{ template "html/_head.html" $ }}
  <title>{{.Val "name"}} | {{$.Aside.Must.Val "string2"}}</title>


@@ 10,8 10,8 @@
  {{end}}
</head>
<body>
  {{template "html/_styles.html" $}}
  <div>
    {{ template "html/_styles.html" $ }}
    {{ template "html/_aside.html" $ }}
    <main>
      <div>

M internal/s/tmpl/html/list.html => internal/s/tmpl/html/list.html +2 -2
@@ 1,12 1,12 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html lang=en xmlns="http://www.w3.org/1999/xhtml">
<head>
  {{template "html/_head.html" $}}
  <title>{{.Aside.Must.Val "string3"}} | {{.Aside.Must.Val "string2"}}</title>
</head>
<body class=list>
  {{template "html/_styles.html" $}}
  <div>
    {{template "html/_styles.html" $}}
    {{template "html/_aside.html" $}}
    <main>
      <div>

M internal/s/tmpl/tmpl.go => internal/s/tmpl/tmpl.go +49 -27
@@ 1,9 1,10 @@
package tmpl

import (
	"embed"
	"html/template"
	"log"
	"path/filepath"
	"sync"
	"time"

	"github.com/tdewolff/minify/v2"


@@ 12,50 13,71 @@ import (
	"github.com/tdewolff/minify/v2/js"
)

//go:generate embed -pattern */* -id tmpls
//go:embed */*
var templs embed.FS

var (
	all = template.New("cms").
var all = template.Must(
	template.New("").
		Funcs(template.FuncMap(map[string]interface{}{
			"html": func(val string) template.HTML { return template.HTML(val) },
			"date": func(val string) (string, error) {
				date, err := time.Parse("2006-01-02", val)
				return date.Format("Jan 2, 2006"), err
			},
		}))
	minifier = minify.New()
	once     sync.Once
)
		})).
		ParseFS(templs, "*/*"))

func MustParse(name string) *template.Template {
	once.Do(func() {
		minifier.AddFunc("text/css", css.Minify)
		minifier.AddFunc("text/html", html.Minify)
		minifier.AddFunc("application/javascript", js.Minify)
// init will minimize all css, html, and javascript assets.
func init() {
	minifier := minify.New()
	minifier.AddFunc("text/css", css.Minify)
	minifier.AddFunc("text/html", html.Minify)
	minifier.AddFunc("application/javascript", js.Minify)

	var minimize func(dirname string)
	minimize = func(dirname string) {
		dir, err := templs.ReadDir(dirname)
		if err != nil {
			log.Fatal(err)
		}

		for key, val := range tmpls {
			var err error
			ext := filepath.Ext(key)
		for _, entry := range dir {
			if entry.IsDir() {
				minimize(filepath.Join(dirname, entry.Name()))
				continue
			}

			name := filepath.Join(dirname, entry.Name())
			bytes, err := templs.ReadFile(name)
			if err != nil {
				log.Fatal(err)
			}

			switch ext {
			switch filepath.Ext(name) {
			case ".html":
				val, err = minifier.String("text/html", val)
				bytes, err = minifier.Bytes("text/html", bytes)
				break
			case ".css":
				val, err = minifier.String("text/css", val)
				bytes, err = minifier.Bytes("text/css", bytes)
				break
			case ".js":
				val, err = minifier.String("application/javascript", val)
				bytes, err = minifier.Bytes("application/javascript", bytes)
				break
			}

			if err != nil {
				panic(err.Error())
			}

			all = template.Must(all.New(key).Parse(val))
			all = template.Must(all.New(name).Parse(string(bytes)))
		}
	})
	}

	return all.Lookup(name)
	minimize("img")
	minimize("css")
	minimize("html")
}

func MustParse(name string) *template.Template {
	t := all.Lookup(name)
	if t == nil {
		log.Fatalf("template %s does not exist", name)
	}
	return t
}

D internal/s/tmpl/tmpls_embed.go => internal/s/tmpl/tmpls_embed.go +0 -57
@@ 1,57 0,0 @@
// Code generated by "embed -pattern */* -id tmpls"; DO NOT EDIT.

package tmpl

import "encoding/base64"

var tmpls map[string]string

func tostring(in string) string {
	bytes, _ := base64.StdEncoding.DecodeString(in)
	return string(bytes)
}

func init() {
	tmpls = make(map[string]string)

	tmpls["css/hyde.css"] = tostring("LyoKICogIF9fICAgICAgICAgICAgICAgICAgX18KICogL1wgXCAgICAgICAgICAgICAgICAvXCBcCiAqIFwgXCBcX19fICAgX18gIF9fICAgXF9cIFwgICAgIF9fCiAqICBcIFwgIF8gYFwvXCBcL1wgXCAgLydfYCBcICAvJ19fYFwKICogICBcIFwgXCBcIFwgXCBcX1wgXC9cIFxfXCBcL1wgIF9fLwogKiAgICBcIFxfXCBcX1wvYF9fX18gXCBcX19fLF9cIFxfX19fXAogKiAgICAgXC9fL1wvXy9gL19fXy8+IFwvX18sXyAvXC9fX19fLwogKiAgICAgICAgICAgICAgICAvXF9fXy8KICogICAgICAgICAgICAgICAgXC9fXy8KICoKICogRGVzaWduZWQsIGJ1aWx0LCBhbmQgcmVsZWFzZWQgdW5kZXIgTUlUIGxpY2Vuc2UgYnkgQG1kby4gTGVhcm4gbW9yZSBhdAogKiBodHRwczovL2dpdGh1Yi5jb20vcG9vbGUvaHlkZS4KICovCgoKLyoKICogQ29udGVudHMKICoKICogR2xvYmFsIHJlc2V0cwogKiBTaWRlYmFyCiAqIENvbnRhaW5lcgogKiBSZXZlcnNlIGxheW91dAogKiBUaGVtZXMKICovCgoKLyoKICogR2xvYmFsIHJlc2V0cwogKgogKiBVcGRhdGUgdGhlIGZvdW5kYXRpb25hbCBhbmQgZ2xvYmFsIGFzcGVjdHMgb2YgdGhlIHBhZ2UuCiAqLwoKaHRtbCB7CiAgZm9udC1mYW1pbHk6ICJQVCBTYW5zIiwgSGVsdmV0aWNhLCBBcmlhbCwgc2Fucy1zZXJpZjsKfQpAbWVkaWEgKG1pbi13aWR0aDogNDhlbSkgewogIGh0bWwgewogICAgZm9udC1zaXplOiAxNnB4OwogIH0KfQpAbWVkaWEgKG1pbi13aWR0aDogNThlbSkgewogIGh0bWwgewogICAgZm9udC1zaXplOiAyMHB4OwogIH0KfQoKCi8qCiAqIFNpZGViYXIKICoKICogRmxleGlibGUgYmFubmVyIGZvciBob3VzaW5nIHNpdGUgbmFtZSwgaW50cm8sIGFuZCAiZm9vdGVyIiBjb250ZW50LiBTdGFydHMKICogb3V0IGFib3ZlIGNvbnRlbnQgaW4gbW9iaWxlIGFuZCBsYXRlciBtb3ZlcyB0byB0aGUgc2lkZSB3aXRoIHdpZGVyIHZpZXdwb3J0cy4KICovCgouc2lkZWJhciB7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIHBhZGRpbmc6IDJyZW0gMXJlbTsKICBjb2xvcjogcmdiYSgyNTUsMjU1LDI1NSwuNSk7CiAgYmFja2dyb3VuZC1jb2xvcjogIzIwMjAyMDsKfQpAbWVkaWEgKG1pbi13aWR0aDogNDhlbSkgewogIC5zaWRlYmFyIHsKICAgIHBvc2l0aW9uOiBmaXhlZDsKICAgIHRvcDogMDsKICAgIGxlZnQ6IDA7CiAgICBib3R0b206IDA7CiAgICB3aWR0aDogMThyZW07CiAgICB0ZXh0LWFsaWduOiBsZWZ0OwogIH0KfQoKLyogU2lkZWJhciBsaW5rcyAqLwouc2lkZWJhciBhIHsKICBjb2xvcjogI2ZmZjsKfQoKLyogQWJvdXQgc2VjdGlvbiAqLwouc2lkZWJhci1hYm91dCBoMSB7CiAgY29sb3I6ICNmZmY7CiAgbWFyZ2luLXRvcDogMDsKICBmb250LWZhbWlseTogIkFicmlsIEZhdGZhY2UiLCBzZXJpZjsKICBmb250LXNpemU6IDMuMjVyZW07Cn0KCi8qIFNpZGViYXIgbmF2ICovCi5zaWRlYmFyLW5hdiB7CiAgcGFkZGluZy1sZWZ0OiAwOwogIGxpc3Qtc3R5bGU6IG5vbmU7Cn0KLnNpZGViYXItbmF2LWl0ZW0gewogIGRpc3BsYXk6IGJsb2NrOwp9CmEuc2lkZWJhci1uYXYtaXRlbTpob3ZlciwKYS5zaWRlYmFyLW5hdi1pdGVtOmZvY3VzIHsKICB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTsKfQouc2lkZWJhci1uYXYtaXRlbS5hY3RpdmUgewogIGZvbnQtd2VpZ2h0OiBib2xkOwp9CgovKiBTdGlja3kgc2lkZWJhcgogKgogKiBBZGQgdGhlIGBzaWRlYmFyLXN0aWNreWAgY2xhc3MgdG8gdGhlIHNpZGViYXIncyBjb250YWluZXIgdG8gYWZmaXggaXQgdGhlCiAqIGNvbnRlbnRzIHRvIHRoZSBib3R0b20gb2YgdGhlIHNpZGViYXIgaW4gdGFibGV0cyBhbmQgdXAuCiAqLwoKQG1lZGlhIChtaW4td2lkdGg6IDQ4ZW0pIHsKICAuc2lkZWJhci1zdGlja3kgewogICAgcG9zaXRpb246IGFic29sdXRlOwogICAgcmlnaHQ6ICAxcmVtOwogICAgYm90dG9tOiAxcmVtOwogICAgbGVmdDogICAxcmVtOwogIH0KfQoKCi8qIENvbnRhaW5lcgogKgogKiBBbGlnbiB0aGUgY29udGVudHMgb2YgdGhlIHNpdGUgYWJvdmUgdGhlIHByb3BlciB0aHJlc2hvbGQgd2l0aCBzb21lIG1hcmdpbi1mdQogKiB3aXRoIGEgMjUlLXdpZGUgYC5zaWRlYmFyYC4KICovCgouY29udGVudCB7CiAgcGFkZGluZy10b3A6ICAgIDRyZW07CiAgcGFkZGluZy1ib3R0b206IDRyZW07Cn0KCkBtZWRpYSAobWluLXdpZHRoOiA0OGVtKSB7CiAgLmNvbnRlbnQgewogICAgbWF4LXdpZHRoOiAzOHJlbTsKICAgIG1hcmdpbi1sZWZ0OiAyMHJlbTsKICAgIG1hcmdpbi1yaWdodDogMnJlbTsKICB9Cn0KCkBtZWRpYSAobWluLXdpZHRoOiA2NGVtKSB7CiAgLmNvbnRlbnQgewogICAgbWFyZ2luLWxlZnQ6IDIycmVtOwogICAgbWFyZ2luLXJpZ2h0OiA0cmVtOwogIH0KfQoKCi8qCiAqIFJldmVyc2UgbGF5b3V0CiAqCiAqIEZsaXAgdGhlIG9yaWVudGF0aW9uIG9mIHRoZSBwYWdlIGJ5IHBsYWNpbmcgdGhlIGAuc2lkZWJhcmAgb24gdGhlIHJpZ2h0LgogKi8KCkBtZWRpYSAobWluLXdpZHRoOiA0OGVtKSB7CiAgLmxheW91dC1yZXZlcnNlIC5zaWRlYmFyIHsKICAgIGxlZnQ6IGF1dG87CiAgICByaWdodDogMDsKICB9CiAgLmxheW91dC1yZXZlcnNlIC5jb250ZW50IHsKICAgIG1hcmdpbi1sZWZ0OiAycmVtOwogICAgbWFyZ2luLXJpZ2h0OiAyMHJlbTsKICB9Cn0KCkBtZWRpYSAobWluLXdpZHRoOiA2NGVtKSB7CiAgLmxheW91dC1yZXZlcnNlIC5jb250ZW50IHsKICAgIG1hcmdpbi1sZWZ0OiA0cmVtOwogICAgbWFyZ2luLXJpZ2h0OiAyMnJlbTsKICB9Cn0KCgoKLyoKICogVGhlbWVzCiAqCiAqIEFzIG9mIHYxLjEsIEh5ZGUgaW5jbHVkZXMgb3B0aW9uYWwgdGhlbWVzIHRvIGNvbG9yIHRoZSBzaWRlYmFyIGFuZCBsaW5rcwogKiB3aXRoaW4gYmxvZyBwb3N0cy4gVG8gdXNlLCBhZGQgdGhlIGNsYXNzIG9mIHlvdXIgY2hvb3NpbmcgdG8gdGhlIGBib2R5YC4KICovCgovKiBCYXNlMTYgKGh0dHA6Ly9jaHJpc2tlbXBzb24uZ2l0aHViLmlvL2Jhc2UxNi8jZGVmYXVsdCkgKi8KCi8qIFJlZCAqLwoudGhlbWUtYmFzZS0wOCAuc2lkZWJhciB7CiAgYmFja2dyb3VuZC1jb2xvcjogI2FjNDE0MjsKfQoudGhlbWUtYmFzZS0wOCAuY29udGVudCBhLAoudGhlbWUtYmFzZS0wOCAucmVsYXRlZC1wb3N0cyBsaSBhOmhvdmVyIHsKICBjb2xvcjogI2FjNDE0MjsKfQoKLyogT3JhbmdlICovCi50aGVtZS1iYXNlLTA5IC5zaWRlYmFyIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZDI4NDQ1Owp9Ci50aGVtZS1iYXNlLTA5IC5jb250ZW50IGEsCi50aGVtZS1iYXNlLTA5IC5yZWxhdGVkLXBvc3RzIGxpIGE6aG92ZXIgewogIGNvbG9yOiAjZDI4NDQ1Owp9CgovKiBZZWxsb3cgKi8KLnRoZW1lLWJhc2UtMGEgLnNpZGViYXIgewogIGJhY2tncm91bmQtY29sb3I6ICNmNGJmNzU7Cn0KLnRoZW1lLWJhc2UtMGEgLmNvbnRlbnQgYSwKLnRoZW1lLWJhc2UtMGEgLnJlbGF0ZWQtcG9zdHMgbGkgYTpob3ZlciB7CiAgY29sb3I6ICNmNGJmNzU7Cn0KCi8qIEdyZWVuICovCi50aGVtZS1iYXNlLTBiIC5zaWRlYmFyIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjOTBhOTU5Owp9Ci50aGVtZS1iYXNlLTBiIC5jb250ZW50IGEsCi50aGVtZS1iYXNlLTBiIC5yZWxhdGVkLXBvc3RzIGxpIGE6aG92ZXIgewogIGNvbG9yOiAjOTBhOTU5Owp9CgovKiBDeWFuICovCi50aGVtZS1iYXNlLTBjIC5zaWRlYmFyIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjNzViNWFhOwp9Ci50aGVtZS1iYXNlLTBjIC5jb250ZW50IGEsCi50aGVtZS1iYXNlLTBjIC5yZWxhdGVkLXBvc3RzIGxpIGE6aG92ZXIgewogIGNvbG9yOiAjNzViNWFhOwp9CgovKiBCbHVlICovCi50aGVtZS1iYXNlLTBkIC5zaWRlYmFyIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjNmE5ZmI1Owp9Ci50aGVtZS1iYXNlLTBkIC5jb250ZW50IGEsCi50aGVtZS1iYXNlLTBkIC5yZWxhdGVkLXBvc3RzIGxpIGE6aG92ZXIgewogIGNvbG9yOiAjNmE5ZmI1Owp9CgovKiBNYWdlbnRhICovCi50aGVtZS1iYXNlLTBlIC5zaWRlYmFyIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjYWE3NTlmOwp9Ci50aGVtZS1iYXNlLTBlIC5jb250ZW50IGEsCi50aGVtZS1iYXNlLTBlIC5yZWxhdGVkLXBvc3RzIGxpIGE6aG92ZXIgewogIGNvbG9yOiAjYWE3NTlmOwp9CgovKiBCcm93biAqLwoudGhlbWUtYmFzZS0wZiAuc2lkZWJhciB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzhmNTUzNjsKfQoudGhlbWUtYmFzZS0wZiAuY29udGVudCBhLAoudGhlbWUtYmFzZS0wZiAucmVsYXRlZC1wb3N0cyBsaSBhOmhvdmVyIHsKICBjb2xvcjogIzhmNTUzNjsKfQo=")

	tmpls["css/main.css"] = tostring("LyogUmVzZXQgQ1NTICovCmh0bWwsIGJvZHksIGRpdiwgc3BhbiwgYXBwbGV0LCBvYmplY3QsIGlmcmFtZSwKaDEsIGgyLCBoMywgaDQsIGg1LCBoNiwgcCwgYmxvY2txdW90ZSwgcHJlLAphLCBhYmJyLCBhY3JvbnltLCBhZGRyZXNzLCBiaWcsIGNpdGUsIGNvZGUsCmRlbCwgZGZuLCBlbSwgaW1nLCBpbnMsIGtiZCwgcSwgcywgc2FtcCwKc21hbGwsIHN0cmlrZSwgc3Ryb25nLCBzdWIsIHN1cCwgdHQsIHZhciwKYiwgdSwgaSwgY2VudGVyLApkbCwgZHQsIGRkLCBtZW51LCBvbCwgdWwsIGxpLApmaWVsZHNldCwgZm9ybSwgbGFiZWwsIGxlZ2VuZCwKdGFibGUsIGNhcHRpb24sIHRib2R5LCB0Zm9vdCwgdGhlYWQsIHRyLCB0aCwgdGQsCmFydGljbGUsIGFzaWRlLCBjYW52YXMsIGRldGFpbHMsIGVtYmVkLApmaWd1cmUsIGZpZ2NhcHRpb24sIGZvb3RlciwgaGVhZGVyLCBoZ3JvdXAsCm1haW4sIG1lbnUsIG5hdiwgb3V0cHV0LCBydWJ5LCBzZWN0aW9uLCBzdW1tYXJ5LAp0aW1lLCBtYXJrLCBhdWRpbywgdmlkZW8gewoJbWFyZ2luOiAwOwoJcGFkZGluZzogMDsKCWJvcmRlcjogMDsKCWZvbnQtc2l6ZTogMTAwJTsKCWZvbnQ6IGluaGVyaXQ7Cgl2ZXJ0aWNhbC1hbGlnbjogYmFzZWxpbmU7Cn0KCmFydGljbGUsIGFzaWRlLCBkZXRhaWxzLCBmaWdjYXB0aW9uLCBmaWd1cmUsCmZvb3RlciwgaGVhZGVyLCBoZ3JvdXAsIG1haW4sIG1lbnUsIG5hdiwgc2VjdGlvbiB7CglkaXNwbGF5OiBibG9jazsKfQoKKltoaWRkZW5dIHsKICAgIGRpc3BsYXk6IG5vbmU7Cn0KCmJvZHkgewoJbGluZS1oZWlnaHQ6IDE7Cn0KCm1lbnUsIG9sLCB1bCB7CglsaXN0LXN0eWxlOiBub25lOwp9CgpibG9ja3F1b3RlLCBxIHsKCXF1b3Rlczogbm9uZTsKfQoKYmxvY2txdW90ZTpiZWZvcmUsIGJsb2NrcXVvdGU6YWZ0ZXIsCnE6YmVmb3JlLCBxOmFmdGVyIHsKCWNvbnRlbnQ6ICcnOwoJY29udGVudDogbm9uZTsKfQoKdGFibGUgewoJYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsKCWJvcmRlci1zcGFjaW5nOiAwOwp9CgovKiBDdXN0b20gQ1NTICovCmJvZHkgeyAKICBmb250LWZhbWlseTogJ0VCIEdhcmFtb25kJywgc2VyaWY7CiAgZm9udC1zaXplOiAyMnB4OwogIGxpbmUtaGVpZ2h0OiAxLjQ7CiAgYmFja2dyb3VuZC1pbWFnZTogdXJsKCJkYXRhOmltYWdlL2dpZjtiYXNlNjQsUjBsR09EbGhkQUJ1QVBjQUFQLy8vLy8velAvL21mLy9adi8vTS8vL0FQL00vLy9NelAvTW1mL01adi9NTS8vTUFQK1ovLytaelArWm1mK1paditaTS8rWkFQOW0vLzltelA5bW1mOW1adjltTS85bUFQOHovLzh6elA4em1mOHpadjh6TS84ekFQOEEvLzhBelA4QW1mOEFadjhBTS84QUFNei8vOHovek16L21jei9ac3ovTTh6L0FNek0vOHpNek16TW1jek1ac3pNTTh6TUFNeVovOHlaek15Wm1jeVpac3laTTh5WkFNeG0vOHhtek14bW1jeG1ac3htTTh4bUFNd3ovOHd6ek13em1jd3pac3d6TTh3ekFNd0EvOHdBek13QW1jd0Fac3dBTTh3QUFKbi8vNW4vekpuL21abi9acG4vTTVuL0FKbk0vNW5NekpuTW1abk1acG5NTTVuTUFKbVovNW1aekptWm1abVpacG1aTTVtWkFKbG0vNWxtekpsbW1abG1acGxtTTVsbUFKa3ovNWt6ekprem1aa3pacGt6TTVrekFKa0EvNWtBekprQW1aa0FacGtBTTVrQUFHYi8vMmIvekdiL21XYi9abWIvTTJiL0FHYk0vMmJNekdiTW1XYk1abWJNTTJiTUFHYVovMmFaekdhWm1XYVpabWFaTTJhWkFHWm0vMlptekdabW1XWm1abVptTTJabUFHWXovMll6ekdZem1XWXpabVl6TTJZekFHWUEvMllBekdZQW1XWUFabVlBTTJZQUFEUC8velAvekRQL21UUC9aalAvTXpQL0FEUE0velBNekRQTW1UUE1aalBNTXpQTUFET1ovek9aekRPWm1UT1paak9aTXpPWkFETm0vek5tekRObW1UTm1aak5tTXpObUFETXovek16ekRNem1UTXpaak16TXpNekFETUEvek1BekRNQW1UTUFaak1BTXpNQUFBRC8vd0QvekFEL21RRC9aZ0QvTXdEL0FBRE0vd0RNekFETW1RRE1aZ0RNTXdETUFBQ1ovd0NaekFDWm1RQ1paZ0NaTXdDWkFBQm0vd0JtekFCbW1RQm1aZ0JtTXdCbUFBQXovd0F6ekFBem1RQXpaZ0F6TXdBekFBQUEvd0FBekFBQW1RQUFaZ0FBTXdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ3dBQUFBQWRBQnVBQUFJL3dBQkNCeElzQ0JCRWdZVEtseW9FQ0hEaHhBSE9veEljZUhFaWhnUFp0d284Q0xIaWg0L1Jnd3BraUhKa2haUmdsUTVrbVZMbHc5UHd1dzQwMlRObERjTnlxeTVjMlpQbHorQjVrd1lWR1ZSbzBOMUp0VzRWR0pUcDArUG9wUmFrdXBIcTFlZjBveXFGUUJXamw4emhoWGJkZXhLcldiUE5rMUxrZTNMdFdYamNrVXJGeTdkdTNiRmt0akx0Ni9mdjRBREN4NU11TERodzRQQjFsM3FGbUxqbUhqelNrNzYyR1preW9zaGk2emNNRFBtdWFBbkQrWGMrZkpvejZkRE0wWjlrelJSMWp4aHgxYjltWFpPMTBwTjM1YnRVL2R1MzdOdC94YWRXbmh3NHNOWEF6OWVHM25yNWIyaEM1VSszVG56NXRpenc3eUltNm54N1Y2cHMvM3M3bDM1OStqVzBhZXZ2cDY5OXVUbTQ4dC9mNzE0ZTZUaThkL1h2NzhxV01RQUJpamdnQVFtdGhGNVVQWG5YMzRMbmdlZWcrN1JwOTU4OWtrNG9ZVVJWb2poZUx3OXFPQm1IWExJWUlNVXdyY2hmeVUrQjZHSUswNFZJb3NwMW1maWpEU3ErR0ZXSStMWW9vczdraGlqaHo2K2xxTmlReEo1bzVGSGtsWGtnVXNxMmFPT1NUcjVJNUJUd2xpbGxScG1XZU9GV3RwNEpZb244dmdrbEdHS0dhVmFaNkpaWnBCZGN1bFlnWERHS2VlY1NIN0o1cFp1eXVpbG5TQTJpUkdDNGZtcFpwdDU2bG5vb1ZRU21xaWlXRExhNko1cjlwbG1XeStheWFla2w1SVphWjJiY29ybm9wOCtDcW1qbG5iSzVKaWVoZ29tcWFXcVdsQkFBRHM9Iik7CiAgZGlzcGxheTogZmxleDsKICBtaW4taGVpZ2h0OiBjYWxjKDEwMHZoIC0gM2VtKTsKICBhbGlnbi1pdGVtczogY2VudGVyOwogIGp1c3RpZnktY29udGVudDogY2VudGVyOwogIHBhZGRpbmc6IDAgMWVtIDNlbTsKfQoKcCB7IAogIHdoaXRlLXNwYWNlOiBwcmUtd3JhcDsKfQoKYSB7IAogIHRleHQtZGVjb3JhdGlvbjogbm9uZTsKfQoKYTpmb2N1cywgCmE6aG92ZXIgewogIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lOwp9CgpibG9ja3F1b3RlIHsgCiAgcGFkZGluZy1sZWZ0OiAxZW07CiAgYm9yZGVyLWxlZnQ6IDJweCBzb2xpZCBibGFjazsKICBtYXJnaW4tdG9wOiAyZW07Cn0KCmNpdGUgeyAKICBmb250LXN0eWxlOiBpdGFsaWM7CiAgbWFyZ2luLWJvdHRvbTogMmVtOwp9CgpjaXRlOmJlZm9yZSB7IAogIGNvbnRlbnQ6ICfigJQnOwogIG1hcmdpbi1yaWdodDogMC41ZW07Cn0KCnByZSB7IAogIG92ZXJmbG93LXg6IGF1dG87CiAgLXdlYmtpdC1vdmVyZmxvdy1zY3JvbGxpbmc6IHRvdWNoOwogIGJhY2tncm91bmQ6IHdoaXRlOwogIGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7CiAgd2hpdGUtc3BhY2U6IHByZTsKICBwYWRkaW5nOiAxZW07CiAgYm9yZGVyOiAxcHggI2FhYSBzb2xpZDsKICBib3JkZXItcmFkaXVzOiAycHg7CiAgZm9udC1zaXplOiAwLjc1ZW07Cn0KCmJvZHkgPiBkaXYgeyAKICB3aWR0aDogNzI1cHg7IAogIHdpZHRoOiA3MGNoOwogIG1heC13aWR0aDogMTAwJTsKfQoKaDEsIGgyLCBoMywgaDQsIGg1LCBoNiB7IGZvbnQtd2VpZ2h0OiBib2xkOyB9CmgxIHsgZm9udC1zaXplOiAxLjc1ZW07IG1hcmdpbi1sZWZ0OiBjYWxjKDFlbSAqIC02LzYpOyB9CmgyIHsgZm9udC1zaXplOiAxLjYwZW07IG1hcmdpbi1sZWZ0OiBjYWxjKDFlbSAqIC01LzYpOyB9CmgzIHsgZm9udC1zaXplOiAxLjQ1ZW07IG1hcmdpbi1sZWZ0OiBjYWxjKDFlbSAqIC00LzYpOyB9Cmg0IHsgZm9udC1zaXplOiAxLjMwZW07IG1hcmdpbi1sZWZ0OiBjYWxjKDFlbSAqIC0zLzYpOyB9Cmg1IHsgZm9udC1zaXplOiAxLjE1ZW07IG1hcmdpbi1sZWZ0OiBjYWxjKDFlbSAqIC0yLzYpOyB9Cmg2IHsgZm9udC1zaXplOiAxLjAwZW07IG1hcmdpbi1sZWZ0OiBjYWxjKDFlbSAqIC0xLzYpOyB9CgpoMSwgaDIsIGgzLCBoNCwgaDUsIGg2LCBwLCB1bCwgb2wsIHByZSB7IAogIG1hcmdpbi10b3A6ICAgIDAuNWVtOyAKICBtYXJnaW4tYm90dG9tOiAwLjVlbTsgCn0KCmFzaWRlIHVsIGxpIHsgCiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwp9Cgphc2lkZSB1bCBsaTpub3QoOmxhc3Qtb2YtdHlwZSk6YWZ0ZXIgeyAKICBjb250ZW50OiAnIHwgJzsKICBtYXJnaW46IDAgMC41ZW07Cn0KCm1haW4gb2wgbGksCm1haW4gdWwgbGkgeyAKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgbWFyZ2luLWJvdHRvbTogMC4yNWVtOwogIHBhZGRpbmctbGVmdDogMS4wZW07Cn0KCm1haW4gb2wgbGk6YmVmb3JlLAptYWluIHVsIGxpOmJlZm9yZSB7IAogIGNvbnRlbnQ6ICc+JzsKICBmb250LXdlaWdodDogYm9sZDsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgdG9wOiAwOwogIGxlZnQ6IDBlbTsKfQoKdGFibGUgeyAKICB3aWR0aDogMTAwJTsKfQoKdGFibGUgdGQgeyAKICBwYWRkaW5nLXRvcDogM2VtOwp9CgpzdHJvbmcgeyAKICBmb250LXdlaWdodDogYm9sZDsKfQoKaSB7IAogIGZvbnQtc3R5bGU6IGl0YWxpYzsKfQoKaW1nIHsgCiAgbWF4LXdpZHRoOiAxMDAlOwogIGJvcmRlci1yYWRpdXM6IDJweDsKICBvdmVyZmxvdzogaGlkZGVuOwp9Cgpib2R5Lmxpc3QgbWFpbiBoMSB7IAogIG1hcmdpbi1ib3R0b206IDA7Cn0KCkBtZWRpYSAobWF4LXdpZHRoOiAxMDAwcHgpIHsKICBib2R5IHsgZm9udC1zaXplOiAyMHB4OyB9CgogIGgxIHsgbWFyZ2luLWxlZnQ6IDA7IH0KICBoMiB7IG1hcmdpbi1sZWZ0OiAwOyB9CiAgaDMgeyBtYXJnaW4tbGVmdDogMDsgfQogIGg0IHsgbWFyZ2luLWxlZnQ6IDA7IH0KICBoNSB7IG1hcmdpbi1sZWZ0OiAwOyB9CiAgaDYgeyBtYXJnaW4tbGVmdDogMDsgfQoKICB0YWJsZSB0ZCB7IAogICAgZGlzcGxheTogYmxvY2s7CiAgICB3aWR0aDogMTAwJTsKICAgIG1hcmdpbi10b3A6IDFlbTsKICAgIHBhZGRpbmctdG9wOiAwOwogIH0KfQo=")

	tmpls["css/poole.css"] = tostring("LyoKICogICAgICAgICAgICAgICAgICAgICAgICBfX18KICogICAgICAgICAgICAgICAgICAgICAgIC9cXyBcCiAqICBfX19fXyAgICAgX19fICAgICBfX19cLy9cIFwgICAgICBfXwogKiAvXCAnX19gXCAgLyBfX2BcICAvIF9fYFxcIFwgXCAgIC8nX19gXAogKiBcIFwgXF9cIFwvXCBcX1wgXC9cIFxfXCBcXF9cIFxfL1wgIF9fLwogKiAgXCBcICxfXy9cIFxfX19fL1wgXF9fX18vL1xfX19fXCBcX19fX1wKICogICBcIFwgXC8gIFwvX19fLyAgXC9fX18vIFwvX19fXy9cL19fX18vCiAqICAgIFwgXF9cCiAqICAgICBcL18vCiAqCiAqIERlc2lnbmVkLCBidWlsdCwgYW5kIHJlbGVhc2VkIHVuZGVyIE1JVCBsaWNlbnNlIGJ5IEBtZG8uIExlYXJuIG1vcmUgYXQKICogaHR0cHM6Ly9naXRodWIuY29tL3Bvb2xlL3Bvb2xlLgogKi8KCgovKgogKiBDb250ZW50cwogKgogKiBCb2R5IHJlc2V0cwogKiBDdXN0b20gdHlwZQogKiBNZXNzYWdlcwogKiBDb250YWluZXIKICogTWFzdGhlYWQKICogUG9zdHMgYW5kIHBhZ2VzCiAqIFBhZ2luYXRpb24KICogUmV2ZXJzZSBsYXlvdXQKICogVGhlbWVzCiAqLwoKCi8qCiAqIEJvZHkgcmVzZXRzCiAqCiAqIFVwZGF0ZSB0aGUgZm91bmRhdGlvbmFsIGFuZCBnbG9iYWwgYXNwZWN0cyBvZiB0aGUgcGFnZS4KICovCgoqIHsKICAtd2Via2l0LWJveC1zaXppbmc6IGJvcmRlci1ib3g7CiAgICAgLW1vei1ib3gtc2l6aW5nOiBib3JkZXItYm94OwogICAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDsKfQoKaHRtbCwKYm9keSB7CiAgbWFyZ2luOiAwOwogIHBhZGRpbmc6IDA7Cn0KCmh0bWwgewogIGZvbnQtZmFtaWx5OiAiSGVsdmV0aWNhIE5ldWUiLCBIZWx2ZXRpY2EsIEFyaWFsLCBzYW5zLXNlcmlmOwogIGZvbnQtc2l6ZTogMTZweDsKICBsaW5lLWhlaWdodDogMS41Owp9CkBtZWRpYSAobWluLXdpZHRoOiAzOGVtKSB7CiAgaHRtbCB7CiAgICBmb250LXNpemU6IDIwcHg7CiAgfQp9Cgpib2R5IHsKICBjb2xvcjogIzUxNTE1MTsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmOwogIC13ZWJraXQtdGV4dC1zaXplLWFkanVzdDogMTAwJTsKICAgICAgLW1zLXRleHQtc2l6ZS1hZGp1c3Q6IDEwMCU7CiAgICAgICAgICB0ZXh0LXNpemUtYWRqdXN0OiAxMDAlOwp9CgovKiBObyBgOnZpc2l0ZWRgIHN0YXRlIGlzIHJlcXVpcmVkIGJ5IGRlZmF1bHQgKGJyb3dzZXJzIHdpbGwgdXNlIGBhYCkgKi8KYSB7CiAgY29sb3I6ICMyMjdiYjk7CiAgdGV4dC1kZWNvcmF0aW9uOiBub25lOwp9Ci8qIGA6Zm9jdXNgIGlzIGxpbmtlZCB0byBgOmhvdmVyYCBmb3IgYmFzaWMgYWNjZXNzaWJpbGl0eSAqLwphOmhvdmVyLAphOmZvY3VzIHsKICB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTsKfQoKLyogSGVhZGluZ3MgKi8KaDEsIGgyLCBoMywgaDQsIGg1LCBoNiB7CiAgbWFyZ2luLWJvdHRvbTogLjVyZW07CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgbGluZS1oZWlnaHQ6IDEuMjU7CiAgY29sb3I6ICMzMTMxMzE7CiAgdGV4dC1yZW5kZXJpbmc6IG9wdGltaXplTGVnaWJpbGl0eTsKfQpoMSB7CiAgZm9udC1zaXplOiAycmVtOwp9CmgyIHsKICBtYXJnaW4tdG9wOiAxcmVtOwogIGZvbnQtc2l6ZTogMS41cmVtOwp9CmgzIHsKICBtYXJnaW4tdG9wOiAxLjVyZW07CiAgZm9udC1zaXplOiAxLjI1cmVtOwp9Cmg0LCBoNSwgaDYgewogIG1hcmdpbi10b3A6IDFyZW07CiAgZm9udC1zaXplOiAxcmVtOwp9CgovKiBCb2R5IHRleHQgKi8KcCB7CiAgbWFyZ2luLXRvcDogMDsKICBtYXJnaW4tYm90dG9tOiAxcmVtOwp9CgpzdHJvbmcgewogIGNvbG9yOiAjMzAzMDMwOwp9CgoKLyogTGlzdHMgKi8KdWwsIG9sLCBkbCB7CiAgbWFyZ2luLXRvcDogMDsKICBtYXJnaW4tYm90dG9tOiAxcmVtOwp9CgpkdCB7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7Cn0KZGQgewogIG1hcmdpbi1ib3R0b206IC41cmVtOwp9CgovKiBNaXNjICovCmhyIHsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgbWFyZ2luOiAxLjVyZW0gMDsKICBib3JkZXI6IDA7CiAgYm9yZGVyLXRvcDogMXB4IHNvbGlkICNlZWU7CiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICNmZmY7Cn0KCmFiYnIgewogIGZvbnQtc2l6ZTogODUlOwogIGZvbnQtd2VpZ2h0OiBib2xkOwogIGNvbG9yOiAjNTU1OwogIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7Cn0KYWJiclt0aXRsZV0gewogIGN1cnNvcjogaGVscDsKICBib3JkZXItYm90dG9tOiAxcHggZG90dGVkICNlNWU1ZTU7Cn0KCi8qIENvZGUgKi8KY29kZSwKcHJlIHsKICBmb250LWZhbWlseTogTWVubG8sIE1vbmFjbywgIkNvdXJpZXIgTmV3IiwgbW9ub3NwYWNlOwp9CmNvZGUgewogIHBhZGRpbmc6IC4yNWVtIC41ZW07CiAgZm9udC1zaXplOiA4NSU7CiAgY29sb3I6ICNiMzU1NWU7CiAgYmFja2dyb3VuZC1jb2xvcjogI2Y5ZjlmOTsKICBib3JkZXItcmFkaXVzOiAzcHg7Cn0KcHJlIHsKICBkaXNwbGF5OiBibG9jazsKICBtYXJnaW4tdG9wOiAwOwogIG1hcmdpbi1ib3R0b206IDFyZW07CiAgcGFkZGluZzogMXJlbTsKICBmb250LXNpemU6IC44cmVtOwogIGxpbmUtaGVpZ2h0OiAxLjQ7CiAgd2hpdGUtc3BhY2U6IHByZTsKICB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7CiAgd29yZC1icmVhazogYnJlYWstYWxsOwogIHdvcmQtd3JhcDogYnJlYWstd29yZDsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjlmOWY5Owp9CnByZSBjb2RlIHsKICBwYWRkaW5nOiAwOwogIGZvbnQtc2l6ZTogMTAwJTsKICBjb2xvcjogaW5oZXJpdDsKICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDsKfQouaGlnaGxpZ2h0IHsKICBtYXJnaW4tYm90dG9tOiAxcmVtOwogIGJvcmRlci1yYWRpdXM6IDRweDsKfQouaGlnaGxpZ2h0IHByZSB7CiAgbWFyZ2luLWJvdHRvbTogMDsKfQoKLyogUXVvdGVzICovCmJsb2NrcXVvdGUgewogIHBhZGRpbmc6IC41cmVtIDFyZW07CiAgbWFyZ2luOiAuOHJlbSAwOwogIGNvbG9yOiAjN2E3YTdhOwogIGJvcmRlci1sZWZ0OiAuMjVyZW0gc29saWQgI2U1ZTVlNTsKfQpibG9ja3F1b3RlIHA6bGFzdC1jaGlsZCB7CiAgbWFyZ2luLWJvdHRvbTogMDsKfQpAbWVkaWEgKG1pbi13aWR0aDogMzBlbSkgewogIGJsb2NrcXVvdGUgewogICAgcGFkZGluZy1yaWdodDogNXJlbTsKICAgIHBhZGRpbmctbGVmdDogMS4yNXJlbTsKICB9Cn0KCmltZyB7CiAgZGlzcGxheTogYmxvY2s7CiAgbWFyZ2luOiAwIDAgMXJlbTsKICBib3JkZXItcmFkaXVzOiA1cHg7CiAgbWF4LXdpZHRoOiAxMDAlOwp9CgovKiBUYWJsZXMgKi8KdGFibGUgewogIG1hcmdpbi1ib3R0b206IDFyZW07CiAgd2lkdGg6IDEwMCU7CiAgYm9yZGVyOiAxcHggc29saWQgI2U1ZTVlNTsKICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlOwp9CnRkLAp0aCB7CiAgcGFkZGluZzogLjI1cmVtIC41cmVtOwogIGJvcmRlcjogMXB4IHNvbGlkICNlNWU1ZTU7Cn0KdGJvZHkgdHI6bnRoLWNoaWxkKG9kZCkgdGQsCnRib2R5IHRyOm50aC1jaGlsZChvZGQpIHRoIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjlmOWY5Owp9CgoKLyoKICogQ3VzdG9tIHR5cGUKICoKICogRXh0ZW5kIHBhcmFncmFwaHMgd2l0aCBgLmxlYWRgIGZvciBsYXJnZXIgaW50cm9kdWN0b3J5IHRleHQuCiAqLwoKLmxlYWQgewogIGZvbnQtc2l6ZTogMS4yNXJlbTsKICBmb250LXdlaWdodDogMzAwOwp9CgoKLyoKICogTWVzc2FnZXMKICoKICogU2hvdyBhbGVydCBtZXNzYWdlcyB0byB1c2Vycy4gWW91IG1heSBhZGQgaXQgdG8gc2luZ2xlIGVsZW1lbnRzIGxpa2UgYSBgPHA+YCwKICogb3IgdG8gYSBwYXJlbnQgaWYgdGhlcmUgYXJlIG11bHRpcGxlIGVsZW1lbnRzIHRvIHNob3cuCiAqLwoKLm1lc3NhZ2UgewogIG1hcmdpbi1ib3R0b206IDFyZW07CiAgcGFkZGluZzogMXJlbTsKICBjb2xvcjogIzcxNzE3MTsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjlmOWY5Owp9CgoKLyoKICogQ29udGFpbmVyCiAqCiAqIENlbnRlciB0aGUgcGFnZSBjb250ZW50LgogKi8KCi5jb250YWluZXIgewogIG1heC13aWR0aDogMzhyZW07CiAgcGFkZGluZy1sZWZ0OiAgMXJlbTsKICBwYWRkaW5nLXJpZ2h0OiAxcmVtOwogIG1hcmdpbi1sZWZ0OiAgYXV0bzsKICBtYXJnaW4tcmlnaHQ6IGF1dG87Cn0KCgovKgogKiBNYXN0aGVhZAogKgogKiBTdXBlciBzbWFsbCBoZWFkZXIgYWJvdmUgdGhlIGNvbnRlbnQgZm9yIHNpdGUgbmFtZSBhbmQgc2hvcnQgZGVzY3JpcHRpb24uCiAqLwoKLm1hc3RoZWFkIHsKICBwYWRkaW5nLXRvcDogICAgMXJlbTsKICBwYWRkaW5nLWJvdHRvbTogMXJlbTsKICBtYXJnaW4tYm90dG9tOiAzcmVtOwp9Ci5tYXN0aGVhZC10aXRsZSB7CiAgbWFyZ2luLXRvcDogMDsKICBtYXJnaW4tYm90dG9tOiAwOwogIGNvbG9yOiAjNTA1MDUwOwp9Ci5tYXN0aGVhZC10aXRsZSBhIHsKICBjb2xvcjogIzUwNTA1MDsKfQoubWFzdGhlYWQtdGl0bGUgc21hbGwgewogIGZvbnQtc2l6ZTogNzUlOwogIGZvbnQtd2VpZ2h0OiA0MDA7CiAgY29sb3I6ICNjMGMwYzA7CiAgbGV0dGVyLXNwYWNpbmc6IDA7Cn0KCgovKgogKiBQb3N0cyBhbmQgcGFnZXMKICoKICogRWFjaCBwb3N0IGlzIHdyYXBwZWQgaW4gYC5wb3N0YCBhbmQgaXMgdXNlZCBvbiBkZWZhdWx0IGFuZCBwb3N0IGxheW91dHMuIEVhY2gKICogcGFnZSBpcyB3cmFwcGVkIGluIGAucGFnZWAgYW5kIGlzIG9ubHkgdXNlZCBvbiB0aGUgcGFnZSBsYXlvdXQuCiAqLwoKLnBhZ2UsCi5wb3N0IHsKICBtYXJnaW4tYm90dG9tOiA0ZW07Cn0KCi8qIEJsb2cgcG9zdCBvciBwYWdlIHRpdGxlICovCi5wYWdlLXRpdGxlLAoucG9zdC10aXRsZSwKLnBvc3QtdGl0bGUgYSB7CiAgY29sb3I6ICMzMDMwMzA7Cn0KLnBhZ2UtdGl0bGUsCi5wb3N0LXRpdGxlIHsKICBtYXJnaW4tdG9wOiAwOwp9CgovKiBNZXRhIGRhdGEgbGluZSBiZWxvdyBwb3N0IHRpdGxlICovCi5wb3N0LWRhdGUgewogIGRpc3BsYXk6IGJsb2NrOwogIG1hcmdpbi10b3A6IC0uNXJlbTsKICBtYXJnaW4tYm90dG9tOiAxcmVtOwogIGNvbG9yOiAjNzU3NTc1Owp9CgovKiBSZWxhdGVkIHBvc3RzICovCi5yZWxhdGVkIHsKICBwYWRkaW5nLXRvcDogMnJlbTsKICBwYWRkaW5nLWJvdHRvbTogMnJlbTsKICBib3JkZXItdG9wOiAxcHggc29saWQgI2VlZTsKfQoucmVsYXRlZC1wb3N0cyB7CiAgcGFkZGluZy1sZWZ0OiAwOwogIGxpc3Qtc3R5bGU6IG5vbmU7Cn0KLnJlbGF0ZWQtcG9zdHMgaDMgewogIG1hcmdpbi10b3A6IDA7Cn0KLnJlbGF0ZWQtcG9zdHMgbGkgc21hbGwgewogIGZvbnQtc2l6ZTogNzUlOwogIGNvbG9yOiAjOTk5Owp9Ci5yZWxhdGVkLXBvc3RzIGxpIGE6aG92ZXIgewogIGNvbG9yOiAjMjI3YmI5OwogIHRleHQtZGVjb3JhdGlvbjogbm9uZTsKfQoucmVsYXRlZC1wb3N0cyBsaSBhOmhvdmVyIHNtYWxsIHsKICBjb2xvcjogaW5oZXJpdDsKfQoKCi8qCiAqIFBhZ2luYXRpb24KICoKICogU3VwZXIgbGlnaHR3ZWlnaHQgKEhUTUwtd2lzZSkgYmxvZyBwYWdpbmF0aW9uLiBgc3BhbmBzIGFyZSBwcm92aWRlIGZvciB3aGVuCiAqIHRoZXJlIGFyZSBubyBtb3JlIHByZXZpb3VzIG9yIG5leHQgcG9zdHMgdG8gc2hvdy4KICovCgoucGFnaW5hdGlvbiB7CiAgb3ZlcmZsb3c6IGhpZGRlbjsgLyogY2xlYXJmaXggKi8KICBtYXJnaW4tbGVmdDogLTFyZW07CiAgbWFyZ2luLXJpZ2h0OiAtMXJlbTsKICBmb250LWZhbWlseTogIlBUIFNhbnMiLCBIZWx2ZXRpY2EsIEFyaWFsLCBzYW5zLXNlcmlmOwogIGNvbG9yOiAjY2NjOwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKLyogUGFnaW5hdGlvbiBpdGVtcyBjYW4gYmUgYHNwYW5gcyBvciBgYWBzICovCi5wYWdpbmF0aW9uLWl0ZW0gewogIGRpc3BsYXk6IGJsb2NrOwogIHBhZGRpbmc6IDFyZW07CiAgYm9yZGVyOiAxcHggc29saWQgI2VlZTsKfQoucGFnaW5hdGlvbi1pdGVtOmZpcnN0LWNoaWxkIHsKICBtYXJnaW4tYm90dG9tOiAtMXB4Owp9CgovKiBPbmx5IHByb3ZpZGUgYSBob3ZlciBzdGF0ZSBmb3IgbGlua2VkIHBhZ2luYXRpb24gaXRlbXMgKi8KYS5wYWdpbmF0aW9uLWl0ZW06aG92ZXIgewogIGJhY2tncm91bmQtY29sb3I6ICNmNWY1ZjU7Cn0KCkBtZWRpYSAobWluLXdpZHRoOiAzMGVtKSB7CiAgLnBhZ2luYXRpb24gewogICAgbWFyZ2luOiAzcmVtIDA7CiAgfQogIC5wYWdpbmF0aW9uLWl0ZW0gewogICAgZmxvYXQ6IGxlZnQ7CiAgICB3aWR0aDogNTAlOwogIH0KICAucGFnaW5hdGlvbi1pdGVtOmZpcnN0LWNoaWxkIHsKICAgIG1hcmdpbi1ib3R0b206IDA7CiAgICBib3JkZXItdG9wLWxlZnQtcmFkaXVzOiAgICA0cHg7CiAgICBib3JkZXItYm90dG9tLWxlZnQtcmFkaXVzOiA0cHg7CiAgfQogIC5wYWdpbmF0aW9uLWl0ZW06bGFzdC1jaGlsZCB7CiAgICBtYXJnaW4tbGVmdDogLTFweDsKICAgIGJvcmRlci10b3AtcmlnaHQtcmFkaXVzOiAgICA0cHg7CiAgICBib3JkZXItYm90dG9tLXJpZ2h0LXJhZGl1czogNHB4OwogIH0KfQo=")

	tmpls["css/print.css"] = tostring("LnNpZGViYXIgewogIGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDsKfQoKLmNvbnRlbnQgewogIG1hcmdpbjogMCBhdXRvOwogIHdpZHRoOiAxMDAlOwogIGZsb2F0OiBub25lOwogIGRpc3BsYXk6IGluaXRpYWw7Cn0KCi5jb250YWluZXIgewogIHdpZHRoOiAxMDAlOwogIGZsb2F0OiBub25lOwogIGRpc3BsYXk6IGluaXRpYWw7CiAgcGFkZGluZy1sZWZ0OiAgMXJlbTsKICBwYWRkaW5nLXJpZ2h0OiAxcmVtOwogIG1hcmdpbjogMCBhdXRvOwp9Cg==")

	tmpls["css/syntax.css"] = tostring("LmhsbCB7IGJhY2tncm91bmQtY29sb3I6ICNmZmZmY2MgfQogLyp7IGJhY2tncm91bmQ6ICNmMGYzZjM7IH0qLwouYyB7IGNvbG9yOiAjOTk5OyB9IC8qIENvbW1lbnQgKi8KLmVyciB7IGNvbG9yOiAjQUEwMDAwOyBiYWNrZ3JvdW5kLWNvbG9yOiAjRkZBQUFBIH0gLyogRXJyb3IgKi8KLmsgeyBjb2xvcjogIzAwNjY5OTsgfSAvKiBLZXl3b3JkICovCi5vIHsgY29sb3I6ICM1NTU1NTUgfSAvKiBPcGVyYXRvciAqLwouY20geyBjb2xvcjogIzAwOTlGRjsgZm9udC1zdHlsZTogaXRhbGljIH0gLyogQ29tbWVudC5NdWx0aWxpbmUgKi8KLmNwIHsgY29sb3I6ICMwMDk5OTkgfSAvKiBDb21tZW50LlByZXByb2MgKi8KLmMxIHsgY29sb3I6ICM5OTk7IH0gLyogQ29tbWVudC5TaW5nbGUgKi8KLmNzIHsgY29sb3I6ICM5OTk7IH0gLyogQ29tbWVudC5TcGVjaWFsICovCi5nZCB7IGJhY2tncm91bmQtY29sb3I6ICNGRkNDQ0M7IGJvcmRlcjogMXB4IHNvbGlkICNDQzAwMDAgfSAvKiBHZW5lcmljLkRlbGV0ZWQgKi8KLmdlIHsgZm9udC1zdHlsZTogaXRhbGljIH0gLyogR2VuZXJpYy5FbXBoICovCi5nciB7IGNvbG9yOiAjRkYwMDAwIH0gLyogR2VuZXJpYy5FcnJvciAqLwouZ2ggeyBjb2xvcjogIzAwMzMwMDsgfSAvKiBHZW5lcmljLkhlYWRpbmcgKi8KLmdpIHsgYmFja2dyb3VuZC1jb2xvcjogI0NDRkZDQzsgYm9yZGVyOiAxcHggc29saWQgIzAwQ0MwMCB9IC8qIEdlbmVyaWMuSW5zZXJ0ZWQgKi8KLmdvIHsgY29sb3I6ICNBQUFBQUEgfSAvKiBHZW5lcmljLk91dHB1dCAqLwouZ3AgeyBjb2xvcjogIzAwMDA5OTsgfSAvKiBHZW5lcmljLlByb21wdCAqLwouZ3MgeyB9IC8qIEdlbmVyaWMuU3Ryb25nICovCi5ndSB7IGNvbG9yOiAjMDAzMzAwOyB9IC8qIEdlbmVyaWMuU3ViaGVhZGluZyAqLwouZ3QgeyBjb2xvcjogIzk5Q0M2NiB9IC8qIEdlbmVyaWMuVHJhY2ViYWNrICovCi5rYyB7IGNvbG9yOiAjMDA2Njk5OyB9IC8qIEtleXdvcmQuQ29uc3RhbnQgKi8KLmtkIHsgY29sb3I6ICMwMDY2OTk7IH0gLyogS2V5d29yZC5EZWNsYXJhdGlvbiAqLwoua24geyBjb2xvcjogIzAwNjY5OTsgfSAvKiBLZXl3b3JkLk5hbWVzcGFjZSAqLwoua3AgeyBjb2xvcjogIzAwNjY5OSB9IC8qIEtleXdvcmQuUHNldWRvICovCi5rciB7IGNvbG9yOiAjMDA2Njk5OyB9IC8qIEtleXdvcmQuUmVzZXJ2ZWQgKi8KLmt0IHsgY29sb3I6ICMwMDc3ODg7IH0gLyogS2V5d29yZC5UeXBlICovCi5tIHsgY29sb3I6ICNGRjY2MDAgfSAvKiBMaXRlcmFsLk51bWJlciAqLwoucyB7IGNvbG9yOiAjZDQ0OTUwIH0gLyogTGl0ZXJhbC5TdHJpbmcgKi8KLm5hIHsgY29sb3I6ICM0ZjlmY2YgfSAvKiBOYW1lLkF0dHJpYnV0ZSAqLwoubmIgeyBjb2xvcjogIzMzNjY2NiB9IC8qIE5hbWUuQnVpbHRpbiAqLwoubmMgeyBjb2xvcjogIzAwQUE4ODsgfSAvKiBOYW1lLkNsYXNzICovCi5ubyB7IGNvbG9yOiAjMzM2NjAwIH0gLyogTmFtZS5Db25zdGFudCAqLwoubmQgeyBjb2xvcjogIzk5OTlGRiB9IC8qIE5hbWUuRGVjb3JhdG9yICovCi5uaSB7IGNvbG9yOiAjOTk5OTk5OyB9IC8qIE5hbWUuRW50aXR5ICovCi5uZSB7IGNvbG9yOiAjQ0MwMDAwOyB9IC8qIE5hbWUuRXhjZXB0aW9uICovCi5uZiB7IGNvbG9yOiAjQ0MwMEZGIH0gLyogTmFtZS5GdW5jdGlvbiAqLwoubmwgeyBjb2xvcjogIzk5OTlGRiB9IC8qIE5hbWUuTGFiZWwgKi8KLm5uIHsgY29sb3I6ICMwMENDRkY7IH0gLyogTmFtZS5OYW1lc3BhY2UgKi8KLm50IHsgY29sb3I6ICMyZjZmOWY7IH0gLyogTmFtZS5UYWcgKi8KLm52IHsgY29sb3I6ICMwMDMzMzMgfSAvKiBOYW1lLlZhcmlhYmxlICovCi5vdyB7IGNvbG9yOiAjMDAwMDAwOyB9IC8qIE9wZXJhdG9yLldvcmQgKi8KLncgeyBjb2xvcjogI2JiYmJiYiB9IC8qIFRleHQuV2hpdGVzcGFjZSAqLwoubWYgeyBjb2xvcjogI0ZGNjYwMCB9IC8qIExpdGVyYWwuTnVtYmVyLkZsb2F0ICovCi5taCB7IGNvbG9yOiAjRkY2NjAwIH0gLyogTGl0ZXJhbC5OdW1iZXIuSGV4ICovCi5taSB7IGNvbG9yOiAjRkY2NjAwIH0gLyogTGl0ZXJhbC5OdW1iZXIuSW50ZWdlciAqLwoubW8geyBjb2xvcjogI0ZGNjYwMCB9IC8qIExpdGVyYWwuTnVtYmVyLk9jdCAqLwouc2IgeyBjb2xvcjogI0NDMzMwMCB9IC8qIExpdGVyYWwuU3RyaW5nLkJhY2t0aWNrICovCi5zYyB7IGNvbG9yOiAjQ0MzMzAwIH0gLyogTGl0ZXJhbC5TdHJpbmcuQ2hhciAqLwouc2QgeyBjb2xvcjogI0NDMzMwMDsgZm9udC1zdHlsZTogaXRhbGljIH0gLyogTGl0ZXJhbC5TdHJpbmcuRG9jICovCi5zMiB7IGNvbG9yOiAjQ0MzMzAwIH0gLyogTGl0ZXJhbC5TdHJpbmcuRG91YmxlICovCi5zZSB7IGNvbG9yOiAjQ0MzMzAwOyB9IC8qIExpdGVyYWwuU3RyaW5nLkVzY2FwZSAqLwouc2ggeyBjb2xvcjogI0NDMzMwMCB9IC8qIExpdGVyYWwuU3RyaW5nLkhlcmVkb2MgKi8KLnNpIHsgY29sb3I6ICNBQTAwMDAgfSAvKiBMaXRlcmFsLlN0cmluZy5JbnRlcnBvbCAqLwouc3ggeyBjb2xvcjogI0NDMzMwMCB9IC8qIExpdGVyYWwuU3RyaW5nLk90aGVyICovCi5zciB7IGNvbG9yOiAjMzNBQUFBIH0gLyogTGl0ZXJhbC5TdHJpbmcuUmVnZXggKi8KLnMxIHsgY29sb3I6ICNDQzMzMDAgfSAvKiBMaXRlcmFsLlN0cmluZy5TaW5nbGUgKi8KLnNzIHsgY29sb3I6ICNGRkNDMzMgfSAvKiBMaXRlcmFsLlN0cmluZy5TeW1ib2wgKi8KLmJwIHsgY29sb3I6ICMzMzY2NjYgfSAvKiBOYW1lLkJ1aWx0aW4uUHNldWRvICovCi52YyB7IGNvbG9yOiAjMDAzMzMzIH0gLyogTmFtZS5WYXJpYWJsZS5DbGFzcyAqLwoudmcgeyBjb2xvcjogIzAwMzMzMyB9IC8qIE5hbWUuVmFyaWFibGUuR2xvYmFsICovCi52aSB7IGNvbG9yOiAjMDAzMzMzIH0gLyogTmFtZS5WYXJpYWJsZS5JbnN0YW5jZSAqLwouaWwgeyBjb2xvcjogI0ZGNjYwMCB9IC8qIExpdGVyYWwuTnVtYmVyLkludGVnZXIuTG9uZyAqLwoKLmNzcyAubywKLmNzcyAubyArIC5udCwKLmNzcyAubnQgKyAubnQgeyBjb2xvcjogIzk5OTsgfQo=")

	tmpls["html/_aside.html"] = tostring("e3t3aXRoIC5Bc2lkZS5NdXN0fX0KPGFzaWRlPgogIDxkaXY+CiAgICA8ZGl2PgogICAgICA8YSBocmVmPSIvIj4KICAgICAgICA8aDE+e3suVmFsICJzdHJpbmcxIn19PC9oMT4KICAgICAgPC9hPgogICAgICA8cD57ey5WYWwgImRlc2MifX08L3A+CiAgICAgIDxuYXY+CiAgICAgICAgPHVsPgogICAgICAgICAge3tyYW5nZSAuTGlzdCAibmF2In19CiAgICAgICAgICB7e3dpdGggLk11c3R9fQogICAgICAgICAgPGxpPjxhIGhyZWY9J3t7LlZhbCAic2x1ZyJ9fSc+e3suVmFsICJuYW1lIn19PC9hPjwvbGk+CiAgICAgICAgICB7e2VuZH19CiAgICAgICAgICB7e2VuZH19CiAgICAgICAgPC91bD4KICAgICAgPC9uYXY+CiAgPC9kaXY+CjwvYXNpZGU+Cnt7ZW5kfX0K")

	tmpls["html/_head.html"] = tostring("PG1ldGEgaHR0cC1lcXVpdj0iY29udGVudC10eXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLTgiPgo8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCI+CjxsaW5rIGhyZWY9Imh0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzMj9mYW1pbHk9RUIrR2FyYW1vbmQ6aXRhbCx3Z2h0QDAsNDAwOzAsNTAwOzAsNjAwOzAsNzAwOzAsODAwOzEsNDAwOzEsNTAwOzEsNjAwOzEsNzAwOzEsODAwJmRpc3BsYXk9c3dhcCIgcmVsPSJzdHlsZXNoZWV0Ij4K")

	tmpls["html/_styles.html"] = tostring("PHN0eWxlPgogIHt7IHRlbXBsYXRlICJjc3MvbWFpbi5jc3MiIH19Cjwvc3R5bGU+Cg==")

	tmpls["html/_tracker.html"] = tostring("e3tpZiAuQX19CjxpbWcgc3R5bGU9J3Bvc2l0aW9uOiBmaXhlZDsgYm90dG9tOiAwOyByaWdodDogMDsnIHNyYz0iLy9ldmFuam9uZXMuZ29hdGNvdW50ZXIuY29tL2NvdW50P3A9e3suQS5QYXRofX17e2lmIC5BLlJlZmVyZXJ9fSZyPXt7LkEuUmVmZXJlcn19e3tlbmR9fSZybmQ9e3suQS5STkR9fSI+Cnt7ZW5kfX0K")

	tmpls["html/item.html"] = tostring("e3t3aXRoIC5JdGVtLk11c3R9fQo8IURPQ1RZUEUgaHRtbD4KPGh0bWwgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiPgo8aGVhZD4KICB7eyB0ZW1wbGF0ZSAiaHRtbC9faGVhZC5odG1sIiAkIH19CiAgPHRpdGxlPnt7LlZhbCAibmFtZSJ9fSB8IHt7JC5Bc2lkZS5NdXN0LlZhbCAic3RyaW5nMiJ9fTwvdGl0bGU+CiAgPCEtLSBGb3Igc29tZSByZWFzb24gdGVtcGxhdGVzIGJsb3dzIGl0cyBicmFpbnMgaGVyZS4gLS0+CiAge3t3aXRoIC5WYWwgInNob3J0In19CiAgPG1ldGEgbmFtZT1kZXNjcmlwdGlvbiBjb250ZW50PSJ7ey59fSIgLz4KICB7e2VuZH19CjwvaGVhZD4KPGJvZHk+CiAgPGRpdj4KICAgIHt7IHRlbXBsYXRlICJodG1sL19zdHlsZXMuaHRtbCIgJCB9fQogICAge3sgdGVtcGxhdGUgImh0bWwvX2FzaWRlLmh0bWwiICQgfX0KICAgIDxtYWluPgogICAgICA8ZGl2PgogICAgICAgIDxoMSBpZD1tb3JlPnt7LlZhbCAibmFtZSJ9fTwvaDE+CiAgICAgICAge3tpZiAkLlNob3dEYXRlfX0KICAgICAgICA8dGltZT57ey5WYWwgImRhdGUiIHwgZGF0ZX19PC90aW1lPgogICAgICAgIHt7ZW5kfX0KICAgICAgICA8YXJ0aWNsZT57ey5WYWwgImRlc2MiIHwgaHRtbCB9fTwvYXJ0aWNsZT4KICAgICAgPC9kaXY+CiAgICAgIHt7aWYgb3IgKC5SZWYgInByZXYiKSAoLlJlZiAibmV4dCIpfX0KICAgICAgPHRhYmxlPgogICAgICAgIDx0cj4KICAgICAgICAgIHt7d2l0aCAuUmVmICJwcmV2In19CiAgICAgICAgICA8dGQgd2lkdGg9IjUwJSI+CiAgICAgICAgICAgIDxkaXY+CiAgICAgICAgICAgICAgPGEgaHJlZj0nL3t7Lk11c3QuVmFsICJzbHVnIn19Jz4mbGFycjsge3suTXVzdC5WYWwgIm5hbWUifX08L2E+CiAgICAgICAgICAgIDwvZGl2PgogICAgICAgICAgPC90ZD4KICAgICAgICAgIHt7ZW5kfX0KICAgICAgICAgIHt7d2l0aCAuUmVmICJuZXh0In19CiAgICAgICAgICA8dGQgd2lkdGg9IjUwJSI+CiAgICAgICAgICAgIDxkaXYgc3R5bGU9J3RleHQtYWxpZ246IHJpZ2h0Oyc+CiAgICAgICAgICAgICAgPGEgaHJlZj0nL3t7Lk11c3QuVmFsICJzbHVnIn19Jz57ey5NdXN0LlZhbCAibmFtZSJ9fSAmcmFycjs8L2E+CiAgICAgICAgICAgIDwvZGl2PgogICAgICAgICAgPC90ZD4KICAgICAgICAgIHt7ZW5kfX0KICAgICAgICA8L3RyPgogICAgICA8L3RhYmxlPgogICAgICB7e2VuZH19CiAgICA8L21haW4+CiAgPC9kaXY+CiAge3sgdGVtcGxhdGUgImh0bWwvX3RyYWNrZXIuaHRtbCIgJCB9fQo8L2JvZHk+CjwvaHRtbD4Ke3tlbmR9fQo=")

	tmpls["html/list.html"] = tostring("PCFET0NUWVBFIGh0bWw+CjxodG1sIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIj4KPGhlYWQ+CiAge3t0ZW1wbGF0ZSAiaHRtbC9faGVhZC5odG1sIiAkfX0KICA8dGl0bGU+e3suQXNpZGUuTXVzdC5WYWwgInN0cmluZzMifX0gfCB7ey5Bc2lkZS5NdXN0LlZhbCAic3RyaW5nMiJ9fTwvdGl0bGU+CjwvaGVhZD4KPGJvZHkgY2xhc3M9bGlzdD4KICA8ZGl2PgogICAge3t0ZW1wbGF0ZSAiaHRtbC9fc3R5bGVzLmh0bWwiICR9fQogICAge3t0ZW1wbGF0ZSAiaHRtbC9fYXNpZGUuaHRtbCIgJH19CiAgICA8bWFpbj4KICAgICAgPGRpdj4KICAgICAgICB7e3JhbmdlIC5MaXN0fX0KICAgICAgICAgIHt7d2l0aCAuTXVzdH19CiAgICAgICAgICA8YXJ0aWNsZT4KICAgICAgICAgICAgPGgxPgogICAgICAgICAgICAgIDxhIGhyZWY9Jy97ey5WYWwgInNsdWcifX0nPnt7LlZhbCAibmFtZSJ9fTwvYT4KICAgICAgICAgICAgPC9oMT4KICAgICAgICAgICAgPHRpbWU+e3suVmFsICJkYXRlIiB8IGRhdGV9fTwvdGltZT4KICAgICAgICAgICAgPHA+e3suVmFsICJzaG9ydCJ9fTwvcD4KICAgICAgICAgIDwvYXJ0aWNsZT4KICAgICAgICAgIHt7ZW5kfX0KICAgICAgICB7e2VuZH19CiAgICAgIDwvZGl2PgogICAgPC9tYWluPgogIDwvZGl2PgogIHt7IHRlbXBsYXRlICJodG1sL190cmFja2VyLmh0bWwiICQgfX0KPC9ib2R5Pgo8L2h0bWw+Cg==")

	tmpls["img/_code-24px.svg"] = tostring("PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNMCAwaDI0djI0SDBWMHoiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSJNOS40IDE2LjZMNC44IDEybDQuNi00LjZMOCA2bC02IDYgNiA2IDEuNC0xLjR6bTUuMiAwbDQuNi00LjYtNC42LTQuNkwxNiA2bDYgNi02IDYtMS40LTEuNHoiLz48L3N2Zz4=")

	tmpls["img/_email-24px.svg"] = tostring("PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNMjAgNEg0Yy0xLjEgMC0xLjk5LjktMS45OSAyTDIgMThjMCAxLjEuOSAyIDIgMmgxNmMxLjEgMCAyLS45IDItMlY2YzAtMS4xLS45LTItMi0yem0wIDRsLTggNS04LTVWNmw4IDUgOC01djJ6Ii8+PHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPjwvc3ZnPg==")

	tmpls["img/_rss_feed-24px.svg"] = tostring("PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+PGNpcmNsZSBjeD0iNi4xOCIgY3k9IjE3LjgyIiByPSIyLjE4Ii8+PHBhdGggZD0iTTQgNC40NHYyLjgzYzcuMDMgMCAxMi43MyA1LjcgMTIuNzMgMTIuNzNoMi44M2MwLTguNTktNi45Ny0xNS41Ni0xNS41Ni0xNS41NnptMCA1LjY2djIuODNjMy45IDAgNy4wNyAzLjE3IDcuMDcgNy4wN2gyLjgzYzAtNS40Ny00LjQzLTkuOS05LjktOS45eiIvPjwvc3ZnPg==")

	tmpls["img/_vpn_key-24px.svg"] = tostring("PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+PHBhdGggZD0iTTEyLjY1IDEwQzExLjgzIDcuNjcgOS42MSA2IDcgNmMtMy4zMSAwLTYgMi42OS02IDZzMi42OSA2IDYgNmMyLjYxIDAgNC44My0xLjY3IDUuNjUtNEgxN3Y0aDR2LTRoMnYtNEgxMi42NXpNNyAxNGMtMS4xIDAtMi0uOS0yLTJzLjktMiAyLTIgMiAuOSAyIDItLjkgMi0yIDJ6Ii8+PC9zdmc+")

}

func Get(name string) (string, bool) {
	val, ok := tmpls[name]
	return val, ok
}

func Must(name string) string {
	val, _ := tmpls[name]
	return val
}

M makefile => makefile +17 -7
@@ 1,27 1,37 @@
BIN=evanjon.es
ENV=`cat .env`
VER=`git rev-parse HEAD`
CC=go1.16rc1

all: setup vendor gen build

setup:
	@go get git.sr.ht/~evanj/embed/cmd/embed
	@env GOMOD=off go get golang.org/dl/go1.16rc1
	@env GOMOD=off $(CC) download
	@env GOMOD=off $(CC) get git.sr.ht/~evanj/embed/cmd/embed

vendor: go.mod go.sum
	@go mod tidy
	@go mod vendor
	@$(CC) mod tidy
	@$(CC) mod vendor

build:
	@go build -ldflags='-s -w' -o $(BIN)
	@echo $(VER) | xargs -I {} $(CC) build -ldflags='-s -w -X main.build={}' -o $(BIN)

gen: 
	@go generate ./...
	@$(CC) generate ./...

test: 
	@go test ./...
	@env $(ENV) $(CC) test ./... -cover -count 1

coverage: 
	@env $(ENV) $(CC) test ./... -cover -coverprofile=coverage.out ; $(CC) tool cover -html=coverage.out

lint: 
	@find * -not -name '*_embed.go' | grep -E '*.(sql|go|js|css|html)' | entr -cr $(CC) vet ./...

run: gen build
	@clear
	@env $(ENV) ./$(BIN)

dev:
	@find * -not -name '*_embed.go' | grep -E '*.(go|js|css|html)' | entr -r make run
	@find * -not -name '*_embed.go' | grep -E '*.(sql|go|js|css|html)' | entr -cr make run