Compare commits

...
Sign in to create a new pull request.

19 commits
rust ... main

Author SHA1 Message Date
308b4e1114 Frontend: Added some responsiveness. 2025-06-05 00:12:22 +02:00
9698bf2f43 Backend: config now asks for more information (root url, port, photopath...). Automatically creating compressed in the same folder. Removed FileServer. 2025-06-01 22:53:14 +02:00
3cf03c9b8c Added some gitignore rules. 2025-06-01 19:36:10 +02:00
22bb8cc6d9 Backend: Fixed issue when creating config json file. 2025-06-01 15:12:36 +02:00
e266164530 Added "under construction" for some pages. 2025-06-01 14:33:53 +02:00
16f629df6a Frontend: Fixed an issue when using the photography buttons. 2025-06-01 14:02:01 +02:00
7db9bd0771 Frontend: Fixed some issues with SSR. 2025-06-01 13:55:57 +02:00
0d1e9dfee8 Backend: Added 'ignore_folder' inside the photo path. 2025-06-01 13:23:28 +02:00
3a6213d412 Backend/Frontend: Added all fields for photography section. 2025-06-01 13:16:05 +02:00
7549aa7bea Frontend: Reading from backend pictures. 2025-06-01 12:42:23 +02:00
64818f0970 Backend: Added multiple endpoints to gather pictures: both uncompressed and compressed. 2025-06-01 12:41:59 +02:00
a810fcbd76 Backend: Added 'CompressFiles' function. Optimised 'CompressImage' to check if the file already exists. 2025-05-30 14:19:27 +02:00
fc4326e715 Backend: added 'CompressImage' function. 2025-05-30 12:36:22 +02:00
0f1325bb6f Backend: working REST API. 2025-05-10 11:59:37 +02:00
2156d96ffe CSS: Changed base colors (mainly red and purple) 2025-05-10 11:07:21 +02:00
84d43e1bb0 Backend: Fixed some issues (files reading, config creation...) 2025-05-05 09:57:11 +02:00
9e3a211cba Backend: Fixed error checking and added time check. 2025-05-04 19:01:29 +02:00
9c19c8afae Backend: Added config.go that creates a config file and read the photo path from it. 2025-05-03 22:39:03 +02:00
9e86258588 Backend: Added file reading capabilities. 2025-05-02 12:22:26 +02:00
41 changed files with 1029 additions and 284 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*.service

5
backend/.gitignore vendored
View file

