├── sdk
├── memx_sdk
│ ├── __init__.py
│ ├── test_client.py
│ └── client.py
├── dist
│ ├── memx_sdk-0.1.1.tar.gz
│ └── memx_sdk-0.1.1-py3-none-any.whl
├── pyproject.toml
├── LICENSE
├── README.md
└── poetry.lock
├── assets
└── example.gif
├── Makefile
├── frontend
├── memx-frontend
│ ├── app
│ │ ├── favicon.ico
│ │ ├── components
│ │ │ ├── LogoutButton.js
│ │ │ ├── Header.js
│ │ │ ├── KeyViewer.js
│ │ │ ├── CreateKeyForm.js
│ │ │ └── AuthForm.js
│ │ ├── globals.css
│ │ ├── layout.js
│ │ ├── login
│ │ │ └── page.js
│ │ └── page.js
│ ├── public
│ │ ├── example.gif
│ │ ├── vercel.svg
│ │ ├── window.svg
│ │ ├── file.svg
│ │ ├── globe.svg
│ │ └── next.svg
│ ├── postcss.config.mjs
│ ├── next.config.mjs
│ ├── jsconfig.json
│ ├── package.json
│ ├── .gitignore
│ ├── README.md
│ └── package-lock.json
└── streamlit.py
├── .gitignore
├── config
└── acl.json
├── auth.py
├── Dockerfile
├── examples
├── query_agent.py
├── monitor_agent.py
├── test.py
├── explorer_agent.py
└── synthesizer_agent.py
├── store.py
├── docker-compose.yml
├── schema.py
├── pubsub.py
├── pyproject.toml
├── LICENSE
├── validate_api.py
├── main.py
├── README.md
└── requirements.txt
/sdk/memx_sdk/__init__.py:
--------------------------------------------------------------------------------
1 | from .client import memxContext
2 |
--------------------------------------------------------------------------------
/assets/example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MehulG/memX/HEAD/assets/example.gif
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | dev:
2 | docker-compose up --build
3 |
4 | down:
5 | docker-compose down
6 |
--------------------------------------------------------------------------------
/sdk/dist/memx_sdk-0.1.1.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MehulG/memX/HEAD/sdk/dist/memx_sdk-0.1.1.tar.gz
--------------------------------------------------------------------------------
/frontend/memx-frontend/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MehulG/memX/HEAD/frontend/memx-frontend/app/favicon.ico
--------------------------------------------------------------------------------
/sdk/dist/memx_sdk-0.1.1-py3-none-any.whl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MehulG/memX/HEAD/sdk/dist/memx_sdk-0.1.1-py3-none-any.whl
--------------------------------------------------------------------------------
/frontend/memx-frontend/public/example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MehulG/memX/HEAD/frontend/memx-frontend/public/example.gif
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /__pycache__
2 | /sdk/memx_sdk.egg-info
3 | /sdk/memx_sdk.egg-info
4 | /sdk/memx_sdk/__pycache__
5 | /frontend/.streamlit
6 | .env
--------------------------------------------------------------------------------
/frontend/memx-frontend/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | const config = {
2 | plugins: ["@tailwindcss/postcss"],
3 | };
4 |
5 | export default config;
6 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {};
3 |
4 | export default nextConfig;
5 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/config/acl.json:
--------------------------------------------------------------------------------
1 | {
2 | "agent_key_1": [
3 | "memx:query",
4 | "memx:context",
5 | "memx:search_results:0",
6 | "memx:thoughts:0",
7 | "memx:thoughts:1",
8 | "memx:summary"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | // "baseUrl": ".",
4 | "paths": {
5 | // "@/*": ["./*"],
6 | // "@/components/*": ["components/*"]
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/auth.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | with open("config/acl.json") as f:
4 | acl = json.load(f)
5 |
6 | def is_authorized(api_key, key):
7 | scopes = acl.get(api_key, [])
8 | return any(key.startswith(scope.rstrip("*")) for scope in scopes)
9 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.12-slim
2 |
3 | WORKDIR /app
4 |
5 | # Install dependencies
6 | COPY requirements.txt .
7 | RUN pip install --no-cache-dir -r requirements.txt
8 |
9 | # Copy app code
10 | COPY . .
11 |
12 | EXPOSE 8000
13 |
14 | CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
15 |
--------------------------------------------------------------------------------
/examples/query_agent.py:
--------------------------------------------------------------------------------
1 | from memx_sdk import memxContext
2 |
3 | ctx = memxContext(api_key="agent_key_1")
4 |
5 | ctx.set("memx:query", "Impacts of open-source LLMs on enterprise adoption")
6 | ctx.set("memx:context", "Customer is preparing a technical brief for leadership")
7 |
8 | print("🧠 QueryAgent: seeded query + context")
9 |
--------------------------------------------------------------------------------
/store.py:
--------------------------------------------------------------------------------
1 | import time
2 |
3 | store = {}
4 |
5 | def get_value(key):
6 | return store.get(key)
7 |
8 | def set_value(key, value):
9 | now = time.time()
10 | prev = store.get(key)
11 | if not prev or now > prev['ts']:
12 | store[key] = {'value': value, 'ts': now}
13 | return True
14 | return False
15 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | memx-backend:
3 | build:
4 | context: .
5 | dockerfile: Dockerfile
6 | container_name: memx-backend
7 | ports:
8 | - "8000:8000"
9 | environment:
10 | SUPABASE_URL: ${SUPABASE_URL}
11 | SUPABASE_SERVICE_KEY: ${SUPABASE_SERVICE_KEY}
12 | restart: unless-stopped
13 | dns:
14 | - 8.8.8.8
15 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/public/window.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/public/file.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/monitor_agent.py:
--------------------------------------------------------------------------------
1 | from memx_sdk import memxContext
2 | import time
3 |
4 | ctx = memxContext(api_key="agent_key_1")
5 |
6 | def log(data):
7 | print(f"📡 Monitor saw: {data['key']} → {data['value']}")
8 |
9 | for k in [
10 | "memx:query",
11 | "memx:context",
12 | "memx:search_results:0",
13 | "memx:summary",
14 | "memx:thoughts:0",
15 | "memx:thoughts:1"
16 | ]:
17 | ctx.subscribe(k, log)
18 |
19 | while True:
20 | time.sleep(1)
21 |
--------------------------------------------------------------------------------
/schema.py:
--------------------------------------------------------------------------------
1 | import jsonschema
2 |
3 | schemas = {}
4 |
5 | def register_schema(key, schema_dict):
6 | jsonschema.Draft7Validator.check_schema(schema_dict)
7 | schemas[key] = schema_dict
8 |
9 | def validate_schema(key, value):
10 | schema = schemas.get(key)
11 | if schema:
12 | jsonschema.validate(instance=value, schema=schema)
13 |
14 | def get_schema(key):
15 | return schemas.get(key)
16 |
17 | def delete_schema(key):
18 | return schemas.pop(key, None)
19 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/app/components/LogoutButton.js:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { createClientComponentClient } from "@supabase/auth-helpers-nextjs";
3 |
4 | export default function LogoutButton({ onLogout }) {
5 | const supabase = createClientComponentClient();
6 |
7 | async function handleLogout() {
8 | await supabase.auth.signOut();
9 | onLogout();
10 | }
11 |
12 | return (
13 |
19 | );
20 | }
--------------------------------------------------------------------------------
/pubsub.py:
--------------------------------------------------------------------------------
1 | from collections import defaultdict
2 |
3 | subscriptions = defaultdict(list)
4 |
5 | def subscribe(key, websocket):
6 | subscriptions[key].append(websocket)
7 |
8 | async def publish(key, value):
9 | disconnected = []
10 | for ws in subscriptions.get(key, []):
11 | try:
12 | await ws.send_json({"key": key, "value": value})
13 | except Exception as e:
14 | print(f"[WARN] Failed to send to WebSocket: {e}")
15 | disconnected.append(ws)
16 |
17 | # Remove dead sockets
18 | for ws in disconnected:
19 | subscriptions[key].remove(ws)
20 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "memx-frontend",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev --turbopack",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@supabase/auth-helpers-nextjs": "^0.10.0",
13 | "next": "15.3.4",
14 | "react": "^19.0.0",
15 | "react-dom": "^19.0.0"
16 | },
17 | "devDependencies": {
18 | "@tailwindcss/postcss": "^4",
19 | "autoprefixer": "^10.4.21",
20 | "postcss": "^8.5.6",
21 | "tailwindcss": "^4.1.10"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/app/globals.css:
--------------------------------------------------------------------------------
1 | @import "tailwindcss";
2 |
3 | :root {
4 | --background: #ffffff;
5 | --foreground: #171717;
6 | }
7 |
8 | @theme inline {
9 | --color-background: var(--background);
10 | --color-foreground: var(--foreground);
11 | --font-sans: var(--font-geist-sans);
12 | --font-mono: var(--font-geist-mono);
13 | }
14 |
15 | @media (prefers-color-scheme: dark) {
16 | :root {
17 | --background: #0a0a0a;
18 | --foreground: #ededed;
19 | }
20 | }
21 |
22 | body {
23 | background: var(--background);
24 | color: var(--foreground);
25 | font-family: Arial, Helvetica, sans-serif;
26 | }
27 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/app/components/Header.js:
--------------------------------------------------------------------------------
1 | "use client";
2 | import LogoutButton from "./LogoutButton";
3 |
4 | export default function Header({ onLogout, showLogout = true }) {
5 | return (
6 |
7 |
13 | {showLogout && }
14 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/sdk/pyproject.toml:
--------------------------------------------------------------------------------
1 | [project]
2 | name = "memx-sdk"
3 | version = "0.1.1"
4 | description = "Python client for memX shared memory platform"
5 | authors = [{ name="Mehul", email="memx.founders@gmail.com" }]
6 | license = { text = "MIT" }
7 | readme = "README.md"
8 | requires-python = ">=3.8"
9 | dependencies = [
10 | "httpx>=0.24.0",
11 | "websockets",
12 | "hatchling (>=1.27.0,<2.0.0)"
13 | ]
14 |
15 | [build-system]
16 | requires = ["hatchling"]
17 | build-backend = "hatchling.build"
18 |
19 | [project.urls]
20 | "Homepage" = "https://github.com/MehulG/memx"
21 | "Repository" = "https://github.com/MehulG/memx"
22 | "Documentation" = "https://github.com/MehulG/memx#readme"
--------------------------------------------------------------------------------
/sdk/memx_sdk/test_client.py:
--------------------------------------------------------------------------------
1 | from memx_sdk import memxContext
2 | import time
3 |
4 | schema = {
5 | "type": "object",
6 | "properties": { "x": { "type": "number" }, "y": { "type": "number" } },
7 | "required": ["x", "y"]
8 | }
9 | ctx = memxContext(api_key="agent_key_1")
10 |
11 |
12 | ctx.set_schema("agent:state", schema)
13 | print(ctx.get_schema("agent:state"))
14 | # ctx.delete_schema("agent:state")
15 |
16 |
17 | def on_update(data):
18 | print("🔥 Update received:", data)
19 |
20 | ctx.subscribe("agent:goal", on_update)
21 |
22 | ctx.set("agent:goal", "go to kitchen")
23 | time.sleep(1)
24 | ctx.set("agent:goal", "go to hallway")
25 | time.sleep(3)
26 |
27 |
28 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.*
7 | .yarn/*
8 | !.yarn/patches
9 | !.yarn/plugins
10 | !.yarn/releases
11 | !.yarn/versions
12 |
13 | # testing
14 | /coverage
15 |
16 | # next.js
17 | /.next/
18 | /out/
19 |
20 | # production
21 | /build
22 |
23 | # misc
24 | .DS_Store
25 | *.pem
26 |
27 | # debug
28 | npm-debug.log*
29 | yarn-debug.log*
30 | yarn-error.log*
31 | .pnpm-debug.log*
32 |
33 | # env files (can opt-in for committing if needed)
34 | .env*
35 |
36 | # vercel
37 | .vercel
38 |
39 | # typescript
40 | *.tsbuildinfo
41 | next-env.d.ts
42 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [project]
2 | name = "memx"
3 | version = "0.1.0"
4 | description = ""
5 | authors = [
6 | {name = "Mehul Gaidhani",email = "mehulgaidhani@gmail.com"}
7 | ]
8 | readme = "README.md"
9 | requires-python = ">=3.12,<4.0"
10 | dependencies = [
11 | "fastapi[all] (>=0.115.12,<0.116.0)",
12 | "jsonschema (>=4.24.0,<5.0.0)",
13 | "requests (>=2.32.4,<3.0.0)",
14 | "supabase (>=2.15.3,<3.0.0)",
15 | "streamlit (>=1.46.0,<2.0.0)",
16 | "python-dotenv (>=1.1.1,<2.0.0)",
17 | "hatchling (>=1.27.0,<2.0.0)"
18 | ]
19 |
20 |
21 | [build-system]
22 | requires = ["poetry-core>=2.0.0,<3.0.0"]
23 | build-backend = "poetry.core.masonry.api"
24 |
25 | [tool.poetry.requires-plugins]
26 | poetry-plugin-export = ">=1.8"
--------------------------------------------------------------------------------
/frontend/memx-frontend/app/layout.js:
--------------------------------------------------------------------------------
1 | import { Geist, Geist_Mono } from "next/font/google";
2 | import "./globals.css";
3 |
4 | const geistSans = Geist({
5 | variable: "--font-geist-sans",
6 | subsets: ["latin"],
7 | });
8 |
9 | const geistMono = Geist_Mono({
10 | variable: "--font-geist-mono",
11 | subsets: ["latin"],
12 | });
13 |
14 | export const metadata = {
15 | title: "memX",
16 | description: "A real-time shared memory layer for multi-agent LLM systems.",
17 | };
18 |
19 | export default function RootLayout({ children }) {
20 | return (
21 |
22 |
25 | {children}
26 |
27 |
28 | );
29 | }
30 |
--------------------------------------------------------------------------------
/examples/test.py:
--------------------------------------------------------------------------------
1 | from memx_sdk import memxContext
2 |
3 |
4 | ctx = memxContext(api_key="74748d89f9cef9987ecc9dbe16b72daf")
5 |
6 | ctx.set_schema("agent:goal", {
7 | "type": "object",
8 | "properties": {
9 | "x": { "type": "number" },
10 | "y": { "type": "number" }
11 | },
12 | "required": ["x", "y"]
13 | })
14 |
15 | get1 = ctx.get("agent:goal")
16 |
17 | print(get1)
18 |
19 | ctx.set("agent:goal", {"x":1, "y":7})
20 |
21 | get2 = ctx.get("agent:goal")
22 |
23 | print(get2)
24 |
25 | for i in range(0,10):
26 | ctx.set_schema("agent:goal:"+str(i), {
27 | "type": "object",
28 | "properties": {
29 | "x": { "type": "number" },
30 | "y": { "type": "number" }
31 | },
32 | "required": ["x", "y"]
33 | })
34 | ctx.set("agent:goal"+str(i), {"x":i, "y":i*2})
35 | get1 = ctx.get("agent:goal"+str(i))
36 |
37 | print(get1)
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/app/login/page.js:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { useState, useCallback } from "react";
3 | import AuthForm from "../components/AuthForm";
4 | import KeyViewer from "../components/KeyViewer";
5 | import CreateKeyForm from "../components/CreateKeyForm";
6 | import Header from "../components/Header";
7 |
8 | export default function Login() {
9 | const [session, setSession] = useState(null);
10 | const [reload, setReload] = useState(0);
11 |
12 | const triggerReload = useCallback(() => {
13 | setReload((prev) => prev + 1);
14 | }, []);
15 |
16 | if (!session) {
17 | return ;
18 | }
19 |
20 | return (
21 |
22 | setSession(null)} />
23 |
24 |
25 |
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/public/globe.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 Mehul Gaidhani
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/sdk/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 Mehul Gaidhani
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the “Software”), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | # or
12 | pnpm dev
13 | # or
14 | bun dev
15 | ```
16 |
17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18 |
19 | You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file.
20 |
21 | This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
22 |
23 | ## Learn More
24 |
25 | To learn more about Next.js, take a look at the following resources:
26 |
27 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29 |
30 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
31 |
32 | ## Deploy on Vercel
33 |
34 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35 |
36 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
37 |
--------------------------------------------------------------------------------
/sdk/README.md:
--------------------------------------------------------------------------------
1 | # 🧠 memx-sdk
2 |
3 | A Python client for [memX](https://github.com/MehulG/memX) — a real-time shared memory layer for multi-agent LLM systems.
4 |
5 | Built for fast, schema-validated coordination between autonomous agents. Supports JSON key/value operations, schema enforcement, and pub/sub via WebSocket.
6 |
7 | ---
8 |
9 | ## 🚀 Features
10 |
11 | - 🔑 Authenticate via API keys
12 | - 📥 Get/set JSON values by key
13 | - 📐 Define and validate key schemas
14 | - 🔄 Real-time memory sync via WebSocket
15 | - 🔔 Pub/sub for key-level updates
16 |
17 | ---
18 |
19 | ## 📦 Installation
20 |
21 | ```bash
22 | pip install memx-sdk
23 | ```
24 |
25 | ## 🧪 Usage Example
26 |
27 | Log in to [dashboard](https://mem-x.vercel.app) and create api keys with relevent scopes.
28 |
29 | ```python
30 | from memx_sdk import memxContext
31 |
32 | client = memxContext(api_key="your-api-key")
33 |
34 | # Define schema
35 | client.set_schema("agent:goal", {
36 | "type": "object",
37 | "properties": { "x": { "type": "number" }, "y": { "type": "number" } },
38 | "required": ["x", "y"]
39 | })
40 |
41 | # Set a value
42 | client.set("agent:goal", {"x": 3, "y": 5})
43 |
44 | # Get a value
45 | value = client.get("agent:goal")
46 | print(value)
47 |
48 | # Subscribe to updates
49 | def on_update(data):
50 | print("Updated:", data)
51 |
52 | client.subscribe("agent:goal", callback=on_update)
53 | ```
54 |
55 | ## 🛠️ Requirements
56 | - Python 3.7+
57 | - httpx
58 | - websockets
59 |
60 | ## 📄 License
61 | MIT
62 |
63 | ## 🧠 Learn More
64 | - Dashboard: https://mem-x.vercel.app
65 | - Project: [memX README](https://github.com/MehulG/memX)
--------------------------------------------------------------------------------
/examples/explorer_agent.py:
--------------------------------------------------------------------------------
1 | from memx_sdk import memxContext
2 | import time
3 | import requests
4 |
5 | ctx = memxContext(api_key="agent_key_1")
6 |
7 | query_handled = False
8 | summary_handled = False
9 |
10 | def call_mistral(prompt: str) -> str:
11 | res = requests.post("http://localhost:11434/api/generate", json={
12 | "model": "mistral",
13 | "prompt": prompt,
14 | "stream": False
15 | })
16 | return res.json()["response"].strip() if res.status_code == 200 else "LLM error."
17 |
18 | def on_memory(data):
19 | global query_handled, summary_handled
20 |
21 | key, value = data["key"], data["value"]
22 |
23 | if key == "memx:query" and not query_handled:
24 | context = ctx.get("memx:context")["value"]
25 | prompt = f"""You are a research assistant.
26 | Given the query: "{value}" and context: "{context}", list one relevant source and one key observation."""
27 | print("🔍 ExplorerAgent: generating initial info with Mistral...")
28 | output = call_mistral(prompt)
29 | ctx.set("memx:search_results:0", output)
30 | ctx.set("memx:thoughts:0", f"Initial observation: {output}")
31 | query_handled = True
32 |
33 | elif key == "memx:summary" and not summary_handled:
34 | prompt = f"""You are a second-pass reviewer.
35 | Based on this summary: "{value}", what additional consideration should be mentioned?"""
36 | print("🔄 ExplorerAgent: reacting to summary via Mistral...")
37 | thought = call_mistral(prompt)
38 | ctx.set("memx:thoughts:1", f"Follow-up observation: {thought}")
39 | summary_handled = True
40 |
41 | ctx.subscribe("memx:query", on_memory)
42 | ctx.subscribe("memx:summary", on_memory)
43 |
44 | while True:
45 | time.sleep(1)
46 |
--------------------------------------------------------------------------------
/validate_api.py:
--------------------------------------------------------------------------------
1 | import fnmatch
2 | from fastapi import Request, HTTPException, WebSocket
3 | from supabase import create_client
4 | import os
5 | from dotenv import load_dotenv
6 | load_dotenv()
7 |
8 | supabase = create_client(os.getenv("SUPABASE_URL"), os.getenv("SUPABASE_SERVICE_KEY"))
9 |
10 | def _check_scope(scopes: dict, action: str, key: str, user_id: str):
11 | namespaced_key = f"{user_id[:8]}:{key}"
12 | return any(fnmatch.fnmatch(namespaced_key, pattern) for pattern in scopes.get(action, []))
13 |
14 | async def validate_api_key(request: Request, key: str, action: str = "write"):
15 | api_key = request.headers.get("x-api-key")
16 | if not api_key:
17 | raise HTTPException(status_code=401, detail="Missing API key")
18 |
19 | res = supabase.from_("api_keys").select("*").eq("key", api_key).eq("active", True).execute()
20 | if not res.data:
21 | raise HTTPException(status_code=403, detail="Invalid or inactive API key")
22 |
23 | record = res.data[0]
24 | scopes = record.get("scopes", {})
25 | user_id = record.get("user_id", "")
26 |
27 | if not _check_scope(scopes, action, key, user_id):
28 | raise HTTPException(status_code=403, detail=f"{action.upper()} not permitted for key '{key}'")
29 |
30 | request.state.api_key = record
31 |
32 | async def validate_websocket(websocket: WebSocket, key: str) -> bool:
33 | api_key = websocket.headers.get("x-api-key")
34 | if not api_key:
35 | await websocket.close(code=4401, reason="Missing API key")
36 | return False
37 |
38 | res = supabase.table("api_keys").select("*").eq("key", api_key).eq("active", True).execute()
39 | if not res.data:
40 | await websocket.close(code=4403, reason="Invalid API key")
41 | return False
42 |
43 | record = res.data[0]
44 | scopes = record.get("scopes", {})
45 | user_id = record.get("user_id", "")
46 |
47 | if not _check_scope(scopes, "read", key, user_id):
48 | await websocket.close(code=4403, reason="Unauthorized to subscribe to this key")
49 | return False
50 |
51 | return True
52 |
--------------------------------------------------------------------------------
/examples/synthesizer_agent.py:
--------------------------------------------------------------------------------
1 | from memx_sdk import memxContext
2 | import time
3 | import requests
4 | import hashlib
5 |
6 | ctx = memxContext(api_key="agent_key_1")
7 | last_summary_hash = None
8 | final_summary = ''
9 | count = 0
10 | def hash_text(text):
11 | return hashlib.sha256(text.encode()).hexdigest()
12 |
13 | def call_mistral(prompt: str) -> str:
14 | try:
15 | res = requests.post("http://localhost:11434/api/generate", json={
16 | "model": "mistral",
17 | "prompt": prompt,
18 | "stream": False
19 | })
20 | res.raise_for_status()
21 | return res.json()["response"].strip()
22 | except Exception as e:
23 | print("❌ Mistral error:", e)
24 | return "LLM error."
25 |
26 | def summarize():
27 | global last_summary_hash
28 | global final_summary
29 | global count
30 | try:
31 | query = ctx.get("memx:query")["value"]
32 | results = ctx.get("memx:search_results:0")["value"]
33 | thoughts = [ctx.get("memx:thoughts:0")["value"]]
34 | try:
35 | thoughts.append(ctx.get("memx:thoughts:1")["value"])
36 | except:
37 | pass # optional follow-up thought
38 | except:
39 | print("⏳ Waiting for all inputs...")
40 | return
41 |
42 | prompt = f"""You are a summarizer agent.
43 |
44 | Based on the following:
45 | - Query: {query}
46 | - Search Result: {results}
47 | - Thoughts:
48 | {"".join(f"- {t}\n" for t in thoughts)}
49 |
50 | Write a final 2-sentence summary suitable for a leadership audience.
51 | """
52 |
53 | print("🧠 SynthesizerAgent: summarizing via Mistral...")
54 | summary = call_mistral(prompt)
55 | summary_hash = hash_text(summary)
56 |
57 | if summary_hash != last_summary_hash:
58 | ctx.set("memx:summary", summary)
59 | last_summary_hash = summary_hash
60 | final_summary = summary
61 | count += 1
62 | if count > 1:
63 | print("✅ Final summary written:\n", final_summary, "\n")
64 | else:
65 | print("⚠️ Summary unchanged — skipping write.")
66 |
67 | def on_data(_):
68 | summarize()
69 |
70 | # ctx.subscribe("memx:search_results:0", on_data)
71 | ctx.subscribe("memx:thoughts:0", on_data)
72 | ctx.subscribe("memx:thoughts:1", on_data)
73 |
74 |
75 |
76 | while True:
77 | time.sleep(1)
78 |
--------------------------------------------------------------------------------
/sdk/memx_sdk/client.py:
--------------------------------------------------------------------------------
1 | import httpx
2 | import asyncio
3 | import websockets
4 | import threading
5 | import json
6 |
7 | class memxContext:
8 | def __init__(self, api_key, base_url="https://memx-production.up.railway.app"):
9 | self.api_key = api_key
10 | self.base_url = base_url
11 |
12 | def set(self, key, value):
13 | res = httpx.post(
14 | f"{self.base_url}/set",
15 | headers={"x-api-key": self.api_key},
16 | json={"key": key, "value": value}
17 | )
18 | res.raise_for_status()
19 | return res.json()
20 |
21 | def get(self, key):
22 | res = httpx.get(
23 | f"{self.base_url}/get",
24 | headers={"x-api-key": self.api_key},
25 | params={"key": key}
26 | )
27 | res.raise_for_status()
28 | return res.json()
29 |
30 | def subscribe(self, key, callback):
31 | def _listen():
32 | uri = f"{self.base_url.replace('http', 'ws')}/subscribe/{key}"
33 | async def _inner():
34 | async with websockets.connect(uri, additional_headers={"x-api-key": self.api_key}) as ws:
35 | while True:
36 | try:
37 | msg = await ws.recv()
38 | data = json.loads(msg)
39 | callback(data)
40 | except Exception as e:
41 | print("[WebSocket error]", e)
42 | break
43 | asyncio.run(_inner())
44 |
45 | thread = threading.Thread(target=_listen, daemon=True)
46 | thread.start()
47 |
48 | def set_schema(self, key, schema):
49 | res = httpx.post(
50 | f"{self.base_url}/schema",
51 | headers={"x-api-key": self.api_key},
52 | json={"key": key, "schema": schema}
53 | )
54 | res.raise_for_status()
55 | return res.json()
56 |
57 | def get_schema(self, key):
58 | res = httpx.get(
59 | f"{self.base_url}/schema",
60 | headers={"x-api-key": self.api_key},
61 | params={"key": key}
62 | )
63 | res.raise_for_status()
64 | return res.json()
65 |
66 | def delete_schema(self, key):
67 | res = httpx.delete(
68 | f"{self.base_url}/schema",
69 | headers={"x-api-key": self.api_key},
70 | params={"key": key}
71 | )
72 | res.raise_for_status()
73 | return res.json()
74 |
75 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | from fastapi import FastAPI, WebSocket, Request, HTTPException
2 | from store import get_value, set_value
3 | from pubsub import subscribe, publish
4 | from schema import register_schema, validate_schema, get_schema, delete_schema
5 | import asyncio
6 | import jsonschema
7 | import validate_api
8 |
9 | app = FastAPI()
10 |
11 | @app.get("/get")
12 | async def get(key: str, request: Request):
13 | await validate_api.validate_api_key(request, key, action="read")
14 | return get_value(key)
15 |
16 | @app.post("/set")
17 | async def set(request: Request):
18 | body = await request.json()
19 | value = body["value"]
20 | key = body["key"]
21 |
22 | await validate_api.validate_api_key(request, key, action="write")
23 |
24 | try:
25 | validate_schema(key, value)
26 | except jsonschema.exceptions.ValidationError as e:
27 | raise HTTPException(400, detail=str(e))
28 |
29 | updated = set_value(key, value)
30 | if updated:
31 | await publish(key, value)
32 |
33 | return {"ok": True, "updated": updated}
34 |
35 | @app.websocket("/subscribe/{key}")
36 | async def websocket_endpoint(websocket: WebSocket, key: str):
37 | await websocket.accept()
38 | if not await validate_api.validate_websocket(websocket, key):
39 | return
40 | print(f"[WebSocket] Subscribed to {key}")
41 | subscribe(key, websocket)
42 | try:
43 | while True:
44 | await asyncio.sleep(1)
45 | except:
46 | print(f"[WebSocket] closed: {key}")
47 |
48 | @app.post("/schema")
49 | async def set_schema(request: Request):
50 | body = await request.json()
51 | key = body["key"]
52 | schema = body["schema"]
53 |
54 | await validate_api.validate_api_key(request, key, action="write")
55 |
56 | try:
57 | register_schema(key, schema)
58 | except jsonschema.exceptions.SchemaError as e:
59 | raise HTTPException(400, detail=f"Invalid schema: {e}")
60 | return {"ok": True}
61 |
62 | @app.get("/schema")
63 | async def fetch_schema(key: str, request: Request):
64 | await validate_api.validate_api_key(request, key, action="read")
65 | schema = get_schema(key)
66 | if not schema:
67 | raise HTTPException(404, detail="Schema not found")
68 | return {"key": key, "schema": schema}
69 |
70 | @app.delete("/schema")
71 | async def remove_schema(key: str, request: Request):
72 | await validate_api.validate_api_key(request, key, action="write")
73 | deleted = delete_schema(key)
74 | if not deleted:
75 | raise HTTPException(404, detail="Schema not found")
76 | return {"ok": True}
77 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/app/components/KeyViewer.js:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { useEffect, useState } from "react";
3 | import { createClientComponentClient } from "@supabase/auth-helpers-nextjs";
4 |
5 | export default function KeyViewer({ session }) {
6 | const supabase = createClientComponentClient();
7 | const [keys, setKeys] = useState([]);
8 | const [loading, setLoading] = useState(true);
9 | const [deleting, setDeleting] = useState(null);
10 |
11 | const fetchKeys = async () => {
12 | setLoading(true);
13 | const { data } = await supabase.from("api_keys").select("*");
14 | setKeys(data || []);
15 | setLoading(false);
16 | };
17 |
18 | useEffect(() => {
19 | fetchKeys();
20 | }, []);
21 |
22 | const deleteKey = async (key) => {
23 | setDeleting(key);
24 | await supabase.from("api_keys").delete().eq("key", key);
25 | setDeleting(null);
26 | fetchKeys();
27 | };
28 |
29 | const userPrefix = session.user.id.slice(0, 8);
30 |
31 | return (
32 |
33 |
🔑 Your API Keys
34 |
Namespace: {userPrefix}
35 | {loading ? (
36 |
Loading keys...
37 | ) : keys.length === 0 ? (
38 |
No keys found.
39 | ) : (
40 |
41 |
42 |
43 | | Name |
44 | Key |
45 | Read Scope |
46 | Write Scope |
47 | Created At |
48 | Actions |
49 |
50 |
51 |
52 | {keys.map((k) => (
53 |
54 | | {k.name} |
55 | {k.key} |
56 | {k.scopes.read?.join(", ")} |
57 | {k.scopes.write?.join(", ")} |
58 | {new Date(k.created_at).toLocaleString()} |
59 |
60 |
67 | |
68 |
69 | ))}
70 |
71 |
72 | )}
73 |
74 | );
75 | }
--------------------------------------------------------------------------------
/frontend/memx-frontend/app/components/CreateKeyForm.js:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { useState } from "react";
3 | import { createClientComponentClient } from "@supabase/auth-helpers-nextjs";
4 |
5 | export default function CreateKeyForm({ session, onCreated }) {
6 | const supabase = createClientComponentClient();
7 | const [name, setName] = useState("");
8 | const [readScope, setReadScope] = useState("agent:*");
9 | const [writeScope, setWriteScope] = useState("agent:goal");
10 | const [status, setStatus] = useState(null);
11 | const [loading, setLoading] = useState(false);
12 |
13 | const userPrefix = session.user.id.slice(0, 8);
14 |
15 | async function handleCreate(e) {
16 | e.preventDefault();
17 | setLoading(true);
18 | const apiKey = crypto.randomUUID().replace(/-/g, "").slice(0, 32);
19 | const scopes = {
20 | read: readScope.split(",").map((s) => `${userPrefix}:${s.trim()}`),
21 | write: writeScope.split(",").map((s) => `${userPrefix}:${s.trim()}`),
22 | };
23 |
24 | const { error } = await supabase.rpc("create_api_key", {
25 | key_name: name,
26 | key_value: apiKey,
27 | scopes,
28 | is_active: true,
29 | });
30 |
31 | if (error) {
32 | setStatus(`Error: ${error.message}`);
33 | } else {
34 | setStatus(`API Key Created: ${apiKey}`);
35 | setName("");
36 | setReadScope("agent:*");
37 | setWriteScope("agent:goal");
38 | if (onCreated) onCreated();
39 | }
40 | setLoading(false);
41 | }
42 |
43 | return (
44 |
79 | );
80 | }
81 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/app/components/AuthForm.js:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { useState } from "react";
3 | import { createClientComponentClient } from "@supabase/auth-helpers-nextjs";
4 | import Header from "./Header";
5 |
6 | export default function AuthForm({ onAuth }) {
7 | const supabase = createClientComponentClient();
8 | const [email, setEmail] = useState("");
9 | const [password, setPassword] = useState("");
10 | const [mode, setMode] = useState("login");
11 | const [error, setError] = useState(null);
12 | const [info, setInfo] = useState(null);
13 | const [loading, setLoading] = useState(false);
14 |
15 | async function handleSubmit(e) {
16 | e.preventDefault();
17 | setError(null);
18 | setInfo(null);
19 | setLoading(true);
20 | try {
21 | if (mode === "login") {
22 | const { data, error } = await supabase.auth.signInWithPassword({ email, password });
23 | if (error) throw error;
24 | onAuth(data.session);
25 | } else {
26 | const { error: signupError } = await supabase.auth.signUp({ email, password });
27 | if (signupError) throw signupError;
28 | setInfo("Signed up successfully. Please check your email to confirm your account.");
29 | }
30 | } catch (err) {
31 | setError(err.message);
32 | } finally {
33 | setLoading(false);
34 | }
35 | }
36 |
37 | return (
38 |
39 |
40 |
41 |
42 |
{mode === "login" ? "Login" : "Signup"}
43 |
70 |
71 | {mode === "login" ? "Don't have an account?" : "Already have an account?"} {" "}
72 |
79 |
80 |
81 |
82 |
83 | );
84 | }
85 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/app/page.js:
--------------------------------------------------------------------------------
1 | export default function LandingPage() {
2 | return (
3 |
4 | {/* Hero Section */}
5 |
6 | 🧠 memX
7 |
8 | Real-time shared memory for multi-agent LLM systems: no chat, no controller.
9 |
10 |
11 | No setup. Free to use. Just shared memory between agents.
12 |
13 |
14 |
28 |
29 |
30 | {/* Features */}
31 |
32 | ⚡ Why memX?
33 |
34 | - Real-time shared key-value store
35 | - Pub/Sub updates across agents
36 | - JSON Schema enforcement
37 | - API-key-based access control
38 |
39 |
40 |
41 | {/* Quickstart */}
42 |
43 | 🚀 Quickstart
44 |
45 | - Install SDK:
pip install memx_sdk
46 | - Get your API key
47 | - Start coding:
48 |
49 |
50 | {`from memx_sdk import memxContext
51 |
52 | ctx = memxContext(api_key="your_api_key")
53 |
54 | ctx.set_schema("agent:goal", {
55 | "type": "object",
56 | "properties": {"x": {"type": "number"}, "y": {"type": "number"}},
57 | "required": ["x", "y"]
58 | })
59 |
60 | ctx.set("agent:goal", {"x": 1, "y": 7})
61 | print(ctx.get("agent:goal"))
62 | `}
63 |
64 |
65 |
66 | {/* Agent Table */}
67 |
68 | 🧬 Example: Multi Agents, One Memory
69 |
74 |
75 |
76 |
77 |
78 |
79 | {/* Use Cases */}
80 |
81 | 🌐 Use Cases
82 |
83 | - Autonomous research agents
84 | - LangGraph / CrewAI memory plugins
85 | - LLM workflows with persistent state
86 |
87 |
88 |
89 | {/* Footer */}
90 |
94 |
95 | );
96 | }
97 |
--------------------------------------------------------------------------------
/frontend/streamlit.py:
--------------------------------------------------------------------------------
1 | # memX Streamlit Dashboard MVP
2 |
3 | import streamlit as st
4 | import secrets
5 | import json
6 | import time
7 | import pandas as pd
8 | from supabase import create_client, Client, ClientOptions
9 |
10 | # --- Setup ---
11 | SUPABASE_URL = st.secrets["SUPABASE_URL"]
12 | SUPABASE_KEY = st.secrets["SUPABASE_SERVICE_KEY"]
13 |
14 | # Initialize temporary client for login/signup
15 | supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
16 |
17 | # --- Auth (signup/login) ---
18 | st.title("🔐 memX Dashboard")
19 | if "session" not in st.session_state:
20 | st.session_state.session = None
21 | if "auth_mode" not in st.session_state:
22 | st.session_state.auth_mode = "login"
23 |
24 | st.sidebar.title("Account")
25 | auth_mode = st.sidebar.radio("Select Mode", ["login", "signup"])
26 | st.session_state.auth_mode = auth_mode
27 |
28 | if not st.session_state.session:
29 | with st.form("Auth"):
30 | email = st.text_input("Email")
31 | password = st.text_input("Password", type="password")
32 | submitted = st.form_submit_button("Submit")
33 | if submitted:
34 | try:
35 | if st.session_state.auth_mode == "login":
36 | session = supabase.auth.sign_in_with_password({"email": email, "password": password})
37 | st.session_state.session = session
38 | st.success(f"Logged in as {email}")
39 | time.sleep(1)
40 | st.rerun()
41 | else:
42 | session = supabase.auth.sign_up({"email": email, "password": password})
43 | st.success(f"Signed up as {email}. Please check your email to confirm.")
44 | st.session_state.session = session
45 | time.sleep(1)
46 | st.rerun()
47 | except Exception as e:
48 | st.error("{} failed: {}".format(st.session_state.auth_mode.capitalize(), str(e)))
49 | st.stop()
50 |
51 | access_token = st.session_state.session.session.access_token
52 | supabase = create_client(
53 | SUPABASE_URL,
54 | SUPABASE_KEY,
55 | options=ClientOptions(headers={"Authorization": f"Bearer {access_token}"})
56 | )
57 |
58 | user_id = st.session_state.session.user.id
59 | user_prefix = user_id[:8] # used to namespace scope keys
60 |
61 | # --- API Key Viewer ---
62 | st.header("🔑 Your API Keys")
63 | st.caption(f"🔒 Namespace: `{user_prefix}` (automatically applied to all scopes)")
64 |
65 | keys = supabase.table("api_keys").select("*").execute()
66 | if keys.data:
67 | table_data = [
68 | {
69 | "Key": k["key"],
70 | "Read Scope": ", ".join(k["scopes"].get("read", [])),
71 | "Write Scope": ", ".join(k["scopes"].get("write", [])),
72 | "Created At": k["created_at"]
73 | }
74 | for k in keys.data
75 | ]
76 | df = pd.DataFrame(table_data)
77 | st.dataframe(df)
78 | else:
79 | st.info("No keys found.")
80 |
81 | # --- API Key Creator ---
82 | st.header("➕ Create New API Key")
83 |
84 | with st.form("create_key"):
85 | key_name = st.text_input("Name")
86 | read_scope = st.text_input("Read scope (comma-separated)", "agent:*")
87 | write_scope = st.text_input("Write scope (comma-separated)", "agent:goal")
88 | submit_key = st.form_submit_button("Create")
89 |
90 | if submit_key:
91 | api_key = secrets.token_hex(16)
92 | scopes = {
93 | "read": [f"{user_prefix}:{s.strip()}" for s in read_scope.split(",")],
94 | "write": [f"{user_prefix}:{s.strip()}" for s in write_scope.split(",")]
95 | }
96 | supabase.rpc("create_api_key", {
97 | "key_name": key_name,
98 | "key_value": api_key,
99 | "scopes": scopes,
100 | "is_active": True
101 | }).execute()
102 | st.success("API Key Created: {}".format(api_key))
103 |
104 | # --- Memory Viewer (Optional) ---
105 | # You could add polling here to connect to your FastAPI memX backend
106 | # and display live key-value state or pub/sub logs.
107 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🧠 memX: Shared Memory for Multi-Agent LLM Systems
2 |
3 | **memX** is an open-source real-time shared memory layer designed for agent-based systems powered by LLMs. It enables **coordination-first workflows** via:
4 |
5 | * ⚡ Real-time CRDT-style state sync
6 | * 📐 JSON Schema enforcement for data sanity
7 | * 🔐 API-key-based access control
8 | * 📣 Pub/Sub updates for reactive agents
9 |
10 | ---
11 |
12 | ## 🔍 What Problem Does memX Solve?
13 |
14 | Modern multi-agent setups—whether using LangGraph, Autogen, or custom orchestration—lack a reliable way to **share evolving context** (state, goals, thoughts) between agents. memX provides a simple and secure memory layer that agents can read/write from in real-time — no message-passing or controller required.
15 |
16 | ---
17 |
18 | ## 🤖 Example: Collaborative LLM Agents Using memX
19 |
20 | Three autonomous agents solving a research task, fully decentralized:
21 |
22 | | Agent | Behavior |
23 | | ------------------ | ---------------------------------------------------- |
24 | | `QueryAgent` | Seeds the research question + background context |
25 | | `ExplorerAgent` | Adds search results + working notes |
26 | | `SynthesizerAgent` | Summarizes the shared context into final insights |
27 | | `MonitorAgent` | Logs real-time evolution of memory for observability |
28 |
29 | > All communication flows through **shared keys** in memX — not through chat or a controller.
30 |
31 | 
32 |
33 | ---
34 |
35 | ## 🚀 Features at a Glance
36 |
37 | ✅ Real-time memory sync (WebSocket)
38 | 📬 Pub/Sub updates on change
39 | 📐 Per-key JSON Schema validation
40 | 🔐 Fine-grained ACLs via API keys
41 | 🐍 Python SDK (`memx-sdk`) for easy integration
42 | 🐳 Docker-compatible for local hosting or cloud deployment
43 |
44 | ---
45 |
46 | ## ⚡ Quickstart
47 |
48 | ### 1. Install the SDK
49 |
50 | ```bash
51 | pip install memx-sdk
52 | ```
53 |
54 | ### 2. Generate an API Key
55 |
56 | Visit: [mem-x.vercel.com](https://mem-x.vercel.com)
57 | Generate scoped API keys with just a few clicks.
58 |
59 | ### 3. Use in Python
60 |
61 | ```python
62 | from memx_sdk import memxContext
63 |
64 | ctx = memxContext(api_key="your_api_key")
65 |
66 | ctx.set_schema("agent:goal", {
67 | "type": "object",
68 | "properties": {"x": {"type": "number"}, "y": {"type": "number"}},
69 | "required": ["x", "y"]
70 | })
71 |
72 | ctx.set("agent:goal", {"x": 1, "y": 7})
73 | print(ctx.get("agent:goal"))
74 | ```
75 |
76 | ---
77 |
78 | ## 🧰 Running memX Locally
79 |
80 | ### Option 1: Dev Server
81 |
82 | ```bash
83 | uvicorn main:app --reload
84 | ```
85 |
86 | ### Option 2: Docker
87 |
88 | ```bash
89 | docker-compose up --build
90 | ```
91 |
92 | Swagger docs: [http://localhost:8000/docs](http://localhost:8000/docs)
93 |
94 | ---
95 |
96 | ## 🔑 API Key Management
97 |
98 | ### Hosted
99 |
100 | 1. Log in at [mem-x.vercel.com](https://mem-x.vercel.com)
101 | 2. Generate API keys with scoped access control
102 |
103 | ### Local Config
104 |
105 | Edit `config/acl.json` to define access scopes:
106 |
107 | ```json
108 | {
109 | "agent_key_1": ["agent:*"],
110 | "planner_key": ["agent:goal"]
111 | }
112 | ```
113 |
114 | ---
115 |
116 | ## 📐 Define Schemas (Optional but Recommended)
117 |
118 | Set schema for a key via API:
119 |
120 | ```bash
121 | POST /schema
122 | Headers: x-api-key: your_key
123 | Body:
124 | {
125 | "key": "agent:state",
126 | "schema": {
127 | "type": "object",
128 | "properties": {"x": {"type": "number"}, "y": {"type": "number"}},
129 | "required": ["x", "y"]
130 | }
131 | }
132 | ```
133 |
134 | Or via SDK:
135 |
136 | ```python
137 | ctx.set_schema("agent:state", schema_dict)
138 | ```
139 |
140 | ---
141 |
142 | ## 🗂 Project Structure
143 |
144 | ```
145 | core/ # FastAPI + WebSocket backend
146 | sdk/ # Python SDK (pip installable)
147 | config/ # Access control & schemas
148 | examples/ # LLM agent integration demos
149 | ```
150 |
151 | ---
152 |
153 | ## 🌐 Use Cases
154 |
155 | * LangGraph / Autogen workflows with shared memory
156 | * Autonomous research or planning agents
157 | * IoT / robotics with real-time state coordination
158 | * Any multi-agent system needing structured memory
159 |
160 | ---
161 |
162 | ## 📣 Join Us
163 |
164 | memX is built for developers pushing the frontier of multi-agent systems.
165 | Explore the SDK, try out agent demos, and contribute!
166 |
167 | ---
168 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | aiohappyeyeballs==2.6.1 ; python_version >= "3.12" and python_version < "4.0"
2 | aiohttp==3.12.13 ; python_version >= "3.12" and python_version < "4.0"
3 | aiosignal==1.3.2 ; python_version >= "3.12" and python_version < "4.0"
4 | altair==5.5.0 ; python_version >= "3.12" and python_version < "4.0"
5 | annotated-types==0.7.0 ; python_version >= "3.12" and python_version < "4.0"
6 | anyio==4.9.0 ; python_version >= "3.12" and python_version < "4.0"
7 | attrs==25.3.0 ; python_version >= "3.12" and python_version < "4.0"
8 | blinker==1.9.0 ; python_version >= "3.12" and python_version < "4.0"
9 | cachetools==6.1.0 ; python_version >= "3.12" and python_version < "4.0"
10 | certifi==2025.4.26 ; python_version >= "3.12" and python_version < "4.0"
11 | charset-normalizer==3.4.2 ; python_version >= "3.12" and python_version < "4.0"
12 | click==8.2.1 ; python_version >= "3.12" and python_version < "4.0"
13 | colorama==0.4.6 ; python_version >= "3.12" and python_version < "4.0" and (platform_system == "Windows" or sys_platform == "win32")
14 | deprecation==2.1.0 ; python_version >= "3.12" and python_version < "4.0"
15 | dnspython==2.7.0 ; python_version >= "3.12" and python_version < "4.0"
16 | email-validator==2.2.0 ; python_version >= "3.12" and python_version < "4.0"
17 | fastapi-cli==0.0.7 ; python_version >= "3.12" and python_version < "4.0"
18 | fastapi==0.115.12 ; python_version >= "3.12" and python_version < "4.0"
19 | frozenlist==1.7.0 ; python_version >= "3.12" and python_version < "4.0"
20 | gitdb==4.0.12 ; python_version >= "3.12" and python_version < "4.0"
21 | gitpython==3.1.44 ; python_version >= "3.12" and python_version < "4.0"
22 | gotrue==2.12.0 ; python_version >= "3.12" and python_version < "4.0"
23 | h11==0.16.0 ; python_version >= "3.12" and python_version < "4.0"
24 | h2==4.2.0 ; python_version >= "3.12" and python_version < "4.0"
25 | hpack==4.1.0 ; python_version >= "3.12" and python_version < "4.0"
26 | httpcore==1.0.9 ; python_version >= "3.12" and python_version < "4.0"
27 | httptools==0.6.4 ; python_version >= "3.12" and python_version < "4.0"
28 | httpx==0.28.1 ; python_version >= "3.12" and python_version < "4.0"
29 | hyperframe==6.1.0 ; python_version >= "3.12" and python_version < "4.0"
30 | idna==3.10 ; python_version >= "3.12" and python_version < "4.0"
31 | iniconfig==2.1.0 ; python_version >= "3.12" and python_version < "4.0"
32 | itsdangerous==2.2.0 ; python_version >= "3.12" and python_version < "4.0"
33 | jinja2==3.1.6 ; python_version >= "3.12" and python_version < "4.0"
34 | jsonschema-specifications==2025.4.1 ; python_version >= "3.12" and python_version < "4.0"
35 | jsonschema==4.24.0 ; python_version >= "3.12" and python_version < "4.0"
36 | markdown-it-py==3.0.0 ; python_version >= "3.12" and python_version < "4.0"
37 | markupsafe==3.0.2 ; python_version >= "3.12" and python_version < "4.0"
38 | mdurl==0.1.2 ; python_version >= "3.12" and python_version < "4.0"
39 | multidict==6.5.0 ; python_version >= "3.12" and python_version < "4.0"
40 | narwhals==1.44.0 ; python_version >= "3.12" and python_version < "4.0"
41 | numpy==2.3.1 ; python_version >= "3.12" and python_version < "4.0"
42 | orjson==3.10.18 ; python_version >= "3.12" and python_version < "4.0"
43 | packaging==25.0 ; python_version >= "3.12" and python_version < "4.0"
44 | pandas==2.3.0 ; python_version >= "3.12" and python_version < "4.0"
45 | pillow==11.2.1 ; python_version >= "3.12" and python_version < "4.0"
46 | pluggy==1.6.0 ; python_version >= "3.12" and python_version < "4.0"
47 | postgrest==1.0.2 ; python_version >= "3.12" and python_version < "4.0"
48 | propcache==0.3.2 ; python_version >= "3.12" and python_version < "4.0"
49 | protobuf==6.31.1 ; python_version >= "3.12" and python_version < "4.0"
50 | pyarrow==20.0.0 ; python_version >= "3.12" and python_version < "4.0"
51 | pydantic-core==2.33.2 ; python_version >= "3.12" and python_version < "4.0"
52 | pydantic-extra-types==2.10.5 ; python_version >= "3.12" and python_version < "4.0"
53 | pydantic-settings==2.9.1 ; python_version >= "3.12" and python_version < "4.0"
54 | pydantic==2.11.7 ; python_version >= "3.12" and python_version < "4.0"
55 | pydeck==0.9.1 ; python_version >= "3.12" and python_version < "4.0"
56 | pygments==2.19.1 ; python_version >= "3.12" and python_version < "4.0"
57 | pyjwt==2.10.1 ; python_version >= "3.12" and python_version < "4.0"
58 | pytest-mock==3.14.1 ; python_version >= "3.12" and python_version < "4.0"
59 | pytest==8.4.1 ; python_version >= "3.12" and python_version < "4.0"
60 | python-dateutil==2.9.0.post0 ; python_version >= "3.12" and python_version < "4.0"
61 | python-dotenv==1.1.0 ; python_version >= "3.12" and python_version < "4.0"
62 | python-multipart==0.0.20 ; python_version >= "3.12" and python_version < "4.0"
63 | pytz==2025.2 ; python_version >= "3.12" and python_version < "4.0"
64 | pyyaml==6.0.2 ; python_version >= "3.12" and python_version < "4.0"
65 | realtime==2.4.3 ; python_version >= "3.12" and python_version < "4.0"
66 | referencing==0.36.2 ; python_version >= "3.12" and python_version < "4.0"
67 | requests==2.32.4 ; python_version >= "3.12" and python_version < "4.0"
68 | rich-toolkit==0.14.7 ; python_version >= "3.12" and python_version < "4.0"
69 | rich==14.0.0 ; python_version >= "3.12" and python_version < "4.0"
70 | rpds-py==0.25.1 ; python_version >= "3.12" and python_version < "4.0"
71 | shellingham==1.5.4 ; python_version >= "3.12" and python_version < "4.0"
72 | six==1.17.0 ; python_version >= "3.12" and python_version < "4.0"
73 | smmap==5.0.2 ; python_version >= "3.12" and python_version < "4.0"
74 | sniffio==1.3.1 ; python_version >= "3.12" and python_version < "4.0"
75 | starlette==0.46.2 ; python_version >= "3.12" and python_version < "4.0"
76 | storage3==0.11.3 ; python_version >= "3.12" and python_version < "4.0"
77 | streamlit==1.46.0 ; python_version >= "3.12" and python_version < "4.0"
78 | strenum==0.4.15 ; python_version >= "3.12" and python_version < "4.0"
79 | supabase==2.15.3 ; python_version >= "3.12" and python_version < "4.0"
80 | supafunc==0.9.4 ; python_version >= "3.12" and python_version < "4.0"
81 | tenacity==9.1.2 ; python_version >= "3.12" and python_version < "4.0"
82 | toml==0.10.2 ; python_version >= "3.12" and python_version < "4.0"
83 | tornado==6.5.1 ; python_version >= "3.12" and python_version < "4.0"
84 | typer==0.16.0 ; python_version >= "3.12" and python_version < "4.0"
85 | typing-extensions==4.14.0 ; python_version >= "3.12" and python_version < "4.0"
86 | typing-inspection==0.4.1 ; python_version >= "3.12" and python_version < "4.0"
87 | tzdata==2025.2 ; python_version >= "3.12" and python_version < "4.0"
88 | ujson==5.10.0 ; python_version >= "3.12" and python_version < "4.0"
89 | urllib3==2.4.0 ; python_version >= "3.12" and python_version < "4.0"
90 | uvicorn==0.34.3 ; python_version >= "3.12" and python_version < "4.0"
91 | uvloop==0.21.0 ; python_version >= "3.12" and python_version < "4.0" and sys_platform != "win32" and sys_platform != "cygwin" and platform_python_implementation != "PyPy"
92 | watchdog==6.0.0 ; python_version >= "3.12" and python_version < "4.0" and platform_system != "Darwin"
93 | watchfiles==1.0.5 ; python_version >= "3.12" and python_version < "4.0"
94 | websockets==14.2 ; python_version >= "3.12" and python_version < "4.0"
95 | yarl==1.20.1 ; python_version >= "3.12" and python_version < "4.0"
96 |
--------------------------------------------------------------------------------
/sdk/poetry.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand.
2 |
3 | [[package]]
4 | name = "anyio"
5 | version = "4.5.2"
6 | description = "High level compatibility layer for multiple asynchronous event loop implementations"
7 | optional = false
8 | python-versions = ">=3.8"
9 | groups = ["main"]
10 | files = [
11 | {file = "anyio-4.5.2-py3-none-any.whl", hash = "sha256:c011ee36bc1e8ba40e5a81cb9df91925c218fe9b778554e0b56a21e1b5d4716f"},
12 | {file = "anyio-4.5.2.tar.gz", hash = "sha256:23009af4ed04ce05991845451e11ef02fc7c5ed29179ac9a420e5ad0ac7ddc5b"},
13 | ]
14 |
15 | [package.dependencies]
16 | exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""}
17 | idna = ">=2.8"
18 | sniffio = ">=1.1"
19 | typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""}
20 |
21 | [package.extras]
22 | doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
23 | test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1) ; python_version >= \"3.10\"", "uvloop (>=0.21.0b1) ; platform_python_implementation == \"CPython\" and platform_system != \"Windows\""]
24 | trio = ["trio (>=0.26.1)"]
25 |
26 | [[package]]
27 | name = "certifi"
28 | version = "2025.6.15"
29 | description = "Python package for providing Mozilla's CA Bundle."
30 | optional = false
31 | python-versions = ">=3.7"
32 | groups = ["main"]
33 | files = [
34 | {file = "certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057"},
35 | {file = "certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b"},
36 | ]
37 |
38 | [[package]]
39 | name = "exceptiongroup"
40 | version = "1.3.0"
41 | description = "Backport of PEP 654 (exception groups)"
42 | optional = false
43 | python-versions = ">=3.7"
44 | groups = ["main"]
45 | markers = "python_version < \"3.11\""
46 | files = [
47 | {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"},
48 | {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"},
49 | ]
50 |
51 | [package.dependencies]
52 | typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""}
53 |
54 | [package.extras]
55 | test = ["pytest (>=6)"]
56 |
57 | [[package]]
58 | name = "h11"
59 | version = "0.16.0"
60 | description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
61 | optional = false
62 | python-versions = ">=3.8"
63 | groups = ["main"]
64 | files = [
65 | {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"},
66 | {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"},
67 | ]
68 |
69 | [[package]]
70 | name = "hatchling"
71 | version = "1.27.0"
72 | description = "Modern, extensible Python build backend"
73 | optional = false
74 | python-versions = ">=3.8"
75 | groups = ["main"]
76 | files = [
77 | {file = "hatchling-1.27.0-py3-none-any.whl", hash = "sha256:d3a2f3567c4f926ea39849cdf924c7e99e6686c9c8e288ae1037c8fa2a5d937b"},
78 | {file = "hatchling-1.27.0.tar.gz", hash = "sha256:971c296d9819abb3811112fc52c7a9751c8d381898f36533bb16f9791e941fd6"},
79 | ]
80 |
81 | [package.dependencies]
82 | packaging = ">=24.2"
83 | pathspec = ">=0.10.1"
84 | pluggy = ">=1.0.0"
85 | tomli = {version = ">=1.2.2", markers = "python_version < \"3.11\""}
86 | trove-classifiers = "*"
87 |
88 | [[package]]
89 | name = "httpcore"
90 | version = "1.0.9"
91 | description = "A minimal low-level HTTP client."
92 | optional = false
93 | python-versions = ">=3.8"
94 | groups = ["main"]
95 | files = [
96 | {file = "httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"},
97 | {file = "httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8"},
98 | ]
99 |
100 | [package.dependencies]
101 | certifi = "*"
102 | h11 = ">=0.16"
103 |
104 | [package.extras]
105 | asyncio = ["anyio (>=4.0,<5.0)"]
106 | http2 = ["h2 (>=3,<5)"]
107 | socks = ["socksio (==1.*)"]
108 | trio = ["trio (>=0.22.0,<1.0)"]
109 |
110 | [[package]]
111 | name = "httpx"
112 | version = "0.28.1"
113 | description = "The next generation HTTP client."
114 | optional = false
115 | python-versions = ">=3.8"
116 | groups = ["main"]
117 | files = [
118 | {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"},
119 | {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"},
120 | ]
121 |
122 | [package.dependencies]
123 | anyio = "*"
124 | certifi = "*"
125 | httpcore = "==1.*"
126 | idna = "*"
127 |
128 | [package.extras]
129 | brotli = ["brotli ; platform_python_implementation == \"CPython\"", "brotlicffi ; platform_python_implementation != \"CPython\""]
130 | cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"]
131 | http2 = ["h2 (>=3,<5)"]
132 | socks = ["socksio (==1.*)"]
133 | zstd = ["zstandard (>=0.18.0)"]
134 |
135 | [[package]]
136 | name = "idna"
137 | version = "3.10"
138 | description = "Internationalized Domain Names in Applications (IDNA)"
139 | optional = false
140 | python-versions = ">=3.6"
141 | groups = ["main"]
142 | files = [
143 | {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"},
144 | {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"},
145 | ]
146 |
147 | [package.extras]
148 | all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
149 |
150 | [[package]]
151 | name = "packaging"
152 | version = "25.0"
153 | description = "Core utilities for Python packages"
154 | optional = false
155 | python-versions = ">=3.8"
156 | groups = ["main"]
157 | files = [
158 | {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"},
159 | {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"},
160 | ]
161 |
162 | [[package]]
163 | name = "pathspec"
164 | version = "0.12.1"
165 | description = "Utility library for gitignore style pattern matching of file paths."
166 | optional = false
167 | python-versions = ">=3.8"
168 | groups = ["main"]
169 | files = [
170 | {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"},
171 | {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"},
172 | ]
173 |
174 | [[package]]
175 | name = "pluggy"
176 | version = "1.5.0"
177 | description = "plugin and hook calling mechanisms for python"
178 | optional = false
179 | python-versions = ">=3.8"
180 | groups = ["main"]
181 | files = [
182 | {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
183 | {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
184 | ]
185 |
186 | [package.extras]
187 | dev = ["pre-commit", "tox"]
188 | testing = ["pytest", "pytest-benchmark"]
189 |
190 | [[package]]
191 | name = "sniffio"
192 | version = "1.3.1"
193 | description = "Sniff out which async library your code is running under"
194 | optional = false
195 | python-versions = ">=3.7"
196 | groups = ["main"]
197 | files = [
198 | {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"},
199 | {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
200 | ]
201 |
202 | [[package]]
203 | name = "tomli"
204 | version = "2.2.1"
205 | description = "A lil' TOML parser"
206 | optional = false
207 | python-versions = ">=3.8"
208 | groups = ["main"]
209 | markers = "python_version < \"3.11\""
210 | files = [
211 | {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
212 | {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
213 | {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"},
214 | {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"},
215 | {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"},
216 | {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"},
217 | {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"},
218 | {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"},
219 | {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"},
220 | {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"},
221 | {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"},
222 | {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"},
223 | {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"},
224 | {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"},
225 | {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"},
226 | {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"},
227 | {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"},
228 | {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"},
229 | {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"},
230 | {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"},
231 | {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"},
232 | {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"},
233 | {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"},
234 | {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"},
235 | {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"},
236 | {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"},
237 | {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"},
238 | {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"},
239 | {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"},
240 | {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"},
241 | {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"},
242 | {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"},
243 | ]
244 |
245 | [[package]]
246 | name = "trove-classifiers"
247 | version = "2025.5.9.12"
248 | description = "Canonical source for classifiers on PyPI (pypi.org)."
249 | optional = false
250 | python-versions = "*"
251 | groups = ["main"]
252 | files = [
253 | {file = "trove_classifiers-2025.5.9.12-py3-none-any.whl", hash = "sha256:e381c05537adac78881c8fa345fd0e9970159f4e4a04fcc42cfd3129cca640ce"},
254 | {file = "trove_classifiers-2025.5.9.12.tar.gz", hash = "sha256:7ca7c8a7a76e2cd314468c677c69d12cc2357711fcab4a60f87994c1589e5cb5"},
255 | ]
256 |
257 | [[package]]
258 | name = "typing-extensions"
259 | version = "4.13.2"
260 | description = "Backported and Experimental Type Hints for Python 3.8+"
261 | optional = false
262 | python-versions = ">=3.8"
263 | groups = ["main"]
264 | markers = "python_version < \"3.11\""
265 | files = [
266 | {file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"},
267 | {file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"},
268 | ]
269 |
270 | [[package]]
271 | name = "websockets"
272 | version = "13.1"
273 | description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
274 | optional = false
275 | python-versions = ">=3.8"
276 | groups = ["main"]
277 | files = [
278 | {file = "websockets-13.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f48c749857f8fb598fb890a75f540e3221d0976ed0bf879cf3c7eef34151acee"},
279 | {file = "websockets-13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7e72ce6bda6fb9409cc1e8164dd41d7c91466fb599eb047cfda72fe758a34a7"},
280 | {file = "websockets-13.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f779498eeec470295a2b1a5d97aa1bc9814ecd25e1eb637bd9d1c73a327387f6"},
281 | {file = "websockets-13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4676df3fe46956fbb0437d8800cd5f2b6d41143b6e7e842e60554398432cf29b"},
282 | {file = "websockets-13.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7affedeb43a70351bb811dadf49493c9cfd1ed94c9c70095fd177e9cc1541fa"},
283 | {file = "websockets-13.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1971e62d2caa443e57588e1d82d15f663b29ff9dfe7446d9964a4b6f12c1e700"},
284 | {file = "websockets-13.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5f2e75431f8dc4a47f31565a6e1355fb4f2ecaa99d6b89737527ea917066e26c"},
285 | {file = "websockets-13.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58cf7e75dbf7e566088b07e36ea2e3e2bd5676e22216e4cad108d4df4a7402a0"},
286 | {file = "websockets-13.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c90d6dec6be2c7d03378a574de87af9b1efea77d0c52a8301dd831ece938452f"},
287 | {file = "websockets-13.1-cp310-cp310-win32.whl", hash = "sha256:730f42125ccb14602f455155084f978bd9e8e57e89b569b4d7f0f0c17a448ffe"},
288 | {file = "websockets-13.1-cp310-cp310-win_amd64.whl", hash = "sha256:5993260f483d05a9737073be197371940c01b257cc45ae3f1d5d7adb371b266a"},
289 | {file = "websockets-13.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:61fc0dfcda609cda0fc9fe7977694c0c59cf9d749fbb17f4e9483929e3c48a19"},
290 | {file = "websockets-13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ceec59f59d092c5007e815def4ebb80c2de330e9588e101cf8bd94c143ec78a5"},
291 | {file = "websockets-13.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c1dca61c6db1166c48b95198c0b7d9c990b30c756fc2923cc66f68d17dc558fd"},
292 | {file = "websockets-13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:308e20f22c2c77f3f39caca508e765f8725020b84aa963474e18c59accbf4c02"},
293 | {file = "websockets-13.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d516c325e6540e8a57b94abefc3459d7dab8ce52ac75c96cad5549e187e3a7"},
294 | {file = "websockets-13.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c6e35319b46b99e168eb98472d6c7d8634ee37750d7693656dc766395df096"},
295 | {file = "websockets-13.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5f9fee94ebafbc3117c30be1844ed01a3b177bb6e39088bc6b2fa1dc15572084"},
296 | {file = "websockets-13.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7c1e90228c2f5cdde263253fa5db63e6653f1c00e7ec64108065a0b9713fa1b3"},
297 | {file = "websockets-13.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6548f29b0e401eea2b967b2fdc1c7c7b5ebb3eeb470ed23a54cd45ef078a0db9"},
298 | {file = "websockets-13.1-cp311-cp311-win32.whl", hash = "sha256:c11d4d16e133f6df8916cc5b7e3e96ee4c44c936717d684a94f48f82edb7c92f"},
299 | {file = "websockets-13.1-cp311-cp311-win_amd64.whl", hash = "sha256:d04f13a1d75cb2b8382bdc16ae6fa58c97337253826dfe136195b7f89f661557"},
300 | {file = "websockets-13.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9d75baf00138f80b48f1eac72ad1535aac0b6461265a0bcad391fc5aba875cfc"},
301 | {file = "websockets-13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9b6f347deb3dcfbfde1c20baa21c2ac0751afaa73e64e5b693bb2b848efeaa49"},
302 | {file = "websockets-13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de58647e3f9c42f13f90ac7e5f58900c80a39019848c5547bc691693098ae1bd"},
303 | {file = "websockets-13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1b54689e38d1279a51d11e3467dd2f3a50f5f2e879012ce8f2d6943f00e83f0"},
304 | {file = "websockets-13.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf1781ef73c073e6b0f90af841aaf98501f975d306bbf6221683dd594ccc52b6"},
305 | {file = "websockets-13.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d23b88b9388ed85c6faf0e74d8dec4f4d3baf3ecf20a65a47b836d56260d4b9"},
306 | {file = "websockets-13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3c78383585f47ccb0fcf186dcb8a43f5438bd7d8f47d69e0b56f71bf431a0a68"},
307 | {file = "websockets-13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d6d300f8ec35c24025ceb9b9019ae9040c1ab2f01cddc2bcc0b518af31c75c14"},
308 | {file = "websockets-13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf"},
309 | {file = "websockets-13.1-cp312-cp312-win32.whl", hash = "sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c"},
310 | {file = "websockets-13.1-cp312-cp312-win_amd64.whl", hash = "sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3"},
311 | {file = "websockets-13.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a9ab1e71d3d2e54a0aa646ab6d4eebfaa5f416fe78dfe4da2839525dc5d765c6"},
312 | {file = "websockets-13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b9d7439d7fab4dce00570bb906875734df13d9faa4b48e261c440a5fec6d9708"},
313 | {file = "websockets-13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327b74e915cf13c5931334c61e1a41040e365d380f812513a255aa804b183418"},
314 | {file = "websockets-13.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:325b1ccdbf5e5725fdcb1b0e9ad4d2545056479d0eee392c291c1bf76206435a"},
315 | {file = "websockets-13.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:346bee67a65f189e0e33f520f253d5147ab76ae42493804319b5716e46dddf0f"},
316 | {file = "websockets-13.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91a0fa841646320ec0d3accdff5b757b06e2e5c86ba32af2e0815c96c7a603c5"},
317 | {file = "websockets-13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:18503d2c5f3943e93819238bf20df71982d193f73dcecd26c94514f417f6b135"},
318 | {file = "websockets-13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a9cd1af7e18e5221d2878378fbc287a14cd527fdd5939ed56a18df8a31136bb2"},
319 | {file = "websockets-13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:70c5be9f416aa72aab7a2a76c90ae0a4fe2755c1816c153c1a2bcc3333ce4ce6"},
320 | {file = "websockets-13.1-cp313-cp313-win32.whl", hash = "sha256:624459daabeb310d3815b276c1adef475b3e6804abaf2d9d2c061c319f7f187d"},
321 | {file = "websockets-13.1-cp313-cp313-win_amd64.whl", hash = "sha256:c518e84bb59c2baae725accd355c8dc517b4a3ed8db88b4bc93c78dae2974bf2"},
322 | {file = "websockets-13.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c7934fd0e920e70468e676fe7f1b7261c1efa0d6c037c6722278ca0228ad9d0d"},
323 | {file = "websockets-13.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:149e622dc48c10ccc3d2760e5f36753db9cacf3ad7bc7bbbfd7d9c819e286f23"},
324 | {file = "websockets-13.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a569eb1b05d72f9bce2ebd28a1ce2054311b66677fcd46cf36204ad23acead8c"},
325 | {file = "websockets-13.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95df24ca1e1bd93bbca51d94dd049a984609687cb2fb08a7f2c56ac84e9816ea"},
326 | {file = "websockets-13.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8dbb1bf0c0a4ae8b40bdc9be7f644e2f3fb4e8a9aca7145bfa510d4a374eeb7"},
327 | {file = "websockets-13.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:035233b7531fb92a76beefcbf479504db8c72eb3bff41da55aecce3a0f729e54"},
328 | {file = "websockets-13.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e4450fc83a3df53dec45922b576e91e94f5578d06436871dce3a6be38e40f5db"},
329 | {file = "websockets-13.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:463e1c6ec853202dd3657f156123d6b4dad0c546ea2e2e38be2b3f7c5b8e7295"},
330 | {file = "websockets-13.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6d6855bbe70119872c05107e38fbc7f96b1d8cb047d95c2c50869a46c65a8e96"},
331 | {file = "websockets-13.1-cp38-cp38-win32.whl", hash = "sha256:204e5107f43095012b00f1451374693267adbb832d29966a01ecc4ce1db26faf"},
332 | {file = "websockets-13.1-cp38-cp38-win_amd64.whl", hash = "sha256:485307243237328c022bc908b90e4457d0daa8b5cf4b3723fd3c4a8012fce4c6"},
333 | {file = "websockets-13.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9b37c184f8b976f0c0a231a5f3d6efe10807d41ccbe4488df8c74174805eea7d"},
334 | {file = "websockets-13.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:163e7277e1a0bd9fb3c8842a71661ad19c6aa7bb3d6678dc7f89b17fbcc4aeb7"},
335 | {file = "websockets-13.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4b889dbd1342820cc210ba44307cf75ae5f2f96226c0038094455a96e64fb07a"},
336 | {file = "websockets-13.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:586a356928692c1fed0eca68b4d1c2cbbd1ca2acf2ac7e7ebd3b9052582deefa"},
337 | {file = "websockets-13.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7bd6abf1e070a6b72bfeb71049d6ad286852e285f146682bf30d0296f5fbadfa"},
338 | {file = "websockets-13.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2aad13a200e5934f5a6767492fb07151e1de1d6079c003ab31e1823733ae79"},
339 | {file = "websockets-13.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:df01aea34b6e9e33572c35cd16bae5a47785e7d5c8cb2b54b2acdb9678315a17"},
340 | {file = "websockets-13.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e54affdeb21026329fb0744ad187cf812f7d3c2aa702a5edb562b325191fcab6"},
341 | {file = "websockets-13.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9ef8aa8bdbac47f4968a5d66462a2a0935d044bf35c0e5a8af152d58516dbeb5"},
342 | {file = "websockets-13.1-cp39-cp39-win32.whl", hash = "sha256:deeb929efe52bed518f6eb2ddc00cc496366a14c726005726ad62c2dd9017a3c"},
343 | {file = "websockets-13.1-cp39-cp39-win_amd64.whl", hash = "sha256:7c65ffa900e7cc958cd088b9a9157a8141c991f8c53d11087e6fb7277a03f81d"},
344 | {file = "websockets-13.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5dd6da9bec02735931fccec99d97c29f47cc61f644264eb995ad6c0c27667238"},
345 | {file = "websockets-13.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2510c09d8e8df777177ee3d40cd35450dc169a81e747455cc4197e63f7e7bfe5"},
346 | {file = "websockets-13.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1c3cf67185543730888b20682fb186fc8d0fa6f07ccc3ef4390831ab4b388d9"},
347 | {file = "websockets-13.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcc03c8b72267e97b49149e4863d57c2d77f13fae12066622dc78fe322490fe6"},
348 | {file = "websockets-13.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:004280a140f220c812e65f36944a9ca92d766b6cc4560be652a0a3883a79ed8a"},
349 | {file = "websockets-13.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e2620453c075abeb0daa949a292e19f56de518988e079c36478bacf9546ced23"},
350 | {file = "websockets-13.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9156c45750b37337f7b0b00e6248991a047be4aa44554c9886fe6bdd605aab3b"},
351 | {file = "websockets-13.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:80c421e07973a89fbdd93e6f2003c17d20b69010458d3a8e37fb47874bd67d51"},
352 | {file = "websockets-13.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82d0ba76371769d6a4e56f7e83bb8e81846d17a6190971e38b5de108bde9b0d7"},
353 | {file = "websockets-13.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e9875a0143f07d74dc5e1ded1c4581f0d9f7ab86c78994e2ed9e95050073c94d"},
354 | {file = "websockets-13.1-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a11e38ad8922c7961447f35c7b17bffa15de4d17c70abd07bfbe12d6faa3e027"},
355 | {file = "websockets-13.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4059f790b6ae8768471cddb65d3c4fe4792b0ab48e154c9f0a04cefaabcd5978"},
356 | {file = "websockets-13.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:25c35bf84bf7c7369d247f0b8cfa157f989862c49104c5cf85cb5436a641d93e"},
357 | {file = "websockets-13.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:83f91d8a9bb404b8c2c41a707ac7f7f75b9442a0a876df295de27251a856ad09"},
358 | {file = "websockets-13.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a43cfdcddd07f4ca2b1afb459824dd3c6d53a51410636a2c7fc97b9a8cf4842"},
359 | {file = "websockets-13.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48a2ef1381632a2f0cb4efeff34efa97901c9fbc118e01951ad7cfc10601a9bb"},
360 | {file = "websockets-13.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:459bf774c754c35dbb487360b12c5727adab887f1622b8aed5755880a21c4a20"},
361 | {file = "websockets-13.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:95858ca14a9f6fa8413d29e0a585b31b278388aa775b8a81fa24830123874678"},
362 | {file = "websockets-13.1-py3-none-any.whl", hash = "sha256:a9a396a6ad26130cdae92ae10c36af09d9bfe6cafe69670fd3b6da9b07b4044f"},
363 | {file = "websockets-13.1.tar.gz", hash = "sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878"},
364 | ]
365 |
366 | [metadata]
367 | lock-version = "2.1"
368 | python-versions = ">=3.8"
369 | content-hash = "79368ff0df91343e168832d4f749fac1cc63e5c82c57915a1f1f0528ca9298f7"
370 |
--------------------------------------------------------------------------------
/frontend/memx-frontend/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "memx-frontend",
3 | "version": "0.1.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "memx-frontend",
9 | "version": "0.1.0",
10 | "dependencies": {
11 | "@supabase/auth-helpers-nextjs": "^0.10.0",
12 | "next": "15.3.4",
13 | "react": "^19.0.0",
14 | "react-dom": "^19.0.0"
15 | },
16 | "devDependencies": {
17 | "@tailwindcss/postcss": "^4",
18 | "autoprefixer": "^10.4.21",
19 | "postcss": "^8.5.6",
20 | "tailwindcss": "^4.1.10"
21 | }
22 | },
23 | "node_modules/@alloc/quick-lru": {
24 | "version": "5.2.0",
25 | "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
26 | "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
27 | "dev": true,
28 | "license": "MIT",
29 | "engines": {
30 | "node": ">=10"
31 | },
32 | "funding": {
33 | "url": "https://github.com/sponsors/sindresorhus"
34 | }
35 | },
36 | "node_modules/@ampproject/remapping": {
37 | "version": "2.3.0",
38 | "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
39 | "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
40 | "dev": true,
41 | "license": "Apache-2.0",
42 | "dependencies": {
43 | "@jridgewell/gen-mapping": "^0.3.5",
44 | "@jridgewell/trace-mapping": "^0.3.24"
45 | },
46 | "engines": {
47 | "node": ">=6.0.0"
48 | }
49 | },
50 | "node_modules/@emnapi/runtime": {
51 | "version": "1.4.3",
52 | "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz",
53 | "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==",
54 | "license": "MIT",
55 | "optional": true,
56 | "dependencies": {
57 | "tslib": "^2.4.0"
58 | }
59 | },
60 | "node_modules/@img/sharp-darwin-arm64": {
61 | "version": "0.34.2",
62 | "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.2.tgz",
63 | "integrity": "sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==",
64 | "cpu": [
65 | "arm64"
66 | ],
67 | "license": "Apache-2.0",
68 | "optional": true,
69 | "os": [
70 | "darwin"
71 | ],
72 | "engines": {
73 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
74 | },
75 | "funding": {
76 | "url": "https://opencollective.com/libvips"
77 | },
78 | "optionalDependencies": {
79 | "@img/sharp-libvips-darwin-arm64": "1.1.0"
80 | }
81 | },
82 | "node_modules/@img/sharp-darwin-x64": {
83 | "version": "0.34.2",
84 | "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.2.tgz",
85 | "integrity": "sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==",
86 | "cpu": [
87 | "x64"
88 | ],
89 | "license": "Apache-2.0",
90 | "optional": true,
91 | "os": [
92 | "darwin"
93 | ],
94 | "engines": {
95 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
96 | },
97 | "funding": {
98 | "url": "https://opencollective.com/libvips"
99 | },
100 | "optionalDependencies": {
101 | "@img/sharp-libvips-darwin-x64": "1.1.0"
102 | }
103 | },
104 | "node_modules/@img/sharp-libvips-darwin-arm64": {
105 | "version": "1.1.0",
106 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz",
107 | "integrity": "sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==",
108 | "cpu": [
109 | "arm64"
110 | ],
111 | "license": "LGPL-3.0-or-later",
112 | "optional": true,
113 | "os": [
114 | "darwin"
115 | ],
116 | "funding": {
117 | "url": "https://opencollective.com/libvips"
118 | }
119 | },
120 | "node_modules/@img/sharp-libvips-darwin-x64": {
121 | "version": "1.1.0",
122 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz",
123 | "integrity": "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==",
124 | "cpu": [
125 | "x64"
126 | ],
127 | "license": "LGPL-3.0-or-later",
128 | "optional": true,
129 | "os": [
130 | "darwin"
131 | ],
132 | "funding": {
133 | "url": "https://opencollective.com/libvips"
134 | }
135 | },
136 | "node_modules/@img/sharp-libvips-linux-arm": {
137 | "version": "1.1.0",
138 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz",
139 | "integrity": "sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==",
140 | "cpu": [
141 | "arm"
142 | ],
143 | "license": "LGPL-3.0-or-later",
144 | "optional": true,
145 | "os": [
146 | "linux"
147 | ],
148 | "funding": {
149 | "url": "https://opencollective.com/libvips"
150 | }
151 | },
152 | "node_modules/@img/sharp-libvips-linux-arm64": {
153 | "version": "1.1.0",
154 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz",
155 | "integrity": "sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==",
156 | "cpu": [
157 | "arm64"
158 | ],
159 | "license": "LGPL-3.0-or-later",
160 | "optional": true,
161 | "os": [
162 | "linux"
163 | ],
164 | "funding": {
165 | "url": "https://opencollective.com/libvips"
166 | }
167 | },
168 | "node_modules/@img/sharp-libvips-linux-ppc64": {
169 | "version": "1.1.0",
170 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz",
171 | "integrity": "sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==",
172 | "cpu": [
173 | "ppc64"
174 | ],
175 | "license": "LGPL-3.0-or-later",
176 | "optional": true,
177 | "os": [
178 | "linux"
179 | ],
180 | "funding": {
181 | "url": "https://opencollective.com/libvips"
182 | }
183 | },
184 | "node_modules/@img/sharp-libvips-linux-s390x": {
185 | "version": "1.1.0",
186 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz",
187 | "integrity": "sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==",
188 | "cpu": [
189 | "s390x"
190 | ],
191 | "license": "LGPL-3.0-or-later",
192 | "optional": true,
193 | "os": [
194 | "linux"
195 | ],
196 | "funding": {
197 | "url": "https://opencollective.com/libvips"
198 | }
199 | },
200 | "node_modules/@img/sharp-libvips-linux-x64": {
201 | "version": "1.1.0",
202 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz",
203 | "integrity": "sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==",
204 | "cpu": [
205 | "x64"
206 | ],
207 | "license": "LGPL-3.0-or-later",
208 | "optional": true,
209 | "os": [
210 | "linux"
211 | ],
212 | "funding": {
213 | "url": "https://opencollective.com/libvips"
214 | }
215 | },
216 | "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
217 | "version": "1.1.0",
218 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz",
219 | "integrity": "sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==",
220 | "cpu": [
221 | "arm64"
222 | ],
223 | "license": "LGPL-3.0-or-later",
224 | "optional": true,
225 | "os": [
226 | "linux"
227 | ],
228 | "funding": {
229 | "url": "https://opencollective.com/libvips"
230 | }
231 | },
232 | "node_modules/@img/sharp-libvips-linuxmusl-x64": {
233 | "version": "1.1.0",
234 | "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz",
235 | "integrity": "sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==",
236 | "cpu": [
237 | "x64"
238 | ],
239 | "license": "LGPL-3.0-or-later",
240 | "optional": true,
241 | "os": [
242 | "linux"
243 | ],
244 | "funding": {
245 | "url": "https://opencollective.com/libvips"
246 | }
247 | },
248 | "node_modules/@img/sharp-linux-arm": {
249 | "version": "0.34.2",
250 | "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.2.tgz",
251 | "integrity": "sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==",
252 | "cpu": [
253 | "arm"
254 | ],
255 | "license": "Apache-2.0",
256 | "optional": true,
257 | "os": [
258 | "linux"
259 | ],
260 | "engines": {
261 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
262 | },
263 | "funding": {
264 | "url": "https://opencollective.com/libvips"
265 | },
266 | "optionalDependencies": {
267 | "@img/sharp-libvips-linux-arm": "1.1.0"
268 | }
269 | },
270 | "node_modules/@img/sharp-linux-arm64": {
271 | "version": "0.34.2",
272 | "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.2.tgz",
273 | "integrity": "sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==",
274 | "cpu": [
275 | "arm64"
276 | ],
277 | "license": "Apache-2.0",
278 | "optional": true,
279 | "os": [
280 | "linux"
281 | ],
282 | "engines": {
283 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
284 | },
285 | "funding": {
286 | "url": "https://opencollective.com/libvips"
287 | },
288 | "optionalDependencies": {
289 | "@img/sharp-libvips-linux-arm64": "1.1.0"
290 | }
291 | },
292 | "node_modules/@img/sharp-linux-s390x": {
293 | "version": "0.34.2",
294 | "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.2.tgz",
295 | "integrity": "sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==",
296 | "cpu": [
297 | "s390x"
298 | ],
299 | "license": "Apache-2.0",
300 | "optional": true,
301 | "os": [
302 | "linux"
303 | ],
304 | "engines": {
305 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
306 | },
307 | "funding": {
308 | "url": "https://opencollective.com/libvips"
309 | },
310 | "optionalDependencies": {
311 | "@img/sharp-libvips-linux-s390x": "1.1.0"
312 | }
313 | },
314 | "node_modules/@img/sharp-linux-x64": {
315 | "version": "0.34.2",
316 | "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.2.tgz",
317 | "integrity": "sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==",
318 | "cpu": [
319 | "x64"
320 | ],
321 | "license": "Apache-2.0",
322 | "optional": true,
323 | "os": [
324 | "linux"
325 | ],
326 | "engines": {
327 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
328 | },
329 | "funding": {
330 | "url": "https://opencollective.com/libvips"
331 | },
332 | "optionalDependencies": {
333 | "@img/sharp-libvips-linux-x64": "1.1.0"
334 | }
335 | },
336 | "node_modules/@img/sharp-linuxmusl-arm64": {
337 | "version": "0.34.2",
338 | "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.2.tgz",
339 | "integrity": "sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==",
340 | "cpu": [
341 | "arm64"
342 | ],
343 | "license": "Apache-2.0",
344 | "optional": true,
345 | "os": [
346 | "linux"
347 | ],
348 | "engines": {
349 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
350 | },
351 | "funding": {
352 | "url": "https://opencollective.com/libvips"
353 | },
354 | "optionalDependencies": {
355 | "@img/sharp-libvips-linuxmusl-arm64": "1.1.0"
356 | }
357 | },
358 | "node_modules/@img/sharp-linuxmusl-x64": {
359 | "version": "0.34.2",
360 | "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.2.tgz",
361 | "integrity": "sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==",
362 | "cpu": [
363 | "x64"
364 | ],
365 | "license": "Apache-2.0",
366 | "optional": true,
367 | "os": [
368 | "linux"
369 | ],
370 | "engines": {
371 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
372 | },
373 | "funding": {
374 | "url": "https://opencollective.com/libvips"
375 | },
376 | "optionalDependencies": {
377 | "@img/sharp-libvips-linuxmusl-x64": "1.1.0"
378 | }
379 | },
380 | "node_modules/@img/sharp-wasm32": {
381 | "version": "0.34.2",
382 | "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.2.tgz",
383 | "integrity": "sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==",
384 | "cpu": [
385 | "wasm32"
386 | ],
387 | "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
388 | "optional": true,
389 | "dependencies": {
390 | "@emnapi/runtime": "^1.4.3"
391 | },
392 | "engines": {
393 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
394 | },
395 | "funding": {
396 | "url": "https://opencollective.com/libvips"
397 | }
398 | },
399 | "node_modules/@img/sharp-win32-arm64": {
400 | "version": "0.34.2",
401 | "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.2.tgz",
402 | "integrity": "sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==",
403 | "cpu": [
404 | "arm64"
405 | ],
406 | "license": "Apache-2.0 AND LGPL-3.0-or-later",
407 | "optional": true,
408 | "os": [
409 | "win32"
410 | ],
411 | "engines": {
412 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
413 | },
414 | "funding": {
415 | "url": "https://opencollective.com/libvips"
416 | }
417 | },
418 | "node_modules/@img/sharp-win32-ia32": {
419 | "version": "0.34.2",
420 | "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.2.tgz",
421 | "integrity": "sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==",
422 | "cpu": [
423 | "ia32"
424 | ],
425 | "license": "Apache-2.0 AND LGPL-3.0-or-later",
426 | "optional": true,
427 | "os": [
428 | "win32"
429 | ],
430 | "engines": {
431 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
432 | },
433 | "funding": {
434 | "url": "https://opencollective.com/libvips"
435 | }
436 | },
437 | "node_modules/@img/sharp-win32-x64": {
438 | "version": "0.34.2",
439 | "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.2.tgz",
440 | "integrity": "sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==",
441 | "cpu": [
442 | "x64"
443 | ],
444 | "license": "Apache-2.0 AND LGPL-3.0-or-later",
445 | "optional": true,
446 | "os": [
447 | "win32"
448 | ],
449 | "engines": {
450 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
451 | },
452 | "funding": {
453 | "url": "https://opencollective.com/libvips"
454 | }
455 | },
456 | "node_modules/@isaacs/fs-minipass": {
457 | "version": "4.0.1",
458 | "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
459 | "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
460 | "dev": true,
461 | "license": "ISC",
462 | "dependencies": {
463 | "minipass": "^7.0.4"
464 | },
465 | "engines": {
466 | "node": ">=18.0.0"
467 | }
468 | },
469 | "node_modules/@jridgewell/gen-mapping": {
470 | "version": "0.3.8",
471 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
472 | "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
473 | "dev": true,
474 | "license": "MIT",
475 | "dependencies": {
476 | "@jridgewell/set-array": "^1.2.1",
477 | "@jridgewell/sourcemap-codec": "^1.4.10",
478 | "@jridgewell/trace-mapping": "^0.3.24"
479 | },
480 | "engines": {
481 | "node": ">=6.0.0"
482 | }
483 | },
484 | "node_modules/@jridgewell/resolve-uri": {
485 | "version": "3.1.2",
486 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
487 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
488 | "dev": true,
489 | "license": "MIT",
490 | "engines": {
491 | "node": ">=6.0.0"
492 | }
493 | },
494 | "node_modules/@jridgewell/set-array": {
495 | "version": "1.2.1",
496 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
497 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
498 | "dev": true,
499 | "license": "MIT",
500 | "engines": {
501 | "node": ">=6.0.0"
502 | }
503 | },
504 | "node_modules/@jridgewell/sourcemap-codec": {
505 | "version": "1.5.0",
506 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
507 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
508 | "dev": true,
509 | "license": "MIT"
510 | },
511 | "node_modules/@jridgewell/trace-mapping": {
512 | "version": "0.3.25",
513 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
514 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
515 | "dev": true,
516 | "license": "MIT",
517 | "dependencies": {
518 | "@jridgewell/resolve-uri": "^3.1.0",
519 | "@jridgewell/sourcemap-codec": "^1.4.14"
520 | }
521 | },
522 | "node_modules/@next/env": {
523 | "version": "15.3.4",
524 | "resolved": "https://registry.npmjs.org/@next/env/-/env-15.3.4.tgz",
525 | "integrity": "sha512-ZkdYzBseS6UjYzz6ylVKPOK+//zLWvD6Ta+vpoye8cW11AjiQjGYVibF0xuvT4L0iJfAPfZLFidaEzAOywyOAQ==",
526 | "license": "MIT"
527 | },
528 | "node_modules/@next/swc-darwin-arm64": {
529 | "version": "15.3.4",
530 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.3.4.tgz",
531 | "integrity": "sha512-z0qIYTONmPRbwHWvpyrFXJd5F9YWLCsw3Sjrzj2ZvMYy9NPQMPZ1NjOJh4ojr4oQzcGYwgJKfidzehaNa1BpEg==",
532 | "cpu": [
533 | "arm64"
534 | ],
535 | "license": "MIT",
536 | "optional": true,
537 | "os": [
538 | "darwin"
539 | ],
540 | "engines": {
541 | "node": ">= 10"
542 | }
543 | },
544 | "node_modules/@next/swc-darwin-x64": {
545 | "version": "15.3.4",
546 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.3.4.tgz",
547 | "integrity": "sha512-Z0FYJM8lritw5Wq+vpHYuCIzIlEMjewG2aRkc3Hi2rcbULknYL/xqfpBL23jQnCSrDUGAo/AEv0Z+s2bff9Zkw==",
548 | "cpu": [
549 | "x64"
550 | ],
551 | "license": "MIT",
552 | "optional": true,
553 | "os": [
554 | "darwin"
555 | ],
556 | "engines": {
557 | "node": ">= 10"
558 | }
559 | },
560 | "node_modules/@next/swc-linux-arm64-gnu": {
561 | "version": "15.3.4",
562 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.3.4.tgz",
563 | "integrity": "sha512-l8ZQOCCg7adwmsnFm8m5q9eIPAHdaB2F3cxhufYtVo84pymwKuWfpYTKcUiFcutJdp9xGHC+F1Uq3xnFU1B/7g==",
564 | "cpu": [
565 | "arm64"
566 | ],
567 | "license": "MIT",
568 | "optional": true,
569 | "os": [
570 | "linux"
571 | ],
572 | "engines": {
573 | "node": ">= 10"
574 | }
575 | },
576 | "node_modules/@next/swc-linux-arm64-musl": {
577 | "version": "15.3.4",
578 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.3.4.tgz",
579 | "integrity": "sha512-wFyZ7X470YJQtpKot4xCY3gpdn8lE9nTlldG07/kJYexCUpX1piX+MBfZdvulo+t1yADFVEuzFfVHfklfEx8kw==",
580 | "cpu": [
581 | "arm64"
582 | ],
583 | "license": "MIT",
584 | "optional": true,
585 | "os": [
586 | "linux"
587 | ],
588 | "engines": {
589 | "node": ">= 10"
590 | }
591 | },
592 | "node_modules/@next/swc-linux-x64-gnu": {
593 | "version": "15.3.4",
594 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.3.4.tgz",
595 | "integrity": "sha512-gEbH9rv9o7I12qPyvZNVTyP/PWKqOp8clvnoYZQiX800KkqsaJZuOXkWgMa7ANCCh/oEN2ZQheh3yH8/kWPSEg==",
596 | "cpu": [
597 | "x64"
598 | ],
599 | "license": "MIT",
600 | "optional": true,
601 | "os": [
602 | "linux"
603 | ],
604 | "engines": {
605 | "node": ">= 10"
606 | }
607 | },
608 | "node_modules/@next/swc-linux-x64-musl": {
609 | "version": "15.3.4",
610 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.3.4.tgz",
611 | "integrity": "sha512-Cf8sr0ufuC/nu/yQ76AnarbSAXcwG/wj+1xFPNbyNo8ltA6kw5d5YqO8kQuwVIxk13SBdtgXrNyom3ZosHAy4A==",
612 | "cpu": [
613 | "x64"
614 | ],
615 | "license": "MIT",
616 | "optional": true,
617 | "os": [
618 | "linux"
619 | ],
620 | "engines": {
621 | "node": ">= 10"
622 | }
623 | },
624 | "node_modules/@next/swc-win32-arm64-msvc": {
625 | "version": "15.3.4",
626 | "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.3.4.tgz",
627 | "integrity": "sha512-ay5+qADDN3rwRbRpEhTOreOn1OyJIXS60tg9WMYTWCy3fB6rGoyjLVxc4dR9PYjEdR2iDYsaF5h03NA+XuYPQQ==",
628 | "cpu": [
629 | "arm64"
630 | ],
631 | "license": "MIT",
632 | "optional": true,
633 | "os": [
634 | "win32"
635 | ],
636 | "engines": {
637 | "node": ">= 10"
638 | }
639 | },
640 | "node_modules/@next/swc-win32-x64-msvc": {
641 | "version": "15.3.4",
642 | "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.3.4.tgz",
643 | "integrity": "sha512-4kDt31Bc9DGyYs41FTL1/kNpDeHyha2TC0j5sRRoKCyrhNcfZ/nRQkAUlF27mETwm8QyHqIjHJitfcza2Iykfg==",
644 | "cpu": [
645 | "x64"
646 | ],
647 | "license": "MIT",
648 | "optional": true,
649 | "os": [
650 | "win32"
651 | ],
652 | "engines": {
653 | "node": ">= 10"
654 | }
655 | },
656 | "node_modules/@supabase/auth-helpers-nextjs": {
657 | "version": "0.10.0",
658 | "resolved": "https://registry.npmjs.org/@supabase/auth-helpers-nextjs/-/auth-helpers-nextjs-0.10.0.tgz",
659 | "integrity": "sha512-2dfOGsM4yZt0oS4TPiE7bD4vf7EVz7NRz/IJrV6vLg0GP7sMUx8wndv2euLGq4BjN9lUCpu6DG/uCC8j+ylwPg==",
660 | "deprecated": "This package is now deprecated - please use the @supabase/ssr package instead.",
661 | "license": "MIT",
662 | "dependencies": {
663 | "@supabase/auth-helpers-shared": "0.7.0",
664 | "set-cookie-parser": "^2.6.0"
665 | },
666 | "peerDependencies": {
667 | "@supabase/supabase-js": "^2.39.8"
668 | }
669 | },
670 | "node_modules/@supabase/auth-helpers-shared": {
671 | "version": "0.7.0",
672 | "resolved": "https://registry.npmjs.org/@supabase/auth-helpers-shared/-/auth-helpers-shared-0.7.0.tgz",
673 | "integrity": "sha512-FBFf2ei2R7QC+B/5wWkthMha8Ca2bWHAndN+syfuEUUfufv4mLcAgBCcgNg5nJR8L0gZfyuaxgubtOc9aW3Cpg==",
674 | "deprecated": "This package is now deprecated - please use the @supabase/ssr package instead.",
675 | "license": "MIT",
676 | "dependencies": {
677 | "jose": "^4.14.4"
678 | },
679 | "peerDependencies": {
680 | "@supabase/supabase-js": "^2.39.8"
681 | }
682 | },
683 | "node_modules/@supabase/auth-js": {
684 | "version": "2.70.0",
685 | "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.70.0.tgz",
686 | "integrity": "sha512-BaAK/tOAZFJtzF1sE3gJ2FwTjLf4ky3PSvcvLGEgEmO4BSBkwWKu8l67rLLIBZPDnCyV7Owk2uPyKHa0kj5QGg==",
687 | "license": "MIT",
688 | "peer": true,
689 | "dependencies": {
690 | "@supabase/node-fetch": "^2.6.14"
691 | }
692 | },
693 | "node_modules/@supabase/functions-js": {
694 | "version": "2.4.4",
695 | "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.4.4.tgz",
696 | "integrity": "sha512-WL2p6r4AXNGwop7iwvul2BvOtuJ1YQy8EbOd0dhG1oN1q8el/BIRSFCFnWAMM/vJJlHWLi4ad22sKbKr9mvjoA==",
697 | "license": "MIT",
698 | "peer": true,
699 | "dependencies": {
700 | "@supabase/node-fetch": "^2.6.14"
701 | }
702 | },
703 | "node_modules/@supabase/node-fetch": {
704 | "version": "2.6.15",
705 | "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz",
706 | "integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==",
707 | "license": "MIT",
708 | "peer": true,
709 | "dependencies": {
710 | "whatwg-url": "^5.0.0"
711 | },
712 | "engines": {
713 | "node": "4.x || >=6.0.0"
714 | }
715 | },
716 | "node_modules/@supabase/postgrest-js": {
717 | "version": "1.19.4",
718 | "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.19.4.tgz",
719 | "integrity": "sha512-O4soKqKtZIW3olqmbXXbKugUtByD2jPa8kL2m2c1oozAO11uCcGrRhkZL0kVxjBLrXHE0mdSkFsMj7jDSfyNpw==",
720 | "license": "MIT",
721 | "peer": true,
722 | "dependencies": {
723 | "@supabase/node-fetch": "^2.6.14"
724 | }
725 | },
726 | "node_modules/@supabase/realtime-js": {
727 | "version": "2.11.15",
728 | "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.11.15.tgz",
729 | "integrity": "sha512-HQKRnwAqdVqJW/P9TjKVK+/ETpW4yQ8tyDPPtRMKOH4Uh3vQD74vmj353CYs8+YwVBKubeUOOEpI9CT8mT4obw==",
730 | "license": "MIT",
731 | "peer": true,
732 | "dependencies": {
733 | "@supabase/node-fetch": "^2.6.13",
734 | "@types/phoenix": "^1.6.6",
735 | "@types/ws": "^8.18.1",
736 | "isows": "^1.0.7",
737 | "ws": "^8.18.2"
738 | }
739 | },
740 | "node_modules/@supabase/storage-js": {
741 | "version": "2.7.1",
742 | "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.7.1.tgz",
743 | "integrity": "sha512-asYHcyDR1fKqrMpytAS1zjyEfvxuOIp1CIXX7ji4lHHcJKqyk+sLl/Vxgm4sN6u8zvuUtae9e4kDxQP2qrwWBA==",
744 | "license": "MIT",
745 | "peer": true,
746 | "dependencies": {
747 | "@supabase/node-fetch": "^2.6.14"
748 | }
749 | },
750 | "node_modules/@supabase/supabase-js": {
751 | "version": "2.50.2",
752 | "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.50.2.tgz",
753 | "integrity": "sha512-+27xlGgw7VyfwXXe+OiDJQosJNS+PPtjj1EnLR4uk+PKKZ91RA0/8NbIQybe6AGPanAaPtgOFFMMCArC6fZ++Q==",
754 | "license": "MIT",
755 | "peer": true,
756 | "dependencies": {
757 | "@supabase/auth-js": "2.70.0",
758 | "@supabase/functions-js": "2.4.4",
759 | "@supabase/node-fetch": "2.6.15",
760 | "@supabase/postgrest-js": "1.19.4",
761 | "@supabase/realtime-js": "2.11.15",
762 | "@supabase/storage-js": "2.7.1"
763 | }
764 | },
765 | "node_modules/@swc/counter": {
766 | "version": "0.1.3",
767 | "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
768 | "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
769 | "license": "Apache-2.0"
770 | },
771 | "node_modules/@swc/helpers": {
772 | "version": "0.5.15",
773 | "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
774 | "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
775 | "license": "Apache-2.0",
776 | "dependencies": {
777 | "tslib": "^2.8.0"
778 | }
779 | },
780 | "node_modules/@tailwindcss/node": {
781 | "version": "4.1.10",
782 | "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.10.tgz",
783 | "integrity": "sha512-2ACf1znY5fpRBwRhMgj9ZXvb2XZW8qs+oTfotJ2C5xR0/WNL7UHZ7zXl6s+rUqedL1mNi+0O+WQr5awGowS3PQ==",
784 | "dev": true,
785 | "license": "MIT",
786 | "dependencies": {
787 | "@ampproject/remapping": "^2.3.0",
788 | "enhanced-resolve": "^5.18.1",
789 | "jiti": "^2.4.2",
790 | "lightningcss": "1.30.1",
791 | "magic-string": "^0.30.17",
792 | "source-map-js": "^1.2.1",
793 | "tailwindcss": "4.1.10"
794 | }
795 | },
796 | "node_modules/@tailwindcss/oxide": {
797 | "version": "4.1.10",
798 | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.10.tgz",
799 | "integrity": "sha512-v0C43s7Pjw+B9w21htrQwuFObSkio2aV/qPx/mhrRldbqxbWJK6KizM+q7BF1/1CmuLqZqX3CeYF7s7P9fbA8Q==",
800 | "dev": true,
801 | "hasInstallScript": true,
802 | "license": "MIT",
803 | "dependencies": {
804 | "detect-libc": "^2.0.4",
805 | "tar": "^7.4.3"
806 | },
807 | "engines": {
808 | "node": ">= 10"
809 | },
810 | "optionalDependencies": {
811 | "@tailwindcss/oxide-android-arm64": "4.1.10",
812 | "@tailwindcss/oxide-darwin-arm64": "4.1.10",
813 | "@tailwindcss/oxide-darwin-x64": "4.1.10",
814 | "@tailwindcss/oxide-freebsd-x64": "4.1.10",
815 | "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.10",
816 | "@tailwindcss/oxide-linux-arm64-gnu": "4.1.10",
817 | "@tailwindcss/oxide-linux-arm64-musl": "4.1.10",
818 | "@tailwindcss/oxide-linux-x64-gnu": "4.1.10",
819 | "@tailwindcss/oxide-linux-x64-musl": "4.1.10",
820 | "@tailwindcss/oxide-wasm32-wasi": "4.1.10",
821 | "@tailwindcss/oxide-win32-arm64-msvc": "4.1.10",
822 | "@tailwindcss/oxide-win32-x64-msvc": "4.1.10"
823 | }
824 | },
825 | "node_modules/@tailwindcss/oxide-android-arm64": {
826 | "version": "4.1.10",
827 | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.10.tgz",
828 | "integrity": "sha512-VGLazCoRQ7rtsCzThaI1UyDu/XRYVyH4/EWiaSX6tFglE+xZB5cvtC5Omt0OQ+FfiIVP98su16jDVHDEIuH4iQ==",
829 | "cpu": [
830 | "arm64"
831 | ],
832 | "dev": true,
833 | "license": "MIT",
834 | "optional": true,
835 | "os": [
836 | "android"
837 | ],
838 | "engines": {
839 | "node": ">= 10"
840 | }
841 | },
842 | "node_modules/@tailwindcss/oxide-darwin-arm64": {
843 | "version": "4.1.10",
844 | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.10.tgz",
845 | "integrity": "sha512-ZIFqvR1irX2yNjWJzKCqTCcHZbgkSkSkZKbRM3BPzhDL/18idA8uWCoopYA2CSDdSGFlDAxYdU2yBHwAwx8euQ==",
846 | "cpu": [
847 | "arm64"
848 | ],
849 | "dev": true,
850 | "license": "MIT",
851 | "optional": true,
852 | "os": [
853 | "darwin"
854 | ],
855 | "engines": {
856 | "node": ">= 10"
857 | }
858 | },
859 | "node_modules/@tailwindcss/oxide-darwin-x64": {
860 | "version": "4.1.10",
861 | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.10.tgz",
862 | "integrity": "sha512-eCA4zbIhWUFDXoamNztmS0MjXHSEJYlvATzWnRiTqJkcUteSjO94PoRHJy1Xbwp9bptjeIxxBHh+zBWFhttbrQ==",
863 | "cpu": [
864 | "x64"
865 | ],
866 | "dev": true,
867 | "license": "MIT",
868 | "optional": true,
869 | "os": [
870 | "darwin"
871 | ],
872 | "engines": {
873 | "node": ">= 10"
874 | }
875 | },
876 | "node_modules/@tailwindcss/oxide-freebsd-x64": {
877 | "version": "4.1.10",
878 | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.10.tgz",
879 | "integrity": "sha512-8/392Xu12R0cc93DpiJvNpJ4wYVSiciUlkiOHOSOQNH3adq9Gi/dtySK7dVQjXIOzlpSHjeCL89RUUI8/GTI6g==",
880 | "cpu": [
881 | "x64"
882 | ],
883 | "dev": true,
884 | "license": "MIT",
885 | "optional": true,
886 | "os": [
887 | "freebsd"
888 | ],
889 | "engines": {
890 | "node": ">= 10"
891 | }
892 | },
893 | "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
894 | "version": "4.1.10",
895 | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.10.tgz",
896 | "integrity": "sha512-t9rhmLT6EqeuPT+MXhWhlRYIMSfh5LZ6kBrC4FS6/+M1yXwfCtp24UumgCWOAJVyjQwG+lYva6wWZxrfvB+NhQ==",
897 | "cpu": [
898 | "arm"
899 | ],
900 | "dev": true,
901 | "license": "MIT",
902 | "optional": true,
903 | "os": [
904 | "linux"
905 | ],
906 | "engines": {
907 | "node": ">= 10"
908 | }
909 | },
910 | "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
911 | "version": "4.1.10",
912 | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.10.tgz",
913 | "integrity": "sha512-3oWrlNlxLRxXejQ8zImzrVLuZ/9Z2SeKoLhtCu0hpo38hTO2iL86eFOu4sVR8cZc6n3z7eRXXqtHJECa6mFOvA==",
914 | "cpu": [
915 | "arm64"
916 | ],
917 | "dev": true,
918 | "license": "MIT",
919 | "optional": true,
920 | "os": [
921 | "linux"
922 | ],
923 | "engines": {
924 | "node": ">= 10"
925 | }
926 | },
927 | "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
928 | "version": "4.1.10",
929 | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.10.tgz",
930 | "integrity": "sha512-saScU0cmWvg/Ez4gUmQWr9pvY9Kssxt+Xenfx1LG7LmqjcrvBnw4r9VjkFcqmbBb7GCBwYNcZi9X3/oMda9sqQ==",
931 | "cpu": [
932 | "arm64"
933 | ],
934 | "dev": true,
935 | "license": "MIT",
936 | "optional": true,
937 | "os": [
938 | "linux"
939 | ],
940 | "engines": {
941 | "node": ">= 10"
942 | }
943 | },
944 | "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
945 | "version": "4.1.10",
946 | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.10.tgz",
947 | "integrity": "sha512-/G3ao/ybV9YEEgAXeEg28dyH6gs1QG8tvdN9c2MNZdUXYBaIY/Gx0N6RlJzfLy/7Nkdok4kaxKPHKJUlAaoTdA==",
948 | "cpu": [
949 | "x64"
950 | ],
951 | "dev": true,
952 | "license": "MIT",
953 | "optional": true,
954 | "os": [
955 | "linux"
956 | ],
957 | "engines": {
958 | "node": ">= 10"
959 | }
960 | },
961 | "node_modules/@tailwindcss/oxide-linux-x64-musl": {
962 | "version": "4.1.10",
963 | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.10.tgz",
964 | "integrity": "sha512-LNr7X8fTiKGRtQGOerSayc2pWJp/9ptRYAa4G+U+cjw9kJZvkopav1AQc5HHD+U364f71tZv6XamaHKgrIoVzA==",
965 | "cpu": [
966 | "x64"
967 | ],
968 | "dev": true,
969 | "license": "MIT",
970 | "optional": true,
971 | "os": [
972 | "linux"
973 | ],
974 | "engines": {
975 | "node": ">= 10"
976 | }
977 | },
978 | "node_modules/@tailwindcss/oxide-wasm32-wasi": {
979 | "version": "4.1.10",
980 | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.10.tgz",
981 | "integrity": "sha512-d6ekQpopFQJAcIK2i7ZzWOYGZ+A6NzzvQ3ozBvWFdeyqfOZdYHU66g5yr+/HC4ipP1ZgWsqa80+ISNILk+ae/Q==",
982 | "bundleDependencies": [
983 | "@napi-rs/wasm-runtime",
984 | "@emnapi/core",
985 | "@emnapi/runtime",
986 | "@tybys/wasm-util",
987 | "@emnapi/wasi-threads",
988 | "tslib"
989 | ],
990 | "cpu": [
991 | "wasm32"
992 | ],
993 | "dev": true,
994 | "license": "MIT",
995 | "optional": true,
996 | "dependencies": {
997 | "@emnapi/core": "^1.4.3",
998 | "@emnapi/runtime": "^1.4.3",
999 | "@emnapi/wasi-threads": "^1.0.2",
1000 | "@napi-rs/wasm-runtime": "^0.2.10",
1001 | "@tybys/wasm-util": "^0.9.0",
1002 | "tslib": "^2.8.0"
1003 | },
1004 | "engines": {
1005 | "node": ">=14.0.0"
1006 | }
1007 | },
1008 | "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
1009 | "version": "4.1.10",
1010 | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.10.tgz",
1011 | "integrity": "sha512-i1Iwg9gRbwNVOCYmnigWCCgow8nDWSFmeTUU5nbNx3rqbe4p0kRbEqLwLJbYZKmSSp23g4N6rCDmm7OuPBXhDA==",
1012 | "cpu": [
1013 | "arm64"
1014 | ],
1015 | "dev": true,
1016 | "license": "MIT",
1017 | "optional": true,
1018 | "os": [
1019 | "win32"
1020 | ],
1021 | "engines": {
1022 | "node": ">= 10"
1023 | }
1024 | },
1025 | "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
1026 | "version": "4.1.10",
1027 | "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.10.tgz",
1028 | "integrity": "sha512-sGiJTjcBSfGq2DVRtaSljq5ZgZS2SDHSIfhOylkBvHVjwOsodBhnb3HdmiKkVuUGKD0I7G63abMOVaskj1KpOA==",
1029 | "cpu": [
1030 | "x64"
1031 | ],
1032 | "dev": true,
1033 | "license": "MIT",
1034 | "optional": true,
1035 | "os": [
1036 | "win32"
1037 | ],
1038 | "engines": {
1039 | "node": ">= 10"
1040 | }
1041 | },
1042 | "node_modules/@tailwindcss/postcss": {
1043 | "version": "4.1.10",
1044 | "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.10.tgz",
1045 | "integrity": "sha512-B+7r7ABZbkXJwpvt2VMnS6ujcDoR2OOcFaqrLIo1xbcdxje4Vf+VgJdBzNNbrAjBj/rLZ66/tlQ1knIGNLKOBQ==",
1046 | "dev": true,
1047 | "license": "MIT",
1048 | "dependencies": {
1049 | "@alloc/quick-lru": "^5.2.0",
1050 | "@tailwindcss/node": "4.1.10",
1051 | "@tailwindcss/oxide": "4.1.10",
1052 | "postcss": "^8.4.41",
1053 | "tailwindcss": "4.1.10"
1054 | }
1055 | },
1056 | "node_modules/@types/node": {
1057 | "version": "24.0.4",
1058 | "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.4.tgz",
1059 | "integrity": "sha512-ulyqAkrhnuNq9pB76DRBTkcS6YsmDALy6Ua63V8OhrOBgbcYt6IOdzpw5P1+dyRIyMerzLkeYWBeOXPpA9GMAA==",
1060 | "license": "MIT",
1061 | "peer": true,
1062 | "dependencies": {
1063 | "undici-types": "~7.8.0"
1064 | }
1065 | },
1066 | "node_modules/@types/phoenix": {
1067 | "version": "1.6.6",
1068 | "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.6.tgz",
1069 | "integrity": "sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==",
1070 | "license": "MIT",
1071 | "peer": true
1072 | },
1073 | "node_modules/@types/ws": {
1074 | "version": "8.18.1",
1075 | "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
1076 | "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
1077 | "license": "MIT",
1078 | "peer": true,
1079 | "dependencies": {
1080 | "@types/node": "*"
1081 | }
1082 | },
1083 | "node_modules/autoprefixer": {
1084 | "version": "10.4.21",
1085 | "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
1086 | "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==",
1087 | "dev": true,
1088 | "funding": [
1089 | {
1090 | "type": "opencollective",
1091 | "url": "https://opencollective.com/postcss/"
1092 | },
1093 | {
1094 | "type": "tidelift",
1095 | "url": "https://tidelift.com/funding/github/npm/autoprefixer"
1096 | },
1097 | {
1098 | "type": "github",
1099 | "url": "https://github.com/sponsors/ai"
1100 | }
1101 | ],
1102 | "license": "MIT",
1103 | "dependencies": {
1104 | "browserslist": "^4.24.4",
1105 | "caniuse-lite": "^1.0.30001702",
1106 | "fraction.js": "^4.3.7",
1107 | "normalize-range": "^0.1.2",
1108 | "picocolors": "^1.1.1",
1109 | "postcss-value-parser": "^4.2.0"
1110 | },
1111 | "bin": {
1112 | "autoprefixer": "bin/autoprefixer"
1113 | },
1114 | "engines": {
1115 | "node": "^10 || ^12 || >=14"
1116 | },
1117 | "peerDependencies": {
1118 | "postcss": "^8.1.0"
1119 | }
1120 | },
1121 | "node_modules/browserslist": {
1122 | "version": "4.25.1",
1123 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz",
1124 | "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==",
1125 | "dev": true,
1126 | "funding": [
1127 | {
1128 | "type": "opencollective",
1129 | "url": "https://opencollective.com/browserslist"
1130 | },
1131 | {
1132 | "type": "tidelift",
1133 | "url": "https://tidelift.com/funding/github/npm/browserslist"
1134 | },
1135 | {
1136 | "type": "github",
1137 | "url": "https://github.com/sponsors/ai"
1138 | }
1139 | ],
1140 | "license": "MIT",
1141 | "dependencies": {
1142 | "caniuse-lite": "^1.0.30001726",
1143 | "electron-to-chromium": "^1.5.173",
1144 | "node-releases": "^2.0.19",
1145 | "update-browserslist-db": "^1.1.3"
1146 | },
1147 | "bin": {
1148 | "browserslist": "cli.js"
1149 | },
1150 | "engines": {
1151 | "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
1152 | }
1153 | },
1154 | "node_modules/busboy": {
1155 | "version": "1.6.0",
1156 | "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
1157 | "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
1158 | "dependencies": {
1159 | "streamsearch": "^1.1.0"
1160 | },
1161 | "engines": {
1162 | "node": ">=10.16.0"
1163 | }
1164 | },
1165 | "node_modules/caniuse-lite": {
1166 | "version": "1.0.30001726",
1167 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz",
1168 | "integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==",
1169 | "funding": [
1170 | {
1171 | "type": "opencollective",
1172 | "url": "https://opencollective.com/browserslist"
1173 | },
1174 | {
1175 | "type": "tidelift",
1176 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
1177 | },
1178 | {
1179 | "type": "github",
1180 | "url": "https://github.com/sponsors/ai"
1181 | }
1182 | ],
1183 | "license": "CC-BY-4.0"
1184 | },
1185 | "node_modules/chownr": {
1186 | "version": "3.0.0",
1187 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
1188 | "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
1189 | "dev": true,
1190 | "license": "BlueOak-1.0.0",
1191 | "engines": {
1192 | "node": ">=18"
1193 | }
1194 | },
1195 | "node_modules/client-only": {
1196 | "version": "0.0.1",
1197 | "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
1198 | "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
1199 | "license": "MIT"
1200 | },
1201 | "node_modules/color": {
1202 | "version": "4.2.3",
1203 | "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
1204 | "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
1205 | "license": "MIT",
1206 | "optional": true,
1207 | "dependencies": {
1208 | "color-convert": "^2.0.1",
1209 | "color-string": "^1.9.0"
1210 | },
1211 | "engines": {
1212 | "node": ">=12.5.0"
1213 | }
1214 | },
1215 | "node_modules/color-convert": {
1216 | "version": "2.0.1",
1217 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
1218 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
1219 | "license": "MIT",
1220 | "optional": true,
1221 | "dependencies": {
1222 | "color-name": "~1.1.4"
1223 | },
1224 | "engines": {
1225 | "node": ">=7.0.0"
1226 | }
1227 | },
1228 | "node_modules/color-name": {
1229 | "version": "1.1.4",
1230 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
1231 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
1232 | "license": "MIT",
1233 | "optional": true
1234 | },
1235 | "node_modules/color-string": {
1236 | "version": "1.9.1",
1237 | "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
1238 | "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
1239 | "license": "MIT",
1240 | "optional": true,
1241 | "dependencies": {
1242 | "color-name": "^1.0.0",
1243 | "simple-swizzle": "^0.2.2"
1244 | }
1245 | },
1246 | "node_modules/detect-libc": {
1247 | "version": "2.0.4",
1248 | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
1249 | "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
1250 | "devOptional": true,
1251 | "license": "Apache-2.0",
1252 | "engines": {
1253 | "node": ">=8"
1254 | }
1255 | },
1256 | "node_modules/electron-to-chromium": {
1257 | "version": "1.5.176",
1258 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.176.tgz",
1259 | "integrity": "sha512-2nDK9orkm7M9ZZkjO3PjbEd3VUulQLyg5T9O3enJdFvUg46Hzd4DUvTvAuEgbdHYXyFsiG4A5sO9IzToMH1cDg==",
1260 | "dev": true,
1261 | "license": "ISC"
1262 | },
1263 | "node_modules/enhanced-resolve": {
1264 | "version": "5.18.2",
1265 | "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz",
1266 | "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==",
1267 | "dev": true,
1268 | "license": "MIT",
1269 | "dependencies": {
1270 | "graceful-fs": "^4.2.4",
1271 | "tapable": "^2.2.0"
1272 | },
1273 | "engines": {
1274 | "node": ">=10.13.0"
1275 | }
1276 | },
1277 | "node_modules/escalade": {
1278 | "version": "3.2.0",
1279 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
1280 | "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
1281 | "dev": true,
1282 | "license": "MIT",
1283 | "engines": {
1284 | "node": ">=6"
1285 | }
1286 | },
1287 | "node_modules/fraction.js": {
1288 | "version": "4.3.7",
1289 | "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
1290 | "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
1291 | "dev": true,
1292 | "license": "MIT",
1293 | "engines": {
1294 | "node": "*"
1295 | },
1296 | "funding": {
1297 | "type": "patreon",
1298 | "url": "https://github.com/sponsors/rawify"
1299 | }
1300 | },
1301 | "node_modules/graceful-fs": {
1302 | "version": "4.2.11",
1303 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
1304 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
1305 | "dev": true,
1306 | "license": "ISC"
1307 | },
1308 | "node_modules/is-arrayish": {
1309 | "version": "0.3.2",
1310 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
1311 | "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
1312 | "license": "MIT",
1313 | "optional": true
1314 | },
1315 | "node_modules/isows": {
1316 | "version": "1.0.7",
1317 | "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz",
1318 | "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==",
1319 | "funding": [
1320 | {
1321 | "type": "github",
1322 | "url": "https://github.com/sponsors/wevm"
1323 | }
1324 | ],
1325 | "license": "MIT",
1326 | "peer": true,
1327 | "peerDependencies": {
1328 | "ws": "*"
1329 | }
1330 | },
1331 | "node_modules/jiti": {
1332 | "version": "2.4.2",
1333 | "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
1334 | "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
1335 | "dev": true,
1336 | "license": "MIT",
1337 | "bin": {
1338 | "jiti": "lib/jiti-cli.mjs"
1339 | }
1340 | },
1341 | "node_modules/jose": {
1342 | "version": "4.15.9",
1343 | "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz",
1344 | "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==",
1345 | "license": "MIT",
1346 | "funding": {
1347 | "url": "https://github.com/sponsors/panva"
1348 | }
1349 | },
1350 | "node_modules/lightningcss": {
1351 | "version": "1.30.1",
1352 | "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz",
1353 | "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==",
1354 | "dev": true,
1355 | "license": "MPL-2.0",
1356 | "dependencies": {
1357 | "detect-libc": "^2.0.3"
1358 | },
1359 | "engines": {
1360 | "node": ">= 12.0.0"
1361 | },
1362 | "funding": {
1363 | "type": "opencollective",
1364 | "url": "https://opencollective.com/parcel"
1365 | },
1366 | "optionalDependencies": {
1367 | "lightningcss-darwin-arm64": "1.30.1",
1368 | "lightningcss-darwin-x64": "1.30.1",
1369 | "lightningcss-freebsd-x64": "1.30.1",
1370 | "lightningcss-linux-arm-gnueabihf": "1.30.1",
1371 | "lightningcss-linux-arm64-gnu": "1.30.1",
1372 | "lightningcss-linux-arm64-musl": "1.30.1",
1373 | "lightningcss-linux-x64-gnu": "1.30.1",
1374 | "lightningcss-linux-x64-musl": "1.30.1",
1375 | "lightningcss-win32-arm64-msvc": "1.30.1",
1376 | "lightningcss-win32-x64-msvc": "1.30.1"
1377 | }
1378 | },
1379 | "node_modules/lightningcss-darwin-arm64": {
1380 | "version": "1.30.1",
1381 | "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz",
1382 | "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==",
1383 | "cpu": [
1384 | "arm64"
1385 | ],
1386 | "dev": true,
1387 | "license": "MPL-2.0",
1388 | "optional": true,
1389 | "os": [
1390 | "darwin"
1391 | ],
1392 | "engines": {
1393 | "node": ">= 12.0.0"
1394 | },
1395 | "funding": {
1396 | "type": "opencollective",
1397 | "url": "https://opencollective.com/parcel"
1398 | }
1399 | },
1400 | "node_modules/lightningcss-darwin-x64": {
1401 | "version": "1.30.1",
1402 | "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz",
1403 | "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==",
1404 | "cpu": [
1405 | "x64"
1406 | ],
1407 | "dev": true,
1408 | "license": "MPL-2.0",
1409 | "optional": true,
1410 | "os": [
1411 | "darwin"
1412 | ],
1413 | "engines": {
1414 | "node": ">= 12.0.0"
1415 | },
1416 | "funding": {
1417 | "type": "opencollective",
1418 | "url": "https://opencollective.com/parcel"
1419 | }
1420 | },
1421 | "node_modules/lightningcss-freebsd-x64": {
1422 | "version": "1.30.1",
1423 | "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz",
1424 | "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==",
1425 | "cpu": [
1426 | "x64"
1427 | ],
1428 | "dev": true,
1429 | "license": "MPL-2.0",
1430 | "optional": true,
1431 | "os": [
1432 | "freebsd"
1433 | ],
1434 | "engines": {
1435 | "node": ">= 12.0.0"
1436 | },
1437 | "funding": {
1438 | "type": "opencollective",
1439 | "url": "https://opencollective.com/parcel"
1440 | }
1441 | },
1442 | "node_modules/lightningcss-linux-arm-gnueabihf": {
1443 | "version": "1.30.1",
1444 | "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz",
1445 | "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==",
1446 | "cpu": [
1447 | "arm"
1448 | ],
1449 | "dev": true,
1450 | "license": "MPL-2.0",
1451 | "optional": true,
1452 | "os": [
1453 | "linux"
1454 | ],
1455 | "engines": {
1456 | "node": ">= 12.0.0"
1457 | },
1458 | "funding": {
1459 | "type": "opencollective",
1460 | "url": "https://opencollective.com/parcel"
1461 | }
1462 | },
1463 | "node_modules/lightningcss-linux-arm64-gnu": {
1464 | "version": "1.30.1",
1465 | "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz",
1466 | "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==",
1467 | "cpu": [
1468 | "arm64"
1469 | ],
1470 | "dev": true,
1471 | "license": "MPL-2.0",
1472 | "optional": true,
1473 | "os": [
1474 | "linux"
1475 | ],
1476 | "engines": {
1477 | "node": ">= 12.0.0"
1478 | },
1479 | "funding": {
1480 | "type": "opencollective",
1481 | "url": "https://opencollective.com/parcel"
1482 | }
1483 | },
1484 | "node_modules/lightningcss-linux-arm64-musl": {
1485 | "version": "1.30.1",
1486 | "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz",
1487 | "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==",
1488 | "cpu": [
1489 | "arm64"
1490 | ],
1491 | "dev": true,
1492 | "license": "MPL-2.0",
1493 | "optional": true,
1494 | "os": [
1495 | "linux"
1496 | ],
1497 | "engines": {
1498 | "node": ">= 12.0.0"
1499 | },
1500 | "funding": {
1501 | "type": "opencollective",
1502 | "url": "https://opencollective.com/parcel"
1503 | }
1504 | },
1505 | "node_modules/lightningcss-linux-x64-gnu": {
1506 | "version": "1.30.1",
1507 | "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz",
1508 | "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==",
1509 | "cpu": [
1510 | "x64"
1511 | ],
1512 | "dev": true,
1513 | "license": "MPL-2.0",
1514 | "optional": true,
1515 | "os": [
1516 | "linux"
1517 | ],
1518 | "engines": {
1519 | "node": ">= 12.0.0"
1520 | },
1521 | "funding": {
1522 | "type": "opencollective",
1523 | "url": "https://opencollective.com/parcel"
1524 | }
1525 | },
1526 | "node_modules/lightningcss-linux-x64-musl": {
1527 | "version": "1.30.1",
1528 | "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz",
1529 | "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==",
1530 | "cpu": [
1531 | "x64"
1532 | ],
1533 | "dev": true,
1534 | "license": "MPL-2.0",
1535 | "optional": true,
1536 | "os": [
1537 | "linux"
1538 | ],
1539 | "engines": {
1540 | "node": ">= 12.0.0"
1541 | },
1542 | "funding": {
1543 | "type": "opencollective",
1544 | "url": "https://opencollective.com/parcel"
1545 | }
1546 | },
1547 | "node_modules/lightningcss-win32-arm64-msvc": {
1548 | "version": "1.30.1",
1549 | "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz",
1550 | "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==",
1551 | "cpu": [
1552 | "arm64"
1553 | ],
1554 | "dev": true,
1555 | "license": "MPL-2.0",
1556 | "optional": true,
1557 | "os": [
1558 | "win32"
1559 | ],
1560 | "engines": {
1561 | "node": ">= 12.0.0"
1562 | },
1563 | "funding": {
1564 | "type": "opencollective",
1565 | "url": "https://opencollective.com/parcel"
1566 | }
1567 | },
1568 | "node_modules/lightningcss-win32-x64-msvc": {
1569 | "version": "1.30.1",
1570 | "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz",
1571 | "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==",
1572 | "cpu": [
1573 | "x64"
1574 | ],
1575 | "dev": true,
1576 | "license": "MPL-2.0",
1577 | "optional": true,
1578 | "os": [
1579 | "win32"
1580 | ],
1581 | "engines": {
1582 | "node": ">= 12.0.0"
1583 | },
1584 | "funding": {
1585 | "type": "opencollective",
1586 | "url": "https://opencollective.com/parcel"
1587 | }
1588 | },
1589 | "node_modules/magic-string": {
1590 | "version": "0.30.17",
1591 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
1592 | "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
1593 | "dev": true,
1594 | "license": "MIT",
1595 | "dependencies": {
1596 | "@jridgewell/sourcemap-codec": "^1.5.0"
1597 | }
1598 | },
1599 | "node_modules/minipass": {
1600 | "version": "7.1.2",
1601 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
1602 | "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
1603 | "dev": true,
1604 | "license": "ISC",
1605 | "engines": {
1606 | "node": ">=16 || 14 >=14.17"
1607 | }
1608 | },
1609 | "node_modules/minizlib": {
1610 | "version": "3.0.2",
1611 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz",
1612 | "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==",
1613 | "dev": true,
1614 | "license": "MIT",
1615 | "dependencies": {
1616 | "minipass": "^7.1.2"
1617 | },
1618 | "engines": {
1619 | "node": ">= 18"
1620 | }
1621 | },
1622 | "node_modules/mkdirp": {
1623 | "version": "3.0.1",
1624 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
1625 | "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
1626 | "dev": true,
1627 | "license": "MIT",
1628 | "bin": {
1629 | "mkdirp": "dist/cjs/src/bin.js"
1630 | },
1631 | "engines": {
1632 | "node": ">=10"
1633 | },
1634 | "funding": {
1635 | "url": "https://github.com/sponsors/isaacs"
1636 | }
1637 | },
1638 | "node_modules/nanoid": {
1639 | "version": "3.3.11",
1640 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
1641 | "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
1642 | "funding": [
1643 | {
1644 | "type": "github",
1645 | "url": "https://github.com/sponsors/ai"
1646 | }
1647 | ],
1648 | "license": "MIT",
1649 | "bin": {
1650 | "nanoid": "bin/nanoid.cjs"
1651 | },
1652 | "engines": {
1653 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1654 | }
1655 | },
1656 | "node_modules/next": {
1657 | "version": "15.3.4",
1658 | "resolved": "https://registry.npmjs.org/next/-/next-15.3.4.tgz",
1659 | "integrity": "sha512-mHKd50C+mCjam/gcnwqL1T1vPx/XQNFlXqFIVdgQdVAFY9iIQtY0IfaVflEYzKiqjeA7B0cYYMaCrmAYFjs4rA==",
1660 | "license": "MIT",
1661 | "dependencies": {
1662 | "@next/env": "15.3.4",
1663 | "@swc/counter": "0.1.3",
1664 | "@swc/helpers": "0.5.15",
1665 | "busboy": "1.6.0",
1666 | "caniuse-lite": "^1.0.30001579",
1667 | "postcss": "8.4.31",
1668 | "styled-jsx": "5.1.6"
1669 | },
1670 | "bin": {
1671 | "next": "dist/bin/next"
1672 | },
1673 | "engines": {
1674 | "node": "^18.18.0 || ^19.8.0 || >= 20.0.0"
1675 | },
1676 | "optionalDependencies": {
1677 | "@next/swc-darwin-arm64": "15.3.4",
1678 | "@next/swc-darwin-x64": "15.3.4",
1679 | "@next/swc-linux-arm64-gnu": "15.3.4",
1680 | "@next/swc-linux-arm64-musl": "15.3.4",
1681 | "@next/swc-linux-x64-gnu": "15.3.4",
1682 | "@next/swc-linux-x64-musl": "15.3.4",
1683 | "@next/swc-win32-arm64-msvc": "15.3.4",
1684 | "@next/swc-win32-x64-msvc": "15.3.4",
1685 | "sharp": "^0.34.1"
1686 | },
1687 | "peerDependencies": {
1688 | "@opentelemetry/api": "^1.1.0",
1689 | "@playwright/test": "^1.41.2",
1690 | "babel-plugin-react-compiler": "*",
1691 | "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
1692 | "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
1693 | "sass": "^1.3.0"
1694 | },
1695 | "peerDependenciesMeta": {
1696 | "@opentelemetry/api": {
1697 | "optional": true
1698 | },
1699 | "@playwright/test": {
1700 | "optional": true
1701 | },
1702 | "babel-plugin-react-compiler": {
1703 | "optional": true
1704 | },
1705 | "sass": {
1706 | "optional": true
1707 | }
1708 | }
1709 | },
1710 | "node_modules/next/node_modules/postcss": {
1711 | "version": "8.4.31",
1712 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
1713 | "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
1714 | "funding": [
1715 | {
1716 | "type": "opencollective",
1717 | "url": "https://opencollective.com/postcss/"
1718 | },
1719 | {
1720 | "type": "tidelift",
1721 | "url": "https://tidelift.com/funding/github/npm/postcss"
1722 | },
1723 | {
1724 | "type": "github",
1725 | "url": "https://github.com/sponsors/ai"
1726 | }
1727 | ],
1728 | "license": "MIT",
1729 | "dependencies": {
1730 | "nanoid": "^3.3.6",
1731 | "picocolors": "^1.0.0",
1732 | "source-map-js": "^1.0.2"
1733 | },
1734 | "engines": {
1735 | "node": "^10 || ^12 || >=14"
1736 | }
1737 | },
1738 | "node_modules/node-releases": {
1739 | "version": "2.0.19",
1740 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
1741 | "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
1742 | "dev": true,
1743 | "license": "MIT"
1744 | },
1745 | "node_modules/normalize-range": {
1746 | "version": "0.1.2",
1747 | "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
1748 | "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
1749 | "dev": true,
1750 | "license": "MIT",
1751 | "engines": {
1752 | "node": ">=0.10.0"
1753 | }
1754 | },
1755 | "node_modules/picocolors": {
1756 | "version": "1.1.1",
1757 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
1758 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
1759 | "license": "ISC"
1760 | },
1761 | "node_modules/postcss": {
1762 | "version": "8.5.6",
1763 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
1764 | "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
1765 | "dev": true,
1766 | "funding": [
1767 | {
1768 | "type": "opencollective",
1769 | "url": "https://opencollective.com/postcss/"
1770 | },
1771 | {
1772 | "type": "tidelift",
1773 | "url": "https://tidelift.com/funding/github/npm/postcss"
1774 | },
1775 | {
1776 | "type": "github",
1777 | "url": "https://github.com/sponsors/ai"
1778 | }
1779 | ],
1780 | "license": "MIT",
1781 | "dependencies": {
1782 | "nanoid": "^3.3.11",
1783 | "picocolors": "^1.1.1",
1784 | "source-map-js": "^1.2.1"
1785 | },
1786 | "engines": {
1787 | "node": "^10 || ^12 || >=14"
1788 | }
1789 | },
1790 | "node_modules/postcss-value-parser": {
1791 | "version": "4.2.0",
1792 | "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
1793 | "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
1794 | "dev": true,
1795 | "license": "MIT"
1796 | },
1797 | "node_modules/react": {
1798 | "version": "19.1.0",
1799 | "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
1800 | "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
1801 | "license": "MIT",
1802 | "engines": {
1803 | "node": ">=0.10.0"
1804 | }
1805 | },
1806 | "node_modules/react-dom": {
1807 | "version": "19.1.0",
1808 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
1809 | "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
1810 | "license": "MIT",
1811 | "dependencies": {
1812 | "scheduler": "^0.26.0"
1813 | },
1814 | "peerDependencies": {
1815 | "react": "^19.1.0"
1816 | }
1817 | },
1818 | "node_modules/scheduler": {
1819 | "version": "0.26.0",
1820 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
1821 | "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
1822 | "license": "MIT"
1823 | },
1824 | "node_modules/semver": {
1825 | "version": "7.7.2",
1826 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
1827 | "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
1828 | "license": "ISC",
1829 | "optional": true,
1830 | "bin": {
1831 | "semver": "bin/semver.js"
1832 | },
1833 | "engines": {
1834 | "node": ">=10"
1835 | }
1836 | },
1837 | "node_modules/set-cookie-parser": {
1838 | "version": "2.7.1",
1839 | "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
1840 | "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
1841 | "license": "MIT"
1842 | },
1843 | "node_modules/sharp": {
1844 | "version": "0.34.2",
1845 | "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.2.tgz",
1846 | "integrity": "sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==",
1847 | "hasInstallScript": true,
1848 | "license": "Apache-2.0",
1849 | "optional": true,
1850 | "dependencies": {
1851 | "color": "^4.2.3",
1852 | "detect-libc": "^2.0.4",
1853 | "semver": "^7.7.2"
1854 | },
1855 | "engines": {
1856 | "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
1857 | },
1858 | "funding": {
1859 | "url": "https://opencollective.com/libvips"
1860 | },
1861 | "optionalDependencies": {
1862 | "@img/sharp-darwin-arm64": "0.34.2",
1863 | "@img/sharp-darwin-x64": "0.34.2",
1864 | "@img/sharp-libvips-darwin-arm64": "1.1.0",
1865 | "@img/sharp-libvips-darwin-x64": "1.1.0",
1866 | "@img/sharp-libvips-linux-arm": "1.1.0",
1867 | "@img/sharp-libvips-linux-arm64": "1.1.0",
1868 | "@img/sharp-libvips-linux-ppc64": "1.1.0",
1869 | "@img/sharp-libvips-linux-s390x": "1.1.0",
1870 | "@img/sharp-libvips-linux-x64": "1.1.0",
1871 | "@img/sharp-libvips-linuxmusl-arm64": "1.1.0",
1872 | "@img/sharp-libvips-linuxmusl-x64": "1.1.0",
1873 | "@img/sharp-linux-arm": "0.34.2",
1874 | "@img/sharp-linux-arm64": "0.34.2",
1875 | "@img/sharp-linux-s390x": "0.34.2",
1876 | "@img/sharp-linux-x64": "0.34.2",
1877 | "@img/sharp-linuxmusl-arm64": "0.34.2",
1878 | "@img/sharp-linuxmusl-x64": "0.34.2",
1879 | "@img/sharp-wasm32": "0.34.2",
1880 | "@img/sharp-win32-arm64": "0.34.2",
1881 | "@img/sharp-win32-ia32": "0.34.2",
1882 | "@img/sharp-win32-x64": "0.34.2"
1883 | }
1884 | },
1885 | "node_modules/simple-swizzle": {
1886 | "version": "0.2.2",
1887 | "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
1888 | "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
1889 | "license": "MIT",
1890 | "optional": true,
1891 | "dependencies": {
1892 | "is-arrayish": "^0.3.1"
1893 | }
1894 | },
1895 | "node_modules/source-map-js": {
1896 | "version": "1.2.1",
1897 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
1898 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
1899 | "license": "BSD-3-Clause",
1900 | "engines": {
1901 | "node": ">=0.10.0"
1902 | }
1903 | },
1904 | "node_modules/streamsearch": {
1905 | "version": "1.1.0",
1906 | "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
1907 | "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
1908 | "engines": {
1909 | "node": ">=10.0.0"
1910 | }
1911 | },
1912 | "node_modules/styled-jsx": {
1913 | "version": "5.1.6",
1914 | "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz",
1915 | "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==",
1916 | "license": "MIT",
1917 | "dependencies": {
1918 | "client-only": "0.0.1"
1919 | },
1920 | "engines": {
1921 | "node": ">= 12.0.0"
1922 | },
1923 | "peerDependencies": {
1924 | "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0"
1925 | },
1926 | "peerDependenciesMeta": {
1927 | "@babel/core": {
1928 | "optional": true
1929 | },
1930 | "babel-plugin-macros": {
1931 | "optional": true
1932 | }
1933 | }
1934 | },
1935 | "node_modules/tailwindcss": {
1936 | "version": "4.1.10",
1937 | "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.10.tgz",
1938 | "integrity": "sha512-P3nr6WkvKV/ONsTzj6Gb57sWPMX29EPNPopo7+FcpkQaNsrNpZ1pv8QmrYI2RqEKD7mlGqLnGovlcYnBK0IqUA==",
1939 | "dev": true,
1940 | "license": "MIT"
1941 | },
1942 | "node_modules/tapable": {
1943 | "version": "2.2.2",
1944 | "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz",
1945 | "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==",
1946 | "dev": true,
1947 | "license": "MIT",
1948 | "engines": {
1949 | "node": ">=6"
1950 | }
1951 | },
1952 | "node_modules/tar": {
1953 | "version": "7.4.3",
1954 | "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
1955 | "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==",
1956 | "dev": true,
1957 | "license": "ISC",
1958 | "dependencies": {
1959 | "@isaacs/fs-minipass": "^4.0.0",
1960 | "chownr": "^3.0.0",
1961 | "minipass": "^7.1.2",
1962 | "minizlib": "^3.0.1",
1963 | "mkdirp": "^3.0.1",
1964 | "yallist": "^5.0.0"
1965 | },
1966 | "engines": {
1967 | "node": ">=18"
1968 | }
1969 | },
1970 | "node_modules/tr46": {
1971 | "version": "0.0.3",
1972 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
1973 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
1974 | "license": "MIT",
1975 | "peer": true
1976 | },
1977 | "node_modules/tslib": {
1978 | "version": "2.8.1",
1979 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
1980 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
1981 | "license": "0BSD"
1982 | },
1983 | "node_modules/undici-types": {
1984 | "version": "7.8.0",
1985 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
1986 | "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
1987 | "license": "MIT",
1988 | "peer": true
1989 | },
1990 | "node_modules/update-browserslist-db": {
1991 | "version": "1.1.3",
1992 | "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
1993 | "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
1994 | "dev": true,
1995 | "funding": [
1996 | {
1997 | "type": "opencollective",
1998 | "url": "https://opencollective.com/browserslist"
1999 | },
2000 | {
2001 | "type": "tidelift",
2002 | "url": "https://tidelift.com/funding/github/npm/browserslist"
2003 | },
2004 | {
2005 | "type": "github",
2006 | "url": "https://github.com/sponsors/ai"
2007 | }
2008 | ],
2009 | "license": "MIT",
2010 | "dependencies": {
2011 | "escalade": "^3.2.0",
2012 | "picocolors": "^1.1.1"
2013 | },
2014 | "bin": {
2015 | "update-browserslist-db": "cli.js"
2016 | },
2017 | "peerDependencies": {
2018 | "browserslist": ">= 4.21.0"
2019 | }
2020 | },
2021 | "node_modules/webidl-conversions": {
2022 | "version": "3.0.1",
2023 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
2024 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
2025 | "license": "BSD-2-Clause",
2026 | "peer": true
2027 | },
2028 | "node_modules/whatwg-url": {
2029 | "version": "5.0.0",
2030 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
2031 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
2032 | "license": "MIT",
2033 | "peer": true,
2034 | "dependencies": {
2035 | "tr46": "~0.0.3",
2036 | "webidl-conversions": "^3.0.0"
2037 | }
2038 | },
2039 | "node_modules/ws": {
2040 | "version": "8.18.2",
2041 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz",
2042 | "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==",
2043 | "license": "MIT",
2044 | "peer": true,
2045 | "engines": {
2046 | "node": ">=10.0.0"
2047 | },
2048 | "peerDependencies": {
2049 | "bufferutil": "^4.0.1",
2050 | "utf-8-validate": ">=5.0.2"
2051 | },
2052 | "peerDependenciesMeta": {
2053 | "bufferutil": {
2054 | "optional": true
2055 | },
2056 | "utf-8-validate": {
2057 | "optional": true
2058 | }
2059 | }
2060 | },
2061 | "node_modules/yallist": {
2062 | "version": "5.0.0",
2063 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
2064 | "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
2065 | "dev": true,
2066 | "license": "BlueOak-1.0.0",
2067 | "engines": {
2068 | "node": ">=18"
2069 | }
2070 | }
2071 | }
2072 | }
2073 |
--------------------------------------------------------------------------------