├── .env.local ├── .gitignore ├── Makefile ├── README.md ├── assets └── app.css ├── cmd └── app │ ├── engine.go │ └── main.go ├── data └── todo.go ├── db └── db.go ├── go.mod ├── go.sum ├── handlers ├── error.go ├── home.go └── middleware.go ├── package-lock.json ├── package.json ├── public └── assets │ └── app.css ├── tailwind.config.js ├── util └── util.go └── views ├── error ├── 404.html └── 500.html ├── home ├── bored.html └── index.html └── partials ├── app_base.html ├── base.html └── navigation.html /.env.local: -------------------------------------------------------------------------------- 1 | HTTP_LISTEN_ADDR=:3000 2 | PRODUCTION=false 3 | 4 | DB_PASSWORD= 5 | DB_USER= 6 | DB_NAME= 7 | DB_HOST= 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | .env 3 | node_modules -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | build-app: 2 | @go build -o bin/app ./cmd/app/ 3 | 4 | run: build-app 5 | @./bin/app 6 | 7 | clean: 8 | @rm -rf bin -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The bored stack 2 | Programming stack for the no bullshit builder. -------------------------------------------------------------------------------- /assets/app.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | .btn { 6 | @apply py-2 px-3 border border-black rounded-lg cursor-pointer 7 | } 8 | 9 | .btn-sm { 10 | @apply py-1 px-3 11 | } 12 | 13 | .btn-black { 14 | @apply bg-black text-white hover:bg-gray-800 15 | } 16 | -------------------------------------------------------------------------------- /cmd/app/engine.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "html/template" 5 | "os" 6 | "path/filepath" 7 | 8 | "github.com/gofiber/template/django/v3" 9 | ) 10 | 11 | func createEngine() *django.Engine { 12 | engine := django.New("./views", ".html") 13 | engine.Reload(true) 14 | engine.AddFunc("css", func(name string) (res template.HTML) { 15 | filepath.Walk("public/assets", func(path string, info os.FileInfo, err error) error { 16 | if err != nil { 17 | return err 18 | } 19 | if info.Name() == name { 20 | res = template.HTML("") 21 | } 22 | return nil 23 | }) 24 | return 25 | }) 26 | return engine 27 | } 28 | -------------------------------------------------------------------------------- /cmd/app/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | 8 | "github.com/anthdm/bs/handlers" 9 | "github.com/anthdm/bs/util" 10 | "github.com/gofiber/fiber/v2" 11 | "github.com/joho/godotenv" 12 | ) 13 | 14 | func main() { 15 | if err := godotenv.Load(".env.local"); err != nil { 16 | log.Fatal(err) 17 | } 18 | 19 | app := fiber.New(fiber.Config{ 20 | ErrorHandler: handlers.ErrorHandler, 21 | DisableStartupMessage: true, 22 | PassLocalsToViews: true, 23 | Views: createEngine(), 24 | }) 25 | 26 | initRoutes(app) 27 | listenAddr := os.Getenv("HTTP_LISTEN_ADDR") 28 | fmt.Printf("app running in %s and listening on: http://127.0.0.1:%s\n", util.AppEnv(), listenAddr) 29 | log.Fatal(app.Listen(listenAddr)) 30 | } 31 | 32 | func initRoutes(app *fiber.App) { 33 | app.Static("/public", "./public") 34 | 35 | app.Use(handlers.FlashMiddleware) 36 | 37 | app.Get("/", handlers.HandleHome) 38 | app.Get("/bored", handlers.HandleBored) 39 | app.Get("/flash", handlers.HandleFlash) 40 | 41 | app.Use(handlers.NotFoundMiddleware) 42 | } 43 | -------------------------------------------------------------------------------- /data/todo.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | type Todo struct { 4 | ID int64 `bun:",pk,autoincrement"` 5 | Title string 6 | Description string 7 | } 8 | -------------------------------------------------------------------------------- /db/db.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | "os" 7 | "sync" 8 | 9 | "github.com/anthdm/bs/util" 10 | _ "github.com/lib/pq" 11 | 12 | "github.com/uptrace/bun" 13 | "github.com/uptrace/bun/dialect/pgdialect" 14 | "github.com/uptrace/bun/driver/pgdriver" 15 | "github.com/uptrace/bun/extra/bundebug" 16 | ) 17 | 18 | var Bun *bun.DB 19 | 20 | func Init() { 21 | var ( 22 | user = os.Getenv("DB_USER") 23 | password = os.Getenv("DB_PASSWORD") 24 | host = os.Getenv("DB_HOST") 25 | name = os.Getenv("DB_NAME") 26 | uri = fmt.Sprintf("postgresql://%s:%s@%s/%s", user, password, host, name) 27 | sqldb = sql.OpenDB(pgdriver.NewConnector(pgdriver.WithDSN(uri))) 28 | once = sync.Once{} 29 | ) 30 | fmt.Println(uri) 31 | once.Do(func() { 32 | Bun = bun.NewDB(sqldb, pgdialect.New()) 33 | if util.IsDev() { 34 | Bun.AddQueryHook(bundebug.NewQueryHook(bundebug.WithVerbose(true))) 35 | } 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/anthdm/bs 2 | 3 | go 1.20 4 | 5 | require ( 6 | github.com/gofiber/fiber/v2 v2.47.0 7 | github.com/gofiber/template/django/v3 v3.1.4 8 | github.com/joho/godotenv v1.5.1 9 | ) 10 | 11 | require ( 12 | github.com/andybalholm/brotli v1.0.5 // indirect 13 | github.com/fatih/color v1.15.0 // indirect 14 | github.com/flosch/pongo2/v6 v6.0.0 // indirect 15 | github.com/gofiber/template v1.8.2 // indirect 16 | github.com/gofiber/utils v1.1.0 // indirect 17 | github.com/google/uuid v1.3.0 // indirect 18 | github.com/jinzhu/inflection v1.0.0 // indirect 19 | github.com/klauspost/compress v1.16.5 // indirect 20 | github.com/lib/pq v1.10.9 21 | github.com/mattn/go-colorable v0.1.13 // indirect 22 | github.com/mattn/go-isatty v0.0.19 // indirect 23 | github.com/mattn/go-runewidth v0.0.14 // indirect 24 | github.com/philhofer/fwd v1.1.2 // indirect 25 | github.com/rivo/uniseg v0.2.0 // indirect 26 | github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 // indirect 27 | github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect 28 | github.com/sujit-baniya/flash v0.1.8 29 | github.com/tinylib/msgp v1.1.8 // indirect 30 | github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect 31 | github.com/uptrace/bun v1.1.14 32 | github.com/uptrace/bun/dialect/pgdialect v1.1.14 33 | github.com/uptrace/bun/driver/pgdriver v1.1.14 34 | github.com/uptrace/bun/extra/bundebug v1.1.14 35 | github.com/valyala/bytebufferpool v1.0.0 // indirect 36 | github.com/valyala/fasthttp v1.47.0 // indirect 37 | github.com/valyala/tcplisten v1.0.0 // indirect 38 | github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect 39 | github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect 40 | golang.org/x/crypto v0.9.0 // indirect 41 | golang.org/x/sys v0.9.0 // indirect 42 | mellium.im/sasl v0.3.1 // indirect 43 | ) 44 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= 2 | github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= 3 | github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= 4 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 6 | github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= 7 | github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= 8 | github.com/flosch/pongo2/v6 v6.0.0 h1:lsGru8IAzHgIAw6H2m4PCyleO58I40ow6apih0WprMU= 9 | github.com/flosch/pongo2/v6 v6.0.0/go.mod h1:CuDpFm47R0uGGE7z13/tTlt1Y6zdxvr2RLT5LJhsHEU= 10 | github.com/gofiber/fiber/v2 v2.36.0/go.mod h1:tgCr+lierLwLoVHHO/jn3Niannv34WRkQETU8wiL9fQ= 11 | github.com/gofiber/fiber/v2 v2.47.0 h1:EN5lHVCc+Pyqh5OEsk8fzRiifgwpbrP0rulQ4iNf3fs= 12 | github.com/gofiber/fiber/v2 v2.47.0/go.mod h1:mbFMVN1lQuzziTkkakgtKKdjfsXSw9BKR5lmcNksUoU= 13 | github.com/gofiber/template v1.8.2 h1:PIv9s/7Uq6m+Fm2MDNd20pAFFKt5wWs7ZBd8iV9pWwk= 14 | github.com/gofiber/template v1.8.2/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8= 15 | github.com/gofiber/template/django/v3 v3.1.4 h1:NezHw7E4ZphLfd1hn8xq+nWmgXZhYwXGmifLhHNogyQ= 16 | github.com/gofiber/template/django/v3 v3.1.4/go.mod h1:LfBp8rLiEirKt20NPOmWNR2BexbRFKOuGqvT8FFYjeY= 17 | github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM= 18 | github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0= 19 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 20 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 21 | github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= 22 | github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= 23 | github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= 24 | github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= 25 | github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= 26 | github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= 27 | github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= 28 | github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= 29 | github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= 30 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 31 | github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= 32 | github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= 33 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 34 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 35 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 36 | github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= 37 | github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 38 | github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= 39 | github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 40 | github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= 41 | github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= 42 | github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= 43 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 44 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 45 | github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= 46 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 47 | github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 h1:rmMl4fXJhKMNWl+K+r/fq4FbbKI+Ia2m9hYBLm2h4G4= 48 | github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94/go.mod h1:90zrgN3D/WJsDd1iXHT96alCoN2KJo6/4x1DZC3wZs8= 49 | github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d/go.mod h1:Gy+0tqhJvgGlqnTF8CVGP0AaGRjwBtXs/a5PA0Y3+A4= 50 | github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee h1:8Iv5m6xEo1NR1AvpV+7XmhI4r39LGNzwUL4YpMuL5vk= 51 | github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g= 52 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 53 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 54 | github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= 55 | github.com/sujit-baniya/flash v0.1.8 h1:BwcrybCatPU30VMA9IBA5q3ZE0VSr5c7qTqwZrSvyRI= 56 | github.com/sujit-baniya/flash v0.1.8/go.mod h1:kmlAIkLDMlLshEeeE6fETEW8kSOopKN5WA3KXLmS/U0= 57 | github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw= 58 | github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0= 59 | github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw= 60 | github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= 61 | github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= 62 | github.com/uptrace/bun v1.1.14 h1:S5vvNnjEynJ0CvnrBOD7MIRW7q/WbtvFXrdfy0lddAM= 63 | github.com/uptrace/bun v1.1.14/go.mod h1:RHk6DrIisO62dv10pUOJCz5MphXThuOTpVNYEYv7NI8= 64 | github.com/uptrace/bun/dialect/pgdialect v1.1.14 h1:b7+V1KDJPQSFYgkG/6YLXCl2uvwEY3kf/GSM7hTHRDY= 65 | github.com/uptrace/bun/dialect/pgdialect v1.1.14/go.mod h1:v6YiaXmnKQ2FlhRD2c0ZfKd+QXH09pYn4H8ojaavkKk= 66 | github.com/uptrace/bun/driver/pgdriver v1.1.14 h1:V2Etm7mLGS3mhx8ddxZcUnwZLX02Jmq9JTlo0sNVDhA= 67 | github.com/uptrace/bun/driver/pgdriver v1.1.14/go.mod h1:D4FjWV9arDYct6sjMJhFoyU71SpllZRHXFRRP2Kd0Kw= 68 | github.com/uptrace/bun/extra/bundebug v1.1.14 h1:9OCGfP9ZDlh41u6OLerWdhBtJAVGXHr0xtxO4xWi6t0= 69 | github.com/uptrace/bun/extra/bundebug v1.1.14/go.mod h1:lto3guzS2v6mnQp1+akyE+ecBLOltevDDe324NXEYdw= 70 | github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= 71 | github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= 72 | github.com/valyala/fasthttp v1.38.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= 73 | github.com/valyala/fasthttp v1.47.0 h1:y7moDoxYzMooFpT5aHgNgVOQDrS3qlkfiP9mDtGGK9c= 74 | github.com/valyala/fasthttp v1.47.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= 75 | github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= 76 | github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= 77 | github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= 78 | github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= 79 | github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= 80 | github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= 81 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 82 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 83 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 84 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 85 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 86 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 87 | golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 88 | golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= 89 | golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= 90 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 91 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 92 | golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 93 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 94 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 95 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 96 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 97 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 98 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 99 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 100 | golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= 101 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 102 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 103 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 104 | golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 105 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 106 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 107 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 108 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 109 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 110 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 111 | golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 112 | golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 113 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 114 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 115 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 116 | golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 117 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 118 | golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= 119 | golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 120 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 121 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 122 | golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= 123 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 124 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 125 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 126 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 127 | golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 128 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 129 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 130 | golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 131 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 132 | golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= 133 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 134 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 135 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 136 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 137 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 138 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 139 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 140 | mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo= 141 | mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw= 142 | -------------------------------------------------------------------------------- /handlers/error.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "github.com/gofiber/fiber/v2" 5 | ) 6 | 7 | func ErrorHandler(c *fiber.Ctx, err error) error { 8 | return c.Render("error/500", nil) 9 | } 10 | -------------------------------------------------------------------------------- /handlers/home.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "github.com/gofiber/fiber/v2" 5 | "github.com/sujit-baniya/flash" 6 | ) 7 | 8 | func HandleHome(c *fiber.Ctx) error { 9 | return c.Render("home/index", fiber.Map{}) 10 | } 11 | 12 | func HandleBored(c *fiber.Ctx) error { 13 | return c.Render("home/bored", fiber.Map{}) 14 | } 15 | 16 | func HandleFlash(c *fiber.Ctx) error { 17 | context := fiber.Map{ 18 | "systemMessage": "a flash message for you user", 19 | } 20 | return flash.WithData(c, context).RedirectBack("/") 21 | } 22 | -------------------------------------------------------------------------------- /handlers/middleware.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gofiber/fiber/v2" 7 | "github.com/sujit-baniya/flash" 8 | ) 9 | 10 | func NotFoundMiddleware(c *fiber.Ctx) error { 11 | return c.Status(http.StatusNotFound).Render("error/404", nil) 12 | } 13 | 14 | func FlashMiddleware(c *fiber.Ctx) error { 15 | c.Locals("flash", flash.Get(c)) 16 | return c.Next() 17 | } 18 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "The bored stack", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "name": "The bored stack", 8 | "devDependencies": { 9 | "daisyui": "^3.1.7", 10 | "tailwindcss": "3.3.2" 11 | } 12 | }, 13 | "node_modules/@alloc/quick-lru": { 14 | "version": "5.2.0", 15 | "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", 16 | "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", 17 | "dev": true, 18 | "engines": { 19 | "node": ">=10" 20 | }, 21 | "funding": { 22 | "url": "https://github.com/sponsors/sindresorhus" 23 | } 24 | }, 25 | "node_modules/@jridgewell/gen-mapping": { 26 | "version": "0.3.3", 27 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", 28 | "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", 29 | "dev": true, 30 | "dependencies": { 31 | "@jridgewell/set-array": "^1.0.1", 32 | "@jridgewell/sourcemap-codec": "^1.4.10", 33 | "@jridgewell/trace-mapping": "^0.3.9" 34 | }, 35 | "engines": { 36 | "node": ">=6.0.0" 37 | } 38 | }, 39 | "node_modules/@jridgewell/resolve-uri": { 40 | "version": "3.1.0", 41 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", 42 | "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", 43 | "dev": true, 44 | "engines": { 45 | "node": ">=6.0.0" 46 | } 47 | }, 48 | "node_modules/@jridgewell/set-array": { 49 | "version": "1.1.2", 50 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", 51 | "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", 52 | "dev": true, 53 | "engines": { 54 | "node": ">=6.0.0" 55 | } 56 | }, 57 | "node_modules/@jridgewell/sourcemap-codec": { 58 | "version": "1.4.15", 59 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 60 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 61 | "dev": true 62 | }, 63 | "node_modules/@jridgewell/trace-mapping": { 64 | "version": "0.3.18", 65 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", 66 | "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", 67 | "dev": true, 68 | "dependencies": { 69 | "@jridgewell/resolve-uri": "3.1.0", 70 | "@jridgewell/sourcemap-codec": "1.4.14" 71 | } 72 | }, 73 | "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { 74 | "version": "1.4.14", 75 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", 76 | "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", 77 | "dev": true 78 | }, 79 | "node_modules/@nodelib/fs.scandir": { 80 | "version": "2.1.5", 81 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 82 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 83 | "dev": true, 84 | "dependencies": { 85 | "@nodelib/fs.stat": "2.0.5", 86 | "run-parallel": "^1.1.9" 87 | }, 88 | "engines": { 89 | "node": ">= 8" 90 | } 91 | }, 92 | "node_modules/@nodelib/fs.stat": { 93 | "version": "2.0.5", 94 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 95 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 96 | "dev": true, 97 | "engines": { 98 | "node": ">= 8" 99 | } 100 | }, 101 | "node_modules/@nodelib/fs.walk": { 102 | "version": "1.2.8", 103 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 104 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 105 | "dev": true, 106 | "dependencies": { 107 | "@nodelib/fs.scandir": "2.1.5", 108 | "fastq": "^1.6.0" 109 | }, 110 | "engines": { 111 | "node": ">= 8" 112 | } 113 | }, 114 | "node_modules/any-promise": { 115 | "version": "1.3.0", 116 | "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", 117 | "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", 118 | "dev": true 119 | }, 120 | "node_modules/anymatch": { 121 | "version": "3.1.3", 122 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", 123 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", 124 | "dev": true, 125 | "dependencies": { 126 | "normalize-path": "^3.0.0", 127 | "picomatch": "^2.0.4" 128 | }, 129 | "engines": { 130 | "node": ">= 8" 131 | } 132 | }, 133 | "node_modules/arg": { 134 | "version": "5.0.2", 135 | "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", 136 | "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", 137 | "dev": true 138 | }, 139 | "node_modules/balanced-match": { 140 | "version": "1.0.2", 141 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 142 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 143 | "dev": true 144 | }, 145 | "node_modules/binary-extensions": { 146 | "version": "2.2.0", 147 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 148 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 149 | "dev": true, 150 | "engines": { 151 | "node": ">=8" 152 | } 153 | }, 154 | "node_modules/brace-expansion": { 155 | "version": "1.1.11", 156 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 157 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 158 | "dev": true, 159 | "dependencies": { 160 | "balanced-match": "^1.0.0", 161 | "concat-map": "0.0.1" 162 | } 163 | }, 164 | "node_modules/braces": { 165 | "version": "3.0.2", 166 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 167 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 168 | "dev": true, 169 | "dependencies": { 170 | "fill-range": "^7.0.1" 171 | }, 172 | "engines": { 173 | "node": ">=8" 174 | } 175 | }, 176 | "node_modules/camelcase-css": { 177 | "version": "2.0.1", 178 | "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", 179 | "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", 180 | "dev": true, 181 | "engines": { 182 | "node": ">= 6" 183 | } 184 | }, 185 | "node_modules/chokidar": { 186 | "version": "3.5.3", 187 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 188 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 189 | "dev": true, 190 | "funding": [ 191 | { 192 | "type": "individual", 193 | "url": "https://paulmillr.com/funding/" 194 | } 195 | ], 196 | "dependencies": { 197 | "anymatch": "~3.1.2", 198 | "braces": "~3.0.2", 199 | "glob-parent": "~5.1.2", 200 | "is-binary-path": "~2.1.0", 201 | "is-glob": "~4.0.1", 202 | "normalize-path": "~3.0.0", 203 | "readdirp": "~3.6.0" 204 | }, 205 | "engines": { 206 | "node": ">= 8.10.0" 207 | }, 208 | "optionalDependencies": { 209 | "fsevents": "~2.3.2" 210 | } 211 | }, 212 | "node_modules/chokidar/node_modules/glob-parent": { 213 | "version": "5.1.2", 214 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 215 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 216 | "dev": true, 217 | "dependencies": { 218 | "is-glob": "^4.0.1" 219 | }, 220 | "engines": { 221 | "node": ">= 6" 222 | } 223 | }, 224 | "node_modules/colord": { 225 | "version": "2.9.3", 226 | "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", 227 | "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", 228 | "dev": true 229 | }, 230 | "node_modules/commander": { 231 | "version": "4.1.1", 232 | "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", 233 | "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", 234 | "dev": true, 235 | "engines": { 236 | "node": ">= 6" 237 | } 238 | }, 239 | "node_modules/concat-map": { 240 | "version": "0.0.1", 241 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 242 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 243 | "dev": true 244 | }, 245 | "node_modules/css-selector-tokenizer": { 246 | "version": "0.8.0", 247 | "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz", 248 | "integrity": "sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==", 249 | "dev": true, 250 | "dependencies": { 251 | "cssesc": "^3.0.0", 252 | "fastparse": "^1.1.2" 253 | } 254 | }, 255 | "node_modules/cssesc": { 256 | "version": "3.0.0", 257 | "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", 258 | "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", 259 | "dev": true, 260 | "bin": { 261 | "cssesc": "bin/cssesc" 262 | }, 263 | "engines": { 264 | "node": ">=4" 265 | } 266 | }, 267 | "node_modules/daisyui": { 268 | "version": "3.2.1", 269 | "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-3.2.1.tgz", 270 | "integrity": "sha512-gIqE6wiqoJt9G8+n3R/SwLeUnpNCE2eDhT73rP0yZYVaM7o6zVcakBH3aEW5RGpx3UkonPiLuvcgxRcb2lE8TA==", 271 | "dev": true, 272 | "dependencies": { 273 | "colord": "^2.9", 274 | "css-selector-tokenizer": "^0.8", 275 | "postcss": "^8", 276 | "postcss-js": "^4", 277 | "tailwindcss": "^3" 278 | }, 279 | "engines": { 280 | "node": ">=16.9.0" 281 | }, 282 | "funding": { 283 | "type": "opencollective", 284 | "url": "https://opencollective.com/daisyui" 285 | } 286 | }, 287 | "node_modules/didyoumean": { 288 | "version": "1.2.2", 289 | "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", 290 | "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", 291 | "dev": true 292 | }, 293 | "node_modules/dlv": { 294 | "version": "1.1.3", 295 | "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", 296 | "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", 297 | "dev": true 298 | }, 299 | "node_modules/fast-glob": { 300 | "version": "3.3.0", 301 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", 302 | "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", 303 | "dev": true, 304 | "dependencies": { 305 | "@nodelib/fs.stat": "^2.0.2", 306 | "@nodelib/fs.walk": "^1.2.3", 307 | "glob-parent": "^5.1.2", 308 | "merge2": "^1.3.0", 309 | "micromatch": "^4.0.4" 310 | }, 311 | "engines": { 312 | "node": ">=8.6.0" 313 | } 314 | }, 315 | "node_modules/fast-glob/node_modules/glob-parent": { 316 | "version": "5.1.2", 317 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 318 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 319 | "dev": true, 320 | "dependencies": { 321 | "is-glob": "^4.0.1" 322 | }, 323 | "engines": { 324 | "node": ">= 6" 325 | } 326 | }, 327 | "node_modules/fastparse": { 328 | "version": "1.1.2", 329 | "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", 330 | "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", 331 | "dev": true 332 | }, 333 | "node_modules/fastq": { 334 | "version": "1.15.0", 335 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", 336 | "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", 337 | "dev": true, 338 | "dependencies": { 339 | "reusify": "^1.0.4" 340 | } 341 | }, 342 | "node_modules/fill-range": { 343 | "version": "7.0.1", 344 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 345 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 346 | "dev": true, 347 | "dependencies": { 348 | "to-regex-range": "^5.0.1" 349 | }, 350 | "engines": { 351 | "node": ">=8" 352 | } 353 | }, 354 | "node_modules/fs.realpath": { 355 | "version": "1.0.0", 356 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 357 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 358 | "dev": true 359 | }, 360 | "node_modules/fsevents": { 361 | "version": "2.3.2", 362 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 363 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 364 | "dev": true, 365 | "hasInstallScript": true, 366 | "optional": true, 367 | "os": [ 368 | "darwin" 369 | ], 370 | "engines": { 371 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 372 | } 373 | }, 374 | "node_modules/function-bind": { 375 | "version": "1.1.1", 376 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 377 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 378 | "dev": true 379 | }, 380 | "node_modules/glob": { 381 | "version": "7.1.6", 382 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 383 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 384 | "dev": true, 385 | "dependencies": { 386 | "fs.realpath": "^1.0.0", 387 | "inflight": "^1.0.4", 388 | "inherits": "2", 389 | "minimatch": "^3.0.4", 390 | "once": "^1.3.0", 391 | "path-is-absolute": "^1.0.0" 392 | }, 393 | "engines": { 394 | "node": "*" 395 | }, 396 | "funding": { 397 | "url": "https://github.com/sponsors/isaacs" 398 | } 399 | }, 400 | "node_modules/glob-parent": { 401 | "version": "6.0.2", 402 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 403 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 404 | "dev": true, 405 | "dependencies": { 406 | "is-glob": "^4.0.3" 407 | }, 408 | "engines": { 409 | "node": ">=10.13.0" 410 | } 411 | }, 412 | "node_modules/has": { 413 | "version": "1.0.3", 414 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 415 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 416 | "dev": true, 417 | "dependencies": { 418 | "function-bind": "^1.1.1" 419 | }, 420 | "engines": { 421 | "node": ">= 0.4.0" 422 | } 423 | }, 424 | "node_modules/inflight": { 425 | "version": "1.0.6", 426 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 427 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 428 | "dev": true, 429 | "dependencies": { 430 | "once": "^1.3.0", 431 | "wrappy": "1" 432 | } 433 | }, 434 | "node_modules/inherits": { 435 | "version": "2.0.4", 436 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 437 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 438 | "dev": true 439 | }, 440 | "node_modules/is-binary-path": { 441 | "version": "2.1.0", 442 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 443 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 444 | "dev": true, 445 | "dependencies": { 446 | "binary-extensions": "^2.0.0" 447 | }, 448 | "engines": { 449 | "node": ">=8" 450 | } 451 | }, 452 | "node_modules/is-core-module": { 453 | "version": "2.12.1", 454 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", 455 | "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", 456 | "dev": true, 457 | "dependencies": { 458 | "has": "^1.0.3" 459 | }, 460 | "funding": { 461 | "url": "https://github.com/sponsors/ljharb" 462 | } 463 | }, 464 | "node_modules/is-extglob": { 465 | "version": "2.1.1", 466 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 467 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 468 | "dev": true, 469 | "engines": { 470 | "node": ">=0.10.0" 471 | } 472 | }, 473 | "node_modules/is-glob": { 474 | "version": "4.0.3", 475 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 476 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 477 | "dev": true, 478 | "dependencies": { 479 | "is-extglob": "^2.1.1" 480 | }, 481 | "engines": { 482 | "node": ">=0.10.0" 483 | } 484 | }, 485 | "node_modules/is-number": { 486 | "version": "7.0.0", 487 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 488 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 489 | "dev": true, 490 | "engines": { 491 | "node": ">=0.12.0" 492 | } 493 | }, 494 | "node_modules/jiti": { 495 | "version": "1.19.1", 496 | "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.1.tgz", 497 | "integrity": "sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg==", 498 | "dev": true, 499 | "bin": { 500 | "jiti": "bin/jiti.js" 501 | } 502 | }, 503 | "node_modules/lilconfig": { 504 | "version": "2.1.0", 505 | "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", 506 | "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", 507 | "dev": true, 508 | "engines": { 509 | "node": ">=10" 510 | } 511 | }, 512 | "node_modules/lines-and-columns": { 513 | "version": "1.2.4", 514 | "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", 515 | "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", 516 | "dev": true 517 | }, 518 | "node_modules/merge2": { 519 | "version": "1.4.1", 520 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 521 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 522 | "dev": true, 523 | "engines": { 524 | "node": ">= 8" 525 | } 526 | }, 527 | "node_modules/micromatch": { 528 | "version": "4.0.5", 529 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", 530 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", 531 | "dev": true, 532 | "dependencies": { 533 | "braces": "^3.0.2", 534 | "picomatch": "^2.3.1" 535 | }, 536 | "engines": { 537 | "node": ">=8.6" 538 | } 539 | }, 540 | "node_modules/minimatch": { 541 | "version": "3.1.2", 542 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 543 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 544 | "dev": true, 545 | "dependencies": { 546 | "brace-expansion": "^1.1.7" 547 | }, 548 | "engines": { 549 | "node": "*" 550 | } 551 | }, 552 | "node_modules/mz": { 553 | "version": "2.7.0", 554 | "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", 555 | "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", 556 | "dev": true, 557 | "dependencies": { 558 | "any-promise": "^1.0.0", 559 | "object-assign": "^4.0.1", 560 | "thenify-all": "^1.0.0" 561 | } 562 | }, 563 | "node_modules/nanoid": { 564 | "version": "3.3.6", 565 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", 566 | "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", 567 | "dev": true, 568 | "funding": [ 569 | { 570 | "type": "github", 571 | "url": "https://github.com/sponsors/ai" 572 | } 573 | ], 574 | "bin": { 575 | "nanoid": "bin/nanoid.cjs" 576 | }, 577 | "engines": { 578 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 579 | } 580 | }, 581 | "node_modules/normalize-path": { 582 | "version": "3.0.0", 583 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 584 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 585 | "dev": true, 586 | "engines": { 587 | "node": ">=0.10.0" 588 | } 589 | }, 590 | "node_modules/object-assign": { 591 | "version": "4.1.1", 592 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 593 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 594 | "dev": true, 595 | "engines": { 596 | "node": ">=0.10.0" 597 | } 598 | }, 599 | "node_modules/object-hash": { 600 | "version": "3.0.0", 601 | "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", 602 | "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", 603 | "dev": true, 604 | "engines": { 605 | "node": ">= 6" 606 | } 607 | }, 608 | "node_modules/once": { 609 | "version": "1.4.0", 610 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 611 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 612 | "dev": true, 613 | "dependencies": { 614 | "wrappy": "1" 615 | } 616 | }, 617 | "node_modules/path-is-absolute": { 618 | "version": "1.0.1", 619 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 620 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 621 | "dev": true, 622 | "engines": { 623 | "node": ">=0.10.0" 624 | } 625 | }, 626 | "node_modules/path-parse": { 627 | "version": "1.0.7", 628 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 629 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 630 | "dev": true 631 | }, 632 | "node_modules/picocolors": { 633 | "version": "1.0.0", 634 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 635 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 636 | "dev": true 637 | }, 638 | "node_modules/picomatch": { 639 | "version": "2.3.1", 640 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 641 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 642 | "dev": true, 643 | "engines": { 644 | "node": ">=8.6" 645 | }, 646 | "funding": { 647 | "url": "https://github.com/sponsors/jonschlinkert" 648 | } 649 | }, 650 | "node_modules/pify": { 651 | "version": "2.3.0", 652 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 653 | "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", 654 | "dev": true, 655 | "engines": { 656 | "node": ">=0.10.0" 657 | } 658 | }, 659 | "node_modules/pirates": { 660 | "version": "4.0.6", 661 | "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", 662 | "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", 663 | "dev": true, 664 | "engines": { 665 | "node": ">= 6" 666 | } 667 | }, 668 | "node_modules/postcss": { 669 | "version": "8.4.25", 670 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.25.tgz", 671 | "integrity": "sha512-7taJ/8t2av0Z+sQEvNzCkpDynl0tX3uJMCODi6nT3PfASC7dYCWV9aQ+uiCf+KBD4SEFcu+GvJdGdwzQ6OSjCw==", 672 | "dev": true, 673 | "funding": [ 674 | { 675 | "type": "opencollective", 676 | "url": "https://opencollective.com/postcss/" 677 | }, 678 | { 679 | "type": "tidelift", 680 | "url": "https://tidelift.com/funding/github/npm/postcss" 681 | }, 682 | { 683 | "type": "github", 684 | "url": "https://github.com/sponsors/ai" 685 | } 686 | ], 687 | "dependencies": { 688 | "nanoid": "^3.3.6", 689 | "picocolors": "^1.0.0", 690 | "source-map-js": "^1.0.2" 691 | }, 692 | "engines": { 693 | "node": "^10 || ^12 || >=14" 694 | } 695 | }, 696 | "node_modules/postcss-import": { 697 | "version": "15.1.0", 698 | "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", 699 | "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", 700 | "dev": true, 701 | "dependencies": { 702 | "postcss-value-parser": "^4.0.0", 703 | "read-cache": "^1.0.0", 704 | "resolve": "^1.1.7" 705 | }, 706 | "engines": { 707 | "node": ">=14.0.0" 708 | }, 709 | "peerDependencies": { 710 | "postcss": "^8.0.0" 711 | } 712 | }, 713 | "node_modules/postcss-js": { 714 | "version": "4.0.1", 715 | "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", 716 | "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", 717 | "dev": true, 718 | "dependencies": { 719 | "camelcase-css": "^2.0.1" 720 | }, 721 | "engines": { 722 | "node": "^12 || ^14 || >= 16" 723 | }, 724 | "funding": { 725 | "type": "opencollective", 726 | "url": "https://opencollective.com/postcss/" 727 | }, 728 | "peerDependencies": { 729 | "postcss": "^8.4.21" 730 | } 731 | }, 732 | "node_modules/postcss-load-config": { 733 | "version": "4.0.1", 734 | "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", 735 | "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", 736 | "dev": true, 737 | "dependencies": { 738 | "lilconfig": "^2.0.5", 739 | "yaml": "^2.1.1" 740 | }, 741 | "engines": { 742 | "node": ">= 14" 743 | }, 744 | "funding": { 745 | "type": "opencollective", 746 | "url": "https://opencollective.com/postcss/" 747 | }, 748 | "peerDependencies": { 749 | "postcss": ">=8.0.9", 750 | "ts-node": ">=9.0.0" 751 | }, 752 | "peerDependenciesMeta": { 753 | "postcss": { 754 | "optional": true 755 | }, 756 | "ts-node": { 757 | "optional": true 758 | } 759 | } 760 | }, 761 | "node_modules/postcss-nested": { 762 | "version": "6.0.1", 763 | "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", 764 | "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", 765 | "dev": true, 766 | "dependencies": { 767 | "postcss-selector-parser": "^6.0.11" 768 | }, 769 | "engines": { 770 | "node": ">=12.0" 771 | }, 772 | "funding": { 773 | "type": "opencollective", 774 | "url": "https://opencollective.com/postcss/" 775 | }, 776 | "peerDependencies": { 777 | "postcss": "^8.2.14" 778 | } 779 | }, 780 | "node_modules/postcss-selector-parser": { 781 | "version": "6.0.13", 782 | "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", 783 | "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", 784 | "dev": true, 785 | "dependencies": { 786 | "cssesc": "^3.0.0", 787 | "util-deprecate": "^1.0.2" 788 | }, 789 | "engines": { 790 | "node": ">=4" 791 | } 792 | }, 793 | "node_modules/postcss-value-parser": { 794 | "version": "4.2.0", 795 | "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", 796 | "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", 797 | "dev": true 798 | }, 799 | "node_modules/queue-microtask": { 800 | "version": "1.2.3", 801 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 802 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 803 | "dev": true, 804 | "funding": [ 805 | { 806 | "type": "github", 807 | "url": "https://github.com/sponsors/feross" 808 | }, 809 | { 810 | "type": "patreon", 811 | "url": "https://www.patreon.com/feross" 812 | }, 813 | { 814 | "type": "consulting", 815 | "url": "https://feross.org/support" 816 | } 817 | ] 818 | }, 819 | "node_modules/read-cache": { 820 | "version": "1.0.0", 821 | "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", 822 | "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", 823 | "dev": true, 824 | "dependencies": { 825 | "pify": "^2.3.0" 826 | } 827 | }, 828 | "node_modules/readdirp": { 829 | "version": "3.6.0", 830 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 831 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 832 | "dev": true, 833 | "dependencies": { 834 | "picomatch": "^2.2.1" 835 | }, 836 | "engines": { 837 | "node": ">=8.10.0" 838 | } 839 | }, 840 | "node_modules/resolve": { 841 | "version": "1.22.2", 842 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", 843 | "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", 844 | "dev": true, 845 | "dependencies": { 846 | "is-core-module": "^2.11.0", 847 | "path-parse": "^1.0.7", 848 | "supports-preserve-symlinks-flag": "^1.0.0" 849 | }, 850 | "bin": { 851 | "resolve": "bin/resolve" 852 | }, 853 | "funding": { 854 | "url": "https://github.com/sponsors/ljharb" 855 | } 856 | }, 857 | "node_modules/reusify": { 858 | "version": "1.0.4", 859 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 860 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 861 | "dev": true, 862 | "engines": { 863 | "iojs": ">=1.0.0", 864 | "node": ">=0.10.0" 865 | } 866 | }, 867 | "node_modules/run-parallel": { 868 | "version": "1.2.0", 869 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 870 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 871 | "dev": true, 872 | "funding": [ 873 | { 874 | "type": "github", 875 | "url": "https://github.com/sponsors/feross" 876 | }, 877 | { 878 | "type": "patreon", 879 | "url": "https://www.patreon.com/feross" 880 | }, 881 | { 882 | "type": "consulting", 883 | "url": "https://feross.org/support" 884 | } 885 | ], 886 | "dependencies": { 887 | "queue-microtask": "^1.2.2" 888 | } 889 | }, 890 | "node_modules/source-map-js": { 891 | "version": "1.0.2", 892 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 893 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 894 | "dev": true, 895 | "engines": { 896 | "node": ">=0.10.0" 897 | } 898 | }, 899 | "node_modules/sucrase": { 900 | "version": "3.32.0", 901 | "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz", 902 | "integrity": "sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==", 903 | "dev": true, 904 | "dependencies": { 905 | "@jridgewell/gen-mapping": "^0.3.2", 906 | "commander": "^4.0.0", 907 | "glob": "7.1.6", 908 | "lines-and-columns": "^1.1.6", 909 | "mz": "^2.7.0", 910 | "pirates": "^4.0.1", 911 | "ts-interface-checker": "^0.1.9" 912 | }, 913 | "bin": { 914 | "sucrase": "bin/sucrase", 915 | "sucrase-node": "bin/sucrase-node" 916 | }, 917 | "engines": { 918 | "node": ">=8" 919 | } 920 | }, 921 | "node_modules/supports-preserve-symlinks-flag": { 922 | "version": "1.0.0", 923 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 924 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 925 | "dev": true, 926 | "engines": { 927 | "node": ">= 0.4" 928 | }, 929 | "funding": { 930 | "url": "https://github.com/sponsors/ljharb" 931 | } 932 | }, 933 | "node_modules/tailwindcss": { 934 | "version": "3.3.2", 935 | "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.2.tgz", 936 | "integrity": "sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w==", 937 | "dev": true, 938 | "dependencies": { 939 | "@alloc/quick-lru": "^5.2.0", 940 | "arg": "^5.0.2", 941 | "chokidar": "^3.5.3", 942 | "didyoumean": "^1.2.2", 943 | "dlv": "^1.1.3", 944 | "fast-glob": "^3.2.12", 945 | "glob-parent": "^6.0.2", 946 | "is-glob": "^4.0.3", 947 | "jiti": "^1.18.2", 948 | "lilconfig": "^2.1.0", 949 | "micromatch": "^4.0.5", 950 | "normalize-path": "^3.0.0", 951 | "object-hash": "^3.0.0", 952 | "picocolors": "^1.0.0", 953 | "postcss": "^8.4.23", 954 | "postcss-import": "^15.1.0", 955 | "postcss-js": "^4.0.1", 956 | "postcss-load-config": "^4.0.1", 957 | "postcss-nested": "^6.0.1", 958 | "postcss-selector-parser": "^6.0.11", 959 | "postcss-value-parser": "^4.2.0", 960 | "resolve": "^1.22.2", 961 | "sucrase": "^3.32.0" 962 | }, 963 | "bin": { 964 | "tailwind": "lib/cli.js", 965 | "tailwindcss": "lib/cli.js" 966 | }, 967 | "engines": { 968 | "node": ">=14.0.0" 969 | } 970 | }, 971 | "node_modules/thenify": { 972 | "version": "3.3.1", 973 | "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", 974 | "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", 975 | "dev": true, 976 | "dependencies": { 977 | "any-promise": "^1.0.0" 978 | } 979 | }, 980 | "node_modules/thenify-all": { 981 | "version": "1.6.0", 982 | "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", 983 | "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", 984 | "dev": true, 985 | "dependencies": { 986 | "thenify": ">= 3.1.0 < 4" 987 | }, 988 | "engines": { 989 | "node": ">=0.8" 990 | } 991 | }, 992 | "node_modules/to-regex-range": { 993 | "version": "5.0.1", 994 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 995 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 996 | "dev": true, 997 | "dependencies": { 998 | "is-number": "^7.0.0" 999 | }, 1000 | "engines": { 1001 | "node": ">=8.0" 1002 | } 1003 | }, 1004 | "node_modules/ts-interface-checker": { 1005 | "version": "0.1.13", 1006 | "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", 1007 | "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", 1008 | "dev": true 1009 | }, 1010 | "node_modules/util-deprecate": { 1011 | "version": "1.0.2", 1012 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1013 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 1014 | "dev": true 1015 | }, 1016 | "node_modules/wrappy": { 1017 | "version": "1.0.2", 1018 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1019 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 1020 | "dev": true 1021 | }, 1022 | "node_modules/yaml": { 1023 | "version": "2.3.1", 1024 | "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", 1025 | "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", 1026 | "dev": true, 1027 | "engines": { 1028 | "node": ">= 14" 1029 | } 1030 | } 1031 | } 1032 | } 1033 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "The bored stack", 3 | "scripts": { 4 | "css": "tailwindcss -i ./assets/app.css -o ./public/assets/app.css --watch" 5 | }, 6 | "devDependencies": { 7 | "daisyui": "^3.1.7", 8 | "tailwindcss": "3.3.2" 9 | } 10 | } -------------------------------------------------------------------------------- /public/assets/app.css: -------------------------------------------------------------------------------- 1 | /* 2 | ! tailwindcss v3.3.2 | MIT License | https://tailwindcss.com 3 | */ 4 | 5 | /* 6 | 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) 7 | 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) 8 | */ 9 | 10 | *, 11 | ::before, 12 | ::after { 13 | box-sizing: border-box; 14 | /* 1 */ 15 | border-width: 0; 16 | /* 2 */ 17 | border-style: solid; 18 | /* 2 */ 19 | border-color: #e5e7eb; 20 | /* 2 */ 21 | } 22 | 23 | ::before, 24 | ::after { 25 | --tw-content: ''; 26 | } 27 | 28 | /* 29 | 1. Use a consistent sensible line-height in all browsers. 30 | 2. Prevent adjustments of font size after orientation changes in iOS. 31 | 3. Use a more readable tab size. 32 | 4. Use the user's configured `sans` font-family by default. 33 | 5. Use the user's configured `sans` font-feature-settings by default. 34 | 6. Use the user's configured `sans` font-variation-settings by default. 35 | */ 36 | 37 | html { 38 | line-height: 1.5; 39 | /* 1 */ 40 | -webkit-text-size-adjust: 100%; 41 | /* 2 */ 42 | -moz-tab-size: 4; 43 | /* 3 */ 44 | -o-tab-size: 4; 45 | tab-size: 4; 46 | /* 3 */ 47 | font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 48 | /* 4 */ 49 | font-feature-settings: normal; 50 | /* 5 */ 51 | font-variation-settings: normal; 52 | /* 6 */ 53 | } 54 | 55 | /* 56 | 1. Remove the margin in all browsers. 57 | 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. 58 | */ 59 | 60 | body { 61 | margin: 0; 62 | /* 1 */ 63 | line-height: inherit; 64 | /* 2 */ 65 | } 66 | 67 | /* 68 | 1. Add the correct height in Firefox. 69 | 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 70 | 3. Ensure horizontal rules are visible by default. 71 | */ 72 | 73 | hr { 74 | height: 0; 75 | /* 1 */ 76 | color: inherit; 77 | /* 2 */ 78 | border-top-width: 1px; 79 | /* 3 */ 80 | } 81 | 82 | /* 83 | Add the correct text decoration in Chrome, Edge, and Safari. 84 | */ 85 | 86 | abbr:where([title]) { 87 | -webkit-text-decoration: underline dotted; 88 | text-decoration: underline dotted; 89 | } 90 | 91 | /* 92 | Remove the default font size and weight for headings. 93 | */ 94 | 95 | h1, 96 | h2, 97 | h3, 98 | h4, 99 | h5, 100 | h6 { 101 | font-size: inherit; 102 | font-weight: inherit; 103 | } 104 | 105 | /* 106 | Reset links to optimize for opt-in styling instead of opt-out. 107 | */ 108 | 109 | a { 110 | color: inherit; 111 | text-decoration: inherit; 112 | } 113 | 114 | /* 115 | Add the correct font weight in Edge and Safari. 116 | */ 117 | 118 | b, 119 | strong { 120 | font-weight: bolder; 121 | } 122 | 123 | /* 124 | 1. Use the user's configured `mono` font family by default. 125 | 2. Correct the odd `em` font sizing in all browsers. 126 | */ 127 | 128 | code, 129 | kbd, 130 | samp, 131 | pre { 132 | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 133 | /* 1 */ 134 | font-size: 1em; 135 | /* 2 */ 136 | } 137 | 138 | /* 139 | Add the correct font size in all browsers. 140 | */ 141 | 142 | small { 143 | font-size: 80%; 144 | } 145 | 146 | /* 147 | Prevent `sub` and `sup` elements from affecting the line height in all browsers. 148 | */ 149 | 150 | sub, 151 | sup { 152 | font-size: 75%; 153 | line-height: 0; 154 | position: relative; 155 | vertical-align: baseline; 156 | } 157 | 158 | sub { 159 | bottom: -0.25em; 160 | } 161 | 162 | sup { 163 | top: -0.5em; 164 | } 165 | 166 | /* 167 | 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 168 | 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 169 | 3. Remove gaps between table borders by default. 170 | */ 171 | 172 | table { 173 | text-indent: 0; 174 | /* 1 */ 175 | border-color: inherit; 176 | /* 2 */ 177 | border-collapse: collapse; 178 | /* 3 */ 179 | } 180 | 181 | /* 182 | 1. Change the font styles in all browsers. 183 | 2. Remove the margin in Firefox and Safari. 184 | 3. Remove default padding in all browsers. 185 | */ 186 | 187 | button, 188 | input, 189 | optgroup, 190 | select, 191 | textarea { 192 | font-family: inherit; 193 | /* 1 */ 194 | font-size: 100%; 195 | /* 1 */ 196 | font-weight: inherit; 197 | /* 1 */ 198 | line-height: inherit; 199 | /* 1 */ 200 | color: inherit; 201 | /* 1 */ 202 | margin: 0; 203 | /* 2 */ 204 | padding: 0; 205 | /* 3 */ 206 | } 207 | 208 | /* 209 | Remove the inheritance of text transform in Edge and Firefox. 210 | */ 211 | 212 | button, 213 | select { 214 | text-transform: none; 215 | } 216 | 217 | /* 218 | 1. Correct the inability to style clickable types in iOS and Safari. 219 | 2. Remove default button styles. 220 | */ 221 | 222 | button, 223 | [type='button'], 224 | [type='reset'], 225 | [type='submit'] { 226 | -webkit-appearance: button; 227 | /* 1 */ 228 | background-color: transparent; 229 | /* 2 */ 230 | background-image: none; 231 | /* 2 */ 232 | } 233 | 234 | /* 235 | Use the modern Firefox focus style for all focusable elements. 236 | */ 237 | 238 | :-moz-focusring { 239 | outline: auto; 240 | } 241 | 242 | /* 243 | Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) 244 | */ 245 | 246 | :-moz-ui-invalid { 247 | box-shadow: none; 248 | } 249 | 250 | /* 251 | Add the correct vertical alignment in Chrome and Firefox. 252 | */ 253 | 254 | progress { 255 | vertical-align: baseline; 256 | } 257 | 258 | /* 259 | Correct the cursor style of increment and decrement buttons in Safari. 260 | */ 261 | 262 | ::-webkit-inner-spin-button, 263 | ::-webkit-outer-spin-button { 264 | height: auto; 265 | } 266 | 267 | /* 268 | 1. Correct the odd appearance in Chrome and Safari. 269 | 2. Correct the outline style in Safari. 270 | */ 271 | 272 | [type='search'] { 273 | -webkit-appearance: textfield; 274 | /* 1 */ 275 | outline-offset: -2px; 276 | /* 2 */ 277 | } 278 | 279 | /* 280 | Remove the inner padding in Chrome and Safari on macOS. 281 | */ 282 | 283 | ::-webkit-search-decoration { 284 | -webkit-appearance: none; 285 | } 286 | 287 | /* 288 | 1. Correct the inability to style clickable types in iOS and Safari. 289 | 2. Change font properties to `inherit` in Safari. 290 | */ 291 | 292 | ::-webkit-file-upload-button { 293 | -webkit-appearance: button; 294 | /* 1 */ 295 | font: inherit; 296 | /* 2 */ 297 | } 298 | 299 | /* 300 | Add the correct display in Chrome and Safari. 301 | */ 302 | 303 | summary { 304 | display: list-item; 305 | } 306 | 307 | /* 308 | Removes the default spacing and border for appropriate elements. 309 | */ 310 | 311 | blockquote, 312 | dl, 313 | dd, 314 | h1, 315 | h2, 316 | h3, 317 | h4, 318 | h5, 319 | h6, 320 | hr, 321 | figure, 322 | p, 323 | pre { 324 | margin: 0; 325 | } 326 | 327 | fieldset { 328 | margin: 0; 329 | padding: 0; 330 | } 331 | 332 | legend { 333 | padding: 0; 334 | } 335 | 336 | ol, 337 | ul, 338 | menu { 339 | list-style: none; 340 | margin: 0; 341 | padding: 0; 342 | } 343 | 344 | /* 345 | Prevent resizing textareas horizontally by default. 346 | */ 347 | 348 | textarea { 349 | resize: vertical; 350 | } 351 | 352 | /* 353 | 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) 354 | 2. Set the default placeholder color to the user's configured gray 400 color. 355 | */ 356 | 357 | input::-moz-placeholder, textarea::-moz-placeholder { 358 | opacity: 1; 359 | /* 1 */ 360 | color: #9ca3af; 361 | /* 2 */ 362 | } 363 | 364 | input::placeholder, 365 | textarea::placeholder { 366 | opacity: 1; 367 | /* 1 */ 368 | color: #9ca3af; 369 | /* 2 */ 370 | } 371 | 372 | /* 373 | Set the default cursor for buttons. 374 | */ 375 | 376 | button, 377 | [role="button"] { 378 | cursor: pointer; 379 | } 380 | 381 | /* 382 | Make sure disabled buttons don't get the pointer cursor. 383 | */ 384 | 385 | :disabled { 386 | cursor: default; 387 | } 388 | 389 | /* 390 | 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) 391 | 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) 392 | This can trigger a poorly considered lint error in some tools but is included by design. 393 | */ 394 | 395 | img, 396 | svg, 397 | video, 398 | canvas, 399 | audio, 400 | iframe, 401 | embed, 402 | object { 403 | display: block; 404 | /* 1 */ 405 | vertical-align: middle; 406 | /* 2 */ 407 | } 408 | 409 | /* 410 | Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) 411 | */ 412 | 413 | img, 414 | video { 415 | max-width: 100%; 416 | height: auto; 417 | } 418 | 419 | /* Make elements with the HTML hidden attribute stay hidden by default */ 420 | 421 | [hidden] { 422 | display: none; 423 | } 424 | 425 | *, ::before, ::after { 426 | --tw-border-spacing-x: 0; 427 | --tw-border-spacing-y: 0; 428 | --tw-translate-x: 0; 429 | --tw-translate-y: 0; 430 | --tw-rotate: 0; 431 | --tw-skew-x: 0; 432 | --tw-skew-y: 0; 433 | --tw-scale-x: 1; 434 | --tw-scale-y: 1; 435 | --tw-pan-x: ; 436 | --tw-pan-y: ; 437 | --tw-pinch-zoom: ; 438 | --tw-scroll-snap-strictness: proximity; 439 | --tw-gradient-from-position: ; 440 | --tw-gradient-via-position: ; 441 | --tw-gradient-to-position: ; 442 | --tw-ordinal: ; 443 | --tw-slashed-zero: ; 444 | --tw-numeric-figure: ; 445 | --tw-numeric-spacing: ; 446 | --tw-numeric-fraction: ; 447 | --tw-ring-inset: ; 448 | --tw-ring-offset-width: 0px; 449 | --tw-ring-offset-color: #fff; 450 | --tw-ring-color: rgb(59 130 246 / 0.5); 451 | --tw-ring-offset-shadow: 0 0 #0000; 452 | --tw-ring-shadow: 0 0 #0000; 453 | --tw-shadow: 0 0 #0000; 454 | --tw-shadow-colored: 0 0 #0000; 455 | --tw-blur: ; 456 | --tw-brightness: ; 457 | --tw-contrast: ; 458 | --tw-grayscale: ; 459 | --tw-hue-rotate: ; 460 | --tw-invert: ; 461 | --tw-saturate: ; 462 | --tw-sepia: ; 463 | --tw-drop-shadow: ; 464 | --tw-backdrop-blur: ; 465 | --tw-backdrop-brightness: ; 466 | --tw-backdrop-contrast: ; 467 | --tw-backdrop-grayscale: ; 468 | --tw-backdrop-hue-rotate: ; 469 | --tw-backdrop-invert: ; 470 | --tw-backdrop-opacity: ; 471 | --tw-backdrop-saturate: ; 472 | --tw-backdrop-sepia: ; 473 | } 474 | 475 | ::backdrop { 476 | --tw-border-spacing-x: 0; 477 | --tw-border-spacing-y: 0; 478 | --tw-translate-x: 0; 479 | --tw-translate-y: 0; 480 | --tw-rotate: 0; 481 | --tw-skew-x: 0; 482 | --tw-skew-y: 0; 483 | --tw-scale-x: 1; 484 | --tw-scale-y: 1; 485 | --tw-pan-x: ; 486 | --tw-pan-y: ; 487 | --tw-pinch-zoom: ; 488 | --tw-scroll-snap-strictness: proximity; 489 | --tw-gradient-from-position: ; 490 | --tw-gradient-via-position: ; 491 | --tw-gradient-to-position: ; 492 | --tw-ordinal: ; 493 | --tw-slashed-zero: ; 494 | --tw-numeric-figure: ; 495 | --tw-numeric-spacing: ; 496 | --tw-numeric-fraction: ; 497 | --tw-ring-inset: ; 498 | --tw-ring-offset-width: 0px; 499 | --tw-ring-offset-color: #fff; 500 | --tw-ring-color: rgb(59 130 246 / 0.5); 501 | --tw-ring-offset-shadow: 0 0 #0000; 502 | --tw-ring-shadow: 0 0 #0000; 503 | --tw-shadow: 0 0 #0000; 504 | --tw-shadow-colored: 0 0 #0000; 505 | --tw-blur: ; 506 | --tw-brightness: ; 507 | --tw-contrast: ; 508 | --tw-grayscale: ; 509 | --tw-hue-rotate: ; 510 | --tw-invert: ; 511 | --tw-saturate: ; 512 | --tw-sepia: ; 513 | --tw-drop-shadow: ; 514 | --tw-backdrop-blur: ; 515 | --tw-backdrop-brightness: ; 516 | --tw-backdrop-contrast: ; 517 | --tw-backdrop-grayscale: ; 518 | --tw-backdrop-hue-rotate: ; 519 | --tw-backdrop-invert: ; 520 | --tw-backdrop-opacity: ; 521 | --tw-backdrop-saturate: ; 522 | --tw-backdrop-sepia: ; 523 | } 524 | 525 | .container { 526 | width: 100%; 527 | } 528 | 529 | @media (min-width: 640px) { 530 | .container { 531 | max-width: 640px; 532 | } 533 | } 534 | 535 | @media (min-width: 768px) { 536 | .container { 537 | max-width: 768px; 538 | } 539 | } 540 | 541 | @media (min-width: 1024px) { 542 | .container { 543 | max-width: 1024px; 544 | } 545 | } 546 | 547 | @media (min-width: 1280px) { 548 | .container { 549 | max-width: 1280px; 550 | } 551 | } 552 | 553 | @media (min-width: 1536px) { 554 | .container { 555 | max-width: 1536px; 556 | } 557 | } 558 | 559 | .mx-auto { 560 | margin-left: auto; 561 | margin-right: auto; 562 | } 563 | 564 | .mb-8 { 565 | margin-bottom: 2rem; 566 | } 567 | 568 | .mt-\[calc\(10vh\)\] { 569 | margin-top: calc(10vh); 570 | } 571 | 572 | .block { 573 | display: block; 574 | } 575 | 576 | .flex { 577 | display: flex; 578 | } 579 | 580 | .w-full { 581 | width: 100%; 582 | } 583 | 584 | .flex-wrap { 585 | flex-wrap: wrap; 586 | } 587 | 588 | .items-center { 589 | align-items: center; 590 | } 591 | 592 | .justify-between { 593 | justify-content: space-between; 594 | } 595 | 596 | .space-x-10 > :not([hidden]) ~ :not([hidden]) { 597 | --tw-space-x-reverse: 0; 598 | margin-right: calc(2.5rem * var(--tw-space-x-reverse)); 599 | margin-left: calc(2.5rem * calc(1 - var(--tw-space-x-reverse))); 600 | } 601 | 602 | .space-x-4 > :not([hidden]) ~ :not([hidden]) { 603 | --tw-space-x-reverse: 0; 604 | margin-right: calc(1rem * var(--tw-space-x-reverse)); 605 | margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); 606 | } 607 | 608 | .bg-red-300 { 609 | --tw-bg-opacity: 1; 610 | background-color: rgb(252 165 165 / var(--tw-bg-opacity)); 611 | } 612 | 613 | .px-4 { 614 | padding-left: 1rem; 615 | padding-right: 1rem; 616 | } 617 | 618 | .py-4 { 619 | padding-top: 1rem; 620 | padding-bottom: 1rem; 621 | } 622 | 623 | .text-center { 624 | text-align: center; 625 | } 626 | 627 | .text-2xl { 628 | font-size: 1.5rem; 629 | line-height: 2rem; 630 | } 631 | 632 | .text-5xl { 633 | font-size: 3rem; 634 | line-height: 1; 635 | } 636 | 637 | .text-7xl { 638 | font-size: 4.5rem; 639 | line-height: 1; 640 | } 641 | 642 | .text-xl { 643 | font-size: 1.25rem; 644 | line-height: 1.75rem; 645 | } 646 | 647 | .font-bold { 648 | font-weight: 700; 649 | } 650 | 651 | .font-semibold { 652 | font-weight: 600; 653 | } 654 | 655 | .leading-relaxed { 656 | line-height: 1.625; 657 | } 658 | 659 | .text-blue-600 { 660 | --tw-text-opacity: 1; 661 | color: rgb(37 99 235 / var(--tw-text-opacity)); 662 | } 663 | 664 | .underline { 665 | text-decoration-line: underline; 666 | } 667 | 668 | .btn { 669 | cursor: pointer; 670 | border-radius: 0.5rem; 671 | border-width: 1px; 672 | --tw-border-opacity: 1; 673 | border-color: rgb(0 0 0 / var(--tw-border-opacity)); 674 | padding-top: 0.5rem; 675 | padding-bottom: 0.5rem; 676 | padding-left: 0.75rem; 677 | padding-right: 0.75rem; 678 | } 679 | 680 | .btn-sm { 681 | padding-top: 0.25rem; 682 | padding-bottom: 0.25rem; 683 | padding-left: 0.75rem; 684 | padding-right: 0.75rem; 685 | } 686 | 687 | .btn-black { 688 | --tw-bg-opacity: 1; 689 | background-color: rgb(0 0 0 / var(--tw-bg-opacity)); 690 | --tw-text-opacity: 1; 691 | color: rgb(255 255 255 / var(--tw-text-opacity)); 692 | } 693 | 694 | .btn-black:hover { 695 | --tw-bg-opacity: 1; 696 | background-color: rgb(31 41 55 / var(--tw-bg-opacity)); 697 | } 698 | 699 | .hover\:underline:hover { 700 | text-decoration-line: underline; 701 | } 702 | 703 | @media (min-width: 768px) { 704 | .md\:text-3xl { 705 | font-size: 1.875rem; 706 | line-height: 2.25rem; 707 | } 708 | 709 | .md\:text-4xl { 710 | font-size: 2.25rem; 711 | line-height: 2.5rem; 712 | } 713 | 714 | .md\:text-7xl { 715 | font-size: 4.5rem; 716 | line-height: 1; 717 | } 718 | } 719 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: ["./views/**/*.{html,js}"], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | } -------------------------------------------------------------------------------- /util/util.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import "os" 4 | 5 | func IsProd() bool { 6 | return os.Getenv("PRODUCTION") == "true" 7 | } 8 | 9 | func IsDev() bool { 10 | return !IsProd() 11 | } 12 | 13 | func AppEnv() string { 14 | if IsProd() { 15 | return "production" 16 | } 17 | return "development" 18 | } 19 | -------------------------------------------------------------------------------- /views/error/404.html: -------------------------------------------------------------------------------- 1 | {% extends "partials/base.html" %} 2 | 3 | {% block content %} 4 |
5 |
6 |

The page you are looking for could not be found.

7 | Take me back 8 |
9 |
10 | {% endblock %} -------------------------------------------------------------------------------- /views/error/500.html: -------------------------------------------------------------------------------- 1 | {% extends "partials/base.html" %} 2 | 3 | {% block content %} 4 |
5 |
6 |

An unexpected error occured.

7 | Take me back 8 |
9 |
10 | {% endblock %} -------------------------------------------------------------------------------- /views/home/bored.html: -------------------------------------------------------------------------------- 1 |
2 |

Time to start building!

3 |
-------------------------------------------------------------------------------- /views/home/index.html: -------------------------------------------------------------------------------- 1 | {% extends "partials/app_base.html" %} 2 | 3 | {% block pageContent %} 4 | 5 |
6 |
7 |

The bored stack.

8 |

Programming stack for the no-bullshit builder.

9 |

Golang - HTMX - Tailwind - Postgres

10 |
11 |
12 | {% endblock %} -------------------------------------------------------------------------------- /views/partials/app_base.html: -------------------------------------------------------------------------------- 1 | {% extends "partials/base.html" %} 2 | 3 | {% block content %} 4 | 5 | {% if flash.systemMessage %} 6 |
7 | {{ flash.systemMessage }} 8 |
9 | {% endif %} 10 | 11 | {% include "partials/navigation.html" %} 12 | 13 | {% block pageContent %}{% endblock %} 14 | 15 | {% endblock %} -------------------------------------------------------------------------------- /views/partials/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | The bored stack - programming stack for the no-bullshit builder 8 | 9 | {{ css("app.css") }} 10 | 11 | {% block script %} 12 | 13 | {% endblock%} 14 | 15 | 16 | 17 | {% block content %}{% endblock %} 18 | 19 | 20 | -------------------------------------------------------------------------------- /views/partials/navigation.html: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------