@ -1 +1,4 @@
.env
config.json
.temp/**
.vscode/**
main

119
backend/core/file.go Normal file
View file

@ -0,0 +1,119 @@
package core
import (
"backend/util"
"encoding/json"
"errors"
"io/fs"
"os"
"path/filepath"
"sort"
"strings"
"time"
)
type PictureData struct {
Name string `json:"name"`
Date time.Time `json:"date"`
Album string `json:"album"`
URL string `json:"url"`
URLCompressed string `json:"urlcompressed"`
Title string `json:"title"`
Localisation string `json:"localisation"`
Description string `json:"description"`
}
type PictureJson struct {
Title string `json:"title"`
Localisation string `json:"localisation"`
Description string `json:"description"`
}
var picd []PictureData
func listFiles(path string, actualdir string, picd []PictureData) []PictureData {
entries, err := os.ReadDir(path)
if err != nil {
util.Logformat(util.WARNING, "Could not read files in '%s'\n", path)
return picd
}
for _, entry := range entries {
info, err := entry.Info()
if err != nil {
continue
}
if info.IsDir() && !util.StringInSlice(info.Name(), util.GetConfig().IgnoreFolder) {
// fmt.Printf("\uf07b %s\n", entry.Name())
picd = listFiles(path+"/"+info.Name(), info.Name(), picd)
} else {
// fmt.Printf("\uf15b %s: %do\n", entry.Name(), info.Size())
picd = getFileInfo(path, info, picd, actualdir)
}
}
return picd
}
func isPicture(s string) bool {
extensions := []string{".jpg", ".jpeg", ".jfif", ".pjpeg", ".pjp", ".webp", ".png", ".apng", ".svg", ".avif"}
for _, ext := range extensions {
if strings.HasSuffix(s, ext) {
return true
}
}
return false
}
func getFileInfo(path string, info fs.FileInfo, picd []PictureData, actualdir string) []PictureData {
if isPicture(info.Name()) {
title := strings.TrimSuffix(info.Name(), filepath.Ext(info.Name()))
file, err := os.Open(filepath.Join(path, title+".json"))
var pictureinfo PictureJson
if err == nil {
decoder := json.NewDecoder(file)
decoder.DisallowUnknownFields()
decoder.Decode(&pictureinfo)
}
defer file.Close()
// Setting parameters
if pictureinfo.Title != "" {
title = pictureinfo.Title
}
picd = append(picd, PictureData{
Name: info.Name(),
Date: info.ModTime(),
Album: actualdir,
URL: util.GetURL() + actualdir + "/" + info.Name(),
Title: title,
Localisation: pictureinfo.Localisation,
Description: pictureinfo.Description,
})
util.Logformatrn(util.INFO, "Reading %d files...", len(picd))
}
// Ordering by most recent
sort.Slice(picd, func(i, j int) bool {
return picd[i].Date.After(picd[j].Date) // descending: newer dates first
})
return picd
}
func ListFiles(path string) error {
start := time.Now()
picd = listFiles(path, "", picd)
if len(picd) == 0 {
return errors.New("ListFiles(): Could not gather any file")
} else {
elapsed := time.Since(start)
print("\n")
util.Logformat(util.CORRECT, "Gathered %d files in %dms.\n", len(picd), elapsed.Milliseconds())
return nil
}
}
func GetPictureData() []PictureData {
return picd
}

84
backend/core/img.go Normal file
View file

@ -0,0 +1,84 @@
package core
import (
"backend/util"
"errors"
"image"
"image/jpeg"
"os"
"path/filepath"
"strings"
"time"
"github.com/disintegration/imaging"
)
func CompressImage(path string) (string, error) {
name := strings.TrimSuffix(filepath.Base(path), filepath.Ext(filepath.Base(path))) + "_compressed.jpeg"
basedir := filepath.Join(util.GetConfig().PhotoPath, ".compressed", name)
// Creating folder
if err := os.MkdirAll(filepath.Join(util.GetConfig().PhotoPath, ".compressed"), 0755); err != nil {
return "", err
}
// Checking output file
if _, err := os.Stat(basedir); err == nil {
return name, errors.New("file already created")
}
// Create file
outputFile, err := os.Create(basedir)
if err != nil {
return "", err
}
defer outputFile.Close()
// Opening image + Reducing its size and quality
img, err := imaging.Open(path)
if err != nil {
return "", err
}
width := float64(img.Bounds().Dx())
height := float64(img.Bounds().Dy())
ratio := float64(0)
var imgOutput *image.NRGBA
if width < height {
ratio = height / width
imgOutput = imaging.Resize(img, 320, int(320*ratio), imaging.Lanczos)
} else {
ratio = width / height
imgOutput = imaging.Resize(img, int(320*ratio), 320, imaging.Lanczos)
}
// Encoding to jpeg afterwards
if err := jpeg.Encode(outputFile, imgOutput, &jpeg.Options{Quality: 100}); err != nil {
return "", err
}
return name, nil
}
func CompressFiles() {
picd := GetPictureData()
cfg := util.GetConfig()
count := 0
start := time.Now()
for i := range picd {
path := filepath.Join(cfg.PhotoPath, picd[i].Album, picd[i].Name)
compressed_name, err := CompressImage(path)
if err != nil {
if strings.Compare(err.Error(), "file already created") != 0 {
util.Logformat(util.WARNING, "Failed to compress '%s' : (%v)\n", picd[i].Name, err)
} else {
picd[i].URLCompressed = util.GetURL() + "/.compressed/" + compressed_name
}
} else {
util.Logformatrn(util.INFO, "Compressing %d files...", count)
picd[i].URLCompressed = util.GetURL() + "/.compressed/" + compressed_name
count++
}
}
if count > 0 {
elapsed := time.Since(start)
util.Logformatrn(util.CORRECT, "Compressed %d files in %dms.\n", count, elapsed.Milliseconds())
}
}

View file

@ -1,3 +1,8 @@
module backend
go 1.24.2
go 1.23.6
require (
github.com/disintegration/imaging v1.6.2 // indirect
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 // indirect
)

5
backend/go.sum Normal file
View file

@ -0,0 +1,5 @@
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View file

@ -1,14 +1,40 @@
package main
import (
"backend/core"
"backend/server"
"backend/util"
"errors"
"os"
)
func main() {
// Checking arguments
// Set Log Level
util.SetLevel(util.NOLOG)
// Rest API start on port
server.Start(8085)
cfg, err := util.ReadConfig("config.json")
if err != nil {
if errors.Is(err, os.ErrNotExist) {
util.Logformat(util.INFO, "Creating config file...\n")
util.CreateConfig()
cfg, _ = util.ReadConfig("config.json")
} else {
util.Logformat(util.ERROR, "Could not read configuration file: %s\n", err.Error())
os.Exit(2)
}
}
// Reading files
util.Logformat(util.INFO, "Reading folder '%s'\n", cfg.PhotoPath)
err = core.ListFiles(cfg.PhotoPath)
if err != nil {
util.Logformat(util.ERROR, "%s\n", err.Error())
os.Exit(3)
}
// Compress files
core.CompressFiles()
// Rest API start on port
server.Start(int64(cfg.Port))
}

View file

@ -1,16 +1,38 @@
package server
import (
"backend/core"
"backend/util"
"net/http"
)
func getphoto(w http.ResponseWriter, r *http.Request) {
idStr := r.URL.Query().Get("id")
if idStr == "" {
util.Logformat(util.ERROR, "%s: Missing 'id' parameter.", util.GetFunctionName())
http.Error(w, "Missing or invalid parameters : id", http.StatusBadRequest)
func getphotolist(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
util.Logformat(util.ERROR, "%s: Only GET is accepted (%s received)", util.GetFunctionName(), r.Method)
http.Error(w, "Only GET method is accepted", http.StatusBadRequest)
} else {
sendResponse(w, 0)
sendResponse(w, core.GetPictureData())
}
}
/*
func getphoto(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
util.Logformat(util.ERROR, "%s: Only GET is accepted (%s received)", util.GetFunctionName(), r.Method)
http.Error(w, "Only GET method is accepted", http.StatusBadRequest)
} else {
util_config := util.GetConfig()
http.StripPrefix("/photo/", http.FileServer(http.Dir(util_config.PhotoPath))).ServeHTTP(w, r)
}
}
func getphoto_compressed(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
util.Logformat(util.ERROR, "%s: Only GET is accepted (%s received)", util.GetFunctionName(), r.Method)
http.Error(w, "Only GET method is accepted", http.StatusBadRequest)
} else {
util_config := util.GetConfig()
http.StripPrefix("/photo_compressed/", http.FileServer(http.Dir(util_config.CompressPath))).ServeHTTP(w, r)
}
}
*/

View file

