feat(web): unified json viewer/editor + edit existing automation

This commit is contained in:
CREDO23 2026-05-28 16:07:54 +02:00
parent 2d8d42bd9c
commit fa0cdb9760
15 changed files with 504 additions and 119 deletions

View file

@ -11,9 +11,8 @@ interface AutomationDefinitionSectionProps {
}
/**
* The Definition card. Read-only in v1 editing definitions happens via
* chat (re-run create_automation with a refined intent) or, later, via
* the raw-JSON path. Layout is top-down:
* The Definition card. Read view; editing happens on the sibling /edit
* route (Edit button in the header). Layout is top-down:
* goal tags execution defaults inputs schema (if any) plan
*
* The schema_version is rendered as a small badge next to the section

View file

@ -1,6 +1,6 @@
"use client";
import { useAtomValue } from "jotai";
import { ArrowLeft, Pause, Play, Trash2 } from "lucide-react";
import { ArrowLeft, Pause, Pencil, Play, Trash2 } from "lucide-react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useCallback, useState } from "react";
@ -82,6 +82,14 @@ export function AutomationDetailHeader({
</div>
<div className="flex items-center gap-2 shrink-0">
{canUpdate && (
<Button asChild type="button" variant="outline" size="sm">
<Link href={`/dashboard/${searchSpaceId}/automations/${automation.id}/edit`}>
<Pencil className="mr-2 h-4 w-4" />
Edit
</Link>
</Button>
)}
{canToggle && (
<Button
type="button"

View file

@ -1,4 +1,5 @@
"use client";
import { JsonView } from "@/components/json-view";
import type { Inputs } from "@/contracts/types/automation.types";
interface InputsSchemaPreviewProps {
@ -6,15 +7,15 @@ interface InputsSchemaPreviewProps {
}
/**
* Read-only JSON preview of an automation's accepted-inputs schema.
* Most automations don't define inputs (defaults are baked into the
* trigger's static_inputs), so the parent skips rendering this card
* when ``inputs`` is null.
* Read-only preview of an automation's accepted-inputs schema. Most
* automations don't define inputs (defaults are baked into the trigger's
* static_inputs), so the parent skips rendering this card when ``inputs``
* is null.
*/
export function InputsSchemaPreview({ inputs }: InputsSchemaPreviewProps) {
return (
<pre className="rounded-md bg-muted/40 px-3 py-2 text-xs font-mono text-foreground overflow-x-auto whitespace-pre-wrap break-words max-h-72">
{JSON.stringify(inputs.schema, null, 2)}
</pre>
<div className="rounded-md bg-muted/40 px-3 py-2 max-h-72 overflow-auto">
<JsonView src={inputs.schema} collapsed={2} />
</div>
);
}

View file

