diff --git a/.idea/webResources.xml b/.idea/webResources.xml new file mode 100644 index 0000000..d29937f --- /dev/null +++ b/.idea/webResources.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Makefile b/Makefile index dd59880..627a037 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ ids: run: build mkdir -p .run-data - sudo _build/bunny_backend + sudo BUNNY_LIVERELOAD="$(shell pwd)/webassets" CONF_NS="local-host" _build/bunny_backend gow: # go install github.com/mitranim/gow@latest diff --git a/api/handler/apiHandler.go b/api/handler/apiHandler.go new file mode 100644 index 0000000..f1ecaa8 --- /dev/null +++ b/api/handler/apiHandler.go @@ -0,0 +1,47 @@ +package handler + +import ( + "gogs.mikescher.com/BlackForestBytes/goext/ginext" + bunny "locbunny" + "locbunny/logic" + "locbunny/models" + "net/http" +) + +type APIHandler struct { + app *logic.Application +} + +func NewAPIHandler(app *logic.Application) APIHandler { + return APIHandler{ + app: app, + } +} + +// ListServer swaggerdoc +// +// @Summary List running server +// +// @Success 200 {object} handler.ListServer.response +// @Failure 400 {object} models.APIError +// @Failure 500 {object} models.APIError +// +// @Router /server [GET] +func (h APIHandler) ListServer(pctx ginext.PreContext) ginext.HTTPResponse { + type response struct { + Server []models.Server `json:"server"` + } + + ctx, _, errResp := pctx.Start() + if errResp != nil { + return *errResp + } + defer ctx.Cancel() + + srvs, err := h.app.ListServer(ctx, bunny.Conf.VerifyConnTimeoutAPI) + if err != nil { + return ginext.Error(err) + } + + return ginext.JSON(http.StatusOK, response{Server: srvs}) +} diff --git a/api/handler/webHandler.go b/api/handler/webHandler.go index c0d4ebe..2fd0682 100644 --- a/api/handler/webHandler.go +++ b/api/handler/webHandler.go @@ -1,11 +1,20 @@ package handler import ( + "bytes" + "context" + "encoding/json" + "github.com/gin-gonic/gin" "gogs.mikescher.com/BlackForestBytes/goext/ginext" - "gogs.mikescher.com/BlackForestBytes/goext/langext" + templhtml "html/template" + bunny "locbunny" "locbunny/logic" "locbunny/models" + "locbunny/webassets" "net/http" + "path/filepath" + templtext "text/template" + "time" ) type WebHandler struct { @@ -18,32 +27,151 @@ func NewWebHandler(app *logic.Application) WebHandler { } } -// ListServer swaggerdoc +// ServeIndexHTML swaggerdoc // -// @Summary List running server +// @Summary (Website) // -// @Success 200 {object} handler.ListServer.response -// @Failure 400 {object} models.APIError -// @Failure 500 {object} models.APIError -// -// @Router /server [GET] -func (h WebHandler) ListServer(pctx ginext.PreContext) ginext.HTTPResponse { - type response struct { - Server []models.Server `json:"server"` - } - +// @Router / [GET] +// @Router /index.html [GET] +func (h WebHandler) ServeIndexHTML(pctx ginext.PreContext) ginext.HTTPResponse { ctx, _, errResp := pctx.Start() if errResp != nil { return *errResp } defer ctx.Cancel() - srvs, err := h.app.ListServer(ctx) + templ, err := h.app.Assets.Template("index.html", h.buildIndexHTMLTemplate) if err != nil { return ginext.Error(err) } - langext.SortBy(srvs, func(v models.Server) int { return v.Port }) + data := map[string]any{} - return ginext.JSON(http.StatusOK, response{Server: srvs}) + bin := bytes.Buffer{} + err = templ.Execute(&bin, data) + if err != nil { + return ginext.Error(err) + } + + return ginext.Data(http.StatusOK, "text/html", bin.Bytes()) +} + +// ServeScriptJS swaggerdoc +// +// @Summary (Website) +// +// @Router /scripts.script.js [GET] +func (h WebHandler) ServeScriptJS(pctx ginext.PreContext) ginext.HTTPResponse { + ctx, _, errResp := pctx.Start() + if errResp != nil { + return *errResp + } + defer ctx.Cancel() + + templ, err := h.app.Assets.Template("scripts/script.js", h.buildScriptJSTemplate) + if err != nil { + return ginext.Error(err) + } + + data := map[string]any{} + + bin := bytes.Buffer{} + err = templ.Execute(&bin, data) + if err != nil { + return ginext.Error(err) + } + + return ginext.Data(http.StatusOK, "text/javascript", bin.Bytes()) +} + +func (h WebHandler) buildIndexHTMLTemplate(content []byte) (webassets.ITemplate, error) { + t := templhtml.New("index.html") + + t.Funcs(h.templateFuncMap()) + + _, err := t.Parse(string(content)) + if err != nil { + return nil, err + } + + return t, nil +} + +func (h WebHandler) ServeAssets(pctx ginext.PreContext) ginext.HTTPResponse { + type uri struct { + FP1 *string `uri:"fp1"` + FP2 *string `uri:"fp2"` + FP3 *string `uri:"fp3"` + } + + var u uri + ctx, _, errResp := pctx.URI(&u).Start() + if errResp != nil { + return *errResp + } + defer ctx.Cancel() + + assetpath := "" + if u.FP1 == nil && u.FP2 == nil && u.FP3 == nil { + assetpath = filepath.Join() + } else if u.FP2 == nil && u.FP3 == nil { + assetpath = filepath.Join(*u.FP1) + } else if u.FP3 == nil { + assetpath = filepath.Join(*u.FP1, *u.FP2) + } else { + assetpath = filepath.Join(*u.FP1, *u.FP2, *u.FP3) + } + + data, err := h.app.Assets.Read(assetpath) + if err != nil { + return ginext.JSON(http.StatusNotFound, gin.H{"error": "AssetNotFound", "assetpath": assetpath}) + } + + mime := bunny.FilenameToMime(assetpath, "text/plain") + + return ginext.Data(http.StatusOK, mime, data) +} + +func (h WebHandler) buildScriptJSTemplate(content []byte) (webassets.ITemplate, error) { + t := templtext.New("scripts/script.js") + + t.Funcs(h.templateFuncMap()) + + _, err := t.Parse(string(content)) + if err != nil { + return nil, err + } + + return t, nil +} + +func (h WebHandler) templateFuncMap() map[string]any { + return map[string]any{ + "listServers": func() []models.Server { + ctx, cancel := context.WithTimeout(context.Background(), bunny.Conf.VerifyConnTimeoutHTML+2*time.Second) + defer cancel() + v, err := h.app.ListServer(ctx, bunny.Conf.VerifyConnTimeoutHTML) + if err != nil { + panic(err) + } + return v + }, + "safe_html": func(s string) templhtml.HTML { return templhtml.HTML(s) }, //nolint:gosec + "safe_js": func(s string) templhtml.JS { return templhtml.JS(s) }, //nolint:gosec + "json": func(obj any) string { + v, err := json.Marshal(obj) + if err != nil { + panic(err) + } + return string(v) + }, + "json_indent": func(obj any) string { + v, err := json.MarshalIndent(obj, "", " ") + if err != nil { + panic(err) + } + return string(v) + }, + "mkarr": func(ln int) []int { return make([]int, ln) }, + } } diff --git a/api/router.go b/api/router.go index 8cd0b4e..70afc34 100644 --- a/api/router.go +++ b/api/router.go @@ -13,6 +13,7 @@ type Router struct { app *logic.Application commonHandler handler.CommonHandler + apiHandler handler.APIHandler webHandler handler.WebHandler } @@ -21,6 +22,7 @@ func NewRouter(app *logic.Application) *Router { app: app, commonHandler: handler.NewCommonHandler(app), + apiHandler: handler.NewAPIHandler(app), webHandler: handler.NewWebHandler(app), } } @@ -50,9 +52,18 @@ func (r *Router) Init(e *ginext.GinWrapper) { docs.GET("/swagger/*sub").Handle(swagger.Handle) } + // ================ Website ================ + + e.Routes().GET("/").Handle(r.webHandler.ServeIndexHTML) + e.Routes().GET("/index.html").Handle(r.webHandler.ServeIndexHTML) + e.Routes().GET("/scripts/script.js").Handle(r.webHandler.ServeScriptJS) + e.Routes().GET("/:fp1").Handle(r.webHandler.ServeAssets) + e.Routes().GET("/:fp1/:fp2").Handle(r.webHandler.ServeAssets) + e.Routes().GET("/:fp1/:fp2/:fp3").Handle(r.webHandler.ServeAssets) + // ================ API ================ - api.GET("/server").Handle(r.webHandler.ListServer) + api.GET("/server").Handle(r.apiHandler.ListServer) // ================ ================ diff --git a/cmd/server/main.go b/cmd/server/main.go index 2e8d5e6..db9ea1c 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -7,6 +7,7 @@ import ( bunny "locbunny" "locbunny/api" "locbunny/logic" + "locbunny/webassets" ) func main() { @@ -16,7 +17,9 @@ func main() { log.Info().Msg(fmt.Sprintf("Starting with config-namespace <%s>", conf.Namespace)) - app := logic.NewApp() + assets := webassets.NewAssets() + + app := logic.NewApp(assets) ginengine := ginext.NewEngine(conf.Cors, conf.GinDebug, true, conf.RequestTimeout) diff --git a/config.go b/config.go index 92eb59f..7fb8446 100644 --- a/config.go +++ b/config.go @@ -14,92 +14,110 @@ const APILevel = 1 var SelfProcessID int type Config struct { - Namespace string - GinDebug bool `env:"GINDEBUG"` - ReturnRawErrors bool `env:"RETURNERRORS"` - Custom404 bool `env:"CUSTOM404"` - LogLevel zerolog.Level `env:"LOGLEVEL"` - ServerIP string `env:"IP"` - ServerPort int `env:"PORT"` - RequestTimeout time.Duration `env:"REQUEST_TIMEOUT"` - Cors bool `env:"CORS"` - VerifyConnTimeout time.Duration `env:"VERIFY_CONN_TIMEOUT"` + Namespace string + GinDebug bool `env:"GINDEBUG"` + ReturnRawErrors bool `env:"RETURNERRORS"` + Custom404 bool `env:"CUSTOM404"` + LogLevel zerolog.Level `env:"LOGLEVEL"` + ServerIP string `env:"IP"` + ServerPort int `env:"PORT"` + RequestTimeout time.Duration `env:"REQUEST_TIMEOUT"` + Cors bool `env:"CORS"` + VerifyConnTimeoutHTML time.Duration `env:"VERIFY_CONN_TIMEOUT_HTML"` + VerifyConnTimeoutAPI time.Duration `env:"VERIFY_CONN_TIMEOUT_API"` + LiveReload *string `env:"LIVERELOAD"` + CacheDuration time.Duration `env:"CACHE_DURATION"` } var Conf Config var configLocHost = func() Config { return Config{ - Namespace: "local", - GinDebug: true, - ServerIP: "0.0.0.0", - ServerPort: 80, - Custom404: true, - ReturnRawErrors: true, - RequestTimeout: 16 * time.Second, - LogLevel: zerolog.DebugLevel, - Cors: true, - VerifyConnTimeout: time.Second, + Namespace: "local", + GinDebug: true, + ServerIP: "0.0.0.0", + ServerPort: 80, + Custom404: true, + ReturnRawErrors: true, + RequestTimeout: 16 * time.Second, + LogLevel: zerolog.DebugLevel, + Cors: true, + VerifyConnTimeoutAPI: 2 * time.Second, + VerifyConnTimeoutHTML: 500 * time.Millisecond, + LiveReload: nil, + CacheDuration: 8 * time.Second, } } var configLocDocker = func() Config { return Config{ - Namespace: "local-docker", - GinDebug: true, - ServerIP: "0.0.0.0", - ServerPort: 80, - Custom404: true, - ReturnRawErrors: true, - RequestTimeout: 16 * time.Second, - LogLevel: zerolog.DebugLevel, - Cors: true, - VerifyConnTimeout: time.Second, + Namespace: "local-docker", + GinDebug: true, + ServerIP: "0.0.0.0", + ServerPort: 80, + Custom404: true, + ReturnRawErrors: true, + RequestTimeout: 16 * time.Second, + LogLevel: zerolog.DebugLevel, + Cors: true, + VerifyConnTimeoutAPI: 2 * time.Second, + VerifyConnTimeoutHTML: 500 * time.Millisecond, + LiveReload: nil, + CacheDuration: 8 * time.Second, } } var configDev = func() Config { return Config{ - Namespace: "develop", - GinDebug: true, - ServerIP: "0.0.0.0", - ServerPort: 80, - Custom404: false, - ReturnRawErrors: false, - RequestTimeout: 16 * time.Second, - LogLevel: zerolog.DebugLevel, - Cors: false, - VerifyConnTimeout: time.Second, + Namespace: "develop", + GinDebug: true, + ServerIP: "0.0.0.0", + ServerPort: 80, + Custom404: false, + ReturnRawErrors: false, + RequestTimeout: 16 * time.Second, + LogLevel: zerolog.DebugLevel, + Cors: false, + VerifyConnTimeoutAPI: 2 * time.Second, + VerifyConnTimeoutHTML: 500 * time.Millisecond, + LiveReload: nil, + CacheDuration: 8 * time.Second, } } var configStag = func() Config { return Config{ - Namespace: "staging", - GinDebug: true, - ServerIP: "0.0.0.0", - ServerPort: 80, - Custom404: false, - ReturnRawErrors: false, - RequestTimeout: 16 * time.Second, - LogLevel: zerolog.DebugLevel, - Cors: false, - VerifyConnTimeout: time.Second, + Namespace: "staging", + GinDebug: true, + ServerIP: "0.0.0.0", + ServerPort: 80, + Custom404: false, + ReturnRawErrors: false, + RequestTimeout: 16 * time.Second, + LogLevel: zerolog.DebugLevel, + Cors: false, + VerifyConnTimeoutAPI: 2 * time.Second, + VerifyConnTimeoutHTML: 500 * time.Millisecond, + LiveReload: nil, + CacheDuration: 8 * time.Second, } } var configProd = func() Config { return Config{ - Namespace: "production", - GinDebug: false, - ServerIP: "0.0.0.0", - ServerPort: 80, - Custom404: false, - ReturnRawErrors: false, - RequestTimeout: 16 * time.Second, - LogLevel: zerolog.InfoLevel, - Cors: false, - VerifyConnTimeout: time.Second, + Namespace: "production", + GinDebug: false, + ServerIP: "0.0.0.0", + ServerPort: 80, + Custom404: false, + ReturnRawErrors: false, + RequestTimeout: 16 * time.Second, + LogLevel: zerolog.InfoLevel, + Cors: false, + VerifyConnTimeoutAPI: 2 * time.Second, + VerifyConnTimeoutHTML: 500 * time.Millisecond, + LiveReload: nil, + CacheDuration: 8 * time.Second, } } @@ -119,7 +137,7 @@ func InstanceID() string { func getConfig(ns string) (Config, bool) { if ns == "" { - ns = "local-host" + ns = "production" } if cfn, ok := allConfig[ns]; ok { c := cfn() diff --git a/logic/application.go b/logic/application.go index c0ee0ee..5a05163 100644 --- a/logic/application.go +++ b/logic/application.go @@ -12,6 +12,7 @@ import ( "io" bunny "locbunny" "locbunny/models" + "locbunny/webassets" "net" "net/http" "os" @@ -30,12 +31,19 @@ type Application struct { Port string IsRunning *syncext.AtomicBool - Gin *ginext.GinWrapper - Jobs []Job + Gin *ginext.GinWrapper + Assets *webassets.Assets + Jobs []Job + + cacheLock sync.Mutex + serverCacheValue []models.Server + serverCacheTime *time.Time } -func NewApp() *Application { +func NewApp(ass *webassets.Assets) *Application { + //nolint:exhaustruct return &Application{ + Assets: ass, stopChan: make(chan bool), IsRunning: syncext.NewAtomicBool(false), } @@ -110,18 +118,35 @@ func (app *Application) Run() { app.IsRunning.Set(false) } -func (app *Application) ListServer(ctx *ginext.AppContext) ([]models.Server, error) { +func (app *Application) ListServer(ctx context.Context, timeout time.Duration) ([]models.Server, error) { + + app.cacheLock.Lock() + if app.serverCacheTime != nil && app.serverCacheTime.After(time.Now().Add(-bunny.Conf.CacheDuration)) { + v := langext.ArrCopy(app.serverCacheValue) + log.Debug().Msg(fmt.Sprintf("Return cache values (from %s)", app.serverCacheTime.Format(time.RFC3339Nano))) + app.cacheLock.Unlock() + return v, nil + } + app.cacheLock.Unlock() socks4, err := netstat.TCPSocks(netstat.NoopFilter) if err != nil { return nil, err } + if err := ctx.Err(); err != nil { + return nil, err + } + socks6, err := netstat.TCP6Socks(netstat.NoopFilter) if err != nil { return nil, err } + if err := ctx.Err(); err != nil { + return nil, err + } + sockCount := len(socks4) + len(socks6) wg := sync.WaitGroup{} @@ -135,7 +160,7 @@ func (app *Application) ListServer(ctx *ginext.AppContext) ([]models.Server, err go func() { defer wg.Done() - con1, err := app.verifyHTTPConn(socks4[i], "HTTP", "v4") + con1, err := app.verifyHTTPConn(socks4[i], "HTTP", "v4", timeout) if err == nil { rchan <- con1 return @@ -148,7 +173,7 @@ func (app *Application) ListServer(ctx *ginext.AppContext) ([]models.Server, err go func() { defer wg.Done() - con2, err := app.verifyHTTPConn(socks4[i], "HTTPS", "v4") + con2, err := app.verifyHTTPConn(socks4[i], "HTTPS", "v4", timeout) if err == nil { rchan <- con2 return @@ -164,7 +189,7 @@ func (app *Application) ListServer(ctx *ginext.AppContext) ([]models.Server, err go func() { defer wg.Done() - con1, err := app.verifyHTTPConn(socks6[i], "HTTP", "v6") + con1, err := app.verifyHTTPConn(socks6[i], "HTTP", "v6", timeout) if err == nil { rchan <- con1 return @@ -177,7 +202,7 @@ func (app *Application) ListServer(ctx *ginext.AppContext) ([]models.Server, err go func() { defer wg.Done() - con2, err := app.verifyHTTPConn(socks6[i], "HTTPS", "v6") + con2, err := app.verifyHTTPConn(socks6[i], "HTTPS", "v6", timeout) if err == nil { rchan <- con2 return @@ -191,6 +216,10 @@ func (app *Application) ListServer(ctx *ginext.AppContext) ([]models.Server, err close(echan) close(rchan) + if err := ctx.Err(); err != nil { + return nil, err + } + duplicates := make(map[int]bool, sockCount*3) res := make([]models.Server, 0, sockCount*3) for v := range rchan { @@ -201,35 +230,44 @@ func (app *Application) ListServer(ctx *ginext.AppContext) ([]models.Server, err } } + langext.SortBy(res, func(v models.Server) int { return v.Port }) + + app.cacheLock.Lock() + app.serverCacheValue = langext.ArrCopy(res) + app.serverCacheTime = langext.Ptr(time.Now()) + app.cacheLock.Unlock() + return res, nil } -func (app *Application) verifyHTTPConn(sock netstat.SockTabEntry, proto string, ipversion string) (models.Server, error) { +func (app *Application) verifyHTTPConn(sock netstat.SockTabEntry, proto string, ipversion string, timeout time.Duration) (models.Server, error) { - ctx, cancel := context.WithTimeout(context.Background(), bunny.Conf.VerifyConnTimeout) + ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() - if sock.State != netstat.Listen { - log.Debug().Msg(fmt.Sprintf("Failed to verify socket [%s|%s] invalid state: %s", ipversion, strings.ToUpper(proto), sock.State.String())) + port := int(sock.LocalAddr.Port) + + if sock.State != netstat.Listen && sock.State != netstat.Established && sock.State != netstat.TimeWait { + log.Debug().Msg(fmt.Sprintf("Failed to verify socket [%s|%s|%d] invalid state: %s", strings.ToUpper(proto), ipversion, port, sock.State.String())) return models.Server{}, errors.New("invalid sock-state") } - if int(sock.LocalAddr.Port) == bunny.Conf.ServerPort && sock.Process != nil && sock.Process.Pid == bunny.SelfProcessID { - log.Debug().Msg(fmt.Sprintf("Skip socket [%s|%s] (this is our own server)", ipversion, strings.ToUpper(proto))) + if port == bunny.Conf.ServerPort && sock.Process != nil && sock.Process.Pid == bunny.SelfProcessID { + log.Debug().Msg(fmt.Sprintf("Skip socket [%s|%s|%d] (this is our own server)", strings.ToUpper(proto), ipversion, port)) return models.Server{}, errors.New("skip self") } c := http.Client{} - url := fmt.Sprintf("%s://localhost:%d", strings.ToLower(proto), sock.LocalAddr.Port) - req, err := http.NewRequestWithContext(ctx, "GET", url, nil) + url := fmt.Sprintf("%s://localhost:%d", strings.ToLower(proto), port) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { - log.Debug().Msg(fmt.Sprintf("Failed to create [%s|%s] request to %d", ipversion, strings.ToUpper(proto), sock.LocalAddr.Port)) + log.Debug().Msg(fmt.Sprintf("Failed to create [%s|%s|%d] request to %d (-> %s)", strings.ToUpper(proto), ipversion, port, port, err.Error())) return models.Server{}, err } resp1, err := c.Do(req) if err != nil { - log.Debug().Msg(fmt.Sprintf("Failed to send [%s|%s] request to %s", ipversion, strings.ToUpper(proto), url)) + log.Debug().Msg(fmt.Sprintf("Failed to send [%s|%s|%d] request to %s (-> %s)", strings.ToUpper(proto), ipversion, port, url, err.Error())) return models.Server{}, err } @@ -237,7 +275,7 @@ func (app *Application) verifyHTTPConn(sock netstat.SockTabEntry, proto string, resbody, err := io.ReadAll(resp1.Body) if err != nil { - log.Debug().Msg(fmt.Sprintf("Failed to read [%s|%s] response from %s", ipversion, strings.ToUpper(proto), url)) + log.Debug().Msg(fmt.Sprintf("Failed to read [%s|%s|%d] response from %s (-> %s)", strings.ToUpper(proto), ipversion, port, url, err.Error())) return models.Server{}, err } @@ -252,7 +290,7 @@ func (app *Application) verifyHTTPConn(sock netstat.SockTabEntry, proto string, } return models.Server{ - Port: int(sock.LocalAddr.Port), + Port: port, IP: sock.LocalAddr.IP.String(), Protocol: proto, StatusCode: resp1.StatusCode, @@ -265,6 +303,6 @@ func (app *Application) verifyHTTPConn(sock netstat.SockTabEntry, proto string, }, nil } - log.Debug().Msg(fmt.Sprintf("Failed to categorize [%s|%s] response from %s (Content-Type: '%s')", ipversion, strings.ToUpper(proto), url, ct)) + log.Debug().Msg(fmt.Sprintf("Failed to categorize [%s|%s|%d] response from %s (Content-Type: '%s')", strings.ToUpper(proto), ipversion, port, url, ct)) return models.Server{}, errors.New("invalid response-type") } diff --git a/swagger/swagger.go b/swagger/swagger.go index fef7094..ca09267 100644 --- a/swagger/swagger.go +++ b/swagger/swagger.go @@ -2,7 +2,6 @@ package swagger import ( "embed" - _ "embed" "github.com/gin-gonic/gin" "gogs.mikescher.com/BlackForestBytes/goext/ginext" "net/http" diff --git a/swagger/swagger.json b/swagger/swagger.json index 6251f76..982e59e 100644 --- a/swagger/swagger.json +++ b/swagger/swagger.json @@ -8,6 +8,12 @@ "host": "localhost", "basePath": "/api/v1/", "paths": { + "/": { + "get": { + "summary": "(Website)", + "responses": {} + } + }, "/api/health": { "get": { "tags": [ @@ -169,6 +175,18 @@ } } }, + "/index.html": { + "get": { + "summary": "(Website)", + "responses": {} + } + }, + "/scripts.script.js": { + "get": { + "summary": "(Website)", + "responses": {} + } + }, "/server": { "get": { "summary": "List running server", diff --git a/swagger/swagger.yaml b/swagger/swagger.yaml index f1b3c9f..202e263 100644 --- a/swagger/swagger.yaml +++ b/swagger/swagger.yaml @@ -83,6 +83,10 @@ info: title: LocalHostBunny version: "1.0" paths: + /: + get: + responses: {} + summary: (Website) /api/health: get: responses: @@ -187,6 +191,14 @@ paths: summary: Return 200 after x seconds tags: - Common + /index.html: + get: + responses: {} + summary: (Website) + /scripts.script.js: + get: + responses: {} + summary: (Website) /server: get: responses: diff --git a/utils.go b/utils.go new file mode 100644 index 0000000..e7f9bfa --- /dev/null +++ b/utils.go @@ -0,0 +1,39 @@ +package bunny + +import "strings" + +func FilenameToMime(fn string, fallback string) string { + lowerFN := strings.ToLower(fn) + if strings.HasSuffix(lowerFN, ".html") || strings.HasSuffix(lowerFN, ".htm") { + return "text/html" + } + if strings.HasSuffix(lowerFN, ".css") { + return "text/css" + } + if strings.HasSuffix(lowerFN, ".js") { + return "text/javascript" + } + if strings.HasSuffix(lowerFN, ".json") { + return "application/json" + } + if strings.HasSuffix(lowerFN, ".jpeg") || strings.HasSuffix(lowerFN, ".jpg") { + return "image/jpeg" + } + if strings.HasSuffix(lowerFN, ".png") { + return "image/png" + } + if strings.HasSuffix(lowerFN, ".svg") { + return "image/svg+xml" + } + if strings.HasSuffix(lowerFN, ".gif") { + return "image/gif" + } + if strings.HasSuffix(lowerFN, ".webp") { + return "audio/webm" + } + if strings.HasSuffix(lowerFN, ".bmp") { + return "image/bmp" + } + + return fallback +} diff --git a/webassets/css/fonts.css b/webassets/css/fonts.css new file mode 100644 index 0000000..27af7ff --- /dev/null +++ b/webassets/css/fonts.css @@ -0,0 +1,20 @@ +@font-face { font-display: swap; font-family: 'MonaspaceArgon'; font-weight: bold; font-style: normal; src: url('/fonts/MonaspaceArgon-Bold.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceArgon'; font-weight: bold; font-style: italic; src: url('/fonts/MonaspaceArgon-BoldItalic.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceArgon'; font-weight: normal; font-style: italic; src: url('/fonts/MonaspaceArgon-Italic.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceArgon'; font-weight: normal; font-style: normal; src: url('/fonts/MonaspaceArgon-Regular.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceKrypton'; font-weight: bold; font-style: normal; src: url('/fonts/MonaspaceKrypton-Bold.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceKrypton'; font-weight: bold; font-style: italic; src: url('/fonts/MonaspaceKrypton-BoldItalic.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceKrypton'; font-weight: normal; font-style: italic; src: url('/fonts/MonaspaceKrypton-Italic.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceKrypton'; font-weight: normal; font-style: normal; src: url('/fonts/MonaspaceKrypton-Regular.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceNeon'; font-weight: bold; font-style: normal; src: url('/fonts/MonaspaceNeon-Bold.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceNeon'; font-weight: bold; font-style: italic; src: url('/fonts/MonaspaceNeon-BoldItalic.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceNeon'; font-weight: normal; font-style: italic; src: url('/fonts/MonaspaceNeon-Italic.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceNeon'; font-weight: normal; font-style: normal; src: url('/fonts/MonaspaceNeon-Regular.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceRadon'; font-weight: bold; font-style: normal; src: url('/fonts/MonaspaceRadon-Bold.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceRadon'; font-weight: bold; font-style: italic; src: url('/fonts/MonaspaceRadon-BoldItalic.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceRadon'; font-weight: normal; font-style: italic; src: url('/fonts/MonaspaceRadon-Italic.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceRadon'; font-weight: normal; font-style: normal; src: url('/fonts/MonaspaceRadon-Regular.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceXenon'; font-weight: bold; font-style: normal; src: url('/fonts/MonaspaceXenon-Bold.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceXenon'; font-weight: bold; font-style: italic; src: url('/fonts/MonaspaceXenon-BoldItalic.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceXenon'; font-weight: normal; font-style: italic; src: url('/fonts/MonaspaceXenon-Italic.woff') format('woff2') } +@font-face { font-display: swap; font-family: 'MonaspaceXenon'; font-weight: normal; font-style: normal; src: url('/fonts/MonaspaceXenon-Regular.woff') format('woff2') } diff --git a/webassets/css/reset.css b/webassets/css/reset.css new file mode 100644 index 0000000..932c3e9 --- /dev/null +++ b/webassets/css/reset.css @@ -0,0 +1,51 @@ + + +/* https://meyerweb.com/eric/tools/css/reset/ */ + + +/* + 1. Use a more-intuitive box-sizing model. +*/ +*, *::before, *::after { + box-sizing: border-box; +} +/* + 2. Remove default margin +*/ +* { + margin: 0; +} +/* + Typographic tweaks! + 3. Add accessible line-height + 4. Improve text rendering +*/ +body { + line-height: 1.5; + -webkit-font-smoothing: antialiased; +} +/* + 5. Improve media defaults +*/ +img, picture, video, canvas, svg { + display: block; + max-width: 100%; +} +/* + 6. Remove built-in form typography styles +*/ +input, button, textarea, select { + font: inherit; +} +/* + 7. Avoid text overflows +*/ +p, h1, h2, h3, h4, h5, h6 { + overflow-wrap: break-word; +} +/* + 8. Create a root stacking context +*/ +#root, #__next { + isolation: isolate; +} \ No newline at end of file diff --git a/webassets/css/styles.css b/webassets/css/styles.css new file mode 100644 index 0000000..9b9a250 --- /dev/null +++ b/webassets/css/styles.css @@ -0,0 +1,55 @@ + +* { + font-family: 'MonaspaceXenon'; +} + +html, body { + width: 100%; +} + +body { + display: flex; + justify-content: center; +} + +main { + display: flex; + flex-direction: column; + + margin: 1rem; +} + +h1 { + margin-bottom: 1rem; +} + +#maincontent { + display: flex; + flex-direction: column; + gap: 0.5rem; + + padding: 0 1rem; +} + +.server { + background-color: #CCC; + text-align: center; + padding: 2px 0.5rem; + + color: black; + text-decoration: none; + + border-radius: 6px; + border: 1px solid #888; + + box-shadow: 0 0 4px #888; + + transition: all 0.2s; +} + +.server:hover { + box-shadow: 0 0 4px #000; + background-color: #AAA; + color: #00F; +} + diff --git a/webassets/favicon.ico b/webassets/favicon.ico new file mode 100644 index 0000000..37d44b8 Binary files /dev/null and b/webassets/favicon.ico differ diff --git a/webassets/fonts/MonaspaceArgon-Bold.woff b/webassets/fonts/MonaspaceArgon-Bold.woff new file mode 100644 index 0000000..1c00d13 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-Bold.woff differ diff --git a/webassets/fonts/MonaspaceArgon-BoldItalic.woff b/webassets/fonts/MonaspaceArgon-BoldItalic.woff new file mode 100644 index 0000000..05006ea Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-BoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-ExtraBold.woff b/webassets/fonts/MonaspaceArgon-ExtraBold.woff new file mode 100644 index 0000000..ec5d5e6 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-ExtraBold.woff differ diff --git a/webassets/fonts/MonaspaceArgon-ExtraBoldItalic.woff b/webassets/fonts/MonaspaceArgon-ExtraBoldItalic.woff new file mode 100644 index 0000000..79dad47 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-ExtraBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-ExtraLight.woff b/webassets/fonts/MonaspaceArgon-ExtraLight.woff new file mode 100644 index 0000000..4d7c6a2 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-ExtraLight.woff differ diff --git a/webassets/fonts/MonaspaceArgon-ExtraLightItalic.woff b/webassets/fonts/MonaspaceArgon-ExtraLightItalic.woff new file mode 100644 index 0000000..b878e39 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-ExtraLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-Italic.woff b/webassets/fonts/MonaspaceArgon-Italic.woff new file mode 100644 index 0000000..140547c Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-Italic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-Light.woff b/webassets/fonts/MonaspaceArgon-Light.woff new file mode 100644 index 0000000..1f008e9 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-Light.woff differ diff --git a/webassets/fonts/MonaspaceArgon-LightItalic.woff b/webassets/fonts/MonaspaceArgon-LightItalic.woff new file mode 100644 index 0000000..dc64d0d Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-LightItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-Medium.woff b/webassets/fonts/MonaspaceArgon-Medium.woff new file mode 100644 index 0000000..7ffe215 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-Medium.woff differ diff --git a/webassets/fonts/MonaspaceArgon-MediumItalic.woff b/webassets/fonts/MonaspaceArgon-MediumItalic.woff new file mode 100644 index 0000000..ca4053e Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-MediumItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-Regular.woff b/webassets/fonts/MonaspaceArgon-Regular.woff new file mode 100644 index 0000000..adcd7ba Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-Regular.woff differ diff --git a/webassets/fonts/MonaspaceArgon-SemiBold.woff b/webassets/fonts/MonaspaceArgon-SemiBold.woff new file mode 100644 index 0000000..26b60db Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-SemiBold.woff differ diff --git a/webassets/fonts/MonaspaceArgon-SemiBoldItalic.woff b/webassets/fonts/MonaspaceArgon-SemiBoldItalic.woff new file mode 100644 index 0000000..ca613e8 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-SemiBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-SemiWideBold.woff b/webassets/fonts/MonaspaceArgon-SemiWideBold.woff new file mode 100644 index 0000000..96b7f4d Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-SemiWideBold.woff differ diff --git a/webassets/fonts/MonaspaceArgon-SemiWideBoldItalic.woff b/webassets/fonts/MonaspaceArgon-SemiWideBoldItalic.woff new file mode 100644 index 0000000..8ec1b93 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-SemiWideBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-SemiWideExtraBold.woff b/webassets/fonts/MonaspaceArgon-SemiWideExtraBold.woff new file mode 100644 index 0000000..e7d7bfb Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-SemiWideExtraBold.woff differ diff --git a/webassets/fonts/MonaspaceArgon-SemiWideExtraBoldItalic.woff b/webassets/fonts/MonaspaceArgon-SemiWideExtraBoldItalic.woff new file mode 100644 index 0000000..57b75fc Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-SemiWideExtraBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-SemiWideExtraLight.woff b/webassets/fonts/MonaspaceArgon-SemiWideExtraLight.woff new file mode 100644 index 0000000..561de12 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-SemiWideExtraLight.woff differ diff --git a/webassets/fonts/MonaspaceArgon-SemiWideExtraLightItalic.woff b/webassets/fonts/MonaspaceArgon-SemiWideExtraLightItalic.woff new file mode 100644 index 0000000..9eb06f3 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-SemiWideExtraLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-SemiWideItalic.woff b/webassets/fonts/MonaspaceArgon-SemiWideItalic.woff new file mode 100644 index 0000000..98fa54f Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-SemiWideItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-SemiWideLight.woff b/webassets/fonts/MonaspaceArgon-SemiWideLight.woff new file mode 100644 index 0000000..809e92c Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-SemiWideLight.woff differ diff --git a/webassets/fonts/MonaspaceArgon-SemiWideLightItalic.woff b/webassets/fonts/MonaspaceArgon-SemiWideLightItalic.woff new file mode 100644 index 0000000..f177036 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-SemiWideLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-SemiWideMedium.woff b/webassets/fonts/MonaspaceArgon-SemiWideMedium.woff new file mode 100644 index 0000000..d344175 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-SemiWideMedium.woff differ diff --git a/webassets/fonts/MonaspaceArgon-SemiWideMediumItalic.woff b/webassets/fonts/MonaspaceArgon-SemiWideMediumItalic.woff new file mode 100644 index 0000000..4021053 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-SemiWideMediumItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-SemiWideRegular.woff b/webassets/fonts/MonaspaceArgon-SemiWideRegular.woff new file mode 100644 index 0000000..26b6c1f Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-SemiWideRegular.woff differ diff --git a/webassets/fonts/MonaspaceArgon-SemiWideSemiBold.woff b/webassets/fonts/MonaspaceArgon-SemiWideSemiBold.woff new file mode 100644 index 0000000..0be9d54 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-SemiWideSemiBold.woff differ diff --git a/webassets/fonts/MonaspaceArgon-SemiWideSemiBoldItalic.woff b/webassets/fonts/MonaspaceArgon-SemiWideSemiBoldItalic.woff new file mode 100644 index 0000000..4bae061 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-SemiWideSemiBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-WideBold.woff b/webassets/fonts/MonaspaceArgon-WideBold.woff new file mode 100644 index 0000000..c03ddc2 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-WideBold.woff differ diff --git a/webassets/fonts/MonaspaceArgon-WideBoldItalic.woff b/webassets/fonts/MonaspaceArgon-WideBoldItalic.woff new file mode 100644 index 0000000..f99890a Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-WideBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-WideExtraBold.woff b/webassets/fonts/MonaspaceArgon-WideExtraBold.woff new file mode 100644 index 0000000..693213d Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-WideExtraBold.woff differ diff --git a/webassets/fonts/MonaspaceArgon-WideExtraBoldItalic.woff b/webassets/fonts/MonaspaceArgon-WideExtraBoldItalic.woff new file mode 100644 index 0000000..8da659a Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-WideExtraBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-WideExtraLight.woff b/webassets/fonts/MonaspaceArgon-WideExtraLight.woff new file mode 100644 index 0000000..7b3f395 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-WideExtraLight.woff differ diff --git a/webassets/fonts/MonaspaceArgon-WideExtraLightItalic.woff b/webassets/fonts/MonaspaceArgon-WideExtraLightItalic.woff new file mode 100644 index 0000000..9809437 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-WideExtraLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-WideItalic.woff b/webassets/fonts/MonaspaceArgon-WideItalic.woff new file mode 100644 index 0000000..6ecdc3c Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-WideItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-WideLight.woff b/webassets/fonts/MonaspaceArgon-WideLight.woff new file mode 100644 index 0000000..98af621 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-WideLight.woff differ diff --git a/webassets/fonts/MonaspaceArgon-WideLightItalic.woff b/webassets/fonts/MonaspaceArgon-WideLightItalic.woff new file mode 100644 index 0000000..bb0577f Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-WideLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-WideMedium.woff b/webassets/fonts/MonaspaceArgon-WideMedium.woff new file mode 100644 index 0000000..f045979 Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-WideMedium.woff differ diff --git a/webassets/fonts/MonaspaceArgon-WideMediumItalic.woff b/webassets/fonts/MonaspaceArgon-WideMediumItalic.woff new file mode 100644 index 0000000..a24855f Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-WideMediumItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgon-WideRegular.woff b/webassets/fonts/MonaspaceArgon-WideRegular.woff new file mode 100644 index 0000000..abbb77b Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-WideRegular.woff differ diff --git a/webassets/fonts/MonaspaceArgon-WideSemiBold.woff b/webassets/fonts/MonaspaceArgon-WideSemiBold.woff new file mode 100644 index 0000000..a0c546c Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-WideSemiBold.woff differ diff --git a/webassets/fonts/MonaspaceArgon-WideSemiBoldItalic.woff b/webassets/fonts/MonaspaceArgon-WideSemiBoldItalic.woff new file mode 100644 index 0000000..3d9956a Binary files /dev/null and b/webassets/fonts/MonaspaceArgon-WideSemiBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceArgonVarVF[wght,wdth,slnt].woff b/webassets/fonts/MonaspaceArgonVarVF[wght,wdth,slnt].woff new file mode 100644 index 0000000..b10ceac Binary files /dev/null and b/webassets/fonts/MonaspaceArgonVarVF[wght,wdth,slnt].woff differ diff --git a/webassets/fonts/MonaspaceArgonVarVF[wght,wdth,slnt].woff2 b/webassets/fonts/MonaspaceArgonVarVF[wght,wdth,slnt].woff2 new file mode 100644 index 0000000..6ec49f0 Binary files /dev/null and b/webassets/fonts/MonaspaceArgonVarVF[wght,wdth,slnt].woff2 differ diff --git a/webassets/fonts/MonaspaceKrypton-Bold.woff b/webassets/fonts/MonaspaceKrypton-Bold.woff new file mode 100644 index 0000000..19fe6e7 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-Bold.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-BoldItalic.woff b/webassets/fonts/MonaspaceKrypton-BoldItalic.woff new file mode 100644 index 0000000..e82e99c Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-BoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-ExtraBold.woff b/webassets/fonts/MonaspaceKrypton-ExtraBold.woff new file mode 100644 index 0000000..8bc44da Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-ExtraBold.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-ExtraBoldItalic.woff b/webassets/fonts/MonaspaceKrypton-ExtraBoldItalic.woff new file mode 100644 index 0000000..2c5b631 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-ExtraBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-ExtraLight.woff b/webassets/fonts/MonaspaceKrypton-ExtraLight.woff new file mode 100644 index 0000000..b6150be Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-ExtraLight.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-ExtraLightItalic.woff b/webassets/fonts/MonaspaceKrypton-ExtraLightItalic.woff new file mode 100644 index 0000000..2ca63fb Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-ExtraLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-Italic.woff b/webassets/fonts/MonaspaceKrypton-Italic.woff new file mode 100644 index 0000000..d2c9cfe Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-Italic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-Light.woff b/webassets/fonts/MonaspaceKrypton-Light.woff new file mode 100644 index 0000000..f2ad9ff Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-Light.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-LightItalic.woff b/webassets/fonts/MonaspaceKrypton-LightItalic.woff new file mode 100644 index 0000000..f7d3b1b Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-LightItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-Medium.woff b/webassets/fonts/MonaspaceKrypton-Medium.woff new file mode 100644 index 0000000..87ee1cd Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-Medium.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-MediumItalic.woff b/webassets/fonts/MonaspaceKrypton-MediumItalic.woff new file mode 100644 index 0000000..fde0ec8 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-MediumItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-Regular.woff b/webassets/fonts/MonaspaceKrypton-Regular.woff new file mode 100644 index 0000000..34e5a87 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-Regular.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-SemiBold.woff b/webassets/fonts/MonaspaceKrypton-SemiBold.woff new file mode 100644 index 0000000..7a7185e Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-SemiBold.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-SemiBoldItalic.woff b/webassets/fonts/MonaspaceKrypton-SemiBoldItalic.woff new file mode 100644 index 0000000..3ed5727 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-SemiBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-SemiWideBold.woff b/webassets/fonts/MonaspaceKrypton-SemiWideBold.woff new file mode 100644 index 0000000..fb575b3 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-SemiWideBold.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-SemiWideBoldItalic.woff b/webassets/fonts/MonaspaceKrypton-SemiWideBoldItalic.woff new file mode 100644 index 0000000..42ca502 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-SemiWideBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-SemiWideExtraBold.woff b/webassets/fonts/MonaspaceKrypton-SemiWideExtraBold.woff new file mode 100644 index 0000000..8b48386 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-SemiWideExtraBold.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-SemiWideExtraBoldItalic.woff b/webassets/fonts/MonaspaceKrypton-SemiWideExtraBoldItalic.woff new file mode 100644 index 0000000..a1786a3 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-SemiWideExtraBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-SemiWideExtraLight.woff b/webassets/fonts/MonaspaceKrypton-SemiWideExtraLight.woff new file mode 100644 index 0000000..891bd12 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-SemiWideExtraLight.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-SemiWideExtraLightItalic.woff b/webassets/fonts/MonaspaceKrypton-SemiWideExtraLightItalic.woff new file mode 100644 index 0000000..b2f16ce Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-SemiWideExtraLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-SemiWideItalic.woff b/webassets/fonts/MonaspaceKrypton-SemiWideItalic.woff new file mode 100644 index 0000000..fcd54c8 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-SemiWideItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-SemiWideLight.woff b/webassets/fonts/MonaspaceKrypton-SemiWideLight.woff new file mode 100644 index 0000000..42b924c Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-SemiWideLight.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-SemiWideLightItalic.woff b/webassets/fonts/MonaspaceKrypton-SemiWideLightItalic.woff new file mode 100644 index 0000000..12b19d7 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-SemiWideLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-SemiWideMedium.woff b/webassets/fonts/MonaspaceKrypton-SemiWideMedium.woff new file mode 100644 index 0000000..2a9fea8 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-SemiWideMedium.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-SemiWideMediumItalic.woff b/webassets/fonts/MonaspaceKrypton-SemiWideMediumItalic.woff new file mode 100644 index 0000000..0fa808d Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-SemiWideMediumItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-SemiWideRegular.woff b/webassets/fonts/MonaspaceKrypton-SemiWideRegular.woff new file mode 100644 index 0000000..b9dea16 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-SemiWideRegular.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-SemiWideSemiBold.woff b/webassets/fonts/MonaspaceKrypton-SemiWideSemiBold.woff new file mode 100644 index 0000000..1b1617e Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-SemiWideSemiBold.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-SemiWideSemiBoldItalic.woff b/webassets/fonts/MonaspaceKrypton-SemiWideSemiBoldItalic.woff new file mode 100644 index 0000000..c23969d Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-SemiWideSemiBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-WideBold.woff b/webassets/fonts/MonaspaceKrypton-WideBold.woff new file mode 100644 index 0000000..3b98b7f Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-WideBold.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-WideBoldItalic.woff b/webassets/fonts/MonaspaceKrypton-WideBoldItalic.woff new file mode 100644 index 0000000..3846089 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-WideBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-WideExtraBold.woff b/webassets/fonts/MonaspaceKrypton-WideExtraBold.woff new file mode 100644 index 0000000..8988e49 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-WideExtraBold.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-WideExtraBoldItalic.woff b/webassets/fonts/MonaspaceKrypton-WideExtraBoldItalic.woff new file mode 100644 index 0000000..d5197ad Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-WideExtraBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-WideExtraLight.woff b/webassets/fonts/MonaspaceKrypton-WideExtraLight.woff new file mode 100644 index 0000000..d34ac4f Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-WideExtraLight.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-WideExtraLightItalic.woff b/webassets/fonts/MonaspaceKrypton-WideExtraLightItalic.woff new file mode 100644 index 0000000..1fab466 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-WideExtraLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-WideItalic.woff b/webassets/fonts/MonaspaceKrypton-WideItalic.woff new file mode 100644 index 0000000..0b5914f Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-WideItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-WideLight.woff b/webassets/fonts/MonaspaceKrypton-WideLight.woff new file mode 100644 index 0000000..137707d Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-WideLight.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-WideLightItalic.woff b/webassets/fonts/MonaspaceKrypton-WideLightItalic.woff new file mode 100644 index 0000000..ecd5738 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-WideLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-WideMedium.woff b/webassets/fonts/MonaspaceKrypton-WideMedium.woff new file mode 100644 index 0000000..b141388 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-WideMedium.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-WideMediumItalic.woff b/webassets/fonts/MonaspaceKrypton-WideMediumItalic.woff new file mode 100644 index 0000000..9725fdd Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-WideMediumItalic.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-WideRegular.woff b/webassets/fonts/MonaspaceKrypton-WideRegular.woff new file mode 100644 index 0000000..ee89b68 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-WideRegular.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-WideSemiBold.woff b/webassets/fonts/MonaspaceKrypton-WideSemiBold.woff new file mode 100644 index 0000000..3b4f039 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-WideSemiBold.woff differ diff --git a/webassets/fonts/MonaspaceKrypton-WideSemiBoldItalic.woff b/webassets/fonts/MonaspaceKrypton-WideSemiBoldItalic.woff new file mode 100644 index 0000000..54cdb84 Binary files /dev/null and b/webassets/fonts/MonaspaceKrypton-WideSemiBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceKryptonVarVF[wght,wdth,slnt].woff b/webassets/fonts/MonaspaceKryptonVarVF[wght,wdth,slnt].woff new file mode 100644 index 0000000..0c38488 Binary files /dev/null and b/webassets/fonts/MonaspaceKryptonVarVF[wght,wdth,slnt].woff differ diff --git a/webassets/fonts/MonaspaceKryptonVarVF[wght,wdth,slnt].woff2 b/webassets/fonts/MonaspaceKryptonVarVF[wght,wdth,slnt].woff2 new file mode 100644 index 0000000..dfb9866 Binary files /dev/null and b/webassets/fonts/MonaspaceKryptonVarVF[wght,wdth,slnt].woff2 differ diff --git a/webassets/fonts/MonaspaceNeon-Bold.woff b/webassets/fonts/MonaspaceNeon-Bold.woff new file mode 100644 index 0000000..541cb4b Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-Bold.woff differ diff --git a/webassets/fonts/MonaspaceNeon-BoldItalic.woff b/webassets/fonts/MonaspaceNeon-BoldItalic.woff new file mode 100644 index 0000000..1509ddd Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-BoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-ExtraBold.woff b/webassets/fonts/MonaspaceNeon-ExtraBold.woff new file mode 100644 index 0000000..f2640e8 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-ExtraBold.woff differ diff --git a/webassets/fonts/MonaspaceNeon-ExtraBoldItalic.woff b/webassets/fonts/MonaspaceNeon-ExtraBoldItalic.woff new file mode 100644 index 0000000..fcbafb6 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-ExtraBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-ExtraLight.woff b/webassets/fonts/MonaspaceNeon-ExtraLight.woff new file mode 100644 index 0000000..f8380b7 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-ExtraLight.woff differ diff --git a/webassets/fonts/MonaspaceNeon-ExtraLightItalic.woff b/webassets/fonts/MonaspaceNeon-ExtraLightItalic.woff new file mode 100644 index 0000000..1bb5381 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-ExtraLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-Italic.woff b/webassets/fonts/MonaspaceNeon-Italic.woff new file mode 100644 index 0000000..9264e0b Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-Italic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-Light.woff b/webassets/fonts/MonaspaceNeon-Light.woff new file mode 100644 index 0000000..192619c Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-Light.woff differ diff --git a/webassets/fonts/MonaspaceNeon-LightItalic.woff b/webassets/fonts/MonaspaceNeon-LightItalic.woff new file mode 100644 index 0000000..a920535 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-LightItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-Medium.woff b/webassets/fonts/MonaspaceNeon-Medium.woff new file mode 100644 index 0000000..91ae113 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-Medium.woff differ diff --git a/webassets/fonts/MonaspaceNeon-MediumItalic.woff b/webassets/fonts/MonaspaceNeon-MediumItalic.woff new file mode 100644 index 0000000..9a7a07f Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-MediumItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-Regular.woff b/webassets/fonts/MonaspaceNeon-Regular.woff new file mode 100644 index 0000000..ce0168b Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-Regular.woff differ diff --git a/webassets/fonts/MonaspaceNeon-SemiBold.woff b/webassets/fonts/MonaspaceNeon-SemiBold.woff new file mode 100644 index 0000000..c31abc1 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-SemiBold.woff differ diff --git a/webassets/fonts/MonaspaceNeon-SemiBoldItalic.woff b/webassets/fonts/MonaspaceNeon-SemiBoldItalic.woff new file mode 100644 index 0000000..9e0a4e6 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-SemiBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-SemiWideBold.woff b/webassets/fonts/MonaspaceNeon-SemiWideBold.woff new file mode 100644 index 0000000..1bd5544 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-SemiWideBold.woff differ diff --git a/webassets/fonts/MonaspaceNeon-SemiWideBoldItalic.woff b/webassets/fonts/MonaspaceNeon-SemiWideBoldItalic.woff new file mode 100644 index 0000000..36d969e Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-SemiWideBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-SemiWideExtraBold.woff b/webassets/fonts/MonaspaceNeon-SemiWideExtraBold.woff new file mode 100644 index 0000000..66c6e10 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-SemiWideExtraBold.woff differ diff --git a/webassets/fonts/MonaspaceNeon-SemiWideExtraBoldItalic.woff b/webassets/fonts/MonaspaceNeon-SemiWideExtraBoldItalic.woff new file mode 100644 index 0000000..8a6f43d Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-SemiWideExtraBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-SemiWideExtraLight.woff b/webassets/fonts/MonaspaceNeon-SemiWideExtraLight.woff new file mode 100644 index 0000000..2df8b26 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-SemiWideExtraLight.woff differ diff --git a/webassets/fonts/MonaspaceNeon-SemiWideExtraLightItalic.woff b/webassets/fonts/MonaspaceNeon-SemiWideExtraLightItalic.woff new file mode 100644 index 0000000..6252c87 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-SemiWideExtraLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-SemiWideItalic.woff b/webassets/fonts/MonaspaceNeon-SemiWideItalic.woff new file mode 100644 index 0000000..e60fad9 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-SemiWideItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-SemiWideLight.woff b/webassets/fonts/MonaspaceNeon-SemiWideLight.woff new file mode 100644 index 0000000..7ca6ddc Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-SemiWideLight.woff differ diff --git a/webassets/fonts/MonaspaceNeon-SemiWideLightItalic.woff b/webassets/fonts/MonaspaceNeon-SemiWideLightItalic.woff new file mode 100644 index 0000000..a06c738 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-SemiWideLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-SemiWideMedium.woff b/webassets/fonts/MonaspaceNeon-SemiWideMedium.woff new file mode 100644 index 0000000..57a67ab Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-SemiWideMedium.woff differ diff --git a/webassets/fonts/MonaspaceNeon-SemiWideMediumItalic.woff b/webassets/fonts/MonaspaceNeon-SemiWideMediumItalic.woff new file mode 100644 index 0000000..f59f939 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-SemiWideMediumItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-SemiWideRegular.woff b/webassets/fonts/MonaspaceNeon-SemiWideRegular.woff new file mode 100644 index 0000000..d9baf49 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-SemiWideRegular.woff differ diff --git a/webassets/fonts/MonaspaceNeon-SemiWideSemiBold.woff b/webassets/fonts/MonaspaceNeon-SemiWideSemiBold.woff new file mode 100644 index 0000000..0f31632 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-SemiWideSemiBold.woff differ diff --git a/webassets/fonts/MonaspaceNeon-SemiWideSemiBoldItalic.woff b/webassets/fonts/MonaspaceNeon-SemiWideSemiBoldItalic.woff new file mode 100644 index 0000000..89816fa Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-SemiWideSemiBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-WideBold.woff b/webassets/fonts/MonaspaceNeon-WideBold.woff new file mode 100644 index 0000000..0eadcb9 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-WideBold.woff differ diff --git a/webassets/fonts/MonaspaceNeon-WideBoldItalic.woff b/webassets/fonts/MonaspaceNeon-WideBoldItalic.woff new file mode 100644 index 0000000..1040f92 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-WideBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-WideExtraBold.woff b/webassets/fonts/MonaspaceNeon-WideExtraBold.woff new file mode 100644 index 0000000..6e3a20a Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-WideExtraBold.woff differ diff --git a/webassets/fonts/MonaspaceNeon-WideExtraBoldItalic.woff b/webassets/fonts/MonaspaceNeon-WideExtraBoldItalic.woff new file mode 100644 index 0000000..c3f24c3 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-WideExtraBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-WideExtraLight.woff b/webassets/fonts/MonaspaceNeon-WideExtraLight.woff new file mode 100644 index 0000000..d569685 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-WideExtraLight.woff differ diff --git a/webassets/fonts/MonaspaceNeon-WideExtraLightItalic.woff b/webassets/fonts/MonaspaceNeon-WideExtraLightItalic.woff new file mode 100644 index 0000000..fa657b3 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-WideExtraLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-WideItalic.woff b/webassets/fonts/MonaspaceNeon-WideItalic.woff new file mode 100644 index 0000000..fa8627b Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-WideItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-WideLight.woff b/webassets/fonts/MonaspaceNeon-WideLight.woff new file mode 100644 index 0000000..58197a8 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-WideLight.woff differ diff --git a/webassets/fonts/MonaspaceNeon-WideLightItalic.woff b/webassets/fonts/MonaspaceNeon-WideLightItalic.woff new file mode 100644 index 0000000..e8cceb3 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-WideLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-WideMedium.woff b/webassets/fonts/MonaspaceNeon-WideMedium.woff new file mode 100644 index 0000000..36afb79 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-WideMedium.woff differ diff --git a/webassets/fonts/MonaspaceNeon-WideMediumItalic.woff b/webassets/fonts/MonaspaceNeon-WideMediumItalic.woff new file mode 100644 index 0000000..f1efbe7 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-WideMediumItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeon-WideRegular.woff b/webassets/fonts/MonaspaceNeon-WideRegular.woff new file mode 100644 index 0000000..b4dbee5 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-WideRegular.woff differ diff --git a/webassets/fonts/MonaspaceNeon-WideSemiBold.woff b/webassets/fonts/MonaspaceNeon-WideSemiBold.woff new file mode 100644 index 0000000..3e204d7 Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-WideSemiBold.woff differ diff --git a/webassets/fonts/MonaspaceNeon-WideSemiBoldItalic.woff b/webassets/fonts/MonaspaceNeon-WideSemiBoldItalic.woff new file mode 100644 index 0000000..9a6ef6a Binary files /dev/null and b/webassets/fonts/MonaspaceNeon-WideSemiBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceNeonVarVF[wght,wdth,slnt].woff b/webassets/fonts/MonaspaceNeonVarVF[wght,wdth,slnt].woff new file mode 100644 index 0000000..cc93a04 Binary files /dev/null and b/webassets/fonts/MonaspaceNeonVarVF[wght,wdth,slnt].woff differ diff --git a/webassets/fonts/MonaspaceNeonVarVF[wght,wdth,slnt].woff2 b/webassets/fonts/MonaspaceNeonVarVF[wght,wdth,slnt].woff2 new file mode 100644 index 0000000..74117fc Binary files /dev/null and b/webassets/fonts/MonaspaceNeonVarVF[wght,wdth,slnt].woff2 differ diff --git a/webassets/fonts/MonaspaceRadon-Bold.woff b/webassets/fonts/MonaspaceRadon-Bold.woff new file mode 100644 index 0000000..75b8894 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-Bold.woff differ diff --git a/webassets/fonts/MonaspaceRadon-BoldItalic.woff b/webassets/fonts/MonaspaceRadon-BoldItalic.woff new file mode 100644 index 0000000..b27d652 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-BoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-ExtraBold.woff b/webassets/fonts/MonaspaceRadon-ExtraBold.woff new file mode 100644 index 0000000..7695651 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-ExtraBold.woff differ diff --git a/webassets/fonts/MonaspaceRadon-ExtraBoldItalic.woff b/webassets/fonts/MonaspaceRadon-ExtraBoldItalic.woff new file mode 100644 index 0000000..92cdbbb Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-ExtraBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-ExtraLight.woff b/webassets/fonts/MonaspaceRadon-ExtraLight.woff new file mode 100644 index 0000000..75cbe70 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-ExtraLight.woff differ diff --git a/webassets/fonts/MonaspaceRadon-ExtraLightItalic.woff b/webassets/fonts/MonaspaceRadon-ExtraLightItalic.woff new file mode 100644 index 0000000..9030786 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-ExtraLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-Italic.woff b/webassets/fonts/MonaspaceRadon-Italic.woff new file mode 100644 index 0000000..4a2939c Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-Italic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-Light.woff b/webassets/fonts/MonaspaceRadon-Light.woff new file mode 100644 index 0000000..81bcaf1 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-Light.woff differ diff --git a/webassets/fonts/MonaspaceRadon-LightItalic.woff b/webassets/fonts/MonaspaceRadon-LightItalic.woff new file mode 100644 index 0000000..5e93a26 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-LightItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-Medium.woff b/webassets/fonts/MonaspaceRadon-Medium.woff new file mode 100644 index 0000000..2f0aa07 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-Medium.woff differ diff --git a/webassets/fonts/MonaspaceRadon-MediumItalic.woff b/webassets/fonts/MonaspaceRadon-MediumItalic.woff new file mode 100644 index 0000000..938c7ef Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-MediumItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-Regular.woff b/webassets/fonts/MonaspaceRadon-Regular.woff new file mode 100644 index 0000000..2a72b04 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-Regular.woff differ diff --git a/webassets/fonts/MonaspaceRadon-SemiBold.woff b/webassets/fonts/MonaspaceRadon-SemiBold.woff new file mode 100644 index 0000000..af383b0 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-SemiBold.woff differ diff --git a/webassets/fonts/MonaspaceRadon-SemiBoldItalic.woff b/webassets/fonts/MonaspaceRadon-SemiBoldItalic.woff new file mode 100644 index 0000000..ade405d Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-SemiBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-SemiWideBold.woff b/webassets/fonts/MonaspaceRadon-SemiWideBold.woff new file mode 100644 index 0000000..7d76db6 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-SemiWideBold.woff differ diff --git a/webassets/fonts/MonaspaceRadon-SemiWideBoldItalic.woff b/webassets/fonts/MonaspaceRadon-SemiWideBoldItalic.woff new file mode 100644 index 0000000..85e0486 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-SemiWideBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-SemiWideExtraBold.woff b/webassets/fonts/MonaspaceRadon-SemiWideExtraBold.woff new file mode 100644 index 0000000..2513973 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-SemiWideExtraBold.woff differ diff --git a/webassets/fonts/MonaspaceRadon-SemiWideExtraBoldItalic.woff b/webassets/fonts/MonaspaceRadon-SemiWideExtraBoldItalic.woff new file mode 100644 index 0000000..4ebb9a5 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-SemiWideExtraBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-SemiWideExtraLight.woff b/webassets/fonts/MonaspaceRadon-SemiWideExtraLight.woff new file mode 100644 index 0000000..cf4574d Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-SemiWideExtraLight.woff differ diff --git a/webassets/fonts/MonaspaceRadon-SemiWideExtraLightItalic.woff b/webassets/fonts/MonaspaceRadon-SemiWideExtraLightItalic.woff new file mode 100644 index 0000000..60b8dd0 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-SemiWideExtraLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-SemiWideItalic.woff b/webassets/fonts/MonaspaceRadon-SemiWideItalic.woff new file mode 100644 index 0000000..b23b008 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-SemiWideItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-SemiWideLight.woff b/webassets/fonts/MonaspaceRadon-SemiWideLight.woff new file mode 100644 index 0000000..2d05296 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-SemiWideLight.woff differ diff --git a/webassets/fonts/MonaspaceRadon-SemiWideLightItalic.woff b/webassets/fonts/MonaspaceRadon-SemiWideLightItalic.woff new file mode 100644 index 0000000..c00d6ca Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-SemiWideLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-SemiWideMedium.woff b/webassets/fonts/MonaspaceRadon-SemiWideMedium.woff new file mode 100644 index 0000000..057e397 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-SemiWideMedium.woff differ diff --git a/webassets/fonts/MonaspaceRadon-SemiWideMediumItalic.woff b/webassets/fonts/MonaspaceRadon-SemiWideMediumItalic.woff new file mode 100644 index 0000000..dfaed41 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-SemiWideMediumItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-SemiWideRegular.woff b/webassets/fonts/MonaspaceRadon-SemiWideRegular.woff new file mode 100644 index 0000000..cf55da5 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-SemiWideRegular.woff differ diff --git a/webassets/fonts/MonaspaceRadon-SemiWideSemiBold.woff b/webassets/fonts/MonaspaceRadon-SemiWideSemiBold.woff new file mode 100644 index 0000000..5f5b50c Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-SemiWideSemiBold.woff differ diff --git a/webassets/fonts/MonaspaceRadon-SemiWideSemiBoldItalic.woff b/webassets/fonts/MonaspaceRadon-SemiWideSemiBoldItalic.woff new file mode 100644 index 0000000..bae92e4 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-SemiWideSemiBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-WideBold.woff b/webassets/fonts/MonaspaceRadon-WideBold.woff new file mode 100644 index 0000000..fe477fd Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-WideBold.woff differ diff --git a/webassets/fonts/MonaspaceRadon-WideBoldItalic.woff b/webassets/fonts/MonaspaceRadon-WideBoldItalic.woff new file mode 100644 index 0000000..820906c Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-WideBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-WideExtraBold.woff b/webassets/fonts/MonaspaceRadon-WideExtraBold.woff new file mode 100644 index 0000000..c14184d Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-WideExtraBold.woff differ diff --git a/webassets/fonts/MonaspaceRadon-WideExtraBoldItalic.woff b/webassets/fonts/MonaspaceRadon-WideExtraBoldItalic.woff new file mode 100644 index 0000000..7ffe48d Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-WideExtraBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-WideExtraLight.woff b/webassets/fonts/MonaspaceRadon-WideExtraLight.woff new file mode 100644 index 0000000..393e742 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-WideExtraLight.woff differ diff --git a/webassets/fonts/MonaspaceRadon-WideExtraLightItalic.woff b/webassets/fonts/MonaspaceRadon-WideExtraLightItalic.woff new file mode 100644 index 0000000..3416740 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-WideExtraLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-WideItalic.woff b/webassets/fonts/MonaspaceRadon-WideItalic.woff new file mode 100644 index 0000000..c9d071c Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-WideItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-WideLight.woff b/webassets/fonts/MonaspaceRadon-WideLight.woff new file mode 100644 index 0000000..65ab94b Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-WideLight.woff differ diff --git a/webassets/fonts/MonaspaceRadon-WideLightItalic.woff b/webassets/fonts/MonaspaceRadon-WideLightItalic.woff new file mode 100644 index 0000000..8a9c4bc Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-WideLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-WideMedium.woff b/webassets/fonts/MonaspaceRadon-WideMedium.woff new file mode 100644 index 0000000..6c342d0 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-WideMedium.woff differ diff --git a/webassets/fonts/MonaspaceRadon-WideMediumItalic.woff b/webassets/fonts/MonaspaceRadon-WideMediumItalic.woff new file mode 100644 index 0000000..db5dbc1 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-WideMediumItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadon-WideRegular.woff b/webassets/fonts/MonaspaceRadon-WideRegular.woff new file mode 100644 index 0000000..567246f Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-WideRegular.woff differ diff --git a/webassets/fonts/MonaspaceRadon-WideSemiBold.woff b/webassets/fonts/MonaspaceRadon-WideSemiBold.woff new file mode 100644 index 0000000..491ded7 Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-WideSemiBold.woff differ diff --git a/webassets/fonts/MonaspaceRadon-WideSemiBoldItalic.woff b/webassets/fonts/MonaspaceRadon-WideSemiBoldItalic.woff new file mode 100644 index 0000000..0555bdd Binary files /dev/null and b/webassets/fonts/MonaspaceRadon-WideSemiBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceRadonVarVF[wght,wdth,slnt].woff b/webassets/fonts/MonaspaceRadonVarVF[wght,wdth,slnt].woff new file mode 100644 index 0000000..e328b99 Binary files /dev/null and b/webassets/fonts/MonaspaceRadonVarVF[wght,wdth,slnt].woff differ diff --git a/webassets/fonts/MonaspaceRadonVarVF[wght,wdth,slnt].woff2 b/webassets/fonts/MonaspaceRadonVarVF[wght,wdth,slnt].woff2 new file mode 100644 index 0000000..b2feb7b Binary files /dev/null and b/webassets/fonts/MonaspaceRadonVarVF[wght,wdth,slnt].woff2 differ diff --git a/webassets/fonts/MonaspaceXenon-Bold.woff b/webassets/fonts/MonaspaceXenon-Bold.woff new file mode 100644 index 0000000..99daf27 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-Bold.woff differ diff --git a/webassets/fonts/MonaspaceXenon-BoldItalic.woff b/webassets/fonts/MonaspaceXenon-BoldItalic.woff new file mode 100644 index 0000000..50ed959 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-BoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-ExtraBold.woff b/webassets/fonts/MonaspaceXenon-ExtraBold.woff new file mode 100644 index 0000000..1f18154 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-ExtraBold.woff differ diff --git a/webassets/fonts/MonaspaceXenon-ExtraBoldItalic.woff b/webassets/fonts/MonaspaceXenon-ExtraBoldItalic.woff new file mode 100644 index 0000000..e8242f7 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-ExtraBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-ExtraLight.woff b/webassets/fonts/MonaspaceXenon-ExtraLight.woff new file mode 100644 index 0000000..7318830 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-ExtraLight.woff differ diff --git a/webassets/fonts/MonaspaceXenon-ExtraLightItalic.woff b/webassets/fonts/MonaspaceXenon-ExtraLightItalic.woff new file mode 100644 index 0000000..a0ae787 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-ExtraLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-Italic.woff b/webassets/fonts/MonaspaceXenon-Italic.woff new file mode 100644 index 0000000..2fd2009 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-Italic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-Light.woff b/webassets/fonts/MonaspaceXenon-Light.woff new file mode 100644 index 0000000..2fdbe64 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-Light.woff differ diff --git a/webassets/fonts/MonaspaceXenon-LightItalic.woff b/webassets/fonts/MonaspaceXenon-LightItalic.woff new file mode 100644 index 0000000..f702449 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-LightItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-Medium.woff b/webassets/fonts/MonaspaceXenon-Medium.woff new file mode 100644 index 0000000..abaf72b Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-Medium.woff differ diff --git a/webassets/fonts/MonaspaceXenon-MediumItalic.woff b/webassets/fonts/MonaspaceXenon-MediumItalic.woff new file mode 100644 index 0000000..43d2045 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-MediumItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-Regular.woff b/webassets/fonts/MonaspaceXenon-Regular.woff new file mode 100644 index 0000000..ad34890 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-Regular.woff differ diff --git a/webassets/fonts/MonaspaceXenon-SemiBold.woff b/webassets/fonts/MonaspaceXenon-SemiBold.woff new file mode 100644 index 0000000..a397b0f Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-SemiBold.woff differ diff --git a/webassets/fonts/MonaspaceXenon-SemiBoldItalic.woff b/webassets/fonts/MonaspaceXenon-SemiBoldItalic.woff new file mode 100644 index 0000000..5496ce3 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-SemiBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-SemiWideBold.woff b/webassets/fonts/MonaspaceXenon-SemiWideBold.woff new file mode 100644 index 0000000..1e603b7 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-SemiWideBold.woff differ diff --git a/webassets/fonts/MonaspaceXenon-SemiWideBoldItalic.woff b/webassets/fonts/MonaspaceXenon-SemiWideBoldItalic.woff new file mode 100644 index 0000000..d2da3c6 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-SemiWideBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-SemiWideExtraBold.woff b/webassets/fonts/MonaspaceXenon-SemiWideExtraBold.woff new file mode 100644 index 0000000..5cbce66 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-SemiWideExtraBold.woff differ diff --git a/webassets/fonts/MonaspaceXenon-SemiWideExtraBoldItalic.woff b/webassets/fonts/MonaspaceXenon-SemiWideExtraBoldItalic.woff new file mode 100644 index 0000000..e58b7a3 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-SemiWideExtraBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-SemiWideExtraLight.woff b/webassets/fonts/MonaspaceXenon-SemiWideExtraLight.woff new file mode 100644 index 0000000..5df264e Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-SemiWideExtraLight.woff differ diff --git a/webassets/fonts/MonaspaceXenon-SemiWideExtraLightItalic.woff b/webassets/fonts/MonaspaceXenon-SemiWideExtraLightItalic.woff new file mode 100644 index 0000000..1301f44 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-SemiWideExtraLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-SemiWideItalic.woff b/webassets/fonts/MonaspaceXenon-SemiWideItalic.woff new file mode 100644 index 0000000..2537b82 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-SemiWideItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-SemiWideLight.woff b/webassets/fonts/MonaspaceXenon-SemiWideLight.woff new file mode 100644 index 0000000..8a81ffd Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-SemiWideLight.woff differ diff --git a/webassets/fonts/MonaspaceXenon-SemiWideLightItalic.woff b/webassets/fonts/MonaspaceXenon-SemiWideLightItalic.woff new file mode 100644 index 0000000..007ccc1 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-SemiWideLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-SemiWideMedium.woff b/webassets/fonts/MonaspaceXenon-SemiWideMedium.woff new file mode 100644 index 0000000..ab2ab03 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-SemiWideMedium.woff differ diff --git a/webassets/fonts/MonaspaceXenon-SemiWideMediumItalic.woff b/webassets/fonts/MonaspaceXenon-SemiWideMediumItalic.woff new file mode 100644 index 0000000..9428598 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-SemiWideMediumItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-SemiWideRegular.woff b/webassets/fonts/MonaspaceXenon-SemiWideRegular.woff new file mode 100644 index 0000000..f2951e1 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-SemiWideRegular.woff differ diff --git a/webassets/fonts/MonaspaceXenon-SemiWideSemiBold.woff b/webassets/fonts/MonaspaceXenon-SemiWideSemiBold.woff new file mode 100644 index 0000000..8bfdc66 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-SemiWideSemiBold.woff differ diff --git a/webassets/fonts/MonaspaceXenon-SemiWideSemiBoldItalic.woff b/webassets/fonts/MonaspaceXenon-SemiWideSemiBoldItalic.woff new file mode 100644 index 0000000..97a4ffd Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-SemiWideSemiBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-WideBold.woff b/webassets/fonts/MonaspaceXenon-WideBold.woff new file mode 100644 index 0000000..d0bdadc Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-WideBold.woff differ diff --git a/webassets/fonts/MonaspaceXenon-WideBoldItalic.woff b/webassets/fonts/MonaspaceXenon-WideBoldItalic.woff new file mode 100644 index 0000000..acc0485 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-WideBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-WideExtraBold.woff b/webassets/fonts/MonaspaceXenon-WideExtraBold.woff new file mode 100644 index 0000000..27ecf88 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-WideExtraBold.woff differ diff --git a/webassets/fonts/MonaspaceXenon-WideExtraBoldItalic.woff b/webassets/fonts/MonaspaceXenon-WideExtraBoldItalic.woff new file mode 100644 index 0000000..8d481b1 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-WideExtraBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-WideExtraLight.woff b/webassets/fonts/MonaspaceXenon-WideExtraLight.woff new file mode 100644 index 0000000..4db048b Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-WideExtraLight.woff differ diff --git a/webassets/fonts/MonaspaceXenon-WideExtraLightItalic.woff b/webassets/fonts/MonaspaceXenon-WideExtraLightItalic.woff new file mode 100644 index 0000000..16a0381 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-WideExtraLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-WideItalic.woff b/webassets/fonts/MonaspaceXenon-WideItalic.woff new file mode 100644 index 0000000..9dd6d39 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-WideItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-WideLight.woff b/webassets/fonts/MonaspaceXenon-WideLight.woff new file mode 100644 index 0000000..ecd2cab Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-WideLight.woff differ diff --git a/webassets/fonts/MonaspaceXenon-WideLightItalic.woff b/webassets/fonts/MonaspaceXenon-WideLightItalic.woff new file mode 100644 index 0000000..dd7a014 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-WideLightItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-WideMedium.woff b/webassets/fonts/MonaspaceXenon-WideMedium.woff new file mode 100644 index 0000000..7d65fcc Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-WideMedium.woff differ diff --git a/webassets/fonts/MonaspaceXenon-WideMediumItalic.woff b/webassets/fonts/MonaspaceXenon-WideMediumItalic.woff new file mode 100644 index 0000000..c2895f2 Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-WideMediumItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenon-WideRegular.woff b/webassets/fonts/MonaspaceXenon-WideRegular.woff new file mode 100644 index 0000000..40d9cbf Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-WideRegular.woff differ diff --git a/webassets/fonts/MonaspaceXenon-WideSemiBold.woff b/webassets/fonts/MonaspaceXenon-WideSemiBold.woff new file mode 100644 index 0000000..319dd5a Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-WideSemiBold.woff differ diff --git a/webassets/fonts/MonaspaceXenon-WideSemiBoldItalic.woff b/webassets/fonts/MonaspaceXenon-WideSemiBoldItalic.woff new file mode 100644 index 0000000..a667e3c Binary files /dev/null and b/webassets/fonts/MonaspaceXenon-WideSemiBoldItalic.woff differ diff --git a/webassets/fonts/MonaspaceXenonVarVF[wght,wdth,slnt].woff b/webassets/fonts/MonaspaceXenonVarVF[wght,wdth,slnt].woff new file mode 100644 index 0000000..87ebf9b Binary files /dev/null and b/webassets/fonts/MonaspaceXenonVarVF[wght,wdth,slnt].woff differ diff --git a/webassets/fonts/MonaspaceXenonVarVF[wght,wdth,slnt].woff2 b/webassets/fonts/MonaspaceXenonVarVF[wght,wdth,slnt].woff2 new file mode 100644 index 0000000..a9f8115 Binary files /dev/null and b/webassets/fonts/MonaspaceXenonVarVF[wght,wdth,slnt].woff2 differ diff --git a/webassets/index.html b/webassets/index.html new file mode 100644 index 0000000..91abd03 --- /dev/null +++ b/webassets/index.html @@ -0,0 +1,33 @@ + + + + + + LocalhostBunny + + + + + + + + + +
+ +