@ -9,7 +9,9 @@ import (
func Start(port int64) {
// Creating endpoints
http.HandleFunc("/getphoto", wrapHeader(getphoto))
http.HandleFunc("/photo_list", wrapHeader(getphotolist))
// http.HandleFunc("/photo/", wrapHeader(getphoto))
// http.HandleFunc("/photo_compressed/", wrapHeader(getphoto_compressed))
util.Logformat(util.INFO, "Starting server on port %d...\n", port)
if err := http.ListenAndServe(":"+strconv.FormatInt(port, 10), nil); err != nil {

117
backend/util/config.go Normal file
View file

@ -0,0 +1,117 @@
package util
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"strconv"
)
type Config struct {
PhotoPath string `json:"photo_path"`
IgnoreFolder []string `json:"ignore_folder"`
Port uint64 `json:"port"`
RootUrl string `json:"root_url"`
}
var main_config Config
func GetConfig() Config {
return main_config
}
func GetURL() string {
if main_config.RootUrl == "http://localhost" {
return "http://localhost" + strconv.FormatUint(main_config.Port, 10)
} else {
return main_config.RootUrl
}
}
func ReadConfig(path string) (Config, error) {
// Gathering photo path
file, err := os.Open(path)
if err != nil {
return main_config, err
}
defer file.Close()
decoder := json.NewDecoder(file)
decoder.DisallowUnknownFields()
err = decoder.Decode(&main_config)
return main_config, err
}
func createConfigFile(cfg Config) {
data, err := json.MarshalIndent(cfg, "", " ")
if err != nil {
panic(err)
}
err = os.WriteFile("config.json", data, 0644)
if err != nil {
panic(err)
}
}
func CreateConfig() {
var cfg Config
println("┌ Please Configure your backend !\n│")
// Checking PhotoPath
println("├\uf03e Enter photo album path \033[90m(press Enter for './')\033[0m")
for {
photopath := InputString("│> ")
if photopath == "" {
photopath = "./"
}
if _, err := os.ReadDir(photopath); err != nil {
fmt.Println("│\033[31m\u2a2f " + err.Error() + "\033[0m")
} else {
fmt.Println("│\033[32m\uf00c Path correct.\033[0m")
cfg.PhotoPath = photopath
fmt.Println("│\033[36m󰑓 Creating '.compressed' folder...\033[0m")
err := os.MkdirAll(filepath.Join(photopath, ".compressed"), 0755)
if err != nil {
fmt.Println("│\033[31m\u2a2f " + err.Error() + "\033[0m")
} else {
fmt.Println("│\033[32m\uf00c Folder created/already exists.\033[0m\n│")
}
cfg.IgnoreFolder = append(cfg.IgnoreFolder, ".compressed")
break
}
}
// Check port
println("├\uf233 Enter the port number for the server \033[90m(press Enter for '8085')\033[0m")
for {
port := InputString("│> ")
if port == "" {
port = "8085"
}
portnum, err := strconv.ParseUint(port, 10, 0)
if err != nil {
fmt.Println("│\033[31m\u2a2f " + err.Error() + "\033[0m")
continue
}
fmt.Println("│\033[32m\uf00c Choosen port: " + port + ".\033[0m\n│")
cfg.Port = portnum
break
}
// Check root URL
println("├󰇧 Enter the root URL for the server \033[90m(press Enter for 'http://localhost')\033[0m")
rootUrl := InputString("│> ")
if rootUrl == "" {
rootUrl = "http://localhost"
}
cfg.RootUrl = rootUrl
// Ending configuration
println("└ Configuration finished !")
createConfigFile(cfg)
}

View file

@ -11,10 +11,13 @@ type LogLevel int
const (
BLUE colorFormat = "\033[34m"
GREEN colorFormat = "\033[32m"
LIGHT_GREEN colorFormat = "\033[92m"
YELLOW colorFormat = "\033[33m"
LIGHT_YELLOW colorFormat = "\033[93m"
RED colorFormat = "\033[31m"
LIGHT_RED colorFormat = "\033[91m"
WHITE colorFormat = "\033[97m"
GREY colorFormat = "\033[90m"
RESET colorFormat = "\033[0m"
)
@ -29,9 +32,9 @@ const (
var colorPrint = map[LogLevel]colorFormat{
NOLOG: "",
INFO: BLUE + "[INFO]" + RESET,
CORRECT: GREEN,
WARNING: YELLOW + "[WARN]",
ERROR: RED + "[ERR.]" + LIGHT_RED,
CORRECT: GREEN + "[OK ]" + LIGHT_GREEN,
WARNING: YELLOW + "[WARN]" + LIGHT_YELLOW,
ERROR: RED + "[ERR ]" + LIGHT_RED,
}
var minimumlog = NOLOG
@ -47,10 +50,24 @@ func Logformat(level LogLevel, format string, args ...interface{}) {
time := fmt.Sprintf("[%02d/%02d/%d %02d:%02d:%02d]", currentTime.Day(), currentTime.Month(), currentTime.Year(), currentTime.Hour(), currentTime.Minute(), currentTime.Second())
if level == NOLOG {
fmt.Printf("%s\t\t%s", time, message)
} else if level != INFO {
fmt.Printf("%s%s\t%s%s", header, time, message, RESET)
} else {
fmt.Printf("%s%s\t%s", header, time, message)
fmt.Printf("%s%s\t%s%s", header, time, message, RESET)
}
}
func Logformatrn(level LogLevel, format string, args ...interface{}) {
if level < minimumlog {
return
}
header := colorPrint[level]
message := fmt.Sprintf(format, args...)
currentTime := time.Now()
time := fmt.Sprintf("[%02d/%02d/%d %02d:%02d:%02d]", currentTime.Day(), currentTime.Month(), currentTime.Year(), currentTime.Hour(), currentTime.Minute(), currentTime.Second())
if level == NOLOG {
fmt.Printf("\r%s\t\t%s", time, message)
} else {
fmt.Printf("\r%s%s\t%s%s", header, time, message, RESET)
}
}

View file

@ -1,7 +1,10 @@
package util
import (
"bufio"
"fmt"
"net/http"
"os"
"runtime"
"strings"
)
@ -16,3 +19,22 @@ func HasSubURI(r *http.Request) (bool, string) {
url := strings.Split(r.URL.Path, "/")
return (len(url[2]) > 0), url[2]
}
func InputString(print string) string {
reader := bufio.NewReader(os.Stdin)
fmt.Print(print)
input, err := reader.ReadString('\n')
if err != nil {
panic(err)
}
return strings.TrimSpace(input)
}
func StringInSlice(s string, list []string) bool {
for _, v := range list {
if v == s {
return true
}
}
return false
}

1
frontend/.gitignore vendored
View file

@ -1,4 +1,5 @@
node_modules
run.sh
# Output
.output

View file

@ -1,24 +1,13 @@
# sv
# Etheryo Frontend
Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli).
## Creating a project
If you're seeing this, you've probably already done this step. Congrats!
```bash
# create a new project in the current directory
npx sv create
# create a new project in my-app
npx sv create my-app
```
*Powered by the Svelte Framework*
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```bash
npm install
npm run dev
# or start the server and open the app in a new browser tab
@ -27,12 +16,10 @@ npm run dev -- --open
## Building
To create a production version of your app:
To create a production version of the app:
```bash
npm install
npm run build
node build
```
You can preview the production build with `npm run preview`.
> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.

View file

@ -10,6 +10,7 @@
"dependencies": {
"@jamescoyle/svelte-icon": "^0.1.1",
"@mdi/js": "^7.4.47",
"@sveltejs/adapter-node": "^5.2.12",
"animejs": "^3.2.2",
"language-map": "^1.5.0",
"svelte2tsx": "^0.7.35"
@ -44,7 +45,6 @@
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -61,7 +61,6 @@
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -78,7 +77,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -95,7 +93,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -112,7 +109,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -129,7 +125,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -146,7 +141,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -163,7 +157,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -180,7 +173,6 @@
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -197,7 +189,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -214,7 +205,6 @@
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -231,7 +221,6 @@
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -248,7 +237,6 @@
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -265,7 +253,6 @@
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -282,7 +269,6 @@
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -299,7 +285,6 @@
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -316,7 +301,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -333,7 +317,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -350,7 +333,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -367,7 +349,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -384,7 +365,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -401,7 +381,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -418,7 +397,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -435,7 +413,6 @@
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -452,7 +429,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -526,9 +502,109 @@
"version": "1.0.0-next.28",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz",
"integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==",
"dev": true,
"license": "MIT"
},
"node_modules/@rollup/plugin-commonjs": {
"version": "28.0.3",
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.3.tgz",
"integrity": "sha512-pyltgilam1QPdn+Zd9gaCfOLcnjMEJ9gV+bTw6/r73INdvzf1ah9zLIJBm+kW7R6IUFIQ1YO+VqZtYxZNWFPEQ==",
"license": "MIT",
"dependencies": {
"@rollup/pluginutils": "^5.0.1",
"commondir": "^1.0.1",
"estree-walker": "^2.0.2",
"fdir": "^6.2.0",
"is-reference": "1.2.1",
"magic-string": "^0.30.3",
"picomatch": "^4.0.2"
},
"engines": {
"node": ">=16.0.0 || 14 >= 14.17"
},
"peerDependencies": {
"rollup": "^2.68.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/plugin-commonjs/node_modules/is-reference": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
"integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
"license": "MIT",
"dependencies": {
"@types/estree": "*"
}
},
"node_modules/@rollup/plugin-json": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz",
"integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==",
"license": "MIT",
"dependencies": {
"@rollup/pluginutils": "^5.1.0"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/plugin-node-resolve": {
"version": "16.0.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.1.tgz",
"integrity": "sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==",
"license": "MIT",
"dependencies": {
"@rollup/pluginutils": "^5.0.1",
"@types/resolve": "1.20.2",
"deepmerge": "^4.2.2",
"is-module": "^1.0.0",
"resolve": "^1.22.1"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^2.78.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/pluginutils": {
"version": "5.1.4",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz",
"integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==",
"license": "MIT",
"dependencies": {
"@types/estree": "^1.0.0",
"estree-walker": "^2.0.2",
"picomatch": "^4.0.2"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.37.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.37.0.tgz",
@ -536,7 +612,6 @@
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -550,7 +625,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -564,7 +638,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -578,7 +651,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -592,7 +664,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -606,7 +677,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -620,7 +690,6 @@
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -634,7 +703,6 @@
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -648,7 +716,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -662,7 +729,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -676,7 +742,6 @@
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -690,7 +755,6 @@
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -704,7 +768,6 @@
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -718,7 +781,6 @@
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -732,7 +794,6 @@
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -746,7 +807,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -760,7 +820,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -774,7 +833,6 @@
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -788,7 +846,6 @@
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -802,7 +859,6 @@
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
@ -818,6 +874,21 @@
"acorn": "^8.9.0"
}
},
"node_modules/@sveltejs/adapter-node": {
"version": "5.2.12",
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-node/-/adapter-node-5.2.12.tgz",
"integrity": "sha512-0bp4Yb3jKIEcZWVcJC/L1xXp9zzJS4hDwfb4VITAkfT4OVdkspSHsx7YhqJDbb2hgLl6R9Vs7VQR+fqIVOxPUQ==",
"license": "MIT",
"dependencies": {
"@rollup/plugin-commonjs": "^28.0.1",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^16.0.0",
"rollup": "^4.9.5"
},
"peerDependencies": {
"@sveltejs/kit": "^2.4.0"
}
},
"node_modules/@sveltejs/adapter-static": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.8.tgz",
@ -832,7 +903,6 @@
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.20.3.tgz",
"integrity": "sha512-z1SQ8qra/kGY3DzarG7xc6XsbKm8UY3SnI82XLI3PqMYWbYj/LpjPWuAz9WA5EyLjFNLD7sOAOEW8Gt4yjr5Vg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/cookie": "^0.6.0",
@ -863,7 +933,6 @@
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-5.0.3.tgz",
"integrity": "sha512-MCFS6CrQDu1yGwspm4qtli0e63vaPCehf6V7pIMP15AsWgMKrqDGCPFF/0kn4SP0ii4aySu4Pa62+fIRGFMjgw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@sveltejs/vite-plugin-svelte-inspector": "^4.0.1",
@ -885,7 +954,6 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-4.0.1.tgz",
"integrity": "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw==",
"dev": true,
"license": "MIT",
"dependencies": {
"debug": "^4.3.7"
@ -903,7 +971,6 @@
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/estree": {
@ -912,6 +979,12 @@
"integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
"license": "MIT"
},
"node_modules/@types/resolve": {
"version": "1.20.2",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
"license": "MIT"
},
"node_modules/acorn": {
"version": "8.14.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
@ -973,11 +1046,16 @@
"node": ">=6"
}
},
"node_modules/commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
"integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
"license": "MIT"
},
"node_modules/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
@ -987,7 +1065,6 @@
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@ -1011,7 +1088,6 @@
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@ -1021,14 +1097,12 @@
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz",
"integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==",
"dev": true,
"license": "MIT"
},
"node_modules/esbuild": {
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz",
"integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
@ -1080,11 +1154,16 @@
"@jridgewell/sourcemap-codec": "^1.4.15"
}
},
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"license": "MIT"
},
"node_modules/fdir": {
"version": "6.4.3",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz",
"integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==",
"dev": true,
"license": "MIT",
"peerDependencies": {
"picomatch": "^3 || ^4"
@ -1099,7 +1178,6 @@
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
@ -1110,17 +1188,58 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/import-meta-resolve": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz",
"integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==",
"dev": true,
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/is-core-module": {
"version": "2.16.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
"license": "MIT",
"dependencies": {
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-module": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
"license": "MIT"
},
"node_modules/is-reference": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz",
@ -1134,7 +1253,6 @@
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
"integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@ -1174,7 +1292,6 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
"integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@ -1184,7 +1301,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
"integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@ -1194,14 +1310,12 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true,
"license": "MIT"
},
"node_modules/nanoid": {
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
"dev": true,
"funding": [
{
"type": "github",
@ -1236,18 +1350,34 @@
"tslib": "^2.0.3"
}
},
"node_modules/path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"license": "MIT"
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/postcss": {
"version": "8.5.3",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
"integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
"dev": true,
"funding": [
{
"type": "opencollective",
@ -1286,11 +1416,30 @@
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/resolve": {
"version": "1.22.10",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
"integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
"license": "MIT",
"dependencies": {
"is-core-module": "^2.16.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
"resolve": "bin/resolve"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/rollup": {
"version": "4.37.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.37.0.tgz",
"integrity": "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/estree": "1.0.6"
@ -1330,14 +1479,12 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
"dev": true,
"license": "MIT"
},
"node_modules/sade": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
"integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
"dev": true,
"license": "MIT",
"dependencies": {
"mri": "^1.1.0"
@ -1350,14 +1497,12 @@
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
"integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
"dev": true,
"license": "MIT"
},
"node_modules/sirv": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.1.tgz",
"integrity": "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@polka/url": "^1.0.0-next.24",
@ -1372,12 +1517,23 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/svelte": {
"version": "5.25.3",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.25.3.tgz",
@ -1445,7 +1601,6 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
"integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@ -1474,7 +1629,6 @@
"version": "6.2.4",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.4.tgz",
"integrity": "sha512-veHMSew8CcRzhL5o8ONjy8gkfmFJAd5Ac16oxBUjlwgX3Gq2Wqr+qNC3TjPIpy7TPV/KporLga5GT9HqdrCizw==",
"dev": true,
"license": "MIT",
"dependencies": {
"esbuild": "^0.25.0",
@ -1546,7 +1700,6 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.0.6.tgz",
"integrity": "sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==",
"dev": true,
"license": "MIT",
"workspaces": [
"tests/deps/*",

View file

@ -23,6 +23,7 @@
"dependencies": {
"@jamescoyle/svelte-icon": "^0.1.1",
"@mdi/js": "^7.4.47",
"@sveltejs/adapter-node": "^5.2.12",
"animejs": "^3.2.2",
"language-map": "^1.5.0",
"svelte2tsx": "^0.7.35"

View file

@ -52,7 +52,7 @@
</div>
<div class="footer-slider align-center ">
<span>2023-{new Date().getFullYear()}{mainjson.footer.copyright}</span>
<div class="flex-end">
<div>
<ButtonSlider
keys={[mainjson.footer.about.name, mainjson.footer.vision.name, mainjson.footer.contact.name]}
on:click={slideText}

View file

@ -135,7 +135,7 @@
</script>
<div
class="overlay-container"
class="overlay-container margin-mobile git-main"
role="button"
tabindex="0"
on:mousemove={(event) => {

View file

@ -48,6 +48,7 @@
easing: "easeInOutQuad",
});
translateValues = translateValues.map((e) => -e);
if (divHoverCardMetadata.localisation) {
anime({
targets: [divHoverCardMetadata.localisation],
opacity: opacityValues,
@ -57,6 +58,7 @@
easing: "easeInOutQuad",
});
}
}
function showPopup() {
popupComponent.set({
@ -101,10 +103,15 @@
bind:this={divHoverCardMetadata.div}
>
<h1 bind:this={divHoverCardMetadata.title}>{title}</h1>
<div bind:this={divHoverCardMetadata.localisation} class="flex align-center">
{#if localisation}
<div
bind:this={divHoverCardMetadata.localisation}
class="flex align-center"
>
<SvgIcon type="mdi" path={mdiMapMarker}></SvgIcon>
<p>{localisation}</p>
</div>
{/if}
</div>
</div>
</div>

View file

@ -6,7 +6,10 @@
import anime from "animejs";
import mainjson from "$lib/json/main.json";
import Search from "$lib/components/search.svelte";
import SvgIcon from "@jamescoyle/svelte-icon";
import { mdiMenuClose } from '@mdi/js';
// import Search from "$lib/components/search.svelte";
const SCROLL = 150;
@ -65,13 +68,17 @@
<svelte:window bind:scrollY on:scroll={changeScroll} />
<!-- Navbar -->
<nav class={scrollY < SCROLL ? "flex-row" : "flex-row floating"}>
<!-- Navbar ONLY DESKTOP -->
<nav
class={scrollY < SCROLL
? "flex-row navbar-full"
: "flex-row navbar-full floating"}
>
<div
role="banner"
class={scrollY < SCROLL
? "disabled"
: "navbar-height flex-row container"}
: "navbar-logo navbar-height flex-row navbar-container"}
>
<div class="navbar-title navbar-content">
<h1 class="title">Etheryo</h1>
@ -80,7 +87,7 @@
<div
role="banner"
class="navbar-height flex-row flex-end container"
class="navbar-height navbar-flex-end navbar-container navbar-overlay"
on:mousemove={(event) => {
update_gradient(event, navbar_category);
}}
@ -91,7 +98,7 @@
animateForeground(false, navbar_category);
}}
>
<div class="navbar-content navbar-categories">
<div class="navbar-content navbar-categories flex-row">
<div>
<a class={isActiveHome(pageUrl)} href="/">{mainjson.tab.hub}</a>
</div>
@ -119,3 +126,8 @@
></div>
</div>
</nav>
<!--
<nav class="flex-row navbar-mobile">
<SvgIcon type="mdi" path={mdiMenuClose}></SvgIcon>
</nav>
-->

View file

@ -1,5 +1,6 @@
<script>
import "$lib/css/person.css";
import "$lib/css/base.css";
import Button from "$lib/components/button.svelte";
import hubjson from "$lib/json/hub.json";
@ -12,19 +13,19 @@
</script>
<div class="flex center">
<div class="person-container flex-row">
<div class="person-picture">
<div class="person-container flex-col-mobile">
<div class="person-picture center-mobile">
<img alt="person" src={picture} />
</div>
<div class="person-content flex-col">
<div class="person-span flex-row">
<div class="person-span w-100 flex-row center-mobile">
<h1>{name}</h1>
{#if pronouns != ""}
<span>{pronouns}</span>
{/if}
</div>
<p>{description}</p>
<div class="flex-row flex-end">
<div class="flex-row person-button center-mobile">
<Button
label={hubjson.person.knowme}
action={() => {

View file

@ -1,6 +1,6 @@
<script>
import "$lib/css/hover-card.css";
import { mdiMapMarker } from '@mdi/js'
import { mdiMapMarker } from "@mdi/js";
import SvgIcon from "@jamescoyle/svelte-icon/src/svg-icon.svelte";
export let title = "";
@ -12,10 +12,13 @@
<div class="hover-card-popup-container flex">
<div class="hover-card-popup-text">
<h1>{title}</h1>
{#if localisation}
<div class="flex align-center">
<SvgIcon type="mdi" path={mdiMapMarker}></SvgIcon>
<span>{localisation}</span>
</div>
{/if}
<p>{description}</p>
</div>
<div class="hover-card-popup-picture">

View file

@ -13,7 +13,7 @@
export let cover =
"https://share.etheryo.fr/rando/2024.07.28/IMG20240728142327.jpg";
export let title = "Title";
export let url = ""
export let url = "";
export let description =
"This is a description, you can add some explaination to your project in here! It can always be interesting to talk about some subtext before going into the subject!";
export let topic = topics.embedded;
@ -72,7 +72,7 @@
role="button"
tabindex="0"
type="button"
class="project-container"
class="project-container margin-mobile"
on:mousemove={(event) => {
update_gradient(event, post_div);
}}

View file

@ -0,0 +1,12 @@
<script>
import "$lib/css/base.css";
import "$lib/css/cover-img.css";
</script>
<div class="flex-row center" style="height:80dvh">
<img style="height:50dvh;" src="/under_construction.png" alt="Under Construction" />
<div class="flex-col section">
<h1>Page under construction !</h1>
<p style="width:auto;">please check it later!</p>
</div>
</div>

View file

@ -33,11 +33,11 @@ h2 {
--color-pill: #D0D4CA;
--palette-pink: #ad62aa;
--palette-red: #9A031E;
--palette-red: #872341;
--palette-orange: #FF5B22;
--palette-yellow: #ff9843;
--palette-green: #0d9276;
--palette-purple: #4B1E78;
--palette-purple: #7c4585;
--palette-brown: #3c2317;
--background-light: linear-gradient(180deg, rgba(248, 241, 241, 1) 0%, rgba(15, 11, 17, 0.1) 100%);
@ -58,21 +58,74 @@ h2 {
--border-max: 2rem;
--profile-content-width-max: 40rem;
--profile-content-width-min: 36rem;
--content-width: 55rem;
--content-height: 29rem;
--content-3-width: calc((var(--content-width) - 2rem)/3);
--width-min-desktop: 1275px;
--width-mobile: 875px;
/* https://clamp.font-size.app/
min=875px max=1100px */
--0-9-rem: clamp(0.7rem, -0.0778rem + 1.4222vw, 0.9rem);
--1-rem: clamp(0.75rem, -0.2222rem + 1.7778vw, 1rem);
--1-1-rem: clamp(0.8rem, -0.3667rem + 2.1333vw, 1.1rem);
--1-2-rem: clamp(0.9rem, -0.2667rem + 2.1333vw, 1.2rem);
--1-4-rem: clamp(1rem, -0.5556rem + 2.8444vw, 1.4rem);
--1-6-rem: clamp(1.2rem, -0.3556rem + 2.8444vw, 1.6rem);
--2-rem: clamp(1.4rem, -0.834rem + 4.0851vw, 2rem);
--2-5-rem: clamp(1.8rem, -0.9222rem + 4.9778vw, 2.5rem);
--max-width-mobile: 700px;
--max-width-tablet: 1275px;
--min-width-desktop: 1275px;
--navbar-height: 6rem;
--transition: all .4s ease 0s;
--content-3-width: calc((var(--content-width) - 2rem)/3);
}
@media screen and (min-width: 975px) {
:root {
--content-width: 55rem;
--content-height: 29rem;
}
}
@media screen and (max-width: 975px) {
:root {
--content-width: 50rem;
--content-height: 25rem;
}
}
@media screen and (min-width: 640px) {
.flex-col-mobile {
display: flex;
align-items: center;
flex-direction: row;
}
.margin-mobile {
margin-left: 1rem;
margin-right: 1rem;
}
:root {
--margin-section: 2rem;
}
}
@media screen and (max-width: 640px) {
.flex-col-mobile {
display: flex;
flex-direction: column;
}
.margin-mobile {
margin-top: 1rem;
margin-bottom: 1rem;
}
:root {
--margin-section: 0;
}
}
.base {
@ -86,7 +139,7 @@ h2 {
font-weight: 700;
cursor: default;
transition: var(--transition);
font-size: 1.5rem;
font-size: var(--1-6-rem);
margin: 0;
}
@ -105,17 +158,22 @@ h2 {
color: var(--color-text);
font-family: Gabarito;
font-weight: 700;
font-size: 2.5rem;
margin: 2rem;
font-size: var(--2-5-rem);
margin: var(--margin-section);
margin-top: 2rem;
margin-bottom: 2rem;
}
.section p {
color: var(--color-subtext);
font-family: "JetBrains Mono";
font-weight: 500;
font-size: 1rem;
margin: 2rem;
width: var(--content-width);
font-size: var(--1-rem);
margin: var(--margin-section);
margin-top: 2rem;
margin-bottom: 2rem;
max-width: var(--content-width);
text-align: justify;
}
.content {

View file

@ -89,5 +89,6 @@
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
line-clamp: 2;
font-size: 1.4rem;
}

View file

@ -30,7 +30,6 @@
}
.cover-img-text h2 {
font-size: 1.1rem;
font-family: 'JetBrains Mono';
color: var(--color-background);
}

View file

@ -4,6 +4,37 @@
--height-footer: 25rem;
}
@media screen and (min-width: 640px) {
.footer-slider div {
margin-left: auto !important;
padding-right: 2rem;
}
.footer-slider>span {
padding-left: 2rem;
}
}
@media screen and (max-width: 640px) {
.footer-left {
min-height: 10rem;
}
.footer-content {
flex-direction: column !important;
height: 100% !important;
}
.footer-slider {
flex-direction: column-reverse;
}
.footer-slider>* {
margin-top: 1rem;
margin-bottom: 1rem;
}
}
.footer-container:before {
content: "";
position: absolute;
@ -20,7 +51,6 @@
flex-direction: column;
margin-top: 3rem;
padding-top: 2rem;
height: var(--height-footer);
background-image: linear-gradient(to right, var(--navbar-dark) 0%, var(--navbar-light) 100%);
box-shadow: rgba(72, 50, 93, 0.2) 0px 120px 60px -20px inset, rgba(0, 0, 0, 0.4) 0px 100px 60px -18px inset;
}
@ -58,15 +88,10 @@
.footer-slider>span {
font-family: 'JetBrains Mono';
padding-left: 2rem;
color: var(--color-hiddentext);
font-size: var(--1-rem);
}
.footer-slider div {
padding-right: 2rem;
}
.footer-page {
min-height: 15rem;
max-height: 15rem;

View file

@ -1,7 +1,11 @@
.git-main {
width: var(--content-3-width);
}
.git-container {
background-color: #00000000;
border-radius: 1rem;
width: var(--content-3-width);
width: auto;
height: 10rem;
cursor: pointer;
overflow: hidden;
@ -19,7 +23,7 @@
.git-container h1 {
font-family: "JetBrains Mono";
font-weight: 800;
font-size: 1.2rem;
font-size: var(--1-2-rem);
margin: 1rem;
margin-top: 0;
}
@ -42,7 +46,7 @@
.git-commit svg {
transform: translate(0) !important;
width: 2rem;
width: var(--2-rem);
margin-left: 0.3rem;
margin-right: 0.3rem;
}
@ -50,7 +54,7 @@
.git-commit p {
color: var(--color-subtext);
font-family: "JetBrains Mono";
font-size: 1rem;
font-size: var(--1-rem);
margin: 0;
margin-left: 0.6rem;
user-select: none;

View file

@ -8,6 +8,68 @@
--navbar-blur: blur(0.6rem);
}
/* Responsive */
@media screen and (min-width: 640px) {
.navbar-flex-end {
margin-left: auto !important;
}
.navbar-height {
height: var(--navbar-height);
padding-left: 0.5rem;
padding-right: 0.5rem;
}
.navbar-categories {
padding-left: 1rem;
padding-right: 1rem;
}
}
/* Little window */
@media screen and (max-width: 640px) {
.navbar-logo {
display: none !important;
}
.navbar-height {
height: var(--navbar-height);
width: 95dvw;
margin-left: 2.5dvw;
margin-right: 2.5dvw;
}
}
/* Mobile */
@media screen and (max-width: 480px) {
.navbar-content {
overflow-x: auto;
white-space: nowrap;
padding-left: 2rem;
padding-right: 2rem;
width: 100% !important;
height: calc(var(--navbar-height)*0.75) !important;
box-sizing: border-box;
}
.navbar-height {
height: calc(var(--navbar-height)*0.75);
width: 100dvw;
padding: 0 !important;
margin: 0 !important;
}
nav {
padding-top: 0 !important;
height: calc(var(--navbar-height)*0.75) !important;
}
.navbar-categories {
justify-content: left !important;
}
}
nav {
height: var(--navbar-height);
width: 100%;
@ -30,7 +92,7 @@ a {
/* Background */
.container {
.navbar-overlay {
display: grid;
grid-template-areas:
"navbar-overlay-back"
@ -59,17 +121,12 @@ a {
.navbar-content {
grid-area: overlay;
z-index: var(--z-index-normal);
z-index: var(--z-index-front);
width: inherit;
display: flex;
}
/* Each element */
.navbar-height {
height: var(--navbar-height);
padding-left: 0.5rem;
padding-right: 0.5rem;
}
.navbar-title {
margin-left: 3rem;
@ -78,9 +135,8 @@ a {
.navbar-categories {
align-items: center;
justify-content: center;
height: var(--navbar-height);
padding-left: 1rem;
padding-right: 1rem;
}
.navbar-categories a {
@ -90,7 +146,6 @@ a {
font-size: 1rem;
transition: var(--transition);
color: var(--color-background);
transition: var(--transition);
}
.navbar-categories div {
@ -152,6 +207,7 @@ a {
padding-top: 0;
-webkit-backdrop-filter: var(--navbar-blur);
backdrop-filter: var(--navbar-blur);
width: 100dvw;
}
.floating>div {

View file

@ -4,8 +4,6 @@
"overlay-back"
"overlay-front"
"overlay";
margin-left: 1rem;
margin-right: 1rem;
}
.overlay {

View file

@ -1,5 +1,27 @@
@media screen and (min-width: 640px) {
:root {
--picture-width: 15rem;
--picture-margin: 3rem;
--span-margin: 1rem;
}
.person-button {
margin-left: auto !important;
}
}
@media screen and (max-width: 640px) {
:root {
--picture-width: 10rem;
--picture-margin: 0;
--span-margin: 0;
}
.center-mobile {
display: flex;
justify-content: center;
align-items: center;
}
}
.person-container {
@ -15,7 +37,7 @@
}
.person-picture {
margin-right: 3rem;
margin-right: var(--picture-margin);
}
.person-content {
@ -24,10 +46,14 @@
width: 100%;
}
.person-span {
width: 100%;
}
.person-span>span {
background-color: var(--color-pill);
margin-left: 1rem;
margin-right: 1rem;
margin-right: var(--span-margin);
padding: 0.5rem;
border-radius: var(--border-min);
font-size: var(--1-2-rem);

View file

@ -1,40 +1,12 @@
@media screen and (max-width: 1275px) {
.project-container {
height: var(--content-height);
width: var(--content-3-width);
}
.project {
height: var(--content-height);
}
}
@media screen and (min-width: 1276px) {
.project-container {
height: var(--content-height);
width: var(--content-3-width);
}
.project {
height: var(--content-height);
}
}
.project img {
height: calc(var(--content-3-width)*3/4);
width: 100%;
}
.project-container {
display: grid;
grid-template-areas:
"post-min-overlay-back"
"post-min-overlay-front"
"project";
margin-left: 1rem;
margin-right: 1rem;
width: 100%;
max-width: var(--content-3-width);
height: var(--content-height);
}
.project {
@ -43,10 +15,11 @@
flex-direction: column;
grid-area: overlay;
z-index: var(--z-index-front);
height: var(--content-height);
}
.project img {
width: auto;
height: calc(var(--content-3-width)*3/4);
width: 100%;
object-fit: cover;
border-top-left-radius: 1rem;
@ -59,11 +32,10 @@
.project h1 {
font-family: 'JetBrains Mono';
font-weight: 800;
font-size: 1.1rem;
font-size: var(--1-1-rem);
margin-left: 1rem;
margin-right: 1rem;
margin-bottom: 0;
user-select: none;
/* Overflow */
overflow: hidden;
display: -webkit-box;
@ -71,13 +43,14 @@
text-overflow: ellipsis;
-webkit-line-clamp: 2;
line-clamp: 2;
}
.project p {
font-family: 'JetBrains Mono';
font-weight: 400;
font-style: italic;
font-size: 0.9rem;
font-size: var(--0-9-rem);
margin-left: 1rem;
margin-right: 1rem;
/* Overflow */
@ -92,6 +65,7 @@
.project span {
font-family: 'JetBrains Mono';
color: var(--color-background);
font-size: var(--0-9-rem);
margin: 0.7rem;
padding: 0;

View file

@ -49,35 +49,5 @@
"photo": {
"title": "Photographie",
"description": "Je ne suis pas un professionnel, mais il faut avouer que prendre des photos, faire du montage dessus, ou simplement régler la colorimétrie fait partie de mes passions. Cette petite galerie montre mes dernières photos, souvent liées à une émotion actuelle."
},
"photos": [
{
"urlcompressed": "https://cloud.etheryo.fr/s/azb63ct3bGn84Da/download?path=&files=IMG20240728150532_compressed.jpg",
"url": "https://share.etheryo.fr/rando/2024.07.28/IMG20240728150532.jpg",
"title": "Tarnished Peak (afterwar)",
"localisation": "Cruach Adrain, Écosse",
"description": "L'appel à l'aventure était trop fort. Je ne voulais plus m'arrêter, mais comme à mon habitude, mon corps ne pouvait suivre mes pensées. Je me suis posé pendant plusieurs minutes devant cette falaise, me demandant ce qu'il y'avait derrière. Les nuages flottants et changeant de place à la vitesse du vent était un reflet de mes émotions qui changeaient."
},
{
"urlcompressed": "https://cloud.etheryo.fr/s/azb63ct3bGn84Da/download?path=&files=IMG20240728142327_compressed.jpg",
"url": "https://share.etheryo.fr/rando/2024.07.28/IMG20240728142327.jpg",
"title": "Whitewashed",
"localisation": "Cruach Adrain, Écosse",
"description": "Photo modifiée pour ajouter cet effet de brume lointaine. Le ciel était bien bleu mais les nuages cachaient cette lumière et laissait paraître une ambiance blanchâtre."
},
{
"urlcompressed": "https://cloud.etheryo.fr/s/azb63ct3bGn84Da/download?path=&files=Groupe%20Ombre%20Lac%20Montagne%20Rouge%20Bleu_compressed.jpg",
"url": "https://share.etheryo.fr/rando/2023.11.01/Groupe%20Ombre%20Lac%20Montagne%20Rouge%20Bleu.jpg",
"title": "Compagnons",
"localisation": "Lac d'Oô, France",
"description": "Lors de notre petit periple avec quelques camarades de l'INSA nous avons décidé de nous balader vers l'autre bout du lac. Cette photo est une prise de vue de loin par ma part de mes camarades, observant leurs divers déplacements devant le coucher du soleil."
},
{
"urlcompressed": "https://cloud.etheryo.fr/s/azb63ct3bGn84Da/download?path=&files=IMG20240728155726_compressed.jpg",
"url": "https://share.etheryo.fr/rando/2024.07.28/IMG20240728155726.jpg",
"title": "Replica",
"localisation": "Cruach Adrain, Écosse",
"description": "'Replca' ou 'Replique' montre la nature fractale des collines écossaises."
}
]
}

View file

@ -0,0 +1,31 @@
// Server Side Rendering
export async function load(context) {
async function fetchData(data) {
try {
const resTemp = await context.fetch(`http://0.0.0.0:8085/${data}`);
if (resTemp.ok == false) {
return {
status: resTemp.status,
}
}
return {
status: 0, data: await resTemp.json(),
}
} catch (error) {
return {
status: 500,
}
}
}
const res = (await fetchData("photo_list"));
if (res.status == 500) return {
status: res.status
}
return {
status: 0,
content: res.data,
};
}

