@meridiona/meridian-darwin-arm64 1.4.5 → 1.6.0
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/.env.example +24 -8
- package/VERSION +1 -1
- package/bin/meridian +0 -0
- package/package.json +1 -1
- package/services/agents/_prompts.py +21 -13
- package/services/agents/run_task_linker_mlx.py +10 -6
- package/services/pyproject.toml +1 -1
- package/services/skills/activity/task-classifier/SKILL.md +14 -12
- package/services/tests/evals/classify_session.py +122 -0
- package/services/tests/evals/metrics.py +34 -5
- package/ui/.next/BUILD_ID +1 -1
- package/ui/.next/build-manifest.json +3 -3
- package/ui/.next/prerender-manifest.json +3 -3
- package/ui/.next/server/app/_global-error.html +1 -1
- package/ui/.next/server/app/_global-error.rsc +1 -1
- package/ui/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/ui/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/ui/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/ui/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/ui/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/ui/.next/server/app/_not-found.html +1 -1
- package/ui/.next/server/app/_not-found.rsc +1 -1
- package/ui/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/ui/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/ui/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/ui/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/ui/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/ui/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/ui/.next/server/app/index.html +1 -1
- package/ui/.next/server/app/index.rsc +2 -2
- package/ui/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/ui/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/ui/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/ui/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/ui/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/ui/.next/server/app/page/react-loadable-manifest.json +1 -1
- package/ui/.next/server/app/page_client-reference-manifest.js +1 -1
- package/ui/.next/server/app/settings.html +1 -1
- package/ui/.next/server/app/settings.rsc +1 -1
- package/ui/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- package/ui/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/ui/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/ui/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/ui/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
- package/ui/.next/server/app/settings.segments/settings.segment.rsc +1 -1
- package/ui/.next/server/chunks/[root-of-the-server]__0yrr4w1._.js +4 -3
- package/ui/.next/server/middleware-build-manifest.js +3 -3
- package/ui/.next/server/pages/404.html +1 -1
- package/ui/.next/server/pages/500.html +1 -1
- package/ui/.next/server/server-reference-manifest.js +1 -1
- package/ui/.next/server/server-reference-manifest.json +1 -1
- package/ui/.next/static/chunks/16f557ymkx721.js +1 -0
- package/ui/.next/static/chunks/{0_mff2ov-3xrz.js → 17.0_3q.gw7x2.js} +1 -1
- package/ui/package.json +1 -1
- package/ui/.next/static/chunks/0h14_sgzq5gl7.js +0 -1
- /package/ui/.next/static/{4Kes2MbQQcEg1Xxh2Wka2 → HSR1kI5kYuEYQoBEIrPgc}/_buildManifest.js +0 -0
- /package/ui/.next/static/{4Kes2MbQQcEg1Xxh2Wka2 → HSR1kI5kYuEYQoBEIrPgc}/_clientMiddlewareManifest.js +0 -0
- /package/ui/.next/static/{4Kes2MbQQcEg1Xxh2Wka2 → HSR1kI5kYuEYQoBEIrPgc}/_ssgManifest.js +0 -0
package/.env.example
CHANGED
|
@@ -33,15 +33,21 @@
|
|
|
33
33
|
# JIRA_PROJECT_KEYS=KAN,ENG # optional — comma-separated; empty = all projects
|
|
34
34
|
|
|
35
35
|
# ---------------------------------------------------------------------------
|
|
36
|
-
# PM worklog (Stage 4) —
|
|
36
|
+
# PM worklog (Stage 4) — worklogs from classified sessions, for whichever
|
|
37
|
+
# tracker is configured above (Jira, Linear, or GitHub).
|
|
37
38
|
# Runs inside the Rust daemon: one hour-driven worklog per task per hour,
|
|
38
39
|
# synthesised via the MLX server's /synthesise_worklog endpoint. Requires the
|
|
39
40
|
# MLX server (it hosts the synth agent).
|
|
41
|
+
#
|
|
42
|
+
# How each tracker records a worklog:
|
|
43
|
+
# Jira — native worklog API (time spent + comment).
|
|
44
|
+
# Linear — a structured comment on the issue (Linear has no time-tracking API).
|
|
45
|
+
# GitHub — a structured comment on the issue (GitHub has no time tracking).
|
|
40
46
|
# ---------------------------------------------------------------------------
|
|
41
47
|
|
|
42
|
-
# Nothing posts to
|
|
43
|
-
# you review, edit, and approve each one in the dashboard (Worklogs view),
|
|
44
|
-
# the daemon posts approved worklogs within ~60s. Approval is the only gate —
|
|
48
|
+
# Nothing posts to your tracker automatically. The daemon DRAFTS worklogs every
|
|
49
|
+
# hour; you review, edit, and approve each one in the dashboard (Worklogs view),
|
|
50
|
+
# and the daemon posts approved worklogs within ~60s. Approval is the only gate —
|
|
45
51
|
# there is no auto-post switch.
|
|
46
52
|
|
|
47
53
|
# Driver cadence in hours (clamped to a 60s floor). Default 1.0.
|
|
@@ -62,19 +68,29 @@
|
|
|
62
68
|
# PM_WORKLOG_SYNTH_TIMEOUT_S=300
|
|
63
69
|
|
|
64
70
|
# ---------------------------------------------------------------------------
|
|
65
|
-
# GitHub (
|
|
71
|
+
# GitHub (GITHUB_TOKEN + GITHUB_ORG required to enable the GitHub connector)
|
|
72
|
+
# Syncs the OPEN issues assigned to you under GITHUB_ORG; logs worklogs as
|
|
73
|
+
# structured issue comments (GitHub has no native time tracking).
|
|
74
|
+
# Token: Settings > Developer settings > Personal access tokens. A classic token
|
|
75
|
+
# with the `repo` scope is simplest (works for personal + org issues); a
|
|
76
|
+
# fine-grained token needs Issues: Read and write on the relevant repos.
|
|
77
|
+
# GITHUB_ORG is the issue owner — an org slug OR your own username.
|
|
66
78
|
# ---------------------------------------------------------------------------
|
|
67
79
|
|
|
68
80
|
# GITHUB_TOKEN=ghp_your_personal_access_token
|
|
69
81
|
# GITHUB_ORG=your-org
|
|
70
|
-
# GITHUB_REPOS=your-org/api,your-org/web # optional — comma-separated; empty = all
|
|
82
|
+
# GITHUB_REPOS=your-org/api,your-org/web # optional — comma-separated owner/repo; empty = all repos under the owner
|
|
71
83
|
|
|
72
84
|
# ---------------------------------------------------------------------------
|
|
73
|
-
# Linear (required to enable the Linear connector)
|
|
85
|
+
# Linear (LINEAR_API_KEY required to enable the Linear connector)
|
|
86
|
+
# Syncs the issues assigned to you; logs worklogs as structured issue comments
|
|
87
|
+
# (Linear has no native time-tracking API).
|
|
88
|
+
# Key: linear.app > Settings > Account > Security & access > Personal API keys.
|
|
89
|
+
# Sent raw in the Authorization header (no "Bearer" prefix).
|
|
74
90
|
# ---------------------------------------------------------------------------
|
|
75
91
|
|
|
76
92
|
# LINEAR_API_KEY=lin_api_your_key_here
|
|
77
|
-
# LINEAR_TEAM_IDS=
|
|
93
|
+
# LINEAR_TEAM_IDS=ENG,DESIGN # optional — comma-separated team KEY or id; empty = all teams
|
|
78
94
|
|
|
79
95
|
# ---------------------------------------------------------------------------
|
|
80
96
|
# Python LLM backend — cloud fallback for the coding-agent summariser (Claude/
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.
|
|
1
|
+
1.6.0
|
package/bin/meridian
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meridiona/meridian-darwin-arm64",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Prebuilt Meridian app for macOS arm64 (daemon binary + dashboard + Python services). Installed via @meridiona/meridian.",
|
|
5
5
|
"homepage": "https://github.com/Meridiona/meridian",
|
|
6
6
|
"repository": {
|
|
@@ -11,12 +11,17 @@ _VSCODE_BANNER_RE = re.compile(
|
|
|
11
11
|
re.IGNORECASE | re.DOTALL,
|
|
12
12
|
)
|
|
13
13
|
|
|
14
|
-
# Max chars of session_text included in the prompt. Default
|
|
15
|
-
# 4 chars/token)
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
|
|
14
|
+
# Max chars of session_text included in the prompt. Default 10000 (~2500 tokens
|
|
15
|
+
# at 4 chars/token). The old 2500 cap kept only the FIRST frames of a multi-frame
|
|
16
|
+
# OCR capture, so when a session spanned more than one window/app the later
|
|
17
|
+
# (often foreground) activity was silently dropped — e.g. a session whose head
|
|
18
|
+
# showed an IDE but whose tail showed the user had moved to a different app/
|
|
19
|
+
# project got misclassified on the stale head. The classifier model has a 128K
|
|
20
|
+
# context window, so 2500 was far too conservative; 10000 comfortably holds a
|
|
21
|
+
# full multi-frame session while staying trivial for the model. Override via
|
|
22
|
+
# SESSION_TEXT_CAP env var; set to 0 to disable truncation entirely (caller is
|
|
23
|
+
# then responsible for not blowing the model's context window).
|
|
24
|
+
SESSION_TEXT_CAP = int(os.environ.get("SESSION_TEXT_CAP", "10000"))
|
|
20
25
|
|
|
21
26
|
|
|
22
27
|
def _fmt_dur(duration_s: int | float) -> str:
|
|
@@ -51,10 +56,12 @@ def _format_session(session: dict) -> str:
|
|
|
51
56
|
parts.append(f"time: {time_range}{dur_str}")
|
|
52
57
|
elif dur is not None:
|
|
53
58
|
parts.append(f"duration: {_fmt_dur(dur)}")
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
# NOTE: the rule-based ETL category is intentionally NOT included here. It is
|
|
60
|
+
# a cheap heuristic derived from the SAME app/window/OCR signals the LLM
|
|
61
|
+
# already sees, so feeding it in only injects a correlated prior — when the
|
|
62
|
+
# heuristic is wrong (e.g. background-window OCR bleed), it biases the LLM
|
|
63
|
+
# toward the same mistake. The classifier re-derives category from the raw
|
|
64
|
+
# evidence and its output overwrites the rule-based value anyway.
|
|
58
65
|
titles = session.get("window_titles") or []
|
|
59
66
|
if titles:
|
|
60
67
|
parts.append("top windows:")
|
|
@@ -116,7 +123,6 @@ def _format_recent_sessions(sessions: list[dict]) -> str:
|
|
|
116
123
|
dur_str = _fmt_dur(s.get("duration_s") or 0)
|
|
117
124
|
task_key = s.get("task_key")
|
|
118
125
|
routing = s.get("task_routing") # None means unclassified
|
|
119
|
-
category = (s.get("category") or "").strip()
|
|
120
126
|
if task_key:
|
|
121
127
|
target = f"→ {task_key}"
|
|
122
128
|
elif routing == "untracked":
|
|
@@ -126,8 +132,10 @@ def _format_recent_sessions(sessions: list[dict]) -> str:
|
|
|
126
132
|
target = "→ [pending]"
|
|
127
133
|
else:
|
|
128
134
|
target = "→ [overhead]"
|
|
129
|
-
|
|
130
|
-
|
|
135
|
+
# Category is intentionally omitted — recent-context is a task-continuity
|
|
136
|
+
# signal only; carrying the (rule-based or prior-LLM) category tag would
|
|
137
|
+
# feed a category prior back into classification.
|
|
138
|
+
rows.append(f" {time_str} {app:<14} {dur_str:<7} {target}")
|
|
131
139
|
return "\n".join(rows)
|
|
132
140
|
|
|
133
141
|
|
|
@@ -83,10 +83,10 @@ class SessionClassification(BaseModel):
|
|
|
83
83
|
] = Field(
|
|
84
84
|
...,
|
|
85
85
|
description=(
|
|
86
|
-
"The single best activity category for this session.
|
|
87
|
-
"
|
|
88
|
-
"
|
|
89
|
-
"it before the long session_summary field."
|
|
86
|
+
"The single best activity category for this session. Derive it from "
|
|
87
|
+
"the evidence (app, window titles, screen content); no category is "
|
|
88
|
+
"supplied in the input. Declared early in the schema so FSM decoding "
|
|
89
|
+
"always emits it before the long session_summary field."
|
|
90
90
|
),
|
|
91
91
|
)
|
|
92
92
|
category_confidence: float = Field(
|
|
@@ -232,9 +232,13 @@ def _fetch_session(
|
|
|
232
232
|
def _fetch_recent_sessions(
|
|
233
233
|
con: _sqlite3.Connection, before_id: int
|
|
234
234
|
) -> list[dict[str, Any]]:
|
|
235
|
+
# Recent context is a task-continuity signal only: app, time, duration and
|
|
236
|
+
# which ticket each recent session mapped to. We deliberately do NOT select
|
|
237
|
+
# session_text/excerpt or category — recent OCR is noise here and a category
|
|
238
|
+
# tag would feed a prior back into classification. (session_text is still
|
|
239
|
+
# referenced in WHERE only to skip empty-capture rows.)
|
|
235
240
|
rows = con.execute(
|
|
236
|
-
"SELECT app_name, started_at, duration_s, task_key, task_routing
|
|
237
|
-
" COALESCE(SUBSTR(session_text, 1, 200), '') AS text_excerpt"
|
|
241
|
+
"SELECT app_name, started_at, duration_s, task_key, task_routing"
|
|
238
242
|
" FROM app_sessions"
|
|
239
243
|
" WHERE id < ? AND duration_s > 1 AND COALESCE(session_text,'') != ''"
|
|
240
244
|
" ORDER BY id DESC LIMIT ?",
|
package/services/pyproject.toml
CHANGED
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "meridian-agents"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.6.0"
|
|
8
8
|
description = "Meridian agents — hermes task linking and Jira progress updates for meridian.db"
|
|
9
9
|
requires-python = ">=3.11"
|
|
10
10
|
authors = [{ name = "Meridiona" }]
|
|
@@ -24,7 +24,7 @@ The task classifier sits at the center of Meridian's workflow understanding:
|
|
|
24
24
|
|
|
25
25
|
## Classification Decision Tree
|
|
26
26
|
|
|
27
|
-
For each session,
|
|
27
|
+
For each session, decide in this order. **Core principle: do NOT try to fit every session to an existing ticket. Assign a `task_key` only when the session's OWN evidence clearly matches that specific ticket's scope. Most real work that isn't an obvious match is `untracked`, not a forced link.**
|
|
28
28
|
|
|
29
29
|
### 1. Is this overhead?
|
|
30
30
|
If the session is **idle, music, system settings,or clearly personal/unrelated activity** → return:
|
|
@@ -33,27 +33,29 @@ If the session is **idle, music, system settings,or clearly personal/unrelated a
|
|
|
33
33
|
```
|
|
34
34
|
**overhead is a hard discard.** These sessions are thrown away — never surfaced, never used for inference, never create tasks. When in doubt between overhead and untracked, ask: *"Would a manager care that this happened?"* If no, it's overhead.
|
|
35
35
|
|
|
36
|
-
### 2. Is this work
|
|
37
|
-
If the session shows **any real work signal** (coding, research, meetings, writing, debugging, reviewing, learning) but **
|
|
36
|
+
### 2. Is this real work that ISN'T clearly one of the candidate tickets? → untracked
|
|
37
|
+
If the session shows **any real work signal** (coding, research, meetings, writing, debugging, reviewing, learning) but it does **not clearly match the scope of a candidate ticket** → mark as **untracked**:
|
|
38
38
|
```json
|
|
39
39
|
{"task_key": null, "confidence": 0.6-0.8, "session_type": "untracked", "routing": "queue"}
|
|
40
40
|
```
|
|
41
|
-
**
|
|
41
|
+
**This is the important, common case — and it is what `untracked` MEANS: the user genuinely did this work, but there is no Jira ticket for it yet.** Downstream, Meridian uses untracked sessions to **create or update** the matching Jira task. So it is critical that you do **not** shoehorn this work into an unrelated existing ticket just because it is the only candidate available, or because recent sessions were on it. **A wrong task link is worse than `untracked`** — it pollutes a real ticket's worklog and hides the genuine untracked work that should have spawned its own ticket. When the evidence doesn't clearly fit a candidate, choose `untracked`.
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
`untracked` sessions are kept and used downstream (workload analysis, capacity reporting, new-task creation). Mark dimensions to capture *what* the work was. Examples that must be `untracked` (not `overhead`): standups, retros, code reviews on untracked PRs, config/infra housekeeping, general repo exploration, general research, **and any work on a feature/bug/chore that has no matching candidate ticket**.
|
|
44
|
+
|
|
45
|
+
### 3. Does it CLEARLY map to one specific candidate ticket? → task
|
|
46
|
+
Assign a `task_key` **only** when the session's own evidence (window titles, OCR, file/branch names, an explicit ticket-key mention) directly matches the **scope described in that ticket's title/description** → return:
|
|
45
47
|
```json
|
|
46
48
|
{"task_key": "KEY-123", "confidence": 0.50-0.90, "session_type": "task", "routing": "auto"}
|
|
47
49
|
```
|
|
48
|
-
|
|
50
|
+
Recent-session continuity may *support* a match, but **continuity alone is never enough** — the current session must carry its own evidence that fits the ticket. If the active app/window shows the user is now on something else (a different project, a meeting, another repo, a doc for another team), classify by **that**, not by what they were doing minutes ago. Cite the specific evidence, and infer activity dimensions.
|
|
49
51
|
|
|
50
52
|
## Your inputs
|
|
51
53
|
|
|
52
54
|
The user message contains:
|
|
53
55
|
|
|
54
|
-
- **SESSION** — app,
|
|
56
|
+
- **SESSION** — app, duration, top window titles, and the screen content (OCR / a11y). Decide the category yourself from this evidence; no category is provided.
|
|
55
57
|
- **CANDIDATE TICKETS** — all open Jira tickets. These are the only tickets you may choose from.
|
|
56
|
-
- **RECENT SESSIONS** (previous 5) —
|
|
58
|
+
- **RECENT SESSIONS** (previous 5) — app / time / duration / which ticket each mapped to (no screen text). A **weak disambiguation hint only**: it can support a match when the current session ALSO has matching evidence, but it must never override what the current session itself shows. Recent activity on a ticket does not make the current session that ticket.
|
|
57
59
|
|
|
58
60
|
## Available capabilities
|
|
59
61
|
|
|
@@ -98,7 +100,7 @@ Reply with ONE valid JSON object — no preamble, no markdown fences, no follow-
|
|
|
98
100
|
### Field rules
|
|
99
101
|
- `task_key` — must be one of the supplied candidates, or `null`. Never invent a key.
|
|
100
102
|
- `confidence` — see Scoring heuristics section for exact ranges per outcome type.
|
|
101
|
-
- `category` — the single best activity category (see taxonomy below).
|
|
103
|
+
- `category` — the single best activity category (see taxonomy below). Derive it yourself from the evidence (app, window titles, screen content); no category is provided in the input.
|
|
102
104
|
- `category_confidence` — how certain you are about `category`, `0.0`–`1.0`.
|
|
103
105
|
- `category_explanation` — ONE concise sentence justifying the category, citing the app / window titles / OCR evidence. Shown in the dashboard next to the category.
|
|
104
106
|
- `session_type` — `"task"` links to Jira; `"overhead"` is thrown away; `"untracked"` is kept for workload analysis.
|
|
@@ -199,7 +201,7 @@ You have access to **the previous 5 sessions** to disambiguate the current sessi
|
|
|
199
201
|
- Session 2 (3 min ago): Slack, discussing PR review for KAN-42 → **if related to same work**, task_key: KAN-42, confidence: 0.75 (work mention + prior context)
|
|
200
202
|
- Session 3 (now): VS Code, editing same file → task_key: KAN-42, confidence: 0.85 (context continuity)
|
|
201
203
|
|
|
202
|
-
**Decision:**
|
|
204
|
+
**Decision:** Only link Session 2 to KAN-42 if Session 2's **own content** shows it is about that work (the OCR/window discusses or searches the KAN-42 work). If Session 2 is generic, OR shows the user has moved to *different* work (another project, another team's doc, an unrelated meeting), return `null` with `session_type: "untracked"` (or a different ticket if its own evidence matches one) — **do not inherit KAN-42 just because it was the recent task.** Continuity is a tie-breaker between plausible matches, never a substitute for current-session evidence.
|
|
203
205
|
|
|
204
206
|
Example reasoning for Session 2 (if task-related): `"Slack discusses PR review for KAN-42 implementation mentioned in prior VS Code session; linked via work context."`
|
|
205
207
|
|
|
@@ -208,7 +210,7 @@ Example reasoning for Session 2 (if task-related): `"Slack discusses PR review f
|
|
|
208
210
|
**When task_key is not null (matched to a ticket):**
|
|
209
211
|
- **Task key + work alignment** — `confidence ≥ 0.90`, `session_type: "task"`
|
|
210
212
|
- **Work description alignment** — `0.75–0.85`, `session_type: "task"`
|
|
211
|
-
- **Context continuity** — `0.75–0.85`, `session_type: "task"`
|
|
213
|
+
- **Context continuity (current session ALSO has matching evidence)** — `0.75–0.85`, `session_type: "task"`. Continuity with no current-session evidence is **not** a task — use `untracked`.
|
|
212
214
|
- **Generic project-level match** — `0.50–0.65`, `session_type: "task"`
|
|
213
215
|
- **Task key only** — `0.60–0.75`, `session_type: "task"` (lower than key+alignment because work intent unclear)
|
|
214
216
|
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""Dry-run the task classifier for one or more session ids — read-only.
|
|
2
|
+
|
|
3
|
+
Drives the SAME code path the daemon uses: POSTs the session id(s) to the
|
|
4
|
+
running MLX server's /classify_sessions endpoint, which runs `_classify_one`
|
|
5
|
+
(fetch session + recent context + pm_tasks → build prompt → model → parse).
|
|
6
|
+
The Python endpoint only RETURNS the result; the DB write is done separately by
|
|
7
|
+
the Rust daemon, so calling this never mutates app_sessions — you see exactly
|
|
8
|
+
what the classifier WOULD output right now, with the current code and prompt.
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
services/.venv/bin/python services/tests/evals/classify_session.py 20128
|
|
12
|
+
services/.venv/bin/python services/tests/evals/classify_session.py 20128 20127 --show-prompt
|
|
13
|
+
MLX_SERVER_URL=http://127.0.0.1:7823 ... classify_session.py 20128
|
|
14
|
+
|
|
15
|
+
The MLX server must be running (meridian status / port 7823). It uses the
|
|
16
|
+
already-loaded model, so this is fast — no in-process model load.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import argparse
|
|
22
|
+
import json
|
|
23
|
+
import os
|
|
24
|
+
import sqlite3
|
|
25
|
+
import sys
|
|
26
|
+
import urllib.request
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
|
|
29
|
+
_DEFAULT_URL = os.environ.get("MLX_SERVER_URL", "http://127.0.0.1:7823").rstrip("/")
|
|
30
|
+
_DEFAULT_DB = os.path.expanduser(
|
|
31
|
+
os.environ.get("MERIDIAN_DB", "~/.meridian/meridian.db")
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _reconstruct_prompt(db_path: str, session_id: int) -> str | None:
|
|
36
|
+
"""Rebuild the exact prompt via the production builder (read-only)."""
|
|
37
|
+
# Import lazily so the common path (no --show-prompt) needs no agents deps.
|
|
38
|
+
sys.path.insert(0, str(Path(__file__).resolve().parents[2])) # services/
|
|
39
|
+
from agents._prompts import build_user_message
|
|
40
|
+
from agents.run_task_linker_mlx import (
|
|
41
|
+
_fetch_pm_tasks,
|
|
42
|
+
_fetch_recent_sessions,
|
|
43
|
+
_fetch_session,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
con = sqlite3.connect(f"file:{db_path}?mode=ro", uri=True)
|
|
47
|
+
con.row_factory = sqlite3.Row
|
|
48
|
+
raw = _fetch_session(con, session_id)
|
|
49
|
+
if raw is None:
|
|
50
|
+
return None
|
|
51
|
+
recent = _fetch_recent_sessions(con, session_id)
|
|
52
|
+
pm_tasks = _fetch_pm_tasks(con)
|
|
53
|
+
session_text = raw.get("session_text") or ""
|
|
54
|
+
if raw.get("claude_session_uuid") and (raw.get("session_summary") or "").strip():
|
|
55
|
+
session_text = raw["session_summary"]
|
|
56
|
+
session = {
|
|
57
|
+
"id": session_id,
|
|
58
|
+
"app_name": raw.get("app_name"),
|
|
59
|
+
"started_at": raw.get("started_at", ""),
|
|
60
|
+
"ended_at": raw.get("ended_at", ""),
|
|
61
|
+
"duration_s": raw.get("duration_s"),
|
|
62
|
+
"session_text": session_text,
|
|
63
|
+
"session_text_source": raw.get("session_text_source", "unknown"),
|
|
64
|
+
"window_titles": json.loads(raw.get("window_titles") or "[]"),
|
|
65
|
+
"category": raw.get("category"),
|
|
66
|
+
"confidence": raw.get("confidence", 0.0),
|
|
67
|
+
"audio_snippets": [],
|
|
68
|
+
}
|
|
69
|
+
return build_user_message(session, pm_tasks, recent_sessions=recent)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _classify(url: str, db_path: str, session_ids: list[int]) -> list[dict]:
|
|
73
|
+
payload = json.dumps({"session_ids": session_ids, "meridian_db": db_path}).encode()
|
|
74
|
+
req = urllib.request.Request(
|
|
75
|
+
f"{url}/classify_sessions",
|
|
76
|
+
data=payload,
|
|
77
|
+
headers={"Content-Type": "application/json"},
|
|
78
|
+
)
|
|
79
|
+
with urllib.request.urlopen(req, timeout=600) as resp:
|
|
80
|
+
return json.loads(resp.read()).get("results", [])
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def main() -> int:
|
|
84
|
+
ap = argparse.ArgumentParser(description=__doc__)
|
|
85
|
+
ap.add_argument("session_ids", nargs="+", type=int, help="session id(s) to classify")
|
|
86
|
+
ap.add_argument("--show-prompt", action="store_true", help="also print the exact prompt sent")
|
|
87
|
+
ap.add_argument("--url", default=_DEFAULT_URL, help=f"MLX server (default {_DEFAULT_URL})")
|
|
88
|
+
ap.add_argument("--db", default=_DEFAULT_DB, help=f"meridian.db (default {_DEFAULT_DB})")
|
|
89
|
+
ap.add_argument("--json", action="store_true", help="print raw JSON results")
|
|
90
|
+
args = ap.parse_args()
|
|
91
|
+
|
|
92
|
+
if args.show_prompt:
|
|
93
|
+
for sid in args.session_ids:
|
|
94
|
+
prompt = _reconstruct_prompt(args.db, sid)
|
|
95
|
+
print(f"\n{'='*30} PROMPT for session {sid} {'='*30}")
|
|
96
|
+
print(prompt if prompt is not None else f"(session {sid} not found)")
|
|
97
|
+
|
|
98
|
+
results = _classify(args.url, args.db, args.session_ids)
|
|
99
|
+
|
|
100
|
+
if args.json:
|
|
101
|
+
print(json.dumps(results, indent=2))
|
|
102
|
+
return 0
|
|
103
|
+
|
|
104
|
+
for r in results:
|
|
105
|
+
print(f"\n{'='*30} RESULT for session {r.get('session_id')} {'='*30}")
|
|
106
|
+
for k in (
|
|
107
|
+
"task_key",
|
|
108
|
+
"session_type",
|
|
109
|
+
"confidence",
|
|
110
|
+
"category",
|
|
111
|
+
"category_confidence",
|
|
112
|
+
"method",
|
|
113
|
+
):
|
|
114
|
+
print(f" {k:20} = {r.get(k)}")
|
|
115
|
+
reasoning = (r.get("reasoning") or "").strip()
|
|
116
|
+
if reasoning:
|
|
117
|
+
print(f" reasoning = {reasoning}")
|
|
118
|
+
return 0
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
if __name__ == "__main__":
|
|
122
|
+
raise SystemExit(main())
|
|
@@ -23,7 +23,6 @@ from pathlib import Path
|
|
|
23
23
|
import sys
|
|
24
24
|
|
|
25
25
|
from deepeval.metrics import BaseMetric, TaskCompletionMetric
|
|
26
|
-
from deepeval.models import OllamaModel
|
|
27
26
|
from deepeval.test_case import LLMTestCase
|
|
28
27
|
|
|
29
28
|
_SERVICES_DIR = Path(__file__).parent.parent.parent
|
|
@@ -33,7 +32,33 @@ if str(_SERVICES_DIR) not in sys.path:
|
|
|
33
32
|
_MODEL = os.environ.get("OLLAMA_MODEL", "gemma4:31b")
|
|
34
33
|
_HOST = os.environ.get("OLLAMA_HOST", "http://localhost:11434")
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
|
|
36
|
+
def _make_judge() -> "object | None":
|
|
37
|
+
"""Build the LLM judge — ONLY the agent-e2e TaskCompletionMetric needs it.
|
|
38
|
+
|
|
39
|
+
The classifier metrics below (TaskKeyMatch / SessionTypeMatch) are pure
|
|
40
|
+
exact-match and require no judge. Importing this module must therefore NOT
|
|
41
|
+
hard-depend on Ollama: if the `ollama` package or server is unavailable we
|
|
42
|
+
return None and the classifier eval runs unaffected. Construction is inside
|
|
43
|
+
the function (not at import) because OllamaModel() pulls in `ollama` only
|
|
44
|
+
when instantiated.
|
|
45
|
+
"""
|
|
46
|
+
try:
|
|
47
|
+
from deepeval.models import OllamaModel
|
|
48
|
+
|
|
49
|
+
return OllamaModel(model=_MODEL, base_url=_HOST)
|
|
50
|
+
except Exception as exc: # noqa: BLE001 — missing pkg, server down, etc.
|
|
51
|
+
import warnings
|
|
52
|
+
|
|
53
|
+
warnings.warn(
|
|
54
|
+
f"LLM judge unavailable ({exc}); agent-e2e metrics disabled. "
|
|
55
|
+
"Classifier exact-match metrics are unaffected.",
|
|
56
|
+
stacklevel=2,
|
|
57
|
+
)
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
_judge = _make_judge()
|
|
37
62
|
|
|
38
63
|
_NULL_LITERALS = {"none", "null", "n/a", "nil", "undefined", ""}
|
|
39
64
|
|
|
@@ -146,9 +171,13 @@ class SessionTypeMatchMetric(BaseMetric):
|
|
|
146
171
|
# Metric lists — import these in eval files
|
|
147
172
|
# ---------------------------------------------------------------------------
|
|
148
173
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
174
|
+
# Only built when a judge is available — otherwise empty so importing this module
|
|
175
|
+
# (e.g. for the classifier eval) never requires Ollama.
|
|
176
|
+
AGENT_E2E_METRICS = (
|
|
177
|
+
[TaskCompletionMetric(threshold=0.5, model=_judge, include_reason=True)]
|
|
178
|
+
if _judge is not None
|
|
179
|
+
else []
|
|
180
|
+
)
|
|
152
181
|
|
|
153
182
|
CLASSIFIER_METRICS = [
|
|
154
183
|
TaskKeyMatchMetric(threshold=1.0),
|
package/ui/.next/BUILD_ID
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
HSR1kI5kYuEYQoBEIrPgc
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
"static/chunks/03~yq9q893hmn.js"
|
|
8
8
|
],
|
|
9
9
|
"lowPriorityFiles": [
|
|
10
|
-
"static/
|
|
11
|
-
"static/
|
|
12
|
-
"static/
|
|
10
|
+
"static/HSR1kI5kYuEYQoBEIrPgc/_buildManifest.js",
|
|
11
|
+
"static/HSR1kI5kYuEYQoBEIrPgc/_ssgManifest.js",
|
|
12
|
+
"static/HSR1kI5kYuEYQoBEIrPgc/_clientMiddlewareManifest.js"
|
|
13
13
|
],
|
|
14
14
|
"rootMainFiles": [
|
|
15
15
|
"static/chunks/120gq8w9i9o8g.js",
|
|
@@ -102,8 +102,8 @@
|
|
|
102
102
|
"dynamicRoutes": {},
|
|
103
103
|
"notFoundRoutes": [],
|
|
104
104
|
"preview": {
|
|
105
|
-
"previewModeId": "
|
|
106
|
-
"previewModeSigningKey": "
|
|
107
|
-
"previewModeEncryptionKey": "
|
|
105
|
+
"previewModeId": "5f7a3850682c84e2757e7ca539ddc5a1",
|
|
106
|
+
"previewModeSigningKey": "d5c9fffc27c32dee509ee94a8a572e4e725eb91fe3ee2974879915e2e129d0d4",
|
|
107
|
+
"previewModeEncryptionKey": "5732f49d3782565713514da6e106a37714e2b6b9c631bb155f09cd13cc87a3ad"
|
|
108
108
|
}
|
|
109
109
|
}
|
|
@@ -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/120gq8w9i9o8g.js"/><script src="/_next/static/chunks/140ovxvjat1ch.js" async=""></script><script src="/_next/static/chunks/0chwa38d3r7hi.js" async=""></script><script src="/_next/static/chunks/turbopack-0-ynxavni4q39.js" async=""></script><script src="/_next/static/chunks/0dbhjjzl8qfwv.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/120gq8w9i9o8g.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/0dbhjjzl8qfwv.js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/0dbhjjzl8qfwv.js\"],\"default\"]\n4:I[97367,[\"/_next/static/chunks/0dbhjjzl8qfwv.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[97367,[\"/_next/static/chunks/0dbhjjzl8qfwv.js\"],\"ViewportBoundary\"]\na:I[97367,[\"/_next/static/chunks/0dbhjjzl8qfwv.js\"],\"MetadataBoundary\"]\nc:I[68027,[\"/_next/static/chunks/0dbhjjzl8qfwv.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/120gq8w9i9o8g.js"/><script src="/_next/static/chunks/140ovxvjat1ch.js" async=""></script><script src="/_next/static/chunks/0chwa38d3r7hi.js" async=""></script><script src="/_next/static/chunks/turbopack-0-ynxavni4q39.js" async=""></script><script src="/_next/static/chunks/0dbhjjzl8qfwv.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/120gq8w9i9o8g.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/0dbhjjzl8qfwv.js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/0dbhjjzl8qfwv.js\"],\"default\"]\n4:I[97367,[\"/_next/static/chunks/0dbhjjzl8qfwv.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[97367,[\"/_next/static/chunks/0dbhjjzl8qfwv.js\"],\"ViewportBoundary\"]\na:I[97367,[\"/_next/static/chunks/0dbhjjzl8qfwv.js\"],\"MetadataBoundary\"]\nc:I[68027,[\"/_next/static/chunks/0dbhjjzl8qfwv.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\":\"HSR1kI5kYuEYQoBEIrPgc\"}\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/0dbhjjzl8qfwv.js"],"ViewportBoundary"]
|
|
7
7
|
a:I[97367,["/_next/static/chunks/0dbhjjzl8qfwv.js"],"MetadataBoundary"]
|
|
8
8
|
c:I[68027,["/_next/static/chunks/0dbhjjzl8qfwv.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":"HSR1kI5kYuEYQoBEIrPgc"}
|
|
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/0dbhjjzl8qfwv.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":"HSR1kI5kYuEYQoBEIrPgc"}
|
|
5
5
|
4:null
|