diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0ef17b272..a4d2035d2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,87 @@
# Changelog
+## [1.46.6] — 2026-11-02
+
+### Added
+
+- **Lab values without a unit.** Ratios and indices such as INR,
+ cholesterol/HDL or albumin/globulin had nowhere to go: manual entry, the
+ CSV import and the document review all required a unit. Entry, the
+ scanned-report rows and the document review now offer an explicit "No
+ unit" choice, stored as the UCUM unity `"1"`, and the CSV import reads
+ `1` in the unit column the same way. An empty unit is still refused, so
+ a unit the reading lost is not mistaken for none, and a document read
+ that answers "no unit" by itself is held for review. Such a value shows
+ as the number alone, a marker kept in a real unit refuses it, and the
+ FHIR export codes it as UCUM `1`. (#1313)
+- **MCP reads follow their links.** Lab readings in `get_labs` and
+ `fetch lab:` list the documents and visits they are linked to, with the
+ linked records once per answer instead of on every reading of the same
+ report. `fetch med:` and `get_medication_schedule` list theirs, and
+ `fetch document:` now also names the lab results and medications filed
+ against it. Rows of `get_visits`, `get_medication_schedule` and
+ `get_illness_recovery` carry an id `fetch` takes. An imported document
+ names its source system and id, never the address of the instance it
+ came from. (#1323)
+
+### Fixed
+
+- **A refused lab value can be corrected in the review.** A value that
+ Finish review refused, such as a ratio printed without a unit or a unit
+ that disagrees with the marker, showed the reason but could only be
+ discarded. The row now offers the same Check control as a low-confidence
+ value. (#1313, #1327)
+- **The doctor report prints every language.** The PDF used a built-in
+ font that covers Western European letters only, so Polish letters such
+ as ą, ł or ś, the whole Korean report, and any medication name or note in
+ another script printed as empty boxes. The report now embeds an open
+ Unicode font family covering Latin, Greek, Cyrillic and, when the report
+ needs it, Korean, and arrows, ≤ and ² print as themselves instead of
+ ASCII stand-ins. The file is compressed, so a report stays around
+ 65 KB. Chinese, Japanese and Arabic text are not covered yet.
+- **PDFs read on a Raspberry Pi 4.** The native canvas build for arm64
+ Alpine needs CPU features an ARMv8.0 core lacks, and loading it ended
+ every PDF read with an illegal instruction. The CPU check now covers that
+ case, and PDF reading carries on without the canvas, so the text layer
+ and the index work; thumbnails keep their existing fallback. (#1311)
+- **The display name greets you.** The dashboard and Insights greetings,
+ the top bar and the sidebar showed the username even when a display name
+ was set. They now use the display name and fall back to the username.
+ (#1309)
+- **Summaries count every reading right after an import.** A type whose
+ history was not folded yet counted as covered as soon as one day was, so
+ a summary could show one day of weight readings out of three. A type now
+ counts as covered only when its folded days reach back to its oldest
+ reading.
+- **The repeated hour of a clock change stays two hours.** On the night
+ the clocks go back, a dense pulse or glucose chart folded both runs of
+ the repeated hour into one point. Each hour is its own point now.
+- **Google Health heals a connection that lost its account id.** The
+ 1.46.4 update cleared a placeholder id on existing connections. After a
+ clean sync such a connection now reads its real id back, so the
+ one-account-per-profile check covers it again.
+- **WHOOP refuses a sign-in without a user id** instead of storing the
+ text "undefined" as the account.
+
+### Changed
+
+- Next.js 16.4.3 and the weekly dependency updates. node-forge, reached
+ through the APNs client, is raised to 1.4.2, which closes five high
+ advisories.
+
+### Thanks
+
+- @johnnyrepo026 for the precise report on unitless lab ratios (#1313),
+ with the cause already traced to the right two files, and for the pull
+ request that fixed the review half of it (#1327).
+- @mbreitkreuz for the MCP linked-records request (#1323), a careful spec
+ with the real case that made date matching fail.
+- @Oguz3003 for tracking the Raspberry Pi 4 crash down to the CPU and
+ confirming the workaround (#1311).
+- @angusmaul for noticing the greeting ignored the display name (#1309).
+- @mills1975 for the heart-rate sync report and the diagnostics that
+ pinned it to the iPhone app (#1326); the fix follows in an app update.
+
## [1.46.5] — 2026-10-30
### Fixed
diff --git a/Dockerfile b/Dockerfile
index 9290eedd1..37143e516 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -312,7 +312,7 @@ RUN mkdir -p /opt/prisma-cli && \
npm pkg set 'overrides.mysql2=^3.22.0' && \
npm pkg set 'overrides.@hono/node-server=^1.19.15' && \
npm pkg set 'overrides.valibot=^1.4.2' && \
- npm install --omit=dev prisma@7.10.1 @prisma/engines@7.10.1 tsx@4.23.1 dotenv@18.0.8 && \
+ npm install --omit=dev prisma@7.10.1 @prisma/engines@7.10.1 tsx@4.23.1 dotenv@18.0.9 && \
ln -sfn /opt/prisma-cli/node_modules/.bin/tsx /usr/local/bin/healthlog-tsx && \
ln -sfn /opt/prisma-cli/node_modules/dotenv /app/node_modules/dotenv && \
ln -sfn /opt/prisma-cli/node_modules/prisma /app/node_modules/prisma && \
diff --git a/docs/api/openapi.yaml b/docs/api/openapi.yaml
index 202e7ec9d..9191779ac 100644
--- a/docs/api/openapi.yaml
+++ b/docs/api/openapi.yaml
@@ -1,7 +1,7 @@
openapi: 3.1.0
info:
title: HealthLog API
- version: 1.46.5
+ version: 1.46.6
description: >-
Self-hosted personal-health-tracking PWA — public API surface for the iOS native client and external ingest.
@@ -15875,10 +15875,11 @@ paths:
checks an hour, the import itself the shared 5-an-hour `import:` bucket. Owner only; refused with
`module.disabled` when the module is switched off. An unknown query parameter is refused with 422, so a misspelt
`dryRun` never writes. Each row's name resolves to the account's marker the way a scanned report's rows do
- (name, alias, catalog name); a new analyte mints one marker from its first row. A numeric result needs a unit;
- one in another unit is converted when the conversion is known and keeps the printed value beside it, otherwise
- the row is refused with `unit_mismatch`. Any other text in the value column is a qualitative result. A date
- without a time is stored as that calendar date. At most 20 000 data rows."
+ (name, alias, catalog name); a new analyte mints one marker from its first row. A numeric result needs a unit:
+ an empty unit cell is refused with `missing_unit`, and `1` (the UCUM unity) states a value without a unit, such
+ as a ratio or INR. A result in another unit is converted when the conversion is known and keeps the printed
+ value beside it, otherwise the row is refused with `unit_mismatch`. Any other text in the value column is a
+ qualitative result. A date without a time is stored as that calendar date. At most 20 000 data rows."
parameters:
- in: query
name: dryRun
@@ -34146,6 +34147,11 @@ components:
minLength: 1
maxLength: 120
unit:
+ description: 'The unit the value is in, free-form as the report prints it (e.g. `mg/dL`). `"1"`, the UCUM unity, means
+ the value has no unit: a ratio or an index such as INR or cholesterol/HDL. It is an explicit choice and a
+ unit of its own: it matches only `"1"`, so a reading without a unit is refused under a marker kept in a real
+ unit and the other way round. Clients show nothing beside such a value. An empty unit on a numeric value is
+ never read as `"1"` and stays refused.'
type: string
minLength: 1
maxLength: 40
@@ -34215,6 +34221,11 @@ components:
minLength: 1
maxLength: 120
unit:
+ description: 'The unit the value is in, free-form as the report prints it (e.g. `mg/dL`). `"1"`, the UCUM unity, means
+ the value has no unit: a ratio or an index such as INR or cholesterol/HDL. It is an explicit choice and a
+ unit of its own: it matches only `"1"`, so a reading without a unit is refused under a marker kept in a real
+ unit and the other way round. Clients show nothing beside such a value. An empty unit on a numeric value is
+ never read as `"1"` and stays refused.'
type: string
minLength: 1
maxLength: 40
@@ -34309,6 +34320,11 @@ components:
minLength: 1
maxLength: 120
unit:
+ description: 'The unit the value is in, free-form as the report prints it (e.g. `mg/dL`). `"1"`, the UCUM unity, means
+ the value has no unit: a ratio or an index such as INR or cholesterol/HDL. It is an explicit choice
+ and a unit of its own: it matches only `"1"`, so a reading without a unit is refused under a marker
+ kept in a real unit and the other way round. Clients show nothing beside such a value. An empty unit
+ on a numeric value is never read as `"1"` and stays refused.'
type: string
minLength: 1
maxLength: 40
@@ -34363,6 +34379,11 @@ components:
type: string
minLength: 1
maxLength: 40
+ description: 'The unit the value is in, free-form as the report prints it (e.g. `mg/dL`). `"1"`, the UCUM unity, means
+ the value has no unit: a ratio or an index such as INR or cholesterol/HDL. It is an explicit choice and a
+ unit of its own: it matches only `"1"`, so a reading without a unit is refused under a marker kept in a real
+ unit and the other way round. Clients show nothing beside such a value. An empty unit on a numeric value is
+ never read as `"1"` and stays refused.'
lowerBound:
type: number
upperBound:
@@ -34392,6 +34413,11 @@ components:
minLength: 1
maxLength: 120
unit:
+ description: 'The unit the value is in, free-form as the report prints it (e.g. `mg/dL`). `"1"`, the UCUM unity, means
+ the value has no unit: a ratio or an index such as INR or cholesterol/HDL. It is an explicit choice and a
+ unit of its own: it matches only `"1"`, so a reading without a unit is refused under a marker kept in a real
+ unit and the other way round. Clients show nothing beside such a value. An empty unit on a numeric value is
+ never read as `"1"` and stays refused.'
type: string
minLength: 1
maxLength: 40
@@ -35759,6 +35785,11 @@ components:
maxLength: 300
- type: "null"
unit:
+ description: 'The unit the value is in, free-form as the report prints it (e.g. `mg/dL`). `"1"`, the UCUM unity, means
+ the value has no unit: a ratio or an index such as INR or cholesterol/HDL. It is an explicit choice and
+ a unit of its own: it matches only `"1"`, so a reading without a unit is refused under a marker kept in
+ a real unit and the other way round. Clients show nothing beside such a value. An empty unit on a
+ numeric value is never read as `"1"` and stays refused.'
anyOf:
- type: string
maxLength: 80
@@ -75275,6 +75306,11 @@ components:
- "null"
unit:
type: string
+ description: 'The unit the value is in, free-form as the report prints it (e.g. `mg/dL`). `"1"`, the UCUM unity, means
+ the value has no unit: a ratio or an index such as INR or cholesterol/HDL. It is an explicit choice and a
+ unit of its own: it matches only `"1"`, so a reading without a unit is refused under a marker kept in a real
+ unit and the other way round. Clients show nothing beside such a value. An empty unit on a numeric value is
+ never read as `"1"` and stays refused.'
converted:
type: boolean
sourceValue:
@@ -75524,6 +75560,11 @@ components:
- "null"
unit:
type: string
+ description: 'The unit the value is in, free-form as the report prints it (e.g. `mg/dL`). `"1"`, the UCUM unity, means
+ the value has no unit: a ratio or an index such as INR or cholesterol/HDL. It is an explicit choice and a
+ unit of its own: it matches only `"1"`, so a reading without a unit is refused under a marker kept in a real
+ unit and the other way round. Clients show nothing beside such a value. An empty unit on a numeric value is
+ never read as `"1"` and stays refused.'
converted:
type: boolean
sourceValue:
@@ -76503,6 +76544,11 @@ components:
type: string
unit:
type: string
+ description: 'The unit the value is in, free-form as the report prints it (e.g. `mg/dL`). `"1"`, the UCUM unity, means
+ the value has no unit: a ratio or an index such as INR or cholesterol/HDL. It is an explicit choice and a
+ unit of its own: it matches only `"1"`, so a reading without a unit is refused under a marker kept in a real
+ unit and the other way round. Clients show nothing beside such a value. An empty unit on a numeric value is
+ never read as `"1"` and stays refused.'
lowerBound:
type:
- number
@@ -76602,6 +76648,11 @@ components:
type: string
unit:
type: string
+ description: 'The unit the value is in, free-form as the report prints it (e.g. `mg/dL`). `"1"`, the UCUM unity, means
+ the value has no unit: a ratio or an index such as INR or cholesterol/HDL. It is an explicit choice and a
+ unit of its own: it matches only `"1"`, so a reading without a unit is refused under a marker kept in a real
+ unit and the other way round. Clients show nothing beside such a value. An empty unit on a numeric value is
+ never read as `"1"` and stays refused.'
lowerBound:
type:
- number
diff --git a/messages/de.json b/messages/de.json
index 1614425f1..3c914dfc9 100644
--- a/messages/de.json
+++ b/messages/de.json
@@ -10396,7 +10396,9 @@
"pdfNeedsAnthropic": "PDF-Scannen benötigt einen Claude-Bildanbieter; lade stattdessen ein Foto hoch.",
"refTextLabel": "Bereich wie gedruckt",
"refTextPlaceholder": "z. B. 3,5 - 5,0",
- "aiUnavailable": "Das Scannen eines Befunds mit KI ist hier gerade nicht verfügbar."
+ "aiUnavailable": "Das Scannen eines Befunds mit KI ist hier gerade nicht verfügbar.",
+ "errorUnitMismatchNoUnit": "Dieser Marker wird ohne Einheit geführt. Setz das Häkchen bei Keine Einheit, falls der Befund falsch gelesen wurde, oder wähle den Wert ab.",
+ "unitDiffersBadgeNoUnit": "Ohne Einheit geführt; dieser Befund nennt {unit}"
},
"loadMoreReadings": "Weitere Werte laden",
"documentsLink": "Befund-Dokumente",
@@ -10474,6 +10476,10 @@
"stale": "Der neueste Wert ist vom {date}, also älter als ein Jahr. Die Gerade gilt für diesen Stand, ohne Projektion."
},
"interval": "95-%-Intervall der jährlichen Veränderung: {lo} bis {hi} {unit}."
+ },
+ "unit": {
+ "none": "Keine Einheit",
+ "noneHint": "Für einen Quotienten oder Index wie INR oder Cholesterin/HDL."
}
},
"modules": {
@@ -14093,6 +14099,7 @@
"asNeeded": "Bei Bedarf",
"startsOn": "Beginn",
"endsOn": "Ende"
- }
+ },
+ "unitlessHint": "Ein Quotient oder Index ohne Einheit (INR, Cholesterin/HDL): Trag in der Spalte für die Einheit eine 1 ein. Eine leere Einheit bleibt ein Fehler."
}
}
diff --git a/messages/en.json b/messages/en.json
index 0b9a78b16..aea2d6a89 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -10396,7 +10396,9 @@
"pdfNeedsAnthropic": "PDF scanning needs a Claude vision provider; upload a photo instead.",
"refTextLabel": "Range as printed",
"refTextPlaceholder": "e.g. 3.5 - 5.0",
- "aiUnavailable": "Scanning a report with AI is not available here right now."
+ "aiUnavailable": "Scanning a report with AI is not available here right now.",
+ "errorUnitMismatchNoUnit": "This marker is tracked without a unit. Tick No unit if the report was misread, or deselect this reading.",
+ "unitDiffersBadgeNoUnit": "Tracked without a unit; this report says {unit}"
},
"loadMoreReadings": "Load more readings",
"documentsLink": "Lab report documents",
@@ -10474,6 +10476,10 @@
"stale": "The newest reading is from {date}, more than a year ago. The line is shown as of then, without a projection."
},
"interval": "95 % interval of the yearly change: {lo} to {hi} {unit}."
+ },
+ "unit": {
+ "none": "No unit",
+ "noneHint": "For a ratio or an index such as INR or cholesterol/HDL."
}
},
"modules": {
@@ -14093,6 +14099,7 @@
"asNeeded": "As needed",
"startsOn": "Start",
"endsOn": "End"
- }
+ },
+ "unitlessHint": "A ratio or an index without a unit (INR, cholesterol/HDL): write 1 in the unit column. An empty unit cell stays an error."
}
}
diff --git a/messages/es.json b/messages/es.json
index 494161998..a729ed506 100644
--- a/messages/es.json
+++ b/messages/es.json
@@ -10396,7 +10396,9 @@
"pdfNeedsAnthropic": "El escaneo de PDF necesita un proveedor de visión de Claude; sube una foto en su lugar.",
"refTextLabel": "Rango tal como aparece",
"refTextPlaceholder": "p. ej. 3,5 - 5,0",
- "aiUnavailable": "Escanear un informe con IA no está disponible aquí ahora mismo."
+ "aiUnavailable": "Escanear un informe con IA no está disponible aquí ahora mismo.",
+ "errorUnitMismatchNoUnit": "Este marcador se registra sin unidad. Marca Sin unidad si el informe se leyó mal o deselecciona este valor.",
+ "unitDiffersBadgeNoUnit": "Registrado sin unidad; este informe indica {unit}"
},
"loadMoreReadings": "Cargar más mediciones",
"documentsLink": "Documentos de resultados",
@@ -10474,6 +10476,10 @@
"stale": "El valor más reciente es del {date}, hace más de un año. La línea se muestra a esa fecha, sin proyección."
},
"interval": "Intervalo del 95 % del cambio anual: de {lo} a {hi} {unit}."
+ },
+ "unit": {
+ "none": "Sin unidad",
+ "noneHint": "Para un cociente o un índice como el INR o colesterol/HDL."
}
},
"modules": {
@@ -14093,6 +14099,7 @@
"asNeeded": "A demanda",
"startsOn": "Inicio",
"endsOn": "Fin"
- }
+ },
+ "unitlessHint": "Un cociente o un índice sin unidad (INR, colesterol/HDL): escribe 1 en la columna de la unidad. Una unidad vacía sigue siendo un error."
}
}
diff --git a/messages/fr.json b/messages/fr.json
index 3cf6c27ec..130a2dcec 100644
--- a/messages/fr.json
+++ b/messages/fr.json
@@ -10396,7 +10396,9 @@
"pdfNeedsAnthropic": "Le scan PDF nécessite un fournisseur de vision Claude ; importez plutôt une photo.",
"refTextLabel": "Plage telle qu'imprimée",
"refTextPlaceholder": "p. ex. 3,5 - 5,0",
- "aiUnavailable": "La numérisation d'un compte rendu par IA n'est pas disponible ici pour le moment."
+ "aiUnavailable": "La numérisation d'un compte rendu par IA n'est pas disponible ici pour le moment.",
+ "errorUnitMismatchNoUnit": "Ce marqueur est suivi sans unité. Cochez Sans unité si le compte rendu a été mal lu, ou désélectionnez cette valeur.",
+ "unitDiffersBadgeNoUnit": "Suivi sans unité ; ce compte rendu indique {unit}"
},
"loadMoreReadings": "Charger plus de mesures",
"documentsLink": "Documents de résultats",
@@ -10474,6 +10476,10 @@
"stale": "La valeur la plus récente date du {date}, il y a plus d’un an. La droite est montrée à cette date, sans projection."
},
"interval": "Intervalle à 95 % de la variation annuelle : de {lo} à {hi} {unit}."
+ },
+ "unit": {
+ "none": "Sans unité",
+ "noneHint": "Pour un rapport ou un indice comme l'INR ou cholestérol/HDL."
}
},
"modules": {
@@ -14093,6 +14099,7 @@
"asNeeded": "Si besoin",
"startsOn": "Début",
"endsOn": "Fin"
- }
+ },
+ "unitlessHint": "Un rapport ou un indice sans unité (INR, cholestérol/HDL) : inscrivez 1 dans la colonne de l'unité. Une unité vide reste une erreur."
}
}
diff --git a/messages/it.json b/messages/it.json
index f72bbde59..7c417dc4c 100644
--- a/messages/it.json
+++ b/messages/it.json
@@ -10396,7 +10396,9 @@
"pdfNeedsAnthropic": "La scansione PDF richiede un provider di visione Claude; carica invece una foto.",
"refTextLabel": "Intervallo come stampato",
"refTextPlaceholder": "es. 3,5 - 5,0",
- "aiUnavailable": "La scansione di un referto con IA non è disponibile qui al momento."
+ "aiUnavailable": "La scansione di un referto con IA non è disponibile qui al momento.",
+ "errorUnitMismatchNoUnit": "Questo marcatore è registrato senza unità. Spunta Nessuna unità se il referto è stato letto male, oppure deseleziona questo valore.",
+ "unitDiffersBadgeNoUnit": "Registrato senza unità; questo referto indica {unit}"
},
"loadMoreReadings": "Carica altre misurazioni",
"documentsLink": "Documenti dei referti",
@@ -10474,6 +10476,10 @@
"stale": "Il valore più recente è del {date}, più di un anno fa. La retta è mostrata a quella data, senza proiezione."
},
"interval": "Intervallo al 95 % della variazione annua: da {lo} a {hi} {unit}."
+ },
+ "unit": {
+ "none": "Nessuna unità",
+ "noneHint": "Per un rapporto o un indice come l'INR o colesterolo/HDL."
}
},
"modules": {
@@ -14093,6 +14099,7 @@
"asNeeded": "Al bisogno",
"startsOn": "Inizio",
"endsOn": "Fine"
- }
+ },
+ "unitlessHint": "Un rapporto o un indice senza unità (INR, colesterolo/HDL): scrivi 1 nella colonna dell'unità. Un'unità vuota resta un errore."
}
}
diff --git a/messages/ko.json b/messages/ko.json
index fa858cc6a..6687f8fd6 100644
--- a/messages/ko.json
+++ b/messages/ko.json
@@ -10396,7 +10396,9 @@
"pdfNeedsAnthropic": "PDF 스캔에는 Claude 비전 제공자가 필요해요. 대신 사진을 올려 주세요.",
"refTextLabel": "적힌 그대로의 범위",
"refTextPlaceholder": "예: 3.5 - 5.0",
- "aiUnavailable": "지금 여기에서는 AI로 결과지를 스캔할 수 없습니다."
+ "aiUnavailable": "지금 여기에서는 AI로 결과지를 스캔할 수 없습니다.",
+ "errorUnitMismatchNoUnit": "이 지표는 단위 없이 기록됩니다. 결과지를 잘못 읽었다면 단위 없음을 선택하거나 이 값의 선택을 해제하세요.",
+ "unitDiffersBadgeNoUnit": "단위 없이 기록 중; 이 결과지는 {unit}"
},
"loadMoreReadings": "측정값 더 보기",
"documentsLink": "검사 결과지 문서",
@@ -10474,6 +10476,10 @@
"stale": "가장 최근 값은 {date}로 1년이 넘었습니다. 직선은 그 시점 기준으로 표시하며 예측은 하지 않습니다."
},
"interval": "연간 변화의 95% 구간: {lo}~{hi} {unit}."
+ },
+ "unit": {
+ "none": "단위 없음",
+ "noneHint": "INR이나 콜레스테롤/HDL 같은 비율 또는 지수에 사용해요."
}
},
"modules": {
@@ -14093,6 +14099,7 @@
"asNeeded": "필요시",
"startsOn": "시작",
"endsOn": "종료"
- }
+ },
+ "unitlessHint": "단위가 없는 비율이나 지수(INR, 콜레스테롤/HDL)는 단위 열에 1을 입력하세요. 단위 칸이 비어 있으면 여전히 오류예요."
}
}
diff --git a/messages/nl.json b/messages/nl.json
index 0d7a0de24..17aefb7de 100644
--- a/messages/nl.json
+++ b/messages/nl.json
@@ -10396,7 +10396,9 @@
"pdfNeedsAnthropic": "Voor het scannen van PDF's is een Claude-provider met beeldherkenning nodig; upload in plaats daarvan een foto.",
"refTextLabel": "Bereik zoals afgedrukt",
"refTextPlaceholder": "bijv. 3,5 - 5,0",
- "aiUnavailable": "Een rapport scannen met AI is hier op dit moment niet beschikbaar."
+ "aiUnavailable": "Een rapport scannen met AI is hier op dit moment niet beschikbaar.",
+ "errorUnitMismatchNoUnit": "Deze marker wordt zonder eenheid bijgehouden. Vink Geen eenheid aan als het rapport verkeerd is gelezen, of deselecteer deze meting.",
+ "unitDiffersBadgeNoUnit": "Zonder eenheid bijgehouden; dit rapport vermeldt {unit}"
},
"loadMoreReadings": "Meer metingen laden",
"documentsLink": "Documenten met labrapporten",
@@ -10474,6 +10476,10 @@
"stale": "De nieuwste waarde is van {date}, meer dan een jaar geleden. De lijn staat op die datum, zonder projectie."
},
"interval": "95%-interval van de jaarlijkse verandering: {lo} tot {hi} {unit}."
+ },
+ "unit": {
+ "none": "Geen eenheid",
+ "noneHint": "Voor een verhouding of index zoals INR of cholesterol/HDL."
}
},
"modules": {
@@ -14093,6 +14099,7 @@
"asNeeded": "Zo nodig",
"startsOn": "Begin",
"endsOn": "Einde"
- }
+ },
+ "unitlessHint": "Een verhouding of index zonder eenheid (INR, cholesterol/HDL): vul 1 in de eenheidskolom in. Een lege eenheid blijft een fout."
}
}
diff --git a/messages/pl.json b/messages/pl.json
index 03b936c1b..5132eeb8a 100644
--- a/messages/pl.json
+++ b/messages/pl.json
@@ -10396,7 +10396,9 @@
"pdfNeedsAnthropic": "Skanowanie PDF wymaga dostawcy wizji Claude; prześlij zamiast tego zdjęcie.",
"refTextLabel": "Zakres tak jak wydrukowano",
"refTextPlaceholder": "np. 3,5 - 5,0",
- "aiUnavailable": "Skanowanie wyniku przez AI jest tu teraz niedostępne."
+ "aiUnavailable": "Skanowanie wyniku przez AI jest tu teraz niedostępne.",
+ "errorUnitMismatchNoUnit": "Ten wskaźnik jest prowadzony bez jednostki. Zaznacz Bez jednostki, jeśli wynik został źle odczytany, albo odznacz tę wartość.",
+ "unitDiffersBadgeNoUnit": "Prowadzony bez jednostki; ten wynik podaje {unit}"
},
"loadMoreReadings": "Wczytaj więcej pomiarów",
"documentsLink": "Dokumenty wyników badań",
@@ -10474,6 +10476,10 @@
"stale": "Najnowszy wynik pochodzi z {date}, sprzed ponad roku. Prosta jest pokazana na ten dzień, bez projekcji."
},
"interval": "95% przedział rocznej zmiany: od {lo} do {hi} {unit}."
+ },
+ "unit": {
+ "none": "Bez jednostki",
+ "noneHint": "Dla ilorazu lub wskaźnika, np. INR albo cholesterol/HDL."
}
},
"modules": {
@@ -14093,6 +14099,7 @@
"asNeeded": "W razie potrzeby",
"startsOn": "Początek",
"endsOn": "Koniec"
- }
+ },
+ "unitlessHint": "Iloraz lub wskaźnik bez jednostki (INR, cholesterol/HDL): wpisz 1 w kolumnie jednostki. Pusta jednostka nadal jest błędem."
}
}
diff --git a/messages/pt-BR.json b/messages/pt-BR.json
index d3a4ecb84..d8d87e84b 100644
--- a/messages/pt-BR.json
+++ b/messages/pt-BR.json
@@ -10396,7 +10396,9 @@
"pdfNeedsAnthropic": "A digitalização de PDF precisa de um provedor de visão Claude; envie uma foto em vez disso.",
"refTextLabel": "Faixa como impressa",
"refTextPlaceholder": "ex.: 3,5 - 5,0",
- "aiUnavailable": "Digitalizar um laudo com IA não está disponível aqui agora."
+ "aiUnavailable": "Digitalizar um laudo com IA não está disponível aqui agora.",
+ "errorUnitMismatchNoUnit": "Este marcador é acompanhado sem unidade. Marque Sem unidade se o laudo foi lido errado, ou desmarque esta leitura.",
+ "unitDiffersBadgeNoUnit": "Acompanhado sem unidade; este laudo diz {unit}"
},
"loadMoreReadings": "Carregar mais leituras",
"documentsLink": "Documentos de laudos laboratoriais",
@@ -10474,6 +10476,10 @@
"stale": "O resultado mais recente é de {date}, há mais de um ano. A linha é mostrada até essa data, sem projeção."
},
"interval": "Intervalo de 95 % da mudança anual: {lo} a {hi} {unit}."
+ },
+ "unit": {
+ "none": "Sem unidade",
+ "noneHint": "Para uma razão ou um índice como INR ou colesterol/HDL."
}
},
"modules": {
@@ -14093,6 +14099,7 @@
"asNeeded": "Conforme necessário",
"startsOn": "Início",
"endsOn": "Fim"
- }
+ },
+ "unitlessHint": "Uma razão ou um índice sem unidade (INR, colesterol/HDL): escreva 1 na coluna da unidade. Uma unidade vazia continua sendo um erro."
}
}
diff --git a/next.config.ts b/next.config.ts
index 013e81c7a..a4813cdab 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -309,6 +309,9 @@ const nextConfig: NextConfig = {
"./src/lib/documents/pdf-child.mjs",
"./src/lib/documents/pdf-engine.mjs",
"./src/lib/documents/image-engine.mjs",
+ // The doctor-report PDF embeds its fonts, read from disk by a path the
+ // tracer cannot follow (`src/lib/doctor-report-pdf/fonts.ts`).
+ "./src/lib/doctor-report-pdf/fonts/**",
// Document AI local text extraction and rasterization both run the
// app's one pdfjs-dist (`src/lib/documents/pdfjs.ts`) server-side; the
// text read is the provider-free fallback that keeps content search
diff --git a/package.json b/package.json
index 6368ffab5..0da3bb19f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "healthlog",
- "version": "1.46.5",
+ "version": "1.46.6",
"description": "Self-hosted personal-health-tracking PWA with Withings integration, AI insights, and doctor-report PDF export.",
"license": "PolyForm-Noncommercial-1.0.0",
"homepage": "https://healthlog.dev",
@@ -54,34 +54,34 @@
"mcp:stdio": "npx tsx src/cli/mcp-stdio.ts"
},
"dependencies": {
- "@aws-sdk/client-s3": "^3.1155.0",
- "@aws-sdk/lib-storage": "3.1155.0",
+ "@aws-sdk/client-s3": "^3.1159.0",
+ "@aws-sdk/lib-storage": "3.1159.0",
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
- "@modelcontextprotocol/sdk": "^1.32.1",
+ "@modelcontextprotocol/sdk": "^1.32.2",
"@napi-rs/canvas": "1.0.13",
"@node-rs/argon2": "^2.2.2",
- "@parse/node-apn": "^8.1.0",
+ "@parse/node-apn": "^8.1.1",
"@prisma/adapter-pg": "^7.10.1",
"@prisma/client": "^7.10.1",
"@simplewebauthn/browser": "^14.0.0",
"@simplewebauthn/server": "^14.0.3",
- "@tanstack/react-query": "5.104.5",
- "@tanstack/react-virtual": "^3.14.22",
+ "@tanstack/react-query": "5.105.0",
+ "@tanstack/react-virtual": "^3.14.25",
"@types/sax": "^1.2.7",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"date-fns": "^4.4.0",
- "dotenv": "^18.0.8",
+ "dotenv": "^18.0.9",
"fflate": "^0.8.3",
- "jose": "^6.2.13",
+ "jose": "^6.2.14",
"jspdf": "^4.2.1",
"jspdf-autotable": "^5.0.9",
- "lucide-react": "^1.61.0",
+ "lucide-react": "^1.66.0",
"mmdb-lib": "^3.0.3",
- "next": "16.4.2",
- "nodemailer": "10.2.1",
+ "next": "16.4.3",
+ "nodemailer": "10.3.1",
"otpauth": "^9.5.2",
"p-limit": "^7.3.3",
"pg": "^8.23.1",
@@ -107,15 +107,15 @@
},
"devDependencies": {
"@axe-core/playwright": "^4.14.0",
- "@next/bundle-analyzer": "16.4.2",
+ "@next/bundle-analyzer": "16.4.3",
"@playwright/test": "^1.64.1",
- "@stryker-mutator/core": "10.0.0",
+ "@stryker-mutator/core": "10.1.1",
"@stryker-mutator/vitest-runner": "10.0.0",
"@tailwindcss/postcss": "^4",
"@tesseract.js-data/deu": "1.0.0",
"@tesseract.js-data/eng": "1.0.0",
"@testcontainers/postgresql": "^12.2.1",
- "@types/node": "26.6.5",
+ "@types/node": "26.6.6",
"@types/pg": "^8.23.1",
"@types/qrcode": "^1.5.6",
"@types/react": "^19.3.0",
@@ -125,14 +125,14 @@
"@vitest/coverage-v8": "^5.0.5",
"ajv": "^8.20.0",
"eslint": "^9",
- "eslint-config-next": "16.4.2",
+ "eslint-config-next": "16.4.3",
"fast-check": "4.10.2",
- "knip": "^6.42.0",
+ "knip": "^6.44.1",
"lefthook": "^2.2.2",
"pdfjs-dist": "6.4.299",
"prettier": "^3.9.10",
"prettier-plugin-tailwindcss": "^0.8.1",
- "shadcn": "^4.22.1",
+ "shadcn": "^4.23.0",
"tailwindcss": "^4",
"testcontainers": "^12.2.1",
"tw-animate-css": "^1.4.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 18b066b1a..1c07cb070 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -46,11 +46,11 @@ importers:
.:
dependencies:
'@aws-sdk/client-s3':
- specifier: ^3.1155.0
- version: 3.1155.0
+ specifier: ^3.1159.0
+ version: 3.1159.0
'@aws-sdk/lib-storage':
- specifier: 3.1155.0
- version: 3.1155.0(@aws-sdk/client-s3@3.1155.0)
+ specifier: 3.1159.0
+ version: 3.1159.0(@aws-sdk/client-s3@3.1159.0)
'@dnd-kit/core':
specifier: ^6.3.1
version: 6.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
@@ -61,8 +61,8 @@ importers:
specifier: ^3.2.2
version: 3.2.2(react@19.3.1)
'@modelcontextprotocol/sdk':
- specifier: ^1.32.1
- version: 1.32.1(@cfworker/json-schema@4.1.1)(supports-color@7.2.0)(zod@4.6.7)
+ specifier: ^1.32.2
+ version: 1.32.2(@cfworker/json-schema@4.1.1)(supports-color@7.2.0)(zod@4.6.7)
'@napi-rs/canvas':
specifier: 1.0.13
version: 1.0.13
@@ -70,14 +70,14 @@ importers:
specifier: ^2.2.2
version: 2.2.2
'@parse/node-apn':
- specifier: ^8.1.0
- version: 8.1.0(supports-color@7.2.0)
+ specifier: ^8.1.1
+ version: 8.1.1(supports-color@7.2.0)
'@prisma/adapter-pg':
specifier: ^7.10.1
version: 7.10.1
'@prisma/client':
specifier: ^7.10.1
- version: 7.10.1(prisma@7.10.1(@types/node@26.6.5)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(magicast@0.5.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(typescript@6.0.3))(typescript@6.0.3)
+ version: 7.10.1(prisma@7.10.1(@types/node@26.6.6)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(magicast@0.5.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(typescript@6.0.3))(typescript@6.0.3)
'@simplewebauthn/browser':
specifier: ^14.0.0
version: 14.0.0
@@ -85,11 +85,11 @@ importers:
specifier: ^14.0.3
version: 14.0.3
'@tanstack/react-query':
- specifier: 5.104.5
- version: 5.104.5(@types/react@19.3.0)(react@19.3.1)
+ specifier: 5.105.0
+ version: 5.105.0(@types/react@19.3.0)(react@19.3.1)
'@tanstack/react-virtual':
- specifier: ^3.14.22
- version: 3.14.22(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
+ specifier: ^3.14.25
+ version: 3.14.25(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
'@types/sax':
specifier: ^1.2.7
version: 1.2.7
@@ -103,14 +103,14 @@ importers:
specifier: ^4.4.0
version: 4.4.0
dotenv:
- specifier: ^18.0.8
- version: 18.0.8
+ specifier: ^18.0.9
+ version: 18.0.9
fflate:
specifier: ^0.8.3
version: 0.8.3
jose:
- specifier: ^6.2.13
- version: 6.2.13
+ specifier: ^6.2.14
+ version: 6.2.14
jspdf:
specifier: ^4.2.1
version: 4.2.1
@@ -118,17 +118,17 @@ importers:
specifier: ^5.0.9
version: 5.0.9(jspdf@4.2.1)
lucide-react:
- specifier: ^1.61.0
- version: 1.61.0(@types/react@19.3.0)(react@19.3.1)
+ specifier: ^1.66.0
+ version: 1.66.0(@types/react@19.3.0)(react@19.3.1)
mmdb-lib:
specifier: ^3.0.3
version: 3.0.3
next:
- specifier: 16.4.2
- version: 16.4.2(@babel/core@7.29.7(supports-color@7.2.0))(@opentelemetry/api@1.9.1)(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
+ specifier: 16.4.3
+ version: 16.4.3(@babel/core@8.0.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.64.1)(@types/node@26.6.6)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
nodemailer:
- specifier: 10.2.1
- version: 10.2.1
+ specifier: 10.3.1
+ version: 10.3.1
otpauth:
specifier: ^9.5.2
version: 9.5.2
@@ -143,7 +143,7 @@ importers:
version: 12.38.0(@opentelemetry/api@1.9.1)
prisma:
specifier: ^7.10.1
- version: 7.10.1(@types/node@26.6.5)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(magicast@0.5.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(typescript@6.0.3)
+ version: 7.10.1(@types/node@26.6.6)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(magicast@0.5.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(typescript@6.0.3)
qrcode:
specifier: ^1.5.4
version: 1.5.4
@@ -200,17 +200,17 @@ importers:
specifier: ^4.14.0
version: 4.14.0(playwright-core@1.64.1)
'@next/bundle-analyzer':
- specifier: 16.4.2
- version: 16.4.2
+ specifier: 16.4.3
+ version: 16.4.3
'@playwright/test':
specifier: ^1.64.1
version: 1.64.1
'@stryker-mutator/core':
- specifier: 10.0.0
- version: 10.0.0(@types/node@26.6.5)
+ specifier: 10.1.1
+ version: 10.1.1(@types/node@26.6.6)
'@stryker-mutator/vitest-runner':
specifier: 10.0.0
- version: 10.0.0(patch_hash=9ad3e9855fd9781fd36e872ed42c5f934f91b962d6830e6cc56d56bf16e1dabd)(@stryker-mutator/core@10.0.0(@types/node@26.6.5))(vitest@5.0.5)
+ version: 10.0.0(patch_hash=9ad3e9855fd9781fd36e872ed42c5f934f91b962d6830e6cc56d56bf16e1dabd)(@stryker-mutator/core@10.1.1(@types/node@26.6.6))(vitest@5.0.5)
'@tailwindcss/postcss':
specifier: ^4
version: 4.3.3
@@ -224,8 +224,8 @@ importers:
specifier: ^12.2.1
version: 12.2.1(supports-color@7.2.0)
'@types/node':
- specifier: 26.6.5
- version: 26.6.5
+ specifier: 26.6.6
+ version: 26.6.6
'@types/pg':
specifier: ^8.23.1
version: 8.23.1
@@ -243,7 +243,7 @@ importers:
version: 3.6.4
'@vitest/browser-playwright':
specifier: ^5.0.5
- version: 5.0.5(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(playwright@1.64.1)(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))(vitest@5.0.5)
+ version: 5.0.5(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(playwright@1.64.1)(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))(vitest@5.0.5)
'@vitest/coverage-v8':
specifier: ^5.0.5
version: 5.0.5(@vitest/browser@5.0.5)(vitest@5.0.5)
@@ -254,14 +254,14 @@ importers:
specifier: ^9
version: 9.39.3(jiti@2.7.0)(supports-color@7.2.0)
eslint-config-next:
- specifier: 16.4.2
- version: 16.4.2(@typescript-eslint/parser@8.71.0(eslint@9.39.3(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.3(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3)
+ specifier: 16.4.3
+ version: 16.4.3(@typescript-eslint/parser@8.71.0(eslint@9.39.3(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.3(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3)
fast-check:
specifier: 4.10.2
version: 4.10.2
knip:
- specifier: ^6.42.0
- version: 6.42.1
+ specifier: ^6.44.1
+ version: 6.44.1
lefthook:
specifier: ^2.2.2
version: 2.2.2
@@ -275,8 +275,8 @@ importers:
specifier: ^0.8.1
version: 0.8.1(prettier@3.9.10)
shadcn:
- specifier: ^4.22.1
- version: 4.22.1(@cfworker/json-schema@4.1.1)(supports-color@7.2.0)
+ specifier: ^4.23.0
+ version: 4.23.0(supports-color@7.2.0)
tailwindcss:
specifier: ^4
version: 4.3.3
@@ -291,7 +291,7 @@ importers:
version: 6.0.3
vitest:
specifier: ^5.0.5
- version: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@26.6.5)(@vitest/browser-playwright@5.0.5)(@vitest/coverage-v8@5.0.5)(@vitest/ui@5.0.5)(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))
+ version: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@26.6.6)(@vitest/browser-playwright@5.0.5)(@vitest/coverage-v8@5.0.5)(@vitest/ui@5.0.5)(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))
vitest-browser-react:
specifier: ^2.3.0
version: 2.3.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(vitest@5.0.5)
@@ -302,78 +302,78 @@ packages:
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
engines: {node: '>=10'}
- '@aws-sdk/checksums@3.1001.5':
- resolution: {integrity: sha512-6erto9nK2OZO/woEgmFIaPh5gChgdNd7nL6jgAf8TAXz3/QHC8Pan2TFe9GYp3IxOIKCCGWPylSjtOHKfNzQlw==}
+ '@aws-sdk/checksums@3.1002.1':
+ resolution: {integrity: sha512-CXNESwkQC9jdrUG6cKXBfudVt1frGcYQykcCYbNclVrsewuGMbo3PlFjRteMe4OftNAqhyc3xC2jTz7SUqLasQ==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/client-s3@3.1155.0':
- resolution: {integrity: sha512-l3uMeIlzWVgj/RTJTh5sKYKtQz1la3cvWLUPn1cwFH4UZpcqTH66SgJHCeB2FOE9bEAjOdbmCyPKt9aw867Fng==}
+ '@aws-sdk/client-s3@3.1159.0':
+ resolution: {integrity: sha512-el/Ihylk4PjJh/uJvYUeAzBiVLR6zt0xBOPIbciybePABWD/cOcxinHEPQslogm61LI2etnRrixSQltX94gzLA==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/core@3.978.5':
- resolution: {integrity: sha512-ruI0AWqcrfL20XDS6SwZIJFPOBZ6N0ADa9nLzWlBhxk1aoUjbUX3JkTR9vEmk7o35XpAHi68ahZ4T6RE2U9XyA==}
+ '@aws-sdk/core@3.979.1':
+ resolution: {integrity: sha512-ayOlV1VhLNMiq8PW9ZkVobG4gkldnUoHjG69yy2b8j+VYFlhz/uAL7ZdYQAoQ+eShtGUdNDnnG5rxDg6yUJrOg==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/credential-provider-env@3.972.76':
- resolution: {integrity: sha512-YxmL1Ar7bV9ZkJvtv+lj+MF6le76NnZnbmgySyZuxpZaCv0/1lZ3KxKy6RIj1h9ui2hWnVjZxbmTMeO0y/NrQA==}
+ '@aws-sdk/credential-provider-env@3.972.80':
+ resolution: {integrity: sha512-uO5TiSvb6j1w9RTe5z28OaOmsrOxVQUPaC5+wZl50RfOXcrYD/KgnS8I9lfyGXc7sGbkCopK6VnhNIAoLqfewQ==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/credential-provider-http@3.972.78':
- resolution: {integrity: sha512-3VHknDRngoebsaqyT1iR75b5cBT2zfEtODK6yYmYltljkK1HEAQLs2FEd1IpWqAeOYdMGaG9wikngWLTufY7RA==}
+ '@aws-sdk/credential-provider-http@3.972.82':
+ resolution: {integrity: sha512-vQzlDHlC24Yz42p+rT4NBoP/5VdetkBoujbOLq9h6QYWC8THuZSPYnXIR9OP3XcOrdMgPBBipOrdssfxnIiWUg==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/credential-provider-ini@3.973.21':
- resolution: {integrity: sha512-aLx9hbCX6mGAyv4ZZd8UagJ4RASHVJw6BFDSIyuKmLkqNL6H47EjBPK6qaJ4B5TDV6mc+vMa0SJFYyo4mkvVQg==}
+ '@aws-sdk/credential-provider-ini@3.973.25':
+ resolution: {integrity: sha512-b5xl71uCRdWsu7P1VeGpiGuCf6zfYETsSNOv8AmYVTrsgbvTJRXdmmOPVfxkvGGVNsiKkGctClQW3jAn0SZLug==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/credential-provider-login@3.972.83':
- resolution: {integrity: sha512-9bJU6FjRacF4FK/QHf8Dyxhur7B1grRj8C1Yh4IkpoFW2exQflPdCv0VrbemLW9ZctLNle+AE7TETs9KNvuLYg==}
+ '@aws-sdk/credential-provider-login@3.972.87':
+ resolution: {integrity: sha512-C4ZFmcwM+Zj14Z8huVUk54Gv4uzT1ZdzG9cY3Gdh8FePakq7Bss1OFsgZjAhWFOkFOGpBvFBeu0OWjWf8HNKRQ==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/credential-provider-node@3.972.88':
- resolution: {integrity: sha512-AG0KID5qhQPzrFkh5b0Cws1Amytvzo0L0Xj6hMgJXEwD6ZXAqninDhSNAWJiN5zU4YVVZnuidnqwPwYJ04IamA==}
+ '@aws-sdk/credential-provider-node@3.972.92':
+ resolution: {integrity: sha512-jC3zmOo7Qxlk+oBivvSsS1Ph7sFGm0QfuhqDGbqgRXi4cxUYMG+dWtBwS2XYYXgc8TIVXJiwgQ65sbNpbYupTA==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/credential-provider-process@3.972.76':
- resolution: {integrity: sha512-pdhKFTXv1zPYhh92MTlp0jVbLWvUEV9v+rziuEkoskGGQ2iJskxHTO38nA8UAbT/N4IM3n8OZJ9rIY5IBO15/A==}
+ '@aws-sdk/credential-provider-process@3.972.80':
+ resolution: {integrity: sha512-xqfixO5aclje7tbQJDias+iNND5wp/3QZixCdZcVQpgWPTZ0V5DfTW9A804A5Z7ezu7sH3WRO+vzUjtiJBA8yg==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/credential-provider-sso@3.973.20':
- resolution: {integrity: sha512-DlxrAB3MnjNLx/da7b89W+3DyJQYso/q7Ns15MsST2IV2nkAYQOYTUCaffNSjgrpMP99Dm2mV2jxzcbyF94ZfA==}
+ '@aws-sdk/credential-provider-sso@3.973.24':
+ resolution: {integrity: sha512-nlg3BKG03Cgzvv/dMnhxvDJPhAhQSpaN0RUdwgU7ziwkasoev7iI8el8Xy4Rd5sqzgaDUbV269fOXck5SargqA==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/credential-provider-web-identity@3.972.82':
- resolution: {integrity: sha512-LUo46IqPTJ4xKBsrLuoaxiv/D2GTBCcFDMD1y3jKIqPR/p7Rw14RJFZ0iRWftqZtyLPQX9JMGnSi3mBu4y/pNA==}
+ '@aws-sdk/credential-provider-web-identity@3.972.86':
+ resolution: {integrity: sha512-zKTyLJBEyfQBVlYqT6Jt+mYV4r8kGbWM7dn6v4Y4MRARizhYafjDXP/iMu76UMRhToSPNmIKX1XAb24gtpBFIA==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/lib-storage@3.1155.0':
- resolution: {integrity: sha512-ThvepKZILBOGCO1rsRsuAWps6hwfMfFVVhRpNrxup+o0q/Hyi50IaDSGZYxrZMPbWH/8pG2LFld//OYDmyr48A==}
+ '@aws-sdk/lib-storage@3.1159.0':
+ resolution: {integrity: sha512-dJmPlATEBG4jKpdtDliywSb4JO2HZs5QtOwMkK1J/Jb3rw/WUU0z/JkWPqKgEs4GSHaH7Ep3uYY+1Tw64r0C8g==}
engines: {node: '>=20.0.0'}
peerDependencies:
- '@aws-sdk/client-s3': ^3.1155.0
+ '@aws-sdk/client-s3': ^3.1159.0
- '@aws-sdk/middleware-sdk-s3@3.972.81':
- resolution: {integrity: sha512-jfanv1pV0sJFZw6/DPiNjvK7B478god0zOum5yIWo+/+1Gy+CSXWpGBWx+3nBJyDvjcu/2kUMr4ADUp9BHH34Q==}
+ '@aws-sdk/middleware-sdk-s3@3.972.85':
+ resolution: {integrity: sha512-Kyl2G6zhIS9qFoeLdlxvXFrWyc6g9D9ZCIRJnGkkfX6JZhxCZB5ebXBc7GKEeetrnhXcail6ALZT0lKbojcaNA==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/nested-clients@3.997.50':
- resolution: {integrity: sha512-nKb8qu4QsnpZTq/6JIXc72mzuzfh7BK4sUQkpQznPec2z4W7Ob2xYkcM4i5e1yGTBnbJVeFv/0sf3jcz85hclA==}
+ '@aws-sdk/nested-clients@3.997.54':
+ resolution: {integrity: sha512-/OczlavsS7U5sOodRO10Ug4R/AKFVZiXTstKipWe68EfjPkmdDFNXNl9FCJyXWkg1DG6RBm3qAuVB8FNW9O8KQ==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/signature-v4-multi-region@3.996.49':
- resolution: {integrity: sha512-nvuAZNRrRRVCiARRKsYlQ0VnXiEQiq7vXPH+UA+LSo+kN3Djl9eo/V2r0udkw85PnsNshmv2Em1clld5M3j67w==}
+ '@aws-sdk/signature-v4-multi-region@3.996.51':
+ resolution: {integrity: sha512-+aHvUugVBuMPXxgkPfWnTMyGdE/yWS8GHi5+qQ37HowS0YqzrbuaDLznj+Dtmtu5jgCdqz36gXmujOToUhNNWw==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/token-providers@3.1155.0':
- resolution: {integrity: sha512-iIcQnYLhWuq9qOLQbIWFrxF3PF0svVeZvHnUS4DUnO4zUFmFHIyGyjqrntXG+e/5PUgfavV0pYfDIKHxTzN2LA==}
+ '@aws-sdk/token-providers@3.1161.0':
+ resolution: {integrity: sha512-ypbXSofNcSHwf/KA40bFCXJb0MLaAKrfT7sot4dFaA+2lsuXNah4zLRJIAU7Qmvs9PFJ6rnY0bZFEC+mE7attA==}
engines: {node: '>=20.0.0'}
'@aws-sdk/types@3.975.0':
resolution: {integrity: sha512-WQlhs6juByzWOzj5fwxOx0mPJaEqMcG/sDpl3Id61B3XhKE63xY+0QWcnG+sWR/sCfprmreyUo1lM7IKZmHMzw==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/xml-builder@3.972.41':
- resolution: {integrity: sha512-ctjVSyCMegrWfXlx6VqzSBFI6UqmQ5ZlnfMhdLIiWmhoH8UAQxSCP5N3OpG7X3k4LnS7ou74C4mt20+bfTW2aQ==}
+ '@aws-sdk/xml-builder@3.972.42':
+ resolution: {integrity: sha512-smX8/gNP8Kjq+CWTBMZQLQ912vOQjiWExzwzvMO+eujPB5RY8IbtF0AGdUUXHKN7KoDWK9dIcuW0WG269kiP6w==}
engines: {node: '>=20.0.0'}
'@aws/lambda-invoke-store@0.3.0':
@@ -1224,8 +1224,12 @@ packages:
'@levischuck/tiny-cbor@0.2.11':
resolution: {integrity: sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow==}
- '@modelcontextprotocol/sdk@1.32.1':
- resolution: {integrity: sha512-2DdE+SJDtzLEEWzY1ZjY7Q+VcPhcV1KisD3zI4u0XZyktsjHum1mwbMI+JaulUBi2OZk+KJAi2uPXzxichPkdw==}
+ '@modelcontextprotocol/core@2.4.0':
+ resolution: {integrity: sha512-z8QBKqdfXLPzkLQuG4xp8hrVEMm1PZ1IgxMN2sMbJiFiAKOWXnAzogXn2W4aqIBlP1ea6U5yiqVquvUNM1Cj6Q==}
+ engines: {node: '>=20'}
+
+ '@modelcontextprotocol/sdk@1.32.2':
+ resolution: {integrity: sha512-SWsVtH/0vULSQStoZ6xxH2K09Li8fXYTMC64ZeogCdpZ3XSi1eCPOByV1OpuJxuI3OcmHhosDWYyii07tpPsLw==}
engines: {node: '>=18'}
peerDependencies:
'@cfworker/json-schema': ^4.1.1
@@ -1234,6 +1238,10 @@ packages:
'@cfworker/json-schema':
optional: true
+ '@modelcontextprotocol/server@2.4.0':
+ resolution: {integrity: sha512-rgR9yxSaAJ+bcsi/XroT/S2AfPiIWloXAnrdfYSCms9ivVju0ishu/wW0J21Ho6+ZOR1r7RyeRbjiRuF87ix5Q==}
+ engines: {node: '>=20'}
+
'@mswjs/interceptors@0.41.9':
resolution: {integrity: sha512-VVPPgHyQ6ShqnrmDWuxjmUIsO9gWyOZFmuOfLd9LfBGQJwZfy0gvv9pbHSJuoFNIYC7ZDX9aoFwowjcdSC4E8w==}
engines: {node: '>=18'}
@@ -1320,63 +1328,63 @@ packages:
'@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4
'@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4
- '@next/bundle-analyzer@16.4.2':
- resolution: {integrity: sha512-tpNTC/WZYsmmixg3MZfx5JUuTh+Sgryu4eKhe7leQRcXHabztqtTkPCQM1Bk1VsE0trZ3w7NUCC3Zf7SeIBVzg==}
+ '@next/bundle-analyzer@16.4.3':
+ resolution: {integrity: sha512-FGcLziT2rqvGZTxZUjnCzwjCANnigN9vrbCm+1hQtzXbbtc1bXBTRmkXohVqyB/ReF5bOjpM2bNJQhz0PfLk9Q==}
- '@next/env@16.4.2':
- resolution: {integrity: sha512-nTUTFH7G5/J/fmpkjVLegOkqyKOP0CEsJcMsyO4UCYeN1su+YMW/MfaSErnJskL7XM+UDK6aTvslxsRCyya/sA==}
+ '@next/env@16.4.3':
+ resolution: {integrity: sha512-a7tz1QCcWWkwC/rPJcPMJk/UNRu9CFhDd3OHYE5hddbJrs8BqRTalxI6GlKCWEGzRLHN+S/B7a4PAHCtm25aBQ==}
- '@next/eslint-plugin-next@16.4.2':
- resolution: {integrity: sha512-gCTWlw0e+Y6kajpFyKKgA195jUJCRhlzJE0lV7ufe8a+ghIsANWZ0/FiJwg6DuOG1+OvRbcZDcFBoRh3mNJx0g==}
+ '@next/eslint-plugin-next@16.4.3':
+ resolution: {integrity: sha512-oxuC06wt/71h6ACYCV9GbKOfnf5a7VlRe/p80YHTut15TNgDEmynDnaq8t/xhy5rlvk7dhItIPs6H3rvIM4kyw==}
- '@next/swc-darwin-arm64@16.4.2':
- resolution: {integrity: sha512-ONkhFvZNFWlsEHOM/81AtxdyuJP2KRYKYR0JxPwvcu1AuPMMMgcL+wW2luldJvMtZwKtUxoSkCychW5wIeoYSw==}
+ '@next/swc-darwin-arm64@16.4.3':
+ resolution: {integrity: sha512-4yq5EXBt+VDtAZwTyfijaFp5D2C5oz3Ikw5a2kiX2K9nw72vrZX2q5UuAlkPtUMO1tQz6JTKpaKWjS7OOefTDQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
- '@next/swc-darwin-x64@16.4.2':
- resolution: {integrity: sha512-luPCMbOsCoaF+kXJEUjmjmOZg1lC3BflhmUu+ZmW4tBu2vW/4AXak8JBFvePizGkxVmNiAw/r9ra+6UviCWtWQ==}
+ '@next/swc-darwin-x64@16.4.3':
+ resolution: {integrity: sha512-1Rvkn/LUhnEF8WxnRkOrqGhbwXui1bkWFxONKIbN+r7C+9KHDSZ+iUoj4CzymVMWUyZIyx9szcb9+kbKhD500A==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
- '@next/swc-linux-arm64-gnu@16.4.2':
- resolution: {integrity: sha512-xhwFTAncJyaCNy5KqKKuKaIIdCy1/1ZV1s5S1G0hhT7wGMkDTlfJ6aQbfRFnIG/s3/kDrxQ8aycVe+c5QnP8ow==}
+ '@next/swc-linux-arm64-gnu@16.4.3':
+ resolution: {integrity: sha512-dCKpXErGg3abUM6t5JTJV/ottVBTStJB5lRJTbgdUdQaQ+jNHiK56Hsc0YAEg/rinSh42hYG3HWiYmEMdilnxg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
libc: [glibc]
- '@next/swc-linux-arm64-musl@16.4.2':
- resolution: {integrity: sha512-T1PNmfbPcxr5ndtWUL/3wQtLXsz808lq6sc2GrNT5k2oquF7UyqZddHSuAewHVsWsGXe6nsl9HoN1YNriVjuSg==}
+ '@next/swc-linux-arm64-musl@16.4.3':
+ resolution: {integrity: sha512-WwYbhWkhYBvBtib1K4W0kL8MW2snBD2A5b3SN4vPpqalZbZs5+bQ1yzAdepVoOqrFfEW3dmREy4Zs1MrWcrFbw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
libc: [musl]
- '@next/swc-linux-x64-gnu@16.4.2':
- resolution: {integrity: sha512-N9cDUOCGtkJG5PNKDFZUF3xXndrJJcpLp121uAGjIGvO/U2p9tfdNOM9htj7+5f72l0m8rMw/cvYacUJBQoudg==}
+ '@next/swc-linux-x64-gnu@16.4.3':
+ resolution: {integrity: sha512-QymWvfUwDEC5/lpJOsxX5VAbyoR2D13+2Jsjz4be7gT4LPqEgdpkeLIR/HFfCLgKzoMhpJbp6I/JnogyNZHcaA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
libc: [glibc]
- '@next/swc-linux-x64-musl@16.4.2':
- resolution: {integrity: sha512-yY2uh1YhX6ufuYy2FCbw1dqblbhI57GLYAJfCkqD9auTv6pLrH67Uccjc3QMKBeCYAG6lkgu08ExmX1bbjejjQ==}
+ '@next/swc-linux-x64-musl@16.4.3':
+ resolution: {integrity: sha512-Vmjd9D7DpA4Vv3cUlr82QWgJD/BQZmns801vtC5VWHg6jCIA4a5vMKpQnfrM2pyCrp2eV0ENdUg4PlN3bAc2Yw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
libc: [musl]
- '@next/swc-win32-arm64-msvc@16.4.2':
- resolution: {integrity: sha512-j/ArWRIHpMMB6wYLMhr2puTguBt70lNU/Cmjl9p6dTDE8DGknYJMP9PdwPk2dqpCNL/KIX9yfngDvIesxJPmsg==}
+ '@next/swc-win32-arm64-msvc@16.4.3':
+ resolution: {integrity: sha512-lG1pPdPLk7gTyGb00n5JIMLdBJgjb+UEhSdZvFbhUMg0DyC6z4B7RnpSKF9VCd4imkLObVbXOFA0kFCpw7yFow==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
- '@next/swc-win32-x64-msvc@16.4.2':
- resolution: {integrity: sha512-AA4edyWHDko3NCSo0x6GomsdgFb0oR1J3MXU1b5xt6FRFg4AucrMPW3S0hCe/9onU0O1BbpGQBsqo1r0Gneu1g==}
+ '@next/swc-win32-x64-msvc@16.4.3':
+ resolution: {integrity: sha512-NmQC9RkJdnPXRaMxtkCzobB3teVjqF33oSOnwDfi+XYGWWYpt+xlGK3mtktSKLbdjwaWbJu2OkkMiRFGUUncKg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
@@ -1503,124 +1511,124 @@ packages:
resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==}
engines: {node: '>=8.0.0'}
- '@oxc-parser/binding-android-arm-eabi@0.154.0':
- resolution: {integrity: sha512-sDdEtDl7vKdCvf54j72RJbowE3jCmyRz/+oOB6IAwQxAHZ0eI+Dcj4hvVnm0b9Dy31plUkdmfds9C+/Zt895Tg==}
+ '@oxc-parser/binding-android-arm-eabi@0.155.0':
+ resolution: {integrity: sha512-A6xv7hDtnTm+xlZ7utn6rRQpRMJHRhVr3gjRGqlx0RUX84mNk0pAsy6YN/wWhuOTkaZhRrrzaLxf0NfbH77j2w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [android]
- '@oxc-parser/binding-android-arm64@0.154.0':
- resolution: {integrity: sha512-UHrDPELzvWZoVkIDdSycj4bzcTMCJG3IbN++mSUgVBaUtNtWHjQ98U6Vz5bpF/1Ic3FYJyYhMr74huO5tVvpZw==}
+ '@oxc-parser/binding-android-arm64@0.155.0':
+ resolution: {integrity: sha512-T1wWwH9/JI5g7Z4kEQwDOwhToxdDhRyOTklH+uuNpJ16m3MZFmGl+l2rKc0NHQdbVRG2LTOBsNjpW3h1BWytPA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
- '@oxc-parser/binding-darwin-arm64@0.154.0':
- resolution: {integrity: sha512-mokYzajOSXxtSRDWCdHARGdntrKH+rZZ24Jzo8AtafyNzz0NARmpMm26Tc5B6qiGrr6UliWibHCOif1qRN2vaA==}
+ '@oxc-parser/binding-darwin-arm64@0.155.0':
+ resolution: {integrity: sha512-ZoRB3qJxJ8DWA41jHja+YeB0lLfjBy4T+Kr15vnN1k65X3zbJt3rPZftEwN4Ju4tmA4K/T9dWWD7Z8ewQLnrVA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
- '@oxc-parser/binding-darwin-x64@0.154.0':
- resolution: {integrity: sha512-WbtUBrclOVItWfLRSvs+Z/WLtXxJ2Ctv50PyuX894HzDN5/e0qzxVpTNPIVMzOerBhgKtFsSMcfxlYIAbvdVgg==}
+ '@oxc-parser/binding-darwin-x64@0.155.0':
+ resolution: {integrity: sha512-vxtL86BtM+IgrpejA86nbTk5j0HKTIMeuaJ1fQciw6p9RfavPtIPjI7gN34owap0yG9txXBaAWpGdxokNwdqIw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
- '@oxc-parser/binding-freebsd-x64@0.154.0':
- resolution: {integrity: sha512-YooHZSLawOe2fqm+lDdG8oAaQh2NYV/RMYTYzWRLy72stm2BgE9O/8Al6kFENjkmzyyBccDLLBirGxVtpzQfrw==}
+ '@oxc-parser/binding-freebsd-x64@0.155.0':
+ resolution: {integrity: sha512-tN6Ru5e0UVnWaIuiH8jEwnvxuxg7FvhWwSd3oe5oDhOD4ObsSr9/N6WfHLjilUWlPPj65ptwrSDH0Y7lzwTzmw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
- '@oxc-parser/binding-linux-arm-gnueabihf@0.154.0':
- resolution: {integrity: sha512-hKOwhZbrXdTwc4bGVfbLCXl9f2swl6zWdISocLQSNX9MgPmwHE3qGzOUkCrkuGpwdCVHPnkfOwsqTuYsrP5uNg==}
+ '@oxc-parser/binding-linux-arm-gnueabihf@0.155.0':
+ resolution: {integrity: sha512-h4ozA5n6L6lwolsz9iwunEhKWnIVbmFRots5QxEix0H6nJ5ICpuDa7PuShuhfpIDFe3+Qvyscioyiv+9g+4Syg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
- '@oxc-parser/binding-linux-arm-musleabihf@0.154.0':
- resolution: {integrity: sha512-tnjiooXEU013349O/yxKbF5Cusp1CfHWQ8kYR8tGeRzR/P4sOpQGQo21fsS71M0fMD6ESLq+lbvXFWi43PuKeQ==}
+ '@oxc-parser/binding-linux-arm-musleabihf@0.155.0':
+ resolution: {integrity: sha512-058/+LardpfuUlsKIvBGk/CYoakEVcMgqYx8GgyUZeOxFWTojYLlCc1Gb60/y21v3esDhHidgiY/Zbq9LpBhaQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
- '@oxc-parser/binding-linux-arm64-gnu@0.154.0':
- resolution: {integrity: sha512-Cao2kj+8d7BT6XJU1gV9eVQjV+Cr+e8vQm3tddDRZiM2hHrMDxwy3j6t+ofaSl0idyuPPCZ4AlpmQoj8yOT1QA==}
+ '@oxc-parser/binding-linux-arm64-gnu@0.155.0':
+ resolution: {integrity: sha512-nrOt2Y3xIAzu+lSPzH0864ieO+iCCXgoo9qFlGANE8Xh0cQ+RP8Wstfp+/wXN2YCyb98cAGzX0VruKYw7it/jw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
- '@oxc-parser/binding-linux-arm64-musl@0.154.0':
- resolution: {integrity: sha512-uiwA0V3q8llWA7/8r+a9BBjk4j5YMDmi6wfOsyQfGOJMQSLHEiZ3HI8ulea766ykUa9wJFWk9XWEl4uJrZLQqw==}
+ '@oxc-parser/binding-linux-arm64-musl@0.155.0':
+ resolution: {integrity: sha512-KYAayyN5hQbJPtGKtRxlyc8XYmyntOplyXSQzTDrmbz7l/GCrzQbSswvyJFBTH1LGtsZrbXOAfN52i/Kz6kLKg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
- '@oxc-parser/binding-linux-ppc64-gnu@0.154.0':
- resolution: {integrity: sha512-LICfN0Xs4Zdko+bJy6eOAEQojDuIR26suF2JtOsMaXjgbCrpRSH7/NCvJhY13YvYBx12V6hnwrL8n0lk0rbNJQ==}
+ '@oxc-parser/binding-linux-ppc64-gnu@0.155.0':
+ resolution: {integrity: sha512-CSuSY5hfjtsBnHXydOj8jiNfS1qHbdPZuPz1YL1cSgK7VmNYP+QlZIbG0BBYYBgX/vYEgZwbG9mBdW4YairZ5w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
- '@oxc-parser/binding-linux-riscv64-gnu@0.154.0':
- resolution: {integrity: sha512-gbbSYxLF8ssRbQ2qQPy+2EhGNwNH1bAoRdkk6cnWaKHqmCikpSIPtpXjFbCCtjTi0uojqOM3ghFQwQPbDQsU0Q==}
+ '@oxc-parser/binding-linux-riscv64-gnu@0.155.0':
+ resolution: {integrity: sha512-7KCfOQm+Nz2N8trAXbQkal4TQ5756WVEmhm35y816YHvyFnEfVsICsiV5k0pEszNf/fRm4cm2i6i18SJ6/iCWg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [glibc]
- '@oxc-parser/binding-linux-riscv64-musl@0.154.0':
- resolution: {integrity: sha512-nSnRYYDLCcRVjSQzF3g6rKqCNYwo5o+aQgnn8BBXfe+ofCgMGlGqkfRyvXm6ptZvoxNkkWtLlqM8W7Xc3j6ZnQ==}
+ '@oxc-parser/binding-linux-riscv64-musl@0.155.0':
+ resolution: {integrity: sha512-JSlhgoK+/g1TGJI5NuADx2+6syhxnQNLCWLXyO5QLFyetomcr/vIxSdiNlmyAv963YXUzCuwAwRG6npZ5xyJ1A==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [musl]
- '@oxc-parser/binding-linux-s390x-gnu@0.154.0':
- resolution: {integrity: sha512-BxBQoJKtzRQgZEKQIt6CDUm8RGKC5T8Qo4576yDa5/xgc10X3fBDItMbRabzLtbUBfTqKLl+8AVr/H6CF7W22g==}
+ '@oxc-parser/binding-linux-s390x-gnu@0.155.0':
+ resolution: {integrity: sha512-WFIX+dPokWp64mi434Md3U3lJaTwNxAphvGjpltoyQjGUsdXavOIRrnp9dOS34Hd75HOAwDxAI+YwWOwqmJbtg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
- '@oxc-parser/binding-linux-x64-gnu@0.154.0':
- resolution: {integrity: sha512-/whkust2vYy+GjRUVL5cWaJmEu6jkdFfo5mkxgckyeOX61eMwo4iBoiwzeJZeMWAdzb/XOtQyLApHhFht3sOWA==}
+ '@oxc-parser/binding-linux-x64-gnu@0.155.0':
+ resolution: {integrity: sha512-g6xSDC/JpbnVOz5uafMGyK3txBVRFMQTx8opv/yHXGxqV3ZMVl3bf7W8XrSnF68dmy3gM4dgReNryuE53+WkeQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
- '@oxc-parser/binding-linux-x64-musl@0.154.0':
- resolution: {integrity: sha512-EXURTyW9riw4B/kZnnE+58emAtw6+3VEszQfXUZkRqGaKIcmWDYkZtKB+xY/blHvuZ+Qy/fDclc31nmUCgtkSA==}
+ '@oxc-parser/binding-linux-x64-musl@0.155.0':
+ resolution: {integrity: sha512-6/4xlxKlZJWrQ0uwDFPc0H9+xLu7068CKhX3vIDW3SbvP/lVgnVuT5v6dyugeWskWpuxqF/WJ4WKwhxjU3pG2w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
- '@oxc-parser/binding-openharmony-arm64@0.154.0':
- resolution: {integrity: sha512-ZRFooyH3qsR6vuR4jFGlG3XM36490SvvXtNaUahBK4zHpooMdTHNaOMtGGJI0EW38m5hi4rOco9kw7ZwCIp28w==}
+ '@oxc-parser/binding-openharmony-arm64@0.155.0':
+ resolution: {integrity: sha512-tltklL0J0XjDxIRTBXWOBhvc2mitcmES45pIxhwDWfxRyqz7Vkeu0NekTZEIxGE4f/lXgq3vZcjjffteQOVorg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
- '@oxc-parser/binding-win32-arm64-msvc@0.154.0':
- resolution: {integrity: sha512-U0Vp+4lvwUa/PnOCJTZOjydj1rX2+VLHz4Y2vSFqlN8/7LTiURgD7z4uQ9yNv9O/NlU3mELBnPDlu7aaSYG1zQ==}
+ '@oxc-parser/binding-win32-arm64-msvc@0.155.0':
+ resolution: {integrity: sha512-alAb9TzjatUEsOeoncAziUnfdTDxfyswhalFZ9sC6plUgATIUx2NIZ0+bMn6aJ28AduS1OpG/OAisr/YISn4Ig==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
- '@oxc-parser/binding-win32-ia32-msvc@0.154.0':
- resolution: {integrity: sha512-Hc8QgsFY5eUUP25we8TISUruibG2cDt0H4IcPG9RKdabb6odkCzIqjV6Gk9beGWGuOwMVCr81H/Su1q363LCCg==}
+ '@oxc-parser/binding-win32-ia32-msvc@0.155.0':
+ resolution: {integrity: sha512-yc5cbSfcGmRv/KpxDFuyk8adEBaWd/9HilWvBbQ4bFbus1V2PUh2mGB2Cfq9rqZTqLeiMT8x0skV+LKp9hOMgQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ia32]
os: [win32]
- '@oxc-parser/binding-win32-x64-msvc@0.154.0':
- resolution: {integrity: sha512-hD7judkUMA/hZPoamvKADs6+an1smp8UTK0aMYRijkvi00K/1vl7vEtmyn2JyQ9S+vibtnfcNzxqTLGyJUZCRQ==}
+ '@oxc-parser/binding-win32-x64-msvc@0.155.0':
+ resolution: {integrity: sha512-8heq6jGq+rfpTDRDjoQiBHw0maQZf3IXkS99pdHQZPoTL5kyF5qyPS0RidUlSdnWDIqxXb5nux7GBD9cT+imUw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
@@ -1628,8 +1636,8 @@ packages:
'@oxc-project/types@0.139.0':
resolution: {integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==}
- '@oxc-project/types@0.154.0':
- resolution: {integrity: sha512-KYOUGQFlLWR+s4QMV2Q9ko38TZm7EdO87Qm7rvZLqk/webse/cDjtyxKhg/47l0byCbs/k46LT8qc4PKjAikzA==}
+ '@oxc-project/types@0.155.0':
+ resolution: {integrity: sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==}
'@oxc-resolver/binding-android-arm-eabi@11.24.2':
resolution: {integrity: sha512-y09e0L0SRI2OA2tUIrjBgoV3eH5hvUKXNkJqXmNo5V2WxIjyC7I7aJfRLMEVpA8yi95f90gFDvO0VMgrDw+vwA==}
@@ -1734,8 +1742,8 @@ packages:
cpu: [x64]
os: [win32]
- '@parse/node-apn@8.1.0':
- resolution: {integrity: sha512-LowcdkKPDikbbzIr3zwEdoFW5wfEbbTzpYQeen3S8kKLePG0AQK586Li+OLC7bonyLmlk//Yk3smHZOLSV6TZA==}
+ '@parse/node-apn@8.1.1':
+ resolution: {integrity: sha512-PXhWpSZiMSwxqJm9bR88bYcZGfe8JhauEEcUSbPlgwEEzGExK23Zxfj1a/9zy9/JWxP5VcULUVCvezJqV9mwUw==}
engines: {node: 20 || 22 || 24}
'@peculiar/asn1-android@2.9.4':
@@ -2778,8 +2786,8 @@ packages:
'@sec-ant/readable-stream@0.4.1':
resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==}
- '@shadcn/registry@0.2.0':
- resolution: {integrity: sha512-m3TeqU/+av2kgOLfESHkWzsmhuQuY4NXZd5Y1Rd4lzy4IX3JJ5+k2mYfkq6OT8oMuk2W4GQPAkO7+CC7KlpSbw==}
+ '@shadcn/registry@0.2.1':
+ resolution: {integrity: sha512-wMvZ3DGdnhCwtpeFbwKybSGfCcP52bZX77jMKgZvupmirgyA5KRLlkeQXkI2RGHIaD8TX2iWe2wcIEjjqzg2FQ==}
engines: {node: '>=20.18.1'}
'@simplewebauthn/browser@14.0.0':
@@ -2793,8 +2801,8 @@ packages:
resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
engines: {node: '>=18'}
- '@smithy/core@3.36.2':
- resolution: {integrity: sha512-oRw0rB9QSUiCZfEs23G5F4Af+b2rQt1lItIICWu5IejFNd+uPM8SWqiKLMpQ6bX1Q7slsLbjuoE2niErFtkVPQ==}
+ '@smithy/core@3.38.1':
+ resolution: {integrity: sha512-U/mB2XiwTLaf+NSgLSWwJfptsMT/H8aBi0aTAA/E5e2/TagFeGCqAyhKGG0w0A9IWTkm4qYEmLoD/HB6aYfnRA==}
engines: {node: '>=18.0.0'}
'@smithy/credential-provider-imds@4.5.2':
@@ -2805,12 +2813,12 @@ packages:
resolution: {integrity: sha512-ycSJu3tFAQ4v04CBB0agqFMVsSQ1iG3yw+SpgxRqKfaURpQD4CZ8Wn0zPMmSnOuTpTh65Vz+EA0rMrw089wvkA==}
engines: {node: '>=18.0.0'}
- '@smithy/node-http-handler@4.12.1':
- resolution: {integrity: sha512-ThMkboGeONWXAelq9FvGsuJC4rOi+qyC4/zhUF58xYpxUg5sQKx2VXZYJmtNjr4dSuBJ1HeJXETQILCz3wOHvw==}
+ '@smithy/node-http-handler@4.14.1':
+ resolution: {integrity: sha512-/T6E1jzCL0fErS9uq8JqES/5yYQQ4ppVmmYHwXw2nlov8KFzLb+3QqHR5iAun1BsuAB50IPxZliV8YMgghLwhA==}
engines: {node: '>=18.0.0'}
- '@smithy/signature-v4@5.7.4':
- resolution: {integrity: sha512-tHy0K0VtqNd5Y7Y41h0a0Lhh0L1GzC08dTWg0F7vRJWFtTENg7IZikf3wQkanYIRdb7ngoIPMTmqgUi401fEeQ==}
+ '@smithy/signature-v4@5.7.5':
+ resolution: {integrity: sha512-WPjdr5oWOk1LArpI4pavu+fSo+/evi0Re1olxGvqwuZopd4gYR1UGCi+Soyn/IjmafqbWs+ZC+3AKxJS3ZpwUg==}
engines: {node: '>=18.0.0'}
'@smithy/types@4.19.0':
@@ -2827,18 +2835,25 @@ packages:
resolution: {integrity: sha512-ZtAJ0ZT3MVRCWJTBE2h90XB/6E+4lifHYtcTyNG6nU2nLekPgTo4gD5esjX6Okxo1b/JB4jJzyxYB54fwKAoJw==}
engines: {node: '>=22.0.0'}
- '@stryker-mutator/core@10.0.0':
- resolution: {integrity: sha512-ZvMsRyaXQQ5e6Thcid9pkuODv6Fn9E3nrBQJUap+hcJuGJ4unm26afo3m6YKSjn8kinyxJ/3TXf0cTWRDaTxVw==}
+ '@stryker-mutator/api@10.1.1':
+ resolution: {integrity: sha512-3s/ECsrD1Tf1WEB7amBk0HxjN7zgkabKvmqnI2C831rTNszJ6o2HoV9PVxtElDEWxb2+t4iavK5x25G+DTUOUA==}
+ engines: {node: '>=22.0.0'}
+
+ '@stryker-mutator/core@10.1.1':
+ resolution: {integrity: sha512-4xJAOCw9utJMLyrTk9gINi434tBxnyuwt8lU/InyoKagKd2/zh/2ui7ncWoD0qZeJrxClYzblg8iUh5ewBAB3Q==}
engines: {node: '>=22.0.0'}
hasBin: true
- '@stryker-mutator/instrumenter@10.0.0':
- resolution: {integrity: sha512-B7Wmn1KlEWyFeOz6D6oGvQGRfi5Xw3VemG6dEKvFQp4qLvxD9Mf4kcZghfxffgnYwXd3bFgqXsJ+ZGlhdfIOrQ==}
+ '@stryker-mutator/instrumenter@10.1.1':
+ resolution: {integrity: sha512-Vyude2i8LhDciLV1q6J55KtdA7gZpRuMfZcBcmWV6hLHAvWocoPKnCKc5BlZt1mwGWkX3Olc0457I7Ue6F1WEg==}
engines: {node: '>=22.0.0'}
'@stryker-mutator/util@10.0.0':
resolution: {integrity: sha512-LzOpHiJaCp2ABQgnPMlrQQcsK43bd5Vo/2FGL78aN62yDoeRQ+4j3tzeuXxK5OAHdC3fUz6TDoy4IsoAuLAd3w==}
+ '@stryker-mutator/util@10.1.1':
+ resolution: {integrity: sha512-Z0zDzsmhoSykE1gT3DvD1knFxySgNMfBlpSSs1j87kWvjEMfeMqfLOk0bqEPRg/rTFIUNSEXLZapxePUhZmfZA==}
+
'@stryker-mutator/vitest-runner@10.0.0':
resolution: {integrity: sha512-SHK2/vfvRUpiz7jXPnQMBnr6zLdm69DK03Mo5mPhaZWcRSygrKUqYsPqWsXsK+5ySHzlMTfCyFK5NQ/X9sJFFw==}
engines: {node: '>=22.0.0'}
@@ -2941,11 +2956,11 @@ packages:
'@tailwindcss/postcss@4.3.3':
resolution: {integrity: sha512-JTSZZGQi1AyKirbLN3azmjVzef92tcX7h+iSqPdaeStyFpGpDlKvvpxeOE8njhbUanbRwr3z8DyzhICWnMtQeg==}
- '@tanstack/query-core@5.104.5':
- resolution: {integrity: sha512-Q94gI8Opd+CbdVNOdj8ZCyV8WqLYitrDq1t96Xc8WZT6lY0r5iRnJLXYDxMex7EEf2v+mXvn4FcjaBKSxXZQ9A==}
+ '@tanstack/query-core@5.105.0':
+ resolution: {integrity: sha512-7p56vRmT/z4UJ6sctGIdl5WRUQyUv53IUpUwEKi2g97zMbO7zh8ZsCLffGAvCPBR4xD72e3VXsDyLwXHhoNTMQ==}
- '@tanstack/react-query@5.104.5':
- resolution: {integrity: sha512-RORgFe052U+93weaNuqg7qHq7vNVNzXN/VrXqD4bbAuQCWUqOl2lV5Ui9flWk5CVvMyL/Bh27QWhzwH0aaOx9g==}
+ '@tanstack/react-query@5.105.0':
+ resolution: {integrity: sha512-y+hMuDERvgg6ay1da0V1a6ZC0ZONt7dELxSFkqRZuwm7p1TTZs0MoXrPlBRflIpRoYjvzQVYxycnLImpFLhWrw==}
peerDependencies:
'@types/react': ^18 || ^19
react: ^18 || ^19
@@ -2953,14 +2968,14 @@ packages:
'@types/react':
optional: true
- '@tanstack/react-virtual@3.14.22':
- resolution: {integrity: sha512-zNiB9IF3prySTfAUrj9tPHjD/lonBYkfxrPP4v4ITUx+qwHajJR5cY/xirjvwc+KWkur10GX3TpsbKh7JkD8Lw==}
+ '@tanstack/react-virtual@3.14.25':
+ resolution: {integrity: sha512-LYNLaogi8NZUqjPgJ0byKQrXprkDJsZLd94u0i1UpYtXz2fgvbP4KrHygM4MSgSAvEaqykQofYdJ1Vuf7XIz/Q==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
- '@tanstack/virtual-core@3.19.7':
- resolution: {integrity: sha512-gxy5SvH0mFRJ0YujtrflB/1HAu9Wn1KGvL0bjZfQkYVVMsIpQiwcf1mR06/ViN4NjllUb4HNCjqE9FGwgTvMCQ==}
+ '@tanstack/virtual-core@3.19.10':
+ resolution: {integrity: sha512-/ltpH0qUCs5XQYE7fIhgA+aqgC5NzSfLTDQkC+N1wOOdvIYx1FH/kz2LGfSeanNbekqy3WBu6mNIbqXhxE/pew==}
'@tesseract.js-data/deu@1.0.0':
resolution: {integrity: sha512-3ter1p2gFAiCd5CMC+PodZ9YY2UDomkKj+ytlKeeZqOUmhLx1SDnYPf5zog0g5MBbxYveW+8omI3PUflqHfZ4Q==}
@@ -3073,8 +3088,8 @@ packages:
'@types/node@18.19.130':
resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==}
- '@types/node@26.6.5':
- resolution: {integrity: sha512-uMzsv9stDdofIZBx4UGh4Z9ZgXnGC9seRDscilBcTHAeOFk67MZg/k9bWVfO+bk4qZmG+l52hRnLwUiH2LnJTg==}
+ '@types/node@26.6.6':
+ resolution: {integrity: sha512-MzQj+8Kx3XI40OmUAE6Qoh58ZMNstNNMwn2nfd3qWsfe7nDNSqJNzes4njhz6AHwrSHOffSLwXU6yb474Q4aog==}
'@types/pako@2.0.4':
resolution: {integrity: sha512-VWDCbrLeVXJM9fihYodcLiIv0ku+AlOa/TQ1SvYOaBuyrSKgEcro95LJyIsJ4vSo6BXIxOKxiJAat04CmST9Fw==}
@@ -4133,8 +4148,8 @@ packages:
resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==}
engines: {node: '>=12'}
- dotenv@18.0.8:
- resolution: {integrity: sha512-2KDeoFoK/zRtcnbunCDlLG5VWVMcyqeQc6iK65o231nfNAcuGrKoqUQfJFUtBI+QlShk5HKIHxwebBtUl3rEfA==}
+ dotenv@18.0.9:
+ resolution: {integrity: sha512-3fVOW4cB02R066PUSwn8O4TJyz9NckQl7F81blIbaq9jKBm2tSmOKky7ZHIXzGvkVPXCSn6jkpziBPZdGFs8Tw==}
engines: {node: '>=12'}
hasBin: true
@@ -4256,8 +4271,8 @@ packages:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
- eslint-config-next@16.4.2:
- resolution: {integrity: sha512-P33vjcETMXc+qBjpF77TeJHZLzk6cPcTy8KjpxLucYB3mCIFIORMcZ+cBXcAiIYjE5RM7jyknEEOwMNdnx/ADQ==}
+ eslint-config-next@16.4.3:
+ resolution: {integrity: sha512-j9IqBma6abp800frdUURaizYMgXOK+jNGyq6CsYcM9AxpSJs5D/TgMNGeAmRUilZvA7g9V1Tr71gNg9/SVTuMQ==}
peerDependencies:
eslint: '>=9.0.0'
typescript: '>=3.3.1'
@@ -5044,6 +5059,9 @@ packages:
jose@6.2.13:
resolution: {integrity: sha512-7TIg10ZE1x82YediN+lcrPNvGMKge9yFHQD+Qho/b8y2adfugU3AsvvHfxV0fzyFllT6l9xCjf4RWY9g/Z9PJQ==}
+ jose@6.2.14:
+ resolution: {integrity: sha512-3JasLuki1NRLQvY4wCoC37KZk4qxoBx2k2aFqLxT84IezqW0bkJKnNtxnZj/Fu1xsQivoc/lytxaRHJoGLjJ1A==}
+
js-md4@0.3.2:
resolution: {integrity: sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA==}
@@ -5128,8 +5146,8 @@ packages:
resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
engines: {node: '>=6'}
- knip@6.42.1:
- resolution: {integrity: sha512-gKJVsiT4LJQ0lfc8uSHOCzkOY8adAXNFGarIeODZbJOkBnQRVsG3e0UZFnO4LMwjA82A5tBWX/VgoeTYcjdKiQ==}
+ knip@6.44.1:
+ resolution: {integrity: sha512-Hbd8nvkIsNgFfXgC7Jsb5LHv7jj6VwA3tmfHd53XPX2z9Vc9RnAZqV0BIiP4OrtYqKwCoLseFHQZerb1bNlbSw==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
@@ -5421,8 +5439,8 @@ packages:
resolution: {integrity: sha512-5J9ysMYUpYIg9RF2vJpy9SinEmSviFSe0GyPpCQ4L5QSkLAgeLXlTAOu2ZwWUU5m+0SBl6gUU1R1ZQB3aKypfA==}
engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'}
- lucide-react@1.61.0:
- resolution: {integrity: sha512-v2SQPPPNjnr+BlhL9Spuzmo5yR+hLkftfuE4E3jaxdNPgSH0hJKPcLJBP7yAta87jQNPsSERS59PJjCJ/CorBA==}
+ lucide-react@1.66.0:
+ resolution: {integrity: sha512-8zjbi/Us+ETXqfBwmXF/FHrWGIqOdE6zT1yUdRJLQVoptomSkB0zdFWVIM667t9K8djWDaXdkBkqi2qVTuDNiw==}
peerDependencies:
'@types/react': '*'
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
@@ -5592,8 +5610,8 @@ packages:
resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
engines: {node: '>= 0.6'}
- next@16.4.2:
- resolution: {integrity: sha512-r+oBJojfefUjOiWkBhXgLS+igxX/7BWyK59uHnyOyplMSLtBZ+QLP3okrdYTbrfrbrmNTVWLBPaHDX9KRaIt3w==}
+ next@16.4.3:
+ resolution: {integrity: sha512-OqxKTGi9u80FydydsMNYNjnuje9Au+kvHlt2GZ//ftdpDHm1dxKqAaENoOOTX5wKzn+9vaKUNIfZeyZUuLhCnA==}
engines: {node: '>=20.9.0'}
hasBin: true
peerDependencies:
@@ -5634,8 +5652,8 @@ packages:
resolution: {integrity: sha512-BdiKAgbfRlvfMq/XzO/AF9NPmaA8a+YpLAyAFTVFBj3gARrAIfWvNq7Q7NE4se3KgFu0KkrvQMxTS0XVnsGzHg==}
engines: {node: '>=18'}
- nodemailer@10.2.1:
- resolution: {integrity: sha512-ZrDNsPFoDMwefNs7sJwrYiEJ/CG4ClJWDZv05iNJsEBWa8GRDry1QJHTJxsuTAY9eDDKjX4k+q3SxslXJOao7w==}
+ nodemailer@10.3.1:
+ resolution: {integrity: sha512-uF0AFsJC07Y1vdW7p580DKAnh7rAO+4UPSSB3mDCPNDufoiaOebV6JmrzpxB14OjEEEiBsNdYoM2Y+fN8M7BBA==}
engines: {node: '>=20.0.0'}
non-error@0.1.0:
@@ -5746,8 +5764,8 @@ packages:
resolution: {integrity: sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==}
engines: {node: '>= 0.4'}
- oxc-parser@0.154.0:
- resolution: {integrity: sha512-Gr/6fkjZwi937c4Tsz8y0iO4U0FLPkZI6JSVucLAIvQyqh379px7RS8ORIc0HOORbFjXZ6zyqWLl53qxhSeofw==}
+ oxc-parser@0.155.0:
+ resolution: {integrity: sha512-C/ReSf1JUFukK/zvk6jhcNibSssvas5+ktIzK7fbKVd3CedWe59C3QwHEOrEZj/4Rt9+xg0Jeis/Jv1F/KM1mw==}
engines: {node: ^20.19.0 || >=22.12.0}
oxc-resolver@11.24.2:
@@ -6114,10 +6132,6 @@ packages:
engines: {node: '>=10.13.0'}
hasBin: true
- qs@6.16.0:
- resolution: {integrity: sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==}
- engines: {node: '>=0.6'}
-
qs@6.16.1:
resolution: {integrity: sha512-5Px6J7rfHBAGUhNQ3es4YzcOdBBw0SDcVtThJml4RdnKw4tKs2epA0kPZ+K8X+WiHktT93RHVcQ/3ym5aTCgtg==}
engines: {node: '>=0.6'}
@@ -6387,11 +6401,6 @@ packages:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
- semver@7.8.0:
- resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==}
- engines: {node: '>=10'}
- hasBin: true
-
semver@7.8.5:
resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==}
engines: {node: '>=10'}
@@ -6430,8 +6439,8 @@ packages:
setprototypeof@1.2.0:
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
- shadcn@4.22.1:
- resolution: {integrity: sha512-LbB4Lro+b0qSVki/tgL5edtKylEnXe1ppxMJC12d7NHPgaT+eSgJGMQULwP72V7X9tbiUq7xfx3VDAfB7jdGoA==}
+ shadcn@4.23.0:
+ resolution: {integrity: sha512-lKgq7QPFgkV/6EOrMCwvEn7ZAw/YnM/grhxzJmK4cZdw3E4F3Ut2EmWvrn2E+vzJp1y/76mxU185OSkXo9Ff+Q==}
engines: {node: '>=20.18.1'}
hasBin: true
@@ -7269,166 +7278,166 @@ snapshots:
'@alloc/quick-lru@5.2.0': {}
- '@aws-sdk/checksums@3.1001.5':
+ '@aws-sdk/checksums@3.1002.1':
dependencies:
- '@aws-sdk/core': 3.978.5
+ '@aws-sdk/core': 3.979.1
'@aws-sdk/types': 3.975.0
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/types': 4.19.0
tslib: 2.8.1
- '@aws-sdk/client-s3@3.1155.0':
+ '@aws-sdk/client-s3@3.1159.0':
dependencies:
- '@aws-sdk/checksums': 3.1001.5
- '@aws-sdk/core': 3.978.5
- '@aws-sdk/credential-provider-node': 3.972.88
- '@aws-sdk/middleware-sdk-s3': 3.972.81
- '@aws-sdk/signature-v4-multi-region': 3.996.49
+ '@aws-sdk/checksums': 3.1002.1
+ '@aws-sdk/core': 3.979.1
+ '@aws-sdk/credential-provider-node': 3.972.92
+ '@aws-sdk/middleware-sdk-s3': 3.972.85
+ '@aws-sdk/signature-v4-multi-region': 3.996.51
'@aws-sdk/types': 3.975.0
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/fetch-http-handler': 5.8.0
- '@smithy/node-http-handler': 4.12.1
+ '@smithy/node-http-handler': 4.14.1
'@smithy/types': 4.19.0
tslib: 2.8.1
- '@aws-sdk/core@3.978.5':
+ '@aws-sdk/core@3.979.1':
dependencies:
'@aws-sdk/types': 3.975.0
- '@aws-sdk/xml-builder': 3.972.41
+ '@aws-sdk/xml-builder': 3.972.42
'@aws/lambda-invoke-store': 0.3.0
- '@smithy/core': 3.36.2
- '@smithy/signature-v4': 5.7.4
+ '@smithy/core': 3.38.1
+ '@smithy/signature-v4': 5.7.5
'@smithy/types': 4.19.0
bowser: 2.14.1
tslib: 2.8.1
- '@aws-sdk/credential-provider-env@3.972.76':
+ '@aws-sdk/credential-provider-env@3.972.80':
dependencies:
- '@aws-sdk/core': 3.978.5
+ '@aws-sdk/core': 3.979.1
'@aws-sdk/types': 3.975.0
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/types': 4.19.0
tslib: 2.8.1
- '@aws-sdk/credential-provider-http@3.972.78':
+ '@aws-sdk/credential-provider-http@3.972.82':
dependencies:
- '@aws-sdk/core': 3.978.5
+ '@aws-sdk/core': 3.979.1
'@aws-sdk/types': 3.975.0
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/fetch-http-handler': 5.8.0
- '@smithy/node-http-handler': 4.12.1
+ '@smithy/node-http-handler': 4.14.1
'@smithy/types': 4.19.0
tslib: 2.8.1
- '@aws-sdk/credential-provider-ini@3.973.21':
+ '@aws-sdk/credential-provider-ini@3.973.25':
dependencies:
- '@aws-sdk/core': 3.978.5
- '@aws-sdk/credential-provider-env': 3.972.76
- '@aws-sdk/credential-provider-http': 3.972.78
- '@aws-sdk/credential-provider-login': 3.972.83
- '@aws-sdk/credential-provider-process': 3.972.76
- '@aws-sdk/credential-provider-sso': 3.973.20
- '@aws-sdk/credential-provider-web-identity': 3.972.82
- '@aws-sdk/nested-clients': 3.997.50
+ '@aws-sdk/core': 3.979.1
+ '@aws-sdk/credential-provider-env': 3.972.80
+ '@aws-sdk/credential-provider-http': 3.972.82
+ '@aws-sdk/credential-provider-login': 3.972.87
+ '@aws-sdk/credential-provider-process': 3.972.80
+ '@aws-sdk/credential-provider-sso': 3.973.24
+ '@aws-sdk/credential-provider-web-identity': 3.972.86
+ '@aws-sdk/nested-clients': 3.997.54
'@aws-sdk/types': 3.975.0
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/credential-provider-imds': 4.5.2
'@smithy/types': 4.19.0
tslib: 2.8.1
- '@aws-sdk/credential-provider-login@3.972.83':
+ '@aws-sdk/credential-provider-login@3.972.87':
dependencies:
- '@aws-sdk/core': 3.978.5
- '@aws-sdk/nested-clients': 3.997.50
+ '@aws-sdk/core': 3.979.1
+ '@aws-sdk/nested-clients': 3.997.54
'@aws-sdk/types': 3.975.0
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/types': 4.19.0
tslib: 2.8.1
- '@aws-sdk/credential-provider-node@3.972.88':
+ '@aws-sdk/credential-provider-node@3.972.92':
dependencies:
- '@aws-sdk/credential-provider-env': 3.972.76
- '@aws-sdk/credential-provider-http': 3.972.78
- '@aws-sdk/credential-provider-ini': 3.973.21
- '@aws-sdk/credential-provider-process': 3.972.76
- '@aws-sdk/credential-provider-sso': 3.973.20
- '@aws-sdk/credential-provider-web-identity': 3.972.82
+ '@aws-sdk/credential-provider-env': 3.972.80
+ '@aws-sdk/credential-provider-http': 3.972.82
+ '@aws-sdk/credential-provider-ini': 3.973.25
+ '@aws-sdk/credential-provider-process': 3.972.80
+ '@aws-sdk/credential-provider-sso': 3.973.24
+ '@aws-sdk/credential-provider-web-identity': 3.972.86
'@aws-sdk/types': 3.975.0
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/credential-provider-imds': 4.5.2
'@smithy/types': 4.19.0
tslib: 2.8.1
- '@aws-sdk/credential-provider-process@3.972.76':
+ '@aws-sdk/credential-provider-process@3.972.80':
dependencies:
- '@aws-sdk/core': 3.978.5
+ '@aws-sdk/core': 3.979.1
'@aws-sdk/types': 3.975.0
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/types': 4.19.0
tslib: 2.8.1
- '@aws-sdk/credential-provider-sso@3.973.20':
+ '@aws-sdk/credential-provider-sso@3.973.24':
dependencies:
- '@aws-sdk/core': 3.978.5
- '@aws-sdk/nested-clients': 3.997.50
- '@aws-sdk/token-providers': 3.1155.0
+ '@aws-sdk/core': 3.979.1
+ '@aws-sdk/nested-clients': 3.997.54
+ '@aws-sdk/token-providers': 3.1161.0
'@aws-sdk/types': 3.975.0
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/types': 4.19.0
tslib: 2.8.1
- '@aws-sdk/credential-provider-web-identity@3.972.82':
+ '@aws-sdk/credential-provider-web-identity@3.972.86':
dependencies:
- '@aws-sdk/core': 3.978.5
- '@aws-sdk/nested-clients': 3.997.50
+ '@aws-sdk/core': 3.979.1
+ '@aws-sdk/nested-clients': 3.997.54
'@aws-sdk/types': 3.975.0
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/types': 4.19.0
tslib: 2.8.1
- '@aws-sdk/lib-storage@3.1155.0(@aws-sdk/client-s3@3.1155.0)':
+ '@aws-sdk/lib-storage@3.1159.0(@aws-sdk/client-s3@3.1159.0)':
dependencies:
- '@aws-sdk/client-s3': 3.1155.0
- '@smithy/core': 3.36.2
+ '@aws-sdk/client-s3': 3.1159.0
+ '@smithy/core': 3.38.1
'@smithy/types': 4.19.0
buffer: 5.6.0
events: 3.3.0
stream-browserify: 3.0.0
tslib: 2.8.1
- '@aws-sdk/middleware-sdk-s3@3.972.81':
+ '@aws-sdk/middleware-sdk-s3@3.972.85':
dependencies:
- '@aws-sdk/core': 3.978.5
- '@aws-sdk/signature-v4-multi-region': 3.996.49
+ '@aws-sdk/core': 3.979.1
+ '@aws-sdk/signature-v4-multi-region': 3.996.51
'@aws-sdk/types': 3.975.0
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/types': 4.19.0
tslib: 2.8.1
- '@aws-sdk/nested-clients@3.997.50':
+ '@aws-sdk/nested-clients@3.997.54':
dependencies:
- '@aws-sdk/core': 3.978.5
- '@aws-sdk/signature-v4-multi-region': 3.996.49
+ '@aws-sdk/core': 3.979.1
+ '@aws-sdk/signature-v4-multi-region': 3.996.51
'@aws-sdk/types': 3.975.0
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/fetch-http-handler': 5.8.0
- '@smithy/node-http-handler': 4.12.1
+ '@smithy/node-http-handler': 4.14.1
'@smithy/types': 4.19.0
tslib: 2.8.1
- '@aws-sdk/signature-v4-multi-region@3.996.49':
+ '@aws-sdk/signature-v4-multi-region@3.996.51':
dependencies:
'@aws-sdk/types': 3.975.0
- '@smithy/signature-v4': 5.7.4
+ '@smithy/signature-v4': 5.7.5
'@smithy/types': 4.19.0
tslib: 2.8.1
- '@aws-sdk/token-providers@3.1155.0':
+ '@aws-sdk/token-providers@3.1161.0':
dependencies:
- '@aws-sdk/core': 3.978.5
- '@aws-sdk/nested-clients': 3.997.50
+ '@aws-sdk/core': 3.979.1
+ '@aws-sdk/nested-clients': 3.997.54
'@aws-sdk/types': 3.975.0
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/types': 4.19.0
tslib: 2.8.1
@@ -7437,7 +7446,7 @@ snapshots:
'@smithy/types': 4.19.0
tslib: 2.8.1
- '@aws-sdk/xml-builder@3.972.41':
+ '@aws-sdk/xml-builder@3.972.42':
dependencies:
'@smithy/types': 4.19.0
tslib: 2.8.1
@@ -8196,122 +8205,122 @@ snapshots:
'@inquirer/ansi@2.0.9': {}
- '@inquirer/checkbox@5.2.7(@types/node@26.6.5)':
+ '@inquirer/checkbox@5.2.7(@types/node@26.6.6)':
dependencies:
'@inquirer/ansi': 2.0.9
- '@inquirer/core': 12.0.5(@types/node@26.6.5)
+ '@inquirer/core': 12.0.5(@types/node@26.6.6)
'@inquirer/figures': 2.0.9
- '@inquirer/type': 4.2.0(@types/node@26.6.5)
+ '@inquirer/type': 4.2.0(@types/node@26.6.6)
optionalDependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
- '@inquirer/confirm@6.3.4(@types/node@26.6.5)':
+ '@inquirer/confirm@6.3.4(@types/node@26.6.6)':
dependencies:
- '@inquirer/core': 12.0.5(@types/node@26.6.5)
- '@inquirer/type': 4.2.0(@types/node@26.6.5)
+ '@inquirer/core': 12.0.5(@types/node@26.6.6)
+ '@inquirer/type': 4.2.0(@types/node@26.6.6)
optionalDependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
- '@inquirer/core@12.0.5(@types/node@26.6.5)':
+ '@inquirer/core@12.0.5(@types/node@26.6.6)':
dependencies:
'@inquirer/ansi': 2.0.9
'@inquirer/figures': 2.0.9
- '@inquirer/type': 4.2.0(@types/node@26.6.5)
+ '@inquirer/type': 4.2.0(@types/node@26.6.6)
cli-width: 4.1.0
fast-wrap-ansi: 0.2.2
mute-stream: 3.0.0
signal-exit: 4.1.0
optionalDependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
- '@inquirer/editor@5.3.5(@types/node@26.6.5)':
+ '@inquirer/editor@5.3.5(@types/node@26.6.6)':
dependencies:
- '@inquirer/core': 12.0.5(@types/node@26.6.5)
- '@inquirer/external-editor': 3.0.6(@types/node@26.6.5)
- '@inquirer/type': 4.2.0(@types/node@26.6.5)
+ '@inquirer/core': 12.0.5(@types/node@26.6.6)
+ '@inquirer/external-editor': 3.0.6(@types/node@26.6.6)
+ '@inquirer/type': 4.2.0(@types/node@26.6.6)
optionalDependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
- '@inquirer/expand@5.1.7(@types/node@26.6.5)':
+ '@inquirer/expand@5.1.7(@types/node@26.6.6)':
dependencies:
- '@inquirer/core': 12.0.5(@types/node@26.6.5)
- '@inquirer/type': 4.2.0(@types/node@26.6.5)
+ '@inquirer/core': 12.0.5(@types/node@26.6.6)
+ '@inquirer/type': 4.2.0(@types/node@26.6.6)
optionalDependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
- '@inquirer/external-editor@3.0.6(@types/node@26.6.5)':
+ '@inquirer/external-editor@3.0.6(@types/node@26.6.6)':
dependencies:
chardet: 2.2.0
iconv-lite: 0.7.3
optionalDependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
'@inquirer/figures@2.0.9': {}
- '@inquirer/input@5.1.8(@types/node@26.6.5)':
+ '@inquirer/input@5.1.8(@types/node@26.6.6)':
dependencies:
- '@inquirer/core': 12.0.5(@types/node@26.6.5)
- '@inquirer/type': 4.2.0(@types/node@26.6.5)
+ '@inquirer/core': 12.0.5(@types/node@26.6.6)
+ '@inquirer/type': 4.2.0(@types/node@26.6.6)
optionalDependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
- '@inquirer/number@4.2.5(@types/node@26.6.5)':
+ '@inquirer/number@4.2.5(@types/node@26.6.6)':
dependencies:
- '@inquirer/core': 12.0.5(@types/node@26.6.5)
- '@inquirer/type': 4.2.0(@types/node@26.6.5)
+ '@inquirer/core': 12.0.5(@types/node@26.6.6)
+ '@inquirer/type': 4.2.0(@types/node@26.6.6)
optionalDependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
- '@inquirer/password@5.2.4(@types/node@26.6.5)':
+ '@inquirer/password@5.2.4(@types/node@26.6.6)':
dependencies:
'@inquirer/ansi': 2.0.9
- '@inquirer/core': 12.0.5(@types/node@26.6.5)
- '@inquirer/type': 4.2.0(@types/node@26.6.5)
+ '@inquirer/core': 12.0.5(@types/node@26.6.6)
+ '@inquirer/type': 4.2.0(@types/node@26.6.6)
optionalDependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
- '@inquirer/prompts@8.7.4(@types/node@26.6.5)':
+ '@inquirer/prompts@8.7.4(@types/node@26.6.6)':
dependencies:
- '@inquirer/checkbox': 5.2.7(@types/node@26.6.5)
- '@inquirer/confirm': 6.3.4(@types/node@26.6.5)
- '@inquirer/editor': 5.3.5(@types/node@26.6.5)
- '@inquirer/expand': 5.1.7(@types/node@26.6.5)
- '@inquirer/input': 5.1.8(@types/node@26.6.5)
- '@inquirer/number': 4.2.5(@types/node@26.6.5)
- '@inquirer/password': 5.2.4(@types/node@26.6.5)
- '@inquirer/rawlist': 5.3.7(@types/node@26.6.5)
- '@inquirer/search': 4.3.5(@types/node@26.6.5)
- '@inquirer/select': 5.2.7(@types/node@26.6.5)
+ '@inquirer/checkbox': 5.2.7(@types/node@26.6.6)
+ '@inquirer/confirm': 6.3.4(@types/node@26.6.6)
+ '@inquirer/editor': 5.3.5(@types/node@26.6.6)
+ '@inquirer/expand': 5.1.7(@types/node@26.6.6)
+ '@inquirer/input': 5.1.8(@types/node@26.6.6)
+ '@inquirer/number': 4.2.5(@types/node@26.6.6)
+ '@inquirer/password': 5.2.4(@types/node@26.6.6)
+ '@inquirer/rawlist': 5.3.7(@types/node@26.6.6)
+ '@inquirer/search': 4.3.5(@types/node@26.6.6)
+ '@inquirer/select': 5.2.7(@types/node@26.6.6)
optionalDependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
- '@inquirer/rawlist@5.3.7(@types/node@26.6.5)':
+ '@inquirer/rawlist@5.3.7(@types/node@26.6.6)':
dependencies:
- '@inquirer/core': 12.0.5(@types/node@26.6.5)
- '@inquirer/type': 4.2.0(@types/node@26.6.5)
+ '@inquirer/core': 12.0.5(@types/node@26.6.6)
+ '@inquirer/type': 4.2.0(@types/node@26.6.6)
optionalDependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
- '@inquirer/search@4.3.5(@types/node@26.6.5)':
+ '@inquirer/search@4.3.5(@types/node@26.6.6)':
dependencies:
- '@inquirer/core': 12.0.5(@types/node@26.6.5)
+ '@inquirer/core': 12.0.5(@types/node@26.6.6)
'@inquirer/figures': 2.0.9
- '@inquirer/type': 4.2.0(@types/node@26.6.5)
+ '@inquirer/type': 4.2.0(@types/node@26.6.6)
optionalDependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
- '@inquirer/select@5.2.7(@types/node@26.6.5)':
+ '@inquirer/select@5.2.7(@types/node@26.6.6)':
dependencies:
'@inquirer/ansi': 2.0.9
- '@inquirer/core': 12.0.5(@types/node@26.6.5)
+ '@inquirer/core': 12.0.5(@types/node@26.6.6)
'@inquirer/figures': 2.0.9
- '@inquirer/type': 4.2.0(@types/node@26.6.5)
+ '@inquirer/type': 4.2.0(@types/node@26.6.6)
optionalDependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
- '@inquirer/type@4.2.0(@types/node@26.6.5)':
+ '@inquirer/type@4.2.0(@types/node@26.6.6)':
optionalDependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
'@isaacs/cliui@8.0.2':
dependencies:
@@ -8356,7 +8365,11 @@ snapshots:
'@levischuck/tiny-cbor@0.2.11': {}
- '@modelcontextprotocol/sdk@1.32.1(@cfworker/json-schema@4.1.1)(supports-color@7.2.0)(zod@4.6.7)':
+ '@modelcontextprotocol/core@2.4.0':
+ dependencies:
+ zod: 4.6.7
+
+ '@modelcontextprotocol/sdk@1.32.2(@cfworker/json-schema@4.1.1)(supports-color@7.2.0)(zod@4.6.7)':
dependencies:
'@hono/node-server': 1.19.17(hono@4.13.13)
ajv: 8.20.0
@@ -8380,6 +8393,11 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ '@modelcontextprotocol/server@2.4.0':
+ dependencies:
+ '@modelcontextprotocol/core': 2.4.0
+ zod: 4.6.7
+
'@mswjs/interceptors@0.41.9':
dependencies:
'@open-draft/deferred-promise': 2.2.0
@@ -8458,44 +8476,44 @@ snapshots:
'@tybys/wasm-util': 0.10.4
optional: true
- '@next/bundle-analyzer@16.4.2':
+ '@next/bundle-analyzer@16.4.3':
dependencies:
webpack-bundle-analyzer: 4.10.1
transitivePeerDependencies:
- bufferutil
- utf-8-validate
- '@next/env@16.4.2': {}
+ '@next/env@16.4.3': {}
- '@next/eslint-plugin-next@16.4.2(eslint@9.39.3(jiti@2.7.0)(supports-color@7.2.0))':
+ '@next/eslint-plugin-next@16.4.3(eslint@9.39.3(jiti@2.7.0)(supports-color@7.2.0))':
dependencies:
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.7.0)(supports-color@7.2.0))
fast-glob: 3.3.1
transitivePeerDependencies:
- eslint
- '@next/swc-darwin-arm64@16.4.2':
+ '@next/swc-darwin-arm64@16.4.3':
optional: true
- '@next/swc-darwin-x64@16.4.2':
+ '@next/swc-darwin-x64@16.4.3':
optional: true
- '@next/swc-linux-arm64-gnu@16.4.2':
+ '@next/swc-linux-arm64-gnu@16.4.3':
optional: true
- '@next/swc-linux-arm64-musl@16.4.2':
+ '@next/swc-linux-arm64-musl@16.4.3':
optional: true
- '@next/swc-linux-x64-gnu@16.4.2':
+ '@next/swc-linux-x64-gnu@16.4.3':
optional: true
- '@next/swc-linux-x64-musl@16.4.2':
+ '@next/swc-linux-x64-musl@16.4.3':
optional: true
- '@next/swc-win32-arm64-msvc@16.4.2':
+ '@next/swc-win32-arm64-msvc@16.4.3':
optional: true
- '@next/swc-win32-x64-msvc@16.4.2':
+ '@next/swc-win32-x64-msvc@16.4.3':
optional: true
'@noble/hashes@2.4.0': {}
@@ -8586,66 +8604,66 @@ snapshots:
'@opentelemetry/api@1.9.1': {}
- '@oxc-parser/binding-android-arm-eabi@0.154.0':
+ '@oxc-parser/binding-android-arm-eabi@0.155.0':
optional: true
- '@oxc-parser/binding-android-arm64@0.154.0':
+ '@oxc-parser/binding-android-arm64@0.155.0':
optional: true
- '@oxc-parser/binding-darwin-arm64@0.154.0':
+ '@oxc-parser/binding-darwin-arm64@0.155.0':
optional: true
- '@oxc-parser/binding-darwin-x64@0.154.0':
+ '@oxc-parser/binding-darwin-x64@0.155.0':
optional: true
- '@oxc-parser/binding-freebsd-x64@0.154.0':
+ '@oxc-parser/binding-freebsd-x64@0.155.0':
optional: true
- '@oxc-parser/binding-linux-arm-gnueabihf@0.154.0':
+ '@oxc-parser/binding-linux-arm-gnueabihf@0.155.0':
optional: true
- '@oxc-parser/binding-linux-arm-musleabihf@0.154.0':
+ '@oxc-parser/binding-linux-arm-musleabihf@0.155.0':
optional: true
- '@oxc-parser/binding-linux-arm64-gnu@0.154.0':
+ '@oxc-parser/binding-linux-arm64-gnu@0.155.0':
optional: true
- '@oxc-parser/binding-linux-arm64-musl@0.154.0':
+ '@oxc-parser/binding-linux-arm64-musl@0.155.0':
optional: true
- '@oxc-parser/binding-linux-ppc64-gnu@0.154.0':
+ '@oxc-parser/binding-linux-ppc64-gnu@0.155.0':
optional: true
- '@oxc-parser/binding-linux-riscv64-gnu@0.154.0':
+ '@oxc-parser/binding-linux-riscv64-gnu@0.155.0':
optional: true
- '@oxc-parser/binding-linux-riscv64-musl@0.154.0':
+ '@oxc-parser/binding-linux-riscv64-musl@0.155.0':
optional: true
- '@oxc-parser/binding-linux-s390x-gnu@0.154.0':
+ '@oxc-parser/binding-linux-s390x-gnu@0.155.0':
optional: true
- '@oxc-parser/binding-linux-x64-gnu@0.154.0':
+ '@oxc-parser/binding-linux-x64-gnu@0.155.0':
optional: true
- '@oxc-parser/binding-linux-x64-musl@0.154.0':
+ '@oxc-parser/binding-linux-x64-musl@0.155.0':
optional: true
- '@oxc-parser/binding-openharmony-arm64@0.154.0':
+ '@oxc-parser/binding-openharmony-arm64@0.155.0':
optional: true
- '@oxc-parser/binding-win32-arm64-msvc@0.154.0':
+ '@oxc-parser/binding-win32-arm64-msvc@0.155.0':
optional: true
- '@oxc-parser/binding-win32-ia32-msvc@0.154.0':
+ '@oxc-parser/binding-win32-ia32-msvc@0.155.0':
optional: true
- '@oxc-parser/binding-win32-x64-msvc@0.154.0':
+ '@oxc-parser/binding-win32-x64-msvc@0.155.0':
optional: true
'@oxc-project/types@0.139.0': {}
- '@oxc-project/types@0.154.0': {}
+ '@oxc-project/types@0.155.0': {}
'@oxc-resolver/binding-android-arm-eabi@11.24.2':
optional: true
@@ -8708,7 +8726,7 @@ snapshots:
'@oxc-resolver/binding-win32-x64-msvc@11.24.2':
optional: true
- '@parse/node-apn@8.1.0(supports-color@7.2.0)':
+ '@parse/node-apn@8.1.1(supports-color@7.2.0)':
dependencies:
debug: 4.4.3(supports-color@7.2.0)
jsonwebtoken: 9.0.3
@@ -8853,11 +8871,11 @@ snapshots:
'@prisma/client-runtime-utils@7.10.1': {}
- '@prisma/client@7.10.1(prisma@7.10.1(@types/node@26.6.5)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(magicast@0.5.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(typescript@6.0.3))(typescript@6.0.3)':
+ '@prisma/client@7.10.1(prisma@7.10.1(@types/node@26.6.6)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(magicast@0.5.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(typescript@6.0.3))(typescript@6.0.3)':
dependencies:
'@prisma/client-runtime-utils': 7.10.1
optionalDependencies:
- prisma: 7.10.1(@types/node@26.6.5)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(magicast@0.5.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(typescript@6.0.3)
+ prisma: 7.10.1(@types/node@26.6.6)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(magicast@0.5.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(typescript@6.0.3)
typescript: 6.0.3
'@prisma/config@7.10.1(magicast@0.5.5)':
@@ -9843,7 +9861,7 @@ snapshots:
'@sec-ant/readable-stream@0.4.1': {}
- '@shadcn/registry@0.2.0(supports-color@7.2.0)':
+ '@shadcn/registry@0.2.1(supports-color@7.2.0)':
dependencies:
'@babel/core': 7.29.7(supports-color@7.2.0)
'@babel/parser': 7.29.9
@@ -9888,32 +9906,32 @@ snapshots:
'@sindresorhus/merge-streams@4.0.0': {}
- '@smithy/core@3.36.2':
+ '@smithy/core@3.38.1':
dependencies:
'@smithy/types': 4.19.0
tslib: 2.8.1
'@smithy/credential-provider-imds@4.5.2':
dependencies:
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/types': 4.19.0
tslib: 2.8.1
'@smithy/fetch-http-handler@5.8.0':
dependencies:
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/types': 4.19.0
tslib: 2.8.1
- '@smithy/node-http-handler@4.12.1':
+ '@smithy/node-http-handler@4.14.1':
dependencies:
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/types': 4.19.0
tslib: 2.8.1
- '@smithy/signature-v4@5.7.4':
+ '@smithy/signature-v4@5.7.5':
dependencies:
- '@smithy/core': 3.36.2
+ '@smithy/core': 3.38.1
'@smithy/types': 4.19.0
tslib: 2.8.1
@@ -9932,12 +9950,19 @@ snapshots:
tslib: 2.8.1
typed-inject: 5.0.0
- '@stryker-mutator/core@10.0.0(@types/node@26.6.5)':
+ '@stryker-mutator/api@10.1.1':
dependencies:
- '@inquirer/prompts': 8.7.4(@types/node@26.6.5)
- '@stryker-mutator/api': 10.0.0
- '@stryker-mutator/instrumenter': 10.0.0
- '@stryker-mutator/util': 10.0.0
+ mutation-testing-metrics: 3.8.4
+ mutation-testing-report-schema: 3.8.4
+ tslib: 2.8.1
+ typed-inject: 5.0.0
+
+ '@stryker-mutator/core@10.1.1(@types/node@26.6.6)':
+ dependencies:
+ '@inquirer/prompts': 8.7.4(@types/node@26.6.6)
+ '@stryker-mutator/api': 10.1.1
+ '@stryker-mutator/instrumenter': 10.1.1
+ '@stryker-mutator/util': 10.1.1
ajv: 8.20.0
chalk: 5.6.2
commander: 14.0.3
@@ -9963,7 +9988,7 @@ snapshots:
transitivePeerDependencies:
- '@types/node'
- '@stryker-mutator/instrumenter@10.0.0':
+ '@stryker-mutator/instrumenter@10.1.1':
dependencies:
'@babel/core': 8.0.7
'@babel/generator': 8.0.6
@@ -9973,8 +9998,8 @@ snapshots:
'@babel/preset-react': 8.0.1(@babel/core@8.0.7)
'@babel/preset-typescript': 8.0.7(@babel/core@8.0.7)
'@babel/traverse': 8.0.7
- '@stryker-mutator/api': 10.0.0
- '@stryker-mutator/util': 10.0.0
+ '@stryker-mutator/api': 10.1.1
+ '@stryker-mutator/util': 10.1.1
angular-html-parser: 10.11.0
semver: 7.8.5
tslib: 2.8.1
@@ -9982,14 +10007,16 @@ snapshots:
'@stryker-mutator/util@10.0.0': {}
- '@stryker-mutator/vitest-runner@10.0.0(patch_hash=9ad3e9855fd9781fd36e872ed42c5f934f91b962d6830e6cc56d56bf16e1dabd)(@stryker-mutator/core@10.0.0(@types/node@26.6.5))(vitest@5.0.5)':
+ '@stryker-mutator/util@10.1.1': {}
+
+ '@stryker-mutator/vitest-runner@10.0.0(patch_hash=9ad3e9855fd9781fd36e872ed42c5f934f91b962d6830e6cc56d56bf16e1dabd)(@stryker-mutator/core@10.1.1(@types/node@26.6.6))(vitest@5.0.5)':
dependencies:
'@stryker-mutator/api': 10.0.0
- '@stryker-mutator/core': 10.0.0(@types/node@26.6.5)
+ '@stryker-mutator/core': 10.1.1(@types/node@26.6.6)
'@stryker-mutator/util': 10.0.0
semver: 7.8.5
tslib: 2.8.1
- vitest: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@26.6.5)(@vitest/browser-playwright@5.0.5)(@vitest/coverage-v8@5.0.5)(@vitest/ui@5.0.5)(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))
+ vitest: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@26.6.6)(@vitest/browser-playwright@5.0.5)(@vitest/coverage-v8@5.0.5)(@vitest/ui@5.0.5)(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))
'@swc/helpers@0.5.23':
dependencies:
@@ -10064,22 +10091,22 @@ snapshots:
postcss: 8.5.26
tailwindcss: 4.3.3
- '@tanstack/query-core@5.104.5': {}
+ '@tanstack/query-core@5.105.0': {}
- '@tanstack/react-query@5.104.5(@types/react@19.3.0)(react@19.3.1)':
+ '@tanstack/react-query@5.105.0(@types/react@19.3.0)(react@19.3.1)':
dependencies:
- '@tanstack/query-core': 5.104.5
+ '@tanstack/query-core': 5.105.0
react: 19.3.1
optionalDependencies:
'@types/react': 19.3.0
- '@tanstack/react-virtual@3.14.22(react-dom@19.3.1(react@19.3.1))(react@19.3.1)':
+ '@tanstack/react-virtual@3.14.25(react-dom@19.3.1(react@19.3.1))(react@19.3.1)':
dependencies:
- '@tanstack/virtual-core': 3.19.7
+ '@tanstack/virtual-core': 3.19.10
react: 19.3.1
react-dom: 19.3.1(react@19.3.1)
- '@tanstack/virtual-core@3.19.7': {}
+ '@tanstack/virtual-core@3.19.10': {}
'@tesseract.js-data/deu@1.0.0': {}
@@ -10166,13 +10193,13 @@ snapshots:
'@types/docker-modem@3.0.6':
dependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
'@types/ssh2': 1.15.6
'@types/dockerode@4.0.2':
dependencies:
'@types/docker-modem': 3.0.6
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
'@types/ssh2': 1.15.6
'@types/estree@1.0.8': {}
@@ -10195,7 +10222,7 @@ snapshots:
dependencies:
undici-types: 5.26.5
- '@types/node@26.6.5':
+ '@types/node@26.6.6':
dependencies:
undici-types: 8.9.0
@@ -10203,13 +10230,13 @@ snapshots:
'@types/pg@8.23.1':
dependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
pg-protocol: 1.16.0
pg-types: 2.2.0
'@types/qrcode@1.5.6':
dependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
'@types/raf@3.4.3':
optional: true
@@ -10224,20 +10251,20 @@ snapshots:
'@types/sax@1.2.7':
dependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
'@types/set-cookie-parser@2.4.10':
dependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
optional: true
'@types/ssh2-streams@0.1.13':
dependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
'@types/ssh2@0.5.52':
dependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
'@types/ssh2-streams': 0.1.13
'@types/ssh2@1.15.6':
@@ -10256,7 +10283,7 @@ snapshots:
'@types/web-push@3.6.4':
dependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
'@typescript-eslint/eslint-plugin@8.71.0(@typescript-eslint/parser@8.71.0(eslint@9.39.3(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.3(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3)':
dependencies:
@@ -10496,30 +10523,30 @@ snapshots:
d3-time-format: 4.1.0
internmap: 2.0.3
- '@vitest/browser-playwright@5.0.5(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(playwright@1.64.1)(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))(vitest@5.0.5)':
+ '@vitest/browser-playwright@5.0.5(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(playwright@1.64.1)(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))(vitest@5.0.5)':
dependencies:
- '@vitest/browser': 5.0.5(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))(vitest@5.0.5)
- '@vitest/mocker': 5.0.5(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))
+ '@vitest/browser': 5.0.5(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))(vitest@5.0.5)
+ '@vitest/mocker': 5.0.5(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))
playwright: 1.64.1
tinyrainbow: 3.2.0
- vitest: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@26.6.5)(@vitest/browser-playwright@5.0.5)(@vitest/coverage-v8@5.0.5)(@vitest/ui@5.0.5)(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))
+ vitest: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@26.6.6)(@vitest/browser-playwright@5.0.5)(@vitest/coverage-v8@5.0.5)(@vitest/ui@5.0.5)(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))
transitivePeerDependencies:
- bufferutil
- msw
- utf-8-validate
- vite
- '@vitest/browser@5.0.5(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))(vitest@5.0.5)':
+ '@vitest/browser@5.0.5(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))(vitest@5.0.5)':
dependencies:
'@blazediff/core': 1.10.0
- '@vitest/mocker': 5.0.5(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))
+ '@vitest/mocker': 5.0.5(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))
'@vitest/ui': 5.0.5(vitest@5.0.5)
'@vitest/utils': 5.0.5
magic-string: 1.4.3
pngjs: 7.0.0
sirv: 3.0.2
tinyrainbow: 3.2.0
- vitest: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@26.6.5)(@vitest/browser-playwright@5.0.5)(@vitest/coverage-v8@5.0.5)(@vitest/ui@5.0.5)(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))
+ vitest: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@26.6.6)(@vitest/browser-playwright@5.0.5)(@vitest/coverage-v8@5.0.5)(@vitest/ui@5.0.5)(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))
ws: 8.22.0
transitivePeerDependencies:
- bufferutil
@@ -10537,9 +10564,9 @@ snapshots:
obug: 3.0.0
std-env: 4.3.0
tinyrainbow: 3.2.0
- vitest: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@26.6.5)(@vitest/browser-playwright@5.0.5)(@vitest/coverage-v8@5.0.5)(@vitest/ui@5.0.5)(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))
+ vitest: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@26.6.6)(@vitest/browser-playwright@5.0.5)(@vitest/coverage-v8@5.0.5)(@vitest/ui@5.0.5)(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))
optionalDependencies:
- '@vitest/browser': 5.0.5(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))(vitest@5.0.5)
+ '@vitest/browser': 5.0.5(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))(vitest@5.0.5)
'@vitest/istanbul-lib-coverage@1.0.2': {}
@@ -10547,15 +10574,15 @@ snapshots:
dependencies:
'@vitest/istanbul-lib-coverage': 1.0.2
- '@vitest/mocker@5.0.5(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))':
+ '@vitest/mocker@5.0.5(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))':
dependencies:
'@jridgewell/trace-mapping': 0.3.31
'@vitest/spy': 5.0.5
estree-walker: 3.0.3
magic-string: 1.4.3
optionalDependencies:
- msw: 2.14.6(@types/node@26.6.5)(typescript@6.0.3)
- vite: 8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1)
+ msw: 2.14.6(@types/node@26.6.6)(typescript@6.0.3)
+ vite: 8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1)
'@vitest/pretty-format@5.0.5':
dependencies:
@@ -10571,7 +10598,7 @@ snapshots:
pathe: 2.0.3
sirv: 3.0.2
tinyrainbow: 3.2.0
- vitest: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@26.6.5)(@vitest/browser-playwright@5.0.5)(@vitest/coverage-v8@5.0.5)(@vitest/ui@5.0.5)(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))
+ vitest: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@26.6.6)(@vitest/browser-playwright@5.0.5)(@vitest/coverage-v8@5.0.5)(@vitest/ui@5.0.5)(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))
'@vitest/utils@5.0.5':
dependencies:
@@ -11309,7 +11336,7 @@ snapshots:
dotenv@17.4.2: {}
- dotenv@18.0.8: {}
+ dotenv@18.0.9: {}
dunder-proto@1.0.1:
dependencies:
@@ -11487,9 +11514,9 @@ snapshots:
escape-string-regexp@4.0.0: {}
- eslint-config-next@16.4.2(@typescript-eslint/parser@8.71.0(eslint@9.39.3(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.3(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3):
+ eslint-config-next@16.4.3(@typescript-eslint/parser@8.71.0(eslint@9.39.3(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@9.39.3(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3):
dependencies:
- '@next/eslint-plugin-next': 16.4.2(eslint@9.39.3(jiti@2.7.0)(supports-color@7.2.0))
+ '@next/eslint-plugin-next': 16.4.3(eslint@9.39.3(jiti@2.7.0)(supports-color@7.2.0))
eslint: 9.39.3(jiti@2.7.0)(supports-color@7.2.0)
eslint-import-resolver-node: 0.3.10(supports-color@7.2.0)
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)
@@ -11777,7 +11804,7 @@ snapshots:
once: 1.4.0
parseurl: 1.3.3
proxy-addr: 2.0.8
- qs: 6.16.0
+ qs: 6.16.1
range-parser: 1.3.0
router: 2.2.0(supports-color@7.2.0)
send: 1.2.1(supports-color@7.2.0)
@@ -12357,6 +12384,8 @@ snapshots:
jose@6.2.13: {}
+ jose@6.2.14: {}
+
js-md4@0.3.2: {}
js-tokens@10.0.0: {}
@@ -12406,7 +12435,7 @@ snapshots:
lodash.isstring: 4.0.1
lodash.once: 4.1.1
ms: 2.1.3
- semver: 7.8.0
+ semver: 7.8.5
jspdf-autotable@5.0.9(jspdf@4.2.1):
dependencies:
@@ -12449,12 +12478,12 @@ snapshots:
kleur@4.1.5: {}
- knip@6.42.1:
+ knip@6.44.1:
dependencies:
formatly: 0.11.4
get-tsconfig: 4.14.3
jiti: 2.7.0
- oxc-parser: 0.154.0
+ oxc-parser: 0.155.0
oxc-resolver: 11.24.2
picomatch: 4.0.7
smol-toml: 1.9.1
@@ -12678,7 +12707,7 @@ snapshots:
lru.min@1.1.5: {}
- lucide-react@1.61.0(@types/react@19.3.0)(react@19.3.1):
+ lucide-react@1.66.0(@types/react@19.3.0)(react@19.3.1):
dependencies:
react: 19.3.1
optionalDependencies:
@@ -12759,9 +12788,9 @@ snapshots:
ms@2.1.3: {}
- msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3):
+ msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3):
dependencies:
- '@inquirer/confirm': 6.3.4(@types/node@26.6.5)
+ '@inquirer/confirm': 6.3.4(@types/node@26.6.6)
'@mswjs/interceptors': 0.41.9
'@open-draft/deferred-promise': 3.0.0
'@types/statuses': 2.0.6
@@ -12799,9 +12828,9 @@ snapshots:
mute-stream@3.0.0: {}
- mysql2@3.24.4(@types/node@26.6.5):
+ mysql2@3.24.4(@types/node@26.6.6):
dependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
aws-ssl-profiles: 1.1.2
generate-function: 2.3.1
iconv-lite: 0.7.3
@@ -12827,28 +12856,28 @@ snapshots:
negotiator@1.0.0: {}
- next@16.4.2(@babel/core@7.29.7(supports-color@7.2.0))(@opentelemetry/api@1.9.1)(@playwright/test@1.64.1)(@types/node@26.6.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1):
+ next@16.4.3(@babel/core@8.0.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.64.1)(@types/node@26.6.6)(react-dom@19.3.1(react@19.3.1))(react@19.3.1):
dependencies:
- '@next/env': 16.4.2
+ '@next/env': 16.4.3
'@swc/helpers': 0.5.23
baseline-browser-mapping: 2.11.27
caniuse-lite: 1.0.30001815
postcss: 8.5.23
react: 19.3.1
react-dom: 19.3.1(react@19.3.1)
- styled-jsx: 5.1.6(@babel/core@7.29.7(supports-color@7.2.0))(react@19.3.1)
+ styled-jsx: 5.1.6(@babel/core@8.0.7)(react@19.3.1)
optionalDependencies:
- '@next/swc-darwin-arm64': 16.4.2
- '@next/swc-darwin-x64': 16.4.2
- '@next/swc-linux-arm64-gnu': 16.4.2
- '@next/swc-linux-arm64-musl': 16.4.2
- '@next/swc-linux-x64-gnu': 16.4.2
- '@next/swc-linux-x64-musl': 16.4.2
- '@next/swc-win32-arm64-msvc': 16.4.2
- '@next/swc-win32-x64-msvc': 16.4.2
+ '@next/swc-darwin-arm64': 16.4.3
+ '@next/swc-darwin-x64': 16.4.3
+ '@next/swc-linux-arm64-gnu': 16.4.3
+ '@next/swc-linux-arm64-musl': 16.4.3
+ '@next/swc-linux-x64-gnu': 16.4.3
+ '@next/swc-linux-x64-musl': 16.4.3
+ '@next/swc-win32-arm64-msvc': 16.4.3
+ '@next/swc-win32-x64-msvc': 16.4.3
'@opentelemetry/api': 1.9.1
'@playwright/test': 1.64.1
- sharp: 0.35.5(@types/node@26.6.5)
+ sharp: 0.35.5(@types/node@26.6.6)
transitivePeerDependencies:
- '@babel/core'
- '@types/node'
@@ -12869,7 +12898,7 @@ snapshots:
node-releases@2.0.58: {}
- nodemailer@10.2.1: {}
+ nodemailer@10.3.1: {}
non-error@0.1.0: {}
@@ -13002,29 +13031,29 @@ snapshots:
object-keys: 1.1.1
safe-push-apply: 1.0.0
- oxc-parser@0.154.0:
+ oxc-parser@0.155.0:
dependencies:
- '@oxc-project/types': 0.154.0
+ '@oxc-project/types': 0.155.0
optionalDependencies:
- '@oxc-parser/binding-android-arm-eabi': 0.154.0
- '@oxc-parser/binding-android-arm64': 0.154.0
- '@oxc-parser/binding-darwin-arm64': 0.154.0
- '@oxc-parser/binding-darwin-x64': 0.154.0
- '@oxc-parser/binding-freebsd-x64': 0.154.0
- '@oxc-parser/binding-linux-arm-gnueabihf': 0.154.0
- '@oxc-parser/binding-linux-arm-musleabihf': 0.154.0
- '@oxc-parser/binding-linux-arm64-gnu': 0.154.0
- '@oxc-parser/binding-linux-arm64-musl': 0.154.0
- '@oxc-parser/binding-linux-ppc64-gnu': 0.154.0
- '@oxc-parser/binding-linux-riscv64-gnu': 0.154.0
- '@oxc-parser/binding-linux-riscv64-musl': 0.154.0
- '@oxc-parser/binding-linux-s390x-gnu': 0.154.0
- '@oxc-parser/binding-linux-x64-gnu': 0.154.0
- '@oxc-parser/binding-linux-x64-musl': 0.154.0
- '@oxc-parser/binding-openharmony-arm64': 0.154.0
- '@oxc-parser/binding-win32-arm64-msvc': 0.154.0
- '@oxc-parser/binding-win32-ia32-msvc': 0.154.0
- '@oxc-parser/binding-win32-x64-msvc': 0.154.0
+ '@oxc-parser/binding-android-arm-eabi': 0.155.0
+ '@oxc-parser/binding-android-arm64': 0.155.0
+ '@oxc-parser/binding-darwin-arm64': 0.155.0
+ '@oxc-parser/binding-darwin-x64': 0.155.0
+ '@oxc-parser/binding-freebsd-x64': 0.155.0
+ '@oxc-parser/binding-linux-arm-gnueabihf': 0.155.0
+ '@oxc-parser/binding-linux-arm-musleabihf': 0.155.0
+ '@oxc-parser/binding-linux-arm64-gnu': 0.155.0
+ '@oxc-parser/binding-linux-arm64-musl': 0.155.0
+ '@oxc-parser/binding-linux-ppc64-gnu': 0.155.0
+ '@oxc-parser/binding-linux-riscv64-gnu': 0.155.0
+ '@oxc-parser/binding-linux-riscv64-musl': 0.155.0
+ '@oxc-parser/binding-linux-s390x-gnu': 0.155.0
+ '@oxc-parser/binding-linux-x64-gnu': 0.155.0
+ '@oxc-parser/binding-linux-x64-musl': 0.155.0
+ '@oxc-parser/binding-openharmony-arm64': 0.155.0
+ '@oxc-parser/binding-win32-arm64-msvc': 0.155.0
+ '@oxc-parser/binding-win32-ia32-msvc': 0.155.0
+ '@oxc-parser/binding-win32-x64-msvc': 0.155.0
oxc-resolver@11.24.2:
optionalDependencies:
@@ -13247,13 +13276,13 @@ snapshots:
dependencies:
parse-ms: 4.0.0
- prisma@7.10.1(@types/node@26.6.5)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(magicast@0.5.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(typescript@6.0.3):
+ prisma@7.10.1(@types/node@26.6.6)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(magicast@0.5.5)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)(typescript@6.0.3):
dependencies:
'@prisma/config': 7.10.1(magicast@0.5.5)
'@prisma/dev': 0.24.17(typescript@6.0.3)
'@prisma/engines': 7.10.1
'@prisma/studio-core': 0.33.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
- mysql2: 3.24.4(@types/node@26.6.5)
+ mysql2: 3.24.4(@types/node@26.6.6)
postgres: 3.4.7
optionalDependencies:
typescript: 6.0.3
@@ -13306,7 +13335,7 @@ snapshots:
'@protobufjs/path': 1.1.2
'@protobufjs/pool': 1.1.0
'@protobufjs/utf8': 1.1.2
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
long: 5.3.2
proxy-addr@2.0.8:
@@ -13337,11 +13366,6 @@ snapshots:
pngjs: 5.0.0
yargs: 15.4.1
- qs@6.16.0:
- dependencies:
- es-define-property: 1.0.1
- side-channel: 1.1.1
-
qs@6.16.1:
dependencies:
es-define-property: 1.0.1
@@ -13700,8 +13724,6 @@ snapshots:
semver@6.3.1: {}
- semver@7.8.0: {}
-
semver@7.8.5: {}
send@1.2.1(supports-color@7.2.0):
@@ -13763,15 +13785,15 @@ snapshots:
setprototypeof@1.2.0: {}
- shadcn@4.22.1(@cfworker/json-schema@4.1.1)(supports-color@7.2.0):
+ shadcn@4.23.0(supports-color@7.2.0):
dependencies:
'@babel/core': 7.29.7(supports-color@7.2.0)
'@babel/parser': 7.29.9
'@babel/plugin-transform-typescript': 7.29.9(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0)
'@babel/preset-typescript': 7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0)
'@dotenvx/dotenvx': 1.75.1
- '@modelcontextprotocol/sdk': 1.32.1(@cfworker/json-schema@4.1.1)(supports-color@7.2.0)(zod@4.6.7)
- '@shadcn/registry': 0.2.0(supports-color@7.2.0)
+ '@modelcontextprotocol/server': 2.4.0
+ '@shadcn/registry': 0.2.1(supports-color@7.2.0)
'@types/validate-npm-package-name': 4.0.2
browserslist: 4.29.3
cn: 0.2.6
@@ -13798,11 +13820,10 @@ snapshots:
validate-npm-package-name: 7.0.2
zod: 4.6.7
transitivePeerDependencies:
- - '@cfworker/json-schema'
- babel-plugin-macros
- supports-color
- sharp@0.35.5(@types/node@26.6.5):
+ sharp@0.35.5(@types/node@26.6.6):
dependencies:
'@img/colour': 1.1.0
detect-libc: 2.1.2
@@ -13833,7 +13854,7 @@ snapshots:
'@img/sharp-win32-arm64': 0.35.5
'@img/sharp-win32-ia32': 0.35.5
'@img/sharp-win32-x64': 0.35.5
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
optional: true
shebang-command@2.0.0:
@@ -14065,12 +14086,12 @@ snapshots:
strip-json-comments@5.0.3: {}
- styled-jsx@5.1.6(@babel/core@7.29.7(supports-color@7.2.0))(react@19.3.1):
+ styled-jsx@5.1.6(@babel/core@8.0.7)(react@19.3.1):
dependencies:
client-only: 0.0.1
react: 19.3.1
optionalDependencies:
- '@babel/core': 7.29.7(supports-color@7.2.0)
+ '@babel/core': 8.0.7
supports-color@7.2.0:
dependencies:
@@ -14318,7 +14339,7 @@ snapshots:
dependencies:
des.js: 1.1.0
js-md4: 0.3.2
- qs: 6.16.0
+ qs: 6.16.1
tunnel: 0.0.6
underscore: 1.13.8
@@ -14459,7 +14480,7 @@ snapshots:
d3-time: 3.1.0
d3-timer: 3.0.1
- vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1):
+ vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1):
dependencies:
lightningcss: 1.33.0
picomatch: 4.0.7
@@ -14467,7 +14488,7 @@ snapshots:
rolldown: 1.1.5
tinyglobby: 0.2.17
optionalDependencies:
- '@types/node': 26.6.5
+ '@types/node': 26.6.6
fsevents: 2.3.3
jiti: 2.7.0
yaml: 2.9.1
@@ -14476,15 +14497,15 @@ snapshots:
dependencies:
react: 19.3.1
react-dom: 19.3.1(react@19.3.1)
- vitest: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@26.6.5)(@vitest/browser-playwright@5.0.5)(@vitest/coverage-v8@5.0.5)(@vitest/ui@5.0.5)(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))
+ vitest: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@26.6.6)(@vitest/browser-playwright@5.0.5)(@vitest/coverage-v8@5.0.5)(@vitest/ui@5.0.5)(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))
optionalDependencies:
'@types/react': 19.3.0
'@types/react-dom': 19.3.0(@types/react@19.3.0)
- vitest@5.0.5(@opentelemetry/api@1.9.1)(@types/node@26.6.5)(@vitest/browser-playwright@5.0.5)(@vitest/coverage-v8@5.0.5)(@vitest/ui@5.0.5)(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1)):
+ vitest@5.0.5(@opentelemetry/api@1.9.1)(@types/node@26.6.6)(@vitest/browser-playwright@5.0.5)(@vitest/coverage-v8@5.0.5)(@vitest/ui@5.0.5)(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1)):
dependencies:
'@types/chai': 5.2.3
- '@vitest/mocker': 5.0.5(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))
+ '@vitest/mocker': 5.0.5(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))
chai: 6.3.0
es-module-lexer: 2.3.2
expect-type: 1.4.0
@@ -14495,12 +14516,12 @@ snapshots:
tinybench: 6.2.2
tinyexec: 1.3.1
tinyglobby: 0.2.17
- vite: 8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1)
+ vite: 8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1)
why-is-node-running: 3.2.1
optionalDependencies:
'@opentelemetry/api': 1.9.1
- '@types/node': 26.6.5
- '@vitest/browser-playwright': 5.0.5(msw@2.14.6(@types/node@26.6.5)(typescript@6.0.3))(playwright@1.64.1)(vite@8.1.6(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.1))(vitest@5.0.5)
+ '@types/node': 26.6.6
+ '@vitest/browser-playwright': 5.0.5(msw@2.14.6(@types/node@26.6.6)(typescript@6.0.3))(playwright@1.64.1)(vite@8.1.6(@types/node@26.6.6)(jiti@2.7.0)(yaml@2.9.1))(vitest@5.0.5)
'@vitest/coverage-v8': 5.0.5(@vitest/browser@5.0.5)(vitest@5.0.5)
'@vitest/ui': 5.0.5(vitest@5.0.5)
transitivePeerDependencies:
diff --git a/public/sw.js b/public/sw.js
index 9b9502e0f..d6e87d86a 100644
--- a/public/sw.js
+++ b/public/sw.js
@@ -36,7 +36,7 @@ try {
// v1.4.38.4 → v1.4.42. Do not hand-edit; bump `package.json` and rebuild.
const CACHE_VERSION =
(typeof self !== "undefined" && self.__APP_VERSION__) ||
- /* @sw-version-fallback */ "v1.46.5";
+ /* @sw-version-fallback */ "v1.46.6";
const STATIC_CACHE = `healthlog-static-${CACHE_VERSION}`;
const PAGE_CACHE = `healthlog-pages-${CACHE_VERSION}`;
// v1.18.6 — read-only data cache for a curated allowlist of safe GET `/api/*`
diff --git a/scripts/README.md b/scripts/README.md
index 5692b78e4..18da03099 100644
--- a/scripts/README.md
+++ b/scripts/README.md
@@ -31,6 +31,7 @@ typecheck.
- **`bench/`** — `seed-large-account.ts` (a synthetic ten-year account of about 1.26 million measurement rows) and `run.ts` (latency and SQL statements per request against it); see `docs/contributing/benchmarks.md`. Results land in `bench/results/`.
- **`test-notifications.ts`** — exercise the notification dispatcher + reminder check.
- **`fetch-geolite2.sh`** — download the MaxMind GeoLite2 MMDBs (needs a licence key) before `docker build`.
+- **`build-pdf-fonts.py`** — rebuild the fonts the doctor-report PDF embeds (`src/lib/doctor-report-pdf/fonts/`) from the upstream Noto sources; needs `fonttools`. The source URLs are in its header.
- **`install-hooks.sh`** — install the local git hooks.
- **`generate-sw-version.mjs`**, **`print-bundle-report.mjs`** — service-worker version stamp and bundle-size report.
- **`i18n/`** — locale tooling; **`__tests__/`** — tests for the scripts above.
diff --git a/scripts/build-pdf-fonts.py b/scripts/build-pdf-fonts.py
new file mode 100644
index 000000000..e6d2d5b2f
--- /dev/null
+++ b/scripts/build-pdf-fonts.py
@@ -0,0 +1,191 @@
+#!/usr/bin/env python3
+"""Build the fonts the doctor-report PDF embeds.
+
+jsPDF draws one font per text run and has no glyph fallback, so every script
+the report can carry has to live in one font file. No single upstream Noto
+font covers what the report needs: Noto Sans has Latin, Greek and Cyrillic but
+no arrows or comparison signs, Noto Sans KR has Hangul but no Latin
+Extended-A (Polish). This script merges them:
+
+ ReportSans-{Regular,Bold,Italic}.ttf
+ Noto Sans (Latin, Latin Extended-A/B, Greek, Cyrillic, punctuation,
+ super-/subscripts, currency) plus the arrows and mathematical operators
+ of Noto Sans Math.
+ ReportSansKR-{Regular,Bold}.ttf
+ The matching ReportSans weight plus Hangul (syllables, jamo,
+ compatibility jamo) and CJK punctuation from Noto Sans KR, instanced
+ at weight 400 / 700. Loaded only for a report that contains Hangul.
+
+All sources are SIL Open Font License 1.1; the licence texts sit beside the
+output. The merged fonts carry their own family name, as the OFL asks of a
+modified version. Layout tables (GSUB/GPOS/GDEF/MATH) are dropped: jsPDF
+does no shaping, and precomposed Hangul syllables need none.
+
+Requires fonttools (`pip install fonttools`). Usage:
+
+ python3 scripts/build-pdf-fonts.py
+
+where holds the unhinted upstream TTFs:
+ NotoSans-Regular.ttf, NotoSans-Bold.ttf, NotoSans-Italic.ttf
+ https://github.com/notofonts/notofonts.github.io/tree/main/fonts/NotoSans/unhinted/ttf
+ NotoSansMath-Regular.ttf
+ https://github.com/notofonts/notofonts.github.io/tree/main/fonts/NotoSansMath/unhinted/ttf
+ NotoSansKR[wght].ttf
+ https://github.com/google/fonts/tree/main/ofl/notosanskr
+"""
+
+import copy
+import sys
+from pathlib import Path
+
+from fontTools import subset
+from fontTools.ttLib import TTFont
+from fontTools.varLib import instancer
+
+
+def ranges(*spans):
+ out = set()
+ for lo, hi in spans:
+ out.update(range(lo, hi + 1))
+ return out
+
+
+BASE_CODEPOINTS = ranges(
+ (0x0020, 0x007E), # Basic Latin
+ (0x00A0, 0x024F), # Latin-1, Latin Extended-A/B
+ (0x0250, 0x02FF), # IPA, spacing modifiers
+ (0x0300, 0x036F), # combining diacritics
+ (0x0370, 0x03FF), # Greek
+ (0x0400, 0x052F), # Cyrillic + supplement
+ (0x1E00, 0x1EFF), # Latin Extended Additional
+ (0x2000, 0x206F), # general punctuation
+ (0x2070, 0x209F), # super-/subscripts
+ (0x20A0, 0x20CF), # currency
+ (0x2100, 0x214F), # letterlike (°C, №, ™)
+ (0x2150, 0x218F), # number forms
+)
+SYMBOL_CODEPOINTS = ranges(
+ (0x2190, 0x21FF), # arrows
+ (0x2200, 0x22FF), # mathematical operators (≈ ≤ ≥ ±)
+)
+HANGUL_CODEPOINTS = ranges(
+ (0x1100, 0x11FF), # Hangul jamo
+ (0x3000, 0x303F), # CJK symbols and punctuation
+ (0x3130, 0x318F), # compatibility jamo
+ (0xA960, 0xA97F), # jamo extended-A
+ (0xAC00, 0xD7A3), # syllables
+ (0xD7B0, 0xD7FF), # jamo extended-B
+)
+DROP_TABLES = ["GSUB", "GPOS", "GDEF", "MATH", "BASE", "JSTF", "DSIG", "STAT"]
+
+
+def subset_font(font: TTFont, codepoints: set[int]) -> TTFont:
+ options = subset.Options()
+ options.layout_features = []
+ options.drop_tables += DROP_TABLES
+ options.hinting = False
+ options.notdef_outline = True
+ options.name_IDs = ["*"]
+ options.glyph_names = True
+ subsetter = subset.Subsetter(options)
+ subsetter.populate(unicodes=codepoints & set(font.getBestCmap()))
+ subsetter.subset(font)
+ return font
+
+
+def copy_glyph(base: TTFont, donor: TTFont, name: str, prefix: str) -> str:
+ """Copy one donor glyph (and its components) into base; return its name."""
+ new_name = f"{prefix}{name}"
+ glyf = base["glyf"]
+ if new_name in glyf.glyphs:
+ return new_name
+ glyph = copy.deepcopy(donor["glyf"][name])
+ if glyph.isComposite():
+ for component in glyph.components:
+ component.glyphName = copy_glyph(
+ base, donor, component.glyphName, prefix
+ )
+ glyf.glyphs[new_name] = glyph
+ glyf.glyphOrder.append(new_name)
+ base["hmtx"].metrics[new_name] = donor["hmtx"].metrics[name]
+ order = base.getGlyphOrder()
+ if new_name not in order:
+ order.append(new_name)
+ base.setGlyphOrder(order)
+ return new_name
+
+
+def merge(base: TTFont, donor: TTFont, prefix: str) -> None:
+ if base["head"].unitsPerEm != donor["head"].unitsPerEm:
+ raise SystemExit("unitsPerEm differs between base and donor")
+ base_cmap = base.getBestCmap()
+ additions = {}
+ for cp, name in donor.getBestCmap().items():
+ if cp in base_cmap:
+ continue
+ additions[cp] = copy_glyph(base, donor, name, prefix)
+ for table in base["cmap"].tables:
+ if table.isUnicode():
+ if table.format == 4 and any(cp > 0xFFFF for cp in additions):
+ continue
+ table.cmap.update(additions)
+ base["maxp"].numGlyphs = len(base.getGlyphOrder())
+ base["hhea"].numberOfHMetrics = len(base.getGlyphOrder())
+ base["hhea"].advanceWidthMax = max(
+ base["hhea"].advanceWidthMax,
+ max(width for width, _ in donor["hmtx"].metrics.values()),
+ )
+
+
+def finish(font: TTFont, family: str, style: str, path: Path) -> None:
+ """Rename, drop glyph names, save.
+
+ jsPDF copies the whole `post` table into every PDF it writes, subset or
+ not, so glyph names would cost each report tens of kilobytes (hundreds
+ with Hangul). Format 3 carries none.
+ """
+ font["post"].formatType = 3.0
+ rename(font, family, style)
+ font.save(path)
+
+
+def rename(font: TTFont, family: str, style: str) -> None:
+ name = font["name"]
+ postscript = f"{family}-{style}"
+ for record in list(name.names):
+ if record.nameID in (1, 16):
+ record.string = family
+ elif record.nameID in (2, 17):
+ record.string = style
+ elif record.nameID == 3:
+ record.string = f"{postscript};HealthLog"
+ elif record.nameID == 4:
+ record.string = f"{family} {style}"
+ elif record.nameID == 6:
+ record.string = postscript
+
+
+def build(src: Path, out: Path) -> None:
+ out.mkdir(parents=True, exist_ok=True)
+ math = subset_font(TTFont(src / "NotoSansMath-Regular.ttf"), SYMBOL_CODEPOINTS)
+ kr_source = src / "NotoSansKR[wght].ttf"
+
+ for style in ("Regular", "Bold", "Italic"):
+ base = subset_font(TTFont(src / f"NotoSans-{style}.ttf"), BASE_CODEPOINTS)
+ merge(base, math, "math.")
+ finish(base, "ReportSans", style, out / f"ReportSans-{style}.ttf")
+
+ if style == "Italic":
+ continue
+ weight = 400 if style == "Regular" else 700
+ kr = subset_font(TTFont(kr_source), HANGUL_CODEPOINTS)
+ kr = instancer.instantiateVariableFont(kr, {"wght": weight})
+ with_hangul = TTFont(out / f"ReportSans-{style}.ttf")
+ merge(with_hangul, kr, "kr.")
+ finish(with_hangul, "ReportSansKR", style, out / f"ReportSansKR-{style}.ttf")
+
+
+if __name__ == "__main__":
+ if len(sys.argv) != 3:
+ raise SystemExit(__doc__)
+ build(Path(sys.argv[1]), Path(sys.argv[2]))
diff --git a/src/__tests__/aging-fixture-dates-guard.test.ts b/src/__tests__/aging-fixture-dates-guard.test.ts
index ba785e961..84a21a76c 100644
--- a/src/__tests__/aging-fixture-dates-guard.test.ts
+++ b/src/__tests__/aging-fixture-dates-guard.test.ts
@@ -83,6 +83,11 @@ const ALLOWLIST: Record = {
reason:
"the discovery matrix reads from a fixed since forward; the fixture days stay inside it as now moves on",
},
+ "tests/integration/dense-series-dst-hour.test.ts": {
+ max: 1,
+ reason:
+ "the read starts at a fixed fall-back night and runs forward to now; the readings are pinned to that night, so the case cannot age",
+ },
};
export interface AgingFinding {
diff --git a/src/__tests__/baselines/source-file-lines.json b/src/__tests__/baselines/source-file-lines.json
index 27b6e688a..79303990c 100644
--- a/src/__tests__/baselines/source-file-lines.json
+++ b/src/__tests__/baselines/source-file-lines.json
@@ -1,7 +1,7 @@
{
"$comment": "Production files over 800 lines and their length. Maintained by src/__tests__/source-size-ratchet.test.ts.",
"count": 84,
- "total": 94362,
+ "total": 94292,
"entries": {
"app/medications/page-client.tsx": 839,
"components/charts/mood-chart.tsx": 1166,
@@ -69,7 +69,7 @@
"lib/jobs/offhost-backup.ts": 1094,
"lib/jobs/reaction-line.ts": 803,
"lib/managed-profiles/handover.ts": 986,
- "lib/mcp/record-search.ts": 1467,
+ "lib/mcp/record-search.ts": 1397,
"lib/mcp/rich-reads.ts": 1467,
"lib/measurements/dense-intraday-retention.ts": 1016,
"lib/measurements/import-apple-health-export.ts": 1722,
diff --git a/src/__tests__/baselines/source-function-lines.json b/src/__tests__/baselines/source-function-lines.json
index a9e9c0346..e4bb6649d 100644
--- a/src/__tests__/baselines/source-function-lines.json
+++ b/src/__tests__/baselines/source-function-lines.json
@@ -1,7 +1,7 @@
{
"$comment": "Production functions over 200 lines, keyed \"file :: name\", and their length. Maintained by src/__tests__/source-size-ratchet.test.ts.",
"count": 345,
- "total": 111929,
+ "total": 111918,
"entries": {
"app/achievements/page.tsx :: AchievementsPage": 206,
"app/api/admin/backups/upload/route.ts :: apiHandler(arg)": 275,
@@ -45,7 +45,7 @@
"app/coach/plans/page.tsx :: CoachPlansBody": 216,
"app/insights/catalog/page.tsx :: MetricCatalogPage": 204,
"app/insights/medications/page.tsx :: InsightsMedikamentePage": 265,
- "app/insights/page-client.tsx :: InsightsPageClient": 376,
+ "app/insights/page-client.tsx :: InsightsPageClient": 375,
"app/labs/page.tsx :: LabsPage": 228,
"app/medications/page-client.tsx :: MedicationsPageClient": 590,
"app/notifications/page.tsx :: NotificationsPage": 327,
@@ -93,7 +93,7 @@
"components/documents/document-card.tsx :: DocumentCard": 354,
"components/documents/document-detail-sheet.tsx :: DocumentDetailSheet": 325,
"components/documents/document-facts-review.tsx :: DocumentFactsSection": 242,
- "components/documents/document-facts-review.tsx :: FactRow": 262,
+ "components/documents/document-facts-review.tsx :: FactRow": 261,
"components/documents/document-filter-bar.tsx :: DocumentFilterBar": 348,
"components/documents/document-record-links.tsx :: DocumentRecordLinks": 202,
"components/documents/document-timeline.tsx :: DocumentTimeline": 314,
@@ -139,7 +139,7 @@
"components/labs/lab-history-list.tsx :: LabHistoryList": 534,
"components/labs/lab-list.tsx :: LabList": 308,
"components/labs/ocr-review-dialog.tsx :: OcrReviewDialog": 359,
- "components/labs/ocr-row-editor.tsx :: OcrRowEditor": 393,
+ "components/labs/ocr-row-editor.tsx :: OcrRowEditor": 386,
"components/layout/auth-shell.tsx :: AuthShell": 518,
"components/layout/bottom-nav.tsx :: BottomNav": 262,
"components/layout/capture-picker.tsx :: CapturePicker": 235,
@@ -205,7 +205,7 @@
"components/settings/import-panel/csv-import-card.tsx :: CsvImportCard": 212,
"components/settings/import-panel/dose-history-import-card.tsx :: DoseHistoryImportCard": 225,
"components/settings/import-panel/health-connect-import-card.tsx :: HealthConnectImportCard": 293,
- "components/settings/import-panel/record-csv-import-card.tsx :: RecordCsvImportSheet": 460,
+ "components/settings/import-panel/record-csv-import-card.tsx :: RecordCsvImportSheet": 458,
"components/settings/insights-pill-order-section.tsx :: InsightsPillOrderSection": 255,
"components/settings/integrations/connections-panel.tsx :: ConnectionsPanel": 230,
"components/settings/integrations/document-sources-card.tsx :: SourceForm": 306,
diff --git a/src/__tests__/baselines/version-stamp-comments.json b/src/__tests__/baselines/version-stamp-comments.json
index 8ad581d44..69c0ee030 100644
--- a/src/__tests__/baselines/version-stamp-comments.json
+++ b/src/__tests__/baselines/version-stamp-comments.json
@@ -1,7 +1,7 @@
{
"$comment": "Comment lines that open with a release version, per file under src/. Maintained by src/__tests__/version-stamp-ratchet.test.ts.",
- "count": 2895,
- "total": 9226,
+ "count": 2894,
+ "total": 9223,
"entries": {
"__tests__/account-payload-consumer-guard.test.ts": 2,
"__tests__/acting-account-boundary-guard.test.ts": 7,
@@ -824,7 +824,7 @@
"components/documents/document-ai-transport.ts": 2,
"components/documents/document-bulk-bar.tsx": 1,
"components/documents/document-card.tsx": 2,
- "components/documents/document-facts-review.tsx": 2,
+ "components/documents/document-facts-review.tsx": 1,
"components/documents/document-summary-block.tsx": 2,
"components/documents/use-content-index.ts": 1,
"components/documents/use-document-assist.ts": 1,
@@ -917,7 +917,7 @@
"components/insights/coach-panel/chat-bubble.tsx": 25,
"components/insights/coach-panel/coach-conversation.tsx": 40,
"components/insights/coach-panel/coach-drawer-body.tsx": 6,
- "components/insights/coach-panel/coach-drawer.tsx": 14,
+ "components/insights/coach-panel/coach-drawer.tsx": 13,
"components/insights/coach-panel/coach-hero.tsx": 2,
"components/insights/coach-panel/coach-input.tsx": 12,
"components/insights/coach-panel/coach-model-picker.tsx": 1,
@@ -958,7 +958,6 @@
"components/insights/derived/coach-read-strip.tsx": 2,
"components/insights/derived/composite-score-anatomy.tsx": 6,
"components/insights/derived/coverage-meter.tsx": 1,
- "components/insights/derived/index.ts": 1,
"components/insights/derived/provenance-explainer.tsx": 2,
"components/insights/derived/ring-hues.ts": 2,
"components/insights/derived/score-anatomy-view.tsx": 3,
diff --git a/src/app/api/labs/route.ts b/src/app/api/labs/route.ts
index 65373f80c..32fb3924e 100644
--- a/src/app/api/labs/route.ts
+++ b/src/app/api/labs/route.ts
@@ -17,6 +17,7 @@ import { withIdempotency } from "@/lib/idempotency";
import { enqueueReminderSatisfy } from "@/lib/jobs/reminder-satisfy";
import { emitDataArrival } from "@/lib/arrivals/emit-shared";
import { resolveOrMintBiomarker } from "@/lib/labs/biomarker-store";
+import { isDimensionlessUnit } from "@/lib/labs/dimensionless";
import { readingInMarkerUnit } from "@/lib/labs/reading-conversion";
import {
type ResolvedBiomarker,
@@ -270,7 +271,7 @@ async function postLabResult(request: NextRequest) {
meta: { biomarkerId: biomarker.id, reason: reading.reason },
});
return apiError(
- `The reading is in ${unit}, but ${biomarker.name} is tracked in ${biomarker.unit}.`,
+ unitMismatchMessage(unit, biomarker.name, biomarker.unit),
422,
{
errorCode: "labs.unit.mismatch",
@@ -392,3 +393,19 @@ async function postLabResult(request: NextRequest) {
return apiSuccess(dto, 201);
}
+
+/** The refusal for a reading whose unit differs from its marker's. */
+function unitMismatchMessage(
+ readingUnit: string | undefined,
+ markerName: string,
+ markerUnit: string,
+): string {
+ const readingSide =
+ !readingUnit || isDimensionlessUnit(readingUnit)
+ ? "The reading has no unit"
+ : `The reading is in ${readingUnit}`;
+ const markerSide = isDimensionlessUnit(markerUnit)
+ ? "tracked without a unit"
+ : `tracked in ${markerUnit}`;
+ return `${readingSide}, but ${markerName} is ${markerSide}.`;
+}
diff --git a/src/app/api/measurements/series/__tests__/route.test.ts b/src/app/api/measurements/series/__tests__/route.test.ts
index 0742d921b..ea63202db 100644
--- a/src/app/api/measurements/series/__tests__/route.test.ts
+++ b/src/app/api/measurements/series/__tests__/route.test.ts
@@ -131,7 +131,7 @@ function req(query: string): NextRequest {
* `tests/integration/series-source-ladder.test.ts`.
*/
function adaptSeriesSql(sql: string): Promise {
- if (/GROUP BY local_day|STDDEV_POP/.test(sql)) {
+ if (/GROUP BY (?:local_day|bucket_start)|STDDEV_POP/.test(sql)) {
return (prisma.$queryRaw as unknown as () => Promise)();
}
const type = /'([A-Z0-9_]+)'::"measurement_type"/.exec(sql)?.[1];
@@ -914,7 +914,7 @@ describe("GET /api/measurements/series — dense-kind day-bucketing (v1.28.25)",
const bucketCall = vi
.mocked(prisma.$queryRawUnsafe)
.mock.calls.find(([sql]) =>
- /GROUP BY local_day/.test(sql as string),
+ /GROUP BY (?:local_day|bucket_start)/.test(sql as string),
) as unknown[];
expect(bucketCall.slice(1)).toContain("hour");
});
@@ -981,7 +981,7 @@ describe("GET /api/measurements/series — dense-kind day-bucketing (v1.28.25)",
const bucketCall = vi
.mocked(prisma.$queryRawUnsafe)
.mock.calls.find(([sql]) =>
- /GROUP BY local_day/.test(sql as string),
+ /GROUP BY (?:local_day|bucket_start)/.test(sql as string),
) as unknown[];
expect(bucketCall.slice(1)).toContain("hour");
});
diff --git a/src/app/mcp/__tests__/route.test.ts b/src/app/mcp/__tests__/route.test.ts
index 9a5589b20..d5c956613 100644
--- a/src/app/mcp/__tests__/route.test.ts
+++ b/src/app/mcp/__tests__/route.test.ts
@@ -52,6 +52,12 @@ vi.mock("@/lib/ai/coach/tools/executor", () => ({ executeCoachTool }));
vi.mock("@/lib/ai/coach/tools/inventory", () => ({
buildCoachDataInventory: vi.fn(),
}));
+// `get_labs` builds its labs block first and asks the Coach only on a miss;
+// a miss keeps the health-reader case on the executor it asserts.
+vi.mock("@/lib/ai/coach/labs-snapshot", async (importOriginal) => ({
+ ...(await importOriginal()),
+ buildLabsSnapshotBlock: vi.fn(async () => null),
+}));
vi.mock("@/lib/mcp/server", async (importOriginal) => {
const actual = await importOriginal();
return {
diff --git a/src/components/clinician/history-sections.tsx b/src/components/clinician/history-sections.tsx
index 308f74ea4..dd6a25138 100644
--- a/src/components/clinician/history-sections.tsx
+++ b/src/components/clinician/history-sections.tsx
@@ -26,6 +26,7 @@ import {
type LeafScope,
type Translate,
} from "./report-sections";
+import { withLabUnit } from "@/lib/labs/dimensionless";
/** Join the parts of a composed value, dropping the ones with nothing in. */
function compose(parts: Array): string {
@@ -73,7 +74,7 @@ export function LabResultsSection({
const qualitative = lab.value === null;
const reading = qualitative
? lab.valueText
- : `${fmtLab(lab.value as number, lab.sourceValue)} ${lab.unit}`.trim();
+ : withLabUnit(fmtLab(lab.value as number, lab.sourceValue), lab.unit);
const range = (
low: number | null,
high: number | null,
diff --git a/src/components/documents/__tests__/document-facts-review.test.tsx b/src/components/documents/__tests__/document-facts-review.test.tsx
index fbb28cccb..23cc24dd8 100644
--- a/src/components/documents/__tests__/document-facts-review.test.tsx
+++ b/src/components/documents/__tests__/document-facts-review.test.tsx
@@ -8,7 +8,7 @@ import type {
InboundDocumentDetailDto,
} from "@/lib/validations/inbound-documents";
-import { DocumentFactsSection } from "../document-facts-review";
+import { DocumentFactsSection, FactRow } from "../document-facts-review";
/**
* The staged-facts block's honest states, pinned by static render:
@@ -173,3 +173,56 @@ describe("", () => {
expect(html).toBe("");
});
});
+
+describe("", () => {
+ // A confident lab value the last save refused (here a ratio printed without
+ // a unit) gets the same edit control as a low-confidence one: it is the only
+ // way to add the unit and finish the review.
+ const unitless = fact({
+ data: {
+ label: "Ratio",
+ code: null,
+ codeSystem: null,
+ value: 4.2,
+ valueText: null,
+ unit: null,
+ referenceLow: null,
+ referenceHigh: 5,
+ referenceText: "<5.0",
+ effectiveDate: "2026-08-01",
+ },
+ provenance: {
+ sourceText: "Ratio 4.2 <5.0",
+ anchored: true,
+ sourceOffset: 10,
+ page: 0,
+ confidence: 0.95,
+ },
+ });
+
+ const rowProps = {
+ documentId: "doc-1",
+ checked: true,
+ onCheckedChange: () => {},
+ chosenBiomarkerId: null,
+ onChooseBiomarker: () => {},
+ markerName: () => null,
+ };
+
+ it("offers the edit control on a confident row whose save was refused", () => {
+ const html = render(
+ ,
+ );
+ expect(html).toContain('data-slot="document-fact-verify-open"');
+ expect(html).toContain("A numeric value needs a unit");
+ });
+
+ it("leaves a confident row without a refusal free of the edit control", () => {
+ const html = render();
+ expect(html).not.toContain('data-slot="document-fact-verify-open"');
+ });
+});
diff --git a/src/components/documents/document-facts-review.tsx b/src/components/documents/document-facts-review.tsx
index ded9d2d6a..00745a89c 100644
--- a/src/components/documents/document-facts-review.tsx
+++ b/src/components/documents/document-facts-review.tsx
@@ -37,10 +37,12 @@ import { Checkbox } from "@/components/ui/checkbox";
import { DateField } from "@/components/ui/date-field";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
+import { LabUnitInput } from "@/components/labs/lab-unit-input";
import { MarkerMatchField } from "@/components/labs/marker-match-field";
import type { BiomarkerListResponse } from "@/components/labs/types";
import { apiGet } from "@/lib/api/api-fetch";
import type { DocumentExtractRunResult } from "@/lib/documents/ai-runs/types";
+import { withLabUnit } from "@/lib/labs/dimensionless";
import { useTranslations } from "@/lib/i18n/context";
import { queryKeys } from "@/lib/query-keys";
import { cn } from "@/lib/utils";
@@ -81,7 +83,7 @@ function factHeadline(fact: ExtractedFactDto): string {
const data = fact.data as ObservationFactData;
const value =
typeof data.value === "number"
- ? `${data.value}${data.unit ? ` ${data.unit}` : ""}`
+ ? withLabUnit(String(data.value), data.unit)
: (data.valueText ?? "");
return value ? `${data.label}: ${value}` : data.label;
}
@@ -204,8 +206,8 @@ function draftFor(fact: ExtractedFactDto): VerifyDraft {
};
}
-/** One pending fact: include-toggle, stated values, verify-first when low-confidence. */
-function FactRow({
+/** One pending fact: include-toggle, stated values, and the edit control when it is low-confidence or its last save was refused. */
+export function FactRow({
documentId,
fact,
checked,
@@ -221,7 +223,7 @@ function FactRow({
onCheckedChange: (checked: boolean) => void;
/** A per-fact commit refusal from the last confirm attempt, or null. */
failure: string | null;
- /** v1.43 — the suggestion the person picked for a lab value, or null. */
+ /** The suggestion the person picked for a lab value, or null. */
chosenBiomarkerId: string | null;
onChooseBiomarker: (biomarkerId: string | null) => void;
/** The account's marker name by id, for the matched marker. */
@@ -250,8 +252,7 @@ function FactRow({
{
onSuccess: () => {
setVerifying(false);
- // The refetched fact arrives with needsReview cleared; include it —
- // the person just asserted these values.
+ // Include it: the refetched fact clears needsReview, as asserted.
onCheckedChange(true);
},
},
@@ -319,9 +320,10 @@ function FactRow({
) : null}
- {fact.needsReview && !verifying ? (
+ {(fact.needsReview || failure !== null) && !verifying ? (