View file

@ -18,7 +18,9 @@
import SvgIcon from "@jamescoyle/svelte-icon/src/svg-icon.svelte";
import { mdiChevronRight, mdiChevronLeft } from "@mdi/js";
let photoList = filterPhotos(hubjson.photos);
export let data;
const photoData = data.status == 0 ? data : undefined;
let photoList = filterPhotos(photoData.content);
$: index = 0;
let photoDiv;
let tempPhotoDiv;
@ -30,6 +32,14 @@
);
}
function backIndex() {
return index - 1 < 0 ? index : index - 1;
}
function advanceIndex() {
return index + 1 > photoList.length - 1 ? index : index + 1;
}
function swipeCanva(advance) {
const width = window.innerWidth / 2;
const animTranslate = advance ? [-width, width] : [width, -width];
@ -44,7 +54,7 @@
duration: 300,
easing: "easeInQuad",
complete: function () {
index = advance ? index + 1 : index - 1;
index = advance ? advanceIndex() : backIndex();
photoDiv.style.transform = `translateX(${animTranslate[1]}px)`;
anime({
targets: photoDiv,
@ -58,6 +68,11 @@
}
</script>
<svelte:head>
<title>Etheryo</title>
</svelte:head>
<div class="main-banner">
<CoverImg
cover={hubjson.cover}
@ -85,7 +100,7 @@
<h1>{hubjson.project.title}</h1>
<p>{hubjson.project.description}</p>
</div>
<div class="flex w-100 justify-center">
<div class="flex w-100 center flex-col-mobile">
{#each hubjson.projects as project, index}
<Project
cover={hubjson.projects[index].cover}
@ -100,7 +115,7 @@
<h1>{hubjson.lab.title}</h1>
<p>{hubjson.lab.description}</p>
</div>
<div class="flex w-100 justify-center">
<div class="flex w-100 center flex-col-mobile">
{#each hubjson.repos as repo}
<Git {repo} />
{/each}

View file

@ -1,16 +1,10 @@
<script>
import "$lib/css/base.css";
import "$lib/css/main.css";
import UnderConstruction from "$lib/components/under_construction.svelte";
</script>
<div class="main-banner">
<div class="main-banner-gradient"></div>
<div class="main-banner-content">
<div
class="flex-row center"
style="padding-top: 15rem;padding-bottom: 15rem;"
>
<h1>About</h1>
</div>
</div>
<UnderConstruction/>
</div>

View file

@ -1,19 +1,13 @@
<script>
import "$lib/css/base.css";
import "$lib/css/main.css";
import UnderConstruction from "$lib/components/under_construction.svelte";
export let data;
// export let data;
</script>
<div class="main-banner">
<div class="main-banner-gradient"></div>
<div class="main-banner-content">
<div
class="flex-col center"
style="padding-top: 15rem;padding-bottom: 15rem;"
>
<h1>Project</h1>
<h2>{data.project}</h2>
</div>
</div>
<UnderConstruction />
<!-- <p>Project Name: {data.project}</p> -->
</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

View file

@ -1,4 +1,4 @@
import adapter from '@sveltejs/adapter-static';
import adapter from '@sveltejs/adapter-node';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
const config = {