Port frontend code to pure Javascript

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2018-10-06 19:57:53 +02:00
parent 223bfa1605
commit b2843a828a
No known key found for this signature in database
GPG Key ID: DC2729FDD34BE99E
13 changed files with 7106 additions and 1561 deletions

View File

@ -1,20 +0,0 @@
{
"presets": [
[
"env",
{
"targets": {
"browsers": [
"last 3 versions",
"Safari >= 10",
"not ie <= 8",
"Edge >= 12",
"iOS >= 10",
"Android >= 4.4"
]
}
}
],
"minify"
]
}

View File

@ -9,8 +9,8 @@ VER_POPPER=1.14.1
default: generate
generate: l10n download_libs
docker run --rm -ti -v $(CURDIR):$(CURDIR) -w $(CURDIR) node \
bash -exc "npm ci && npx coffee -t -c frontend/application.coffee && chown -R $(shell id -u) frontend"
docker run --rm -ti -v $(CURDIR):$(CURDIR) -w $(CURDIR)/src node:10-alpine \
sh -exc "npm ci && npm run build && rm -rf node_modules && chown -R $(shell id -u) ../frontend"
go generate
l10n:

256
assets.go
View File

@ -1,7 +1,6 @@
// Code generated by go-bindata. DO NOT EDIT.
// sources:
// frontend/application.coffee
// frontend/application.js
// frontend/app.js
// frontend/css/bootstrap.min.css
// frontend/css/bootswatch.min.css
// frontend/css/fa-brands.css
@ -115,125 +114,70 @@ func (fi bindataFileInfo) Sys() interface{} {
return nil
}
var _bindataFrontendApplicationcoffee = []byte(
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x56\x5f\x6f\xdb\x36\x10\x7f\xe7\xa7\xb8\xd9\x01\x28\x61\x8e\xea\x64" +
"\xd9\x1e\x5c\x78\x40\x97\xfd\xe9\x80\xb6\x28\x92\x14\x7b\x18\x8a\x81\x16\x4f\x16\x1b\x99\xd4\xc8\x53\x9c\x2c\xcd" +
"\x77\x1f\x28\x4a\xb2\xe4\xa8\x9e\xf7\xd6\xbc\xc4\xe2\xef\xfe\xf1\xee\xf8\xbb\x73\x98\x56\x16\xdf\x0b\xe7\xb6\xc6" +
"\x4a\x58\x82\xae\x8a\x82\xb1\xd4\xa2\x20\xbc\xc6\xd4\x22\xc1\x12\xa2\x18\x4e\x7f\x64\x00\xae\x3d\x38\x89\xf8\x34" +
"\x33\x76\x73\xd9\x93\xe3\x71\x92\x29\x2d\x23\x4e\x78\x4f\xc2\xa2\xe0\x71\x72\x27\x8a\x28\x66\x41\x73\xe8\xe7\xad" +
"\xa0\x3c\xb1\x42\x4b\xb3\x89\xe2\x84\xcc\x35\x59\xa5\xd7\xd1\x77\x3f\xc4\x89\xab\x56\x2e\x7c\x9d\xc7\x7d\xa7\xbf" +
"\xa9\xd5\x0a\xad\x72\xf9\xab\x5f\xae\x13\xd4\x69\x14\x90\xd9\x9e\xf1\xda\xdf\x49\x22\x3e\x89\x7b\xe0\xa2\x54\x2f" +
"\xc2\x65\xf8\x8c\x01\x00\x6c\x90\x72\x23\x17\x30\x29\x8d\xa3\x49\x7d\x24\x05\x89\x45\xfd\xab\x75\xb6\x68\xfe\x77" +
"\xf0\xcd\x43\x89\x0b\x98\x7c\x72\x46\x07\x1d\x47\x82\x2a\x77\x69\x24\xb6\x9a\xe7\xf3\xb3\x56\x2d\x64\x45\x36\xc0" +
"\xc5\x7c\xbe\x00\x67\xbc\x63\xa5\xd7\x7f\x58\xa3\xd7\x0d\xf2\xfd\x17\x91\x8b\xf9\xc5\xa2\xcb\x7a\xf8\x9b\xc2\x5b" +
"\x93\xde\x42\x66\x2c\x28\x4d\x68\x33\x91\x22\x10\x3a\x52\x9d\x16\x8c\xfa\xdf\x9d\xff\xa5\xe4\x02\x78\x66\xcc\x4a" +
"\x58\xee\xb3\x94\x89\xc2\x21\x63\xfe\x86\xef\x0c\xfd\x6a\x2a\x2d\x7b\xd5\xf6\x45\xd6\x86\x32\x7f\xcc\xe3\xc4\xe5" +
"\x66\xeb\x8b\x99\x0b\x97\xbf\x31\xa2\x2f\xe9\x8f\x60\x09\x5b\xa5\xa5\xd9\x26\x85\x49\x05\x29\xa3\x13\x7f\xcc\x00" +
"\x54\x56\x0b\x24\x05\xea\x35\xe5\xb0\x5c\xc2\xbc\x0e\xcd\x22\x55\x56\xb3\xc6\x53\x2a\xac\x7c\x87\xdb\xae\x97\x72" +
"\x25\x31\x8a\x7b\x60\x40\x3e\x5c\xbd\xd9\x07\x7b\x31\x0e\xce\xbb\xcc\x6e\x7d\x66\xc7\x4c\x5e\xa1\x68\xcc\xbe\xb7" +
"\xd8\xbb\xa2\xc5\xbf\x2b\x74\xf4\xac\xff\x0f\xdf\xb3\x41\x25\xa6\x46\xe2\x87\xab\xdf\x2f\xcd\xa6\x34\x1a\x35\x45" +
"\x1e\xa9\xdb\xb2\x14\x96\x1c\x2c\x43\x3e\x5c\x59\x28\x02\xfe\x99\x87\x1c\xd5\x58\x2f\x49\xe7\x75\x92\x1a\xa3\x35" +
"\xf8\xe7\xfc\x23\x6b\xaa\x39\x7c\x4c\x01\x3d\xfb\xe8\x5d\x28\xd9\xd9\xef\xde\xd1\x59\xbc\x7b\x12\x13\xff\x24\xd6" +
"\x48\x2f\xa6\x8f\x4a\x3e\x4d\x66\xff\xa7\xc7\xeb\xb6\xec\x77\x4b\xd7\xfb\xbe\x91\x73\xb3\xfd\x59\x90\x60\x4c\x69" +
"\x45\x3f\x29\x2d\xdd\x5e\x33\x8d\x30\xc6\x4a\x69\x09\xdc\x55\xab\x8d\x22\x3e\x83\x3e\xef\xb4\xd5\x6d\x7b\x62\x06" +
"\x89\x16\x77\x2b\x61\x4f\x57\x9e\x37\x3a\xe5\xb4\x50\xe9\x2d\x9f\x41\x27\x58\x2b\x86\x1a\xb5\x32\x3e\x1f\x69\x2e" +
"\xf4\x1a\xf9\x0c\xda\x06\x6e\x1c\x58\xbc\x43\x51\xec\x45\xd4\x1a\x1d\x74\x02\x03\xf0\xe8\x15\x3a\xf5\x0f\xde\x34" +
"\x2c\xe7\xfb\xa5\x73\xdd\xbb\xf0\xae\x3b\x2c\x66\xb0\x1c\x7e\x87\xda\x47\x7c\xca\xe3\x50\xd4\xe6\x25\x3e\x37\x3f" +
"\x4c\x61\x8f\x5a\x51\xa4\x79\xb4\xa3\x08\x8f\xc0\x12\x28\x57\x8e\x85\x92\x9a\x60\x28\x18\x58\xb6\x44\x32\xf5\x82" +
"\x89\xa3\x87\x02\x93\x1c\xd5\x3a\xf7\x5a\x5c\x54\x64\x78\x23\x31\x26\x10\x79\xbb\x89\x4b\xad\x29\x8a\xd7\xf5\x61" +
"\x0c\xdf\x02\x2f\xef\x79\xe3\x0c\x0b\xf1\x80\x72\xd4\x63\xf3\x5a\x1c\xd2\x8d\xda\xa0\xa9\xa8\x0b\x6d\x06\x73\xc6" +
"\x76\x2e\x91\x5e\x11\x59\xb5\xaa\x08\x23\x5e\x07\xc0\x67\x30\x09\x31\x2c\x60\xfa\xf8\x2c\x86\xa7\xf2\xfe\x25\x6c" +
"\x94\x3e\xfd\x2f\x19\x73\x87\x36\x2b\xcc\xf6\xf4\x61\x91\x2b\x29\x51\xbf\x9c\xc4\xc1\xf3\x49\xe4\x7d\xc7\x4d\xa8" +
"\x89\xd1\x11\xef\xfa\xa4\x0d\x73\x88\x56\xbe\x4f\x07\xf7\x1d\xe0\xa5\x70\x84\x07\x25\xa4\x35\xe5\x41\x81\x5b\x7c" +
"\x90\x66\xab\xc7\x64\x62\xc6\xd8\x80\xe3\x7d\xae\xfd\x83\x1c\x0c\xe8\xd7\x0d\x11\x09\x12\x49\xc7\xfc\x81\x64\xf6" +
"\xa8\xe3\x9b\x66\xe0\xef\x66\x44\xa3\x3b\x99\x3e\xee\xbe\x9f\x3e\xd7\x5f\x3d\xc5\x27\xcf\x10\x95\x2d\x82\xe4\x81" +
"\xd6\x7e\x9a\x0e\x0c\x4d\x8e\x66\xfb\x7d\x6a\x3e\x38\x0e\x1a\xde\x1e\x07\xc3\x52\xa2\x74\x59\x51\xd8\x48\x7c\xe0" +
"\x47\xc9\x66\x26\xad\xdc\x91\x76\x1d\x16\x98\xd2\x17\x96\x9d\xb0\x54\xb5\x04\x39\x5a\x33\x58\x42\xbf\x60\x47\x56" +
"\x6b\x7f\x2b\x92\x78\x78\x2b\xfa\x4a\xe6\xec\x01\x81\xb1\x6a\x0e\xd0\xb1\x1d\x73\xb7\xae\x1d\xa7\x42\x56\xad\xd7" +
"\x68\xa1\x7d\xeb\x8c\x0d\xb7\xb0\xbd\xb9\xf5\xec\x82\xed\x9e\xc0\x4e\x82\x50\x37\xf0\xea\xb0\xdb\xf9\x12\xc5\xec" +
"\xdf\x00\x00\x00\xff\xff\x17\xa4\xb5\x7c\x5f\x0b\x00\x00")
var _bindataFrontendAppjs = []byte(
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xc4\x56\x6d\x6f\xdb\x36\x10\xfe\x2b\x36\x53\x08\x24\xc2\xb2\x4a\x96\x0d" +
"\x83\x0c\x62\x28\x8a\x61\x1b\xb0\xae\x45\xd3\x7e\x0a\x82\x82\x96\x4e\x16\x5b\x99\x14\xc8\x53\x9c\x40\xd1\x7f\x1f" +
"\xa8\x77\xe7\xa5\xcb\xb7\x01\x86\x4d\xf2\x5e\x78\xf7\xdc\x73\x47\xaf\xf3\xda\xa4\xa8\xad\xa1\xc0\x9a\x1b\xe5\x56" +
"\x28\x9b\x76\x33\x1e\xae\x0c\x75\xac\xd1\x39\xc5\x2b\x77\xcd\x1c\x60\xed\xcc\x2a\xac\x05\xdc\x56\xd6\xa1\xdf\x04" +
"\x13\x2b\xc3\x91\x6c\x74\xe2\x78\x99\xac\xcf\xf8\x20\x4c\x9a\xb6\xdd\x0c\x46\x10\x8c\x52\x55\x96\xd4\x8e\xb6\xdc" +
"\xf2\x79\x6d\x18\xb7\xa2\x94\xeb\x78\x3e\x6b\x8d\xd8\x4b\xe0\x46\xa4\x12\xb9\x11\x99\x9c\x43\xe5\xc8\x1d\x6b\x8c" +
"\xb0\x61\xc9\xee\xef\x3f\x6c\xbf\x41\x8a\x22\x83\x5c\x1b\xf8\xe8\x6c\x05\x0e\xef\x3a\xb5\x06\x4c\xbd\x07\xa7\xb6" +
"\x25\x24\xeb\x98\xef\x00\x13\xd7\xb2\x96\x1b\xe1\xe4\x32\x75\x52\x9b\xde\x3a\x23\x6b\x89\x77\x15\xd8\x7c\x75\x79" +
"\xb7\xdf\xda\x32\x8a\xfa\x5f\x81\xf6\x12\x9d\x36\xbb\xcf\x6a\x17\x45\xcf\xdd\xf8\x58\x97\x37\x37\xaa\xac\x21\x21" +
"\xef\x6d\x56\x97\x40\x5a\xc6\x9f\x33\x26\x5f\xbf\x82\x1f\xd4\x46\xb3\x75\xdc\x87\x8b\x47\xe9\x77\x45\x39\x8b\x30" +
"\x8a\x28\xc8\x90\x00\xe3\xbf\x46\x38\x56\x08\x36\x3a\xa7\x17\x41\x4a\x6c\x77\x15\x91\x63\x4e\x10\x45\xe1\x23\xe6" +
"\x9b\x66\xa3\x50\x4b\x27\x87\xe0\x52\x07\x0a\x81\x9a\xba\x2c\x59\x70\x67\x84\xa3\xee\xb9\xd0\x1d\x27\x19\xe4\xaa" +
"\x2e\x91\x3c\x44\xbc\xcf\x02\x5a\xc6\xcf\xbb\x80\x7c\x87\xcb\x0c\x32\xb0\xdc\x3a\xda\xd1\x68\xa5\xcd\x0a\x98\x11" +
"\x19\x75\xdc\xf2\x29\x5d\x64\xcd\x44\x22\xbc\x6e\xc5\x56\x9b\xac\x8b\x8b\x5b\xc6\x46\x7e\xb9\x80\x91\x91\x8f\xd9" +
"\xfc\x20\xdb\xdf\x26\x8d\xd9\xab\x18\x62\x6f\x93\x27\x84\x13\x83\x43\x5c\xc8\x89\x22\x1c\x19\xc7\x70\x9d\x7d\x50" +
"\x92\x41\x71\x80\xa8\x72\x16\x6d\x48\x52\x14\xca\x7f\x38\x98\x11\xac\xbe\x0b\x82\x41\xf0\x51\x49\x42\xb8\xa1\x46" +
"\x78\x19\xb3\x96\x5e\x1d\x71\xdc\x04\x5e\x7a\x58\x05\xcc\x52\x24\x43\x81\x42\xea\x73\x87\x5a\xda\x67\x0a\xf2\x15" +
"\x25\x27\xb9\x75\xfb\x77\x5d\xe5\x2e\x21\x75\x80\x84\x89\x3c\xc0\x45\x10\x6e\x51\x39\x50\x84\x89\x1b\x55\xd2\x19" +
"\x37\xf9\x5e\x61\x21\x9c\x32\x99\xdd\x53\x36\x11\x97\xfe\xf4\x0b\x13\xbe\xde\xf6\xe5\xa2\xe7\x8c\x83\xfc\x43\x6f" +
"\xb7\xe0\xb4\x2f\xde\xfe\x7e\x29\xc0\xa4\x14\xb8\x63\xfc\x95\x50\xdf\xd4\x2d\x25\xaa\xd2\x6f\x7a\xd2\x10\xde\xec" +
"\x01\x0b\x9b\x25\xa4\xb2\x1e\x09\xcf\x14\xaa\xa4\xf1\x5d\x44\x09\xb4\xdd\xfe\xf3\x5d\x05\x09\xf9\xe6\xad\x21\xdc" +
"\xa3\xc2\xda\xbf\xb3\x19\x24\xcd\x79\x7c\x96\x94\xfc\x22\x8e\x13\xcf\x7f\xee\xbe\x2f\xe2\x8b\x65\x61\x4a\x3a\x78" +
"\xfa\xaa\xb3\x84\xe4\xd6\x6e\x95\x23\x2d\x6b\xdb\x96\xf1\xf5\x59\x3b\x01\xa3\x29\x6b\x02\x24\xc6\x62\x6e\x6b\x93" +
"\x11\x26\x7c\x61\x0f\x94\xcd\x2a\x29\x65\x4d\xbc\x96\xf2\xa0\x4d\x66\x0f\xa2\xb4\xa9\x0a\xe7\xa1\x60\x85\x28\xc1" +
"\xec\xb0\x88\x22\x1a\x9c\xa4\xca\x65\xff\xc0\x61\x02\xb5\xd0\x19\x50\xc6\x47\x51\x7f\xfe\xe5\xd3\xdf\xc7\xa2\xc5" +
"\xd5\x8b\x53\x6f\x03\x3a\xda\xec\x0e\xce\x9a\xdd\x63\x67\x9f\x40\x0d\x0e\x3f\x3a\x98\xa2\x5e\x84\xad\x86\xcc\x9e" +
"\x28\x76\xd7\x1b\xc4\xd7\xdb\xbd\x46\xc2\xed\x10\xc6\x18\x38\x5f\x09\xa3\x6e\xb6\xca\xbd\xde\x86\x82\x4f\xfa\x69" +
"\xa9\xd3\xef\x84\x67\x41\xbd\xc7\x62\x94\x04\x24\xd2\x42\x99\x1d\x10\x9e\xf6\xde\x1c\xdc\x80\x2a\x1f\xdc\x38\x78" +
"\xa8\x3b\x95\x05\xd7\x40\xa5\x05\x3d\xee\x92\x40\xd6\x45\xa3\xb2\x06\x85\xc7\xbb\x12\x44\x01\x7a\x57\xa0\x44\xe1" +
"\x53\x67\xcb\xf2\xcf\x6e\x7b\x4a\xaa\x5b\xd2\x72\xb7\x34\x18\xca\xe5\x01\x3f\xeb\x3d\xd8\x1a\xa9\xe1\x31\x6b\x37" +
"\x18\x8e\xde\x22\x3a\xbd\xad\x11\x28\xe9\xdc\x12\x4e\x7a\xc7\xc9\xea\xa4\xc1\x42\xfb\x23\xf7\x6d\x75\xbb\x59\xed" +
"\xb5\x79\xfd\x5f\x3a\xf6\x06\x5c\x5e\xda\xc3\xeb\xbb\xa4\xd0\x59\x06\x66\x43\x42\xae\xc8\x84\x35\x94\x8c\x10\x99" +
"\x61\x5b\x23\xe1\xae\x5f\x57\xca\x87\x8e\x18\x76\x99\xb3\xd5\xb4\xf9\x0e\x77\x99\x3d\x98\xb0\x6f\x17\xe5\xcd\x02" +
"\xc9\x27\x2a\x3a\xc8\xe5\xd1\x4e\xf8\xaa\xd4\x48\xc9\x09\x61\x57\xf1\xf5\x6c\x56\x4f\x83\xe0\x29\x3a\x73\x94\x14" +
"\x64\x06\xa9\xcd\xe0\xcb\xa7\xbf\xde\xd9\x7d\x65\x0d\x18\x0c\x4f\xc7\xe8\xf1\x9e\xb0\xcd\xb9\x94\x12\x67\xee\x83" +
"\xc4\xab\xf8\x9a\x3b\x89\x57\x67\xd7\x6c\xd3\xd7\x0e\x16\x83\xe1\x8c\x6d\x96\x03\x60\x07\xf8\x86\x9c\x1a\xde\xfc" +
"\xa8\xc5\x43\x43\x6b\x7e\x1e\xc7\x49\xde\x2e\x13\x2f\x17\x53\x5b\x4c\x3d\xbe\x09\xf3\x6e\x2d\xa5\x8b\x22\x8a\x12" +
"\x4f\xc9\x3d\x39\x75\x63\x28\x3f\x40\xe6\x94\x9c\x90\x53\xdc\xbc\xa0\x7b\x1f\x36\xdc\x0f\x9a\xbb\xef\xc5\x27\x45" +
"\xfd\x9c\xd5\xa6\xaa\x71\x18\xb2\xe6\x25\x8a\xb9\x4d\x6b\xff\x22\x97\x1e\x4a\x48\x91\x32\xde\x3f\x01\x33\x6e\xf9" +
"\x63\xdc\x8e\x41\x3b\x1a\xdc\x19\xa4\x34\xfc\x7d\x9a\xaf\xfc\xbf\x06\xdb\xb3\xe2\xc7\x40\x1f\xc9\x9e\x7c\xd1\xf0" +
"\xa5\xca\xe8\xf4\x6e\x07\x6e\x6a\xda\x05\x01\xfd\x30\x58\x1f\x25\x32\x3c\x1c\xaf\xe8\x62\x0a\x29\xca\x78\x4a\x43" +
"\xe7\x5e\xb3\xcd\xbf\x01\x00\x00\xff\xff\x08\xce\x6c\x8a\x47\x0b\x00\x00")
func bindataFrontendApplicationcoffeeBytes() ([]byte, error) {
func bindataFrontendAppjsBytes() ([]byte, error) {
return bindataRead(
_bindataFrontendApplicationcoffee,
"frontend/application.coffee",
_bindataFrontendAppjs,
"frontend/app.js",
)
}
func bindataFrontendApplicationcoffee() (*asset, error) {
bytes, err := bindataFrontendApplicationcoffeeBytes()
func bindataFrontendAppjs() (*asset, error) {
bytes, err := bindataFrontendAppjsBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{
name: "frontend/application.coffee",
size: 2911,
md5checksum: "3b6e46919590964a6ce7eb5102fe280d",
mode: os.FileMode(436),
modTime: time.Unix(1, 0),
}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var _bindataFrontendApplicationjs = []byte(
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x55\x41\x6f\xe3\x36\x13\xfd\x2b\x0e\x12\x84\x24\x3c\xd1\x3a\xf9\xf2" +
"\xf5\x20\x83\x87\x45\x50\xb4\x05\xda\xa2\x48\x76\x4f\x8b\x45\x31\x24\x47\x12\x13\x99\x34\x48\xca\x4e\xe0\xd5\x7f" +
"\x2f\x68\x5b\x89\x1d\x3b\x69\x2e\xbd\x18\x1e\xce\x68\xc8\xf7\xe6\xf1\x91\x75\x91\x46\x31\x05\xab\x13\x9b\xf2\xaa" +
"\x73\x3a\x59\xef\xb8\x58\x2d\x30\x8c\x10\x14\x68\x30\x40\x50\x41\x0d\x0d\x58\xb8\x87\x87\xa9\x95\xae\x6b\x5b\x50" +
"\xf2\x75\xf5\x34\x50\xea\x82\x1b\xa1\x3c\xe3\xec\xb4\xf2\x61\x76\x13\x08\x13\xdd\x91\x0e\x94\x98\x28\x2a\xeb\x0c" +
"\x67\x89\x1e\x13\x06\x42\x26\x8a\x05\xb6\x5c\x80\x95\x7f\x60\x6a\x8a\x80\xce\xf8\x19\x17\x45\xf2\x77\x29\x58\x57" +
"\xf3\xff\xfd\x24\x8a\xd8\xa9\xb8\x89\xae\x04\xa0\xfc\xc5\x2a\x45\xc1\xc6\xe6\xf3\xcf\x77\x05\x39\xcd\x11\xac\x80" +
"\xb3\x02\xef\xf1\x91\x33\x9c\xdb\x4f\x7a\xbd\x27\x83\xd5\x8c\x52\xe3\x4d\xc9\xe6\x3e\x26\x06\x06\x13\x96\xab\xb8" +
"\x3e\x4a\x89\xfd\x3a\xfe\xf2\x34\xa7\x92\xdd\x47\xef\x18\xc4\x84\xa9\x8b\x37\xde\x50\xb9\xba\x9a\x5c\x96\x0d\x5c" +
"\x4f\x26\xe5\x03\xfc\x7f\xfd\x7b\x3d\xb9\x2e\x07\xb8\x23\xe4\x62\xb5\x85\xda\xf0\x6d\xcb\xbf\xad\x29\x59\xe5\xbd" +
"\xc2\xc0\x7a\xd1\xf7\xbd\x80\x93\xcb\x1e\xf4\x2e\x49\xdb\x6f\x32\x39\xce\xa7\xca\x77\xce\x30\x51\xc4\xc6\x2f\xb9" +
"\xe8\xc1\x1c\xf2\x69\x2b\x8e\x72\x69\x9d\xf1\xcb\xa2\xf5\x1a\x73\xb2\x68\x30\x36\x30\x39\x91\x12\x8b\x96\x5c\x9d" +
"\x1a\xb1\xd3\x57\x63\x30\x7f\xd2\xf2\x99\xf1\xc6\x1a\xe2\x02\x86\xd4\x66\xfd\xeb\xed\xef\xfb\xa9\x9d\xd3\xec\xac" +
"\x46\x9f\x19\xb4\xae\x5e\x06\xef\xea\xc3\x66\xb7\x84\xdb\x86\x7f\x05\xda\x01\x52\x1f\x00\x01\x05\xe6\x45\x1c\x47" +
"\x01\xa1\x34\xa4\xbd\xa1\xaf\xb7\xbf\xdd\xf8\xd9\xdc\x3b\x72\x89\xa3\x00\x23\xb1\x88\xf3\xd6\x26\xce\x7e\x30\x01" +
"\x57\x52\x4a\xb3\xc5\x7d\x7e\xce\x51\x9a\x6f\x93\xef\x60\xa5\xf9\x76\xf9\x5d\x80\xca\xc5\xcf\x7a\xb9\xdc\xd7\x45" +
"\x4d\xe9\x13\x1b\x2b\x58\xbd\x37\xf9\x3c\x67\x0d\x57\x93\x49\x79\xdf\xf7\xa2\x07\x7a\x63\x7e\x47\xc4\xad\xd6\xe2" +
"\x8e\x9d\x9a\xd9\xc4\x40\x6d\x99\x1d\x66\x01\xa3\xc2\xe1\x42\x61\xb8\x50\x59\xe7\xcf\xf5\xba\xb5\xfa\x81\x41\x95" +
"\xcb\x37\xc4\x0c\x99\x4c\x8b\x6e\xd0\xd5\xc4\xc0\x6c\xba\x05\x5a\x10\xb6\xaf\x76\xdc\x76\xa8\x05\x60\x66\xbf\x3a" +
"\x72\xe2\x17\xaa\x03\x55\x72\x2f\x1a\xc8\x3d\x65\x22\x33\x99\x35\x8b\xc7\x31\xef\x5c\x5b\x42\xdd\xbc\xe1\x15\x32" +
"\x35\x36\x0e\xb3\xd6\xeb\x68\xdf\x29\x86\x54\x11\xd3\x53\x4b\x45\x43\xb6\x6e\x92\x34\x45\xd4\xc1\xb7\xed\xaf\xeb" +
"\x70\xcc\xe6\x8f\xec\xf8\x41\xb6\xe2\x89\x94\xbe\xd8\x19\xf9\x2e\x71\x05\x13\xd1\x83\xce\x4b\x9f\x53\x0a\x56\x75" +
"\x89\x38\x5b\x77\x67\xc0\x36\xfd\xcb\x11\x1b\xe7\xa3\x1c\xec\x32\x1d\xcd\xac\xbb\xf8\xd7\x22\xbf\xa0\x50\xb5\x7e" +
"\x79\xf1\x54\x36\xd6\x18\x72\x53\x96\x27\xa2\x45\xe1\x1d\x67\xc3\x94\xd4\x36\xec\x12\x03\xdc\xfc\x9f\x63\xcc\x5e" +
"\xb4\x8d\x4c\xf0\xf3\xe7\xe0\x81\x9e\x8c\x5f\xba\x1c\x67\xa5\x35\x2f\x60\x71\xc3\xa8\x02\x3d\x10\xb9\x16\xf6\xe0" +
"\x33\x90\xed\xf7\x44\x4a\x7b\x7e\xce\x95\x54\x63\xf6\x83\x8d\xad\x00\xfd\xde\x60\xc7\xec\x34\x6b\xff\x03\x16\xf1" +
"\xfa\x56\xbf\xe3\x20\x9b\x0b\x7f\x34\xb5\x71\x7a\xeb\xe6\x5d\xda\xda\xbc\xfe\x48\x61\xe5\x75\x17\x3f\xd4\x32\x52" +
"\x4b\x3a\xad\x1f\x8f\x4c\x47\x0f\xf7\x87\xfc\x1d\xb2\xb7\x4f\xdd\xde\x5b\x62\x48\x73\x05\x56\x88\x8f\x90\xf4\x9f" +
"\xfa\xe8\x9b\xe9\x43\xca\xf7\x72\x47\x5f\x57\xf5\xd1\xe2\x14\x6c\x5d\x53\x78\x56\xb3\xe8\xe1\xe1\x0d\xf3\x3b\x00" +
"\x34\x38\xff\x19\x3f\xfc\x20\x43\x31\x3c\x4b\x5c\x14\x1a\xdb\x96\x2f\xbc\x35\xa3\x89\x98\xfe\x13\x00\x00\xff\xff" +
"\x1a\xcb\xdd\x44\x7a\x08\x00\x00")
func bindataFrontendApplicationjsBytes() ([]byte, error) {
return bindataRead(
_bindataFrontendApplicationjs,
"frontend/application.js",
)
}
func bindataFrontendApplicationjs() (*asset, error) {
bytes, err := bindataFrontendApplicationjsBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{
name: "frontend/application.js",
size: 2170,
md5checksum: "0ce1c4882aa2faf4e7ef349830c643bb",
mode: os.FileMode(436),
name: "frontend/app.js",
size: 2887,
md5checksum: "ae40c0761928772e95498d67481e1422",
mode: os.FileMode(420),
modTime: time.Unix(1, 0),
}
@ -3425,55 +3369,55 @@ func bindataFrontendCssFontawesomemincss() (*asset, error) {
var _bindataFrontendIndexhtml = []byte(
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x58\xd1\x6f\xdb\xbe\x11\x7e\xcf\x5f\x71\x3f\xe6\x35\x8c\xd6\x62\x05" +
"\xb6\x54\x32\x30\x14\x03\x56\xa0\x58\x87\x24\x05\xf6\x58\x4a\x3c\x4b\x4c\x29\x52\x25\x4f\x76\x5d\xc3\xff\xfb\x40" +
"\x51\x52\x2c\xcb\x76\xdc\xae\x7d\xf8\x21\x40\x6c\x51\xc7\xfb\x78\xdf\x7d\x3c\x9e\x99\xfe\x21\x6d\x41\x9b\x06\xa1" +
"\xa2\x5a\x2f\xae\xd2\xf0\x01\x5a\x98\x32\x63\x68\xd8\xe2\x0a\x20\xad\x50\xc8\xf0\x05\x20\xfd\x83\x73\xb8\xc7\xaf" +
"\xad\x72\x28\xa1\x46\x12\x40\xa2\xf4\xc0\x79\xff\xbe\x1b\x2a\x2a\xe1\x3c\x52\xc6\x5a\x5a\xf2\xbf\xb1\xfd\x57\x15" +
"\x51\xc3\xc3\xfc\x55\xc6\xfe\xcb\x3f\xfd\x83\xbf\xb3\x75\x23\x48\xe5\x1a\x19\x14\xd6\x10\x1a\xca\xd8\xfb\x7f\x66" +
"\x28\x4b\x9c\xcc\x34\xa2\xc6\x8c\xad\x14\xae\x1b\xeb\x68\xcf\x78\xad\x24\x55\x99\xc4\x95\x2a\x90\x77\x0f\x37\xa0" +
"\x51\x52\x2c\xcb\x76\xdc\xae\x7d\xf8\xa1\x40\x13\x91\xc7\xfb\x78\xdf\x7d\x3c\x5e\x98\xfe\x21\x6d\x41\x9b\x06\xa1" +
"\xa2\x5a\x2f\xae\xd2\xf0\x03\xb4\x30\x65\xc6\xd0\xb0\xc5\x15\x40\x5a\xa1\x90\xe1\x17\x80\xf4\x0f\xce\xe1\x1e\xbf" +
"\xb6\xca\xa1\x84\x1a\x49\x00\x89\xd2\x03\xe7\xfd\x7c\x37\x54\x54\xc2\x79\xa4\x8c\xb5\xb4\xe4\x7f\x63\xfb\x53\x15" +
"\x51\xc3\xc3\xfa\x55\xc6\xfe\xcb\x3f\xfd\x83\xbf\xb3\x75\x23\x48\xe5\x1a\x19\x14\xd6\x10\x1a\xca\xd8\xfb\x7f\x66" +
"\x28\x4b\x9c\xac\x34\xa2\xc6\x8c\xad\x14\xae\x1b\xeb\x68\xcf\x78\xad\x24\x55\x99\xc4\x95\x2a\x90\x77\x1f\x37\xa0" +
"\x8c\x22\x25\x34\xf7\x85\xd0\x98\xbd\xba\x01\x5f\x39\x65\xbe\x70\xb2\x7c\xa9\x28\x33\x96\x2d\xae\xa2\x6f\xad\xcc" +
"\x17\x70\xa8\x33\xe6\x69\xa3\xd1\x57\x88\xc4\xa0\x72\xb8\xcc\x58\x52\x78\x9f\xe4\xd6\x92\x27\x27\x9a\xdb\x5a\x99" +
"\xdb\xc2\x7b\x06\xca\x10\x96\x4e\xd1\x26\x63\xdb\xed\xc3\xfd\xfb\x7f\x09\x5f\xc1\xe7\xe3\xd6\x9f\x77\x3b\x06\xc9" +
"\xe2\x47\xc0\xd6\x82\x8a\xea\x72\xb4\x89\xf9\x8f\xc1\x2d\xad\x21\xb1\x46\x6f\x6b\xe4\x42\xeb\x8b\x30\x4f\xcc\x19" +
"\x80\x23\x32\x29\xd2\xb8\xf8\xf8\xf8\x00\x1c\x3e\x1a\x84\x47\x55\x23\x3c\x60\xe1\x90\x7c\x9a\xc4\xb7\xbd\x69\xb7" +
"\xb4\xb8\x60\x80\xeb\xe0\x96\x2a\x65\xca\xb5\xb3\xa6\xbc\x81\x6b\x63\x69\x69\x5b\x23\x6f\xe0\xba\x10\x4e\xde\xa3" +
"\x90\xd1\x4f\x3f\x10\x1f\x3e\xdd\x7f\x98\x19\xfc\xc7\x21\x6c\x41\x2a\xdf\x68\xb1\xb9\x03\x63\x0d\xbe\x85\x5d\x0f" +
"\x74\xbb\xb4\x96\xd0\xc1\x16\x0a\xab\xad\xbb\x83\xeb\xd7\xcb\xf0\xf7\x16\x42\x7c\xdc\xab\xef\x78\x07\x7f\xb9\xfd" +
"\x3b\xd6\x6f\x81\xf0\x1b\x71\xa1\x55\x69\xee\xa0\x40\x43\xe8\x9e\xfd\x84\x77\xc2\xa1\x80\x6d\x9c\xb8\x14\xb5\xd2" +
"\x9b\x3b\xa8\xad\xb1\xbe\x11\xc5\x08\x99\x26\x63\xa0\x69\x32\x6c\xa8\x34\xb7\x72\x33\x10\x61\xc4\x0a\x0a\x2d\xbc" +
"\xcf\x98\x11\xab\x5c\x38\x88\x1f\x1c\xbf\x35\xc2\x48\xae\xcb\x61\x40\x0a\xf7\x05\xf2\x92\x37\x4e\xd5\xc2\x6d\xd8" +
"\xe2\x47\xc0\xd6\x82\x8a\xea\x72\xb4\x89\xf9\x8f\xc1\x2d\xad\x21\xb1\x46\x6f\x6b\xe4\x42\xeb\x8b\x30\x4f\xac\x19" +
"\x80\x23\x32\x29\xd2\xb8\xf8\xf8\xf8\x00\x1c\x3e\x1a\x84\x47\x55\x23\x3c\x60\xe1\x90\x7c\x9a\xc4\xd9\xde\xb4\xdb" +
"\x5a\xdc\x30\xc0\x75\x70\x4b\x95\x32\xe5\xda\x59\x53\xde\xc0\xb5\xb1\xb4\xb4\xad\x91\x37\x70\x5d\x08\x27\xef\x51" +
"\xc8\xe8\xa7\x1f\x88\x1f\x9f\xee\x3f\xcc\x0c\xfe\xe3\x10\xb6\x20\x95\x6f\xb4\xd8\xdc\x81\xb1\x06\xdf\xc2\xae\x07" +
"\xba\x5d\x5a\x4b\xe8\x60\x0b\x85\xd5\xd6\xdd\xc1\xf5\xeb\x65\xf8\xf7\x16\x42\x7c\xdc\xab\xef\x78\x07\x7f\xb9\xfd" +
"\x3b\xd6\x6f\x81\xf0\x1b\x71\xa1\x55\x69\xee\xa0\x40\x43\xe8\x9e\xfd\x84\x39\xe1\x50\xc0\x36\x2e\x5c\x8a\x5a\xe9" +
"\xcd\x1d\xd4\xd6\x58\xdf\x88\x62\x84\x4c\x93\x31\xd0\x34\x19\x0e\x54\x9a\x5b\xb9\x19\x88\x30\x62\x05\x85\x16\xde" +
"\x67\xcc\x88\x55\x2e\x1c\xc4\x1f\x1c\xbf\x35\xc2\x48\xae\xcb\x61\x40\x0a\xf7\x05\xf2\x92\x37\x4e\xd5\xc2\x6d\xd8" +
"\xc0\x5e\x2a\xa6\x0e\x78\xee\x84\x91\x43\xc6\xaf\xd9\x22\x55\x83\xc1\x52\x78\x58\x0a\xde\x7a\x74\xdc\x77\x74\xb1" +
"\x45\x9a\xa8\x05\x9c\xca\x99\x18\x41\xf2\x96\xc8\x9a\x03\x24\xb2\x65\xa9\xd1\x31\x08\xa5\x24\x63\xd1\x86\x81\x14" +
"\x24\xfa\x77\x19\x2b\xac\xd6\xa2\xf1\x38\x0c\x0b\x57\x86\x22\x71\x1d\x5d\x3c\xb4\x4d\xd8\xd8\x28\xdf\xc5\x8d\xcd" +
"\x40\x38\x25\x78\xd8\xe6\xce\xea\x11\xe9\x84\x59\xe4\x08\x65\x88\x4c\x07\x88\x6e\x54\x8b\x3c\xa8\xff\xb1\x5b\x40" +
"\x60\x4f\x95\x82\x94\x35\x23\x63\x41\x7f\x8d\x38\x11\x0c\x57\x45\x30\x4d\x93\x60\x32\x86\x9f\xc4\xd8\xfa\xac\x01" +
"\xa4\x52\x8d\x79\x1b\x22\x1c\x12\xf5\x1c\xb1\x92\x27\x03\xd8\x5b\x4b\xab\x0f\x56\x12\x34\x51\x6b\x2e\x5a\xb2\x7b" +
"\x76\xdd\xd6\xde\xb3\xe4\x8a\xb0\x0e\x0b\xd5\xea\x65\x23\x31\xca\x21\x2e\x0a\xd7\x0f\x43\xfe\x0f\xd5\xd1\xe8\xd6" +
"\xf7\xb2\xd8\x6e\x1f\x81\xe5\x64\xb8\xc1\xf5\x20\x98\xdd\x2e\xc8\x62\x8a\x9a\x26\xad\x7e\xa6\x4a\xaa\x55\x5f\x8a" +
"\x12\x23\x56\x83\xd0\x27\x84\x19\x12\xca\xa0\x83\x9a\xf8\x5f\x9f\x85\xbc\x67\xe2\xec\x1a\x9e\x5a\x4f\x6a\xb9\xe1" +
"\x7d\xcd\xe7\x71\x17\xee\x33\x37\x4d\x02\xaf\xe5\x78\xee\xcc\x0d\x84\x46\x47\xd0\xfd\xe7\x52\x98\x32\xc8\xd6\xd9" +
"\x24\xfa\xb9\x8c\x15\x56\x6b\xd1\x78\x1c\x86\x85\x2b\x43\x91\xb8\x8e\x2e\x1e\xda\x26\x1c\x6c\x94\xef\xe2\xc1\x66" +
"\x20\x9c\x12\x3c\x1c\x73\x67\xf5\x88\x74\xc2\x2c\x72\x84\x32\x44\xa6\x03\x44\x37\xaa\x45\x1e\xd4\xff\xd8\x6d\x20" +
"\xb0\xa7\x4a\x41\xca\x9a\x91\xb1\xa0\xbf\x46\x9c\x08\x86\xab\x22\x98\xa6\x49\x30\x19\xc3\x4f\x62\x6c\x7d\xd6\x00" +
"\x52\xa9\xc6\xbc\x0d\x11\x0e\x89\x7a\x8e\x58\xc9\x93\x01\xec\xed\xa5\xd5\x07\x3b\x09\x9a\xa8\x35\x17\x2d\xd9\x3d" +
"\xbb\xee\x68\xef\x59\x72\x45\x58\x87\x8d\x6a\xf5\xb2\x91\x18\xe5\x10\x37\x85\xeb\x87\x21\xff\x87\xea\x68\x74\xeb" +
"\x7b\x59\x6c\xb7\x8f\xc0\x72\x32\xdc\xe0\x7a\x10\xcc\x6e\x17\x64\x31\x45\x4d\x93\x56\x3f\x53\x25\xd5\xaa\x2f\x45" +
"\x89\x11\xab\x41\xe8\x13\xc2\x0c\x09\x65\xd0\x41\x4d\xfc\xaf\xcf\x42\xde\x33\x71\x76\x0d\x4f\xad\x27\xb5\xdc\xf0" +
"\xbe\xe6\xf3\x78\x0a\xf7\x99\x9b\x26\x81\xd7\x72\xbc\x77\xe6\x06\x42\xa3\x23\xe8\xfe\xe7\x52\x98\x32\xc8\xd6\xd9" +
"\xa0\xd0\x6e\xac\xe7\xa5\xaf\x3b\x13\x2f\x00\x33\x8e\xbe\xb6\xe8\x83\xa4\x78\xa1\x5c\xa1\x07\xe1\x55\x4a\x4a\x34" +
"\x19\x23\xd7\x62\x64\x70\xe2\xa5\x63\x33\x2e\x20\x72\xc9\x8d\x25\x1e\xf1\x76\xbb\xfd\x65\x3f\x53\xf8\x93\x71\x4c" +
"\x0b\xea\x6f\x8f\x66\x40\xe3\xeb\x90\xa7\x88\x79\x2e\xa2\xc9\x63\xff\x70\x5c\x04\xe7\xb3\xfd\xea\x35\x1b\x27\xce" +
"\x4c\x84\x93\x90\x5b\x27\xd1\x8d\x25\xb3\xe3\x26\xbc\xf8\xf7\xb3\xfe\xa7\xd4\x1c\x38\xe0\xa1\x66\xa3\xdb\x2b\xbb" +
"\xf1\x5c\x58\x57\x8a\xf0\x60\x6e\x4f\x49\x77\xcc\x4d\x37\xcc\x14\xe2\x30\xb9\x47\x50\xc3\x01\x31\xf3\x9e\x2e\xad" +
"\xab\xbb\x08\xc2\x97\x77\x0e\x05\xe1\xd1\x20\x0e\x5d\x06\x73\x5e\x3a\xdb\x36\x47\x0c\x43\xc1\x08\xf5\x12\x96\xd6" +
"\x65\x6c\x38\x14\xba\x48\xba\xf1\x41\xaa\xa1\x78\x77\x7b\xbf\x1b\x3d\xea\x67\x3c\x15\xf7\x71\xfb\x4a\x1e\x34\xba" +
"\xf6\x19\x7b\xd3\xeb\x73\x3c\x7c\x86\x49\x47\x42\x98\x13\xd5\x0d\x2b\xd3\xb4\x34\x60\xe4\x64\x20\x14\x28\xdf\x16" +
"\x05\x86\x1e\x26\x9e\x44\xbe\xcd\x6b\x45\x0c\x56\x42\xb7\x18\xba\x99\xbe\x8e\x15\x1d\x6b\xcf\x99\x99\x93\x9c\x84" +
"\x55\x2f\xce\x67\x6c\xaa\xd8\x63\x19\x1c\x84\x37\x2e\x6b\x10\xde\xd8\xb8\x5c\x2e\xbc\xde\xc7\x85\xc2\xeb\xd3\x15" +
"\x03\x95\xbf\x4e\x7c\xcd\x3c\x13\x11\x35\xac\xaa\x71\xc8\x5b\xa7\x0f\xd1\x02\xde\x6c\xde\xc5\xca\xec\x13\x1d\x13" +
"\x1a\x60\xd8\x09\x61\xa1\x90\xd6\xe8\xcd\x3c\x95\x47\xf4\x73\x3e\x8e\xbc\x75\x86\x57\xca\xcc\x36\xed\x91\x48\xfe" +
"\x19\x23\xd7\x62\x64\x70\xe2\xa5\x63\x33\x6e\x20\x72\xc9\x8d\x25\x1e\xf1\x76\xbb\xfd\x6d\x3f\x53\xf8\x93\x71\x4c" +
"\x0b\xea\x6f\x8f\x66\x40\xe3\xeb\x90\xa7\x88\x79\x2e\xa2\xc9\x67\xff\x71\x5c\x04\xe7\xb3\xfd\xea\x35\x1b\x17\xce" +
"\x4c\x84\x93\x90\x5b\x27\xd1\x8d\x25\xb3\xe3\x26\x4c\xfc\xfb\x59\xff\x53\x6a\x0e\x1c\xf0\x50\xb3\xd1\xed\x95\xdd" +
"\x78\x2f\xac\x2b\x45\x78\xb0\xb6\xa7\xa4\xbb\xe6\xa6\x07\x66\x0a\x71\x98\xdc\x23\xa8\xe1\x82\x98\x79\x4f\x97\xd6" +
"\xd5\x5d\x04\xe1\x97\x77\x0e\x05\xe1\xd1\x20\x0e\x5d\x06\x73\x5e\x3a\xdb\x36\x47\x0c\x43\xc1\x08\xf5\x12\x96\xd6" +
"\x65\x6c\xb8\x14\xba\x48\xba\xf1\x41\xaa\xa1\x78\x77\x67\xbf\x1b\x3d\xea\x67\xbc\x15\xf7\x71\xfb\x4a\x1e\x34\xba" +
"\xf6\x19\x7b\xd3\xeb\x73\xbc\x7c\x86\x45\x47\x42\x98\x13\xd5\x0d\x2b\xd3\xb4\x34\x60\xe4\x64\x20\x14\x28\xdf\x16" +
"\x05\x86\x1e\x26\xde\x44\xbe\xcd\x6b\x45\x0c\x56\x42\xb7\x18\xba\x99\xbe\x8e\x15\x1d\x6b\xcf\x99\x99\x93\x9c\x84" +
"\x5d\x2f\xce\x67\x6c\xaa\xd8\x63\x19\x1c\x84\x37\x6e\x6b\x10\xde\xd8\xb8\x5c\x2e\xbc\xde\xc7\x85\xc2\xeb\xd3\x15" +
"\x03\x95\xbf\x4e\x7c\xcd\x3c\x13\x11\x35\xec\xaa\x71\xc8\x5b\xa7\x0f\xd1\x02\xde\x6c\xdd\xc5\xca\xec\x13\x1d\x13" +
"\x1a\x60\xd8\x09\x61\xa1\x90\xd6\xe8\xcd\x3c\x95\x47\xf4\x73\x3e\x8e\xbc\x75\x86\x57\xca\xcc\x0e\xed\x91\x48\xfe" +
"\x0f\x55\xcc\xca\xd1\xa4\x7d\xfd\x5d\x25\x29\xf0\x14\x6a\xf4\xaf\x2e\x4b\x2f\x2a\xc3\xe1\x0a\x85\x3e\xc7\xeb\x05" +
"\x2e\x0f\x1a\xd0\xd9\xbe\x0f\x54\x46\xa0\x87\xfd\x1a\x16\x6c\x7a\xfc\xbd\xfe\x65\x68\xe6\x8e\x2c\xe5\x2c\x27\xbf" +
"\x24\xc5\x7f\xb6\xfc\x5e\xbc\x5f\x2f\xac\xff\xe3\x7e\x3d\x5d\xfc\xe7\x3c\xc3\x8b\x4a\x0b\xf2\xea\x36\xf0\xbc\xea" +
"\xfd\x4c\x6a\xe3\x73\xbc\xfa\x48\x6e\xc7\x7e\x63\xbc\xf3\x38\xb4\x08\x0d\x6b\x78\x77\xa2\x97\xad\x89\xbf\x79\xa9" +
"\x97\x81\xf8\xeb\x74\x42\xed\xde\x4e\xb2\x6b\x74\x28\x79\xbe\x61\xbb\x1d\x8c\x0d\x7d\x45\xd4\xf8\xbb\x24\x29\x15" +
"\x2e\x0f\x1a\xd0\xd9\xb9\x0f\x54\x46\xa0\x87\xfd\x1a\x16\x6c\x7a\xfc\xbd\xfe\x65\x68\xe6\x8e\x6c\xe5\x2c\x27\xbf" +
"\x24\xc5\x7f\xb6\xfc\x5e\x7c\x5e\x2f\xac\xff\xe3\x79\x3d\x5d\xfc\xe7\x3c\xc3\x8b\x4a\x0b\xf2\xea\x0e\xf0\xbc\xea" +
"\xfd\x4c\x6a\xe3\x77\x7c\xfa\x48\x6e\xc7\x7e\x63\x7c\xf3\x38\xb4\x08\x0d\x6b\x98\x3b\xd1\xcb\xd6\xc4\xdf\xbc\xd4" +
"\xcb\x40\xfc\xeb\x74\x42\xed\xde\x49\xb2\x6b\x74\x28\x79\xbe\x61\xbb\x1d\x8c\x0d\x7d\x45\xd4\xf8\xbb\x24\x29\x15" +
"\x55\x6d\x7e\x5b\xd8\x3a\xf9\xd0\x7e\x57\x4b\x74\x89\x25\x3f\x6d\xef\xf3\xd0\xec\x45\xc3\xbe\xc1\x1f\x4c\x3f\x3e" +
"\x3e\x84\xae\x1e\xb6\xdb\xdb\x15\x3a\xaf\xac\xd9\xa3\xf0\x58\xb7\x76\x48\x59\xea\x0b\xa7\x1a\x02\xef\x8a\x8c\x25" +
"\x4f\x3e\x79\xfa\xda\xa2\xdb\x74\xf7\x04\x4f\xa7\xaf\x16\x0e\x0d\x3f\x87\x23\x39\x4d\xa2\xb3\xc5\x71\xcf\x8d\x6d" +
"\x1a\x74\x17\x78\x9e\x18\x5e\xe2\x79\x7a\x8d\x73\xde\xf9\xa1\xed\x25\xfe\x4b\x95\xe7\xe8\x94\xaf\xb8\x40\x7f\x01" +
"\xc6\x31\xfb\x97\x70\x44\xd3\x68\x55\x74\xbf\x77\xcf\x78\x9f\x5a\xcd\x7c\xa6\x49\xbc\xa2\x48\x93\x78\x3d\x78\xf5" +
"\xbf\x00\x00\x00\xff\xff\x72\x3b\xda\x38\x30\x14\x00\x00")
"\x4f\x3e\x79\xfa\xda\xa2\xdb\x74\xef\x04\x4f\xa7\x9f\x16\x0e\x0d\x3f\x87\x2b\x39\x4d\xa2\xb3\xc5\x71\xcf\x8d\x6d" +
"\x1a\x74\x17\x78\x9e\x18\x5e\xe2\x79\xfa\x8c\x73\xde\xf9\xa1\xed\x25\xfe\x4b\x95\xe7\xe8\x94\xaf\xb8\x40\x7f\x01" +
"\xc6\x31\xfb\x97\x70\x44\xd3\x9c\xf1\x1a\x67\x67\x3e\xd2\x24\x3e\x49\xa4\x49\x7c\x0e\xbc\xfa\x5f\x00\x00\x00\xff" +
"\xff\xcd\x69\x67\x1e\x20\x14\x00\x00")
func bindataFrontendIndexhtmlBytes() ([]byte, error) {
return bindataRead(
@ -3492,8 +3436,8 @@ func bindataFrontendIndexhtml() (*asset, error) {
info := bindataFileInfo{
name: "frontend/index.html",
size: 5168,
md5checksum: "fee5388d6adb9685d39a89ef10e96a05",
size: 5152,
md5checksum: "2dfa0784504f7bdac4929bd06a1f88d5",
mode: os.FileMode(436),
modTime: time.Unix(1, 0),
}
@ -5663,7 +5607,7 @@ func bindataFrontendLocaleDedeuntranslatedjson() (*asset, error) {
name: "frontend/locale/de-de.untranslated.json",
size: 2,
md5checksum: "99914b932bd37a50b983c5e7c90ae93b",
mode: os.FileMode(436),
mode: os.FileMode(420),
modTime: time.Unix(1, 0),
}
@ -5744,7 +5688,7 @@ func bindataFrontendLocaleEnusuntranslatedjson() (*asset, error) {
name: "frontend/locale/en-us.untranslated.json",
size: 2,
md5checksum: "99914b932bd37a50b983c5e7c90ae93b",
mode: os.FileMode(436),
mode: os.FileMode(420),
modTime: time.Unix(1, 0),
}
@ -39343,8 +39287,7 @@ func AssetNames() []string {
// _bindata is a table, holding each asset generator, mapped to its name.
//
var _bindata = map[string]func() (*asset, error){
"frontend/application.coffee": bindataFrontendApplicationcoffee,
"frontend/application.js": bindataFrontendApplicationjs,
"frontend/app.js": bindataFrontendAppjs,
"frontend/css/bootstrap.min.css": bindataFrontendCssBootstrapmincss,
"frontend/css/bootswatch.min.css": bindataFrontendCssBootswatchmincss,
"frontend/css/fa-brands.css": bindataFrontendCssFabrandscss,
@ -39436,8 +39379,7 @@ type bintree struct {
var _bintree = &bintree{Func: nil, Children: map[string]*bintree{
"frontend": {Func: nil, Children: map[string]*bintree{
"application.coffee": {Func: bindataFrontendApplicationcoffee, Children: map[string]*bintree{}},
"application.js": {Func: bindataFrontendApplicationjs, Children: map[string]*bintree{}},
"app.js": {Func: bindataFrontendAppjs, Children: map[string]*bintree{}},
"css": {Func: nil, Children: map[string]*bintree{
"bootstrap.min.css": {Func: bindataFrontendCssBootstrapmincss, Children: map[string]*bintree{}},
"bootswatch.min.css": {Func: bindataFrontendCssBootswatchmincss, Children: map[string]*bintree{}},

1
frontend/app.js Normal file
View File

@ -0,0 +1 @@
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";var r=null;function o(){var e=$("#formCreateSecret").find("textarea").val();return r=Math.random().toString(36).substring(2),e=GibberishAES.enc(e,r),$.ajax("api/create",{method:"post",data:{secret:e},dataType:"json",statusCode:{201:l,400:s,500:s,404:function(){l({secret_id:"foobar"})}}}),!1}function i(){$("#notfound").show()}function c(){0!==window.location.hash.length&&($("#cardNewSecret").hide(),$("#cardSecretURL").hide(),$("#notfound").hide(),$("#somethingwrong").hide(),$("#cardReadSecretPre").show())}function a(){$("#formCreateSecret").bind("submit",o),$("#newSecret, .navbar-brand").bind("click",d),$(window).bind("hashchange",c),$("#revealSecret").bind("click",u),$("textarea").each(function(e,t){var n=function(){t.style.height=t.scrollHeight+"px"},r=function(){window.setTimeout(n,0)};t.setAttribute("style","height: #{this.scrollHeight}px; min-height: #{this.scrollHeight}px; overflow-y:hidden;"),$(t).on("change",n).on("cut",r).on("paste",r).on("drop",r).on("keydown",r)})}function d(){location.href=location.href.split("#")[0]}function u(){var e=window.location.hash,t=(e=decodeURIComponent(e)).split("|");2===t.length&&(e=t[0],r=t[1]);var n=e.substring(1);$.ajax("api/get/"+n,{dataType:"json",statusCode:{404:i,200:f}})}function l(e){var t=e.secret_id;null!==r&&(t=t+"|"+r);var n=location.href.split("#")[0]+"#"+t;$("#cardNewSecret").hide(),$("#cardReadSecretPre").hide(),$("#cardSecretURL").show(),$("#cardSecretURL").find("input").val(n),$("#cardSecretURL").find("input").focus(),$("#cardSecretURL").find("input").select(),r=null}function f(e){var t=e.secret;null!==r&&(t=GibberishAES.dec(t,r)),$("#cardNewSecret").hide(),$("#cardSecretURL").hide(),$("#notfound").hide(),$("#somethingwrong").hide(),$("#cardReadSecretPre").hide(),$("#cardReadSecret").show(),$("#cardReadSecret").find("textarea").val(t),$("#cardReadSecret").find("textarea").trigger("change")}function s(){$("#somethingwrong").show()}$(function(){a(),c()})}]);

View File

@ -1,123 +0,0 @@
securePassword = null
createSecret = () ->
secret = $('#formCreateSecret').find('textarea').val()
securePassword = Math.random().toString(36).substring(2)
secret = GibberishAES.enc(secret, securePassword)
$.ajax 'api/create',
method: "post"
data:
secret: secret
dataType: "json"
statusCode:
201: secretCreated
400: somethingWrong
500: somethingWrong
404: () ->
# Mock for interface testing
secretCreated
secret_id: 'foobar'
false
dataNotFound = () ->
$('#notfound').show()
hashLoad = () ->
hash = window.location.hash
if hash.length == 0
return
$('#cardNewSecret').hide()
$('#cardSecretURL').hide()
$('#notfound').hide()
$('#somethingwrong').hide()
$('#cardReadSecretPre').show()
requestSecret = () ->
hash = window.location.hash
hash = decodeURIComponent(hash)
parts = hash.split '|'
if parts.length == 2
hash = parts[0]
securePassword = parts[1]
id = hash.substring(1)
$.ajax "api/get/#{id}",
dataType: "json"
statusCode:
404: dataNotFound
200: showData
initBinds = () ->
$('#formCreateSecret').bind 'submit', createSecret
$('#newSecret, .navbar-brand').bind 'click', newSecret
$(window).bind 'hashchange', hashLoad
$('#revealSecret').bind 'click', requestSecret
bindResizeTextarea()
newSecret = () ->
location.href = location.href.split('#')[0]
false
bindResizeTextarea = () ->
$('textarea').each(() ->
text = this
doResize = () =>
#text.style.height = 'auto'
text.style.height = (this.scrollHeight) + 'px'
delayedResize = () =>
window.setTimeout doResize, 0
text.setAttribute('style', "height: #{this.scrollHeight}px; min-height: #{this.scrollHeight}px; overflow-y:hidden;")
$(text)
.on('change', doResize)
.on('cut', delayedResize)
.on('paste', delayedResize)
.on('drop', delayedResize)
.on('keydown', delayedResize)
)
secretCreated = (data) ->
secretHash = data.secret_id
if securePassword != null
secretHash = "#{secretHash}|#{securePassword}"
url = "#{location.href.split('#')[0]}##{secretHash}"
$('#cardNewSecret').hide()
$('#cardReadSecretPre').hide()
$('#cardSecretURL').show()
$('#cardSecretURL').find('input').val url
$('#cardSecretURL').find('input').focus()
$('#cardSecretURL').find('input').select()
securePassword = null
showData = (data) ->
secret = data.secret
if securePassword != null
secret = GibberishAES.dec(secret, securePassword)
$('#cardNewSecret').hide()
$('#cardSecretURL').hide()
$('#notfound').hide()
$('#somethingwrong').hide()
$('#cardReadSecretPre').hide()
$('#cardReadSecret').show()
$('#cardReadSecret').find('textarea').val secret
$('#cardReadSecret').find('textarea').trigger 'change'
somethingWrong = () ->
$('#somethingwrong').show()
$ ->
initBinds()
hashLoad()

View File

@ -1 +0,0 @@
'use strict';(function(){var a,b,c,d,e,f,g,h,i,j,k;i=null,b=function(){var a;return a=$('#formCreateSecret').find('textarea').val(),i=Math.random().toString(36).substring(2),a=GibberishAES.enc(a,i),$.ajax('api/create',{method:'post',data:{secret:a},dataType:'json',statusCode:{201:h,400:k,500:k,404:function a(){return h({secret_id:'foobar'})}}}),!1},c=function(){return $('#notfound').show()},d=function(){var a;if(a=window.location.hash,0!==a.length)return $('#cardNewSecret').hide(),$('#cardSecretURL').hide(),$('#notfound').hide(),$('#somethingwrong').hide(),$('#cardReadSecretPre').show()},g=function(){var a,b,d;return a=window.location.hash,a=decodeURIComponent(a),d=a.split('|'),2===d.length&&(a=d[0],i=d[1]),b=a.substring(1),$.ajax('api/get/'+b,{dataType:'json',statusCode:{404:c,200:j}})},e=function(){return $('#formCreateSecret').bind('submit',b),$('#newSecret, .navbar-brand').bind('click',f),$(window).bind('hashchange',d),$('#revealSecret').bind('click',g),a()},f=function(){return location.href=location.href.split('#')[0],!1},a=function(){return $('textarea').each(function(){var a,b,c,d=this;return c=this,b=function(){return c.style.height=d.scrollHeight+'px'},a=function(){return window.setTimeout(b,0)},c.setAttribute('style','height: '+this.scrollHeight+'px; min-height: '+this.scrollHeight+'px; overflow-y:hidden;'),$(c).on('change',b).on('cut',a).on('paste',a).on('drop',a).on('keydown',a)})},h=function(a){var b,c;return b=a.secret_id,null!==i&&(b=b+'|'+i),c=location.href.split('#')[0]+'#'+b,$('#cardNewSecret').hide(),$('#cardReadSecretPre').hide(),$('#cardSecretURL').show(),$('#cardSecretURL').find('input').val(c),$('#cardSecretURL').find('input').focus(),$('#cardSecretURL').find('input').select(),i=null},j=function(a){var b;return b=a.secret,null!==i&&(b=GibberishAES.dec(b,i)),$('#cardNewSecret').hide(),$('#cardSecretURL').hide(),$('#notfound').hide(),$('#somethingwrong').hide(),$('#cardReadSecretPre').hide(),$('#cardReadSecret').show(),$('#cardReadSecret').find('textarea').val(b),$('#cardReadSecret').find('textarea').trigger('change')},k=function(){return $('#somethingwrong').show()},$(function(){return e(),d()})}).call(void 0);

View File

@ -127,7 +127,7 @@
<script src="/js/popper.min.js" integrity="{{SRIHash `/js/popper.min.js`}}"></script>
<script src="/js/bootstrap.min.js" integrity="{{SRIHash `/js/bootstrap.min.js`}}"></script>
<script src="/js/gibberish-aes.min.js" integrity="{{SRIHash `/js/gibberish-aes.min.js`}}"></script>
<script src="application.js" integrity="{{SRIHash `application.js`}}"></script>
<script src="app.js" integrity="{{SRIHash `app.js`}}"></script>
</body>
</html>

1246
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +0,0 @@
{
"name": "ots",
"version": "0.0.0",
"internal": true,
"devDependencies": {
"babel-core": "^6.26.3",
"babel-preset-env": "^1.7.0",
"babel-preset-minify": "^0.4.3",
"coffeescript": "^2.3.1"
}
}

146
src/app.js Normal file
View File

@ -0,0 +1,146 @@
let securePassword = null
// bindResizeTextarea attaches resize triggers to all available text areas
function bindResizeTextarea() {
$('textarea').each((idx, text) => {
let doResize = () => {
text.style.height = text.scrollHeight + 'px'
}
let delayedResize = () => {
window.setTimeout(doResize, 0)
}
text.setAttribute('style', "height: #{this.scrollHeight}px; min-height: #{this.scrollHeight}px; overflow-y:hidden;")
$(text)
.on('change', doResize)
.on('cut', delayedResize)
.on('paste', delayedResize)
.on('drop', delayedResize)
.on('keydown', delayedResize)
})
}
// createSecret executes the secret creation after encrypting the secret
function createSecret() {
let secret = $('#formCreateSecret').find('textarea').val()
securePassword = Math.random().toString(36).substring(2)
secret = GibberishAES.enc(secret, securePassword)
$.ajax('api/create', {
method: "post",
data: {
secret: secret,
},
dataType: "json",
statusCode: {
201: secretCreated,
400: somethingWrong,
500: somethingWrong,
404: () => {
// Mock for interface testing
secretCreated({
secret_id: 'foobar',
})
},
},
})
return false
}
// dataNotFound displays the not-found error
function dataNotFound() {
$('#notfound').show()
}
// hashLoad reacts on a changed window hash an starts the diplaying of the secret
function hashLoad() {
let hash = window.location.hash
if (hash.length === 0) return
$('#cardNewSecret').hide()
$('#cardSecretURL').hide()
$('#notfound').hide()
$('#somethingwrong').hide()
$('#cardReadSecretPre').show()
}
// initBinds attaches functions to frontend elements
function initBinds() {
$('#formCreateSecret').bind('submit', createSecret)
$('#newSecret, .navbar-brand').bind('click', newSecret)
$(window).bind('hashchange', hashLoad)
$('#revealSecret').bind('click', requestSecret)
bindResizeTextarea()
}
// newSecret removes the window hash and therefore returns to "new secret" mode
function newSecret() {
location.href = location.href.split('#')[0]
}
// requestSecret requests the encrypted secret from the backend
function requestSecret() {
let hash = window.location.hash
hash = decodeURIComponent(hash)
let parts = hash.split('|')
if (parts.length === 2) {
hash = parts[0]
securePassword = parts[1]
}
let id = hash.substring(1)
$.ajax(`api/get/${id}`, {
dataType: "json",
statusCode: {
404: dataNotFound,
200: showData,
}
})
}
// secretCreated generates the share URLs and displays them to the user
function secretCreated(data) {
let secretHash = data.secret_id
if (securePassword !== null) secretHash = `${secretHash}|${securePassword}`
let url = `${location.href.split('#')[0]}#${secretHash}`
$('#cardNewSecret').hide()
$('#cardReadSecretPre').hide()
$('#cardSecretURL').show()
$('#cardSecretURL').find('input').val(url)
$('#cardSecretURL').find('input').focus()
$('#cardSecretURL').find('input').select()
securePassword = null
}
// showData takes the backend answer, decrypts the secret and shows it
function showData(data) {
let secret = data.secret
if (securePassword !== null) secret = GibberishAES.dec(secret, securePassword)
$('#cardNewSecret').hide()
$('#cardSecretURL').hide()
$('#notfound').hide()
$('#somethingwrong').hide()
$('#cardReadSecretPre').hide()
$('#cardReadSecret').show()
$('#cardReadSecret').find('textarea').val(secret)
$('#cardReadSecret').find('textarea').trigger('change')
}
// somethingWrong shows the "something went wrong" screen
function somethingWrong() {
$('#somethingwrong').show()
}
// Trigger initialization functions
$(() => {
initBinds()
hashLoad()
})

6785
src/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

20
src/package.json Normal file
View File

@ -0,0 +1,20 @@
{
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-env": "^1.7.0",
"css-loader": "^1.0.0",
"node-sass": "^4.9.2",
"sass-loader": "^7.0.3",
"style-loader": "^0.21.0",
"webpack": "^4.16.2",
"webpack-cli": "^3.1.0",
"webpack-dev-middleware": "^1.4.0",
"webpack-hot-middleware": "^2.9.1"
},
"name": "ots",
"private": true,
"scripts": {
"build": "webpack -p"
}
}

52
src/webpack.config.js Normal file
View File

@ -0,0 +1,52 @@
const path = require('path')
const webpack = require('webpack');
function resolve(dir) {
return path.join(__dirname, dir)
}
module.exports = {
entry: './app.js',
output: {
filename: 'app.js',
path: path.resolve(__dirname, '..', 'frontend')
},
plugins: [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
})
],
optimization: {
minimize: true
},
module: {
rules: [{
test: /\.(s?)css$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
],
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: [
['env', {
"targets": {
"browsers": [">0.25%", "not ie 11", "not op_mini all"]
}
}]
]
}
}
},
]
}
}