synapse-orch-ai 1.9.0 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/backend/core/config.py +10 -0
- package/backend/core/internal_auth.py +68 -14
- package/backend/core/mcp_client.py +62 -1
- package/backend/core/routes/tools.py +14 -0
- package/backend/core/scale/worker_server_module.py +22 -1
- package/backend/core/server.py +22 -0
- package/frontend-build/.next/BUILD_ID +1 -1
- package/frontend-build/.next/build-manifest.json +3 -3
- package/frontend-build/.next/prerender-manifest.json +3 -3
- package/frontend-build/.next/server/app/_global-error.html +1 -1
- package/frontend-build/.next/server/app/_global-error.rsc +1 -1
- package/frontend-build/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/frontend-build/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/frontend-build/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/frontend-build/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/frontend-build/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/frontend-build/.next/server/app/_not-found.html +1 -1
- package/frontend-build/.next/server/app/_not-found.rsc +1 -1
- package/frontend-build/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/frontend-build/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/frontend-build/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/frontend-build/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/frontend-build/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/frontend-build/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/frontend-build/.next/server/app/index.html +1 -1
- package/frontend-build/.next/server/app/index.rsc +1 -1
- package/frontend-build/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/frontend-build/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/frontend-build/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/frontend-build/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/frontend-build/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/frontend-build/.next/server/app/login.html +1 -1
- package/frontend-build/.next/server/app/login.rsc +1 -1
- package/frontend-build/.next/server/app/login.segments/_full.segment.rsc +1 -1
- package/frontend-build/.next/server/app/login.segments/_head.segment.rsc +1 -1
- package/frontend-build/.next/server/app/login.segments/_index.segment.rsc +1 -1
- package/frontend-build/.next/server/app/login.segments/_tree.segment.rsc +1 -1
- package/frontend-build/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
- package/frontend-build/.next/server/app/login.segments/login.segment.rsc +1 -1
- package/frontend-build/.next/server/middleware-build-manifest.js +3 -3
- package/frontend-build/.next/server/pages/404.html +1 -1
- package/frontend-build/.next/server/pages/500.html +1 -1
- package/frontend-build/.next/server/server-reference-manifest.js +1 -1
- package/frontend-build/.next/server/server-reference-manifest.json +1 -1
- package/package.json +1 -1
- /package/frontend-build/.next/static/{08oDqCbK0BRht0JB9AgpU → sxSQKRDxOSif09kARGRDM}/_buildManifest.js +0 -0
- /package/frontend-build/.next/static/{08oDqCbK0BRht0JB9AgpU → sxSQKRDxOSif09kARGRDM}/_clientMiddlewareManifest.js +0 -0
- /package/frontend-build/.next/static/{08oDqCbK0BRht0JB9AgpU → sxSQKRDxOSif09kARGRDM}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -64,6 +64,8 @@ docker run -d \
|
|
|
64
64
|
|
|
65
65
|
Then open `http://localhost:3000`. See the [Docker guide](https://docs.synapseorch.com/getting-started/installation#docker) in the docs for custom ports and environment variable configuration.
|
|
66
66
|
|
|
67
|
+
> **Security:** publish only the frontend port `3000` — the backend (`8765`) serves an internal API and should not be exposed on `0.0.0.0` (docker-compose binds it to `127.0.0.1`). The container auto-generates a shared internal token so that surface is authenticated by default. For any network-reachable deployment, enable **login** (Settings → Security) and/or set `allow_stdio_mcp=false`, since registering a stdio MCP server launches local commands.
|
|
68
|
+
|
|
67
69
|
### Upgrading
|
|
68
70
|
|
|
69
71
|
| Install method | Upgrade command |
|
|
@@ -73,6 +75,8 @@ Then open `http://localhost:3000`. See the [Docker guide](https://docs.synapseor
|
|
|
73
75
|
| npm | `npm update -g synapse-orch-ai` |
|
|
74
76
|
| Docker | `docker pull synapseorchai/synapse-ai:latest` |
|
|
75
77
|
|
|
78
|
+
> **Upgrade note (security hardening):** the backend now auto-generates a shared internal token and, under docker-compose, binds its port to `127.0.0.1` by default. The UI and its API are unaffected (the frontend proxies the backend internally). If you previously called the **backend directly** on `:8765` (e.g. external API clients), either point them at the frontend instead — `http://host:3000/api/v1|v2/...` — or set `SYNAPSE_BACKEND_BIND=0.0.0.0` in `.env` to keep publishing `:8765`.
|
|
79
|
+
|
|
76
80
|
---
|
|
77
81
|
|
|
78
82
|
## Scale Mode
|
package/backend/core/config.py
CHANGED
|
@@ -108,6 +108,16 @@ def load_settings():
|
|
|
108
108
|
"messaging_enabled": True,
|
|
109
109
|
"embed_code": False,
|
|
110
110
|
"bash_allowed_dirs": [],
|
|
111
|
+
# ── MCP stdio server registration (security) ──
|
|
112
|
+
# stdio MCP servers launch local OS processes (npx/uvx/python/…). This is
|
|
113
|
+
# a powerful, admin-only capability. Allowed by default for local
|
|
114
|
+
# single-user use, but force-disabled in scale mode (multi-tenant /
|
|
115
|
+
# network-exposed) — see stdio_mcp_allowed(). See GHSA-3j67-x3j8-r32x.
|
|
116
|
+
"allow_stdio_mcp": True,
|
|
117
|
+
# Optional hardening: when non-empty, only these command basenames may be
|
|
118
|
+
# registered as stdio servers. Empty = allow any command in PATH.
|
|
119
|
+
# Recommended for exposed UIs: ["npx","uvx","uv","node","python","python3","docker"]
|
|
120
|
+
"mcp_command_allowlist": [],
|
|
111
121
|
"login_enabled": False,
|
|
112
122
|
"login_username": "",
|
|
113
123
|
"login_password_hash": "",
|
|
@@ -10,9 +10,23 @@ that try to hit /api/settings, /api/agents, etc. directly will get 403.
|
|
|
10
10
|
Rules:
|
|
11
11
|
- /api/v1/*, /api/v2/*, ... → SKIP (external versioned API; uses API key auth instead)
|
|
12
12
|
- /docs, /openapi.json, /redoc → SKIP (FastAPI docs)
|
|
13
|
-
- /
|
|
14
|
-
- /api
|
|
15
|
-
- If SYNAPSE_INTERNAL_TOKEN is not set →
|
|
13
|
+
- /auth/* → SKIP (OAuth redirects; browser-navigated, cannot carry a header)
|
|
14
|
+
- /api/*, /chat* → REQUIRE X-Synapse-Internal header
|
|
15
|
+
- If SYNAPSE_INTERNAL_TOKEN is not set → LOOPBACK-ONLY: allow requests whose
|
|
16
|
+
direct peer is 127.0.0.1/::1 (local dev, same-container proxy) and 403 any
|
|
17
|
+
remote caller. This closes the unauthenticated-RCE hole on network-exposed
|
|
18
|
+
token-less deployments (GHSA-3j67-x3j8-r32x). Docker images auto-generate a
|
|
19
|
+
token (docker/entrypoint.sh) so they never rely on this fallback.
|
|
20
|
+
|
|
21
|
+
Why /chat is gated even though it is not under /api/:
|
|
22
|
+
POST /chat and /chat/stream (core/routes/chat.py) run the full ReAct loop with
|
|
23
|
+
the complete tool surface — bash, execute_python, SQL, every MCP server. They
|
|
24
|
+
are mounted at the root, so the "not /api/ → skip" rule let any caller who
|
|
25
|
+
could reach the port drive them with no credentials at all.
|
|
26
|
+
The public, externally-authenticated chat API is /api/v1/chat (require_api_key)
|
|
27
|
+
— a different route. Root /chat is reached only by the Next.js route handler
|
|
28
|
+
(frontend/src/app/api/chat/**), which already sends X-Synapse-Internal via
|
|
29
|
+
backendHeaders(), so gating it is transparent to the UI.
|
|
16
30
|
"""
|
|
17
31
|
import os
|
|
18
32
|
import re
|
|
@@ -21,6 +35,27 @@ from fastapi import Request
|
|
|
21
35
|
from fastapi.responses import JSONResponse
|
|
22
36
|
from starlette.middleware.base import BaseHTTPMiddleware
|
|
23
37
|
|
|
38
|
+
# Direct-peer addresses treated as local. We deliberately check request.client
|
|
39
|
+
# (the immediate TCP peer), NOT X-Forwarded-For, which is attacker-spoofable.
|
|
40
|
+
_LOOPBACK_HOSTS = frozenset({"127.0.0.1", "::1", "localhost"})
|
|
41
|
+
|
|
42
|
+
# Root-mounted routes that are internal despite not living under /api/.
|
|
43
|
+
# Matched as exact path or path-prefixed segment so /chat and /chat/stream are
|
|
44
|
+
# both covered while an unrelated future route like /chatbot-docs is not.
|
|
45
|
+
_INTERNAL_ROOT_PREFIXES = ("/chat",)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _is_loopback(request: Request) -> bool:
|
|
49
|
+
client = request.client
|
|
50
|
+
return bool(client) and client.host in _LOOPBACK_HOSTS
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _is_internal_root_route(path: str) -> bool:
|
|
54
|
+
return any(
|
|
55
|
+
path == prefix or path.startswith(prefix + "/")
|
|
56
|
+
for prefix in _INTERNAL_ROOT_PREFIXES
|
|
57
|
+
)
|
|
58
|
+
|
|
24
59
|
|
|
25
60
|
class InternalTokenMiddleware(BaseHTTPMiddleware):
|
|
26
61
|
"""Block direct access to internal /api/* routes without the internal token."""
|
|
@@ -32,29 +67,48 @@ class InternalTokenMiddleware(BaseHTTPMiddleware):
|
|
|
32
67
|
async def dispatch(self, request: Request, call_next):
|
|
33
68
|
path = request.url.path
|
|
34
69
|
|
|
35
|
-
#
|
|
36
|
-
|
|
37
|
-
|
|
70
|
+
# ── Skips run FIRST, independent of the internal token ──────────────────
|
|
71
|
+
# These routes are either externally authenticated (versioned API → API
|
|
72
|
+
# key) or intentionally public, so they must stay reachable even when the
|
|
73
|
+
# token is unset/loopback-gated. This lets external clients hit the open
|
|
74
|
+
# /api/v1|v2 API through the frontend proxy (or a directly-published
|
|
75
|
+
# backend port) without the internal frontend token.
|
|
38
76
|
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
# /api/v<N> prefix so future versions are exempt automatically.
|
|
77
|
+
# External versioned API (v1, v2, ...) — uses require_api_key, not the
|
|
78
|
+
# internal token. Match any /api/v<N> prefix so future versions are exempt.
|
|
42
79
|
if re.match(r"^/api/v\d+(/|$)", path):
|
|
43
80
|
return await call_next(request)
|
|
44
81
|
|
|
45
|
-
#
|
|
82
|
+
# MCP OAuth callback — called by external OAuth providers, not the frontend.
|
|
46
83
|
if path == "/api/mcp/oauth/callback":
|
|
47
84
|
return await call_next(request)
|
|
48
85
|
|
|
49
|
-
#
|
|
86
|
+
# FastAPI docs.
|
|
50
87
|
if path in ("/docs", "/openapi.json", "/redoc"):
|
|
51
88
|
return await call_next(request)
|
|
52
89
|
|
|
53
|
-
#
|
|
54
|
-
|
|
90
|
+
# Non-API routes (auth redirects, health, websocket, etc.) — EXCEPT the
|
|
91
|
+
# root-mounted internal routes, which are gated below. /chat drives the
|
|
92
|
+
# full agent tool surface and must never be reachable unauthenticated.
|
|
93
|
+
if not path.startswith("/api/") and not _is_internal_root_route(path):
|
|
55
94
|
return await call_next(request)
|
|
56
95
|
|
|
57
|
-
#
|
|
96
|
+
# ── Internal surface — /api/* plus the root-mounted internal routes.
|
|
97
|
+
# The sensitive routes (settings, agents, mcp/servers, chat, …) that rely
|
|
98
|
+
# on the internal token for protection ──────────────────────────────────
|
|
99
|
+
if not self.token:
|
|
100
|
+
# No token configured → permissive ONLY for loopback callers. A remote
|
|
101
|
+
# client hitting a token-less backend directly is rejected, so the
|
|
102
|
+
# internal surface is never exposed unauthenticated over the network
|
|
103
|
+
# even in a misconfigured/bare-metal deployment (GHSA-3j67-x3j8-r32x).
|
|
104
|
+
if _is_loopback(request):
|
|
105
|
+
return await call_next(request)
|
|
106
|
+
return JSONResponse(
|
|
107
|
+
status_code=403,
|
|
108
|
+
content={"detail": "Forbidden: internal token not configured"},
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
# Token configured → require the matching header.
|
|
58
112
|
provided = request.headers.get("X-Synapse-Internal", "")
|
|
59
113
|
if provided != self.token:
|
|
60
114
|
return JSONResponse(
|
|
@@ -39,13 +39,44 @@ from mcp.client.stdio import stdio_client
|
|
|
39
39
|
from mcp.client.streamable_http import streamable_http_client
|
|
40
40
|
from mcp.shared.auth import OAuthClientInformationFull, OAuthClientMetadata, OAuthToken
|
|
41
41
|
|
|
42
|
-
from core.config import DATA_DIR, MCP_SESSION_READ_TIMEOUT
|
|
42
|
+
from core.config import DATA_DIR, MCP_SESSION_READ_TIMEOUT, load_settings
|
|
43
43
|
import core.mcp_oauth_state as oauth_state
|
|
44
44
|
|
|
45
45
|
# ── Constants ──────────────────────────────────────────────────────────────────
|
|
46
46
|
|
|
47
47
|
_SESSION_READ_TIMEOUT = timedelta(seconds=MCP_SESSION_READ_TIMEOUT)
|
|
48
48
|
|
|
49
|
+
|
|
50
|
+
# ── stdio MCP registration policy (security) ────────────────────────────────────
|
|
51
|
+
# stdio MCP servers launch arbitrary local OS processes (npx/uvx/python -c/…),
|
|
52
|
+
# which is the whole point of the transport but also an RCE-shaped capability.
|
|
53
|
+
# These helpers gate every path that can spawn one. See GHSA-3j67-x3j8-r32x.
|
|
54
|
+
|
|
55
|
+
def stdio_mcp_allowed() -> bool:
|
|
56
|
+
"""Whether stdio MCP servers may be registered/spawned on this deployment.
|
|
57
|
+
|
|
58
|
+
Disabled in scale mode (multi-tenant / network-exposed) and toggleable via
|
|
59
|
+
the ``allow_stdio_mcp`` setting. Fails open only if settings are unreadable,
|
|
60
|
+
to preserve local behaviour when config is unavailable.
|
|
61
|
+
"""
|
|
62
|
+
try:
|
|
63
|
+
s = load_settings()
|
|
64
|
+
except Exception:
|
|
65
|
+
return True
|
|
66
|
+
if s.get("scale_mode_enabled"):
|
|
67
|
+
return False
|
|
68
|
+
return bool(s.get("allow_stdio_mcp", True))
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def check_stdio_command_allowed(command: str) -> None:
|
|
72
|
+
"""Enforce the optional ``mcp_command_allowlist`` (empty list = allow any)."""
|
|
73
|
+
try:
|
|
74
|
+
allowlist = load_settings().get("mcp_command_allowlist") or []
|
|
75
|
+
except Exception:
|
|
76
|
+
allowlist = []
|
|
77
|
+
if allowlist and os.path.basename(command) not in allowlist:
|
|
78
|
+
raise ValueError(f"Command '{command}' is not in the allowed MCP command list.")
|
|
79
|
+
|
|
49
80
|
MCP_SERVERS_FILE = os.path.join(DATA_DIR, "mcp_servers.json")
|
|
50
81
|
MCP_TOKENS_DIR = os.path.join(DATA_DIR, "mcp_tokens")
|
|
51
82
|
|
|
@@ -231,6 +262,24 @@ class MCPClientManager:
|
|
|
231
262
|
print(f"Skipping '{name}': no command")
|
|
232
263
|
return None
|
|
233
264
|
|
|
265
|
+
# Gate at the sink, not only at the callers. Spawning a stdio server is
|
|
266
|
+
# arbitrary local command execution, so the check belongs on the code
|
|
267
|
+
# path that actually spawns — otherwise any new (or overlooked) call site
|
|
268
|
+
# silently bypasses it. POST /api/import did exactly that: it wrote a
|
|
269
|
+
# bundle's MCP configs to disk and called this method directly, skipping
|
|
270
|
+
# the add_server/reconnect_server/connect_all gates entirely.
|
|
271
|
+
if not stdio_mcp_allowed():
|
|
272
|
+
print(f"[MCP] Refusing to spawn stdio server '{name}': "
|
|
273
|
+
f"stdio MCP servers are disabled on this deployment.")
|
|
274
|
+
self._set_status(name, "disconnected")
|
|
275
|
+
return None
|
|
276
|
+
try:
|
|
277
|
+
check_stdio_command_allowed(command)
|
|
278
|
+
except ValueError as e:
|
|
279
|
+
print(f"[MCP] Refusing to spawn stdio server '{name}': {e}")
|
|
280
|
+
self._set_status(name, "disconnected")
|
|
281
|
+
return None
|
|
282
|
+
|
|
234
283
|
env = os.environ.copy()
|
|
235
284
|
env.update(env_vars)
|
|
236
285
|
|
|
@@ -432,6 +481,13 @@ class MCPClientManager:
|
|
|
432
481
|
|
|
433
482
|
server_type = config.get("server_type", "stdio")
|
|
434
483
|
if server_type == "stdio":
|
|
484
|
+
# Do not re-spawn persisted stdio servers when the capability is
|
|
485
|
+
# disabled — otherwise a saved (possibly malicious) config would
|
|
486
|
+
# execute on every boot. See GHSA-3j67-x3j8-r32x.
|
|
487
|
+
if not stdio_mcp_allowed():
|
|
488
|
+
print(f"[MCP] Skipping stdio server '{name}': stdio MCP disabled on this deployment.")
|
|
489
|
+
self._set_status(name, "disabled")
|
|
490
|
+
continue
|
|
435
491
|
session = await self.connect_stdio_server(config)
|
|
436
492
|
elif config.get("token"):
|
|
437
493
|
session = await self.connect_remote_server(config)
|
|
@@ -472,8 +528,11 @@ class MCPClientManager:
|
|
|
472
528
|
new_config: Dict[str, Any] = {"name": name, "label": label or name, "server_type": server_type, "status": "disconnected"}
|
|
473
529
|
|
|
474
530
|
if server_type == "stdio":
|
|
531
|
+
if not stdio_mcp_allowed():
|
|
532
|
+
raise PermissionError("stdio MCP server registration is disabled on this deployment.")
|
|
475
533
|
if not command:
|
|
476
534
|
raise ValueError("Command is required for stdio servers.")
|
|
535
|
+
check_stdio_command_allowed(command)
|
|
477
536
|
if shutil.which(command) is None:
|
|
478
537
|
hints = {"uvx": "Install uv: curl -LsSf https://astral.sh/uv/install.sh | sh",
|
|
479
538
|
"npx": "Install Node.js/npm."}
|
|
@@ -527,6 +586,8 @@ class MCPClientManager:
|
|
|
527
586
|
|
|
528
587
|
server_type = config.get("server_type", "stdio")
|
|
529
588
|
if server_type == "stdio":
|
|
589
|
+
if not stdio_mcp_allowed():
|
|
590
|
+
raise PermissionError("stdio MCP servers are disabled on this deployment.")
|
|
530
591
|
session = await self.connect_stdio_server(config)
|
|
531
592
|
elif config.get("token"):
|
|
532
593
|
session = await self.connect_remote_server(config)
|
|
@@ -407,6 +407,16 @@ async def list_mcp_servers():
|
|
|
407
407
|
@router.post("/api/mcp/servers")
|
|
408
408
|
async def add_mcp_server(req: AddMCPServerRequest):
|
|
409
409
|
import core.server as _server
|
|
410
|
+
from core.mcp_client import stdio_mcp_allowed
|
|
411
|
+
|
|
412
|
+
# stdio MCP servers launch arbitrary local commands. Gate that capability up
|
|
413
|
+
# front (before touching the manager) so it is enforced in scale mode / when
|
|
414
|
+
# explicitly disabled, independent of auth. See GHSA-3j67-x3j8-r32x.
|
|
415
|
+
if req.server_type == "stdio" and not stdio_mcp_allowed():
|
|
416
|
+
raise HTTPException(
|
|
417
|
+
status_code=403,
|
|
418
|
+
detail="stdio MCP server registration is disabled on this deployment.",
|
|
419
|
+
)
|
|
410
420
|
if not _server.mcp_manager:
|
|
411
421
|
raise HTTPException(status_code=500, detail="MCP Manager not initialized")
|
|
412
422
|
try:
|
|
@@ -443,6 +453,8 @@ async def add_mcp_server(req: AddMCPServerRequest):
|
|
|
443
453
|
"connected": connected,
|
|
444
454
|
"message": "Server connected and saved." if connected else "Config saved. Use Retry to reconnect.",
|
|
445
455
|
}
|
|
456
|
+
except PermissionError as e:
|
|
457
|
+
raise HTTPException(status_code=403, detail=str(e))
|
|
446
458
|
except Exception as e:
|
|
447
459
|
raise HTTPException(status_code=400, detail=str(e))
|
|
448
460
|
|
|
@@ -477,6 +489,8 @@ async def reconnect_mcp_server(name: str):
|
|
|
477
489
|
pass
|
|
478
490
|
|
|
479
491
|
return {"status": "failed", "connected": False, "needs_oauth": False, "message": "Could not reconnect."}
|
|
492
|
+
except PermissionError as e:
|
|
493
|
+
raise HTTPException(status_code=403, detail=str(e))
|
|
480
494
|
except Exception as e:
|
|
481
495
|
raise HTTPException(status_code=400, detail=str(e))
|
|
482
496
|
|
|
@@ -205,13 +205,34 @@ def _get_native_mcp_servers(tools_dir: Path, backend_root: Path) -> dict:
|
|
|
205
205
|
|
|
206
206
|
|
|
207
207
|
def _build_stdio_mcp_params(cfg: dict):
|
|
208
|
-
"""Build StdioServerParameters from a saved mcp_servers.json config dict.
|
|
208
|
+
"""Build StdioServerParameters from a saved mcp_servers.json config dict.
|
|
209
|
+
|
|
210
|
+
Returns None when this deployment must not spawn user-supplied stdio servers.
|
|
211
|
+
Workers run in scale mode, where ``stdio_mcp_allowed()`` is force-disabled —
|
|
212
|
+
this is a second, independent spawn sink from
|
|
213
|
+
``MCPClientManager.connect_stdio_server``, so it needs its own gate rather
|
|
214
|
+
than inheriting one.
|
|
215
|
+
"""
|
|
209
216
|
import shlex
|
|
210
217
|
from mcp import StdioServerParameters
|
|
218
|
+
from core.mcp_client import stdio_mcp_allowed, check_stdio_command_allowed
|
|
211
219
|
|
|
212
220
|
command = cfg.get("command", "")
|
|
213
221
|
if not command:
|
|
214
222
|
return None
|
|
223
|
+
|
|
224
|
+
if not stdio_mcp_allowed():
|
|
225
|
+
print(f"[worker] Refusing to spawn stdio MCP server "
|
|
226
|
+
f"'{cfg.get('name', '?')}': stdio MCP is disabled on this deployment.",
|
|
227
|
+
flush=True)
|
|
228
|
+
return None
|
|
229
|
+
try:
|
|
230
|
+
check_stdio_command_allowed(command)
|
|
231
|
+
except ValueError as e:
|
|
232
|
+
print(f"[worker] Refusing to spawn stdio MCP server "
|
|
233
|
+
f"'{cfg.get('name', '?')}': {e}", flush=True)
|
|
234
|
+
return None
|
|
235
|
+
|
|
215
236
|
args_raw = cfg.get("args", [])
|
|
216
237
|
# Support both list and space-separated string for args
|
|
217
238
|
if isinstance(args_raw, str):
|
package/backend/core/server.py
CHANGED
|
@@ -374,10 +374,32 @@ mcp_manager: Optional[MCPClientManager] = None
|
|
|
374
374
|
messaging_manager: Any = None # MessagingManager (set in lifespan if enabled)
|
|
375
375
|
schedule_manager: Any = None # ScheduleManager (set in lifespan)
|
|
376
376
|
|
|
377
|
+
def _log_security_posture() -> None:
|
|
378
|
+
"""Warn loudly when the backend starts with the exact weak-default posture
|
|
379
|
+
that GHSA-3j67-x3j8-r32x exploits: no internal token, login disabled, and
|
|
380
|
+
stdio MCP registration allowed. Docker images auto-generate a token, so this
|
|
381
|
+
normally only fires for a misconfigured bare-metal deployment."""
|
|
382
|
+
try:
|
|
383
|
+
from core.mcp_client import stdio_mcp_allowed
|
|
384
|
+
no_token = not os.getenv("SYNAPSE_INTERNAL_TOKEN", "")
|
|
385
|
+
login_off = not _settings.get("login_enabled")
|
|
386
|
+
if no_token and login_off and stdio_mcp_allowed():
|
|
387
|
+
print(
|
|
388
|
+
"[SECURITY] No SYNAPSE_INTERNAL_TOKEN set and login is disabled. "
|
|
389
|
+
"Remote /api/* access is refused (loopback-only), but if this backend "
|
|
390
|
+
"is reachable through the frontend without login, stdio MCP registration "
|
|
391
|
+
"can execute local commands. Enable login and/or set allow_stdio_mcp=false "
|
|
392
|
+
"for any network-reachable deployment. See GHSA-3j67-x3j8-r32x."
|
|
393
|
+
)
|
|
394
|
+
except Exception:
|
|
395
|
+
pass
|
|
396
|
+
|
|
397
|
+
|
|
377
398
|
@asynccontextmanager
|
|
378
399
|
async def lifespan(app: FastAPI):
|
|
379
400
|
global exit_stack
|
|
380
401
|
print("Starting Multi-Agent Orchestrator...")
|
|
402
|
+
_log_security_posture()
|
|
381
403
|
exit_stack = AsyncExitStack()
|
|
382
404
|
|
|
383
405
|
if _settings.get("coding_agent_enabled"):
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
sxSQKRDxOSif09kARGRDM
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
"static/chunks/03~yq9q893hmn.js"
|
|
8
8
|
],
|
|
9
9
|
"lowPriorityFiles": [
|
|
10
|
-
"static/
|
|
11
|
-
"static/
|
|
12
|
-
"static/
|
|
10
|
+
"static/sxSQKRDxOSif09kARGRDM/_buildManifest.js",
|
|
11
|
+
"static/sxSQKRDxOSif09kARGRDM/_ssgManifest.js",
|
|
12
|
+
"static/sxSQKRDxOSif09kARGRDM/_clientMiddlewareManifest.js"
|
|
13
13
|
],
|
|
14
14
|
"rootMainFiles": [
|
|
15
15
|
"static/chunks/0qmh881w772ef.js",
|
|
@@ -131,8 +131,8 @@
|
|
|
131
131
|
"dynamicRoutes": {},
|
|
132
132
|
"notFoundRoutes": [],
|
|
133
133
|
"preview": {
|
|
134
|
-
"previewModeId": "
|
|
135
|
-
"previewModeSigningKey": "
|
|
136
|
-
"previewModeEncryptionKey": "
|
|
134
|
+
"previewModeId": "0a0cd9b6367b1d38744ba4d875f5af6f",
|
|
135
|
+
"previewModeSigningKey": "d2df4e06ea65535e529d02adfdbc8e309b415e197106243591e39b19b6bf40f4",
|
|
136
|
+
"previewModeEncryptionKey": "db623dd16ac0913b70f9649c1771f7b7de3bbf9de17d87b49d8e95c52add3cb0"
|
|
137
137
|
}
|
|
138
138
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/0qmh881w772ef.js"/><script src="/_next/static/chunks/02i7dfk78~t~2.js" async=""></script><script src="/_next/static/chunks/0c7h~x4_chf35.js" async=""></script><script src="/_next/static/chunks/00xhsd~k-wxkl.js" async=""></script><script src="/_next/static/chunks/turbopack-09lztqg9--eu..js" async=""></script><script src="/_next/static/chunks/01xlw8hd842-c.js" async=""></script><script src="/_next/static/chunks/0m92kh92cfh_..js" async=""></script><meta name="next-size-adjust" content=""/><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/03~yq9q893hmn.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/0qmh881w772ef.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"default\"]\n4:I[97367,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[97367,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"ViewportBoundary\"]\na:I[97367,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"MetadataBoundary\"]\nc:I[68027,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"default\",1]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"
|
|
1
|
+
<!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/0qmh881w772ef.js"/><script src="/_next/static/chunks/02i7dfk78~t~2.js" async=""></script><script src="/_next/static/chunks/0c7h~x4_chf35.js" async=""></script><script src="/_next/static/chunks/00xhsd~k-wxkl.js" async=""></script><script src="/_next/static/chunks/turbopack-09lztqg9--eu..js" async=""></script><script src="/_next/static/chunks/01xlw8hd842-c.js" async=""></script><script src="/_next/static/chunks/0m92kh92cfh_..js" async=""></script><meta name="next-size-adjust" content=""/><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/03~yq9q893hmn.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/0qmh881w772ef.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"default\"]\n4:I[97367,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[97367,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"ViewportBoundary\"]\na:I[97367,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"MetadataBoundary\"]\nc:I[68027,[\"/_next/static/chunks/01xlw8hd842-c.js\",\"/_next/static/chunks/0m92kh92cfh_..js\"],\"default\",1]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"sxSQKRDxOSif09kARGRDM\"}\n"])</script><script>self.__next_f.push([1,"d:[]\n7:\"$Wd\"\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\nb:[]\n"])</script></body></html>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
8:I[97367,["/_next/static/chunks/01xlw8hd842-c.js","/_next/static/chunks/0m92kh92cfh_..js"],"ViewportBoundary"]
|
|
7
7
|
a:I[97367,["/_next/static/chunks/01xlw8hd842-c.js","/_next/static/chunks/0m92kh92cfh_..js"],"MetadataBoundary"]
|
|
8
8
|
c:I[68027,["/_next/static/chunks/01xlw8hd842-c.js","/_next/static/chunks/0m92kh92cfh_..js"],"default",1]
|
|
9
|
-
0:{"P":null,"c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,null]},null,false,"$@7"],["$","$1","h",{"children":[null,["$","$L8",null,{"children":"$L9"}],["$","div",null,{"hidden":true,"children":["$","$La",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$Lb"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$c",[]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"
|
|
9
|
+
0:{"P":null,"c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,null]},null,false,"$@7"],["$","$1","h",{"children":[null,["$","$L8",null,{"children":"$L9"}],["$","div",null,{"hidden":true,"children":["$","$La",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$Lb"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$c",[]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"sxSQKRDxOSif09kARGRDM"}
|
|
10
10
|
d:[]
|
|
11
11
|
7:"$Wd"
|
|
12
12
|
9:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
1:"$Sreact.fragment"
|
|
2
2
|
2:I[97367,["/_next/static/chunks/01xlw8hd842-c.js","/_next/static/chunks/0m92kh92cfh_..js"],"OutletBoundary"]
|
|
3
3
|
3:"$Sreact.suspense"
|
|
4
|
-
0:{"rsc":["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L2",null,{"children":["$","$3",null,{"name":"Next.MetadataOutlet","children":"$@4"}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"
|
|
4
|
+
0:{"rsc":["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L2",null,{"children":["$","$3",null,{"name":"Next.MetadataOutlet","children":"$@4"}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"sxSQKRDxOSif09kARGRDM"}
|
|
5
5
|
4:null
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
8:I[97367,["/_next/static/chunks/01xlw8hd842-c.js","/_next/static/chunks/0m92kh92cfh_..js"],"ViewportBoundary"]
|
|
7
7
|
a:I[97367,["/_next/static/chunks/01xlw8hd842-c.js","/_next/static/chunks/0m92kh92cfh_..js"],"MetadataBoundary"]
|
|
8
8
|
c:I[68027,["/_next/static/chunks/01xlw8hd842-c.js","/_next/static/chunks/0m92kh92cfh_..js"],"default",1]
|
|
9
|
-
0:{"P":null,"c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,null]},null,false,"$@7"],["$","$1","h",{"children":[null,["$","$L8",null,{"children":"$L9"}],["$","div",null,{"hidden":true,"children":["$","$La",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$Lb"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$c",[]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"
|
|
9
|
+
0:{"P":null,"c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,null]},null,false,"$@7"],["$","$1","h",{"children":[null,["$","$L8",null,{"children":"$L9"}],["$","div",null,{"hidden":true,"children":["$","$La",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$Lb"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$c",[]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"sxSQKRDxOSif09kARGRDM"}
|
|
10
10
|
d:[]
|
|
11
11
|
7:"$Wd"
|
|
12
12
|
9:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
2:I[97367,["/_next/static/chunks/01xlw8hd842-c.js","/_next/static/chunks/0m92kh92cfh_..js"],"ViewportBoundary"]
|
|
3
3
|
3:I[97367,["/_next/static/chunks/01xlw8hd842-c.js","/_next/static/chunks/0m92kh92cfh_..js"],"MetadataBoundary"]
|
|
4
4
|
4:"$Sreact.suspense"
|
|
5
|
-
0:{"rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"
|
|
5
|
+
0:{"rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"sxSQKRDxOSif09kARGRDM"}
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
2:I[39756,["/_next/static/chunks/01xlw8hd842-c.js","/_next/static/chunks/0m92kh92cfh_..js"],"default"]
|
|
3
3
|
3:I[37457,["/_next/static/chunks/01xlw8hd842-c.js","/_next/static/chunks/0m92kh92cfh_..js"],"default"]
|
|
4
4
|
4:[]
|
|
5
|
-
0:{"rsc":["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","template":["$","$L3",null,{}]}]]}],"isPartial":false,"staleTime":300,"varyParams":"$W4","buildId":"
|
|
5
|
+
0:{"rsc":["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","template":["$","$L3",null,{}]}]]}],"isPartial":false,"staleTime":300,"varyParams":"$W4","buildId":"sxSQKRDxOSif09kARGRDM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0:{"tree":{"name":"","param":null,"prefetchHints":0,"slots":{"children":{"name":"__PAGE__","param":null,"prefetchHints":0,"slots":null}}},"staleTime":300,"buildId":"
|
|
1
|
+
0:{"tree":{"name":"","param":null,"prefetchHints":0,"slots":{"children":{"name":"__PAGE__","param":null,"prefetchHints":0,"slots":null}}},"staleTime":300,"buildId":"sxSQKRDxOSif09kARGRDM"}
|