From cec5fdd14430455153802ee3a8abeecf31e9653d Mon Sep 17 00:00:00 2001 From: Jan-Timo Hesse Date: Mon, 5 Aug 2024 09:42:16 +0200 Subject: [PATCH 01/73] Added EXTRA_MODULES argument --- Dockerfile | 4 +++- backend/start.sh | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 8078bf0eac..f1ea4e0645 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,6 +38,7 @@ ARG USE_OLLAMA ARG USE_CUDA_VER ARG USE_EMBEDDING_MODEL ARG USE_RERANKING_MODEL +ARG EXTRA_MODULES ARG UID ARG GID @@ -49,7 +50,8 @@ ENV ENV=prod \ USE_CUDA_DOCKER=${USE_CUDA} \ USE_CUDA_DOCKER_VER=${USE_CUDA_VER} \ USE_EMBEDDING_MODEL_DOCKER=${USE_EMBEDDING_MODEL} \ - USE_RERANKING_MODEL_DOCKER=${USE_RERANKING_MODEL} + USE_RERANKING_MODEL_DOCKER=${USE_RERANKING_MODEL} \ + EXTRA_MODULES_DOCKER=${EXTRA_MODULES} ## Basis URL Config ## ENV OLLAMA_BASE_URL="/ollama" \ diff --git a/backend/start.sh b/backend/start.sh index 16a004e45c..b499736b8f 100755 --- a/backend/start.sh +++ b/backend/start.sh @@ -30,6 +30,10 @@ if [[ "${USE_CUDA_DOCKER,,}" == "true" ]]; then export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib/python3.11/site-packages/torch/lib:/usr/local/lib/python3.11/site-packages/nvidia/cudnn/lib" fi +if [ -n "$EXTRA_MODULES_DOCKER" ]; then + echo "Loading extra modules: $EXTRA_MODULES_DOCKER" + uv pip install --system $EXTRA_MODULES_DOCKER --no-cache-dir +fi # Check if SPACE_ID is set, if so, configure for space if [ -n "$SPACE_ID" ]; then From 6a012d290e919e2ce30b35c57bcca1535a9942b5 Mon Sep 17 00:00:00 2001 From: Candido Sales Gomes Date: Mon, 5 Aug 2024 11:00:30 -0400 Subject: [PATCH 02/73] migration to SvelteKit 2 --- package.json | 35 ++++++++++++++++++++--------------- svelte.config.js | 2 +- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 6687cef755..a9fadef1ad 100644 --- a/package.json +++ b/package.json @@ -20,30 +20,31 @@ "pyodide:fetch": "node scripts/prepare-pyodide.js" }, "devDependencies": { - "@sveltejs/adapter-auto": "^2.0.0", - "@sveltejs/adapter-static": "^2.0.3", - "@sveltejs/kit": "^1.30.0", - "@tailwindcss/typography": "^0.5.10", + "@sveltejs/adapter-auto": "3.2.2", + "@sveltejs/adapter-static": "^3.0.2", + "@sveltejs/kit": "^2.5.20", + "@sveltejs/vite-plugin-svelte": "^3.1.1", + "@tailwindcss/typography": "^0.5.13", "@types/bun": "latest", "@typescript-eslint/eslint-plugin": "^6.17.0", "@typescript-eslint/parser": "^6.17.0", "autoprefixer": "^10.4.16", "cypress": "^13.8.1", "eslint": "^8.56.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-cypress": "^3.0.2", - "eslint-plugin-svelte": "^2.30.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-cypress": "^3.4.0", + "eslint-plugin-svelte": "^2.43.0", "i18next-parser": "^8.13.0", "postcss": "^8.4.31", - "prettier": "^2.8.0", - "prettier-plugin-svelte": "^2.10.1", - "svelte": "^4.0.5", - "svelte-check": "^3.4.3", + "prettier": "^3.3.3", + "prettier-plugin-svelte": "^3.2.6", + "svelte": "^4.2.18", + "svelte-check": "^3.8.5", "svelte-confetti": "^1.3.2", "tailwindcss": "^3.3.3", "tslib": "^2.4.1", - "typescript": "^5.0.0", - "vite": "^4.4.2", + "typescript": "^5.5.4", + "vite": "^5.3.5", "vitest": "^1.6.0" }, "type": "module", @@ -52,7 +53,7 @@ "@codemirror/lang-python": "^6.1.6", "@codemirror/theme-one-dark": "^6.1.2", "@pyscript/core": "^0.4.32", - "@sveltejs/adapter-node": "^1.3.1", + "@sveltejs/adapter-node": "^2.0.0", "async": "^3.2.5", "bits-ui": "^0.19.7", "codemirror": "^6.0.1", @@ -77,5 +78,9 @@ "tippy.js": "^6.3.7", "turndown": "^7.2.0", "uuid": "^9.0.1" + }, + "engines": { + "node": ">=18.13.0 <=21.x.x", + "npm": ">=6.0.0" } -} +} \ No newline at end of file diff --git a/svelte.config.js b/svelte.config.js index 1ff7ceeb74..d756191d30 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,5 +1,5 @@ import adapter from '@sveltejs/adapter-static'; -import { vitePreprocess } from '@sveltejs/kit/vite'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ const config = { From 5315fb201d802bd0e1af1f00a076be28fc59bb3f Mon Sep 17 00:00:00 2001 From: Candido Sales Gomes Date: Mon, 5 Aug 2024 11:10:31 -0400 Subject: [PATCH 03/73] changelod updated --- CHANGELOG.md | 24 ++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d62360f878..d56f4965b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,30 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.12] - 2024-08-05 + +### Added + +- **✨ Migrated to SvelteKit 2**: Added visuals for model selection, including images next to model names for more intuitive navigation. + +### Changed + +- **⬆️ Dependency Updates** + - Added '@sveltejs/vite-plugin-svelte'. + - Upgraded '@sveltejs/adapter-auto' from version 2.0.0 to 3.2.2. + - Upgraded '@sveltejs/adapter-static' from version 2.0.3 to 3.0.2. + - Upgraded '@sveltejs/kit' from version 1.30.0 to 2.5.20. + - Upgraded '@tailwindcss/typography' from version 0.5.10 to 0.5.13. + - Upgraded 'eslint-config-prettier' from version 8.5.0 to 9.1.0. + - Upgraded 'eslint-plugin-cypress' from version 3.0.2 to 3.4.0. + - Upgraded 'eslint-plugin-svelte' from version 2.30.0 to 2.43.0. + - Upgraded 'prettier' from version 2.8.0 to 3.3.3. + - Upgraded 'prettier-plugin-svelte' from version 2.10.1 to 3.2.6. + - Upgraded 'svelte' from version 4.0.5 to 4.2.18. + - Upgraded 'svelte-check' from version 3.4.3 to 3.8.5. + - Upgraded 'typescript' from version 5.0.0 to 5.5.4. + - Upgraded 'vite' from version 4.4.2 to 5.3.5. + ## [0.3.11] - 2024-08-02 ### Added diff --git a/package.json b/package.json index a9fadef1ad..8d78367b76 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open-webui", - "version": "0.3.11", + "version": "0.3.12", "private": true, "scripts": { "dev": "npm run pyodide:fetch && vite dev --host", From b289eef5233216261e94314caa581df30b38859e Mon Sep 17 00:00:00 2001 From: Candido Sales Gomes Date: Mon, 5 Aug 2024 11:16:28 -0400 Subject: [PATCH 04/73] typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d56f4965b2..d5361fbbd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- **✨ Migrated to SvelteKit 2**: Added visuals for model selection, including images next to model names for more intuitive navigation. +- **✨ Migrated to SvelteKit 2**: Significant improvements in performance and simplification of state management. ### Changed From 831fe9f509d0f7438369edda9497e761e3494acf Mon Sep 17 00:00:00 2001 From: Michael Poluektov Date: Tue, 6 Aug 2024 10:15:29 +0100 Subject: [PATCH 05/73] cleanup --- backend/apps/ollama/main.py | 63 ++++++++++++++----------------------- 1 file changed, 24 insertions(+), 39 deletions(-) diff --git a/backend/apps/ollama/main.py b/backend/apps/ollama/main.py index 442d99ff26..88b0bc9f2e 100644 --- a/backend/apps/ollama/main.py +++ b/backend/apps/ollama/main.py @@ -1,27 +1,21 @@ from fastapi import ( FastAPI, Request, - Response, HTTPException, Depends, - status, UploadFile, File, - BackgroundTasks, ) from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import StreamingResponse -from fastapi.concurrency import run_in_threadpool from pydantic import BaseModel, ConfigDict import os import re -import copy import random import requests import json -import uuid import aiohttp import asyncio import logging @@ -32,11 +26,8 @@ from typing import Optional, List, Union from starlette.background import BackgroundTask from apps.webui.models.models import Models -from apps.webui.models.users import Users from constants import ERROR_MESSAGES from utils.utils import ( - decode_token, - get_current_user, get_verified_user, get_admin_user, ) @@ -183,7 +174,7 @@ async def post_streaming_url(url: str, payload: str, stream: bool = True): res = await r.json() if "error" in res: error_detail = f"Ollama: {res['error']}" - except: + except Exception: error_detail = f"Ollama: {e}" raise HTTPException( @@ -238,7 +229,7 @@ async def get_all_models(): async def get_ollama_tags( url_idx: Optional[int] = None, user=Depends(get_verified_user) ): - if url_idx == None: + if url_idx is None: models = await get_all_models() if app.state.config.ENABLE_MODEL_FILTER: @@ -269,7 +260,7 @@ async def get_ollama_tags( res = r.json() if "error" in res: error_detail = f"Ollama: {res['error']}" - except: + except Exception: error_detail = f"Ollama: {e}" raise HTTPException( @@ -282,8 +273,7 @@ async def get_ollama_tags( @app.get("/api/version/{url_idx}") async def get_ollama_versions(url_idx: Optional[int] = None): if app.state.config.ENABLE_OLLAMA_API: - if url_idx == None: - + if url_idx is None: # returns lowest version tasks = [ fetch_url(f"{url}/api/version") @@ -323,7 +313,7 @@ async def get_ollama_versions(url_idx: Optional[int] = None): res = r.json() if "error" in res: error_detail = f"Ollama: {res['error']}" - except: + except Exception: error_detail = f"Ollama: {e}" raise HTTPException( @@ -367,7 +357,7 @@ async def push_model( url_idx: Optional[int] = None, user=Depends(get_admin_user), ): - if url_idx == None: + if url_idx is None: if form_data.name in app.state.MODELS: url_idx = app.state.MODELS[form_data.name]["urls"][0] else: @@ -417,7 +407,7 @@ async def copy_model( url_idx: Optional[int] = None, user=Depends(get_admin_user), ): - if url_idx == None: + if url_idx is None: if form_data.source in app.state.MODELS: url_idx = app.state.MODELS[form_data.source]["urls"][0] else: @@ -448,7 +438,7 @@ async def copy_model( res = r.json() if "error" in res: error_detail = f"Ollama: {res['error']}" - except: + except Exception: error_detail = f"Ollama: {e}" raise HTTPException( @@ -464,7 +454,7 @@ async def delete_model( url_idx: Optional[int] = None, user=Depends(get_admin_user), ): - if url_idx == None: + if url_idx is None: if form_data.name in app.state.MODELS: url_idx = app.state.MODELS[form_data.name]["urls"][0] else: @@ -495,7 +485,7 @@ async def delete_model( res = r.json() if "error" in res: error_detail = f"Ollama: {res['error']}" - except: + except Exception: error_detail = f"Ollama: {e}" raise HTTPException( @@ -533,7 +523,7 @@ async def show_model_info(form_data: ModelNameForm, user=Depends(get_verified_us res = r.json() if "error" in res: error_detail = f"Ollama: {res['error']}" - except: + except Exception: error_detail = f"Ollama: {e}" raise HTTPException( @@ -556,7 +546,7 @@ async def generate_embeddings( url_idx: Optional[int] = None, user=Depends(get_verified_user), ): - if url_idx == None: + if url_idx is None: model = form_data.model if ":" not in model: @@ -590,7 +580,7 @@ async def generate_embeddings( res = r.json() if "error" in res: error_detail = f"Ollama: {res['error']}" - except: + except Exception: error_detail = f"Ollama: {e}" raise HTTPException( @@ -603,10 +593,9 @@ def generate_ollama_embeddings( form_data: GenerateEmbeddingsForm, url_idx: Optional[int] = None, ): - log.info(f"generate_ollama_embeddings {form_data}") - if url_idx == None: + if url_idx is None: model = form_data.model if ":" not in model: @@ -638,7 +627,7 @@ def generate_ollama_embeddings( if "embedding" in data: return data["embedding"] else: - raise "Something went wrong :/" + raise Exception("Something went wrong :/") except Exception as e: log.exception(e) error_detail = "Open WebUI: Server Connection Error" @@ -647,10 +636,10 @@ def generate_ollama_embeddings( res = r.json() if "error" in res: error_detail = f"Ollama: {res['error']}" - except: + except Exception: error_detail = f"Ollama: {e}" - raise error_detail + raise Exception(error_detail) class GenerateCompletionForm(BaseModel): @@ -674,8 +663,7 @@ async def generate_completion( url_idx: Optional[int] = None, user=Depends(get_verified_user), ): - - if url_idx == None: + if url_idx is None: model = form_data.model if ":" not in model: @@ -720,7 +708,6 @@ async def generate_chat_completion( url_idx: Optional[int] = None, user=Depends(get_verified_user), ): - log.debug( "form_data.model_dump_json(exclude_none=True).encode(): {0} ".format( form_data.model_dump_json(exclude_none=True).encode() @@ -906,7 +893,7 @@ async def generate_chat_completion( system, payload["messages"] ) - if url_idx == None: + if url_idx is None: if ":" not in payload["model"]: payload["model"] = f"{payload['model']}:latest" @@ -1016,7 +1003,7 @@ async def generate_openai_chat_completion( }, ) - if url_idx == None: + if url_idx is None: if ":" not in payload["model"]: payload["model"] = f"{payload['model']}:latest" @@ -1044,7 +1031,7 @@ async def get_openai_models( url_idx: Optional[int] = None, user=Depends(get_verified_user), ): - if url_idx == None: + if url_idx is None: models = await get_all_models() if app.state.config.ENABLE_MODEL_FILTER: @@ -1099,7 +1086,7 @@ async def get_openai_models( res = r.json() if "error" in res: error_detail = f"Ollama: {res['error']}" - except: + except Exception: error_detail = f"Ollama: {e}" raise HTTPException( @@ -1125,7 +1112,6 @@ def parse_huggingface_url(hf_url): path_components = parsed_url.path.split("/") # Extract the desired output - user_repo = "/".join(path_components[1:3]) model_file = path_components[-1] return model_file @@ -1190,7 +1176,6 @@ async def download_model( url_idx: Optional[int] = None, user=Depends(get_admin_user), ): - allowed_hosts = ["https://huggingface.co/", "https://github.com/"] if not any(form_data.url.startswith(host) for host in allowed_hosts): @@ -1199,7 +1184,7 @@ async def download_model( detail="Invalid file_url. Only URLs from allowed hosts are permitted.", ) - if url_idx == None: + if url_idx is None: url_idx = 0 url = app.state.config.OLLAMA_BASE_URLS[url_idx] @@ -1222,7 +1207,7 @@ def upload_model( url_idx: Optional[int] = None, user=Depends(get_admin_user), ): - if url_idx == None: + if url_idx is None: url_idx = 0 ollama_url = app.state.config.OLLAMA_BASE_URLS[url_idx] From 44c781f414007a7968d7c38560668a457c0f1900 Mon Sep 17 00:00:00 2001 From: Michael Poluektov Date: Tue, 6 Aug 2024 10:50:22 +0100 Subject: [PATCH 06/73] cleanup --- backend/apps/ollama/main.py | 173 +++++++++++++++--------------------- 1 file changed, 70 insertions(+), 103 deletions(-) diff --git a/backend/apps/ollama/main.py b/backend/apps/ollama/main.py index 88b0bc9f2e..f1544c80b1 100644 --- a/backend/apps/ollama/main.py +++ b/backend/apps/ollama/main.py @@ -336,8 +336,6 @@ async def pull_model( url = app.state.config.OLLAMA_BASE_URLS[url_idx] log.info(f"url: {url}") - r = None - # Admin should be able to pull models from any source payload = {**form_data.model_dump(exclude_none=True), "insecure": True} @@ -418,13 +416,13 @@ async def copy_model( url = app.state.config.OLLAMA_BASE_URLS[url_idx] log.info(f"url: {url}") + r = requests.request( + method="POST", + url=f"{url}/api/copy", + data=form_data.model_dump_json(exclude_none=True).encode(), + ) try: - r = requests.request( - method="POST", - url=f"{url}/api/copy", - data=form_data.model_dump_json(exclude_none=True).encode(), - ) r.raise_for_status() log.debug(f"r.text: {r.text}") @@ -466,12 +464,12 @@ async def delete_model( url = app.state.config.OLLAMA_BASE_URLS[url_idx] log.info(f"url: {url}") + r = requests.request( + method="DELETE", + url=f"{url}/api/delete", + data=form_data.model_dump_json(exclude_none=True).encode(), + ) try: - r = requests.request( - method="DELETE", - url=f"{url}/api/delete", - data=form_data.model_dump_json(exclude_none=True).encode(), - ) r.raise_for_status() log.debug(f"r.text: {r.text}") @@ -506,12 +504,12 @@ async def show_model_info(form_data: ModelNameForm, user=Depends(get_verified_us url = app.state.config.OLLAMA_BASE_URLS[url_idx] log.info(f"url: {url}") + r = requests.request( + method="POST", + url=f"{url}/api/show", + data=form_data.model_dump_json(exclude_none=True).encode(), + ) try: - r = requests.request( - method="POST", - url=f"{url}/api/show", - data=form_data.model_dump_json(exclude_none=True).encode(), - ) r.raise_for_status() return r.json() @@ -563,12 +561,12 @@ async def generate_embeddings( url = app.state.config.OLLAMA_BASE_URLS[url_idx] log.info(f"url: {url}") + r = requests.request( + method="POST", + url=f"{url}/api/embeddings", + data=form_data.model_dump_json(exclude_none=True).encode(), + ) try: - r = requests.request( - method="POST", - url=f"{url}/api/embeddings", - data=form_data.model_dump_json(exclude_none=True).encode(), - ) r.raise_for_status() return r.json() @@ -612,12 +610,12 @@ def generate_ollama_embeddings( url = app.state.config.OLLAMA_BASE_URLS[url_idx] log.info(f"url: {url}") + r = requests.request( + method="POST", + url=f"{url}/api/embeddings", + data=form_data.model_dump_json(exclude_none=True).encode(), + ) try: - r = requests.request( - method="POST", - url=f"{url}/api/embeddings", - data=form_data.model_dump_json(exclude_none=True).encode(), - ) r.raise_for_status() data = r.json() @@ -727,152 +725,121 @@ async def generate_chat_completion( if model_info.base_model_id: payload["model"] = model_info.base_model_id - model_info.params = model_info.params.model_dump() + params = model_info.params.model_dump() - if model_info.params: + if params: if payload.get("options") is None: payload["options"] = {} if ( - model_info.params.get("mirostat", None) + params.get("mirostat", None) and payload["options"].get("mirostat") is None ): - payload["options"]["mirostat"] = model_info.params.get("mirostat", None) + payload["options"]["mirostat"] = params.get("mirostat", None) if ( - model_info.params.get("mirostat_eta", None) + params.get("mirostat_eta", None) and payload["options"].get("mirostat_eta") is None ): - payload["options"]["mirostat_eta"] = model_info.params.get( - "mirostat_eta", None - ) + payload["options"]["mirostat_eta"] = params.get("mirostat_eta", None) if ( - model_info.params.get("mirostat_tau", None) + params.get("mirostat_tau", None) and payload["options"].get("mirostat_tau") is None ): - payload["options"]["mirostat_tau"] = model_info.params.get( - "mirostat_tau", None - ) + payload["options"]["mirostat_tau"] = params.get("mirostat_tau", None) if ( - model_info.params.get("num_ctx", None) + params.get("num_ctx", None) and payload["options"].get("num_ctx") is None ): - payload["options"]["num_ctx"] = model_info.params.get("num_ctx", None) + payload["options"]["num_ctx"] = params.get("num_ctx", None) if ( - model_info.params.get("num_batch", None) + params.get("num_batch", None) and payload["options"].get("num_batch") is None ): - payload["options"]["num_batch"] = model_info.params.get( - "num_batch", None - ) + payload["options"]["num_batch"] = params.get("num_batch", None) if ( - model_info.params.get("num_keep", None) + params.get("num_keep", None) and payload["options"].get("num_keep") is None ): - payload["options"]["num_keep"] = model_info.params.get("num_keep", None) + payload["options"]["num_keep"] = params.get("num_keep", None) if ( - model_info.params.get("repeat_last_n", None) + params.get("repeat_last_n", None) and payload["options"].get("repeat_last_n") is None ): - payload["options"]["repeat_last_n"] = model_info.params.get( - "repeat_last_n", None - ) + payload["options"]["repeat_last_n"] = params.get("repeat_last_n", None) if ( - model_info.params.get("frequency_penalty", None) + params.get("frequency_penalty", None) and payload["options"].get("frequency_penalty") is None ): - payload["options"]["repeat_penalty"] = model_info.params.get( + payload["options"]["repeat_penalty"] = params.get( "frequency_penalty", None ) if ( - model_info.params.get("temperature", None) is not None + params.get("temperature", None) is not None and payload["options"].get("temperature") is None ): - payload["options"]["temperature"] = model_info.params.get( - "temperature", None - ) + payload["options"]["temperature"] = params.get("temperature", None) if ( - model_info.params.get("seed", None) is not None + params.get("seed", None) is not None and payload["options"].get("seed") is None ): - payload["options"]["seed"] = model_info.params.get("seed", None) + payload["options"]["seed"] = params.get("seed", None) - if ( - model_info.params.get("stop", None) - and payload["options"].get("stop") is None - ): + if params.get("stop", None) and payload["options"].get("stop") is None: payload["options"]["stop"] = ( [ bytes(stop, "utf-8").decode("unicode_escape") - for stop in model_info.params["stop"] + for stop in params["stop"] ] - if model_info.params.get("stop", None) + if params.get("stop", None) else None ) - if ( - model_info.params.get("tfs_z", None) - and payload["options"].get("tfs_z") is None - ): - payload["options"]["tfs_z"] = model_info.params.get("tfs_z", None) + if params.get("tfs_z", None) and payload["options"].get("tfs_z") is None: + payload["options"]["tfs_z"] = params.get("tfs_z", None) if ( - model_info.params.get("max_tokens", None) + params.get("max_tokens", None) and payload["options"].get("max_tokens") is None ): - payload["options"]["num_predict"] = model_info.params.get( - "max_tokens", None - ) + payload["options"]["num_predict"] = params.get("max_tokens", None) + + if params.get("top_k", None) and payload["options"].get("top_k") is None: + payload["options"]["top_k"] = params.get("top_k", None) + + if params.get("top_p", None) and payload["options"].get("top_p") is None: + payload["options"]["top_p"] = params.get("top_p", None) + + if params.get("min_p", None) and payload["options"].get("min_p") is None: + payload["options"]["min_p"] = params.get("min_p", None) if ( - model_info.params.get("top_k", None) - and payload["options"].get("top_k") is None - ): - payload["options"]["top_k"] = model_info.params.get("top_k", None) - - if ( - model_info.params.get("top_p", None) - and payload["options"].get("top_p") is None - ): - payload["options"]["top_p"] = model_info.params.get("top_p", None) - - if ( - model_info.params.get("min_p", None) - and payload["options"].get("min_p") is None - ): - payload["options"]["min_p"] = model_info.params.get("min_p", None) - - if ( - model_info.params.get("use_mmap", None) + params.get("use_mmap", None) and payload["options"].get("use_mmap") is None ): - payload["options"]["use_mmap"] = model_info.params.get("use_mmap", None) + payload["options"]["use_mmap"] = params.get("use_mmap", None) if ( - model_info.params.get("use_mlock", None) + params.get("use_mlock", None) and payload["options"].get("use_mlock") is None ): - payload["options"]["use_mlock"] = model_info.params.get( - "use_mlock", None - ) + payload["options"]["use_mlock"] = params.get("use_mlock", None) if ( - model_info.params.get("num_thread", None) + params.get("num_thread", None) and payload["options"].get("num_thread") is None ): - payload["options"]["num_thread"] = model_info.params.get( - "num_thread", None - ) + payload["options"]["num_thread"] = params.get("num_thread", None) - system = model_info.params.get("system", None) + system = params.get("system", None) if system: system = prompt_template( system, From fc31267a54c4ba20a4a0252b05f46d878791eb55 Mon Sep 17 00:00:00 2001 From: Michael Poluektov Date: Tue, 6 Aug 2024 11:31:45 +0100 Subject: [PATCH 07/73] refac: re-use utils.misc --- backend/apps/ollama/main.py | 252 ++++++------------------------------ backend/apps/openai/main.py | 7 +- backend/apps/webui/main.py | 4 +- backend/utils/misc.py | 51 ++++++-- 4 files changed, 85 insertions(+), 229 deletions(-) diff --git a/backend/apps/ollama/main.py b/backend/apps/ollama/main.py index f1544c80b1..19d914c4b4 100644 --- a/backend/apps/ollama/main.py +++ b/backend/apps/ollama/main.py @@ -44,7 +44,13 @@ from config import ( UPLOAD_DIR, AppConfig, ) -from utils.misc import calculate_sha256, add_or_update_system_message +from utils.misc import ( + apply_model_params_to_body_ollama, + calculate_sha256, + add_or_update_system_message, + apply_model_params_to_body_openai, + apply_model_system_prompt_to_body, +) log = logging.getLogger(__name__) log.setLevel(SRC_LOG_LEVELS["OLLAMA"]) @@ -699,6 +705,18 @@ class GenerateChatCompletionForm(BaseModel): keep_alive: Optional[Union[int, str]] = None +def get_ollama_url(url_idx: Optional[int], model: str): + if url_idx is None: + if model not in app.state.MODELS: + raise HTTPException( + status_code=400, + detail=ERROR_MESSAGES.MODEL_NOT_FOUND(model), + ) + url_idx = random.choice(app.state.MODELS[model]["urls"]) + url = app.state.config.OLLAMA_BASE_URLS[url_idx] + return url + + @app.post("/api/chat") @app.post("/api/chat/{url_idx}") async def generate_chat_completion( @@ -706,17 +724,12 @@ async def generate_chat_completion( url_idx: Optional[int] = None, user=Depends(get_verified_user), ): - log.debug( - "form_data.model_dump_json(exclude_none=True).encode(): {0} ".format( - form_data.model_dump_json(exclude_none=True).encode() - ) - ) + log.debug(f"{form_data.model_dump_json(exclude_none=True).encode()}=") payload = { **form_data.model_dump(exclude_none=True, exclude=["metadata"]), } - if "metadata" in payload: - del payload["metadata"] + payload.pop("metadata") model_id = form_data.model model_info = Models.get_model_by_id(model_id) @@ -731,148 +744,15 @@ async def generate_chat_completion( if payload.get("options") is None: payload["options"] = {} - if ( - params.get("mirostat", None) - and payload["options"].get("mirostat") is None - ): - payload["options"]["mirostat"] = params.get("mirostat", None) - - if ( - params.get("mirostat_eta", None) - and payload["options"].get("mirostat_eta") is None - ): - payload["options"]["mirostat_eta"] = params.get("mirostat_eta", None) - - if ( - params.get("mirostat_tau", None) - and payload["options"].get("mirostat_tau") is None - ): - payload["options"]["mirostat_tau"] = params.get("mirostat_tau", None) - - if ( - params.get("num_ctx", None) - and payload["options"].get("num_ctx") is None - ): - payload["options"]["num_ctx"] = params.get("num_ctx", None) - - if ( - params.get("num_batch", None) - and payload["options"].get("num_batch") is None - ): - payload["options"]["num_batch"] = params.get("num_batch", None) - - if ( - params.get("num_keep", None) - and payload["options"].get("num_keep") is None - ): - payload["options"]["num_keep"] = params.get("num_keep", None) - - if ( - params.get("repeat_last_n", None) - and payload["options"].get("repeat_last_n") is None - ): - payload["options"]["repeat_last_n"] = params.get("repeat_last_n", None) - - if ( - params.get("frequency_penalty", None) - and payload["options"].get("frequency_penalty") is None - ): - payload["options"]["repeat_penalty"] = params.get( - "frequency_penalty", None - ) - - if ( - params.get("temperature", None) is not None - and payload["options"].get("temperature") is None - ): - payload["options"]["temperature"] = params.get("temperature", None) - - if ( - params.get("seed", None) is not None - and payload["options"].get("seed") is None - ): - payload["options"]["seed"] = params.get("seed", None) - - if params.get("stop", None) and payload["options"].get("stop") is None: - payload["options"]["stop"] = ( - [ - bytes(stop, "utf-8").decode("unicode_escape") - for stop in params["stop"] - ] - if params.get("stop", None) - else None - ) - - if params.get("tfs_z", None) and payload["options"].get("tfs_z") is None: - payload["options"]["tfs_z"] = params.get("tfs_z", None) - - if ( - params.get("max_tokens", None) - and payload["options"].get("max_tokens") is None - ): - payload["options"]["num_predict"] = params.get("max_tokens", None) - - if params.get("top_k", None) and payload["options"].get("top_k") is None: - payload["options"]["top_k"] = params.get("top_k", None) - - if params.get("top_p", None) and payload["options"].get("top_p") is None: - payload["options"]["top_p"] = params.get("top_p", None) - - if params.get("min_p", None) and payload["options"].get("min_p") is None: - payload["options"]["min_p"] = params.get("min_p", None) - - if ( - params.get("use_mmap", None) - and payload["options"].get("use_mmap") is None - ): - payload["options"]["use_mmap"] = params.get("use_mmap", None) - - if ( - params.get("use_mlock", None) - and payload["options"].get("use_mlock") is None - ): - payload["options"]["use_mlock"] = params.get("use_mlock", None) - - if ( - params.get("num_thread", None) - and payload["options"].get("num_thread") is None - ): - payload["options"]["num_thread"] = params.get("num_thread", None) - - system = params.get("system", None) - if system: - system = prompt_template( - system, - **( - { - "user_name": user.name, - "user_location": ( - user.info.get("location") if user.info else None - ), - } - if user - else {} - ), + payload["options"] = apply_model_params_to_body_ollama( + params, payload["options"] ) + payload = apply_model_system_prompt_to_body(params, payload, user) - if payload.get("messages"): - payload["messages"] = add_or_update_system_message( - system, payload["messages"] - ) + if ":" not in payload["model"]: + payload["model"] = f"{payload['model']}:latest" - if url_idx is None: - if ":" not in payload["model"]: - payload["model"] = f"{payload['model']}:latest" - - if payload["model"] in app.state.MODELS: - url_idx = random.choice(app.state.MODELS[payload["model"]]["urls"]) - else: - raise HTTPException( - status_code=400, - detail=ERROR_MESSAGES.MODEL_NOT_FOUND(form_data.model), - ) - - url = app.state.config.OLLAMA_BASE_URLS[url_idx] + url = get_ollama_url(url_idx, payload["model"]) log.info(f"url: {url}") log.debug(payload) @@ -906,83 +786,27 @@ async def generate_openai_chat_completion( url_idx: Optional[int] = None, user=Depends(get_verified_user), ): - form_data = OpenAIChatCompletionForm(**form_data) - payload = {**form_data.model_dump(exclude_none=True, exclude=["metadata"])} + completion_form = OpenAIChatCompletionForm(**form_data) + payload = {**completion_form.model_dump(exclude_none=True, exclude=["metadata"])} + payload.pop("metadata") - if "metadata" in payload: - del payload["metadata"] - - model_id = form_data.model + model_id = completion_form.model model_info = Models.get_model_by_id(model_id) if model_info: if model_info.base_model_id: payload["model"] = model_info.base_model_id - model_info.params = model_info.params.model_dump() + params = model_info.params.model_dump() - if model_info.params: - payload["temperature"] = model_info.params.get("temperature", None) - payload["top_p"] = model_info.params.get("top_p", None) - payload["max_tokens"] = model_info.params.get("max_tokens", None) - payload["frequency_penalty"] = model_info.params.get( - "frequency_penalty", None - ) - payload["seed"] = model_info.params.get("seed", None) - payload["stop"] = ( - [ - bytes(stop, "utf-8").decode("unicode_escape") - for stop in model_info.params["stop"] - ] - if model_info.params.get("stop", None) - else None - ) + if params: + payload = apply_model_params_to_body_openai(params, payload) + payload = apply_model_system_prompt_to_body(params, payload, user) - system = model_info.params.get("system", None) + if ":" not in payload["model"]: + payload["model"] = f"{payload['model']}:latest" - if system: - system = prompt_template( - system, - **( - { - "user_name": user.name, - "user_location": ( - user.info.get("location") if user.info else None - ), - } - if user - else {} - ), - ) - # Check if the payload already has a system message - # If not, add a system message to the payload - if payload.get("messages"): - for message in payload["messages"]: - if message.get("role") == "system": - message["content"] = system + message["content"] - break - else: - payload["messages"].insert( - 0, - { - "role": "system", - "content": system, - }, - ) - - if url_idx is None: - if ":" not in payload["model"]: - payload["model"] = f"{payload['model']}:latest" - - if payload["model"] in app.state.MODELS: - url_idx = random.choice(app.state.MODELS[payload["model"]]["urls"]) - else: - raise HTTPException( - status_code=400, - detail=ERROR_MESSAGES.MODEL_NOT_FOUND(form_data.model), - ) - - url = app.state.config.OLLAMA_BASE_URLS[url_idx] + url = get_ollama_url(url_idx, payload["model"]) log.info(f"url: {url}") return await post_streaming_url( diff --git a/backend/apps/openai/main.py b/backend/apps/openai/main.py index a0d8f37507..1313d20910 100644 --- a/backend/apps/openai/main.py +++ b/backend/apps/openai/main.py @@ -17,7 +17,10 @@ from utils.utils import ( get_verified_user, get_admin_user, ) -from utils.misc import apply_model_params_to_body, apply_model_system_prompt_to_body +from utils.misc import ( + apply_model_params_to_body_openai, + apply_model_system_prompt_to_body, +) from config import ( SRC_LOG_LEVELS, @@ -366,7 +369,7 @@ async def generate_chat_completion( payload["model"] = model_info.base_model_id params = model_info.params.model_dump() - payload = apply_model_params_to_body(params, payload) + payload = apply_model_params_to_body_openai(params, payload) payload = apply_model_system_prompt_to_body(params, payload, user) model = app.state.MODELS[payload.get("model")] diff --git a/backend/apps/webui/main.py b/backend/apps/webui/main.py index a0b9f50085..6848fdd4de 100644 --- a/backend/apps/webui/main.py +++ b/backend/apps/webui/main.py @@ -22,7 +22,7 @@ from apps.webui.utils import load_function_module_by_id from utils.misc import ( openai_chat_chunk_message_template, openai_chat_completion_message_template, - apply_model_params_to_body, + apply_model_params_to_body_openai, apply_model_system_prompt_to_body, ) @@ -289,7 +289,7 @@ async def generate_function_chat_completion(form_data, user): form_data["model"] = model_info.base_model_id params = model_info.params.model_dump() - form_data = apply_model_params_to_body(params, form_data) + form_data = apply_model_params_to_body_openai(params, form_data) form_data = apply_model_system_prompt_to_body(params, form_data, user) pipe_id = get_pipe_id(form_data) diff --git a/backend/utils/misc.py b/backend/utils/misc.py index 25dd4dd5b6..ffe6a6e530 100644 --- a/backend/utils/misc.py +++ b/backend/utils/misc.py @@ -2,7 +2,7 @@ from pathlib import Path import hashlib import re from datetime import timedelta -from typing import Optional, List, Tuple +from typing import Optional, List, Tuple, Callable import uuid import time @@ -135,19 +135,12 @@ def apply_model_system_prompt_to_body(params: dict, form_data: dict, user) -> di # inplace function: form_data is modified -def apply_model_params_to_body(params: dict, form_data: dict) -> dict: +def apply_model_params_to_body( + params: dict, form_data: dict, mappings: dict[str, Callable] +) -> dict: if not params: return form_data - mappings = { - "temperature": float, - "top_p": int, - "max_tokens": int, - "frequency_penalty": int, - "seed": lambda x: x, - "stop": lambda x: [bytes(s, "utf-8").decode("unicode_escape") for s in x], - } - for key, cast_func in mappings.items(): if (value := params.get(key)) is not None: form_data[key] = cast_func(value) @@ -155,6 +148,42 @@ def apply_model_params_to_body(params: dict, form_data: dict) -> dict: return form_data +OPENAI_MAPPINGS = { + "temperature": float, + "top_p": int, + "max_tokens": int, + "frequency_penalty": int, + "seed": lambda x: x, + "stop": lambda x: [bytes(s, "utf-8").decode("unicode_escape") for s in x], +} + + +# inplace function: form_data is modified +def apply_model_params_to_body_openai(params: dict, form_data: dict) -> dict: + return apply_model_params_to_body(params, form_data, OPENAI_MAPPINGS) + + +def apply_model_params_to_body_ollama(params: dict, form_data: dict) -> dict: + opts = [ + "mirostat", + "mirostat_eta", + "mirostat_tau", + "num_ctx", + "num_batch", + "num_keep", + "repeat_last_n", + "tfs_z", + "top_k", + "min_p", + "use_mmap", + "use_mlock", + "num_thread", + ] + mappings = {i: lambda x: x for i in opts} + mappings = {**mappings, **OPENAI_MAPPINGS} + return apply_model_params_to_body(params, form_data, mappings) + + def get_gravatar_url(email): # Trim leading and trailing whitespace from # an email address and force all characters From ed205d82e8799a06ea9db4e6334228d99fad6678 Mon Sep 17 00:00:00 2001 From: Michael Poluektov Date: Tue, 6 Aug 2024 12:25:00 +0100 Subject: [PATCH 08/73] fix: pop --- backend/apps/ollama/main.py | 4 ++-- backend/apps/openai/main.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/apps/ollama/main.py b/backend/apps/ollama/main.py index 19d914c4b4..79a2773ba0 100644 --- a/backend/apps/ollama/main.py +++ b/backend/apps/ollama/main.py @@ -729,7 +729,7 @@ async def generate_chat_completion( payload = { **form_data.model_dump(exclude_none=True, exclude=["metadata"]), } - payload.pop("metadata") + payload.pop("metadata", None) model_id = form_data.model model_info = Models.get_model_by_id(model_id) @@ -788,7 +788,7 @@ async def generate_openai_chat_completion( ): completion_form = OpenAIChatCompletionForm(**form_data) payload = {**completion_form.model_dump(exclude_none=True, exclude=["metadata"])} - payload.pop("metadata") + payload.pop("metadata", None) model_id = completion_form.model model_info = Models.get_model_by_id(model_id) diff --git a/backend/apps/openai/main.py b/backend/apps/openai/main.py index 1313d20910..44b3151e0e 100644 --- a/backend/apps/openai/main.py +++ b/backend/apps/openai/main.py @@ -359,7 +359,7 @@ async def generate_chat_completion( ): idx = 0 payload = {**form_data} - payload.pop("metadata") + payload.pop("metadata", None) model_id = form_data.get("model") model_info = Models.get_model_by_id(model_id) From 4105c9735ea188f115356c0e17eef1f17a10277c Mon Sep 17 00:00:00 2001 From: Candido Sales Gomes Date: Tue, 6 Aug 2024 09:38:42 -0400 Subject: [PATCH 09/73] revert files --- CHANGELOG.md | 24 ------------------------ package.json | 2 +- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5361fbbd1..d62360f878 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,30 +5,6 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.3.12] - 2024-08-05 - -### Added - -- **✨ Migrated to SvelteKit 2**: Significant improvements in performance and simplification of state management. - -### Changed - -- **⬆️ Dependency Updates** - - Added '@sveltejs/vite-plugin-svelte'. - - Upgraded '@sveltejs/adapter-auto' from version 2.0.0 to 3.2.2. - - Upgraded '@sveltejs/adapter-static' from version 2.0.3 to 3.0.2. - - Upgraded '@sveltejs/kit' from version 1.30.0 to 2.5.20. - - Upgraded '@tailwindcss/typography' from version 0.5.10 to 0.5.13. - - Upgraded 'eslint-config-prettier' from version 8.5.0 to 9.1.0. - - Upgraded 'eslint-plugin-cypress' from version 3.0.2 to 3.4.0. - - Upgraded 'eslint-plugin-svelte' from version 2.30.0 to 2.43.0. - - Upgraded 'prettier' from version 2.8.0 to 3.3.3. - - Upgraded 'prettier-plugin-svelte' from version 2.10.1 to 3.2.6. - - Upgraded 'svelte' from version 4.0.5 to 4.2.18. - - Upgraded 'svelte-check' from version 3.4.3 to 3.8.5. - - Upgraded 'typescript' from version 5.0.0 to 5.5.4. - - Upgraded 'vite' from version 4.4.2 to 5.3.5. - ## [0.3.11] - 2024-08-02 ### Added diff --git a/package.json b/package.json index 8d78367b76..a9fadef1ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open-webui", - "version": "0.3.12", + "version": "0.3.11", "private": true, "scripts": { "dev": "npm run pyodide:fetch && vite dev --host", From 2fb4d3356cbf3173b5d9b6d50f080538063d7967 Mon Sep 17 00:00:00 2001 From: Sylvere Richard Date: Wed, 7 Aug 2024 16:33:24 +0200 Subject: [PATCH 10/73] fix: #4158 allow reconnection when websocket is closed log reconnection attempts mark session_id as mandatory on client-side --- src/lib/apis/index.ts | 1 + src/routes/+layout.svelte | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/lib/apis/index.ts b/src/lib/apis/index.ts index c2e90855b6..c4778cadbd 100644 --- a/src/lib/apis/index.ts +++ b/src/lib/apis/index.ts @@ -69,6 +69,7 @@ type ChatCompletedForm = { model: string; messages: string[]; chat_id: string; + session_id: string; }; export const chatCompleted = async (token: string, body: ChatCompletedForm) => { diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index b306c57e35..df72083937 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -111,6 +111,10 @@ if ($config) { const _socket = io(`${WEBUI_BASE_URL}` || undefined, { + reconnection: true, + reconnectionDelay: 1000, + reconnectionDelayMax: 5000, + randomizationFactor: 0.5 path: '/ws/socket.io', auth: { token: localStorage.token } }); @@ -119,6 +123,21 @@ console.log('connected'); }); + _socket.on("reconnect_attempt", (attempt) => { + console.log('reconnect_attempt', attempt); + }); + + _socket.on("reconnect_failed", () => { + console.log('reconnect_failed'); + }); + + _socket.on("disconnect", (reason, details) => { + console.log(`Socket ${socket.id} disconnected due to ${reason}`); + if (details) { + console.log('Additional details:', details); + } + }); + await socket.set(_socket); _socket.on('user-count', (data) => { From 678dd780ee391c8fab48b2eb81f8e1d0664dbf0c Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Wed, 7 Aug 2024 17:39:00 +0200 Subject: [PATCH 11/73] chore: package --- package-lock.json | 960 ++++++++++++++++++---------------------------- package.json | 4 +- 2 files changed, 367 insertions(+), 597 deletions(-) diff --git a/package-lock.json b/package-lock.json index f903771f6c..b7e714ed78 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@codemirror/lang-python": "^6.1.6", "@codemirror/theme-one-dark": "^6.1.2", "@pyscript/core": "^0.4.32", - "@sveltejs/adapter-node": "^1.3.1", + "@sveltejs/adapter-node": "^2.0.0", "async": "^3.2.5", "bits-ui": "^0.19.7", "codemirror": "^6.0.1", @@ -39,31 +39,36 @@ "uuid": "^9.0.1" }, "devDependencies": { - "@sveltejs/adapter-auto": "^2.0.0", - "@sveltejs/adapter-static": "^2.0.3", - "@sveltejs/kit": "^1.30.0", - "@tailwindcss/typography": "^0.5.10", + "@sveltejs/adapter-auto": "3.2.2", + "@sveltejs/adapter-static": "^3.0.2", + "@sveltejs/kit": "^2.5.20", + "@sveltejs/vite-plugin-svelte": "^3.1.1", + "@tailwindcss/typography": "^0.5.13", "@types/bun": "latest", "@typescript-eslint/eslint-plugin": "^6.17.0", "@typescript-eslint/parser": "^6.17.0", "autoprefixer": "^10.4.16", "cypress": "^13.8.1", "eslint": "^8.56.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-cypress": "^3.0.2", - "eslint-plugin-svelte": "^2.30.0", - "i18next-parser": "^8.13.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-cypress": "^3.4.0", + "eslint-plugin-svelte": "^2.43.0", + "i18next-parser": "^9.0.1", "postcss": "^8.4.31", - "prettier": "^2.8.0", - "prettier-plugin-svelte": "^2.10.1", - "svelte": "^4.0.5", - "svelte-check": "^3.4.3", + "prettier": "^3.3.3", + "prettier-plugin-svelte": "^3.2.6", + "svelte": "^4.2.18", + "svelte-check": "^3.8.5", "svelte-confetti": "^1.3.2", "tailwindcss": "^3.3.3", "tslib": "^2.4.1", - "typescript": "^5.0.0", - "vite": "^4.4.2", + "typescript": "^5.5.4", + "vite": "^5.3.5", "vitest": "^1.6.0" + }, + "engines": { + "node": ">=18.13.0 <=21.x.x", + "npm": ">=6.0.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -741,14 +746,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@fastify/busboy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", - "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", - "engines": { - "node": ">=14" - } - }, "node_modules/@floating-ui/core": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", @@ -932,9 +929,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", @@ -1168,208 +1165,192 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", - "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.20.0.tgz", + "integrity": "sha512-TSpWzflCc4VGAUJZlPpgAJE1+V60MePDQnBd7PPkpuEmOy8i87aL6tinFGKBFKuEDikYpig72QzdT3QPYIi+oA==", "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", - "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.20.0.tgz", + "integrity": "sha512-u00Ro/nok7oGzVuh/FMYfNoGqxU5CPWz1mxV85S2w9LxHR8OoMQBuSk+3BKVIDYgkpeOET5yXkx90OYFc+ytpQ==", "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", - "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.20.0.tgz", + "integrity": "sha512-uFVfvzvsdGtlSLuL0ZlvPJvl6ZmrH4CBwLGEFPe7hUmf7htGAN+aXo43R/V6LATyxlKVC/m6UsLb7jbG+LG39Q==", "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", - "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.20.0.tgz", + "integrity": "sha512-xbrMDdlev53vNXexEa6l0LffojxhqDTBeL+VUxuuIXys4x6xyvbKq5XqTXBCEUA8ty8iEJblHvFaWRJTk/icAQ==", "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", - "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.20.0.tgz", + "integrity": "sha512-jMYvxZwGmoHFBTbr12Xc6wOdc2xA5tF5F2q6t7Rcfab68TT0n+r7dgawD4qhPEvasDsVpQi+MgDzj2faOLsZjA==", "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", - "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.20.0.tgz", + "integrity": "sha512-1asSTl4HKuIHIB1GcdFHNNZhxAYEdqML/MW4QmPS4G0ivbEcBr1JKlFLKsIRqjSwOBkdItn3/ZDlyvZ/N6KPlw==", "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", - "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.20.0.tgz", + "integrity": "sha512-COBb8Bkx56KldOYJfMf6wKeYJrtJ9vEgBRAOkfw6Ens0tnmzPqvlpjZiLgkhg6cA3DGzCmLmmd319pmHvKWWlQ==", "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", - "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.20.0.tgz", + "integrity": "sha512-+it+mBSyMslVQa8wSPvBx53fYuZK/oLTu5RJoXogjk6x7Q7sz1GNRsXWjn6SwyJm8E/oMjNVwPhmNdIjwP135Q==", "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", - "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.20.0.tgz", + "integrity": "sha512-yAMvqhPfGKsAxHN8I4+jE0CpLWD8cv4z7CK7BMmhjDuz606Q2tFKkWRY8bHR9JQXYcoLfopo5TTqzxgPUjUMfw==", "cpu": [ "ppc64" ], - "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", - "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.20.0.tgz", + "integrity": "sha512-qmuxFpfmi/2SUkAw95TtNq/w/I7Gpjurx609OOOV7U4vhvUhBcftcmXwl3rqAek+ADBwSjIC4IVNLiszoj3dPA==", "cpu": [ "riscv64" ], - "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", - "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.20.0.tgz", + "integrity": "sha512-I0BtGXddHSHjV1mqTNkgUZLnS3WtsqebAXv11D5BZE/gfw5KoyXSAXVqyJximQXNvNzUo4GKlCK/dIwXlz+jlg==", "cpu": [ "s390x" ], - "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", - "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.20.0.tgz", + "integrity": "sha512-y+eoL2I3iphUg9tN9GB6ku1FA8kOfmF4oUEWhztDJ4KXJy1agk/9+pejOuZkNFhRwHAOxMsBPLbXPd6mJiCwew==", "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", - "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.20.0.tgz", + "integrity": "sha512-hM3nhW40kBNYUkZb/r9k2FKK+/MnKglX7UYd4ZUy5DJs8/sMsIbqWK2piZtVGE3kcXVNj3B2IrUYROJMMCikNg==", "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", - "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.20.0.tgz", + "integrity": "sha512-psegMvP+Ik/Bg7QRJbv8w8PAytPA7Uo8fpFjXyCRHWm6Nt42L+JtoqH8eDQ5hRP7/XW2UiIriy1Z46jf0Oa1kA==", "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", - "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.20.0.tgz", + "integrity": "sha512-GabekH3w4lgAJpVxkk7hUzUf2hICSQO0a/BLFA11/RMxQT92MabKAqyubzDZmMOC/hcJNlc+rrypzNzYl4Dx7A==", "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", - "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.20.0.tgz", + "integrity": "sha512-aJ1EJSuTdGnM6qbVC4B5DSmozPTqIag9fSzXRNNo+humQLG89XpPgdt16Ia56ORD7s+H8Pmyx44uczDQ0yDzpg==", "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -1387,106 +1368,106 @@ "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==" }, "node_modules/@sveltejs/adapter-auto": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-2.1.1.tgz", - "integrity": "sha512-nzi6x/7/3Axh5VKQ8Eed3pYxastxoa06Y/bFhWb7h3Nu+nGRVxKAy3+hBJgmPCwWScy8n0TsstZjSVKfyrIHkg==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-3.2.2.tgz", + "integrity": "sha512-Mso5xPCA8zgcKrv+QioVlqMZkyUQ5MjDJiEPuG/Z7cV/5tmwV7LmcVWk5tZ+H0NCOV1x12AsoSpt/CwFwuVXMA==", "dev": true, "dependencies": { - "import-meta-resolve": "^4.0.0" + "import-meta-resolve": "^4.1.0" }, "peerDependencies": { - "@sveltejs/kit": "^1.0.0" + "@sveltejs/kit": "^2.0.0" } }, "node_modules/@sveltejs/adapter-node": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-node/-/adapter-node-1.3.1.tgz", - "integrity": "sha512-A0VgRQDCDPzdLNoiAbcOxGw4zT1Mc+n1LwT1OmO350R7WxrEqdMUChPPOd1iMfIDWlP4ie6E2d/WQf5es2d4Zw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-node/-/adapter-node-2.1.2.tgz", + "integrity": "sha512-ZfVY5buBclWHoBT+RbkMUViJGEIZ3IfT/0Hvhlgp+qC3LRZwp+wS1Zsw5dgkB2sFDZXctbLNXJtwlkjSp1mw0g==", "dependencies": { - "@rollup/plugin-commonjs": "^25.0.0", - "@rollup/plugin-json": "^6.0.0", - "@rollup/plugin-node-resolve": "^15.0.1", - "rollup": "^3.7.0" + "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "rollup": "^4.8.0" }, "peerDependencies": { - "@sveltejs/kit": "^1.0.0" + "@sveltejs/kit": "^2.0.0" } }, "node_modules/@sveltejs/adapter-static": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-2.0.3.tgz", - "integrity": "sha512-VUqTfXsxYGugCpMqQv1U0LIdbR3S5nBkMMDmpjGVJyM6Q2jHVMFtdWJCkeHMySc6mZxJ+0eZK3T7IgmUCDrcUQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.2.tgz", + "integrity": "sha512-/EBFydZDwfwFfFEuF1vzUseBoRziwKP7AoHAwv+Ot3M084sE/HTVBHf9mCmXfdM9ijprY5YEugZjleflncX5fQ==", "dev": true, "peerDependencies": { - "@sveltejs/kit": "^1.5.0" + "@sveltejs/kit": "^2.0.0" } }, "node_modules/@sveltejs/kit": { - "version": "1.30.4", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.30.4.tgz", - "integrity": "sha512-JSQIQT6XvdchCRQEm7BABxPC56WP5RYVONAi+09S8tmzeP43fBsRlr95bFmsTQM2RHBldfgQk+jgdnsKI75daA==", + "version": "2.5.20", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.20.tgz", + "integrity": "sha512-47rJ5BoYwURE/Rp7FNMLp3NzdbWC9DQ/PmKd0mebxT2D/PrPxZxcLImcD3zsWdX2iS6oJk8ITJbO/N2lWnnUqA==", "hasInstallScript": true, "dependencies": { - "@sveltejs/vite-plugin-svelte": "^2.5.0", - "@types/cookie": "^0.5.1", - "cookie": "^0.5.0", - "devalue": "^4.3.1", + "@types/cookie": "^0.6.0", + "cookie": "^0.6.0", + "devalue": "^5.0.0", "esm-env": "^1.0.0", + "import-meta-resolve": "^4.1.0", "kleur": "^4.1.5", - "magic-string": "^0.30.0", - "mrmime": "^1.0.1", + "magic-string": "^0.30.5", + "mrmime": "^2.0.0", "sade": "^1.8.1", "set-cookie-parser": "^2.6.0", - "sirv": "^2.0.2", - "tiny-glob": "^0.2.9", - "undici": "^5.28.3" + "sirv": "^2.0.4", + "tiny-glob": "^0.2.9" }, "bin": { "svelte-kit": "svelte-kit.js" }, "engines": { - "node": "^16.14 || >=18" + "node": ">=18.13" }, "peerDependencies": { - "svelte": "^3.54.0 || ^4.0.0-next.0 || ^5.0.0-next.0", - "vite": "^4.0.0" + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.3" } }, "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.5.3.tgz", - "integrity": "sha512-erhNtXxE5/6xGZz/M9eXsmI7Pxa6MS7jyTy06zN3Ck++ldrppOnOlJwHHTsMC7DHDQdgUp4NAc4cDNQ9eGdB/w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.1.tgz", + "integrity": "sha512-rimpFEAboBBHIlzISibg94iP09k/KYdHgVhJlcsTfn7KMBhc70jFX/GRWkRdFCc2fdnk+4+Bdfej23cMDnJS6A==", "dependencies": { - "@sveltejs/vite-plugin-svelte-inspector": "^1.0.4", + "@sveltejs/vite-plugin-svelte-inspector": "^2.1.0", "debug": "^4.3.4", "deepmerge": "^4.3.1", "kleur": "^4.1.5", - "magic-string": "^0.30.3", - "svelte-hmr": "^0.15.3", - "vitefu": "^0.2.4" + "magic-string": "^0.30.10", + "svelte-hmr": "^0.16.0", + "vitefu": "^0.2.5" }, "engines": { - "node": "^14.18.0 || >= 16" + "node": "^18.0.0 || >=20" }, "peerDependencies": { - "svelte": "^3.54.0 || ^4.0.0 || ^5.0.0-next.0", - "vite": "^4.0.0" + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" } }, "node_modules/@sveltejs/vite-plugin-svelte-inspector": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-1.0.4.tgz", - "integrity": "sha512-zjiuZ3yydBtwpF3bj0kQNV0YXe+iKE545QGZVTaylW3eAzFr+pJ/cwK8lZEaRp4JtaJXhD5DyWAV4AxLh6DgaQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", + "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", "dependencies": { "debug": "^4.3.4" }, "engines": { - "node": "^14.18.0 || >= 16" + "node": "^18.0.0 || >=20" }, "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^2.2.0", - "svelte": "^3.54.0 || ^4.0.0", - "vite": "^4.0.0" + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" } }, "node_modules/@swc/helpers": { @@ -1498,9 +1479,9 @@ } }, "node_modules/@tailwindcss/typography": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.10.tgz", - "integrity": "sha512-Pe8BuPJQJd3FfRnm6H0ulKIGoMEQS+Vq01R6M5aCrFB/ccR/shT+0kXLjouGC1gFLm9hopTFN+DMP0pfwRWzPw==", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.13.tgz", + "integrity": "sha512-ADGcJ8dX21dVVHIwTRgzrcunY6YY9uSlAHHGVKvkA+vLc5qLwEszvKts40lx7z0qc4clpjclwLeK5rVCV2P/uw==", "dev": true, "dependencies": { "lodash.castarray": "^4.4.0", @@ -1522,9 +1503,9 @@ } }, "node_modules/@types/cookie": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.5.4.tgz", - "integrity": "sha512-7z/eR6O859gyWIAjuvBWFzNURmf2oPBmJlfVWkwehU5nzIyjwBsTh7WMmEEV4JFnHuQ3ex4oyTvfKzcyJVDBNA==" + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" }, "node_modules/@types/d3-scale": { "version": "4.0.8", @@ -3004,12 +2985,12 @@ } }, "node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "dev": true, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/common-tags": { @@ -3045,9 +3026,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { "node": ">= 0.6" } @@ -3726,12 +3707,6 @@ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" }, - "node_modules/de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", - "dev": true - }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -3838,9 +3813,9 @@ } }, "node_modules/devalue": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-4.3.2.tgz", - "integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.0.0.tgz", + "integrity": "sha512-gO+/OMXF7488D+u3ue+G7Y4AA3ZmUnB3eHJXmBTgNHvr4ZNzl36A0ZtG+XCRNYCkYx/bFmw4qtkoFLa+wSrwAA==" }, "node_modules/didyoumean": { "version": "1.2.2", @@ -4196,10 +4171,13 @@ } }, "node_modules/eslint-compat-utils": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz", - "integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", "dev": true, + "dependencies": { + "semver": "^7.5.4" + }, "engines": { "node": ">=12" }, @@ -4208,9 +4186,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", - "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -4220,35 +4198,34 @@ } }, "node_modules/eslint-plugin-cypress": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-3.0.2.tgz", - "integrity": "sha512-5hIWc3SqXSuR+Sd7gmNMzx8yJ3LWQQS0e+qLvEVF4C1JfFtu1s9imtEm1KxlCBCcKb7+6CyR9KQYs0GiI02AlA==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-3.4.0.tgz", + "integrity": "sha512-Rrrr3Ri6wHqzrRr+TyUV7bDS4UnMMrFY1R1PP2F7XdGfe9txDC6lQEshyoNOWqGoPkbbeDm1x1XPc/adxemsnA==", "dev": true, "dependencies": { "globals": "^13.20.0" }, "peerDependencies": { - "eslint": ">=7 <9" + "eslint": ">=7" } }, "node_modules/eslint-plugin-svelte": { - "version": "2.35.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.35.1.tgz", - "integrity": "sha512-IF8TpLnROSGy98Z3NrsKXWDSCbNY2ReHDcrYTuXZMbfX7VmESISR78TWgO9zdg4Dht1X8coub5jKwHzP0ExRug==", + "version": "2.43.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.43.0.tgz", + "integrity": "sha512-REkxQWvg2pp7QVLxQNa+dJ97xUqRe7Y2JJbSWkHSuszu0VcblZtXkPBPckkivk99y5CdLw4slqfPylL2d/X4jQ==", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@jridgewell/sourcemap-codec": "^1.4.14", - "debug": "^4.3.1", - "eslint-compat-utils": "^0.1.2", + "@eslint-community/eslint-utils": "^4.4.0", + "@jridgewell/sourcemap-codec": "^1.4.15", + "eslint-compat-utils": "^0.5.1", "esutils": "^2.0.3", - "known-css-properties": "^0.29.0", - "postcss": "^8.4.5", + "known-css-properties": "^0.34.0", + "postcss": "^8.4.38", "postcss-load-config": "^3.1.4", "postcss-safe-parser": "^6.0.0", - "postcss-selector-parser": "^6.0.11", - "semver": "^7.5.3", - "svelte-eslint-parser": ">=0.33.0 <1.0.0" + "postcss-selector-parser": "^6.1.0", + "semver": "^7.6.2", + "svelte-eslint-parser": "^0.41.0" }, "engines": { "node": "^14.17.0 || >=16.0.0" @@ -4257,8 +4234,8 @@ "url": "https://github.com/sponsors/ota-meshi" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0-0", - "svelte": "^3.37.0 || ^4.0.0" + "eslint": "^7.0.0 || ^8.0.0-0 || ^9.0.0-0", + "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.191" }, "peerDependenciesMeta": { "svelte": { @@ -4267,9 +4244,9 @@ } }, "node_modules/eslint-plugin-svelte/node_modules/postcss-selector-parser": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", - "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", + "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -5104,15 +5081,6 @@ "node": ">= 0.4" } }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, "node_modules/heimdalljs": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/heimdalljs/-/heimdalljs-0.2.6.tgz", @@ -5239,16 +5207,16 @@ } }, "node_modules/i18next-parser": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/i18next-parser/-/i18next-parser-8.13.0.tgz", - "integrity": "sha512-XU7resoeNcpJazh29OncQQUH6HsgCxk06RqBBDAmLHldafxopfCHY1vElyG/o3EY0Sn7XjelAmPTV0SgddJEww==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/i18next-parser/-/i18next-parser-9.0.1.tgz", + "integrity": "sha512-/Pr93/yEBdwsMKRsk4Zn63K368ALhzh8BRVrM6JNGOHy86ZKpiNJI6m8l1S/4T4Ofy1J4dlwkD7N98M70GP4aA==", "dev": true, "dependencies": { "@babel/runtime": "^7.23.2", "broccoli-plugin": "^4.0.7", "cheerio": "^1.0.0-rc.2", "colors": "1.4.0", - "commander": "~11.1.0", + "commander": "~12.1.0", "eol": "^0.9.1", "esbuild": "^0.20.1", "fs-extra": "^11.1.0", @@ -5260,14 +5228,13 @@ "sort-keys": "^5.0.0", "typescript": "^5.0.4", "vinyl": "~3.0.0", - "vinyl-fs": "^4.0.0", - "vue-template-compiler": "^2.6.11" + "vinyl-fs": "^4.0.0" }, "bin": { "i18next": "bin/cli.js" }, "engines": { - "node": ">=16.0.0 || >=18.0.0 || >=20.0.0", + "node": ">=18.0.0 || >=20.0.0 || >=22.0.0", "npm": ">=6", "yarn": ">=1" } @@ -5342,10 +5309,9 @@ } }, "node_modules/import-meta-resolve": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz", - "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==", - "dev": true, + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -5763,9 +5729,9 @@ } }, "node_modules/known-css-properties": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.29.0.tgz", - "integrity": "sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==", + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz", + "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==", "dev": true }, "node_modules/layout-base": { @@ -6051,27 +6017,12 @@ "get-func-name": "^2.0.1" } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/magic-string": { - "version": "0.30.8", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", - "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/marked": { @@ -6750,9 +6701,9 @@ } }, "node_modules/mrmime": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", - "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", "engines": { "node": ">=10" } @@ -7142,9 +7093,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -7210,9 +7161,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", "funding": [ { "type": "opencollective", @@ -7229,7 +7180,7 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "source-map-js": "^1.2.0" }, "engines": { @@ -7430,28 +7381,28 @@ } }, "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=10.13.0" + "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/prettier-plugin-svelte": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-2.10.1.tgz", - "integrity": "sha512-Wlq7Z5v2ueCubWo0TZzKc9XHcm7TDxqcuzRuGd0gcENfzfT4JZ9yDlCbEgxWgiPmLHkBjfOtpAWkcT28MCDpUQ==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.2.6.tgz", + "integrity": "sha512-Y1XWLw7vXUQQZmgv1JAEiLcErqUniAF2wO7QJsw8BVMvpLET2dI5WpEIEJx1r11iHVdSMzQxivyfrH9On9t2IQ==", "dev": true, "peerDependencies": { - "prettier": "^1.16.4 || ^2.0.0", - "svelte": "^3.2.0 || ^4.0.0-next.0" + "prettier": "^3.0.0", + "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" } }, "node_modules/pretty-bytes": { @@ -7887,17 +7838,36 @@ "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" }, "node_modules/rollup": { - "version": "3.29.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", - "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.20.0.tgz", + "integrity": "sha512-6rbWBChcnSGzIlXeIdNIZTopKYad8ZG8ajhl78lGRLsI2rX8IkaotQhVas2Ma+GPxJav19wrSzvRvuiv0YKzWw==", + "dependencies": { + "@types/estree": "1.0.5" + }, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14.18.0", + "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.20.0", + "@rollup/rollup-android-arm64": "4.20.0", + "@rollup/rollup-darwin-arm64": "4.20.0", + "@rollup/rollup-darwin-x64": "4.20.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.20.0", + "@rollup/rollup-linux-arm-musleabihf": "4.20.0", + "@rollup/rollup-linux-arm64-gnu": "4.20.0", + "@rollup/rollup-linux-arm64-musl": "4.20.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.20.0", + "@rollup/rollup-linux-riscv64-gnu": "4.20.0", + "@rollup/rollup-linux-s390x-gnu": "4.20.0", + "@rollup/rollup-linux-x64-gnu": "4.20.0", + "@rollup/rollup-linux-x64-musl": "4.20.0", + "@rollup/rollup-win32-arm64-msvc": "4.20.0", + "@rollup/rollup-win32-ia32-msvc": "4.20.0", + "@rollup/rollup-win32-x64-msvc": "4.20.0", "fsevents": "~2.3.2" } }, @@ -8036,13 +8006,10 @@ } }, "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -8142,14 +8109,6 @@ "node": ">= 10" } }, - "node_modules/sirv/node_modules/mrmime": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", - "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", - "engines": { - "node": ">=10" - } - }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -8543,9 +8502,9 @@ } }, "node_modules/svelte": { - "version": "4.2.12", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.12.tgz", - "integrity": "sha512-d8+wsh5TfPwqVzbm4/HCXC783/KPHV60NvwitJnyTA5lWn1elhXMNWhXGCJ7PwPa8qFUnyJNIyuIRt2mT0WMug==", + "version": "4.2.18", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.18.tgz", + "integrity": "sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==", "dependencies": { "@ampproject/remapping": "^2.2.1", "@jridgewell/sourcemap-codec": "^1.4.15", @@ -8567,15 +8526,13 @@ } }, "node_modules/svelte-check": { - "version": "3.6.8", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.6.8.tgz", - "integrity": "sha512-rhXU7YCDtL+lq2gCqfJDXKTxJfSsCgcd08d7VWBFxTw6IWIbMWSaASbAOD3N0VV9TYSSLUqEBiratLd8WxAJJA==", + "version": "3.8.5", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.8.5.tgz", + "integrity": "sha512-3OGGgr9+bJ/+1nbPgsvulkLC48xBsqsgtc8Wam281H4G9F5v3mYGa2bHRsPuwHC5brKl4AxJH95QF73kmfihGQ==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.17", "chokidar": "^3.4.1", - "fast-glob": "^3.2.7", - "import-fresh": "^3.2.1", "picocolors": "^1.0.0", "sade": "^1.7.4", "svelte-preprocess": "^5.1.3", @@ -8598,16 +8555,16 @@ } }, "node_modules/svelte-eslint-parser": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.33.1.tgz", - "integrity": "sha512-vo7xPGTlKBGdLH8T5L64FipvTrqv3OQRx9d2z5X05KKZDlF4rQk8KViZO4flKERY+5BiVdOh7zZ7JGJWo5P0uA==", + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.41.0.tgz", + "integrity": "sha512-L6f4hOL+AbgfBIB52Z310pg1d2QjRqm7wy3kI1W6hhdhX5bvu7+f0R6w4ykp5HoDdzq+vGhIJmsisaiJDGmVfA==", "dev": true, "dependencies": { - "eslint-scope": "^7.0.0", - "eslint-visitor-keys": "^3.0.0", - "espree": "^9.0.0", - "postcss": "^8.4.29", - "postcss-scss": "^4.0.8" + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "postcss": "^8.4.39", + "postcss-scss": "^4.0.9" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -8616,7 +8573,7 @@ "url": "https://github.com/sponsors/ota-meshi" }, "peerDependencies": { - "svelte": "^3.37.0 || ^4.0.0" + "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.191" }, "peerDependenciesMeta": { "svelte": { @@ -8625,9 +8582,9 @@ } }, "node_modules/svelte-hmr": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.3.tgz", - "integrity": "sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", + "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", "engines": { "node": "^12.20 || ^14.13.1 || >= 16" }, @@ -9119,9 +9076,9 @@ } }, "node_modules/typescript": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", - "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -9150,17 +9107,6 @@ "node": "*" } }, - "node_modules/undici": { - "version": "5.28.4", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", - "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -9382,31 +9328,32 @@ } }, "node_modules/vite": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", - "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.0.tgz", + "integrity": "sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==", "dependencies": { - "esbuild": "^0.18.10", - "postcss": "^8.4.27", - "rollup": "^3.27.1" + "esbuild": "^0.21.3", + "postcss": "^8.4.40", + "rollup": "^4.13.0" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^18.0.0 || >=20.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { - "fsevents": "~2.3.2" + "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": ">= 14", + "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" @@ -9424,6 +9371,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, @@ -9457,100 +9407,25 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/vite-node/node_modules/rollup": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", - "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.17.2", - "@rollup/rollup-android-arm64": "4.17.2", - "@rollup/rollup-darwin-arm64": "4.17.2", - "@rollup/rollup-darwin-x64": "4.17.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", - "@rollup/rollup-linux-arm-musleabihf": "4.17.2", - "@rollup/rollup-linux-arm64-gnu": "4.17.2", - "@rollup/rollup-linux-arm64-musl": "4.17.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", - "@rollup/rollup-linux-riscv64-gnu": "4.17.2", - "@rollup/rollup-linux-s390x-gnu": "4.17.2", - "@rollup/rollup-linux-x64-gnu": "4.17.2", - "@rollup/rollup-linux-x64-musl": "4.17.2", - "@rollup/rollup-win32-arm64-msvc": "4.17.2", - "@rollup/rollup-win32-ia32-msvc": "4.17.2", - "@rollup/rollup-win32-x64-msvc": "4.17.2", - "fsevents": "~2.3.2" - } - }, - "node_modules/vite-node/node_modules/vite": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", - "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", - "dev": true, - "dependencies": { - "esbuild": "^0.20.1", - "postcss": "^8.4.38", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } + "node": ">=12" } }, "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], @@ -9563,9 +9438,9 @@ } }, "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], @@ -9578,9 +9453,9 @@ } }, "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], @@ -9593,9 +9468,9 @@ } }, "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], @@ -9608,9 +9483,9 @@ } }, "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], @@ -9623,9 +9498,9 @@ } }, "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], @@ -9638,9 +9513,9 @@ } }, "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], @@ -9653,9 +9528,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], @@ -9668,9 +9543,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], @@ -9683,9 +9558,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], @@ -9698,9 +9573,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], @@ -9713,9 +9588,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], @@ -9728,9 +9603,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], @@ -9743,9 +9618,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], @@ -9758,9 +9633,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], @@ -9773,9 +9648,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], @@ -9788,9 +9663,9 @@ } }, "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], @@ -9803,9 +9678,9 @@ } }, "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], @@ -9818,9 +9693,9 @@ } }, "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], @@ -9833,9 +9708,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], @@ -9848,9 +9723,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], @@ -9863,9 +9738,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], @@ -9878,9 +9753,9 @@ } }, "node_modules/vite/node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -9889,28 +9764,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/vitefu": { @@ -10101,41 +9977,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/vitest/node_modules/rollup": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", - "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.17.2", - "@rollup/rollup-android-arm64": "4.17.2", - "@rollup/rollup-darwin-arm64": "4.17.2", - "@rollup/rollup-darwin-x64": "4.17.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", - "@rollup/rollup-linux-arm-musleabihf": "4.17.2", - "@rollup/rollup-linux-arm64-gnu": "4.17.2", - "@rollup/rollup-linux-arm64-musl": "4.17.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", - "@rollup/rollup-linux-riscv64-gnu": "4.17.2", - "@rollup/rollup-linux-s390x-gnu": "4.17.2", - "@rollup/rollup-linux-x64-gnu": "4.17.2", - "@rollup/rollup-linux-x64-musl": "4.17.2", - "@rollup/rollup-win32-arm64-msvc": "4.17.2", - "@rollup/rollup-win32-ia32-msvc": "4.17.2", - "@rollup/rollup-win32-x64-msvc": "4.17.2", - "fsevents": "~2.3.2" - } - }, "node_modules/vitest/node_modules/strip-final-newline": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", @@ -10148,71 +9989,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/vitest/node_modules/vite": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", - "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", - "dev": true, - "dependencies": { - "esbuild": "^0.20.1", - "postcss": "^8.4.38", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vue-template-compiler": { - "version": "2.7.16", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", - "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", - "dev": true, - "dependencies": { - "de-indent": "^1.0.2", - "he": "^1.2.0" - } - }, "node_modules/w3c-keyname": { "version": "2.2.8", "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", @@ -10427,12 +10203,6 @@ "node": ">=0.4" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", diff --git a/package.json b/package.json index 8d78367b76..0c7a8518ac 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-cypress": "^3.4.0", "eslint-plugin-svelte": "^2.43.0", - "i18next-parser": "^8.13.0", + "i18next-parser": "^9.0.1", "postcss": "^8.4.31", "prettier": "^3.3.3", "prettier-plugin-svelte": "^3.2.6", @@ -83,4 +83,4 @@ "node": ">=18.13.0 <=21.x.x", "npm": ">=6.0.0" } -} \ No newline at end of file +} From dbe463a53d170c94514bf5454b362de89c31995b Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Wed, 7 Aug 2024 17:39:54 +0200 Subject: [PATCH 12/73] fix --- src/routes/+layout.svelte | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index df72083937..ef582bfc05 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -114,7 +114,7 @@ reconnection: true, reconnectionDelay: 1000, reconnectionDelayMax: 5000, - randomizationFactor: 0.5 + randomizationFactor: 0.5, path: '/ws/socket.io', auth: { token: localStorage.token } }); @@ -123,15 +123,15 @@ console.log('connected'); }); - _socket.on("reconnect_attempt", (attempt) => { + _socket.on('reconnect_attempt', (attempt) => { console.log('reconnect_attempt', attempt); }); - _socket.on("reconnect_failed", () => { + _socket.on('reconnect_failed', () => { console.log('reconnect_failed'); }); - _socket.on("disconnect", (reason, details) => { + _socket.on('disconnect', (reason, details) => { console.log(`Socket ${socket.id} disconnected due to ${reason}`); if (details) { console.log('Additional details:', details); From d72d5d0e8eef814553466eb0b1daf4568816274d Mon Sep 17 00:00:00 2001 From: Carter Roeser Date: Wed, 7 Aug 2024 11:39:51 -0700 Subject: [PATCH 13/73] feat: Add OAuth Email Claim Variable Add an `OAUTH_EMAIL_CLAIM` variable to override the default "email" claim value. --- backend/apps/webui/main.py | 2 ++ backend/config.py | 6 ++++++ backend/main.py | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/backend/apps/webui/main.py b/backend/apps/webui/main.py index a0b9f50085..3c387842d8 100644 --- a/backend/apps/webui/main.py +++ b/backend/apps/webui/main.py @@ -46,6 +46,7 @@ from config import ( AppConfig, OAUTH_USERNAME_CLAIM, OAUTH_PICTURE_CLAIM, + OAUTH_EMAIL_CLAIM, ) from apps.socket.main import get_event_call, get_event_emitter @@ -84,6 +85,7 @@ app.state.config.ENABLE_COMMUNITY_SHARING = ENABLE_COMMUNITY_SHARING app.state.config.OAUTH_USERNAME_CLAIM = OAUTH_USERNAME_CLAIM app.state.config.OAUTH_PICTURE_CLAIM = OAUTH_PICTURE_CLAIM +app.state.config.OAUTH_EMAIL_CLAIM = OAUTH_EMAIL_CLAIM app.state.MODELS = {} app.state.TOOLS = {} diff --git a/backend/config.py b/backend/config.py index 30a970012b..7d6c0bd7c9 100644 --- a/backend/config.py +++ b/backend/config.py @@ -433,6 +433,12 @@ OAUTH_PICTURE_CLAIM = PersistentConfig( os.environ.get("OAUTH_PICTURE_CLAIM", "picture"), ) +OAUTH_EMAIL_CLAIM = PersistentConfig( + "OAUTH_EMAIL_CLAIM", + "oauth.oidc.email_claim", + os.environ.get("OAUTH_EMAIL_CLAIM", "email"), +) + def load_oauth_providers(): OAUTH_PROVIDERS.clear() diff --git a/backend/main.py b/backend/main.py index d7bff888e2..6e4265a5ca 100644 --- a/backend/main.py +++ b/backend/main.py @@ -2158,7 +2158,8 @@ async def oauth_callback(provider: str, request: Request, response: Response): log.warning(f"OAuth callback failed, sub is missing: {user_data}") raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) provider_sub = f"{provider}@{sub}" - email = user_data.get("email", "").lower() + email_claim = webui_app.state.config.OAUTH_EMAIL_CLAIM + email = user_data.get(email_claim, "").lower() # We currently mandate that email addresses are provided if not email: log.warning(f"OAuth callback failed, email is missing: {user_data}") From 958fe9639a08732c04b102ca494d11f522b33b34 Mon Sep 17 00:00:00 2001 From: John Karabudak Date: Wed, 7 Aug 2024 21:45:20 -0230 Subject: [PATCH 14/73] fix: ComfyUI generation no longer causes FastAPI to stall for all users as the get_images() function involves a `while True` loop while waiting for a response from ComfyUI and is not async, when image generation is running the entire UI becomes unresponsive for all users. furthermore, when image generation takes too long, the Docker health check starts failing. this is certainly a bad fix as it does not convert everything to async, but rather just puts the blocking loop in a separate thread. however, it works and it at least fixes the problem for now. --- backend/apps/images/main.py | 2 +- backend/apps/images/utils/comfyui.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/backend/apps/images/main.py b/backend/apps/images/main.py index 4239f3f457..a418f26938 100644 --- a/backend/apps/images/main.py +++ b/backend/apps/images/main.py @@ -514,7 +514,7 @@ async def image_generations( data = ImageGenerationPayload(**data) - res = comfyui_generate_image( + res = await comfyui_generate_image( app.state.config.MODEL, data, user.id, diff --git a/backend/apps/images/utils/comfyui.py b/backend/apps/images/utils/comfyui.py index 6c37f0c497..f82076809e 100644 --- a/backend/apps/images/utils/comfyui.py +++ b/backend/apps/images/utils/comfyui.py @@ -1,3 +1,4 @@ +import asyncio import websocket # NOTE: websocket-client (https://github.com/websocket-client/websocket-client) import uuid import json @@ -328,7 +329,7 @@ class ImageGenerationPayload(BaseModel): flux_fp8_clip: Optional[bool] = None -def comfyui_generate_image( +async def comfyui_generate_image( model: str, payload: ImageGenerationPayload, client_id, base_url ): ws_url = base_url.replace("http://", "ws://").replace("https://", "wss://") @@ -397,7 +398,7 @@ def comfyui_generate_image( return None try: - images = get_images(ws, comfyui_prompt, client_id, base_url) + images = await asyncio.to_thread(get_images, ws, comfyui_prompt, client_id, base_url) except Exception as e: log.exception(f"Error while receiving images: {e}") images = None From 71d88fe35d68dc8ba5907d63fb787ea33bed072e Mon Sep 17 00:00:00 2001 From: Jan-Timo Hesse Date: Thu, 8 Aug 2024 09:45:52 +0200 Subject: [PATCH 15/73] revert --- Dockerfile | 4 +--- backend/start.sh | 5 ----- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index f1ea4e0645..8078bf0eac 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,7 +38,6 @@ ARG USE_OLLAMA ARG USE_CUDA_VER ARG USE_EMBEDDING_MODEL ARG USE_RERANKING_MODEL -ARG EXTRA_MODULES ARG UID ARG GID @@ -50,8 +49,7 @@ ENV ENV=prod \ USE_CUDA_DOCKER=${USE_CUDA} \ USE_CUDA_DOCKER_VER=${USE_CUDA_VER} \ USE_EMBEDDING_MODEL_DOCKER=${USE_EMBEDDING_MODEL} \ - USE_RERANKING_MODEL_DOCKER=${USE_RERANKING_MODEL} \ - EXTRA_MODULES_DOCKER=${EXTRA_MODULES} + USE_RERANKING_MODEL_DOCKER=${USE_RERANKING_MODEL} ## Basis URL Config ## ENV OLLAMA_BASE_URL="/ollama" \ diff --git a/backend/start.sh b/backend/start.sh index b499736b8f..0a5c48e8c4 100755 --- a/backend/start.sh +++ b/backend/start.sh @@ -30,11 +30,6 @@ if [[ "${USE_CUDA_DOCKER,,}" == "true" ]]; then export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib/python3.11/site-packages/torch/lib:/usr/local/lib/python3.11/site-packages/nvidia/cudnn/lib" fi -if [ -n "$EXTRA_MODULES_DOCKER" ]; then - echo "Loading extra modules: $EXTRA_MODULES_DOCKER" - uv pip install --system $EXTRA_MODULES_DOCKER --no-cache-dir -fi - # Check if SPACE_ID is set, if so, configure for space if [ -n "$SPACE_ID" ]; then echo "Configuring for HuggingFace Space deployment" From 367fa039a0fa0f7d3599437421057186549761e2 Mon Sep 17 00:00:00 2001 From: Jan-Timo Hesse Date: Thu, 8 Aug 2024 09:46:14 +0200 Subject: [PATCH 16/73] added install_frontmatter_requirements --- backend/apps/webui/utils.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/backend/apps/webui/utils.py b/backend/apps/webui/utils.py index 96d2b29ebf..34682920b8 100644 --- a/backend/apps/webui/utils.py +++ b/backend/apps/webui/utils.py @@ -1,6 +1,8 @@ from importlib import util import os import re +import sys +import subprocess from config import TOOLS_DIR, FUNCTIONS_DIR @@ -52,6 +54,7 @@ def load_toolkit_module_by_id(toolkit_id): frontmatter = extract_frontmatter(toolkit_path) try: + install_frontmatter_requirements(frontmatter.get("requirements", "")) spec.loader.exec_module(module) print(f"Loaded module: {module.__name__}") if hasattr(module, "Tools"): @@ -73,6 +76,7 @@ def load_function_module_by_id(function_id): frontmatter = extract_frontmatter(function_path) try: + install_frontmatter_requirements(frontmatter.get("requirements", "")) spec.loader.exec_module(module) print(f"Loaded module: {module.__name__}") if hasattr(module, "Pipe"): @@ -88,3 +92,12 @@ def load_function_module_by_id(function_id): # Move the file to the error folder os.rename(function_path, f"{function_path}.error") raise e + +def install_frontmatter_requirements(requirements): + if requirements: + req_list = [req.strip() for req in requirements.split(',')] + for req in req_list: + print(f"Installing requirement: {req}") + subprocess.check_call([sys.executable, "-m", "pip", "install", req]) + else: + print("No requirements found in frontmatter.") \ No newline at end of file From e6bbce439d81443cf37da9573df1fc9bc4d813e8 Mon Sep 17 00:00:00 2001 From: Michael Poluektov Date: Thu, 8 Aug 2024 10:52:09 +0100 Subject: [PATCH 17/73] fix: repeat_penalty --- backend/apps/ollama/main.py | 3 --- backend/utils/misc.py | 7 ++++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/backend/apps/ollama/main.py b/backend/apps/ollama/main.py index 79a2773ba0..3d86b852a9 100644 --- a/backend/apps/ollama/main.py +++ b/backend/apps/ollama/main.py @@ -31,8 +31,6 @@ from utils.utils import ( get_verified_user, get_admin_user, ) -from utils.task import prompt_template - from config import ( SRC_LOG_LEVELS, @@ -47,7 +45,6 @@ from config import ( from utils.misc import ( apply_model_params_to_body_ollama, calculate_sha256, - add_or_update_system_message, apply_model_params_to_body_openai, apply_model_system_prompt_to_body, ) diff --git a/backend/utils/misc.py b/backend/utils/misc.py index ffe6a6e530..993aa9f600 100644 --- a/backend/utils/misc.py +++ b/backend/utils/misc.py @@ -181,7 +181,12 @@ def apply_model_params_to_body_ollama(params: dict, form_data: dict) -> dict: ] mappings = {i: lambda x: x for i in opts} mappings = {**mappings, **OPENAI_MAPPINGS} - return apply_model_params_to_body(params, form_data, mappings) + form_data = apply_model_params_to_body(params, form_data, mappings) + + # only param that changes name + if (param := params.get("frequency_penalty", None)) is not None: + form_data["repeat_penalty"] = param + return form_data def get_gravatar_url(email): From 8cdf9814bde8049a31c09961263f3ef91d4607c0 Mon Sep 17 00:00:00 2001 From: Michael Poluektov Date: Thu, 8 Aug 2024 11:01:00 +0100 Subject: [PATCH 18/73] fix: name differences --- backend/utils/misc.py | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/backend/utils/misc.py b/backend/utils/misc.py index 993aa9f600..3dc1cf7ee3 100644 --- a/backend/utils/misc.py +++ b/backend/utils/misc.py @@ -148,23 +148,24 @@ def apply_model_params_to_body( return form_data -OPENAI_MAPPINGS = { - "temperature": float, - "top_p": int, - "max_tokens": int, - "frequency_penalty": int, - "seed": lambda x: x, - "stop": lambda x: [bytes(s, "utf-8").decode("unicode_escape") for s in x], -} - - # inplace function: form_data is modified def apply_model_params_to_body_openai(params: dict, form_data: dict) -> dict: - return apply_model_params_to_body(params, form_data, OPENAI_MAPPINGS) + mappings = { + "temperature": float, + "top_p": int, + "max_tokens": int, + "frequency_penalty": int, + "seed": lambda x: x, + "stop": lambda x: [bytes(s, "utf-8").decode("unicode_escape") for s in x], + } + return apply_model_params_to_body(params, form_data, mappings) def apply_model_params_to_body_ollama(params: dict, form_data: dict) -> dict: opts = [ + "temperature", + "top_p", + "seed", "mirostat", "mirostat_eta", "mirostat_tau", @@ -180,12 +181,18 @@ def apply_model_params_to_body_ollama(params: dict, form_data: dict) -> dict: "num_thread", ] mappings = {i: lambda x: x for i in opts} - mappings = {**mappings, **OPENAI_MAPPINGS} form_data = apply_model_params_to_body(params, form_data, mappings) - # only param that changes name - if (param := params.get("frequency_penalty", None)) is not None: - form_data["repeat_penalty"] = param + name_differences = { + "max_tokens": "num_predict", + "frequency_penalty": "repeat_penalty", + } + + for key, value in name_differences.items(): + if (param := params.get(key, None)) is not None: + form_data[value] = param + + print(form_data) return form_data From a725801e5559956f33291706b89af774cbefb472 Mon Sep 17 00:00:00 2001 From: Michael Poluektov Date: Thu, 8 Aug 2024 11:30:13 +0100 Subject: [PATCH 19/73] fix: formatting test errors, remove print, merge dev --- backend/apps/images/main.py | 2 +- backend/apps/images/utils/comfyui.py | 11 ++++++----- backend/apps/openai/main.py | 4 ++-- backend/utils/misc.py | 1 - 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/backend/apps/images/main.py b/backend/apps/images/main.py index 4239f3f457..a418f26938 100644 --- a/backend/apps/images/main.py +++ b/backend/apps/images/main.py @@ -514,7 +514,7 @@ async def image_generations( data = ImageGenerationPayload(**data) - res = comfyui_generate_image( + res = await comfyui_generate_image( app.state.config.MODEL, data, user.id, diff --git a/backend/apps/images/utils/comfyui.py b/backend/apps/images/utils/comfyui.py index 6c37f0c497..ec0f8c59e9 100644 --- a/backend/apps/images/utils/comfyui.py +++ b/backend/apps/images/utils/comfyui.py @@ -1,3 +1,4 @@ +import asyncio import websocket # NOTE: websocket-client (https://github.com/websocket-client/websocket-client) import uuid import json @@ -328,7 +329,7 @@ class ImageGenerationPayload(BaseModel): flux_fp8_clip: Optional[bool] = None -def comfyui_generate_image( +async def comfyui_generate_image( model: str, payload: ImageGenerationPayload, client_id, base_url ): ws_url = base_url.replace("http://", "ws://").replace("https://", "wss://") @@ -377,9 +378,9 @@ def comfyui_generate_image( comfyui_prompt["12"]["inputs"]["weight_dtype"] = payload.flux_weight_dtype if payload.flux_fp8_clip: - comfyui_prompt["11"]["inputs"][ - "clip_name2" - ] = "t5xxl_fp8_e4m3fn.safetensors" + comfyui_prompt["11"]["inputs"]["clip_name2"] = ( + "t5xxl_fp8_e4m3fn.safetensors" + ) comfyui_prompt["5"]["inputs"]["batch_size"] = payload.n comfyui_prompt["5"]["inputs"]["width"] = payload.width @@ -397,7 +398,7 @@ def comfyui_generate_image( return None try: - images = get_images(ws, comfyui_prompt, client_id, base_url) + images = await asyncio.to_thread(get_images, ws, comfyui_prompt, client_id, base_url) except Exception as e: log.exception(f"Error while receiving images: {e}") images = None diff --git a/backend/apps/openai/main.py b/backend/apps/openai/main.py index 831da783b2..50de53a537 100644 --- a/backend/apps/openai/main.py +++ b/backend/apps/openai/main.py @@ -359,10 +359,10 @@ async def generate_chat_completion( ): idx = 0 payload = {**form_data} - + if "metadata" in payload: del payload["metadata"] - + model_id = form_data.get("model") model_info = Models.get_model_by_id(model_id) diff --git a/backend/utils/misc.py b/backend/utils/misc.py index 3dc1cf7ee3..9de19d3f69 100644 --- a/backend/utils/misc.py +++ b/backend/utils/misc.py @@ -192,7 +192,6 @@ def apply_model_params_to_body_ollama(params: dict, form_data: dict) -> dict: if (param := params.get(key, None)) is not None: form_data[value] = param - print(form_data) return form_data From 309cd645f13de63d36650293f1424195955168d5 Mon Sep 17 00:00:00 2001 From: Michael Poluektov Date: Thu, 8 Aug 2024 12:30:07 +0100 Subject: [PATCH 20/73] undo del --- backend/apps/ollama/main.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/apps/ollama/main.py b/backend/apps/ollama/main.py index 3d86b852a9..d5ef829423 100644 --- a/backend/apps/ollama/main.py +++ b/backend/apps/ollama/main.py @@ -726,7 +726,8 @@ async def generate_chat_completion( payload = { **form_data.model_dump(exclude_none=True, exclude=["metadata"]), } - payload.pop("metadata", None) + if "metadata" in payload: + del payload["metadata"] model_id = form_data.model model_info = Models.get_model_by_id(model_id) @@ -785,7 +786,8 @@ async def generate_openai_chat_completion( ): completion_form = OpenAIChatCompletionForm(**form_data) payload = {**completion_form.model_dump(exclude_none=True, exclude=["metadata"])} - payload.pop("metadata", None) + if "metadata" in payload: + del payload["metadata"] model_id = completion_form.model model_info = Models.get_model_by_id(model_id) From fa4d1d42a53bd6df6e62467bc825c866cab23451 Mon Sep 17 00:00:00 2001 From: Michael Poluektov Date: Thu, 8 Aug 2024 12:41:41 +0100 Subject: [PATCH 21/73] fix: backend format test --- backend/apps/images/utils/comfyui.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/apps/images/utils/comfyui.py b/backend/apps/images/utils/comfyui.py index ec0f8c59e9..ab6f4e4075 100644 --- a/backend/apps/images/utils/comfyui.py +++ b/backend/apps/images/utils/comfyui.py @@ -1,6 +1,5 @@ import asyncio import websocket # NOTE: websocket-client (https://github.com/websocket-client/websocket-client) -import uuid import json import urllib.request import urllib.parse @@ -398,7 +397,9 @@ async def comfyui_generate_image( return None try: - images = await asyncio.to_thread(get_images, ws, comfyui_prompt, client_id, base_url) + images = await asyncio.to_thread( + get_images, ws, comfyui_prompt, client_id, base_url + ) except Exception as e: log.exception(f"Error while receiving images: {e}") images = None From 204a4fbe7a3cf77f83f5b310fdd75b9853f5361d Mon Sep 17 00:00:00 2001 From: Michael Poluektov Date: Thu, 8 Aug 2024 12:45:23 +0100 Subject: [PATCH 22/73] fix: backend format test --- backend/apps/images/utils/comfyui.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/apps/images/utils/comfyui.py b/backend/apps/images/utils/comfyui.py index ab6f4e4075..94875d9595 100644 --- a/backend/apps/images/utils/comfyui.py +++ b/backend/apps/images/utils/comfyui.py @@ -377,9 +377,9 @@ async def comfyui_generate_image( comfyui_prompt["12"]["inputs"]["weight_dtype"] = payload.flux_weight_dtype if payload.flux_fp8_clip: - comfyui_prompt["11"]["inputs"]["clip_name2"] = ( - "t5xxl_fp8_e4m3fn.safetensors" - ) + comfyui_prompt["11"]["inputs"][ + "clip_name2" + ] = "t5xxl_fp8_e4m3fn.safetensors" comfyui_prompt["5"]["inputs"]["batch_size"] = payload.n comfyui_prompt["5"]["inputs"]["width"] = payload.width From 13403cd7dc15a684f685180756fa5ce1dcee4059 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 8 Aug 2024 14:24:47 +0200 Subject: [PATCH 23/73] enh: codeblock i18n --- src/lib/components/chat/Messages/CodeBlock.svelte | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lib/components/chat/Messages/CodeBlock.svelte b/src/lib/components/chat/Messages/CodeBlock.svelte index daa8a8cd06..2d4133298f 100644 --- a/src/lib/components/chat/Messages/CodeBlock.svelte +++ b/src/lib/components/chat/Messages/CodeBlock.svelte @@ -1,12 +1,15 @@ diff --git a/src/lib/components/chat/Messages/MarkdownTokens.svelte b/src/lib/components/chat/Messages/MarkdownTokens.svelte index 530548e56c..1f27fb4eb1 100644 --- a/src/lib/components/chat/Messages/MarkdownTokens.svelte +++ b/src/lib/components/chat/Messages/MarkdownTokens.svelte @@ -1,141 +1,112 @@ -
- {#each tokens as token, tokenIdx (`${id}-${tokenIdx}`)} - {#if token.type === 'code'} - {#if token.lang === 'mermaid'} -
{revertSanitizedResponseContent(token.text)}
- {:else} - - {/if} +{#each tokens as token, tokenIdx} + {#if token.type === 'hr'} +
+ {:else if token.type === 'heading'} + + + + {:else if token.type === 'code'} + + {:else if token.type === 'table'} + + + + {#each token.header as header, headerIdx} + + {/each} + + + + {#each token.rows as row, rowIdx} + + {#each row ?? [] as cell, cellIdx} + + {/each} + + {/each} + +
+ +
+ +
+ {:else if token.type === 'blockquote'} +
+ +
+ {:else if token.type === 'list'} + {#if token.ordered} +
    + {#each token.items as item, itemIdx} +
  1. + +
  2. + {/each} +
{:else} - {@html marked.parse(token.raw, { - ...defaults, - gfm: true, - breaks: true, - renderer - })} +
    + {#each token.items as item, itemIdx} +
  • + +
  • + {/each} +
{/if} - {/each} -
+ {:else if token.type === 'html'} + {@html token.text} + {:else if token.type === 'paragraph'} +

+ +

+ {:else if token.type === 'text'} + {#if top} +

+ {#if token.tokens} + + {:else} + {unescapeHtml(token.text)} + {/if} +

+ {:else if token.tokens} + + {:else} + {unescapeHtml(token.text)} + {/if} + {:else if token.type === 'space'} + {''} + {:else} + {console.log('Unknown token', token)} + {/if} +{/each} diff --git a/src/lib/components/chat/Messages/ResponseMessage.svelte b/src/lib/components/chat/Messages/ResponseMessage.svelte index fdc846205b..1226b5231b 100644 --- a/src/lib/components/chat/Messages/ResponseMessage.svelte +++ b/src/lib/components/chat/Messages/ResponseMessage.svelte @@ -99,7 +99,7 @@ tooltipInstance[0]?.destroy(); } - renderLatex(); + // renderLatex(); if (message.info) { let tooltipContent = ''; @@ -420,7 +420,7 @@ {/if}
{#if (message?.statusHistory ?? [...(message?.status ? [message?.status] : [])]).length > 0} From 92e77d7b33fc8498a3164a5cc30eb64110978020 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Fri, 9 Aug 2024 00:01:38 +0200 Subject: [PATCH 30/73] refac: katex --- package-lock.json | 18 +++++ package.json | 1 + .../chat/Messages/KatexRenderer.svelte | 9 +++ .../chat/Messages/MarkdownInlineTokens.svelte | 16 +++- .../chat/Messages/MarkdownTokens.svelte | 14 +++- .../chat/Messages/ResponseMessage.svelte | 16 ++-- src/lib/utils/index.ts | 5 +- src/lib/utils/katex-extension.ts | 80 +++++++++++++++++++ 8 files changed, 147 insertions(+), 12 deletions(-) create mode 100644 src/lib/components/chat/Messages/KatexRenderer.svelte create mode 100644 src/lib/utils/katex-extension.ts diff --git a/package-lock.json b/package-lock.json index b7e714ed78..2006a3fd30 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "js-sha256": "^0.10.1", "katex": "^0.16.9", "marked": "^9.1.0", + "marked-katex-extension": "^5.1.1", "mermaid": "^10.9.1", "pyodide": "^0.26.1", "socket.io-client": "^4.2.0", @@ -1544,6 +1545,11 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/katex": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", + "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==" + }, "node_modules/@types/mdast": { "version": "3.0.15", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", @@ -6036,6 +6042,18 @@ "node": ">= 16" } }, + "node_modules/marked-katex-extension": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/marked-katex-extension/-/marked-katex-extension-5.1.1.tgz", + "integrity": "sha512-piquiCyZpZ1aiocoJlJkRXr+hkk5UI4xw9GhRZiIAAgvX5rhzUDSJ0seup1JcsgueC8MLNDuqe5cRcAzkFE42Q==", + "dependencies": { + "@types/katex": "^0.16.7" + }, + "peerDependencies": { + "katex": ">=0.16 <0.17", + "marked": ">=4 <15" + } + }, "node_modules/matcher-collection": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-2.0.1.tgz", diff --git a/package.json b/package.json index 0c7a8518ac..bd2b173bf8 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "js-sha256": "^0.10.1", "katex": "^0.16.9", "marked": "^9.1.0", + "marked-katex-extension": "^5.1.1", "mermaid": "^10.9.1", "pyodide": "^0.26.1", "socket.io-client": "^4.2.0", diff --git a/src/lib/components/chat/Messages/KatexRenderer.svelte b/src/lib/components/chat/Messages/KatexRenderer.svelte new file mode 100644 index 0000000000..766454c298 --- /dev/null +++ b/src/lib/components/chat/Messages/KatexRenderer.svelte @@ -0,0 +1,9 @@ + + +{@html katex.renderToString(content, { displayMode, throwOnError: false })} diff --git a/src/lib/components/chat/Messages/MarkdownInlineTokens.svelte b/src/lib/components/chat/Messages/MarkdownInlineTokens.svelte index 7f984264b2..170429f4be 100644 --- a/src/lib/components/chat/Messages/MarkdownInlineTokens.svelte +++ b/src/lib/components/chat/Messages/MarkdownInlineTokens.svelte @@ -1,8 +1,11 @@ @@ -25,14 +28,21 @@ {:else if token.type === 'codespan'} - {unescapeHtml(token.text.replaceAll('&', '&'))} + {revertSanitizedResponseContent(token.raw)} {:else if token.type === 'br'}
{:else if token.type === 'del'} + {:else if token.type === 'inlineKatex'} + {#if token.text} + + {/if} {:else if token.type === 'text'} - {unescapeHtml(token.text)} + {token.raw} {/if} {/each} diff --git a/src/lib/components/chat/Messages/MarkdownTokens.svelte b/src/lib/components/chat/Messages/MarkdownTokens.svelte index 1f27fb4eb1..089a0847ac 100644 --- a/src/lib/components/chat/Messages/MarkdownTokens.svelte +++ b/src/lib/components/chat/Messages/MarkdownTokens.svelte @@ -1,17 +1,22 @@ + {#each tokens as token, tokenIdx} {#if token.type === 'hr'}
@@ -104,6 +109,13 @@ {:else} {unescapeHtml(token.text)} {/if} + {:else if token.type === 'inlineKatex'} + {#if token.text} + + {/if} {:else if token.type === 'space'} {''} {:else} diff --git a/src/lib/components/chat/Messages/ResponseMessage.svelte b/src/lib/components/chat/Messages/ResponseMessage.svelte index 1226b5231b..2ecbd418c4 100644 --- a/src/lib/components/chat/Messages/ResponseMessage.svelte +++ b/src/lib/components/chat/Messages/ResponseMessage.svelte @@ -4,7 +4,6 @@ import { marked } from 'marked'; import tippy from 'tippy.js'; import auto_render from 'katex/dist/contrib/auto-render.mjs'; - import 'katex/dist/katex.min.css'; import mermaid from 'mermaid'; import { fade } from 'svelte/transition'; @@ -79,19 +78,24 @@ let tokens; + import 'katex/dist/katex.min.css'; + + import markedKatex from '$lib/utils/katex-extension'; + + const options = { + throwOnError: false + }; + + marked.use(markedKatex(options)); + $: (async () => { if (message?.content) { tokens = marked.lexer( replaceTokens(sanitizeResponseContent(message?.content), model?.name, $user?.name) ); - // console.log(message?.content, tokens); } })(); - $: if (message) { - renderStyling(); - } - const renderStyling = async () => { await tick(); diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 5b5c690478..de3a2ca2cb 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -25,7 +25,8 @@ const convertLatexToSingleLine = (content) => { export const sanitizeResponseContent = (content: string) => { // replace single backslash with double backslash - content = content.replace(/\\/g, '\\\\'); + content = content.replace(/\\\\/g, '\\\\\\\\'); + content = convertLatexToSingleLine(content); // First, temporarily replace valid
+
+
+
{$i18n.t('num_gpu (Ollama)')}
+ + +
+ + {#if (params?.num_gpu ?? null) !== null} +
+
+ +
+
+ +
+
+ {/if} +
+