@ -1,5 +1,6 @@
"use client";
import { ArrowRightCircle, GitCommitHorizontal } from "lucide-react";
import { JsonView } from "@/components/json-view";
import type { PlanStep } from "@/contracts/types/automation.types";
interface PlanStepCardProps {
@ -54,9 +55,9 @@ export function PlanStepCard({ step, index }: PlanStepCardProps) {
<GitCommitHorizontal className="h-3.5 w-3.5" aria-hidden />
Params
</div>
<pre className="rounded-md bg-muted/40 px-3 py-2 text-xs font-mono text-foreground overflow-x-auto whitespace-pre-wrap break-words">
{JSON.stringify(step.params, null, 2)}
</pre>
<div className="rounded-md bg-muted/40 px-3 py-2 overflow-auto">
<JsonView src={step.params} collapsed={1} />
</div>
</div>
</div>
</div>

View file

@ -1,5 +1,6 @@
"use client";
import { AlertCircle, FileOutput, GitCommitHorizontal, Package, Settings2 } from "lucide-react";
import { JsonView } from "@/components/json-view";
import { Skeleton } from "@/components/ui/skeleton";
import { useAutomationRun } from "@/hooks/use-automation-runs";
@ -109,8 +110,8 @@ function Section({
function JsonBlock({ value }: { value: unknown }) {
return (
<pre className="rounded-md bg-muted/40 px-3 py-2 text-[11px] font-mono text-foreground overflow-x-auto whitespace-pre-wrap break-words max-h-64">
{JSON.stringify(value, null, 2)}
</pre>
<div className="rounded-md bg-muted/40 px-3 py-2 max-h-64 overflow-auto">
<JsonView src={value} collapsed={1} />
</div>
);
}

View file

@ -3,6 +3,7 @@ import { useAtomValue } from "jotai";
import { CalendarClock, Clock, Trash2 } from "lucide-react";
import { useState } from "react";
import { updateTriggerMutationAtom } from "@/atoms/automations/automations-mutation.atoms";
import { JsonView } from "@/components/json-view";
import { Button } from "@/components/ui/button";
import { Switch } from "@/components/ui/switch";
import type { Trigger } from "@/contracts/types/automation.types";
@ -109,9 +110,9 @@ export function TriggerCard({ trigger, automationId, canUpdate, canDelete }: Tri
{hasStaticInputs && (
<div>
<div className="text-muted-foreground mb-1">Static inputs</div>
<pre className="rounded-md bg-muted/40 px-3 py-2 font-mono text-foreground overflow-x-auto whitespace-pre-wrap break-words">
{JSON.stringify(trigger.static_inputs, null, 2)}
</pre>
<div className="rounded-md bg-muted/40 px-3 py-2 overflow-auto">
<JsonView src={trigger.static_inputs} collapsed={1} />
</div>
</div>
)}
</div>

View file

@ -0,0 +1,56 @@
"use client";
import { ShieldAlert } from "lucide-react";
import { useAutomation } from "@/hooks/use-automation";
import { useAutomationPermissions } from "../../hooks/use-automation-permissions";
import { AutomationDetailLoading } from "../components/automation-detail-loading";
import { AutomationNotFound } from "../components/automation-not-found";
import { AutomationEditForm } from "./components/automation-edit-form";
interface AutomationEditContentProps {
searchSpaceId: number;
automationId: number;
}
/**
* Client orchestrator for the edit route. Mirrors detail-content's branch
* structure but gates on ``canUpdate`` instead of ``canRead``: a user who
* can read but not update is bounced to the access-denied panel.
*/
export function AutomationEditContent({
searchSpaceId,
automationId,
}: AutomationEditContentProps) {
const perms = useAutomationPermissions();
const validId = Number.isInteger(automationId) && automationId > 0;
const { data: automation, isLoading, error } = useAutomation(validId ? automationId : undefined);
if (perms.loading) {
return <AutomationDetailLoading />;
}
if (!perms.canUpdate) {
return (
<div className="rounded-lg border border-border/60 bg-muted/20 px-6 py-12 text-center">
<ShieldAlert className="mx-auto h-10 w-10 text-muted-foreground" aria-hidden />
<h2 className="mt-3 text-base font-semibold text-foreground">Access denied</h2>
<p className="mt-1 text-sm text-muted-foreground max-w-md mx-auto">
You don't have permission to edit automations in this search space.
</p>
</div>
);
}
if (!validId) {
return <AutomationNotFound searchSpaceId={searchSpaceId} />;
}
if (isLoading) {
return <AutomationDetailLoading />;
}
if (error || !automation) {
return <AutomationNotFound searchSpaceId={searchSpaceId} error={error} />;
}
return <AutomationEditForm automation={automation} searchSpaceId={searchSpaceId} />;
}

View file

@ -0,0 +1,121 @@
"use client";
import { useAtomValue } from "jotai";
import { AlertCircle, ArrowLeft, Save } from "lucide-react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { updateAutomationMutationAtom } from "@/atoms/automations/automations-mutation.atoms";
import { JsonView } from "@/components/json-view";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Spinner } from "@/components/ui/spinner";
import {
type Automation,
automationUpdateRequest,
} from "@/contracts/types/automation.types";
interface AutomationEditFormProps {
automation: Automation;
searchSpaceId: number;
}
/**
* Edit-existing-automation form. Surfaces the four mutable fields
* (name, description, status, definition) as one editable JSON tree;
* triggers stay on the detail page where they have their own management
* UI. Validates with the same Zod schema the API expects, then PATCHes
* the changed shape back.
*/
export function AutomationEditForm({ automation, searchSpaceId }: AutomationEditFormProps) {
const router = useRouter();
const { mutateAsync: updateAutomation, isPending } = useAtomValue(updateAutomationMutationAtom);
const detailHref = `/dashboard/${searchSpaceId}/automations/${automation.id}`;
const [value, setValue] = useState(() => ({
name: automation.name,
description: automation.description ?? null,
status: automation.status,
definition: automation.definition,
}));
const [issues, setIssues] = useState<string[]>([]);
async function handleSave() {
setIssues([]);
const result = automationUpdateRequest.safeParse(value);
if (!result.success) {
setIssues(
result.error.issues.map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`)
);
return;
}
try {
await updateAutomation({ automationId: automation.id, patch: result.data });
router.push(detailHref);
} catch (err) {
setIssues([(err as Error).message ?? "Update failed"]);
}
}
return (
<>
<div className="space-y-3">
<Button asChild variant="ghost" size="sm" className="-ml-2 h-auto px-2 py-1">
<Link href={detailHref} className="text-xs text-muted-foreground">
<ArrowLeft className="mr-1.5 h-3.5 w-3.5" />
Back to automation
</Link>
</Button>
<div>
<h1 className="text-xl md:text-2xl font-semibold text-foreground break-words">
Edit automation
</h1>
<p className="text-sm text-muted-foreground mt-1">{automation.name}</p>
</div>
</div>
<Card className="border-border/60 bg-accent">
<CardHeader className="pb-4">
<CardTitle className="text-base font-semibold">Definition</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="rounded-md border border-input bg-background px-3 py-2 max-h-[36rem] overflow-auto">
<JsonView
src={value}
editable
onChange={(next) => setValue(next as typeof value)}
collapsed={false}
/>
</div>
{issues.length > 0 && (
<div className="rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2">
<div className="flex items-center gap-1.5 text-xs font-medium text-destructive mb-1.5">
<AlertCircle className="h-3.5 w-3.5" aria-hidden />
{issues.length === 1 ? "1 issue" : `${issues.length} issues`}
</div>
<ul className="space-y-0.5 text-xs text-destructive list-disc list-inside">
{issues.map((issue) => (
<li key={issue}>{issue}</li>
))}
</ul>
</div>
)}
<div className="flex items-center justify-end gap-2">
<Button asChild type="button" variant="ghost" size="sm">
<Link href={detailHref}>Cancel</Link>
</Button>
<Button type="button" onClick={handleSave} disabled={isPending} size="sm">
{isPending ? (
<Spinner size="xs" className="mr-2" />
) : (
<Save className="mr-2 h-4 w-4" />
)}
Save changes
</Button>
</div>
</CardContent>
</Card>
</>
);
}

View file

@ -0,0 +1,18 @@
import { AutomationEditContent } from "./automation-edit-content";
export default async function AutomationEditPage({
params,
}: {
params: Promise<{ search_space_id: string; automation_id: string }>;
}) {
const { search_space_id, automation_id } = await params;
return (
<div className="w-full space-y-6">
<AutomationEditContent
searchSpaceId={Number(search_space_id)}
automationId={Number(automation_id)}
/>
</div>
);
}

View file

@ -1,9 +1,10 @@
"use client";
import { useAtomValue } from "jotai";
import { AlertCircle, Code, FileJson, Save } from "lucide-react";
import { AlertCircle, FileJson, Save } from "lucide-react";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { createAutomationMutationAtom } from "@/atoms/automations/automations-mutation.atoms";
import { JsonView } from "@/components/json-view";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Spinner } from "@/components/ui/spinner";
@ -17,45 +18,24 @@ interface AutomationJsonFormProps {
/**
* Raw-JSON create form. Lets power users skip the chat drafter when they
* already know the shape they want. Flow:
* parse JSON inject search_space_id Zod validate POST navigate
* edit tree inject search_space_id Zod validate POST navigate
*
* ``search_space_id`` is injected here rather than required in the pasted
* payload the user shouldn't have to know their numeric id, and it
* keeps the template copy-paste-friendly across search spaces.
* ``search_space_id`` is injected here rather than required in the edited
* tree the user shouldn't have to know their numeric id, and it keeps
* the template copy-paste-friendly across search spaces.
*/
export function AutomationJsonForm({ searchSpaceId }: AutomationJsonFormProps) {
const router = useRouter();
const { mutateAsync: createAutomation, isPending } = useAtomValue(createAutomationMutationAtom);
const [text, setText] = useState(() => JSON.stringify(DEFAULT_AUTOMATION_TEMPLATE, null, 2));
const [value, setValue] = useState<Record<string, unknown>>(
() => DEFAULT_AUTOMATION_TEMPLATE as Record<string, unknown>
);
const [issues, setIssues] = useState<string[]>([]);
function handleFormat() {
try {
const parsed = JSON.parse(text);
setText(JSON.stringify(parsed, null, 2));
setIssues([]);
} catch (err) {
setIssues([`Cannot format — not valid JSON: ${(err as Error).message}`]);
}
}
async function handleSubmit() {
setIssues([]);
let parsed: unknown;
try {
parsed = JSON.parse(text);
} catch (err) {
setIssues([`Invalid JSON: ${(err as Error).message}`]);
return;
}
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
setIssues(["Root must be a JSON object."]);
return;
}
const payload = { ...(parsed as Record<string, unknown>), search_space_id: searchSpaceId };
const payload = { ...value, search_space_id: searchSpaceId };
const result = automationCreateRequest.safeParse(payload);
if (!result.success) {
setIssues(
@ -76,25 +56,21 @@ export function AutomationJsonForm({ searchSpaceId }: AutomationJsonFormProps) {
return (
<Card className="border-border/60 bg-accent">
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-4">
<CardHeader className="pb-4">
<CardTitle className="text-base font-semibold inline-flex items-center gap-2">
<FileJson className="h-4 w-4 text-muted-foreground" aria-hidden />
Definition + triggers
</CardTitle>
<Button type="button" variant="outline" size="sm" onClick={handleFormat}>
<Code className="mr-2 h-3.5 w-3.5" />
Format
</Button>
</CardHeader>
<CardContent className="space-y-4">
<textarea
value={text}
onChange={(e) => setText(e.target.value)}
spellCheck={false}
rows={24}
className="w-full rounded-md border border-input bg-background px-3 py-2 text-xs font-mono text-foreground shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring resize-y min-h-[16rem]"
aria-label="Automation JSON"
/>
<div className="rounded-md border border-input bg-background px-3 py-2 max-h-[32rem] overflow-auto">
<JsonView
src={value}
editable
onChange={(next) => setValue(next as Record<string, unknown>)}
collapsed={false}
/>
</div>
{hasIssues && (
<div className="rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2">

View file

@ -1,6 +1,6 @@
import { FileJson } from "lucide-react";
import React from "react";
import { defaultStyles, JsonView } from "react-json-view-lite";
import { JsonView } from "@/components/json-view";
import { Button } from "@/components/ui/button";
import {
Dialog,
@ -10,7 +10,6 @@ import {
DialogTrigger,
} from "@/components/ui/dialog";
import { Spinner } from "@/components/ui/spinner";
import "react-json-view-lite/dist/index.css";
interface JsonMetadataViewerProps {
title: string;
@ -56,13 +55,13 @@ export function JsonMetadataViewer({
{title} - Metadata
</DialogTitle>
</DialogHeader>
<div className="mt-2 sm:mt-4 p-2 sm:p-4 bg-muted/30 rounded-md text-xs sm:text-sm">
<div className="mt-2 sm:mt-4 p-2 sm:p-4 bg-muted/30 rounded-md text-xs sm:text-sm overflow-auto">
{loading ? (
<div className="flex items-center justify-center py-12">
<Spinner size="lg" className="text-muted-foreground" />
</div>
) : (
<JsonView data={jsonData} style={defaultStyles} />
<JsonView src={jsonData} collapsed={2} />
)}
</div>
</DialogContent>
@ -87,8 +86,8 @@ export function JsonMetadataViewer({
{title} - Metadata
</DialogTitle>
</DialogHeader>
<div className="mt-2 sm:mt-4 p-2 sm:p-4 bg-muted/30 rounded-md text-xs sm:text-sm">
<JsonView data={jsonData} style={defaultStyles} />
<div className="mt-2 sm:mt-4 p-2 sm:p-4 bg-muted/30 rounded-md text-xs sm:text-sm overflow-auto">
<JsonView src={jsonData} collapsed={2} />
</div>
</DialogContent>
</Dialog>

View file

@ -0,0 +1,93 @@
"use client";
import ReactJson, { type InteractionProps } from "@microlink/react-json-view";
import { useTheme } from "next-themes";
import { useCallback, useMemo } from "react";
/**
* Shared JSON viewer/editor wrapper around @microlink/react-json-view.
*
* One component, dual mode: passing ``editable`` + ``onChange`` enables
* inline value editing, key renaming, add and delete. Omitting them
* yields a read-only viewer. The underlying library is uncontrolled it
* mutates its own internal copy of ``src`` and surfaces the final tree on
* each interaction via ``updated_src``, which we forward to ``onChange``.
*
* Theme follows ``next-themes``: a dark base-16 palette in dark mode, the
* library's neutral default in light mode. Defaults are tuned for our
* compact UI surfaces (no data-type labels, no key quotes, triangle icons,
* tight indent).
*/
export interface JsonViewProps {
/** The JSON value to display. Primitives are wrapped under ``{ value }``
* because the underlying library requires an object root. */
src: unknown;
/** Enables value/key editing + add + delete. Requires ``onChange`` to
* observe the result; without it the toggle is silently a no-op. */
editable?: boolean;
/** Called with the full updated tree on every accepted interaction. */
onChange?: (next: unknown) => void;
/** Collapse depth. ``true`` collapses everything past the root; a number
* collapses from that depth onward. */
collapsed?: boolean | number;
/** Root label. Default ``false`` (no label — saves vertical space). */
name?: string | false;
className?: string;
}
const DARK_THEME = "monokai" as const;
const LIGHT_THEME = "rjv-default" as const;
const SHARED_DEFAULTS = {
iconStyle: "triangle" as const,
indentWidth: 2,
enableClipboard: true,
displayDataTypes: false,
displayObjectSize: true,
quotesOnKeys: false,
collapseStringsAfterLength: 80,
};
export function JsonView({
src,
editable = false,
onChange,
collapsed = 2,
name = false,
className,
}: JsonViewProps) {
const { resolvedTheme } = useTheme();
const theme = resolvedTheme === "dark" ? DARK_THEME : LIGHT_THEME;
// The library throws on non-object roots. Wrap primitives and null/undefined.
const safeSrc = useMemo(() => {
if (src && typeof src === "object") return src as object;
return { value: src };
}, [src]);
const handleChange = useCallback(
(interaction: InteractionProps) => {
onChange?.(interaction.updated_src);
return true;
},
[onChange]
);
const interactive = editable && onChange ? handleChange : (false as const);
return (
<div className={className}>
<ReactJson
src={safeSrc}
name={name}
theme={theme}
collapsed={collapsed}
onEdit={interactive}
onAdd={interactive}
onDelete={interactive}
style={{ backgroundColor: "transparent", fontSize: 12, fontFamily: "var(--font-mono)" }}
{...SHARED_DEFAULTS}
/>
</div>
);
}

View file

@ -2,17 +2,11 @@
import type { ToolCallMessagePartProps } from "@assistant-ui/react";
import { useAtomValue } from "jotai";
import {
AlertCircle,
Code,
CornerDownLeftIcon,
ExternalLink,
Pencil,
Workflow,
} from "lucide-react";
import { AlertCircle, CornerDownLeftIcon, ExternalLink, Pencil, Workflow } from "lucide-react";
import Link from "next/link";
import { useCallback, useEffect, useMemo, useState } from "react";
import { activeSearchSpaceIdAtom } from "@/atoms/search-spaces/search-space-query.atoms";
import { JsonView } from "@/components/json-view";
import { TextShimmerLoader } from "@/components/prompt-kit/loader";
import { Button } from "@/components/ui/button";
import { automationCreateRequest } from "@/contracts/types/automation.types";
@ -231,28 +225,12 @@ interface JsonEditorProps {
}
function JsonEditor({ initialValue, onSave, onCancel }: JsonEditorProps) {
const [text, setText] = useState(() => JSON.stringify(initialValue, null, 2));
const [value, setValue] = useState<Record<string, unknown>>(initialValue);
const [issues, setIssues] = useState<string[]>([]);
function handleFormat() {
try {
setText(JSON.stringify(JSON.parse(text), null, 2));
setIssues([]);
} catch (err) {
setIssues([`Cannot format — not valid JSON: ${(err as Error).message}`]);
}
}
function handleSave() {
setIssues([]);
let parsed: unknown;
try {
parsed = JSON.parse(text);
} catch (err) {
setIssues([`Invalid JSON: ${(err as Error).message}`]);
return;
}
const result = editArgsSchema.safeParse(parsed);
const result = editArgsSchema.safeParse(value);
if (!result.success) {
setIssues(
result.error.issues.map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`)
@ -264,14 +242,14 @@ function JsonEditor({ initialValue, onSave, onCancel }: JsonEditorProps) {
return (
<div className="space-y-3">
<textarea
value={text}
onChange={(e) => setText(e.target.value)}
spellCheck={false}
rows={16}
className="w-full rounded-md border border-input bg-background px-3 py-2 text-xs font-mono text-foreground shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring resize-y min-h-[12rem]"
aria-label="Automation JSON"
/>
<div className="rounded-md border border-input bg-background px-3 py-2 max-h-[24rem] overflow-auto">
<JsonView
src={value}
editable
onChange={(next) => setValue(next as Record<string, unknown>)}
collapsed={false}
/>
</div>
{issues.length > 0 && (
<div className="rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2">
<div className="flex items-center gap-1.5 text-xs font-medium text-destructive">
@ -291,10 +269,6 @@ function JsonEditor({ initialValue, onSave, onCancel }: JsonEditorProps) {
<Button type="button" variant="ghost" size="sm" onClick={onCancel}>
Cancel
</Button>
<Button type="button" variant="outline" size="sm" onClick={handleFormat}>
<Code className="mr-1.5 h-3.5 w-3.5" />
Format
</Button>
<Button type="button" size="sm" onClick={handleSave}>
Save edits
</Button>

View file

@ -36,6 +36,7 @@
"@babel/standalone": "^7.29.2",
"@hookform/resolvers": "^5.2.2",
"@marsidev/react-turnstile": "^1.5.0",
"@microlink/react-json-view": "^1.31.20",
"@monaco-editor/react": "^4.7.0",
"@number-flow/react": "^0.5.10",
"@platejs/autoformat": "^52.0.11",
@ -134,7 +135,6 @@
"react-dom": "^19.2.3",
"react-dropzone": "^14.3.8",
"react-hook-form": "^7.61.1",
"react-json-view-lite": "^2.4.1",
"react-syntax-highlighter": "^15.6.1",
"react-wrap-balancer": "^1.1.1",
"rehype-katex": "^7.0.1",

View file

@ -29,6 +29,9 @@ importers:
'@marsidev/react-turnstile':
specifier: ^1.5.0
version: 1.5.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@microlink/react-json-view':
specifier: ^1.31.20
version: 1.31.20(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@monaco-editor/react':
specifier: ^4.7.0
version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@ -323,9 +326,6 @@ importers:
react-hook-form:
specifier: ^7.61.1
version: 7.71.2(react@19.2.4)
react-json-view-lite:
specifier: ^2.4.1
version: 2.5.0(react@19.2.4)
react-syntax-highlighter:
specifier: ^15.6.1
version: 15.6.6(react@19.2.4)
@ -1143,24 +1143,28 @@ packages:
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@biomejs/cli-linux-arm64@2.4.6':
resolution: {integrity: sha512-kMLaI7OF5GN1Q8Doymjro1P8rVEoy7BKQALNz6fiR8IC1WKduoNyteBtJlHT7ASIL0Cx2jR6VUOBIbcB1B8pew==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@biomejs/cli-linux-x64-musl@2.4.6':
resolution: {integrity: sha512-C9s98IPDu7DYarjlZNuzJKTjVHN03RUnmHV5htvqsx6vEUXCDSJ59DNwjKVD5XYoSS4N+BYhq3RTBAL8X6svEg==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
libc: [musl]
'@biomejs/cli-linux-x64@2.4.6':
resolution: {integrity: sha512-oHXmUFEoH8Lql1xfc3QkFLiC1hGR7qedv5eKNlC185or+o4/4HiaU7vYODAH3peRCfsuLr1g6v2fK9dFFOYdyw==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@biomejs/cli-win32-arm64@2.4.6':
resolution: {integrity: sha512-xzThn87Pf3YrOGTEODFGONmqXpTwUNxovQb72iaUOdcw8sBSY3+3WD8Hm9IhMYLnPi0n32s3L3NWU6+eSjfqFg==}
@ -1836,89 +1840,105 @@ packages:
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-arm@1.2.4':
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
cpu: [arm]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-ppc64@1.2.4':
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-riscv64@1.2.4':
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-s390x@1.2.4':
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-x64@1.2.4':
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
cpu: [x64]
os: [linux]
libc: [musl]
'@img/sharp-linux-arm64@0.34.5':
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@img/sharp-linux-arm@0.34.5':
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm]
os: [linux]
libc: [glibc]
'@img/sharp-linux-ppc64@0.34.5':
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@img/sharp-linux-riscv64@0.34.5':
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@img/sharp-linux-s390x@0.34.5':
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@img/sharp-linux-x64@0.34.5':
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@img/sharp-linuxmusl-arm64@0.34.5':
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@img/sharp-linuxmusl-x64@0.34.5':
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@img/sharp-wasm32@0.34.5':
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
@ -1989,6 +2009,13 @@ packages:
peerDependencies:
mediabunny: ^1.0.0
'@microlink/react-json-view@1.31.20':
resolution: {integrity: sha512-gNLkGvjFDeAqVGvK3H7lfoDqetn/9lW2ugiYiJhchc7jQU1ZaKsZnt97ANluXWFfd/wifoA9TrVOTsUXwXCJwA==}
engines: {node: '>=17'}
peerDependencies:
react: '>= 15'
react-dom: '>= 15'
'@monaco-editor/loader@1.7.0':
resolution: {integrity: sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA==}
@ -2028,30 +2055,35 @@ packages:
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@napi-rs/canvas-linux-arm64-musl@0.1.97':
resolution: {integrity: sha512-kKmSkQVnWeqg7qdsiXvYxKhAFuHz3tkBjW/zyQv5YKUPhotpaVhpBGv5LqCngzyuRV85SXoe+OFj+Tv0a0QXkQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@napi-rs/canvas-linux-riscv64-gnu@0.1.97':
resolution: {integrity: sha512-Jc7I3A51jnEOIAXeLsN/M/+Z28LUeakcsXs07FLq9prXc0eYOtVwsDEv913Gr+06IRo34gJJVgT0TXvmz+N2VA==}
engines: {node: '>= 10'}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@napi-rs/canvas-linux-x64-gnu@0.1.97':
resolution: {integrity: sha512-iDUBe7AilfuBSRbSa8/IGX38Mf+iCSBqoVKLSQ5XaY2JLOaqz1TVyPFEyIck7wT6mRQhQt5sN6ogfjIDfi74tg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@napi-rs/canvas-linux-x64-musl@0.1.97':
resolution: {integrity: sha512-AKLFd/v0Z5fvgqBDqhvqtAdx+fHMJ5t9JcUNKq4FIZ5WH+iegGm8HPdj00NFlCSnm83Fp3Ln8I2f7uq1aIiWaA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
libc: [musl]
'@napi-rs/canvas-win32-arm64-msvc@0.1.97':
resolution: {integrity: sha512-u883Yr6A6fO7Vpsy9YE4FVCIxzzo5sO+7pIUjjoDLjS3vQaNMkVzx5bdIpEL+ob+gU88WDK4VcxYMZ6nmnoX9A==}
@ -2095,24 +2127,28 @@ packages:
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@next/swc-linux-arm64-musl@16.1.6':
resolution: {integrity: sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@next/swc-linux-x64-gnu@16.1.6':
resolution: {integrity: sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@next/swc-linux-x64-musl@16.1.6':
resolution: {integrity: sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
libc: [musl]
'@next/swc-win32-arm64-msvc@16.1.6':
resolution: {integrity: sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw==}
@ -2768,48 +2804,56 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-arm64-musl@0.45.0':
resolution: {integrity: sha512-XQKXZIKYJC3GQJ8FnD3iMntpw69Wd9kDDK/Xt79p6xnFYlGGxSNv2vIBvRTDg5CKByWFWWZLCRDOXoP/m6YN4g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@oxfmt/binding-linux-ppc64-gnu@0.45.0':
resolution: {integrity: sha512-+g5RiG+xOkdrCWkKodv407nTvMq4vYM18Uox2MhZBm/YoqFxxJpWKsloskFFG5NU13HGPw1wzYjjOVcyd9moCA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-riscv64-gnu@0.45.0':
resolution: {integrity: sha512-V7dXKoSyEbWAkkSF4JJNtF+NJZDmJoSarSoP30WCsB3X636Rehd3CvxBj49FIJxEBFWhvcUjGSHVeU8Erck1bQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-riscv64-musl@0.45.0':
resolution: {integrity: sha512-Vdelft1sAEYojVGgcODEFXSWYQYlIvoyIGWebKCuUibd1tvS1TjTx413xG2ZLuHpYj45CkN/ztMLMX6jrgqpgg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@oxfmt/binding-linux-s390x-gnu@0.45.0':
resolution: {integrity: sha512-RR7xKgNpqwENnK0aYCGYg0JycY2n93J0reNjHyes+I9Gq52dH95x+CBlnlAQHCPfz6FGnKA9HirgUl14WO6o7w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-x64-gnu@0.45.0':
resolution: {integrity: sha512-U/QQ0+BQNSHxjuXR/utvXnQ50Vu5kUuqEomZvQ1/3mhgbBiMc2WU9q5kZ5WwLp3gnFIx9ibkveoRSe2EZubkqg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@oxfmt/binding-linux-x64-musl@0.45.0':
resolution: {integrity: sha512-o5TLOUCF0RWQjsIS06yVC+kFgp092/yLe6qBGSUvtnmTVw9gxjpdQSXc3VN5Cnive4K11HNstEZF8ROKHfDFSw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@oxfmt/binding-openharmony-arm64@0.45.0':
resolution: {integrity: sha512-RnGcV3HgPuOjsGx/k9oyRNKmOp+NBLGzZTdPDYbc19r7NGeYPplnUU/BfU35bX2Y/O4ejvHxcfkvW2WoYL/gsg==}
@ -2864,36 +2908,42 @@ packages:
engines: {node: '>= 10.0.0'}
cpu: [arm]
os: [linux]
libc: [glibc]
'@parcel/watcher-linux-arm-musl@2.5.6':
resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==}
engines: {node: '>= 10.0.0'}
cpu: [arm]
os: [linux]
libc: [musl]
'@parcel/watcher-linux-arm64-glibc@2.5.6':
resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@parcel/watcher-linux-arm64-musl@2.5.6':
resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@parcel/watcher-linux-x64-glibc@2.5.6':
resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@parcel/watcher-linux-x64-musl@2.5.6':
resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [linux]
libc: [musl]
'@parcel/watcher-win32-arm64@2.5.6':
resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==}
@ -4222,66 +4272,79 @@ packages:
resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==}
cpu: [arm]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm-musleabihf@4.59.0':
resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==}
cpu: [arm]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-arm64-gnu@4.59.0':
resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm64-musl@4.59.0':
resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-loong64-gnu@4.59.0':
resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==}
cpu: [loong64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-loong64-musl@4.59.0':
resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==}
cpu: [loong64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-ppc64-gnu@4.59.0':
resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-ppc64-musl@4.59.0':
resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==}
cpu: [ppc64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-riscv64-gnu@4.59.0':
resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-riscv64-musl@4.59.0':
resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-s390x-gnu@4.59.0':
resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-gnu@4.59.0':
resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-musl@4.59.0':
resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==}
cpu: [x64]
os: [linux]
libc: [musl]
'@rollup/rollup-openbsd-x64@4.59.0':
resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==}
@ -4472,24 +4535,28 @@ packages:
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@swc/core-linux-arm64-musl@1.15.13':
resolution: {integrity: sha512-SmZ9m+XqCB35NddHCctvHFLqPZDAs5j8IgD36GoutufDJmeq2VNfgk5rQoqNqKmAK3Y7iFdEmI76QoHIWiCLyw==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@swc/core-linux-x64-gnu@1.15.13':
resolution: {integrity: sha512-5rij+vB9a29aNkHq72EXI2ihDZPszJb4zlApJY4aCC/q6utgqFA6CkrfTfIb+O8hxtG3zP5KERETz8mfFK6A0A==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@swc/core-linux-x64-musl@1.15.13':
resolution: {integrity: sha512-OlSlaOK9JplQ5qn07WiBLibkOw7iml2++ojEXhhR3rbWrNEKCD7sd8+6wSavsInyFdw4PhLA+Hy6YyDBIE23Yw==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
libc: [musl]
'@swc/core-win32-arm64-msvc@1.15.13':
resolution: {integrity: sha512-zwQii5YVdsfG8Ti9gIKgBKZg8qMkRZxl+OlYWUT5D93Jl4NuNBRausP20tfEkQdAPSRrMCSUZBM6FhW7izAZRg==}
@ -4573,24 +4640,28 @@ packages:
engines: {node: '>= 20'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@tailwindcss/oxide-linux-arm64-musl@4.2.1':
resolution: {integrity: sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==}
engines: {node: '>= 20'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@tailwindcss/oxide-linux-x64-gnu@4.2.1':
resolution: {integrity: sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==}
engines: {node: '>= 20'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@tailwindcss/oxide-linux-x64-musl@4.2.1':
resolution: {integrity: sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==}
engines: {node: '>= 20'}
cpu: [x64]
os: [linux]
libc: [musl]
'@tailwindcss/oxide-wasm32-wasi@4.2.1':
resolution: {integrity: sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==}
@ -4732,6 +4803,9 @@ packages:
'@types/katex@0.16.8':
resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==}
'@types/lodash@4.17.24':
resolution: {integrity: sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==}
'@types/mdast@4.0.4':
resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
@ -4915,41 +4989,49 @@ packages:
resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@unrs/resolver-binding-linux-arm64-musl@1.11.1':
resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@unrs/resolver-binding-linux-ppc64-gnu@1.11.1':
resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@unrs/resolver-binding-linux-riscv64-gnu@1.11.1':
resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@unrs/resolver-binding-linux-riscv64-musl@1.11.1':
resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@unrs/resolver-binding-linux-s390x-gnu@1.11.1':
resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@unrs/resolver-binding-linux-x64-gnu@1.11.1':
resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@unrs/resolver-binding-linux-x64-musl@1.11.1':
resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==}
cpu: [x64]
os: [linux]
libc: [musl]
'@unrs/resolver-binding-wasm32-wasi@1.11.1':
resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==}
@ -5323,6 +5405,13 @@ packages:
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
color-string@1.9.1:
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
color@4.2.3:
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
engines: {node: '>=12.5.0'}
comma-separated-tokens@1.0.8:
resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==}
@ -6471,6 +6560,9 @@ packages:
is-arrayish@0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
is-arrayish@0.3.4:
resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==}
is-async-function@2.1.1:
resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==}
engines: {node: '>= 0.4'}
@ -6838,24 +6930,28 @@ packages:
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
libc: [glibc]
lightningcss-linux-arm64-musl@1.31.1:
resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
libc: [musl]
lightningcss-linux-x64-gnu@1.31.1:
resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
libc: [glibc]
lightningcss-linux-x64-musl@1.31.1:
resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
libc: [musl]
lightningcss-win32-arm64-msvc@1.31.1:
resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==}
@ -6880,6 +6976,9 @@ packages:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
lodash-es@4.18.1:
resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==}
lodash.camelcase@4.3.0:
resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
@ -7673,6 +7772,9 @@ packages:
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
hasBin: true
react-base16-styling@0.10.0:
resolution: {integrity: sha512-H1k2eFB6M45OaiRru3PBXkuCcn2qNmx+gzLb4a9IPMR7tMH8oBRXU5jGbPDYG1Hz+82d88ED0vjR8BmqU3pQdg==}
react-compiler-runtime@1.0.0:
resolution: {integrity: sha512-rRfjYv66HlG8896yPUDONgKzG5BxZD1nV9U6rkm+7VCuvQc903C4MjcoZR4zPw53IKSOX9wMQVpA1IAbRtzQ7w==}
peerDependencies:
@ -7729,11 +7831,8 @@ packages:
react-is@16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
react-json-view-lite@2.5.0:
resolution: {integrity: sha512-tk7o7QG9oYyELWHL8xiMQ8x4WzjCzbWNyig3uexmkLb54r8jO0yH3WCWx8UZS0c49eSA4QUmG5caiRJ8fAn58g==}
engines: {node: '>=18'}
peerDependencies:
react: ^18.0.0 || ^19.0.0
react-lifecycles-compat@3.0.4:
resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==}
react-markdown@10.1.0:
resolution: {integrity: sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==}
@ -8121,6 +8220,9 @@ packages:
simple-get@4.0.1:
resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==}
simple-swizzle@0.2.4:
resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==}
slate-dom@0.119.0:
resolution: {integrity: sha512-foc8a2NkE+1SldDIYaoqjhVKupt8RSuvHI868rfYOcypD4we5TT7qunjRKJ852EIRh/Ql8sSTepXgXKOUJnt1w==}
peerDependencies:
@ -10316,6 +10418,16 @@ snapshots:
dependencies:
mediabunny: 1.39.2
'@microlink/react-json-view@1.31.20(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
dependencies:
react: 19.2.4
react-base16-styling: 0.10.0
react-dom: 19.2.4(react@19.2.4)
react-lifecycles-compat: 3.0.4
react-textarea-autosize: 8.5.9(@types/react@19.2.14)(react@19.2.4)
transitivePeerDependencies:
- '@types/react'
'@monaco-editor/loader@1.7.0':
dependencies:
state-local: 1.0.7
@ -13283,6 +13395,8 @@ snapshots:
'@types/katex@0.16.8': {}
'@types/lodash@4.17.24': {}
'@types/mdast@4.0.4':
dependencies:
'@types/unist': 3.0.3
@ -13905,6 +14019,16 @@ snapshots:
color-name@1.1.4: {}
color-string@1.9.1:
dependencies:
color-name: 1.1.4
simple-swizzle: 0.2.4
color@4.2.3:
dependencies:
color-convert: 2.0.1
color-string: 1.9.1
comma-separated-tokens@1.0.8: {}
comma-separated-tokens@2.0.3: {}
@ -15327,6 +15451,8 @@ snapshots:
is-arrayish@0.2.1: {}
is-arrayish@0.3.4: {}
is-async-function@2.1.1:
dependencies:
async-function: 1.0.0
@ -15662,6 +15788,8 @@ snapshots:
dependencies:
p-locate: 5.0.0
lodash-es@4.18.1: {}
lodash.camelcase@4.3.0: {}
lodash.debounce@4.0.8: {}
@ -16843,6 +16971,13 @@ snapshots:
minimist: 1.2.8
strip-json-comments: 2.0.1
react-base16-styling@0.10.0:
dependencies:
'@types/lodash': 4.17.24
color: 4.2.3
csstype: 3.2.3
lodash-es: 4.18.1
react-compiler-runtime@1.0.0(react@19.2.4):
dependencies:
react: 19.2.4
@ -16894,9 +17029,7 @@ snapshots:
react-is@16.13.1: {}
react-json-view-lite@2.5.0(react@19.2.4):
dependencies:
react: 19.2.4
react-lifecycles-compat@3.0.4: {}
react-markdown@10.1.0(@types/react@19.2.14)(react@19.2.4):
dependencies:
@ -17458,6 +17591,10 @@ snapshots:
once: 1.4.0
simple-concat: 1.0.1
simple-swizzle@0.2.4:
dependencies:
is-arrayish: 0.3.4
slate-dom@0.119.0(slate@0.120.0):
dependencies:
'@juggle/resize-observer': 3.4.0