From 78ebae60958c45b461b681577b453c2a71c06ed6 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 22 Oct 2023 00:16:34 -0500 Subject: [PATCH 1/9] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 38 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..dd84ea78 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..bbcbbe7d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From f4f1283cd5c1ac461e80d3128c113b64252b6006 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Sat, 21 Oct 2023 14:43:56 -0600 Subject: [PATCH 2/9] feat: enable static builds --- package-lock.json | 17 ++++++++++++++++ package.json | 1 + src/lib/constants.ts | 8 ++++---- src/routes/+layout.js | 16 +++++++++++++++ src/routes/+page.server.ts | 28 +++----------------------- src/routes/+page.svelte | 40 ++++++++++++++++++++++++++------------ svelte.config.js | 8 ++++++-- 7 files changed, 75 insertions(+), 43 deletions(-) create mode 100644 src/routes/+layout.js diff --git a/package-lock.json b/package-lock.json index 7ce78925..4e8b9ed4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ }, "devDependencies": { "@sveltejs/adapter-auto": "^2.0.0", + "@sveltejs/adapter-static": "^2.0.3", "@sveltejs/kit": "^1.20.4", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", @@ -759,6 +760,15 @@ "@sveltejs/kit": "^1.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==", + "dev": true, + "peerDependencies": { + "@sveltejs/kit": "^1.5.0" + } + }, "node_modules/@sveltejs/kit": { "version": "1.26.0", "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.26.0.tgz", @@ -4254,6 +4264,13 @@ "rollup": "^3.7.0" } }, + "@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==", + "dev": true, + "requires": {} + }, "@sveltejs/kit": { "version": "1.26.0", "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.26.0.tgz", diff --git a/package.json b/package.json index ea472a6f..f6259075 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ }, "devDependencies": { "@sveltejs/adapter-auto": "^2.0.0", + "@sveltejs/adapter-static": "^2.0.3", "@sveltejs/kit": "^1.20.4", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", diff --git a/src/lib/constants.ts b/src/lib/constants.ts index d76fce8a..c6e18bf9 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -1,7 +1,7 @@ import { browser, dev } from '$app/environment'; -export const ENDPOINT = browser - ? `http://${location.hostname}:11434` +export const API_ENDPOINT = browser + ? `https://localhost/api` : dev - ? 'http://127.0.0.1:11434' - : 'http://host.docker.internal:11434'; + ? `http://localhost:11434/api` + : 'http://host.docker.internal:11434/api'; diff --git a/src/routes/+layout.js b/src/routes/+layout.js new file mode 100644 index 00000000..8a35c5d4 --- /dev/null +++ b/src/routes/+layout.js @@ -0,0 +1,16 @@ +// if you want to generate a static html file +// for your page. +// Documentation: https://kit.svelte.dev/docs/page-options#prerender +export const prerender = true; + +// if you want to Generate a SPA +// you have to set ssr to false. +// This is not the case (so set as true or comment the line) +// Documentation: https://kit.svelte.dev/docs/page-options#ssr +export const ssr = true; + +// How to manage the trailing slashes in the URLs +// the URL for about page witll be /about with 'ignore' (default) +// the URL for about page witll be /about/ with 'always' +// https://kit.svelte.dev/docs/page-options#trailingslash +export const trailingSlash = 'ignore'; diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts index f0286982..2899c2fb 100644 --- a/src/routes/+page.server.ts +++ b/src/routes/+page.server.ts @@ -1,30 +1,8 @@ -import { ENDPOINT } from '$lib/constants'; import type { PageServerLoad } from './$types'; -export const load: PageServerLoad = async ({ url }) => { - const OLLAMA_ENDPOINT = process.env.OLLAMA_ENDPOINT; - console.log(OLLAMA_ENDPOINT); - const models = await fetch( - `${OLLAMA_ENDPOINT != undefined ? OLLAMA_ENDPOINT : ENDPOINT}/api/tags`, - { - method: 'GET', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json' - } - } - ) - .then(async (res) => { - if (!res.ok) throw await res.json(); - return res.json(); - }) - .catch((error) => { - console.log(error); - return null; - }); - +export const load: PageServerLoad = () => { + const API_ENDPOINT = process.env.API_ENDPOINT; return { - models: models?.models ?? [], - OLLAMA_ENDPOINT: process.env.OLLAMA_ENDPOINT + API_ENDPOINT }; }; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 063fd427..7c747c26 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -9,18 +9,23 @@ import 'highlight.js/styles/dark.min.css'; import type { PageData } from './$types'; - import { ENDPOINT as SERVER_ENDPOINT } from '$lib/constants'; + import { API_ENDPOINT as DEV_API_ENDPOINT } from '$lib/constants'; import { onMount, tick } from 'svelte'; import { page } from '$app/stores'; - const suggestions = $page.url.searchParams.get('suggestions'); + const suggestions = ''; // $page.url.searchParams.get('suggestions'); import Navbar from '$lib/components/layout/Navbar.svelte'; import SettingsModal from '$lib/components/chat/SettingsModal.svelte'; - export let data: PageData; - $: ({ models, OLLAMA_ENDPOINT } = data); + /* export let data: PageData; */ + /* $: ({ API_ENDPOINT } = data); */ + /* if (!API_ENDPOINT) { */ + /* API_ENDPOINT = DEV_API_ENDPOINT; */ + /* } */ + /* console.log('API_ENDPOINT',API_ENDPOINT) */ + /* console.log('DEV_API_ENDPOINT', DEV_API_ENDPOINT) */ - let ENDPOINT; + let models = []; let textareaElement; let showSettings = false; let db; @@ -36,10 +41,21 @@ let messages = []; onMount(async () => { - ENDPOINT = OLLAMA_ENDPOINT ? OLLAMA_ENDPOINT : SERVER_ENDPOINT; - console.log(OLLAMA_ENDPOINT); - console.log(SERVER_ENDPOINT); - console.log(ENDPOINT); + /* console.log('API_ENDPOINT 2', API_ENDPOINT) */ + const resp = await fetch(`${DEV_API_ENDPOINT}/tags`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json' + } + }); + if (!resp.ok) { + let msg = await resp.text(); + let err = new Error(msg); + throw err; + } + const data = await resp.json(); + models = data.models; let settings = localStorage.getItem('settings'); if (settings) { @@ -267,7 +283,7 @@ messages = [...messages, responseMessage]; window.scrollTo({ top: document.body.scrollHeight }); - const res = await fetch(`${ENDPOINT}/api/generate`, { + const res = await fetch(`${API_ENDPOINT}/generate`, { method: 'POST', headers: { 'Content-Type': 'text/event-stream' @@ -363,7 +379,7 @@ messages = [...messages, responseMessage]; window.scrollTo({ top: document.body.scrollHeight }); - const res = await fetch(`${ENDPOINT}/api/generate`, { + const res = await fetch(`${API_ENDPOINT}/generate`, { method: 'POST', headers: { 'Content-Type': 'text/event-stream' @@ -443,7 +459,7 @@ const generateTitle = async (user_prompt) => { console.log('generateTitle'); - const res = await fetch(`${ENDPOINT}/api/generate`, { + const res = await fetch(`${API_ENDPOINT}/generate`, { method: 'POST', headers: { 'Content-Type': 'text/event-stream' diff --git a/svelte.config.js b/svelte.config.js index 2214c60d..fdcd0148 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,4 +1,4 @@ -import adapter from '@sveltejs/adapter-node'; +import adapter from '@sveltejs/adapter-static'; import { vitePreprocess } from '@sveltejs/kit/vite'; /** @type {import('@sveltejs/kit').Config} */ @@ -11,7 +11,11 @@ const config = { // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. // If your environment is not supported or you settled on a specific environment, switch out the adapter. // See https://kit.svelte.dev/docs/adapters for more information about adapters. - adapter: adapter() + adapter: adapter({ + pages: 'build', + assets: 'build', + fallback: null + }) } }; From 86395a8c1f01c6a7f38a23ad58b6cedcf891522f Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 21 Oct 2023 16:14:12 -0700 Subject: [PATCH 3/9] feat: enable buildtime API_ENDPOINT env var --- .env.example | 2 + Dockerfile | 11 +- README.md | 18 +- package-lock.json | 651 +++++++++++++++++++++++++++++++++++-- package.json | 2 + run.sh | 2 +- src/lib/constants.ts | 24 +- src/routes/+layout.js | 2 +- src/routes/+page.server.ts | 8 - src/routes/+page.svelte | 36 +- 10 files changed, 692 insertions(+), 64 deletions(-) create mode 100644 .env.example delete mode 100644 src/routes/+page.server.ts diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..601c5844 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +OLLAMA_API_ENDPOINT="" +PUBLIC_API_ENDPOINT="$OLLAMA_API_ENDPOINT" \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 9748ee01..4ac679a9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,20 @@ # syntax=docker/dockerfile:1 FROM node:latest - WORKDIR /app + +ARG OLLAMA_API_ENDPOINT='' +RUN echo $OLLAMA_API_ENDPOINT + ENV ENV prod +ENV PUBLIC_API_ENDPOINT $OLLAMA_API_ENDPOINT +RUN echo $PUBLIC_API_ENDPOINT + COPY package.json package-lock.json ./ RUN npm ci - COPY . . RUN npm run build -CMD [ "node", "./build/index.js"] +CMD [ "npm", "run", "start"] diff --git a/README.md b/README.md index d1063f5e..b67aaf10 100644 --- a/README.md +++ b/README.md @@ -7,15 +7,25 @@ ChatGPT-Style Web Interface for Ollama 🦙 ## Features ⭐ - 🖥️ **Intuitive Interface**: Our chat interface takes inspiration from ChatGPT, ensuring a user-friendly experience. + - 📱 **Responsive Design**: Enjoy a seamless experience on both desktop and mobile devices. + - ⚡ **Swift Responsiveness**: Enjoy fast and responsive performance. + - 🚀 **Effortless Setup**: Install seamlessly using Docker for a hassle-free experience. + - 🤖 **Multiple Model Support**: Seamlessly switch between different chat models for diverse interactions. + - 📜 **Chat History**: Effortlessly access and manage your conversation history. + - 📤📥 **Import/Export Chat History**: Seamlessly move your chat data in and out of the platform. + - ⚙️ **Fine-Tuned Control with Advanced Parameters**: Gain a deeper level of control by adjusting parameters such as temperature and defining your system prompts to tailor the conversation to your specific preferences and needs. + - 💻 **Code Syntax Highlighting**: Enjoy enhanced code readability with our syntax highlighting feature. -- 🔗 **External Ollama Server Connection**: Link to the model when Ollama is hosted on a different server via the environment variable -e OLLAMA_ENDPOINT="http://[insert your Ollama address]". + +- 🔗 **External Ollama Server Connection**: You can seamlessly connect to an external Ollama server hosted on a different address by setting the environment variable during the Docker build process. Execute the following command to include the Ollama API endpoint in the Docker image: `docker build --build-arg OLLAMA_API_ENDPOINT="http://[Your Ollama URL]/api" -t ollama-webui .`. + - 🌟 **Continuous Updates**: We are committed to improving Ollama Web UI with regular updates and new features. ## How to Install 🚀 @@ -40,7 +50,7 @@ OLLAMA_HOST=0.0.0.0 OLLAMA_ORIGINS=* ollama serve ```bash docker build -t ollama-webui . -docker run -d -p 3000:3000 --add-host=host.docker.internal:host-gateway --name ollama-webui --restart always ollama-webui +docker run -d -p 3000:8080 --name ollama-webui --restart always ollama-webui ``` Your Ollama Web UI should now be hosted at [http://localhost:3000](http://localhost:3000). Enjoy! 😄 @@ -50,8 +60,8 @@ Your Ollama Web UI should now be hosted at [http://localhost:3000](http://localh If Ollama is hosted on a server other than your local machine, you can connect to it using the following environment variable: ```bash -docker build -t ollama-webui . -docker run -d -p 3000:3000 --add-host=host.docker.internal:host-gateway -e OLLAMA_ENDPOINT="http://[insert your ollama url]" --name ollama-webui --restart always ollama-webui +docker build --build-arg OLLAMA_API_ENDPOINT="http://[Your Ollama URL]/api" -t ollama-webui . +docker run -d -p 3000:8080 --name ollama-webui --restart always ollama-webui ``` ## What's Next? 🚀 diff --git a/package-lock.json b/package-lock.json index 4e8b9ed4..7080e3cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@sveltejs/adapter-node": "^1.3.1", "file-saver": "^2.0.5", "highlight.js": "^11.9.0", + "http-server": "^14.1.1", "idb": "^7.1.1", "marked": "^9.1.0", "svelte-french-toast": "^1.2.0", @@ -1108,7 +1109,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -1167,6 +1167,14 @@ "node": ">=8" } }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dependencies": { + "lodash": "^4.17.14" + } + }, "node_modules/autoprefixer": { "version": "10.4.16", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", @@ -1217,6 +1225,17 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -1300,6 +1319,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1342,7 +1374,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -1409,7 +1440,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -1420,8 +1450,7 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/commander": { "version": "4.1.1", @@ -1451,6 +1480,14 @@ "node": ">= 0.6" } }, + "node_modules/corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1519,6 +1556,19 @@ "node": ">=0.10.0" } }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -1846,6 +1896,11 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1966,6 +2021,25 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/fraction.js": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.6.tgz", @@ -1997,6 +2071,28 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -2074,6 +2170,17 @@ "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -2098,11 +2205,62 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "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==", + "bin": { + "he": "bin/he" + } + }, "node_modules/highlight.js": { "version": "11.9.0", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", @@ -2111,6 +2269,67 @@ "node": ">=12.0.0" } }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-server": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", + "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", + "dependencies": { + "basic-auth": "^2.0.1", + "chalk": "^4.1.2", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.6", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + }, + "bin": { + "http-server": "bin/http-server" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/idb": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", @@ -2379,6 +2598,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -2446,6 +2670,17 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -2471,7 +2706,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2480,7 +2714,6 @@ "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, "dependencies": { "minimist": "^1.2.6" }, @@ -2585,6 +2818,14 @@ "node": ">= 6" } }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2593,6 +2834,14 @@ "wrappy": "1" } }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "bin": { + "opener": "bin/opener-bin.js" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -2737,6 +2986,27 @@ "node": ">= 6" } }, + "node_modules/portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "dependencies": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", @@ -2952,6 +3222,20 @@ "node": ">=6" } }, + "node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -2993,6 +3277,11 @@ "node": ">=8.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "node_modules/resolve": { "version": "1.22.6", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", @@ -3092,6 +3381,16 @@ "node": ">=6" } }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "node_modules/sander": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", @@ -3116,6 +3415,11 @@ "rimraf": "bin.js" } }, + "node_modules/secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==" + }, "node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -3136,6 +3440,20 @@ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==" }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -3157,6 +3475,19 @@ "node": ">=8" } }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/sirv": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.3.tgz", @@ -3284,7 +3615,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -3685,6 +4015,17 @@ "node": ">=14.0" } }, + "node_modules/union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dependencies": { + "qs": "^6.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", @@ -3724,6 +4065,11 @@ "punycode": "^2.1.0" } }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -3809,6 +4155,17 @@ } } }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4480,7 +4837,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -4527,6 +4883,14 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, + "async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "requires": { + "lodash": "^4.17.14" + } + }, "autoprefixer": { "version": "10.4.16", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", @@ -4554,6 +4918,14 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + } + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -4602,6 +4974,16 @@ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==" }, + "call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "requires": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -4624,7 +5006,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4673,7 +5054,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -4681,8 +5061,7 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "commander": { "version": "4.1.1", @@ -4706,6 +5085,11 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" }, + "corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==" + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -4751,6 +5135,16 @@ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==" }, + "define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "requires": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, "dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -4991,6 +5385,11 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5092,6 +5491,11 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, + "follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==" + }, "fraction.js": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.6.tgz", @@ -5109,6 +5513,22 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "optional": true }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "requires": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -5165,6 +5585,14 @@ "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -5185,14 +5613,90 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "requires": { + "get-intrinsic": "^1.2.2" + } + }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "requires": { + "function-bind": "^1.1.2" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, "highlight.js": { "version": "11.9.0", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", "integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==" }, + "html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "requires": { + "whatwg-encoding": "^2.0.0" + } + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-server": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", + "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", + "requires": { + "basic-auth": "^2.0.1", + "chalk": "^4.1.2", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.6", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + } + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, "idb": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", @@ -5400,6 +5904,11 @@ "p-locate": "^5.0.0" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -5449,6 +5958,11 @@ "picomatch": "^2.3.1" } }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, "min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -5467,14 +5981,12 @@ "minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" }, "mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, "requires": { "minimist": "^1.2.6" } @@ -5546,6 +6058,11 @@ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", "dev": true }, + "object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -5554,6 +6071,11 @@ "wrappy": "1" } }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==" + }, "optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -5656,6 +6178,26 @@ "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true }, + "portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "requires": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, "postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", @@ -5760,6 +6302,14 @@ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, + "qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "requires": { + "side-channel": "^1.0.4" + } + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -5784,6 +6334,11 @@ "picomatch": "^2.2.1" } }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "resolve": { "version": "1.22.6", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", @@ -5840,6 +6395,16 @@ "mri": "^1.1.0" } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "sander": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", @@ -5863,6 +6428,11 @@ } } }, + "secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==" + }, "semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -5877,6 +6447,17 @@ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==" }, + "set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "requires": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -5892,6 +6473,16 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, "sirv": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.3.tgz", @@ -5984,7 +6575,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -6230,6 +6820,14 @@ "@fastify/busboy": "^2.0.0" } }, + "union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "requires": { + "qs": "^6.4.0" + } + }, "update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", @@ -6249,6 +6847,11 @@ "punycode": "^2.1.0" } }, + "url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -6277,6 +6880,14 @@ "integrity": "sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==", "requires": {} }, + "whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "requires": { + "iconv-lite": "0.6.3" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index f6259075..2f454eda 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "0.0.1", "private": true, "scripts": { + "start": "http-server ./build", "dev": "vite dev --host", "build": "vite build", "preview": "vite preview", @@ -40,6 +41,7 @@ "@sveltejs/adapter-node": "^1.3.1", "file-saver": "^2.0.5", "highlight.js": "^11.9.0", + "http-server": "^14.1.1", "idb": "^7.1.1", "marked": "^9.1.0", "svelte-french-toast": "^1.2.0", diff --git a/run.sh b/run.sh index 9d0d0360..2c520052 100644 --- a/run.sh +++ b/run.sh @@ -1,5 +1,5 @@ docker stop ollama-webui || true docker rm ollama-webui || true docker build -t ollama-webui . -docker run -d -p 3000:3000 --add-host=host.docker.internal:host-gateway --name ollama-webui --restart always ollama-webui +docker run -d -p 3000:8080 --name ollama-webui --restart always ollama-webui docker image prune -f \ No newline at end of file diff --git a/src/lib/constants.ts b/src/lib/constants.ts index c6e18bf9..4d7baeb1 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -1,7 +1,19 @@ -import { browser, dev } from '$app/environment'; +import { browser } from '$app/environment'; +import { PUBLIC_API_ENDPOINT } from '$env/static/public'; -export const API_ENDPOINT = browser - ? `https://localhost/api` - : dev - ? `http://localhost:11434/api` - : 'http://host.docker.internal:11434/api'; +export const API_ENDPOINT = + PUBLIC_API_ENDPOINT === '' + ? browser + ? `http://${location.hostname}:11434/api` + : `http://localhost:11434/api` + : PUBLIC_API_ENDPOINT; + +// Source: https://kit.svelte.dev/docs/modules#$env-static-public +// This feature, akin to $env/static/private, exclusively incorporates environment variables +// that are prefixed with config.kit.env.publicPrefix (usually set to PUBLIC_). +// Consequently, these variables can be securely exposed to client-side code. + +// Example of the .env configuration: +// OLLAMA_API_ENDPOINT="http://localhost:11434/api" +// # Public +// PUBLIC_API_ENDPOINT=$OLLAMA_API_ENDPOINT diff --git a/src/routes/+layout.js b/src/routes/+layout.js index 8a35c5d4..9220eb55 100644 --- a/src/routes/+layout.js +++ b/src/routes/+layout.js @@ -7,7 +7,7 @@ export const prerender = true; // you have to set ssr to false. // This is not the case (so set as true or comment the line) // Documentation: https://kit.svelte.dev/docs/page-options#ssr -export const ssr = true; +// export const ssr = false; // How to manage the trailing slashes in the URLs // the URL for about page witll be /about with 'ignore' (default) diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts deleted file mode 100644 index 2899c2fb..00000000 --- a/src/routes/+page.server.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { PageServerLoad } from './$types'; - -export const load: PageServerLoad = () => { - const API_ENDPOINT = process.env.API_ENDPOINT; - return { - API_ENDPOINT - }; -}; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 7c747c26..cd9013c5 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -7,23 +7,13 @@ const { saveAs } = fileSaver; import hljs from 'highlight.js'; import 'highlight.js/styles/dark.min.css'; - - import type { PageData } from './$types'; - import { API_ENDPOINT as DEV_API_ENDPOINT } from '$lib/constants'; + import { API_ENDPOINT } from '$lib/constants'; import { onMount, tick } from 'svelte'; - import { page } from '$app/stores'; - const suggestions = ''; // $page.url.searchParams.get('suggestions'); import Navbar from '$lib/components/layout/Navbar.svelte'; import SettingsModal from '$lib/components/chat/SettingsModal.svelte'; - /* export let data: PageData; */ - /* $: ({ API_ENDPOINT } = data); */ - /* if (!API_ENDPOINT) { */ - /* API_ENDPOINT = DEV_API_ENDPOINT; */ - /* } */ - /* console.log('API_ENDPOINT',API_ENDPOINT) */ - /* console.log('DEV_API_ENDPOINT', DEV_API_ENDPOINT) */ + let suggestions = ''; // $page.url.searchParams.get('suggestions'); let models = []; let textareaElement; @@ -41,20 +31,24 @@ let messages = []; onMount(async () => { - /* console.log('API_ENDPOINT 2', API_ENDPOINT) */ - const resp = await fetch(`${DEV_API_ENDPOINT}/tags`, { + console.log(API_ENDPOINT); + const res = await fetch(`${API_ENDPOINT}/tags`, { method: 'GET', headers: { Accept: 'application/json', 'Content-Type': 'application/json' } - }); - if (!resp.ok) { - let msg = await resp.text(); - let err = new Error(msg); - throw err; - } - const data = await resp.json(); + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((error) => { + console.log(error); + return { models: [] }; + }); + + const data = res; models = data.models; let settings = localStorage.getItem('settings'); From b035de1b869ca4946102d8de8fc14df39ebf78ba Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 21 Oct 2023 22:21:50 -0700 Subject: [PATCH 4/9] Update node.js.yaml --- .github/workflows/node.js.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/node.js.yaml b/.github/workflows/node.js.yaml index 694cd772..29a9cd8d 100644 --- a/.github/workflows/node.js.yaml +++ b/.github/workflows/node.js.yaml @@ -6,6 +6,8 @@ on: jobs: build: name: 'Fmt, Lint, & Build' + env: + PUBLIC_API_ENDPOINT: '' runs-on: ubuntu-latest strategy: matrix: From c307777a6db9f2336882a7034452d3d88d748add Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Sun, 22 Oct 2023 00:28:27 -0600 Subject: [PATCH 5/9] feat: update .env.example and add Caddyfile --- .env.example | 8 ++++-- Caddyfile.localhost | 64 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 Caddyfile.localhost diff --git a/.env.example b/.env.example index 601c5844..9ca55625 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,6 @@ -OLLAMA_API_ENDPOINT="" -PUBLIC_API_ENDPOINT="$OLLAMA_API_ENDPOINT" \ No newline at end of file +PUBLIC_API_ENDPOINT="http://localhost:11434/api" + +OLLAMA_API_ID='my-api-token' +OLLAMA_API_TOKEN='xxxxxxxxxxxxxxxx' +# generated by passing the token to `caddy hash-password` +OLLAMA_API_TOKEN_DIGEST='$2a$14$iyyuawykR92xTHNR9lWzfu.uCct/9/xUPX3zBqLqrjAu0usNRPbyi' diff --git a/Caddyfile.localhost b/Caddyfile.localhost new file mode 100644 index 00000000..80728eed --- /dev/null +++ b/Caddyfile.localhost @@ -0,0 +1,64 @@ +# Run with +# caddy run --envfile ./example.env --config ./Caddyfile.localhost +# +# This is configured for +# - Automatic HTTPS (even for localhost) +# - Reverse Proxying to Ollama API Base URL (http://localhost:11434/api) +# - CORS +# - HTTP Basic Auth API Tokens (uncomment basicauth section) + + +# CORS Preflight (OPTIONS) + Request (GET, POST, PATCH, PUT, DELETE) +(cors-api) { + @match-cors-api-preflight method OPTIONS + handle @match-cors-api-preflight { + header { + Access-Control-Allow-Origin "{http.request.header.origin}" + Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS" + Access-Control-Allow-Headers "Origin, Accept, Authorization, Content-Type, X-Requested-With" + Access-Control-Allow-Credentials "true" + Access-Control-Max-Age "3600" + defer + } + respond "" 204 + } + + @match-cors-api-request { + not { + header Origin "{http.request.scheme}://{http.request.host}" + } + header Origin "{http.request.header.origin}" + } + handle @match-cors-api-request { + header { + Access-Control-Allow-Origin "{http.request.header.origin}" + Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS" + Access-Control-Allow-Headers "Origin, Accept, Authorization, Content-Type, X-Requested-With" + Access-Control-Allow-Credentials "true" + Access-Control-Max-Age "3600" + defer + } + } +} + +# replace localhost with example.com or whatever +localhost { + ## HTTP Basic Auth + ## (uncomment to enable) + # basicauth { + # # see .example.env for how to generate tokens + # {env.OLLAMA_API_ID} {env.OLLAMA_API_TOKEN_DIGEST} + # } + + handle /api/* { + # Comment to disable CORS + import cors-api + + reverse_proxy localhost:11434 + } + + # Same-Origin Static Web Server + file_server { + root ./build/ + } +} From 859adee36957e09339086684e3957c301d05405c Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Sun, 22 Oct 2023 00:38:12 -0600 Subject: [PATCH 6/9] chore: change to API_ENDPOINT to conventional name API_BASE_URL --- .github/workflows/node.js.yaml | 2 +- Dockerfile | 8 ++++---- README.md | 9 +++++---- .env.example => example.env | 2 +- src/lib/constants.ts | 12 ++++++------ src/routes/+page.svelte | 12 ++++++------ 6 files changed, 23 insertions(+), 22 deletions(-) rename .env.example => example.env (81%) diff --git a/.github/workflows/node.js.yaml b/.github/workflows/node.js.yaml index 29a9cd8d..20a04dc0 100644 --- a/.github/workflows/node.js.yaml +++ b/.github/workflows/node.js.yaml @@ -7,7 +7,7 @@ jobs: build: name: 'Fmt, Lint, & Build' env: - PUBLIC_API_ENDPOINT: '' + PUBLIC_API_BASE_URL: '' runs-on: ubuntu-latest strategy: matrix: diff --git a/Dockerfile b/Dockerfile index 4ac679a9..b3749ade 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,13 +3,13 @@ FROM node:latest WORKDIR /app -ARG OLLAMA_API_ENDPOINT='' -RUN echo $OLLAMA_API_ENDPOINT +ARG OLLAMA_API_BASE_URL='' +RUN echo $OLLAMA_API_BASE_URL ENV ENV prod -ENV PUBLIC_API_ENDPOINT $OLLAMA_API_ENDPOINT -RUN echo $PUBLIC_API_ENDPOINT +ENV PUBLIC_API_BASE_URL $OLLAMA_API_BASE_URL +RUN echo $PUBLIC_API_BASE_URL COPY package.json package-lock.json ./ RUN npm ci diff --git a/README.md b/README.md index b67aaf10..d20e47fa 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ ChatGPT-Style Web Interface for Ollama 🦙 - 💻 **Code Syntax Highlighting**: Enjoy enhanced code readability with our syntax highlighting feature. -- 🔗 **External Ollama Server Connection**: You can seamlessly connect to an external Ollama server hosted on a different address by setting the environment variable during the Docker build process. Execute the following command to include the Ollama API endpoint in the Docker image: `docker build --build-arg OLLAMA_API_ENDPOINT="http://[Your Ollama URL]/api" -t ollama-webui .`. +- 🔗 **External Ollama Server Connection**: You can seamlessly connect to an external Ollama server hosted on a different address by setting the environment variable during the Docker build process. Execute the following command to include the Ollama API base URL in the Docker image: `docker build --build-arg OLLAMA_API_BASE_URL='http://localhost:11343/api' -t ollama-webui .`. - 🌟 **Continuous Updates**: We are committed to improving Ollama Web UI with regular updates and new features. @@ -49,7 +49,8 @@ OLLAMA_HOST=0.0.0.0 OLLAMA_ORIGINS=* ollama serve ### Using Docker 🐳 ```bash -docker build -t ollama-webui . +docker build --build-arg OLLAMA_API_BASE_URL='http://localhost:11434/api' -t ollama-webui . + docker run -d -p 3000:8080 --name ollama-webui --restart always ollama-webui ``` @@ -57,10 +58,10 @@ Your Ollama Web UI should now be hosted at [http://localhost:3000](http://localh #### Connecting to Ollama on a Different Server -If Ollama is hosted on a server other than your local machine, you can connect to it using the following environment variable: +If Ollama is hosted on a server other than your local machine, change `OLLAMA_API_BASE_URL` to match: ```bash -docker build --build-arg OLLAMA_API_ENDPOINT="http://[Your Ollama URL]/api" -t ollama-webui . +docker build --build-arg OLLAMA_API_BASE_URL='https://example.com/api' -t ollama-webui . docker run -d -p 3000:8080 --name ollama-webui --restart always ollama-webui ``` diff --git a/.env.example b/example.env similarity index 81% rename from .env.example rename to example.env index 9ca55625..e7394bd8 100644 --- a/.env.example +++ b/example.env @@ -1,4 +1,4 @@ -PUBLIC_API_ENDPOINT="http://localhost:11434/api" +PUBLIC_API_BASE_URL="http://localhost:11434/api" OLLAMA_API_ID='my-api-token' OLLAMA_API_TOKEN='xxxxxxxxxxxxxxxx' diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 4d7baeb1..5450a17a 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -1,12 +1,12 @@ import { browser } from '$app/environment'; -import { PUBLIC_API_ENDPOINT } from '$env/static/public'; +import { PUBLIC_API_BASE_URL } from '$env/static/public'; -export const API_ENDPOINT = - PUBLIC_API_ENDPOINT === '' +export const API_BASE_URL = + PUBLIC_API_BASE_URL === '' ? browser ? `http://${location.hostname}:11434/api` : `http://localhost:11434/api` - : PUBLIC_API_ENDPOINT; + : PUBLIC_API_BASE_URL; // Source: https://kit.svelte.dev/docs/modules#$env-static-public // This feature, akin to $env/static/private, exclusively incorporates environment variables @@ -14,6 +14,6 @@ export const API_ENDPOINT = // Consequently, these variables can be securely exposed to client-side code. // Example of the .env configuration: -// OLLAMA_API_ENDPOINT="http://localhost:11434/api" +// OLLAMA_API_BASE_URL="http://localhost:11434/api" // # Public -// PUBLIC_API_ENDPOINT=$OLLAMA_API_ENDPOINT +// PUBLIC_API_BASE_URL=$OLLAMA_API_BASE_URL diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index cd9013c5..1d57ea4d 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -7,7 +7,7 @@ const { saveAs } = fileSaver; import hljs from 'highlight.js'; import 'highlight.js/styles/dark.min.css'; - import { API_ENDPOINT } from '$lib/constants'; + import { API_BASE_URL } from '$lib/constants'; import { onMount, tick } from 'svelte'; import Navbar from '$lib/components/layout/Navbar.svelte'; @@ -31,8 +31,8 @@ let messages = []; onMount(async () => { - console.log(API_ENDPOINT); - const res = await fetch(`${API_ENDPOINT}/tags`, { + console.log(API_BASE_URL); + const res = await fetch(`${API_BASE_URL}/tags`, { method: 'GET', headers: { Accept: 'application/json', @@ -277,7 +277,7 @@ messages = [...messages, responseMessage]; window.scrollTo({ top: document.body.scrollHeight }); - const res = await fetch(`${API_ENDPOINT}/generate`, { + const res = await fetch(`${API_BASE_URL}/generate`, { method: 'POST', headers: { 'Content-Type': 'text/event-stream' @@ -373,7 +373,7 @@ messages = [...messages, responseMessage]; window.scrollTo({ top: document.body.scrollHeight }); - const res = await fetch(`${API_ENDPOINT}/generate`, { + const res = await fetch(`${API_BASE_URL}/generate`, { method: 'POST', headers: { 'Content-Type': 'text/event-stream' @@ -453,7 +453,7 @@ const generateTitle = async (user_prompt) => { console.log('generateTitle'); - const res = await fetch(`${API_ENDPOINT}/generate`, { + const res = await fetch(`${API_BASE_URL}/generate`, { method: 'POST', headers: { 'Content-Type': 'text/event-stream' From 87c8467dd63af404d43d47aaa3339406a8ba7c20 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Sun, 22 Oct 2023 00:49:25 -0600 Subject: [PATCH 7/9] doc: how to build and test static site --- README.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/README.md b/README.md index d20e47fa..d34ba444 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,49 @@ docker build --build-arg OLLAMA_API_BASE_URL='https://example.com/api' -t ollama docker run -d -p 3000:8080 --name ollama-webui --restart always ollama-webui ``` +## How to Build for Static Deployment + +1. Install `node` + + ```sh + # Mac, Linux + curl https://webi.sh/node@lts | sh + source ~/.config/envman/PATH.env + ``` + + ```pwsh + # Windows + curl.exe https://webi.ms/node@lts | powershell + ``` + +2. Clone & Enter the project + ```sh + git clone https://github.com/ollama-webui/ollama-webui.git + pushd ./ollama-webui/ + ``` +3. Create and edit `.env` + ```sh + cp -RPp example.env .env + ``` +4. Run in dev mode, or build the site for deployment + - Test in Dev mode: + ```sh + npm run dev + ``` + - Build for Deploy: \ + (`PUBLIC_API_BASE_URL` will overwrite the value in `.env`) + ```sh + PUBLIC_API_BASE_URL='https://example.com/api' npm run build + ``` +5. Test the build with `caddy` (or the server of your choice) + + ```sh + curl https://webi.sh/caddy | sh + + PUBLIC_API_BASE_URL='https://localhost/api' npm run build + caddy run --envfile .env --config ./Caddyfile.localhost + ``` + ## What's Next? 🚀 ### To-Do List 📝 From 6129f41273bbb9e7fa4de3c76ab4909f906c173f Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sun, 22 Oct 2023 10:09:38 -0700 Subject: [PATCH 8/9] doc: clarify usage of OLLAMA_API_BASE_URL --- README.md | 5 +++-- example.env | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d34ba444..70fcadb8 100644 --- a/README.md +++ b/README.md @@ -48,9 +48,10 @@ OLLAMA_HOST=0.0.0.0 OLLAMA_ORIGINS=* ollama serve ### Using Docker 🐳 -```bash -docker build --build-arg OLLAMA_API_BASE_URL='http://localhost:11434/api' -t ollama-webui . +If Ollama is hosted on your local machine, run the following command: +```bash +docker build --build-arg OLLAMA_API_BASE_URL='' -t ollama-webui . docker run -d -p 3000:8080 --name ollama-webui --restart always ollama-webui ``` diff --git a/example.env b/example.env index e7394bd8..09911a5c 100644 --- a/example.env +++ b/example.env @@ -1,4 +1,6 @@ -PUBLIC_API_BASE_URL="http://localhost:11434/api" +# must be defined, but defaults to 'http://{location.hostname}:11434/api' +# can also use path, such as '/api' +PUBLIC_API_BASE_URL='' OLLAMA_API_ID='my-api-token' OLLAMA_API_TOKEN='xxxxxxxxxxxxxxxx' From f25359f455a5361956cd65e126b7ce90e5423f4d Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sun, 22 Oct 2023 12:41:20 -0700 Subject: [PATCH 9/9] doc: contributor added & typo fix --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 70fcadb8..452ce0f7 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ ChatGPT-Style Web Interface for Ollama 🦙 - 💻 **Code Syntax Highlighting**: Enjoy enhanced code readability with our syntax highlighting feature. -- 🔗 **External Ollama Server Connection**: You can seamlessly connect to an external Ollama server hosted on a different address by setting the environment variable during the Docker build process. Execute the following command to include the Ollama API base URL in the Docker image: `docker build --build-arg OLLAMA_API_BASE_URL='http://localhost:11343/api' -t ollama-webui .`. +- 🔗 **External Ollama Server Connection**: You can seamlessly connect to an external Ollama server hosted on a different address by setting the environment variable during the Docker build process. Execute the following command to include the Ollama API base URL in the Docker image: `docker build --build-arg OLLAMA_API_BASE_URL='http://localhost:11434/api' -t ollama-webui .`. - 🌟 **Continuous Updates**: We are committed to improving Ollama Web UI with regular updates and new features. @@ -131,6 +131,7 @@ A big shoutout to our amazing contributors who have helped make this project pos - [Ollama Team](https://github.com/jmorganca/ollama) - [Timothy J. Baek](https://github.com/tjbck) +- [AJ ONeal](https://github.com/coolaj86) ## License 📜