Compare commits

..

1 Commits

Author SHA1 Message Date
Ben Visness b0b863d134 A bunch of stupid junk that didn't work re: snippets
This was a pile of changes I made live on master that ultimately just
did not work at all. Don't program on 4 hours of sleep.

Handle a Not Found more gracefully in snippet code

I don't really know how this happens, but there's no reason to crash if
it happens.

Add example of disabling search engine indexing in beta

Fix incorrect varargs

I dunno change some snippet stuff

I'm so done with this

What if we didn't return for no reason

Actually parse the discord messages for tags

none of this is shippable. none of it

Final WIP
2021-12-14 20:52:52 -06:00
843 changed files with 5248 additions and 162157 deletions

9
.gitignore vendored
View File

@ -13,12 +13,3 @@ hmn.conf
adminmailer/config.go
adminmailer/adminmailer
local/backups
/tmp
*.exe
.DS_Store
# vim session saves
Session.vim
# tags files
tags

View File

@ -1,83 +0,0 @@
# Handmade Network
This is the codebase for the Handmade Network website, located online at https://handmade.network. The website is the home for all Handmade projects, the forums, the podcast, and other various initiatives.
The site is written in Go, and uses the standard library HTTP server with custom utilities for routing and middleware. It uses Postgres for its database, making heavy use of the excellent [pgx](https://github.com/jackc/pgx) library along with some custom wrappers. See the documentation in the `db` package for more details.
We want the website to be a great example of Handmade software on the web. We encourage you to read through the source, run it yourself, and learn from how we work. If you have questions about the code, or you're interested in contributing directly, reach out to us in #network-meta on the [Handmade Network Discord](https://discord.gg/hmn)!
## Prerequisites
You will need the following software installed:
- Go 1.18 or 1.19: https://go.dev/
You can download Go directly from the website, or install it through major package managers. If you already have Go installed, but are unsure of the version, you can check by running `go version`.
**PLEASE NOTE:** Go 1.20 currently does not work due to a bug in a third-party library. See [this issue](https://git.handmade.network/hmn/hmn/issues/59#issuecomment-1335).
- Postgres: https://www.postgresql.org/
Any Postgres installation should work fine, although less common distributions may not work as nicely with our scripts out of the box. On Mac, [Postgres.app](https://postgresapp.com/) is recommended.
## First-time setup
- **Configure the site.** Copy `src/config/config.go.example` to `src/config/config.go`:
```
# On Windows
copy src\config\config.go.example src\config\config.go
# On Mac and Linux
cp src/config/config.go.example src/config/config.go
```
Depending on your installation of Postgres, you may need to modify the hostname and port in the Postgres section of the config.
- **Set up the database.** Run `go run . db seed` to initialize the database and fill it with sample data.
- **Update your hosts file.** The website uses subdomains for official projects, so the site cannot simply be run off `localhost`. Add the following
line to your hosts file:
```
127.0.0.1 handmade.local hero.handmade.local 4coder.handmade.local
```
You may need to edit the hosts file again in the future if you add more official projects.
On Windows, the hosts file is located at `C:\Windows\System32\Drivers\etc\hosts`. On Mac and Linux, the hosts file should be located at `/etc/hosts`. It can be edited using any plain text editor, but you will need superuser permissions.
## Running the site
Running the site is easy:
```
go run .
```
You should now be able to visit http://handmade.local:9001 to see the website!
There are also several other commands built into the website executable. You can see documentation for each of them by running `go run . help` or adding the `-h` flag to any command.
## Running tests
Also easy:
```
go test ./...
```
Note that we have a special coverage requirement for the `hmnurl` package. We use the tests in this package to ensure that our URL builder functions never go out of sync with the regexes used for routing. As a result, we mandate 100% coverage for all `Build` functions in `hmnurl`.
## Starter data
The `db seed` command pre-populates the site with realistic data. It also includes several user accounts that you may log into to test various situations:
| Username | Password |
| -------- | -------- |
| `admin` | `password` |
| `alice` | `password` |
| `bob` | `password` |
| `charlie` | `password` |
The `admin` user is a superuser on the site and will have access to all features, as well as the special admin UI for performing site maintenance and moderation. The other users are all normal users.

View File

@ -4,7 +4,6 @@ const RecvAddress = "admin@example.com"
const RecvName = "Admin"
const FromName = "From Name"
const FromAddress = "from@address.com"
const ServerUsername = "username"
const ServerPassword = "password"
const FromAddressPassword = "password"
const ServerAddress = "server.address"
const ServerPort = 587

View File

@ -46,7 +46,7 @@ func sendMail(toAddress, toName, subject, contentHtml string) error {
)
return smtp.SendMail(
fmt.Sprintf("%s:%d", ServerAddress, ServerPort),
smtp.PlainAuth("", ServerUsername, ServerPassword, ServerAddress),
smtp.PlainAuth("", FromAddress, FromAddressPassword, ServerAddress),
FromAddress,
[]string{toAddress},
contents,

View File

@ -1 +0,0 @@
!.vscode

View File

@ -1,10 +0,0 @@
{
"Resource Link": {
"prefix": [
"hmn-link"
],
"body": [
"<a class=\"inserted-after\" href=\"$1\" target=\"_blank\">$TM_SELECTED_TEXT</a>"
]
}
}

View File

@ -1,65 +0,0 @@
- [ ] Export with [DiscordChatExporter](https://github.com/Tyrrrz/DiscordChatExporter) CLI 2.39.1
```
DiscordChatExporter.Cli.exe export -c [thread-id] -t [token] -o [fishbowl].html --media
```
- [ ] Rename `[fishbowl].html_Files` to `files`, replace links in html
- [ ] Add target="_blank" to links
```
(a href="[^"]+")>
$1 target="_blank">
```
- [ ] Add JQuery to `<head>`
```html
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
<script>
$( function() {
$( ".chatlog" ).sortable();
} );
</script>
```
- [ ] Drag/delete noise/edit in the browser
- [ ] Save as `[fishbowl]-dragged.html` (devtools -> `<html>` -> copy outerHTML)
- [ ] Remove JQuery, sortable classes
```
ui-sortable
ui-sortable-handle
```
- [ ] Check `#fishbowl-audience` for highlights
- [ ] Fix audience avatar paths if anything copied
- [ ] Fix bad pictures (composite emojis 404)
- [ ] Fix links with extra braces at the end
```
href="[^"]+\)"
```
- [ ] Fill in resource links with vscode snippet (select phrase, Ctrl+Shift+P -> Insert Snippet -> hmn-link, paste the url)
- [ ] Download twemojies
```
go run twemoji.go [fishbowl]-dragged.html files [fishbowl]-twemojied.html
```
- [ ] Fix timestamps, validate they look correct
```
go run timestamps.go [fishbowl]-twemojied.html [fishbowl]-timestamped.html
```
- [ ] Create a branch off latest `hmn` master
- [ ] Create fishbowl folder under `hmn/src/templates/src/fishbowls/`
- [ ] Copy timestamped html and files, rename html
- [ ] Remove everything from html but chatlog
- [ ] Remove js, css and ggsans from files
- [ ] Add content path to `fishbowl.go`
- [ ] Test locally
- [ ] Submit a pull request

View File

@ -1,45 +0,0 @@
package main
import (
"fmt"
"os"
"regexp"
"strconv"
"time"
)
func main() {
if len(os.Args) != 3 {
fmt.Println("Usage: go run timestamps.go <fishbowl>.html <fishbowl>-timestamped.html")
os.Exit(1)
}
htmlPath := os.Args[1]
htmlOutPath := os.Args[2]
htmlBytes, err := os.ReadFile(htmlPath)
if err != nil {
panic(err)
}
html := string(htmlBytes)
regex := regexp.MustCompile(
`(<span class="?chatlog__timestamp"?><a href=[^>]+>)(\d+)/(\d+)/(\d+)( [^<]+</a></span>)`,
)
htmlOut := regex.ReplaceAllStringFunc(html, func(s string) string {
match := regex.FindStringSubmatch(s)
month, err := strconv.ParseInt(match[2], 10, 64)
if err != nil {
panic(err)
}
monthStr := time.Month(month).String()
return fmt.Sprintf("%s%s %s, %s%s", match[1], monthStr, match[3], match[4], match[5])
})
err = os.WriteFile(htmlOutPath, []byte(htmlOut), 0666)
if err != nil {
panic(err)
}
}

View File

@ -1,77 +0,0 @@
package main
import (
"fmt"
"io"
"net/http"
"os"
"path"
"strings"
)
func main() {
if len(os.Args) != 4 {
fmt.Println("Usage: go run twemoji.go [fishbowl].html files [fishbowl]-twemojied.html")
os.Exit(1)
}
htmlPath := os.Args[1]
filesDir := os.Args[2]
htmlOutPath := os.Args[3]
htmlBytes, err := os.ReadFile(htmlPath)
if err != nil {
panic(err)
}
html := string(htmlBytes)
for {
linkStart := strings.Index(html, "https://twemoji.maxcdn.com/")
if linkStart == -1 {
break
}
linkEnd := strings.Index(html[linkStart:], "\"") + linkStart
link := html[linkStart:linkEnd]
emojiFilenameStart := strings.LastIndex(link, "/") + 1
emojiFilename := "twemoji_" + link[emojiFilenameStart:]
emojiPath := path.Join(filesDir, emojiFilename)
emojiResponse, err := http.Get(link)
if err != nil {
panic(err)
}
defer emojiResponse.Body.Close()
if emojiResponse.StatusCode > 299 {
panic("Non-200 status code: " + fmt.Sprint(emojiResponse.StatusCode))
}
emojiFile, err := os.Create(emojiPath)
if err != nil {
panic(err)
}
defer emojiFile.Close()
_, err = io.Copy(emojiFile, emojiResponse.Body)
if err != nil {
panic(err)
}
html = strings.ReplaceAll(html, link, emojiPath)
fmt.Println(emojiFilename)
}
html = strings.ReplaceAll(
html,
"<div class=\"chatlog\">",
"<div class=\"chatlog\">\n<!-- Emojis by Twitter's Twemoji https://twemoji.twitter.com/ -->",
)
err = os.WriteFile(htmlOutPath, []byte(html), 0666)
if err != nil {
panic(err)
}
}

58
go.mod
View File

@ -1,9 +1,10 @@
module git.handmade.network/hmn/hmn
go 1.18
go 1.16
require (
github.com/HandmadeNetwork/golorem v0.0.0-20220507185207-414965a3a817
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Masterminds/sprig v2.22.0+incompatible
github.com/alecthomas/chroma v0.9.2
github.com/aws/aws-sdk-go-v2 v1.8.1
@ -11,60 +12,27 @@ require (
github.com/aws/aws-sdk-go-v2/credentials v1.3.3
github.com/aws/aws-sdk-go-v2/service/s3 v1.13.0
github.com/aws/smithy-go v1.7.0
github.com/emersion/go-ical v0.0.0-20220601085725-0864dccc089f
github.com/frustra/bbcode v0.0.0-20201127003707-6ef347fbe1c8
github.com/go-stack/stack v1.8.0
github.com/google/uuid v1.2.0
github.com/gorilla/websocket v1.4.2
github.com/jackc/pgx-zerolog v0.0.0-20220923130014-7856b90a65ae
github.com/jackc/pgx/v5 v5.2.0
github.com/huandu/xstrings v1.3.2 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/jackc/pgconn v1.8.0
github.com/jackc/pgtype v1.6.2
github.com/jackc/pgx/v4 v4.10.1
github.com/jpillora/backoff v1.0.0
github.com/rs/zerolog v1.28.0
github.com/mitchellh/copystructure v1.1.1 // indirect
github.com/rs/zerolog v1.21.0
github.com/spf13/cobra v1.1.3
github.com/stretchr/testify v1.8.1
github.com/stretchr/testify v1.7.0
github.com/tcolgate/mp3 v0.0.0-20170426193717-e79c5a46d300
github.com/teacat/noire v1.1.0
github.com/wellington/go-libsass v0.9.2
github.com/yuin/goldmark v1.4.13
github.com/yuin/goldmark v1.4.1
github.com/yuin/goldmark-highlighting v0.0.0-20210516132338-9216f9c5aa01
golang.org/x/crypto v0.6.0
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d
mvdan.cc/xurls/v2 v2.4.0
)
require (
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.4.1 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.2.1 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.2.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.2.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.5.3 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.3.3 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.6.2 // indirect
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/huandu/xstrings v1.3.2 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/puddle/v2 v2.1.2 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mitchellh/copystructure v1.1.1 // indirect
github.com/mitchellh/reflectwalk v1.0.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/teambition/rrule-go v1.7.2 // indirect
go.uber.org/atomic v1.10.0 // indirect
golang.org/x/net v0.6.0 // indirect
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace (

194
go.sum
View File

@ -15,8 +15,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/HandmadeNetwork/bbcode v0.0.0-20210623031351-ec0e2e2e39d9 h1:5WhEr56CD1uWDPcDIIa+UtNPPlJCoNJ3u38Rk+4XIks=
github.com/HandmadeNetwork/bbcode v0.0.0-20210623031351-ec0e2e2e39d9/go.mod h1:vMiNHD8absjmnO60Do5KCaJBwdbaiI/AzhMmSipMme4=
github.com/HandmadeNetwork/golorem v0.0.0-20220507185207-414965a3a817 h1:cBqVP/sLiK7DPay7Aac1PRUwu3fCVyL5Wc+xLXzqwkE=
github.com/HandmadeNetwork/golorem v0.0.0-20220507185207-414965a3a817/go.mod h1:doKbGBIdiM1nkEfvAeP5hvUmERah9H6StTVfCverqdE=
github.com/HandmadeNetwork/goldmark v1.4.1-0.20210707024600-f7e596e26b5e h1:z0GlF2OMmy852mrcMVpjZIzEHYCbUweS8RaWRCPfL1g=
github.com/HandmadeNetwork/goldmark v1.4.1-0.20210707024600-f7e596e26b5e/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
@ -70,13 +70,16 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -88,8 +91,6 @@ github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55k
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/emersion/go-ical v0.0.0-20220601085725-0864dccc089f h1:feGUUxxvOtWVOhTko8Cbmp33a+tU0IMZxMEmnkoAISQ=
github.com/emersion/go-ical v0.0.0-20220601085725-0864dccc089f/go.mod h1:2MKFUgfNMULRxqZkadG1Vh44we3y5gJAtTBlVsx1BKQ=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@ -99,7 +100,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@ -157,16 +159,59 @@ github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk=
github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
github.com/jackc/pgconn v1.8.0 h1:FmjZ0rOyXTr1wfWs45i4a9vjnjWUAGpMuQLD9OSs+lw=
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 h1:JVX6jT/XfzNqIjye4717ITLaNwV9mWbJx0dLCpcRzdA=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx-zerolog v0.0.0-20220923130014-7856b90a65ae h1:s/r/bBI1EUCZvGtoJ/Ow6WPUYe08V9VpQY3fv6eq99s=
github.com/jackc/pgx-zerolog v0.0.0-20220923130014-7856b90a65ae/go.mod h1:CRUuPsmIajLt3dZIlJ5+O8IDSib6y8yrst8DkCthTa4=
github.com/jackc/pgx/v5 v5.2.0 h1:NdPpngX0Y6z6XDFKqmFQaE+bCtkqzvQIOt1wvBlAqs8=
github.com/jackc/pgx/v5 v5.2.0/go.mod h1:Ptn7zmohNsWEsdxRawMzk3gaKma2obW+NWTnKa0S4nk=
github.com/jackc/puddle/v2 v2.1.2 h1:0f7vaaXINONKTsxYDn4otOAiJanX/BMeAtY//BXqzlg=
github.com/jackc/puddle/v2 v2.1.2/go.mod h1:2lpufsF5mRHO6SuZkm0fNYxM6SWHfvyFj62KwNzgels=
github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgproto3/v2 v2.0.6 h1:b1105ZGEMFe7aCvrT1Cca3VoVb4ZFMaFJLJcg/3zD+8=
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0=
github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po=
github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ=
github.com/jackc/pgtype v1.6.2 h1:b3pDeuhbbzBYcg5kwNmNDun4pFUD/0AAr1kLXZLeNt8=
github.com/jackc/pgtype v1.6.2/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig=
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA=
github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o=
github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg=
github.com/jackc/pgx/v4 v4.10.1 h1:/6Q3ye4myIj6AaplUm+eRcz4OhK9HAvFf4ePsG40LJY=
github.com/jackc/pgx/v4 v4.10.1/go.mod h1:QlrWebbs3kqEZPHCTGyxecvzG6tvIsYu+A5b1raylkA=
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.3 h1:JnPg/5Q9xVJGfjsO5CPUOjnJps1JaRUm8I9FXVCFK94=
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
@ -179,24 +224,32 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
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/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
@ -217,9 +270,9 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@ -235,18 +288,24 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/rs/zerolog v1.21.0 h1:Q3vdXlfLNT+OftyBHsU0Y445MD+8m8axjKgf2si0QcM=
github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc h1:jUIKcSPO9MoMJBbEoyE/RJoE8vz7Mb8AjvifMMwSyvY=
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@ -262,47 +321,52 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tcolgate/mp3 v0.0.0-20170426193717-e79c5a46d300 h1:XQdibLKagjdevRB6vAjVY4qbSr8rQ610YzTkWcxzxSI=
github.com/tcolgate/mp3 v0.0.0-20170426193717-e79c5a46d300/go.mod h1:FNa/dfN95vAYCNFrIKRrlRo+MBLbwmR9Asa5f2ljmBI=
github.com/teacat/noire v1.1.0 h1:5IgJ1H8jodiSSYnrVadV2JjbAnEgCCjYUQxSUuaQ7Sg=
github.com/teacat/noire v1.1.0/go.mod h1:cetGlnqr+9yKJcFgRgYXOWJY66XIrrjUsGBwNlNNtAk=
github.com/teambition/rrule-go v1.7.2 h1:goEajFWYydfCgavn2m/3w5U+1b3PGqPUHx/fFSVfTy0=
github.com/teambition/rrule-go v1.7.2/go.mod h1:mBJ1Ht5uboJ6jexKdNUJg2NcwP8uUMNvStWXlJD3MvU=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/wellington/go-libsass v0.9.2 h1:6Ims04UDdBs6/CGSVK5JC8FNikR5ssrsMMKE/uaO5Q8=
github.com/wellington/go-libsass v0.9.2/go.mod h1:mxgxgam0N0E+NAUMHLcu20Ccfc3mVpDkyrLDayqfiTs=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.6/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark-highlighting v0.0.0-20210516132338-9216f9c5aa01 h1:0SJnXjE4jDClMW6grE0xpNhwpqbPwkBTn8zpVw5C0SI=
github.com/yuin/goldmark-highlighting v0.0.0-20210516132338-9216f9c5aa01/go.mod h1:TwKQPa5XkCCRC2GRZ5wtfNUTQ2+9/i19mGRijFeJ4BE=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -323,6 +387,7 @@ golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -337,8 +402,10 @@ golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -347,9 +414,7 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc=
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -358,26 +423,31 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -389,15 +459,24 @@ golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -424,25 +503,24 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
mvdan.cc/xurls/v2 v2.4.0 h1:tzxjVAj+wSBmDcF6zBB7/myTy3gX9xvi8Tyr28AuQgc=
mvdan.cc/xurls/v2 v2.4.0/go.mod h1:+GEjq9uNjqs8LQfM9nVnM8rff0OQ5Iash5rzX+N1CSg=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=

View File

@ -1,20 +0,0 @@
#!/usr/bin/env python3
import boto3
# You must already have configured your "AWS" (DigitalOcean) credentials via the AWS CLI.
s3 = boto3.resource("s3")
bucket = s3.Bucket("hmn-backup")
for obj in bucket.objects.filter(Prefix="db"):
print(obj.key)
print()
print("Above is a list of all the available database backups.")
print("Enter the name of the one you would like to download (e.g. \"hmn_pg_dump_live_2023-09-24\"):")
filename = input()
s3 = boto3.client("s3")
s3.download_file("hmn-backup", f"db/{filename}", f"local/backups/{filename}")
print(f"Downloaded {filename} to local/backups.")

15
local/download_database.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
set -euo pipefail
s3cmd ls s3://hmn-backup/db/
echo ""
echo "Above is a list of all the available database backups."
echo "Enter the name of the one you would like to download (e.g. \"hmn_pg_dump_live_2021-09-01\"):"
read filename
s3cmd get --force s3://hmn-backup/db/$filename ./local/backups/$filename
echo ""
echo "Downloaded $filename to local/backups."

View File

@ -1 +0,0 @@
boto3

23
local/resetdb.sh Executable file
View File

@ -0,0 +1,23 @@
#!/bin/bash
set -euxo pipefail
# This script is for use in local development only. It wipes the existing db,
# creates a new empty one, runs the initial migration to create the schema,
# and then imports actual db content on top of that.
# TODO(opensource): We should adapt Asaf's seedfile command and then delete this.
THIS_PATH=$(pwd)
BETA_PATH='/mnt/c/Users/bvisn/Developer/handmade/handmade-beta'
# BETA_PATH='/Users/benvisness/Developer/handmade/handmade-beta'
pushd $BETA_PATH
docker-compose down -v
docker-compose up -d postgres s3
sleep 3
docker-compose exec postgres bash -c "psql -U postgres -c \"CREATE ROLE hmn CREATEDB LOGIN PASSWORD 'password';\""
popd
go run src/main.go seedfile local/backups/hmn_pg_dump_live_2021-11-14
# go run src/main.go seedfile local/backups/hmn_pg_dump_live_2021-10-23

15
main.go
View File

@ -1,15 +0,0 @@
package main
import (
_ "git.handmade.network/hmn/hmn/src/admintools"
_ "git.handmade.network/hmn/hmn/src/assets"
_ "git.handmade.network/hmn/hmn/src/buildscss"
_ "git.handmade.network/hmn/hmn/src/discord/cmd"
_ "git.handmade.network/hmn/hmn/src/initimage"
_ "git.handmade.network/hmn/hmn/src/migration"
"git.handmade.network/hmn/hmn/src/website"
)
func main() {
website.WebsiteCommand.Execute()
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 28 KiB

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 256 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(0.402516,0,0,0.410256,60.3774,109.538)">
<rect x="-150" y="-267" width="636" height="117" style="fill:rgb(88,101,242);"/>
</g>
<g transform="matrix(0.266745,0,0,0.266745,60.1574,11.1482)">
<g id="图层_2">
<g id="Discord_Logos">
<g id="Discord_Logo_-_Large_-_White">
<path d="M170.85,20.2L198.15,20.2C204.73,20.2 210.297,21.227 214.85,23.28C219.042,25.042 222.602,28.034 225.06,31.86C227.361,35.639 228.54,39.996 228.46,44.42C228.511,48.864 227.285,53.231 224.93,57C222.303,60.982 218.545,64.088 214.14,65.92C209.313,68.12 203.33,69.217 196.19,69.21L170.85,69.21L170.85,20.2ZM195.91,56.74C200.343,56.74 203.75,55.633 206.13,53.42C208.57,51.054 209.873,47.745 209.7,44.35C209.85,41.202 208.699,38.127 206.52,35.85C204.387,33.73 201.177,32.667 196.89,32.66L188.35,32.66L188.35,56.74L195.91,56.74Z" style="fill:white;fill-rule:nonzero;"/>
<path d="M269.34,69.13C265.738,68.228 262.293,66.788 259.12,64.86L259.12,53.24C261.89,55.255 265.009,56.74 268.32,57.62C271.942,58.725 275.704,59.301 279.49,59.33C280.797,59.4 282.102,59.174 283.31,58.67C284.17,58.23 284.6,57.67 284.6,57.09C284.619,56.435 284.365,55.801 283.9,55.34C283.101,54.726 282.164,54.317 281.17,54.15L272.77,52.26C267.957,51.14 264.54,49.59 262.52,47.61C260.471,45.543 259.381,42.707 259.52,39.8C259.486,37.194 260.437,34.668 262.18,32.73C264.248,30.543 266.855,28.939 269.74,28.08C273.452,26.913 277.329,26.356 281.22,26.43C284.852,26.396 288.474,26.819 292,27.69C294.848,28.365 297.583,29.449 300.12,30.91L300.12,41.91C297.741,40.53 295.184,39.483 292.52,38.8C289.634,38.026 286.658,37.636 283.67,37.64C279.283,37.64 277.09,38.387 277.09,39.88C277.075,40.559 277.47,41.183 278.09,41.46C279.289,41.97 280.544,42.332 281.83,42.54L288.83,43.8C293.377,44.6 296.767,46 299,48C301.233,50 302.353,52.927 302.36,56.78C302.432,60.898 300.308,64.758 296.79,66.9C293.103,69.373 287.84,70.607 281,70.6C277.067,70.606 273.149,70.112 269.34,69.13Z" style="fill:white;fill-rule:nonzero;"/>
<path d="M318.9,67.66C315.158,65.941 312.003,63.158 309.83,59.66C307.803,56.23 306.764,52.304 306.83,48.32C306.77,44.338 307.864,40.423 309.98,37.05C312.235,33.607 315.447,30.896 319.22,29.25C323.807,27.251 328.778,26.282 333.78,26.41C340.78,26.41 346.59,27.88 351.21,30.82L351.21,43.65C349.452,42.468 347.532,41.549 345.51,40.92C343.246,40.205 340.884,39.851 338.51,39.87C334.17,39.87 330.773,40.663 328.32,42.25C326.06,43.511 324.655,45.905 324.655,48.493C324.655,51.041 326.016,53.403 328.22,54.68C330.6,56.287 334.053,57.09 338.58,57.09C340.916,57.096 343.241,56.759 345.48,56.09C347.522,55.504 349.484,54.668 351.32,53.6L351.32,66C345.91,69.154 339.731,70.754 333.47,70.62C328.451,70.757 323.467,69.744 318.9,67.66Z" style="fill:white;fill-rule:nonzero;"/>
<path d="M368.64,67.66C364.856,65.932 361.645,63.155 359.39,59.66C357.265,56.238 356.161,52.278 356.21,48.25C356.142,44.27 357.248,40.356 359.39,37C361.657,33.594 364.854,30.907 368.6,29.26C377.799,25.528 388.101,25.528 397.3,29.26C401.031,30.894 404.215,33.568 406.47,36.96C408.597,40.328 409.693,44.247 409.62,48.23C409.67,52.254 408.577,56.211 406.47,59.64C404.239,63.138 401.044,65.917 397.27,67.64C388.133,71.558 377.777,71.558 368.64,67.64L368.64,67.66ZM389.91,55.24C391.657,53.436 392.584,50.989 392.47,48.48C392.592,45.994 391.662,43.568 389.91,41.8C388.01,40.058 385.483,39.159 382.91,39.31C380.339,39.175 377.818,40.072 375.91,41.8C374.164,43.571 373.239,45.996 373.36,48.48C373.247,50.987 374.169,53.433 375.91,55.24C377.8,57.004 380.328,57.925 382.91,57.79C385.494,57.94 388.028,57.017 389.91,55.24Z" style="fill:white;fill-rule:nonzero;"/>
<path d="M451.69,29L451.69,44.14C449.6,42.893 447.191,42.285 444.76,42.39C441.03,42.39 438.15,43.53 436.15,45.79C434.15,48.05 433.15,51.56 433.15,56.32L433.15,69.2L416,69.2L416,28.25L432.8,28.25L432.8,41.25C433.733,36.49 435.24,32.98 437.32,30.72C439.36,28.472 442.286,27.228 445.32,27.32C447.56,27.259 449.771,27.842 451.69,29Z" style="fill:white;fill-rule:nonzero;"/>
<path d="M508.67,18.8L508.67,69.2L491.52,69.2L491.52,60C490.227,63.275 487.903,66.041 484.9,67.88C481.585,69.769 477.814,70.71 474,70.6C470.411,70.684 466.878,69.698 463.85,67.77C460.918,65.865 458.581,63.172 457.11,60C455.504,56.499 454.705,52.681 454.77,48.83C454.657,44.837 455.508,40.875 457.25,37.28C458.851,33.988 461.351,31.214 464.46,29.28C467.656,27.344 471.334,26.349 475.07,26.41C483.23,26.41 488.713,29.957 491.52,37.05L491.52,18.8L508.67,18.8ZM489,55C490.766,53.261 491.722,50.857 491.63,48.38C491.705,45.976 490.747,43.652 489,42C484.971,38.719 479.139,38.719 475.11,42C473.368,43.69 472.425,46.045 472.52,48.47C472.431,50.918 473.384,53.292 475.14,55C476.995,56.725 479.47,57.63 482,57.51C484.575,57.652 487.102,56.746 489,55Z" style="fill:white;fill-rule:nonzero;"/>
<path d="M107.7,8.07C99.347,4.246 90.528,1.533 81.47,0C80.23,2.216 79.109,4.496 78.11,6.83C68.461,5.376 58.649,5.376 49,6.83C48.001,4.496 46.879,2.216 45.64,-0C36.576,1.546 27.752,4.265 19.39,8.09C2.79,32.65 -1.71,56.6 0.54,80.21C10.261,87.392 21.143,92.855 32.71,96.36C35.315,92.857 37.62,89.14 39.6,85.25C35.838,83.845 32.208,82.112 28.75,80.07C29.66,79.41 30.55,78.73 31.41,78.07C51.768,87.644 75.372,87.644 95.73,78.07C96.6,78.78 97.49,79.46 98.39,80.07C94.926,82.115 91.288,83.852 87.52,85.26C89.498,89.149 91.803,92.862 94.41,96.36C105.987,92.869 116.877,87.409 126.6,80.22C129.24,52.84 122.09,29.11 107.7,8.07ZM42.45,65.69C36.18,65.69 31,60 31,53C31,46 36,40.26 42.43,40.26C48.86,40.26 54,46 53.89,53C53.78,60 48.84,65.69 42.45,65.69ZM84.69,65.69C78.41,65.69 73.25,60 73.25,53C73.25,46 78.25,40.26 84.69,40.26C91.13,40.26 96.23,46 96.12,53C96.01,60 91.08,65.69 84.69,65.69Z" style="fill:white;fill-rule:nonzero;"/>
<ellipse cx="242.92" cy="24.93" rx="8.55" ry="7.68" style="fill:white;"/>
<path d="M234.36,37.9C239.829,40.199 246.001,40.199 251.47,37.9L251.47,69.42L234.36,69.42L234.36,37.9Z" style="fill:white;fill-rule:nonzero;"/>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,626 +0,0 @@
.fishbowl {
background-color: #36393e;
color: #dcddde;
}
.fishbowl a {
color: #00aff4;
text-decoration: none;
}
.fishbowl a:hover {
text-decoration: underline;
}
.fishbowl img {
object-fit: contain;
image-rendering: high-quality;
image-rendering: -webkit-optimize-contrast;
}
.fishbowl .preamble {
display: grid;
grid-template-columns: auto 1fr;
max-width: 100%;
padding: 1rem;
}
.fishbowl .preamble__guild-icon-container {
grid-column: 1;
}
.fishbowl .preamble__guild-icon {
max-width: 88px;
max-height: 88px;
}
.fishbowl .preamble__entries-container {
grid-column: 2;
margin-left: 1rem;
}
.fishbowl .preamble__entry {
margin-bottom: 0.15rem;
color: #ffffff;
font-size: 1.4rem;
}
.fishbowl .preamble__entry--small {
font-size: 1rem;
}
.fishbowl .chatlog {
padding: 1rem 0;
width: 100%;
}
.fishbowl .chatlog__message-group {
margin-bottom: 1rem;
}
.fishbowl .chatlog__message-container {
background-color: transparent;
transition: background-color 1s ease;
}
.fishbowl .chatlog__message-container--highlighted {
background-color: rgba(114, 137, 218, 0.2);
}
.fishbowl .chatlog__message-container--pinned {
background-color: rgba(249, 168, 37, 0.05);
}
.fishbowl .chatlog__message {
display: grid;
grid-template-columns: auto 1fr;
padding: 0.15rem 0;
direction: ltr;
unicode-bidi: bidi-override;
}
.fishbowl .chatlog__message:hover {
background-color: #32353b;
}
.fishbowl .chatlog__message:hover .chatlog__short-timestamp {
display: block;
}
.fishbowl .chatlog__message-aside {
grid-column: 1;
width: 72px;
padding: 0.15rem 0.15rem 0 0.15rem;
text-align: center;
}
.fishbowl .chatlog__reference-symbol, .fishbowl .chatlog__reply-symbol {
height: 10px;
margin: 6px 4px 4px 36px;
border-left: 2px solid #4f545c;
border-top: 2px solid #4f545c;
border-radius: 8px 0 0 0;
}
.fishbowl .chatlog__avatar {
width: 40px;
height: 40px;
border-radius: 50%;
}
.fishbowl .chatlog__short-timestamp {
display: none;
color: #a3a6aa;
font-size: 0.7em;
line-height: 1.4em;
direction: ltr;
unicode-bidi: bidi-override;
}
.fishbowl .chatlog__message-primary {
grid-column: 2;
min-width: 0;
}
.fishbowl .chatlog__reference, .fishbowl .chatlog__reply {
display: flex;
margin-bottom: 0.15rem;
align-items: center;
color: #b5b6b8;
font-size: 0.85em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.fishbowl .chatlog__reference-avatar, .fishbowl .chatlog__reply-avatar {
width: 16px;
height: 16px;
margin-right: 0.25rem;
border-radius: 50%;
}
.fishbowl .chatlog__reference-author, .fishbowl .chatlog__reply-author {
margin-right: 0.3rem;
font-weight: 600;
}
.fishbowl .chatlog__reference-content, .fishbowl .chatlog__reply-content {
overflow: hidden;
text-overflow: ellipsis;
}
.fishbowl .chatlog__reference-link, .fishbowl .chatlog__reply-link {
cursor: pointer;
}
.fishbowl .chatlog__reference-link *, .fishbowl .chatlog__reply-link * {
display: inline;
pointer-events: none;
}
.fishbowl .chatlog__reference-link .hljs, .fishbowl .chatlog__reply-link .hljs {
display: inline;
}
.fishbowl .chatlog__reference-link .chatlog__markdown-quote, .fishbowl .chatlog__reply-link .chatlog__markdown-quote {
display: inline
}
.fishbowl .chatlog__reference-link .chatlog__markdown-pre, .fishbowl .chatlog__reply-link .chatlog__markdown-pre {
display: inline
}
.fishbowl .chatlog__reference-link:hover, .fishbowl .chatlog__reply-link:hover {
color: #ffffff;
}
.fishbowl .chatlog__reference-link:hover *:not(.chatlog__markdown-spoiler), .fishbowl .chatlog__reply-link:hover *:not(.chatlog__markdown-spoiler) {
color: inherit;
}
.fishbowl .chatlog__reference-edited-timestamp, .fishbowl .chatlog__reply-edited-timestamp {
margin-left: 0.25rem;
color: #a3a6aa;
font-size: 0.75rem;
font-weight: 500;
direction: ltr;
unicode-bidi: bidi-override;
}
.fishbowl .chatlog__header {
margin-bottom: 0.1rem;
}
.fishbowl .chatlog__author {
font-weight: 500;
color: #ffffff;
}
.fishbowl .chatlog__bot-label {
position: relative;
top: -0.1rem;
margin-left: 0.3rem;
padding: 0.05rem 0.3rem;
border-radius: 3px;
background-color: #5865F2;
color: #ffffff;
font-size: 0.625rem;
font-weight: 500;
line-height: 1.3;
}
.fishbowl .chatlog__timestamp {
margin-left: 0.3rem;
color: #a3a6aa;
font-size: 0.75rem;
direction: ltr;
unicode-bidi: bidi-override;
}
.fishbowl .chatlog__content {
padding-right: 1rem;
word-wrap: break-word;
}
.fishbowl .chatlog__edited-timestamp {
margin-left: 0.15rem;
color: #a3a6aa;
font-size: 0.7em;
}
.fishbowl .chatlog__attachment {
position: relative;
width: fit-content;
margin-top: 0.3rem;
border-radius: 3px;
overflow: hidden;
}
.fishbowl .chatlog__attachment--hidden {
cursor: pointer;
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.1);
}
.fishbowl .chatlog__attachment--hidden * {
pointer-events: none;
}
.fishbowl .chatlog__attachment-spoiler-caption {
display: none;
position: absolute;
left: 50%;
top: 50%;
z-index: 999;
padding: 0.4rem 0.8rem;
border-radius: 20px;
transform: translate(-50%, -50%);
background-color: rgba(0, 0, 0, 0.9);
color: #dcddde;
font-size: 0.9rem;
font-weight: 600;
letter-spacing: 0.05rem;
}
.fishbowl .chatlog__attachment--hidden .chatlog__attachment-spoiler-caption {
display: block;
}
.fishbowl .chatlog__attachment--hidden:hover .chatlog__attachment-spoiler-caption {
color: #fff;
}
.fishbowl .chatlog__attachment-media {
max-width: 500px;
max-height: 400px;
vertical-align: top;
border-radius: 3px;
}
.fishbowl .chatlog__attachment--hidden .chatlog__attachment-media {
filter: blur(44px);
}
.fishbowl .chatlog__attachment-generic {
max-width: 520px;
width: 100%;
height: 40px;
padding: 10px;
border: 1px solid #292b2f;
border-radius: 3px;
background-color: #2f3136;
overflow: hidden;
}
.fishbowl .chatlog__attachment--hidden .chatlog__attachment-generic {
filter: blur(44px);
}
.fishbowl .chatlog__attachment-generic-icon {
float: left;
width: 30px;
height: 100%;
margin-right: 10px;
}
.fishbowl .chatlog__attachment-generic-size {
color: #72767d;
font-size: 12px;
}
.fishbowl .chatlog__attachment-generic-name {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.fishbowl .chatlog__embed {
display: flex;
margin-top: 0.3rem;
max-width: 520px;
}
.fishbowl .chatlog__embed-color-pill {
flex-shrink: 0;
width: 0.25rem;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
.fishbowl .chatlog__embed-color-pill--default {
background-color: #202225;
}
.fishbowl .chatlog__embed-content-container {
display: flex;
flex-direction: column;
padding: 0.5rem 0.6rem;
border: 1px solid rgba(46, 48, 54, 0.6);
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
background-color: rgba(46, 48, 54, 0.3);
}
.fishbowl .chatlog__embed-content {
display: flex;
width: 100%;
}
.fishbowl .chatlog__embed-text {
flex: 1;
}
.fishbowl .chatlog__embed-author-container {
display: flex;
margin-bottom: 0.5rem;
align-items: center;
}
.fishbowl .chatlog__embed-author-icon {
width: 20px;
height: 20px;
margin-right: 0.5rem;
border-radius: 50%;
}
.fishbowl .chatlog__embed-author {
color: #ffffff;
font-size: 0.875rem;
font-weight: 600;
direction: ltr;
unicode-bidi: bidi-override;
}
.fishbowl .chatlog__embed-author-link {
color: #ffffff;
}
.fishbowl .chatlog__embed-title {
margin-bottom: 0.5rem;
color: #ffffff;
font-size: 0.875rem;
font-weight: 600;
}
.fishbowl .chatlog__embed-description {
color: #dcddde;
font-weight: 500;
font-size: 0.85rem;
}
.fishbowl .chatlog__embed-fields {
display: flex;
flex-wrap: wrap;
gap: 0 0.5rem;
}
.fishbowl .chatlog__embed-field {
flex: 0;
min-width: 100%;
max-width: 506px;
padding-top: 0.6rem;
font-size: 0.875rem;
}
.fishbowl .chatlog__embed-field--inline {
flex: 1;
flex-basis: auto;
min-width: 50px;
}
.fishbowl .chatlog__embed-field-name {
margin-bottom: 0.2rem;
color: #ffffff;
font-weight: 600;
}
.fishbowl .chatlog__embed-field-value {
color: #dcddde;
font-weight: 500;
}
.fishbowl .chatlog__embed-thumbnail {
flex: 0;
max-width: 80px;
max-height: 80px;
margin-left: 1.2rem;
border-radius: 3px;
}
.fishbowl .chatlog__embed-image-container {
margin-top: 0.6rem;
}
.fishbowl .chatlog__embed-image {
max-width: 500px;
max-height: 400px;
border-radius: 3px;
}
.fishbowl .chatlog__embed-footer {
margin-top: 0.6rem;
color: #dcddde;
}
.fishbowl .chatlog__embed-footer-icon {
width: 20px;
height: 20px;
margin-right: 0.2rem;
border-radius: 50%;
vertical-align: middle;
}
.fishbowl .chatlog__embed-footer-text {
vertical-align: middle;
font-size: 0.75rem;
font-weight: 500;
}
.fishbowl .chatlog__embed-plainimage {
max-width: 45vw;
max-height: 500px;
vertical-align: top;
border-radius: 3px;
}
.fishbowl .chatlog__embed-spotify {
border: 0;
}
.fishbowl .chatlog__embed-youtube-container {
margin-top: 0.6rem;
}
.fishbowl .chatlog__embed-youtube {
border: 0;
border-radius: 3px;
}
.fishbowl .chatlog__sticker {
width: 180px;
height: 180px;
}
.fishbowl .chatlog__sticker--media {
max-width: 100%;
max-height: 100%;
}
.fishbowl .chatlog__reactions {
display: flex;
}
.fishbowl .chatlog__reaction {
display: flex;
margin: 0.35rem 0.1rem 0.1rem 0;
padding: 0.125rem 0.375rem;
border: 1px solid transparent;
border-radius: 8px;
background-color: #2f3136;
align-items: center;
}
.fishbowl .chatlog__reaction:hover {
border: 1px solid hsla(0,0%,100%,.2);
background-color: transparent;
}
.fishbowl .chatlog__reaction-count {
min-width: 9px;
margin-left: 0.35rem;
color: #b9bbbe;
font-size: 0.875rem;
}
.fishbowl .chatlog__reaction:hover .chatlog__reaction-count {
color: #dcddde;
}
.fishbowl .chatlog__markdown {
max-width: 100%;
line-height: 1.3;
overflow-wrap: break-word;
}
.fishbowl .chatlog__markdown-preserve {
white-space: pre-wrap;
}
.fishbowl .chatlog__markdown-spoiler {
background-color: rgba(255, 255, 255, 0.1);
border-radius: 3px;
}
.fishbowl .chatlog__markdown-spoiler--hidden {
cursor: pointer;
background-color: #202225;
color: rgba(0, 0, 0, 0);
}
.fishbowl .chatlog__markdown-spoiler--hidden:hover {
background-color: rgba(32, 34, 37, 0.8);
}
.fishbowl .chatlog__markdown-spoiler--hidden::selection {
color: rgba(0, 0, 0, 0);
}
.fishbowl .chatlog__markdown-quote {
display: flex;
margin: 0.05rem 0;
}
.fishbowl .chatlog__markdown-quote-border {
margin-right: 0.5rem;
border: 2px solid #4f545c;
border-radius: 3px;
background-color: #4f545c;
}
.fishbowl .chatlog__markdown-pre {
background-color: #2f3136;
font-family: "Consolas", "Courier New", Courier, monospace;
}
.fishbowl .chatlog__markdown-pre--multiline {
margin-top: 0.25rem;
padding: 0.5rem;
border: 2px solid #282b30;
border-radius: 5px;
color: #b9bbbe;
}
.fishbowl .chatlog__markdown-pre--multiline.hljs {
background-color: inherit;
color: inherit;
}
.fishbowl .chatlog__markdown-pre--inline {
padding: 2px;
border-radius: 3px;
font-size: 0.85rem;
}
.fishbowl .chatlog__markdown-mention {
border-radius: 3px;
padding: 0 2px;
background-color: rgba(88, 101, 242, .3);
color: #dee0fc;
font-weight: 500;
}
.fishbowl .chatlog__markdown-mention:hover {
background-color: #5865f2;
color: #ffffff
}
.fishbowl .chatlog__markdown-timestamp {
border-radius: 3px;
padding: 0 2px;
color: #a3a6aa;
}
.fishbowl .chatlog__emoji {
width: 1.325rem;
height: 1.325rem;
margin: 0 0.06rem;
vertical-align: -0.4rem;
}
.fishbowl .chatlog__emoji--small {
width: 1rem;
height: 1rem;
}
.fishbowl .chatlog__emoji--large {
width: 2.8rem;
height: 2.8rem;
}
.fishbowl .postamble {
padding: 1.25rem;
}
.fishbowl .postamble__entry {
color: #ffffff;
}

View File

@ -1,627 +0,0 @@
.fishbowl {
background-color: #ffffff;
color: #23262a;
border: 1px solid #ddd;
}
.fishbowl a {
color: #0068e0;
text-decoration: none;
}
.fishbowl a:hover {
text-decoration: underline;
}
.fishbowl img {
object-fit: contain;
image-rendering: high-quality;
image-rendering: -webkit-optimize-contrast;
}
.fishbowl .preamble {
display: grid;
grid-template-columns: auto 1fr;
max-width: 100%;
padding: 1rem;
}
.fishbowl .preamble__guild-icon-container {
grid-column: 1;
}
.fishbowl .preamble__guild-icon {
max-width: 88px;
max-height: 88px;
}
.fishbowl .preamble__entries-container {
grid-column: 2;
margin-left: 1rem;
}
.fishbowl .preamble__entry {
margin-bottom: 0.15rem;
color: #2f3136;
font-size: 1.4rem;
}
.fishbowl .preamble__entry--small {
font-size: 1rem;
}
.fishbowl .chatlog {
padding: 1rem 0;
width: 100%;
}
.fishbowl .chatlog__message-group {
margin-bottom: 1rem;
}
.fishbowl .chatlog__message-container {
background-color: transparent;
transition: background-color 1s ease;
}
.fishbowl .chatlog__message-container--highlighted {
background-color: rgba(114, 137, 218, 0.2);
}
.fishbowl .chatlog__message-container--pinned {
background-color: rgba(249, 168, 37, 0.05);
}
.fishbowl .chatlog__message {
display: grid;
grid-template-columns: auto 1fr;
padding: 0.15rem 0;
direction: ltr;
unicode-bidi: bidi-override;
}
.fishbowl .chatlog__message:hover {
background-color: #fafafa;
}
.fishbowl .chatlog__message:hover .chatlog__short-timestamp {
display: block;
}
.fishbowl .chatlog__message-aside {
grid-column: 1;
width: 72px;
padding: 0.15rem 0.15rem 0 0.15rem;
text-align: center;
}
.fishbowl .chatlog__reference-symbol, .fishbowl .chatlog__reply-symbol {
height: 10px;
margin: 6px 4px 4px 36px;
border-left: 2px solid #c7ccd1;
border-top: 2px solid #c7ccd1;
border-radius: 8px 0 0 0;
}
.fishbowl .chatlog__avatar {
width: 40px;
height: 40px;
border-radius: 50%;
}
.fishbowl .chatlog__short-timestamp {
display: none;
color: #5e6772;
font-size: 0.7em;
line-height: 1.4em;
direction: ltr;
unicode-bidi: bidi-override;
}
.fishbowl .chatlog__message-primary {
grid-column: 2;
min-width: 0;
}
.fishbowl .chatlog__reference, .fishbowl .chatlog__reply {
display: flex;
margin-bottom: 0.15rem;
align-items: center;
color: #5f5f60;
font-size: 0.85em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.fishbowl .chatlog__reference-avatar, .fishbowl .chatlog__reply-avatar {
width: 16px;
height: 16px;
margin-right: 0.25rem;
border-radius: 50%;
}
.fishbowl .chatlog__reference-author, .fishbowl .chatlog__reply-author {
margin-right: 0.3rem;
font-weight: 600;
}
.fishbowl .chatlog__reference-content, .fishbowl .chatlog__reply-content {
overflow: hidden;
text-overflow: ellipsis;
}
.fishbowl .chatlog__reference-link, .fishbowl .chatlog__reply-link {
cursor: pointer;
}
.fishbowl .chatlog__reference-link *, .fishbowl .chatlog__reply-link * {
display: inline;
pointer-events: none;
}
.fishbowl .chatlog__reference-link .hljs, .fishbowl .chatlog__reply-link .hljs {
display: inline;
}
.fishbowl .chatlog__reference-link .chatlog__markdown-quote, .fishbowl .chatlog__reply-link .chatlog__markdown-quote {
display: inline
}
.fishbowl .chatlog__reference-link .chatlog__markdown-pre, .fishbowl .chatlog__reply-link .chatlog__markdown-pre {
display: inline
}
.fishbowl .chatlog__reference-link:hover, .fishbowl .chatlog__reply-link:hover {
color: #2f3136;
}
.fishbowl .chatlog__reference-link:hover *:not(.chatlog__markdown-spoiler), .fishbowl .chatlog__reply-link:hover *:not(.chatlog__markdown-spoiler) {
color: inherit;
}
.fishbowl .chatlog__reference-edited-timestamp, .fishbowl .chatlog__reply-edited-timestamp {
margin-left: 0.25rem;
color: #5e6772;
font-size: 0.75rem;
font-weight: 500;
direction: ltr;
unicode-bidi: bidi-override;
}
.fishbowl .chatlog__header {
margin-bottom: 0.1rem;
}
.fishbowl .chatlog__author {
font-weight: 600;
color: #2f3136;
}
.fishbowl .chatlog__bot-label {
position: relative;
top: -0.1rem;
margin-left: 0.3rem;
padding: 0.05rem 0.3rem;
border-radius: 3px;
background-color: #5865F2;
color: #ffffff;
font-size: 0.625rem;
font-weight: 500;
line-height: 1.3;
}
.fishbowl .chatlog__timestamp {
margin-left: 0.3rem;
color: #5e6772;
font-size: 0.75rem;
direction: ltr;
unicode-bidi: bidi-override;
}
.fishbowl .chatlog__content {
padding-right: 1rem;
word-wrap: break-word;
}
.fishbowl .chatlog__edited-timestamp {
margin-left: 0.15rem;
color: #5e6772;
font-size: 0.7em;
}
.fishbowl .chatlog__attachment {
position: relative;
width: fit-content;
margin-top: 0.3rem;
border-radius: 3px;
overflow: hidden;
}
.fishbowl .chatlog__attachment--hidden {
cursor: pointer;
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.1);
}
.fishbowl .chatlog__attachment--hidden * {
pointer-events: none;
}
.fishbowl .chatlog__attachment-spoiler-caption {
display: none;
position: absolute;
left: 50%;
top: 50%;
z-index: 999;
padding: 0.4rem 0.8rem;
border-radius: 20px;
transform: translate(-50%, -50%);
background-color: rgba(0, 0, 0, 0.9);
color: #dcddde;
font-size: 0.9rem;
font-weight: 600;
letter-spacing: 0.05rem;
}
.fishbowl .chatlog__attachment--hidden .chatlog__attachment-spoiler-caption {
display: block;
}
.fishbowl .chatlog__attachment--hidden:hover .chatlog__attachment-spoiler-caption {
color: #fff;
}
.fishbowl .chatlog__attachment-media {
max-width: 500px;
max-height: 400px;
vertical-align: top;
border-radius: 3px;
}
.fishbowl .chatlog__attachment--hidden .chatlog__attachment-media {
filter: blur(44px);
}
.fishbowl .chatlog__attachment-generic {
max-width: 520px;
width: 100%;
height: 40px;
padding: 10px;
border: 1px solid #ebedef;
border-radius: 3px;
background-color: #f2f3f5;
overflow: hidden;
}
.fishbowl .chatlog__attachment--hidden .chatlog__attachment-generic {
filter: blur(44px);
}
.fishbowl .chatlog__attachment-generic-icon {
float: left;
width: 30px;
height: 100%;
margin-right: 10px;
}
.fishbowl .chatlog__attachment-generic-size {
color: #72767d;
font-size: 12px;
}
.fishbowl .chatlog__attachment-generic-name {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.fishbowl .chatlog__embed {
display: flex;
margin-top: 0.3rem;
max-width: 520px;
}
.fishbowl .chatlog__embed-color-pill {
flex-shrink: 0;
width: 0.25rem;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
.fishbowl .chatlog__embed-color-pill--default {
background-color: rgba(227, 229, 232, 1);
}
.fishbowl .chatlog__embed-content-container {
display: flex;
flex-direction: column;
padding: 0.5rem 0.6rem;
border: 1px solid rgba(204, 204, 204, 0.3);
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
background-color: rgba(249, 249, 249, 0.3);
}
.fishbowl .chatlog__embed-content {
display: flex;
width: 100%;
}
.fishbowl .chatlog__embed-text {
flex: 1;
}
.fishbowl .chatlog__embed-author-container {
display: flex;
margin-bottom: 0.5rem;
align-items: center;
}
.fishbowl .chatlog__embed-author-icon {
width: 20px;
height: 20px;
margin-right: 0.5rem;
border-radius: 50%;
}
.fishbowl .chatlog__embed-author {
color: #4f545c;
font-size: 0.875rem;
font-weight: 600;
direction: ltr;
unicode-bidi: bidi-override;
}
.fishbowl .chatlog__embed-author-link {
color: #4f545c;
}
.fishbowl .chatlog__embed-title {
margin-bottom: 0.5rem;
color: #4f545c;
font-size: 0.875rem;
font-weight: 600;
}
.fishbowl .chatlog__embed-description {
color: #2e3338;
font-weight: 500;
font-size: 0.85rem;
}
.fishbowl .chatlog__embed-fields {
display: flex;
flex-wrap: wrap;
gap: 0 0.5rem;
}
.fishbowl .chatlog__embed-field {
flex: 0;
min-width: 100%;
max-width: 506px;
padding-top: 0.6rem;
font-size: 0.875rem;
}
.fishbowl .chatlog__embed-field--inline {
flex: 1;
flex-basis: auto;
min-width: 50px;
}
.fishbowl .chatlog__embed-field-name {
margin-bottom: 0.2rem;
color: #36393e;
font-weight: 600;
}
.fishbowl .chatlog__embed-field-value {
color: #2e3338;
font-weight: 500;
}
.fishbowl .chatlog__embed-thumbnail {
flex: 0;
max-width: 80px;
max-height: 80px;
margin-left: 1.2rem;
border-radius: 3px;
}
.fishbowl .chatlog__embed-image-container {
margin-top: 0.6rem;
}
.fishbowl .chatlog__embed-image {
max-width: 500px;
max-height: 400px;
border-radius: 3px;
}
.fishbowl .chatlog__embed-footer {
margin-top: 0.6rem;
color: #2e3338;
}
.fishbowl .chatlog__embed-footer-icon {
width: 20px;
height: 20px;
margin-right: 0.2rem;
border-radius: 50%;
vertical-align: middle;
}
.fishbowl .chatlog__embed-footer-text {
vertical-align: middle;
font-size: 0.75rem;
font-weight: 500;
}
.fishbowl .chatlog__embed-plainimage {
max-width: 45vw;
max-height: 500px;
vertical-align: top;
border-radius: 3px;
}
.fishbowl .chatlog__embed-spotify {
border: 0;
}
.fishbowl .chatlog__embed-youtube-container {
margin-top: 0.6rem;
}
.fishbowl .chatlog__embed-youtube {
border: 0;
border-radius: 3px;
}
.fishbowl .chatlog__sticker {
width: 180px;
height: 180px;
}
.fishbowl .chatlog__sticker--media {
max-width: 100%;
max-height: 100%;
}
.fishbowl .chatlog__reactions {
display: flex;
}
.fishbowl .chatlog__reaction {
display: flex;
margin: 0.35rem 0.1rem 0.1rem 0;
padding: 0.125rem 0.375rem;
border: 1px solid transparent;
border-radius: 8px;
background-color: #f2f3f5;
align-items: center;
}
.fishbowl .chatlog__reaction:hover {
border: 1px solid rgba(0, 0, 0, 0.2);
background-color: white;
}
.fishbowl .chatlog__reaction-count {
min-width: 9px;
margin-left: 0.35rem;
color: #4f5660;
font-size: 0.875rem;
}
.fishbowl .chatlog__reaction:hover .chatlog__reaction-count {
color: #2e3338;
}
.fishbowl .chatlog__markdown {
max-width: 100%;
line-height: 1.3;
overflow-wrap: break-word;
}
.fishbowl .chatlog__markdown-preserve {
white-space: pre-wrap;
}
.fishbowl .chatlog__markdown-spoiler {
background-color: rgba(0, 0, 0, 0.1);
border-radius: 3px;
}
.fishbowl .chatlog__markdown-spoiler--hidden {
cursor: pointer;
background-color: #b9bbbe;
color: rgba(0, 0, 0, 0);
}
.fishbowl .chatlog__markdown-spoiler--hidden:hover {
background-color: rgba(185, 187, 190, 0.8);
}
.fishbowl .chatlog__markdown-spoiler--hidden::selection {
color: rgba(0, 0, 0, 0);
}
.fishbowl .chatlog__markdown-quote {
display: flex;
margin: 0.05rem 0;
}
.fishbowl .chatlog__markdown-quote-border {
margin-right: 0.5rem;
border: 2px solid #c7ccd1;
border-radius: 3px;
background-color: #c7ccd1;
}
.fishbowl .chatlog__markdown-pre {
background-color: #f9f9f9;
font-family: "Consolas", "Courier New", Courier, monospace;
}
.fishbowl .chatlog__markdown-pre--multiline {
margin-top: 0.25rem;
padding: 0.5rem;
border: 2px solid #f3f3f3;
border-radius: 5px;
color: #657b83;
}
.fishbowl .chatlog__markdown-pre--multiline.hljs {
background-color: inherit;
color: inherit;
}
.fishbowl .chatlog__markdown-pre--inline {
padding: 2px;
border-radius: 3px;
font-size: 0.85rem;
}
.fishbowl .chatlog__markdown-mention {
border-radius: 3px;
padding: 0 2px;
background-color: rgba(88, 101, 242, .15);
color: #505cdc;
font-weight: 500;
}
.fishbowl .chatlog__markdown-mention:hover {
background-color: #5865f2;
color: #ffffff
}
.fishbowl .chatlog__markdown-timestamp {
border-radius: 3px;
padding: 0 2px;
color: #5e6772;
}
.fishbowl .chatlog__emoji {
width: 1.325rem;
height: 1.325rem;
margin: 0 0.06rem;
vertical-align: -0.4rem;
}
.fishbowl .chatlog__emoji--small {
width: 1rem;
height: 1rem;
}
.fishbowl .chatlog__emoji--large {
width: 2.8rem;
height: 2.8rem;
}
.fishbowl .postamble {
padding: 1.25rem;
}
.fishbowl .postamble__entry {
color: #2f3136;
}

View File

@ -2,18 +2,47 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
"use strict";
(() => {
// Map multiple JavaScript environments to a single common API,
// preferring web standards over Node.js API.
//
// Environments considered:
// - Browsers
// - Node.js
// - Electron
// - Parcel
// - Webpack
if (typeof global !== "undefined") {
// global already exists
} else if (typeof window !== "undefined") {
window.global = window;
} else if (typeof self !== "undefined") {
self.global = self;
} else {
throw new Error("cannot export Go (neither global, window nor self is defined)");
}
if (!global.require && typeof require !== "undefined") {
global.require = require;
}
if (!global.fs && global.require) {
const fs = require("fs");
if (typeof fs === "object" && fs !== null && Object.keys(fs).length !== 0) {
global.fs = fs;
}
}
const enosys = () => {
const err = new Error("not implemented");
err.code = "ENOSYS";
return err;
};
if (!globalThis.fs) {
if (!global.fs) {
let outputBuf = "";
globalThis.fs = {
global.fs = {
constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1 }, // unused
writeSync(fd, buf) {
outputBuf += decoder.decode(buf);
@ -58,8 +87,8 @@
};
}
if (!globalThis.process) {
globalThis.process = {
if (!global.process) {
global.process = {
getuid() { return -1; },
getgid() { return -1; },
geteuid() { return -1; },
@ -73,26 +102,47 @@
}
}
if (!globalThis.crypto) {
throw new Error("globalThis.crypto is not available, polyfill required (crypto.getRandomValues only)");
if (!global.crypto && global.require) {
const nodeCrypto = require("crypto");
global.crypto = {
getRandomValues(b) {
nodeCrypto.randomFillSync(b);
},
};
}
if (!global.crypto) {
throw new Error("global.crypto is not available, polyfill required (getRandomValues only)");
}
if (!globalThis.performance) {
throw new Error("globalThis.performance is not available, polyfill required (performance.now only)");
if (!global.performance) {
global.performance = {
now() {
const [sec, nsec] = process.hrtime();
return sec * 1000 + nsec / 1000000;
},
};
}
if (!globalThis.TextEncoder) {
throw new Error("globalThis.TextEncoder is not available, polyfill required");
if (!global.TextEncoder && global.require) {
global.TextEncoder = require("util").TextEncoder;
}
if (!global.TextEncoder) {
throw new Error("global.TextEncoder is not available, polyfill required");
}
if (!globalThis.TextDecoder) {
throw new Error("globalThis.TextDecoder is not available, polyfill required");
if (!global.TextDecoder && global.require) {
global.TextDecoder = require("util").TextDecoder;
}
if (!global.TextDecoder) {
throw new Error("global.TextDecoder is not available, polyfill required");
}
// End of polyfills for common API.
const encoder = new TextEncoder("utf-8");
const decoder = new TextDecoder("utf-8");
globalThis.Go = class {
global.Go = class {
constructor() {
this.argv = ["js"];
this.env = {};
@ -246,8 +296,8 @@
setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000);
},
// func walltime() (sec int64, nsec int32)
"runtime.walltime": (sp) => {
// func walltime1() (sec int64, nsec int32)
"runtime.walltime1": (sp) => {
sp >>>= 0;
const msec = (new Date).getTime();
setInt64(sp + 8, msec / 1000);
@ -351,7 +401,6 @@
storeValue(sp + 56, result);
this.mem.setUint8(sp + 64, 1);
} catch (err) {
sp = this._inst.exports.getsp() >>> 0; // see comment above
storeValue(sp + 56, err);
this.mem.setUint8(sp + 64, 0);
}
@ -368,7 +417,6 @@
storeValue(sp + 40, result);
this.mem.setUint8(sp + 48, 1);
} catch (err) {
sp = this._inst.exports.getsp() >>> 0; // see comment above
storeValue(sp + 40, err);
this.mem.setUint8(sp + 48, 0);
}
@ -385,7 +433,6 @@
storeValue(sp + 40, result);
this.mem.setUint8(sp + 48, 1);
} catch (err) {
sp = this._inst.exports.getsp() >>> 0; // see comment above
storeValue(sp + 40, err);
this.mem.setUint8(sp + 48, 0);
}
@ -467,7 +514,7 @@
null,
true,
false,
globalThis,
global,
this,
];
this._goRefCounts = new Array(this._values.length).fill(Infinity); // number of references that Go has to a JS value, indexed by reference id
@ -476,7 +523,7 @@
[null, 2],
[true, 3],
[false, 4],
[globalThis, 5],
[global, 5],
[this, 6],
]);
this._idPool = []; // unused ids that have been garbage collected
@ -517,13 +564,6 @@
offset += 8;
});
// The linker guarantees global data starts from at least wasmMinDataAddr.
// Keep in sync with cmd/link/internal/ld/data.go:wasmMinDataAddr.
const wasmMinDataAddr = 4096 + 8192;
if (offset >= wasmMinDataAddr) {
throw new Error("total length of command line and environment variables exceeds limit");
}
this._inst.exports.run(argc, argv);
if (this.exited) {
this._resolveExitPromise();
@ -551,4 +591,36 @@
};
}
}
if (
typeof module !== "undefined" &&
global.require &&
global.require.main === module &&
global.process &&
global.process.versions &&
!global.process.versions.electron
) {
if (process.argv.length < 3) {
console.error("usage: go_js_wasm_exec [wasm binary] [arguments]");
process.exit(1);
}
const go = new Go();
go.argv = process.argv.slice(2);
go.env = Object.assign({ TMPDIR: require("os").tmpdir() }, process.env);
go.exit = process.exit;
WebAssembly.instantiate(fs.readFileSync(process.argv[2]), go.importObject).then((result) => {
process.on("exit", (code) => { // Node.js exits if no event handler is pending
if (code === 0 && !go.exited) {
// deadlock, make Go print error and stack traces
go._pendingEvent = { id: 0 };
go._resume();
}
});
return go.run(result.instance);
}).catch((err) => {
console.error(err);
process.exit(1);
});
}
})();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 682 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 459 KiB

View File

@ -1,78 +0,0 @@
function initCarousel(container, options = {}) {
const durationMS = options.durationMS ?? 0;
const onChange = options.onChange ?? (() => {});
const numCarouselItems = container.querySelectorAll('.carousel-item').length;
const buttonContainer = container.querySelector('.carousel-buttons');
let current = 0;
function activateCarousel(i, silent = false) {
const items = document.querySelectorAll('.carousel-item');
for (const item of items) {
item.classList.remove('active');
}
items[i].classList.add('active');
const smallItems = document.querySelectorAll('.carousel-item-small');
if (smallItems.length > 0) {
for (const item of smallItems) {
item.classList.remove('active');
}
smallItems[i].classList.add('active');
}
const buttons = document.querySelectorAll('.carousel-button');
for (const button of buttons) {
button.classList.remove('active');
}
buttons[i].classList.add('active');
current = i;
if (!silent) {
onChange(current);
}
}
function activateNext() {
activateCarousel((current + numCarouselItems + 1) % numCarouselItems);
}
function activatePrev() {
activateCarousel((current + numCarouselItems - 1) % numCarouselItems);
}
const carouselTimer = durationMS > 0 && setInterval(() => {
if (numCarouselItems === 0) {
return;
}
activateNext();
}, durationMS);
function carouselButtonClick(i) {
activateCarousel(i);
if (carouselTimer) {
clearInterval(carouselTimer);
}
}
for (let i = 0; i < numCarouselItems; i++) {
const button = document.createElement('div');
button.classList.add('carousel-button', 'br-pill', 'w1', 'h1', 'mh2');
button.classList.toggle('active', i === 0);
const clickIndex = i;
button.addEventListener('click', () => {
carouselButtonClick(clickIndex);
});
buttonContainer.appendChild(button);
}
activateCarousel(0, true);
return {
next: activateNext,
prev: activatePrev,
};
}

View File

@ -1,4 +1,4 @@
function ImageSelector(form, maxFileSize, container, defaultImageUrl) {
function ImageSelector(form, maxFileSize, container) {
this.form = form;
this.maxFileSize = maxFileSize;
this.fileInput = container.querySelector(".image_input");
@ -8,7 +8,6 @@ function ImageSelector(form, maxFileSize, container, defaultImageUrl) {
this.removeLink = container.querySelector(".remove");
this.originalImageUrl = this.imageEl.getAttribute("data-original");
this.currentImageUrl = this.originalImageUrl;
this.defaultImageUrl = defaultImageUrl || "";
this.fileInput.value = "";
this.removeImageInput.value = "";
@ -46,7 +45,7 @@ ImageSelector.prototype.removeImage = function() {
this.updateSizeLimit(0);
this.fileInput.value = "";
this.removeImageInput.value = "true";
this.setImageUrl(this.defaultImageUrl);
this.setImageUrl("");
this.updateButtons();
};
@ -83,15 +82,13 @@ ImageSelector.prototype.setImageUrl = function(url) {
};
ImageSelector.prototype.updateButtons = function() {
if ((this.originalImageUrl.length > 0 && this.originalImageUrl != this.defaultImageUrl)
&& this.currentImageUrl != this.originalImageUrl) {
if (this.originalImageUrl.length > 0 && this.currentImageUrl != this.originalImageUrl) {
this.resetLink.style.display = "inline-block";
} else {
this.resetLink.style.display = "none";
}
if (!this.fileInput.required && this.currentImageUrl != this.defaultImageUrl) {
if (!this.fileInput.required && this.currentImageUrl != "") {
this.removeLink.style.display = "inline-block";
} else {
this.removeLink.style.display = "none";

View File

@ -1,246 +0,0 @@
// Requires base64.js
/**
* Sets up file / image uploading for Markdown content.
*
* @param eSubmits A list of elements of buttons to submit/save the page you're on. They
* will be disabled and tell users files are uploading while uploading is
* happening.
* @param eFileInput The `<input type="file">`
* @param eUploadBar Usually looks like
* ```
* <div class="upload_bar flex-grow-1">
* <div class="instructions">
* Upload files by dragging & dropping, pasting, or <label class="pointer link" for="file_input">selecting</label> them.
* </div>
* <div class="progress flex">
* <div class="progress_text mr3"></div>
* <div class="progress_bar flex-grow-1 flex-shrink-1 pa1"><div class=""></div></div>
* </div>
* </div>
* ```
* @param eText The text field that can be dropped into and is editing the markdown.
* @param doMarkdown The function returned by `initLiveMarkdown`.
* @param maxFileSize The max allowed file size in bytes.
* @param uploadUrl The URL to POST assets to (unique per project to avoid CORS issues).
*/
function setupMarkdownUpload(eSubmits, eFileInput, eUploadBar, eText, doMarkdown, maxFileSize, uploadUrl) {
const submitTexts = Array.from(eSubmits).map(e => e.value);
const uploadProgress = eUploadBar.querySelector('.progress');
const uploadProgressText = eUploadBar.querySelector('.progress_text');
const uploadProgressBar = eUploadBar.querySelector('.progress_bar');
const uploadProgressBarFill = eUploadBar.querySelector('.progress_bar > div');
let fileCounter = 0;
let enterCounter = 0;
let uploadQueue = [];
let currentUpload = null;
let currentXhr = null;
let currentBatchSize = 0;
let currentBatchDone = 0;
eFileInput.addEventListener("change", function(ev) {
if (eFileInput.files.length > 0) {
importUserFiles(eFileInput.files);
}
});
eText.addEventListener("dragover", function(ev) {
let effect = "none";
for (let i = 0; i < ev.dataTransfer.items.length; ++i) {
if (ev.dataTransfer.items[i].kind.toLowerCase() == "file") {
effect = "copy";
break;
}
}
ev.dataTransfer.dropEffect = effect;
ev.preventDefault();
});
eText.addEventListener("dragenter", function(ev) {
enterCounter++;
let droppable = false;
for (let i = 0; i < ev.dataTransfer.items.length; ++i) {
if (ev.dataTransfer.items[i].kind.toLowerCase() == "file") {
droppable = true;
break;
}
}
if (droppable) {
eText.classList.add("drop");
}
});
eText.addEventListener("dragleave", function(ev) {
enterCounter--;
if (enterCounter == 0) {
eText.classList.remove("drop");
}
});
function makeUploadString(uploadNumber, filename) {
return `Uploading file #${uploadNumber}: \`${filename}\`...`;
}
eText.addEventListener("drop", function(ev) {
enterCounter = 0;
eText.classList.remove("drop");
if (ev.dataTransfer && ev.dataTransfer.files) {
importUserFiles(ev.dataTransfer.files)
}
ev.preventDefault();
});
eText.addEventListener("paste", function(ev) {
const files = ev.clipboardData?.files ?? [];
if (files.length > 0) {
importUserFiles(files)
}
});
function importUserFiles(files) {
let items = [];
for (let i = 0; i < files.length; ++i) {
let f = files[i];
if (f.size < maxFileSize) {
items.push({ file: f, error: null });
} else {
items.push({ file: null, error: `\`${f.name}\` is too big! Max size is ${maxFileSize} but the file is ${f.size}.` });
}
}
let cursorStart = eText.selectionStart;
let cursorEnd = eText.selectionEnd;
let toInsert = "";
let linesToCursor = eText.value.substr(0, cursorStart).split("\n");
let cursorLine = linesToCursor[linesToCursor.length-1].trim();
if (cursorLine.length > 0) {
toInsert = "\n\n";
}
for (let i = 0; i < items.length; ++i) {
if (items[i].file) {
fileCounter++;
toInsert += makeUploadString(fileCounter, items[i].file.name) + "\n\n";
queueUpload(fileCounter, items[i].file);
} else {
toInsert += `${items[i].error}\n\n`;
}
}
eText.value = eText.value.substring(0, cursorStart) + toInsert + eText.value.substring(cursorEnd, eText.value.length);
doMarkdown();
uploadNext();
}
function replaceUploadString(upload, newString) {
let cursorStart = eText.selectionStart;
let cursorEnd = eText.selectionEnd;
let uploadString = makeUploadString(upload.uploadNumber, upload.file.name);
let insertIndex = eText.value.indexOf(uploadString)
eText.value = eText.value.replace(uploadString, newString);
if (cursorStart <= insertIndex + uploadString.length) {
eText.selectionStart = cursorStart;
} else {
eText.selectionStart = cursorStart - uploadString.length + newString.length;
}
if (cursorEnd <= insertIndex + uploadString.length) {
eText.selectionEnd = cursorEnd;
} else {
eText.selectionEnd = cursorEnd - uploadString.length + newString.length;
}
doMarkdown();
}
function replaceUploadStringError(upload) {
replaceUploadString(upload, `There was a problem uploading your file \`${upload.file.name}\`.`);
}
function queueUpload(uploadNumber, file) {
uploadQueue.push({
uploadNumber: uploadNumber,
file: file
});
currentBatchSize++;
uploadProgressText.textContent = `Uploading files ${currentBatchDone+1}/${currentBatchSize}`;
}
function uploadDone(ev) {
try {
if (currentXhr.status == 200 && currentXhr.response) {
if (currentXhr.response.url) {
let url = currentXhr.response.url;
let newString = `[${currentUpload.file.name}](${url})`;
if (currentXhr.response.mime.startsWith("image")) {
newString = "!" + newString;
}
replaceUploadString(currentUpload, newString);
} else if (currentXhr.response.error) {
replaceUploadString(currentUpload, `Upload failed for \`${currentUpload.file.name}\`: ${currentXhr.response.error}.`);
} else {
replaceUploadStringError(currentUpload);
}
} else {
replaceUploadStringError(currentUpload);
}
} catch (err) {
console.error(err);
replaceUploadStringError(currentUpload);
}
currentUpload = null;
currentXhr = null;
currentBatchDone++;
uploadNext();
}
function updateUploadProgress(ev) {
if (ev.lengthComputable) {
let progress = ev.loaded / ev.total;
uploadProgressBarFill.style.width = Math.floor(progress * 100) + "%";
}
}
function uploadNext() {
if (currentUpload == null) {
next = uploadQueue.shift();
if (next) {
uploadProgressText.textContent = `Uploading files ${currentBatchDone+1}/${currentBatchSize}`;
eUploadBar.classList.add("uploading");
uploadProgressBarFill.style.width = "0%";
for (const e of eSubmits) {
e.disabled = true;
e.value = "Uploading files...";
}
try {
let utf8Filename = strToUTF8Arr(next.file.name);
let base64Filename = base64EncArr(utf8Filename);
// NOTE(asaf): We use XHR because fetch can't do upload progress reports. Womp womp. https://youtu.be/Pubd-spHN-0?t=2
currentXhr = new XMLHttpRequest();
currentXhr.upload.addEventListener("progress", updateUploadProgress);
currentXhr.open("POST", uploadUrl, true);
currentXhr.setRequestHeader("Hmn-Upload-Filename", base64Filename);
currentXhr.responseType = "json";
currentXhr.addEventListener("loadend", uploadDone);
currentXhr.send(next.file);
currentUpload = next;
} catch (err) {
replaceUploadStringError(next);
console.error(err);
uploadNext();
}
} else {
for (const [i, e] of eSubmits.entries()) {
e.disabled = false;
e.value = submitTexts[i];
}
eUploadBar.classList.remove("uploading");
currentBatchSize = 0;
currentBatchDone = 0;
}
}
}
}

View File

@ -1,5 +1,4 @@
const TimelineMediaTypes = {
UNKNOWN: 0,
IMAGE: 1,
VIDEO: 2,
AUDIO: 3,
@ -8,7 +7,7 @@ const TimelineMediaTypes = {
const showcaseItemTemplate = makeTemplateCloner("showcase_item");
const modalTemplate = makeTemplateCloner("timeline_modal");
const projectLinkTemplate = makeTemplateCloner("project_link");
const tagTemplate = makeTemplateCloner("timeline_item_tag");
function showcaseTimestamp(rawDate) {
const date = new Date(rawDate*1000);
@ -52,30 +51,19 @@ function makeShowcaseItem(timelineItem) {
break;
case TimelineMediaTypes.VIDEO:
addThumbnailFunc = () => {
let thumbEl;
if (timelineItem.thumbnail_url) {
thumbEl = document.createElement('img');
thumbEl.src = timelineItem.thumbnail_url;
} else {
thumbEl = document.createElement('video');
thumbEl.src = timelineItem.asset_url;
thumbEl.controls = false;
thumbEl.preload = 'metadata';
}
thumbEl.classList.add('h-100');
itemEl.thumbnail.appendChild(thumbEl);
const video = document.createElement('video');
video.src = timelineItem.asset_url; // TODO: Use image thumbnails
video.controls = false;
video.classList.add('h-100');
video.preload = 'metadata';
itemEl.thumbnail.appendChild(video);
};
createModalContentFunc = () => {
const modalVideo = document.createElement('video');
modalVideo.src = timelineItem.asset_url;
if (timelineItem.thumbnail_url) {
modalVideo.poster = timelineItem.thumbnail_url;
modalVideo.preload = 'none';
} else {
modalVideo.preload = 'metadata';
}
modalVideo.controls = true;
modalVideo.preload = 'metadata';
modalVideo.classList.add('mw-100', 'mh-60vh');
return modalVideo;
};
@ -108,24 +96,18 @@ function makeShowcaseItem(timelineItem) {
modalEl.date.textContent = timestamp;
modalEl.date.setAttribute("href", timelineItem.snippet_url);
if (timelineItem.projects.length === 0) {
modalEl.projects.remove();
if (timelineItem.tags.length === 0) {
modalEl.tags.remove();
} else {
for (const proj of timelineItem.projects) {
const projectLink = projectLinkTemplate();
projectLink.root.href = proj.url;
projectLink.logo.src = proj.logo;
projectLink.name.textContent = proj.name;
for (const tag of timelineItem.tags) {
const tagItem = tagTemplate();
tagItem.tag.innerText = tag.text;
modalEl.projects.appendChild(projectLink.root);
modalEl.tags.appendChild(tagItem.root);
}
}
if (timelineItem.discord_message_url != "") {
modalEl.discord_link.href = timelineItem.discord_message_url;
} else {
modalEl.discord_link.remove();
}
modalEl.discord_link.href = timelineItem.discord_message_url;
function close() {
modalEl.overlay.remove();

View File

@ -1,385 +0,0 @@
const snippetEditTemplate = makeTemplateCloner("snippet-edit");
const snippetEditProjectTemplate = makeTemplateCloner("snippet-edit-project");
function readableByteSize(numBytes) {
const scales = [
" bytes",
"kb",
"mb",
"gb"
];
let scale = 0;
while (numBytes > 1024 && scale < scales.length-1) {
numBytes /= 1024;
scale++;
}
return new Intl.NumberFormat([], { maximumFractionDigits: (scale > 0 ? 2 : 0) }).format(numBytes) + scales[scale];
}
function makeSnippetEdit(ownerName, ownerAvatar, ownerUrl, date, text, attachmentElement, projectIds, stickyProjectId, snippetId, originalSnippetEl) {
let snippetEdit = snippetEditTemplate();
let projectSelector = null;
let originalAttachment = null;
let originalText = text;
let attachmentChanged = false;
let hasAttachment = false;
snippetEdit.redirect.value = location.href;
snippetEdit.avatarImg.src = ownerAvatar;
snippetEdit.avatarLink.href = ownerUrl;
snippetEdit.username.textContent = ownerName;
snippetEdit.username.href = ownerUrl;
snippetEdit.date.textContent = new Intl.DateTimeFormat([], {month: "2-digit", day: "2-digit", year: "numeric"}).format(date);
snippetEdit.text.value = text;
if (attachmentElement) {
originalAttachment = attachmentElement.cloneNode(true);
clearAttachment(true);
}
if (snippetId !== undefined && snippetId !== null) {
snippetEdit.snippetId.value = snippetId;
} else {
snippetEdit.deleteButton.remove();
}
for (let i = 0; i < projectIds.length; ++i) {
let proj = null;
for (let j = 0; j < availableProjects.length; ++j) {
if (projectIds[i] == availableProjects[j].id) {
proj = availableProjects[j];
break;
}
}
if (proj) {
addProject(proj);
}
}
updateProjectSelector();
if (originalSnippetEl) {
snippetEdit.cancelLink.addEventListener("click", function() {
cancel();
});
} else {
snippetEdit.cancelLink.remove();
}
function cancel() {
if (originalSnippetEl) {
snippetEdit.root.parentElement.insertBefore(originalSnippetEl, snippetEdit.root);
}
snippetEdit.root.remove();
}
function addProject(proj) {
let projEl = snippetEditProjectTemplate();
projEl.projectId.value = proj.id;
projEl.projectLogo.src = proj.logo;
projEl.projectName.textContent = proj.name;
if (proj.id == stickyProjectId) {
projEl.removeButton.remove();
} else {
projEl.removeButton.addEventListener("click", function(ev) {
projEl.root.remove();
updateProjectSelector();
});
}
snippetEdit.projectList.appendChild(projEl.root);
}
function updateProjectSelector() {
if (projectSelector) {
projectSelector.remove();
}
let remainingProjects = [];
let projInputs = snippetEdit.projectList.querySelectorAll("input[name=project_id]");
let assignedIds = [];
for (let i = 0; i < projInputs.length; ++i) {
let id = parseInt(projInputs[i].value, 10);
if (!isNaN(id)) {
assignedIds.push(id);
}
}
for (let i = 0; i < availableProjects.length; ++i) {
let found = false;
for (let j = 0; j < assignedIds.length; ++j) {
if (assignedIds[j] == availableProjects[i].id) {
found = true;
break;
}
}
if (!found) {
remainingProjects.push(availableProjects[i]);
}
}
if (remainingProjects.length > 0) {
projectSelector = document.createElement("SELECT");
let option = document.createElement("OPTION");
option.textContent = "Add to project...";
option.selected = true;
projectSelector.appendChild(option);
for (let i = 0; i < remainingProjects.length; ++i) {
option = document.createElement("OPTION");
option.value = remainingProjects[i].id;
option.selected = false;
option.textContent = remainingProjects[i].name;
projectSelector.appendChild(option);
}
projectSelector.addEventListener("change", function(ev) {
if (projectSelector.selectedOptions.length > 0) {
let selected = projectSelector.selectedOptions[0];
if (selected.value != "") {
let id = parseInt(selected.value, 10);
if (!isNaN(id)) {
for (let i = 0; i < availableProjects.length; ++i) {
if (availableProjects[i].id == id) {
addProject(availableProjects[i]);
break;
}
}
}
updateProjectSelector();
}
}
});
snippetEdit.projectList.appendChild(projectSelector);
}
}
function setFile(file) {
let dt = new DataTransfer();
dt.items.add(file);
snippetEdit.file.files = dt.files;
attachmentChanged = true;
snippetEdit.removeAttachment.value = "false";
hasAttachment = true;
let el = null;
if (file.type.startsWith("image/")) {
el = document.createElement("img");
el.src = URL.createObjectURL(file);
} else if (file.type.startsWith("video/")) {
el = document.createElement("video");
el.src = URL.createObjectURL(file);
el.controls = true;
} else if (file.type.startsWith("audio/")) {
el = document.createElement("audio");
el.src = URL.createObjectURL(file);
} else {
el = document.createElement("div");
el.classList.add("project-card", "br2", "pv1", "ph2");
let anchor = document.createElement("a");
anchor.href = URL.createObjectURL(file);
anchor.setAttribute("target", "_blank");
anchor.textContent = file.name + " (" + readableByteSize(file.size) + ")";
el.appendChild(anchor);
}
setPreview(el);
validate();
}
function clearAttachment(restoreOriginal) {
snippetEdit.file.value = "";
let el = null;
attachmentChanged = false;
hasAttachment = false;
snippetEdit.removeAttachment.value = "false";
if (originalAttachment) {
if (restoreOriginal) {
hasAttachment = true;
el = originalAttachment;
} else {
attachmentChanged = true;
snippetEdit.removeAttachment.value = "true";
}
}
setPreview(el);
validate();
}
function setPreview(el) {
if (el) {
snippetEdit.uploadBox.style.display = "none";
snippetEdit.previewBox.style.display = "block";
snippetEdit.uploadResetBox.style.display = "none";
snippetEdit.previewContent = emptyElement(snippetEdit.previewContent);
snippetEdit.previewContent.appendChild(el);
snippetEdit.resetLink.style.display = (!originalAttachment || el == originalAttachment) ? "none" : "inline-block";
} else {
snippetEdit.uploadBox.style.display = "block";
snippetEdit.previewBox.style.display = "none";
if (originalAttachment) {
snippetEdit.uploadResetBox.style.display = "block";
}
}
}
function validate() {
let sizeGood = true;
if (snippetEdit.file.files.length > 0 && snippetEdit.file.files[0].size > maxFilesize) {
// NOTE(asaf): Writing this out in bytes to make the limit exactly clear to the user.
let readableSize = new Intl.NumberFormat([], { useGrouping: "always" }).format(maxFilesize);
snippetEdit.errors.textContent = "File is too big! Max filesize is " + readableSize + " bytes.";
sizeGood = false;
} else {
snippetEdit.errors.textContent = "";
}
let hasText = snippetEdit.text.value.trim().length > 0;
if ((hasText || hasAttachment) && sizeGood) {
snippetEdit.saveButton.disabled = false;
} else {
snippetEdit.saveButton.disabled = true;
}
}
snippetEdit.uploadLink.addEventListener("click", function() {
snippetEdit.file.click();
});
snippetEdit.removeLink.addEventListener("click", function() {
clearAttachment(false);
});
snippetEdit.replaceLink.addEventListener("click", function() {
snippetEdit.file.click();
});
snippetEdit.resetLink.addEventListener("click", function() {
clearAttachment(true);
});
snippetEdit.uploadResetLink.addEventListener("click", function() {
clearAttachment(true);
});
snippetEdit.file.addEventListener("change", function() {
if (snippetEdit.file.files.length > 0) {
setFile(snippetEdit.file.files[0]);
}
});
snippetEdit.root.addEventListener("dragover", function(ev) {
let effect = "none";
for (let i = 0; i < ev.dataTransfer.items.length; ++i) {
if (ev.dataTransfer.items[i].kind.toLowerCase() == "file") {
effect = "copy";
break;
}
}
ev.dataTransfer.dropEffect = effect;
ev.preventDefault();
});
let enterCounter = 0;
snippetEdit.root.addEventListener("dragenter", function(ev) {
enterCounter++;
let droppable = Array.from(ev.dataTransfer.items).some(
item => item.kind.toLowerCase() === "file"
);
if (droppable) {
snippetEdit.root.classList.add("drop");
}
});
snippetEdit.root.addEventListener("dragleave", function(ev) {
enterCounter--;
if (enterCounter == 0) {
snippetEdit.root.classList.remove("drop");
}
});
snippetEdit.root.addEventListener("drop", function(ev) {
enterCounter = 0;
snippetEdit.root.classList.remove("drop");
if (ev.dataTransfer && ev.dataTransfer.files && ev.dataTransfer.files.length > 0) {
setFile(ev.dataTransfer.files[0]);
}
ev.preventDefault();
});
snippetEdit.text.addEventListener("paste", function(ev) {
const files = ev.clipboardData?.files ?? [];
if (files.length > 0) {
setFile(files[0]);
}
});
snippetEdit.text.addEventListener("input", function(ev) {
validate();
});
snippetEdit.saveButton.addEventListener("click", function(ev) {
let projectsChanged = false;
let projInputs = snippetEdit.projectList.querySelectorAll("input[name=project_id]");
let assignedIds = [];
for (let i = 0; i < projInputs.length; ++i) {
let id = parseInt(projInputs[i].value, 10);
if (!isNaN(id)) {
assignedIds.push(id);
}
}
if (projectIds.length != assignedIds.length) {
projectsChanged = true;
} else {
for (let i = 0; i < projectIds.length; ++i) {
let found = false;
for (let j = 0; j < assignedIds.length; ++j) {
if (projectIds[i] == assignedIds[j]) {
found = true;
}
}
if (!found) {
projectsChanged = true;
break;
}
}
}
if (originalSnippetEl && (!attachmentChanged && originalText == snippetEdit.text.value.trim() && !projectsChanged)) {
// NOTE(asaf): We're in edit mode and nothing changed, so no need to submit to the server.
ev.preventDefault();
cancel();
}
});
snippetEdit.deleteButton.addEventListener("click", function(ev) {
if (!window.confirm("Are you sure you want to delete this snippet?")) {
ev.preventDefault();
return;
}
snippetEdit.file.value = "";
});
validate();
return snippetEdit;
}
function editTimelineSnippet(timelineItemEl, stickyProjectId) {
let ownerName = timelineItemEl.querySelector(".user")?.textContent;
let ownerUrl = timelineItemEl.querySelector(".user")?.href;
let ownerAvatar = timelineItemEl.querySelector(".avatar-icon")?.src;
let creationDate = new Date(timelineItemEl.querySelector("time").dateTime);
let rawDesc = timelineItemEl.querySelector(".rawdesc").textContent;
let attachment = timelineItemEl.querySelector(".timeline-content-box")?.children?.[0];
let projectIds = [];
let projectEls = timelineItemEl.querySelectorAll(".projects > a");
for (let i = 0; i < projectEls.length; ++i) {
let projid = projectEls[i].getAttribute("data-projid");
if (projid) {
projectIds.push(projid);
}
}
let snippetEdit = makeSnippetEdit(ownerName, ownerAvatar, ownerUrl, creationDate, rawDesc, attachment, projectIds, stickyProjectId, timelineItemEl.getAttribute("data-id"), timelineItemEl);
timelineItemEl.parentElement.insertBefore(snippetEdit.root, timelineItemEl);
timelineItemEl.remove();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 236 253" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><rect id="books" x="0" y="0" width="235.74" height="252.97" style="fill:none;"/><path d="M77.61,252.704l0,-230.569l80.52,-0l-0,230.569l-80.52,0Zm59.686,-188.853l0,-20.883l-38.853,-0l0,20.883l38.853,0Zm0,128.926l0,-108.092l-38.853,-0l0,108.092l38.853,-0Zm-38.853,20.833l0,18.261l38.853,-0l0,-18.261l-38.853,0Zm-98.032,39.094l-0,-252.438l70.429,-0l-0,252.438l-70.429,0Zm49.596,-206.372l-0,-25.233l-28.763,-0l0,25.233l28.763,0Zm-0,142.369l-0,-121.536l-28.763,0l0,121.536l28.763,-0Zm-28.763,20.833l0,22.337c0,-0 28.763,-0 28.763,-0l-0,-22.337l-28.763,-0Zm143.656,43.17l-0,-252.438l70.429,-0l-0,252.438l-70.429,0Zm49.596,-206.372l-0,-25.233l-28.763,-0l0,25.233l28.763,0Zm-0,142.369l-0,-121.536l-28.763,0l0,121.536l28.763,-0Zm-28.763,20.833l0,22.337l28.763,-0l-0,-22.337l-28.763,-0Z"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 336 233" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><rect id="lightbulb" x="0" y="0" width="335.159" height="232.656" style="fill:none;"/><path d="M197.613,202.015c0,16.576 -13.457,30.034 -30.034,30.034c-16.576,-0 -30.034,-13.458 -30.034,-30.034l60.068,-0Zm0.06,-9.97l-60.206,-0c-3.155,-16.04 -5.152,-23.793 -32.39,-57.373c-10.513,-12.96 -16.178,-29.812 -16.178,-47.773c0,-43.425 35.256,-78.68 78.68,-78.68c43.425,-0 78.68,34.8 78.68,78.224c0,17.961 -5.665,34.814 -16.177,47.774c-27.238,33.58 -29.254,41.788 -32.409,57.828Zm-16.343,-20.834c3.88,-11.276 11.569,-24.225 32.572,-50.118c7.611,-9.383 11.524,-21.647 11.524,-34.65c-0,-31.893 -25.954,-57.391 -57.847,-57.391c-31.926,0 -57.846,25.92 -57.846,57.847c-0,13.003 3.913,25.266 11.524,34.649c20.946,25.823 28.639,38.556 32.521,49.663l27.552,0Zm-160.921,-151.684c-4.694,-3.321 -5.808,-9.827 -2.488,-14.52c3.321,-4.693 9.827,-5.808 14.52,-2.488l31.239,22.101c4.694,3.321 5.808,9.827 2.488,14.52c-3.32,4.693 -9.827,5.808 -14.52,2.488l-31.239,-22.101Zm12.032,153.97c-4.693,3.32 -11.199,2.205 -14.52,-2.488c-3.32,-4.693 -2.206,-11.199 2.488,-14.52l31.239,-22.101c4.693,-3.32 11.2,-2.205 14.52,2.488c3.32,4.693 2.206,11.199 -2.488,14.52l-31.239,22.101Zm-21.856,-74.77c-5.749,-0 -10.416,-4.668 -10.416,-10.417c-0,-5.749 4.667,-10.417 10.416,-10.417l38.267,0c5.749,0 10.417,4.668 10.417,10.417c-0,5.749 -4.668,10.417 -10.417,10.417l-38.267,-0Zm292.133,-95.906c4.693,-3.32 11.199,-2.205 14.519,2.488c3.321,4.693 2.206,11.199 -2.487,14.52l-31.239,22.101c-4.694,3.32 -11.2,2.206 -14.52,-2.488c-3.321,-4.693 -2.206,-11.199 2.487,-14.52l31.24,-22.101Zm12.032,153.97c4.693,3.321 5.808,9.827 2.487,14.52c-3.32,4.694 -9.826,5.808 -14.519,2.488l-31.24,-22.101c-4.693,-3.321 -5.808,-9.827 -2.487,-14.52c3.32,-4.693 9.826,-5.808 14.52,-2.488l31.239,22.101Zm9.823,-78.595c5.75,-0 10.417,4.667 10.417,10.416c0,5.749 -4.667,10.417 -10.417,10.417l-38.266,-0c-5.75,-0 -10.417,-4.668 -10.417,-10.417c-0,-5.749 4.667,-10.416 10.417,-10.416l38.266,-0Z"/></svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 301 229" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><rect id="presentation" x="-0" y="0" width="300.716" height="228.578" style="fill:none;"/><path d="M124.979,14.95l175.159,0l0,152.429l-137.896,0c-1.49,-7.262 -3.898,-14.19 -7.097,-20.659l124.334,-0l-0,-111.11l-143.514,-0c-2.302,-7.632 -6.074,-14.628 -10.986,-20.66Zm-119.77,196.191c-2.997,-8.252 -4.631,-17.155 -4.631,-26.437c0,-42.797 34.745,-77.542 77.541,-77.542c42.796,0 77.541,34.745 77.541,77.542c0,9.282 -1.634,18.185 -4.631,26.437c-22.091,10.548 -46.816,16.455 -72.91,16.455c-26.094,0 -50.819,-5.907 -72.91,-16.455Zm15.522,-13.612c17.693,7.296 37.075,11.317 57.388,11.317c20.314,0 39.695,-4.021 57.389,-11.317c0.919,-4.129 1.402,-8.421 1.402,-12.825c0,-32.448 -26.343,-58.792 -58.791,-58.792c-32.448,0 -58.791,26.344 -58.791,58.792c0,4.404 0.484,8.696 1.403,12.825Zm57.388,-196.547c28.741,-0 52.075,23.334 52.075,52.074c-0,28.741 -23.334,52.075 -52.075,52.075c-28.74,-0 -52.074,-23.334 -52.074,-52.075c-0,-28.74 23.334,-52.074 52.074,-52.074Zm0,18.75c-18.392,-0 -33.324,14.932 -33.324,33.324c-0,18.392 14.932,33.325 33.324,33.325c18.392,-0 33.325,-14.933 33.325,-33.325c-0,-18.392 -14.933,-33.324 -33.325,-33.324Z"/></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 872 KiB

File diff suppressed because it is too large Load Diff

View File

@ -216,8 +216,6 @@ pre, code, .codeblock {
--theme-color-dim: #444;
--theme-color-dimmer: #383838;
--theme-color-dimmest: #333;
--theme-color-dark: #666;
--theme-color-light: #666;
--link-color: #aaa;
--link-border-color: #aaa;
--hr-color: #aaa;
@ -272,7 +270,7 @@ pre, code, .codeblock {
--landing-search-background-hover: #181818;
--editor-toolbar-background: #282828;
--editor-toolbar-border-color: #333;
--editor-toolbar-button-background: #282828;
--editor-toolbar-button-background: 282828;
--editor-toolbar-button-background-hover: #333;
--editor-toolbar-button-border-color: #333;
--post-blockquote-border-color: #555;
@ -290,7 +288,6 @@ pre, code, .codeblock {
--forum-diff-insert-border-color: #30591b;
--card-background: #282828;
--card-background-hover: #333;
--timeline-content-background: rgba(255, 255, 255, 0.06);
--irc-border-color: #333;
--irc-tab-current-shadow: 0px 0px 5px #000 inset;
--irc-tab-close-button-color: #bbb;

View File

@ -234,8 +234,6 @@ pre, code, .codeblock {
--theme-color-dim: #aaa;
--theme-color-dimmer: #bbb;
--theme-color-dimmest: #ccc;
--theme-color-dark: #666;
--theme-color-light: #666;
--link-color: #666;
--link-border-color: #666;
--hr-color: #444;
@ -308,7 +306,6 @@ pre, code, .codeblock {
--forum-diff-insert-border-color: #5baa3f;
--card-background: #e8e8e8;
--card-background-hover: #f0f0f0;
--timeline-content-background: rgba(0, 0, 0, 0.2);
--irc-border-color: #ddd;
--irc-tab-current-shadow: 0px 0px 5px #bbb inset;
--irc-tab-close-button-color: #fff;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 239 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 423 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

View File

@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 461 280" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;">
<g id="Layer1">
</g>
<circle cx="56.5" cy="200.5" r="22.5" style="fill:white;"/>
<circle cx="101.5" cy="147.5" r="22.5" style="fill:white;"/>
<circle cx="183.5" cy="188.5" r="22.5" style="fill:white;"/>
<circle cx="183.5" cy="97.5" r="22.5" style="fill:white;"/>
<circle cx="83.5" cy="52.5" r="22.5" style="fill:white;"/>
<path d="M83.948,51.442L101.948,146.442" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:6px;"/>
<path d="M53.713,198.058L98.713,145.058" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:6px;"/>
<path d="M183.59,99.544L103.59,149.544" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:6px;"/>
<path d="M181.645,190.677L100.645,149.677" style="fill:none;fill-rule:nonzero;stroke:white;stroke-width:6px;"/>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,457,-385)">
<path d="M442,41C442,38.24 439.76,36 437,36L426,36C423.24,36 421,38.24 421,41L421,85C421,87.76 423.24,90 426,90L437,90C439.76,90 442,87.76 442,85L442,41Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,426,-296)">
<path d="M382,70C382,67.24 379.76,65 377,65L366,65C363.24,65 361,67.24 361,70L361,114C361,116.76 363.24,119 366,119L377,119C379.76,119 382,116.76 382,114L382,70Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,486,-356)">
<path d="M442,70C442,67.24 439.76,65 437,65L426,65C423.24,65 421,67.24 421,70L421,159C421,161.76 423.24,164 426,164L437,164C439.76,164 442,161.76 442,159L442,70Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,455,-267)">
<path d="M382,99C382,96.24 379.76,94 377,94L366,94C363.24,94 361,96.24 361,99L361,188C361,190.76 363.24,193 366,193L377,193C379.76,193 382,190.76 382,188L382,99Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,515,-327)">
<path d="M442,99C442,96.24 439.76,94 437,94L426,94C423.24,94 421,96.24 421,99L421,158C421,160.76 423.24,163 426,163L437,163C439.76,163 442,160.76 442,158L442,99Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,484,-238)">
<path d="M382,128C382,125.24 379.76,123 377,123L366,123C363.24,123 361,125.24 361,128L361,187C361,189.76 363.24,192 366,192L377,192C379.76,192 382,189.76 382,187L382,128Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,544,-298)">
<path d="M442,128C442,125.24 439.76,123 437,123L426,123C423.24,123 421,125.24 421,128L421,238C421,240.76 423.24,243 426,243L437,243C439.76,243 442,240.76 442,238L442,128Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,513,-209)">
<path d="M382,157C382,154.24 379.76,152 377,152L366,152C363.24,152 361,154.24 361,157L361,267C361,269.76 363.24,272 366,272L377,272C379.76,272 382,269.76 382,267L382,157Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,573,-269)">
<path d="M442,157C442,154.24 439.76,152 437,152L426,152C423.24,152 421,154.24 421,157L421,187C421,189.76 423.24,192 426,192L437,192C439.76,192 442,189.76 442,187L442,157Z" style="fill:white;"/>
</g>
<g transform="matrix(-3.82857e-16,1,-1,-3.82857e-16,542,-180)">
<path d="M382,186C382,183.24 379.76,181 377,181L366,181C363.24,181 361,183.24 361,186L361,216C361,218.76 363.24,221 366,221L377,221C379.76,221 382,218.76 382,216L382,186Z" style="fill:white;"/>
</g>
<path d="M461,21.739C461,9.741 451.259,0 439.261,0L21.739,0C9.741,0 0,9.741 0,21.739L0,258.261C0,270.259 9.741,280 21.739,280L439.261,280C451.259,280 461,270.259 461,258.261L461,21.739ZM447,21.739L447,258.261C447,262.532 443.532,266 439.261,266C439.261,266 21.739,266 21.739,266C17.468,266 14,262.532 14,258.261L14,21.739C14,17.468 17.468,14 21.739,14L439.261,14C443.532,14 447,17.468 447,21.739Z" style="fill:white;"/>
<g transform="matrix(2.90789,0,0,1.65,-31.7105,-153.4)">
<rect x="14" y="236" width="152" height="20" style="fill:white;"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 400 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 734 30" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(0.412851,0,0,0.412851,-164.727,-144.911)">
<path d="M399,404C477.667,404 563.667,422.167 640,421C712.766,419.888 784.237,398.26 857,397C934,395.667 1021,413.167 1102,413C1182.53,412.834 1262.47,395.225 1343,396C1482.5,397.343 1719.83,418.976 1861,421.056C1915.68,421.862 2097.72,404.026 2176.88,404.026L2176.88,351.026L399,351L399,404Z" style="fill:rgb(55,83,123);"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 861 B

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 734 30" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(0.412851,0,0,0.412851,-164.727,-144.911)">
<path d="M399,404C477.667,404 563.667,422.167 640,421C712.766,419.888 784.237,398.26 857,397C934,395.667 1021,413.167 1102,413C1182.53,412.834 1262.47,395.225 1343,396C1482.5,397.343 1719.83,418.976 1861,421.056C1915.68,421.862 2097.72,404.026 2176.88,404.026L2176.88,351.026L399,351L399,404Z" style="fill:rgb(183,218,255);"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 863 B

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Before

Width:  |  Height:  |  Size: 211 KiB

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 475 283" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
<g id="Handlebars" transform="matrix(1,0,0,1,-100,-167)">
<path d="M404,196C407.778,166.333 384.333,169 364,184" style="fill:none;stroke:white;stroke-width:9px;"/>
</g>
<g id="Seat">
</g>
<path d="M120,42L160,42C177.006,42.052 186.77,48.289 191,58" style="fill:none;stroke:white;stroke-width:9px;"/>
<g id="Frame" transform="matrix(1,0,0,1,-100,-167)">
<path d="M314,390L445,274" style="fill:none;stroke:white;stroke-width:9px;"/>
<path d="M500,375L404,196" style="fill:none;stroke:white;stroke-width:9px;stroke-linecap:butt;"/>
<path d="M266,259L437,259" style="fill:none;stroke:white;stroke-width:9px;"/>
<path d="M314,390L248,209" style="fill:none;stroke:white;stroke-width:9px;stroke-linecap:butt;"/>
<g transform="matrix(0.815396,-0.0212494,-0.0212494,0.997554,66.2531,7.62625)">
<path d="M143.044,371.322L314,390" style="fill:none;stroke:white;stroke-width:10.11px;"/>
</g>
<path d="M175,375L266,259" style="fill:none;stroke:white;stroke-width:9px;"/>
</g>
<g id="Wheel" transform="matrix(1,0,0,1,-100,-167)">
<g transform="matrix(0.980392,0,0,0.980392,-46.0784,31.3725)">
<path d="M302,293.019C302,282.522 293.478,274 282.981,274L168.019,274C157.522,274 149,282.522 149,293.019L149,407.981C149,418.478 157.522,427 168.019,427L282.981,427C293.478,427 302,418.478 302,407.981L302,293.019ZM292.82,293.019L292.82,407.981C292.82,413.411 288.411,417.82 282.981,417.82C282.981,417.82 168.019,417.82 168.019,417.82C162.589,417.82 158.18,413.411 158.18,407.981L158.18,293.019C158.18,287.589 162.589,283.18 168.019,283.18L282.981,283.18C288.411,283.18 292.82,287.589 292.82,293.019Z" style="fill:white;"/>
</g>
<g transform="matrix(1,0,0,1,-50,26)">
<path d="M237,343C237,339.689 234.311,337 231,337L219,337C215.689,337 213,339.689 213,343L213,355C213,358.311 215.689,361 219,361L231,361C234.311,361 237,358.311 237,355L237,343Z" style="fill:white;"/>
</g>
</g>
<g id="Wheel1" serif:id="Wheel" transform="matrix(1,0,0,1,225,-167)">
<g transform="matrix(0.980392,0,0,0.980392,-46.0784,31.3725)">
<path d="M302,293.019C302,282.522 293.478,274 282.981,274L168.019,274C157.522,274 149,282.522 149,293.019L149,407.981C149,418.478 157.522,427 168.019,427L282.981,427C293.478,427 302,418.478 302,407.981L302,293.019ZM292.82,293.019L292.82,407.981C292.82,413.411 288.411,417.82 282.981,417.82C282.981,417.82 168.019,417.82 168.019,417.82C162.589,417.82 158.18,413.411 158.18,407.981L158.18,293.019C158.18,287.589 162.589,283.18 168.019,283.18L282.981,283.18C288.411,283.18 292.82,287.589 292.82,293.019Z" style="fill:white;"/>
</g>
<g transform="matrix(1,0,0,1,-50,26)">
<path d="M237,343C237,339.689 234.311,337 231,337L219,337C215.689,337 213,339.689 213,343L213,355C213,358.311 215.689,361 219,361L231,361C234.311,361 237,358.311 237,355L237,343Z" style="fill:white;"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 472 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 475 283" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
<g id="Handlebars" transform="matrix(1,0,0,1,-100,-167)">
<path d="M404,196C407.778,166.333 384.333,169 364,184" style="fill:none;stroke:white;stroke-width:9px;"/>
</g>
<g id="Seat">
</g>
<path d="M120,42L160,42C177.006,42.052 186.77,48.289 191,58" style="fill:none;stroke:white;stroke-width:9px;"/>
<g id="Frame" transform="matrix(1,0,0,1,-100,-167)">
<path d="M314,390L445,274" style="fill:none;stroke:white;stroke-width:9px;"/>
<path d="M500,375L404,196" style="fill:none;stroke:white;stroke-width:9px;stroke-linecap:butt;"/>
<path d="M266,259L437,259" style="fill:none;stroke:white;stroke-width:9px;"/>
<path d="M314,390L248,209" style="fill:none;stroke:white;stroke-width:9px;stroke-linecap:butt;"/>
<g transform="matrix(0.815396,-0.0212494,-0.0212494,0.997554,66.2531,7.62625)">
<path d="M143.044,371.322L314,390" style="fill:none;stroke:white;stroke-width:10.11px;"/>
</g>
<path d="M175,375L266,259" style="fill:none;stroke:white;stroke-width:9px;"/>
</g>
<g id="Wheel" transform="matrix(1,0,0,1,-100,-167)">
<g transform="matrix(0.980392,0,0,0.980392,-46.0784,31.3725)">
<path d="M302,293.019C302,282.522 293.478,274 282.981,274L168.019,274C157.522,274 149,282.522 149,293.019L149,407.981C149,418.478 157.522,427 168.019,427L282.981,427C293.478,427 302,418.478 302,407.981L302,293.019ZM292.82,293.019L292.82,407.981C292.82,413.411 288.411,417.82 282.981,417.82C282.981,417.82 168.019,417.82 168.019,417.82C162.589,417.82 158.18,413.411 158.18,407.981L158.18,293.019C158.18,287.589 162.589,283.18 168.019,283.18L282.981,283.18C288.411,283.18 292.82,287.589 292.82,293.019Z" style="fill:white;"/>
</g>
<g transform="matrix(1,0,0,1,-50,26)">
<path d="M237,343C237,339.689 234.311,337 231,337L219,337C215.689,337 213,339.689 213,343L213,355C213,358.311 215.689,361 219,361L231,361C234.311,361 237,358.311 237,355L237,343Z" style="fill:white;"/>
</g>
</g>
<g id="Wheel1" serif:id="Wheel" transform="matrix(1,0,0,1,225,-167)">
<g transform="matrix(0.980392,0,0,0.980392,-46.0784,31.3725)">
<path d="M302,293.019C302,282.522 293.478,274 282.981,274L168.019,274C157.522,274 149,282.522 149,293.019L149,407.981C149,418.478 157.522,427 168.019,427L282.981,427C293.478,427 302,418.478 302,407.981L302,293.019ZM292.82,293.019L292.82,407.981C292.82,413.411 288.411,417.82 282.981,417.82C282.981,417.82 168.019,417.82 168.019,417.82C162.589,417.82 158.18,413.411 158.18,407.981L158.18,293.019C158.18,287.589 162.589,283.18 168.019,283.18L282.981,283.18C288.411,283.18 292.82,287.589 292.82,293.019Z" style="fill:white;"/>
</g>
<g transform="matrix(1,0,0,1,-50,26)">
<path d="M237,343C237,339.689 234.311,337 231,337L219,337C215.689,337 213,339.689 213,343L213,355C213,358.311 215.689,361 219,361L231,361C234.311,361 237,358.311 237,355L237,343Z" style="fill:white;"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 KiB

View File

@ -9,6 +9,15 @@
respond "{\"m.server\": \"matrix.handmade.network:443\"}"
header Content-Type application/json
}
# Uncomment this ONLY FOR BETA!
# It disables all search engine indexing!
# If you do this on the real site you will destroy all the site's SEO!
# ONLY UNCOMMENT THIS IN BETA!
# handle /robots.txt {
# respond "User-agent: *
# Disallow: /
# "
# }
handle /public/* {
file_server {
root /home/hmn/hmn

View File

@ -23,14 +23,14 @@ set -euo pipefail
cd /home/hmn/hmn
git fetch --all
git reset --hard origin/$branch
go build -o /home/hmn/bin/hmn .
go build -o /home/hmn/bin/hmn src/main.go
SCRIPT
echo "Running migrations..."
systemctl stop hmn
do_as hmn <<'SCRIPT'
set -euo pipefail
/home/hmn/bin/hmn db migrate
/home/hmn/bin/hmn migrate
SCRIPT
systemctl start hmn

View File

@ -15,7 +15,7 @@ deploy: ## Manually build and deploy a branch of the website.
/home/hmn/hmn/server/deploy.sh
build: ## Rebuild the website binary
sudo -u hmn --preserve-env=PATH bash -c "cd ~/hmn && go build -o /home/hmn/bin/hmn ."
sudo -u hmn --preserve-env=PATH bash -c "cd ~/hmn && go build -o /home/hmn/bin/hmn src/main.go"
edit-config: ## Edit the website config
vim /home/hmn/hmn/src/config/config.go

Some files were not shown because too many files have changed in this diff Show More