Installer: Refactor and give each searver its own directory
Change-Id: I1db2929e7a35b6f92022dec0c6506d68e0297563
diff --git a/core/auth/memberships/main.go b/core/auth/memberships/main.go
index 955e783..2e52323 100644
--- a/core/auth/memberships/main.go
+++ b/core/auth/memberships/main.go
@@ -673,7 +673,7 @@
e := make(chan error)
go func() {
r := mux.NewRouter()
- r.PathPrefix("/stat/").Handler(http.FileServer(http.FS(staticResources)))
+ r.PathPrefix("/static/").Handler(http.FileServer(http.FS(staticResources)))
r.HandleFunc("/group/{group-name}/add-user/", s.addUserToGroupHandler).Methods(http.MethodPost)
r.HandleFunc("/group/{parent-group}/add-child-group", s.addChildGroupHandler).Methods(http.MethodPost)
r.HandleFunc("/group/{owned-group}/add-owner-group", s.addOwnerGroupHandler).Methods(http.MethodPost)
diff --git a/core/auth/memberships/memberships-tmpl/base.html b/core/auth/memberships/memberships-tmpl/base.html
index e824597..9755c08 100644
--- a/core/auth/memberships/memberships-tmpl/base.html
+++ b/core/auth/memberships/memberships-tmpl/base.html
@@ -4,8 +4,8 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ block "title" . }}{{ end }}</title>
- <link rel="stylesheet" href="/stat/pico.2.0.6.min.css">
- <link rel="stylesheet" href="/stat/main.css?v=0.0.3">
+ <link rel="stylesheet" href="/static/pico.2.0.6.min.css">
+ <link rel="stylesheet" href="/static/main.css?v=0.0.3">
</head>
<body class="container">
{{ define "svgIcon" }}
@@ -29,6 +29,6 @@
</article>
</dialog>
{{ end }}
- <script src="/stat/main.js"></script>
+ <script src="/static/main.js"></script>
</body>
</html>
diff --git a/core/installer/cmd/app_manager.go b/core/installer/cmd/app_manager.go
index 16ac83a..afc7d32 100644
--- a/core/installer/cmd/app_manager.go
+++ b/core/installer/cmd/app_manager.go
@@ -7,9 +7,9 @@
"golang.org/x/crypto/ssh"
"github.com/giolekva/pcloud/core/installer"
+ "github.com/giolekva/pcloud/core/installer/server/appmanager"
"github.com/giolekva/pcloud/core/installer/soft"
"github.com/giolekva/pcloud/core/installer/tasks"
- "github.com/giolekva/pcloud/core/installer/welcome"
"github.com/go-git/go-billy/v5/memfs"
"github.com/spf13/cobra"
@@ -143,7 +143,7 @@
if err != nil {
return err
}
- s, err := welcome.NewAppManagerServer(
+ s, err := appmanager.NewServer(
appManagerFlags.port,
repoIO,
m,
diff --git a/core/installer/cmd/dodo_app.go b/core/installer/cmd/dodo_app.go
index 7954690..562627c 100644
--- a/core/installer/cmd/dodo_app.go
+++ b/core/installer/cmd/dodo_app.go
@@ -12,9 +12,9 @@
"os"
"github.com/giolekva/pcloud/core/installer"
+ dodoapp "github.com/giolekva/pcloud/core/installer/server/dodo-app"
"github.com/giolekva/pcloud/core/installer/soft"
"github.com/giolekva/pcloud/core/installer/tasks"
- "github.com/giolekva/pcloud/core/installer/welcome"
_ "github.com/ncruces/go-sqlite3"
_ "github.com/ncruces/go-sqlite3/driver"
@@ -172,14 +172,14 @@
if err != nil {
return err
}
- if ok, err := softClient.RepoExists(welcome.ConfigRepoName); err != nil {
+ if ok, err := softClient.RepoExists(dodoapp.ConfigRepoName); err != nil {
return err
} else if !ok {
- if err := softClient.AddRepository(welcome.ConfigRepoName); err != nil {
+ if err := softClient.AddRepository(dodoapp.ConfigRepoName); err != nil {
return err
}
}
- configRepo, err := softClient.GetRepo(welcome.ConfigRepoName)
+ configRepo, err := softClient.GetRepo(dodoapp.ConfigRepoName)
if err != nil {
return err
}
@@ -187,24 +187,24 @@
if err != nil {
return err
}
- st, err := welcome.NewStore(configRepo, db)
+ st, err := dodoapp.NewStore(configRepo, db)
if err != nil {
return err
}
- var nf welcome.NetworkFilter
+ var nf dodoapp.NetworkFilter
if len(dodoAppFlags.networks) == 0 {
- nf = welcome.NewNoNetworkFilter()
+ nf = dodoapp.NewNoNetworkFilter()
} else {
- nf = welcome.NewAllowListFilter(dodoAppFlags.networks)
+ nf = dodoapp.NewAllowListFilter(dodoAppFlags.networks)
}
if dodoAppFlags.external {
- nf = welcome.NewCombinedFilter(welcome.NewNetworkFilterByOwner(st), nf)
+ nf = dodoapp.NewCombinedFilter(dodoapp.NewNetworkFilterByOwner(st), nf)
}
- var ug welcome.UserGetter
+ var ug dodoapp.UserGetter
if dodoAppFlags.external {
- ug = welcome.NewExternalUserGetter()
+ ug = dodoapp.NewExternalUserGetter()
} else {
- ug = welcome.NewInternalUserGetter()
+ ug = dodoapp.NewInternalUserGetter()
}
reconciler := &tasks.SequentialReconciler{
[]tasks.Reconciler{
@@ -214,7 +214,7 @@
}
vpnKeyGen := installer.NewHeadscaleAPIClient(dodoAppFlags.headscaleAPIAddr)
cnc := &proxyConfigurator{dodoAppFlags.envAppManagerAddr}
- s, err := welcome.NewDodoAppServer(
+ s, err := dodoapp.NewServer(
st,
nf,
ug,
diff --git a/core/installer/cmd/env_manager.go b/core/installer/cmd/env_manager.go
index c0ea8e8..483211e 100644
--- a/core/installer/cmd/env_manager.go
+++ b/core/installer/cmd/env_manager.go
@@ -8,9 +8,9 @@
"github.com/giolekva/pcloud/core/installer"
"github.com/giolekva/pcloud/core/installer/dns"
"github.com/giolekva/pcloud/core/installer/http"
+ "github.com/giolekva/pcloud/core/installer/server/env"
"github.com/giolekva/pcloud/core/installer/soft"
"github.com/giolekva/pcloud/core/installer/tasks"
- "github.com/giolekva/pcloud/core/installer/welcome"
)
var envManagerFlags struct {
@@ -82,7 +82,7 @@
return err
}
httpClient := http.NewClient()
- s := welcome.NewEnvServer(
+ s := env.NewEnvServer(
envManagerFlags.port,
ss,
repoIO,
diff --git a/core/installer/cmd/launcher.go b/core/installer/cmd/launcher.go
index 71decb6..20b8d26 100644
--- a/core/installer/cmd/launcher.go
+++ b/core/installer/cmd/launcher.go
@@ -7,8 +7,8 @@
"os"
"github.com/giolekva/pcloud/core/installer"
+ "github.com/giolekva/pcloud/core/installer/server/launcher"
"github.com/giolekva/pcloud/core/installer/soft"
- "github.com/giolekva/pcloud/core/installer/welcome"
"github.com/spf13/cobra"
"golang.org/x/crypto/ssh"
@@ -84,10 +84,10 @@
if err != nil {
return err
}
- s, err := welcome.NewLauncherServer(
+ s, err := launcher.NewLauncherServer(
launcherFlags.port,
fmt.Sprintf("https://%s", authBaseAddr.Host),
- &welcome.AppManagerDirectory{AppManager: appManager},
+ &launcher.AppManagerDirectory{AppManager: appManager},
)
if err != nil {
return fmt.Errorf("failed to create LauncherServer: %v", err)
diff --git a/core/installer/cmd/welcome.go b/core/installer/cmd/welcome.go
index d754ad3..32d5c42 100644
--- a/core/installer/cmd/welcome.go
+++ b/core/installer/cmd/welcome.go
@@ -4,8 +4,8 @@
"os"
"github.com/giolekva/pcloud/core/installer"
+ "github.com/giolekva/pcloud/core/installer/server/welcome"
"github.com/giolekva/pcloud/core/installer/soft"
- "github.com/giolekva/pcloud/core/installer/welcome"
"github.com/spf13/cobra"
"golang.org/x/crypto/ssh"
)
diff --git a/core/installer/welcome/appmanager.go b/core/installer/server/appmanager/server.go
similarity index 88%
rename from core/installer/welcome/appmanager.go
rename to core/installer/server/appmanager/server.go
index a5050ef..5e1e06b 100644
--- a/core/installer/welcome/appmanager.go
+++ b/core/installer/server/appmanager/server.go
@@ -1,4 +1,4 @@
-package welcome
+package appmanager
import (
"context"
@@ -19,12 +19,16 @@
"github.com/giolekva/pcloud/core/installer"
"github.com/giolekva/pcloud/core/installer/cluster"
+ "github.com/giolekva/pcloud/core/installer/server"
"github.com/giolekva/pcloud/core/installer/soft"
"github.com/giolekva/pcloud/core/installer/tasks"
)
-//go:embed appmanager-tmpl/*
-var appTmpls embed.FS
+//go:embed templates/*
+var templates embed.FS
+
+//go:embed static/*
+var staticAssets embed.FS
type taskForward struct {
task tasks.Task
@@ -32,7 +36,7 @@
id int
}
-type AppManagerServer struct {
+type Server struct {
l sync.Locker
port int
repo soft.RepoIO
@@ -55,8 +59,8 @@
task *template.Template
}
-func parseTemplatesAppManager(fs embed.FS) (tmplts, error) {
- base, err := template.New("base.html").Funcs(template.FuncMap(sprig.FuncMap())).ParseFS(fs, "appmanager-tmpl/base.html")
+func parseTemplates(fs embed.FS) (tmplts, error) {
+ base, err := template.New("base.html").Funcs(template.FuncMap(sprig.FuncMap())).ParseFS(fs, "templates/base.html")
if err != nil {
return tmplts{}, err
}
@@ -67,30 +71,30 @@
return b.ParseFS(fs, path)
}
}
- index, err := parse("appmanager-tmpl/index.html")
+ index, err := parse("templates/index.html")
if err != nil {
return tmplts{}, err
}
- app, err := parse("appmanager-tmpl/app.html")
+ app, err := parse("templates/app.html")
if err != nil {
return tmplts{}, err
}
- allClusters, err := parse("appmanager-tmpl/all-clusters.html")
+ allClusters, err := parse("templates/all-clusters.html")
if err != nil {
return tmplts{}, err
}
- cluster, err := parse("appmanager-tmpl/cluster.html")
+ cluster, err := parse("templates/cluster.html")
if err != nil {
return tmplts{}, err
}
- task, err := parse("appmanager-tmpl/task.html")
+ task, err := parse("templates/task.html")
if err != nil {
return tmplts{}, err
}
return tmplts{index, app, allClusters, cluster, task}, nil
}
-func NewAppManagerServer(
+func NewServer(
port int,
repo soft.RepoIO,
m *installer.AppManager,
@@ -100,12 +104,12 @@
h installer.HelmReleaseMonitor,
cnc installer.ClusterNetworkConfigurator,
vpnAPIClient installer.VPNAPIClient,
-) (*AppManagerServer, error) {
- tmpl, err := parseTemplatesAppManager(appTmpls)
+) (*Server, error) {
+ tmpl, err := parseTemplates(templates)
if err != nil {
return nil, err
}
- return &AppManagerServer{
+ return &Server{
l: &sync.Mutex{},
port: port,
repo: repo,
@@ -121,18 +125,9 @@
}, nil
}
-type cachingHandler struct {
- h http.Handler
-}
-
-func (h cachingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Cache-Control", "max-age=604800")
- h.h.ServeHTTP(w, r)
-}
-
-func (s *AppManagerServer) Start() error {
+func (s *Server) Start() error {
r := mux.NewRouter()
- r.PathPrefix("/stat/").Handler(cachingHandler{http.FileServer(http.FS(statAssets))})
+ r.PathPrefix("/static/").Handler(server.NewCachingHandler(http.FileServer(http.FS(staticAssets))))
r.HandleFunc("/api/networks", s.handleNetworks).Methods(http.MethodGet)
r.HandleFunc("/api/clusters", s.handleClusters).Methods(http.MethodGet)
r.HandleFunc("/api/proxy/add", s.handleProxyAdd).Methods(http.MethodPost)
@@ -159,7 +154,7 @@
return http.ListenAndServe(fmt.Sprintf(":%d", s.port), r)
}
-func (s *AppManagerServer) handleNetworks(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleNetworks(w http.ResponseWriter, r *http.Request) {
env, err := s.m.Config()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -176,7 +171,7 @@
}
}
-func (s *AppManagerServer) handleClusters(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleClusters(w http.ResponseWriter, r *http.Request) {
clusters, err := s.m.GetClusters()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -193,7 +188,7 @@
To string `json:"to"`
}
-func (s *AppManagerServer) handleProxyAdd(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleProxyAdd(w http.ResponseWriter, r *http.Request) {
var req proxyPair
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
@@ -205,7 +200,7 @@
}
}
-func (s *AppManagerServer) handleProxyRemove(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleProxyRemove(w http.ResponseWriter, r *http.Request) {
var req proxyPair
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
@@ -225,7 +220,7 @@
Instances []installer.AppInstanceConfig `json:"instances,omitempty"`
}
-func (s *AppManagerServer) handleAppRepo(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleAppRepo(w http.ResponseWriter, r *http.Request) {
all, err := s.r.GetAll()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -242,7 +237,7 @@
}
}
-func (s *AppManagerServer) handleApp(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleApp(w http.ResponseWriter, r *http.Request) {
slug, ok := mux.Vars(r)["slug"]
if !ok {
http.Error(w, "empty slug", http.StatusBadRequest)
@@ -266,7 +261,7 @@
}
}
-func (s *AppManagerServer) handleInstance(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleInstance(w http.ResponseWriter, r *http.Request) {
slug, ok := mux.Vars(r)["slug"]
if !ok {
http.Error(w, "empty slug", http.StatusBadRequest)
@@ -290,7 +285,7 @@
}
}
-func (s *AppManagerServer) handleAppInstall(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleAppInstall(w http.ResponseWriter, r *http.Request) {
s.l.Lock()
defer s.l.Unlock()
slug, ok := mux.Vars(r)["slug"]
@@ -342,7 +337,7 @@
}
}
-func (s *AppManagerServer) handleAppUpdate(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleAppUpdate(w http.ResponseWriter, r *http.Request) {
s.l.Lock()
defer s.l.Unlock()
slug, ok := mux.Vars(r)["slug"]
@@ -380,7 +375,7 @@
}
}
-func (s *AppManagerServer) handleAppRemove(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleAppRemove(w http.ResponseWriter, r *http.Request) {
slug, ok := mux.Vars(r)["slug"]
if !ok {
http.Error(w, "empty slug", http.StatusBadRequest)
@@ -405,7 +400,7 @@
SearchValue string
}
-func (s *AppManagerServer) handleAppsList(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleAppsList(w http.ResponseWriter, r *http.Request) {
pageType := mux.Vars(r)["pageType"]
if pageType == "" {
pageType = "all"
@@ -456,7 +451,7 @@
CurrentPage string
}
-func (s *AppManagerServer) handleAppUI(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleAppUI(w http.ResponseWriter, r *http.Request) {
global, err := s.m.Config()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -500,7 +495,7 @@
}
}
-func (s *AppManagerServer) handleInstanceUI(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleInstanceUI(w http.ResponseWriter, r *http.Request) {
s.l.Lock()
defer s.l.Unlock()
global, err := s.m.Config()
@@ -561,7 +556,7 @@
Task tasks.Task
}
-func (s *AppManagerServer) handleTaskStatus(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleTaskStatus(w http.ResponseWriter, r *http.Request) {
s.l.Lock()
defer s.l.Unlock()
slug, ok := mux.Vars(r)["slug"]
@@ -594,7 +589,7 @@
Clusters []cluster.State
}
-func (s *AppManagerServer) handleAllClusters(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleAllClusters(w http.ResponseWriter, r *http.Request) {
clusters, err := s.m.GetClusters()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -615,7 +610,7 @@
Cluster cluster.State
}
-func (s *AppManagerServer) handleCluster(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleCluster(w http.ResponseWriter, r *http.Request) {
name, ok := mux.Vars(r)["name"]
if !ok {
http.Error(w, "empty name", http.StatusBadRequest)
@@ -640,7 +635,7 @@
}
}
-func (s *AppManagerServer) handleClusterSetupStorage(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleClusterSetupStorage(w http.ResponseWriter, r *http.Request) {
cName, ok := mux.Vars(r)["name"]
if !ok {
http.Error(w, "empty name", http.StatusBadRequest)
@@ -670,7 +665,7 @@
http.Redirect(w, r, fmt.Sprintf("/tasks/%s", cName), http.StatusSeeOther)
}
-func (s *AppManagerServer) handleClusterRemoveServer(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleClusterRemoveServer(w http.ResponseWriter, r *http.Request) {
s.l.Lock()
defer s.l.Unlock()
cName, ok := mux.Vars(r)["cluster"]
@@ -707,7 +702,7 @@
http.Redirect(w, r, fmt.Sprintf("/tasks/%s", cName), http.StatusSeeOther)
}
-func (s *AppManagerServer) getClusterManager(cName string) (cluster.Manager, error) {
+func (s *Server) getClusterManager(cName string) (cluster.Manager, error) {
clusters, err := s.m.GetClusters()
if err != nil {
return nil, err
@@ -725,7 +720,7 @@
return cluster.RestoreKubeManager(*c)
}
-func (s *AppManagerServer) handleClusterAddServer(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleClusterAddServer(w http.ResponseWriter, r *http.Request) {
s.l.Lock()
defer s.l.Unlock()
cName, ok := mux.Vars(r)["cluster"]
@@ -790,7 +785,7 @@
http.Redirect(w, r, fmt.Sprintf("/tasks/%s", cName), http.StatusSeeOther)
}
-func (s *AppManagerServer) handleCreateCluster(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleCreateCluster(w http.ResponseWriter, r *http.Request) {
cName := r.PostFormValue("name")
if cName == "" {
http.Error(w, "no name", http.StatusBadRequest)
@@ -809,7 +804,7 @@
http.Redirect(w, r, fmt.Sprintf("/clusters/%s", cName), http.StatusSeeOther)
}
-func (s *AppManagerServer) handleRemoveCluster(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleRemoveCluster(w http.ResponseWriter, r *http.Request) {
cName, ok := mux.Vars(r)["name"]
if !ok {
http.Error(w, "empty name", http.StatusBadRequest)
@@ -839,7 +834,7 @@
http.Redirect(w, r, fmt.Sprintf("/tasks/%s", cName), http.StatusSeeOther)
}
-func (s *AppManagerServer) setupRemoteCluster() cluster.ClusterIngressSetupFunc {
+func (s *Server) setupRemoteCluster() cluster.ClusterIngressSetupFunc {
const vpnUser = "private-network-proxy"
return func(name, kubeconfig, ingressClassName string) (net.IP, error) {
hostname := fmt.Sprintf("cluster-%s", name)
@@ -893,7 +888,7 @@
}
}
-func (s *AppManagerServer) setupRemoteClusterStorage() cluster.ClusterSetupFunc {
+func (s *Server) setupRemoteClusterStorage() cluster.ClusterSetupFunc {
return func(cm cluster.Manager) error {
name := cm.State().Name
t := tasks.NewInstallTask(s.h, func() (installer.ReleaseResources, error) {
@@ -932,7 +927,7 @@
}
}
-func (s *AppManagerServer) cleanTask(name string, id int) func(error) {
+func (s *Server) cleanTask(name string, id int) func(error) {
return func(err error) {
if err != nil {
fmt.Printf("Task %s failed: %s", name, err.Error())
diff --git a/core/installer/welcome/stat/appmanager.css b/core/installer/server/appmanager/static/main.css
similarity index 100%
rename from core/installer/welcome/stat/appmanager.css
rename to core/installer/server/appmanager/static/main.css
diff --git a/core/installer/welcome/stat/app-manager.js b/core/installer/server/appmanager/static/main.js
similarity index 100%
rename from core/installer/welcome/stat/app-manager.js
rename to core/installer/server/appmanager/static/main.js
diff --git a/core/installer/welcome/static/pico.2.0.6.min.css b/core/installer/server/appmanager/static/pico.2.0.6.min.css
similarity index 100%
copy from core/installer/welcome/static/pico.2.0.6.min.css
copy to core/installer/server/appmanager/static/pico.2.0.6.min.css
diff --git a/core/installer/welcome/appmanager-tmpl/all-clusters.html b/core/installer/server/appmanager/templates/all-clusters.html
similarity index 100%
rename from core/installer/welcome/appmanager-tmpl/all-clusters.html
rename to core/installer/server/appmanager/templates/all-clusters.html
diff --git a/core/installer/welcome/appmanager-tmpl/app.html b/core/installer/server/appmanager/templates/app.html
similarity index 100%
rename from core/installer/welcome/appmanager-tmpl/app.html
rename to core/installer/server/appmanager/templates/app.html
diff --git a/core/installer/welcome/appmanager-tmpl/base.html b/core/installer/server/appmanager/templates/base.html
similarity index 88%
rename from core/installer/welcome/appmanager-tmpl/base.html
rename to core/installer/server/appmanager/templates/base.html
index cb69970..77f43f0 100644
--- a/core/installer/welcome/appmanager-tmpl/base.html
+++ b/core/installer/server/appmanager/templates/base.html
@@ -2,8 +2,8 @@
<html lang="en" data-theme="light">
<head>
<meta charset="utf-8" />
- <link rel="stylesheet" href="/stat/pico.2.0.6.min.css">
- <link rel="stylesheet" type="text/css" href="/stat/appmanager.css?v=0.0.16">
+ <link rel="stylesheet" href="/static/pico.2.0.6.min.css">
+ <link rel="stylesheet" type="text/css" href="/static/main.css?v=0.0.16">
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
@@ -28,7 +28,7 @@
{{ block "content" . }}{{ end }}
</div>
</main>
- <script src="/stat/app-manager.js?v=0.0.11"></script>
+ <script src="/static/main.js?v=0.0.11"></script>
</body>
</html>
diff --git a/core/installer/welcome/appmanager-tmpl/cluster.html b/core/installer/server/appmanager/templates/cluster.html
similarity index 100%
rename from core/installer/welcome/appmanager-tmpl/cluster.html
rename to core/installer/server/appmanager/templates/cluster.html
diff --git a/core/installer/welcome/appmanager-tmpl/index.html b/core/installer/server/appmanager/templates/index.html
similarity index 100%
rename from core/installer/welcome/appmanager-tmpl/index.html
rename to core/installer/server/appmanager/templates/index.html
diff --git a/core/installer/welcome/appmanager-tmpl/task.html b/core/installer/server/appmanager/templates/task.html
similarity index 100%
rename from core/installer/welcome/appmanager-tmpl/task.html
rename to core/installer/server/appmanager/templates/task.html
diff --git a/core/installer/server/caching_handler.go b/core/installer/server/caching_handler.go
new file mode 100644
index 0000000..3d31c25
--- /dev/null
+++ b/core/installer/server/caching_handler.go
@@ -0,0 +1,18 @@
+package server
+
+import (
+ "net/http"
+)
+
+type cachingHandler struct {
+ h http.Handler
+}
+
+func NewCachingHandler(h http.Handler) http.Handler {
+ return cachingHandler{h}
+}
+
+func (h cachingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Cache-Control", "max-age=604800")
+ h.h.ServeHTTP(w, r)
+}
diff --git a/core/installer/welcome/app-tmpl/golang-1.20.0/app.json.gotmpl b/core/installer/server/dodo-app/app-templates/golang-1.20.0/app.json.gotmpl
similarity index 100%
rename from core/installer/welcome/app-tmpl/golang-1.20.0/app.json.gotmpl
rename to core/installer/server/dodo-app/app-templates/golang-1.20.0/app.json.gotmpl
diff --git a/core/installer/welcome/app-tmpl/golang-1.20.0/go.mod.gotmpl b/core/installer/server/dodo-app/app-templates/golang-1.20.0/go.mod.gotmpl
similarity index 100%
rename from core/installer/welcome/app-tmpl/golang-1.20.0/go.mod.gotmpl
rename to core/installer/server/dodo-app/app-templates/golang-1.20.0/go.mod.gotmpl
diff --git a/core/installer/welcome/app-tmpl/golang-1.20.0/main.go b/core/installer/server/dodo-app/app-templates/golang-1.20.0/main.go
similarity index 100%
rename from core/installer/welcome/app-tmpl/golang-1.20.0/main.go
rename to core/installer/server/dodo-app/app-templates/golang-1.20.0/main.go
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/.gitignore b/core/installer/server/dodo-app/app-templates/hugo-latest/.gitignore
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/.gitignore
rename to core/installer/server/dodo-app/app-templates/hugo-latest/.gitignore
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/app.json.gotmpl b/core/installer/server/dodo-app/app-templates/hugo-latest/app.json.gotmpl
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/app.json.gotmpl
rename to core/installer/server/dodo-app/app-templates/hugo-latest/app.json.gotmpl
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/archetypes/default.md b/core/installer/server/dodo-app/app-templates/hugo-latest/archetypes/default.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/archetypes/default.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/archetypes/default.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/content/posts/hello-dodo.md b/core/installer/server/dodo-app/app-templates/hugo-latest/content/posts/hello-dodo.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/content/posts/hello-dodo.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/content/posts/hello-dodo.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/hugo.toml.gotmpl b/core/installer/server/dodo-app/app-templates/hugo-latest/hugo.toml.gotmpl
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/hugo.toml.gotmpl
rename to core/installer/server/dodo-app/app-templates/hugo-latest/hugo.toml.gotmpl
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/.gitignore b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/.gitignore
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/.gitignore
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/.gitignore
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/CHANGELOG.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/CHANGELOG.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/CHANGELOG.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/CHANGELOG.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/LICENSE.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/LICENSE.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/LICENSE.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/LICENSE.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/README.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/README.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/README.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/README.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/archetypes/default.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/archetypes/default.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/archetypes/default.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/archetypes/default.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/css/_code.css b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/css/_code.css
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/css/_code.css
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/css/_code.css
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/css/_hugo-internal-templates.css b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/css/_hugo-internal-templates.css
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/css/_hugo-internal-templates.css
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/css/_hugo-internal-templates.css
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/css/_social-icons.css b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/css/_social-icons.css
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/css/_social-icons.css
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/css/_social-icons.css
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/css/_styles.css b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/css/_styles.css
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/css/_styles.css
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/css/_styles.css
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/css/_tachyons.css b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/css/_tachyons.css
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/css/_tachyons.css
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/css/_tachyons.css
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/dist/main.css_5c99d70a7725bacd4c701e995b969fea.css b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/dist/main.css_5c99d70a7725bacd4c701e995b969fea.css
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/dist/main.css_5c99d70a7725bacd4c701e995b969fea.css
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/dist/main.css_5c99d70a7725bacd4c701e995b969fea.css
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/facebook.svg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/facebook.svg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/facebook.svg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/facebook.svg
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/github.svg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/github.svg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/github.svg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/github.svg
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/gitlab.svg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/gitlab.svg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/gitlab.svg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/gitlab.svg
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/instagram.svg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/instagram.svg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/instagram.svg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/instagram.svg
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/keybase.svg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/keybase.svg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/keybase.svg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/keybase.svg
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/linkedin.svg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/linkedin.svg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/linkedin.svg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/linkedin.svg
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/mastodon.svg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/mastodon.svg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/mastodon.svg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/mastodon.svg
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/medium.svg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/medium.svg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/medium.svg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/medium.svg
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/rss.svg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/rss.svg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/rss.svg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/rss.svg
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/slack.svg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/slack.svg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/slack.svg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/slack.svg
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/stackoverflow.svg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/stackoverflow.svg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/stackoverflow.svg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/stackoverflow.svg
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/tiktok.svg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/tiktok.svg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/tiktok.svg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/tiktok.svg
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/twitter.svg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/twitter.svg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/twitter.svg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/twitter.svg
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/youtube.svg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/youtube.svg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/assets/ananke/socials/youtube.svg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/assets/ananke/socials/youtube.svg
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/config.yaml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/config.yaml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/config.yaml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/config.yaml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/config.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/config.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/config.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/config.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/_index.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/_index.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/_index.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/_index.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/about/index.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/about/index.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/about/index.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/about/index.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/contact.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/contact.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/contact.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/contact.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/post/_index.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/post/_index.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/post/_index.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/post/_index.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-1.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-1.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-1.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-1.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-2.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-2.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-2.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-2.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-3.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-3.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-3.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-3.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-4.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-4.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-4.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-4.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-5.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-5.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-5.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-5.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-6.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-6.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-6.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/en/post/chapter-6.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/fr/_index.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/fr/_index.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/fr/_index.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/fr/_index.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/fr/contact.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/fr/contact.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/fr/contact.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/fr/contact.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/fr/post/_index.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/fr/post/_index.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/fr/post/_index.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/fr/post/_index.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/fr/post/chapter-1.md b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/fr/post/chapter-1.md
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/content/fr/post/chapter-1.md
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/content/fr/post/chapter-1.md
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/go.mod b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/go.mod
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/go.mod
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/go.mod
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/go.sum b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/go.sum
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/go.sum
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/go.sum
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/static/images/Pope-Edouard-de-Beaumont-1844.jpg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/static/images/Pope-Edouard-de-Beaumont-1844.jpg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/static/images/Pope-Edouard-de-Beaumont-1844.jpg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/static/images/Pope-Edouard-de-Beaumont-1844.jpg
Binary files differ
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/static/images/Victor_Hugo-Hunchback.jpg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/static/images/Victor_Hugo-Hunchback.jpg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/static/images/Victor_Hugo-Hunchback.jpg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/static/images/Victor_Hugo-Hunchback.jpg
Binary files differ
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/static/images/esmeralda.jpg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/static/images/esmeralda.jpg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/static/images/esmeralda.jpg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/static/images/esmeralda.jpg
Binary files differ
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/static/images/notebook.jpg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/static/images/notebook.jpg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/exampleSite/static/images/notebook.jpg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/exampleSite/static/images/notebook.jpg
Binary files differ
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/go.mod.gotmpl b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/go.mod.gotmpl
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/go.mod.gotmpl
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/go.mod.gotmpl
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/bg.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/bg.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/bg.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/bg.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/ca.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/ca.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/ca.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/ca.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/cs.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/cs.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/cs.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/cs.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/de.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/de.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/de.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/de.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/en.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/en.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/en.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/en.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/es.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/es.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/es.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/es.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/fi.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/fi.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/fi.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/fi.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/fr.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/fr.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/fr.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/fr.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/he.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/he.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/he.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/he.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/hi.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/hi.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/hi.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/hi.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/hu.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/hu.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/hu.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/hu.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/it.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/it.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/it.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/it.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/ja.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/ja.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/ja.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/ja.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/nl.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/nl.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/nl.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/nl.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/no.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/no.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/no.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/no.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/pl.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/pl.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/pl.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/pl.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/pt.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/pt.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/pt.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/pt.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/ru.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/ru.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/ru.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/ru.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/sv.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/sv.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/sv.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/sv.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/tr.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/tr.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/tr.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/tr.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/uk.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/uk.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/uk.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/uk.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/zh-tw.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/zh-tw.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/zh-tw.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/zh-tw.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/zh.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/zh.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/i18n/zh.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/i18n/zh.toml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/images/screenshot.png b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/images/screenshot.png
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/images/screenshot.png
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/images/screenshot.png
Binary files differ
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/images/tn.png b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/images/tn.png
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/images/tn.png
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/images/tn.png
Binary files differ
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/404.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/404.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/404.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/404.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/_default/baseof.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/_default/baseof.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/_default/baseof.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/_default/baseof.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/_default/by.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/_default/by.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/_default/by.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/_default/by.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/_default/list.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/_default/list.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/_default/list.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/_default/list.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/_default/single.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/_default/single.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/_default/single.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/_default/single.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/_default/summary-with-image.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/_default/summary-with-image.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/_default/summary-with-image.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/_default/summary-with-image.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/_default/summary.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/_default/summary.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/_default/summary.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/_default/summary.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/_default/taxonomy.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/_default/taxonomy.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/_default/taxonomy.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/_default/taxonomy.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/_default/terms.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/_default/terms.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/_default/terms.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/_default/terms.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/index.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/index.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/index.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/index.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/page/single.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/page/single.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/page/single.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/page/single.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/commento.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/commento.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/commento.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/commento.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/GetFeaturedImage.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/GetFeaturedImage.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/GetFeaturedImage.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/GetFeaturedImage.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/GetLanguageDirection.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/GetLanguageDirection.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/GetLanguageDirection.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/GetLanguageDirection.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/socials/Get.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/socials/Get.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/socials/Get.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/socials/Get.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/socials/GetBuiltInServicesDefaults.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/socials/GetBuiltInServicesDefaults.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/socials/GetBuiltInServicesDefaults.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/socials/GetBuiltInServicesDefaults.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/socials/GetRegisteredServices.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/socials/GetRegisteredServices.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/socials/GetRegisteredServices.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/socials/GetRegisteredServices.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/socials/GetServiceData.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/socials/GetServiceData.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/socials/GetServiceData.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/socials/GetServiceData.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/socials/GetServiceIcon.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/socials/GetServiceIcon.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/socials/GetServiceIcon.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/socials/GetServiceIcon.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/style/GetMainCSS.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/style/GetMainCSS.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/style/GetMainCSS.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/style/GetMainCSS.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/style/GetResource.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/style/GetResource.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/style/GetResource.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/style/GetResource.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/warn.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/warn.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/func/warn.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/func/warn.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/head-additions.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/head-additions.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/head-additions.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/head-additions.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/i18nlist.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/i18nlist.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/i18nlist.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/i18nlist.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/menu-contextual.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/menu-contextual.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/menu-contextual.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/menu-contextual.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/new-window-icon.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/new-window-icon.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/new-window-icon.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/new-window-icon.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/page-header.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/page-header.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/page-header.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/page-header.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/site-favicon.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/site-favicon.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/site-favicon.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/site-favicon.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/site-footer.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/site-footer.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/site-footer.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/site-footer.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/site-header.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/site-header.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/site-header.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/site-header.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/site-navigation.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/site-navigation.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/site-navigation.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/site-navigation.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/site-scripts.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/site-scripts.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/site-scripts.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/site-scripts.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/site-style.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/site-style.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/site-style.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/site-style.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/social-follow.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/social-follow.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/social-follow.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/social-follow.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/social-share.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/social-share.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/social-share.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/social-share.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/summary-with-image.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/summary-with-image.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/summary-with-image.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/summary-with-image.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/summary.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/summary.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/summary.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/summary.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/svg/new-window.svg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/svg/new-window.svg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/svg/new-window.svg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/svg/new-window.svg
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/svg/tiktok.svg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/svg/tiktok.svg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/svg/tiktok.svg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/svg/tiktok.svg
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/tags.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/tags.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/partials/tags.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/partials/tags.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/post/list.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/post/list.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/post/list.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/post/list.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/post/summary.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/post/summary.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/post/summary.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/post/summary.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/robots.txt b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/robots.txt
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/robots.txt
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/robots.txt
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/shortcodes/form-contact.html b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/shortcodes/form-contact.html
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/layouts/shortcodes/form-contact.html
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/layouts/shortcodes/form-contact.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/package.hugo.json b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/package.hugo.json
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/package.hugo.json
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/package.hugo.json
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/package.json b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/package.json
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/package.json
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/package.json
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/stackbit.yaml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/stackbit.yaml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/stackbit.yaml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/stackbit.yaml
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/static/images/gohugo-default-sample-hero-image.jpg b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/static/images/gohugo-default-sample-hero-image.jpg
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/static/images/gohugo-default-sample-hero-image.jpg
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/static/images/gohugo-default-sample-hero-image.jpg
Binary files differ
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/theme.toml b/core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/theme.toml
similarity index 100%
rename from core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/theme.toml
rename to core/installer/server/dodo-app/app-templates/hugo-latest/themes/ananke/theme.toml
diff --git a/core/installer/welcome/app-tmpl/php-8.2-apache/app.cue.gotmpl b/core/installer/server/dodo-app/app-templates/php-8.2-apache/app.cue.gotmpl
similarity index 100%
rename from core/installer/welcome/app-tmpl/php-8.2-apache/app.cue.gotmpl
rename to core/installer/server/dodo-app/app-templates/php-8.2-apache/app.cue.gotmpl
diff --git a/core/installer/welcome/app-tmpl/php-8.2-apache/index.php b/core/installer/server/dodo-app/app-templates/php-8.2-apache/index.php
similarity index 100%
rename from core/installer/welcome/app-tmpl/php-8.2-apache/index.php
rename to core/installer/server/dodo-app/app-templates/php-8.2-apache/index.php
diff --git a/core/installer/welcome/app_tmpl.go b/core/installer/server/dodo-app/app_tmpl.go
similarity index 99%
rename from core/installer/welcome/app_tmpl.go
rename to core/installer/server/dodo-app/app_tmpl.go
index 911b9b8..ca2364a 100644
--- a/core/installer/welcome/app_tmpl.go
+++ b/core/installer/server/dodo-app/app_tmpl.go
@@ -1,4 +1,4 @@
-package welcome
+package dodoapp
import (
"bytes"
diff --git a/core/installer/welcome/app_tmpl_test.go b/core/installer/server/dodo-app/app_tmpl_test.go
similarity index 90%
rename from core/installer/welcome/app_tmpl_test.go
rename to core/installer/server/dodo-app/app_tmpl_test.go
index f3ff71e..1f253f3 100644
--- a/core/installer/welcome/app_tmpl_test.go
+++ b/core/installer/server/dodo-app/app_tmpl_test.go
@@ -1,4 +1,4 @@
-package welcome
+package dodoapp
import (
"embed"
@@ -9,7 +9,7 @@
"github.com/giolekva/pcloud/core/installer"
)
-//go:embed app-tmpl
+//go:embed app-templates
var appTmpl embed.FS
var network = installer.Network{
@@ -23,7 +23,7 @@
}
func TestAppTmplGolang1200(t *testing.T) {
- d, err := fs.Sub(appTmpl, "app-tmpl")
+ d, err := fs.Sub(appTmpl, "app-templates")
if err != nil {
t.Fatal(err)
}
@@ -41,7 +41,7 @@
}
func TestAppTmplHugoLatest(t *testing.T) {
- d, err := fs.Sub(appTmpl, "app-tmpl")
+ d, err := fs.Sub(appTmpl, "app-templates")
if err != nil {
t.Fatal(err)
}
@@ -59,7 +59,7 @@
}
func TestAppTmplPHP82(t *testing.T) {
- d, err := fs.Sub(appTmpl, "app-tmpl")
+ d, err := fs.Sub(appTmpl, "app-templates")
if err != nil {
t.Fatal(err)
}
diff --git a/core/installer/welcome/dodo_app.go b/core/installer/server/dodo-app/server.go
similarity index 91%
rename from core/installer/welcome/dodo_app.go
rename to core/installer/server/dodo-app/server.go
index 00cf794..b932c33 100644
--- a/core/installer/welcome/dodo_app.go
+++ b/core/installer/server/dodo-app/server.go
@@ -1,4 +1,4 @@
-package welcome
+package dodoapp
import (
"bytes"
@@ -21,6 +21,7 @@
"golang.org/x/exp/rand"
"github.com/giolekva/pcloud/core/installer"
+ "github.com/giolekva/pcloud/core/installer/server"
"github.com/giolekva/pcloud/core/installer/soft"
"github.com/giolekva/pcloud/core/installer/tasks"
@@ -29,13 +30,16 @@
"github.com/gorilla/securecookie"
)
-//go:embed dodo-app-tmpl/*
-var dodoAppTmplFS embed.FS
+//go:embed templates/*
+var templates embed.FS
-//go:embed all:app-tmpl
+//go:embed all:app-templates
var appTmplsFS embed.FS
-//go:embed stat/schemas/app.schema.json
+//go:embed static/*
+var staticAssets embed.FS
+
+//go:embed static/schemas/app.schema.json
var dodoAppJsonSchema []byte
const (
@@ -43,7 +47,7 @@
appConfigsFile = "/apps.json"
loginPath = "/login"
logoutPath = "/logout"
- staticPath = "/stat/"
+ staticPath = "/static/"
schemasPath = "/schemas/"
apiPublicData = "/api/public-data"
apiCreateApp = "/api/apps"
@@ -52,17 +56,17 @@
initCommitMsg = "init"
)
-type dodoAppTmplts struct {
+type tmplts struct {
index *template.Template
appStatus *template.Template
commitStatus *template.Template
logs *template.Template
}
-func parseTemplatesDodoApp(fs embed.FS) (dodoAppTmplts, error) {
- base, err := template.ParseFS(fs, "dodo-app-tmpl/base.html")
+func parseTemplates(fs embed.FS) (tmplts, error) {
+ base, err := template.ParseFS(fs, "templates/base.html")
if err != nil {
- return dodoAppTmplts{}, err
+ return tmplts{}, err
}
parse := func(path string) (*template.Template, error) {
if b, err := base.Clone(); err != nil {
@@ -71,26 +75,26 @@
return b.ParseFS(fs, path)
}
}
- index, err := parse("dodo-app-tmpl/index.html")
+ index, err := parse("templates/index.html")
if err != nil {
- return dodoAppTmplts{}, err
+ return tmplts{}, err
}
- appStatus, err := parse("dodo-app-tmpl/app_status.html")
+ appStatus, err := parse("templates/app_status.html")
if err != nil {
- return dodoAppTmplts{}, err
+ return tmplts{}, err
}
- commitStatus, err := parse("dodo-app-tmpl/commit_status.html")
+ commitStatus, err := parse("templates/commit_status.html")
if err != nil {
- return dodoAppTmplts{}, err
+ return tmplts{}, err
}
- logs, err := parse("dodo-app-tmpl/logs.html")
+ logs, err := parse("templates/logs.html")
if err != nil {
- return dodoAppTmplts{}, err
+ return tmplts{}, err
}
- return dodoAppTmplts{index, appStatus, commitStatus, logs}, nil
+ return tmplts{index, appStatus, commitStatus, logs}, nil
}
-type DodoAppServer struct {
+type Server struct {
l sync.Locker
st Store
nf NetworkFilter
@@ -112,7 +116,7 @@
cnc installer.ClusterNetworkConfigurator
workers map[string]map[string]struct{}
appConfigs map[string]appConfig
- tmplts dodoAppTmplts
+ tmplts tmplts
appTmpls AppTmplStore
external bool
fetchUsersAddr string
@@ -126,7 +130,7 @@
}
// TODO(gio): Initialize appNs on startup
-func NewDodoAppServer(
+func NewServer(
st Store,
nf NetworkFilter,
ug UserGetter,
@@ -148,8 +152,8 @@
external bool,
fetchUsersAddr string,
reconciler tasks.Reconciler,
-) (*DodoAppServer, error) {
- tmplts, err := parseTemplatesDodoApp(dodoAppTmplFS)
+) (*Server, error) {
+ tmplts, err := parseTemplates(templates)
if err != nil {
return nil, err
}
@@ -161,7 +165,7 @@
if err != nil {
return nil, err
}
- s := &DodoAppServer{
+ s := &Server{
&sync.Mutex{},
st,
nf,
@@ -206,15 +210,15 @@
return s, nil
}
-func (s *DodoAppServer) getAppConfig(app, branch string) appConfig {
+func (s *Server) getAppConfig(app, branch string) appConfig {
return s.appConfigs[fmt.Sprintf("%s-%s", app, branch)]
}
-func (s *DodoAppServer) setAppConfig(app, branch string, cfg appConfig) {
+func (s *Server) setAppConfig(app, branch string, cfg appConfig) {
s.appConfigs[fmt.Sprintf("%s-%s", app, branch)] = cfg
}
-func (s *DodoAppServer) Start() error {
+func (s *Server) Start() error {
// if err := s.client.DisableKeyless(); err != nil {
// return err
// }
@@ -226,7 +230,7 @@
r := mux.NewRouter()
r.Use(s.mwAuth)
r.HandleFunc(schemasPath+"app.schema.json", s.handleSchema).Methods(http.MethodGet)
- r.PathPrefix(staticPath).Handler(cachingHandler{http.FileServer(http.FS(statAssets))})
+ r.PathPrefix(staticPath).Handler(server.NewCachingHandler(http.FileServer(http.FS(staticAssets))))
r.HandleFunc(logoutPath, s.handleLogout).Methods(http.MethodGet)
r.HandleFunc(apiPublicData, s.handleAPIPublicData)
r.HandleFunc(apiCreateApp, s.handleAPICreateApp).Methods(http.MethodPost)
@@ -325,7 +329,7 @@
return nil
}
-func (s *DodoAppServer) mwAuth(next http.Handler) http.Handler {
+func (s *Server) mwAuth(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if strings.HasSuffix(r.URL.Path, loginPath) ||
strings.HasPrefix(r.URL.Path, logoutPath) ||
@@ -351,12 +355,12 @@
})
}
-func (s *DodoAppServer) handleSchema(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleSchema(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/schema+json")
w.Write(dodoAppJsonSchema)
}
-func (s *DodoAppServer) handleLogout(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleLogout(w http.ResponseWriter, r *http.Request) {
// TODO(gio): move to UserGetter
http.SetCookie(w, &http.Cookie{
Name: sessionCookie,
@@ -368,7 +372,7 @@
http.Redirect(w, r, "/", http.StatusSeeOther)
}
-func (s *DodoAppServer) handleLoginForm(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleLoginForm(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
appName, ok := vars["app-name"]
if !ok || appName == "" {
@@ -392,7 +396,7 @@
`)
}
-func (s *DodoAppServer) handleLogin(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleLogin(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
appName, ok := vars["app-name"]
if !ok || appName == "" {
@@ -437,7 +441,7 @@
Types []string
}
-func (s *DodoAppServer) handleStatus(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleStatus(w http.ResponseWriter, r *http.Request) {
user := r.Context().Value(userCtx)
if user == nil {
http.Error(w, "unauthorized", http.StatusUnauthorized)
@@ -475,7 +479,7 @@
Branches []string
}
-func (s *DodoAppServer) handleAppStatus(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleAppStatus(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
appName, ok := vars["app-name"]
if !ok || appName == "" {
@@ -554,7 +558,7 @@
Profile string `json:"envProfile"`
}
-func (s *DodoAppServer) handleBranchEnvProfile(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleBranchEnvProfile(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
appName, ok := vars["app-name"]
if !ok || appName == "" {
@@ -614,7 +618,7 @@
Resources resourceData
}
-func (s *DodoAppServer) handleAppCommit(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleAppCommit(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
appName, ok := vars["app-name"]
if !ok || appName == "" {
@@ -683,7 +687,7 @@
Logs template.HTML
}
-func (s *DodoAppServer) handleAppLogs(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleAppLogs(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
appName, ok := vars["app-name"]
if !ok || appName == "" {
@@ -737,7 +741,7 @@
} `json:"commits"`
}
-func (s *DodoAppServer) handleAPIUpdate(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleAPIUpdate(w http.ResponseWriter, r *http.Request) {
fmt.Println("update")
var req apiUpdateReq
var contents strings.Builder
@@ -810,7 +814,7 @@
Logs string `json:"logs"`
}
-func (s *DodoAppServer) handleAPIRegisterWorker(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleAPIRegisterWorker(w http.ResponseWriter, r *http.Request) {
// TODO(gio): lock
vars := mux.Vars(r)
appName, ok := vars["app-name"]
@@ -830,7 +834,7 @@
s.logs[appName] = req.Logs
}
-func (s *DodoAppServer) handleCreateApp(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleCreateApp(w http.ResponseWriter, r *http.Request) {
u := r.Context().Value(userCtx)
if u == nil {
http.Error(w, "unauthorized", http.StatusUnauthorized)
@@ -888,7 +892,7 @@
http.Redirect(w, r, fmt.Sprintf("/%s", appName), http.StatusSeeOther)
}
-func (s *DodoAppServer) handleCreateDevBranch(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleCreateDevBranch(w http.ResponseWriter, r *http.Request) {
u := r.Context().Value(userCtx)
if u == nil {
http.Error(w, "unauthorized", http.StatusUnauthorized)
@@ -917,7 +921,7 @@
http.Redirect(w, r, fmt.Sprintf("/%s/branch/%s", appName, branch), http.StatusSeeOther)
}
-func (s *DodoAppServer) handleBranchDelete(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleBranchDelete(w http.ResponseWriter, r *http.Request) {
u := r.Context().Value(userCtx)
if u == nil {
http.Error(w, "unauthorized", http.StatusUnauthorized)
@@ -941,7 +945,7 @@
http.Redirect(w, r, fmt.Sprintf("/%s", appName), http.StatusSeeOther)
}
-func (s *DodoAppServer) handleAppDelete(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleAppDelete(w http.ResponseWriter, r *http.Request) {
u := r.Context().Value(userCtx)
if u == nil {
http.Error(w, "unauthorized", http.StatusUnauthorized)
@@ -972,7 +976,7 @@
Password string `json:"password"`
}
-func (s *DodoAppServer) handleAPICreateApp(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleAPICreateApp(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
var req apiCreateAppReq
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
@@ -1027,7 +1031,7 @@
}
}
-func (s *DodoAppServer) isNetworkUseAllowed(network string) bool {
+func (s *Server) isNetworkUseAllowed(network string) bool {
if !s.external {
return true
}
@@ -1039,7 +1043,7 @@
return true
}
-func (s *DodoAppServer) createApp(user, appName, appType, network, subdomain string) error {
+func (s *Server) createApp(user, appName, appType, network, subdomain string) error {
s.l.Lock()
defer s.l.Unlock()
fmt.Printf("Creating app: %s\n", appName)
@@ -1074,7 +1078,7 @@
return s.createAppForBranch(appRepo, appName, "master", user, network, files)
}
-func (s *DodoAppServer) createDevBranch(appName, fromBranch, toBranch, user string) error {
+func (s *Server) createDevBranch(appName, fromBranch, toBranch, user string) error {
s.l.Lock()
defer s.l.Unlock()
fmt.Printf("Creating dev branch app: %s %s %s\n", appName, fromBranch, toBranch)
@@ -1093,7 +1097,7 @@
return s.createAppForBranch(appRepo, appName, toBranch, user, network, map[string][]byte{"app.json": branchCfg})
}
-func (s *DodoAppServer) deleteBranch(appName string, branch string) error {
+func (s *Server) deleteBranch(appName string, branch string) error {
appBranch := fmt.Sprintf("dodo_%s", branch)
hf := installer.NewGitHelmFetcher()
if err := func() error {
@@ -1132,7 +1136,7 @@
return s.st.DeleteBranch(appName, branch)
}
-func (s *DodoAppServer) deleteApp(appName string) error {
+func (s *Server) deleteApp(appName string) error {
configRepo, err := s.client.GetRepo(ConfigRepoName)
if err != nil {
return err
@@ -1155,7 +1159,7 @@
return s.st.DeleteApp(appName)
}
-func (s *DodoAppServer) createAppForBranch(
+func (s *Server) createAppForBranch(
repo soft.RepoIO,
appName string,
branch string,
@@ -1253,7 +1257,7 @@
return s.initAppACLs(m, appPath, appName, branch, user)
}
-func (s *DodoAppServer) initAppACLs(m *installer.AppManager, path, appName, branch, user string) error {
+func (s *Server) initAppACLs(m *installer.AppManager, path, appName, branch, user string) error {
cfg, err := m.GetInstance(path)
if err != nil {
return err
@@ -1314,7 +1318,7 @@
PublicKey string `json:"publicKey"`
}
-func (s *DodoAppServer) handleAPIAddPublicKey(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleAPIAddPublicKey(w http.ResponseWriter, r *http.Request) {
var req apiAddAdminKeyReq
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
@@ -1347,7 +1351,7 @@
}
// TODO(gio): must not require owner, now we need it to bootstrap dev vm.
-func (s *DodoAppServer) updateDodoApp(
+func (s *Server) updateDodoApp(
appStatus installer.EnvApp,
name string,
branch string,
@@ -1437,20 +1441,20 @@
return ret, nil
}
-func (s *DodoAppServer) renderAppConfigTemplate(appType string, network installer.Network, subdomain string) (map[string][]byte, error) {
+func (s *Server) renderAppConfigTemplate(appType string, network installer.Network, subdomain string) (map[string][]byte, error) {
appType = strings.Replace(appType, ":", "-", 1)
appTmpl, err := s.appTmpls.Find(appType)
if err != nil {
return nil, err
}
- return appTmpl.Render(fmt.Sprintf("%s/stat/schemas/dodo_app.jsonschema", s.selfPublic), network, subdomain)
+ return appTmpl.Render(fmt.Sprintf("%s/statit/schemas/dodo_app.jsonschema", s.selfPublic), network, subdomain)
}
func generatePassword() string {
return "foo"
}
-func (s *DodoAppServer) getNetworks(user string) ([]installer.Network, error) {
+func (s *Server) getNetworks(user string) ([]installer.Network, error) {
addr := fmt.Sprintf("%s/api/networks", s.envAppManagerAddr)
resp, err := http.Get(addr)
if err != nil {
@@ -1463,7 +1467,7 @@
return s.nf.Filter(user, networks)
}
-func (s *DodoAppServer) getClusters() ([]installer.Cluster, error) {
+func (s *Server) getClusters() ([]installer.Cluster, error) {
addr := fmt.Sprintf("%s/api/clusters", s.envAppManagerAddr)
resp, err := http.Get(addr)
if err != nil {
@@ -1487,7 +1491,7 @@
Types []string `json:"types"`
}
-func (s *DodoAppServer) handleAPIPublicData(w http.ResponseWriter, r *http.Request) {
+func (s *Server) handleAPIPublicData(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
s.l.Lock()
defer s.l.Unlock()
@@ -1511,7 +1515,7 @@
}
}
-func (s *DodoAppServer) createCommit(name, branch, hash, message string, err error, resources installer.ReleaseResources) error {
+func (s *Server) createCommit(name, branch, hash, message string, err error, resources installer.ReleaseResources) error {
if err != nil {
fmt.Printf("Error: %s\n", err.Error())
if err := s.st.CreateCommit(name, branch, hash, message, "FAILED", err.Error(), nil); err != nil {
@@ -1627,11 +1631,11 @@
SSHPublicKeys []string `json:"sshPublicKeys,omitempty"`
}
-func (s *DodoAppServer) handleAPISyncUsers(_ http.ResponseWriter, _ *http.Request) {
+func (s *Server) handleAPISyncUsers(_ http.ResponseWriter, _ *http.Request) {
go s.syncUsers()
}
-func (s *DodoAppServer) syncUsers() {
+func (s *Server) syncUsers() {
if s.external {
panic("MUST NOT REACH!")
}
diff --git a/core/installer/welcome/dodo_app_test.go b/core/installer/server/dodo-app/server_test.go
similarity index 95%
rename from core/installer/welcome/dodo_app_test.go
rename to core/installer/server/dodo-app/server_test.go
index 8fc83e7..8bc0c59 100644
--- a/core/installer/welcome/dodo_app_test.go
+++ b/core/installer/server/dodo-app/server_test.go
@@ -1,4 +1,4 @@
-package welcome
+package dodoapp
import (
"testing"
diff --git a/core/installer/welcome/stat/dodo_app.css b/core/installer/server/dodo-app/static/main.css
similarity index 100%
rename from core/installer/welcome/stat/dodo_app.css
rename to core/installer/server/dodo-app/static/main.css
diff --git a/core/installer/welcome/stat/dodo-app.js b/core/installer/server/dodo-app/static/main.js
similarity index 100%
rename from core/installer/welcome/stat/dodo-app.js
rename to core/installer/server/dodo-app/static/main.js
diff --git a/core/installer/welcome/static/pico.2.0.6.min.css b/core/installer/server/dodo-app/static/pico.2.0.6.min.css
similarity index 100%
copy from core/installer/welcome/static/pico.2.0.6.min.css
copy to core/installer/server/dodo-app/static/pico.2.0.6.min.css
diff --git a/core/installer/welcome/stat/schemas/app.schema.json b/core/installer/server/dodo-app/static/schemas/app.schema.json
similarity index 100%
rename from core/installer/welcome/stat/schemas/app.schema.json
rename to core/installer/server/dodo-app/static/schemas/app.schema.json
diff --git a/core/installer/welcome/store.go b/core/installer/server/dodo-app/store.go
similarity index 99%
rename from core/installer/welcome/store.go
rename to core/installer/server/dodo-app/store.go
index 328c7fd..0ccde8d 100644
--- a/core/installer/welcome/store.go
+++ b/core/installer/server/dodo-app/store.go
@@ -1,4 +1,4 @@
-package welcome
+package dodoapp
import (
"bytes"
diff --git a/core/installer/welcome/dodo-app-tmpl/app_status.html b/core/installer/server/dodo-app/templates/app_status.html
similarity index 100%
rename from core/installer/welcome/dodo-app-tmpl/app_status.html
rename to core/installer/server/dodo-app/templates/app_status.html
diff --git a/core/installer/welcome/dodo-app-tmpl/base.html b/core/installer/server/dodo-app/templates/base.html
similarity index 87%
rename from core/installer/welcome/dodo-app-tmpl/base.html
rename to core/installer/server/dodo-app/templates/base.html
index 0e20ff5..9129c4d 100644
--- a/core/installer/welcome/dodo-app-tmpl/base.html
+++ b/core/installer/server/dodo-app/templates/base.html
@@ -4,8 +4,8 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ block "title" . }}{{ end }}</title>
- <link rel="stylesheet" href="/stat/pico.2.0.6.min.css">
- <link rel="stylesheet" href="/stat/dodo_app.css?v=0.0.10">
+ <link rel="stylesheet" href="/static/pico.2.0.6.min.css">
+ <link rel="stylesheet" href="/static/main.css?v=0.0.10">
</head>
<body class="container">
<nav aria-label="breadcrumb">
@@ -17,7 +17,7 @@
</nav>
{{- block "content" . }}
{{- end }}
- <script src="/stat/dodo-app.js?v=0.0.9"></script>
+ <script src="/static/main.js?v=0.0.9"></script>
</body>
</html>
{{ define "resources" }}
diff --git a/core/installer/welcome/dodo-app-tmpl/commit_status.html b/core/installer/server/dodo-app/templates/commit_status.html
similarity index 100%
rename from core/installer/welcome/dodo-app-tmpl/commit_status.html
rename to core/installer/server/dodo-app/templates/commit_status.html
diff --git a/core/installer/welcome/dodo-app-tmpl/index.html b/core/installer/server/dodo-app/templates/index.html
similarity index 100%
rename from core/installer/welcome/dodo-app-tmpl/index.html
rename to core/installer/server/dodo-app/templates/index.html
diff --git a/core/installer/welcome/dodo-app-tmpl/logs.html b/core/installer/server/dodo-app/templates/logs.html
similarity index 100%
rename from core/installer/welcome/dodo-app-tmpl/logs.html
rename to core/installer/server/dodo-app/templates/logs.html
diff --git a/core/installer/welcome/dns.go b/core/installer/server/env/dns.go
similarity index 98%
rename from core/installer/welcome/dns.go
rename to core/installer/server/env/dns.go
index 0593937..97efd91 100644
--- a/core/installer/welcome/dns.go
+++ b/core/installer/server/env/dns.go
@@ -1,4 +1,4 @@
-package welcome
+package env
import (
"context"
diff --git a/core/installer/welcome/dns_test.go b/core/installer/server/env/dns_test.go
similarity index 96%
rename from core/installer/welcome/dns_test.go
rename to core/installer/server/env/dns_test.go
index 4eec16b..6d3cd26 100644
--- a/core/installer/welcome/dns_test.go
+++ b/core/installer/server/env/dns_test.go
@@ -1,4 +1,4 @@
-package welcome
+package env
import (
"strings"
diff --git a/core/installer/welcome/env.go b/core/installer/server/env/server.go
similarity index 91%
rename from core/installer/welcome/env.go
rename to core/installer/server/env/server.go
index 31264fe..9bd0a34 100644
--- a/core/installer/welcome/env.go
+++ b/core/installer/server/env/server.go
@@ -1,4 +1,4 @@
-package welcome
+package env
import (
"context"
@@ -20,15 +20,19 @@
"github.com/giolekva/pcloud/core/installer"
"github.com/giolekva/pcloud/core/installer/dns"
phttp "github.com/giolekva/pcloud/core/installer/http"
+ "github.com/giolekva/pcloud/core/installer/server"
"github.com/giolekva/pcloud/core/installer/soft"
"github.com/giolekva/pcloud/core/installer/tasks"
)
-//go:embed env-manager-tmpl/*
+//go:embed templates/*
var tmpls embed.FS
var tmplsParsed templates
+//go:embed static/*
+var staticAssets embed.FS
+
func init() {
if t, err := parseTemplates(tmpls); err != nil {
panic(err)
@@ -43,7 +47,7 @@
}
func parseTemplates(fs embed.FS) (templates, error) {
- base, err := template.ParseFS(fs, "env-manager-tmpl/base.html")
+ base, err := template.ParseFS(fs, "templates/base.html")
if err != nil {
return templates{}, err
}
@@ -54,11 +58,11 @@
return b.ParseFS(fs, path)
}
}
- form, err := parse("env-manager-tmpl/form.html")
+ form, err := parse("templates/form.html")
if err != nil {
return templates{}, err
}
- status, err := parse("env-manager-tmpl/status.html")
+ status, err := parse("templates/status.html")
if err != nil {
return templates{}, err
}
@@ -133,7 +137,7 @@
func (s *EnvServer) Start() error {
r := mux.NewRouter()
- r.PathPrefix("/stat/").Handler(cachingHandler{http.FileServer(http.FS(statAssets))})
+ r.PathPrefix("/static/").Handler(server.NewCachingHandler(http.FileServer(http.FS(staticAssets))))
r.Path("/env/{key}").Methods("GET").HandlerFunc(s.monitorTask)
r.Path("/env/{key}").Methods("POST").HandlerFunc(s.publishDNSRecords)
r.Path("/").Methods("GET").HandlerFunc(s.createEnvForm)
@@ -206,7 +210,7 @@
return
}
r.ParseForm()
- if apiToken, err := getFormValue(r.PostForm, "api-token"); err != nil {
+ if apiToken, err := server.GetFormValue(r.PostForm, "api-token"); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
} else {
@@ -304,19 +308,19 @@
if err = r.ParseForm(); err != nil {
return err
}
- if req.SecretToken, err = getFormValue(r.PostForm, "secret-token"); err != nil {
+ if req.SecretToken, err = server.GetFormValue(r.PostForm, "secret-token"); err != nil {
return err
}
- if req.Domain, err = getFormValue(r.PostForm, "domain"); err != nil {
+ if req.Domain, err = server.GetFormValue(r.PostForm, "domain"); err != nil {
return err
}
- if req.PrivateNetworkSubdomain, err = getFormValue(r.PostForm, "private-network-subdomain"); err != nil {
+ if req.PrivateNetworkSubdomain, err = server.GetFormValue(r.PostForm, "private-network-subdomain"); err != nil {
return err
}
- if req.ContactEmail, err = getFormValue(r.PostForm, "contact-email"); err != nil {
+ if req.ContactEmail, err = server.GetFormValue(r.PostForm, "contact-email"); err != nil {
return err
}
- if req.AdminPublicKey, err = getFormValue(r.PostForm, "admin-public-key"); err != nil {
+ if req.AdminPublicKey, err = server.GetFormValue(r.PostForm, "admin-public-key"); err != nil {
return err
}
return nil
diff --git a/core/installer/welcome/env_test.go b/core/installer/server/env/server_test.go
similarity index 99%
rename from core/installer/welcome/env_test.go
rename to core/installer/server/env/server_test.go
index cec2458..d45a463 100644
--- a/core/installer/welcome/env_test.go
+++ b/core/installer/server/env/server_test.go
@@ -1,4 +1,4 @@
-package welcome
+package env
import (
"bytes"
diff --git a/core/installer/welcome/static/main.css b/core/installer/server/env/static/main.css
similarity index 100%
rename from core/installer/welcome/static/main.css
rename to core/installer/server/env/static/main.css
diff --git a/core/installer/welcome/static/pico.2.0.6.min.css b/core/installer/server/env/static/pico.2.0.6.min.css
similarity index 100%
copy from core/installer/welcome/static/pico.2.0.6.min.css
copy to core/installer/server/env/static/pico.2.0.6.min.css
diff --git a/core/installer/welcome/env-manager-tmpl/base.html b/core/installer/server/env/templates/base.html
similarity index 86%
rename from core/installer/welcome/env-manager-tmpl/base.html
rename to core/installer/server/env/templates/base.html
index 3e4b6b6..689ca79 100644
--- a/core/installer/welcome/env-manager-tmpl/base.html
+++ b/core/installer/server/env/templates/base.html
@@ -1,9 +1,9 @@
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
- <link rel="stylesheet" href="/stat/pico.2.0.6.min.css">
+ <link rel="stylesheet" href="/static/pico.2.0.6.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/hack-font/3.3.0/web/hack.min.css">
- <link rel="stylesheet" href="/stat/main.css">
+ <link rel="stylesheet" href="/static/main.css">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>dodo:</title>
diff --git a/core/installer/welcome/env-manager-tmpl/form.html b/core/installer/server/env/templates/form.html
similarity index 100%
rename from core/installer/welcome/env-manager-tmpl/form.html
rename to core/installer/server/env/templates/form.html
diff --git a/core/installer/welcome/env-manager-tmpl/status.html b/core/installer/server/env/templates/status.html
similarity index 100%
rename from core/installer/welcome/env-manager-tmpl/status.html
rename to core/installer/server/env/templates/status.html
diff --git a/core/installer/server/form.go b/core/installer/server/form.go
new file mode 100644
index 0000000..05bbc44
--- /dev/null
+++ b/core/installer/server/form.go
@@ -0,0 +1,14 @@
+package server
+
+import (
+ "fmt"
+ "net/url"
+)
+
+func GetFormValue(v url.Values, name string) (string, error) {
+ items, ok := v[name]
+ if !ok || len(items) != 1 {
+ return "", fmt.Errorf("%s not found", name)
+ }
+ return items[0], nil
+}
diff --git a/core/installer/welcome/fake_app_directory.go b/core/installer/server/launcher/fake_app_directory.go
similarity index 99%
rename from core/installer/welcome/fake_app_directory.go
rename to core/installer/server/launcher/fake_app_directory.go
index e47bb13..216043b 100644
--- a/core/installer/welcome/fake_app_directory.go
+++ b/core/installer/server/launcher/fake_app_directory.go
@@ -1,4 +1,4 @@
-package welcome
+package launcher
type FakeAppDirectory struct {
}
diff --git a/core/installer/welcome/launcher.go b/core/installer/server/launcher/server.go
similarity index 92%
rename from core/installer/welcome/launcher.go
rename to core/installer/server/launcher/server.go
index bab9163..f75a86c 100644
--- a/core/installer/welcome/launcher.go
+++ b/core/installer/server/launcher/server.go
@@ -1,4 +1,4 @@
-package welcome
+package launcher
import (
"embed"
@@ -10,14 +10,18 @@
"strings"
"github.com/giolekva/pcloud/core/installer"
+ "github.com/giolekva/pcloud/core/installer/server"
"github.com/Masterminds/sprig/v3"
"github.com/gomarkdown/markdown"
)
-//go:embed launcher-tmpl/launcher.html
+//go:embed templates/launcher.html
var indexHTML embed.FS
+//go:embed static/*
+var staticAssets embed.FS
+
type AppLauncherInfo struct {
Id string
Name string
@@ -90,7 +94,7 @@
authBaseAddr string,
appDirectory AppDirectory,
) (*LauncherServer, error) {
- tmpl, err := indexHTML.ReadFile("launcher-tmpl/launcher.html")
+ tmpl, err := indexHTML.ReadFile("templates/launcher.html")
if err != nil {
return nil, fmt.Errorf("failed to parse template: %v", err)
}
@@ -137,7 +141,7 @@
}
func (s *LauncherServer) Start() {
- http.Handle("/stat/", cachingHandler{http.FileServer(http.FS(statAssets))})
+ http.Handle("/static/", server.NewCachingHandler(http.FileServer(http.FS(staticAssets))))
http.HandleFunc("/", s.homeHandler)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", s.port), nil))
}
diff --git a/core/installer/welcome/stat/launcher.css b/core/installer/server/launcher/static/main.css
similarity index 100%
rename from core/installer/welcome/stat/launcher.css
rename to core/installer/server/launcher/static/main.css
diff --git a/core/installer/welcome/static/launcher.js b/core/installer/server/launcher/static/main.js
similarity index 100%
rename from core/installer/welcome/static/launcher.js
rename to core/installer/server/launcher/static/main.js
diff --git a/core/installer/welcome/static/pico.2.0.6.min.css b/core/installer/server/launcher/static/pico.2.0.6.min.css
similarity index 100%
copy from core/installer/welcome/static/pico.2.0.6.min.css
copy to core/installer/server/launcher/static/pico.2.0.6.min.css
diff --git a/core/installer/welcome/launcher-tmpl/launcher.html b/core/installer/server/launcher/templates/launcher.html
similarity index 94%
rename from core/installer/welcome/launcher-tmpl/launcher.html
rename to core/installer/server/launcher/templates/launcher.html
index 76f7dd5..608d3df 100644
--- a/core/installer/welcome/launcher-tmpl/launcher.html
+++ b/core/installer/server/launcher/templates/launcher.html
@@ -4,8 +4,8 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>dodo: Launcher</title>
- <link rel="stylesheet" type="text/css" href="/stat/pico.2.0.6.min.css">
- <link rel="stylesheet" type="text/css" href="/stat/launcher.css?v=0.0.21">
+ <link rel="stylesheet" type="text/css" href="/static/pico.2.0.6.min.css">
+ <link rel="stylesheet" type="text/css" href="/static/main.css?v=0.0.21">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/hack-font/3.3.0/web/hack.min.css">
</head>
<body class="container-fluid">
@@ -83,6 +83,6 @@
{{ template "help-content-template" (dict "Help" $h.Children "First" false) }}
{{ end }}
{{ end }}
- <script src="/stat/launcher.js?v=0.0.19"></script>
+ <script src="/static/main.js?v=0.0.19"></script>
</body>
</html>
diff --git a/core/installer/welcome/welcome.go b/core/installer/server/welcome/server.go
similarity index 84%
rename from core/installer/welcome/welcome.go
rename to core/installer/server/welcome/server.go
index 7aa6d3a..198f637 100644
--- a/core/installer/welcome/welcome.go
+++ b/core/installer/server/welcome/server.go
@@ -9,33 +9,30 @@
"io"
"log"
"net/http"
- "net/url"
"os"
"github.com/gorilla/mux"
"github.com/giolekva/pcloud/core/installer"
+ "github.com/giolekva/pcloud/core/installer/server"
"github.com/giolekva/pcloud/core/installer/soft"
)
-//go:embed welcome-tmpl/*
-var welcomeTmpls embed.FS
+//go:embed templates/*
+var tmpls embed.FS
//go:embed static/*
var staticAssets embed.FS
-//go:embed stat/*
-var statAssets embed.FS
-
-type welcomeTmplts struct {
+type templates struct {
createAccount *template.Template
createAccountSuccess *template.Template
}
-func parseTemplatesWelcome(fs embed.FS) (welcomeTmplts, error) {
- base, err := template.New("base.html").ParseFS(fs, "welcome-tmpl/base.html")
+func parseTemplatesWelcome(fs embed.FS) (templates, error) {
+ base, err := template.New("base.html").ParseFS(fs, "templates/base.html")
if err != nil {
- return welcomeTmplts{}, err
+ return templates{}, err
}
parse := func(path string) (*template.Template, error) {
if b, err := base.Clone(); err != nil {
@@ -44,15 +41,15 @@
return b.ParseFS(fs, path)
}
}
- createAccount, err := parse("welcome-tmpl/create-account.html")
+ createAccount, err := parse("templates/create-account.html")
if err != nil {
- return welcomeTmplts{}, err
+ return templates{}, err
}
- createAccountSuccess, err := parse("welcome-tmpl/create-account-success.html")
+ createAccountSuccess, err := parse("templates/create-account-success.html")
if err != nil {
- return welcomeTmplts{}, err
+ return templates{}, err
}
- return welcomeTmplts{createAccount, createAccountSuccess}, nil
+ return templates{createAccount, createAccountSuccess}, nil
}
type Server struct {
@@ -63,7 +60,7 @@
createAccountAddr string
loginAddr string
membershipsAddr string
- tmpl welcomeTmplts
+ tmpl templates
}
func NewServer(
@@ -75,7 +72,7 @@
loginAddr string,
membershipsAddr string,
) (*Server, error) {
- tmplts, err := parseTemplatesWelcome(welcomeTmpls)
+ tmplts, err := parseTemplatesWelcome(tmpls)
if err != nil {
return nil, err
}
@@ -93,7 +90,7 @@
func (s *Server) Start() {
r := mux.NewRouter()
- r.PathPrefix("/stat/").Handler(cachingHandler{http.FileServer(http.FS(statAssets))})
+ r.PathPrefix("/static/").Handler(server.NewCachingHandler(http.FileServer(http.FS(staticAssets))))
r.Path("/").Methods("POST").HandlerFunc(s.createAccount)
r.Path("/").Methods("GET").HandlerFunc(s.createAccountForm)
http.Handle("/", r)
@@ -136,14 +133,6 @@
Errors []ValidationError `json:"errors"`
}
-func getFormValue(v url.Values, name string) (string, error) {
- items, ok := v[name]
- if !ok || len(items) != 1 {
- return "", fmt.Errorf("%s not found", name)
- }
- return items[0], nil
-}
-
func extractReq(r *http.Request) (createAccountReq, error) {
var req createAccountReq
if err := func() error {
@@ -151,13 +140,13 @@
if err = r.ParseForm(); err != nil {
return err
}
- if req.Username, err = getFormValue(r.PostForm, "username"); err != nil {
+ if req.Username, err = server.GetFormValue(r.PostForm, "username"); err != nil {
return err
}
- if req.Password, err = getFormValue(r.PostForm, "password"); err != nil {
+ if req.Password, err = server.GetFormValue(r.PostForm, "password"); err != nil {
return err
}
- if req.SecretToken, err = getFormValue(r.PostForm, "secret-token"); err != nil {
+ if req.SecretToken, err = server.GetFormValue(r.PostForm, "secret-token"); err != nil {
return err
}
return nil
diff --git a/core/installer/welcome/static/welcome.css b/core/installer/server/welcome/static/main.css
similarity index 100%
rename from core/installer/welcome/static/welcome.css
rename to core/installer/server/welcome/static/main.css
diff --git a/core/installer/welcome/static/pico.2.0.6.min.css b/core/installer/server/welcome/static/pico.2.0.6.min.css
similarity index 100%
rename from core/installer/welcome/static/pico.2.0.6.min.css
rename to core/installer/server/welcome/static/pico.2.0.6.min.css
diff --git a/core/installer/welcome/welcome-tmpl/base.html b/core/installer/server/welcome/templates/base.html
similarity index 77%
rename from core/installer/welcome/welcome-tmpl/base.html
rename to core/installer/server/welcome/templates/base.html
index 44861de..648c04b 100644
--- a/core/installer/welcome/welcome-tmpl/base.html
+++ b/core/installer/server/welcome/templates/base.html
@@ -1,9 +1,9 @@
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
- <link rel="stylesheet" href="/stat/pico.2.0.6.min.css">
+ <link rel="stylesheet" href="/static/pico.2.0.6.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/hack-font/3.3.0/web/hack.min.css">
- <link rel="stylesheet" href="/stat/welcome.css?v=0.0.1">
+ <link rel="stylesheet" href="/static/main.css?v=0.0.1">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1" >
<title>Successful Registration</title>
diff --git a/core/installer/welcome/welcome-tmpl/create-account-success.html b/core/installer/server/welcome/templates/create-account-success.html
similarity index 100%
rename from core/installer/welcome/welcome-tmpl/create-account-success.html
rename to core/installer/server/welcome/templates/create-account-success.html
diff --git a/core/installer/welcome/welcome-tmpl/create-account.html b/core/installer/server/welcome/templates/create-account.html
similarity index 100%
rename from core/installer/welcome/welcome-tmpl/create-account.html
rename to core/installer/server/welcome/templates/create-account.html
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/resources/_gen/assets/css/ananke/css/main.css_83735de7ca999e9c17f3419b41b93fdb.content b/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/resources/_gen/assets/css/ananke/css/main.css_83735de7ca999e9c17f3419b41b93fdb.content
deleted file mode 100644
index 984a769..0000000
--- a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/resources/_gen/assets/css/ananke/css/main.css_83735de7ca999e9c17f3419b41b93fdb.content
+++ /dev/null
@@ -1 +0,0 @@
-/*!TACHYONS v4.9.1 | http://tachyons.io*//*!TACHYONS v4.12.0 | http://tachyons.io*//*!normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css*/html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}.border-box,a,article,aside,blockquote,body,code,dd,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,html,input[type=email],input[type=number],input[type=password],input[type=tel],input[type=text],input[type=url],legend,li,main,nav,ol,p,pre,section,table,td,textarea,th,tr,ul{box-sizing:border-box}.aspect-ratio{height:0;position:relative}.aspect-ratio--16x9{padding-bottom:56.25%}.aspect-ratio--9x16{padding-bottom:177.77%}.aspect-ratio--4x3{padding-bottom:75%}.aspect-ratio--3x4{padding-bottom:133.33%}.aspect-ratio--6x4{padding-bottom:66.6%}.aspect-ratio--4x6{padding-bottom:150%}.aspect-ratio--8x5{padding-bottom:62.5%}.aspect-ratio--5x8{padding-bottom:160%}.aspect-ratio--7x5{padding-bottom:71.42%}.aspect-ratio--5x7{padding-bottom:140%}.aspect-ratio--1x1{padding-bottom:100%}.aspect-ratio--object{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}img{max-width:100%}.cover{background-size:cover!important}.contain{background-size:contain!important}.bg-center{background-position:50%}.bg-center,.bg-top{background-repeat:no-repeat}.bg-top{background-position:top}.bg-right{background-position:100%}.bg-bottom,.bg-right{background-repeat:no-repeat}.bg-bottom{background-position:bottom}.bg-left{background-repeat:no-repeat;background-position:0}.outline{outline:1px solid}.outline-transparent{outline:1px solid transparent}.outline-0{outline:0}.ba{border-style:solid;border-width:1px}.bt{border-top-style:solid;border-top-width:1px}.br{border-right-style:solid;border-right-width:1px}.bb{border-bottom-style:solid;border-bottom-width:1px}.bl{border-left-style:solid;border-left-width:1px}.bn{border-style:none;border-width:0}.b--black{border-color:#000}.b--near-black{border-color:#111}.b--dark-gray{border-color:#333}.b--mid-gray{border-color:#555}.b--gray{border-color:#777}.b--silver{border-color:#999}.b--light-silver{border-color:#aaa}.b--moon-gray{border-color:#ccc}.b--light-gray{border-color:#eee}.b--near-white{border-color:#f4f4f4}.b--white{border-color:#fff}.b--white-90{border-color:rgba(255,255,255,.9)}.b--white-80{border-color:rgba(255,255,255,.8)}.b--white-70{border-color:rgba(255,255,255,.7)}.b--white-60{border-color:rgba(255,255,255,.6)}.b--white-50{border-color:rgba(255,255,255,.5)}.b--white-40{border-color:rgba(255,255,255,.4)}.b--white-30{border-color:rgba(255,255,255,.3)}.b--white-20{border-color:rgba(255,255,255,.2)}.b--white-10{border-color:rgba(255,255,255,.1)}.b--white-05{border-color:rgba(255,255,255,5%)}.b--white-025{border-color:rgba(255,255,255,.025)}.b--white-0125{border-color:rgba(255,255,255,.0125)}.b--black-90{border-color:rgba(0,0,0,.9)}.b--black-80{border-color:rgba(0,0,0,.8)}.b--black-70{border-color:rgba(0,0,0,.7)}.b--black-60{border-color:rgba(0,0,0,.6)}.b--black-50{border-color:rgba(0,0,0,.5)}.b--black-40{border-color:rgba(0,0,0,.4)}.b--black-30{border-color:rgba(0,0,0,.3)}.b--black-20{border-color:rgba(0,0,0,.2)}.b--black-10{border-color:rgba(0,0,0,.1)}.b--black-05{border-color:rgba(0,0,0,5%)}.b--black-025{border-color:rgba(0,0,0,.025)}.b--black-0125{border-color:rgba(0,0,0,.0125)}.b--dark-red{border-color:#e7040f}.b--red{border-color:#ff4136}.b--light-red{border-color:#ff725c}.b--orange{border-color:#ff6300}.b--gold{border-color:#ffb700}.b--yellow{border-color:gold}.b--light-yellow{border-color:#fbf1a9}.b--purple{border-color:#5e2ca5}.b--light-purple{border-color:#a463f2}.b--dark-pink{border-color:#d5008f}.b--hot-pink{border-color:#ff41b4}.b--pink{border-color:#ff80cc}.b--light-pink{border-color:#ffa3d7}.b--dark-green{border-color:#137752}.b--green{border-color:#19a974}.b--light-green{border-color:#9eebcf}.b--navy{border-color:#001b44}.b--dark-blue{border-color:#00449e}.b--blue{border-color:#357edd}.b--light-blue{border-color:#96ccff}.b--lightest-blue{border-color:#cdecff}.b--washed-blue{border-color:#f6fffe}.b--washed-green{border-color:#e8fdf5}.b--washed-yellow{border-color:#fffceb}.b--washed-red{border-color:#ffdfdf}.b--transparent{border-color:transparent}.b--inherit{border-color:inherit}.b--initial{border-color:initial}.b--unset{border-color:unset}.br0{border-radius:0}.br1{border-radius:.125rem}.br2{border-radius:.25rem}.br3{border-radius:.5rem}.br4{border-radius:1rem}.br-100{border-radius:100%}.br-pill{border-radius:9999px}.br--bottom{border-top-left-radius:0;border-top-right-radius:0}.br--top{border-bottom-right-radius:0}.br--right,.br--top{border-bottom-left-radius:0}.br--right{border-top-left-radius:0}.br--left{border-top-right-radius:0;border-bottom-right-radius:0}.br-inherit{border-radius:inherit}.br-initial{border-radius:initial}.br-unset{border-radius:unset}.b--dotted{border-style:dotted}.b--dashed{border-style:dashed}.b--solid{border-style:solid}.b--none{border-style:none}.bw0{border-width:0}.bw1{border-width:.125rem}.bw2{border-width:.25rem}.bw3{border-width:.5rem}.bw4{border-width:1rem}.bw5{border-width:2rem}.bt-0{border-top-width:0}.br-0{border-right-width:0}.bb-0{border-bottom-width:0}.bl-0{border-left-width:0}.shadow-1{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.shadow-2{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.shadow-3{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.shadow-4{box-shadow:2px 2px 8px rgba(0,0,0,.2)}.shadow-5{box-shadow:4px 4px 8px rgba(0,0,0,.2)}.pre{overflow-x:auto;overflow-y:hidden;overflow:scroll}.top-0{top:0}.right-0{right:0}.bottom-0{bottom:0}.left-0{left:0}.top-1{top:1rem}.right-1{right:1rem}.bottom-1{bottom:1rem}.left-1{left:1rem}.top-2{top:2rem}.right-2{right:2rem}.bottom-2{bottom:2rem}.left-2{left:2rem}.top--1{top:-1rem}.right--1{right:-1rem}.bottom--1{bottom:-1rem}.left--1{left:-1rem}.top--2{top:-2rem}.right--2{right:-2rem}.bottom--2{bottom:-2rem}.left--2{left:-2rem}.absolute--fill{top:0;right:0;bottom:0;left:0}.cf:after,.cf:before{content:" ";display:table}.cf:after{clear:both}.cf{*zoom:1}.cl{clear:left}.cr{clear:right}.cb{clear:both}.cn{clear:none}.dn{display:none}.di{display:inline}.db{display:block}.dib{display:inline-block}.dit{display:inline-table}.dt{display:table}.dtc{display:table-cell}.dt-row{display:table-row}.dt-row-group{display:table-row-group}.dt-column{display:table-column}.dt-column-group{display:table-column-group}.dt--fixed{table-layout:fixed;width:100%}.flex{display:flex}.inline-flex{display:inline-flex}.flex-auto{flex:auto;min-width:0;min-height:0}.flex-none{flex:none}.flex-column{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.flex-nowrap{flex-wrap:nowrap}.flex-wrap-reverse{flex-wrap:wrap-reverse}.flex-column-reverse{flex-direction:column-reverse}.flex-row-reverse{flex-direction:row-reverse}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.self-start{align-self:flex-start}.self-end{align-self:flex-end}.self-center{align-self:center}.self-baseline{align-self:baseline}.self-stretch{align-self:stretch}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-around{justify-content:space-around}.content-start{align-content:flex-start}.content-end{align-content:flex-end}.content-center{align-content:center}.content-between{align-content:space-between}.content-around{align-content:space-around}.content-stretch{align-content:stretch}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-last{order:99999}.flex-grow-0{flex-grow:0}.flex-grow-1{flex-grow:1}.flex-shrink-0{flex-shrink:0}.flex-shrink-1{flex-shrink:1}.fl{float:left}.fl,.fr{_display:inline}.fr{float:right}.fn{float:none}.sans-serif{font-family:-apple-system,BlinkMacSystemFont,avenir next,avenir,helvetica neue,helvetica,ubuntu,roboto,noto,segoe ui,arial,sans-serif}.serif{font-family:georgia,times,serif}.system-sans-serif{font-family:sans-serif}.system-serif{font-family:serif}.code,code{font-family:Consolas,monaco,monospace}.courier{font-family:Courier Next,courier,monospace}.helvetica{font-family:helvetica neue,helvetica,sans-serif}.avenir{font-family:avenir next,avenir,sans-serif}.athelas{font-family:athelas,georgia,serif}.georgia{font-family:georgia,serif}.times{font-family:times,serif}.bodoni{font-family:Bodoni MT,serif}.calisto{font-family:Calisto MT,serif}.garamond{font-family:garamond,serif}.baskerville{font-family:baskerville,serif}.i{font-style:italic}.fs-normal{font-style:normal}.normal{font-weight:400}.b{font-weight:700}.fw1{font-weight:100}.fw2{font-weight:200}.fw3{font-weight:300}.fw4{font-weight:400}.fw5{font-weight:500}.fw6{font-weight:600}.fw7{font-weight:700}.fw8{font-weight:800}.fw9{font-weight:900}.input-reset{-webkit-appearance:none;-moz-appearance:none}.button-reset::-moz-focus-inner,.input-reset::-moz-focus-inner{border:0;padding:0}.h1{height:1rem}.h2{height:2rem}.h3{height:4rem}.h4{height:8rem}.h5{height:16rem}.h-25{height:25%}.h-50{height:50%}.h-75{height:75%}.h-100{height:100%}.min-h-100{min-height:100%}.vh-25{height:25vh}.vh-50{height:50vh}.vh-75{height:75vh}.vh-100{height:100vh}.min-vh-100{min-height:100vh}.h-auto{height:auto}.h-inherit{height:inherit}.tracked{letter-spacing:.1em}.tracked-tight{letter-spacing:-.05em}.tracked-mega{letter-spacing:.25em}.lh-solid{line-height:1}.lh-title{line-height:1.25}.lh-copy{line-height:1.5}.link{text-decoration:none}.link,.link:active,.link:focus,.link:hover,.link:link,.link:visited{transition:color .15s ease-in}.link:focus{outline:1px dotted currentColor}.list{list-style-type:none}.mw-100{max-width:100%}.mw1{max-width:1rem}.mw2{max-width:2rem}.mw3{max-width:4rem}.mw4{max-width:8rem}.mw5{max-width:16rem}.mw6{max-width:32rem}.mw7{max-width:48rem}.mw8{max-width:64rem}.mw9{max-width:96rem}.mw-none{max-width:none}.w1{width:1rem}.w2{width:2rem}.w3{width:4rem}.w4{width:8rem}.w5{width:16rem}.w-10{width:10%}.w-20{width:20%}.w-25{width:25%}.w-30{width:30%}.w-33{width:33%}.w-34{width:34%}.w-40{width:40%}.w-50{width:50%}.w-60{width:60%}.w-70{width:70%}.w-75{width:75%}.w-80{width:80%}.w-90{width:90%}.w-100{width:100%}.w-third{width:33.33333%}.w-two-thirds{width:66.66667%}.w-auto{width:auto}.overflow-visible{overflow:visible}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.overflow-auto{overflow:auto}.overflow-x-visible{overflow-x:visible}.overflow-x-hidden{overflow-x:hidden}.overflow-x-scroll{overflow-x:scroll}.overflow-x-auto{overflow-x:auto}.overflow-y-visible{overflow-y:visible}.overflow-y-hidden{overflow-y:hidden}.overflow-y-scroll{overflow-y:scroll}.overflow-y-auto{overflow-y:auto}.static{position:static}.relative{position:relative}.absolute{position:absolute}.fixed{position:fixed}.o-100{opacity:1}.o-90{opacity:.9}.o-80{opacity:.8}.o-70{opacity:.7}.o-60{opacity:.6}.o-50{opacity:.5}.o-40{opacity:.4}.o-30{opacity:.3}.o-20{opacity:.2}.o-10{opacity:.1}.o-05{opacity:.05}.o-025{opacity:.025}.o-0{opacity:0}.rotate-45{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.rotate-135{-webkit-transform:rotate(135deg);transform:rotate(135deg)}.rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.rotate-225{-webkit-transform:rotate(225deg);transform:rotate(225deg)}.rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.rotate-315{-webkit-transform:rotate(315deg);transform:rotate(315deg)}.black-90{color:rgba(0,0,0,.9)}.black-80{color:rgba(0,0,0,.8)}.black-70{color:rgba(0,0,0,.7)}.black-60{color:rgba(0,0,0,.6)}.black-50{color:rgba(0,0,0,.5)}.black-40{color:rgba(0,0,0,.4)}.black-30{color:rgba(0,0,0,.3)}.black-20{color:rgba(0,0,0,.2)}.black-10{color:rgba(0,0,0,.1)}.black-05{color:rgba(0,0,0,5%)}.white-90{color:rgba(255,255,255,.9)}.white-80{color:rgba(255,255,255,.8)}.white-70{color:rgba(255,255,255,.7)}.white-60{color:rgba(255,255,255,.6)}.white-50{color:rgba(255,255,255,.5)}.white-40{color:rgba(255,255,255,.4)}.white-30{color:rgba(255,255,255,.3)}.white-20{color:rgba(255,255,255,.2)}.white-10{color:rgba(255,255,255,.1)}.black{color:#000}.near-black{color:#111}.dark-gray{color:#333}.mid-gray{color:#555}.gray{color:#777}.silver{color:#999}.light-silver{color:#aaa}.moon-gray{color:#ccc}.light-gray{color:#eee}.near-white{color:#f4f4f4}.white{color:#fff}.dark-red{color:#e7040f}.red{color:#ff4136}.light-red{color:#ff725c}.orange{color:#ff6300}.gold{color:#ffb700}.yellow{color:gold}.light-yellow{color:#fbf1a9}.purple{color:#5e2ca5}.light-purple{color:#a463f2}.dark-pink{color:#d5008f}.hot-pink{color:#ff41b4}.pink{color:#ff80cc}.light-pink{color:#ffa3d7}.dark-green{color:#137752}.green{color:#19a974}.light-green{color:#9eebcf}.navy{color:#001b44}.dark-blue{color:#00449e}.blue{color:#357edd}.light-blue{color:#96ccff}.lightest-blue{color:#cdecff}.washed-blue{color:#f6fffe}.washed-green{color:#e8fdf5}.washed-yellow{color:#fffceb}.washed-red{color:#ffdfdf}.color-inherit{color:inherit}.bg-black-90{background-color:rgba(0,0,0,.9)}.bg-black-80{background-color:rgba(0,0,0,.8)}.bg-black-70{background-color:rgba(0,0,0,.7)}.bg-black-60{background-color:rgba(0,0,0,.6)}.bg-black-50{background-color:rgba(0,0,0,.5)}.bg-black-40{background-color:rgba(0,0,0,.4)}.bg-black-30{background-color:rgba(0,0,0,.3)}.bg-black-20{background-color:rgba(0,0,0,.2)}.bg-black-10{background-color:rgba(0,0,0,.1)}.bg-black-05{background-color:rgba(0,0,0,5%)}.bg-white-90{background-color:rgba(255,255,255,.9)}.bg-white-80{background-color:rgba(255,255,255,.8)}.bg-white-70{background-color:rgba(255,255,255,.7)}.bg-white-60{background-color:rgba(255,255,255,.6)}.bg-white-50{background-color:rgba(255,255,255,.5)}.bg-white-40{background-color:rgba(255,255,255,.4)}.bg-white-30{background-color:rgba(255,255,255,.3)}.bg-white-20{background-color:rgba(255,255,255,.2)}.bg-white-10{background-color:rgba(255,255,255,.1)}.bg-black{background-color:#000}.bg-near-black{background-color:#111}.bg-dark-gray{background-color:#333}.bg-mid-gray{background-color:#555}.bg-gray{background-color:#777}.bg-silver{background-color:#999}.bg-light-silver{background-color:#aaa}.bg-moon-gray{background-color:#ccc}.bg-light-gray{background-color:#eee}.bg-near-white{background-color:#f4f4f4}.bg-white{background-color:#fff}.bg-transparent{background-color:transparent}.bg-dark-red{background-color:#e7040f}.bg-red{background-color:#ff4136}.bg-light-red{background-color:#ff725c}.bg-orange{background-color:#ff6300}.bg-gold{background-color:#ffb700}.bg-yellow{background-color:gold}.bg-light-yellow{background-color:#fbf1a9}.bg-purple{background-color:#5e2ca5}.bg-light-purple{background-color:#a463f2}.bg-dark-pink{background-color:#d5008f}.bg-hot-pink{background-color:#ff41b4}.bg-pink{background-color:#ff80cc}.bg-light-pink{background-color:#ffa3d7}.bg-dark-green{background-color:#137752}.bg-green{background-color:#19a974}.bg-light-green{background-color:#9eebcf}.bg-navy{background-color:#001b44}.bg-dark-blue{background-color:#00449e}.bg-blue{background-color:#357edd}.bg-light-blue{background-color:#96ccff}.bg-lightest-blue{background-color:#cdecff}.bg-washed-blue{background-color:#f6fffe}.bg-washed-green{background-color:#e8fdf5}.bg-washed-yellow{background-color:#fffceb}.bg-washed-red{background-color:#ffdfdf}.bg-inherit{background-color:inherit}.hover-black:focus,.hover-black:hover{color:#000}.hover-near-black:focus,.hover-near-black:hover{color:#111}.hover-dark-gray:focus,.hover-dark-gray:hover{color:#333}.hover-mid-gray:focus,.hover-mid-gray:hover{color:#555}.hover-gray:focus,.hover-gray:hover{color:#777}.hover-silver:focus,.hover-silver:hover{color:#999}.hover-light-silver:focus,.hover-light-silver:hover{color:#aaa}.hover-moon-gray:focus,.hover-moon-gray:hover{color:#ccc}.hover-light-gray:focus,.hover-light-gray:hover{color:#eee}.hover-near-white:focus,.hover-near-white:hover{color:#f4f4f4}.hover-white:focus,.hover-white:hover{color:#fff}.hover-black-90:focus,.hover-black-90:hover{color:rgba(0,0,0,.9)}.hover-black-80:focus,.hover-black-80:hover{color:rgba(0,0,0,.8)}.hover-black-70:focus,.hover-black-70:hover{color:rgba(0,0,0,.7)}.hover-black-60:focus,.hover-black-60:hover{color:rgba(0,0,0,.6)}.hover-black-50:focus,.hover-black-50:hover{color:rgba(0,0,0,.5)}.hover-black-40:focus,.hover-black-40:hover{color:rgba(0,0,0,.4)}.hover-black-30:focus,.hover-black-30:hover{color:rgba(0,0,0,.3)}.hover-black-20:focus,.hover-black-20:hover{color:rgba(0,0,0,.2)}.hover-black-10:focus,.hover-black-10:hover{color:rgba(0,0,0,.1)}.hover-white-90:focus,.hover-white-90:hover{color:rgba(255,255,255,.9)}.hover-white-80:focus,.hover-white-80:hover{color:rgba(255,255,255,.8)}.hover-white-70:focus,.hover-white-70:hover{color:rgba(255,255,255,.7)}.hover-white-60:focus,.hover-white-60:hover{color:rgba(255,255,255,.6)}.hover-white-50:focus,.hover-white-50:hover{color:rgba(255,255,255,.5)}.hover-white-40:focus,.hover-white-40:hover{color:rgba(255,255,255,.4)}.hover-white-30:focus,.hover-white-30:hover{color:rgba(255,255,255,.3)}.hover-white-20:focus,.hover-white-20:hover{color:rgba(255,255,255,.2)}.hover-white-10:focus,.hover-white-10:hover{color:rgba(255,255,255,.1)}.hover-inherit:focus,.hover-inherit:hover{color:inherit}.hover-bg-black:focus,.hover-bg-black:hover{background-color:#000}.hover-bg-near-black:focus,.hover-bg-near-black:hover{background-color:#111}.hover-bg-dark-gray:focus,.hover-bg-dark-gray:hover{background-color:#333}.hover-bg-mid-gray:focus,.hover-bg-mid-gray:hover{background-color:#555}.hover-bg-gray:focus,.hover-bg-gray:hover{background-color:#777}.hover-bg-silver:focus,.hover-bg-silver:hover{background-color:#999}.hover-bg-light-silver:focus,.hover-bg-light-silver:hover{background-color:#aaa}.hover-bg-moon-gray:focus,.hover-bg-moon-gray:hover{background-color:#ccc}.hover-bg-light-gray:focus,.hover-bg-light-gray:hover{background-color:#eee}.hover-bg-near-white:focus,.hover-bg-near-white:hover{background-color:#f4f4f4}.hover-bg-white:focus,.hover-bg-white:hover{background-color:#fff}.hover-bg-transparent:focus,.hover-bg-transparent:hover{background-color:transparent}.hover-bg-black-90:focus,.hover-bg-black-90:hover{background-color:rgba(0,0,0,.9)}.hover-bg-black-80:focus,.hover-bg-black-80:hover{background-color:rgba(0,0,0,.8)}.hover-bg-black-70:focus,.hover-bg-black-70:hover{background-color:rgba(0,0,0,.7)}.hover-bg-black-60:focus,.hover-bg-black-60:hover{background-color:rgba(0,0,0,.6)}.hover-bg-black-50:focus,.hover-bg-black-50:hover{background-color:rgba(0,0,0,.5)}.hover-bg-black-40:focus,.hover-bg-black-40:hover{background-color:rgba(0,0,0,.4)}.hover-bg-black-30:focus,.hover-bg-black-30:hover{background-color:rgba(0,0,0,.3)}.hover-bg-black-20:focus,.hover-bg-black-20:hover{background-color:rgba(0,0,0,.2)}.hover-bg-black-10:focus,.hover-bg-black-10:hover{background-color:rgba(0,0,0,.1)}.hover-bg-white-90:focus,.hover-bg-white-90:hover{background-color:rgba(255,255,255,.9)}.hover-bg-white-80:focus,.hover-bg-white-80:hover{background-color:rgba(255,255,255,.8)}.hover-bg-white-70:focus,.hover-bg-white-70:hover{background-color:rgba(255,255,255,.7)}.hover-bg-white-60:focus,.hover-bg-white-60:hover{background-color:rgba(255,255,255,.6)}.hover-bg-white-50:focus,.hover-bg-white-50:hover{background-color:rgba(255,255,255,.5)}.hover-bg-white-40:focus,.hover-bg-white-40:hover{background-color:rgba(255,255,255,.4)}.hover-bg-white-30:focus,.hover-bg-white-30:hover{background-color:rgba(255,255,255,.3)}.hover-bg-white-20:focus,.hover-bg-white-20:hover{background-color:rgba(255,255,255,.2)}.hover-bg-white-10:focus,.hover-bg-white-10:hover{background-color:rgba(255,255,255,.1)}.hover-dark-red:focus,.hover-dark-red:hover{color:#e7040f}.hover-red:focus,.hover-red:hover{color:#ff4136}.hover-light-red:focus,.hover-light-red:hover{color:#ff725c}.hover-orange:focus,.hover-orange:hover{color:#ff6300}.hover-gold:focus,.hover-gold:hover{color:#ffb700}.hover-yellow:focus,.hover-yellow:hover{color:gold}.hover-light-yellow:focus,.hover-light-yellow:hover{color:#fbf1a9}.hover-purple:focus,.hover-purple:hover{color:#5e2ca5}.hover-light-purple:focus,.hover-light-purple:hover{color:#a463f2}.hover-dark-pink:focus,.hover-dark-pink:hover{color:#d5008f}.hover-hot-pink:focus,.hover-hot-pink:hover{color:#ff41b4}.hover-pink:focus,.hover-pink:hover{color:#ff80cc}.hover-light-pink:focus,.hover-light-pink:hover{color:#ffa3d7}.hover-dark-green:focus,.hover-dark-green:hover{color:#137752}.hover-green:focus,.hover-green:hover{color:#19a974}.hover-light-green:focus,.hover-light-green:hover{color:#9eebcf}.hover-navy:focus,.hover-navy:hover{color:#001b44}.hover-dark-blue:focus,.hover-dark-blue:hover{color:#00449e}.hover-blue:focus,.hover-blue:hover{color:#357edd}.hover-light-blue:focus,.hover-light-blue:hover{color:#96ccff}.hover-lightest-blue:focus,.hover-lightest-blue:hover{color:#cdecff}.hover-washed-blue:focus,.hover-washed-blue:hover{color:#f6fffe}.hover-washed-green:focus,.hover-washed-green:hover{color:#e8fdf5}.hover-washed-yellow:focus,.hover-washed-yellow:hover{color:#fffceb}.hover-washed-red:focus,.hover-washed-red:hover{color:#ffdfdf}.hover-bg-dark-red:focus,.hover-bg-dark-red:hover{background-color:#e7040f}.hover-bg-red:focus,.hover-bg-red:hover{background-color:#ff4136}.hover-bg-light-red:focus,.hover-bg-light-red:hover{background-color:#ff725c}.hover-bg-orange:focus,.hover-bg-orange:hover{background-color:#ff6300}.hover-bg-gold:focus,.hover-bg-gold:hover{background-color:#ffb700}.hover-bg-yellow:focus,.hover-bg-yellow:hover{background-color:gold}.hover-bg-light-yellow:focus,.hover-bg-light-yellow:hover{background-color:#fbf1a9}.hover-bg-purple:focus,.hover-bg-purple:hover{background-color:#5e2ca5}.hover-bg-light-purple:focus,.hover-bg-light-purple:hover{background-color:#a463f2}.hover-bg-dark-pink:focus,.hover-bg-dark-pink:hover{background-color:#d5008f}.hover-bg-hot-pink:focus,.hover-bg-hot-pink:hover{background-color:#ff41b4}.hover-bg-pink:focus,.hover-bg-pink:hover{background-color:#ff80cc}.hover-bg-light-pink:focus,.hover-bg-light-pink:hover{background-color:#ffa3d7}.hover-bg-dark-green:focus,.hover-bg-dark-green:hover{background-color:#137752}.hover-bg-green:focus,.hover-bg-green:hover{background-color:#19a974}.hover-bg-light-green:focus,.hover-bg-light-green:hover{background-color:#9eebcf}.hover-bg-navy:focus,.hover-bg-navy:hover{background-color:#001b44}.hover-bg-dark-blue:focus,.hover-bg-dark-blue:hover{background-color:#00449e}.hover-bg-blue:focus,.hover-bg-blue:hover{background-color:#357edd}.hover-bg-light-blue:focus,.hover-bg-light-blue:hover{background-color:#96ccff}.hover-bg-lightest-blue:focus,.hover-bg-lightest-blue:hover{background-color:#cdecff}.hover-bg-washed-blue:focus,.hover-bg-washed-blue:hover{background-color:#f6fffe}.hover-bg-washed-green:focus,.hover-bg-washed-green:hover{background-color:#e8fdf5}.hover-bg-washed-yellow:focus,.hover-bg-washed-yellow:hover{background-color:#fffceb}.hover-bg-washed-red:focus,.hover-bg-washed-red:hover{background-color:#ffdfdf}.hover-bg-inherit:focus,.hover-bg-inherit:hover{background-color:inherit}.pa0{padding:0}.pa1{padding:.25rem}.pa2{padding:.5rem}.pa3{padding:1rem}.pa4{padding:2rem}.pa5{padding:4rem}.pa6{padding:8rem}.pa7{padding:16rem}.pl0{padding-left:0}.pl1{padding-left:.25rem}.pl2{padding-left:.5rem}.pl3{padding-left:1rem}.pl4{padding-left:2rem}.pl5{padding-left:4rem}.pl6{padding-left:8rem}.pl7{padding-left:16rem}.pr0{padding-right:0}.pr1{padding-right:.25rem}.pr2{padding-right:.5rem}.pr3{padding-right:1rem}.pr4{padding-right:2rem}.pr5{padding-right:4rem}.pr6{padding-right:8rem}.pr7{padding-right:16rem}.pb0{padding-bottom:0}.pb1{padding-bottom:.25rem}.pb2{padding-bottom:.5rem}.pb3{padding-bottom:1rem}.pb4{padding-bottom:2rem}.pb5{padding-bottom:4rem}.pb6{padding-bottom:8rem}.pb7{padding-bottom:16rem}.pt0{padding-top:0}.pt1{padding-top:.25rem}.pt2{padding-top:.5rem}.pt3{padding-top:1rem}.pt4{padding-top:2rem}.pt5{padding-top:4rem}.pt6{padding-top:8rem}.pt7{padding-top:16rem}.pv0{padding-top:0;padding-bottom:0}.pv1{padding-top:.25rem;padding-bottom:.25rem}.pv2{padding-top:.5rem;padding-bottom:.5rem}.pv3{padding-top:1rem;padding-bottom:1rem}.pv4{padding-top:2rem;padding-bottom:2rem}.pv5{padding-top:4rem;padding-bottom:4rem}.pv6{padding-top:8rem;padding-bottom:8rem}.pv7{padding-top:16rem;padding-bottom:16rem}.ph0{padding-left:0;padding-right:0}.ph1{padding-left:.25rem;padding-right:.25rem}.ph2{padding-left:.5rem;padding-right:.5rem}.ph3{padding-left:1rem;padding-right:1rem}.ph4{padding-left:2rem;padding-right:2rem}.ph5{padding-left:4rem;padding-right:4rem}.ph6{padding-left:8rem;padding-right:8rem}.ph7{padding-left:16rem;padding-right:16rem}.ma0{margin:0}.ma1{margin:.25rem}.ma2{margin:.5rem}.ma3{margin:1rem}.ma4{margin:2rem}.ma5{margin:4rem}.ma6{margin:8rem}.ma7{margin:16rem}.ml0{margin-left:0}.ml1{margin-left:.25rem}.ml2{margin-left:.5rem}.ml3{margin-left:1rem}.ml4{margin-left:2rem}.ml5{margin-left:4rem}.ml6{margin-left:8rem}.ml7{margin-left:16rem}.mr0{margin-right:0}.mr1{margin-right:.25rem}.mr2{margin-right:.5rem}.mr3{margin-right:1rem}.mr4{margin-right:2rem}.mr5{margin-right:4rem}.mr6{margin-right:8rem}.mr7{margin-right:16rem}.mb0{margin-bottom:0}.mb1{margin-bottom:.25rem}.mb2{margin-bottom:.5rem}.mb3{margin-bottom:1rem}.mb4{margin-bottom:2rem}.mb5{margin-bottom:4rem}.mb6{margin-bottom:8rem}.mb7{margin-bottom:16rem}.mt0{margin-top:0}.mt1{margin-top:.25rem}.mt2{margin-top:.5rem}.mt3{margin-top:1rem}.mt4{margin-top:2rem}.mt5{margin-top:4rem}.mt6{margin-top:8rem}.mt7{margin-top:16rem}.mv0{margin-top:0;margin-bottom:0}.mv1{margin-top:.25rem;margin-bottom:.25rem}.mv2{margin-top:.5rem;margin-bottom:.5rem}.mv3{margin-top:1rem;margin-bottom:1rem}.mv4{margin-top:2rem;margin-bottom:2rem}.mv5{margin-top:4rem;margin-bottom:4rem}.mv6{margin-top:8rem;margin-bottom:8rem}.mv7{margin-top:16rem;margin-bottom:16rem}.mh0{margin-left:0;margin-right:0}.mh1{margin-left:.25rem;margin-right:.25rem}.mh2{margin-left:.5rem;margin-right:.5rem}.mh3{margin-left:1rem;margin-right:1rem}.mh4{margin-left:2rem;margin-right:2rem}.mh5{margin-left:4rem;margin-right:4rem}.mh6{margin-left:8rem;margin-right:8rem}.mh7{margin-left:16rem;margin-right:16rem}.na1{margin:-.25rem}.na2{margin:-.5rem}.na3{margin:-1rem}.na4{margin:-2rem}.na5{margin:-4rem}.na6{margin:-8rem}.na7{margin:-16rem}.nl1{margin-left:-.25rem}.nl2{margin-left:-.5rem}.nl3{margin-left:-1rem}.nl4{margin-left:-2rem}.nl5{margin-left:-4rem}.nl6{margin-left:-8rem}.nl7{margin-left:-16rem}.nr1{margin-right:-.25rem}.nr2{margin-right:-.5rem}.nr3{margin-right:-1rem}.nr4{margin-right:-2rem}.nr5{margin-right:-4rem}.nr6{margin-right:-8rem}.nr7{margin-right:-16rem}.nb1{margin-bottom:-.25rem}.nb2{margin-bottom:-.5rem}.nb3{margin-bottom:-1rem}.nb4{margin-bottom:-2rem}.nb5{margin-bottom:-4rem}.nb6{margin-bottom:-8rem}.nb7{margin-bottom:-16rem}.nt1{margin-top:-.25rem}.nt2{margin-top:-.5rem}.nt3{margin-top:-1rem}.nt4{margin-top:-2rem}.nt5{margin-top:-4rem}.nt6{margin-top:-8rem}.nt7{margin-top:-16rem}.collapse{border-collapse:collapse;border-spacing:0}.striped--light-silver:nth-child(odd){background-color:#aaa}.striped--moon-gray:nth-child(odd){background-color:#ccc}.striped--light-gray:nth-child(odd){background-color:#eee}.striped--near-white:nth-child(odd){background-color:#f4f4f4}.stripe-light:nth-child(odd){background-color:rgba(255,255,255,.1)}.stripe-dark:nth-child(odd){background-color:rgba(0,0,0,.1)}.strike{text-decoration:line-through}.underline{text-decoration:underline}.no-underline{text-decoration:none}.tl{text-align:left}.tr{text-align:right}.tc{text-align:center}.tj{text-align:justify}.ttc{text-transform:capitalize}.ttl{text-transform:lowercase}.ttu{text-transform:uppercase}.ttn{text-transform:none}.f-6,.f-headline{font-size:6rem}.f-5,.f-subheadline{font-size:5rem}.f1{font-size:3rem}.f2{font-size:2.25rem}.f3{font-size:1.5rem}.f4{font-size:1.25rem}.f5{font-size:1rem}.f6{font-size:.875rem}.f7{font-size:.75rem}.measure{max-width:30em}.measure-wide{max-width:34em}.measure-narrow{max-width:20em}.indent{text-indent:1em;margin-top:0;margin-bottom:0}.small-caps{font-variant:small-caps}.truncate{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.overflow-container{overflow-y:scroll}.center{margin-left:auto}.center,.mr-auto{margin-right:auto}.ml-auto{margin-left:auto}.clip{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}.ws-normal{white-space:normal}.nowrap{white-space:nowrap}.pre{white-space:pre}.v-base{vertical-align:baseline}.v-mid{vertical-align:middle}.v-top{vertical-align:top}.v-btm{vertical-align:bottom}.dim{opacity:1}.dim,.dim:focus,.dim:hover{transition:opacity .15s ease-in}.dim:focus,.dim:hover{opacity:.5}.dim:active{opacity:.8;transition:opacity .15s ease-out}.glow,.glow:focus,.glow:hover{transition:opacity .15s ease-in}.glow:focus,.glow:hover{opacity:1}.hide-child .child{opacity:0;transition:opacity .15s ease-in}.hide-child:active .child,.hide-child:focus .child,.hide-child:hover .child{opacity:1;transition:opacity .15s ease-in}.underline-hover:focus,.underline-hover:hover{text-decoration:underline}.grow{-moz-osx-font-smoothing:grayscale;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:translateZ(0);transform:translateZ(0);transition:-webkit-transform .25s ease-out;transition:transform .25s ease-out;transition:transform .25s ease-out,-webkit-transform .25s ease-out}.grow:focus,.grow:hover{-webkit-transform:scale(1.05);transform:scale(1.05)}.grow:active{-webkit-transform:scale(.9);transform:scale(.9)}.grow-large{-moz-osx-font-smoothing:grayscale;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:translateZ(0);transform:translateZ(0);transition:-webkit-transform .25s ease-in-out;transition:transform .25s ease-in-out;transition:transform .25s ease-in-out,-webkit-transform .25s ease-in-out}.grow-large:focus,.grow-large:hover{-webkit-transform:scale(1.2);transform:scale(1.2)}.grow-large:active{-webkit-transform:scale(.95);transform:scale(.95)}.pointer:hover,.shadow-hover{cursor:pointer}.shadow-hover{position:relative;transition:all .5s cubic-bezier(.165,.84,.44,1)}.shadow-hover:after{content:"";box-shadow:0 0 16px 2px rgba(0,0,0,.2);border-radius:inherit;opacity:0;position:absolute;top:0;left:0;width:100%;height:100%;z-index:-1;transition:opacity .5s cubic-bezier(.165,.84,.44,1)}.shadow-hover:focus:after,.shadow-hover:hover:after{opacity:1}.bg-animate,.bg-animate:focus,.bg-animate:hover{transition:background-color .15s ease-in-out}.z-0{z-index:0}.z-1{z-index:1}.z-2{z-index:2}.z-3{z-index:3}.z-4{z-index:4}.z-5{z-index:5}.z-999{z-index:999}.z-9999{z-index:9999}.z-max{z-index:2147483647}.z-inherit{z-index:inherit}.z-initial{z-index:auto}.z-unset{z-index:unset}.nested-copy-line-height ol,.nested-copy-line-height p,.nested-copy-line-height ul{line-height:1.5}.nested-headline-line-height h1,.nested-headline-line-height h2,.nested-headline-line-height h3,.nested-headline-line-height h4,.nested-headline-line-height h5,.nested-headline-line-height h6{line-height:1.25}.nested-list-reset ol,.nested-list-reset ul{padding-left:0;margin-left:0;list-style-type:none}.nested-copy-indent p+p{text-indent:1em;margin-top:0;margin-bottom:0}.nested-copy-separator p+p{margin-top:1.5em}.nested-img img{width:100%;max-width:100%;display:block}.nested-links a{color:#357edd;transition:color .15s ease-in}.nested-links a:focus,.nested-links a:hover{color:#96ccff;transition:color .15s ease-in}.debug *{outline:1px solid gold}.debug-white *{outline:1px solid #fff}.debug-black *{outline:1px solid #000}.debug-grid{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAFElEQVR4AWPAC97/9x0eCsAEPgwAVLshdpENIxcAAAAASUVORK5CYII=)repeat}.debug-grid-16{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMklEQVR4AWOgCLz/b0epAa6UGuBOqQHOQHLUgFEDnAbcBZ4UGwDOkiCnkIhdgNgNxAYAiYlD+8sEuo8AAAAASUVORK5CYII=)repeat}.debug-grid-8-solid{background:#fff url(data:image/gif;base64,R0lGODdhCAAIAPEAAADw/wDx/////wAAACwAAAAACAAIAAACDZQvgaeb/lxbAIKA8y0AOw==)repeat}.debug-grid-16-solid{background:#fff url(data:image/gif;base64,R0lGODdhEAAQAPEAAADw/wDx/xXy/////ywAAAAAEAAQAAACIZyPKckYDQFsb6ZqD85jZ2+BkwiRFKehhqQCQgDHcgwEBQA7)repeat}@media screen and (min-width:30em){.aspect-ratio-ns{height:0;position:relative}.aspect-ratio--16x9-ns{padding-bottom:56.25%}.aspect-ratio--9x16-ns{padding-bottom:177.77%}.aspect-ratio--4x3-ns{padding-bottom:75%}.aspect-ratio--3x4-ns{padding-bottom:133.33%}.aspect-ratio--6x4-ns{padding-bottom:66.6%}.aspect-ratio--4x6-ns{padding-bottom:150%}.aspect-ratio--8x5-ns{padding-bottom:62.5%}.aspect-ratio--5x8-ns{padding-bottom:160%}.aspect-ratio--7x5-ns{padding-bottom:71.42%}.aspect-ratio--5x7-ns{padding-bottom:140%}.aspect-ratio--1x1-ns{padding-bottom:100%}.aspect-ratio--object-ns{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}.cover-ns{background-size:cover!important}.contain-ns{background-size:contain!important}.bg-center-ns{background-position:50%}.bg-center-ns,.bg-top-ns{background-repeat:no-repeat}.bg-top-ns{background-position:top}.bg-right-ns{background-position:100%}.bg-bottom-ns,.bg-right-ns{background-repeat:no-repeat}.bg-bottom-ns{background-position:bottom}.bg-left-ns{background-repeat:no-repeat;background-position:0}.outline-ns{outline:1px solid}.outline-transparent-ns{outline:1px solid transparent}.outline-0-ns{outline:0}.ba-ns{border-style:solid;border-width:1px}.bt-ns{border-top-style:solid;border-top-width:1px}.br-ns{border-right-style:solid;border-right-width:1px}.bb-ns{border-bottom-style:solid;border-bottom-width:1px}.bl-ns{border-left-style:solid;border-left-width:1px}.bn-ns{border-style:none;border-width:0}.br0-ns{border-radius:0}.br1-ns{border-radius:.125rem}.br2-ns{border-radius:.25rem}.br3-ns{border-radius:.5rem}.br4-ns{border-radius:1rem}.br-100-ns{border-radius:100%}.br-pill-ns{border-radius:9999px}.br--bottom-ns{border-top-left-radius:0;border-top-right-radius:0}.br--top-ns{border-bottom-right-radius:0}.br--right-ns,.br--top-ns{border-bottom-left-radius:0}.br--right-ns{border-top-left-radius:0}.br--left-ns{border-top-right-radius:0;border-bottom-right-radius:0}.br-inherit-ns{border-radius:inherit}.br-initial-ns{border-radius:initial}.br-unset-ns{border-radius:unset}.b--dotted-ns{border-style:dotted}.b--dashed-ns{border-style:dashed}.b--solid-ns{border-style:solid}.b--none-ns{border-style:none}.bw0-ns{border-width:0}.bw1-ns{border-width:.125rem}.bw2-ns{border-width:.25rem}.bw3-ns{border-width:.5rem}.bw4-ns{border-width:1rem}.bw5-ns{border-width:2rem}.bt-0-ns{border-top-width:0}.br-0-ns{border-right-width:0}.bb-0-ns{border-bottom-width:0}.bl-0-ns{border-left-width:0}.shadow-1-ns{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.shadow-2-ns{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.shadow-3-ns{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.shadow-4-ns{box-shadow:2px 2px 8px rgba(0,0,0,.2)}.shadow-5-ns{box-shadow:4px 4px 8px rgba(0,0,0,.2)}.top-0-ns{top:0}.left-0-ns{left:0}.right-0-ns{right:0}.bottom-0-ns{bottom:0}.top-1-ns{top:1rem}.left-1-ns{left:1rem}.right-1-ns{right:1rem}.bottom-1-ns{bottom:1rem}.top-2-ns{top:2rem}.left-2-ns{left:2rem}.right-2-ns{right:2rem}.bottom-2-ns{bottom:2rem}.top--1-ns{top:-1rem}.right--1-ns{right:-1rem}.bottom--1-ns{bottom:-1rem}.left--1-ns{left:-1rem}.top--2-ns{top:-2rem}.right--2-ns{right:-2rem}.bottom--2-ns{bottom:-2rem}.left--2-ns{left:-2rem}.absolute--fill-ns{top:0;right:0;bottom:0;left:0}.cl-ns{clear:left}.cr-ns{clear:right}.cb-ns{clear:both}.cn-ns{clear:none}.dn-ns{display:none}.di-ns{display:inline}.db-ns{display:block}.dib-ns{display:inline-block}.dit-ns{display:inline-table}.dt-ns{display:table}.dtc-ns{display:table-cell}.dt-row-ns{display:table-row}.dt-row-group-ns{display:table-row-group}.dt-column-ns{display:table-column}.dt-column-group-ns{display:table-column-group}.dt--fixed-ns{table-layout:fixed;width:100%}.flex-ns{display:flex}.inline-flex-ns{display:inline-flex}.flex-auto-ns{flex:auto;min-width:0;min-height:0}.flex-none-ns{flex:none}.flex-column-ns{flex-direction:column}.flex-row-ns{flex-direction:row}.flex-wrap-ns{flex-wrap:wrap}.flex-nowrap-ns{flex-wrap:nowrap}.flex-wrap-reverse-ns{flex-wrap:wrap-reverse}.flex-column-reverse-ns{flex-direction:column-reverse}.flex-row-reverse-ns{flex-direction:row-reverse}.items-start-ns{align-items:flex-start}.items-end-ns{align-items:flex-end}.items-center-ns{align-items:center}.items-baseline-ns{align-items:baseline}.items-stretch-ns{align-items:stretch}.self-start-ns{align-self:flex-start}.self-end-ns{align-self:flex-end}.self-center-ns{align-self:center}.self-baseline-ns{align-self:baseline}.self-stretch-ns{align-self:stretch}.justify-start-ns{justify-content:flex-start}.justify-end-ns{justify-content:flex-end}.justify-center-ns{justify-content:center}.justify-between-ns{justify-content:space-between}.justify-around-ns{justify-content:space-around}.content-start-ns{align-content:flex-start}.content-end-ns{align-content:flex-end}.content-center-ns{align-content:center}.content-between-ns{align-content:space-between}.content-around-ns{align-content:space-around}.content-stretch-ns{align-content:stretch}.order-0-ns{order:0}.order-1-ns{order:1}.order-2-ns{order:2}.order-3-ns{order:3}.order-4-ns{order:4}.order-5-ns{order:5}.order-6-ns{order:6}.order-7-ns{order:7}.order-8-ns{order:8}.order-last-ns{order:99999}.flex-grow-0-ns{flex-grow:0}.flex-grow-1-ns{flex-grow:1}.flex-shrink-0-ns{flex-shrink:0}.flex-shrink-1-ns{flex-shrink:1}.fl-ns{float:left}.fl-ns,.fr-ns{_display:inline}.fr-ns{float:right}.fn-ns{float:none}.i-ns{font-style:italic}.fs-normal-ns{font-style:normal}.normal-ns{font-weight:400}.b-ns{font-weight:700}.fw1-ns{font-weight:100}.fw2-ns{font-weight:200}.fw3-ns{font-weight:300}.fw4-ns{font-weight:400}.fw5-ns{font-weight:500}.fw6-ns{font-weight:600}.fw7-ns{font-weight:700}.fw8-ns{font-weight:800}.fw9-ns{font-weight:900}.h1-ns{height:1rem}.h2-ns{height:2rem}.h3-ns{height:4rem}.h4-ns{height:8rem}.h5-ns{height:16rem}.h-25-ns{height:25%}.h-50-ns{height:50%}.h-75-ns{height:75%}.h-100-ns{height:100%}.min-h-100-ns{min-height:100%}.vh-25-ns{height:25vh}.vh-50-ns{height:50vh}.vh-75-ns{height:75vh}.vh-100-ns{height:100vh}.min-vh-100-ns{min-height:100vh}.h-auto-ns{height:auto}.h-inherit-ns{height:inherit}.tracked-ns{letter-spacing:.1em}.tracked-tight-ns{letter-spacing:-.05em}.tracked-mega-ns{letter-spacing:.25em}.lh-solid-ns{line-height:1}.lh-title-ns{line-height:1.25}.lh-copy-ns{line-height:1.5}.mw-100-ns{max-width:100%}.mw1-ns{max-width:1rem}.mw2-ns{max-width:2rem}.mw3-ns{max-width:4rem}.mw4-ns{max-width:8rem}.mw5-ns{max-width:16rem}.mw6-ns{max-width:32rem}.mw7-ns{max-width:48rem}.mw8-ns{max-width:64rem}.mw9-ns{max-width:96rem}.mw-none-ns{max-width:none}.w1-ns{width:1rem}.w2-ns{width:2rem}.w3-ns{width:4rem}.w4-ns{width:8rem}.w5-ns{width:16rem}.w-10-ns{width:10%}.w-20-ns{width:20%}.w-25-ns{width:25%}.w-30-ns{width:30%}.w-33-ns{width:33%}.w-34-ns{width:34%}.w-40-ns{width:40%}.w-50-ns{width:50%}.w-60-ns{width:60%}.w-70-ns{width:70%}.w-75-ns{width:75%}.w-80-ns{width:80%}.w-90-ns{width:90%}.w-100-ns{width:100%}.w-third-ns{width:33.33333%}.w-two-thirds-ns{width:66.66667%}.w-auto-ns{width:auto}.overflow-visible-ns{overflow:visible}.overflow-hidden-ns{overflow:hidden}.overflow-scroll-ns{overflow:scroll}.overflow-auto-ns{overflow:auto}.overflow-x-visible-ns{overflow-x:visible}.overflow-x-hidden-ns{overflow-x:hidden}.overflow-x-scroll-ns{overflow-x:scroll}.overflow-x-auto-ns{overflow-x:auto}.overflow-y-visible-ns{overflow-y:visible}.overflow-y-hidden-ns{overflow-y:hidden}.overflow-y-scroll-ns{overflow-y:scroll}.overflow-y-auto-ns{overflow-y:auto}.static-ns{position:static}.relative-ns{position:relative}.absolute-ns{position:absolute}.fixed-ns{position:fixed}.rotate-45-ns{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.rotate-90-ns{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.rotate-135-ns{-webkit-transform:rotate(135deg);transform:rotate(135deg)}.rotate-180-ns{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.rotate-225-ns{-webkit-transform:rotate(225deg);transform:rotate(225deg)}.rotate-270-ns{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.rotate-315-ns{-webkit-transform:rotate(315deg);transform:rotate(315deg)}.pa0-ns{padding:0}.pa1-ns{padding:.25rem}.pa2-ns{padding:.5rem}.pa3-ns{padding:1rem}.pa4-ns{padding:2rem}.pa5-ns{padding:4rem}.pa6-ns{padding:8rem}.pa7-ns{padding:16rem}.pl0-ns{padding-left:0}.pl1-ns{padding-left:.25rem}.pl2-ns{padding-left:.5rem}.pl3-ns{padding-left:1rem}.pl4-ns{padding-left:2rem}.pl5-ns{padding-left:4rem}.pl6-ns{padding-left:8rem}.pl7-ns{padding-left:16rem}.pr0-ns{padding-right:0}.pr1-ns{padding-right:.25rem}.pr2-ns{padding-right:.5rem}.pr3-ns{padding-right:1rem}.pr4-ns{padding-right:2rem}.pr5-ns{padding-right:4rem}.pr6-ns{padding-right:8rem}.pr7-ns{padding-right:16rem}.pb0-ns{padding-bottom:0}.pb1-ns{padding-bottom:.25rem}.pb2-ns{padding-bottom:.5rem}.pb3-ns{padding-bottom:1rem}.pb4-ns{padding-bottom:2rem}.pb5-ns{padding-bottom:4rem}.pb6-ns{padding-bottom:8rem}.pb7-ns{padding-bottom:16rem}.pt0-ns{padding-top:0}.pt1-ns{padding-top:.25rem}.pt2-ns{padding-top:.5rem}.pt3-ns{padding-top:1rem}.pt4-ns{padding-top:2rem}.pt5-ns{padding-top:4rem}.pt6-ns{padding-top:8rem}.pt7-ns{padding-top:16rem}.pv0-ns{padding-top:0;padding-bottom:0}.pv1-ns{padding-top:.25rem;padding-bottom:.25rem}.pv2-ns{padding-top:.5rem;padding-bottom:.5rem}.pv3-ns{padding-top:1rem;padding-bottom:1rem}.pv4-ns{padding-top:2rem;padding-bottom:2rem}.pv5-ns{padding-top:4rem;padding-bottom:4rem}.pv6-ns{padding-top:8rem;padding-bottom:8rem}.pv7-ns{padding-top:16rem;padding-bottom:16rem}.ph0-ns{padding-left:0;padding-right:0}.ph1-ns{padding-left:.25rem;padding-right:.25rem}.ph2-ns{padding-left:.5rem;padding-right:.5rem}.ph3-ns{padding-left:1rem;padding-right:1rem}.ph4-ns{padding-left:2rem;padding-right:2rem}.ph5-ns{padding-left:4rem;padding-right:4rem}.ph6-ns{padding-left:8rem;padding-right:8rem}.ph7-ns{padding-left:16rem;padding-right:16rem}.ma0-ns{margin:0}.ma1-ns{margin:.25rem}.ma2-ns{margin:.5rem}.ma3-ns{margin:1rem}.ma4-ns{margin:2rem}.ma5-ns{margin:4rem}.ma6-ns{margin:8rem}.ma7-ns{margin:16rem}.ml0-ns{margin-left:0}.ml1-ns{margin-left:.25rem}.ml2-ns{margin-left:.5rem}.ml3-ns{margin-left:1rem}.ml4-ns{margin-left:2rem}.ml5-ns{margin-left:4rem}.ml6-ns{margin-left:8rem}.ml7-ns{margin-left:16rem}.mr0-ns{margin-right:0}.mr1-ns{margin-right:.25rem}.mr2-ns{margin-right:.5rem}.mr3-ns{margin-right:1rem}.mr4-ns{margin-right:2rem}.mr5-ns{margin-right:4rem}.mr6-ns{margin-right:8rem}.mr7-ns{margin-right:16rem}.mb0-ns{margin-bottom:0}.mb1-ns{margin-bottom:.25rem}.mb2-ns{margin-bottom:.5rem}.mb3-ns{margin-bottom:1rem}.mb4-ns{margin-bottom:2rem}.mb5-ns{margin-bottom:4rem}.mb6-ns{margin-bottom:8rem}.mb7-ns{margin-bottom:16rem}.mt0-ns{margin-top:0}.mt1-ns{margin-top:.25rem}.mt2-ns{margin-top:.5rem}.mt3-ns{margin-top:1rem}.mt4-ns{margin-top:2rem}.mt5-ns{margin-top:4rem}.mt6-ns{margin-top:8rem}.mt7-ns{margin-top:16rem}.mv0-ns{margin-top:0;margin-bottom:0}.mv1-ns{margin-top:.25rem;margin-bottom:.25rem}.mv2-ns{margin-top:.5rem;margin-bottom:.5rem}.mv3-ns{margin-top:1rem;margin-bottom:1rem}.mv4-ns{margin-top:2rem;margin-bottom:2rem}.mv5-ns{margin-top:4rem;margin-bottom:4rem}.mv6-ns{margin-top:8rem;margin-bottom:8rem}.mv7-ns{margin-top:16rem;margin-bottom:16rem}.mh0-ns{margin-left:0;margin-right:0}.mh1-ns{margin-left:.25rem;margin-right:.25rem}.mh2-ns{margin-left:.5rem;margin-right:.5rem}.mh3-ns{margin-left:1rem;margin-right:1rem}.mh4-ns{margin-left:2rem;margin-right:2rem}.mh5-ns{margin-left:4rem;margin-right:4rem}.mh6-ns{margin-left:8rem;margin-right:8rem}.mh7-ns{margin-left:16rem;margin-right:16rem}.na1-ns{margin:-.25rem}.na2-ns{margin:-.5rem}.na3-ns{margin:-1rem}.na4-ns{margin:-2rem}.na5-ns{margin:-4rem}.na6-ns{margin:-8rem}.na7-ns{margin:-16rem}.nl1-ns{margin-left:-.25rem}.nl2-ns{margin-left:-.5rem}.nl3-ns{margin-left:-1rem}.nl4-ns{margin-left:-2rem}.nl5-ns{margin-left:-4rem}.nl6-ns{margin-left:-8rem}.nl7-ns{margin-left:-16rem}.nr1-ns{margin-right:-.25rem}.nr2-ns{margin-right:-.5rem}.nr3-ns{margin-right:-1rem}.nr4-ns{margin-right:-2rem}.nr5-ns{margin-right:-4rem}.nr6-ns{margin-right:-8rem}.nr7-ns{margin-right:-16rem}.nb1-ns{margin-bottom:-.25rem}.nb2-ns{margin-bottom:-.5rem}.nb3-ns{margin-bottom:-1rem}.nb4-ns{margin-bottom:-2rem}.nb5-ns{margin-bottom:-4rem}.nb6-ns{margin-bottom:-8rem}.nb7-ns{margin-bottom:-16rem}.nt1-ns{margin-top:-.25rem}.nt2-ns{margin-top:-.5rem}.nt3-ns{margin-top:-1rem}.nt4-ns{margin-top:-2rem}.nt5-ns{margin-top:-4rem}.nt6-ns{margin-top:-8rem}.nt7-ns{margin-top:-16rem}.strike-ns{text-decoration:line-through}.underline-ns{text-decoration:underline}.no-underline-ns{text-decoration:none}.tl-ns{text-align:left}.tr-ns{text-align:right}.tc-ns{text-align:center}.tj-ns{text-align:justify}.ttc-ns{text-transform:capitalize}.ttl-ns{text-transform:lowercase}.ttu-ns{text-transform:uppercase}.ttn-ns{text-transform:none}.f-6-ns,.f-headline-ns{font-size:6rem}.f-5-ns,.f-subheadline-ns{font-size:5rem}.f1-ns{font-size:3rem}.f2-ns{font-size:2.25rem}.f3-ns{font-size:1.5rem}.f4-ns{font-size:1.25rem}.f5-ns{font-size:1rem}.f6-ns{font-size:.875rem}.f7-ns{font-size:.75rem}.measure-ns{max-width:30em}.measure-wide-ns{max-width:34em}.measure-narrow-ns{max-width:20em}.indent-ns{text-indent:1em;margin-top:0;margin-bottom:0}.small-caps-ns{font-variant:small-caps}.truncate-ns{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.center-ns{margin-left:auto}.center-ns,.mr-auto-ns{margin-right:auto}.ml-auto-ns{margin-left:auto}.clip-ns{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}.ws-normal-ns{white-space:normal}.nowrap-ns{white-space:nowrap}.pre-ns{white-space:pre}.v-base-ns{vertical-align:baseline}.v-mid-ns{vertical-align:middle}.v-top-ns{vertical-align:top}.v-btm-ns{vertical-align:bottom}}@media screen and (min-width:30em) and (max-width:60em){.aspect-ratio-m{height:0;position:relative}.aspect-ratio--16x9-m{padding-bottom:56.25%}.aspect-ratio--9x16-m{padding-bottom:177.77%}.aspect-ratio--4x3-m{padding-bottom:75%}.aspect-ratio--3x4-m{padding-bottom:133.33%}.aspect-ratio--6x4-m{padding-bottom:66.6%}.aspect-ratio--4x6-m{padding-bottom:150%}.aspect-ratio--8x5-m{padding-bottom:62.5%}.aspect-ratio--5x8-m{padding-bottom:160%}.aspect-ratio--7x5-m{padding-bottom:71.42%}.aspect-ratio--5x7-m{padding-bottom:140%}.aspect-ratio--1x1-m{padding-bottom:100%}.aspect-ratio--object-m{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}.cover-m{background-size:cover!important}.contain-m{background-size:contain!important}.bg-center-m{background-position:50%}.bg-center-m,.bg-top-m{background-repeat:no-repeat}.bg-top-m{background-position:top}.bg-right-m{background-position:100%}.bg-bottom-m,.bg-right-m{background-repeat:no-repeat}.bg-bottom-m{background-position:bottom}.bg-left-m{background-repeat:no-repeat;background-position:0}.outline-m{outline:1px solid}.outline-transparent-m{outline:1px solid transparent}.outline-0-m{outline:0}.ba-m{border-style:solid;border-width:1px}.bt-m{border-top-style:solid;border-top-width:1px}.br-m{border-right-style:solid;border-right-width:1px}.bb-m{border-bottom-style:solid;border-bottom-width:1px}.bl-m{border-left-style:solid;border-left-width:1px}.bn-m{border-style:none;border-width:0}.br0-m{border-radius:0}.br1-m{border-radius:.125rem}.br2-m{border-radius:.25rem}.br3-m{border-radius:.5rem}.br4-m{border-radius:1rem}.br-100-m{border-radius:100%}.br-pill-m{border-radius:9999px}.br--bottom-m{border-top-left-radius:0;border-top-right-radius:0}.br--top-m{border-bottom-right-radius:0}.br--right-m,.br--top-m{border-bottom-left-radius:0}.br--right-m{border-top-left-radius:0}.br--left-m{border-top-right-radius:0;border-bottom-right-radius:0}.br-inherit-m{border-radius:inherit}.br-initial-m{border-radius:initial}.br-unset-m{border-radius:unset}.b--dotted-m{border-style:dotted}.b--dashed-m{border-style:dashed}.b--solid-m{border-style:solid}.b--none-m{border-style:none}.bw0-m{border-width:0}.bw1-m{border-width:.125rem}.bw2-m{border-width:.25rem}.bw3-m{border-width:.5rem}.bw4-m{border-width:1rem}.bw5-m{border-width:2rem}.bt-0-m{border-top-width:0}.br-0-m{border-right-width:0}.bb-0-m{border-bottom-width:0}.bl-0-m{border-left-width:0}.shadow-1-m{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.shadow-2-m{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.shadow-3-m{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.shadow-4-m{box-shadow:2px 2px 8px rgba(0,0,0,.2)}.shadow-5-m{box-shadow:4px 4px 8px rgba(0,0,0,.2)}.top-0-m{top:0}.left-0-m{left:0}.right-0-m{right:0}.bottom-0-m{bottom:0}.top-1-m{top:1rem}.left-1-m{left:1rem}.right-1-m{right:1rem}.bottom-1-m{bottom:1rem}.top-2-m{top:2rem}.left-2-m{left:2rem}.right-2-m{right:2rem}.bottom-2-m{bottom:2rem}.top--1-m{top:-1rem}.right--1-m{right:-1rem}.bottom--1-m{bottom:-1rem}.left--1-m{left:-1rem}.top--2-m{top:-2rem}.right--2-m{right:-2rem}.bottom--2-m{bottom:-2rem}.left--2-m{left:-2rem}.absolute--fill-m{top:0;right:0;bottom:0;left:0}.cl-m{clear:left}.cr-m{clear:right}.cb-m{clear:both}.cn-m{clear:none}.dn-m{display:none}.di-m{display:inline}.db-m{display:block}.dib-m{display:inline-block}.dit-m{display:inline-table}.dt-m{display:table}.dtc-m{display:table-cell}.dt-row-m{display:table-row}.dt-row-group-m{display:table-row-group}.dt-column-m{display:table-column}.dt-column-group-m{display:table-column-group}.dt--fixed-m{table-layout:fixed;width:100%}.flex-m{display:flex}.inline-flex-m{display:inline-flex}.flex-auto-m{flex:auto;min-width:0;min-height:0}.flex-none-m{flex:none}.flex-column-m{flex-direction:column}.flex-row-m{flex-direction:row}.flex-wrap-m{flex-wrap:wrap}.flex-nowrap-m{flex-wrap:nowrap}.flex-wrap-reverse-m{flex-wrap:wrap-reverse}.flex-column-reverse-m{flex-direction:column-reverse}.flex-row-reverse-m{flex-direction:row-reverse}.items-start-m{align-items:flex-start}.items-end-m{align-items:flex-end}.items-center-m{align-items:center}.items-baseline-m{align-items:baseline}.items-stretch-m{align-items:stretch}.self-start-m{align-self:flex-start}.self-end-m{align-self:flex-end}.self-center-m{align-self:center}.self-baseline-m{align-self:baseline}.self-stretch-m{align-self:stretch}.justify-start-m{justify-content:flex-start}.justify-end-m{justify-content:flex-end}.justify-center-m{justify-content:center}.justify-between-m{justify-content:space-between}.justify-around-m{justify-content:space-around}.content-start-m{align-content:flex-start}.content-end-m{align-content:flex-end}.content-center-m{align-content:center}.content-between-m{align-content:space-between}.content-around-m{align-content:space-around}.content-stretch-m{align-content:stretch}.order-0-m{order:0}.order-1-m{order:1}.order-2-m{order:2}.order-3-m{order:3}.order-4-m{order:4}.order-5-m{order:5}.order-6-m{order:6}.order-7-m{order:7}.order-8-m{order:8}.order-last-m{order:99999}.flex-grow-0-m{flex-grow:0}.flex-grow-1-m{flex-grow:1}.flex-shrink-0-m{flex-shrink:0}.flex-shrink-1-m{flex-shrink:1}.fl-m{float:left}.fl-m,.fr-m{_display:inline}.fr-m{float:right}.fn-m{float:none}.i-m{font-style:italic}.fs-normal-m{font-style:normal}.normal-m{font-weight:400}.b-m{font-weight:700}.fw1-m{font-weight:100}.fw2-m{font-weight:200}.fw3-m{font-weight:300}.fw4-m{font-weight:400}.fw5-m{font-weight:500}.fw6-m{font-weight:600}.fw7-m{font-weight:700}.fw8-m{font-weight:800}.fw9-m{font-weight:900}.h1-m{height:1rem}.h2-m{height:2rem}.h3-m{height:4rem}.h4-m{height:8rem}.h5-m{height:16rem}.h-25-m{height:25%}.h-50-m{height:50%}.h-75-m{height:75%}.h-100-m{height:100%}.min-h-100-m{min-height:100%}.vh-25-m{height:25vh}.vh-50-m{height:50vh}.vh-75-m{height:75vh}.vh-100-m{height:100vh}.min-vh-100-m{min-height:100vh}.h-auto-m{height:auto}.h-inherit-m{height:inherit}.tracked-m{letter-spacing:.1em}.tracked-tight-m{letter-spacing:-.05em}.tracked-mega-m{letter-spacing:.25em}.lh-solid-m{line-height:1}.lh-title-m{line-height:1.25}.lh-copy-m{line-height:1.5}.mw-100-m{max-width:100%}.mw1-m{max-width:1rem}.mw2-m{max-width:2rem}.mw3-m{max-width:4rem}.mw4-m{max-width:8rem}.mw5-m{max-width:16rem}.mw6-m{max-width:32rem}.mw7-m{max-width:48rem}.mw8-m{max-width:64rem}.mw9-m{max-width:96rem}.mw-none-m{max-width:none}.w1-m{width:1rem}.w2-m{width:2rem}.w3-m{width:4rem}.w4-m{width:8rem}.w5-m{width:16rem}.w-10-m{width:10%}.w-20-m{width:20%}.w-25-m{width:25%}.w-30-m{width:30%}.w-33-m{width:33%}.w-34-m{width:34%}.w-40-m{width:40%}.w-50-m{width:50%}.w-60-m{width:60%}.w-70-m{width:70%}.w-75-m{width:75%}.w-80-m{width:80%}.w-90-m{width:90%}.w-100-m{width:100%}.w-third-m{width:33.33333%}.w-two-thirds-m{width:66.66667%}.w-auto-m{width:auto}.overflow-visible-m{overflow:visible}.overflow-hidden-m{overflow:hidden}.overflow-scroll-m{overflow:scroll}.overflow-auto-m{overflow:auto}.overflow-x-visible-m{overflow-x:visible}.overflow-x-hidden-m{overflow-x:hidden}.overflow-x-scroll-m{overflow-x:scroll}.overflow-x-auto-m{overflow-x:auto}.overflow-y-visible-m{overflow-y:visible}.overflow-y-hidden-m{overflow-y:hidden}.overflow-y-scroll-m{overflow-y:scroll}.overflow-y-auto-m{overflow-y:auto}.static-m{position:static}.relative-m{position:relative}.absolute-m{position:absolute}.fixed-m{position:fixed}.rotate-45-m{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.rotate-90-m{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.rotate-135-m{-webkit-transform:rotate(135deg);transform:rotate(135deg)}.rotate-180-m{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.rotate-225-m{-webkit-transform:rotate(225deg);transform:rotate(225deg)}.rotate-270-m{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.rotate-315-m{-webkit-transform:rotate(315deg);transform:rotate(315deg)}.pa0-m{padding:0}.pa1-m{padding:.25rem}.pa2-m{padding:.5rem}.pa3-m{padding:1rem}.pa4-m{padding:2rem}.pa5-m{padding:4rem}.pa6-m{padding:8rem}.pa7-m{padding:16rem}.pl0-m{padding-left:0}.pl1-m{padding-left:.25rem}.pl2-m{padding-left:.5rem}.pl3-m{padding-left:1rem}.pl4-m{padding-left:2rem}.pl5-m{padding-left:4rem}.pl6-m{padding-left:8rem}.pl7-m{padding-left:16rem}.pr0-m{padding-right:0}.pr1-m{padding-right:.25rem}.pr2-m{padding-right:.5rem}.pr3-m{padding-right:1rem}.pr4-m{padding-right:2rem}.pr5-m{padding-right:4rem}.pr6-m{padding-right:8rem}.pr7-m{padding-right:16rem}.pb0-m{padding-bottom:0}.pb1-m{padding-bottom:.25rem}.pb2-m{padding-bottom:.5rem}.pb3-m{padding-bottom:1rem}.pb4-m{padding-bottom:2rem}.pb5-m{padding-bottom:4rem}.pb6-m{padding-bottom:8rem}.pb7-m{padding-bottom:16rem}.pt0-m{padding-top:0}.pt1-m{padding-top:.25rem}.pt2-m{padding-top:.5rem}.pt3-m{padding-top:1rem}.pt4-m{padding-top:2rem}.pt5-m{padding-top:4rem}.pt6-m{padding-top:8rem}.pt7-m{padding-top:16rem}.pv0-m{padding-top:0;padding-bottom:0}.pv1-m{padding-top:.25rem;padding-bottom:.25rem}.pv2-m{padding-top:.5rem;padding-bottom:.5rem}.pv3-m{padding-top:1rem;padding-bottom:1rem}.pv4-m{padding-top:2rem;padding-bottom:2rem}.pv5-m{padding-top:4rem;padding-bottom:4rem}.pv6-m{padding-top:8rem;padding-bottom:8rem}.pv7-m{padding-top:16rem;padding-bottom:16rem}.ph0-m{padding-left:0;padding-right:0}.ph1-m{padding-left:.25rem;padding-right:.25rem}.ph2-m{padding-left:.5rem;padding-right:.5rem}.ph3-m{padding-left:1rem;padding-right:1rem}.ph4-m{padding-left:2rem;padding-right:2rem}.ph5-m{padding-left:4rem;padding-right:4rem}.ph6-m{padding-left:8rem;padding-right:8rem}.ph7-m{padding-left:16rem;padding-right:16rem}.ma0-m{margin:0}.ma1-m{margin:.25rem}.ma2-m{margin:.5rem}.ma3-m{margin:1rem}.ma4-m{margin:2rem}.ma5-m{margin:4rem}.ma6-m{margin:8rem}.ma7-m{margin:16rem}.ml0-m{margin-left:0}.ml1-m{margin-left:.25rem}.ml2-m{margin-left:.5rem}.ml3-m{margin-left:1rem}.ml4-m{margin-left:2rem}.ml5-m{margin-left:4rem}.ml6-m{margin-left:8rem}.ml7-m{margin-left:16rem}.mr0-m{margin-right:0}.mr1-m{margin-right:.25rem}.mr2-m{margin-right:.5rem}.mr3-m{margin-right:1rem}.mr4-m{margin-right:2rem}.mr5-m{margin-right:4rem}.mr6-m{margin-right:8rem}.mr7-m{margin-right:16rem}.mb0-m{margin-bottom:0}.mb1-m{margin-bottom:.25rem}.mb2-m{margin-bottom:.5rem}.mb3-m{margin-bottom:1rem}.mb4-m{margin-bottom:2rem}.mb5-m{margin-bottom:4rem}.mb6-m{margin-bottom:8rem}.mb7-m{margin-bottom:16rem}.mt0-m{margin-top:0}.mt1-m{margin-top:.25rem}.mt2-m{margin-top:.5rem}.mt3-m{margin-top:1rem}.mt4-m{margin-top:2rem}.mt5-m{margin-top:4rem}.mt6-m{margin-top:8rem}.mt7-m{margin-top:16rem}.mv0-m{margin-top:0;margin-bottom:0}.mv1-m{margin-top:.25rem;margin-bottom:.25rem}.mv2-m{margin-top:.5rem;margin-bottom:.5rem}.mv3-m{margin-top:1rem;margin-bottom:1rem}.mv4-m{margin-top:2rem;margin-bottom:2rem}.mv5-m{margin-top:4rem;margin-bottom:4rem}.mv6-m{margin-top:8rem;margin-bottom:8rem}.mv7-m{margin-top:16rem;margin-bottom:16rem}.mh0-m{margin-left:0;margin-right:0}.mh1-m{margin-left:.25rem;margin-right:.25rem}.mh2-m{margin-left:.5rem;margin-right:.5rem}.mh3-m{margin-left:1rem;margin-right:1rem}.mh4-m{margin-left:2rem;margin-right:2rem}.mh5-m{margin-left:4rem;margin-right:4rem}.mh6-m{margin-left:8rem;margin-right:8rem}.mh7-m{margin-left:16rem;margin-right:16rem}.na1-m{margin:-.25rem}.na2-m{margin:-.5rem}.na3-m{margin:-1rem}.na4-m{margin:-2rem}.na5-m{margin:-4rem}.na6-m{margin:-8rem}.na7-m{margin:-16rem}.nl1-m{margin-left:-.25rem}.nl2-m{margin-left:-.5rem}.nl3-m{margin-left:-1rem}.nl4-m{margin-left:-2rem}.nl5-m{margin-left:-4rem}.nl6-m{margin-left:-8rem}.nl7-m{margin-left:-16rem}.nr1-m{margin-right:-.25rem}.nr2-m{margin-right:-.5rem}.nr3-m{margin-right:-1rem}.nr4-m{margin-right:-2rem}.nr5-m{margin-right:-4rem}.nr6-m{margin-right:-8rem}.nr7-m{margin-right:-16rem}.nb1-m{margin-bottom:-.25rem}.nb2-m{margin-bottom:-.5rem}.nb3-m{margin-bottom:-1rem}.nb4-m{margin-bottom:-2rem}.nb5-m{margin-bottom:-4rem}.nb6-m{margin-bottom:-8rem}.nb7-m{margin-bottom:-16rem}.nt1-m{margin-top:-.25rem}.nt2-m{margin-top:-.5rem}.nt3-m{margin-top:-1rem}.nt4-m{margin-top:-2rem}.nt5-m{margin-top:-4rem}.nt6-m{margin-top:-8rem}.nt7-m{margin-top:-16rem}.strike-m{text-decoration:line-through}.underline-m{text-decoration:underline}.no-underline-m{text-decoration:none}.tl-m{text-align:left}.tr-m{text-align:right}.tc-m{text-align:center}.tj-m{text-align:justify}.ttc-m{text-transform:capitalize}.ttl-m{text-transform:lowercase}.ttu-m{text-transform:uppercase}.ttn-m{text-transform:none}.f-6-m,.f-headline-m{font-size:6rem}.f-5-m,.f-subheadline-m{font-size:5rem}.f1-m{font-size:3rem}.f2-m{font-size:2.25rem}.f3-m{font-size:1.5rem}.f4-m{font-size:1.25rem}.f5-m{font-size:1rem}.f6-m{font-size:.875rem}.f7-m{font-size:.75rem}.measure-m{max-width:30em}.measure-wide-m{max-width:34em}.measure-narrow-m{max-width:20em}.indent-m{text-indent:1em;margin-top:0;margin-bottom:0}.small-caps-m{font-variant:small-caps}.truncate-m{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.center-m{margin-left:auto}.center-m,.mr-auto-m{margin-right:auto}.ml-auto-m{margin-left:auto}.clip-m{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}.ws-normal-m{white-space:normal}.nowrap-m{white-space:nowrap}.pre-m{white-space:pre}.v-base-m{vertical-align:baseline}.v-mid-m{vertical-align:middle}.v-top-m{vertical-align:top}.v-btm-m{vertical-align:bottom}}@media screen and (min-width:60em){.aspect-ratio-l{height:0;position:relative}.aspect-ratio--16x9-l{padding-bottom:56.25%}.aspect-ratio--9x16-l{padding-bottom:177.77%}.aspect-ratio--4x3-l{padding-bottom:75%}.aspect-ratio--3x4-l{padding-bottom:133.33%}.aspect-ratio--6x4-l{padding-bottom:66.6%}.aspect-ratio--4x6-l{padding-bottom:150%}.aspect-ratio--8x5-l{padding-bottom:62.5%}.aspect-ratio--5x8-l{padding-bottom:160%}.aspect-ratio--7x5-l{padding-bottom:71.42%}.aspect-ratio--5x7-l{padding-bottom:140%}.aspect-ratio--1x1-l{padding-bottom:100%}.aspect-ratio--object-l{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}.cover-l{background-size:cover!important}.contain-l{background-size:contain!important}.bg-center-l{background-position:50%}.bg-center-l,.bg-top-l{background-repeat:no-repeat}.bg-top-l{background-position:top}.bg-right-l{background-position:100%}.bg-bottom-l,.bg-right-l{background-repeat:no-repeat}.bg-bottom-l{background-position:bottom}.bg-left-l{background-repeat:no-repeat;background-position:0}.outline-l{outline:1px solid}.outline-transparent-l{outline:1px solid transparent}.outline-0-l{outline:0}.ba-l{border-style:solid;border-width:1px}.bt-l{border-top-style:solid;border-top-width:1px}.br-l{border-right-style:solid;border-right-width:1px}.bb-l{border-bottom-style:solid;border-bottom-width:1px}.bl-l{border-left-style:solid;border-left-width:1px}.bn-l{border-style:none;border-width:0}.br0-l{border-radius:0}.br1-l{border-radius:.125rem}.br2-l{border-radius:.25rem}.br3-l{border-radius:.5rem}.br4-l{border-radius:1rem}.br-100-l{border-radius:100%}.br-pill-l{border-radius:9999px}.br--bottom-l{border-top-left-radius:0;border-top-right-radius:0}.br--top-l{border-bottom-right-radius:0}.br--right-l,.br--top-l{border-bottom-left-radius:0}.br--right-l{border-top-left-radius:0}.br--left-l{border-top-right-radius:0;border-bottom-right-radius:0}.br-inherit-l{border-radius:inherit}.br-initial-l{border-radius:initial}.br-unset-l{border-radius:unset}.b--dotted-l{border-style:dotted}.b--dashed-l{border-style:dashed}.b--solid-l{border-style:solid}.b--none-l{border-style:none}.bw0-l{border-width:0}.bw1-l{border-width:.125rem}.bw2-l{border-width:.25rem}.bw3-l{border-width:.5rem}.bw4-l{border-width:1rem}.bw5-l{border-width:2rem}.bt-0-l{border-top-width:0}.br-0-l{border-right-width:0}.bb-0-l{border-bottom-width:0}.bl-0-l{border-left-width:0}.shadow-1-l{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.shadow-2-l{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.shadow-3-l{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.shadow-4-l{box-shadow:2px 2px 8px rgba(0,0,0,.2)}.shadow-5-l{box-shadow:4px 4px 8px rgba(0,0,0,.2)}.top-0-l{top:0}.left-0-l{left:0}.right-0-l{right:0}.bottom-0-l{bottom:0}.top-1-l{top:1rem}.left-1-l{left:1rem}.right-1-l{right:1rem}.bottom-1-l{bottom:1rem}.top-2-l{top:2rem}.left-2-l{left:2rem}.right-2-l{right:2rem}.bottom-2-l{bottom:2rem}.top--1-l{top:-1rem}.right--1-l{right:-1rem}.bottom--1-l{bottom:-1rem}.left--1-l{left:-1rem}.top--2-l{top:-2rem}.right--2-l{right:-2rem}.bottom--2-l{bottom:-2rem}.left--2-l{left:-2rem}.absolute--fill-l{top:0;right:0;bottom:0;left:0}.cl-l{clear:left}.cr-l{clear:right}.cb-l{clear:both}.cn-l{clear:none}.dn-l{display:none}.di-l{display:inline}.db-l{display:block}.dib-l{display:inline-block}.dit-l{display:inline-table}.dt-l{display:table}.dtc-l{display:table-cell}.dt-row-l{display:table-row}.dt-row-group-l{display:table-row-group}.dt-column-l{display:table-column}.dt-column-group-l{display:table-column-group}.dt--fixed-l{table-layout:fixed;width:100%}.flex-l{display:flex}.inline-flex-l{display:inline-flex}.flex-auto-l{flex:auto;min-width:0;min-height:0}.flex-none-l{flex:none}.flex-column-l{flex-direction:column}.flex-row-l{flex-direction:row}.flex-wrap-l{flex-wrap:wrap}.flex-nowrap-l{flex-wrap:nowrap}.flex-wrap-reverse-l{flex-wrap:wrap-reverse}.flex-column-reverse-l{flex-direction:column-reverse}.flex-row-reverse-l{flex-direction:row-reverse}.items-start-l{align-items:flex-start}.items-end-l{align-items:flex-end}.items-center-l{align-items:center}.items-baseline-l{align-items:baseline}.items-stretch-l{align-items:stretch}.self-start-l{align-self:flex-start}.self-end-l{align-self:flex-end}.self-center-l{align-self:center}.self-baseline-l{align-self:baseline}.self-stretch-l{align-self:stretch}.justify-start-l{justify-content:flex-start}.justify-end-l{justify-content:flex-end}.justify-center-l{justify-content:center}.justify-between-l{justify-content:space-between}.justify-around-l{justify-content:space-around}.content-start-l{align-content:flex-start}.content-end-l{align-content:flex-end}.content-center-l{align-content:center}.content-between-l{align-content:space-between}.content-around-l{align-content:space-around}.content-stretch-l{align-content:stretch}.order-0-l{order:0}.order-1-l{order:1}.order-2-l{order:2}.order-3-l{order:3}.order-4-l{order:4}.order-5-l{order:5}.order-6-l{order:6}.order-7-l{order:7}.order-8-l{order:8}.order-last-l{order:99999}.flex-grow-0-l{flex-grow:0}.flex-grow-1-l{flex-grow:1}.flex-shrink-0-l{flex-shrink:0}.flex-shrink-1-l{flex-shrink:1}.fl-l{float:left}.fl-l,.fr-l{_display:inline}.fr-l{float:right}.fn-l{float:none}.i-l{font-style:italic}.fs-normal-l{font-style:normal}.normal-l{font-weight:400}.b-l{font-weight:700}.fw1-l{font-weight:100}.fw2-l{font-weight:200}.fw3-l{font-weight:300}.fw4-l{font-weight:400}.fw5-l{font-weight:500}.fw6-l{font-weight:600}.fw7-l{font-weight:700}.fw8-l{font-weight:800}.fw9-l{font-weight:900}.h1-l{height:1rem}.h2-l{height:2rem}.h3-l{height:4rem}.h4-l{height:8rem}.h5-l{height:16rem}.h-25-l{height:25%}.h-50-l{height:50%}.h-75-l{height:75%}.h-100-l{height:100%}.min-h-100-l{min-height:100%}.vh-25-l{height:25vh}.vh-50-l{height:50vh}.vh-75-l{height:75vh}.vh-100-l{height:100vh}.min-vh-100-l{min-height:100vh}.h-auto-l{height:auto}.h-inherit-l{height:inherit}.tracked-l{letter-spacing:.1em}.tracked-tight-l{letter-spacing:-.05em}.tracked-mega-l{letter-spacing:.25em}.lh-solid-l{line-height:1}.lh-title-l{line-height:1.25}.lh-copy-l{line-height:1.5}.mw-100-l{max-width:100%}.mw1-l{max-width:1rem}.mw2-l{max-width:2rem}.mw3-l{max-width:4rem}.mw4-l{max-width:8rem}.mw5-l{max-width:16rem}.mw6-l{max-width:32rem}.mw7-l{max-width:48rem}.mw8-l{max-width:64rem}.mw9-l{max-width:96rem}.mw-none-l{max-width:none}.w1-l{width:1rem}.w2-l{width:2rem}.w3-l{width:4rem}.w4-l{width:8rem}.w5-l{width:16rem}.w-10-l{width:10%}.w-20-l{width:20%}.w-25-l{width:25%}.w-30-l{width:30%}.w-33-l{width:33%}.w-34-l{width:34%}.w-40-l{width:40%}.w-50-l{width:50%}.w-60-l{width:60%}.w-70-l{width:70%}.w-75-l{width:75%}.w-80-l{width:80%}.w-90-l{width:90%}.w-100-l{width:100%}.w-third-l{width:33.33333%}.w-two-thirds-l{width:66.66667%}.w-auto-l{width:auto}.overflow-visible-l{overflow:visible}.overflow-hidden-l{overflow:hidden}.overflow-scroll-l{overflow:scroll}.overflow-auto-l{overflow:auto}.overflow-x-visible-l{overflow-x:visible}.overflow-x-hidden-l{overflow-x:hidden}.overflow-x-scroll-l{overflow-x:scroll}.overflow-x-auto-l{overflow-x:auto}.overflow-y-visible-l{overflow-y:visible}.overflow-y-hidden-l{overflow-y:hidden}.overflow-y-scroll-l{overflow-y:scroll}.overflow-y-auto-l{overflow-y:auto}.static-l{position:static}.relative-l{position:relative}.absolute-l{position:absolute}.fixed-l{position:fixed}.rotate-45-l{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.rotate-90-l{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.rotate-135-l{-webkit-transform:rotate(135deg);transform:rotate(135deg)}.rotate-180-l{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.rotate-225-l{-webkit-transform:rotate(225deg);transform:rotate(225deg)}.rotate-270-l{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.rotate-315-l{-webkit-transform:rotate(315deg);transform:rotate(315deg)}.pa0-l{padding:0}.pa1-l{padding:.25rem}.pa2-l{padding:.5rem}.pa3-l{padding:1rem}.pa4-l{padding:2rem}.pa5-l{padding:4rem}.pa6-l{padding:8rem}.pa7-l{padding:16rem}.pl0-l{padding-left:0}.pl1-l{padding-left:.25rem}.pl2-l{padding-left:.5rem}.pl3-l{padding-left:1rem}.pl4-l{padding-left:2rem}.pl5-l{padding-left:4rem}.pl6-l{padding-left:8rem}.pl7-l{padding-left:16rem}.pr0-l{padding-right:0}.pr1-l{padding-right:.25rem}.pr2-l{padding-right:.5rem}.pr3-l{padding-right:1rem}.pr4-l{padding-right:2rem}.pr5-l{padding-right:4rem}.pr6-l{padding-right:8rem}.pr7-l{padding-right:16rem}.pb0-l{padding-bottom:0}.pb1-l{padding-bottom:.25rem}.pb2-l{padding-bottom:.5rem}.pb3-l{padding-bottom:1rem}.pb4-l{padding-bottom:2rem}.pb5-l{padding-bottom:4rem}.pb6-l{padding-bottom:8rem}.pb7-l{padding-bottom:16rem}.pt0-l{padding-top:0}.pt1-l{padding-top:.25rem}.pt2-l{padding-top:.5rem}.pt3-l{padding-top:1rem}.pt4-l{padding-top:2rem}.pt5-l{padding-top:4rem}.pt6-l{padding-top:8rem}.pt7-l{padding-top:16rem}.pv0-l{padding-top:0;padding-bottom:0}.pv1-l{padding-top:.25rem;padding-bottom:.25rem}.pv2-l{padding-top:.5rem;padding-bottom:.5rem}.pv3-l{padding-top:1rem;padding-bottom:1rem}.pv4-l{padding-top:2rem;padding-bottom:2rem}.pv5-l{padding-top:4rem;padding-bottom:4rem}.pv6-l{padding-top:8rem;padding-bottom:8rem}.pv7-l{padding-top:16rem;padding-bottom:16rem}.ph0-l{padding-left:0;padding-right:0}.ph1-l{padding-left:.25rem;padding-right:.25rem}.ph2-l{padding-left:.5rem;padding-right:.5rem}.ph3-l{padding-left:1rem;padding-right:1rem}.ph4-l{padding-left:2rem;padding-right:2rem}.ph5-l{padding-left:4rem;padding-right:4rem}.ph6-l{padding-left:8rem;padding-right:8rem}.ph7-l{padding-left:16rem;padding-right:16rem}.ma0-l{margin:0}.ma1-l{margin:.25rem}.ma2-l{margin:.5rem}.ma3-l{margin:1rem}.ma4-l{margin:2rem}.ma5-l{margin:4rem}.ma6-l{margin:8rem}.ma7-l{margin:16rem}.ml0-l{margin-left:0}.ml1-l{margin-left:.25rem}.ml2-l{margin-left:.5rem}.ml3-l{margin-left:1rem}.ml4-l{margin-left:2rem}.ml5-l{margin-left:4rem}.ml6-l{margin-left:8rem}.ml7-l{margin-left:16rem}.mr0-l{margin-right:0}.mr1-l{margin-right:.25rem}.mr2-l{margin-right:.5rem}.mr3-l{margin-right:1rem}.mr4-l{margin-right:2rem}.mr5-l{margin-right:4rem}.mr6-l{margin-right:8rem}.mr7-l{margin-right:16rem}.mb0-l{margin-bottom:0}.mb1-l{margin-bottom:.25rem}.mb2-l{margin-bottom:.5rem}.mb3-l{margin-bottom:1rem}.mb4-l{margin-bottom:2rem}.mb5-l{margin-bottom:4rem}.mb6-l{margin-bottom:8rem}.mb7-l{margin-bottom:16rem}.mt0-l{margin-top:0}.mt1-l{margin-top:.25rem}.mt2-l{margin-top:.5rem}.mt3-l{margin-top:1rem}.mt4-l{margin-top:2rem}.mt5-l{margin-top:4rem}.mt6-l{margin-top:8rem}.mt7-l{margin-top:16rem}.mv0-l{margin-top:0;margin-bottom:0}.mv1-l{margin-top:.25rem;margin-bottom:.25rem}.mv2-l{margin-top:.5rem;margin-bottom:.5rem}.mv3-l{margin-top:1rem;margin-bottom:1rem}.mv4-l{margin-top:2rem;margin-bottom:2rem}.mv5-l{margin-top:4rem;margin-bottom:4rem}.mv6-l{margin-top:8rem;margin-bottom:8rem}.mv7-l{margin-top:16rem;margin-bottom:16rem}.mh0-l{margin-left:0;margin-right:0}.mh1-l{margin-left:.25rem;margin-right:.25rem}.mh2-l{margin-left:.5rem;margin-right:.5rem}.mh3-l{margin-left:1rem;margin-right:1rem}.mh4-l{margin-left:2rem;margin-right:2rem}.mh5-l{margin-left:4rem;margin-right:4rem}.mh6-l{margin-left:8rem;margin-right:8rem}.mh7-l{margin-left:16rem;margin-right:16rem}.na1-l{margin:-.25rem}.na2-l{margin:-.5rem}.na3-l{margin:-1rem}.na4-l{margin:-2rem}.na5-l{margin:-4rem}.na6-l{margin:-8rem}.na7-l{margin:-16rem}.nl1-l{margin-left:-.25rem}.nl2-l{margin-left:-.5rem}.nl3-l{margin-left:-1rem}.nl4-l{margin-left:-2rem}.nl5-l{margin-left:-4rem}.nl6-l{margin-left:-8rem}.nl7-l{margin-left:-16rem}.nr1-l{margin-right:-.25rem}.nr2-l{margin-right:-.5rem}.nr3-l{margin-right:-1rem}.nr4-l{margin-right:-2rem}.nr5-l{margin-right:-4rem}.nr6-l{margin-right:-8rem}.nr7-l{margin-right:-16rem}.nb1-l{margin-bottom:-.25rem}.nb2-l{margin-bottom:-.5rem}.nb3-l{margin-bottom:-1rem}.nb4-l{margin-bottom:-2rem}.nb5-l{margin-bottom:-4rem}.nb6-l{margin-bottom:-8rem}.nb7-l{margin-bottom:-16rem}.nt1-l{margin-top:-.25rem}.nt2-l{margin-top:-.5rem}.nt3-l{margin-top:-1rem}.nt4-l{margin-top:-2rem}.nt5-l{margin-top:-4rem}.nt6-l{margin-top:-8rem}.nt7-l{margin-top:-16rem}.strike-l{text-decoration:line-through}.underline-l{text-decoration:underline}.no-underline-l{text-decoration:none}.tl-l{text-align:left}.tr-l{text-align:right}.tc-l{text-align:center}.tj-l{text-align:justify}.ttc-l{text-transform:capitalize}.ttl-l{text-transform:lowercase}.ttu-l{text-transform:uppercase}.ttn-l{text-transform:none}.f-6-l,.f-headline-l{font-size:6rem}.f-5-l,.f-subheadline-l{font-size:5rem}.f1-l{font-size:3rem}.f2-l{font-size:2.25rem}.f3-l{font-size:1.5rem}.f4-l{font-size:1.25rem}.f5-l{font-size:1rem}.f6-l{font-size:.875rem}.f7-l{font-size:.75rem}.measure-l{max-width:30em}.measure-wide-l{max-width:34em}.measure-narrow-l{max-width:20em}.indent-l{text-indent:1em;margin-top:0;margin-bottom:0}.small-caps-l{font-variant:small-caps}.truncate-l{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.center-l{margin-left:auto}.center-l,.mr-auto-l{margin-right:auto}.ml-auto-l{margin-left:auto}.clip-l{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}.ws-normal-l{white-space:normal}.nowrap-l{white-space:nowrap}.pre-l{white-space:pre}.v-base-l{vertical-align:baseline}.v-mid-l{vertical-align:middle}.v-top-l{vertical-align:top}.v-btm-l{vertical-align:bottom}}pre,.pre{overflow-x:auto;overflow-y:hidden;overflow:scroll}pre code{display:block;padding:1.5em;white-space:pre;font-size:.875rem;line-height:2}pre{background-color:#222;color:#ddd;white-space:pre;hyphens:none;position:relative}.pagination{margin:3rem 0}.pagination li{display:inline-block;margin-right:.375rem;font-size:.875rem;margin-bottom:2.5em}[dir=rtl] .pagination li{margin-left:.375rem;margin-right:0}.pagination li a{padding:.5rem .625rem;background-color:#fff;color:#333;border:1px solid #ddd;border-radius:3px;text-decoration:none}.pagination li.disabled{display:none}.pagination li.active a,.pagination li.active a:link,.pagination li.active a:active,.pagination li.active a:visited{background-color:#ddd}#TableOfContents ul li{margin-bottom:1em}.ananke-socials a{display:inline-block;vertical-align:middle;color:#bababa;fill:currentColor}.ananke-socials a .icon svg{width:32px;height:32px}.ananke-socials a:hover{color:#6b7280}.new-window{opacity:0;display:inline-block;vertical-align:top}.link-transition:hover .new-window{opacity:1}#TableOfContents ul li{margin-bottom:1em}.lh-copy blockquote{display:block;font-size:.875em;margin-left:2rem;margin-top:2rem;margin-bottom:2rem;border-left:4px solid #ccc;padding-left:1rem}.nested-links a{overflow-wrap:break-word}.ananke-socials a.twitter:hover{color:#1da1f2}
\ No newline at end of file
diff --git a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/resources/_gen/assets/css/ananke/css/main.css_83735de7ca999e9c17f3419b41b93fdb.json b/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/resources/_gen/assets/css/ananke/css/main.css_83735de7ca999e9c17f3419b41b93fdb.json
deleted file mode 100644
index f3d1135..0000000
--- a/core/installer/welcome/app-tmpl/hugo-latest/themes/ananke/resources/_gen/assets/css/ananke/css/main.css_83735de7ca999e9c17f3419b41b93fdb.json
+++ /dev/null
@@ -1 +0,0 @@
-{"Target":"ananke/css/main.min.css","MediaType":"text/css","Data":{}}
\ No newline at end of file
diff --git a/core/installer/welcome/stat/launcher.js b/core/installer/welcome/stat/launcher.js
deleted file mode 100644
index ab34e4c..0000000
--- a/core/installer/welcome/stat/launcher.js
+++ /dev/null
@@ -1,259 +0,0 @@
-function showTooltip(obj) {
- obj.style.visibility = 'visible';
- obj.style.opacity = '1';
-}
-function hideTooltip(obj) {
- obj.style.visibility = 'hidden';
- obj.style.opacity = '0';
-}
-
-document.addEventListener("DOMContentLoaded", function () {
- document.getElementById('appFrame-default').contentDocument.write("Welcome to the dodo: application launcher, think of it as your desktop environment. You can launch applications from left-hand side dock. You should setup VPN clients on your devices, so you can install applications from Application Manager and access your private network. Instructions on how to do that can be viewed by clicking <b>Help</b> button after hovering over <b>Headscale</b> icon in the dock.");
- document.getElementById('appFrame-default').style.backgroundColor = '#d6d6d6';
- initDock();
- setTimeout(reloadDock, 5000);
-});
-
-function copyToClipboard(elem, text) {
- navigator.clipboard.writeText(text);
- elem.setAttribute("data-tooltip", "Copied");
- elem.setAttribute("data-placement", "bottom");
- setTimeout(() => {
- elem.removeAttribute("data-tooltip");
- elem.removeAttribute("data-placement");
- }, 500);
-};
-
-function reloadDock() {
- fetch("/")
- .then((resp) => {
- if (resp.ok) {
- return resp.text();
- } else {
- return undefined;
- }
- })
- .then((resp) => {
- if (!resp) {
- return;
- }
- const tmp = document.createElement("div");
- tmp.innerHTML = resp;
- const apps = document.querySelector(".app-list");
- let existing = [...document.querySelectorAll(".app-container")];
- let current = [...tmp.querySelectorAll(".app-container")];
- const getId = (e) => e.getAttribute("id");
- const existingIds = existing.map(getId);
- const currentIds = current.map(getId);
- existing.forEach((e) => {
- const id = getId(e);
- if (!currentIds.includes(id)) {
- e.classList.add("fadeout");
- setTimeout(() => apps.removeChild(e), 1900);
- }
- });
- let prevId = undefined;
- current.forEach((c) => {
- const id = getId(c);
- if (existingIds.includes(id)) {
- prevId = id;
- return;
- }
- c.classList.add("pulsate");
- if (prevId) {
- apps.insertBefore(c, document.getElementById(prevId).nextSibling);
- } else {
- apps.insertBefore(c, apps.firstChild);
- }
- prevId = id;
- });
- initDock();
- })
- .finally(() => setTimeout(reloadDock, 5000));
-}
-
-function initDock() {
- const icons = document.querySelectorAll(".app-icon");
- const circle = document.querySelector(".user-circle");
- const tooltipUser = document.querySelector("#tooltip-user");
- const initial = document.getElementById('user-initial');
-
- circle.addEventListener('mouseenter', () => {
- icons.forEach(icon => {
- const tooltip = icon.nextElementSibling;
- hideTooltip(tooltip);
- });
- showTooltip(tooltipUser);
- initial.style.color = "#7f9f7f";
- });
-
- circle.addEventListener('mouseleave', () => {
- hideTooltip(tooltipUser);
- initial.style.color = "#d4888d";
- });
-
- let hideTimeout;
- let activeTooltip;
-
- icons.forEach(function (icon) {
- if (activeAppId && icon.getAttribute("data-app-id") === activeAppId) {
- icon.style.color = "var(--button)";
- }
- icon.addEventListener("click", function (event) {
- event.stopPropagation();
- const appUrl = this.getAttribute("data-app-url");
- const appId = this.getAttribute("data-app-id");
- const modalId = this.getAttribute("data-modal-id");
-
- if (!appUrl && modalId) {
- openModal(document.getElementById(modalId));
- } else {
- if (!iframes[appId]) {
- createIframe(appId, appUrl);
- }
- activeAppId = appId;
- showIframe(appId);
- document.querySelectorAll(".app-icon").forEach((icon) => {
- icon.style.color = "var(--bodyBg)";
- });
- this.style.color = "var(--button)";
- };
- });
-
- const tooltip = icon.nextElementSibling;
- [
- ['mouseenter', () => {
- clearTimeout(hideTimeout);
- if (activeTooltip && activeTooltip !== tooltip) {
- hideTooltip(activeTooltip);
- };
- const rect = icon.getBoundingClientRect();
- tooltip.style.top = `${rect.top + 26}px`;
- showTooltip(tooltip);
- activeTooltip = tooltip;
- }],
- ['mouseleave', () => {
- hideTimeout = setTimeout(() => {
- hideTooltip(tooltip);
- if (activeTooltip === tooltip) {
- activeTooltip = null;
- };
- }, 200);
- }],
- ].forEach(([event, listener]) => {
- icon.addEventListener(event, listener);
- });
-
- tooltip.addEventListener('mouseenter', () => {
- clearTimeout(hideTimeout);
- });
-
- tooltip.addEventListener('mouseleave', () => {
- hideTimeout = setTimeout(() => {
- hideTooltip(tooltip);
- if (activeTooltip === tooltip) {
- activeTooltip = null;
- };
- }, 200);
- });
- });
-
- let visibleModal = undefined;
- const openModal = function (modal) {
- modal.removeAttribute("close");
- modal.setAttribute("open", true);
- visibleModal = modal;
- };
-
- const closeModal = function (modal) {
- modal.removeAttribute("open");
- modal.setAttribute("close", true);
- visibleModal = undefined;
- };
-
- const helpButtons = document.querySelectorAll('.help-button');
-
- helpButtons.forEach(function (button) {
- button.addEventListener('click', function (event) {
- event.stopPropagation();
- const buttonId = button.getAttribute('id');
- const modalId = 'modal-' + buttonId.substring("help-button-".length);
- const closeHelpId = "close-help-" + buttonId.substring("help-button-".length);
- const modal = document.getElementById(modalId);
- openModal(modal);
- const closeHelpButton = document.getElementById(closeHelpId);
- closeHelpButton.addEventListener('click', function (event) {
- event.stopPropagation();
- closeModal(modal);
- });
- });
- });
-
- const modalHelpButtons = document.querySelectorAll('.title-menu');
-
- modalHelpButtons.forEach(function (button) {
- button.addEventListener('click', function (event) {
- event.stopPropagation();
- const helpTitle = button.getAttribute('id');
- const helpTitleId = helpTitle.substring('title-'.length);
- const helpContentId = 'help-content-' + helpTitleId;
- let clDiv = document.getElementById(helpContentId).parentNode;
- const allContentElements = clDiv.querySelectorAll('.help-content');
-
- allContentElements.forEach(function (contentElement) {
- contentElement.style.display = "none";
- });
-
- let currentHelpTitle = button;
- while (currentHelpTitle && !currentHelpTitle.classList.contains('modal-left')) {
- currentHelpTitle = currentHelpTitle.parentNode;
- if (currentHelpTitle === document.body) {
- currentHelpTitle = null;
- break;
- }
- }
-
- currentHelpTitle.querySelectorAll('.title-menu').forEach(function (button) {
- button.removeAttribute("aria-current");
- });
-
- document.getElementById(helpContentId).style.display = 'block';
- button.setAttribute("aria-current", "page");
- });
- });
-
- document.addEventListener("keydown", (event) => {
- if (event.key === "Escape" && visibleModal) {
- closeModal(visibleModal);
- }
- });
-
- document.addEventListener("click", (event) => {
- if (visibleModal === null || visibleModal === undefined) return;
- const modalContent = visibleModal.querySelector("article");
- const closeButton = visibleModal.querySelector(".close-button");
- if (!modalContent.contains(event.target) || closeButton.contains(event.target)) {
- closeModal(visibleModal);
- }
- });
-}
-
-let activeAppId = undefined;
-const iframes = {};
-const rightPanel = document.getElementById('right-panel');
-
-function showIframe(appId) {
- document.querySelectorAll('.appFrame').forEach(iframe => {
- iframe.style.display = iframe.id === `appFrame-${appId}` ? 'block' : 'none';
- });
-};
-
-function createIframe(appId, appUrl) {
- const iframe = document.createElement('iframe');
- iframe.id = `appFrame-${appId}`;
- iframe.className = 'appFrame';
- iframe.src = appUrl;
- iframe.style.display = 'none';
- rightPanel.appendChild(iframe);
- iframes[appId] = iframe;
-};
diff --git a/core/installer/welcome/stat/main.css b/core/installer/welcome/stat/main.css
deleted file mode 100644
index 7c9f8f5..0000000
--- a/core/installer/welcome/stat/main.css
+++ /dev/null
@@ -1,127 +0,0 @@
-[data-theme="light"],
-:root:not([data-theme="dark"]) {
- --pico-font-family: Hack, monospace;
- --pico-font-size: 14px;
- --pico-background-color: #d6d6d6;
- --pico-border-radius: 0;
- --pico-form-element-border-color: #ffffff;
- --pico-form-element-active-border-color: #7f9f7f;
- --pico-primary: #7f9f7f;
- --pico-primary-background: #7f9f7f;
- --pico-primary-hover: #d4888d;
- --pico-primary-hover-background: #d4888d;
- --pico-grid-spacing-horizontal: 0;
-}
-
-input[type="checkbox"] {
- --pico-form-element-border-color: #3a3a3a;
-}
-
-main.container {
- max-width: 850px;
- margin-top: 13rem;
-}
-
-.dodo {
- font-size: 1.6rem;
- font-weight: bold;
- background-color: #3a3a3a;
- border-left: 1px dashed #3a3a3a;
-}
-
-.highlight{
- color: #d4888d;
-}
-
-#menu {
- border-bottom: 1px dashed #3a3a3a;
- padding-left: 5rem;
- padding-right: 5rem;
-}
-
-#menu a {
- /* font-size: 1.2rem; */
- color: #3a3a3a;
-}
-
-#menu li {
- padding-top: 0;
- padding-bottom: 0;
-}
-
-#links {
- --pico-nav-element-spacing-horizontal: 3rem;
-}
-
-#menu li {
- border-right: 1px dashed #3a3a3a;
-}
-
-div.contents-header {
- font-size: 1.2rem;
- border-width: 1px;
- border-style: solid;
-}
-
-#contents {
- border-width: 1px;
- border-style: none solid solid solid;
-}
-
-main > div.grid {
- --pico-grid-column-gap: 0;
-}
-
-div.contents-header > div {
- padding: 1rem 3rem;
-}
-
-#contents > div {
- padding: 3rem;
-}
-
-#create-instance-form {
- --pico-spacing: 10px;
- /* TODO(gio): figure out why overriding --pico-background-color does not work */
- background-color: #3a3a3a;
-}
-
-#create-instance-form label {
- color: #ffffff;
-}
-
-#create-instance-form input, textarea, button, select {
- border-width: 0.5px !important;
- background-color: #3a3a3a;
-}
-
-#create-instance-form p {
- color: #ffffff;
-}
-
-#create-instance-form input {
- height: 3rem;
- color: #ffffff;
-}
-
-#create-instance-form textarea {
- color: #ffffff;
-}
-
-#create-instance-form button {
- width: fit-content;
- font-weight: bold;
- color: #3a3a3a;
-}
-
-.progress {
- padding-left: 0;
-}
-
-.progress ul {
- padding-left: 15px;
-}
-
-.progress li {
- list-style-type: none;
-}
diff --git a/core/installer/welcome/stat/pico.2.0.6.min.css b/core/installer/welcome/stat/pico.2.0.6.min.css
deleted file mode 100644
index 5928ed7..0000000
--- a/core/installer/welcome/stat/pico.2.0.6.min.css
+++ /dev/null
@@ -1,4 +0,0 @@
-@charset "UTF-8";/*!
- * Pico CSS ✨ v2.0.6 (https://picocss.com)
- * Copyright 2019-2024 - Licensed under MIT
- */:root{--pico-font-family-emoji:"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--pico-font-family-sans-serif:system-ui,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,Helvetica,Arial,"Helvetica Neue",sans-serif,var(--pico-font-family-emoji);--pico-font-family-monospace:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace,var(--pico-font-family-emoji);--pico-font-family:var(--pico-font-family-sans-serif);--pico-line-height:1.5;--pico-font-weight:400;--pico-font-size:100%;--pico-text-underline-offset:0.1rem;--pico-border-radius:0.25rem;--pico-border-width:0.0625rem;--pico-outline-width:0.125rem;--pico-transition:0.2s ease-in-out;--pico-spacing:1rem;--pico-typography-spacing-vertical:1rem;--pico-block-spacing-vertical:var(--pico-spacing);--pico-block-spacing-horizontal:var(--pico-spacing);--pico-grid-column-gap:var(--pico-spacing);--pico-grid-row-gap:var(--pico-spacing);--pico-form-element-spacing-vertical:0.75rem;--pico-form-element-spacing-horizontal:1rem;--pico-group-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-group-box-shadow-focus-with-button:0 0 0 var(--pico-outline-width) var(--pico-primary-focus);--pico-group-box-shadow-focus-with-input:0 0 0 0.0625rem var(--pico-form-element-border-color);--pico-modal-overlay-backdrop-filter:blur(0.375rem);--pico-nav-element-spacing-vertical:1rem;--pico-nav-element-spacing-horizontal:0.5rem;--pico-nav-link-spacing-vertical:0.5rem;--pico-nav-link-spacing-horizontal:0.5rem;--pico-nav-breadcrumb-divider:">";--pico-icon-checkbox:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");--pico-icon-minus:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'%3E%3C/line%3E%3C/svg%3E");--pico-icon-chevron:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");--pico-icon-date:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E");--pico-icon-time:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpolyline points='12 6 12 12 16 14'%3E%3C/polyline%3E%3C/svg%3E");--pico-icon-search:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E");--pico-icon-close:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E");--pico-icon-loading:url("data:image/svg+xml,%3Csvg fill='none' height='24' width='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' %3E%3Cstyle%3E g %7B animation: rotate 2s linear infinite; transform-origin: center center; %7D circle %7B stroke-dasharray: 75,100; stroke-dashoffset: -5; animation: dash 1.5s ease-in-out infinite; stroke-linecap: round; %7D @keyframes rotate %7B 0%25 %7B transform: rotate(0deg); %7D 100%25 %7B transform: rotate(360deg); %7D %7D @keyframes dash %7B 0%25 %7B stroke-dasharray: 1,100; stroke-dashoffset: 0; %7D 50%25 %7B stroke-dasharray: 44.5,100; stroke-dashoffset: -17.5; %7D 100%25 %7B stroke-dasharray: 44.5,100; stroke-dashoffset: -62; %7D %7D %3C/style%3E%3Cg%3E%3Ccircle cx='12' cy='12' r='10' fill='none' stroke='rgb(136, 145, 164)' stroke-width='4' /%3E%3C/g%3E%3C/svg%3E")}@media (min-width:576px){:root{--pico-font-size:106.25%}}@media (min-width:768px){:root{--pico-font-size:112.5%}}@media (min-width:1024px){:root{--pico-font-size:118.75%}}@media (min-width:1280px){:root{--pico-font-size:125%}}@media (min-width:1536px){:root{--pico-font-size:131.25%}}a{--pico-text-decoration:underline}a.contrast,a.secondary{--pico-text-decoration:underline}small{--pico-font-size:0.875em}h1,h2,h3,h4,h5,h6{--pico-font-weight:700}h1{--pico-font-size:2rem;--pico-line-height:1.125;--pico-typography-spacing-top:3rem}h2{--pico-font-size:1.75rem;--pico-line-height:1.15;--pico-typography-spacing-top:2.625rem}h3{--pico-font-size:1.5rem;--pico-line-height:1.175;--pico-typography-spacing-top:2.25rem}h4{--pico-font-size:1.25rem;--pico-line-height:1.2;--pico-typography-spacing-top:1.874rem}h5{--pico-font-size:1.125rem;--pico-line-height:1.225;--pico-typography-spacing-top:1.6875rem}h6{--pico-font-size:1rem;--pico-line-height:1.25;--pico-typography-spacing-top:1.5rem}tfoot td,tfoot th,thead td,thead th{--pico-font-weight:600;--pico-border-width:0.1875rem}code,kbd,pre,samp{--pico-font-family:var(--pico-font-family-monospace)}kbd{--pico-font-weight:bolder}:where(select,textarea),input:not([type=submit],[type=button],[type=reset],[type=checkbox],[type=radio],[type=file]){--pico-outline-width:0.0625rem}[type=search]{--pico-border-radius:5rem}[type=checkbox],[type=radio]{--pico-border-width:0.125rem}[type=checkbox][role=switch]{--pico-border-width:0.1875rem}details.dropdown summary:not([role=button]){--pico-outline-width:0.0625rem}nav details.dropdown summary:focus-visible{--pico-outline-width:0.125rem}[role=search]{--pico-border-radius:5rem}[role=group]:has(button.secondary:focus,[type=submit].secondary:focus,[type=button].secondary:focus,[role=button].secondary:focus),[role=search]:has(button.secondary:focus,[type=submit].secondary:focus,[type=button].secondary:focus,[role=button].secondary:focus){--pico-group-box-shadow-focus-with-button:0 0 0 var(--pico-outline-width) var(--pico-secondary-focus)}[role=group]:has(button.contrast:focus,[type=submit].contrast:focus,[type=button].contrast:focus,[role=button].contrast:focus),[role=search]:has(button.contrast:focus,[type=submit].contrast:focus,[type=button].contrast:focus,[role=button].contrast:focus){--pico-group-box-shadow-focus-with-button:0 0 0 var(--pico-outline-width) var(--pico-contrast-focus)}[role=group] [role=button],[role=group] [type=button],[role=group] [type=submit],[role=group] button,[role=search] [role=button],[role=search] [type=button],[role=search] [type=submit],[role=search] button{--pico-form-element-spacing-horizontal:2rem}details summary[role=button]:not(.outline)::after{filter:brightness(0) invert(1)}[aria-busy=true]:not(input,select,textarea):is(button,[type=submit],[type=button],[type=reset],[role=button]):not(.outline)::before{filter:brightness(0) invert(1)}:root:not([data-theme=dark]),[data-theme=light]{--pico-background-color:#fff;--pico-color:#373c44;--pico-text-selection-color:rgba(2, 154, 232, 0.25);--pico-muted-color:#646b79;--pico-muted-border-color:#e7eaf0;--pico-primary:#0172ad;--pico-primary-background:#0172ad;--pico-primary-border:var(--pico-primary-background);--pico-primary-underline:rgba(1, 114, 173, 0.5);--pico-primary-hover:#015887;--pico-primary-hover-background:#02659a;--pico-primary-hover-border:var(--pico-primary-hover-background);--pico-primary-hover-underline:var(--pico-primary-hover);--pico-primary-focus:rgba(2, 154, 232, 0.5);--pico-primary-inverse:#fff;--pico-secondary:#5d6b89;--pico-secondary-background:#525f7a;--pico-secondary-border:var(--pico-secondary-background);--pico-secondary-underline:rgba(93, 107, 137, 0.5);--pico-secondary-hover:#48536b;--pico-secondary-hover-background:#48536b;--pico-secondary-hover-border:var(--pico-secondary-hover-background);--pico-secondary-hover-underline:var(--pico-secondary-hover);--pico-secondary-focus:rgba(93, 107, 137, 0.25);--pico-secondary-inverse:#fff;--pico-contrast:#181c25;--pico-contrast-background:#181c25;--pico-contrast-border:var(--pico-contrast-background);--pico-contrast-underline:rgba(24, 28, 37, 0.5);--pico-contrast-hover:#000;--pico-contrast-hover-background:#000;--pico-contrast-hover-border:var(--pico-contrast-hover-background);--pico-contrast-hover-underline:var(--pico-secondary-hover);--pico-contrast-focus:rgba(93, 107, 137, 0.25);--pico-contrast-inverse:#fff;--pico-box-shadow:0.0145rem 0.029rem 0.174rem rgba(129, 145, 181, 0.01698),0.0335rem 0.067rem 0.402rem rgba(129, 145, 181, 0.024),0.0625rem 0.125rem 0.75rem rgba(129, 145, 181, 0.03),0.1125rem 0.225rem 1.35rem rgba(129, 145, 181, 0.036),0.2085rem 0.417rem 2.502rem rgba(129, 145, 181, 0.04302),0.5rem 1rem 6rem rgba(129, 145, 181, 0.06),0 0 0 0.0625rem rgba(129, 145, 181, 0.015);--pico-h1-color:#2d3138;--pico-h2-color:#373c44;--pico-h3-color:#424751;--pico-h4-color:#4d535e;--pico-h5-color:#5c6370;--pico-h6-color:#646b79;--pico-mark-background-color:#fde7c0;--pico-mark-color:#0f1114;--pico-ins-color:#1d6a54;--pico-del-color:#883935;--pico-blockquote-border-color:var(--pico-muted-border-color);--pico-blockquote-footer-color:var(--pico-muted-color);--pico-button-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-button-hover-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-table-border-color:var(--pico-muted-border-color);--pico-table-row-stripped-background-color:rgba(111, 120, 135, 0.0375);--pico-code-background-color:#f3f5f7;--pico-code-color:#646b79;--pico-code-kbd-background-color:var(--pico-color);--pico-code-kbd-color:var(--pico-background-color);--pico-form-element-background-color:#fbfcfc;--pico-form-element-selected-background-color:#dfe3eb;--pico-form-element-border-color:#cfd5e2;--pico-form-element-color:#23262c;--pico-form-element-placeholder-color:var(--pico-muted-color);--pico-form-element-active-background-color:#fff;--pico-form-element-active-border-color:var(--pico-primary-border);--pico-form-element-focus-color:var(--pico-primary-border);--pico-form-element-disabled-opacity:0.5;--pico-form-element-invalid-border-color:#b86a6b;--pico-form-element-invalid-active-border-color:#c84f48;--pico-form-element-invalid-focus-color:var(--pico-form-element-invalid-active-border-color);--pico-form-element-valid-border-color:#4c9b8a;--pico-form-element-valid-active-border-color:#279977;--pico-form-element-valid-focus-color:var(--pico-form-element-valid-active-border-color);--pico-switch-background-color:#bfc7d9;--pico-switch-checked-background-color:var(--pico-primary-background);--pico-switch-color:#fff;--pico-switch-thumb-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-range-border-color:#dfe3eb;--pico-range-active-border-color:#bfc7d9;--pico-range-thumb-border-color:var(--pico-background-color);--pico-range-thumb-color:var(--pico-secondary-background);--pico-range-thumb-active-color:var(--pico-primary-background);--pico-accordion-border-color:var(--pico-muted-border-color);--pico-accordion-active-summary-color:var(--pico-primary-hover);--pico-accordion-close-summary-color:var(--pico-color);--pico-accordion-open-summary-color:var(--pico-muted-color);--pico-card-background-color:var(--pico-background-color);--pico-card-border-color:var(--pico-muted-border-color);--pico-card-box-shadow:var(--pico-box-shadow);--pico-card-sectioning-background-color:#fbfcfc;--pico-dropdown-background-color:#fff;--pico-dropdown-border-color:#eff1f4;--pico-dropdown-box-shadow:var(--pico-box-shadow);--pico-dropdown-color:var(--pico-color);--pico-dropdown-hover-background-color:#eff1f4;--pico-loading-spinner-opacity:0.5;--pico-modal-overlay-background-color:rgba(232, 234, 237, 0.75);--pico-progress-background-color:#dfe3eb;--pico-progress-color:var(--pico-primary-background);--pico-tooltip-background-color:var(--pico-contrast-background);--pico-tooltip-color:var(--pico-contrast-inverse);--pico-icon-valid:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(76, 155, 138)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");--pico-icon-invalid:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(200, 79, 72)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E");color-scheme:light}:root:not([data-theme=dark]) input:is([type=submit],[type=button],[type=reset],[type=checkbox],[type=radio],[type=file]),[data-theme=light] input:is([type=submit],[type=button],[type=reset],[type=checkbox],[type=radio],[type=file]){--pico-form-element-focus-color:var(--pico-primary-focus)}@media only screen and (prefers-color-scheme:dark){:root:not([data-theme]){--pico-background-color:#13171f;--pico-color:#c2c7d0;--pico-text-selection-color:rgba(1, 170, 255, 0.1875);--pico-muted-color:#7b8495;--pico-muted-border-color:#202632;--pico-primary:#01aaff;--pico-primary-background:#0172ad;--pico-primary-border:var(--pico-primary-background);--pico-primary-underline:rgba(1, 170, 255, 0.5);--pico-primary-hover:#79c0ff;--pico-primary-hover-background:#017fc0;--pico-primary-hover-border:var(--pico-primary-hover-background);--pico-primary-hover-underline:var(--pico-primary-hover);--pico-primary-focus:rgba(1, 170, 255, 0.375);--pico-primary-inverse:#fff;--pico-secondary:#969eaf;--pico-secondary-background:#525f7a;--pico-secondary-border:var(--pico-secondary-background);--pico-secondary-underline:rgba(150, 158, 175, 0.5);--pico-secondary-hover:#b3b9c5;--pico-secondary-hover-background:#5d6b89;--pico-secondary-hover-border:var(--pico-secondary-hover-background);--pico-secondary-hover-underline:var(--pico-secondary-hover);--pico-secondary-focus:rgba(144, 158, 190, 0.25);--pico-secondary-inverse:#fff;--pico-contrast:#dfe3eb;--pico-contrast-background:#eff1f4;--pico-contrast-border:var(--pico-contrast-background);--pico-contrast-underline:rgba(223, 227, 235, 0.5);--pico-contrast-hover:#fff;--pico-contrast-hover-background:#fff;--pico-contrast-hover-border:var(--pico-contrast-hover-background);--pico-contrast-hover-underline:var(--pico-contrast-hover);--pico-contrast-focus:rgba(207, 213, 226, 0.25);--pico-contrast-inverse:#000;--pico-box-shadow:0.0145rem 0.029rem 0.174rem rgba(7, 9, 12, 0.01698),0.0335rem 0.067rem 0.402rem rgba(7, 9, 12, 0.024),0.0625rem 0.125rem 0.75rem rgba(7, 9, 12, 0.03),0.1125rem 0.225rem 1.35rem rgba(7, 9, 12, 0.036),0.2085rem 0.417rem 2.502rem rgba(7, 9, 12, 0.04302),0.5rem 1rem 6rem rgba(7, 9, 12, 0.06),0 0 0 0.0625rem rgba(7, 9, 12, 0.015);--pico-h1-color:#f0f1f3;--pico-h2-color:#e0e3e7;--pico-h3-color:#c2c7d0;--pico-h4-color:#b3b9c5;--pico-h5-color:#a4acba;--pico-h6-color:#8891a4;--pico-mark-background-color:#014063;--pico-mark-color:#fff;--pico-ins-color:#62af9a;--pico-del-color:#ce7e7b;--pico-blockquote-border-color:var(--pico-muted-border-color);--pico-blockquote-footer-color:var(--pico-muted-color);--pico-button-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-button-hover-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-table-border-color:var(--pico-muted-border-color);--pico-table-row-stripped-background-color:rgba(111, 120, 135, 0.0375);--pico-code-background-color:#1a1f28;--pico-code-color:#8891a4;--pico-code-kbd-background-color:var(--pico-color);--pico-code-kbd-color:var(--pico-background-color);--pico-form-element-background-color:#1c212c;--pico-form-element-selected-background-color:#2a3140;--pico-form-element-border-color:#2a3140;--pico-form-element-color:#e0e3e7;--pico-form-element-placeholder-color:#8891a4;--pico-form-element-active-background-color:#1a1f28;--pico-form-element-active-border-color:var(--pico-primary-border);--pico-form-element-focus-color:var(--pico-primary-border);--pico-form-element-disabled-opacity:0.5;--pico-form-element-invalid-border-color:#964a50;--pico-form-element-invalid-active-border-color:#b7403b;--pico-form-element-invalid-focus-color:var(--pico-form-element-invalid-active-border-color);--pico-form-element-valid-border-color:#2a7b6f;--pico-form-element-valid-active-border-color:#16896a;--pico-form-element-valid-focus-color:var(--pico-form-element-valid-active-border-color);--pico-switch-background-color:#333c4e;--pico-switch-checked-background-color:var(--pico-primary-background);--pico-switch-color:#fff;--pico-switch-thumb-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-range-border-color:#202632;--pico-range-active-border-color:#2a3140;--pico-range-thumb-border-color:var(--pico-background-color);--pico-range-thumb-color:var(--pico-secondary-background);--pico-range-thumb-active-color:var(--pico-primary-background);--pico-accordion-border-color:var(--pico-muted-border-color);--pico-accordion-active-summary-color:var(--pico-primary-hover);--pico-accordion-close-summary-color:var(--pico-color);--pico-accordion-open-summary-color:var(--pico-muted-color);--pico-card-background-color:#181c25;--pico-card-border-color:var(--pico-card-background-color);--pico-card-box-shadow:var(--pico-box-shadow);--pico-card-sectioning-background-color:#1a1f28;--pico-dropdown-background-color:#181c25;--pico-dropdown-border-color:#202632;--pico-dropdown-box-shadow:var(--pico-box-shadow);--pico-dropdown-color:var(--pico-color);--pico-dropdown-hover-background-color:#202632;--pico-loading-spinner-opacity:0.5;--pico-modal-overlay-background-color:rgba(8, 9, 10, 0.75);--pico-progress-background-color:#202632;--pico-progress-color:var(--pico-primary-background);--pico-tooltip-background-color:var(--pico-contrast-background);--pico-tooltip-color:var(--pico-contrast-inverse);--pico-icon-valid:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(42, 123, 111)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");--pico-icon-invalid:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(150, 74, 80)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E");color-scheme:dark}:root:not([data-theme]) input:is([type=submit],[type=button],[type=reset],[type=checkbox],[type=radio],[type=file]){--pico-form-element-focus-color:var(--pico-primary-focus)}:root:not([data-theme]) details summary[role=button].contrast:not(.outline)::after{filter:brightness(0)}:root:not([data-theme]) [aria-busy=true]:not(input,select,textarea).contrast:is(button,[type=submit],[type=button],[type=reset],[role=button]):not(.outline)::before{filter:brightness(0)}}[data-theme=dark]{--pico-background-color:#13171f;--pico-color:#c2c7d0;--pico-text-selection-color:rgba(1, 170, 255, 0.1875);--pico-muted-color:#7b8495;--pico-muted-border-color:#202632;--pico-primary:#01aaff;--pico-primary-background:#0172ad;--pico-primary-border:var(--pico-primary-background);--pico-primary-underline:rgba(1, 170, 255, 0.5);--pico-primary-hover:#79c0ff;--pico-primary-hover-background:#017fc0;--pico-primary-hover-border:var(--pico-primary-hover-background);--pico-primary-hover-underline:var(--pico-primary-hover);--pico-primary-focus:rgba(1, 170, 255, 0.375);--pico-primary-inverse:#fff;--pico-secondary:#969eaf;--pico-secondary-background:#525f7a;--pico-secondary-border:var(--pico-secondary-background);--pico-secondary-underline:rgba(150, 158, 175, 0.5);--pico-secondary-hover:#b3b9c5;--pico-secondary-hover-background:#5d6b89;--pico-secondary-hover-border:var(--pico-secondary-hover-background);--pico-secondary-hover-underline:var(--pico-secondary-hover);--pico-secondary-focus:rgba(144, 158, 190, 0.25);--pico-secondary-inverse:#fff;--pico-contrast:#dfe3eb;--pico-contrast-background:#eff1f4;--pico-contrast-border:var(--pico-contrast-background);--pico-contrast-underline:rgba(223, 227, 235, 0.5);--pico-contrast-hover:#fff;--pico-contrast-hover-background:#fff;--pico-contrast-hover-border:var(--pico-contrast-hover-background);--pico-contrast-hover-underline:var(--pico-contrast-hover);--pico-contrast-focus:rgba(207, 213, 226, 0.25);--pico-contrast-inverse:#000;--pico-box-shadow:0.0145rem 0.029rem 0.174rem rgba(7, 9, 12, 0.01698),0.0335rem 0.067rem 0.402rem rgba(7, 9, 12, 0.024),0.0625rem 0.125rem 0.75rem rgba(7, 9, 12, 0.03),0.1125rem 0.225rem 1.35rem rgba(7, 9, 12, 0.036),0.2085rem 0.417rem 2.502rem rgba(7, 9, 12, 0.04302),0.5rem 1rem 6rem rgba(7, 9, 12, 0.06),0 0 0 0.0625rem rgba(7, 9, 12, 0.015);--pico-h1-color:#f0f1f3;--pico-h2-color:#e0e3e7;--pico-h3-color:#c2c7d0;--pico-h4-color:#b3b9c5;--pico-h5-color:#a4acba;--pico-h6-color:#8891a4;--pico-mark-background-color:#014063;--pico-mark-color:#fff;--pico-ins-color:#62af9a;--pico-del-color:#ce7e7b;--pico-blockquote-border-color:var(--pico-muted-border-color);--pico-blockquote-footer-color:var(--pico-muted-color);--pico-button-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-button-hover-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-table-border-color:var(--pico-muted-border-color);--pico-table-row-stripped-background-color:rgba(111, 120, 135, 0.0375);--pico-code-background-color:#1a1f28;--pico-code-color:#8891a4;--pico-code-kbd-background-color:var(--pico-color);--pico-code-kbd-color:var(--pico-background-color);--pico-form-element-background-color:#1c212c;--pico-form-element-selected-background-color:#2a3140;--pico-form-element-border-color:#2a3140;--pico-form-element-color:#e0e3e7;--pico-form-element-placeholder-color:#8891a4;--pico-form-element-active-background-color:#1a1f28;--pico-form-element-active-border-color:var(--pico-primary-border);--pico-form-element-focus-color:var(--pico-primary-border);--pico-form-element-disabled-opacity:0.5;--pico-form-element-invalid-border-color:#964a50;--pico-form-element-invalid-active-border-color:#b7403b;--pico-form-element-invalid-focus-color:var(--pico-form-element-invalid-active-border-color);--pico-form-element-valid-border-color:#2a7b6f;--pico-form-element-valid-active-border-color:#16896a;--pico-form-element-valid-focus-color:var(--pico-form-element-valid-active-border-color);--pico-switch-background-color:#333c4e;--pico-switch-checked-background-color:var(--pico-primary-background);--pico-switch-color:#fff;--pico-switch-thumb-box-shadow:0 0 0 rgba(0, 0, 0, 0);--pico-range-border-color:#202632;--pico-range-active-border-color:#2a3140;--pico-range-thumb-border-color:var(--pico-background-color);--pico-range-thumb-color:var(--pico-secondary-background);--pico-range-thumb-active-color:var(--pico-primary-background);--pico-accordion-border-color:var(--pico-muted-border-color);--pico-accordion-active-summary-color:var(--pico-primary-hover);--pico-accordion-close-summary-color:var(--pico-color);--pico-accordion-open-summary-color:var(--pico-muted-color);--pico-card-background-color:#181c25;--pico-card-border-color:var(--pico-card-background-color);--pico-card-box-shadow:var(--pico-box-shadow);--pico-card-sectioning-background-color:#1a1f28;--pico-dropdown-background-color:#181c25;--pico-dropdown-border-color:#202632;--pico-dropdown-box-shadow:var(--pico-box-shadow);--pico-dropdown-color:var(--pico-color);--pico-dropdown-hover-background-color:#202632;--pico-loading-spinner-opacity:0.5;--pico-modal-overlay-background-color:rgba(8, 9, 10, 0.75);--pico-progress-background-color:#202632;--pico-progress-color:var(--pico-primary-background);--pico-tooltip-background-color:var(--pico-contrast-background);--pico-tooltip-color:var(--pico-contrast-inverse);--pico-icon-valid:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(42, 123, 111)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");--pico-icon-invalid:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(150, 74, 80)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E");color-scheme:dark}[data-theme=dark] input:is([type=submit],[type=button],[type=reset],[type=checkbox],[type=radio],[type=file]){--pico-form-element-focus-color:var(--pico-primary-focus)}[data-theme=dark] details summary[role=button].contrast:not(.outline)::after{filter:brightness(0)}[data-theme=dark] [aria-busy=true]:not(input,select,textarea).contrast:is(button,[type=submit],[type=button],[type=reset],[role=button]):not(.outline)::before{filter:brightness(0)}[type=checkbox],[type=radio],[type=range],progress{accent-color:var(--pico-primary)}*,::after,::before{box-sizing:border-box;background-repeat:no-repeat}::after,::before{text-decoration:inherit;vertical-align:inherit}:where(:root){-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%;background-color:var(--pico-background-color);color:var(--pico-color);font-weight:var(--pico-font-weight);font-size:var(--pico-font-size);line-height:var(--pico-line-height);font-family:var(--pico-font-family);text-underline-offset:var(--pico-text-underline-offset);text-rendering:optimizeLegibility;overflow-wrap:break-word;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{width:100%;margin:0}main{display:block}body>footer,body>header,body>main{padding-block:var(--pico-block-spacing-vertical)}section{margin-bottom:var(--pico-block-spacing-vertical)}.container,.container-fluid{width:100%;margin-right:auto;margin-left:auto;padding-right:var(--pico-spacing);padding-left:var(--pico-spacing)}@media (min-width:576px){.container{max-width:510px;padding-right:0;padding-left:0}}@media (min-width:768px){.container{max-width:700px}}@media (min-width:1024px){.container{max-width:950px}}@media (min-width:1280px){.container{max-width:1200px}}@media (min-width:1536px){.container{max-width:1450px}}.grid{grid-column-gap:var(--pico-grid-column-gap);grid-row-gap:var(--pico-grid-row-gap);display:grid;grid-template-columns:1fr}@media (min-width:768px){.grid{grid-template-columns:repeat(auto-fit,minmax(0%,1fr))}}.grid>*{min-width:0}.overflow-auto{overflow:auto}b,strong{font-weight:bolder}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}address,blockquote,dl,ol,p,pre,table,ul{margin-top:0;margin-bottom:var(--pico-typography-spacing-vertical);color:var(--pico-color);font-style:normal;font-weight:var(--pico-font-weight)}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:var(--pico-typography-spacing-vertical);color:var(--pico-color);font-weight:var(--pico-font-weight);font-size:var(--pico-font-size);line-height:var(--pico-line-height);font-family:var(--pico-font-family)}h1{--pico-color:var(--pico-h1-color)}h2{--pico-color:var(--pico-h2-color)}h3{--pico-color:var(--pico-h3-color)}h4{--pico-color:var(--pico-h4-color)}h5{--pico-color:var(--pico-h5-color)}h6{--pico-color:var(--pico-h6-color)}:where(article,address,blockquote,dl,figure,form,ol,p,pre,table,ul)~:is(h1,h2,h3,h4,h5,h6){margin-top:var(--pico-typography-spacing-top)}p{margin-bottom:var(--pico-typography-spacing-vertical)}hgroup{margin-bottom:var(--pico-typography-spacing-vertical)}hgroup>*{margin-top:0;margin-bottom:0}hgroup>:not(:first-child):last-child{--pico-color:var(--pico-muted-color);--pico-font-weight:unset;font-size:1rem}:where(ol,ul) li{margin-bottom:calc(var(--pico-typography-spacing-vertical) * .25)}:where(dl,ol,ul) :where(dl,ol,ul){margin:0;margin-top:calc(var(--pico-typography-spacing-vertical) * .25)}ul li{list-style:square}mark{padding:.125rem .25rem;background-color:var(--pico-mark-background-color);color:var(--pico-mark-color);vertical-align:baseline}blockquote{display:block;margin:var(--pico-typography-spacing-vertical) 0;padding:var(--pico-spacing);border-right:none;border-left:.25rem solid var(--pico-blockquote-border-color);border-inline-start:0.25rem solid var(--pico-blockquote-border-color);border-inline-end:none}blockquote footer{margin-top:calc(var(--pico-typography-spacing-vertical) * .5);color:var(--pico-blockquote-footer-color)}abbr[title]{border-bottom:1px dotted;text-decoration:none;cursor:help}ins{color:var(--pico-ins-color);text-decoration:none}del{color:var(--pico-del-color)}::-moz-selection{background-color:var(--pico-text-selection-color)}::selection{background-color:var(--pico-text-selection-color)}:where(a:not([role=button])),[role=link]{--pico-color:var(--pico-primary);--pico-background-color:transparent;--pico-underline:var(--pico-primary-underline);outline:0;background-color:var(--pico-background-color);color:var(--pico-color);-webkit-text-decoration:var(--pico-text-decoration);text-decoration:var(--pico-text-decoration);text-decoration-color:var(--pico-underline);text-underline-offset:0.125em;transition:background-color var(--pico-transition),color var(--pico-transition),box-shadow var(--pico-transition),-webkit-text-decoration var(--pico-transition);transition:background-color var(--pico-transition),color var(--pico-transition),text-decoration var(--pico-transition),box-shadow var(--pico-transition);transition:background-color var(--pico-transition),color var(--pico-transition),text-decoration var(--pico-transition),box-shadow var(--pico-transition),-webkit-text-decoration var(--pico-transition)}:where(a:not([role=button])):is([aria-current]:not([aria-current=false]),:hover,:active,:focus),[role=link]:is([aria-current]:not([aria-current=false]),:hover,:active,:focus){--pico-color:var(--pico-primary-hover);--pico-underline:var(--pico-primary-hover-underline);--pico-text-decoration:underline}:where(a:not([role=button])):focus-visible,[role=link]:focus-visible{box-shadow:0 0 0 var(--pico-outline-width) var(--pico-primary-focus)}:where(a:not([role=button])).secondary,[role=link].secondary{--pico-color:var(--pico-secondary);--pico-underline:var(--pico-secondary-underline)}:where(a:not([role=button])).secondary:is([aria-current]:not([aria-current=false]),:hover,:active,:focus),[role=link].secondary:is([aria-current]:not([aria-current=false]),:hover,:active,:focus){--pico-color:var(--pico-secondary-hover);--pico-underline:var(--pico-secondary-hover-underline)}:where(a:not([role=button])).contrast,[role=link].contrast{--pico-color:var(--pico-contrast);--pico-underline:var(--pico-contrast-underline)}:where(a:not([role=button])).contrast:is([aria-current]:not([aria-current=false]),:hover,:active,:focus),[role=link].contrast:is([aria-current]:not([aria-current=false]),:hover,:active,:focus){--pico-color:var(--pico-contrast-hover);--pico-underline:var(--pico-contrast-hover-underline)}a[role=button]{display:inline-block}button{margin:0;overflow:visible;font-family:inherit;text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[role=button],[type=button],[type=file]::file-selector-button,[type=reset],[type=submit],button{--pico-background-color:var(--pico-primary-background);--pico-border-color:var(--pico-primary-border);--pico-color:var(--pico-primary-inverse);--pico-box-shadow:var(--pico-button-box-shadow, 0 0 0 rgba(0, 0, 0, 0));padding:var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal);border:var(--pico-border-width) solid var(--pico-border-color);border-radius:var(--pico-border-radius);outline:0;background-color:var(--pico-background-color);box-shadow:var(--pico-box-shadow);color:var(--pico-color);font-weight:var(--pico-font-weight);font-size:1rem;line-height:var(--pico-line-height);text-align:center;text-decoration:none;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;transition:background-color var(--pico-transition),border-color var(--pico-transition),color var(--pico-transition),box-shadow var(--pico-transition)}[role=button]:is(:hover,:active,:focus),[role=button]:is([aria-current]:not([aria-current=false])),[type=button]:is(:hover,:active,:focus),[type=button]:is([aria-current]:not([aria-current=false])),[type=file]::file-selector-button:is(:hover,:active,:focus),[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])),[type=reset]:is(:hover,:active,:focus),[type=reset]:is([aria-current]:not([aria-current=false])),[type=submit]:is(:hover,:active,:focus),[type=submit]:is([aria-current]:not([aria-current=false])),button:is(:hover,:active,:focus),button:is([aria-current]:not([aria-current=false])){--pico-background-color:var(--pico-primary-hover-background);--pico-border-color:var(--pico-primary-hover-border);--pico-box-shadow:var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0));--pico-color:var(--pico-primary-inverse)}[role=button]:focus,[role=button]:is([aria-current]:not([aria-current=false])):focus,[type=button]:focus,[type=button]:is([aria-current]:not([aria-current=false])):focus,[type=file]::file-selector-button:focus,[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])):focus,[type=reset]:focus,[type=reset]:is([aria-current]:not([aria-current=false])):focus,[type=submit]:focus,[type=submit]:is([aria-current]:not([aria-current=false])):focus,button:focus,button:is([aria-current]:not([aria-current=false])):focus{--pico-box-shadow:var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)),0 0 0 var(--pico-outline-width) var(--pico-primary-focus)}[type=button],[type=reset],[type=submit]{margin-bottom:var(--pico-spacing)}:is(button,[type=submit],[type=button],[role=button]).secondary,[type=file]::file-selector-button,[type=reset]{--pico-background-color:var(--pico-secondary-background);--pico-border-color:var(--pico-secondary-border);--pico-color:var(--pico-secondary-inverse);cursor:pointer}:is(button,[type=submit],[type=button],[role=button]).secondary:is([aria-current]:not([aria-current=false]),:hover,:active,:focus),[type=file]::file-selector-button:is([aria-current]:not([aria-current=false]),:hover,:active,:focus),[type=reset]:is([aria-current]:not([aria-current=false]),:hover,:active,:focus){--pico-background-color:var(--pico-secondary-hover-background);--pico-border-color:var(--pico-secondary-hover-border);--pico-color:var(--pico-secondary-inverse)}:is(button,[type=submit],[type=button],[role=button]).secondary:focus,:is(button,[type=submit],[type=button],[role=button]).secondary:is([aria-current]:not([aria-current=false])):focus,[type=file]::file-selector-button:focus,[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])):focus,[type=reset]:focus,[type=reset]:is([aria-current]:not([aria-current=false])):focus{--pico-box-shadow:var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)),0 0 0 var(--pico-outline-width) var(--pico-secondary-focus)}:is(button,[type=submit],[type=button],[role=button]).contrast{--pico-background-color:var(--pico-contrast-background);--pico-border-color:var(--pico-contrast-border);--pico-color:var(--pico-contrast-inverse)}:is(button,[type=submit],[type=button],[role=button]).contrast:is([aria-current]:not([aria-current=false]),:hover,:active,:focus){--pico-background-color:var(--pico-contrast-hover-background);--pico-border-color:var(--pico-contrast-hover-border);--pico-color:var(--pico-contrast-inverse)}:is(button,[type=submit],[type=button],[role=button]).contrast:focus,:is(button,[type=submit],[type=button],[role=button]).contrast:is([aria-current]:not([aria-current=false])):focus{--pico-box-shadow:var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)),0 0 0 var(--pico-outline-width) var(--pico-contrast-focus)}:is(button,[type=submit],[type=button],[role=button]).outline,[type=reset].outline{--pico-background-color:transparent;--pico-color:var(--pico-primary);--pico-border-color:var(--pico-primary)}:is(button,[type=submit],[type=button],[role=button]).outline:is([aria-current]:not([aria-current=false]),:hover,:active,:focus),[type=reset].outline:is([aria-current]:not([aria-current=false]),:hover,:active,:focus){--pico-background-color:transparent;--pico-color:var(--pico-primary-hover);--pico-border-color:var(--pico-primary-hover)}:is(button,[type=submit],[type=button],[role=button]).outline.secondary,[type=reset].outline{--pico-color:var(--pico-secondary);--pico-border-color:var(--pico-secondary)}:is(button,[type=submit],[type=button],[role=button]).outline.secondary:is([aria-current]:not([aria-current=false]),:hover,:active,:focus),[type=reset].outline:is([aria-current]:not([aria-current=false]),:hover,:active,:focus){--pico-color:var(--pico-secondary-hover);--pico-border-color:var(--pico-secondary-hover)}:is(button,[type=submit],[type=button],[role=button]).outline.contrast{--pico-color:var(--pico-contrast);--pico-border-color:var(--pico-contrast)}:is(button,[type=submit],[type=button],[role=button]).outline.contrast:is([aria-current]:not([aria-current=false]),:hover,:active,:focus){--pico-color:var(--pico-contrast-hover);--pico-border-color:var(--pico-contrast-hover)}:where(button,[type=submit],[type=reset],[type=button],[role=button])[disabled],:where(fieldset[disabled]) :is(button,[type=submit],[type=button],[type=reset],[role=button]){opacity:.5;pointer-events:none}:where(table){width:100%;border-collapse:collapse;border-spacing:0;text-indent:0}td,th{padding:calc(var(--pico-spacing)/ 2) var(--pico-spacing);border-bottom:var(--pico-border-width) solid var(--pico-table-border-color);background-color:var(--pico-background-color);color:var(--pico-color);font-weight:var(--pico-font-weight);text-align:left;text-align:start}tfoot td,tfoot th{border-top:var(--pico-border-width) solid var(--pico-table-border-color);border-bottom:0}table.striped tbody tr:nth-child(odd) td,table.striped tbody tr:nth-child(odd) th{background-color:var(--pico-table-row-stripped-background-color)}:where(audio,canvas,iframe,img,svg,video){vertical-align:middle}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}:where(iframe){border-style:none}img{max-width:100%;height:auto;border-style:none}:where(svg:not([fill])){fill:currentColor}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-size:.875em;font-family:var(--pico-font-family)}pre code{font-size:inherit;font-family:inherit}pre{-ms-overflow-style:scrollbar;overflow:auto}code,kbd,pre{border-radius:var(--pico-border-radius);background:var(--pico-code-background-color);color:var(--pico-code-color);font-weight:var(--pico-font-weight);line-height:initial}code,kbd{display:inline-block;padding:.375rem}pre{display:block;margin-bottom:var(--pico-spacing);overflow-x:auto}pre>code{display:block;padding:var(--pico-spacing);background:0 0;line-height:var(--pico-line-height)}kbd{background-color:var(--pico-code-kbd-background-color);color:var(--pico-code-kbd-color);vertical-align:baseline}figure{display:block;margin:0;padding:0}figure figcaption{padding:calc(var(--pico-spacing) * .5) 0;color:var(--pico-muted-color)}hr{height:0;margin:var(--pico-typography-spacing-vertical) 0;border:0;border-top:1px solid var(--pico-muted-border-color);color:inherit}[hidden],template{display:none!important}canvas{display:inline-block}input,optgroup,select,textarea{margin:0;font-size:1rem;line-height:var(--pico-line-height);font-family:inherit;letter-spacing:inherit}input{overflow:visible}select{text-transform:none}legend{max-width:100%;padding:0;color:inherit;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{padding:0}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}::-moz-focus-inner{padding:0;border-style:none}:-moz-focusring{outline:0}:-moz-ui-invalid{box-shadow:none}::-ms-expand{display:none}[type=file],[type=range]{padding:0;border-width:0}input:not([type=checkbox],[type=radio],[type=range]){height:calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2)}fieldset{width:100%;margin:0;margin-bottom:var(--pico-spacing);padding:0;border:0}fieldset legend,label{display:block;margin-bottom:calc(var(--pico-spacing) * .375);color:var(--pico-color);font-weight:var(--pico-form-label-font-weight,var(--pico-font-weight))}fieldset legend{margin-bottom:calc(var(--pico-spacing) * .5)}button[type=submit],input:not([type=checkbox],[type=radio]),select,textarea{width:100%}input:not([type=checkbox],[type=radio],[type=range],[type=file]),select,textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal)}input,select,textarea{--pico-background-color:var(--pico-form-element-background-color);--pico-border-color:var(--pico-form-element-border-color);--pico-color:var(--pico-form-element-color);--pico-box-shadow:none;border:var(--pico-border-width) solid var(--pico-border-color);border-radius:var(--pico-border-radius);outline:0;background-color:var(--pico-background-color);box-shadow:var(--pico-box-shadow);color:var(--pico-color);font-weight:var(--pico-font-weight);transition:background-color var(--pico-transition),border-color var(--pico-transition),color var(--pico-transition),box-shadow var(--pico-transition)}:where(select,textarea):not([readonly]):is(:active,:focus),input:not([type=submit],[type=button],[type=reset],[type=checkbox],[type=radio],[readonly]):is(:active,:focus){--pico-background-color:var(--pico-form-element-active-background-color)}:where(select,textarea):not([readonly]):is(:active,:focus),input:not([type=submit],[type=button],[type=reset],[role=switch],[readonly]):is(:active,:focus){--pico-border-color:var(--pico-form-element-active-border-color)}:where(select,textarea):not([readonly]):focus,input:not([type=submit],[type=button],[type=reset],[type=range],[type=file],[readonly]):focus{--pico-box-shadow:0 0 0 var(--pico-outline-width) var(--pico-form-element-focus-color)}:where(fieldset[disabled]) :is(input:not([type=submit],[type=button],[type=reset]),select,textarea),input:not([type=submit],[type=button],[type=reset])[disabled],label[aria-disabled=true],select[disabled],textarea[disabled]{opacity:var(--pico-form-element-disabled-opacity);pointer-events:none}label[aria-disabled=true] input[disabled]{opacity:1}:where(input,select,textarea):not([type=checkbox],[type=radio],[type=date],[type=datetime-local],[type=month],[type=time],[type=week],[type=range])[aria-invalid]{padding-right:calc(var(--pico-form-element-spacing-horizontal) + 1.5rem)!important;padding-left:var(--pico-form-element-spacing-horizontal);padding-inline-start:var(--pico-form-element-spacing-horizontal)!important;padding-inline-end:calc(var(--pico-form-element-spacing-horizontal) + 1.5rem)!important;background-position:center right .75rem;background-size:1rem auto;background-repeat:no-repeat}:where(input,select,textarea):not([type=checkbox],[type=radio],[type=date],[type=datetime-local],[type=month],[type=time],[type=week],[type=range])[aria-invalid=false]:not(select){background-image:var(--pico-icon-valid)}:where(input,select,textarea):not([type=checkbox],[type=radio],[type=date],[type=datetime-local],[type=month],[type=time],[type=week],[type=range])[aria-invalid=true]:not(select){background-image:var(--pico-icon-invalid)}:where(input,select,textarea)[aria-invalid=false]{--pico-border-color:var(--pico-form-element-valid-border-color)}:where(input,select,textarea)[aria-invalid=false]:is(:active,:focus){--pico-border-color:var(--pico-form-element-valid-active-border-color)!important}:where(input,select,textarea)[aria-invalid=false]:is(:active,:focus):not([type=checkbox],[type=radio]){--pico-box-shadow:0 0 0 var(--pico-outline-width) var(--pico-form-element-valid-focus-color)!important}:where(input,select,textarea)[aria-invalid=true]{--pico-border-color:var(--pico-form-element-invalid-border-color)}:where(input,select,textarea)[aria-invalid=true]:is(:active,:focus){--pico-border-color:var(--pico-form-element-invalid-active-border-color)!important}:where(input,select,textarea)[aria-invalid=true]:is(:active,:focus):not([type=checkbox],[type=radio]){--pico-box-shadow:0 0 0 var(--pico-outline-width) var(--pico-form-element-invalid-focus-color)!important}[dir=rtl] :where(input,select,textarea):not([type=checkbox],[type=radio]):is([aria-invalid],[aria-invalid=true],[aria-invalid=false]){background-position:center left .75rem}input::-webkit-input-placeholder,input::placeholder,select:invalid,textarea::-webkit-input-placeholder,textarea::placeholder{color:var(--pico-form-element-placeholder-color);opacity:1}input:not([type=checkbox],[type=radio]),select,textarea{margin-bottom:var(--pico-spacing)}select::-ms-expand{border:0;background-color:transparent}select:not([multiple],[size]){padding-right:calc(var(--pico-form-element-spacing-horizontal) + 1.5rem);padding-left:var(--pico-form-element-spacing-horizontal);padding-inline-start:var(--pico-form-element-spacing-horizontal);padding-inline-end:calc(var(--pico-form-element-spacing-horizontal) + 1.5rem);background-image:var(--pico-icon-chevron);background-position:center right .75rem;background-size:1rem auto;background-repeat:no-repeat}select[multiple] option:checked{background:var(--pico-form-element-selected-background-color);color:var(--pico-form-element-color)}[dir=rtl] select:not([multiple],[size]){background-position:center left .75rem}textarea{display:block;resize:vertical}textarea[aria-invalid]{--pico-icon-height:calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2);background-position:top right .75rem!important;background-size:1rem var(--pico-icon-height)!important}:where(input,select,textarea,fieldset,.grid)+small{display:block;width:100%;margin-top:calc(var(--pico-spacing) * -.75);margin-bottom:var(--pico-spacing);color:var(--pico-muted-color)}:where(input,select,textarea,fieldset,.grid)[aria-invalid=false]+small{color:var(--pico-ins-color)}:where(input,select,textarea,fieldset,.grid)[aria-invalid=true]+small{color:var(--pico-del-color)}label>:where(input,select,textarea){margin-top:calc(var(--pico-spacing) * .25)}label:has([type=checkbox],[type=radio]){width:-moz-fit-content;width:fit-content;cursor:pointer}[type=checkbox],[type=radio]{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:1.25em;height:1.25em;margin-top:-.125em;margin-inline-end:.5em;border-width:var(--pico-border-width);vertical-align:middle;cursor:pointer}[type=checkbox]::-ms-check,[type=radio]::-ms-check{display:none}[type=checkbox]:checked,[type=checkbox]:checked:active,[type=checkbox]:checked:focus,[type=radio]:checked,[type=radio]:checked:active,[type=radio]:checked:focus{--pico-background-color:var(--pico-primary-background);--pico-border-color:var(--pico-primary-border);background-image:var(--pico-icon-checkbox);background-position:center;background-size:.75em auto;background-repeat:no-repeat}[type=checkbox]~label,[type=radio]~label{display:inline-block;margin-bottom:0;cursor:pointer}[type=checkbox]~label:not(:last-of-type),[type=radio]~label:not(:last-of-type){margin-inline-end:1em}[type=checkbox]:indeterminate{--pico-background-color:var(--pico-primary-background);--pico-border-color:var(--pico-primary-border);background-image:var(--pico-icon-minus);background-position:center;background-size:.75em auto;background-repeat:no-repeat}[type=radio]{border-radius:50%}[type=radio]:checked,[type=radio]:checked:active,[type=radio]:checked:focus{--pico-background-color:var(--pico-primary-inverse);border-width:.35em;background-image:none}[type=checkbox][role=switch]{--pico-background-color:var(--pico-switch-background-color);--pico-color:var(--pico-switch-color);width:2.25em;height:1.25em;border:var(--pico-border-width) solid var(--pico-border-color);border-radius:1.25em;background-color:var(--pico-background-color);line-height:1.25em}[type=checkbox][role=switch]:not([aria-invalid]){--pico-border-color:var(--pico-switch-background-color)}[type=checkbox][role=switch]:before{display:block;aspect-ratio:1;height:100%;border-radius:50%;background-color:var(--pico-color);box-shadow:var(--pico-switch-thumb-box-shadow);content:"";transition:margin .1s ease-in-out}[type=checkbox][role=switch]:focus{--pico-background-color:var(--pico-switch-background-color);--pico-border-color:var(--pico-switch-background-color)}[type=checkbox][role=switch]:checked{--pico-background-color:var(--pico-switch-checked-background-color);--pico-border-color:var(--pico-switch-checked-background-color);background-image:none}[type=checkbox][role=switch]:checked::before{margin-inline-start:calc(2.25em - 1.25em)}[type=checkbox][role=switch][disabled]{--pico-background-color:var(--pico-border-color)}[type=checkbox][aria-invalid=false]:checked,[type=checkbox][aria-invalid=false]:checked:active,[type=checkbox][aria-invalid=false]:checked:focus,[type=checkbox][role=switch][aria-invalid=false]:checked,[type=checkbox][role=switch][aria-invalid=false]:checked:active,[type=checkbox][role=switch][aria-invalid=false]:checked:focus{--pico-background-color:var(--pico-form-element-valid-border-color)}[type=checkbox]:checked:active[aria-invalid=true],[type=checkbox]:checked:focus[aria-invalid=true],[type=checkbox]:checked[aria-invalid=true],[type=checkbox][role=switch]:checked:active[aria-invalid=true],[type=checkbox][role=switch]:checked:focus[aria-invalid=true],[type=checkbox][role=switch]:checked[aria-invalid=true]{--pico-background-color:var(--pico-form-element-invalid-border-color)}[type=checkbox][aria-invalid=false]:checked,[type=checkbox][aria-invalid=false]:checked:active,[type=checkbox][aria-invalid=false]:checked:focus,[type=checkbox][role=switch][aria-invalid=false]:checked,[type=checkbox][role=switch][aria-invalid=false]:checked:active,[type=checkbox][role=switch][aria-invalid=false]:checked:focus,[type=radio][aria-invalid=false]:checked,[type=radio][aria-invalid=false]:checked:active,[type=radio][aria-invalid=false]:checked:focus{--pico-border-color:var(--pico-form-element-valid-border-color)}[type=checkbox]:checked:active[aria-invalid=true],[type=checkbox]:checked:focus[aria-invalid=true],[type=checkbox]:checked[aria-invalid=true],[type=checkbox][role=switch]:checked:active[aria-invalid=true],[type=checkbox][role=switch]:checked:focus[aria-invalid=true],[type=checkbox][role=switch]:checked[aria-invalid=true],[type=radio]:checked:active[aria-invalid=true],[type=radio]:checked:focus[aria-invalid=true],[type=radio]:checked[aria-invalid=true]{--pico-border-color:var(--pico-form-element-invalid-border-color)}[type=color]::-webkit-color-swatch-wrapper{padding:0}[type=color]::-moz-focus-inner{padding:0}[type=color]::-webkit-color-swatch{border:0;border-radius:calc(var(--pico-border-radius) * .5)}[type=color]::-moz-color-swatch{border:0;border-radius:calc(var(--pico-border-radius) * .5)}input:not([type=checkbox],[type=radio],[type=range],[type=file]):is([type=date],[type=datetime-local],[type=month],[type=time],[type=week]){--pico-icon-position:0.75rem;--pico-icon-width:1rem;padding-right:calc(var(--pico-icon-width) + var(--pico-icon-position));background-image:var(--pico-icon-date);background-position:center right var(--pico-icon-position);background-size:var(--pico-icon-width) auto;background-repeat:no-repeat}input:not([type=checkbox],[type=radio],[type=range],[type=file])[type=time]{background-image:var(--pico-icon-time)}[type=date]::-webkit-calendar-picker-indicator,[type=datetime-local]::-webkit-calendar-picker-indicator,[type=month]::-webkit-calendar-picker-indicator,[type=time]::-webkit-calendar-picker-indicator,[type=week]::-webkit-calendar-picker-indicator{width:var(--pico-icon-width);margin-right:calc(var(--pico-icon-width) * -1);margin-left:var(--pico-icon-position);opacity:0}@-moz-document url-prefix(){[type=date],[type=datetime-local],[type=month],[type=time],[type=week]{padding-right:var(--pico-form-element-spacing-horizontal)!important;background-image:none!important}}[dir=rtl] :is([type=date],[type=datetime-local],[type=month],[type=time],[type=week]){text-align:right}[type=file]{--pico-color:var(--pico-muted-color);margin-left:calc(var(--pico-outline-width) * -1);padding:calc(var(--pico-form-element-spacing-vertical) * .5) 0;padding-left:var(--pico-outline-width);border:0;border-radius:0;background:0 0}[type=file]::file-selector-button{margin-right:calc(var(--pico-spacing)/ 2);padding:calc(var(--pico-form-element-spacing-vertical) * .5) var(--pico-form-element-spacing-horizontal)}[type=file]:is(:hover,:active,:focus)::file-selector-button{--pico-background-color:var(--pico-secondary-hover-background);--pico-border-color:var(--pico-secondary-hover-border)}[type=file]:focus::file-selector-button{--pico-box-shadow:var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)),0 0 0 var(--pico-outline-width) var(--pico-secondary-focus)}[type=range]{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;height:1.25rem;background:0 0}[type=range]::-webkit-slider-runnable-track{width:100%;height:.375rem;border-radius:var(--pico-border-radius);background-color:var(--pico-range-border-color);-webkit-transition:background-color var(--pico-transition),box-shadow var(--pico-transition);transition:background-color var(--pico-transition),box-shadow var(--pico-transition)}[type=range]::-moz-range-track{width:100%;height:.375rem;border-radius:var(--pico-border-radius);background-color:var(--pico-range-border-color);-moz-transition:background-color var(--pico-transition),box-shadow var(--pico-transition);transition:background-color var(--pico-transition),box-shadow var(--pico-transition)}[type=range]::-ms-track{width:100%;height:.375rem;border-radius:var(--pico-border-radius);background-color:var(--pico-range-border-color);-ms-transition:background-color var(--pico-transition),box-shadow var(--pico-transition);transition:background-color var(--pico-transition),box-shadow var(--pico-transition)}[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:1.25rem;height:1.25rem;margin-top:-.4375rem;border:2px solid var(--pico-range-thumb-border-color);border-radius:50%;background-color:var(--pico-range-thumb-color);cursor:pointer;-webkit-transition:background-color var(--pico-transition),transform var(--pico-transition);transition:background-color var(--pico-transition),transform var(--pico-transition)}[type=range]::-moz-range-thumb{-webkit-appearance:none;width:1.25rem;height:1.25rem;margin-top:-.4375rem;border:2px solid var(--pico-range-thumb-border-color);border-radius:50%;background-color:var(--pico-range-thumb-color);cursor:pointer;-moz-transition:background-color var(--pico-transition),transform var(--pico-transition);transition:background-color var(--pico-transition),transform var(--pico-transition)}[type=range]::-ms-thumb{-webkit-appearance:none;width:1.25rem;height:1.25rem;margin-top:-.4375rem;border:2px solid var(--pico-range-thumb-border-color);border-radius:50%;background-color:var(--pico-range-thumb-color);cursor:pointer;-ms-transition:background-color var(--pico-transition),transform var(--pico-transition);transition:background-color var(--pico-transition),transform var(--pico-transition)}[type=range]:active,[type=range]:focus-within{--pico-range-border-color:var(--pico-range-active-border-color);--pico-range-thumb-color:var(--pico-range-thumb-active-color)}[type=range]:active::-webkit-slider-thumb{transform:scale(1.25)}[type=range]:active::-moz-range-thumb{transform:scale(1.25)}[type=range]:active::-ms-thumb{transform:scale(1.25)}input:not([type=checkbox],[type=radio],[type=range],[type=file])[type=search]{padding-inline-start:calc(var(--pico-form-element-spacing-horizontal) + 1.75rem);background-image:var(--pico-icon-search);background-position:center left calc(var(--pico-form-element-spacing-horizontal) + .125rem);background-size:1rem auto;background-repeat:no-repeat}input:not([type=checkbox],[type=radio],[type=range],[type=file])[type=search][aria-invalid]{padding-inline-start:calc(var(--pico-form-element-spacing-horizontal) + 1.75rem)!important;background-position:center left 1.125rem,center right .75rem}input:not([type=checkbox],[type=radio],[type=range],[type=file])[type=search][aria-invalid=false]{background-image:var(--pico-icon-search),var(--pico-icon-valid)}input:not([type=checkbox],[type=radio],[type=range],[type=file])[type=search][aria-invalid=true]{background-image:var(--pico-icon-search),var(--pico-icon-invalid)}[dir=rtl] :where(input):not([type=checkbox],[type=radio],[type=range],[type=file])[type=search]{background-position:center right 1.125rem}[dir=rtl] :where(input):not([type=checkbox],[type=radio],[type=range],[type=file])[type=search][aria-invalid]{background-position:center right 1.125rem,center left .75rem}details{display:block;margin-bottom:var(--pico-spacing)}details summary{line-height:1rem;list-style-type:none;cursor:pointer;transition:color var(--pico-transition)}details summary:not([role]){color:var(--pico-accordion-close-summary-color)}details summary::-webkit-details-marker{display:none}details summary::marker{display:none}details summary::-moz-list-bullet{list-style-type:none}details summary::after{display:block;width:1rem;height:1rem;margin-inline-start:calc(var(--pico-spacing,1rem) * .5);float:right;transform:rotate(-90deg);background-image:var(--pico-icon-chevron);background-position:right center;background-size:1rem auto;background-repeat:no-repeat;content:"";transition:transform var(--pico-transition)}details summary:focus{outline:0}details summary:focus:not([role]){color:var(--pico-accordion-active-summary-color)}details summary:focus-visible:not([role]){outline:var(--pico-outline-width) solid var(--pico-primary-focus);outline-offset:calc(var(--pico-spacing,1rem) * 0.5);color:var(--pico-primary)}details summary[role=button]{width:100%;text-align:left}details summary[role=button]::after{height:calc(1rem * var(--pico-line-height,1.5))}details[open]>summary{margin-bottom:var(--pico-spacing)}details[open]>summary:not([role]):not(:focus){color:var(--pico-accordion-open-summary-color)}details[open]>summary::after{transform:rotate(0)}[dir=rtl] details summary{text-align:right}[dir=rtl] details summary::after{float:left;background-position:left center}article{margin-bottom:var(--pico-block-spacing-vertical);padding:var(--pico-block-spacing-vertical) var(--pico-block-spacing-horizontal);border-radius:var(--pico-border-radius);background:var(--pico-card-background-color);box-shadow:var(--pico-card-box-shadow)}article>footer,article>header{margin-right:calc(var(--pico-block-spacing-horizontal) * -1);margin-left:calc(var(--pico-block-spacing-horizontal) * -1);padding:calc(var(--pico-block-spacing-vertical) * .66) var(--pico-block-spacing-horizontal);background-color:var(--pico-card-sectioning-background-color)}article>header{margin-top:calc(var(--pico-block-spacing-vertical) * -1);margin-bottom:var(--pico-block-spacing-vertical);border-bottom:var(--pico-border-width) solid var(--pico-card-border-color);border-top-right-radius:var(--pico-border-radius);border-top-left-radius:var(--pico-border-radius)}article>footer{margin-top:var(--pico-block-spacing-vertical);margin-bottom:calc(var(--pico-block-spacing-vertical) * -1);border-top:var(--pico-border-width) solid var(--pico-card-border-color);border-bottom-right-radius:var(--pico-border-radius);border-bottom-left-radius:var(--pico-border-radius)}details.dropdown{position:relative;border-bottom:none}details.dropdown summary::after,details.dropdown>a::after,details.dropdown>button::after{display:block;width:1rem;height:calc(1rem * var(--pico-line-height,1.5));margin-inline-start:.25rem;float:right;transform:rotate(0) translateX(.2rem);background-image:var(--pico-icon-chevron);background-position:right center;background-size:1rem auto;background-repeat:no-repeat;content:""}nav details.dropdown{margin-bottom:0}details.dropdown summary:not([role]){height:calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2);padding:var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal);border:var(--pico-border-width) solid var(--pico-form-element-border-color);border-radius:var(--pico-border-radius);background-color:var(--pico-form-element-background-color);color:var(--pico-form-element-placeholder-color);line-height:inherit;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;transition:background-color var(--pico-transition),border-color var(--pico-transition),color var(--pico-transition),box-shadow var(--pico-transition)}details.dropdown summary:not([role]):active,details.dropdown summary:not([role]):focus{border-color:var(--pico-form-element-active-border-color);background-color:var(--pico-form-element-active-background-color)}details.dropdown summary:not([role]):focus{box-shadow:0 0 0 var(--pico-outline-width) var(--pico-form-element-focus-color)}details.dropdown summary:not([role]):focus-visible{outline:0}details.dropdown summary:not([role])[aria-invalid=false]{--pico-form-element-border-color:var(--pico-form-element-valid-border-color);--pico-form-element-active-border-color:var(--pico-form-element-valid-focus-color);--pico-form-element-focus-color:var(--pico-form-element-valid-focus-color)}details.dropdown summary:not([role])[aria-invalid=true]{--pico-form-element-border-color:var(--pico-form-element-invalid-border-color);--pico-form-element-active-border-color:var(--pico-form-element-invalid-focus-color);--pico-form-element-focus-color:var(--pico-form-element-invalid-focus-color)}nav details.dropdown{display:inline;margin:calc(var(--pico-nav-element-spacing-vertical) * -1) 0}nav details.dropdown summary::after{transform:rotate(0) translateX(0)}nav details.dropdown summary:not([role]){height:calc(1rem * var(--pico-line-height) + var(--pico-nav-link-spacing-vertical) * 2);padding:calc(var(--pico-nav-link-spacing-vertical) - var(--pico-border-width) * 2) var(--pico-nav-link-spacing-horizontal)}nav details.dropdown summary:not([role]):focus-visible{box-shadow:0 0 0 var(--pico-outline-width) var(--pico-primary-focus)}details.dropdown summary+ul{display:flex;z-index:99;position:absolute;left:0;flex-direction:column;width:100%;min-width:-moz-fit-content;min-width:fit-content;margin:0;margin-top:var(--pico-outline-width);padding:0;border:var(--pico-border-width) solid var(--pico-dropdown-border-color);border-radius:var(--pico-border-radius);background-color:var(--pico-dropdown-background-color);box-shadow:var(--pico-dropdown-box-shadow);color:var(--pico-dropdown-color);white-space:nowrap;opacity:0;transition:opacity var(--pico-transition),transform 0s ease-in-out 1s}details.dropdown summary+ul[dir=rtl]{right:0;left:auto}details.dropdown summary+ul li{width:100%;margin-bottom:0;padding:calc(var(--pico-form-element-spacing-vertical) * .5) var(--pico-form-element-spacing-horizontal);list-style:none}details.dropdown summary+ul li:first-of-type{margin-top:calc(var(--pico-form-element-spacing-vertical) * .5)}details.dropdown summary+ul li:last-of-type{margin-bottom:calc(var(--pico-form-element-spacing-vertical) * .5)}details.dropdown summary+ul li a{display:block;margin:calc(var(--pico-form-element-spacing-vertical) * -.5) calc(var(--pico-form-element-spacing-horizontal) * -1);padding:calc(var(--pico-form-element-spacing-vertical) * .5) var(--pico-form-element-spacing-horizontal);overflow:hidden;border-radius:0;color:var(--pico-dropdown-color);text-decoration:none;text-overflow:ellipsis}details.dropdown summary+ul li a:active,details.dropdown summary+ul li a:focus,details.dropdown summary+ul li a:focus-visible,details.dropdown summary+ul li a:hover,details.dropdown summary+ul li a[aria-current]:not([aria-current=false]){background-color:var(--pico-dropdown-hover-background-color)}details.dropdown summary+ul li label{width:100%}details.dropdown summary+ul li:has(label):hover{background-color:var(--pico-dropdown-hover-background-color)}details.dropdown[open] summary{margin-bottom:0}details.dropdown[open] summary+ul{transform:scaleY(1);opacity:1;transition:opacity var(--pico-transition),transform 0s ease-in-out 0s}details.dropdown[open] summary::before{display:block;z-index:1;position:fixed;width:100vw;height:100vh;inset:0;background:0 0;content:"";cursor:default}label>details.dropdown{margin-top:calc(var(--pico-spacing) * .25)}[role=group],[role=search]{display:inline-flex;position:relative;width:100%;margin-bottom:var(--pico-spacing);border-radius:var(--pico-border-radius);box-shadow:var(--pico-group-box-shadow,0 0 0 transparent);vertical-align:middle;transition:box-shadow var(--pico-transition)}[role=group] input:not([type=checkbox],[type=radio]),[role=group] select,[role=group]>*,[role=search] input:not([type=checkbox],[type=radio]),[role=search] select,[role=search]>*{position:relative;flex:1 1 auto;margin-bottom:0}[role=group] input:not([type=checkbox],[type=radio]):not(:first-child),[role=group] select:not(:first-child),[role=group]>:not(:first-child),[role=search] input:not([type=checkbox],[type=radio]):not(:first-child),[role=search] select:not(:first-child),[role=search]>:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}[role=group] input:not([type=checkbox],[type=radio]):not(:last-child),[role=group] select:not(:last-child),[role=group]>:not(:last-child),[role=search] input:not([type=checkbox],[type=radio]):not(:last-child),[role=search] select:not(:last-child),[role=search]>:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}[role=group] input:not([type=checkbox],[type=radio]):focus,[role=group] select:focus,[role=group]>:focus,[role=search] input:not([type=checkbox],[type=radio]):focus,[role=search] select:focus,[role=search]>:focus{z-index:2}[role=group] [role=button]:not(:first-child),[role=group] [type=button]:not(:first-child),[role=group] [type=reset]:not(:first-child),[role=group] [type=submit]:not(:first-child),[role=group] button:not(:first-child),[role=group] input:not([type=checkbox],[type=radio]):not(:first-child),[role=group] select:not(:first-child),[role=search] [role=button]:not(:first-child),[role=search] [type=button]:not(:first-child),[role=search] [type=reset]:not(:first-child),[role=search] [type=submit]:not(:first-child),[role=search] button:not(:first-child),[role=search] input:not([type=checkbox],[type=radio]):not(:first-child),[role=search] select:not(:first-child){margin-left:calc(var(--pico-border-width) * -1)}[role=group] [role=button],[role=group] [type=button],[role=group] [type=reset],[role=group] [type=submit],[role=group] button,[role=search] [role=button],[role=search] [type=button],[role=search] [type=reset],[role=search] [type=submit],[role=search] button{width:auto}@supports selector(:has(*)){[role=group]:has(button:focus,[type=submit]:focus,[type=button]:focus,[role=button]:focus),[role=search]:has(button:focus,[type=submit]:focus,[type=button]:focus,[role=button]:focus){--pico-group-box-shadow:var(--pico-group-box-shadow-focus-with-button)}[role=group]:has(button:focus,[type=submit]:focus,[type=button]:focus,[role=button]:focus) input:not([type=checkbox],[type=radio]),[role=group]:has(button:focus,[type=submit]:focus,[type=button]:focus,[role=button]:focus) select,[role=search]:has(button:focus,[type=submit]:focus,[type=button]:focus,[role=button]:focus) input:not([type=checkbox],[type=radio]),[role=search]:has(button:focus,[type=submit]:focus,[type=button]:focus,[role=button]:focus) select{border-color:transparent}[role=group]:has(input:not([type=submit],[type=button]):focus,select:focus),[role=search]:has(input:not([type=submit],[type=button]):focus,select:focus){--pico-group-box-shadow:var(--pico-group-box-shadow-focus-with-input)}[role=group]:has(input:not([type=submit],[type=button]):focus,select:focus) [role=button],[role=group]:has(input:not([type=submit],[type=button]):focus,select:focus) [type=button],[role=group]:has(input:not([type=submit],[type=button]):focus,select:focus) [type=submit],[role=group]:has(input:not([type=submit],[type=button]):focus,select:focus) button,[role=search]:has(input:not([type=submit],[type=button]):focus,select:focus) [role=button],[role=search]:has(input:not([type=submit],[type=button]):focus,select:focus) [type=button],[role=search]:has(input:not([type=submit],[type=button]):focus,select:focus) [type=submit],[role=search]:has(input:not([type=submit],[type=button]):focus,select:focus) button{--pico-button-box-shadow:0 0 0 var(--pico-border-width) var(--pico-primary-border);--pico-button-hover-box-shadow:0 0 0 var(--pico-border-width) var(--pico-primary-hover-border)}[role=group] [role=button]:focus,[role=group] [type=button]:focus,[role=group] [type=reset]:focus,[role=group] [type=submit]:focus,[role=group] button:focus,[role=search] [role=button]:focus,[role=search] [type=button]:focus,[role=search] [type=reset]:focus,[role=search] [type=submit]:focus,[role=search] button:focus{box-shadow:none}}[role=search]>:first-child{border-top-left-radius:5rem;border-bottom-left-radius:5rem}[role=search]>:last-child{border-top-right-radius:5rem;border-bottom-right-radius:5rem}[aria-busy=true]:not(input,select,textarea,html){white-space:nowrap}[aria-busy=true]:not(input,select,textarea,html)::before{display:inline-block;width:1em;height:1em;background-image:var(--pico-icon-loading);background-size:1em auto;background-repeat:no-repeat;content:"";vertical-align:-.125em}[aria-busy=true]:not(input,select,textarea,html):not(:empty)::before{margin-inline-end:calc(var(--pico-spacing) * .5)}[aria-busy=true]:not(input,select,textarea,html):empty{text-align:center}[role=button][aria-busy=true],[type=button][aria-busy=true],[type=reset][aria-busy=true],[type=submit][aria-busy=true],a[aria-busy=true],button[aria-busy=true]{pointer-events:none}:root{--pico-scrollbar-width:0px}dialog{display:flex;z-index:999;position:fixed;top:0;right:0;bottom:0;left:0;align-items:center;justify-content:center;width:inherit;min-width:100%;height:inherit;min-height:100%;padding:0;border:0;-webkit-backdrop-filter:var(--pico-modal-overlay-backdrop-filter);backdrop-filter:var(--pico-modal-overlay-backdrop-filter);background-color:var(--pico-modal-overlay-background-color);color:var(--pico-color)}dialog article{width:100%;max-height:calc(100vh - var(--pico-spacing) * 2);margin:var(--pico-spacing);overflow:auto}@media (min-width:576px){dialog article{max-width:510px}}@media (min-width:768px){dialog article{max-width:700px}}dialog article>header>*{margin-bottom:0}dialog article>header .close,dialog article>header :is(a,button)[rel=prev]{margin:0;margin-left:var(--pico-spacing);padding:0;float:right}dialog article>footer{text-align:right}dialog article>footer [role=button],dialog article>footer button{margin-bottom:0}dialog article>footer [role=button]:not(:first-of-type),dialog article>footer button:not(:first-of-type){margin-left:calc(var(--pico-spacing) * .5)}dialog article .close,dialog article :is(a,button)[rel=prev]{display:block;width:1rem;height:1rem;margin-top:calc(var(--pico-spacing) * -1);margin-bottom:var(--pico-spacing);margin-left:auto;border:none;background-image:var(--pico-icon-close);background-position:center;background-size:auto 1rem;background-repeat:no-repeat;background-color:transparent;opacity:.5;transition:opacity var(--pico-transition)}dialog article .close:is([aria-current]:not([aria-current=false]),:hover,:active,:focus),dialog article :is(a,button)[rel=prev]:is([aria-current]:not([aria-current=false]),:hover,:active,:focus){opacity:1}dialog:not([open]),dialog[open=false]{display:none}.modal-is-open{padding-right:var(--pico-scrollbar-width,0);overflow:hidden;pointer-events:none;touch-action:none}.modal-is-open dialog{pointer-events:auto;touch-action:auto}:where(.modal-is-opening,.modal-is-closing) dialog,:where(.modal-is-opening,.modal-is-closing) dialog>article{animation-duration:.2s;animation-timing-function:ease-in-out;animation-fill-mode:both}:where(.modal-is-opening,.modal-is-closing) dialog{animation-duration:.8s;animation-name:modal-overlay}:where(.modal-is-opening,.modal-is-closing) dialog>article{animation-delay:.2s;animation-name:modal}.modal-is-closing dialog,.modal-is-closing dialog>article{animation-delay:0s;animation-direction:reverse}@keyframes modal-overlay{from{-webkit-backdrop-filter:none;backdrop-filter:none;background-color:transparent}}@keyframes modal{from{transform:translateY(-100%);opacity:0}}:where(nav li)::before{float:left;content:"​"}nav,nav ul{display:flex}nav{justify-content:space-between;overflow:visible}nav ol,nav ul{align-items:center;margin-bottom:0;padding:0;list-style:none}nav ol:first-of-type,nav ul:first-of-type{margin-left:calc(var(--pico-nav-element-spacing-horizontal) * -1)}nav ol:last-of-type,nav ul:last-of-type{margin-right:calc(var(--pico-nav-element-spacing-horizontal) * -1)}nav li{display:inline-block;margin:0;padding:var(--pico-nav-element-spacing-vertical) var(--pico-nav-element-spacing-horizontal)}nav li :where(a,[role=link]){display:inline-block;margin:calc(var(--pico-nav-link-spacing-vertical) * -1) calc(var(--pico-nav-link-spacing-horizontal) * -1);padding:var(--pico-nav-link-spacing-vertical) var(--pico-nav-link-spacing-horizontal);border-radius:var(--pico-border-radius)}nav li :where(a,[role=link]):not(:hover){text-decoration:none}nav li [role=button],nav li [type=button],nav li button,nav li input:not([type=checkbox],[type=radio],[type=range],[type=file]),nav li select{height:auto;margin-right:inherit;margin-bottom:0;margin-left:inherit;padding:calc(var(--pico-nav-link-spacing-vertical) - var(--pico-border-width) * 2) var(--pico-nav-link-spacing-horizontal)}nav[aria-label=breadcrumb]{align-items:center;justify-content:start}nav[aria-label=breadcrumb] ul li:not(:first-child){margin-inline-start:var(--pico-nav-link-spacing-horizontal)}nav[aria-label=breadcrumb] ul li a{margin:calc(var(--pico-nav-link-spacing-vertical) * -1) 0;margin-inline-start:calc(var(--pico-nav-link-spacing-horizontal) * -1)}nav[aria-label=breadcrumb] ul li:not(:last-child)::after{display:inline-block;position:absolute;width:calc(var(--pico-nav-link-spacing-horizontal) * 4);margin:0 calc(var(--pico-nav-link-spacing-horizontal) * -1);content:var(--pico-nav-breadcrumb-divider);color:var(--pico-muted-color);text-align:center;text-decoration:none;white-space:nowrap}nav[aria-label=breadcrumb] a[aria-current]:not([aria-current=false]){background-color:transparent;color:inherit;text-decoration:none;pointer-events:none}aside li,aside nav,aside ol,aside ul{display:block}aside li{padding:calc(var(--pico-nav-element-spacing-vertical) * .5) var(--pico-nav-element-spacing-horizontal)}aside li a{display:block}aside li [role=button]{margin:inherit}[dir=rtl] nav[aria-label=breadcrumb] ul li:not(:last-child) ::after{content:"\\"}progress{display:inline-block;vertical-align:baseline}progress{-webkit-appearance:none;-moz-appearance:none;display:inline-block;appearance:none;width:100%;height:.5rem;margin-bottom:calc(var(--pico-spacing) * .5);overflow:hidden;border:0;border-radius:var(--pico-border-radius);background-color:var(--pico-progress-background-color);color:var(--pico-progress-color)}progress::-webkit-progress-bar{border-radius:var(--pico-border-radius);background:0 0}progress[value]::-webkit-progress-value{background-color:var(--pico-progress-color);-webkit-transition:inline-size var(--pico-transition);transition:inline-size var(--pico-transition)}progress::-moz-progress-bar{background-color:var(--pico-progress-color)}@media (prefers-reduced-motion:no-preference){progress:indeterminate{background:var(--pico-progress-background-color) linear-gradient(to right,var(--pico-progress-color) 30%,var(--pico-progress-background-color) 30%) top left/150% 150% no-repeat;animation:progress-indeterminate 1s linear infinite}progress:indeterminate[value]::-webkit-progress-value{background-color:transparent}progress:indeterminate::-moz-progress-bar{background-color:transparent}}@media (prefers-reduced-motion:no-preference){[dir=rtl] progress:indeterminate{animation-direction:reverse}}@keyframes progress-indeterminate{0%{background-position:200% 0}100%{background-position:-200% 0}}[data-tooltip]{position:relative}[data-tooltip]:not(a,button,input){border-bottom:1px dotted;text-decoration:none;cursor:help}[data-tooltip]::after,[data-tooltip]::before,[data-tooltip][data-placement=top]::after,[data-tooltip][data-placement=top]::before{display:block;z-index:99;position:absolute;bottom:100%;left:50%;padding:.25rem .5rem;overflow:hidden;transform:translate(-50%,-.25rem);border-radius:var(--pico-border-radius);background:var(--pico-tooltip-background-color);content:attr(data-tooltip);color:var(--pico-tooltip-color);font-style:normal;font-weight:var(--pico-font-weight);font-size:.875rem;text-decoration:none;text-overflow:ellipsis;white-space:nowrap;opacity:0;pointer-events:none}[data-tooltip]::after,[data-tooltip][data-placement=top]::after{padding:0;transform:translate(-50%,0);border-top:.3rem solid;border-right:.3rem solid transparent;border-left:.3rem solid transparent;border-radius:0;background-color:transparent;content:"";color:var(--pico-tooltip-background-color)}[data-tooltip][data-placement=bottom]::after,[data-tooltip][data-placement=bottom]::before{top:100%;bottom:auto;transform:translate(-50%,.25rem)}[data-tooltip][data-placement=bottom]:after{transform:translate(-50%,-.3rem);border:.3rem solid transparent;border-bottom:.3rem solid}[data-tooltip][data-placement=left]::after,[data-tooltip][data-placement=left]::before{top:50%;right:100%;bottom:auto;left:auto;transform:translate(-.25rem,-50%)}[data-tooltip][data-placement=left]:after{transform:translate(.3rem,-50%);border:.3rem solid transparent;border-left:.3rem solid}[data-tooltip][data-placement=right]::after,[data-tooltip][data-placement=right]::before{top:50%;right:auto;bottom:auto;left:100%;transform:translate(.25rem,-50%)}[data-tooltip][data-placement=right]:after{transform:translate(-.3rem,-50%);border:.3rem solid transparent;border-right:.3rem solid}[data-tooltip]:focus::after,[data-tooltip]:focus::before,[data-tooltip]:hover::after,[data-tooltip]:hover::before{opacity:1}@media (hover:hover) and (pointer:fine){[data-tooltip]:focus::after,[data-tooltip]:focus::before,[data-tooltip]:hover::after,[data-tooltip]:hover::before{--pico-tooltip-slide-to:translate(-50%, -0.25rem);transform:translate(-50%,.75rem);animation-duration:.2s;animation-fill-mode:forwards;animation-name:tooltip-slide;opacity:0}[data-tooltip]:focus::after,[data-tooltip]:hover::after{--pico-tooltip-caret-slide-to:translate(-50%, 0rem);transform:translate(-50%,-.25rem);animation-name:tooltip-caret-slide}[data-tooltip][data-placement=bottom]:focus::after,[data-tooltip][data-placement=bottom]:focus::before,[data-tooltip][data-placement=bottom]:hover::after,[data-tooltip][data-placement=bottom]:hover::before{--pico-tooltip-slide-to:translate(-50%, 0.25rem);transform:translate(-50%,-.75rem);animation-name:tooltip-slide}[data-tooltip][data-placement=bottom]:focus::after,[data-tooltip][data-placement=bottom]:hover::after{--pico-tooltip-caret-slide-to:translate(-50%, -0.3rem);transform:translate(-50%,-.5rem);animation-name:tooltip-caret-slide}[data-tooltip][data-placement=left]:focus::after,[data-tooltip][data-placement=left]:focus::before,[data-tooltip][data-placement=left]:hover::after,[data-tooltip][data-placement=left]:hover::before{--pico-tooltip-slide-to:translate(-0.25rem, -50%);transform:translate(.75rem,-50%);animation-name:tooltip-slide}[data-tooltip][data-placement=left]:focus::after,[data-tooltip][data-placement=left]:hover::after{--pico-tooltip-caret-slide-to:translate(0.3rem, -50%);transform:translate(.05rem,-50%);animation-name:tooltip-caret-slide}[data-tooltip][data-placement=right]:focus::after,[data-tooltip][data-placement=right]:focus::before,[data-tooltip][data-placement=right]:hover::after,[data-tooltip][data-placement=right]:hover::before{--pico-tooltip-slide-to:translate(0.25rem, -50%);transform:translate(-.75rem,-50%);animation-name:tooltip-slide}[data-tooltip][data-placement=right]:focus::after,[data-tooltip][data-placement=right]:hover::after{--pico-tooltip-caret-slide-to:translate(-0.3rem, -50%);transform:translate(-.05rem,-50%);animation-name:tooltip-caret-slide}}@keyframes tooltip-slide{to{transform:var(--pico-tooltip-slide-to);opacity:1}}@keyframes tooltip-caret-slide{50%{opacity:0}to{transform:var(--pico-tooltip-caret-slide-to);opacity:1}}[aria-controls]{cursor:pointer}[aria-disabled=true],[disabled]{cursor:not-allowed}[aria-hidden=false][hidden]{display:initial}[aria-hidden=false][hidden]:not(:focus){clip:rect(0,0,0,0);position:absolute}[tabindex],a,area,button,input,label,select,summary,textarea{-ms-touch-action:manipulation}[dir=rtl]{direction:rtl}@media (prefers-reduced-motion:reduce){:not([aria-busy=true]),:not([aria-busy=true])::after,:not([aria-busy=true])::before{background-attachment:initial!important;animation-duration:1ms!important;animation-delay:-1ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important;transition-delay:0s!important;transition-duration:0s!important}}
\ No newline at end of file
diff --git a/core/installer/welcome/stat/welcome.css b/core/installer/welcome/stat/welcome.css
deleted file mode 100644
index 6098d88..0000000
--- a/core/installer/welcome/stat/welcome.css
+++ /dev/null
@@ -1,92 +0,0 @@
-[data-theme="light"],
-:root:not([data-theme="dark"]) {
- --pico-font-family: Hack, monospace;
- --pico-font-size: 14px;
- --pico-background-color: #d6d6d6;
- --pico-border-radius: 0;
- --pico-form-element-border-color: #ffffff;
- --pico-form-element-active-border-color: #7f9f7f;
- --pico-form-element-focus-color: #7f9f7f;
- --pico-form-element-background-color: #3a3a3a;
- --pico-form-element-active-background-color: #3a3a3a;
- --pico-form-element-selected-background-color: #3a3a3a;
- --pico-primary: #7f9f7f;
- --pico-primary-background: #7f9f7f;
- --pico-primary-hover: #d4888d;
- --pico-primary-hover-background: #d4888d;
- --pico-grid-spacing-horizontal: 0;
-}
-
-body {
- width: 100%;
- height: 100vh;
- display: flex;
- justify-content: center;
- align-items: center;
-}
-
-.container {
- max-width: 500px !important;
- width: 100%;
-}
-
-form {
- padding: 10px;
- background-color: var(--pico-form-element-background-color);
- width: 100%;
-}
-
-input {
- background: var(--pico-form-element-background-color);
- color: white;
- padding: 10px;
- text-align: left;
- font-family: var(--pico-font-family) !important;
- margin-bottom: 0 !important;
-}
-
-input:-webkit-autofill,
-input:-webkit-autofill:hover,
-input:-webkit-autofill:focus,
-input:-webkit-autofill:active {
- -webkit-text-fill-color: white !important;
- transition: background-color 5000s ease-in-out 0s;
- background-color: var(--pico-form-element-background-color) !important;
-}
-
-&:-webkit-autofill::first-line {
- font-family: var(--pico-font-family) !important;
-}
-
-.logo span:first-child {
- color: white;
- font-size: 24px;
- padding-left: 10px;
-}
-
-.logo span:nth-child(2) {
- color: var(--pico-primary-hover);
- font-size: 24px;
-}
-
-.logo {
- padding-top: var(--pico-spacing);
- background-color: var(--pico-form-element-background-color);
-}
-
-label {
- color: white;
- margin-top: 14px;
-}
-
-label:first-of-type {
- margin-top: 0;
-}
-
-label:last-of-type {
- margin-bottom: 14px;
-}
-
-.error-message {
- color: var(--pico-primary-hover);
-}
diff --git a/core/installer/welcome/static/app-manager.js b/core/installer/welcome/static/app-manager.js
deleted file mode 100644
index 55357f3..0000000
--- a/core/installer/welcome/static/app-manager.js
+++ /dev/null
@@ -1,66 +0,0 @@
-function delaySearch(func, wait) {
- let timeout;
- return function (...args) {
- clearTimeout(timeout);
- timeout = setTimeout(() => func.apply(this, args), wait);
- };
-}
-
-document.addEventListener("DOMContentLoaded", function () {
- let searchRequestCount = 0;
- const page = document.documentElement;
- const headerHeight = parseFloat(getComputedStyle(page).getPropertyValue('--pico-header-height').replace("px", ""));
- const nav = document.getElementById("menu");
- const windowHeight = window.innerHeight - headerHeight;
- nav.style.setProperty("--max-height", `${windowHeight}px`);
- const menu = document.getElementById("menu-nav");
- const menuHeight = parseFloat(getComputedStyle(document.getElementById('menu-nav')).height.replace("px", "")) + 15;
- menu.style.setProperty("height", `${menuHeight}px`);
- const searchForm = document.getElementById('search-form');
- const searchInput = document.getElementById('search-input');
- function fetchAndUpdateAppList() {
- searchRequestCount++;
- const currentRequest = searchRequestCount;
- const formData = new FormData(searchForm);
- const query = formData.get('query');
- const pageType = document.getElementById('page-type').value;
- const url = `/${pageType}?query=${encodeURIComponent(query)}`;
- fetch(url, {
- method: 'GET'
- })
- .then(response => response.text())
- .then(html => {
- if (currentRequest !== searchRequestCount) {
- return;
- }
- const tempDiv = document.createElement('div');
- tempDiv.innerHTML = html;
- const newAppListHTML = tempDiv.querySelector('#app-list').innerHTML;
- const appListContainer = document.getElementById("app-list");
- appListContainer.innerHTML = newAppListHTML;
- })
- .catch(error => console.error('Error fetching app list:', error));
- }
- const delayedFetchAndUpdateAppList = delaySearch(fetchAndUpdateAppList, 300);
- searchForm.addEventListener('submit', (event) => {
- event.preventDefault();
- fetchAndUpdateAppList();
- });
- searchInput.addEventListener('input', () => {
- delayedFetchAndUpdateAppList();
- });
-});
-
-let prevWindowHeight = window.innerHeight;
-
-window.addEventListener("resize", function () {
- const nav = document.getElementById("menu");
- const windowHeight = window.innerHeight;
- const heightDiff = prevWindowHeight - windowHeight;
- const currentMaxHeight = parseFloat(nav.style.getPropertyValue("--max-height").replace("px", ""));
- if (!isNaN(currentMaxHeight)) {
- const newMaxHeight = currentMaxHeight - heightDiff;
- nav.style.setProperty("--max-height", `${newMaxHeight}px`);
- }
- prevWindowHeight = windowHeight;
-});
diff --git a/core/installer/welcome/static/appmanager.css b/core/installer/welcome/static/appmanager.css
deleted file mode 100644
index cde49ab..0000000
--- a/core/installer/welcome/static/appmanager.css
+++ /dev/null
@@ -1,329 +0,0 @@
-[data-theme="light"],
-:root:not([data-theme="dark"]) {
- --pico-font-family: Hack, monospace;
- --pico-font-size: 14px;
- --pico-header-height: 56px;
- --pico-border-radius: 0;
- --pico-background-color: #d6d6d6;
- --pico-form-element-border-color: #3a3a3a;
- --pico-form-element-active-border-color: #7f9f7f;
- --pico-form-element-focus-color: #7f9f7f;
- --pico-form-element-background-color: #d6d6d6;
- --pico-form-element-active-background-color: #d6d6d6;
- --pico-form-element-selected-background-color: #d6d6d6;
- --pico-dropdown-color: #3a3a3a;
- --pico-dropdown-background-color: #d6d6d6;
- --pico-dropdown-border-color: #7f9f7f;
- --pico-dropdown-hover-background-color: #7f9f7f;
- --pico-primary: #7f9f7f;
- --pico-primary-background: #7f9f7f;
- --pico-primary-hover: #d4888d;
- --pico-primary-hover-background: #d4888d;
- --pico-grid-spacing-horizontal: 0;
- --search-background-color: #d6d6d6;
- --pico-color: #3a3a3a;
- --pico-form-element-color: #3a3a3a;
- --pico-primary-inverse: #3a3a3a;
- --pico-tooltip-background-color: #3a3a3a;
- --pico-tooltip-color: #d6d6d6;
- --pico-icon-color: #3a3a3a;
- --icon-width: 50px;
- --icon-height: 50px;
- --icon-margin-left: 6px;
- --icon-margin-right: 6px;
- --app-details-padding-right: calc(
- var(--icon-margin-right) + var(--icon-margin-left) + var(--icon-width)
- );
- h3,
- p {
- --pico-color: #3a3a3a;
- }
- label {
- color: var(--pico-color);
- }
- input:is([type="checkbox"]) {
- --pico-form-element-focus-color: none;
- --pico-border-color: var(--pico-color);
- }
- [data-tooltip]:not(a, button, input) {
- text-decoration: none;
- cursor: pointer;
- }
- #menu-nav nav ul li a {
- --pico-primary: #3a3a3a;
- }
- .icon {
- color: var(--pico-icon-color);
- }
-}
-
-@media (max-width: 768px) {
- body > main {
- grid-template-columns: 9rem 1fr !important;
- column-gap: 0 !important;
- }
-
- .container-fluid {
- padding-left: 1px;
- padding-right: 1px;
- margin-left: 0;
- margin-right: 0;
- }
-
- #content {
- width: 100% !important;
- }
-
- .app-details {
- padding-right: 22px !important;
- }
-}
-
-body > header {
- z-index: 4;
- position: relative;
-}
-
-html {
- scroll-behavior: smooth;
- overflow-x: hidden;
-}
-
-body > header.is-fixed-above-lg + main {
- --pico-main-top-offset: var(--pico-header-height);
-}
-
-body > header.is-fixed-above-lg {
- height: var(--pico-header-height);
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: 2;
- position: sticky;
- top: 0;
- -webkit-backdrop-filter: blur(1rem);
- backdrop-filter: blur(1rem);
- background-color: var(--pico-form-element-border-color);
- transition: border-top-color 0.4s ease-in-out, box-shadow 0.4s ease-in-out;
-}
-
-body > main > aside > nav.is-sticky-above-lg {
- position: sticky;
- top: calc(
- var(--pico-main-top-offset) + var(--pico-block-spacing-vertical) / 2
- );
- max-height: calc(var(--max-height) - var(--pico-spacing));
- overflow: auto;
- transition: top var(--pico-transition);
- transition-delay: 50ms;
-}
-
-body > main {
- display: grid;
- grid-template-rows: auto auto 1fr;
- grid-template-columns: 11rem calc(100% - 11rem);
- grid-template-areas: "menu content";
- column-gap: 2rem;
- margin-top: 1rem;
- padding: 0;
-}
-
-header > h1,
-header > svg {
- margin-bottom: 2.5px;
- color: white;
-}
-
-header > svg {
- margin-right: var(--pico-spacing);
-}
-
-.search-bar {
- max-width: 616px;
- width: 100%;
-}
-
-article {
- margin: 0.3em;
- margin-bottom: 0.3em;
- display: flex;
- padding: 6px !important;
- position: relative;
- align-items: flex-start;
-}
-
-.icon {
- margin: 0 var(--icon-margin-right) 0 var(--icon-margin-left);
- flex-shrink: 0;
- /* --pico-primary: #3a3a3a;
- color: var(--pico-color); */
-}
-
-.app-details {
- display: flex;
- flex-direction: column;
- flex-grow: 1;
- position: relative;
- padding-right: var(--app-details-padding-right);
-}
-
-.app-name-container {
- display: flex;
- align-items: center;
- justify-content: space-between;
-}
-
-.app {
- margin-bottom: 2px;
- margin-top: 0px;
- margin-left: 5px;
- font-weight: bold;
- font-size: 16px;
-}
-
-.app-link:hover h3.app,
-.app-link:hover .icon {
- color: var(--pico-primary-hover);
-}
-
-.app-link:hover .app {
- text-decoration: underline;
-}
-.primary:hover {
- text-decoration: underline;
- color: var(--pico-primary-hover);
-}
-
-.description {
- margin: 0 0 3px 5px;
-}
-
-.instance-count {
- display: flex;
- justify-content: center;
- align-items: center;
- width: 22px;
- height: 22px;
- border-radius: 50%;
- font-weight: bold;
- border: 2px solid var(--pico-color) !important;
- position: absolute;
- top: 10px;
- right: 10px;
- transform: translate(50%, -50%);
-}
-
-pre {
- white-space: pre-wrap;
- /* Since CSS 2.1 */
- white-space: -moz-pre-wrap;
- /* Mozilla, since 1999 */
- white-space: -pre-wrap;
- /* Opera 4-6 */
- white-space: -o-pre-wrap;
- /* Opera 7 */
- word-wrap: break-word;
- /* Internet Explorer 5.5+ */
- background-color: transparent;
-}
-
-.hidden {
- visibility: hidden;
-}
-
-.toast {
- position: fixed;
- z-index: 999;
- bottom: 10px;
-}
-
-.app-link {
- padding-top: 0px;
- padding-bottom: 2px;
- text-decoration: none;
- width: 100%;
- padding-right: 0;
-}
-
-nav li {
- padding-top: 0;
- padding-bottom: 0;
-}
-
-nav hr {
- border-color: var(--pico-color);
-}
-
-input[type="search"] {
- margin-bottom: 0;
- height: 100%;
-}
-
-.page {
- display: flex;
- align-items: center;
- flex-direction: column;
-}
-
-.card-content {
- width: 100%;
-}
-
-.app-card {
- margin-bottom: 6px;
-}
-
-nav {
- height: 100%;
-}
-
-#config-form label {
- width: auto !important;
- padding: 0 5px 0 5px;
-}
-
-#config-form > label:nth-of-type(2) label {
- padding-left: 0;
- padding-right: 0;
-}
-
-input[type="checkbox"]:checked {
- border-color: var(--pico-form-element-focus-color) !important;
-}
-
-#menu-nav {
- grid-area: menu;
-}
-
-#content {
- grid-area: content;
- width: calc(100% - 11rem);
-}
-
-main > aside#menu-nav nav {
- margin-bottom: var(--pico-spacing);
- margin-block: calc(var(--pico-outline-width) * -1);
- padding-block: var(--pico-outline-width);
- overflow: auto;
-}
-
-#menu-nav nav ul:first-of-type {
- margin: 0;
- padding: 0;
-}
-
-.progress {
- padding-left: 0;
-}
-
-.progress ul {
- padding-left: 15px;
-}
-
-.progress li {
- list-style-type: none;
-}
-
-.primary {
- color: #7f9f7f;
-}
diff --git a/core/installer/welcome/static/dodo-app.js b/core/installer/welcome/static/dodo-app.js
deleted file mode 100644
index ccb5252..0000000
--- a/core/installer/welcome/static/dodo-app.js
+++ /dev/null
@@ -1,20 +0,0 @@
-function triggerForm(status, buttonTxt) {
- const form = document.getElementById("create-app");
- const elements = form.querySelectorAll("input, select, textarea, button");
- const button = document.getElementById("create-app-button");
- button.textContent = buttonTxt;
- button.setAttribute("aria-busy", status);
- elements.forEach(element => {
- element.disabled = status;
- });
-}
-
-document.addEventListener("DOMContentLoaded", () => {
- const form = document.getElementById("create-app");
- form.addEventListener("submit", (event) => {
- setTimeout(() => {
- triggerForm(true, "creating app ...");
- }, 0);
- });
- triggerForm(false, "create app");
-});
diff --git a/core/installer/welcome/static/dodo_app.css b/core/installer/welcome/static/dodo_app.css
deleted file mode 100644
index 5a66768..0000000
--- a/core/installer/welcome/static/dodo_app.css
+++ /dev/null
@@ -1,104 +0,0 @@
-[data-theme="light"],
-:root:not([data-theme="dark"]) {
- --pico-font-family: Hack, monospace;
- --pico-font-size: 14px;
- --pico-header-height: 56px;
- --pico-border-radius: 0;
- --pico-background-color: #d6d6d6;
- --pico-form-element-border-color: #3a3a3a;
- --pico-form-element-active-border-color: #7f9f7f;
- --pico-form-element-focus-color: #7f9f7f;
- --pico-form-element-background-color: #d6d6d6;
- --pico-form-element-active-background-color: #d6d6d6;
- --pico-form-element-selected-background-color: #d6d6d6;
- --pico-primary: #7f9f7f;
- --pico-primary-background: #7f9f7f;
- --pico-primary-hover: #d4888d;
- --pico-primary-hover-background: #d4888d;
- --pico-grid-spacing-horizontal: 0;
- --search-background-color: #d6d6d6;
- --pico-color: #3a3a3a;
- --pico-form-element-color: #3a3a3a;
- --pico-primary-inverse: #3a3a3a;
- --pico-tooltip-background-color: #3a3a3a;
- --pico-tooltip-color: #d6d6d6;
- --pico-icon-color: #3a3a3a;
- --pico-group-box-shadow-focus-with-button: 0 0 0 0;
- --pico-card-background-color: var(--pico-card-sectioning-background-color);
- p {
- --pico-color: #3a3a3a;
- }
- h1 {
- font-size: 20px;
- --pico-color: #3a3a3a;
- }
- h2 {
- font-size: 18px;
- --pico-color: #3a3a3a;
- }
- h3 {
- font-size: 16px;
- --pico-color: #3a3a3a;
- }
- h4 {
- font-size: 14px;
- --pico-color: #3a3a3a;
- }
- label {
- color: var(--pico-color);
- }
- input:is([type="checkbox"]) {
- --pico-form-element-focus-color: none;
- --pico-border-color: var(--pico-color);
- }
- [data-tooltip]:not(a, button, input) {
- text-decoration: none;
- cursor: pointer;
- }
- hr {
- border-top: 1px solid var(--pico-color);
- }
- :is(button, [type="submit"], [type="button"], [role="button"]).secondary,
- [type="file"]::file-selector-button,
- [type="reset"] {
- --pico-background-color: var(--pico-primary-hover-background);
- --pico-border-color: var(--pico-primary-hover);
- --pico-color: var(--pico-color);
- cursor: pointer;
- }
- #confirm-button:hover {
- background-color: var(--pico-primary);
- border-color: var(--pico-primary);
- }
-}
-
-body.container {
- padding-top: 15px;
-}
-
-@media (min-width: 768px) {
- fieldset.grid {
- grid-template-columns: 1fr 1fr 1fr 200px;
- }
-}
-
-[role="button"][aria-busy="true"],
-[type="button"][aria-busy="true"],
-[type="reset"][aria-busy="true"],
-[type="submit"][aria-busy="true"],
-a[aria-busy="true"],
-button[aria-busy="true"] {
- pointer-events: auto;
-}
-
-input:disabled,
-select:disabled,
-textarea:disabled,
-button:disabled {
- cursor: not-allowed;
-}
-
-.app-info-link {
- width: fit-content;
-}
-
diff --git a/core/installer/welcome/static/hi.txt b/core/installer/welcome/static/hi.txt
deleted file mode 100644
index 45b983b..0000000
--- a/core/installer/welcome/static/hi.txt
+++ /dev/null
@@ -1 +0,0 @@
-hi
diff --git a/core/installer/welcome/static/launcher.css b/core/installer/welcome/static/launcher.css
deleted file mode 100644
index af8b293..0000000
--- a/core/installer/welcome/static/launcher.css
+++ /dev/null
@@ -1,348 +0,0 @@
-:root:not([data-theme]) {
- --pico-background-color: unset;
- --pico-color: unset;
-}
-
-:root {
- --bg: #d6d6d6;
- --bodyBg: #3a3a3a;
- --text: #3a3a3a;
- --formText: #d6d6d6;
- --button: #7f9f7f;
- --logo: #d4888d;
- --fontSize: 14px;
-}
-
-body {
- margin: 0;
- padding: 0;
- font-family: Hack, monospace;
- display: flex;
- height: 100vh;
- padding-left: 0 !important;
- padding-right: 0 !important;
- background-color: var(--bodyBg);
- overflow-x: hidden;
- overflow-y: hidden;
-}
-
-#left-panel {
- width: 80px;
- background-color: var(--bg);
- display: flex;
- flex-direction: column;
- align-items: center;
-}
-
-.app-list {
- display: flex;
- flex-direction: column;
- align-items: center;
- overflow-y: auto;
- overflow-x: hidden;
- padding-top: 3px;
- width: 95% !important;
-}
-
-.scrollbar-custom {
- scrollbar-width: thin;
- scrollbar-color: var(--bodyBg) var(--bg);
-}
-
-.scrollbar-custom::-webkit-scrollbar {
- width: 6px;
-}
-
-.scrollbar-custom::-webkit-scrollbar-track {
- background-color: var(--bg) !important;
-}
-
-.scrollbar-custom::-webkit-scrollbar-thumb {
- background-color: var(--bodyBg) !important;
- border-radius: 4px !important;
-}
-
-.scrollbar-custom::-webkit-scrollbar-thumb:hover {
- background-color: var(--bodyBg);
-}
-
-#right-panel {
- flex: 1;
- background-color: none !important;
- padding: 0 0 0 2px;
-}
-
-.appFrame {
- border-radius: 0;
- width: 100%;
- height: 100%;
- border: 0;
-}
-
-.app-icon {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- width: 80px !important;
- height: 50px !important;
- margin-bottom: 10px !important;
- cursor: pointer !important;
-}
-
-@keyframes pulsate {
- from { opacity: 1; }
- 10% { opacity: 0; }
- 20% { opacity: 1; }
- 30% { opacity: 0; }
- 40% { opacity: 1; }
- 50% { opacity: 0; }
- 60% { opacity: 1; }
- 70% { opacity: 0; }
- 80% { opacity: 1; }
- 90% { opacity: 0; }
- to { opacity: 1; }
-}
-
-@keyframes fadeout {
- /* TODO(gio): figure out why animating from 1 does not work */
- from { opacity: 0.999; }
- to { opacity: 0; }
-}
-
-.pulsate {
- animation: pulsate 5s linear;
-}
-
-.fadeout {
- animation: fadeout 2s ease-in;
-}
-
-.tooltip {
- position: absolute;
- width: 200px;
- left: 80px;
- transform: translateY(-50%);
- background-color: var(--bodyBg);
- padding: 5px;
- z-index: 1;
- display: flex;
- flex-direction: column;
- align-items: center;
- visibility: hidden;
- opacity: 0;
- cursor: auto;
- font-size: 16px;
- box-shadow: 2px 2px 5px var(--bodyBg);
-}
-
-.help-button {
- margin-top: 5px !important;
- padding: 0 !important;
- border: 0 !important;
- margin-bottom: 1px !important;
- width: 100% !important;
- background-color: var(--button) !important;
- color: var(--bodyBg) !important;
- border-radius: 0 !important;
- cursor: pointer !important;
- font-size: 16px !important;
-}
-
-.tooltip p {
- color: var(--formText);
- margin: 0;
- cursor: auto;
- font-size: var(--fontSize);
-}
-
-.app-icon:hover {
- transform: scale(1.15);
-}
-
-.modal-left {
- overflow-y: auto;
- float: left;
- margin-left: 0px;
- padding-right: 10px;
- background-color: #fbfcfc;
- border-radius: 2px;
-}
-
-.modal-right {
- flex: 1;
- overflow-y: auto;
- float: right;
- margin-left: 2px;
- color: var(--bg);
- padding-left: 10px;
- padding-right: 10px;
- font-size: 16px !important;
-}
-
-.app-help-modal {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- flex-direction: column;
- overflow: hidden;
-}
-
-.app-help-modal-article {
- display: flex;
- flex-direction: row;
- width: 100%;
- max-width: 100%;
- min-height: 97%;
- max-height: 97%;
- overflow: hidden;
-}
-
-.app-info-modal-article header {
- flex: 0 0 auto;
-}
-
-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- position: relative;
- margin-bottom: 2px !important;
- background-color: var(--bodyBg) !important;
-}
-
-header h4 {
- color: var(--formText) !important;
- padding-left: 10px;
-}
-
-.close-button {
- padding: 0;
- border: none;
- background: none;
- cursor: pointer;
- outline: none;
- width: 1.5em;
- height: 1.5em;
- position: absolute;
- top: 11px;
- right: 28px;
-}
-
-.modal-article {
- min-width: 80% !important;
- max-width: 80% !important;
- min-height: 90% !important;
- max-height: 90% !important;
- overflow: hidden;
- padding-left: 5px !important;
- padding-right: 5px !important;
-}
-
-.help-content {
- display: none;
-}
-
-.circle {
- width: 50px;
- height: 50px;
- border-radius: 50%;
- background-color: var(--bodyBg);
- display: flex;
- justify-content: center;
- align-items: center;
- margin-top: 2px;
-}
-
-#user-initial {
- font-size: 24px;
- text-align: center;
- line-height: 50px;
- margin: 0;
- position: relative;
- display: inline-block;
- color: var(--logo);
-}
-
-.user-circle {
- min-width: 80px !important;
- max-width: 80px !important;
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.separator {
- margin-top: 2px !important;
- margin-bottom: 4px !important;
- border-width: 2px !important;
- border-color: var(--bodyBg) !important;
- width: 100% !important;
-}
-
-.modal-left ul {
- padding-inline-start: 0px !important;
- margin-bottom: 0px;
- list-style: none;
- font-size: 14px;
-}
-
-.modal-left ul li {
- list-style: none !important;
- padding-inline-start: 10px !important;
- margin-bottom: 0px;
- font-size: 16px !important;
-}
-
-.modal-left ul li a {
- --pico-text-decoration: none;
- cursor: pointer;
-}
-.modal-left ul li a[aria-current] {
- color: var(--pico-primary);
-}
-
-.tooltip-user {
- position: absolute;
- top: 38.7px;
- left: 80px;
- transform: translateY(-50%);
- width: 234px;
- background-color: var(--bodyBg);
- padding: 5px;
- z-index: 1;
- display: flex;
- flex-direction: column;
- align-items: center;
- visibility: hidden;
- opacity: 0;
- cursor: auto;
- box-shadow: 2px 2px 5px var(--bodyBg);
-}
-
-#logout-button {
- margin-top: 5px !important;
- padding: 0 !important;
- border: 0 !important;
- margin-bottom: 5px !important;
- width: 100% !important;
- cursor: pointer !important;
- font-size: 19px !important;
- border-radius: 0;
- background-color: var(--button);
- color: var(--text) !important;
-}
-
-.tooltip-user p {
- color: white;
- margin: 0;
- cursor: auto;
- font-size: 19px;
- color: var(--logo);
-}