From f3c20a8237a9913e1b37c862742feb2d6b378e01 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 7 Sep 2024 05:54:06 +0200 Subject: [PATCH] heroweb --- authdb/acls/mainacl.toml | 4 +- authserver/authdb/acls/mainacl.toml | 9 + authserver/authdb/acls/myacl.toml | 5 + authserver/authdb/groups/admins.toml | 3 + authserver/authdb/groups/moreusers.toml | 3 + authserver/authdb/info/boardinfo.toml | 5 + authserver/authdb/info/myinfo.toml | 5 + .../authdb/users/mariobassem12@gmail.com.toml | 4 + .../authdb/users/user2@example.com.toml | 4 + authserver/authdb/users/user@example.com.toml | 4 + authserver/group_test.py | 56 +- authserver/main.py | 100 ++- authserver/run.sh | 5 +- authserver/utils/model.py | 68 +- infoserver/frontend/package-lock.json | 694 ++++++++++++++++++ infoserver/frontend/package.json | 18 + infoserver/frontend/public/index.html | 0 infoserver/frontend/src/App.svelte | 0 infoserver/frontend/src/main.js | 7 + infoserver/server.py | 0 package-lock.json | 248 +++++++ package.json | 7 + poc/server.py | 41 +- svelte/.npmrc | 1 + svelte/myfiles/package-lock.json | 18 +- svelte/myfiles/package.json | 3 +- svelte/package-lock.json | 69 +- svelte/package.json | 4 +- 28 files changed, 1313 insertions(+), 72 deletions(-) create mode 100644 authserver/authdb/acls/mainacl.toml create mode 100644 authserver/authdb/acls/myacl.toml create mode 100644 authserver/authdb/groups/admins.toml create mode 100644 authserver/authdb/groups/moreusers.toml create mode 100644 authserver/authdb/info/boardinfo.toml create mode 100644 authserver/authdb/info/myinfo.toml create mode 100644 authserver/authdb/users/mariobassem12@gmail.com.toml create mode 100644 authserver/authdb/users/user2@example.com.toml create mode 100644 authserver/authdb/users/user@example.com.toml mode change 100644 => 100755 authserver/run.sh create mode 100644 infoserver/frontend/package-lock.json create mode 100644 infoserver/frontend/package.json create mode 100644 infoserver/frontend/public/index.html create mode 100644 infoserver/frontend/src/App.svelte create mode 100644 infoserver/frontend/src/main.js create mode 100644 infoserver/server.py create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 svelte/.npmrc diff --git a/authdb/acls/mainacl.toml b/authdb/acls/mainacl.toml index 45ee0e8..cf87684 100644 --- a/authdb/acls/mainacl.toml +++ b/authdb/acls/mainacl.toml @@ -1,9 +1,9 @@ name = "mainacl" [[entries]] user = "user@example.com" -right = [ "w", "r", "i", "t", "e",] +right = "write" [[entries]] group = "admins" -right = [ "a", "d", "m", "i", "n",] +right = "admin" diff --git a/authserver/authdb/acls/mainacl.toml b/authserver/authdb/acls/mainacl.toml new file mode 100644 index 0000000..cf87684 --- /dev/null +++ b/authserver/authdb/acls/mainacl.toml @@ -0,0 +1,9 @@ +name = "mainacl" +[[entries]] +user = "user@example.com" +right = "write" + +[[entries]] +group = "admins" +right = "admin" + diff --git a/authserver/authdb/acls/myacl.toml b/authserver/authdb/acls/myacl.toml new file mode 100644 index 0000000..cfcd14d --- /dev/null +++ b/authserver/authdb/acls/myacl.toml @@ -0,0 +1,5 @@ +name = "myacl" +[[entries]] +user = "mariobassem12@gmail.com" +right = "read" + diff --git a/authserver/authdb/groups/admins.toml b/authserver/authdb/groups/admins.toml new file mode 100644 index 0000000..3b26a87 --- /dev/null +++ b/authserver/authdb/groups/admins.toml @@ -0,0 +1,3 @@ +name = "admins" +users = [ "user@example.com", "user2@example.com",] +groups = [] diff --git a/authserver/authdb/groups/moreusers.toml b/authserver/authdb/groups/moreusers.toml new file mode 100644 index 0000000..78a514a --- /dev/null +++ b/authserver/authdb/groups/moreusers.toml @@ -0,0 +1,3 @@ +name = "moreusers" +users = [ "user@example.com",] +groups = [ "admins",] diff --git a/authserver/authdb/info/boardinfo.toml b/authserver/authdb/info/boardinfo.toml new file mode 100644 index 0000000..ffdc4f6 --- /dev/null +++ b/authserver/authdb/info/boardinfo.toml @@ -0,0 +1,5 @@ +name = "boardinfo" +path = "/tmp" +acl = [ "mainacl",] +description = "Important file" +expiration = "2025-01-01" diff --git a/authserver/authdb/info/myinfo.toml b/authserver/authdb/info/myinfo.toml new file mode 100644 index 0000000..3f5f78d --- /dev/null +++ b/authserver/authdb/info/myinfo.toml @@ -0,0 +1,5 @@ +name = "myinfo" +path = "/tmp/dir1" +acl = [ "myacl",] +description = "Not Important" +expiration = "2025-01-01" diff --git a/authserver/authdb/users/mariobassem12@gmail.com.toml b/authserver/authdb/users/mariobassem12@gmail.com.toml new file mode 100644 index 0000000..937f512 --- /dev/null +++ b/authserver/authdb/users/mariobassem12@gmail.com.toml @@ -0,0 +1,4 @@ +email = "mariobassem12@gmail.com" +description = "Test user 3" +profile = "Profile data 3" +admin = false diff --git a/authserver/authdb/users/user2@example.com.toml b/authserver/authdb/users/user2@example.com.toml new file mode 100644 index 0000000..25f9c6a --- /dev/null +++ b/authserver/authdb/users/user2@example.com.toml @@ -0,0 +1,4 @@ +email = "user2@example.com" +description = "Test user 2" +profile = "Profile data 2" +admin = false diff --git a/authserver/authdb/users/user@example.com.toml b/authserver/authdb/users/user@example.com.toml new file mode 100644 index 0000000..d8ab504 --- /dev/null +++ b/authserver/authdb/users/user@example.com.toml @@ -0,0 +1,4 @@ +email = "user@example.com" +description = "Test user" +profile = "Profile data" +admin = false diff --git a/authserver/group_test.py b/authserver/group_test.py index 9532de8..047b0fc 100644 --- a/authserver/group_test.py +++ b/authserver/group_test.py @@ -1,11 +1,22 @@ from utils.model import FileSystemDatabase, User, Group, ACE, ACL, Info, RightEnum -db = FileSystemDatabase("authdb",reset=True) +db = FileSystemDatabase("authdb", reset=True) # Create a user and save it -user1 = db.user_set(User(email="user@example.com", description="Test user", profile="Profile data")) -user2 = db.user_set(User(email="user2@example.com", description="Test user 2", profile="Profile data 2")) +user1 = db.user_set( + User(email="user@example.com", description="Test user", profile="Profile data") +) +user2 = db.user_set( + User(email="user2@example.com", description="Test user 2", profile="Profile data 2") +) +user3 = db.user_set( + User( + email="mariobassem12@gmail.com", + description="Test user 3", + profile="Profile data 3", + ) +) # Load a user loaded_user = db.user_get("user@example.com") @@ -35,13 +46,42 @@ all_groups = db.group_list() print(all_groups) # Create an ACL and Info object and save it -acl = db.acl_set(ACL(name="MainACL", entries=[ - ACE(user=user1.email, right=RightEnum.write), - ACE(group="admins", right=RightEnum.admin)] -)) -info = Info(name="BoardInfo", path="/tmp", acl=[acl.name], description="Important file", expiration="2025-01-01") +acl = db.acl_set( + ACL( + name="MainACL", + entries=[ + ACE(user=user1.email, right=RightEnum.write), + ACE(group="admins", right=RightEnum.admin), + ], + ) +) + +info = Info( + name="BoardInfo", + path="/tmp", + acl=[acl.name], + description="Important file", + expiration="2025-01-01", +) db.info_set(info) +acl = db.acl_set( + ACL( + name="myACL", + entries=[ + ACE(user=user3.email, right=RightEnum.read), + ], + ) +) + +info = Info( + name="myinfo", + path="/tmp/dir1", + acl=[acl.name], + description="Not Important", + expiration="2025-01-01", +) +db.info_set(info) # Load an info object diff --git a/authserver/main.py b/authserver/main.py index a7e5ea7..47b13b8 100644 --- a/authserver/main.py +++ b/authserver/main.py @@ -1,5 +1,5 @@ from fastapi import FastAPI, Form, Request, Depends, HTTPException -from fastapi.responses import HTMLResponse, RedirectResponse, FileResponse +from fastapi.responses import HTMLResponse, RedirectResponse, FileResponse, JSONResponse from fastapi_mail import FastMail, MessageSchema, ConnectionConfig from fastapi.templating import Jinja2Templates import jwt @@ -10,8 +10,10 @@ from pydantic import BaseModel, EmailStr from starlette.middleware.sessions import SessionMiddleware from starlette.responses import Response from utils.auth import create_access_token, verify_access_token -from utils.model import FileSystemDatabase, ObjNotFound +from utils.model import FileSystemDatabase, ObjNotFound, Info, ACE, RightEnum import os +import uvicorn +from typing import List # Initialize FastAPI app app = FastAPI() @@ -26,9 +28,9 @@ conf = ConnectionConfig( MAIL_FROM="info@threefold.me", MAIL_PORT=587, MAIL_SERVER="smtp-relay.brevo.com", - MAIL_STARTTLS=True, # This replaces MAIL_TLS - MAIL_SSL_TLS=False, # This replaces MAIL_SSL - USE_CREDENTIALS=True + MAIL_STARTTLS=True, # This replaces MAIL_TLS + MAIL_SSL_TLS=False, # This replaces MAIL_SSL + USE_CREDENTIALS=True, ) # Jinja2 templates for rendering HTML @@ -39,13 +41,33 @@ ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 30 # Initialize FileSystemDatabase -fs_db = FileSystemDatabase(base_dir="data") +fs_db = FileSystemDatabase(base_dir="authdb") + + +@app.middleware("http") +async def check_authentication(request: Request, call_next): + if request.url.path in ["/signup", "/loginsubmit", "/register"]: + return await call_next(request) + + token = request.cookies.get("access_token") + if not token: + return RedirectResponse(url="/signup") + + try: + email = verify_access_token(token) + except PyJWTError: + return RedirectResponse(url="/signup") + + request.state.email = email + return await call_next(request) + # Step 1: Render login page to accept email @app.get("/", response_class=HTMLResponse) async def login_form(request: Request): return RedirectResponse(url="/signup") + @app.get("/signup", response_class=HTMLResponse) async def login_form(request: Request): return templates.TemplateResponse("login.html", {"request": request}) @@ -63,14 +85,16 @@ async def send_login_email(request: Request, email: str = Form(...)): email_link = f"http://verse.tf:8000/register?token={access_token}" # Render the email template with the email link - rendered_template = templates.get_template("email.html").render({"email_link": email_link}) + rendered_template = templates.get_template("email.html").render( + {"email_link": email_link} + ) # Create the email message message = MessageSchema( subject="Login to your account", recipients=[email], # List of recipient emails body=rendered_template, # The rendered HTML content - subtype="html" # Specify the subtype as HTML + subtype="html", # Specify the subtype as HTML ) # Send the email @@ -79,6 +103,7 @@ async def send_login_email(request: Request, email: str = Form(...)): return {"message": "Login link has been sent to your email."} + # Step 3: Handle email link redirection and set JWT in cookies @app.get("/register") async def register(request: Request, token: str): @@ -91,23 +116,53 @@ async def register(request: Request, token: str): response.set_cookie(key="access_token", value=token) return response + # Step 4: User info page, read JWT from cookies @app.get("/info", response_class=HTMLResponse) async def get_user_info(request: Request): token = request.cookies.get("access_token") if not token: - #raise HTTPException(status_code=401, detail="Not authenticated") + # raise HTTPException(status_code=401, detail="Not authenticated") return RedirectResponse(url="/signup") try: email = verify_access_token(token) except PyJWTError: - #raise HTTPException(status_code=401, detail="Invalid token") + # raise HTTPException(status_code=401, detail="Invalid token") return RedirectResponse(url="/signup") return templates.TemplateResponse("info.html", {"request": request, "email": email}) +@app.get("/{infoname}", response_class=HTMLResponse) +async def list_dir(request: Request, infoname: str): + try: + info = fs_db.info_get(infoname) + except ObjNotFound: + raise HTTPException(status_code=404, detail="Info not found") + + user_email = request.state.email + try: + user_ace = get_user_ace(info, user_email) + # no need to check for access rights since this is reading + + except Exception: + raise HTTPException(status_code=401, detail="Unauthorized") + + list_dir = os.listdir(info.path) + return JSONResponse({"dir": list_dir}) + + +def get_user_ace(info: Info, user: str) -> ACE: + for acl_str in info.acl: + acl = fs_db.acl_get(acl_str) + for entry in acl.entries: + if entry.user == user: + return entry + + raise Exception(f"user {user} not authorized") + + @app.get("/{infoname}/{relative_path:path}", response_class=HTMLResponse) async def serve_file(request: Request, infoname: str, relative_path: str): try: @@ -115,11 +170,26 @@ async def serve_file(request: Request, infoname: str, relative_path: str): except ObjNotFound: raise HTTPException(status_code=404, detail="Info not found") - file_path = os.path.join(info.path, relative_path) - if not os.path.exists(file_path): + user_email = request.state.email + try: + user_ace = get_user_ace(info, user_email) + # no need to check for access rights since this is reading + + except Exception: + raise HTTPException(status_code=401, detail="Unauthorized") + + new_path = os.path.join(info.path, relative_path) + if not os.path.exists(new_path): raise HTTPException(status_code=404, detail="File not found") - if file_path.endswith(".pdf"): - return templates.TemplateResponse("pdf_viewer.html", {"request": request, "pdf_url": f"/static/{relative_path}"}) + if os.path.isdir(new_path): + list_dir = os.listdir(new_path) + return JSONResponse({"dir": list_dir}) + + if new_path.endswith(".pdf"): + return templates.TemplateResponse( + "pdf_viewer.html", + {"request": request, "pdf_url": f"/static/{relative_path}"}, + ) else: - return FileResponse(file_path) + return FileResponse(new_path) diff --git a/authserver/run.sh b/authserver/run.sh old mode 100644 new mode 100755 index 2600e31..05dd693 --- a/authserver/run.sh +++ b/authserver/run.sh @@ -1,2 +1,3 @@ - -uvicorn main:app --host 0.0.0.0 --port 8000 --reload \ No newline at end of file +pushd /root/code/git.ourworld.tf/freeflowuniverse/heroweb/authserver +uvicorn main:app --host 0.0.0.0 --port 8000 --reload +popd \ No newline at end of file diff --git a/authserver/utils/model.py b/authserver/utils/model.py index 270e392..f8802ca 100644 --- a/authserver/utils/model.py +++ b/authserver/utils/model.py @@ -1,18 +1,22 @@ -from pydantic import BaseModel,validator -from typing import List, Union +from pydantic import BaseModel, validator, model_serializer +from typing import List, Union, Dict, Any from enum import Enum import os import toml from pathlib import Path from typing import Optional + class ObjNotFound(Exception): """Exception raised when an object is not found in the database.""" + pass + def name_fix(name: str) -> str: return name.strip().replace(" ", "_").lower() + # Enum for the ACE rights class RightEnum(str, Enum): read = "read" @@ -26,10 +30,14 @@ class ACE(BaseModel): user: Optional[str] = None # User email, optional right: RightEnum # The access right (read, write, admin) - @validator('right', pre=True) + @model_serializer + def ser_model(self) -> Dict[str, Any]: + return {"group": self.group, "user": self.user, "right": self.right.name} + + @validator("right", pre=True) def validate_right(cls, value): if isinstance(value, list): - value = ''.join(value) + value = "".join(value) return RightEnum(value) @@ -39,11 +47,10 @@ class ACL(BaseModel): entries: List[ACE] # List of ACEs (Access Control Entries) - # User model class User(BaseModel): email: str # User's email (used as a key) - description: str = "" # User's description + description: str = "" # User's description profile: str = "" # User's profile admin: bool = False # Admin flag, default to False @@ -51,9 +58,10 @@ class User(BaseModel): # Group model class Group(BaseModel): name: str # Group name - users: List[str] = [] # List of user emails + users: List[str] = [] # List of user emails groups: List[str] = [] # List of group names + # Info model class Info(BaseModel): name: str # Name of the information @@ -62,6 +70,7 @@ class Info(BaseModel): description: str # Description of the information expiration: str # Expiration date (as string) + class InfoMem(BaseModel): name: str # Name of the information path: str # Path to the resource @@ -75,6 +84,7 @@ User.update_forward_refs() Group.update_forward_refs() ACE.update_forward_refs() + class FileSystemDatabase: def __init__(self, base_dir: str, reset: bool = False): self.base_dir = Path(base_dir) @@ -107,7 +117,9 @@ class FileSystemDatabase: def load_all_data(self): acls = {acl_name: self.acl_get(acl_name) for acl_name in self.acl_list()} - users = {user_email: self.user_get(user_email) for user_email in self.user_list()} + users = { + user_email: self.user_get(user_email) for user_email in self.user_list() + } infos = {info_name: self.info_get(info_name) for info_name in self.info_list()} self.info_mem_dict = {} @@ -129,7 +141,7 @@ class FileSystemDatabase: admin_emails.add(entry.user) if entry.group: group = self.group_get(entry.group) - for member in group.members: + for member in group.users: if member in users: if entry.right == RightEnum.read: read_emails.add(member) @@ -143,11 +155,11 @@ class FileSystemDatabase: path=info.path, read=list(read_emails), write=list(write_emails), - admin=list(admin_emails) + admin=list(admin_emails), ) # --- USER METHODS --- - def admin_check(self,current_user: User): + def admin_check(self, current_user: User): if not current_user.admin: raise PermissionError("Only admin users can perform this action.") @@ -162,9 +174,11 @@ class FileSystemDatabase: group_path = self.groups_dir / f"{user.email}.toml" if group_path.exists(): - raise ValueError(f"A group with the name {user.email} already exists, cannot create a user with the same name.") + raise ValueError( + f"A group with the name {user.email} already exists, cannot create a user with the same name." + ) - with open(user_path, 'w') as f: + with open(user_path, "w") as f: toml.dump(user.dict(), f) return user @@ -174,7 +188,7 @@ class FileSystemDatabase: if not user_path.exists(): raise ObjNotFound(f"User with email {email} not found.") - with open(user_path, 'r') as f: + with open(user_path, "r") as f: user_data = toml.load(f) return User(**user_data) @@ -193,7 +207,9 @@ class FileSystemDatabase: user_path = self.users_dir / f"{group.name}.toml" if user_path.exists(): - raise ValueError(f"A user with the name {group.name} already exists. Cannot create a group with the same name.") + raise ValueError( + f"A user with the name {group.name} already exists. Cannot create a group with the same name." + ) # Check that all mentioned users and groups exist for user_email in group.users: @@ -204,7 +220,7 @@ class FileSystemDatabase: if not self.group_exists(group_name): raise ObjNotFound(f"Group with name {group_name} not found.") - with open(group_path, 'w') as f: + with open(group_path, "w") as f: toml.dump(group.dict(), f) return group @@ -213,7 +229,7 @@ class FileSystemDatabase: group_path = self.groups_dir / f"{name}.toml" if not group_path.exists(): raise ObjNotFound(f"Group with name {name} not found.") - with open(group_path, 'r') as f: + with open(group_path, "r") as f: group_data = toml.load(f) return Group(**group_data) @@ -236,7 +252,7 @@ class FileSystemDatabase: raise ObjNotFound(f"ACL with name {acl_name} not found.") info_path = self.info_dir / f"{info.name}.toml" - with open(info_path, 'w') as f: + with open(info_path, "w") as f: toml.dump(info.dict(), f) return info @@ -245,7 +261,7 @@ class FileSystemDatabase: info_path = self.info_dir / f"{name}.toml" if not info_path.exists(): raise ObjNotFound(f"Info with name {name} not found.") - with open(info_path, 'r') as f: + with open(info_path, "r") as f: info_data = toml.load(f) return Info(**info_data) @@ -260,12 +276,14 @@ class FileSystemDatabase: def acl_set(self, acl: ACL) -> ACL: acl.name = name_fix(acl.name) + acl.entries = [ ACE( group=name_fix(entry.group) if entry.group else None, user=name_fix(entry.user) if entry.user else None, - right=entry.right - ) for entry in acl.entries + right=entry.right, + ) + for entry in acl.entries ] # Check that all mentioned users and groups exist @@ -276,8 +294,10 @@ class FileSystemDatabase: raise ObjNotFound(f"Group with name {entry.group} not found.") acl_path = self.acl_dir / f"{acl.name}.toml" - with open(acl_path, 'w') as f: - toml.dump(acl.dict(), f) + with open(acl_path, "w") as f: + # print(f"my acl: {acl.model_dump()}") + # print(f"toml dump: {toml.dumps(acl.model_dump())}") + toml.dump(acl.model_dump(), f) return acl def acl_get(self, acl_name: str) -> ACL: @@ -285,7 +305,7 @@ class FileSystemDatabase: acl_path = self.acl_dir / f"{acl_name}.toml" if not acl_path.exists(): raise ObjNotFound(f"ACL with name {acl_name} not found.") - with open(acl_path, 'r') as f: + with open(acl_path, "r") as f: acl_data = toml.load(f) return ACL(**acl_data) diff --git a/infoserver/frontend/package-lock.json b/infoserver/frontend/package-lock.json new file mode 100644 index 0000000..bf84500 --- /dev/null +++ b/infoserver/frontend/package-lock.json @@ -0,0 +1,694 @@ +{ + "name": "frontend", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "frontend", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@smui/button": "^7.0.0", + "@smui/circular-progress": "^7.0.0", + "@smui/icon-button": "^7.0.0", + "@smui/list": "^7.0.0", + "@smui/textfield": "^7.0.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "peer": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "peer": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@material/animation": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/animation/-/animation-14.0.0.tgz", + "integrity": "sha512-VlYSfUaIj/BBVtRZI8Gv0VvzikFf+XgK0Zdgsok5c1v5DDnNz5tpB8mnGrveWz0rHbp1X4+CWLKrTwNmjrw3Xw==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/base": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/base/-/base-14.0.0.tgz", + "integrity": "sha512-Ou7vS7n1H4Y10MUZyYAbt6H0t67c6urxoCgeVT7M38aQlaNUwFMODp7KT/myjYz2YULfhu3PtfSV3Sltgac9mA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/button": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/button/-/button-14.0.0.tgz", + "integrity": "sha512-dqqHaJq0peyXBZupFzCjmvScrfljyVU66ZCS3oldsaaj5iz8sn33I/45Z4zPzdR5F5z8ExToHkRcXhakj1UEAA==", + "dependencies": { + "@material/density": "^14.0.0", + "@material/dom": "^14.0.0", + "@material/elevation": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/focus-ring": "^14.0.0", + "@material/ripple": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/shape": "^14.0.0", + "@material/theme": "^14.0.0", + "@material/tokens": "^14.0.0", + "@material/touch-target": "^14.0.0", + "@material/typography": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/circular-progress": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/circular-progress/-/circular-progress-14.0.0.tgz", + "integrity": "sha512-7EdkP6ty54g6qs6zzlsw29vWlUyrcSWr9b4pGGx4D/iNJww+eyxXZ07iWoNOr4uLgguauWEft2axpQiFCwFD0g==", + "dependencies": { + "@material/animation": "^14.0.0", + "@material/base": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/progress-indicator": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/theme": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/density": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/density/-/density-14.0.0.tgz", + "integrity": "sha512-NlxXBV5XjNsKd8UXF4K/+fOXLxoFNecKbsaQO6O2u+iG8QBfFreKRmkhEBb2hPPwC3w8nrODwXX0lHV+toICQw==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/dom": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/dom/-/dom-14.0.0.tgz", + "integrity": "sha512-8t88XyacclTj8qsIw9q0vEj4PI2KVncLoIsIMzwuMx49P2FZg6TsLjor262MI3Qs00UWAifuLMrhnOnfyrbe7Q==", + "dependencies": { + "@material/feature-targeting": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/elevation": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/elevation/-/elevation-14.0.0.tgz", + "integrity": "sha512-Di3tkxTpXwvf1GJUmaC8rd+zVh5dB2SWMBGagL4+kT8UmjSISif/OPRGuGnXs3QhF6nmEjkdC0ijdZLcYQkepw==", + "dependencies": { + "@material/animation": "^14.0.0", + "@material/base": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/theme": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/feature-targeting": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-14.0.0.tgz", + "integrity": "sha512-a5WGgHEq5lJeeNL5yevtgoZjBjXWy6+klfVWQEh8oyix/rMJygGgO7gEc52uv8fB8uAIoYEB3iBMOv8jRq8FeA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/floating-label": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/floating-label/-/floating-label-14.0.0.tgz", + "integrity": "sha512-Aq8BboP1sbNnOtsV72AfaYirHyOrQ/GKFoLrZ1Jt+ZGIAuXPETcj9z7nQDznst0ZeKcz420PxNn9tsybTbeL/Q==", + "dependencies": { + "@material/animation": "^14.0.0", + "@material/base": "^14.0.0", + "@material/dom": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/theme": "^14.0.0", + "@material/typography": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/focus-ring": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/focus-ring/-/focus-ring-14.0.0.tgz", + "integrity": "sha512-fqqka6iSfQGJG3Le48RxPCtnOiaLGPDPikhktGbxlyW9srBVMgeCiONfHM7IT/1eu80O0Y67Lh/4ohu5+C+VAQ==", + "dependencies": { + "@material/dom": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/rtl": "^14.0.0" + } + }, + "node_modules/@material/icon-button": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/icon-button/-/icon-button-14.0.0.tgz", + "integrity": "sha512-wHMqzm7Q/UwbWLoWv32Li1r2iVYxadIrwTNxT0+p+7NdfI3lEwMN3NoB0CvoJnHTljjXDzce0KJ3nZloa0P0gA==", + "dependencies": { + "@material/base": "^14.0.0", + "@material/density": "^14.0.0", + "@material/dom": "^14.0.0", + "@material/elevation": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/focus-ring": "^14.0.0", + "@material/ripple": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/theme": "^14.0.0", + "@material/touch-target": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/line-ripple": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/line-ripple/-/line-ripple-14.0.0.tgz", + "integrity": "sha512-Rx9eSnfp3FcsNz4O+fobNNq2PSm5tYHC3hRpY2ZK3ghTvgp3Y40/soaGEi/Vdg0F7jJXRaBSNOe6p5t9CVfy8Q==", + "dependencies": { + "@material/animation": "^14.0.0", + "@material/base": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/theme": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/list": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/list/-/list-14.0.0.tgz", + "integrity": "sha512-AFaBGV9vQyfnG8BT2R3UGVdF5w2SigQqBH+qbOSxQhk4BgVvhDfJUIKT415poLNMdnaDtcuYz+ZWvVNoRDaL7w==", + "dependencies": { + "@material/base": "^14.0.0", + "@material/density": "^14.0.0", + "@material/dom": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/ripple": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/shape": "^14.0.0", + "@material/theme": "^14.0.0", + "@material/typography": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/notched-outline": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/notched-outline/-/notched-outline-14.0.0.tgz", + "integrity": "sha512-6S58DlWmhCDr4RQF2RuwqANxlmLdHtWy2mF4JQLD9WOiCg4qY9eCQnMXu3Tbhr7f/nOZ0vzc7AtA3vfJoZmCSw==", + "dependencies": { + "@material/base": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/floating-label": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/shape": "^14.0.0", + "@material/theme": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/progress-indicator": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/progress-indicator/-/progress-indicator-14.0.0.tgz", + "integrity": "sha512-09JRTuIySxs670Tcy4jVlqCUbyrO+Ad6z3nHnAi8pYl74duco4n/9jTROV0mlFdr9NIFifnd08lKbiFLDmfJGQ==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/ripple": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-14.0.0.tgz", + "integrity": "sha512-9XoGBFd5JhFgELgW7pqtiLy+CnCIcV2s9cQ2BWbOQeA8faX9UZIDUx/g76nHLZ7UzKFtsULJxZTwORmsEt2zvw==", + "dependencies": { + "@material/animation": "^14.0.0", + "@material/base": "^14.0.0", + "@material/dom": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/theme": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/rtl": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-14.0.0.tgz", + "integrity": "sha512-xl6OZYyRjuiW2hmbjV2omMV8sQtfmKAjeWnD1RMiAPLCTyOW9Lh/PYYnXjxUrNa0cRwIIbOn5J7OYXokja8puA==", + "dependencies": { + "@material/theme": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/shape": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/shape/-/shape-14.0.0.tgz", + "integrity": "sha512-o0mJB0+feOv473KckI8gFnUo8IQAaEA6ynXzw3VIYFjPi48pJwrxa0mZcJP/OoTXrCbDzDeFJfDPXEmRioBb9A==", + "dependencies": { + "@material/feature-targeting": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/theme": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/textfield": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/textfield/-/textfield-14.0.0.tgz", + "integrity": "sha512-HGbtAlvlIB2vWBq85yw5wQeeP3Kndl6Z0TJzQ6piVtcfdl2mPyWhuuVHQRRAOis3rCIaAAaxCQYYTJh8wIi0XQ==", + "dependencies": { + "@material/animation": "^14.0.0", + "@material/base": "^14.0.0", + "@material/density": "^14.0.0", + "@material/dom": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/floating-label": "^14.0.0", + "@material/line-ripple": "^14.0.0", + "@material/notched-outline": "^14.0.0", + "@material/ripple": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/shape": "^14.0.0", + "@material/theme": "^14.0.0", + "@material/tokens": "^14.0.0", + "@material/typography": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/theme": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/theme/-/theme-14.0.0.tgz", + "integrity": "sha512-6/SENWNIFuXzeHMPHrYwbsXKgkvCtWuzzQ3cUu4UEt3KcQ5YpViazIM6h8ByYKZP8A9d8QpkJ0WGX5btGDcVoA==", + "dependencies": { + "@material/feature-targeting": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/tokens": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/tokens/-/tokens-14.0.0.tgz", + "integrity": "sha512-SXgB9VwsKW4DFkHmJfDIS0x0cGdMWC1D06m6z/WQQ5P5j6/m0pKrbHVlrLzXcRjau+mFhXGvj/KyPo9Pp/Rc8Q==", + "dependencies": { + "@material/elevation": "^14.0.0" + } + }, + "node_modules/@material/touch-target": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/touch-target/-/touch-target-14.0.0.tgz", + "integrity": "sha512-o3kvxmS4HkmZoQTvtzLJrqSG+ezYXkyINm3Uiwio1PTg67pDgK5FRwInkz0VNaWPcw9+5jqjUQGjuZMtjQMq8w==", + "dependencies": { + "@material/base": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/rtl": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/typography": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/typography/-/typography-14.0.0.tgz", + "integrity": "sha512-/QtHBYiTR+TPMryM/CT386B2WlAQf/Ae32V324Z7P40gHLKY/YBXx7FDutAWZFeOerq/two4Nd2aAHBcMM2wMw==", + "dependencies": { + "@material/feature-targeting": "^14.0.0", + "@material/theme": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@smui/button": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@smui/button/-/button-7.0.0.tgz", + "integrity": "sha512-T1WK03HlOecrufoO4Z/W1dXC/R+VLqrwmBcIVQwqN0TiwUdHDfeCa1TjrqroLn9eJUe73T/O3Abh9b2Nttz77g==", + "dependencies": { + "@material/button": "^14.0.0", + "@material/elevation": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/ripple": "^14.0.0", + "@material/shape": "^14.0.0", + "@material/theme": "^14.0.0", + "@smui/common": "^7.0.0", + "@smui/ripple": "^7.0.0", + "svelte2tsx": "^0.7.8" + } + }, + "node_modules/@smui/circular-progress": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@smui/circular-progress/-/circular-progress-7.0.0.tgz", + "integrity": "sha512-n6YpMM5VRJ8qBNdbDsNz32CcXESZdNfgsgBNO8Nx7Gq3S0vIglkzHryRQCnKsQA1WN9Tm4lyU0Rafwfb3oWn3w==", + "dependencies": { + "@material/circular-progress": "^14.0.0", + "@smui/common": "^7.0.0", + "svelte2tsx": "^0.7.8" + } + }, + "node_modules/@smui/common": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@smui/common/-/common-7.0.0.tgz", + "integrity": "sha512-/JUf25KMIDLFNfiuMSMs2g7dEZZFUnDJDxpbT3FlGEY/HKoEf0W9GnbmIOzPje1wxW9ajKHN2SIYDPx9so1vnw==", + "dependencies": { + "@material/dom": "^14.0.0", + "svelte2tsx": "^0.7.8" + } + }, + "node_modules/@smui/floating-label": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@smui/floating-label/-/floating-label-7.0.0.tgz", + "integrity": "sha512-XHm8fNURqQqPnu+TFPIWuD7NtQIfdT2tv0eiyU+1g9Df1pH9pAVWixTiBaj5HKeky1u99+vFJNBslQS2qTxGhg==", + "dependencies": { + "@material/floating-label": "^14.0.0", + "@smui/common": "^7.0.0", + "svelte2tsx": "^0.7.8" + } + }, + "node_modules/@smui/icon-button": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@smui/icon-button/-/icon-button-7.0.0.tgz", + "integrity": "sha512-SlcmGTW027X44O2QERC5fCZB1zLDsy9k5Cn+ohM0woSFNV3pIlrWtCyYFr1ariRiT8NTF1ScMdW70y8YgK9ikA==", + "dependencies": { + "@material/density": "^14.0.0", + "@material/icon-button": "^14.0.0", + "@smui/common": "^7.0.0", + "@smui/ripple": "^7.0.0", + "svelte2tsx": "^0.7.8" + } + }, + "node_modules/@smui/line-ripple": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@smui/line-ripple/-/line-ripple-7.0.0.tgz", + "integrity": "sha512-Mm5B8xci4SglMehp404veVu3zGlZVHViiYsNPpypaG+4aOrK0dVgBrd1YgqyXHKFSHOama/Olwe2E2YbkQvxlw==", + "dependencies": { + "@material/line-ripple": "^14.0.0", + "@smui/common": "^7.0.0", + "svelte2tsx": "^0.7.8" + } + }, + "node_modules/@smui/list": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@smui/list/-/list-7.0.0.tgz", + "integrity": "sha512-kZnpfbkFtIs9vZCr2xxDTO5Dcdj6WAtGa+82sN5zGg6hC5q8KMGKOxNIFdTz2hw5a6Bg//Zg2mK5AB4tVM4LBw==", + "dependencies": { + "@material/dom": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/list": "^14.0.0", + "@smui/common": "^7.0.0", + "@smui/ripple": "^7.0.0", + "svelte2tsx": "^0.7.8" + } + }, + "node_modules/@smui/notched-outline": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@smui/notched-outline/-/notched-outline-7.0.0.tgz", + "integrity": "sha512-pE0yWIO0K9wrU+LIbBXCBYJUo1+qq5jiLTFVJEoyLqB7jtl438sylXpti9aLyB9DG5V8rbkNCkyNxyq4ZVhmlw==", + "dependencies": { + "@material/notched-outline": "^14.0.0", + "@smui/common": "^7.0.0", + "@smui/floating-label": "^7.0.0", + "svelte2tsx": "^0.7.8" + } + }, + "node_modules/@smui/ripple": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@smui/ripple/-/ripple-7.0.0.tgz", + "integrity": "sha512-N42jqgLOleOj3fU1BnkTPbjtWpisp8x9oUgF32SDkVh48ih8J8+/xQ1W5g28WrNDErjSu9G4DTcYN6BJYOng3Q==", + "dependencies": { + "@material/dom": "^14.0.0", + "@material/ripple": "^14.0.0", + "@smui/common": "^7.0.0", + "svelte2tsx": "^0.7.8" + } + }, + "node_modules/@smui/textfield": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@smui/textfield/-/textfield-7.0.0.tgz", + "integrity": "sha512-3p/pipFrj6xuA6YUhIEHf4fxInMENI3EFHVYeF1wU0vERSojtqBw+NnAscgv/PHKv4X6nFY3ZvD/9cVf7S4frA==", + "dependencies": { + "@material/dom": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/ripple": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/textfield": "^14.0.0", + "@smui/common": "^7.0.0", + "@smui/floating-label": "^7.0.0", + "@smui/line-ripple": "^7.0.0", + "@smui/notched-outline": "^7.0.0", + "@smui/ripple": "^7.0.0", + "svelte2tsx": "^0.7.8" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "peer": true + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "peer": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/code-red": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", + "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", + "peer": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "@types/estree": "^1.0.1", + "acorn": "^8.10.0", + "estree-walker": "^3.0.3", + "periscopic": "^3.1.0" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "peer": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/dedent-js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dedent-js/-/dedent-js-1.0.1.tgz", + "integrity": "sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "peer": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "peer": true, + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "peer": true + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/magic-string": { + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", + "peer": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "peer": true + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "peer": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/svelte": { + "version": "4.2.19", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.19.tgz", + "integrity": "sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==", + "peer": true, + "dependencies": { + "@ampproject/remapping": "^2.2.1", + "@jridgewell/sourcemap-codec": "^1.4.15", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/estree": "^1.0.1", + "acorn": "^8.9.0", + "aria-query": "^5.3.0", + "axobject-query": "^4.0.0", + "code-red": "^1.0.3", + "css-tree": "^2.3.1", + "estree-walker": "^3.0.3", + "is-reference": "^3.0.1", + "locate-character": "^3.0.0", + "magic-string": "^0.30.4", + "periscopic": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/svelte2tsx": { + "version": "0.7.18", + "resolved": "https://registry.npmjs.org/svelte2tsx/-/svelte2tsx-0.7.18.tgz", + "integrity": "sha512-PCOhH7uQaV472ZvNAcnkvShjFRMMkKUc/eNJImQMH9T4CyHeQpdatedFrEjaMCsweFb/oo3a6bv4qtdfaCPw8g==", + "dependencies": { + "dedent-js": "^1.0.1", + "pascal-case": "^3.1.1" + }, + "peerDependencies": { + "svelte": "^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0", + "typescript": "^4.9.4 || ^5.0.0" + } + }, + "node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + } + } +} diff --git a/infoserver/frontend/package.json b/infoserver/frontend/package.json new file mode 100644 index 0000000..b66203d --- /dev/null +++ b/infoserver/frontend/package.json @@ -0,0 +1,18 @@ +{ + "name": "frontend", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "@smui/button": "^7.0.0", + "@smui/circular-progress": "^7.0.0", + "@smui/icon-button": "^7.0.0", + "@smui/list": "^7.0.0", + "@smui/textfield": "^7.0.0" + } +} diff --git a/infoserver/frontend/public/index.html b/infoserver/frontend/public/index.html new file mode 100644 index 0000000..e69de29 diff --git a/infoserver/frontend/src/App.svelte b/infoserver/frontend/src/App.svelte new file mode 100644 index 0000000..e69de29 diff --git a/infoserver/frontend/src/main.js b/infoserver/frontend/src/main.js new file mode 100644 index 0000000..54ede6a --- /dev/null +++ b/infoserver/frontend/src/main.js @@ -0,0 +1,7 @@ +import App from './App.svelte'; + +const app = new App({ + target: document.body +}); + +export default app; \ No newline at end of file diff --git a/infoserver/server.py b/infoserver/server.py new file mode 100644 index 0000000..e69de29 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..f12f860 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,248 @@ +{ + "name": "heroweb", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@wx/trial-svelte-filemanager": "^1.0.1", + "@wx/trial-svelte-gantt": "^1.0.1", + "@wx/trial-svelte-grid": "^1.2.0" + } + }, + "node_modules/@wx/core-locales": { + "version": "1.2.1", + "resolved": "https://npm.svar.dev/@wx%2fcore-locales/-/core-locales-1.2.1.tgz", + "integrity": "sha512-8c+6sEGoFkPr5WC8BfvAM+d0FLoJll48WNu/lUftSytFTIBWfOrO/QbP9/9LKSGL0TMJc4YA2t4bZCnhiCDNGg==", + "license": "MIT" + }, + "node_modules/@wx/filemanager-data-provider": { + "version": "1.0.1", + "resolved": "https://npm.svar.dev/@wx%2ffilemanager-data-provider/-/filemanager-data-provider-1.0.1.tgz", + "integrity": "sha512-wy3wyNFvN0b4/XiACYMeMIkRhE2Ivog8SpSmKqZk0hxmmxKmtMRlBtcbWIi6onTKZVhEQ5sxSU1m9gSxaSRiKQ==", + "license": "MIT", + "dependencies": { + "@wx/lib-data-provider": "^1.3.2" + } + }, + "node_modules/@wx/filemanager-locales": { + "version": "1.0.1", + "resolved": "https://npm.svar.dev/@wx%2ffilemanager-locales/-/filemanager-locales-1.0.1.tgz", + "integrity": "sha512-1YZAn0SzcLqEtNMyrBsW75jcMWImynON6ie/JRzVNOS7QKe0PqACQ6e7HRw0APW1rmZ7dj5esr87GjmBRpdC+A==", + "license": "MIT" + }, + "node_modules/@wx/gantt-data-provider": { + "version": "1.0.1", + "resolved": "https://npm.svar.dev/@wx%2fgantt-data-provider/-/gantt-data-provider-1.0.1.tgz", + "integrity": "sha512-oa4ytrV1xnhA2AQ32Nx2I89aBC+xeoOsd7q29XgZXyPWaTT0Z6C7yxpenQznuXCG+xxW9c/r5/v4z/05VUzH5Q==", + "license": "MIT", + "dependencies": { + "@wx/lib-data-provider": "^1.3.2", + "date-fns": "^3.3.1" + } + }, + "node_modules/@wx/gantt-locales": { + "version": "1.0.1", + "resolved": "https://npm.svar.dev/@wx%2fgantt-locales/-/gantt-locales-1.0.1.tgz", + "integrity": "sha512-MopJQENo68NClU/6oWJCJfLCJIRK+YV+rmG8tY4gK/ADvISh6yTvIW4t7pw1s22FOlKJK5aaNa8I5u8I6Y+XBg==", + "license": "MIT" + }, + "node_modules/@wx/grid-data-provider": { + "version": "1.2.0", + "resolved": "https://npm.svar.dev/@wx%2fgrid-data-provider/-/grid-data-provider-1.2.0.tgz", + "integrity": "sha512-5shfZY7+HOIgF1UCdeRK2ayp8ItsnK+CPQvcejvILaFVGEVCgJM6aXmXT3AZua5fXvQrQReXuFdtn8btBiIGPA==", + "license": "MIT", + "dependencies": { + "@wx/lib-data-provider": "^1.3.2" + } + }, + "node_modules/@wx/grid-locales": { + "version": "1.2.0", + "resolved": "https://npm.svar.dev/@wx%2fgrid-locales/-/grid-locales-1.2.0.tgz", + "integrity": "sha512-1IuD4fUueh5Kt5s3m7uT2+VIRhlmJVJc94PrWL/HA845RmSv/eGBlpLbYhdndexyEdvU1l2yZe/9smsYIsqIlw==", + "license": "MIT" + }, + "node_modules/@wx/lib-data-provider": { + "version": "1.3.2", + "resolved": "https://npm.svar.dev/@wx%2flib-data-provider/-/lib-data-provider-1.3.2.tgz", + "integrity": "sha512-sidsCqz3TuhyFWH6thh/wQpffNKMjJO1DpMnr8BDCR2RqpiKBt5dYUMKDpG/TaO0YhWaEE/6Nkyg1ZpQsZZW6A==", + "license": "MIT", + "dependencies": { + "@wx/lib-state": "^1.7.0" + } + }, + "node_modules/@wx/lib-dom": { + "version": "0.5.2", + "resolved": "https://npm.svar.dev/@wx%2flib-dom/-/lib-dom-0.5.2.tgz", + "integrity": "sha512-V3TOMRiJiAwoGGAw6vjGmmPKOAr98ZQUEKWracAjeNfdcFnbXoTxmZL7A0+ydZ7pUq1MztdTXbYTFtIc/mQ2YQ==", + "license": "MIT" + }, + "node_modules/@wx/lib-state": { + "version": "1.8.1", + "resolved": "https://npm.svar.dev/@wx%2flib-state/-/lib-state-1.8.1.tgz", + "integrity": "sha512-ZQTkO+gWuT5QDDpLZHs6F80wquDWoQuds4sb3iB7vWnoK4pdhn8kg8inLK5a/exSydH55/XegEs+rEuziKtPsA==", + "license": "MIT" + }, + "node_modules/@wx/lib-svelte": { + "version": "0.2.1", + "resolved": "https://npm.svar.dev/@wx%2flib-svelte/-/lib-svelte-0.2.1.tgz", + "integrity": "sha512-DRhV+QAYg0zXOXulB10TX5t+RF8HY6/b3NBwv0G1/peAmR1BgWS3tHdtwZ/aRazOZSjENHS+Qkiu/rF1nUGM4w==", + "license": "MIT", + "peerDependencies": { + "svelte": "^3.0.0" + } + }, + "node_modules/@wx/svelte-core": { + "version": "1.2.1", + "resolved": "https://npm.svar.dev/@wx%2fsvelte-core/-/svelte-core-1.2.1.tgz", + "integrity": "sha512-dyBKbkDgEXlvuO8RwRFtq346zP/LTqb6g/cTjyHnVM172ksaO3CmVLcky+D2FtTVSNa9Jo48vFGsJzoSV3/3BQ==", + "license": "MIT", + "dependencies": { + "@wx/core-locales": "1.2.1", + "@wx/lib-dom": "0.5.2" + } + }, + "node_modules/@wx/svelte-menu": { + "version": "1.2.1", + "resolved": "https://npm.svar.dev/@wx%2fsvelte-menu/-/svelte-menu-1.2.1.tgz", + "integrity": "sha512-01sw75MQy3zVgWHVnNEvvKY6Z01xkCnjN6d0Izo4LlZsHmrl7nLjhj3jMcLLhq6NG3k8thJzLTmE/mioV0OLUw==", + "license": "MIT", + "dependencies": { + "@wx/lib-dom": "0.5.2", + "@wx/svelte-core": "1.2.1" + } + }, + "node_modules/@wx/svelte-toolbar": { + "version": "1.2.2", + "resolved": "https://npm.svar.dev/@wx%2fsvelte-toolbar/-/svelte-toolbar-1.2.2.tgz", + "integrity": "sha512-+JbtVaXNCflz1ccb6576Z1RLJlzR+0ykyAgpHa/KmteSAkPwVyjDy1VPfJrGUEWIxCkmjsiyQo/FYx5ixvQ7RA==", + "license": "MIT", + "dependencies": { + "@wx/lib-dom": "0.5.2", + "@wx/svelte-core": "1.2.1" + } + }, + "node_modules/@wx/svelte-uploader": { + "version": "0.1.0", + "resolved": "https://npm.svar.dev/@wx%2fsvelte-uploader/-/svelte-uploader-0.1.0.tgz", + "integrity": "sha512-y52yhnjSkaS1MMe0BEjonHVQ30ZC8K5EO7Y9+y4DiVLZmJvYfIkmykRZdBU6WiGPz/Mi/fV10fEAlvUXMPFlBg==", + "license": "MIT", + "dependencies": { + "@wx/lib-dom": "^0.5.0" + } + }, + "node_modules/@wx/trial-filemanager-store": { + "version": "1.0.1", + "resolved": "https://npm.svar.dev/@wx%2ftrial-filemanager-store/-/trial-filemanager-store-1.0.1.tgz", + "integrity": "sha512-1mvg3Idg6PX29/eDO73LwYCefq8HGOdj5HOm1wtqT0FzwsiaDilAHyO+V9zNZ2g9s4T6NV39BfW987M4c2B7tg==", + "license": "UNLICENSED", + "dependencies": { + "@wx/lib-state": "^1.7.1" + } + }, + "node_modules/@wx/trial-gantt-store": { + "version": "1.0.1", + "resolved": "https://npm.svar.dev/@wx%2ftrial-gantt-store/-/trial-gantt-store-1.0.1.tgz", + "integrity": "sha512-OuGLhqq/cU1bajvKZc92gjPBoMnlP5OJK18O1ZneLUpeentkTdz0p0+FdhF032Jv3kg+JJJ+AyG0Y6Jy3DCJbQ==", + "license": "UNLICENSED", + "dependencies": { + "@wx/lib-state": "^1.7.1", + "date-fns": "^3.3.1" + } + }, + "node_modules/@wx/trial-grid-store": { + "version": "1.2.0", + "resolved": "https://npm.svar.dev/@wx%2ftrial-grid-store/-/trial-grid-store-1.2.0.tgz", + "integrity": "sha512-9OmDndMClnyrbFxESI9u1csZai9WAAs5BrlNuoiz0ua0ECrn1i6YRT7shFrBQhinWOYjfWDqgkj3McWGpkf1vw==", + "license": "UNLICENSED", + "dependencies": { + "@wx/lib-state": "^1.8.0" + } + }, + "node_modules/@wx/trial-svelte-filemanager": { + "version": "1.0.1", + "resolved": "https://npm.svar.dev/@wx%2ftrial-svelte-filemanager/-/trial-svelte-filemanager-1.0.1.tgz", + "integrity": "sha512-LSqHl1DHjYQFAhN1C+yGxI16O0zJEta/WJOACC6BBLnHnsrCb8ab6bLRu2YENcr+uiWvjuxWqzh7l85h9mrDxg==", + "license": "SEE LICENSE IN license.txt", + "dependencies": { + "@wx/filemanager-data-provider": "1.0.1", + "@wx/filemanager-locales": "1.0.1", + "@wx/lib-dom": "^0.5.0", + "@wx/lib-state": "^1.7.1", + "@wx/lib-svelte": "^0.2.0", + "@wx/svelte-core": "^1.1.1", + "@wx/svelte-menu": "^1.1.2", + "@wx/svelte-uploader": "^0.1.0", + "@wx/trial-filemanager-store": "1.0.1", + "@wx/trial-svelte-grid": "^1.1.2" + } + }, + "node_modules/@wx/trial-svelte-gantt": { + "version": "1.0.1", + "resolved": "https://npm.svar.dev/@wx%2ftrial-svelte-gantt/-/trial-svelte-gantt-1.0.1.tgz", + "integrity": "sha512-MjFxX+nvzfHVOsh0anf8LBI1IWBSHncb4+kk7pzUoPStbjMrRUf3nL1hdV6Uzgssiz60k6EkTM4nA5bBkuNr9w==", + "license": "SEE LICENSE IN license.txt", + "dependencies": { + "@wx/gantt-data-provider": "1.0.1", + "@wx/gantt-locales": "1.0.1", + "@wx/lib-dom": "^0.5.0", + "@wx/lib-state": "^1.7.1", + "@wx/lib-svelte": "^0.2.1", + "@wx/svelte-core": "^1.1.0", + "@wx/svelte-menu": "^1.1.2", + "@wx/svelte-toolbar": "^1.1.0", + "@wx/trial-gantt-store": "1.0.1", + "@wx/trial-svelte-grid": "^1.1.2" + } + }, + "node_modules/@wx/trial-svelte-grid": { + "version": "1.2.0", + "resolved": "https://npm.svar.dev/@wx%2ftrial-svelte-grid/-/trial-svelte-grid-1.2.0.tgz", + "integrity": "sha512-2M9d6UAxOcBaEpU1nT8XTA9idajY1X6m7+UqVJ4LlD6Bmsd/Jp/QBksy3qeqXwQqgEkMLgnEL/HFaMwN4vtD6g==", + "license": "SEE LICENSE IN license.txt", + "dependencies": { + "@wx/grid-data-provider": "1.2.0", + "@wx/grid-locales": "1.2.0", + "@wx/lib-dom": "0.5.2", + "@wx/lib-state": "1.8.0", + "@wx/lib-svelte": "0.3.0", + "@wx/svelte-core": "1.2.1", + "@wx/svelte-menu": "1.2.1", + "@wx/trial-grid-store": "1.2.0" + } + }, + "node_modules/@wx/trial-svelte-grid/node_modules/@wx/lib-state": { + "version": "1.8.0", + "resolved": "https://npm.svar.dev/@wx%2flib-state/-/lib-state-1.8.0.tgz", + "integrity": "sha512-LhhFETSYE+ytPvmpBG35IuVekFq6gcSq61+DZ4EZSO27ofERh0Ih5+d0wo2srtcBp30SqbnXWalpNWFy2pCx/g==", + "license": "MIT" + }, + "node_modules/@wx/trial-svelte-grid/node_modules/@wx/lib-svelte": { + "version": "0.3.0", + "resolved": "https://npm.svar.dev/@wx%2flib-svelte/-/lib-svelte-0.3.0.tgz", + "integrity": "sha512-z+oov/sfW0XT1Jyzwo0DuDYBqWuizctjmkvSewAIubryNM/O6Tj1HQTUYI4Tc70Byu+QRAhanht/qyddHRNShg==", + "license": "MIT", + "peerDependencies": { + "svelte": "^3.0.0" + } + }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, + "node_modules/svelte": { + "version": "3.59.2", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.2.tgz", + "integrity": "sha512-vzSyuGr3eEoAtT/A6bmajosJZIUWySzY2CzB3w2pgPvnkUjGqlDnsNnA0PMO+mMAhuyMul6C2uuZzY6ELSkzyA==", + "peer": true, + "engines": { + "node": ">= 8" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..37c9530 --- /dev/null +++ b/package.json @@ -0,0 +1,7 @@ +{ + "dependencies": { + "@wx/trial-svelte-filemanager": "^1.0.1", + "@wx/trial-svelte-gantt": "^1.0.1", + "@wx/trial-svelte-grid": "^1.2.0" + } +} diff --git a/poc/server.py b/poc/server.py index 287d3de..df32188 100644 --- a/poc/server.py +++ b/poc/server.py @@ -3,21 +3,22 @@ from fastapi.responses import HTMLResponse, FileResponse from fastapi.templating import Jinja2Templates from fastapi.staticfiles import StaticFiles from jinja2 import Environment, FileSystemLoader, select_autoescape -#from webcomponents.tasks.web import render as render_tasks + +# from webcomponents.tasks.web import render as render_tasks from tools.deduper import Deduper import os from jinja2 import TemplateNotFound -mypath="~/code/git.ourworld.tf/freeflowuniverse/heroweb/poc" +mypath = "~/code/git.ourworld.tf/freeflowuniverse/heroweb/poc" p = os.path.abspath(os.path.expanduser(mypath)) if not os.path.exists(p): raise FileNotFoundError(f"The path does not exist: {p}") -deduper = Deduper(f"{p}/static") +deduper = Deduper(f"{p}/static") + +# from IPython import embed;embed() -#from IPython import embed;embed() - sources_dir = f"{p}/out" static_dir = f"{p}/static" @@ -36,23 +37,25 @@ app.mount("/static", StaticFiles(directory=static_dir), name="static") app.mount("/assets", StaticFiles(directory=static_dir), name="assets") env = Environment( - loader=FileSystemLoader(sources_dir), - autoescape=select_autoescape(['html', 'xml']) + loader=FileSystemLoader(sources_dir), autoescape=select_autoescape(["html", "xml"]) ) # Initialize Jinja2 templates templates = Jinja2Templates(directory=sources_dir) -@app.get('/favicon.ico', include_in_schema=False) + +@app.get("/favicon.ico", include_in_schema=False) async def favicon(): if os.path.exists(f"{static_dir}/favicon.ico"): return FileResponse(f"{static_dir}/favicon.ico") return "" + @app.get("/", response_class=HTMLResponse) -async def read_index(request: Request): +async def read_index(request: Request): template = env.get_template("index.html") return template.render(request=request) + # @app.get("/tasks", response_class=HTMLResponse) # async def get_tasks(request: Request): # #import pudb; pudb.set_trace() @@ -68,19 +71,23 @@ async def read_index(request: Request): async def read_template(request: Request, template_path: str): try: # Ensure the template path ends with .html - if not template_path.endswith('.html'): - template_path += '.html' + if not template_path.endswith(".html"): + template_path += ".html" # Try to get the template template = env.get_template(template_path) return template.render(request=request) except TemplateNotFound: - raise HTTPException(status_code=404, detail=f"Template not found: {template_path}") + raise HTTPException( + status_code=404, detail=f"Template not found: {template_path}" + ) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) - + + if __name__ == "__main__": - - #no need to do this every time - + + # no need to do this every time + import uvicorn - uvicorn.run("server:app", host="127.0.0.1", port=8000, reload=True) \ No newline at end of file + + uvicorn.run("server:app", host="127.0.0.1", port=8000, reload=True) diff --git a/svelte/.npmrc b/svelte/.npmrc new file mode 100644 index 0000000..0618f99 --- /dev/null +++ b/svelte/.npmrc @@ -0,0 +1 @@ +@wx:registry=https://npm.svar.dev diff --git a/svelte/myfiles/package-lock.json b/svelte/myfiles/package-lock.json index 767e73f..80091fc 100644 --- a/svelte/myfiles/package-lock.json +++ b/svelte/myfiles/package-lock.json @@ -8,7 +8,8 @@ "name": "myfiles", "version": "0.0.0", "dependencies": { - "@wx/trial-svelte-filemanager": "^1.0.1" + "@wx/trial-svelte-filemanager": "^1.0.1", + "create-vite": "^5.5.2" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.1.1", @@ -903,6 +904,21 @@ "periscopic": "^3.1.0" } }, + "node_modules/create-vite": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/create-vite/-/create-vite-5.5.2.tgz", + "integrity": "sha512-glwkD5XS2NzNldnYfdyMHZjG15D0LkUvpzbPvwyLtNxiWjpfMvbS430saoBl7B1J3ldJpbtov7dkQVJN0jkn9Q==", + "bin": { + "create-vite": "index.js", + "cva": "index.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + } + }, "node_modules/css-tree": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", diff --git a/svelte/myfiles/package.json b/svelte/myfiles/package.json index 7d41cb9..3947ffa 100644 --- a/svelte/myfiles/package.json +++ b/svelte/myfiles/package.json @@ -14,6 +14,7 @@ "vite": "^5.4.1" }, "dependencies": { - "@wx/trial-svelte-filemanager": "^1.0.1" + "@wx/trial-svelte-filemanager": "^1.0.1", + "create-vite": "^5.5.2" } } diff --git a/svelte/package-lock.json b/svelte/package-lock.json index d93e2c3..c23cad0 100644 --- a/svelte/package-lock.json +++ b/svelte/package-lock.json @@ -5,7 +5,9 @@ "packages": { "": { "dependencies": { - "@wx/trial-svelte-filemanager": "^1.0.1" + "@wx/trial-svelte-filemanager": "^1.0.1", + "@wx/trial-svelte-gantt": "^1.0.1", + "@wx/trial-svelte-grid": "^1.2.0" } }, "node_modules/@wx/core-locales": { @@ -26,6 +28,22 @@ "resolved": "https://npm.svar.dev/@wx%2ffilemanager-locales/-/filemanager-locales-1.0.1.tgz", "integrity": "sha512-1YZAn0SzcLqEtNMyrBsW75jcMWImynON6ie/JRzVNOS7QKe0PqACQ6e7HRw0APW1rmZ7dj5esr87GjmBRpdC+A==" }, + "node_modules/@wx/gantt-data-provider": { + "version": "1.0.1", + "resolved": "https://npm.svar.dev/@wx%2fgantt-data-provider/-/gantt-data-provider-1.0.1.tgz", + "integrity": "sha512-oa4ytrV1xnhA2AQ32Nx2I89aBC+xeoOsd7q29XgZXyPWaTT0Z6C7yxpenQznuXCG+xxW9c/r5/v4z/05VUzH5Q==", + "license": "MIT", + "dependencies": { + "@wx/lib-data-provider": "^1.3.2", + "date-fns": "^3.3.1" + } + }, + "node_modules/@wx/gantt-locales": { + "version": "1.0.1", + "resolved": "https://npm.svar.dev/@wx%2fgantt-locales/-/gantt-locales-1.0.1.tgz", + "integrity": "sha512-MopJQENo68NClU/6oWJCJfLCJIRK+YV+rmG8tY4gK/ADvISh6yTvIW4t7pw1s22FOlKJK5aaNa8I5u8I6Y+XBg==", + "license": "MIT" + }, "node_modules/@wx/grid-data-provider": { "version": "1.2.0", "resolved": "https://npm.svar.dev/@wx%2fgrid-data-provider/-/grid-data-provider-1.2.0.tgz", @@ -83,6 +101,16 @@ "@wx/svelte-core": "1.2.1" } }, + "node_modules/@wx/svelte-toolbar": { + "version": "1.2.2", + "resolved": "https://npm.svar.dev/@wx%2fsvelte-toolbar/-/svelte-toolbar-1.2.2.tgz", + "integrity": "sha512-+JbtVaXNCflz1ccb6576Z1RLJlzR+0ykyAgpHa/KmteSAkPwVyjDy1VPfJrGUEWIxCkmjsiyQo/FYx5ixvQ7RA==", + "license": "MIT", + "dependencies": { + "@wx/lib-dom": "0.5.2", + "@wx/svelte-core": "1.2.1" + } + }, "node_modules/@wx/svelte-uploader": { "version": "0.1.0", "resolved": "https://npm.svar.dev/@wx%2fsvelte-uploader/-/svelte-uploader-0.1.0.tgz", @@ -99,6 +127,16 @@ "@wx/lib-state": "^1.7.1" } }, + "node_modules/@wx/trial-gantt-store": { + "version": "1.0.1", + "resolved": "https://npm.svar.dev/@wx%2ftrial-gantt-store/-/trial-gantt-store-1.0.1.tgz", + "integrity": "sha512-OuGLhqq/cU1bajvKZc92gjPBoMnlP5OJK18O1ZneLUpeentkTdz0p0+FdhF032Jv3kg+JJJ+AyG0Y6Jy3DCJbQ==", + "license": "UNLICENSED", + "dependencies": { + "@wx/lib-state": "^1.7.1", + "date-fns": "^3.3.1" + } + }, "node_modules/@wx/trial-grid-store": { "version": "1.2.0", "resolved": "https://npm.svar.dev/@wx%2ftrial-grid-store/-/trial-grid-store-1.2.0.tgz", @@ -111,6 +149,7 @@ "version": "1.0.1", "resolved": "https://npm.svar.dev/@wx%2ftrial-svelte-filemanager/-/trial-svelte-filemanager-1.0.1.tgz", "integrity": "sha512-LSqHl1DHjYQFAhN1C+yGxI16O0zJEta/WJOACC6BBLnHnsrCb8ab6bLRu2YENcr+uiWvjuxWqzh7l85h9mrDxg==", + "license": "SEE LICENSE IN license.txt", "dependencies": { "@wx/filemanager-data-provider": "1.0.1", "@wx/filemanager-locales": "1.0.1", @@ -124,10 +163,29 @@ "@wx/trial-svelte-grid": "^1.1.2" } }, + "node_modules/@wx/trial-svelte-gantt": { + "version": "1.0.1", + "resolved": "https://npm.svar.dev/@wx%2ftrial-svelte-gantt/-/trial-svelte-gantt-1.0.1.tgz", + "integrity": "sha512-MjFxX+nvzfHVOsh0anf8LBI1IWBSHncb4+kk7pzUoPStbjMrRUf3nL1hdV6Uzgssiz60k6EkTM4nA5bBkuNr9w==", + "license": "SEE LICENSE IN license.txt", + "dependencies": { + "@wx/gantt-data-provider": "1.0.1", + "@wx/gantt-locales": "1.0.1", + "@wx/lib-dom": "^0.5.0", + "@wx/lib-state": "^1.7.1", + "@wx/lib-svelte": "^0.2.1", + "@wx/svelte-core": "^1.1.0", + "@wx/svelte-menu": "^1.1.2", + "@wx/svelte-toolbar": "^1.1.0", + "@wx/trial-gantt-store": "1.0.1", + "@wx/trial-svelte-grid": "^1.1.2" + } + }, "node_modules/@wx/trial-svelte-grid": { "version": "1.2.0", "resolved": "https://npm.svar.dev/@wx%2ftrial-svelte-grid/-/trial-svelte-grid-1.2.0.tgz", "integrity": "sha512-2M9d6UAxOcBaEpU1nT8XTA9idajY1X6m7+UqVJ4LlD6Bmsd/Jp/QBksy3qeqXwQqgEkMLgnEL/HFaMwN4vtD6g==", + "license": "SEE LICENSE IN license.txt", "dependencies": { "@wx/grid-data-provider": "1.2.0", "@wx/grid-locales": "1.2.0", @@ -152,6 +210,15 @@ "svelte": "^3.0.0" } }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/svelte": { "version": "3.59.2", "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.2.tgz", diff --git a/svelte/package.json b/svelte/package.json index ba3781f..37c9530 100644 --- a/svelte/package.json +++ b/svelte/package.json @@ -1,5 +1,7 @@ { "dependencies": { - "@wx/trial-svelte-filemanager": "^1.0.1" + "@wx/trial-svelte-filemanager": "^1.0.1", + "@wx/trial-svelte-gantt": "^1.0.1", + "@wx/trial-svelte-grid": "^1.2.0" } }