LocalHostBunny

+ +
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/webassets/scripts/script.js b/webassets/scripts/script.js new file mode 100644 index 0000000..315a56e --- /dev/null +++ b/webassets/scripts/script.js @@ -0,0 +1,17 @@ + +function updateHTML() { + + const main = document.getElementById('maincontent') + + let html = ''; + + for (const srv of servers) { + + html += `${encodeURIComponent(srv['process'])} @ ${encodeURIComponent(srv['port'])}` + + } + main.innerHTML = html; + +} + +document.addEventListener("DOMContentLoaded", updateHTML); \ No newline at end of file diff --git a/webassets/website.go b/webassets/website.go new file mode 100644 index 0000000..bdd5eb3 --- /dev/null +++ b/webassets/website.go @@ -0,0 +1,222 @@ +package webassets + +import ( + "embed" + "fmt" + "github.com/rs/zerolog/log" + "io" + bunny "locbunny" + "os" + "path/filepath" + "sync" + "time" +) + +//go:embed *.html +//go:embed *.ico +//go:embed scripts/*.js +//go:embed css/*.css +//go:embed fonts/*.woff +//go:embed fonts/*.woff2 +var _assets embed.FS + +type templateCacheEntry struct { + MDate time.Time + Value ITemplate +} + +type fileCacheEntry struct { + MDate time.Time + Value []byte +} + +type Assets struct { + templateCache map[string]templateCacheEntry + fileCache map[string]fileCacheEntry + lock sync.RWMutex +} + +func NewAssets() *Assets { + return &Assets{ + templateCache: make(map[string]templateCacheEntry, 128), + fileCache: make(map[string]fileCacheEntry, 128), + lock: sync.RWMutex{}, + } +} + +type ITemplate interface { + Execute(wr io.Writer, data any) error +} + +func (a *Assets) ListAssets() []string { + result := make([]string, 0) + + entries, err := _assets.ReadDir(".") + if err != nil { + panic(err) + } + + for _, entry := range entries { + if entry.IsDir() { + panic("TODO implement recursion") + } + + if entry.Name() == "index.html" { + continue + } + + result = append(result, "/"+entry.Name()) + } + + return result +} + +func (a *Assets) Read(fp string) ([]byte, error) { + if bunny.Conf.LiveReload == nil { + + // no live-reload: use embedded data + + bin, err := _assets.ReadFile(fp) + if err != nil { + return nil, err + } + return bin, nil + + } else { + + liveFP := filepath.Join(*bunny.Conf.LiveReload, fp) + + stat, err := os.Stat(liveFP) + if err != nil { + return nil, err + } + + a.lock.RLock() + v, ok := a.fileCache[fp] + a.lock.RUnlock() + + if !ok { + + // initial load + + bin, err := os.ReadFile(liveFP) + if err != nil { + return nil, err + } + + a.lock.Lock() + a.fileCache[fp] = fileCacheEntry{MDate: stat.ModTime(), Value: bin} + a.lock.Unlock() + + return bin, nil + + } else if v.MDate != stat.ModTime() { + + // live reload + + log.Info().Msg(fmt.Sprintf("[>>] Live reload file '%s' from filesystem (file changed)", fp)) + + bin, err := os.ReadFile(liveFP) + if err != nil { + return nil, err + } + + a.lock.Lock() + a.fileCache[fp] = fileCacheEntry{MDate: stat.ModTime(), Value: bin} + a.lock.Unlock() + + return bin, nil + + } else { + // return from cache + return v.Value, nil + } + } +} + +func (a *Assets) Template(fp string, builder func([]byte) (ITemplate, error)) (ITemplate, error) { + if bunny.Conf.LiveReload == nil { + + // no live-reload: use embedded data, and permanently cache template + + a.lock.RLock() + v, ok := a.templateCache[fp] + a.lock.RUnlock() + if ok { + return v.Value, nil + } + + bin, err := _assets.ReadFile(fp) + if err != nil { + return nil, err + } + t, err := builder(bin) + if err != nil { + panic(err) + } + + a.lock.Lock() + a.templateCache[fp] = templateCacheEntry{MDate: time.Now(), Value: t} + a.lock.Unlock() + + return t, nil + + } else { + + a.lock.RLock() + v, ok := a.templateCache[fp] + a.lock.RUnlock() + + liveFP := filepath.Join(*bunny.Conf.LiveReload, fp) + + stat, err := os.Stat(liveFP) + if err != nil { + return nil, err + } + + if !ok { + + // initial load + + bin, err := os.ReadFile(liveFP) + if err != nil { + return nil, err + } + t, err := builder(bin) + if err != nil { + return nil, err + } + + a.lock.Lock() + a.templateCache[fp] = templateCacheEntry{MDate: stat.ModTime(), Value: t} + a.lock.Unlock() + + return t, nil + + } else if v.MDate != stat.ModTime() { + + // live reload + + log.Info().Msg(fmt.Sprintf("[>>] Live reload file '%s' from filesystem (file changed)", fp)) + + bin, err := os.ReadFile(liveFP) + if err != nil { + return nil, err + } + t, err := builder(bin) + if err != nil { + return nil, err + } + + a.lock.Lock() + a.templateCache[fp] = templateCacheEntry{MDate: stat.ModTime(), Value: t} + a.lock.Unlock() + + return t, nil + + } else { + // return from cache + return v.Value, nil + } + } +}