From 5cdfd69cc54b0d238496eda42f0669c871d8472e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 16 Aug 2026 02:17:57 +0000 Subject: [PATCH 1/3] Close the client load path: App Router, typed clients, and e2e seams Index Next.js app/pages routes and Server Actions as sinks, stitch RTK Query, openapi-fetch, tRPC, and ts-rest as high-confidence clients, and count Playwright/Cypress visits as tested_by on the published route. Treat GraphQL codegen types and Ninja/Pydantic nested schemas as the same contract family as DRF serializers. Resolve get_serializer_class returns and extract nested serializers, SerializerMethodField, and to_representation keys so those stop dumping to residual AI. Co-authored-by: zord.lack.net --- README.md | 12 +- fixtures/demo_monorepo/backend/billing/api.py | 16 +- .../backend/billing/serializers.py | 25 + .../demo_monorepo/backend/billing/views.py | 12 +- .../frontend/e2e/invoice.spec.ts | 7 + .../frontend/src/app/invoices/[id]/actions.ts | 6 + .../frontend/src/app/invoices/[id]/page.tsx | 13 + .../src/features/billing/invoice.graphql | 6 + .../src/features/billing/invoiceApi.ts | 14 + .../src/features/billing/openapiFetch.ts | 7 + .../frontend/src/features/billing/trpc.ts | 7 + .../frontend/src/generated/graphql.ts | 12 + fixtures/demo_monorepo/loadpath.yml | 2 +- src/loadpath/architecture/snapshot.py | 1 + src/loadpath/config.py | 1 + src/loadpath/detect.py | 1 + src/loadpath/extractors/django.py | 254 ++++++++- src/loadpath/extractors/react.py | 494 +++++++++++++++++- src/loadpath/index.py | 4 +- src/loadpath/review/cluster.py | 1 + src/loadpath/review/engine.py | 5 +- src/loadpath/review/suggested_tests.py | 28 + src/loadpath/stitch/openapi.py | 202 ++++++- src/loadpath/types.py | 2 + tests/e2e/conftest.py | 8 + tests/e2e/test_ui_flows.py | 3 +- tests/unit/test_depth.py | 34 +- tests/unit/test_django_extractors.py | 47 ++ tests/unit/test_index_and_stitch.py | 20 + tests/unit/test_overlays.py | 3 + tests/unit/test_react_extractors.py | 91 ++++ ui/src/graphView.ts | 1 + ui/src/nodeInspector.ts | 54 +- ui/src/types.ts | 1 + 34 files changed, 1349 insertions(+), 45 deletions(-) create mode 100644 fixtures/demo_monorepo/frontend/e2e/invoice.spec.ts create mode 100644 fixtures/demo_monorepo/frontend/src/app/invoices/[id]/actions.ts create mode 100644 fixtures/demo_monorepo/frontend/src/app/invoices/[id]/page.tsx create mode 100644 fixtures/demo_monorepo/frontend/src/features/billing/invoice.graphql create mode 100644 fixtures/demo_monorepo/frontend/src/features/billing/invoiceApi.ts create mode 100644 fixtures/demo_monorepo/frontend/src/features/billing/openapiFetch.ts create mode 100644 fixtures/demo_monorepo/frontend/src/features/billing/trpc.ts create mode 100644 fixtures/demo_monorepo/frontend/src/generated/graphql.ts diff --git a/README.md b/README.md index 8fefcb0..004bd64 100644 --- a/README.md +++ b/README.md @@ -258,11 +258,11 @@ AST is the default extractor. It is a **framework overlay**, not an import graph | Surface | What Loadpath extracts | | --- | --- | | Models | Fields, FK / M2M / O2O, `on_delete`, string refs (`ForeignKey("accounts.User")`) as residuals | -| Serializers | `Meta.fields` / `exclude`, declared fields, `serializes` edges, queryset-in-serializer flag | -| Views | DRF ViewSets / APIViews, `serializer_class`, `get_serializer_class` (residual), `permission_classes`, `get_queryset`, `filterset_class`, `authentication_classes`, `pagination_class` | +| Serializers | `Meta.fields` / `exclude`, declared fields, nested serializers, `SerializerMethodField`, parsed `to_representation` keys, `serializes` edges, queryset-in-serializer flag | +| Views | DRF ViewSets / APIViews, `serializer_class`, `get_serializer_class` (resolved returns; residual only when unresolved), `permission_classes`, `get_queryset`, `filterset_class`, `authentication_classes`, `pagination_class` | | Function views | `@api_view`, `@login_required`, `@csrf_exempt`, … | -| Django Ninja | `@router.get/post/…` routes and views | -| FastAPI (same repo) | `@app.get/post/…` and Pydantic `BaseModel` — only when the file imports FastAPI, so Ninja is not stolen | +| Django Ninja | `@router.get/post/…` routes and views, `Schema` / `ModelSchema` fields (including nested), response annotation → schema | +| FastAPI (same repo) | `@app.get/post/…` and Pydantic `BaseModel` (nested annotations) — only when the file imports FastAPI, so Ninja is not stolen | | GraphQL | Strawberry `@strawberry.type` / `@strawberry.field` and Graphene `ObjectType` / `Mutation`; client `gql` documents stitch by operation/selection name | | Channels | `WebsocketConsumer` subclasses and `path(..., Consumer.as_asgi())` websocket routes | | Templates + HTMX | `.html` files, `{% url %}` / include / extends, `hx-get/post/…` stitched to Django routes | @@ -301,9 +301,9 @@ AST is enough for review. If you need live `_meta` (db_table, resolved relations ## React + stitch -**React:** react-router tables, composition, TanStack Query `queryKey` + fetch/axios URL templates, Zod schemas, feature-folder imports, RTL `render()` as `tested_by`. +**React:** react-router tables, Next.js App Router (`app/**/page.tsx`) and Pages Router, Server Actions, composition, TanStack Query `queryKey` + fetch/axios URL templates, RTK Query `createApi` endpoints, openapi-fetch `client.GET/POST`, tRPC procedures, ts-rest `path:` contracts, Zod schemas, GraphQL codegen types, feature-folder imports, RTL `render()` and Playwright/Cypress `page.goto` / `cy.visit` as `tested_by`. -**Stitch (the moat):** OpenAPI from Spectacular/schema files first; generated clients (`generated/`, orval, openapi-typescript) as high-confidence `consumed_by_client`; FastAPI routes and GraphQL operations stitch the same way; HTMX URLs match Django routes; fallback URL-template matching and serializer/Zod field overlap marked **inferred**. +**Stitch (the moat):** OpenAPI from Spectacular/schema files first; generated clients (`generated/`, orval, openapi-typescript) and typed clients (RTK Query, openapi-fetch, ts-rest, tRPC) as high-confidence `consumed_by_client`; FastAPI routes, Ninja/Pydantic schemas, and GraphQL operations (including codegen types) stitch the same way; HTMX URLs and Playwright/Cypress visits match Django/React routes; fallback URL-template matching and serializer/Zod field overlap marked **inferred**. Frontend roots prefer `frontend/src`, `frontend`, `web/src`, `client/src`, `ui/src`, `src-ui/src` — not a Python package `src/` and not `docs` / docs-site trees. `app/` is a Django root candidate. diff --git a/fixtures/demo_monorepo/backend/billing/api.py b/fixtures/demo_monorepo/backend/billing/api.py index 4f0afa6..90ef7cd 100644 --- a/fixtures/demo_monorepo/backend/billing/api.py +++ b/fixtures/demo_monorepo/backend/billing/api.py @@ -1,11 +1,21 @@ -from ninja import Router +from ninja import Router, Schema from billing.models import Invoice router = Router() +class LedgerLineSchema(Schema): + amount: str + kind: str + + +class InvoiceSchema(Schema): + total: str + lines: list[LedgerLineSchema] + + @router.get("/invoices/{invoice_id}/ledger") -def invoice_ledger(request, invoice_id: int): +def invoice_ledger(request, invoice_id: int) -> InvoiceSchema: invoice = Invoice.objects.get(pk=invoice_id) - return {"total": str(invoice.total)} + return InvoiceSchema(total=str(invoice.total), lines=[]) diff --git a/fixtures/demo_monorepo/backend/billing/serializers.py b/fixtures/demo_monorepo/backend/billing/serializers.py index 485530b..3f61acc 100644 --- a/fixtures/demo_monorepo/backend/billing/serializers.py +++ b/fixtures/demo_monorepo/backend/billing/serializers.py @@ -7,3 +7,28 @@ class InvoiceSerializer(serializers.ModelSerializer): class Meta: model = Invoice fields = ["id", "customer_id", "total", "status"] + + +class LineSerializer(serializers.Serializer): + amount = serializers.DecimalField(max_digits=10, decimal_places=2) + kind = serializers.CharField() + + +class InvoiceDetailSerializer(serializers.ModelSerializer): + lines = LineSerializer(many=True) + display_total = serializers.SerializerMethodField() + + class Meta: + model = Invoice + fields = ["id", "customer_id", "total", "status", "lines", "display_total"] + + def get_display_total(self, obj): + return str(obj.total) + + def to_representation(self, instance): + return { + "id": instance.id, + "total": str(instance.total), + "status": instance.status, + "display_total": str(instance.total), + } diff --git a/fixtures/demo_monorepo/backend/billing/views.py b/fixtures/demo_monorepo/backend/billing/views.py index bdb6e41..7aeb8af 100644 --- a/fixtures/demo_monorepo/backend/billing/views.py +++ b/fixtures/demo_monorepo/backend/billing/views.py @@ -9,7 +9,7 @@ from billing.actors import rebuild_ledger from billing.models import Invoice -from billing.serializers import InvoiceSerializer +from billing.serializers import InvoiceDetailSerializer, InvoiceSerializer from billing.tasks import send_invoice_email @@ -37,6 +37,16 @@ def perform_create(self, serializer): return invoice +class InvoiceDetailViewSet(viewsets.ReadOnlyModelViewSet): + permission_classes = [IsAuthenticated] + queryset = Invoice.objects.all() + + def get_serializer_class(self): + if self.action == "list": + return InvoiceSerializer + return InvoiceDetailSerializer + + class InvoiceBoardView(TemplateView): template_name = "billing/invoice_board.html" diff --git a/fixtures/demo_monorepo/frontend/e2e/invoice.spec.ts b/fixtures/demo_monorepo/frontend/e2e/invoice.spec.ts new file mode 100644 index 0000000..f5d5033 --- /dev/null +++ b/fixtures/demo_monorepo/frontend/e2e/invoice.spec.ts @@ -0,0 +1,7 @@ +import { expect, test } from "@playwright/test"; + +test("invoice page load path", async ({ page }) => { + await page.goto("/invoices/1"); + await page.request.get("/api/invoices/1"); + await expect(page.getByRole("heading")).toBeVisible(); +}); diff --git a/fixtures/demo_monorepo/frontend/src/app/invoices/[id]/actions.ts b/fixtures/demo_monorepo/frontend/src/app/invoices/[id]/actions.ts new file mode 100644 index 0000000..9eda193 --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/app/invoices/[id]/actions.ts @@ -0,0 +1,6 @@ +"use server"; + +export async function saveInvoice(formData: FormData) { + const id = String(formData.get("id") || ""); + return id; +} diff --git a/fixtures/demo_monorepo/frontend/src/app/invoices/[id]/page.tsx b/fixtures/demo_monorepo/frontend/src/app/invoices/[id]/page.tsx new file mode 100644 index 0000000..ee978bd --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/app/invoices/[id]/page.tsx @@ -0,0 +1,13 @@ +import { InvoiceForm } from "../../../features/billing/InvoiceForm"; +import { saveInvoice } from "./actions"; + +export default function InvoicesPage({ params }: { params: { id: string } }) { + return ( +
+ +
+ +
+
+ ); +} diff --git a/fixtures/demo_monorepo/frontend/src/features/billing/invoice.graphql b/fixtures/demo_monorepo/frontend/src/features/billing/invoice.graphql new file mode 100644 index 0000000..ef81b93 --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/features/billing/invoice.graphql @@ -0,0 +1,6 @@ +query Invoice($id: ID!) { + invoice { + total + status + } +} diff --git a/fixtures/demo_monorepo/frontend/src/features/billing/invoiceApi.ts b/fixtures/demo_monorepo/frontend/src/features/billing/invoiceApi.ts new file mode 100644 index 0000000..7d5a61d --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/features/billing/invoiceApi.ts @@ -0,0 +1,14 @@ +import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; + +export const invoiceApi = createApi({ + reducerPath: "invoiceApi", + baseQuery: fetchBaseQuery({ baseUrl: "/api" }), + endpoints: (builder) => ({ + getInvoice: builder.query({ + query: (id: string) => `/invoices/${id}`, + }), + saveInvoice: builder.mutation({ + query: (body: unknown) => ({ url: "/invoices", method: "POST", body }), + }), + }), +}); diff --git a/fixtures/demo_monorepo/frontend/src/features/billing/openapiFetch.ts b/fixtures/demo_monorepo/frontend/src/features/billing/openapiFetch.ts new file mode 100644 index 0000000..a707424 --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/features/billing/openapiFetch.ts @@ -0,0 +1,7 @@ +declare const client: { + GET: (path: string, init?: unknown) => Promise; +}; + +export function getInvoiceTyped(id: string) { + return client.GET("/api/invoices/{id}", { params: { path: { id } } }); +} diff --git a/fixtures/demo_monorepo/frontend/src/features/billing/trpc.ts b/fixtures/demo_monorepo/frontend/src/features/billing/trpc.ts new file mode 100644 index 0000000..5851fac --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/features/billing/trpc.ts @@ -0,0 +1,7 @@ +declare const trpc: { + invoice: { get: { useQuery: (args: { id: string }) => unknown } }; +}; + +export function useInvoiceRpc(id: string) { + return trpc.invoice.get.useQuery({ id }); +} diff --git a/fixtures/demo_monorepo/frontend/src/generated/graphql.ts b/fixtures/demo_monorepo/frontend/src/generated/graphql.ts new file mode 100644 index 0000000..d0cc75a --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/generated/graphql.ts @@ -0,0 +1,12 @@ +/** graphql-codegen types — stitch to InvoiceType by field overlap. */ +export type InvoiceType = { + __typename?: "InvoiceType"; + id: number; + total: number; + status: string; +}; + +export type InvoiceQuery = { + __typename?: "Query"; + invoice?: InvoiceType | null; +}; diff --git a/fixtures/demo_monorepo/loadpath.yml b/fixtures/demo_monorepo/loadpath.yml index 7e49888..9c04a46 100644 --- a/fixtures/demo_monorepo/loadpath.yml +++ b/fixtures/demo_monorepo/loadpath.yml @@ -2,7 +2,7 @@ contexts: billing: django_apps: [billing] - react: [src/features/billing, frontend/src/features/billing] + react: [src/features/billing, frontend/src/features/billing, frontend/src/app/invoices] public_api: - "GET /api/invoices" - "POST /api/invoices" diff --git a/src/loadpath/architecture/snapshot.py b/src/loadpath/architecture/snapshot.py index 7b3e8b5..5ba32e0 100644 --- a/src/loadpath/architecture/snapshot.py +++ b/src/loadpath/architecture/snapshot.py @@ -30,6 +30,7 @@ NodeType.HOOK.value, NodeType.API_CLIENT.value, NodeType.FORM_SCHEMA.value, + NodeType.SERVER_ACTION.value, NodeType.GRAPHQL_TYPE.value, NodeType.GRAPHQL_OPERATION.value, NodeType.FASTAPI_ROUTE.value, diff --git a/src/loadpath/config.py b/src/loadpath/config.py index 60a63ae..2a356c0 100644 --- a/src/loadpath/config.py +++ b/src/loadpath/config.py @@ -55,6 +55,7 @@ class LoadpathConfig: "**/generated/**/*.{ts,tsx,js}", "**/*openapi*.{ts,js}", "**/orval/**/*.{ts,js}", + "**/*graphql*.{ts,tsx,js}", ] ) extra: dict[str, Any] = field(default_factory=dict) diff --git a/src/loadpath/detect.py b/src/loadpath/detect.py index 48ac662..315b7a9 100644 --- a/src/loadpath/detect.py +++ b/src/loadpath/detect.py @@ -176,6 +176,7 @@ def _detect_django_root(repo_root: Path) -> str: "client/src", "ui/src", "ui", + "src/app", ) SKIP_REACT_PARTS = { diff --git a/src/loadpath/extractors/django.py b/src/loadpath/extractors/django.py index b26d58b..ea518e2 100644 --- a/src/loadpath/extractors/django.py +++ b/src/loadpath/extractors/django.py @@ -74,6 +74,7 @@ CELERY_TASK_BASES = {"Task"} DRAMATIQ_TASK_BASES = {"GenericActor"} NINJA_HTTP = {"get", "post", "put", "patch", "delete", "api_operation"} +NINJA_SCHEMA_BASES = {"Schema", "ModelSchema"} FASTAPI_HTTP = {"get", "post", "put", "patch", "delete", "options", "head", "trace", "api_route", "websocket"} CONSUMER_BASES = { "WebsocketConsumer", @@ -154,6 +155,34 @@ def _list_names(node: ast.AST | None) -> list[str]: return [n.split(".")[-1]] if n else [] +def _ann_class_names(node: ast.AST | None) -> list[str]: + if node is None: + return [] + if isinstance(node, ast.Name): + return [node.id] if node.id[:1].isupper() else [] + if isinstance(node, ast.Attribute): + n = _name(node) + short = n.split(".")[-1] if n else "" + return [short] if short[:1].isupper() else [] + if isinstance(node, ast.Subscript): + return _ann_class_names(node.value) + _ann_class_names(node.slice) + if isinstance(node, ast.Tuple): + names: list[str] = [] + for elt in node.elts: + names.extend(_ann_class_names(elt)) + return names + if isinstance(node, ast.BinOp): + return _ann_class_names(node.left) + _ann_class_names(node.right) + if isinstance(node, ast.Constant) and isinstance(node.value, str) and node.value[:1].isupper(): + return [node.value.split(".")[-1]] + return [] + + +def _looks_like_ninja_blob(imports: dict[str, str], from_imports: dict[str, str]) -> bool: + blob = " ".join(imports.values()) + " " + " ".join(from_imports.values()) + return "ninja" in blob.lower() + + def _bases(node: ast.ClassDef) -> list[str]: return [b for b in (_name(base) for base in node.bases) if b] @@ -409,6 +438,8 @@ def visit_ClassDef(self, node: ast.ClassDef) -> None: self._graphql_type(node) elif _has_base(node, {"BaseModel"}) and not _has_base(node, MODEL_BASES): self._pydantic_model(node) + elif _has_base(node, NINJA_SCHEMA_BASES) and self._looks_like_ninja(): + self._pydantic_model(node, ninja=True) elif _has_base(node, ADMIN_BASES) or node.name.endswith("Admin"): self._admin(node) elif any(x.endswith("Config") for x in _bases(node)) or node.name.endswith("Config"): @@ -577,6 +608,9 @@ def _serializer( declared.append((fname, stmt.lineno)) if isinstance(stmt, ast.FunctionDef) and "queryset" in ast.dump(stmt): queryset_in_serializer = True + nested_by_name = self._nested_serializer_fields(node) + method_fields = self._method_field_names(node) + to_repr_fields = self._to_representation_fields(node) body = self._slice(node) if queryset_in_serializer or ".objects." in body or "objects.filter" in body: ser.extra["queryset_in_serializer"] = True @@ -586,10 +620,27 @@ def _serializer( for f in meta_fields: if f not in existing: fields.append((f, node.lineno)) + existing_names = {n for n, _ in fields} + for fname in to_repr_fields: + if fname not in existing_names: + fields.append((fname, node.lineno)) + existing_names.add(fname) for fname, lineno in fields: fq = f"{qname}.{fname}" - fn = self.add_node(NodeType.SERIALIZER_FIELD, fname, fq, lineno, {"app": self.app}) + field_extra: dict = {"app": self.app} + nested = nested_by_name.get(fname) + if nested: + field_extra["nested_serializer"] = nested + if fname in method_fields: + field_extra["method_field"] = True + if fname in to_repr_fields: + field_extra["from_to_representation"] = True + fn = self.add_node(NodeType.SERIALIZER_FIELD, fname, fq, lineno, field_extra) self.add_edge(ser.id, fn.id, EdgeType.HAS_FIELD) + if nested: + nested_q = nested if "." in nested else f"{self.app}.{nested.split('.')[-1]}" + self.add_edge(fn.id, node_id(NodeType.SERIALIZER, nested_q), EdgeType.USES_SERIALIZER, extra={"nested": True}) + self.add_edge(ser.id, node_id(NodeType.SERIALIZER, nested_q), EdgeType.CALLS, extra={"nested": True}) if meta_model: model_q = meta_model if "." in meta_model else f"{self.app}.{meta_model.split('.')[-1]}" self.add_edge(fn.id, node_id(NodeType.FIELD, f"{model_q}.{fname}"), EdgeType.SERIALIZES, confidence=0.85) @@ -598,6 +649,17 @@ def _serializer( self.add_edge(ser.id, node_id(NodeType.MODEL, model_q), EdgeType.SERIALIZES) if meta_exclude: ser.extra["exclude"] = meta_exclude + if nested_by_name: + ser.extra["nested_serializers"] = sorted(set(nested_by_name.values())) + if method_fields: + ser.extra["method_fields"] = sorted(method_fields) + if to_repr_fields: + ser.extra["to_representation_fields"] = to_repr_fields + elif any(isinstance(s, ast.FunctionDef) and s.name == "to_representation" for s in node.body): + ser.extra["to_representation"] = True + self.graph.residuals.append( + f"to_representation on {qname} ({self.rel_path}:{node.lineno}) — published fields not parsed" + ) def _view(self, node: ast.ClassDef) -> None: qname = f"{self.app}.{node.name}" @@ -637,9 +699,14 @@ def _view(self, node: ast.ClassDef) -> None: if isinstance(stmt, ast.FunctionDef) and stmt.name == "get_serializer_class": dynamic_serializer = True extra["get_serializer_class"] = True - self.graph.residuals.append( - f"Dynamic get_serializer_class on {qname} ({self.rel_path}:{stmt.lineno})" - ) + resolved = self._serializer_names_in(stmt) + extra["serializer_classes"] = resolved + if resolved: + extra["get_serializer_class_resolved"] = True + else: + self.graph.residuals.append( + f"Dynamic get_serializer_class on {qname} ({self.rel_path}:{stmt.lineno})" + ) if isinstance(stmt, ast.FunctionDef) and stmt.name in { "list", "create", @@ -662,6 +729,14 @@ def _view(self, node: ast.ClassDef) -> None: else f"{self.app}.{serializer_class.split('.')[-1]}" ) self.add_edge(view.id, node_id(NodeType.SERIALIZER, ser_q), EdgeType.USES_SERIALIZER) + for name in extra.get("serializer_classes") or []: + ser_q = name if "." in name and not name.startswith("serializers") else f"{self.app}.{name.split('.')[-1]}" + self.add_edge( + view.id, + node_id(NodeType.SERIALIZER, ser_q), + EdgeType.USES_SERIALIZER, + extra={"from": "get_serializer_class"}, + ) if extra.get("filterset") and extra["filterset"] not in {True, False}: fs = str(extra["filterset"]) fs_q = fs if "." in fs and not fs.startswith("filter") else f"{self.app}.{fs.split('.')[-1]}" @@ -987,6 +1062,21 @@ def _maybe_ninja(self, node: ast.FunctionDef) -> bool: {"app": self.app, "route": route, "ninja": True, "method": short.upper()}, ) self.add_edge(rn.id, view.id, EdgeType.PUBLISHES_ROUTE) + for schema_name in self._ninja_response_schemas(node, dec): + schema_q = f"{self.app}.{schema_name.split('.')[-1]}" + self.add_edge( + view.id, + node_id(NodeType.PYDANTIC_MODEL, schema_q), + EdgeType.USES_SERIALIZER, + extra={"ninja_schema": True}, + ) + if route: + self.add_edge( + rn.id, + node_id(NodeType.PYDANTIC_MODEL, schema_q), + EdgeType.USES_SERIALIZER, + extra={"ninja_schema": True}, + ) return hit def _owner_id(self) -> tuple[NodeType, str]: @@ -1095,6 +1185,7 @@ def _graphql_type(self, node: ast.ClassDef) -> None: {"app": self.app}, ) self.add_edge(gql.id, field.id, EdgeType.HAS_FIELD) + extra.setdefault("fields", []).append(fname) if root and not any( n.type is NodeType.GRAPHQL_OPERATION and n.name == fname for n in self.graph.nodes ): @@ -1147,21 +1238,170 @@ def _maybe_graphql_operation(self, node: ast.FunctionDef) -> None: EdgeType.PUBLISHES_GRAPHQL, ) - def _pydantic_model(self, node: ast.ClassDef) -> None: + def _pydantic_model(self, node: ast.ClassDef, *, ninja: bool = False) -> None: qname = f"{self.app}.{node.name}" - extra: dict = _with_doc({"app": self.app, "pydantic": True}, node) + extra: dict = _with_doc({"app": self.app, "pydantic": True, "ninja_schema": ninja}, node) + meta_fields: list[str] = [] + for stmt in node.body: + if isinstance(stmt, ast.ClassDef) and stmt.name == "Meta": + for m in stmt.body: + if isinstance(m, ast.Assign) and m.targets and isinstance(m.targets[0], ast.Name) and m.targets[0].id == "fields": + if isinstance(m.value, (ast.List, ast.Tuple)): + meta_fields = [ + elt.value + for elt in m.value.elts + if isinstance(elt, ast.Constant) and isinstance(elt.value, str) + ] + extra["fields"] = [] model = self.add_node(NodeType.PYDANTIC_MODEL, node.name, qname, node.lineno, extra) + seen: set[str] = set() for stmt in node.body: if isinstance(stmt, ast.AnnAssign) and isinstance(stmt.target, ast.Name): fname = stmt.target.id + if fname.startswith("_") or fname in seen: + continue + seen.add(fname) + extra["fields"].append(fname) field = self.add_node( NodeType.SERIALIZER_FIELD, fname, f"{qname}.{fname}", stmt.lineno, - {"app": self.app, "pydantic": True}, + {"app": self.app, "pydantic": True, "ninja_schema": ninja}, ) self.add_edge(model.id, field.id, EdgeType.HAS_FIELD) + for nested in _ann_class_names(stmt.annotation): + if nested in {"Optional", "List", "Dict", "Union", "Any", "Schema", "BaseModel", node.name}: + continue + self.add_edge( + field.id, + node_id(NodeType.PYDANTIC_MODEL, f"{self.app}.{nested}"), + EdgeType.USES_SERIALIZER, + extra={"nested": True}, + ) + self.add_edge( + model.id, + node_id(NodeType.PYDANTIC_MODEL, f"{self.app}.{nested}"), + EdgeType.CALLS, + extra={"nested": True}, + ) + for fname in meta_fields: + if fname in seen: + continue + seen.add(fname) + extra["fields"].append(fname) + field = self.add_node( + NodeType.SERIALIZER_FIELD, + fname, + f"{qname}.{fname}", + node.lineno, + {"app": self.app, "pydantic": True, "ninja_schema": ninja}, + ) + self.add_edge(model.id, field.id, EdgeType.HAS_FIELD) + + def _looks_like_ninja(self) -> bool: + return _looks_like_ninja_blob(self.imports, self.from_imports) + + def _ninja_response_schemas(self, node: ast.FunctionDef, dec: ast.Call) -> list[str]: + names = _ann_class_names(node.returns) + names.extend(_ann_class_names(_kw(dec, "response"))) + resp = _kw(dec, "response") + if isinstance(resp, ast.Dict): + for val in resp.values: + names.extend(_ann_class_names(val)) + skip = { + "dict", + "list", + "Dict", + "List", + "Any", + "None", + "int", + "str", + "bool", + "float", + "Optional", + "Union", + "HttpResponse", + "HttpRequest", + } + out: list[str] = [] + seen: set[str] = set() + for name in names: + short = name.split(".")[-1] + if short in skip or short in seen or not short[:1].isupper(): + continue + seen.add(short) + out.append(short) + return out + + def _nested_serializer_fields(self, node: ast.ClassDef) -> dict[str, str]: + found: dict[str, str] = {} + for stmt in node.body: + if not isinstance(stmt, ast.Assign) or not stmt.targets or not isinstance(stmt.targets[0], ast.Name): + continue + fname = stmt.targets[0].id + call = stmt.value if isinstance(stmt.value, ast.Call) else None + raw = _name(call.func if call else stmt.value) + if not raw: + continue + short = raw.split(".")[-1] + if short.endswith("Serializer") and short not in SERIALIZER_BASES: + found[fname] = short + return found + + def _method_field_names(self, node: ast.ClassDef) -> set[str]: + names: set[str] = set() + for stmt in node.body: + if not isinstance(stmt, ast.Assign) or not stmt.targets or not isinstance(stmt.targets[0], ast.Name): + continue + call = stmt.value if isinstance(stmt.value, ast.Call) else None + raw = _name(call.func if call else None) or "" + if raw.split(".")[-1] == "SerializerMethodField": + names.add(stmt.targets[0].id) + return names + + def _to_representation_fields(self, node: ast.ClassDef) -> list[str]: + for stmt in node.body: + if isinstance(stmt, ast.FunctionDef) and stmt.name == "to_representation": + keys: list[str] = [] + seen: set[str] = set() + for child in ast.walk(stmt): + if not isinstance(child, ast.Return) or not isinstance(child.value, ast.Dict): + continue + for key in child.value.keys: + if isinstance(key, ast.Constant) and isinstance(key.value, str): + if key.value not in seen: + seen.add(key.value) + keys.append(key.value) + return keys + return [] + + def _serializer_names_in(self, node: ast.AST) -> list[str]: + names: list[str] = [] + seen: set[str] = set() + for child in ast.walk(node): + candidates: list[str] = [] + if isinstance(child, ast.Return) and child.value is not None: + n = _name(child.value) + if n: + candidates.append(n) + if isinstance(child.value, ast.Dict): + for val in child.value.values: + vn = _name(val) + if vn: + candidates.append(vn) + if isinstance(child, ast.Dict): + for val in child.values: + vn = _name(val) + if vn: + candidates.append(vn) + for n in candidates: + short = n.split(".")[-1] + if short.endswith("Serializer") and short not in SERIALIZER_BASES and short not in seen: + seen.add(short) + names.append(short) + return names def _consumer(self, node: ast.ClassDef) -> None: qname = f"{self.app}.{node.name}" diff --git a/src/loadpath/extractors/react.py b/src/loadpath/extractors/react.py index 4c5af2b..8e433bd 100644 --- a/src/loadpath/extractors/react.py +++ b/src/loadpath/extractors/react.py @@ -65,13 +65,45 @@ DEFAULT_VALUE_RE = re.compile(r"""(?:defaultValue|name)\s*=\s*(?:\{[^}]*\.(\w+)|['"](\w+)['"])""") BOUNDARY_RE = re.compile(r"""\b(ErrorBoundary|Suspense)\b""") RTK_RE = re.compile(r"""createApi\s*\(\s*\{""") +RTK_ENDPOINT_RE = re.compile( + r"""(?P[A-Za-z_]\w*)\s*:\s*builder\.(?Pquery|mutation|infiniteQuery)\b""" +) +RTK_BASE_URL_RE = re.compile(r"""baseUrl\s*:\s*['"`]([^'"`]+)""") +OPENAPI_FETCH_RE = re.compile( + r"""\.(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\(\s*['"`]([^'"`]+)""" +) +TRPC_RE = re.compile( + r"""\b(?:trpc|api)\.((?:[A-Za-z_]\w*\.)+)use(?:Query|Mutation|InfiniteQuery|SuspenseQuery)\b""" +) +TS_REST_PATH_RE = re.compile(r"""path\s*:\s*['"]([^'"]+)['"]""") +E2E_VISIT_RE = re.compile( + r"""(?:page\.goto|cy\.visit|cy\.request|page\.request\.(?:get|post|put|patch|delete)|request\.(?:get|post))\(\s*(?:['"`]([^'"`]+)['"`]|`([^`]+)`)""", + re.I, +) +E2E_GOTO_RE = re.compile( + r"""(?:page\.goto|cy\.visit)\(\s*(?:['"`]([^'"`]+)['"`]|`([^`]+)`)""", + re.I, +) +SERVER_ACTION_FN_RE = re.compile( + r"""export\s+(?:async\s+)?function\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(""" +) +CODEGEN_TYPE_RE = re.compile(r"""export\s+type\s+([A-Z][A-Za-z0-9_]*)\s*=\s*\{""") +CODEGEN_FIELD_RE = re.compile(r"""^\s{1,6}([A-Za-z_]\w*)\s*\??\s*:""", re.M) FEATURE_FOLDER_RE = re.compile(r"""features/([^/]+)""") GQL_DOC_RE = re.compile( r"""(?:gql|graphql)\s*(?:<[^>]*>)?\s*`([^`]+)`""", re.S, ) +GQL_FILE_OP_RE = re.compile( + r"""^\s*(query|mutation|subscription)\s+([A-Za-z_]\w*)""", + re.M, +) GQL_OP_RE = re.compile(r"""\b(query|mutation|subscription)\s+([A-Za-z_]\w*)""") GQL_SELECTION_RE = re.compile(r"""\{\s*([A-Za-z_]\w*)""") +APP_SPECIAL = {"page", "layout", "route", "loading", "error", "default", "template"} +E2E_TEST_RE = re.compile( + r"""(\.test|\.spec|\.cy)\.(t|j)sx?$""" +) def _feature_from_path(rel: str) -> str | None: @@ -94,14 +126,161 @@ def normalize_url_template(url: str) -> str: return url.rstrip("/") or "/" +def _feature_from_app_segments(segments: list[str]) -> str | None: + for seg in segments: + if seg.startswith("[") or seg.startswith("(") or seg.startswith("@"): + continue + return seg + return None + + +def _dynamic_to_template(seg: str) -> str: + if seg.startswith("[[...") or seg.startswith("[..."): + return "{id}" + if seg.startswith("[") and seg.endswith("]"): + inner = seg.strip("[]") + if inner in {"id", "pk", "slug", "uuid"}: + return "{id}" + return "{" + inner + "}" + return seg + + +def app_router_info(rel: str) -> dict | None: + """Map app/**/page.tsx (and layout/route) to a URL template.""" + parts = rel.replace("\\", "/").split("/") + stem = Path(rel).stem + if stem not in APP_SPECIAL: + return None + if "app" not in parts: + return None + idx = len(parts) - 1 - parts[::-1].index("app") + segs = [p for p in parts[idx + 1 : -1] if not (p.startswith("(") and p.endswith(")")) and not p.startswith("@")] + url_parts = [_dynamic_to_template(s) for s in segs] + route = "/" + "/".join(url_parts) if url_parts else "/" + return {"route": normalize_url_template(route), "kind": stem, "segments": segs} + + +def pages_router_info(rel: str) -> dict | None: + parts = rel.replace("\\", "/").split("/") + if "pages" not in parts: + return None + idx = parts.index("pages") + rest = parts[idx + 1 :] + if not rest: + return None + filename = rest[-1] + if filename.startswith("_"): + return None + stem = Path(filename).stem + segs = list(rest[:-1]) + api = bool(segs and segs[0] == "api") + if stem != "index": + segs.append(stem) + if api and segs[:1] == ["api"]: + segs = segs[1:] + url_parts = [_dynamic_to_template(s) for s in segs] + if api: + url_parts = ["api", *url_parts] + route = "/" + "/".join(url_parts) if url_parts else "/" + return {"route": normalize_url_template(route), "kind": "api" if api else "page", "segments": segs, "api": api} + + +def _e2e_template(url: str) -> str: + url = normalize_url_template(url) + url = re.sub(r"/\d+(?=/|$)", "/{id}", url) + return url + + +def is_e2e_file(rel: str) -> bool: + path = rel.replace("\\", "/") + if E2E_TEST_RE.search(path): + if any(part in path for part in ("/e2e/", "/cypress/", "/playwright/", ".cy.")): + return True + return any(f"/{part}/" in f"/{path}/" for part in ("e2e", "cypress", "playwright")) and path.endswith( + (".ts", ".tsx", ".js", ".jsx") + ) + + +def is_frontend_test(rel: str) -> bool: + path = rel.replace("\\", "/") + return bool( + re.search(r"""(\.test|\.spec|\.cy)\.(t|j)sx?$""", path) + or "/__tests__/" in path + or is_e2e_file(path) + ) + + +def _join_base(base: str, path: str) -> str: + path = path.strip() + if path.startswith("http") or path.startswith("/api/"): + return normalize_url_template(path) + base = (base or "").rstrip("/") + if not path.startswith("/"): + path = "/" + path + if base: + return normalize_url_template(base + path) + return normalize_url_template(path) + + +def _page_name_for_route(route: str, kind: str) -> str: + parts = [p for p in route.strip("/").split("/") if p and not p.startswith("{")] + if not parts: + stem = "Home" + else: + stem = "".join(p[:1].upper() + p[1:] for p in parts[-1].replace("-", "_").split("_") if p) + suffix = {"layout": "Layout", "route": "Route", "loading": "Loading", "error": "Error"}.get(kind, "Page") + return f"{stem}{suffix}" + + +def _looks_like_graphql_codegen(rel: str, source: str) -> bool: + blob = f"{rel}\n{source[:4000]}".lower() + return any( + tok in blob + for tok in ("__typename", "typeddocumentnode", "graphql-codegen", "/generated/", "gql.ts", "graphql.ts") + ) + + +def _extract_graphql_document(graph: ExtractedGraph, add, edge, body: str, line: int, feature, hooks, components, stem: str) -> None: + ops = GQL_OP_RE.findall(body) or GQL_FILE_OP_RE.findall(body) + if not ops: + ops = [("query", f"{stem}Query")] + selections = GQL_SELECTION_RE.findall(body) + for kind, op_name in ops: + extra = { + "kind": kind.lower(), + "feature": feature, + "client": True, + "selections": [s for s in selections if s not in {"query", "mutation", "subscription"}][:8], + } + op = add( + NodeType.GRAPHQL_OPERATION, + op_name, + f"graphql.{op_name}", + line, + extra, + ) + for owner in hooks or components: + edge(owner.id, op.id, EdgeType.CALLS) + if feature: + edge(node_id(NodeType.FEATURE_MODULE, f"features.{feature}"), op.id, EdgeType.CALLS) + + def extract_react_file(rel_path: str, source: str, config: LoadpathConfig) -> ExtractedGraph: rel = rel_path.replace("\\", "/") graph = ExtractedGraph() + app_info = app_router_info(rel) + pages_info = pages_router_info(rel) if not app_info else None feature = _feature_from_path(rel) + if not feature and app_info: + feature = _feature_from_app_segments(app_info.get("segments") or []) + if not feature and pages_info: + feature = _feature_from_app_segments(pages_info.get("segments") or []) context = config.context_for_react_path(rel) is_shared = config.is_shared_react(rel) - is_test = bool(re.search(r"""(\.test|\.spec)\.(t|j)sx?$""", rel) or "/__tests__/" in rel) + is_test = is_frontend_test(rel) + e2e = is_e2e_file(rel) stem = Path(rel).stem + graphql_file = Path(rel).suffix.lower() in {".graphql", ".gql"} def add(ntype: NodeType, name: str, qname: str, line: int = 1, extra: dict | None = None) -> Node: n = Node( @@ -120,8 +299,16 @@ def add(ntype: NodeType, name: str, qname: str, line: int = 1, extra: dict | Non def edge(src: str, dst: str, etype: EdgeType, confidence: float = 1.0, extra: dict | None = None) -> None: graph.edges.append(Edge(src=src, dst=dst, type=etype, confidence=confidence, extra=extra or {})) + if graphql_file: + _extract_graphql_document(graph, add, edge, source, 1, feature, [], [], stem) + return graph + if feature: - feat = add(NodeType.FEATURE_MODULE, feature, f"features.{feature}", extra={"shared": is_shared}) + add(NodeType.FEATURE_MODULE, feature, f"features.{feature}", extra={"shared": is_shared}) + + if e2e: + _extract_e2e(add, edge, rel, source, feature, stem) + return graph imports: list[tuple[str, str]] = [] import_feature: dict[str, str] = {} @@ -166,9 +353,22 @@ def edge(src: str, dst: str, etype: EdgeType, confidence: float = 1.0, extra: di for m in COMPONENT_RE.finditer(source): name = m.group(1) line = source[: m.start()].count("\n") + 1 - is_page = name.endswith("Page") or "pages/" in rel or name.endswith("Screen") + is_page = ( + name.endswith("Page") + or "pages/" in rel + or name.endswith("Screen") + or (app_info and app_info.get("kind") == "page") + or (pages_info and pages_info.get("kind") == "page" and not pages_info.get("api")) + ) ntype = NodeType.PAGE if is_page else NodeType.COMPONENT extra: dict = {"feature": feature} + if app_info: + extra["next_app"] = True + extra["next_kind"] = app_info["kind"] + extra["route"] = app_info["route"] + if pages_info and not pages_info.get("api"): + extra["next_pages"] = True + extra["route"] = pages_info["route"] if is_page: extra["has_error_boundary"] = bool(BOUNDARY_RE.search(source)) defaults = [a or b for a, b in DEFAULT_VALUE_RE.findall(source)] @@ -397,4 +597,292 @@ def edge(src: str, dst: str, etype: EdgeType, confidence: float = 1.0, extra: di confidence=0.5, ) + _extract_next_routes(add, edge, graph, rel, source, feature, app_info, pages_info, components) + _extract_typed_clients(add, edge, graph, rel, source, feature, hooks, components) + _extract_server_actions(add, edge, rel, source, feature, components) + if _looks_like_graphql_codegen(rel, source): + _extract_graphql_codegen(add, edge, source, feature, components) + return graph + + +def _add_client(add, edge, graph, rel, feature, hooks, components, url: str, line: int, extra: dict) -> Node | None: + norm = normalize_url_template(url) + qname = f"client:{rel}:{norm}" + if any(n.qualified_name == qname for n in graph.nodes): + existing = next(n for n in graph.nodes if n.qualified_name == qname) + if extra.get("typed_client") and not existing.extra.get("typed_client"): + existing.extra.update(extra) + existing.extra["inferred"] = False + return existing + payload = { + "raw": url, + "feature": feature, + "file": rel, + **extra, + } + client = add(NodeType.API_CLIENT, norm, qname, line, payload) + for owner in hooks or components: + edge(owner.id, client.id, EdgeType.CALLS) + if feature: + edge(node_id(NodeType.FEATURE_MODULE, f"features.{feature}"), client.id, EdgeType.CALLS) + return client + + +def _extract_next_routes(add, edge, graph, rel, source, feature, app_info, pages_info, components) -> None: + info = app_info or pages_info + if not info: + return + route = info["route"] + kind = info["kind"] + line = 1 + if info.get("api"): + _add_client( + add, + edge, + graph, + rel, + feature, + [], + components, + route if route.startswith("/api/") else "/api" + (route if route.startswith("/") else "/" + route), + line, + {"typed_client": "next-api", "generated": False, "inferred": False, "next_api": True}, + ) + return + page_name = _page_name_for_route(route, kind) + extra = { + "feature": feature, + "route": route, + "next_app": bool(app_info), + "next_pages": bool(pages_info), + "next_kind": kind, + "has_error_boundary": bool(BOUNDARY_RE.search(source)), + } + ntype = NodeType.PAGE if kind in {"page", "route"} else NodeType.COMPONENT + if kind == "layout": + ntype = NodeType.COMPONENT + extra["next_layout"] = True + existing = [n for n in graph.nodes if n.type is ntype and n.extra.get("route") == route] + if not existing: + page = add(ntype, page_name, f"{feature or 'app'}.{page_name}", line, extra) + components.append(page) + if feature: + edge(page.id, node_id(NodeType.FEATURE_MODULE, f"features.{feature}"), EdgeType.BELONGS_TO) + else: + page = existing[0] + rn = add( + NodeType.REACT_ROUTE, + route, + f"react.route:{route}", + line, + {"element": page_name, "next_app": bool(app_info), "next_kind": kind}, + ) + edge(rn.id, page.id, EdgeType.PUBLISHES_ROUTE) + if kind == "layout": + # layout wraps pages under this prefix — linked later if a page route starts with this path + for other in list(graph.nodes): + if other.type is NodeType.PAGE and str((other.extra or {}).get("route") or "").startswith(route.rstrip("/") or "/"): + edge(page.id, other.id, EdgeType.RENDERS, confidence=0.7) + + +def _extract_typed_clients(add, edge, graph, rel, source, feature, hooks, components) -> None: + if RTK_RE.search(source) or "injectEndpoints" in source: + base = "" + bm = RTK_BASE_URL_RE.search(source) + if bm: + base = bm.group(1) + for m in RTK_ENDPOINT_RE.finditer(source): + name = m.group("name") + kind = m.group("kind") + window = source[m.end() : m.end() + 500] + url_m = re.search( + r"""(?:url\s*:\s*)?(?:['"`]([^'"`]*\{[^}]+\}[^'"`]*)['"`]|['"`]([^'"`]+)['"`]|`([^`]+)`)""", + window, + ) + raw = "" + if url_m: + raw = url_m.group(1) or url_m.group(2) or url_m.group(3) or "" + if not raw or raw.startswith("http") and "/api/" not in raw and not raw.startswith("/"): + # still record the endpoint name as a typed client when we have a path-like string later + pass + if raw and (raw.startswith("/") or "/api/" in raw or "{" in raw or ":" in raw): + url = _join_base(base, raw) + elif raw: + url = _join_base(base, raw) + else: + continue + line = source[: m.start()].count("\n") + 1 + _add_client( + add, + edge, + graph, + rel, + feature, + hooks, + components, + url, + line, + { + "typed_client": "rtk", + "generated": True, + "inferred": False, + "endpoint": name, + "kind": kind, + }, + ) + if "createClient" in source or ".GET(" in source or ".POST(" in source: + for m in OPENAPI_FETCH_RE.finditer(source): + method, raw = m.group(1), m.group(2) + if not raw.startswith("/") and "/api/" not in raw: + continue + line = source[: m.start()].count("\n") + 1 + _add_client( + add, + edge, + graph, + rel, + feature, + hooks, + components, + raw, + line, + { + "typed_client": "openapi-fetch", + "generated": True, + "inferred": False, + "method": method, + }, + ) + if "initContract" in source or "@ts-rest" in source or "ts-rest" in rel: + for m in TS_REST_PATH_RE.finditer(source): + raw = m.group(1) + if not raw.startswith("/") and "/api/" not in raw: + continue + line = source[: m.start()].count("\n") + 1 + _add_client( + add, + edge, + graph, + rel, + feature, + hooks, + components, + raw, + line, + {"typed_client": "ts-rest", "generated": True, "inferred": False}, + ) + for m in TRPC_RE.finditer(source): + proc = m.group(1).rstrip(".") + line = source[: m.start()].count("\n") + 1 + qname = f"client:{rel}:trpc.{proc}" + if any(n.qualified_name == qname for n in graph.nodes): + continue + client = add( + NodeType.API_CLIENT, + proc, + qname, + line, + { + "typed_client": "trpc", + "generated": True, + "inferred": False, + "trpc": True, + "procedure": proc, + "feature": feature, + "file": rel, + }, + ) + for owner in hooks or components: + edge(owner.id, client.id, EdgeType.CALLS) + if feature: + edge(node_id(NodeType.FEATURE_MODULE, f"features.{feature}"), client.id, EdgeType.CALLS) + + +def _extract_server_actions(add, edge, rel, source, feature, components) -> None: + if '"use server"' not in source and "'use server'" not in source: + return + for m in SERVER_ACTION_FN_RE.finditer(source): + name = m.group(1) + line = source[: m.start()].count("\n") + 1 + action = add( + NodeType.SERVER_ACTION, + name, + f"{feature or 'app'}.{name}", + line, + {"feature": feature, "server_action": True, "next_app": True}, + ) + for owner in components: + edge(owner.id, action.id, EdgeType.CALLS, confidence=0.8) + if feature: + edge(node_id(NodeType.FEATURE_MODULE, f"features.{feature}"), action.id, EdgeType.CALLS) + + +def _extract_graphql_codegen(add, edge, source, feature, components) -> None: + for m in CODEGEN_TYPE_RE.finditer(source): + name = m.group(1) + start = m.end() + depth = 1 + i = start + while i < len(source) and depth: + if source[i] == "{": + depth += 1 + elif source[i] == "}": + depth -= 1 + i += 1 + body = source[start : i - 1] + fields = [f for f in CODEGEN_FIELD_RE.findall(body) if f not in {"__typename", "Query", "Mutation", "Subscription"}] + if not fields: + continue + line = source[: m.start()].count("\n") + 1 + schema = add( + NodeType.FORM_SCHEMA, + name, + f"{feature or 'app'}.{name}", + line, + {"fields": fields, "kind": "graphql-codegen", "feature": feature, "generated": True, "typed_client": "graphql-codegen"}, + ) + for owner in components: + edge(owner.id, schema.id, EdgeType.CALLS, confidence=0.6) + + +def _extract_e2e(add, edge, rel, source, feature, stem) -> None: + visits: list[str] = [] + for m in E2E_VISIT_RE.finditer(source): + raw = m.group(1) or m.group(2) or "" + if not raw: + continue + if raw.startswith("http"): + raw = re.sub(r"""https?://[^/]+""", "", raw) + if not raw.startswith("/") and "/api/" not in raw: + continue + visits.append(_e2e_template(raw)) + tn = add( + NodeType.REACT_TEST, + stem, + f"test.{rel}", + 1, + { + "file": rel, + "e2e": True, + "visits": visits, + "kind": "cypress" if ".cy." in rel or "/cypress/" in rel else "playwright", + "mentions": sorted(set(re.findall(r"""['"](\w+)['"]""", source))), + }, + ) + for tmpl in visits: + edge(node_id(NodeType.REACT_ROUTE, f"react.route:{tmpl}"), tn.id, EdgeType.TESTED_BY, extra={"via": "e2e"}) + # common react-router param form + alt = tmpl.replace("{id}", ":id") + if alt != tmpl: + edge(node_id(NodeType.REACT_ROUTE, f"react.route:{alt}"), tn.id, EdgeType.TESTED_BY, extra={"via": "e2e"}) + page_name = _page_name_for_route(tmpl, "page") + edge(node_id(NodeType.PAGE, f"{feature or 'app'}.{page_name}"), tn.id, EdgeType.TESTED_BY, extra={"via": "e2e"}, confidence=0.7) + if "/api/" in tmpl: + edge( + node_id(NodeType.API_CLIENT, f"client:{tmpl}"), + tn.id, + EdgeType.TESTED_BY, + extra={"via": "e2e"}, + confidence=0.5, + ) diff --git a/src/loadpath/index.py b/src/loadpath/index.py index 44700ae..778a218 100644 --- a/src/loadpath/index.py +++ b/src/loadpath/index.py @@ -21,9 +21,9 @@ from loadpath.types import GENERATED_PATH_MARKERS, ExtractedGraph, Node, NodeType, node_id PY_SKIP = {"migrations"} # still extract migrations, just not skip -INDEX_EXTENSIONS = {".py", ".ts", ".tsx", ".js", ".jsx", ".html", ".htm"} +INDEX_EXTENSIONS = {".py", ".ts", ".tsx", ".js", ".jsx", ".html", ".htm", ".graphql", ".gql"} # Bump when extractor/stitch node identity changes so incremental indexes rebuild. -INDEX_REVISION = "13" +INDEX_REVISION = "14" _UPSERT_BATCH = 25 ProgressCallback = Callable[[dict[str, Any]], None] diff --git a/src/loadpath/review/cluster.py b/src/loadpath/review/cluster.py index ddd8630..6e914cf 100644 --- a/src/loadpath/review/cluster.py +++ b/src/loadpath/review/cluster.py @@ -20,6 +20,7 @@ NodeType.FORM_SCHEMA, NodeType.HOOK, NodeType.COMPONENT, + NodeType.SERVER_ACTION, NodeType.GRAPHQL_TYPE, NodeType.GRAPHQL_OPERATION, NodeType.FASTAPI_ROUTE, diff --git a/src/loadpath/review/engine.py b/src/loadpath/review/engine.py index b45754a..63dca99 100644 --- a/src/loadpath/review/engine.py +++ b/src/loadpath/review/engine.py @@ -48,6 +48,7 @@ NodeType.API_CLIENT, NodeType.QUERY_KEY, NodeType.COMPONENT, + NodeType.SERVER_ACTION, NodeType.TEST, NodeType.REACT_TEST, NodeType.GRAPHQL_TYPE, @@ -273,7 +274,7 @@ def collect_residuals(store: GraphStore, impact_nodes: list[dict], diff: DiffSet fields_by_name.setdefault(field["name"], []).append(field) for n in impact_nodes: extra = n.get("extra") or {} - if extra.get("get_serializer_class"): + if extra.get("get_serializer_class") and not extra.get("serializer_classes"): residuals.append(f"Dynamic get_serializer_class on {n['qualified_name']}") if extra.get("string_ref"): residuals.append(f"String model ref {n['qualified_name']}") @@ -549,6 +550,8 @@ def _sink_summaries(nodes: list[dict], store: GraphStore) -> list[dict]: NodeType.TASK.value, NodeType.PAGE.value, NodeType.FORM_SCHEMA.value, + NodeType.SERVER_ACTION.value, + NodeType.REACT_ROUTE.value, NodeType.FORM.value, NodeType.PERMISSION.value, NodeType.MIGRATION_OP.value, diff --git a/src/loadpath/review/suggested_tests.py b/src/loadpath/review/suggested_tests.py index 31c328c..6b71f7c 100644 --- a/src/loadpath/review/suggested_tests.py +++ b/src/loadpath/review/suggested_tests.py @@ -57,6 +57,20 @@ def _sketch(ntype: str, name: str, node: dict) -> dict | None: f" assert response.status_code < 500\n" ), } + if ntype == NodeType.PAGE.value and ((node.get("extra") or {}).get("next_app") or (node.get("extra") or {}).get("route")): + route = (node.get("extra") or {}).get("route") or name + return { + "sink": name, + "type": ntype, + "kind": "playwright", + "title": f"Hit {route} through the App Router page", + "body": ( + f"test('{name} load path', async ({{ page }}) => {{\n" + f" await page.goto({route!r})\n" + f" await expect(page.getByRole('heading')).toBeVisible()\n" + f"}})\n" + ), + } if ntype in {NodeType.PAGE.value, NodeType.FORM_SCHEMA.value}: component = name if ntype == NodeType.PAGE.value else name.replace("Schema", "Form") return { @@ -162,6 +176,20 @@ def _sketch(ntype: str, name: str, node: dict) -> dict | None: f" {name}(1) # pass a model pk, not a deserialized object\n" ), } + if ntype == NodeType.SERVER_ACTION.value: + return { + "sink": name, + "type": ntype, + "kind": "playwright", + "title": f"Submit server action {name}", + "body": ( + f"test('{name} server action', async ({{ page }}) => {{\n" + f" await page.goto('/')\n" + f" await page.getByRole('button').click()\n" + f" await expect(page.getByRole('alert')).not.toBeVisible()\n" + f"}})\n" + ), + } return None diff --git a/src/loadpath/stitch/openapi.py b/src/loadpath/stitch/openapi.py index eca60c7..d2f11c8 100644 --- a/src/loadpath/stitch/openapi.py +++ b/src/loadpath/stitch/openapi.py @@ -265,19 +265,30 @@ def stitch(store: GraphStore, config: LoadpathConfig, repo_root: Path) -> list[s ) ) - # Serializer field ↔ Zod field overlap - fields_by_serializer: dict[str, list[dict]] = {} + # Serializer / Pydantic / GraphQL field ↔ Zod / codegen schema overlap + contract_parents: list[dict] = [] + contract_parents.extend(serializers) + contract_parents.extend(store.nodes([NodeType.PYDANTIC_MODEL])) + contract_parents.extend(store.nodes([NodeType.GRAPHQL_TYPE])) + fields_by_parent: dict[str, list[dict]] = {} for f in ser_fields: parent = f["qualified_name"].rsplit(".", 1)[0] - fields_by_serializer.setdefault(parent, []).append(f) + fields_by_parent.setdefault(parent, []).append(f) + for f in store.nodes([NodeType.GRAPHQL_FIELD]): + parent = f["qualified_name"].rsplit(".", 1)[0] + fields_by_parent.setdefault(parent, []).append(f) for schema in schemas: zod_fields = set((schema.get("extra") or {}).get("fields") or []) if not zod_fields: continue + schema_kind = (schema.get("extra") or {}).get("kind") or "zod" + typed = schema_kind == "graphql-codegen" or (schema.get("extra") or {}).get("generated") best: tuple[float, dict, set[str]] | None = None - for ser in serializers: - names = {f["name"] for f in fields_by_serializer.get(ser["qualified_name"], [])} + for ser in contract_parents: + names = {f["name"] for f in fields_by_parent.get(ser["qualified_name"], [])} + extra_fields = (ser.get("extra") or {}).get("fields") or [] + names.update(extra_fields) if not names: continue overlap = zod_fields & names @@ -287,21 +298,28 @@ def stitch(store: GraphStore, config: LoadpathConfig, repo_root: Path) -> list[s best = (score, ser, overlap) if best: score, ser, overlap = best + inferred = not typed store.upsert_edge( Edge( src=ser["id"], dst=schema["id"], type=EdgeType.MATCHES_SCHEMA, - confidence=min(0.85, 0.4 + score), - extra={"overlap": sorted(overlap), "score": score, "inferred": True}, + confidence=min(0.95, 0.55 + score) if typed else min(0.85, 0.4 + score), + extra={ + "overlap": sorted(overlap), + "score": score, + "inferred": inferred, + "via": schema_kind, + }, ) ) - residuals.append( - f"Inferred serializer/Zod overlap {ser['name']} ↔ {schema['name']} " - f"fields={sorted(overlap)} score={score:.2f}" - ) + if inferred: + residuals.append( + f"Inferred serializer/Zod overlap {ser['name']} ↔ {schema['name']} " + f"fields={sorted(overlap)} score={score:.2f}" + ) # field-level edges - ser_fields_map = {f["name"]: f for f in fields_by_serializer.get(ser["qualified_name"], [])} + ser_fields_map = {f["name"]: f for f in fields_by_parent.get(ser["qualified_name"], [])} for fname in overlap: if fname in ser_fields_map: store.upsert_edge( @@ -309,8 +327,8 @@ def stitch(store: GraphStore, config: LoadpathConfig, repo_root: Path) -> list[s src=ser_fields_map[fname]["id"], dst=schema["id"], type=EdgeType.MATCHES_SCHEMA, - confidence=0.6, - extra={"field": fname, "inferred": True}, + confidence=0.85 if typed else 0.6, + extra={"field": fname, "inferred": inferred}, ) ) @@ -333,6 +351,8 @@ def stitch(store: GraphStore, config: LoadpathConfig, repo_root: Path) -> list[s residuals.extend(_stitch_graphql(store)) residuals.extend(_stitch_htmx(store)) + residuals.extend(_stitch_e2e(store)) + residuals.extend(_stitch_trpc(store, routes)) store.conn.commit() return residuals @@ -370,6 +390,44 @@ def match_server(name: str) -> dict | None: extra={"via": "graphql", "operation": client["name"], "server": match["name"]}, ) ) + schemas = [ + n + for n in store.nodes([NodeType.FORM_SCHEMA]) + if (n.get("extra") or {}).get("kind") == "graphql-codegen" + ] + types = store.nodes([NodeType.GRAPHQL_TYPE]) + type_fields = store.nodes([NodeType.GRAPHQL_FIELD]) + fields_by_type: dict[str, set[str]] = {} + for f in type_fields: + parent = f["qualified_name"].rsplit(".", 1)[0] + fields_by_type.setdefault(parent, set()).add(f["name"]) + for schema in schemas: + zod = set((schema.get("extra") or {}).get("fields") or []) + if not zod: + continue + best: tuple[float, dict, set[str]] | None = None + for gql in types: + names = set(fields_by_type.get(gql["qualified_name"]) or []) + names.update((gql.get("extra") or {}).get("fields") or []) + if not names: + continue + overlap = zod & names + union = zod | names + score = len(overlap) / len(union) if union else 0 + if score >= 0.4 and (best is None or score > best[0]): + best = (score, gql, overlap) + if not best: + continue + score, gql, overlap = best + store.upsert_edge( + Edge( + src=gql["id"], + dst=schema["id"], + type=EdgeType.MATCHES_SCHEMA, + confidence=min(0.95, 0.6 + score), + extra={"via": "graphql-codegen", "overlap": sorted(overlap), "score": score, "inferred": False}, + ) + ) return residuals @@ -409,6 +467,120 @@ def _stitch_htmx(store: GraphStore) -> list[str]: return residuals +def _stitch_e2e(store: GraphStore) -> list[str]: + residuals: list[str] = [] + tests = [n for n in store.nodes([NodeType.REACT_TEST]) if (n.get("extra") or {}).get("e2e")] + if not tests: + return residuals + routes = [ + n + for n in store.nodes([NodeType.ROUTE, NodeType.FASTAPI_ROUTE, NodeType.REACT_ROUTE, NodeType.OPENAPI_PATH]) + if not (n.get("extra") or {}).get("include") + ] + pages = store.nodes([NodeType.PAGE]) + for test in tests: + visits = [(normalize_url_template(str(v)), str(v)) for v in ((test.get("extra") or {}).get("visits") or [])] + for tmpl, raw in visits: + matched = False + for route in routes: + extra = route.get("extra") or {} + if route["type"] == NodeType.OPENAPI_PATH.value: + rtmpl = django_route_to_template(str(extra.get("path") or route["name"])) + elif route["type"] == NodeType.REACT_ROUTE.value: + rtmpl = normalize_url_template(str(route["name"])) + else: + rtmpl = django_route_to_template(str(published_route(route))) + if not _paths_match(tmpl, rtmpl) and tmpl.replace("{id}", ":id") != rtmpl: + continue + store.upsert_edge( + Edge( + src=route["id"], + dst=test["id"], + type=EdgeType.TESTED_BY, + confidence=0.9, + extra={"via": "e2e", "visit": raw}, + ) + ) + matched = True + for page in pages: + proute = str((page.get("extra") or {}).get("route") or "") + if proute and _paths_match(tmpl, normalize_url_template(proute)): + store.upsert_edge( + Edge( + src=page["id"], + dst=test["id"], + type=EdgeType.TESTED_BY, + confidence=0.9, + extra={"via": "e2e", "visit": raw}, + ) + ) + matched = True + if not matched and tmpl.startswith("/api/"): + residuals.append(f"E2E visit {tmpl} has no matching route ({test.get('file_path')})") + return residuals + + +def _stitch_trpc(store: GraphStore, routes: list[dict]) -> list[str]: + residuals: list[str] = [] + clients = [ + n + for n in store.nodes([NodeType.API_CLIENT]) + if (n.get("extra") or {}).get("typed_client") == "trpc" + ] + if not clients: + return residuals + ops = store.nodes([NodeType.GRAPHQL_OPERATION]) + views = store.nodes([NodeType.VIEW]) + for client in clients: + proc = str((client.get("extra") or {}).get("procedure") or client["name"]) + head = proc.split(".")[0].lower() + matched = False + for op in ops: + if op["name"].lower() in {proc.lower(), head, proc.replace(".", "_").lower()}: + store.upsert_edge( + Edge( + src=op["id"], + dst=client["id"], + type=EdgeType.CONSUMED_BY_CLIENT, + confidence=0.8, + extra={"via": "trpc", "procedure": proc}, + ) + ) + matched = True + for route in routes: + rraw = published_route(route).lower() + if head and head in rraw: + store.upsert_edge( + Edge( + src=route["id"], + dst=client["id"], + type=EdgeType.CONSUMED_BY_CLIENT, + confidence=0.7, + extra={"via": "trpc", "procedure": proc, "inferred": True}, + ) + ) + matched = True + if not matched: + for view in views: + if head and head in (view.get("name") or "").lower(): + store.upsert_edge( + Edge( + src=view["id"], + dst=client["id"], + type=EdgeType.CONSUMED_BY_CLIENT, + confidence=0.65, + extra={"via": "trpc", "procedure": proc, "inferred": True}, + ) + ) + matched = True + break + if not matched: + residuals.append( + f"tRPC procedure {proc} has no matching GraphQL field or route ({client.get('file_path')})" + ) + return residuals + + def _paths_match(a: str, b: str) -> bool: a = normalize_url_template(a) b = django_route_to_template(b) @@ -428,7 +600,7 @@ def _paths_match(a: str, b: str) -> bool: def _client_is_generated(client: dict, generated_files: list[str]) -> bool: extra = client.get("extra") or {} - if extra.get("generated"): + if extra.get("generated") or extra.get("typed_client"): return True fp = str(client.get("file_path") or extra.get("file") or "").replace("\\", "/") if not fp: diff --git a/src/loadpath/types.py b/src/loadpath/types.py index 1eb7dcc..cea9cfb 100644 --- a/src/loadpath/types.py +++ b/src/loadpath/types.py @@ -61,6 +61,7 @@ class NodeType(StrEnum): FORM_SCHEMA = "react.form_schema" CONTEXT_PROVIDER = "react.context" REACT_TEST = "react.test" + SERVER_ACTION = "react.server_action" # Stitch OPENAPI_PATH = "openapi.path" @@ -156,6 +157,7 @@ class EdgeWeight(StrEnum): NodeType.SIDE_EFFECT, NodeType.GRAPHQL_OPERATION, NodeType.FASTAPI_ROUTE, + NodeType.SERVER_ACTION, } CONTRACT_TYPES = { diff --git a/tests/e2e/conftest.py b/tests/e2e/conftest.py index ccbb19e..25c31c4 100644 --- a/tests/e2e/conftest.py +++ b/tests/e2e/conftest.py @@ -49,12 +49,20 @@ def live_app(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Iterator[tuple[ thread.join(timeout=5) +def force_2d_graph(page) -> None: + btn = page.get_by_test_id("graph-view-2d") + if btn.count(): + btn.first.click() + + def wait_visible_graph(page, timeout: int = 15_000) -> None: """Wait until React Flow has painted a node and at least one on-screen edge. `.react-flow__edge` first can stay `visibility: hidden` (unmeasured or clipped) even when other edges are visible, so filter to a visible edge. + Large reviews default to 3D; switch back so Playwright can see the 2D map. """ + force_2d_graph(page) page.locator(".react-flow__node").first.wait_for(timeout=timeout) page.locator(".react-flow__edge").filter(visible=True).first.wait_for(timeout=timeout) diff --git a/tests/e2e/test_ui_flows.py b/tests/e2e/test_ui_flows.py index 557422d..c50bcb8 100644 --- a/tests/e2e/test_ui_flows.py +++ b/tests/e2e/test_ui_flows.py @@ -4,7 +4,7 @@ import pytest -from tests.e2e.conftest import wait_visible_graph +from tests.e2e.conftest import force_2d_graph, wait_visible_graph def _wait_fonts(page) -> None: @@ -106,6 +106,7 @@ def test_ui_index_review_graph_copy_and_workspace(live_app, browser_page): assert "MEDIUM" in brief or "LOW" in brief or "HIGH" in brief assert "billing-team" in brief assert "MePage" not in brief + force_2d_graph(page) page.locator(".react-flow__node").filter(has_text="InvoicePage").first.wait_for(timeout=15_000) page.locator(".react-flow__edge").filter(visible=True).first.wait_for(timeout=15_000) assert page.locator(".react-flow__node").filter(has_text="MePage").count() == 0 diff --git a/tests/unit/test_depth.py b/tests/unit/test_depth.py index 017c9c6..69348fb 100644 --- a/tests/unit/test_depth.py +++ b/tests/unit/test_depth.py @@ -26,12 +26,40 @@ def test_fixture_leaks_queryset_past_query_module(tmp_path: Path): store.close() -def test_fixture_tests_bypass_published_route_seam(tmp_path: Path): +def test_fixture_e2e_covers_published_invoice_seam(tmp_path: Path): store = index_repo(FIXTURE, db_path=tmp_path / "g.sqlite3", incremental=False) findings = evaluate_depth(store, load_config(FIXTURE)) hits = [f for f in findings if f.rule == "tests_bypass_interface"] - assert hits, [f.message for f in findings] - assert any("interface is the test surface" in f.message for f in hits) + blob = " ".join(f.message for f in hits) + assert "/api/invoices/{id}" not in blob + assert "/invoices/{id}" not in blob + e2e = [ + e + for e in store.edges() + if e["type"] == "tested_by" and (e.get("extra") or {}).get("via") == "e2e" + ] + assert e2e + store.close() + + +def test_tests_bypass_when_only_serializer_is_tested(tmp_path: Path): + from loadpath.graph.store import GraphStore + from loadpath.types import Edge, EdgeType, Node, NodeType, node_id + + store = GraphStore(tmp_path / "g.sqlite3") + route = Node(id=node_id(NodeType.ROUTE, "billing:/secret"), type=NodeType.ROUTE, name="/secret", qualified_name="billing:/secret", extra={"route": "/secret"}) + view = Node(id=node_id(NodeType.VIEW, "billing.SecretView"), type=NodeType.VIEW, name="SecretView", qualified_name="billing.SecretView") + ser = Node(id=node_id(NodeType.SERIALIZER, "billing.SecretSerializer"), type=NodeType.SERIALIZER, name="SecretSerializer", qualified_name="billing.SecretSerializer") + test = Node(id=node_id(NodeType.TEST, "billing.test_secret"), type=NodeType.TEST, name="test_secret", qualified_name="billing.test_secret") + for n in (route, view, ser, test): + store.upsert_node(n) + store.upsert_edge(Edge(src=route.id, dst=view.id, type=EdgeType.PUBLISHES_ROUTE)) + store.upsert_edge(Edge(src=view.id, dst=ser.id, type=EdgeType.USES_SERIALIZER)) + store.upsert_edge(Edge(src=ser.id, dst=test.id, type=EdgeType.TESTED_BY)) + store.conn.commit() + hits = [f for f in evaluate_depth(store, load_config(FIXTURE)) if f.rule == "tests_bypass_interface"] + assert hits + assert any("SecretSerializer" in f.message and "/secret" in f.message for f in hits) store.close() diff --git a/tests/unit/test_django_extractors.py b/tests/unit/test_django_extractors.py index 2d387c8..f938b45 100644 --- a/tests/unit/test_django_extractors.py +++ b/tests/unit/test_django_extractors.py @@ -699,3 +699,50 @@ def test_filterset_is_a_form_and_links_from_the_view(): for e in vg.edges ) + +def test_resolves_get_serializer_class_returns(): + source = (FIXTURE / "backend/billing/views.py").read_text() + g = extract_django_file("backend/billing/views.py", source, _cfg()) + detail = next(n for n in g.nodes if n.name == "InvoiceDetailViewSet") + assert detail.extra.get("get_serializer_class") is True + assert set(detail.extra.get("serializer_classes") or []) >= {"InvoiceSerializer", "InvoiceDetailSerializer"} + assert not any("get_serializer_class" in r and "InvoiceDetailViewSet" in r for r in g.residuals) + assert any( + e.src == detail.id and "InvoiceDetailSerializer" in e.dst and e.type.value == "uses_serializer" + for e in g.edges + ) + + +def test_unresolved_get_serializer_class_is_residual(): + source = ( + "from rest_framework.viewsets import ModelViewSet\n" + "class InvoiceViewSet(ModelViewSet):\n" + " def get_serializer_class(self):\n" + " return registry[self.action]\n" + ) + g = extract_django_file("backend/billing/views.py", source, _cfg()) + assert any("get_serializer_class" in r for r in g.residuals) + + +def test_nested_method_field_and_to_representation(): + source = (FIXTURE / "backend/billing/serializers.py").read_text() + g = extract_django_file("backend/billing/serializers.py", source, _cfg()) + detail = next(n for n in g.nodes if n.name == "InvoiceDetailSerializer") + assert "LineSerializer" in (detail.extra.get("nested_serializers") or []) + assert "display_total" in (detail.extra.get("method_fields") or []) + assert "display_total" in (detail.extra.get("to_representation_fields") or []) + lines = next(n for n in g.nodes if n.name == "lines" and "InvoiceDetailSerializer" in n.qualified_name) + assert lines.extra.get("nested_serializer") == "LineSerializer" + assert any(e.extra.get("nested") and "LineSerializer" in e.dst for e in g.edges) + + +def test_unparsed_to_representation_is_residual(): + source = ( + "from rest_framework import serializers\n" + "class InvoiceSerializer(serializers.Serializer):\n" + " def to_representation(self, instance):\n" + " return helper(instance)\n" + ) + g = extract_django_file("backend/billing/serializers.py", source, _cfg()) + assert any("to_representation" in r for r in g.residuals) + diff --git a/tests/unit/test_index_and_stitch.py b/tests/unit/test_index_and_stitch.py index 6f9dd4a..9396f41 100644 --- a/tests/unit/test_index_and_stitch.py +++ b/tests/unit/test_index_and_stitch.py @@ -26,6 +26,26 @@ def test_index_stitches_django_route_to_react_client(tmp_path: Path): assert any((e.get("extra") or {}).get("superseded_by_generated") for e in inferred) schema_edges = [e for e in edges if e["type"] == "matches_schema"] assert schema_edges, "serializer fields should overlap invoiceSchema" + typed = [ + n + for n in store.nodes([NodeType.API_CLIENT]) + if (n.get("extra") or {}).get("typed_client") in {"rtk", "openapi-fetch"} + ] + assert typed, "RTK / openapi-fetch clients should be indexed" + e2e = [ + e + for e in edges + if e["type"] == "tested_by" and (e.get("extra") or {}).get("via") == "e2e" + ] + assert e2e, "Playwright visits should stitch tested_by onto routes" + gql_schema = [ + e + for e in schema_edges + if (e.get("extra") or {}).get("via") == "graphql-codegen" + ] + assert gql_schema, "graphql-codegen InvoiceType should match the server GraphQL type" + assert any(n["type"] == "react.server_action" for n in store.nodes()) + assert any(n["type"] == "react.page" and (n.get("extra") or {}).get("next_app") for n in store.nodes()) store.close() diff --git a/tests/unit/test_overlays.py b/tests/unit/test_overlays.py index 7638d57..f106f0d 100644 --- a/tests/unit/test_overlays.py +++ b/tests/unit/test_overlays.py @@ -63,6 +63,9 @@ def test_extracts_fastapi_next_to_django_not_ninja(): ) assert not any(n.type is NodeType.FASTAPI_ROUTE for n in ninja.nodes) assert any(n.type is NodeType.ROUTE and n.extra.get("ninja") for n in ninja.nodes) + assert any(n.type is NodeType.PYDANTIC_MODEL and n.name == "InvoiceSchema" for n in ninja.nodes) + assert any(n.name == "LedgerLineSchema" for n in ninja.nodes) + assert any(e.type is EdgeType.USES_SERIALIZER and "InvoiceSchema" in e.dst for e in ninja.edges) mixed = extract_django_file( "backend/billing/api.py", "from fastapi import Depends\nfrom ninja import Router\napi = Router()\n@api.get('/ledger')\ndef ledger():\n return {}\n", diff --git a/tests/unit/test_react_extractors.py b/tests/unit/test_react_extractors.py index e5885ae..d850df2 100644 --- a/tests/unit/test_react_extractors.py +++ b/tests/unit/test_react_extractors.py @@ -117,3 +117,94 @@ def test_invalidate_queries_marked(): assert any((n.extra or {}).get("invalidation") for n in keys) hook = next(n for n in g.nodes if n.name == "useSaveInvoice") assert hook.extra.get("mutation") is True + + +def test_extracts_next_app_router_page_and_server_action(): + page = extract_react_file( + "frontend/src/app/invoices/[id]/page.tsx", + (FIXTURE / "frontend/src/app/invoices/[id]/page.tsx").read_text(), + _cfg(), + ) + routes = [n for n in page.nodes if n.type is NodeType.REACT_ROUTE] + assert any(n.name == "/invoices/{id}" for n in routes) + assert any(n.type is NodeType.PAGE and (n.extra or {}).get("next_app") for n in page.nodes) + actions = extract_react_file( + "frontend/src/app/invoices/[id]/actions.ts", + (FIXTURE / "frontend/src/app/invoices/[id]/actions.ts").read_text(), + _cfg(), + ) + assert any(n.type is NodeType.SERVER_ACTION and n.name == "saveInvoice" for n in actions.nodes) + + +def test_extracts_rtk_openapi_fetch_and_trpc_clients(): + rtk = extract_react_file( + "frontend/src/features/billing/invoiceApi.ts", + (FIXTURE / "frontend/src/features/billing/invoiceApi.ts").read_text(), + _cfg(), + ) + clients = [n for n in rtk.nodes if n.type is NodeType.API_CLIENT] + assert any(c.name == "/api/invoices/{id}" and c.extra.get("typed_client") == "rtk" for c in clients) + assert all(not c.extra.get("inferred") for c in clients) + fetch = extract_react_file( + "frontend/src/features/billing/openapiFetch.ts", + (FIXTURE / "frontend/src/features/billing/openapiFetch.ts").read_text(), + _cfg(), + ) + assert any( + c.type is NodeType.API_CLIENT and c.extra.get("typed_client") == "openapi-fetch" + for c in fetch.nodes + ) + trpc = extract_react_file( + "frontend/src/features/billing/trpc.ts", + (FIXTURE / "frontend/src/features/billing/trpc.ts").read_text(), + _cfg(), + ) + assert any(n.extra.get("typed_client") == "trpc" and n.name == "invoice.get" for n in trpc.nodes) + + +def test_extracts_playwright_e2e_visits(): + g = extract_react_file( + "frontend/e2e/invoice.spec.ts", + (FIXTURE / "frontend/e2e/invoice.spec.ts").read_text(), + _cfg(), + ) + tests = [n for n in g.nodes if n.type is NodeType.REACT_TEST] + assert tests + assert tests[0].extra.get("e2e") is True + visits = tests[0].extra.get("visits") or [] + assert "/invoices/{id}" in visits + assert "/api/invoices/{id}" in visits + assert any(e.type.value == "tested_by" for e in g.edges) + + +def test_extracts_graphql_codegen_and_document(): + g = extract_react_file( + "frontend/src/generated/graphql.ts", + (FIXTURE / "frontend/src/generated/graphql.ts").read_text(), + _cfg(), + ) + schemas = [n for n in g.nodes if n.type is NodeType.FORM_SCHEMA] + assert any(n.name == "InvoiceType" and n.extra.get("kind") == "graphql-codegen" for n in schemas) + doc = extract_react_file( + "frontend/src/features/billing/invoice.graphql", + (FIXTURE / "frontend/src/features/billing/invoice.graphql").read_text(), + _cfg(), + ) + assert any(n.type is NodeType.GRAPHQL_OPERATION and n.name == "Invoice" and n.extra.get("client") for n in doc.nodes) + + +def test_extracts_ts_rest_path_contract(): + src = """ +import { initContract } from '@ts-rest/core'; +const c = initContract(); +export const invoiceContract = c.router({ + getInvoice: { + method: 'GET', + path: '/api/invoices/:id', + responses: { 200: c.type() }, + }, +}); +""" + g = extract_react_file("frontend/src/features/billing/contract.ts", src, _cfg()) + clients = [n for n in g.nodes if n.type is NodeType.API_CLIENT] + assert any(c.name == "/api/invoices/{id}" and c.extra.get("typed_client") == "ts-rest" for c in clients) diff --git a/ui/src/graphView.ts b/ui/src/graphView.ts index d638fb2..94df39d 100644 --- a/ui/src/graphView.ts +++ b/ui/src/graphView.ts @@ -56,6 +56,7 @@ export const TYPE_COLOR: Record = { "react.feature": "#9d4edd", "react.route": "#c77dff", "react.page": "#c77dff", + "react.server_action": "#e76f51", "react.component": "#9d4edd", "react.form_schema": "#ffd166", "react.test": "#6c757d", diff --git a/ui/src/nodeInspector.ts b/ui/src/nodeInspector.ts index acb9cb8..1db02e7 100644 --- a/ui/src/nodeInspector.ts +++ b/ui/src/nodeInspector.ts @@ -9,6 +9,7 @@ export const SINK_TYPES = new Set([ "django.route", "react.route", "react.page", + "react.server_action", "django.task", "django.migration_op", "django.permission", @@ -82,6 +83,7 @@ const TYPE_PURPOSE: Record = { "react.feature": "Frontend feature module (folder).", "react.route": "Client-side route. A sink: this is a URL the user can open.", "react.page": "Page or screen component rendered by a route.", + "react.server_action": "Next.js Server Action. A sink: the mutation runs on the server.", "react.component": "UI component.", "react.form_schema": "Zod (or similar) schema — typed form inputs on the client.", "react.test": "Frontend test covering a page, hook, or component.", @@ -122,7 +124,27 @@ const FACT_LABELS: Record = { get_serializer_class: "Dynamic serializer", dynamic: "Dynamic", fbv: "Function view", - ninja: "Django Ninja", + next_app: "Next.js App Router", + next_pages: "Next.js Pages Router", + next_kind: "Next file", + next_layout: "Layout", + server_action: "Server Action", + typed_client: "Typed client", + endpoint: "Endpoint", + procedure: "Procedure", + e2e: "E2E", + visits: "Visits", + nested_serializer: "Nested serializer", + nested_serializers: "Nested serializers", + method_field: "SerializerMethodField", + method_fields: "Method fields", + from_to_representation: "to_representation", + to_representation_fields: "to_representation fields", + to_representation: "Custom to_representation", + serializer_classes: "get_serializer_class returns", + get_serializer_class_resolved: "Serializer resolved", + ninja_schema: "Ninja Schema", + pydantic: "Pydantic", django_form: "Django form", mutation: "Mutation", has_error_boundary: "Error boundary", @@ -185,6 +207,15 @@ const FACT_ORDER = [ "fields", "form_fields", "exclude", + "nested_serializer", + "nested_serializers", + "method_fields", + "to_representation_fields", + "serializer_classes", + "typed_client", + "endpoint", + "procedure", + "visits", "kind", "bases", "permissions", @@ -275,7 +306,22 @@ const HIDDEN_EXTRA_KEYS = new Set([ ]); const ALWAYS_SHOW_FALSE = new Set(["looks_idempotent_on_pk", "null", "blank"]); -const ROLE_FACT_KEYS = new Set(["inferred", "generated", "mutation", "fbv", "ninja", "filterset"]); +const ROLE_FACT_KEYS = new Set([ + "inferred", + "generated", + "mutation", + "fbv", + "ninja", + "filterset", + "next_app", + "next_pages", + "server_action", + "e2e", + "ninja_schema", + "pydantic", + "method_field", + "trpc", +]); export type InspectorLink = { id: string; @@ -343,6 +389,10 @@ export function inspectNode( if (extra.mutation) roles.push("mutation"); if (extra.fbv) roles.push("function view"); if (extra.ninja) roles.push("ninja"); + if (extra.ninja_schema) roles.push("ninja schema"); + if (extra.next_app) roles.push("app router"); + if (extra.typed_client) roles.push(String(extra.typed_client)); + if (extra.e2e) roles.push("e2e"); if (extra.filterset === true) roles.push("filterset"); const incoming = edges.filter((e) => e.dst === node.id); diff --git a/ui/src/types.ts b/ui/src/types.ts index 843f59e..3e31fd3 100644 --- a/ui/src/types.ts +++ b/ui/src/types.ts @@ -285,6 +285,7 @@ export const LAYER_ORDER: Record = { "react.feature": 11, "react.route": 12, "react.page": 12, + "react.server_action": 12, "django.template": 12, "react.component": 13, "react.context": 13, From acae9f0823ce0debef7a2a0fb7e1c99a9dc636f7 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 16 Aug 2026 02:32:14 +0000 Subject: [PATCH 2/3] Let users pick the 2D graph layout algorithm The map toolbar now has a layout dropdown (architecture layers, edge flow, radial, compact grid) that persists in localStorage. Co-authored-by: zord.lack.net --- tests/e2e/test_ui_flows.py | 20 +++- ui/src/ImpactGraph.test.ts | 11 ++ ui/src/ImpactGraph.tsx | 48 ++++++-- ui/src/graphView.test.ts | 59 +++++++++- ui/src/graphView.ts | 230 ++++++++++++++++++++++++++++++++++++- ui/src/styles.css | 20 ++++ 6 files changed, 374 insertions(+), 14 deletions(-) diff --git a/tests/e2e/test_ui_flows.py b/tests/e2e/test_ui_flows.py index c50bcb8..83c4cae 100644 --- a/tests/e2e/test_ui_flows.py +++ b/tests/e2e/test_ui_flows.py @@ -107,9 +107,25 @@ def test_ui_index_review_graph_copy_and_workspace(live_app, browser_page): assert "billing-team" in brief assert "MePage" not in brief force_2d_graph(page) - page.locator(".react-flow__node").filter(has_text="InvoicePage").first.wait_for(timeout=15_000) + invoice = page.locator(".react-flow__node").filter(has_text="InvoicePage").first + invoice.wait_for(timeout=15_000) page.locator(".react-flow__edge").filter(visible=True).first.wait_for(timeout=15_000) assert page.locator(".react-flow__node").filter(has_text="MePage").count() == 0 + layout = page.get_by_test_id("graph-layout") + layout.wait_for() + assert layout.input_value() == "layers" + before = invoice.get_attribute("style") + layout.select_option("radial") + page.wait_for_function( + """before => { + const n = [...document.querySelectorAll('.react-flow__node')] + .find(el => (el.textContent || '').includes('InvoicePage')); + return Boolean(n && n.getAttribute('style') !== before); + }""", + arg=before, + timeout=10_000, + ) + assert layout.input_value() == "radial" page.get_by_test_id("tab-graph").click() page.get_by_test_id("graph-full").wait_for() @@ -144,9 +160,11 @@ def test_ui_index_review_graph_copy_and_workspace(live_app, browser_page): page.get_by_test_id("graph-view-3d").click() assert page.get_by_test_id("graph-view-3d").get_attribute("aria-pressed") == "true" page.get_by_test_id("graph-3d").wait_for(timeout=15_000) + assert page.get_by_test_id("graph-layout").count() == 0 page.locator("[data-testid='graph-3d-canvas'], [data-testid='graph-3d-fallback']").first.wait_for(timeout=20_000) page.get_by_test_id("graph-view-2d").click() page.locator(".react-flow__node").first.wait_for(timeout=15_000) + page.get_by_test_id("graph-layout").wait_for() page.get_by_test_id("graph-mode-architecture").click() assert page.get_by_test_id("graph-mode-architecture").get_attribute("aria-pressed") == "true" diff --git a/ui/src/ImpactGraph.test.ts b/ui/src/ImpactGraph.test.ts index 11097c9..6eefb0c 100644 --- a/ui/src/ImpactGraph.test.ts +++ b/ui/src/ImpactGraph.test.ts @@ -30,6 +30,17 @@ describe("toReactFlowElements", () => { expect(rfEdges[0].label).toBeUndefined(); }); + it("uses bezier edges and different positions for radial layout", () => { + const layered = toReactFlowElements(nodes, edges); + const radial = toReactFlowElements(nodes, edges, null, "radial"); + expect(radial.rfEdges[0]?.type).toBe("default"); + const moved = layered.rfNodes.some((n, i) => { + const other = radial.rfNodes[i]!; + return n.position.x !== other.position.x || n.position.y !== other.position.y; + }); + expect(moved).toBe(true); + }); + it("labels only edges incident to the selected node", () => { const extraNodes: GraphNode[] = [ ...nodes, diff --git a/ui/src/ImpactGraph.tsx b/ui/src/ImpactGraph.tsx index 35d0b17..e44c874 100644 --- a/ui/src/ImpactGraph.tsx +++ b/ui/src/ImpactGraph.tsx @@ -16,19 +16,24 @@ import { import "@xyflow/react/dist/style.css"; import { typeLabel, wrapHint } from "./format"; import { + GRAPH_LAYOUTS, defaultDetail, defaultProjection, familyFor, + layoutGraph, + layoutUsesColumns, + readGraphLayout, visibleGraph, + writeGraphLayout, type GraphDetail, type GraphFamily, + type GraphLayoutId, type GraphProjection, } from "./graphView"; import { inspectNode, type InspectorLink } from "./nodeInspector"; import { GRAPH_NODE_HEIGHT, GRAPH_NODE_WIDTH, - layoutNodes, type GraphEdge, type GraphNode, } from "./types"; @@ -82,9 +87,11 @@ export function toReactFlowElements( nodes: GraphNode[], edges: GraphEdge[], selectedId: string | null = null, + layout: GraphLayoutId = "layers", ): { rfNodes: Node[]; rfEdges: Edge[] } { const byId = new Map(nodes.map((n) => [n.id, n])); - const pos = layoutNodes(nodes, edges); + const pos = layoutGraph(nodes, edges, layout); + const edgeType = layoutUsesColumns(layout) ? "smoothstep" : "default"; const rfNodes: Node[] = nodes.map((n) => ({ id: n.id, type: "load", @@ -106,7 +113,7 @@ export function toReactFlowElements( id: e.id, source: e.src, target: e.dst, - type: "smoothstep", + type: edgeType, animated: e.weight === "critical", style: { stroke, @@ -276,6 +283,7 @@ export function ImpactGraph({ const [selectedId, setSelectedId] = useState(null); const [projection, setProjection] = useState(null); const [detail, setDetail] = useState(null); + const [layout, setLayout] = useState(() => readGraphLayout()); const [families, setFamilies] = useState>(new Set(ALL_FAMILIES)); const [neighborhoodOnly, setNeighborhoodOnly] = useState(false); const reduceMotion = @@ -295,18 +303,18 @@ export function ImpactGraph({ [nodes, edges, level, families, neighborhoodFocus], ); const topologyKey = useMemo( - () => `${visible.nodes.map((n) => n.id).join("\0")}|${visible.edges.map((e) => e.id).join("\0")}`, - [visible.nodes, visible.edges], + () => `${layout}|${visible.nodes.map((n) => n.id).join("\0")}|${visible.edges.map((e) => e.id).join("\0")}`, + [layout, visible.nodes, visible.edges], ); const byId = useMemo(() => new Map(visible.nodes.map((n) => [n.id, n])), [visible.nodes]); const selected = selectedId ? byId.get(selectedId) ?? null : null; const { rfNodes, rfEdges } = useMemo(() => { - const elements = toReactFlowElements(visible.nodes, visible.edges, selectedId); + const elements = toReactFlowElements(visible.nodes, visible.edges, selectedId, layout); if (reduceMotion) { elements.rfEdges = elements.rfEdges.map((edge) => ({ ...edge, animated: false })); } return elements; - }, [visible.nodes, visible.edges, selectedId, reduceMotion]); + }, [visible.nodes, visible.edges, selectedId, layout, reduceMotion]); useEffect(() => { if (selectedId && !byId.has(selectedId)) setSelectedId(null); @@ -407,7 +415,29 @@ export function ImpactGraph({ ))} - {view === "3d" ? ( + {view === "2d" ? ( + + ) : ( - ) : null} + )} {visible.nodes.length} nodes · {visible.edges.length} edges {hidden ? ` · ${hidden} hidden` : ""} diff --git a/ui/src/graphView.test.ts b/ui/src/graphView.test.ts index 613cac2..fc8484e 100644 --- a/ui/src/graphView.test.ts +++ b/ui/src/graphView.test.ts @@ -1,16 +1,18 @@ -import { describe, expect, it } from "vitest"; -import { LAYER_ORDER } from "./types"; +import { afterEach, describe, expect, it } from "vitest"; import { LARGE_GRAPH, LAYER_LABELS, defaultDetail, defaultProjection, familyFor, + layoutGraph, layoutNodes3d, neighborIds, + readGraphLayout, visibleGraph, + writeGraphLayout, } from "./graphView"; -import type { GraphEdge, GraphNode } from "./types"; +import { LAYER_ORDER, layoutNodes, type GraphEdge, type GraphNode } from "./types"; function node(id: string, type: string, name = id): GraphNode { return { id, type, name, qualified_name: name }; @@ -102,3 +104,54 @@ describe("defaults", () => { } }); }); + +describe("layoutGraph", () => { + it("layers matches the architecture-column layout", () => { + expect(layoutGraph(nodes, edges, "layers")).toEqual(layoutNodes(nodes, edges)); + }); + + it("flow ranks destinations to the right of sources", () => { + const chain = [node("s", "django.view", "S"), node("m", "django.serializer", "M"), node("t", "react.page", "T")]; + const flowEdges = [edge("s", "m"), edge("m", "t")]; + const pos = layoutGraph(chain, flowEdges, "flow"); + expect(pos.get("m")!.x).toBeGreaterThan(pos.get("s")!.x); + expect(pos.get("t")!.x).toBeGreaterThan(pos.get("m")!.x); + }); + + it("radial and grid produce finite coordinates for every node", () => { + for (const layout of ["radial", "grid"] as const) { + const pos = layoutGraph(nodes, edges, layout); + expect(pos.size).toBe(nodes.length); + for (const n of nodes) { + const p = pos.get(n.id)!; + expect(Number.isFinite(p.x)).toBe(true); + expect(Number.isFinite(p.y)).toBe(true); + } + } + }); + + it("switching algorithm moves at least one node", () => { + const layers = layoutGraph(nodes, edges, "layers"); + const radial = layoutGraph(nodes, edges, "radial"); + const moved = nodes.some( + (n) => layers.get(n.id)!.x !== radial.get(n.id)!.x || layers.get(n.id)!.y !== radial.get(n.id)!.y, + ); + expect(moved).toBe(true); + }); +}); + +describe("graph layout preference", () => { + afterEach(() => { + localStorage.removeItem("loadpath.graphLayout"); + }); + + it("falls back to layers for invalid storage", () => { + localStorage.setItem("loadpath.graphLayout", "force-atlas"); + expect(readGraphLayout()).toBe("layers"); + }); + + it("round-trips a valid layout", () => { + writeGraphLayout("radial"); + expect(readGraphLayout()).toBe("radial"); + }); +}); diff --git a/ui/src/graphView.ts b/ui/src/graphView.ts index 94df39d..5088272 100644 --- a/ui/src/graphView.ts +++ b/ui/src/graphView.ts @@ -1,8 +1,29 @@ -import { layerFor, type GraphEdge, type GraphNode } from "./types"; +import { + GRAPH_COL_GAP, + GRAPH_NODE_HEIGHT, + GRAPH_NODE_WIDTH, + GRAPH_ROW_GAP, + layerFor, + layoutNodes, + type GraphEdge, + type GraphNode, +} from "./types"; export type GraphFamily = "django" | "react" | "stitch" | "arch"; export type GraphDetail = "overview" | "full"; export type GraphProjection = "2d" | "3d"; +export type GraphLayoutId = "layers" | "flow" | "radial" | "grid"; + +export const GRAPH_LAYOUTS: { id: GraphLayoutId; label: string }[] = [ + { id: "layers", label: "Architecture layers" }, + { id: "flow", label: "Edge flow" }, + { id: "radial", label: "Radial" }, + { id: "grid", label: "Compact grid" }, +]; + +const GRAPH_LAYOUT_IDS = new Set(GRAPH_LAYOUTS.map((item) => item.id)); +const LAYOUT_STORAGE = "loadpath.graphLayout"; +const LAYOUT_PASSES = 8; export const LARGE_GRAPH = 90; @@ -191,3 +212,210 @@ export function layerCenters(nodes: GraphNode[]): { layer: number; x: number; co .sort((a, b) => a[0] - b[0]) .map(([layer, count]) => ({ layer, x: layer * LAYER_GAP, count })); } + +export function readGraphLayout(): GraphLayoutId { + if (typeof localStorage === "undefined") return "layers"; + const raw = localStorage.getItem(LAYOUT_STORAGE); + return raw && GRAPH_LAYOUT_IDS.has(raw as GraphLayoutId) ? (raw as GraphLayoutId) : "layers"; +} + +export function writeGraphLayout(id: GraphLayoutId): void { + if (typeof localStorage === "undefined") return; + localStorage.setItem(LAYOUT_STORAGE, id); +} + +export function layoutUsesColumns(layout: GraphLayoutId): boolean { + return layout === "layers" || layout === "flow"; +} + +function median(values: number[]): number { + if (!values.length) return Number.NaN; + const sorted = [...values].sort((a, b) => a - b); + const mid = Math.floor(sorted.length / 2); + return sorted.length % 2 ? sorted[mid]! : (sorted[mid - 1]! + sorted[mid]!) / 2; +} + +function byName(a: GraphNode, b: GraphNode): number { + return a.name.localeCompare(b.name) || a.id.localeCompare(b.id); +} + +function placeColumns(order: GraphNode[][], edges: GraphEdge[]): Map { + const pos = new Map(); + if (!order.length) return pos; + + const ids = new Set(order.flat().map((n) => n.id)); + const preds = new Map(); + const succs = new Map(); + for (const n of order.flat()) { + preds.set(n.id, []); + succs.set(n.id, []); + } + for (const e of edges) { + if (!ids.has(e.src) || !ids.has(e.dst) || e.src === e.dst) continue; + succs.get(e.src)!.push(e.dst); + preds.get(e.dst)!.push(e.src); + } + + const colOf = new Map(); + order.forEach((col, colIndex) => { + for (const n of col) colOf.set(n.id, colIndex); + }); + + const rank = new Map(); + const refreshRanks = () => { + for (const col of order) col.forEach((n, i) => rank.set(n.id, i)); + }; + refreshRanks(); + + const sortByBarycenter = (col: GraphNode[], neighborsOf: (id: string) => string[]) => { + const keyed = col.map((n, i) => { + const nbrs = neighborsOf(n.id) + .map((id) => rank.get(id)) + .filter((v): v is number => v !== undefined); + const bary = median(nbrs); + return { n, bary: Number.isNaN(bary) ? i : bary, name: n.name, id: n.id }; + }); + keyed.sort((a, b) => a.bary - b.bary || a.name.localeCompare(b.name) || a.id.localeCompare(b.id)); + return keyed.map((k) => k.n); + }; + const inColumn = (colIndex: number) => (nbr: string) => colOf.get(nbr) === colIndex; + + for (let pass = 0; pass < LAYOUT_PASSES; pass++) { + for (let i = 1; i < order.length; i++) { + order[i] = sortByBarycenter(order[i]!, (id) => (preds.get(id) ?? []).filter(inColumn(i - 1))); + refreshRanks(); + } + for (let i = order.length - 2; i >= 0; i--) { + order[i] = sortByBarycenter(order[i]!, (id) => (succs.get(id) ?? []).filter(inColumn(i + 1))); + refreshRanks(); + } + } + + const colPitch = GRAPH_NODE_WIDTH + GRAPH_COL_GAP; + const rowPitch = GRAPH_NODE_HEIGHT + GRAPH_ROW_GAP; + const maxRows = Math.max(...order.map((col) => col.length), 1); + order.forEach((col, colIndex) => { + const y0 = ((maxRows - col.length) * rowPitch) / 2; + col.forEach((n, i) => { + pos.set(n.id, { x: colIndex * colPitch, y: y0 + i * rowPitch }); + }); + }); + return pos; +} + +function layoutFlow(nodes: GraphNode[], edges: GraphEdge[]): Map { + const ids = new Set(nodes.map((n) => n.id)); + const rank = new Map(); + for (const n of nodes) rank.set(n.id, 0); + for (let pass = 0; pass < nodes.length; pass++) { + let changed = false; + for (const e of edges) { + if (!ids.has(e.src) || !ids.has(e.dst) || e.src === e.dst) continue; + const next = (rank.get(e.src) || 0) + 1; + if (next > (rank.get(e.dst) || 0)) { + rank.set(e.dst, next); + changed = true; + } + } + if (!changed) break; + } + const byRank = new Map(); + for (const n of nodes) { + const r = rank.get(n.id) || 0; + const list = byRank.get(r) ?? []; + list.push(n); + byRank.set(r, list); + } + const order = [...byRank.keys()] + .sort((a, b) => a - b) + .map((r) => (byRank.get(r) ?? []).sort(byName)); + return placeColumns(order, edges); +} + +function layoutRadial(nodes: GraphNode[], edges: GraphEdge[]): Map { + const pos = new Map(); + if (!nodes.length) return pos; + const ids = new Set(nodes.map((n) => n.id)); + const adj = new Map(); + const degree = new Map(); + for (const n of nodes) { + adj.set(n.id, []); + degree.set(n.id, 0); + } + for (const e of edges) { + if (!ids.has(e.src) || !ids.has(e.dst) || e.src === e.dst) continue; + adj.get(e.src)!.push(e.dst); + adj.get(e.dst)!.push(e.src); + degree.set(e.src, (degree.get(e.src) || 0) + 1); + degree.set(e.dst, (degree.get(e.dst) || 0) + 1); + } + const root = + [...nodes].sort((a, b) => (degree.get(b.id) || 0) - (degree.get(a.id) || 0) || byName(a, b))[0] ?? nodes[0]!; + + const depth = new Map(); + const rings: GraphNode[][] = [[root]]; + depth.set(root.id, 0); + const queue = [root]; + while (queue.length) { + const cur = queue.shift()!; + const d = depth.get(cur.id) || 0; + const nbrs = (adj.get(cur.id) ?? []) + .map((id) => nodes.find((n) => n.id === id)) + .filter((n): n is GraphNode => Boolean(n)) + .sort(byName); + for (const nbr of nbrs) { + if (depth.has(nbr.id)) continue; + depth.set(nbr.id, d + 1); + const ring = rings[d + 1] ?? []; + ring.push(nbr); + rings[d + 1] = ring; + queue.push(nbr); + } + } + const leftover = nodes.filter((n) => !depth.has(n.id)).sort(byName); + if (leftover.length) rings.push(leftover); + + const minArc = GRAPH_NODE_WIDTH + 32; + rings.forEach((ring, d) => { + if (d === 0 && ring.length === 1) { + pos.set(ring[0]!.id, { x: 0, y: 0 }); + return; + } + const radius = Math.max( + d * (GRAPH_NODE_WIDTH + GRAPH_COL_GAP), + ring.length <= 1 ? GRAPH_NODE_WIDTH : (ring.length * minArc) / (2 * Math.PI), + ); + ring.forEach((n, i) => { + const theta = -Math.PI / 2 + (2 * Math.PI * i) / ring.length; + pos.set(n.id, { x: Math.cos(theta) * radius, y: Math.sin(theta) * radius }); + }); + }); + return pos; +} + +function layoutGrid(nodes: GraphNode[]): Map { + const pos = new Map(); + const sorted = [...nodes].sort((a, b) => layerFor(a.type) - layerFor(b.type) || byName(a, b)); + const cols = Math.max(1, Math.ceil(Math.sqrt(sorted.length))); + const colPitch = GRAPH_NODE_WIDTH + GRAPH_COL_GAP; + const rowPitch = GRAPH_NODE_HEIGHT + GRAPH_ROW_GAP; + sorted.forEach((n, i) => { + pos.set(n.id, { + x: (i % cols) * colPitch, + y: Math.floor(i / cols) * rowPitch, + }); + }); + return pos; +} + +/** 2D positions for the selected layout. `layers` is the architecture-column default. */ +export function layoutGraph( + nodes: GraphNode[], + edges: GraphEdge[] = [], + layout: GraphLayoutId = "layers", +): Map { + if (layout === "flow") return layoutFlow(nodes, edges); + if (layout === "radial") return layoutRadial(nodes, edges); + if (layout === "grid") return layoutGrid(nodes); + return layoutNodes(nodes, edges); +} diff --git a/ui/src/styles.css b/ui/src/styles.css index 9487392..3a78fe8 100644 --- a/ui/src/styles.css +++ b/ui/src/styles.css @@ -1135,6 +1135,26 @@ kbd { background: var(--bg-2); } .graph-count { margin-left: auto; font-size: 11px; } +.graph-layout { + display: inline-flex; + align-items: center; + gap: 6px; + font-size: 11px; + color: var(--muted); + letter-spacing: 0.04em; +} +.graph-layout select { + background: var(--surface); + border: 1px solid var(--line); + border-radius: 999px; + padding: 0 10px; + height: 26px; + color: var(--ink); + font: inherit; + font-size: 12px; + letter-spacing: 0; + cursor: pointer; +} .chip-btn { background: var(--surface); border: 1px solid var(--line); From 834036f83d477f54545703bfe2e7090283a9158b Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sun, 16 Aug 2026 02:34:45 +0000 Subject: [PATCH 3/3] Rebuild the served UI bundle for the layout dropdown Co-authored-by: zord.lack.net --- ...DBrjUozl.js => LayeredGraph3D-DvLvDCuq.js} | 2 +- src/loadpath/static/assets/index-C1B4bL3d.js | 62 +++++++++++++++++++ src/loadpath/static/assets/index-PXVMaQl_.js | 62 ------------------- ...{index-C3YNVD8c.css => index-ZWkTndM6.css} | 2 +- src/loadpath/static/index.html | 4 +- 5 files changed, 66 insertions(+), 66 deletions(-) rename src/loadpath/static/assets/{LayeredGraph3D-DBrjUozl.js => LayeredGraph3D-DvLvDCuq.js} (99%) create mode 100644 src/loadpath/static/assets/index-C1B4bL3d.js delete mode 100644 src/loadpath/static/assets/index-PXVMaQl_.js rename src/loadpath/static/assets/{index-C3YNVD8c.css => index-ZWkTndM6.css} (73%) diff --git a/src/loadpath/static/assets/LayeredGraph3D-DBrjUozl.js b/src/loadpath/static/assets/LayeredGraph3D-DvLvDCuq.js similarity index 99% rename from src/loadpath/static/assets/LayeredGraph3D-DBrjUozl.js rename to src/loadpath/static/assets/LayeredGraph3D-DvLvDCuq.js index f5edaf4..bb48a9e 100644 --- a/src/loadpath/static/assets/LayeredGraph3D-DBrjUozl.js +++ b/src/loadpath/static/assets/LayeredGraph3D-DvLvDCuq.js @@ -1,4 +1,4 @@ -import{r as un,l as tc,c as nc,a as ic,L as sc,j as ei,t as rc}from"./index-PXVMaQl_.js";/** +import{r as un,l as tc,c as nc,a as ic,L as sc,j as ei,t as rc}from"./index-C1B4bL3d.js";/** * @license * Copyright 2010-2026 Three.js Authors * SPDX-License-Identifier: MIT diff --git a/src/loadpath/static/assets/index-C1B4bL3d.js b/src/loadpath/static/assets/index-C1B4bL3d.js new file mode 100644 index 0000000..3abc68e --- /dev/null +++ b/src/loadpath/static/assets/index-C1B4bL3d.js @@ -0,0 +1,62 @@ +(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))s(a);new MutationObserver(a=>{for(const u of a)if(u.type==="childList")for(const c of u.addedNodes)c.tagName==="LINK"&&c.rel==="modulepreload"&&s(c)}).observe(document,{childList:!0,subtree:!0});function o(a){const u={};return a.integrity&&(u.integrity=a.integrity),a.referrerPolicy&&(u.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?u.credentials="include":a.crossOrigin==="anonymous"?u.credentials="omit":u.credentials="same-origin",u}function s(a){if(a.ep)return;a.ep=!0;const u=o(a);fetch(a.href,u)}})();function Np(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var ju={exports:{}},So={},bu={exports:{}},Te={};/** + * @license React + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var qf;function n0(){if(qf)return Te;qf=1;var t=Symbol.for("react.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),s=Symbol.for("react.strict_mode"),a=Symbol.for("react.profiler"),u=Symbol.for("react.provider"),c=Symbol.for("react.context"),f=Symbol.for("react.forward_ref"),g=Symbol.for("react.suspense"),y=Symbol.for("react.memo"),v=Symbol.for("react.lazy"),x=Symbol.iterator;function m(M){return M===null||typeof M!="object"?null:(M=x&&M[x]||M["@@iterator"],typeof M=="function"?M:null)}var S={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},_=Object.assign,E={};function b(M,A,re){this.props=M,this.context=A,this.refs=E,this.updater=re||S}b.prototype.isReactComponent={},b.prototype.setState=function(M,A){if(typeof M!="object"&&typeof M!="function"&&M!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,M,A,"setState")},b.prototype.forceUpdate=function(M){this.updater.enqueueForceUpdate(this,M,"forceUpdate")};function w(){}w.prototype=b.prototype;function P(M,A,re){this.props=M,this.context=A,this.refs=E,this.updater=re||S}var N=P.prototype=new w;N.constructor=P,_(N,b.prototype),N.isPureReactComponent=!0;var j=Array.isArray,L=Object.prototype.hasOwnProperty,z={current:null},W={key:!0,ref:!0,__self:!0,__source:!0};function D(M,A,re){var ie,ce={},fe=null,de=null;if(A!=null)for(ie in A.ref!==void 0&&(de=A.ref),A.key!==void 0&&(fe=""+A.key),A)L.call(A,ie)&&!W.hasOwnProperty(ie)&&(ce[ie]=A[ie]);var Q=arguments.length-2;if(Q===1)ce.children=re;else if(1>>1,A=T[M];if(0>>1;Ma(ce,U))fea(de,ce)?(T[M]=de,T[fe]=U,M=fe):(T[M]=ce,T[ie]=U,M=ie);else if(fea(de,U))T[M]=de,T[fe]=U,M=fe;else break e}}return H}function a(T,H){var U=T.sortIndex-H.sortIndex;return U!==0?U:T.id-H.id}if(typeof performance=="object"&&typeof performance.now=="function"){var u=performance;t.unstable_now=function(){return u.now()}}else{var c=Date,f=c.now();t.unstable_now=function(){return c.now()-f}}var g=[],y=[],v=1,x=null,m=3,S=!1,_=!1,E=!1,b=typeof setTimeout=="function"?setTimeout:null,w=typeof clearTimeout=="function"?clearTimeout:null,P=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function N(T){for(var H=o(y);H!==null;){if(H.callback===null)s(y);else if(H.startTime<=T)s(y),H.sortIndex=H.expirationTime,r(g,H);else break;H=o(y)}}function j(T){if(E=!1,N(T),!_)if(o(g)!==null)_=!0,B(L);else{var H=o(y);H!==null&&Y(j,H.startTime-T)}}function L(T,H){_=!1,E&&(E=!1,w(D),D=-1),S=!0;var U=m;try{for(N(H),x=o(g);x!==null&&(!(x.expirationTime>H)||T&&!K());){var M=x.callback;if(typeof M=="function"){x.callback=null,m=x.priorityLevel;var A=M(x.expirationTime<=H);H=t.unstable_now(),typeof A=="function"?x.callback=A:x===o(g)&&s(g),N(H)}else s(g);x=o(g)}if(x!==null)var re=!0;else{var ie=o(y);ie!==null&&Y(j,ie.startTime-H),re=!1}return re}finally{x=null,m=U,S=!1}}var z=!1,W=null,D=-1,G=5,J=-1;function K(){return!(t.unstable_now()-JT||125M?(T.sortIndex=U,r(y,T),o(g)===null&&T===o(y)&&(E?(w(D),D=-1):E=!0,Y(j,U-M))):(T.sortIndex=A,r(g,T),_||S||(_=!0,B(L))),T},t.unstable_shouldYield=K,t.unstable_wrapCallback=function(T){var H=m;return function(){var U=m;m=H;try{return T.apply(this,arguments)}finally{m=U}}}})(Pu)),Pu}var eh;function l0(){return eh||(eh=1,Mu.exports=s0()),Mu.exports}/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var th;function a0(){if(th)return Ct;th=1;var t=Bo(),r=l0();function o(e){for(var n="https://reactjs.org/docs/error-decoder.html?invariant="+e,i=1;i"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),g=Object.prototype.hasOwnProperty,y=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,v={},x={};function m(e){return g.call(x,e)?!0:g.call(v,e)?!1:y.test(e)?x[e]=!0:(v[e]=!0,!1)}function S(e,n,i,l){if(i!==null&&i.type===0)return!1;switch(typeof n){case"function":case"symbol":return!0;case"boolean":return l?!1:i!==null?!i.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function _(e,n,i,l){if(n===null||typeof n>"u"||S(e,n,i,l))return!0;if(l)return!1;if(i!==null)switch(i.type){case 3:return!n;case 4:return n===!1;case 5:return isNaN(n);case 6:return isNaN(n)||1>n}return!1}function E(e,n,i,l,d,p,k){this.acceptsBooleans=n===2||n===3||n===4,this.attributeName=l,this.attributeNamespace=d,this.mustUseProperty=i,this.propertyName=e,this.type=n,this.sanitizeURL=p,this.removeEmptyString=k}var b={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){b[e]=new E(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var n=e[0];b[n]=new E(n,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){b[e]=new E(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){b[e]=new E(e,2,!1,e,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){b[e]=new E(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){b[e]=new E(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){b[e]=new E(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){b[e]=new E(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){b[e]=new E(e,5,!1,e.toLowerCase(),null,!1,!1)});var w=/[\-:]([a-z])/g;function P(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var n=e.replace(w,P);b[n]=new E(n,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var n=e.replace(w,P);b[n]=new E(n,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var n=e.replace(w,P);b[n]=new E(n,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){b[e]=new E(e,1,!1,e.toLowerCase(),null,!1,!1)}),b.xlinkHref=new E("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){b[e]=new E(e,1,!1,e.toLowerCase(),null,!0,!0)});function N(e,n,i,l){var d=b.hasOwnProperty(n)?b[n]:null;(d!==null?d.type!==0:l||!(2I||d[k]!==p[I]){var O=` +`+d[k].replace(" at new "," at ");return e.displayName&&O.includes("")&&(O=O.replace("",e.displayName)),O}while(1<=k&&0<=I);break}}}finally{re=!1,Error.prepareStackTrace=i}return(e=e?e.displayName||e.name:"")?A(e):""}function ce(e){switch(e.tag){case 5:return A(e.type);case 16:return A("Lazy");case 13:return A("Suspense");case 19:return A("SuspenseList");case 0:case 2:case 15:return e=ie(e.type,!1),e;case 11:return e=ie(e.type.render,!1),e;case 1:return e=ie(e.type,!0),e;default:return""}}function fe(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case W:return"Fragment";case z:return"Portal";case G:return"Profiler";case D:return"StrictMode";case te:return"Suspense";case C:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case K:return(e.displayName||"Context")+".Consumer";case J:return(e._context.displayName||"Context")+".Provider";case ne:var n=e.render;return e=e.displayName,e||(e=n.displayName||n.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case R:return n=e.displayName||null,n!==null?n:fe(e.type)||"Memo";case B:n=e._payload,e=e._init;try{return fe(e(n))}catch{}}return null}function de(e){var n=e.type;switch(e.tag){case 24:return"Cache";case 9:return(n.displayName||"Context")+".Consumer";case 10:return(n._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=n.render,e=e.displayName||e.name||"",n.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return n;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return fe(n);case 8:return n===D?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof n=="function")return n.displayName||n.name||null;if(typeof n=="string")return n}return null}function Q(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function le(e){var n=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(n==="checkbox"||n==="radio")}function me(e){var n=le(e)?"checked":"value",i=Object.getOwnPropertyDescriptor(e.constructor.prototype,n),l=""+e[n];if(!e.hasOwnProperty(n)&&typeof i<"u"&&typeof i.get=="function"&&typeof i.set=="function"){var d=i.get,p=i.set;return Object.defineProperty(e,n,{configurable:!0,get:function(){return d.call(this)},set:function(k){l=""+k,p.call(this,k)}}),Object.defineProperty(e,n,{enumerable:i.enumerable}),{getValue:function(){return l},setValue:function(k){l=""+k},stopTracking:function(){e._valueTracker=null,delete e[n]}}}}function ke(e){e._valueTracker||(e._valueTracker=me(e))}function xe(e){if(!e)return!1;var n=e._valueTracker;if(!n)return!0;var i=n.getValue(),l="";return e&&(l=le(e)?e.checked?"true":"false":e.value),e=l,e!==i?(n.setValue(e),!0):!1}function pe(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function be(e,n){var i=n.checked;return U({},n,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:i??e._wrapperState.initialChecked})}function Pe(e,n){var i=n.defaultValue==null?"":n.defaultValue,l=n.checked!=null?n.checked:n.defaultChecked;i=Q(n.value!=null?n.value:i),e._wrapperState={initialChecked:l,initialValue:i,controlled:n.type==="checkbox"||n.type==="radio"?n.checked!=null:n.value!=null}}function Ce(e,n){n=n.checked,n!=null&&N(e,"checked",n,!1)}function Re(e,n){Ce(e,n);var i=Q(n.value),l=n.type;if(i!=null)l==="number"?(i===0&&e.value===""||e.value!=i)&&(e.value=""+i):e.value!==""+i&&(e.value=""+i);else if(l==="submit"||l==="reset"){e.removeAttribute("value");return}n.hasOwnProperty("value")?nt(e,n.type,i):n.hasOwnProperty("defaultValue")&&nt(e,n.type,Q(n.defaultValue)),n.checked==null&&n.defaultChecked!=null&&(e.defaultChecked=!!n.defaultChecked)}function tt(e,n,i){if(n.hasOwnProperty("value")||n.hasOwnProperty("defaultValue")){var l=n.type;if(!(l!=="submit"&&l!=="reset"||n.value!==void 0&&n.value!==null))return;n=""+e._wrapperState.initialValue,i||n===e.value||(e.value=n),e.defaultValue=n}i=e.name,i!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,i!==""&&(e.name=i)}function nt(e,n,i){(n!=="number"||pe(e.ownerDocument)!==e)&&(i==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+i&&(e.defaultValue=""+i))}var Je=Array.isArray;function Qe(e,n,i,l){if(e=e.options,n){n={};for(var d=0;d"+n.valueOf().toString()+"",n=mt.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;n.firstChild;)e.appendChild(n.firstChild)}});function ht(e,n){if(n){var i=e.firstChild;if(i&&i===e.lastChild&&i.nodeType===3){i.nodeValue=n;return}}e.textContent=n}var Gt={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},_n=["Webkit","ms","Moz","O"];Object.keys(Gt).forEach(function(e){_n.forEach(function(n){n=n+e.charAt(0).toUpperCase()+e.substring(1),Gt[n]=Gt[e]})});function zn(e,n,i){return n==null||typeof n=="boolean"||n===""?"":i||typeof n!="number"||n===0||Gt.hasOwnProperty(e)&&Gt[e]?(""+n).trim():n+"px"}function Xr(e,n){e=e.style;for(var i in n)if(n.hasOwnProperty(i)){var l=i.indexOf("--")===0,d=zn(i,n[i],l);i==="float"&&(i="cssFloat"),l?e.setProperty(i,d):e[i]=d}}var It=U({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Sn(e,n){if(n){if(It[e]&&(n.children!=null||n.dangerouslySetInnerHTML!=null))throw Error(o(137,e));if(n.dangerouslySetInnerHTML!=null){if(n.children!=null)throw Error(o(60));if(typeof n.dangerouslySetInnerHTML!="object"||!("__html"in n.dangerouslySetInnerHTML))throw Error(o(61))}if(n.style!=null&&typeof n.style!="object")throw Error(o(62))}}function Dn(e,n){if(e.indexOf("-")===-1)return typeof n.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var un=null;function $n(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var mr=null,cn=null,dn=null;function qr(e){if(e=so(e)){if(typeof mr!="function")throw Error(o(280));var n=e.stateNode;n&&(n=ps(n),mr(e.stateNode,e.type,n))}}function Kr(e){cn?dn?dn.push(e):dn=[e]:cn=e}function Qr(){if(cn){var e=cn,n=dn;if(dn=cn=null,qr(e),n)for(e=0;e>>=0,e===0?32:31-(Ul(e)/Yl|0)|0}var oi=64,si=4194304;function Sr(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Nn(e,n){var i=e.pendingLanes;if(i===0)return 0;var l=0,d=e.suspendedLanes,p=e.pingedLanes,k=i&268435455;if(k!==0){var I=k&~d;I!==0?l=Sr(I):(p&=k,p!==0&&(l=Sr(p)))}else k=i&~d,k!==0?l=Sr(k):p!==0&&(l=Sr(p));if(l===0)return 0;if(n!==0&&n!==l&&(n&d)===0&&(d=l&-l,p=n&-n,d>=p||d===16&&(p&4194240)!==0))return n;if((l&4)!==0&&(l|=i&16),n=e.entangledLanes,n!==0)for(e=e.entanglements,n&=l;0i;i++)n.push(e);return n}function Nr(e,n,i){e.pendingLanes|=n,n!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,n=31-Lt(n),e[n]=i}function ql(e,n){var i=e.pendingLanes&~n;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=n,e.mutableReadLanes&=n,e.entangledLanes&=n,n=e.entanglements;var l=e.eventTimes;for(e=e.expirationTimes;0=Qi),Hc=" ",Bc=!1;function Vc(e,n){switch(e){case"keyup":return Qm.indexOf(n.keyCode)!==-1;case"keydown":return n.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Wc(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var ci=!1;function Jm(e,n){switch(e){case"compositionend":return Wc(n);case"keypress":return n.which!==32?null:(Bc=!0,Hc);case"textInput":return e=n.data,e===Hc&&Bc?null:e;default:return null}}function ey(e,n){if(ci)return e==="compositionend"||!sa&&Vc(e,n)?(e=Ac(),rs=ea=qn=null,ci=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(n.ctrlKey||n.altKey||n.metaKey)||n.ctrlKey&&n.altKey){if(n.char&&1=n)return{node:i,offset:n-e};e=l}e:{for(;i;){if(i.nextSibling){i=i.nextSibling;break e}i=i.parentNode}i=void 0}i=Qc(i)}}function Jc(e,n){return e&&n?e===n?!0:e&&e.nodeType===3?!1:n&&n.nodeType===3?Jc(e,n.parentNode):"contains"in e?e.contains(n):e.compareDocumentPosition?!!(e.compareDocumentPosition(n)&16):!1:!1}function ed(){for(var e=window,n=pe();n instanceof e.HTMLIFrameElement;){try{var i=typeof n.contentWindow.location.href=="string"}catch{i=!1}if(i)e=n.contentWindow;else break;n=pe(e.document)}return n}function ua(e){var n=e&&e.nodeName&&e.nodeName.toLowerCase();return n&&(n==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||n==="textarea"||e.contentEditable==="true")}function uy(e){var n=ed(),i=e.focusedElem,l=e.selectionRange;if(n!==i&&i&&i.ownerDocument&&Jc(i.ownerDocument.documentElement,i)){if(l!==null&&ua(i)){if(n=l.start,e=l.end,e===void 0&&(e=n),"selectionStart"in i)i.selectionStart=n,i.selectionEnd=Math.min(e,i.value.length);else if(e=(n=i.ownerDocument||document)&&n.defaultView||window,e.getSelection){e=e.getSelection();var d=i.textContent.length,p=Math.min(l.start,d);l=l.end===void 0?p:Math.min(l.end,d),!e.extend&&p>l&&(d=l,l=p,p=d),d=Zc(i,p);var k=Zc(i,l);d&&k&&(e.rangeCount!==1||e.anchorNode!==d.node||e.anchorOffset!==d.offset||e.focusNode!==k.node||e.focusOffset!==k.offset)&&(n=n.createRange(),n.setStart(d.node,d.offset),e.removeAllRanges(),p>l?(e.addRange(n),e.extend(k.node,k.offset)):(n.setEnd(k.node,k.offset),e.addRange(n)))}}for(n=[],e=i;e=e.parentNode;)e.nodeType===1&&n.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof i.focus=="function"&&i.focus(),i=0;i=document.documentMode,di=null,ca=null,to=null,da=!1;function td(e,n,i){var l=i.window===i?i.document:i.nodeType===9?i:i.ownerDocument;da||di==null||di!==pe(l)||(l=di,"selectionStart"in l&&ua(l)?l={start:l.selectionStart,end:l.selectionEnd}:(l=(l.ownerDocument&&l.ownerDocument.defaultView||window).getSelection(),l={anchorNode:l.anchorNode,anchorOffset:l.anchorOffset,focusNode:l.focusNode,focusOffset:l.focusOffset}),to&&eo(to,l)||(to=l,l=ds(ca,"onSelect"),0mi||(e.current=ka[mi],ka[mi]=null,mi--)}function Be(e,n){mi++,ka[mi]=e.current,e.current=n}var Jn={},yt=Zn(Jn),kt=Zn(!1),jr=Jn;function yi(e,n){var i=e.type.contextTypes;if(!i)return Jn;var l=e.stateNode;if(l&&l.__reactInternalMemoizedUnmaskedChildContext===n)return l.__reactInternalMemoizedMaskedChildContext;var d={},p;for(p in i)d[p]=n[p];return l&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=n,e.__reactInternalMemoizedMaskedChildContext=d),d}function Nt(e){return e=e.childContextTypes,e!=null}function gs(){We(kt),We(yt)}function md(e,n,i){if(yt.current!==Jn)throw Error(o(168));Be(yt,n),Be(kt,i)}function yd(e,n,i){var l=e.stateNode;if(n=n.childContextTypes,typeof l.getChildContext!="function")return i;l=l.getChildContext();for(var d in l)if(!(d in n))throw Error(o(108,de(e)||"Unknown",d));return U({},i,l)}function ms(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Jn,jr=yt.current,Be(yt,e),Be(kt,kt.current),!0}function vd(e,n,i){var l=e.stateNode;if(!l)throw Error(o(169));i?(e=yd(e,n,jr),l.__reactInternalMemoizedMergedChildContext=e,We(kt),We(yt),Be(yt,e)):We(kt),Be(kt,i)}var jn=null,ys=!1,Na=!1;function xd(e){jn===null?jn=[e]:jn.push(e)}function _y(e){ys=!0,xd(e)}function er(){if(!Na&&jn!==null){Na=!0;var e=0,n=Oe;try{var i=jn;for(Oe=1;e>=k,d-=k,bn=1<<32-Lt(n)+d|i<je?(dt=Ee,Ee=null):dt=Ee.sibling;var De=oe(X,Ee,q[je],ue);if(De===null){Ee===null&&(Ee=dt);break}e&&Ee&&De.alternate===null&&n(X,Ee),V=p(De,V,je),Ne===null?we=De:Ne.sibling=De,Ne=De,Ee=dt}if(je===q.length)return i(X,Ee),Ge&&Cr(X,je),we;if(Ee===null){for(;jeje?(dt=Ee,Ee=null):dt=Ee.sibling;var ur=oe(X,Ee,De.value,ue);if(ur===null){Ee===null&&(Ee=dt);break}e&&Ee&&ur.alternate===null&&n(X,Ee),V=p(ur,V,je),Ne===null?we=ur:Ne.sibling=ur,Ne=ur,Ee=dt}if(De.done)return i(X,Ee),Ge&&Cr(X,je),we;if(Ee===null){for(;!De.done;je++,De=q.next())De=ae(X,De.value,ue),De!==null&&(V=p(De,V,je),Ne===null?we=De:Ne.sibling=De,Ne=De);return Ge&&Cr(X,je),we}for(Ee=l(X,Ee);!De.done;je++,De=q.next())De=he(Ee,X,je,De.value,ue),De!==null&&(e&&De.alternate!==null&&Ee.delete(De.key===null?je:De.key),V=p(De,V,je),Ne===null?we=De:Ne.sibling=De,Ne=De);return e&&Ee.forEach(function(t0){return n(X,t0)}),Ge&&Cr(X,je),we}function et(X,V,q,ue){if(typeof q=="object"&&q!==null&&q.type===W&&q.key===null&&(q=q.props.children),typeof q=="object"&&q!==null){switch(q.$$typeof){case L:e:{for(var we=q.key,Ne=V;Ne!==null;){if(Ne.key===we){if(we=q.type,we===W){if(Ne.tag===7){i(X,Ne.sibling),V=d(Ne,q.props.children),V.return=X,X=V;break e}}else if(Ne.elementType===we||typeof we=="object"&&we!==null&&we.$$typeof===B&&Ed(we)===Ne.type){i(X,Ne.sibling),V=d(Ne,q.props),V.ref=lo(X,Ne,q),V.return=X,X=V;break e}i(X,Ne);break}else n(X,Ne);Ne=Ne.sibling}q.type===W?(V=zr(q.props.children,X.mode,ue,q.key),V.return=X,X=V):(ue=Us(q.type,q.key,q.props,null,X.mode,ue),ue.ref=lo(X,V,q),ue.return=X,X=ue)}return k(X);case z:e:{for(Ne=q.key;V!==null;){if(V.key===Ne)if(V.tag===4&&V.stateNode.containerInfo===q.containerInfo&&V.stateNode.implementation===q.implementation){i(X,V.sibling),V=d(V,q.children||[]),V.return=X,X=V;break e}else{i(X,V);break}else n(X,V);V=V.sibling}V=_u(q,X.mode,ue),V.return=X,X=V}return k(X);case B:return Ne=q._init,et(X,V,Ne(q._payload),ue)}if(Je(q))return ye(X,V,q,ue);if(H(q))return ve(X,V,q,ue);_s(X,q)}return typeof q=="string"&&q!==""||typeof q=="number"?(q=""+q,V!==null&&V.tag===6?(i(X,V.sibling),V=d(V,q),V.return=X,X=V):(i(X,V),V=wu(q,X.mode,ue),V.return=X,X=V),k(X)):i(X,V)}return et}var _i=jd(!0),bd=jd(!1),Ss=Zn(null),ks=null,Si=null,Pa=null;function Ia(){Pa=Si=ks=null}function Ta(e){var n=Ss.current;We(Ss),e._currentValue=n}function Ra(e,n,i){for(;e!==null;){var l=e.alternate;if((e.childLanes&n)!==n?(e.childLanes|=n,l!==null&&(l.childLanes|=n)):l!==null&&(l.childLanes&n)!==n&&(l.childLanes|=n),e===i)break;e=e.return}}function ki(e,n){ks=e,Pa=Si=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&n)!==0&&(Et=!0),e.firstContext=null)}function Vt(e){var n=e._currentValue;if(Pa!==e)if(e={context:e,memoizedValue:n,next:null},Si===null){if(ks===null)throw Error(o(308));Si=e,ks.dependencies={lanes:0,firstContext:e}}else Si=Si.next=e;return n}var Mr=null;function La(e){Mr===null?Mr=[e]:Mr.push(e)}function Cd(e,n,i,l){var d=n.interleaved;return d===null?(i.next=i,La(n)):(i.next=d.next,d.next=i),n.interleaved=i,Mn(e,l)}function Mn(e,n){e.lanes|=n;var i=e.alternate;for(i!==null&&(i.lanes|=n),i=e,e=e.return;e!==null;)e.childLanes|=n,i=e.alternate,i!==null&&(i.childLanes|=n),i=e,e=e.return;return i.tag===3?i.stateNode:null}var tr=!1;function Aa(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Md(e,n){e=e.updateQueue,n.updateQueue===e&&(n.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Pn(e,n){return{eventTime:e,lane:n,tag:0,payload:null,callback:null,next:null}}function nr(e,n,i){var l=e.updateQueue;if(l===null)return null;if(l=l.shared,(Ae&2)!==0){var d=l.pending;return d===null?n.next=n:(n.next=d.next,d.next=n),l.pending=n,Mn(e,i)}return d=l.interleaved,d===null?(n.next=n,La(l)):(n.next=d.next,d.next=n),l.interleaved=n,Mn(e,i)}function Ns(e,n,i){if(n=n.updateQueue,n!==null&&(n=n.shared,(i&4194240)!==0)){var l=n.lanes;l&=e.pendingLanes,i|=l,n.lanes=i,li(e,i)}}function Pd(e,n){var i=e.updateQueue,l=e.alternate;if(l!==null&&(l=l.updateQueue,i===l)){var d=null,p=null;if(i=i.firstBaseUpdate,i!==null){do{var k={eventTime:i.eventTime,lane:i.lane,tag:i.tag,payload:i.payload,callback:i.callback,next:null};p===null?d=p=k:p=p.next=k,i=i.next}while(i!==null);p===null?d=p=n:p=p.next=n}else d=p=n;i={baseState:l.baseState,firstBaseUpdate:d,lastBaseUpdate:p,shared:l.shared,effects:l.effects},e.updateQueue=i;return}e=i.lastBaseUpdate,e===null?i.firstBaseUpdate=n:e.next=n,i.lastBaseUpdate=n}function Es(e,n,i,l){var d=e.updateQueue;tr=!1;var p=d.firstBaseUpdate,k=d.lastBaseUpdate,I=d.shared.pending;if(I!==null){d.shared.pending=null;var O=I,Z=O.next;O.next=null,k===null?p=Z:k.next=Z,k=O;var se=e.alternate;se!==null&&(se=se.updateQueue,I=se.lastBaseUpdate,I!==k&&(I===null?se.firstBaseUpdate=Z:I.next=Z,se.lastBaseUpdate=O))}if(p!==null){var ae=d.baseState;k=0,se=Z=O=null,I=p;do{var oe=I.lane,he=I.eventTime;if((l&oe)===oe){se!==null&&(se=se.next={eventTime:he,lane:0,tag:I.tag,payload:I.payload,callback:I.callback,next:null});e:{var ye=e,ve=I;switch(oe=n,he=i,ve.tag){case 1:if(ye=ve.payload,typeof ye=="function"){ae=ye.call(he,ae,oe);break e}ae=ye;break e;case 3:ye.flags=ye.flags&-65537|128;case 0:if(ye=ve.payload,oe=typeof ye=="function"?ye.call(he,ae,oe):ye,oe==null)break e;ae=U({},ae,oe);break e;case 2:tr=!0}}I.callback!==null&&I.lane!==0&&(e.flags|=64,oe=d.effects,oe===null?d.effects=[I]:oe.push(I))}else he={eventTime:he,lane:oe,tag:I.tag,payload:I.payload,callback:I.callback,next:null},se===null?(Z=se=he,O=ae):se=se.next=he,k|=oe;if(I=I.next,I===null){if(I=d.shared.pending,I===null)break;oe=I,I=oe.next,oe.next=null,d.lastBaseUpdate=oe,d.shared.pending=null}}while(!0);if(se===null&&(O=ae),d.baseState=O,d.firstBaseUpdate=Z,d.lastBaseUpdate=se,n=d.shared.interleaved,n!==null){d=n;do k|=d.lane,d=d.next;while(d!==n)}else p===null&&(d.shared.lanes=0);Tr|=k,e.lanes=k,e.memoizedState=ae}}function Id(e,n,i){if(e=n.effects,n.effects=null,e!==null)for(n=0;ni?i:4,e(!0);var l=Fa.transition;Fa.transition={};try{e(!1),n()}finally{Oe=i,Fa.transition=l}}function Kd(){return Wt().memoizedState}function Ey(e,n,i){var l=sr(e);if(i={lane:l,action:i,hasEagerState:!1,eagerState:null,next:null},Qd(e))Zd(n,i);else if(i=Cd(e,n,i,l),i!==null){var d=St();Jt(i,e,l,d),Jd(i,n,l)}}function jy(e,n,i){var l=sr(e),d={lane:l,action:i,hasEagerState:!1,eagerState:null,next:null};if(Qd(e))Zd(n,d);else{var p=e.alternate;if(e.lanes===0&&(p===null||p.lanes===0)&&(p=n.lastRenderedReducer,p!==null))try{var k=n.lastRenderedState,I=p(k,i);if(d.hasEagerState=!0,d.eagerState=I,Xt(I,k)){var O=n.interleaved;O===null?(d.next=d,La(n)):(d.next=O.next,O.next=d),n.interleaved=d;return}}catch{}finally{}i=Cd(e,n,d,l),i!==null&&(d=St(),Jt(i,e,l,d),Jd(i,n,l))}}function Qd(e){var n=e.alternate;return e===qe||n!==null&&n===qe}function Zd(e,n){fo=Cs=!0;var i=e.pending;i===null?n.next=n:(n.next=i.next,i.next=n),e.pending=n}function Jd(e,n,i){if((i&4194240)!==0){var l=n.lanes;l&=e.pendingLanes,i|=l,n.lanes=i,li(e,i)}}var Is={readContext:Vt,useCallback:vt,useContext:vt,useEffect:vt,useImperativeHandle:vt,useInsertionEffect:vt,useLayoutEffect:vt,useMemo:vt,useReducer:vt,useRef:vt,useState:vt,useDebugValue:vt,useDeferredValue:vt,useTransition:vt,useMutableSource:vt,useSyncExternalStore:vt,useId:vt,unstable_isNewReconciler:!1},by={readContext:Vt,useCallback:function(e,n){return mn().memoizedState=[e,n===void 0?null:n],e},useContext:Vt,useEffect:Bd,useImperativeHandle:function(e,n,i){return i=i!=null?i.concat([e]):null,Ms(4194308,4,Ud.bind(null,n,e),i)},useLayoutEffect:function(e,n){return Ms(4194308,4,e,n)},useInsertionEffect:function(e,n){return Ms(4,2,e,n)},useMemo:function(e,n){var i=mn();return n=n===void 0?null:n,e=e(),i.memoizedState=[e,n],e},useReducer:function(e,n,i){var l=mn();return n=i!==void 0?i(n):n,l.memoizedState=l.baseState=n,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:n},l.queue=e,e=e.dispatch=Ey.bind(null,qe,e),[l.memoizedState,e]},useRef:function(e){var n=mn();return e={current:e},n.memoizedState=e},useState:Fd,useDebugValue:Ga,useDeferredValue:function(e){return mn().memoizedState=e},useTransition:function(){var e=Fd(!1),n=e[0];return e=Ny.bind(null,e[1]),mn().memoizedState=e,[n,e]},useMutableSource:function(){},useSyncExternalStore:function(e,n,i){var l=qe,d=mn();if(Ge){if(i===void 0)throw Error(o(407));i=i()}else{if(i=n(),ct===null)throw Error(o(349));(Ir&30)!==0||Ad(l,n,i)}d.memoizedState=i;var p={value:i,getSnapshot:n};return d.queue=p,Bd(Dd.bind(null,l,p,e),[e]),l.flags|=2048,go(9,zd.bind(null,l,p,i,n),void 0,null),i},useId:function(){var e=mn(),n=ct.identifierPrefix;if(Ge){var i=Cn,l=bn;i=(l&~(1<<32-Lt(l)-1)).toString(32)+i,n=":"+n+"R"+i,i=ho++,0<\/script>",e=e.removeChild(e.firstChild)):typeof l.is=="string"?e=k.createElement(i,{is:l.is}):(e=k.createElement(i),i==="select"&&(k=e,l.multiple?k.multiple=!0:l.size&&(k.size=l.size))):e=k.createElementNS(e,i),e[pn]=n,e[oo]=l,wf(e,n,!1,!1),n.stateNode=e;e:{switch(k=Dn(i,l),i){case"dialog":Ve("cancel",e),Ve("close",e),d=l;break;case"iframe":case"object":case"embed":Ve("load",e),d=l;break;case"video":case"audio":for(d=0;dCi&&(n.flags|=128,l=!0,mo(p,!1),n.lanes=4194304)}else{if(!l)if(e=js(k),e!==null){if(n.flags|=128,l=!0,i=e.updateQueue,i!==null&&(n.updateQueue=i,n.flags|=4),mo(p,!0),p.tail===null&&p.tailMode==="hidden"&&!k.alternate&&!Ge)return xt(n),null}else 2*Fe()-p.renderingStartTime>Ci&&i!==1073741824&&(n.flags|=128,l=!0,mo(p,!1),n.lanes=4194304);p.isBackwards?(k.sibling=n.child,n.child=k):(i=p.last,i!==null?i.sibling=k:n.child=k,p.last=k)}return p.tail!==null?(n=p.tail,p.rendering=n,p.tail=n.sibling,p.renderingStartTime=Fe(),n.sibling=null,i=Xe.current,Be(Xe,l?i&1|2:i&1),n):(xt(n),null);case 22:case 23:return yu(),l=n.memoizedState!==null,e!==null&&e.memoizedState!==null!==l&&(n.flags|=8192),l&&(n.mode&1)!==0?($t&1073741824)!==0&&(xt(n),n.subtreeFlags&6&&(n.flags|=8192)):xt(n),null;case 24:return null;case 25:return null}throw Error(o(156,n.tag))}function Ay(e,n){switch(ja(n),n.tag){case 1:return Nt(n.type)&&gs(),e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 3:return Ni(),We(kt),We(yt),Oa(),e=n.flags,(e&65536)!==0&&(e&128)===0?(n.flags=e&-65537|128,n):null;case 5:return Da(n),null;case 13:if(We(Xe),e=n.memoizedState,e!==null&&e.dehydrated!==null){if(n.alternate===null)throw Error(o(340));wi()}return e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 19:return We(Xe),null;case 4:return Ni(),null;case 10:return Ta(n.type._context),null;case 22:case 23:return yu(),null;case 24:return null;default:return null}}var As=!1,wt=!1,zy=typeof WeakSet=="function"?WeakSet:Set,ge=null;function ji(e,n){var i=e.ref;if(i!==null)if(typeof i=="function")try{i(null)}catch(l){Ze(e,n,l)}else i.current=null}function ou(e,n,i){try{i()}catch(l){Ze(e,n,l)}}var kf=!1;function Dy(e,n){if(ya=ts,e=ed(),ua(e)){if("selectionStart"in e)var i={start:e.selectionStart,end:e.selectionEnd};else e:{i=(i=e.ownerDocument)&&i.defaultView||window;var l=i.getSelection&&i.getSelection();if(l&&l.rangeCount!==0){i=l.anchorNode;var d=l.anchorOffset,p=l.focusNode;l=l.focusOffset;try{i.nodeType,p.nodeType}catch{i=null;break e}var k=0,I=-1,O=-1,Z=0,se=0,ae=e,oe=null;t:for(;;){for(var he;ae!==i||d!==0&&ae.nodeType!==3||(I=k+d),ae!==p||l!==0&&ae.nodeType!==3||(O=k+l),ae.nodeType===3&&(k+=ae.nodeValue.length),(he=ae.firstChild)!==null;)oe=ae,ae=he;for(;;){if(ae===e)break t;if(oe===i&&++Z===d&&(I=k),oe===p&&++se===l&&(O=k),(he=ae.nextSibling)!==null)break;ae=oe,oe=ae.parentNode}ae=he}i=I===-1||O===-1?null:{start:I,end:O}}else i=null}i=i||{start:0,end:0}}else i=null;for(va={focusedElem:e,selectionRange:i},ts=!1,ge=n;ge!==null;)if(n=ge,e=n.child,(n.subtreeFlags&1028)!==0&&e!==null)e.return=n,ge=e;else for(;ge!==null;){n=ge;try{var ye=n.alternate;if((n.flags&1024)!==0)switch(n.tag){case 0:case 11:case 15:break;case 1:if(ye!==null){var ve=ye.memoizedProps,et=ye.memoizedState,X=n.stateNode,V=X.getSnapshotBeforeUpdate(n.elementType===n.type?ve:Kt(n.type,ve),et);X.__reactInternalSnapshotBeforeUpdate=V}break;case 3:var q=n.stateNode.containerInfo;q.nodeType===1?q.textContent="":q.nodeType===9&&q.documentElement&&q.removeChild(q.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(o(163))}}catch(ue){Ze(n,n.return,ue)}if(e=n.sibling,e!==null){e.return=n.return,ge=e;break}ge=n.return}return ye=kf,kf=!1,ye}function yo(e,n,i){var l=n.updateQueue;if(l=l!==null?l.lastEffect:null,l!==null){var d=l=l.next;do{if((d.tag&e)===e){var p=d.destroy;d.destroy=void 0,p!==void 0&&ou(n,i,p)}d=d.next}while(d!==l)}}function zs(e,n){if(n=n.updateQueue,n=n!==null?n.lastEffect:null,n!==null){var i=n=n.next;do{if((i.tag&e)===e){var l=i.create;i.destroy=l()}i=i.next}while(i!==n)}}function su(e){var n=e.ref;if(n!==null){var i=e.stateNode;switch(e.tag){case 5:e=i;break;default:e=i}typeof n=="function"?n(e):n.current=e}}function Nf(e){var n=e.alternate;n!==null&&(e.alternate=null,Nf(n)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(n=e.stateNode,n!==null&&(delete n[pn],delete n[oo],delete n[Sa],delete n[xy],delete n[wy])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function Ef(e){return e.tag===5||e.tag===3||e.tag===4}function jf(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||Ef(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function lu(e,n,i){var l=e.tag;if(l===5||l===6)e=e.stateNode,n?i.nodeType===8?i.parentNode.insertBefore(e,n):i.insertBefore(e,n):(i.nodeType===8?(n=i.parentNode,n.insertBefore(e,i)):(n=i,n.appendChild(e)),i=i._reactRootContainer,i!=null||n.onclick!==null||(n.onclick=hs));else if(l!==4&&(e=e.child,e!==null))for(lu(e,n,i),e=e.sibling;e!==null;)lu(e,n,i),e=e.sibling}function au(e,n,i){var l=e.tag;if(l===5||l===6)e=e.stateNode,n?i.insertBefore(e,n):i.appendChild(e);else if(l!==4&&(e=e.child,e!==null))for(au(e,n,i),e=e.sibling;e!==null;)au(e,n,i),e=e.sibling}var pt=null,Qt=!1;function rr(e,n,i){for(i=i.child;i!==null;)bf(e,n,i),i=i.sibling}function bf(e,n,i){if(Rt&&typeof Rt.onCommitFiberUnmount=="function")try{Rt.onCommitFiberUnmount(ii,i)}catch{}switch(i.tag){case 5:wt||ji(i,n);case 6:var l=pt,d=Qt;pt=null,rr(e,n,i),pt=l,Qt=d,pt!==null&&(Qt?(e=pt,i=i.stateNode,e.nodeType===8?e.parentNode.removeChild(i):e.removeChild(i)):pt.removeChild(i.stateNode));break;case 18:pt!==null&&(Qt?(e=pt,i=i.stateNode,e.nodeType===8?_a(e.parentNode,i):e.nodeType===1&&_a(e,i),Xi(e)):_a(pt,i.stateNode));break;case 4:l=pt,d=Qt,pt=i.stateNode.containerInfo,Qt=!0,rr(e,n,i),pt=l,Qt=d;break;case 0:case 11:case 14:case 15:if(!wt&&(l=i.updateQueue,l!==null&&(l=l.lastEffect,l!==null))){d=l=l.next;do{var p=d,k=p.destroy;p=p.tag,k!==void 0&&((p&2)!==0||(p&4)!==0)&&ou(i,n,k),d=d.next}while(d!==l)}rr(e,n,i);break;case 1:if(!wt&&(ji(i,n),l=i.stateNode,typeof l.componentWillUnmount=="function"))try{l.props=i.memoizedProps,l.state=i.memoizedState,l.componentWillUnmount()}catch(I){Ze(i,n,I)}rr(e,n,i);break;case 21:rr(e,n,i);break;case 22:i.mode&1?(wt=(l=wt)||i.memoizedState!==null,rr(e,n,i),wt=l):rr(e,n,i);break;default:rr(e,n,i)}}function Cf(e){var n=e.updateQueue;if(n!==null){e.updateQueue=null;var i=e.stateNode;i===null&&(i=e.stateNode=new zy),n.forEach(function(l){var d=Yy.bind(null,e,l);i.has(l)||(i.add(l),l.then(d,d))})}}function Zt(e,n){var i=n.deletions;if(i!==null)for(var l=0;ld&&(d=k),l&=~p}if(l=d,l=Fe()-l,l=(120>l?120:480>l?480:1080>l?1080:1920>l?1920:3e3>l?3e3:4320>l?4320:1960*Oy(l/1960))-l,10e?16:e,or===null)var l=!1;else{if(e=or,or=null,Hs=0,(Ae&6)!==0)throw Error(o(331));var d=Ae;for(Ae|=4,ge=e.current;ge!==null;){var p=ge,k=p.child;if((ge.flags&16)!==0){var I=p.deletions;if(I!==null){for(var O=0;OFe()-du?Lr(e,0):cu|=i),bt(e,n)}function Hf(e,n){n===0&&((e.mode&1)===0?n=1:(n=si,si<<=1,(si&130023424)===0&&(si=4194304)));var i=St();e=Mn(e,n),e!==null&&(Nr(e,n,i),bt(e,i))}function Uy(e){var n=e.memoizedState,i=0;n!==null&&(i=n.retryLane),Hf(e,i)}function Yy(e,n){var i=0;switch(e.tag){case 13:var l=e.stateNode,d=e.memoizedState;d!==null&&(i=d.retryLane);break;case 19:l=e.stateNode;break;default:throw Error(o(314))}l!==null&&l.delete(n),Hf(e,i)}var Bf;Bf=function(e,n,i){if(e!==null)if(e.memoizedProps!==n.pendingProps||kt.current)Et=!0;else{if((e.lanes&i)===0&&(n.flags&128)===0)return Et=!1,Ry(e,n,i);Et=(e.flags&131072)!==0}else Et=!1,Ge&&(n.flags&1048576)!==0&&wd(n,xs,n.index);switch(n.lanes=0,n.tag){case 2:var l=n.type;Ls(e,n),e=n.pendingProps;var d=yi(n,yt.current);ki(n,i),d=Ba(null,n,l,e,d,i);var p=Va();return n.flags|=1,typeof d=="object"&&d!==null&&typeof d.render=="function"&&d.$$typeof===void 0?(n.tag=1,n.memoizedState=null,n.updateQueue=null,Nt(l)?(p=!0,ms(n)):p=!1,n.memoizedState=d.state!==null&&d.state!==void 0?d.state:null,Aa(n),d.updater=Ts,n.stateNode=d,d._reactInternals=n,qa(n,l,e,i),n=Ja(null,n,l,!0,p,i)):(n.tag=0,Ge&&p&&Ea(n),_t(null,n,d,i),n=n.child),n;case 16:l=n.elementType;e:{switch(Ls(e,n),e=n.pendingProps,d=l._init,l=d(l._payload),n.type=l,d=n.tag=Xy(l),e=Kt(l,e),d){case 0:n=Za(null,n,l,e,i);break e;case 1:n=pf(null,n,l,e,i);break e;case 11:n=uf(null,n,l,e,i);break e;case 14:n=cf(null,n,l,Kt(l.type,e),i);break e}throw Error(o(306,l,""))}return n;case 0:return l=n.type,d=n.pendingProps,d=n.elementType===l?d:Kt(l,d),Za(e,n,l,d,i);case 1:return l=n.type,d=n.pendingProps,d=n.elementType===l?d:Kt(l,d),pf(e,n,l,d,i);case 3:e:{if(gf(n),e===null)throw Error(o(387));l=n.pendingProps,p=n.memoizedState,d=p.element,Md(e,n),Es(n,l,null,i);var k=n.memoizedState;if(l=k.element,p.isDehydrated)if(p={element:l,isDehydrated:!1,cache:k.cache,pendingSuspenseBoundaries:k.pendingSuspenseBoundaries,transitions:k.transitions},n.updateQueue.baseState=p,n.memoizedState=p,n.flags&256){d=Ei(Error(o(423)),n),n=mf(e,n,l,i,d);break e}else if(l!==d){d=Ei(Error(o(424)),n),n=mf(e,n,l,i,d);break e}else for(Dt=Qn(n.stateNode.containerInfo.firstChild),zt=n,Ge=!0,qt=null,i=bd(n,null,l,i),n.child=i;i;)i.flags=i.flags&-3|4096,i=i.sibling;else{if(wi(),l===d){n=In(e,n,i);break e}_t(e,n,l,i)}n=n.child}return n;case 5:return Td(n),e===null&&Ca(n),l=n.type,d=n.pendingProps,p=e!==null?e.memoizedProps:null,k=d.children,xa(l,d)?k=null:p!==null&&xa(l,p)&&(n.flags|=32),hf(e,n),_t(e,n,k,i),n.child;case 6:return e===null&&Ca(n),null;case 13:return yf(e,n,i);case 4:return za(n,n.stateNode.containerInfo),l=n.pendingProps,e===null?n.child=_i(n,null,l,i):_t(e,n,l,i),n.child;case 11:return l=n.type,d=n.pendingProps,d=n.elementType===l?d:Kt(l,d),uf(e,n,l,d,i);case 7:return _t(e,n,n.pendingProps,i),n.child;case 8:return _t(e,n,n.pendingProps.children,i),n.child;case 12:return _t(e,n,n.pendingProps.children,i),n.child;case 10:e:{if(l=n.type._context,d=n.pendingProps,p=n.memoizedProps,k=d.value,Be(Ss,l._currentValue),l._currentValue=k,p!==null)if(Xt(p.value,k)){if(p.children===d.children&&!kt.current){n=In(e,n,i);break e}}else for(p=n.child,p!==null&&(p.return=n);p!==null;){var I=p.dependencies;if(I!==null){k=p.child;for(var O=I.firstContext;O!==null;){if(O.context===l){if(p.tag===1){O=Pn(-1,i&-i),O.tag=2;var Z=p.updateQueue;if(Z!==null){Z=Z.shared;var se=Z.pending;se===null?O.next=O:(O.next=se.next,se.next=O),Z.pending=O}}p.lanes|=i,O=p.alternate,O!==null&&(O.lanes|=i),Ra(p.return,i,n),I.lanes|=i;break}O=O.next}}else if(p.tag===10)k=p.type===n.type?null:p.child;else if(p.tag===18){if(k=p.return,k===null)throw Error(o(341));k.lanes|=i,I=k.alternate,I!==null&&(I.lanes|=i),Ra(k,i,n),k=p.sibling}else k=p.child;if(k!==null)k.return=p;else for(k=p;k!==null;){if(k===n){k=null;break}if(p=k.sibling,p!==null){p.return=k.return,k=p;break}k=k.return}p=k}_t(e,n,d.children,i),n=n.child}return n;case 9:return d=n.type,l=n.pendingProps.children,ki(n,i),d=Vt(d),l=l(d),n.flags|=1,_t(e,n,l,i),n.child;case 14:return l=n.type,d=Kt(l,n.pendingProps),d=Kt(l.type,d),cf(e,n,l,d,i);case 15:return df(e,n,n.type,n.pendingProps,i);case 17:return l=n.type,d=n.pendingProps,d=n.elementType===l?d:Kt(l,d),Ls(e,n),n.tag=1,Nt(l)?(e=!0,ms(n)):e=!1,ki(n,i),tf(n,l,d),qa(n,l,d,i),Ja(null,n,l,!0,e,i);case 19:return xf(e,n,i);case 22:return ff(e,n,i)}throw Error(o(156,n.tag))};function Vf(e,n){return ee(e,n)}function Gy(e,n,i,l){this.tag=e,this.key=i,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=n,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=l,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Yt(e,n,i,l){return new Gy(e,n,i,l)}function xu(e){return e=e.prototype,!(!e||!e.isReactComponent)}function Xy(e){if(typeof e=="function")return xu(e)?1:0;if(e!=null){if(e=e.$$typeof,e===ne)return 11;if(e===R)return 14}return 2}function ar(e,n){var i=e.alternate;return i===null?(i=Yt(e.tag,n,e.key,e.mode),i.elementType=e.elementType,i.type=e.type,i.stateNode=e.stateNode,i.alternate=e,e.alternate=i):(i.pendingProps=n,i.type=e.type,i.flags=0,i.subtreeFlags=0,i.deletions=null),i.flags=e.flags&14680064,i.childLanes=e.childLanes,i.lanes=e.lanes,i.child=e.child,i.memoizedProps=e.memoizedProps,i.memoizedState=e.memoizedState,i.updateQueue=e.updateQueue,n=e.dependencies,i.dependencies=n===null?null:{lanes:n.lanes,firstContext:n.firstContext},i.sibling=e.sibling,i.index=e.index,i.ref=e.ref,i}function Us(e,n,i,l,d,p){var k=2;if(l=e,typeof e=="function")xu(e)&&(k=1);else if(typeof e=="string")k=5;else e:switch(e){case W:return zr(i.children,d,p,n);case D:k=8,d|=8;break;case G:return e=Yt(12,i,n,d|2),e.elementType=G,e.lanes=p,e;case te:return e=Yt(13,i,n,d),e.elementType=te,e.lanes=p,e;case C:return e=Yt(19,i,n,d),e.elementType=C,e.lanes=p,e;case Y:return Ys(i,d,p,n);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case J:k=10;break e;case K:k=9;break e;case ne:k=11;break e;case R:k=14;break e;case B:k=16,l=null;break e}throw Error(o(130,e==null?e:typeof e,""))}return n=Yt(k,i,n,d),n.elementType=e,n.type=l,n.lanes=p,n}function zr(e,n,i,l){return e=Yt(7,e,l,n),e.lanes=i,e}function Ys(e,n,i,l){return e=Yt(22,e,l,n),e.elementType=Y,e.lanes=i,e.stateNode={isHidden:!1},e}function wu(e,n,i){return e=Yt(6,e,null,n),e.lanes=i,e}function _u(e,n,i){return n=Yt(4,e.children!==null?e.children:[],e.key,n),n.lanes=i,n.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},n}function qy(e,n,i,l,d){this.tag=n,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=kr(0),this.expirationTimes=kr(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=kr(0),this.identifierPrefix=l,this.onRecoverableError=d,this.mutableSourceEagerHydrationData=null}function Su(e,n,i,l,d,p,k,I,O){return e=new qy(e,n,i,I,O),n===1?(n=1,p===!0&&(n|=8)):n=0,p=Yt(3,null,null,n),e.current=p,p.stateNode=e,p.memoizedState={element:l,isDehydrated:i,cache:null,transitions:null,pendingSuspenseBoundaries:null},Aa(p),e}function Ky(e,n,i){var l=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(r){console.error(r)}}return t(),Cu.exports=a0(),Cu.exports}var rh;function u0(){if(rh)return Js;rh=1;var t=Ep();return Js.createRoot=t.createRoot,Js.hydrateRoot=t.hydrateRoot,Js}var c0=u0();function d0(t,r="Request failed"){const o=(t||"").trim();if(!o)return r;try{const a=JSON.parse(o).detail;if(typeof a=="string"&&a.trim())return a;if(Array.isArray(a)){const u=a.map(c=>typeof c=="string"?c:c&&typeof c=="object"&&"msg"in c?String(c.msg):"").filter(Boolean);if(u.length)return u.join("; ")}}catch{}return o}async function Ue(t,r){const o=await fetch(t,{...r,headers:{"Content-Type":"application/json",...(r==null?void 0:r.headers)||{}}});if(!o.ok){const s=await o.text();throw new Error(d0(s,o.statusText||"Request failed"))}return o.json()}const f0=["github_token","gitlab_token","gitlab_oauth_client_secret","bitbucket_token","bitbucket_oauth_client_secret","ai_api_key","ai_model","ai_base_url"],$e={health:()=>Ue("/api/health"),settings:()=>Ue("/api/settings"),saveSettings:t=>{const r={...t};for(const o of f0)r[o]===""&&delete r[o];return Ue("/api/settings",{method:"PUT",body:JSON.stringify(r)})},repos:()=>Ue("/api/repos"),browse:t=>Ue(`/api/fs${t?`?path=${encodeURIComponent(t)}`:""}`),gitRefs:(t,r=50)=>Ue(`/api/git/refs?repo_path=${encodeURIComponent(t)}&limit=${r}`),index:(t,r=!0)=>Ue("/api/index",{method:"POST",body:JSON.stringify({repo_path:t,incremental:r})}),indexStatus:t=>Ue(`/api/index?repo_path=${encodeURIComponent(t)}`),indexProgress:t=>Ue(`/api/index/progress?repo_path=${encodeURIComponent(t)}`),architecture:t=>Ue(`/api/architecture?repo_path=${encodeURIComponent(t)}`),review:(t,r,o,s=!0,a=!1)=>Ue("/api/review",{method:"POST",body:JSON.stringify({repo_path:t,base:r,head:o||null,reindex:s,incremental:!0,three_dot:!0,dirty:a})}),whatIf:(t,r)=>Ue("/api/whatif",{method:"POST",body:JSON.stringify({repo_path:t,node_id:r})}),reviewPr:(t,r,o,s)=>Ue("/api/prs/review",{method:"POST",body:JSON.stringify({provider:t,repo:r,number:o,repo_path:s||null})}),init:(t,r=!1)=>Ue("/api/init",{method:"POST",body:JSON.stringify({repo_path:t,overwrite:r})}),postComment:(t,r,o,s)=>Ue("/api/prs/comment",{method:"POST",body:JSON.stringify({provider:t,repo:r,number:o,markdown:s})}),graph:(t,r="full")=>Ue(`/api/graph?repo_path=${encodeURIComponent(t)}&scope=${r}`),prs:(t,r,o="open")=>Ue("/api/prs",{method:"POST",body:JSON.stringify({provider:t,repo:r,state:o})}),scmRepos:t=>Ue(`/api/scm/repos?provider=${encodeURIComponent(t)}`),oauthStatus:()=>Ue("/api/oauth/status"),githubOAuthStart:()=>Ue("/api/oauth/github/start",{method:"POST",body:"{}"}),githubOAuthPoll:t=>Ue("/api/oauth/github/poll",{method:"POST",body:JSON.stringify({flow_id:t})}),bitbucketOAuthStart:()=>Ue("/api/oauth/bitbucket/start"),gitlabOAuthStart:()=>Ue("/api/oauth/gitlab/start"),oauthDisconnect:t=>Ue("/api/oauth/disconnect",{method:"POST",body:JSON.stringify({provider:t})}),residual:t=>Ue("/api/ai/residual",{method:"POST",body:JSON.stringify({review:t})})};function Po(t){return t.replaceAll("_"," ")}function h0(t){return t.replaceAll("_"," ")}function bl(t){return t.split(".").pop()||t}function jp(t){if(!t)return"";const r=new Date(t);return Number.isNaN(r.getTime())?t:r.toLocaleString()}function p0(t){return t.split(/[\\/]/).filter(Boolean).pop()||t}function $r(t){return t.replace(/([/\\._:@-])/g,"$1​")}function Gr({className:t,children:r}){return h.jsx("svg",{className:t,width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:r})}function g0({className:t}){return h.jsxs(Gr,{className:t,children:[h.jsx("path",{d:"M3 3.5h6.5L13 7v5.5H3z"}),h.jsx("path",{d:"M9.5 3.5V7H13"}),h.jsx("path",{d:"M5.5 9.5h5M5.5 11.5h3.5"})]})}function m0({className:t}){return h.jsxs(Gr,{className:t,children:[h.jsx("rect",{x:"2.5",y:"2.5",width:"4.5",height:"4.5",rx:"0.8"}),h.jsx("rect",{x:"9",y:"2.5",width:"4.5",height:"4.5",rx:"0.8"}),h.jsx("rect",{x:"2.5",y:"9",width:"4.5",height:"4.5",rx:"0.8"}),h.jsx("rect",{x:"9",y:"9",width:"4.5",height:"4.5",rx:"0.8"})]})}function y0({className:t}){return h.jsxs(Gr,{className:t,children:[h.jsx("circle",{cx:"4",cy:"8",r:"1.6"}),h.jsx("circle",{cx:"12",cy:"4",r:"1.6"}),h.jsx("circle",{cx:"12",cy:"12",r:"1.6"}),h.jsx("path",{d:"M5.5 7.2 10.4 4.8M5.5 8.8 10.4 11.2"})]})}function v0({className:t}){return h.jsxs(Gr,{className:t,children:[h.jsx("circle",{cx:"4.5",cy:"4",r:"1.4"}),h.jsx("circle",{cx:"4.5",cy:"12",r:"1.4"}),h.jsx("circle",{cx:"11.5",cy:"12",r:"1.4"}),h.jsx("path",{d:"M4.5 5.5v5M4.5 8h4.2a3 3 0 0 1 3 3"})]})}function x0({className:t}){return h.jsxs(Gr,{className:t,children:[h.jsx("circle",{cx:"8",cy:"8",r:"2.1"}),h.jsx("path",{d:"M8 2.5v1.6M8 11.9v1.6M2.5 8h1.6M11.9 8h1.6M4.1 4.1l1.1 1.1M10.8 10.8l1.1 1.1M11.9 4.1l-1.1 1.1M5.2 10.8l-1.1 1.1"})]})}function bp({className:t}){return h.jsx(Gr,{className:t,children:h.jsx("path",{d:"M2.5 4.5h4L8 6h5.5v6.5h-11z"})})}function w0({className:t}){return h.jsx(Gr,{className:t,children:h.jsx("path",{d:"M4 6.5 8 10.5 12 6.5"})})}const _0="modulepreload",S0=function(t,r){return new URL(t,r).href},ih={},k0=function(r,o,s){let a=Promise.resolve();if(o&&o.length>0){let c=function(v){return Promise.all(v.map(x=>Promise.resolve(x).then(m=>({status:"fulfilled",value:m}),m=>({status:"rejected",reason:m}))))};const f=document.getElementsByTagName("link"),g=document.querySelector("meta[property=csp-nonce]"),y=(g==null?void 0:g.nonce)||(g==null?void 0:g.getAttribute("nonce"));a=c(o.map(v=>{if(v=S0(v,s),v in ih)return;ih[v]=!0;const x=v.endsWith(".css"),m=x?'[rel="stylesheet"]':"";if(!!s)for(let E=f.length-1;E>=0;E--){const b=f[E];if(b.href===v&&(!x||b.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${v}"]${m}`))return;const _=document.createElement("link");if(_.rel=x?"stylesheet":_0,x||(_.as="script"),_.crossOrigin="",_.href=v,y&&_.setAttribute("nonce",y),document.head.appendChild(_),x)return new Promise((E,b)=>{_.addEventListener("load",E),_.addEventListener("error",()=>b(new Error(`Unable to preload CSS for ${v}`)))})}))}function u(c){const f=new Event("vite:preloadError",{cancelable:!0});if(f.payload=c,window.dispatchEvent(f),!f.defaultPrevented)throw c}return a.then(c=>{for(const f of c||[])f.status==="rejected"&&u(f.reason);return r().catch(u)})};function it(t){if(typeof t=="string"||typeof t=="number")return""+t;let r="";if(Array.isArray(t))for(let o=0,s;o{}};function Cl(){for(var t=0,r=arguments.length,o={},s;t=0&&(s=o.slice(a+1),o=o.slice(0,a)),o&&!r.hasOwnProperty(o))throw new Error("unknown type: "+o);return{type:o,name:s}})}dl.prototype=Cl.prototype={constructor:dl,on:function(t,r){var o=this._,s=E0(t+"",o),a,u=-1,c=s.length;if(arguments.length<2){for(;++u0)for(var o=new Array(a),s=0,a,u;s=0&&(r=t.slice(0,o))!=="xmlns"&&(t=t.slice(o+1)),sh.hasOwnProperty(r)?{space:sh[r],local:t}:t}function b0(t){return function(){var r=this.ownerDocument,o=this.namespaceURI;return o===Yu&&r.documentElement.namespaceURI===Yu?r.createElement(t):r.createElementNS(o,t)}}function C0(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function Cp(t){var r=Ml(t);return(r.local?C0:b0)(r)}function M0(){}function lc(t){return t==null?M0:function(){return this.querySelector(t)}}function P0(t){typeof t!="function"&&(t=lc(t));for(var r=this._groups,o=r.length,s=new Array(o),a=0;a=N&&(N=P+1);!(L=b[N])&&++N<_;);j._next=L||null}}return c=new Ft(c,s),c._enter=f,c._exit=g,c}function K0(t){return typeof t=="object"&&"length"in t?t:Array.from(t)}function Q0(){return new Ft(this._exit||this._groups.map(Tp),this._parents)}function Z0(t,r,o){var s=this.enter(),a=this,u=this.exit();return typeof t=="function"?(s=t(s),s&&(s=s.selection())):s=s.append(t+""),r!=null&&(a=r(a),a&&(a=a.selection())),o==null?u.remove():o(u),s&&a?s.merge(a).order():a}function J0(t){for(var r=t.selection?t.selection():t,o=this._groups,s=r._groups,a=o.length,u=s.length,c=Math.min(a,u),f=new Array(a),g=0;g=0;)(c=s[a])&&(u&&c.compareDocumentPosition(u)^4&&u.parentNode.insertBefore(c,u),u=c);return this}function tv(t){t||(t=nv);function r(x,m){return x&&m?t(x.__data__,m.__data__):!x-!m}for(var o=this._groups,s=o.length,a=new Array(s),u=0;ur?1:t>=r?0:NaN}function rv(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this}function iv(){return Array.from(this)}function ov(){for(var t=this._groups,r=0,o=t.length;r1?this.each((r==null?mv:typeof r=="function"?vv:yv)(t,r,o??"")):Li(this.node(),t)}function Li(t,r){return t.style.getPropertyValue(r)||Rp(t).getComputedStyle(t,null).getPropertyValue(r)}function wv(t){return function(){delete this[t]}}function _v(t,r){return function(){this[t]=r}}function Sv(t,r){return function(){var o=r.apply(this,arguments);o==null?delete this[t]:this[t]=o}}function kv(t,r){return arguments.length>1?this.each((r==null?wv:typeof r=="function"?Sv:_v)(t,r)):this.node()[t]}function Lp(t){return t.trim().split(/^|\s+/)}function ac(t){return t.classList||new Ap(t)}function Ap(t){this._node=t,this._names=Lp(t.getAttribute("class")||"")}Ap.prototype={add:function(t){var r=this._names.indexOf(t);r<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},remove:function(t){var r=this._names.indexOf(t);r>=0&&(this._names.splice(r,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};function zp(t,r){for(var o=ac(t),s=-1,a=r.length;++s=0&&(o=r.slice(s+1),r=r.slice(0,s)),{type:r,name:o}})}function Qv(t){return function(){var r=this.__on;if(r){for(var o=0,s=-1,a=r.length,u;o()=>t;function Gu(t,{sourceEvent:r,subject:o,target:s,identifier:a,active:u,x:c,y:f,dx:g,dy:y,dispatch:v}){Object.defineProperties(this,{type:{value:t,enumerable:!0,configurable:!0},sourceEvent:{value:r,enumerable:!0,configurable:!0},subject:{value:o,enumerable:!0,configurable:!0},target:{value:s,enumerable:!0,configurable:!0},identifier:{value:a,enumerable:!0,configurable:!0},active:{value:u,enumerable:!0,configurable:!0},x:{value:c,enumerable:!0,configurable:!0},y:{value:f,enumerable:!0,configurable:!0},dx:{value:g,enumerable:!0,configurable:!0},dy:{value:y,enumerable:!0,configurable:!0},_:{value:v}})}Gu.prototype.on=function(){var t=this._.on.apply(this._,arguments);return t===this._?this:t};function lx(t){return!t.ctrlKey&&!t.button}function ax(){return this.parentNode}function ux(t,r){return r??{x:t.x,y:t.y}}function cx(){return navigator.maxTouchPoints||"ontouchstart"in this}function Bp(){var t=lx,r=ax,o=ux,s=cx,a={},u=Cl("start","drag","end"),c=0,f,g,y,v,x=0;function m(j){j.on("mousedown.drag",S).filter(s).on("touchstart.drag",b).on("touchmove.drag",w,sx).on("touchend.drag touchcancel.drag",P).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function S(j,L){if(!(v||!t.call(this,j,L))){var z=N(this,r.call(this,j,L),j,L,"mouse");z&&(Ot(j.view).on("mousemove.drag",_,Io).on("mouseup.drag",E,Io),Fp(j.view),Iu(j),y=!1,f=j.clientX,g=j.clientY,z("start",j))}}function _(j){if(Ti(j),!y){var L=j.clientX-f,z=j.clientY-g;y=L*L+z*z>x}a.mouse("drag",j)}function E(j){Ot(j.view).on("mousemove.drag mouseup.drag",null),Hp(j.view,y),Ti(j),a.mouse("end",j)}function b(j,L){if(t.call(this,j,L)){var z=j.changedTouches,W=r.call(this,j,L),D=z.length,G,J;for(G=0;G>8&15|r>>4&240,r>>4&15|r&240,(r&15)<<4|r&15,1):o===8?tl(r>>24&255,r>>16&255,r>>8&255,(r&255)/255):o===4?tl(r>>12&15|r>>8&240,r>>8&15|r>>4&240,r>>4&15|r&240,((r&15)<<4|r&15)/255):null):(r=fx.exec(t))?new Mt(r[1],r[2],r[3],1):(r=hx.exec(t))?new Mt(r[1]*255/100,r[2]*255/100,r[3]*255/100,1):(r=px.exec(t))?tl(r[1],r[2],r[3],r[4]):(r=gx.exec(t))?tl(r[1]*255/100,r[2]*255/100,r[3]*255/100,r[4]):(r=mx.exec(t))?hh(r[1],r[2]/100,r[3]/100,1):(r=yx.exec(t))?hh(r[1],r[2]/100,r[3]/100,r[4]):lh.hasOwnProperty(t)?ch(lh[t]):t==="transparent"?new Mt(NaN,NaN,NaN,0):null}function ch(t){return new Mt(t>>16&255,t>>8&255,t&255,1)}function tl(t,r,o,s){return s<=0&&(t=r=o=NaN),new Mt(t,r,o,s)}function wx(t){return t instanceof Wo||(t=Br(t)),t?(t=t.rgb(),new Mt(t.r,t.g,t.b,t.opacity)):new Mt}function Xu(t,r,o,s){return arguments.length===1?wx(t):new Mt(t,r,o,s??1)}function Mt(t,r,o,s){this.r=+t,this.g=+r,this.b=+o,this.opacity=+s}uc(Mt,Xu,Vp(Wo,{brighter(t){return t=t==null?yl:Math.pow(yl,t),new Mt(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=t==null?To:Math.pow(To,t),new Mt(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new Mt(Fr(this.r),Fr(this.g),Fr(this.b),vl(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:dh,formatHex:dh,formatHex8:_x,formatRgb:fh,toString:fh}));function dh(){return`#${Or(this.r)}${Or(this.g)}${Or(this.b)}`}function _x(){return`#${Or(this.r)}${Or(this.g)}${Or(this.b)}${Or((isNaN(this.opacity)?1:this.opacity)*255)}`}function fh(){const t=vl(this.opacity);return`${t===1?"rgb(":"rgba("}${Fr(this.r)}, ${Fr(this.g)}, ${Fr(this.b)}${t===1?")":`, ${t})`}`}function vl(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function Fr(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function Or(t){return t=Fr(t),(t<16?"0":"")+t.toString(16)}function hh(t,r,o,s){return s<=0?t=r=o=NaN:o<=0||o>=1?t=r=NaN:r<=0&&(t=NaN),new tn(t,r,o,s)}function Wp(t){if(t instanceof tn)return new tn(t.h,t.s,t.l,t.opacity);if(t instanceof Wo||(t=Br(t)),!t)return new tn;if(t instanceof tn)return t;t=t.rgb();var r=t.r/255,o=t.g/255,s=t.b/255,a=Math.min(r,o,s),u=Math.max(r,o,s),c=NaN,f=u-a,g=(u+a)/2;return f?(r===u?c=(o-s)/f+(o0&&g<1?0:c,new tn(c,f,g,t.opacity)}function Sx(t,r,o,s){return arguments.length===1?Wp(t):new tn(t,r,o,s??1)}function tn(t,r,o,s){this.h=+t,this.s=+r,this.l=+o,this.opacity=+s}uc(tn,Sx,Vp(Wo,{brighter(t){return t=t==null?yl:Math.pow(yl,t),new tn(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=t==null?To:Math.pow(To,t),new tn(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+(this.h<0)*360,r=isNaN(t)||isNaN(this.s)?0:this.s,o=this.l,s=o+(o<.5?o:1-o)*r,a=2*o-s;return new Mt(Tu(t>=240?t-240:t+120,a,s),Tu(t,a,s),Tu(t<120?t+240:t-120,a,s),this.opacity)},clamp(){return new tn(ph(this.h),nl(this.s),nl(this.l),vl(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=vl(this.opacity);return`${t===1?"hsl(":"hsla("}${ph(this.h)}, ${nl(this.s)*100}%, ${nl(this.l)*100}%${t===1?")":`, ${t})`}`}}));function ph(t){return t=(t||0)%360,t<0?t+360:t}function nl(t){return Math.max(0,Math.min(1,t||0))}function Tu(t,r,o){return(t<60?r+(o-r)*t/60:t<180?o:t<240?r+(o-r)*(240-t)/60:r)*255}const cc=t=>()=>t;function kx(t,r){return function(o){return t+o*r}}function Nx(t,r,o){return t=Math.pow(t,o),r=Math.pow(r,o)-t,o=1/o,function(s){return Math.pow(t+s*r,o)}}function Ex(t){return(t=+t)==1?Up:function(r,o){return o-r?Nx(r,o,t):cc(isNaN(r)?o:r)}}function Up(t,r){var o=r-t;return o?kx(t,o):cc(isNaN(t)?r:t)}const xl=(function t(r){var o=Ex(r);function s(a,u){var c=o((a=Xu(a)).r,(u=Xu(u)).r),f=o(a.g,u.g),g=o(a.b,u.b),y=Up(a.opacity,u.opacity);return function(v){return a.r=c(v),a.g=f(v),a.b=g(v),a.opacity=y(v),a+""}}return s.gamma=t,s})(1);function jx(t,r){r||(r=[]);var o=t?Math.min(r.length,t.length):0,s=r.slice(),a;return function(u){for(a=0;ao&&(u=r.slice(o,u),f[c]?f[c]+=u:f[++c]=u),(s=s[0])===(a=a[0])?f[c]?f[c]+=a:f[++c]=a:(f[++c]=null,g.push({i:c,x:vn(s,a)})),o=Ru.lastIndex;return o180?v+=360:v-y>180&&(y+=360),m.push({i:x.push(a(x)+"rotate(",null,s)-2,x:vn(y,v)})):v&&x.push(a(x)+"rotate("+v+s)}function f(y,v,x,m){y!==v?m.push({i:x.push(a(x)+"skewX(",null,s)-2,x:vn(y,v)}):v&&x.push(a(x)+"skewX("+v+s)}function g(y,v,x,m,S,_){if(y!==x||v!==m){var E=S.push(a(S)+"scale(",null,",",null,")");_.push({i:E-4,x:vn(y,x)},{i:E-2,x:vn(v,m)})}else(x!==1||m!==1)&&S.push(a(S)+"scale("+x+","+m+")")}return function(y,v){var x=[],m=[];return y=t(y),v=t(v),u(y.translateX,y.translateY,v.translateX,v.translateY,x,m),c(y.rotate,v.rotate,x,m),f(y.skewX,v.skewX,x,m),g(y.scaleX,y.scaleY,v.scaleX,v.scaleY,x,m),y=v=null,function(S){for(var _=-1,E=m.length,b;++_=0&&t._call.call(void 0,r),t=t._next;--Ai}function yh(){Vr=(_l=Lo.now())+Pl,Ai=Eo=0;try{Hx()}finally{Ai=0,Vx(),Vr=0}}function Bx(){var t=Lo.now(),r=t-_l;r>qp&&(Pl-=r,_l=t)}function Vx(){for(var t,r=wl,o,s=1/0;r;)r._call?(s>r._time&&(s=r._time),t=r,r=r._next):(o=r._next,r._next=null,r=t?t._next=o:wl=o);jo=t,Qu(s)}function Qu(t){if(!Ai){Eo&&(Eo=clearTimeout(Eo));var r=t-Vr;r>24?(t<1/0&&(Eo=setTimeout(yh,t-Lo.now()-Pl)),ko&&(ko=clearInterval(ko))):(ko||(_l=Lo.now(),ko=setInterval(Bx,qp)),Ai=1,Kp(yh))}}function vh(t,r,o){var s=new Sl;return r=r==null?0:+r,s.restart(a=>{s.stop(),t(a+r)},r,o),s}var Wx=Cl("start","end","cancel","interrupt"),Ux=[],Zp=0,xh=1,Zu=2,hl=3,wh=4,Ju=5,pl=6;function Il(t,r,o,s,a,u){var c=t.__transition;if(!c)t.__transition={};else if(o in c)return;Yx(t,o,{name:r,index:s,group:a,on:Wx,tween:Ux,time:u.time,delay:u.delay,duration:u.duration,ease:u.ease,timer:null,state:Zp})}function fc(t,r){var o=sn(t,r);if(o.state>Zp)throw new Error("too late; already scheduled");return o}function wn(t,r){var o=sn(t,r);if(o.state>hl)throw new Error("too late; already running");return o}function sn(t,r){var o=t.__transition;if(!o||!(o=o[r]))throw new Error("transition not found");return o}function Yx(t,r,o){var s=t.__transition,a;s[r]=o,o.timer=Qp(u,0,o.time);function u(y){o.state=xh,o.timer.restart(c,o.delay,o.time),o.delay<=y&&c(y-o.delay)}function c(y){var v,x,m,S;if(o.state!==xh)return g();for(v in s)if(S=s[v],S.name===o.name){if(S.state===hl)return vh(c);S.state===wh?(S.state=pl,S.timer.stop(),S.on.call("interrupt",t,t.__data__,S.index,S.group),delete s[v]):+vZu&&s.state=0&&(r=r.slice(0,o)),!r||r==="start"})}function Sw(t,r,o){var s,a,u=_w(r)?fc:wn;return function(){var c=u(this,t),f=c.on;f!==s&&(a=(s=f).copy()).on(r,o),c.on=a}}function kw(t,r){var o=this._id;return arguments.length<2?sn(this.node(),o).on.on(t):this.each(Sw(o,t,r))}function Nw(t){return function(){var r=this.parentNode;for(var o in this.__transition)if(+o!==t)return;r&&r.removeChild(this)}}function Ew(){return this.on("end.remove",Nw(this._id))}function jw(t){var r=this._name,o=this._id;typeof t!="function"&&(t=lc(t));for(var s=this._groups,a=s.length,u=new Array(a),c=0;c()=>t;function Qw(t,{sourceEvent:r,target:o,transform:s,dispatch:a}){Object.defineProperties(this,{type:{value:t,enumerable:!0,configurable:!0},sourceEvent:{value:r,enumerable:!0,configurable:!0},target:{value:o,enumerable:!0,configurable:!0},transform:{value:s,enumerable:!0,configurable:!0},_:{value:a}})}function Ln(t,r,o){this.k=t,this.x=r,this.y=o}Ln.prototype={constructor:Ln,scale:function(t){return t===1?this:new Ln(this.k*t,this.x,this.y)},translate:function(t,r){return t===0&r===0?this:new Ln(this.k,this.x+this.k*t,this.y+this.k*r)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var Tl=new Ln(1,0,0);ng.prototype=Ln.prototype;function ng(t){for(;!t.__zoom;)if(!(t=t.parentNode))return Tl;return t.__zoom}function Lu(t){t.stopImmediatePropagation()}function No(t){t.preventDefault(),t.stopImmediatePropagation()}function Zw(t){return(!t.ctrlKey||t.type==="wheel")&&!t.button}function Jw(){var t=this;return t instanceof SVGElement?(t=t.ownerSVGElement||t,t.hasAttribute("viewBox")?(t=t.viewBox.baseVal,[[t.x,t.y],[t.x+t.width,t.y+t.height]]):[[0,0],[t.width.baseVal.value,t.height.baseVal.value]]):[[0,0],[t.clientWidth,t.clientHeight]]}function _h(){return this.__zoom||Tl}function e1(t){return-t.deltaY*(t.deltaMode===1?.05:t.deltaMode?1:.002)*(t.ctrlKey?10:1)}function t1(){return navigator.maxTouchPoints||"ontouchstart"in this}function n1(t,r,o){var s=t.invertX(r[0][0])-o[0][0],a=t.invertX(r[1][0])-o[1][0],u=t.invertY(r[0][1])-o[0][1],c=t.invertY(r[1][1])-o[1][1];return t.translate(a>s?(s+a)/2:Math.min(0,s)||Math.max(0,a),c>u?(u+c)/2:Math.min(0,u)||Math.max(0,c))}function rg(){var t=Zw,r=Jw,o=n1,s=e1,a=t1,u=[0,1/0],c=[[-1/0,-1/0],[1/0,1/0]],f=250,g=fl,y=Cl("start","zoom","end"),v,x,m,S=500,_=150,E=0,b=10;function w(C){C.property("__zoom",_h).on("wheel.zoom",D,{passive:!1}).on("mousedown.zoom",G).on("dblclick.zoom",J).filter(a).on("touchstart.zoom",K).on("touchmove.zoom",ne).on("touchend.zoom touchcancel.zoom",te).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}w.transform=function(C,R,B,Y){var T=C.selection?C.selection():C;T.property("__zoom",_h),C!==T?L(C,R,B,Y):T.interrupt().each(function(){z(this,arguments).event(Y).start().zoom(null,typeof R=="function"?R.apply(this,arguments):R).end()})},w.scaleBy=function(C,R,B,Y){w.scaleTo(C,function(){var T=this.__zoom.k,H=typeof R=="function"?R.apply(this,arguments):R;return T*H},B,Y)},w.scaleTo=function(C,R,B,Y){w.transform(C,function(){var T=r.apply(this,arguments),H=this.__zoom,U=B==null?j(T):typeof B=="function"?B.apply(this,arguments):B,M=H.invert(U),A=typeof R=="function"?R.apply(this,arguments):R;return o(N(P(H,A),U,M),T,c)},B,Y)},w.translateBy=function(C,R,B,Y){w.transform(C,function(){return o(this.__zoom.translate(typeof R=="function"?R.apply(this,arguments):R,typeof B=="function"?B.apply(this,arguments):B),r.apply(this,arguments),c)},null,Y)},w.translateTo=function(C,R,B,Y,T){w.transform(C,function(){var H=r.apply(this,arguments),U=this.__zoom,M=Y==null?j(H):typeof Y=="function"?Y.apply(this,arguments):Y;return o(Tl.translate(M[0],M[1]).scale(U.k).translate(typeof R=="function"?-R.apply(this,arguments):-R,typeof B=="function"?-B.apply(this,arguments):-B),H,c)},Y,T)};function P(C,R){return R=Math.max(u[0],Math.min(u[1],R)),R===C.k?C:new Ln(R,C.x,C.y)}function N(C,R,B){var Y=R[0]-B[0]*C.k,T=R[1]-B[1]*C.k;return Y===C.x&&T===C.y?C:new Ln(C.k,Y,T)}function j(C){return[(+C[0][0]+ +C[1][0])/2,(+C[0][1]+ +C[1][1])/2]}function L(C,R,B,Y){C.on("start.zoom",function(){z(this,arguments).event(Y).start()}).on("interrupt.zoom end.zoom",function(){z(this,arguments).event(Y).end()}).tween("zoom",function(){var T=this,H=arguments,U=z(T,H).event(Y),M=r.apply(T,H),A=B==null?j(M):typeof B=="function"?B.apply(T,H):B,re=Math.max(M[1][0]-M[0][0],M[1][1]-M[0][1]),ie=T.__zoom,ce=typeof R=="function"?R.apply(T,H):R,fe=g(ie.invert(A).concat(re/ie.k),ce.invert(A).concat(re/ce.k));return function(de){if(de===1)de=ce;else{var Q=fe(de),le=re/Q[2];de=new Ln(le,A[0]-Q[0]*le,A[1]-Q[1]*le)}U.zoom(null,de)}})}function z(C,R,B){return!B&&C.__zooming||new W(C,R)}function W(C,R){this.that=C,this.args=R,this.active=0,this.sourceEvent=null,this.extent=r.apply(C,R),this.taps=0}W.prototype={event:function(C){return C&&(this.sourceEvent=C),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(C,R){return this.mouse&&C!=="mouse"&&(this.mouse[1]=R.invert(this.mouse[0])),this.touch0&&C!=="touch"&&(this.touch0[1]=R.invert(this.touch0[0])),this.touch1&&C!=="touch"&&(this.touch1[1]=R.invert(this.touch1[0])),this.that.__zoom=R,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(C){var R=Ot(this.that).datum();y.call(C,this.that,new Qw(C,{sourceEvent:this.sourceEvent,target:w,transform:this.that.__zoom,dispatch:y}),R)}};function D(C,...R){if(!t.apply(this,arguments))return;var B=z(this,R).event(C),Y=this.__zoom,T=Math.max(u[0],Math.min(u[1],Y.k*Math.pow(2,s.apply(this,arguments)))),H=en(C);if(B.wheel)(B.mouse[0][0]!==H[0]||B.mouse[0][1]!==H[1])&&(B.mouse[1]=Y.invert(B.mouse[0]=H)),clearTimeout(B.wheel);else{if(Y.k===T)return;B.mouse=[H,Y.invert(H)],gl(this),B.start()}No(C),B.wheel=setTimeout(U,_),B.zoom("mouse",o(N(P(Y,T),B.mouse[0],B.mouse[1]),B.extent,c));function U(){B.wheel=null,B.end()}}function G(C,...R){if(m||!t.apply(this,arguments))return;var B=C.currentTarget,Y=z(this,R,!0).event(C),T=Ot(C.view).on("mousemove.zoom",A,!0).on("mouseup.zoom",re,!0),H=en(C,B),U=C.clientX,M=C.clientY;Fp(C.view),Lu(C),Y.mouse=[H,this.__zoom.invert(H)],gl(this),Y.start();function A(ie){if(No(ie),!Y.moved){var ce=ie.clientX-U,fe=ie.clientY-M;Y.moved=ce*ce+fe*fe>E}Y.event(ie).zoom("mouse",o(N(Y.that.__zoom,Y.mouse[0]=en(ie,B),Y.mouse[1]),Y.extent,c))}function re(ie){T.on("mousemove.zoom mouseup.zoom",null),Hp(ie.view,Y.moved),No(ie),Y.event(ie).end()}}function J(C,...R){if(t.apply(this,arguments)){var B=this.__zoom,Y=en(C.changedTouches?C.changedTouches[0]:C,this),T=B.invert(Y),H=B.k*(C.shiftKey?.5:2),U=o(N(P(B,H),Y,T),r.apply(this,R),c);No(C),f>0?Ot(this).transition().duration(f).call(L,U,Y,C):Ot(this).call(w.transform,U,Y,C)}}function K(C,...R){if(t.apply(this,arguments)){var B=C.touches,Y=B.length,T=z(this,R,C.changedTouches.length===Y).event(C),H,U,M,A;for(Lu(C),U=0;U`Seems like you have not used ${t==="svelte"?"SvelteFlowProvider":"ReactFlowProvider"} as an ancestor. Help: https://${t}flow.dev/error#001`,error002:()=>"It looks like you've created a new nodeTypes or edgeTypes object. If this wasn't on purpose please define the nodeTypes/edgeTypes outside of the component or memoize them.",error003:t=>`Node type "${t}" not found. Using fallback type "default".`,error004:()=>"The parent container needs a width and a height to render the graph.",error005:()=>"Only child nodes can use a parent extent.",error006:()=>"Can't create edge. An edge needs a source and a target.",error007:t=>`The old edge with id=${t} does not exist.`,error009:t=>`Marker type "${t}" doesn't exist.`,error008:(t,{id:r,sourceHandle:o,targetHandle:s})=>`Couldn't create edge for ${t} handle id: "${t==="source"?o:s}", edge id: ${r}.`,error010:()=>"Handle: No node id found. Make sure to only use a Handle inside a custom Node.",error011:t=>`Edge type "${t}" not found. Using fallback type "default".`,error012:t=>`Node with id "${t}" does not exist, it may have been removed. This can happen when a node is deleted before the "onNodeClick" handler is called.`,error013:(t="react")=>`It seems that you haven't loaded the styles. Please import '@xyflow/${t}/dist/style.css' or base.css to make sure everything is working properly.`,error014:()=>"useNodeConnections: No node ID found. Call useNodeConnections inside a custom Node or provide a node ID.",error015:()=>"It seems that you are trying to drag a node that is not initialized. Please use onNodesChange as explained in the docs.",error016:t=>`Edge with id "${t}" does not exist, it may have been removed. This can happen when an edge is deleted before the "onEdgeClick" handler is called.`},Ao=[[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]],ig=["Enter"," ","Escape"],og={"node.a11yDescription.default":"Press enter or space to select a node. Press delete to remove it and escape to cancel.","node.a11yDescription.keyboardDisabled":"Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.","node.a11yDescription.ariaLiveMessage":({direction:t,x:r,y:o})=>`Moved selected node ${t}. New position, x: ${r}, y: ${o}`,"edge.a11yDescription.default":"Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.","controls.ariaLabel":"Control Panel","controls.zoomIn.ariaLabel":"Zoom In","controls.zoomOut.ariaLabel":"Zoom Out","controls.fitView.ariaLabel":"Fit View","controls.interactive.ariaLabel":"Toggle Interactivity","minimap.ariaLabel":"Mini Map","handle.ariaLabel":"Handle"};var zi;(function(t){t.Strict="strict",t.Loose="loose"})(zi||(zi={}));var Hr;(function(t){t.Free="free",t.Vertical="vertical",t.Horizontal="horizontal"})(Hr||(Hr={}));var zo;(function(t){t.Partial="partial",t.Full="full"})(zo||(zo={}));const sg={inProgress:!1,isValid:null,from:null,fromHandle:null,fromPosition:null,fromNode:null,to:null,toHandle:null,toPosition:null,toNode:null,pointer:null};var hr;(function(t){t.Bezier="default",t.Straight="straight",t.Step="step",t.SmoothStep="smoothstep",t.SimpleBezier="simplebezier"})(hr||(hr={}));var Do;(function(t){t.Arrow="arrow",t.ArrowClosed="arrowclosed"})(Do||(Do={}));var Se;(function(t){t.Left="left",t.Top="top",t.Right="right",t.Bottom="bottom"})(Se||(Se={}));const Sh={[Se.Left]:Se.Right,[Se.Right]:Se.Left,[Se.Top]:Se.Bottom,[Se.Bottom]:Se.Top};function lg(t){return t===null?null:t?"valid":"invalid"}const ag=t=>!!t&&typeof t=="object"&&"id"in t&&"source"in t&&"target"in t,r1=t=>!!t&&typeof t=="object"&&"id"in t&&"position"in t&&!("source"in t)&&!("target"in t),pc=t=>!!t&&typeof t=="object"&&"id"in t&&"internals"in t&&!("source"in t)&&!("target"in t),Uo=(t,r=[0,0])=>{const{width:o,height:s}=ln(t),a=t.origin??r,u=o*a[0],c=s*a[1];return{x:t.position.x-u,y:t.position.y-c}},i1=(t,r={nodeOrigin:[0,0]})=>{if(t.length===0)return{x:0,y:0,width:0,height:0};let o=!1;const s=t.reduce((a,u)=>{const c=typeof u=="string";let f=!r.nodeLookup&&!c?u:void 0;return r.nodeLookup&&(f=c?r.nodeLookup.get(u):pc(u)?u:r.nodeLookup.get(u.id)),f?(o=!0,Rl(a,kl(f,r.nodeOrigin))):a},{x:1/0,y:1/0,x2:-1/0,y2:-1/0});return o?Ll(s):{x:0,y:0,width:0,height:0}},Yo=(t,r={})=>{let o={x:1/0,y:1/0,x2:-1/0,y2:-1/0},s=!1;return t.forEach(a=>{(r.filter===void 0||r.filter(a))&&(o=Rl(o,kl(a)),s=!0)}),s?Ll(o):{x:0,y:0,width:0,height:0}},gc=(t,r,[o,s,a]=[0,0,1],u=!1,c=!1)=>{const f=(r.x-o)/a,g=(r.y-s)/a,y=r.width/a,v=r.height/a,x=[];for(const m of t.values()){const{measured:S,selectable:_=!0,hidden:E=!1}=m;if(c&&!_||E)continue;const b=S.width??m.width??m.initialWidth??0,w=S.height??m.height??m.initialHeight??0,{x:P,y:N}=m.internals.positionAbsolute,j=fg(f,g,y,v,P,N,b,w),L=b*w,z=u&&j>0;(!m.internals.handleBounds||z||j>=L||m.dragging)&&x.push(m)}return x},o1=(t,r)=>{const o=new Set;return t.forEach(s=>{o.add(s.id)}),r.filter(s=>o.has(s.source)||o.has(s.target))};function s1(t,r){const o=new Map,s=r!=null&&r.nodes?new Set(r.nodes.map(a=>a.id)):null;return t.forEach(a=>{let u;if(r!=null&&r.includeHiddenNodes){const{width:c,height:f}=ln(a);u=c>0&&f>0}else u=!!(a.measured.width&&a.measured.height&&!a.hidden);u&&(!s||s.has(a.id))&&o.set(a.id,a)}),o}async function l1({nodes:t,width:r,height:o,panZoom:s,minZoom:a,maxZoom:u},c){if(t.size===0)return!0;const f=s1(t,c),g=Yo(f),y=yc(g,r,o,(c==null?void 0:c.minZoom)??a,(c==null?void 0:c.maxZoom)??u,(c==null?void 0:c.padding)??.1);return await s.setViewport(y,{duration:c==null?void 0:c.duration,ease:c==null?void 0:c.ease,interpolate:c==null?void 0:c.interpolate}),!0}function ug({nodeId:t,nextPosition:r,nodeLookup:o,nodeOrigin:s=[0,0],nodeExtent:a,onError:u}){const c=o.get(t),f=c.parentId?o.get(c.parentId):void 0,{x:g,y}=f?f.internals.positionAbsolute:{x:0,y:0},v=c.origin??s;let x=c.extent||a;if(c.extent==="parent"&&!c.expandParent)if(!f)u==null||u("005",on.error005());else{const{width:S,height:_}=ln(f);S&&_&&(x=[[g,y],[g+S,y+_]])}else f&&Ur(c.extent)&&(x=[[c.extent[0][0]+g,c.extent[0][1]+y],[c.extent[1][0]+g,c.extent[1][1]+y]]);const m=Ur(x)?Wr(r,x,c.measured):r;return(c.measured.width===void 0||c.measured.height===void 0)&&(u==null||u("015",on.error015())),{position:{x:m.x-g+(c.measured.width??0)*v[0],y:m.y-y+(c.measured.height??0)*v[1]},positionAbsolute:m}}async function a1({nodesToRemove:t=[],edgesToRemove:r=[],nodes:o,edges:s,onBeforeDelete:a}){const u=new Set(t.map(m=>m.id)),c=[];for(const m of o){if(m.deletable===!1)continue;const S=u.has(m.id),_=!S&&m.parentId&&c.find(E=>E.id===m.parentId);(S||_)&&c.push(m)}const f=new Set(r.map(m=>m.id)),g=s.filter(m=>m.deletable!==!1),v=o1(c,g);for(const m of g)f.has(m.id)&&!v.find(_=>_.id===m.id)&&v.push(m);if(!a)return{edges:v,nodes:c};const x=await a({nodes:c,edges:v});return typeof x=="boolean"?x?{edges:v,nodes:c}:{edges:[],nodes:[]}:x}const Di=(t,r=0,o=1)=>Math.min(Math.max(t,r),o),Wr=(t={x:0,y:0},r,o)=>({x:Di(t.x,r[0][0],r[1][0]-((o==null?void 0:o.width)??0)),y:Di(t.y,r[0][1],r[1][1]-((o==null?void 0:o.height)??0))});function cg(t,r,o){const{width:s,height:a}=ln(o),{x:u,y:c}=o.internals.positionAbsolute;return Wr(t,[[u,c],[u+s,c+a]],r)}const kh=(t,r,o)=>to?-Di(Math.abs(t-o),1,r)/r:0,mc=(t,r,o=15,s=40)=>{const a=kh(t.x,s,r.width-s)*o,u=kh(t.y,s,r.height-s)*o;return[a,u]},Rl=(t,r)=>({x:Math.min(t.x,r.x),y:Math.min(t.y,r.y),x2:Math.max(t.x2,r.x2),y2:Math.max(t.y2,r.y2)}),ec=({x:t,y:r,width:o,height:s})=>({x:t,y:r,x2:t+o,y2:r+s}),Ll=({x:t,y:r,x2:o,y2:s})=>({x:t,y:r,width:o-t,height:s-r}),$o=(t,r=[0,0])=>{var a,u;const{x:o,y:s}=pc(t)?t.internals.positionAbsolute:Uo(t,r);return{x:o,y:s,width:((a=t.measured)==null?void 0:a.width)??t.width??t.initialWidth??0,height:((u=t.measured)==null?void 0:u.height)??t.height??t.initialHeight??0}},kl=(t,r=[0,0])=>{var a,u;const{x:o,y:s}=pc(t)?t.internals.positionAbsolute:Uo(t,r);return{x:o,y:s,x2:o+(((a=t.measured)==null?void 0:a.width)??t.width??t.initialWidth??0),y2:s+(((u=t.measured)==null?void 0:u.height)??t.height??t.initialHeight??0)}},dg=(t,r)=>Ll(Rl(ec(t),ec(r))),fg=(t,r,o,s,a,u,c,f)=>{const g=Math.max(0,Math.min(t+o,a+c)-Math.max(t,a)),y=Math.max(0,Math.min(r+s,u+f)-Math.max(r,u));return Math.ceil(g*y)},Nl=(t,r)=>fg(t.x,t.y,t.width,t.height,r.x,r.y,r.width,r.height),Nh=t=>nn(t.width)&&nn(t.height)&&nn(t.x)&&nn(t.y),nn=t=>!isNaN(t)&&isFinite(t),hg=(t,r)=>(o,s)=>{},Go=(t,r=[1,1])=>({x:r[0]*Math.round(t.x/r[0]),y:r[1]*Math.round(t.y/r[1])}),Xo=({x:t,y:r},[o,s,a],u=!1,c=[1,1])=>{const f={x:(t-o)/a,y:(r-s)/a};return u?Go(f,c):f},$i=({x:t,y:r},[o,s,a])=>({x:t*a+o,y:r*a+s});function Pi(t,r){if(typeof t=="number")return Math.floor((r-r/(1+t))*.5);if(typeof t=="string"&&t.endsWith("px")){const o=parseFloat(t);if(!Number.isNaN(o))return Math.floor(o)}if(typeof t=="string"&&t.endsWith("%")){const o=parseFloat(t);if(!Number.isNaN(o))return Math.floor(r*o*.01)}return console.error(`The padding value "${t}" is invalid. Please provide a number or a string with a valid unit (px or %).`),0}function u1(t,r,o){if(typeof t=="string"||typeof t=="number"){const s=Pi(t,o),a=Pi(t,r);return{top:s,right:a,bottom:s,left:a,x:a*2,y:s*2}}if(typeof t=="object"){const s=Pi(t.top??t.y??0,o),a=Pi(t.bottom??t.y??0,o),u=Pi(t.left??t.x??0,r),c=Pi(t.right??t.x??0,r);return{top:s,right:c,bottom:a,left:u,x:u+c,y:s+a}}return{top:0,right:0,bottom:0,left:0,x:0,y:0}}function c1(t,r,o,s,a,u){const{x:c,y:f}=$i(t,[r,o,s]),{x:g,y}=$i({x:t.x+t.width,y:t.y+t.height},[r,o,s]),v=a-g,x=u-y;return{left:Math.floor(c),top:Math.floor(f),right:Math.floor(v),bottom:Math.floor(x)}}const yc=(t,r,o,s,a,u)=>{const c=u1(u,r,o),f=(r-c.x)/t.width,g=(o-c.y)/t.height,y=Math.min(f,g),v=Di(y,s,a),x=t.x+t.width/2,m=t.y+t.height/2,S=r/2-x*v,_=o/2-m*v,E=c1(t,S,_,v,r,o),b={left:Math.min(E.left-c.left,0),top:Math.min(E.top-c.top,0),right:Math.min(E.right-c.right,0),bottom:Math.min(E.bottom-c.bottom,0)};return{x:S-b.left+b.right,y:_-b.top+b.bottom,zoom:v}},Oo=()=>{var t;return typeof navigator<"u"&&((t=navigator==null?void 0:navigator.userAgent)==null?void 0:t.indexOf("Mac"))>=0};function Ur(t){return t!=null&&t!=="parent"}function ln(t){var r,o;return{width:((r=t.measured)==null?void 0:r.width)??t.width??t.initialWidth??0,height:((o=t.measured)==null?void 0:o.height)??t.height??t.initialHeight??0}}function pg(t){var r,o;return(((r=t.measured)==null?void 0:r.width)??t.width??t.initialWidth)!==void 0&&(((o=t.measured)==null?void 0:o.height)??t.height??t.initialHeight)!==void 0}function gg(t,r={width:0,height:0},o,s,a){const u={...t},c=s.get(o);if(c){const f=c.origin||a;u.x+=c.internals.positionAbsolute.x-(r.width??0)*f[0],u.y+=c.internals.positionAbsolute.y-(r.height??0)*f[1]}return u}function Eh(t,r){if(t.size!==r.size)return!1;for(const o of t)if(!r.has(o))return!1;return!0}function d1(){let t,r;return{promise:new Promise((s,a)=>{t=s,r=a}),resolve:t,reject:r}}function f1(t){return{...og,...t||{}}}function Co(t,{snapGrid:r=[0,0],snapToGrid:o=!1,transform:s,containerBounds:a}){const{x:u,y:c}=rn(t),f=Xo({x:u-((a==null?void 0:a.left)??0),y:c-((a==null?void 0:a.top)??0)},s),{x:g,y}=o?Go(f,r):f;return{xSnapped:g,ySnapped:y,...f}}const vc=t=>({width:t.offsetWidth,height:t.offsetHeight}),mg=t=>{var r;return((r=t==null?void 0:t.getRootNode)==null?void 0:r.call(t))||(window==null?void 0:window.document)},h1=["INPUT","SELECT","TEXTAREA"];function yg(t){var s,a;const r=((a=(s=t.composedPath)==null?void 0:s.call(t))==null?void 0:a[0])||t.target;return(r==null?void 0:r.nodeType)!==1?!1:h1.includes(r.nodeName)||r.hasAttribute("contenteditable")||!!r.closest(".nokey")}const vg=t=>"clientX"in t,rn=(t,r)=>{var u,c;const o=vg(t),s=o?t.clientX:(u=t.touches)==null?void 0:u[0].clientX,a=o?t.clientY:(c=t.touches)==null?void 0:c[0].clientY;return{x:s-((r==null?void 0:r.left)??0),y:a-((r==null?void 0:r.top)??0)}},jh=(t,r,o,s,a)=>{const u=r.querySelectorAll(`.${t}`);return!u||!u.length?null:Array.from(u).map(c=>{const f=c.getBoundingClientRect();return{id:c.getAttribute("data-handleid"),type:t,nodeId:a,position:c.getAttribute("data-handlepos"),x:(f.left-o.left)/s,y:(f.top-o.top)/s,...vc(c)}})};function xg({sourceX:t,sourceY:r,targetX:o,targetY:s,sourceControlX:a,sourceControlY:u,targetControlX:c,targetControlY:f}){const g=t*.125+a*.375+c*.375+o*.125,y=r*.125+u*.375+f*.375+s*.125,v=Math.abs(g-t),x=Math.abs(y-r);return[g,y,v,x]}function ol(t,r){return t>=0?.5*t:r*25*Math.sqrt(-t)}function bh({pos:t,x1:r,y1:o,x2:s,y2:a,c:u}){switch(t){case Se.Left:return[r-ol(r-s,u),o];case Se.Right:return[r+ol(s-r,u),o];case Se.Top:return[r,o-ol(o-a,u)];case Se.Bottom:return[r,o+ol(a-o,u)]}}function wg({sourceX:t,sourceY:r,sourcePosition:o=Se.Bottom,targetX:s,targetY:a,targetPosition:u=Se.Top,curvature:c=.25}){const[f,g]=bh({pos:o,x1:t,y1:r,x2:s,y2:a,c}),[y,v]=bh({pos:u,x1:s,y1:a,x2:t,y2:r,c}),[x,m,S,_]=xg({sourceX:t,sourceY:r,targetX:s,targetY:a,sourceControlX:f,sourceControlY:g,targetControlX:y,targetControlY:v});return[`M${t},${r} C${f},${g} ${y},${v} ${s},${a}`,x,m,S,_]}function _g({sourceX:t,sourceY:r,targetX:o,targetY:s}){const a=Math.abs(o-t)/2,u=o0}const m1=({source:t,sourceHandle:r,target:o,targetHandle:s})=>`xy-edge__${t}${r||""}-${o}${s||""}`,y1=(t,r)=>r.some(o=>o.source===t.source&&o.target===t.target&&(o.sourceHandle===t.sourceHandle||!o.sourceHandle&&!t.sourceHandle)&&(o.targetHandle===t.targetHandle||!o.targetHandle&&!t.targetHandle)),v1=(t,r,o={})=>{var u;if(!t.source||!t.target)return(u=o.onError)==null||u.call(o,"006",on.error006()),r;const s=o.getEdgeId||m1;let a;return ag(t)?a={...t}:a={...t,id:s(t)},y1(a,r)?r:(a.sourceHandle===null&&delete a.sourceHandle,a.targetHandle===null&&delete a.targetHandle,r.concat(a))};function Sg({sourceX:t,sourceY:r,targetX:o,targetY:s}){const[a,u,c,f]=_g({sourceX:t,sourceY:r,targetX:o,targetY:s});return[`M ${t},${r}L ${o},${s}`,a,u,c,f]}const Ch={[Se.Left]:{x:-1,y:0},[Se.Right]:{x:1,y:0},[Se.Top]:{x:0,y:-1},[Se.Bottom]:{x:0,y:1}},x1=({source:t,sourcePosition:r=Se.Bottom,target:o})=>r===Se.Left||r===Se.Right?t.xMath.sqrt(Math.pow(r.x-t.x,2)+Math.pow(r.y-t.y,2));function w1({source:t,sourcePosition:r=Se.Bottom,target:o,targetPosition:s=Se.Top,center:a,offset:u,stepPosition:c}){const f=Ch[r],g=Ch[s],y={x:t.x+f.x*u,y:t.y+f.y*u},v={x:o.x+g.x*u,y:o.y+g.y*u},x=x1({source:y,sourcePosition:r,target:v}),m=x.x!==0?"x":"y",S=x[m];let _=[],E,b;const w={x:0,y:0},P={x:0,y:0},[,,N,j]=_g({sourceX:t.x,sourceY:t.y,targetX:o.x,targetY:o.y});if(f[m]*g[m]===-1){m==="x"?(E=a.x??y.x+(v.x-y.x)*c,b=a.y??(y.y+v.y)/2):(E=a.x??(y.x+v.x)/2,b=a.y??y.y+(v.y-y.y)*c);const D=[{x:E,y:y.y},{x:E,y:v.y}],G=[{x:y.x,y:b},{x:v.x,y:b}];f[m]===S?_=m==="x"?D:G:_=m==="x"?G:D}else{const D=[{x:y.x,y:v.y}],G=[{x:v.x,y:y.y}];if(m==="x"?_=f.x===S?G:D:_=f.y===S?D:G,r===s){const C=Math.abs(t[m]-o[m]);if(C<=u){const R=Math.min(u-1,u-C);f[m]===S?w[m]=(y[m]>t[m]?-1:1)*R:P[m]=(v[m]>o[m]?-1:1)*R}}if(r!==s){const C=m==="x"?"y":"x",R=f[m]===g[C],B=y[C]>v[C],Y=y[C]=te?(E=(J.x+K.x)/2,b=_[0].y):(E=_[0].x,b=(J.y+K.y)/2)}const L={x:y.x+w.x,y:y.y+w.y},z={x:v.x+P.x,y:v.y+P.y};return[[t,...L.x!==_[0].x||L.y!==_[0].y?[L]:[],..._,...z.x!==_[_.length-1].x||z.y!==_[_.length-1].y?[z]:[],o],E,b,N,j]}function _1(t,r,o,s){const a=Math.min(Mh(t,r)/2,Mh(r,o)/2,s),{x:u,y:c}=r;if(t.x===u&&u===o.x||t.y===c&&c===o.y)return`L${u} ${c}`;if(t.y===c){const y=t.xo.id===r):t[0])||null}function nc(t,r){return t?typeof t=="string"?t:`${r?`${r}__`:""}${Object.keys(t).sort().map(s=>`${s}=${t[s]}`).join("&")}`:""}function k1(t,{id:r,defaultColor:o,defaultMarkerStart:s,defaultMarkerEnd:a}){const u=new Set;return t.reduce((c,f)=>([f.markerStart||s,f.markerEnd||a].forEach(g=>{if(g&&typeof g=="object"){const y=nc(g,r);u.has(y)||(c.push({id:y,color:g.color||o,...g}),u.add(y))}}),c),[]).sort((c,f)=>c.id.localeCompare(f.id))}const kg=1e3,N1=10,xc={nodeOrigin:[0,0],nodeExtent:Ao,elevateNodesOnSelect:!0,zIndexMode:"basic",defaults:{}},E1={...xc,checkEquality:!0};function wc(t,r){const o={...t};for(const s in r)r[s]!==void 0&&(o[s]=r[s]);return o}function j1(t,r,o){const s=wc(xc,o);for(const a of t.values())if(a.parentId)Sc(a,t,r,s);else{const u=Uo(a,s.nodeOrigin),c=Ur(a.extent)?a.extent:s.nodeExtent,f=Wr(u,c,ln(a));a.internals.positionAbsolute=f}}function b1(t,r){if(!t.handles)return t.measured?r==null?void 0:r.internals.handleBounds:void 0;const o=[],s=[];for(const a of t.handles){const u={id:a.id,width:a.width??1,height:a.height??1,nodeId:t.id,x:a.x,y:a.y,position:a.position,type:a.type};a.type==="source"?o.push(u):a.type==="target"&&s.push(u)}return{source:o,target:s}}function _c(t){return t==="manual"}function rc(t,r,o,s={}){var v,x;const a=wc(E1,s),u={i:0},c=new Map(r),f=a!=null&&a.elevateNodesOnSelect&&!_c(a.zIndexMode)?kg:0;let g=t.length>0,y=!1;r.clear(),o.clear();for(const m of t){let S=c.get(m.id);if(a.checkEquality&&m===(S==null?void 0:S.internals.userNode))r.set(m.id,S);else{const _=Uo(m,a.nodeOrigin),E=Ur(m.extent)?m.extent:a.nodeExtent,b=Wr(_,E,ln(m));S={...a.defaults,...m,measured:{width:(v=m.measured)==null?void 0:v.width,height:(x=m.measured)==null?void 0:x.height},internals:{positionAbsolute:b,handleBounds:b1(m,S),z:Ng(m,f,a.zIndexMode),userNode:m}},r.set(m.id,S)}(S.measured===void 0||S.measured.width===void 0||S.measured.height===void 0)&&!S.hidden&&(g=!1),m.parentId&&Sc(S,r,o,s,u),y||(y=m.selected??!1)}return{nodesInitialized:g,hasSelectedNodes:y}}function C1(t,r){if(!t.parentId)return;const o=r.get(t.parentId);o?o.set(t.id,t):r.set(t.parentId,new Map([[t.id,t]]))}function Sc(t,r,o,s,a){const{elevateNodesOnSelect:u,nodeOrigin:c,nodeExtent:f,zIndexMode:g}=wc(xc,s),y=t.parentId,v=r.get(y);if(!v){console.warn(`Parent node ${y} not found. Please make sure that parent nodes are in front of their child nodes in the nodes array.`);return}C1(t,o),a&&!v.parentId&&v.internals.rootParentIndex===void 0&&g==="auto"&&(v.internals.rootParentIndex=++a.i,v.internals.z=v.internals.z+a.i*N1),a&&v.internals.rootParentIndex!==void 0&&(a.i=v.internals.rootParentIndex);const x=u&&!_c(g)?kg:0,{x:m,y:S,z:_}=M1(t,v,c,f,x,g),{positionAbsolute:E}=t.internals,b=m!==E.x||S!==E.y;(b||_!==t.internals.z)&&r.set(t.id,{...t,internals:{...t.internals,positionAbsolute:b?{x:m,y:S}:E,z:_}})}function Ng(t,r,o){const s=nn(t.zIndex)?t.zIndex:0;return _c(o)?s:s+(t.selected?r:0)}function M1(t,r,o,s,a,u){const{x:c,y:f}=r.internals.positionAbsolute,g=ln(t),y=Uo(t,o),v=Ur(t.extent)?Wr(y,t.extent,g):y;let x=Wr({x:c+v.x,y:f+v.y},s,g);t.extent==="parent"&&(x=cg(x,g,r));const m=Ng(t,a,u),S=r.internals.z??0;return{x:x.x,y:x.y,z:S>=m?S+1:m}}function kc(t,r,o,s=[0,0]){var c;const a=[],u=new Map;for(const f of t){const g=r.get(f.parentId);if(!g)continue;const y=((c=u.get(f.parentId))==null?void 0:c.expandedRect)??$o(g),v=dg(y,f.rect);u.set(f.parentId,{expandedRect:v,parent:g})}return u.size>0&&u.forEach(({expandedRect:f,parent:g},y)=>{var N;const v=g.internals.positionAbsolute,x=ln(g),m=g.origin??s,S=f.x0||_>0||w||P)&&(a.push({id:y,type:"position",position:{x:g.position.x-S+w,y:g.position.y-_+P}}),(N=o.get(y))==null||N.forEach(j=>{t.some(L=>L.id===j.id)||a.push({id:j.id,type:"position",position:{x:j.position.x+S,y:j.position.y+_}})})),(x.width0){const S=kc(m,r,o,a);y.push(...S)}return{changes:y,updatedInternals:g}}async function I1({delta:t,panZoom:r,transform:o,translateExtent:s,width:a,height:u}){if(!r||!t.x&&!t.y)return!1;const c=await r.setViewportConstrained({x:o[0]+t.x,y:o[1]+t.y,zoom:o[2]},[[0,0],[a,u]],s);return!!c&&(c.x!==o[0]||c.y!==o[1]||c.k!==o[2])}function Rh(t,r,o,s,a,u){let c=a;const f=s.get(c)||new Map;s.set(c,f.set(o,r)),c=`${a}-${t}`;const g=s.get(c)||new Map;if(s.set(c,g.set(o,r)),u){c=`${a}-${t}-${u}`;const y=s.get(c)||new Map;s.set(c,y.set(o,r))}}function Eg(t,r,o){t.clear(),r.clear();for(const s of o){const{source:a,target:u,sourceHandle:c=null,targetHandle:f=null}=s,g={edgeId:s.id,source:a,target:u,sourceHandle:c,targetHandle:f},y=`${a}-${c}--${u}-${f}`,v=`${u}-${f}--${a}-${c}`;Rh("source",g,v,t,a,c),Rh("target",g,y,t,u,f),r.set(s.id,s)}}function jg(t,r){if(!t.parentId)return!1;const o=r.get(t.parentId);return o?o.selected?!0:jg(o,r):!1}function Lh(t,r,o){var a;let s=t;do{if((a=s==null?void 0:s.matches)!=null&&a.call(s,r))return!0;if(s===o)return!1;s=s==null?void 0:s.parentElement}while(s);return!1}function T1(t,r,o,s){const a=new Map;for(const[u,c]of t)if((c.selected||c.id===s)&&(!c.parentId||!jg(c,t))&&(c.draggable||r&&typeof c.draggable>"u")){const f=t.get(u);f&&a.set(u,{id:u,position:f.position||{x:0,y:0},distance:{x:o.x-f.internals.positionAbsolute.x,y:o.y-f.internals.positionAbsolute.y},extent:f.extent,parentId:f.parentId,origin:f.origin,expandParent:f.expandParent,internals:{positionAbsolute:f.internals.positionAbsolute||{x:0,y:0}},measured:{width:f.measured.width??0,height:f.measured.height??0}})}return a}function Au({nodeId:t,dragItems:r,nodeLookup:o,dragging:s=!0}){var c,f,g;const a=[];for(const[y,v]of r){const x=(c=o.get(y))==null?void 0:c.internals.userNode;x&&a.push({...x,position:v.position,dragging:s})}if(!t)return[a[0],a];const u=(f=o.get(t))==null?void 0:f.internals.userNode;return[u?{...u,position:((g=r.get(t))==null?void 0:g.position)||u.position,dragging:s}:a[0],a]}function R1({dragItems:t,snapGrid:r,x:o,y:s}){const a=t.values().next().value;if(!a)return null;const u={x:o-a.distance.x,y:s-a.distance.y},c=Go(u,r);return{x:c.x-u.x,y:c.y-u.y}}function L1({onNodeMouseDown:t,getStoreItems:r,onDragStart:o,onDrag:s,onDragStop:a}){let u={x:null,y:null},c=0,f=new Map,g=!1,y={x:0,y:0},v=null,x=!1,m=null,S=!1,_=!1,E=null;function b({noDragClassName:P,handleSelector:N,domNode:j,isSelectable:L,nodeId:z,nodeClickDistance:W=0}){m=Ot(j);function D({x:ne,y:te}){const{nodeLookup:C,nodeExtent:R,snapGrid:B,snapToGrid:Y,nodeOrigin:T,onNodeDrag:H,onSelectionDrag:U,onError:M,updateNodePositions:A}=r();u={x:ne,y:te};let re=!1;const ie=f.size>1,ce=ie&&R?ec(Yo(f)):null,fe=ie&&Y?R1({dragItems:f,snapGrid:B,x:ne,y:te}):null;for(const[de,Q]of f){if(!C.has(de))continue;let le={x:ne-Q.distance.x,y:te-Q.distance.y};Y&&(le=fe?{x:Math.round(le.x+fe.x),y:Math.round(le.y+fe.y)}:Go(le,B));let me=null;if(ie&&R&&!Q.extent&&ce){const{positionAbsolute:pe}=Q.internals,be=pe.x-ce.x+R[0][0],Pe=pe.x+Q.measured.width-ce.x2+R[1][0],Ce=pe.y-ce.y+R[0][1],Re=pe.y+Q.measured.height-ce.y2+R[1][1];me=[[be,Ce],[Pe,Re]]}const{position:ke,positionAbsolute:xe}=ug({nodeId:de,nextPosition:le,nodeLookup:C,nodeExtent:me||R,nodeOrigin:T,onError:M});re=re||Q.position.x!==ke.x||Q.position.y!==ke.y,Q.position=ke,Q.internals.positionAbsolute=xe}if(_=_||re,!!re&&(A(f,!0),E&&(s||H||!z&&U))){const[de,Q]=Au({nodeId:z,dragItems:f,nodeLookup:C});s==null||s(E,f,de,Q),H==null||H(E,de,Q),z||U==null||U(E,Q)}}async function G(){if(!v)return;const{transform:ne,panBy:te,autoPanSpeed:C,autoPanOnNodeDrag:R}=r();if(!R){g=!1,cancelAnimationFrame(c);return}const[B,Y]=mc(y,v,C);(B!==0||Y!==0)&&(u.x=(u.x??0)-B/ne[2],u.y=(u.y??0)-Y/ne[2],await te({x:B,y:Y})&&D(u)),c=requestAnimationFrame(G)}function J(ne){var ie;const{nodeLookup:te,multiSelectionActive:C,nodesDraggable:R,transform:B,snapGrid:Y,snapToGrid:T,selectNodesOnDrag:H,onNodeDragStart:U,onSelectionDragStart:M,unselectNodesAndEdges:A}=r();x=!0,(!H||!L)&&!C&&z&&((ie=te.get(z))!=null&&ie.selected||A()),L&&H&&z&&(t==null||t(z));const re=Co(ne.sourceEvent,{transform:B,snapGrid:Y,snapToGrid:T,containerBounds:v});if(u=re,f=T1(te,R,re,z),f.size>0&&(o||U||!z&&M)){const[ce,fe]=Au({nodeId:z,dragItems:f,nodeLookup:te});o==null||o(ne.sourceEvent,f,ce,fe),U==null||U(ne.sourceEvent,ce,fe),z||M==null||M(ne.sourceEvent,fe)}}const K=Bp().clickDistance(W).on("start",ne=>{const{domNode:te,nodeDragThreshold:C,transform:R,snapGrid:B,snapToGrid:Y}=r();v=(te==null?void 0:te.getBoundingClientRect())||null,S=!1,_=!1,E=ne.sourceEvent,C===0&&J(ne),u=Co(ne.sourceEvent,{transform:R,snapGrid:B,snapToGrid:Y,containerBounds:v}),y=rn(ne.sourceEvent,v)}).on("drag",ne=>{const{autoPanOnNodeDrag:te,transform:C,snapGrid:R,snapToGrid:B,nodeDragThreshold:Y,nodeLookup:T}=r(),H=Co(ne.sourceEvent,{transform:C,snapGrid:R,snapToGrid:B,containerBounds:v});if(E=ne.sourceEvent,(ne.sourceEvent.type==="touchmove"&&ne.sourceEvent.touches.length>1||z&&!T.has(z))&&(S=!0),!S){if(!g&&te&&x&&(g=!0,G()),!x){const U=rn(ne.sourceEvent,v),M=U.x-y.x,A=U.y-y.y;Math.sqrt(M*M+A*A)>Y&&J(ne)}(u.x!==H.xSnapped||u.y!==H.ySnapped)&&f&&x&&(y=rn(ne.sourceEvent,v),D(H))}}).on("end",ne=>{if(!x||S){S&&f.size>0&&r().updateNodePositions(f,!1);return}if(g=!1,x=!1,cancelAnimationFrame(c),f.size>0){const{nodeLookup:te,updateNodePositions:C,onNodeDragStop:R,onSelectionDragStop:B}=r();if(_&&(C(f,!1),_=!1),a||R||!z&&B){const[Y,T]=Au({nodeId:z,dragItems:f,nodeLookup:te,dragging:!1});a==null||a(ne.sourceEvent,f,Y,T),R==null||R(ne.sourceEvent,Y,T),z||B==null||B(ne.sourceEvent,T)}}}).filter(ne=>{const te=ne.target;return!ne.button&&(!P||!Lh(te,`.${P}`,j))&&(!N||Lh(te,N,j))});m.call(K)}function w(){m==null||m.on(".drag",null)}return{update:b,destroy:w}}function A1(t,r,o){const s=[],a={x:t.x-o,y:t.y-o,width:o*2,height:o*2};for(const u of r.values())Nl(a,$o(u))>0&&s.push(u);return s}const z1=250;function D1(t,r,o,s){var f,g;let a=[],u=1/0;const c=A1(t,o,r+z1);for(const y of c){const v=[...((f=y.internals.handleBounds)==null?void 0:f.source)??[],...((g=y.internals.handleBounds)==null?void 0:g.target)??[]];for(const x of v){if(s.nodeId===x.nodeId&&s.type===x.type&&s.id===x.id)continue;const{x:m,y:S}=Yr(y,x,x.position,!0),_=Math.sqrt(Math.pow(m-t.x,2)+Math.pow(S-t.y,2));_>r||(_1){const y=s.type==="source"?"target":"source";return a.find(v=>v.type===y)??a[0]}return a[0]}function bg(t,r,o,s,a,u=!1){var y,v,x;const c=s.get(t);if(!c)return null;const f=a==="strict"?(y=c.internals.handleBounds)==null?void 0:y[r]:[...((v=c.internals.handleBounds)==null?void 0:v.source)??[],...((x=c.internals.handleBounds)==null?void 0:x.target)??[]],g=(o?f==null?void 0:f.find(m=>m.id===o):f==null?void 0:f[0])??null;return g&&u?{...g,...Yr(c,g,g.position,!0)}:g}function Cg(t,r){return t||(r!=null&&r.classList.contains("target")?"target":r!=null&&r.classList.contains("source")?"source":null)}function $1(t,r){let o=null;return r?o=!0:t&&!r&&(o=!1),o}const Mg=()=>!0;function O1(t,{connectionMode:r,connectionRadius:o,handleId:s,nodeId:a,edgeUpdaterType:u,isTarget:c,domNode:f,nodeLookup:g,lib:y,autoPanOnConnect:v,flowId:x,panBy:m,cancelConnection:S,onConnectStart:_,onConnect:E,onConnectEnd:b,isValidConnection:w=Mg,onReconnectEnd:P,updateConnection:N,getTransform:j,getFromHandle:L,autoPanSpeed:z,dragThreshold:W=1,handleDomNode:D}){const G=mg(t.target);let J=0,K;const{x:ne,y:te}=rn(t),C=Cg(u,D),R=f==null?void 0:f.getBoundingClientRect();let B=!1;if(!R||!C)return;const Y=bg(a,C,s,g,r);if(!Y)return;let T=rn(t,R),H=!1,U=null,M=!1,A=null;function re(){if(!v||!R)return;const[ke,xe]=mc(T,R,z);m({x:ke,y:xe}),J=requestAnimationFrame(re)}const ie={...Y,nodeId:a,type:C,position:Y.position},ce=g.get(a);let de={inProgress:!0,isValid:null,from:Yr(ce,ie,Se.Left,!0),fromHandle:ie,fromPosition:ie.position,fromNode:ce,to:T,toHandle:null,toPosition:Sh[ie.position],toNode:null,pointer:T};function Q(){B=!0,N(de),_==null||_(t,{nodeId:a,handleId:s,handleType:C})}W===0&&Q();function le(ke){if(!B){const{x:Re,y:tt}=rn(ke),nt=Re-ne,Je=tt-te;if(!(nt*nt+Je*Je>W*W))return;Q()}if(!L()||!ie){me(ke);return}const xe=j();T=rn(ke,R),K=D1(Xo(T,xe,!1,[1,1]),o,g,ie),H||(re(),H=!0);const pe=Pg(ke,{handle:K,connectionMode:r,fromNodeId:a,fromHandleId:s,fromType:c?"target":"source",isValidConnection:w,doc:G,lib:y,flowId:x,nodeLookup:g});A=pe.handleDomNode,U=pe.connection,M=$1(!!K,pe.isValid);const be=g.get(a),Pe=be?Yr(be,ie,Se.Left,!0):de.from,Ce={...de,from:Pe,isValid:M,to:pe.toHandle&&M?$i({x:pe.toHandle.x,y:pe.toHandle.y},xe):T,toHandle:pe.toHandle,toPosition:M&&pe.toHandle?pe.toHandle.position:Sh[ie.position],toNode:pe.toHandle?g.get(pe.toHandle.nodeId):null,pointer:T};N(Ce),de=Ce}function me(ke){if(!("touches"in ke&&ke.touches.length>0)){if(B){(K||A)&&U&&M&&(E==null||E(U));const{inProgress:xe,...pe}=de,be={...pe,toPosition:de.toHandle?de.toPosition:null};b==null||b(ke,be),u&&(P==null||P(ke,be))}S(),cancelAnimationFrame(J),H=!1,M=!1,U=null,A=null,G.removeEventListener("mousemove",le),G.removeEventListener("mouseup",me),G.removeEventListener("touchmove",le),G.removeEventListener("touchend",me)}}G.addEventListener("mousemove",le),G.addEventListener("mouseup",me),G.addEventListener("touchmove",le),G.addEventListener("touchend",me)}function Pg(t,{handle:r,connectionMode:o,fromNodeId:s,fromHandleId:a,fromType:u,doc:c,lib:f,flowId:g,isValidConnection:y=Mg,nodeLookup:v}){const x=u==="target",m=r?c.querySelector(`.${f}-flow__handle[data-id="${g}-${r==null?void 0:r.nodeId}-${r==null?void 0:r.id}-${r==null?void 0:r.type}"]`):null,{x:S,y:_}=rn(t),E=c.elementFromPoint(S,_),b=E!=null&&E.classList.contains(`${f}-flow__handle`)?E:m,w={handleDomNode:b,isValid:!1,connection:null,toHandle:null};if(b){const P=Cg(void 0,b),N=b.getAttribute("data-nodeid"),j=b.getAttribute("data-handleid"),L=b.classList.contains("connectable"),z=b.classList.contains("connectableend");if(!N||!P)return w;const W={source:x?N:s,sourceHandle:x?j:a,target:x?s:N,targetHandle:x?a:j};w.connection=W;const G=L&&z&&(o===zi.Strict?x&&P==="source"||!x&&P==="target":N!==s||j!==a);w.isValid=G&&y(W),w.toHandle=bg(N,P,j,v,o,!0)}return w}const ic={onPointerDown:O1,isValid:Pg};function F1({domNode:t,panZoom:r,getTransform:o,getViewScale:s}){const a=Ot(t);function u({translateExtent:f,width:g,height:y,zoomStep:v=1,pannable:x=!0,zoomable:m=!0,inversePan:S=!1}){const _=N=>{if(N.sourceEvent.type!=="wheel"||!r)return;const j=o(),L=N.sourceEvent.ctrlKey&&Oo()?10:1,z=-N.sourceEvent.deltaY*(N.sourceEvent.deltaMode===1?.05:N.sourceEvent.deltaMode?1:.002)*v,W=j[2]*Math.pow(2,z*L);r.scaleTo(W)};let E=[0,0];const b=N=>{(N.sourceEvent.type==="mousedown"||N.sourceEvent.type==="touchstart")&&(E=[N.sourceEvent.clientX??N.sourceEvent.touches[0].clientX,N.sourceEvent.clientY??N.sourceEvent.touches[0].clientY])},w=N=>{const j=o();if(N.sourceEvent.type!=="mousemove"&&N.sourceEvent.type!=="touchmove"||!r)return;const L=[N.sourceEvent.clientX??N.sourceEvent.touches[0].clientX,N.sourceEvent.clientY??N.sourceEvent.touches[0].clientY],z=[L[0]-E[0],L[1]-E[1]];E=L;const W=s()*Math.max(j[2],Math.log(j[2]))*(S?-1:1),D={x:j[0]-z[0]*W,y:j[1]-z[1]*W},G=[[0,0],[g,y]];r.setViewportConstrained({x:D.x,y:D.y,zoom:j[2]},G,f)},P=rg().on("start",b).on("zoom",x?w:null).on("zoom.wheel",m?_:null);a.call(P,{})}function c(){a.on("zoom",null)}return{update:u,destroy:c,pointer:en}}const Al=t=>({x:t.x,y:t.y,zoom:t.k}),zu=({x:t,y:r,zoom:o})=>Tl.translate(t,r).scale(o),fr=(t,r)=>t.target.closest(`.${r}`),Ig=(t,r)=>r===2&&Array.isArray(t)&&t.includes(2),H1=t=>((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2,Du=(t,r=0,o=H1,s=()=>{})=>{const a=typeof r=="number"&&r>0;return a||s(),a?t.transition().duration(r).ease(o).on("end",s):t},Tg=t=>{const r=t.ctrlKey&&Oo()?10:1;return-t.deltaY*(t.deltaMode===1?.05:t.deltaMode?1:.002)*r};function B1({zoomPanValues:t,noWheelClassName:r,d3Selection:o,d3Zoom:s,panOnScrollMode:a,panOnScrollSpeed:u,zoomOnPinch:c,onPanZoomStart:f,onPanZoom:g,onPanZoomEnd:y}){return v=>{if(fr(v,r))return v.ctrlKey&&v.preventDefault(),!1;v.preventDefault(),v.stopImmediatePropagation();const x=o.property("__zoom").k||1;if(v.ctrlKey&&c){const b=en(v),w=Tg(v),P=x*Math.pow(2,w);s.scaleTo(o,P,b,v);return}const m=v.deltaMode===1?20:1;let S=a===Hr.Vertical?0:v.deltaX*m,_=a===Hr.Horizontal?0:v.deltaY*m;!Oo()&&v.shiftKey&&a!==Hr.Vertical&&(S=v.deltaY*m,_=0),s.translateBy(o,-(S/x)*u,-(_/x)*u,{internal:!0});const E=Al(o.property("__zoom"));clearTimeout(t.panScrollTimeout),t.isPanScrolling?g==null||g(v,E):(t.isPanScrolling=!0,f==null||f(v,E)),t.panScrollTimeout=setTimeout(()=>{y==null||y(v,E),t.isPanScrolling=!1},150)}}function V1({noWheelClassName:t,preventScrolling:r,d3ZoomHandler:o}){return function(s,a){const u=s.type==="wheel",c=!r&&u&&!s.ctrlKey,f=fr(s,t);if(s.ctrlKey&&u&&f&&s.preventDefault(),c||f)return null;s.preventDefault(),o.call(this,s,a)}}function W1({zoomPanValues:t,onDraggingChange:r,onPanZoomStart:o}){return s=>{var u,c,f;if((u=s.sourceEvent)!=null&&u.internal)return;const a=Al(s.transform);t.mouseButton=((c=s.sourceEvent)==null?void 0:c.button)||0,t.isZoomingOrPanning=!0,t.prevViewport=a,((f=s.sourceEvent)==null?void 0:f.type)==="mousedown"&&r(!0),o&&(o==null||o(s.sourceEvent,a))}}function U1({zoomPanValues:t,panOnDrag:r,onPaneContextMenu:o,onTransformChange:s,onPanZoom:a}){return u=>{var c,f;t.usedRightMouseButton=!!(o&&Ig(r,t.mouseButton??0)),(c=u.sourceEvent)!=null&&c.sync||s([u.transform.x,u.transform.y,u.transform.k]),a&&!((f=u.sourceEvent)!=null&&f.internal)&&(a==null||a(u.sourceEvent,Al(u.transform)))}}function Y1({zoomPanValues:t,panOnDrag:r,panOnScroll:o,onDraggingChange:s,onPanZoomEnd:a,onPaneContextMenu:u}){return c=>{var f;if(!((f=c.sourceEvent)!=null&&f.internal)&&(t.isZoomingOrPanning=!1,u&&Ig(r,t.mouseButton??0)&&!t.usedRightMouseButton&&c.sourceEvent&&u(c.sourceEvent),t.usedRightMouseButton=!1,s(!1),a)){const g=Al(c.transform);t.prevViewport=g,clearTimeout(t.timerId),t.timerId=setTimeout(()=>{a==null||a(c.sourceEvent,g)},o?150:0)}}}function G1({panActivationKeyPressed:t,zoomActivationKeyPressed:r,zoomOnScroll:o,zoomOnPinch:s,panOnDrag:a,panOnScroll:u,zoomOnDoubleClick:c,userSelectionActive:f,noWheelClassName:g,noPanClassName:y,lib:v,connectionInProgress:x}){return m=>{var w;const S=r||o,_=s&&m.ctrlKey,E=m.type==="wheel";if(m.button===1&&m.type==="mousedown"&&(fr(m,`${v}-flow__node`)||fr(m,`${v}-flow__edge`)||fr(m,`${v}-flow__selection`)||fr(m,`${v}-flow__nodesselection`)))return!0;if(!a&&!S&&!u&&!c&&!s||f||x&&!E||fr(m,g)&&E||fr(m,y)&&(!E||u&&E&&!r)||!s&&m.ctrlKey&&E)return!1;if(!s&&m.type==="touchstart"&&((w=m.touches)==null?void 0:w.length)>1)return m.preventDefault(),!1;if(!S&&!u&&!_&&E||!a&&(m.type==="mousedown"||m.type==="touchstart")||Array.isArray(a)&&!a.includes(m.button)&&m.type==="mousedown")return!1;const b=Array.isArray(a)&&a.includes(m.button)||!m.button||m.button<=1;return(!m.ctrlKey||E||t)&&b}}function X1({domNode:t,minZoom:r,maxZoom:o,translateExtent:s,viewport:a,onPanZoom:u,onPanZoomStart:c,onPanZoomEnd:f,onDraggingChange:g}){const y={isZoomingOrPanning:!1,usedRightMouseButton:!1,prevViewport:{},mouseButton:0,timerId:void 0,panScrollTimeout:void 0,isPanScrolling:!1},v=t.getBoundingClientRect();let x=[[0,0],[v.width,v.height]];const m=typeof ResizeObserver<"u"?new ResizeObserver(te=>{const C=te[0];C&&(x=[[0,0],[C.contentRect.width,C.contentRect.height]])}):null;m==null||m.observe(t);const S=rg().extent(()=>x).scaleExtent([r,o]).translateExtent(s),_=Ot(t).call(S);j({x:a.x,y:a.y,zoom:Di(a.zoom,r,o)},[[0,0],[v.width,v.height]],s);const E=_.on("wheel.zoom"),b=_.on("dblclick.zoom");S.wheelDelta(Tg);async function w(te,C){return _?new Promise(R=>{S==null||S.interpolate((C==null?void 0:C.interpolate)==="linear"?bo:fl).transform(Du(_,C==null?void 0:C.duration,C==null?void 0:C.ease,()=>R(!0)),te)}):!1}function P({noWheelClassName:te,noPanClassName:C,onPaneContextMenu:R,userSelectionActive:B,panOnScroll:Y,panOnDrag:T,panOnScrollMode:H,panOnScrollSpeed:U,preventScrolling:M,zoomOnPinch:A,zoomOnScroll:re,zoomOnDoubleClick:ie,panActivationKeyPressed:ce=!1,zoomActivationKeyPressed:fe,lib:de,onTransformChange:Q,connectionInProgress:le,paneClickDistance:me,selectionOnDrag:ke}){B&&!y.isZoomingOrPanning&&N();const xe=Y&&!fe&&!B;S.clickDistance(ke?1/0:!nn(me)||me<0?0:me);const pe=xe?B1({zoomPanValues:y,noWheelClassName:te,d3Selection:_,d3Zoom:S,panOnScrollMode:H,panOnScrollSpeed:U,zoomOnPinch:A,onPanZoomStart:c,onPanZoom:u,onPanZoomEnd:f}):V1({noWheelClassName:te,preventScrolling:M,d3ZoomHandler:E});_.on("wheel.zoom",pe,{passive:!1});const be=W1({zoomPanValues:y,onDraggingChange:g,onPanZoomStart:c});S.on("start",be);const Pe=U1({zoomPanValues:y,panOnDrag:T,onPaneContextMenu:!!R,onPanZoom:u,onTransformChange:Q});S.on("zoom",Pe);const Ce=Y1({zoomPanValues:y,panOnDrag:T,panOnScroll:Y,onPaneContextMenu:R,onPanZoomEnd:f,onDraggingChange:g});S.on("end",Ce);const Re=G1({panActivationKeyPressed:ce,zoomActivationKeyPressed:fe,panOnDrag:T,zoomOnScroll:re,panOnScroll:Y,zoomOnDoubleClick:ie,zoomOnPinch:A,userSelectionActive:B,noPanClassName:C,noWheelClassName:te,lib:de,connectionInProgress:le});S.filter(Re),ie?_.on("dblclick.zoom",b):_.on("dblclick.zoom",null)}function N(){S.on("zoom",null)}async function j(te,C,R){const B=zu(te),Y=S==null?void 0:S.constrain()(B,C,R);return Y&&await w(Y),Y}async function L(te,C){const R=zu(te);return await w(R,C),R}function z(te){if(_){const C=zu(te),R=_.property("__zoom");(R.k!==te.zoom||R.x!==te.x||R.y!==te.y)&&(S==null||S.transform(_,C,null,{sync:!0}))}}function W(){const te=_?ng(_.node()):{x:0,y:0,k:1};return{x:te.x,y:te.y,zoom:te.k}}async function D(te,C){return _?new Promise(R=>{S==null||S.interpolate((C==null?void 0:C.interpolate)==="linear"?bo:fl).scaleTo(Du(_,C==null?void 0:C.duration,C==null?void 0:C.ease,()=>R(!0)),te)}):!1}async function G(te,C){return _?new Promise(R=>{S==null||S.interpolate((C==null?void 0:C.interpolate)==="linear"?bo:fl).scaleBy(Du(_,C==null?void 0:C.duration,C==null?void 0:C.ease,()=>R(!0)),te)}):!1}function J(te){S==null||S.scaleExtent(te)}function K(te){S==null||S.translateExtent(te)}function ne(te){const C=!nn(te)||te<0?0:te;S==null||S.clickDistance(C)}return{update:P,destroy:N,setViewport:L,setViewportConstrained:j,getViewport:W,scaleTo:D,scaleBy:G,setScaleExtent:J,setTranslateExtent:K,syncViewport:z,setClickDistance:ne}}var Oi;(function(t){t.Line="line",t.Handle="handle"})(Oi||(Oi={}));function q1({width:t,prevWidth:r,height:o,prevHeight:s,affectsX:a,affectsY:u}){const c=t-r,f=o-s,g=[c>0?1:c<0?-1:0,f>0?1:f<0?-1:0];return c&&a&&(g[0]=g[0]*-1),f&&u&&(g[1]=g[1]*-1),g}function Ah(t){const r=t.includes("right")||t.includes("left"),o=t.includes("bottom")||t.includes("top"),s=t.includes("left"),a=t.includes("top");return{isHorizontal:r,isVertical:o,affectsX:s,affectsY:a}}function cr(t,r){return Math.max(0,r-t)}function dr(t,r){return Math.max(0,t-r)}function sl(t,r,o){return Math.max(0,r-t,t-o)}function zh(t,r){return t?!r:r}function K1(t,r,o,s,a,u,c,f){let{affectsX:g,affectsY:y}=r;const{isHorizontal:v,isVertical:x}=r,m=v&&x,{xSnapped:S,ySnapped:_}=o,{minWidth:E,maxWidth:b,minHeight:w,maxHeight:P}=s,{x:N,y:j,width:L,height:z,aspectRatio:W}=t;let D=Math.floor(v?S-t.pointerX:0),G=Math.floor(x?_-t.pointerY:0);const J=L+(g?-D:D),K=z+(y?-G:G),ne=-u[0]*L,te=-u[1]*z;let C=sl(J,E,b),R=sl(K,w,P);if(c){let T=0,H=0;g&&D<0?T=cr(N+D+ne,c[0][0]):!g&&D>0&&(T=dr(N+J+ne,c[1][0])),y&&G<0?H=cr(j+G+te,c[0][1]):!y&&G>0&&(H=dr(j+K+te,c[1][1])),C=Math.max(C,T),R=Math.max(R,H)}if(f){let T=0,H=0;g&&D>0?T=dr(N+D,f[0][0]):!g&&D<0&&(T=cr(N+J,f[1][0])),y&&G>0?H=dr(j+G,f[0][1]):!y&&G<0&&(H=cr(j+K,f[1][1])),C=Math.max(C,T),R=Math.max(R,H)}if(a){if(v){const T=sl(J/W,w,P)*W;if(C=Math.max(C,T),c){let H=0;!g&&!y||g&&!y&&m?H=dr(j+te+J/W,c[1][1])*W:H=cr(j+te+(g?D:-D)/W,c[0][1])*W,C=Math.max(C,H)}if(f){let H=0;!g&&!y||g&&!y&&m?H=cr(j+J/W,f[1][1])*W:H=dr(j+(g?D:-D)/W,f[0][1])*W,C=Math.max(C,H)}}if(x){const T=sl(K*W,E,b)/W;if(R=Math.max(R,T),c){let H=0;!g&&!y||y&&!g&&m?H=dr(N+K*W+ne,c[1][0])/W:H=cr(N+(y?G:-G)*W+ne,c[0][0])/W,R=Math.max(R,H)}if(f){let H=0;!g&&!y||y&&!g&&m?H=cr(N+K*W,f[1][0])/W:H=dr(N+(y?G:-G)*W,f[0][0])/W,R=Math.max(R,H)}}}G=G+(G<0?R:-R),D=D+(D<0?C:-C),a&&(m?J>K*W?G=(zh(g,y)?-D:D)/W:D=(zh(g,y)?-G:G)*W:v?(G=D/W,y=g):(D=G*W,g=y));const B=g?N+D:N,Y=y?j+G:j;return{width:L+(g?-D:D),height:z+(y?-G:G),x:u[0]*D*(g?-1:1)+B,y:u[1]*G*(y?-1:1)+Y}}const Rg={width:0,height:0,x:0,y:0},Q1={...Rg,pointerX:0,pointerY:0,aspectRatio:1};function Z1(t,r,o){const s=r.position.x+t.position.x,a=r.position.y+t.position.y,u=t.measured.width??0,c=t.measured.height??0,f=o[0]*u,g=o[1]*c;return[[s-f,a-g],[s+u-f,a+c-g]]}function J1({domNode:t,nodeId:r,getStoreItems:o,onChange:s,onEnd:a}){const u=Ot(t);let c={controlDirection:Ah("bottom-right"),boundaries:{minWidth:0,minHeight:0,maxWidth:Number.MAX_VALUE,maxHeight:Number.MAX_VALUE},resizeDirection:void 0,keepAspectRatio:!1};function f({controlPosition:y,boundaries:v,keepAspectRatio:x,resizeDirection:m,onResizeStart:S,onResize:_,onResizeEnd:E,shouldResize:b}){let w={...Rg},P={...Q1};c={boundaries:v,resizeDirection:m,keepAspectRatio:x,controlDirection:Ah(y)};let N,j=null,L=[],z,W,D,G=!1;const J=Bp().on("start",K=>{const{nodeLookup:ne,transform:te,snapGrid:C,snapToGrid:R,nodeOrigin:B,paneDomNode:Y}=o();if(N=ne.get(r),!N)return;j=(Y==null?void 0:Y.getBoundingClientRect())??null;const{xSnapped:T,ySnapped:H}=Co(K.sourceEvent,{transform:te,snapGrid:C,snapToGrid:R,containerBounds:j});w={width:N.measured.width??0,height:N.measured.height??0,x:N.position.x??0,y:N.position.y??0},P={...w,pointerX:T,pointerY:H,aspectRatio:w.width/w.height},z=void 0,W=Ur(N.extent)?N.extent:void 0,N.parentId&&(N.extent==="parent"||N.expandParent)&&(z=ne.get(N.parentId)),z&&N.extent==="parent"&&(W=[[0,0],[z.measured.width,z.measured.height]]),L=[],D=void 0;for(const[U,M]of ne)if(M.parentId===r&&(L.push({id:U,position:{...M.position},extent:M.extent}),M.extent==="parent"||M.expandParent)){const A=Z1(M,N,M.origin??B);D?D=[[Math.min(A[0][0],D[0][0]),Math.min(A[0][1],D[0][1])],[Math.max(A[1][0],D[1][0]),Math.max(A[1][1],D[1][1])]]:D=A}S==null||S(K,{...w})}).on("drag",K=>{const{transform:ne,snapGrid:te,snapToGrid:C,nodeOrigin:R}=o(),B=Co(K.sourceEvent,{transform:ne,snapGrid:te,snapToGrid:C,containerBounds:j}),Y=[];if(!N)return;const{x:T,y:H,width:U,height:M}=w,A={},re=N.origin??R,{width:ie,height:ce,x:fe,y:de}=K1(P,c.controlDirection,B,c.boundaries,c.keepAspectRatio,re,W,D),Q=ie!==U,le=ce!==M,me=fe!==T&&Q,ke=de!==H&≤if(!me&&!ke&&!Q&&!le)return;if((me||ke||re[0]===1||re[1]===1)&&(A.x=me?fe:w.x,A.y=ke?de:w.y,w.x=A.x,w.y=A.y,L.length>0)){const Pe=fe-T,Ce=de-H;for(const Re of L)Re.position={x:Re.position.x-Pe+re[0]*(ie-U),y:Re.position.y-Ce+re[1]*(ce-M)},Y.push(Re)}if((Q||le)&&(A.width=Q&&(!c.resizeDirection||c.resizeDirection==="horizontal")?ie:w.width,A.height=le&&(!c.resizeDirection||c.resizeDirection==="vertical")?ce:w.height,w.width=A.width,w.height=A.height),z&&N.expandParent){const Pe=re[0]*(A.width??0);A.x&&A.x{G&&(E==null||E(K,{...w}),a==null||a({...w}),G=!1)});u.call(J)}function g(){u.on(".drag",null)}return{update:f,destroy:g}}var $u={exports:{}},Ou={},Fu={exports:{}},Hu={};/** + * @license React + * use-sync-external-store-shim.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Dh;function e_(){if(Dh)return Hu;Dh=1;var t=Bo();function r(x,m){return x===m&&(x!==0||1/x===1/m)||x!==x&&m!==m}var o=typeof Object.is=="function"?Object.is:r,s=t.useState,a=t.useEffect,u=t.useLayoutEffect,c=t.useDebugValue;function f(x,m){var S=m(),_=s({inst:{value:S,getSnapshot:m}}),E=_[0].inst,b=_[1];return u(function(){E.value=S,E.getSnapshot=m,g(E)&&b({inst:E})},[x,S,m]),a(function(){return g(E)&&b({inst:E}),x(function(){g(E)&&b({inst:E})})},[x]),c(S),S}function g(x){var m=x.getSnapshot;x=x.value;try{var S=m();return!o(x,S)}catch{return!0}}function y(x,m){return m()}var v=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?y:f;return Hu.useSyncExternalStore=t.useSyncExternalStore!==void 0?t.useSyncExternalStore:v,Hu}var $h;function t_(){return $h||($h=1,Fu.exports=e_()),Fu.exports}/** + * @license React + * use-sync-external-store-shim/with-selector.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Oh;function n_(){if(Oh)return Ou;Oh=1;var t=Bo(),r=t_();function o(y,v){return y===v&&(y!==0||1/y===1/v)||y!==y&&v!==v}var s=typeof Object.is=="function"?Object.is:o,a=r.useSyncExternalStore,u=t.useRef,c=t.useEffect,f=t.useMemo,g=t.useDebugValue;return Ou.useSyncExternalStoreWithSelector=function(y,v,x,m,S){var _=u(null);if(_.current===null){var E={hasValue:!1,value:null};_.current=E}else E=_.current;_=f(function(){function w(z){if(!P){if(P=!0,N=z,z=m(z),S!==void 0&&E.hasValue){var W=E.value;if(S(W,z))return j=W}return j=z}if(W=j,s(N,z))return W;var D=m(z);return S!==void 0&&S(W,D)?(N=z,W):(N=z,j=D)}var P=!1,N,j,L=x===void 0?null:x;return[function(){return w(v())},L===null?void 0:function(){return w(L())}]},[v,x,m,S]);var b=a(y,_[0],_[1]);return c(function(){E.hasValue=!0,E.value=b},[b]),g(b),b},Ou}var Fh;function r_(){return Fh||(Fh=1,$u.exports=n_()),$u.exports}var i_=r_();const o_=Np(i_),s_={},Hh=t=>{let r;const o=new Set,s=(v,x)=>{const m=typeof v=="function"?v(r):v;if(!Object.is(m,r)){const S=r;r=x??(typeof m!="object"||m===null)?m:Object.assign({},r,m),o.forEach(_=>_(r,S))}},a=()=>r,g={setState:s,getState:a,getInitialState:()=>y,subscribe:v=>(o.add(v),()=>o.delete(v)),destroy:()=>{(s_?"production":void 0)!=="production"&&console.warn("[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."),o.clear()}},y=r=t(s,a,g);return g},l_=t=>t?Hh(t):Hh,{useDebugValue:a_}=o0,{useSyncExternalStoreWithSelector:u_}=o_,c_=t=>t;function Lg(t,r=c_,o){const s=u_(t.subscribe,t.getState,t.getServerState||t.getInitialState,r,o);return a_(s),s}const Bh=(t,r)=>{const o=l_(t),s=(a,u=r)=>Lg(o,a,u);return Object.assign(s,o),s},d_=(t,r)=>t?Bh(t,r):Bh;function Ke(t,r){if(Object.is(t,r))return!0;if(typeof t!="object"||t===null||typeof r!="object"||r===null)return!1;if(t instanceof Map&&r instanceof Map){if(t.size!==r.size)return!1;for(const[s,a]of t)if(!Object.is(a,r.get(s)))return!1;return!0}if(t instanceof Set&&r instanceof Set){if(t.size!==r.size)return!1;for(const s of t)if(!r.has(s))return!1;return!0}const o=Object.keys(t);if(o.length!==Object.keys(r).length)return!1;for(const s of o)if(!Object.prototype.hasOwnProperty.call(r,s)||!Object.is(t[s],r[s]))return!1;return!0}Ep();const zl=F.createContext(null),f_=zl.Provider,Ag=on.error001("react");function ze(t,r){const o=F.useContext(zl);if(o===null)throw new Error(Ag);return Lg(o,t,r)}function Ye(){const t=F.useContext(zl);if(t===null)throw new Error(Ag);return F.useMemo(()=>({getState:t.getState,setState:t.setState,subscribe:t.subscribe}),[t])}const Vh={display:"none"},h_={position:"absolute",width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0px, 0px, 0px, 0px)",clipPath:"inset(100%)"},zg="react-flow__node-desc",Dg="react-flow__edge-desc",p_="react-flow__aria-live",g_=t=>t.ariaLiveMessage,m_=t=>t.ariaLabelConfig;function y_({rfId:t}){const r=ze(g_);return h.jsx("div",{id:`${p_}-${t}`,"aria-live":"assertive","aria-atomic":"true",style:h_,children:r})}function v_({rfId:t,disableKeyboardA11y:r}){const o=ze(m_);return h.jsxs(h.Fragment,{children:[h.jsx("div",{id:`${zg}-${t}`,style:Vh,children:r?o["node.a11yDescription.default"]:o["node.a11yDescription.keyboardDisabled"]}),h.jsx("div",{id:`${Dg}-${t}`,style:Vh,children:o["edge.a11yDescription.default"]}),!r&&h.jsx(y_,{rfId:t})]})}const Dl=F.forwardRef(({position:t="top-left",children:r,className:o,style:s,...a},u)=>{const c=`${t}`.split("-");return h.jsx("div",{className:it(["react-flow__panel",o,...c]),style:s,ref:u,...a,children:r})});Dl.displayName="Panel";const Wh="https://reactflow.dev?utm_source=attribution";function x_({proOptions:t,position:r="bottom-right"}){return t!=null&&t.hideAttribution?null:h.jsx(Dl,{position:r,className:"react-flow__attribution","data-message":`Please only hide this attribution when you are subscribed to React Flow Pro: ${Wh}`,children:h.jsx("a",{href:Wh,target:"_blank",rel:"noopener noreferrer","aria-label":"React Flow attribution",children:"React Flow"})})}const w_=t=>{const r=[],o=[];for(const[,s]of t.nodeLookup)s.selected&&r.push(s.internals.userNode);for(const[,s]of t.edgeLookup)s.selected&&o.push(s);return{selectedNodes:r,selectedEdges:o}},ll=t=>t.id;function __(t,r){return Ke(t.selectedNodes.map(ll),r.selectedNodes.map(ll))&&Ke(t.selectedEdges.map(ll),r.selectedEdges.map(ll))}function S_({onSelectionChange:t}){const r=Ye(),{selectedNodes:o,selectedEdges:s}=ze(w_,__);return F.useEffect(()=>{const a={nodes:o,edges:s};t==null||t(a),r.getState().onSelectionChangeHandlers.forEach(u=>u(a))},[o,s,t]),null}const k_=t=>!!t.onSelectionChangeHandlers;function N_({onSelectionChange:t}){const r=ze(k_);return t||r?h.jsx(S_,{onSelectionChange:t}):null}const $g=[0,0],E_={x:0,y:0,zoom:1},j_=["nodes","edges","defaultNodes","defaultEdges","onConnect","onConnectStart","onConnectEnd","onClickConnectStart","onClickConnectEnd","nodesDraggable","autoPanOnNodeFocus","nodesConnectable","nodesFocusable","edgesFocusable","edgesReconnectable","elevateNodesOnSelect","elevateEdgesOnSelect","minZoom","maxZoom","nodeExtent","onNodesChange","onEdgesChange","elementsSelectable","connectionMode","snapGrid","snapToGrid","translateExtent","connectOnClick","defaultEdgeOptions","fitView","fitViewOptions","onNodesDelete","onEdgesDelete","onDelete","onNodeDrag","onNodeDragStart","onNodeDragStop","onSelectionDrag","onSelectionDragStart","onSelectionDragStop","onMoveStart","onMove","onMoveEnd","noPanClassName","nodeOrigin","autoPanOnConnect","autoPanOnNodeDrag","onError","connectionRadius","isValidConnection","selectNodesOnDrag","nodeDragThreshold","connectionDragThreshold","onBeforeDelete","debug","autoPanSpeed","ariaLabelConfig","zIndexMode"],Uh=[...j_,"rfId"],b_=t=>({setNodes:t.setNodes,setEdges:t.setEdges,setMinZoom:t.setMinZoom,setMaxZoom:t.setMaxZoom,setTranslateExtent:t.setTranslateExtent,setNodeExtent:t.setNodeExtent,reset:t.reset,setDefaultNodesAndEdges:t.setDefaultNodesAndEdges}),Yh={translateExtent:Ao,nodeOrigin:$g,minZoom:.5,maxZoom:2,elementsSelectable:!0,noPanClassName:"nopan",rfId:"1"};function C_(t){const{setNodes:r,setEdges:o,setMinZoom:s,setMaxZoom:a,setTranslateExtent:u,setNodeExtent:c,reset:f,setDefaultNodesAndEdges:g}=ze(b_,Ke),y=Ye();F.useEffect(()=>(g(t.defaultNodes,t.defaultEdges),()=>{v.current=Yh,f()}),[]);const v=F.useRef(Yh);return F.useEffect(()=>{for(const x of Uh){const m=t[x],S=v.current[x];m!==S&&(typeof t[x]>"u"||(x==="nodes"?r(m):x==="edges"?o(m):x==="minZoom"?s(m):x==="maxZoom"?a(m):x==="translateExtent"?u(m):x==="nodeExtent"?c(m):x==="ariaLabelConfig"?y.setState({ariaLabelConfig:f1(m)}):x==="fitView"?y.setState({fitViewQueued:m}):x==="fitViewOptions"?y.setState({fitViewOptions:m}):y.setState({[x]:m})))}v.current=t},Uh.map(x=>t[x])),null}function Gh(){return typeof window>"u"||!window.matchMedia?null:window.matchMedia("(prefers-color-scheme: dark)")}function M_(t){var s;const[r,o]=F.useState(t==="system"?null:t);return F.useEffect(()=>{if(t!=="system"){o(t);return}const a=Gh(),u=()=>o(a!=null&&a.matches?"dark":"light");return u(),a==null||a.addEventListener("change",u),()=>{a==null||a.removeEventListener("change",u)}},[t]),r!==null?r:(s=Gh())!=null&&s.matches?"dark":"light"}const Xh=typeof document<"u"?document:null;function Fo(t=null,r={target:Xh,actInsideInputWithModifier:!0}){const[o,s]=F.useState(!1),a=F.useRef(!1),u=F.useRef(new Set([])),[c,f]=F.useMemo(()=>{if(t!==null){const y=(Array.isArray(t)?t:[t]).filter(x=>typeof x=="string").map(x=>x.replace(/\+/g,` +`).replace(` + +`,` ++`).split(` +`)),v=y.reduce((x,m)=>x.concat(...m),[]);return[y,v]}return[[],[]]},[t]);return F.useEffect(()=>{const g=(r==null?void 0:r.target)??Xh,y=(r==null?void 0:r.actInsideInputWithModifier)??!0;if(t!==null){const v=S=>{var b,w;if(a.current=S.ctrlKey||S.metaKey||S.shiftKey||S.altKey,(!a.current||a.current&&!y)&&yg(S))return!1;const E=Kh(S.code,f);if(u.current.add(S[E]),qh(c,u.current,!1)){const P=((w=(b=S.composedPath)==null?void 0:b.call(S))==null?void 0:w[0])||S.target,N=(P==null?void 0:P.nodeName)==="BUTTON"||(P==null?void 0:P.nodeName)==="A";r.preventDefault!==!1&&(a.current||!N)&&S.preventDefault(),s(!0)}},x=S=>{const _=Kh(S.code,f);qh(c,u.current,!0)?(s(!1),u.current.clear()):u.current.delete(S[_]),S.key==="Meta"&&u.current.clear(),a.current=!1},m=()=>{u.current.clear(),s(!1)};return g==null||g.addEventListener("keydown",v),g==null||g.addEventListener("keyup",x),window.addEventListener("blur",m),window.addEventListener("contextmenu",m),()=>{g==null||g.removeEventListener("keydown",v),g==null||g.removeEventListener("keyup",x),window.removeEventListener("blur",m),window.removeEventListener("contextmenu",m)}}},[t,s]),o}function qh(t,r,o){return t.filter(s=>o||s.length===r.size).some(s=>s.every(a=>r.has(a)))}function Kh(t,r){return r.includes(t)?"code":"key"}const P_=()=>{const t=Ye();return F.useMemo(()=>({zoomIn:async r=>{const{panZoom:o}=t.getState();return o?o.scaleBy(1.2,r):!1},zoomOut:async r=>{const{panZoom:o}=t.getState();return o?o.scaleBy(1/1.2,r):!1},zoomTo:async(r,o)=>{const{panZoom:s}=t.getState();return s?s.scaleTo(r,o):!1},getZoom:()=>t.getState().transform[2],setViewport:async(r,o)=>{const{transform:[s,a,u],panZoom:c}=t.getState();return c?(await c.setViewport({x:r.x??s,y:r.y??a,zoom:r.zoom??u},o),!0):!1},getViewport:()=>{const[r,o,s]=t.getState().transform;return{x:r,y:o,zoom:s}},setCenter:async(r,o,s)=>t.getState().setCenter(r,o,s),fitBounds:async(r,o)=>{const{width:s,height:a,minZoom:u,maxZoom:c,panZoom:f}=t.getState(),g=yc(r,s,a,u,c,(o==null?void 0:o.padding)??.1);return f?(await f.setViewport(g,{duration:o==null?void 0:o.duration,ease:o==null?void 0:o.ease,interpolate:o==null?void 0:o.interpolate}),!0):!1},screenToFlowPosition:(r,o={})=>{const{transform:s,snapGrid:a,snapToGrid:u,domNode:c}=t.getState();if(!c)return r;const{x:f,y:g}=c.getBoundingClientRect(),y={x:r.x-f,y:r.y-g},v=o.snapGrid??a,x=o.snapToGrid??u;return Xo(y,s,x,v)},flowToScreenPosition:r=>{const{transform:o,domNode:s}=t.getState();if(!s)return r;const{x:a,y:u}=s.getBoundingClientRect(),c=$i(r,o);return{x:c.x+a,y:c.y+u}}}),[])};function Og(t,r){const o=[],s=new Map,a=[];for(const u of t)if(u.type==="add"){a.push(u);continue}else if(u.type==="remove"||u.type==="replace")s.set(u.id,[u]);else{const c=s.get(u.id);c?c.push(u):s.set(u.id,[u])}for(const u of r){const c=s.get(u.id);if(!c){o.push(u);continue}if(c[0].type==="remove")continue;if(c[0].type==="replace"){o.push({...c[0].item});continue}const f={...u};for(const g of c)I_(g,f);o.push(f)}return a.length&&a.forEach(u=>{u.index!==void 0?o.splice(u.index,0,{...u.item}):o.push({...u.item})}),o}function I_(t,r){switch(t.type){case"select":{r.selected=t.selected;break}case"position":{typeof t.position<"u"&&(r.position=t.position),typeof t.dragging<"u"&&(r.dragging=t.dragging);break}case"dimensions":{typeof t.dimensions<"u"&&(r.measured={...t.dimensions},t.setAttributes&&((t.setAttributes===!0||t.setAttributes==="width")&&(r.width=t.dimensions.width),(t.setAttributes===!0||t.setAttributes==="height")&&(r.height=t.dimensions.height))),typeof t.resizing=="boolean"&&(r.resizing=t.resizing);break}}}function T_(t,r){return Og(t,r)}function R_(t,r){return Og(t,r)}function Dr(t,r){return{id:t,type:"select",selected:r}}function Ii(t,r=new Set,o=!1){const s=[];for(const[a,u]of t){const c=r.has(a);!(u.selected===void 0&&!c)&&u.selected!==c&&(o&&(u.selected=c),s.push(Dr(u.id,c)))}return s}function Qh({items:t=[],lookup:r}){var a;const o=[],s=new Map(t.map(u=>[u.id,u]));for(const[u,c]of t.entries()){const f=r.get(c.id),g=((a=f==null?void 0:f.internals)==null?void 0:a.userNode)??f;g!==void 0&&g!==c&&o.push({id:c.id,item:c,type:"replace"}),g===void 0&&o.push({item:c,type:"add",index:u})}for(const[u]of r)s.get(u)===void 0&&o.push({id:u,type:"remove"});return o}function Zh(t){return{id:t.id,type:"remove"}}const L_=hg();function A_(t,r,o={}){return v1(t,r,{...o,onError:o.onError??L_})}const Jh=t=>r1(t),z_=t=>ag(t);function Fg(t){return F.forwardRef(t)}const Hg=typeof window<"u"?F.useLayoutEffect:F.useEffect;function ep(t){const[r,o]=F.useState(BigInt(0)),[s]=F.useState(()=>D_(()=>o(a=>a+BigInt(1))));return Hg(()=>{const a=s.get();a.length&&(t(a),s.reset())},[r]),s}function D_(t){let r=[];return{get:()=>r,reset:()=>{r=[]},push:o=>{r.push(o),t()}}}const Bg=F.createContext(null);function $_({children:t}){const r=Ye(),o=F.useCallback(f=>{const{nodes:g=[],setNodes:y,hasDefaultNodes:v,onNodesChange:x,nodeLookup:m,fitViewQueued:S,onNodesChangeMiddlewareMap:_}=r.getState();let E=g;for(const w of f)E=typeof w=="function"?w(E):w;let b=Qh({items:E,lookup:m});for(const w of _.values())b=w(b);v&&y(E),b.length>0?x==null||x(b):S&&window.requestAnimationFrame(()=>{const{fitViewQueued:w,nodes:P,setNodes:N}=r.getState();w&&N(P)})},[]),s=ep(o),a=F.useCallback(f=>{const{edges:g=[],setEdges:y,hasDefaultEdges:v,onEdgesChange:x,edgeLookup:m}=r.getState();let S=g;for(const _ of f)S=typeof _=="function"?_(S):_;v?y(S):x&&x(Qh({items:S,lookup:m}))},[]),u=ep(a),c=F.useMemo(()=>({nodeQueue:s,edgeQueue:u}),[]);return h.jsx(Bg.Provider,{value:c,children:t})}function O_(){const t=F.useContext(Bg);if(!t)throw new Error("useBatchContext must be used within a BatchProvider");return t}const F_=t=>!!t.panZoom;function $l(){const t=P_(),r=Ye(),o=O_(),s=ze(F_),a=F.useMemo(()=>{const u=x=>r.getState().nodeLookup.get(x),c=x=>{o.nodeQueue.push(x)},f=x=>{o.edgeQueue.push(x)},g=x=>{var w,P;const{nodeLookup:m,nodeOrigin:S}=r.getState(),_=Jh(x)?x:m.get(x.id),E=_.parentId?gg(_.position,_.measured,_.parentId,m,S):_.position,b={..._,position:E,width:((w=_.measured)==null?void 0:w.width)??_.width,height:((P=_.measured)==null?void 0:P.height)??_.height};return $o(b)},y=(x,m,S={replace:!1})=>{c(_=>_.map(E=>{if(E.id===x){const b=typeof m=="function"?m(E):m;return S.replace&&Jh(b)?b:{...E,...b}}return E}))},v=(x,m,S={replace:!1})=>{f(_=>_.map(E=>{if(E.id===x){const b=typeof m=="function"?m(E):m;return S.replace&&z_(b)?b:{...E,...b}}return E}))};return{getNodes:()=>r.getState().nodes.map(x=>({...x})),getNode:x=>{var m;return(m=u(x))==null?void 0:m.internals.userNode},getInternalNode:u,getEdges:()=>{const{edges:x=[]}=r.getState();return x.map(m=>({...m}))},getEdge:x=>r.getState().edgeLookup.get(x),setNodes:c,setEdges:f,addNodes:x=>{const m=Array.isArray(x)?x:[x];o.nodeQueue.push(S=>[...S,...m])},addEdges:x=>{const m=Array.isArray(x)?x:[x];o.edgeQueue.push(S=>[...S,...m])},toObject:()=>{const{nodes:x=[],edges:m=[],transform:S}=r.getState(),[_,E,b]=S;return{nodes:x.map(w=>({...w})),edges:m.map(w=>({...w})),viewport:{x:_,y:E,zoom:b}}},deleteElements:async({nodes:x=[],edges:m=[]})=>{const{nodes:S,edges:_,onNodesDelete:E,onEdgesDelete:b,triggerNodeChanges:w,triggerEdgeChanges:P,onDelete:N,onBeforeDelete:j}=r.getState(),{nodes:L,edges:z}=await a1({nodesToRemove:x,edgesToRemove:m,nodes:S,edges:_,onBeforeDelete:j}),W=z.length>0,D=L.length>0;if(W){const G=z.map(Zh);b==null||b(z),P(G)}if(D){const G=L.map(Zh);E==null||E(L),w(G)}return(D||W)&&(N==null||N({nodes:L,edges:z})),{deletedNodes:L,deletedEdges:z}},getIntersectingNodes:(x,m=!0,S)=>{const _=Nh(x),E=_?x:g(x),b=S!==void 0;return E?(S||r.getState().nodes).filter(w=>{const P=r.getState().nodeLookup.get(w.id);if(P&&!_&&(w.id===x.id||!P.internals.positionAbsolute))return!1;const N=$o(b?w:P),j=Nl(N,E);return m&&j>0||j>=N.width*N.height||j>=E.width*E.height}):[]},isNodeIntersecting:(x,m,S=!0)=>{const E=Nh(x)?x:g(x);if(!E)return!1;const b=Nl(E,m);return S&&b>0||b>=m.width*m.height||b>=E.width*E.height},updateNode:y,updateNodeData:(x,m,S={replace:!1})=>{y(x,_=>{const E=typeof m=="function"?m(_):m;return S.replace?{..._,data:E}:{..._,data:{..._.data,...E}}},S)},updateEdge:v,updateEdgeData:(x,m,S={replace:!1})=>{v(x,_=>{const E=typeof m=="function"?m(_):m;return S.replace?{..._,data:E}:{..._,data:{..._.data,...E}}},S)},getNodesBounds:x=>{const{nodeLookup:m,nodeOrigin:S}=r.getState();return i1(x,{nodeLookup:m,nodeOrigin:S})},getHandleConnections:({type:x,id:m,nodeId:S})=>{var _;return Array.from(((_=r.getState().connectionLookup.get(`${S}-${x}${m?`-${m}`:""}`))==null?void 0:_.values())??[])},getNodeConnections:({type:x,handleId:m,nodeId:S})=>{var _;return Array.from(((_=r.getState().connectionLookup.get(`${S}${x?m?`-${x}-${m}`:`-${x}`:""}`))==null?void 0:_.values())??[])},fitView:async x=>{const m=r.getState().fitViewResolver??d1();return r.setState({fitViewQueued:!0,fitViewOptions:x,fitViewResolver:m}),o.nodeQueue.push(S=>[...S]),m.promise}}},[]);return F.useMemo(()=>({...a,...t,viewportInitialized:s}),[s])}const tp=t=>t.selected,H_=typeof window<"u"?window:void 0;function B_({deleteKeyCode:t,multiSelectionKeyCode:r}){const o=Ye(),{deleteElements:s}=$l(),a=Fo(t,{actInsideInputWithModifier:!1}),u=Fo(r,{target:H_});F.useEffect(()=>{if(a){const{edges:c,nodes:f}=o.getState();s({nodes:f.filter(tp),edges:c.filter(tp)}),o.setState({nodesSelectionActive:!1})}},[a]),F.useEffect(()=>{o.setState({multiSelectionActive:u})},[u])}function V_(t){const r=Ye();F.useEffect(()=>{const o=()=>{var a,u,c,f;if(!t.current||!(((u=(a=t.current).checkVisibility)==null?void 0:u.call(a))??!0))return!1;const s=vc(t.current);(s.height===0||s.width===0)&&((f=(c=r.getState()).onError)==null||f.call(c,"004",on.error004())),r.setState({width:s.width||500,height:s.height||500})};if(t.current){o(),window.addEventListener("resize",o);const s=new ResizeObserver(()=>o());return s.observe(t.current),()=>{window.removeEventListener("resize",o),s&&t.current&&s.unobserve(t.current)}}},[])}const Ol={position:"absolute",width:"100%",height:"100%",top:0,left:0},W_=t=>({userSelectionActive:t.userSelectionActive,lib:t.lib,connectionInProgress:t.connection.inProgress});function U_({onPaneContextMenu:t,zoomOnScroll:r=!0,zoomOnPinch:o=!0,panOnScroll:s=!1,panActivationKeyPressed:a,panOnScrollSpeed:u=.5,panOnScrollMode:c=Hr.Free,zoomOnDoubleClick:f=!0,panOnDrag:g=!0,defaultViewport:y,translateExtent:v,minZoom:x,maxZoom:m,zoomActivationKeyCode:S,preventScrolling:_=!0,children:E,noWheelClassName:b,noPanClassName:w,onViewportChange:P,isControlledViewport:N,paneClickDistance:j,selectionOnDrag:L}){const z=Ye(),W=F.useRef(null),{userSelectionActive:D,lib:G,connectionInProgress:J}=ze(W_,Ke),K=Fo(S),ne=F.useRef();V_(W);const te=F.useCallback(C=>{P==null||P({x:C[0],y:C[1],zoom:C[2]}),N||z.setState({transform:C})},[P,N]);return F.useEffect(()=>{if(W.current){ne.current=X1({domNode:W.current,minZoom:x,maxZoom:m,translateExtent:v,viewport:y,onDraggingChange:Y=>z.setState(T=>T.paneDragging===Y?T:{paneDragging:Y}),onPanZoomStart:(Y,T)=>{const{onViewportChangeStart:H,onMoveStart:U}=z.getState();U==null||U(Y,T),H==null||H(T)},onPanZoom:(Y,T)=>{const{onViewportChange:H,onMove:U}=z.getState();U==null||U(Y,T),H==null||H(T)},onPanZoomEnd:(Y,T)=>{const{onViewportChangeEnd:H,onMoveEnd:U}=z.getState();U==null||U(Y,T),H==null||H(T)}});const{x:C,y:R,zoom:B}=ne.current.getViewport();return z.setState({panZoom:ne.current,transform:[C,R,B],domNode:W.current.closest(".react-flow")}),()=>{var Y;(Y=ne.current)==null||Y.destroy()}}},[]),F.useEffect(()=>{var C;(C=ne.current)==null||C.update({onPaneContextMenu:t,zoomOnScroll:r,zoomOnPinch:o,panOnScroll:s,panActivationKeyPressed:a,panOnScrollSpeed:u,panOnScrollMode:c,zoomOnDoubleClick:f,panOnDrag:g,zoomActivationKeyPressed:K,preventScrolling:_,noPanClassName:w,userSelectionActive:D,noWheelClassName:b,lib:G,onTransformChange:te,connectionInProgress:J,selectionOnDrag:L,paneClickDistance:j})},[t,r,o,s,a,u,c,f,g,K,_,w,D,b,G,te,J,L,j]),h.jsx("div",{className:"react-flow__renderer",ref:W,style:Ol,children:E})}const Y_=t=>({userSelectionActive:t.userSelectionActive,userSelectionRect:t.userSelectionRect});function G_(){const{userSelectionActive:t,userSelectionRect:r}=ze(Y_,Ke);return t&&r?h.jsx("div",{className:"react-flow__selection react-flow__container",style:{width:r.width,height:r.height,transform:`translate(${r.x}px, ${r.y}px)`}}):null}const Bu=(t,r)=>o=>{o.target===r.current&&(t==null||t(o))},X_=t=>({userSelectionActive:t.userSelectionActive,elementsSelectable:t.elementsSelectable,dragging:t.paneDragging,panBy:t.panBy,autoPanSpeed:t.autoPanSpeed});function q_({isSelecting:t,selectionKeyPressed:r,selectionMode:o=zo.Full,panOnDrag:s,autoPanOnSelection:a,paneClickDistance:u,selectionOnDrag:c,onSelectionStart:f,onSelectionEnd:g,onPaneClick:y,onPaneContextMenu:v,onPaneScroll:x,onPaneMouseEnter:m,onPaneMouseMove:S,onPaneMouseLeave:_,children:E}){const b=F.useRef(0),w=Ye(),{userSelectionActive:P,elementsSelectable:N,dragging:j,panBy:L,autoPanSpeed:z}=ze(X_,Ke),W=N&&(t||P),D=F.useRef(null),G=F.useRef(),J=F.useRef(new Set),K=F.useRef(new Set),ne=F.useRef(!1),te=F.useRef(!1),C=F.useRef({x:0,y:0}),R=F.useRef(!1),B=Q=>{if(te.current||ne.current||w.getState().connection.inProgress){te.current=!1,ne.current=!1;return}y==null||y(Q),w.getState().resetSelectedElements(),w.setState({nodesSelectionActive:!1})},Y=Q=>{if(Array.isArray(s)&&(s!=null&&s.includes(2))){Q.preventDefault();return}v==null||v(Q)},T=x?Q=>x(Q):void 0,H=Q=>{te.current&&(Q.stopPropagation(),te.current=!1)},U=Q=>{var Re,tt;if(Q.pointerType==="touch"&&s!==!1&&!r)return;const{domNode:le,transform:me}=w.getState();if(G.current=le==null?void 0:le.getBoundingClientRect(),!G.current)return;const ke=Q.target===D.current;if(!ke&&!!Q.target.closest(".nokey")||!t||!(c&&ke||r)||Q.button!==0||!Q.isPrimary)return;(tt=(Re=Q.target)==null?void 0:Re.setPointerCapture)==null||tt.call(Re,Q.pointerId),te.current=!1;const{x:be,y:Pe}=rn(Q.nativeEvent,G.current),Ce=Xo({x:be,y:Pe},me);w.setState({userSelectionRect:{width:0,height:0,startX:Ce.x,startY:Ce.y,x:be,y:Pe}}),ke||(Q.stopPropagation(),Q.preventDefault())};function M(Q,le){const{userSelectionRect:me}=w.getState();if(!me)return;const{transform:ke,nodeLookup:xe,edgeLookup:pe,connectionLookup:be,triggerNodeChanges:Pe,triggerEdgeChanges:Ce,defaultEdgeOptions:Re}=w.getState(),tt={x:me.startX,y:me.startY},{x:nt,y:Je}=$i(tt,ke),Qe={startX:tt.x,startY:tt.y,x:Qft.id)),K.current=new Set;const st=(Re==null?void 0:Re.selectable)??!0;for(const ft of J.current){const He=be.get(ft);if(He)for(const{edgeId:Le}of He.values()){const mt=pe.get(Le);mt&&(mt.selectable??st)&&K.current.add(Le)}}if(!Eh(ot,J.current)){const ft=Ii(xe,J.current,!0);Pe(ft)}if(!Eh(Pt,K.current)){const ft=Ii(pe,K.current);Ce(ft)}w.setState({userSelectionRect:Qe,userSelectionActive:!0,nodesSelectionActive:!1})}function A(){if(!a||!G.current)return;const[Q,le]=mc(C.current,G.current,z);L({x:Q,y:le}).then(me=>{if(!te.current||!me){b.current=requestAnimationFrame(A);return}const{x:ke,y:xe}=C.current;M(ke,xe),b.current=requestAnimationFrame(A)})}const re=()=>{cancelAnimationFrame(b.current),b.current=0,R.current=!1};F.useEffect(()=>()=>re(),[]);const ie=Q=>{const{userSelectionRect:le,transform:me,resetSelectedElements:ke}=w.getState();if(!G.current||!le)return;const{x:xe,y:pe}=rn(Q.nativeEvent,G.current);C.current={x:xe,y:pe};const be=$i({x:le.startX,y:le.startY},me);if(!te.current){const Pe=r?0:u;if(Math.hypot(xe-be.x,pe-be.y)<=Pe)return;ke(),f==null||f(Q)}te.current=!0,R.current||(A(),R.current=!0),M(xe,pe)},ce=Q=>{var le,me;if(!W){Q.target===D.current&&w.getState().connection.inProgress&&(ne.current=!0);return}Q.button===0&&((me=(le=Q.target)==null?void 0:le.releasePointerCapture)==null||me.call(le,Q.pointerId),!P&&Q.target===D.current&&w.getState().userSelectionRect&&(B==null||B(Q)),w.setState({userSelectionActive:!1,userSelectionRect:null}),te.current&&(g==null||g(Q),w.setState({nodesSelectionActive:J.current.size>0})),re())},fe=Q=>{var le,me;(me=(le=Q.target)==null?void 0:le.releasePointerCapture)==null||me.call(le,Q.pointerId),re()},de=s===!0||Array.isArray(s)&&s.includes(0);return h.jsxs("div",{className:it(["react-flow__pane",{draggable:de,dragging:j,selection:t}]),onClick:W?void 0:Bu(B,D),onContextMenu:Bu(Y,D),onWheel:Bu(T,D),onPointerEnter:W?void 0:m,onPointerMove:W?ie:S,onPointerUp:ce,onPointerCancel:W?fe:void 0,onPointerDownCapture:W?U:void 0,onClickCapture:W?H:void 0,onPointerLeave:_,ref:D,style:Ol,children:[E,h.jsx(G_,{})]})}function oc({id:t,store:r,unselect:o=!1,nodeRef:s}){const{addSelectedNodes:a,unselectNodesAndEdges:u,multiSelectionActive:c,nodeLookup:f,onError:g}=r.getState(),y=f.get(t);if(!y){g==null||g("012",on.error012(t));return}r.setState({nodesSelectionActive:!1}),y.selected?(o||y.selected&&c)&&(u({nodes:[y],edges:[]}),requestAnimationFrame(()=>{var v;return(v=s==null?void 0:s.current)==null?void 0:v.blur()})):a([t])}function Vg({nodeRef:t,disabled:r=!1,noDragClassName:o,handleSelector:s,nodeId:a,isSelectable:u,nodeClickDistance:c}){const f=Ye(),[g,y]=F.useState(!1),v=F.useRef();return F.useEffect(()=>{if(!r)return v.current=L1({getStoreItems:()=>f.getState(),onNodeMouseDown:x=>{oc({id:x,store:f,nodeRef:t})},onDragStart:()=>{y(!0)},onDragStop:()=>{y(!1)}}),()=>{var x;(x=v.current)==null||x.destroy(),v.current=void 0}},[r,f,t]),F.useEffect(()=>{r||!t.current||!v.current||v.current.update({noDragClassName:o,handleSelector:s,domNode:t.current,isSelectable:u,nodeId:a,nodeClickDistance:c})},[o,s,r,u,t,a,c]),g}const K_=t=>r=>r.selected&&(r.draggable||t&&typeof r.draggable>"u");function Wg(){const t=Ye();return F.useCallback(o=>{const{nodeExtent:s,snapToGrid:a,snapGrid:u,nodesDraggable:c,onError:f,updateNodePositions:g,nodeLookup:y,nodeOrigin:v}=t.getState(),x=new Map,m=K_(c),S=a?u[0]:5,_=a?u[1]:5,E=o.direction.x*S*o.factor,b=o.direction.y*_*o.factor;for(const[,w]of y){if(!m(w))continue;let P={x:w.internals.positionAbsolute.x+E,y:w.internals.positionAbsolute.y+b};a&&(P=Go(P,u));const{position:N,positionAbsolute:j}=ug({nodeId:w.id,nextPosition:P,nodeLookup:y,nodeExtent:s,nodeOrigin:v,onError:f});w.position=N,w.internals.positionAbsolute=j,x.set(w.id,w)}g(x)},[])}const Nc=F.createContext(null),Q_=Nc.Provider;Nc.Consumer;const Ug=()=>F.useContext(Nc),Z_=t=>({connectOnClick:t.connectOnClick,noPanClassName:t.noPanClassName,rfId:t.rfId}),Yg=F.createContext(null);function J_({children:t}){const r=ze(Z_,Ke);return h.jsx(Yg.Provider,{value:r,children:t})}function eS(){const t=F.useContext(Yg);if(!t)throw new Error("useHandleConfig must be used within a HandleConfigProvider");return t}const tS={connectingFrom:!1,connectingTo:!1,clickConnecting:!1,isPossibleEndHandle:!0,connectionInProcess:!1,clickConnectionInProcess:!1,valid:!1},nS=(t,r,o)=>s=>{const{connectionClickStartHandle:a,connectionMode:u,connection:c}=s,{fromHandle:f,toHandle:g,isValid:y}=c;if(!f&&!a)return tS;const v=(g==null?void 0:g.nodeId)===t&&(g==null?void 0:g.id)===r&&(g==null?void 0:g.type)===o;return{connectingFrom:(f==null?void 0:f.nodeId)===t&&(f==null?void 0:f.id)===r&&(f==null?void 0:f.type)===o,connectingTo:v,clickConnecting:(a==null?void 0:a.nodeId)===t&&(a==null?void 0:a.id)===r&&(a==null?void 0:a.type)===o,isPossibleEndHandle:u===zi.Strict?(f==null?void 0:f.type)!==o:t!==(f==null?void 0:f.nodeId)||r!==(f==null?void 0:f.id),connectionInProcess:!!f,clickConnectionInProcess:!!a,valid:v&&y}};function rS({type:t="source",position:r=Se.Top,isValidConnection:o,isConnectable:s=!0,isConnectableStart:a=!0,isConnectableEnd:u=!0,id:c,onConnect:f,children:g,className:y,onMouseDown:v,onTouchStart:x,...m},S){var R,B;const _=c||null,E=t==="target",b=Ye(),w=Ug(),{connectOnClick:P,noPanClassName:N,rfId:j}=eS(),{connectingFrom:L,connectingTo:z,clickConnecting:W,isPossibleEndHandle:D,connectionInProcess:G,clickConnectionInProcess:J,valid:K}=ze(nS(w,_,t),Ke);w||(B=(R=b.getState()).onError)==null||B.call(R,"010",on.error010());const ne=Y=>{const{defaultEdgeOptions:T,onConnect:H,hasDefaultEdges:U}=b.getState(),M={...T,...Y};if(U){const{edges:A,setEdges:re,onError:ie}=b.getState();re(A_(M,A,{onError:ie}))}H==null||H(M),f==null||f(M)},te=Y=>{if(!w)return;const T=vg(Y.nativeEvent);if(a&&(T&&Y.button===0||!T)){const H=b.getState();ic.onPointerDown(Y.nativeEvent,{handleDomNode:Y.currentTarget,autoPanOnConnect:H.autoPanOnConnect,connectionMode:H.connectionMode,connectionRadius:H.connectionRadius,domNode:H.domNode,nodeLookup:H.nodeLookup,lib:H.lib,isTarget:E,handleId:_,nodeId:w,flowId:H.rfId,panBy:H.panBy,cancelConnection:H.cancelConnection,onConnectStart:H.onConnectStart,onConnectEnd:(...U)=>{var M,A;return(A=(M=b.getState()).onConnectEnd)==null?void 0:A.call(M,...U)},updateConnection:H.updateConnection,onConnect:ne,isValidConnection:o||((...U)=>{var M,A;return((A=(M=b.getState()).isValidConnection)==null?void 0:A.call(M,...U))??!0}),getTransform:()=>b.getState().transform,getFromHandle:()=>b.getState().connection.fromHandle,autoPanSpeed:H.autoPanSpeed,dragThreshold:H.connectionDragThreshold})}T?v==null||v(Y):x==null||x(Y)},C=Y=>{const{onClickConnectStart:T,onClickConnectEnd:H,connectionClickStartHandle:U,connectionMode:M,isValidConnection:A,lib:re,rfId:ie,nodeLookup:ce,connection:fe}=b.getState();if(!w||!U&&!a)return;if(!U){T==null||T(Y.nativeEvent,{nodeId:w,handleId:_,handleType:t}),b.setState({connectionClickStartHandle:{nodeId:w,type:t,id:_}});return}const de=mg(Y.target),Q=o||A,{connection:le,isValid:me}=ic.isValid(Y.nativeEvent,{handle:{nodeId:w,id:_,type:t},connectionMode:M,fromNodeId:U.nodeId,fromHandleId:U.id||null,fromType:U.type,isValidConnection:Q,flowId:ie,doc:de,lib:re,nodeLookup:ce});me&&le&&ne(le);const ke=structuredClone(fe);delete ke.inProgress,ke.toPosition=ke.toHandle?ke.toHandle.position:null,H==null||H(Y,ke),b.setState({connectionClickStartHandle:null})};return h.jsx("div",{"data-handleid":_,"data-nodeid":w,"data-handlepos":r,"data-id":`${j}-${w}-${_}-${t}`,className:it(["react-flow__handle",`react-flow__handle-${r}`,"nodrag",N,y,{source:!E,target:E,connectable:s,connectablestart:a,connectableend:u,clickconnecting:W,connectingfrom:L,connectingto:z,valid:K,connectionindicator:s&&(!G||D)&&(G||J?u:a)}]),onMouseDown:te,onTouchStart:te,onClick:P?C:void 0,ref:S,...m,children:g})}const Fi=F.memo(Fg(rS));function iS({data:t,isConnectable:r,sourcePosition:o=Se.Bottom}){return h.jsxs(h.Fragment,{children:[t==null?void 0:t.label,h.jsx(Fi,{type:"source",position:o,isConnectable:r})]})}function oS({data:t,isConnectable:r,targetPosition:o=Se.Top,sourcePosition:s=Se.Bottom}){return h.jsxs(h.Fragment,{children:[h.jsx(Fi,{type:"target",position:o,isConnectable:r}),t==null?void 0:t.label,h.jsx(Fi,{type:"source",position:s,isConnectable:r})]})}function sS(){return null}function lS({data:t,isConnectable:r,targetPosition:o=Se.Top}){return h.jsxs(h.Fragment,{children:[h.jsx(Fi,{type:"target",position:o,isConnectable:r}),t==null?void 0:t.label]})}const El={ArrowUp:{x:0,y:-1},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0},ArrowRight:{x:1,y:0}},np={input:iS,default:oS,output:lS,group:sS};function aS(t){var r,o,s,a;return t.internals.handleBounds===void 0?{width:t.width??t.initialWidth??((r=t.style)==null?void 0:r.width),height:t.height??t.initialHeight??((o=t.style)==null?void 0:o.height)}:{width:t.width??((s=t.style)==null?void 0:s.width),height:t.height??((a=t.style)==null?void 0:a.height)}}const uS=t=>{const{width:r,height:o,x:s,y:a}=Yo(t.nodeLookup,{filter:u=>!!u.selected});return{width:nn(r)?r:null,height:nn(o)?o:null,userSelectionActive:t.userSelectionActive,transformString:`translate(${t.transform[0]}px,${t.transform[1]}px) scale(${t.transform[2]}) translate(${s}px,${a}px)`}};function cS({onSelectionContextMenu:t,noPanClassName:r,disableKeyboardA11y:o}){const s=Ye(),{width:a,height:u,transformString:c,userSelectionActive:f}=ze(uS,Ke),g=Wg(),y=F.useRef(null);F.useEffect(()=>{var S;o||(S=y.current)==null||S.focus({preventScroll:!0})},[o]);const v=!f&&a!==null&&u!==null;if(Vg({nodeRef:y,disabled:!v}),!v)return null;const x=t?S=>{const _=s.getState().nodes.filter(E=>E.selected);t(S,_)}:void 0,m=S=>{Object.prototype.hasOwnProperty.call(El,S.key)&&(S.preventDefault(),g({direction:El[S.key],factor:S.shiftKey?4:1}))};return h.jsx("div",{className:it(["react-flow__nodesselection","react-flow__container",r]),style:{transform:c},children:h.jsx("div",{ref:y,className:"react-flow__nodesselection-rect",onContextMenu:x,tabIndex:o?void 0:-1,onKeyDown:o?void 0:m,style:{width:a,height:u}})})}const rp=typeof window<"u"?window:void 0,dS=t=>({nodesSelectionActive:t.nodesSelectionActive,userSelectionActive:t.userSelectionActive});function Gg({children:t,onPaneClick:r,onPaneMouseEnter:o,onPaneMouseMove:s,onPaneMouseLeave:a,onPaneContextMenu:u,onPaneScroll:c,paneClickDistance:f,deleteKeyCode:g,selectionKeyCode:y,selectionOnDrag:v,selectionMode:x,onSelectionStart:m,onSelectionEnd:S,multiSelectionKeyCode:_,panActivationKeyCode:E,zoomActivationKeyCode:b,elementsSelectable:w,zoomOnScroll:P,zoomOnPinch:N,panOnScroll:j,panOnScrollSpeed:L,panOnScrollMode:z,zoomOnDoubleClick:W,panOnDrag:D,autoPanOnSelection:G,defaultViewport:J,translateExtent:K,minZoom:ne,maxZoom:te,preventScrolling:C,onSelectionContextMenu:R,noWheelClassName:B,noPanClassName:Y,disableKeyboardA11y:T,onViewportChange:H,isControlledViewport:U}){const{nodesSelectionActive:M,userSelectionActive:A}=ze(dS,Ke),re=Fo(y,{target:rp}),ie=Fo(E,{target:rp}),ce=ie||D,fe=ie||j,de=v&&ce!==!0,Q=re||A||de;return B_({deleteKeyCode:g,multiSelectionKeyCode:_}),h.jsx(U_,{onPaneContextMenu:u,elementsSelectable:w,zoomOnScroll:P,zoomOnPinch:N,panOnScroll:fe,panActivationKeyPressed:ie,panOnScrollSpeed:L,panOnScrollMode:z,zoomOnDoubleClick:W,panOnDrag:!re&&ce,defaultViewport:J,translateExtent:K,minZoom:ne,maxZoom:te,zoomActivationKeyCode:b,preventScrolling:C,noWheelClassName:B,noPanClassName:Y,onViewportChange:H,isControlledViewport:U,paneClickDistance:f,selectionOnDrag:de,children:h.jsxs(q_,{onSelectionStart:m,onSelectionEnd:S,onPaneClick:r,onPaneMouseEnter:o,onPaneMouseMove:s,onPaneMouseLeave:a,onPaneContextMenu:u,onPaneScroll:c,panOnDrag:ce,autoPanOnSelection:G,isSelecting:!!Q,selectionMode:x,selectionKeyPressed:re,paneClickDistance:f,selectionOnDrag:de,children:[t,M&&h.jsx(cS,{onSelectionContextMenu:R,noPanClassName:Y,disableKeyboardA11y:T})]})})}Gg.displayName="FlowRenderer";const fS=F.memo(Gg),hS=t=>r=>t?gc(r.nodeLookup,{x:0,y:0,width:r.width,height:r.height},r.transform,!0).map(o=>o.id):Array.from(r.nodeLookup.keys());function pS(t){return ze(F.useCallback(hS(t),[t]),Ke)}const gS=t=>t.updateNodeInternals;function mS(){const t=ze(gS),[r]=F.useState(()=>typeof ResizeObserver>"u"?null:new ResizeObserver(o=>{const s=new Map;o.forEach(a=>{const u=a.target.getAttribute("data-id");s.set(u,{id:u,nodeElement:a.target,force:!0})}),t(s)}));return F.useEffect(()=>()=>{r==null||r.disconnect()},[r]),r}function yS({node:t,nodeType:r,hasDimensions:o,resizeObserver:s}){const a=Ye(),u=F.useRef(null),c=F.useRef(null),f=F.useRef(t.sourcePosition),g=F.useRef(t.targetPosition),y=F.useRef(r),v=o&&!!t.internals.handleBounds;return F.useEffect(()=>{u.current&&!t.hidden&&(!v||c.current!==u.current)&&(c.current&&(s==null||s.unobserve(c.current)),s==null||s.observe(u.current),c.current=u.current)},[v,t.hidden]),F.useEffect(()=>()=>{c.current&&(s==null||s.unobserve(c.current),c.current=null)},[]),F.useEffect(()=>{if(u.current){const x=y.current!==r,m=f.current!==t.sourcePosition,S=g.current!==t.targetPosition;(x||m||S)&&(y.current=r,f.current=t.sourcePosition,g.current=t.targetPosition,a.getState().updateNodeInternals(new Map([[t.id,{id:t.id,nodeElement:u.current,force:!0}]])))}},[t.id,r,t.sourcePosition,t.targetPosition]),u}function vS({id:t,onClick:r,onMouseEnter:o,onMouseMove:s,onMouseLeave:a,onContextMenu:u,onDoubleClick:c,nodesDraggable:f,elementsSelectable:g,nodesConnectable:y,nodesFocusable:v,resizeObserver:x,noDragClassName:m,noPanClassName:S,disableKeyboardA11y:_,rfId:E,nodeTypes:b,nodeClickDistance:w,onError:P}){const{node:N,internals:j,isParent:L}=ze(Q=>{const le=Q.nodeLookup.get(t),me=Q.parentLookup.has(t);return{node:le,internals:le.internals,isParent:me}},Ke);let z=N.type||"default",W=(b==null?void 0:b[z])||np[z];W===void 0&&(P==null||P("003",on.error003(z)),z="default",W=(b==null?void 0:b.default)||np.default);const D=!!(N.draggable||f&&typeof N.draggable>"u"),G=!!(N.selectable||g&&typeof N.selectable>"u"),J=!!(N.connectable||y&&typeof N.connectable>"u"),K=!!(N.focusable||v&&typeof N.focusable>"u"),ne=Ye(),te=pg(N),C=yS({node:N,nodeType:z,hasDimensions:te,resizeObserver:x}),R=Vg({nodeRef:C,disabled:N.hidden||!D,noDragClassName:m,handleSelector:N.dragHandle,nodeId:t,isSelectable:G,nodeClickDistance:w}),B=Wg();if(N.hidden)return null;const Y=ln(N),T=aS(N),H=G||D||r||o||s||a,U=o?Q=>o(Q,{...j.userNode}):void 0,M=s?Q=>s(Q,{...j.userNode}):void 0,A=a?Q=>a(Q,{...j.userNode}):void 0,re=u?Q=>u(Q,{...j.userNode}):void 0,ie=c?Q=>c(Q,{...j.userNode}):void 0,ce=Q=>{const{selectNodesOnDrag:le,nodeDragThreshold:me}=ne.getState();G&&(!le||!D||me>0)&&oc({id:t,store:ne,nodeRef:C}),r&&r(Q,{...j.userNode})},fe=Q=>{if(!(yg(Q.nativeEvent)||_)){if(ig.includes(Q.key)&&G){const le=Q.key==="Escape";oc({id:t,store:ne,unselect:le,nodeRef:C})}else if(D&&N.selected&&Object.prototype.hasOwnProperty.call(El,Q.key)){Q.preventDefault();const{ariaLabelConfig:le}=ne.getState();ne.setState({ariaLiveMessage:le["node.a11yDescription.ariaLiveMessage"]({direction:Q.key.replace("Arrow","").toLowerCase(),x:~~j.positionAbsolute.x,y:~~j.positionAbsolute.y})}),B({direction:El[Q.key],factor:Q.shiftKey?4:1})}}},de=()=>{var be;if(_||!((be=C.current)!=null&&be.matches(":focus-visible")))return;const{transform:Q,width:le,height:me,autoPanOnNodeFocus:ke,setCenter:xe}=ne.getState();if(!ke)return;gc(new Map([[t,N]]),{x:0,y:0,width:le,height:me},Q,!0).length>0||xe(N.position.x+Y.width/2,N.position.y+Y.height/2,{zoom:Q[2]})};return h.jsx("div",{className:it(["react-flow__node",`react-flow__node-${z}`,{[S]:D},N.className,{selected:N.selected,selectable:G,parent:L,draggable:D,dragging:R}]),ref:C,style:{zIndex:j.z,transform:`translate(${j.positionAbsolute.x}px,${j.positionAbsolute.y}px)`,pointerEvents:H?"all":"none",visibility:te?"visible":"hidden",...N.style,...T},"data-id":t,"data-testid":`rf__node-${t}`,onMouseEnter:U,onMouseMove:M,onMouseLeave:A,onContextMenu:re,onClick:ce,onDoubleClick:ie,onKeyDown:K?fe:void 0,tabIndex:K?0:void 0,onFocus:K?de:void 0,role:N.ariaRole??(K?"group":void 0),"aria-roledescription":"node","aria-describedby":_?void 0:`${zg}-${E}`,"aria-label":N.ariaLabel,...N.domAttributes,children:h.jsx(Q_,{value:t,children:h.jsx(W,{id:t,data:N.data,type:z,positionAbsoluteX:j.positionAbsolute.x,positionAbsoluteY:j.positionAbsolute.y,selected:N.selected??!1,selectable:G,draggable:D,deletable:N.deletable??!0,isConnectable:J,sourcePosition:N.sourcePosition,targetPosition:N.targetPosition,dragging:R,dragHandle:N.dragHandle,zIndex:j.z,parentId:N.parentId,...Y})})})}var xS=F.memo(vS);const wS=t=>({nodesConnectable:t.nodesConnectable,nodesFocusable:t.nodesFocusable,elementsSelectable:t.elementsSelectable,onError:t.onError});function Xg(t){const{nodesConnectable:r,nodesFocusable:o,elementsSelectable:s,onError:a}=ze(wS,Ke),u=pS(t.onlyRenderVisibleElements),c=mS();return h.jsx("div",{className:"react-flow__nodes",style:Ol,children:u.map(f=>h.jsx(xS,{id:f,nodeTypes:t.nodeTypes,nodeExtent:t.nodeExtent,onClick:t.onNodeClick,onMouseEnter:t.onNodeMouseEnter,onMouseMove:t.onNodeMouseMove,onMouseLeave:t.onNodeMouseLeave,onContextMenu:t.onNodeContextMenu,onDoubleClick:t.onNodeDoubleClick,noDragClassName:t.noDragClassName,noPanClassName:t.noPanClassName,rfId:t.rfId,disableKeyboardA11y:t.disableKeyboardA11y,resizeObserver:c,nodesDraggable:t.nodesDraggable??!0,nodesConnectable:r,nodesFocusable:o,elementsSelectable:s,nodeClickDistance:t.nodeClickDistance,onError:a},f))})}Xg.displayName="NodeRenderer";const _S=F.memo(Xg);function SS(t){return ze(F.useCallback(o=>{if(!t)return o.edges.map(a=>a.id);const s=[];if(o.width&&o.height)for(const a of o.edges){const u=o.nodeLookup.get(a.source),c=o.nodeLookup.get(a.target);u&&c&&g1({sourceNode:u,targetNode:c,width:o.width,height:o.height,transform:o.transform})&&s.push(a.id)}return s},[t]),Ke)}const kS=({color:t="none",strokeWidth:r=1})=>{const o={strokeWidth:r,...t&&{stroke:t}};return h.jsx("polyline",{className:"arrow",style:o,strokeLinecap:"round",fill:"none",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4"})},NS=({color:t="none",strokeWidth:r=1})=>{const o={strokeWidth:r,...t&&{stroke:t,fill:t}};return h.jsx("polyline",{className:"arrowclosed",style:o,strokeLinecap:"round",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4 -5,-4"})},ip={[Do.Arrow]:kS,[Do.ArrowClosed]:NS};function ES(t){const r=Ye();return F.useMemo(()=>{var a,u;return Object.prototype.hasOwnProperty.call(ip,t)?ip[t]:((u=(a=r.getState()).onError)==null||u.call(a,"009",on.error009(t)),null)},[t])}const jS=({id:t,type:r,color:o,width:s=12.5,height:a=12.5,markerUnits:u="strokeWidth",strokeWidth:c,orient:f="auto-start-reverse"})=>{const g=ES(r);return g?h.jsx("marker",{className:"react-flow__arrowhead",id:t,markerWidth:`${s}`,markerHeight:`${a}`,viewBox:"-10 -10 20 20",markerUnits:u,orient:f,refX:"0",refY:"0",children:h.jsx(g,{color:o,strokeWidth:c})}):null},qg=({defaultColor:t,rfId:r})=>{const o=ze(u=>u.edges),s=ze(u=>u.defaultEdgeOptions),a=F.useMemo(()=>k1(o,{id:r,defaultColor:t,defaultMarkerStart:s==null?void 0:s.markerStart,defaultMarkerEnd:s==null?void 0:s.markerEnd}),[o,s,r,t]);return a.length?h.jsx("svg",{className:"react-flow__marker","aria-hidden":"true",children:h.jsx("defs",{children:a.map(u=>h.jsx(jS,{id:u.id,type:u.type,color:u.color,width:u.width,height:u.height,markerUnits:u.markerUnits,strokeWidth:u.strokeWidth,orient:u.orient},u.id))})}):null};qg.displayName="MarkerDefinitions";var bS=F.memo(qg);function Kg({x:t,y:r,label:o,labelStyle:s,labelShowBg:a=!0,labelBgStyle:u,labelBgPadding:c=[2,4],labelBgBorderRadius:f=2,children:g,className:y,...v}){const[x,m]=F.useState({x:1,y:0,width:0,height:0}),S=it(["react-flow__edge-textwrapper",y]),_=F.useRef(null);return F.useEffect(()=>{if(_.current){const E=_.current.getBBox();m({x:E.x,y:E.y,width:E.width,height:E.height})}},[o]),o?h.jsxs("g",{transform:`translate(${t-x.width/2} ${r-x.height/2})`,className:S,visibility:x.width?"visible":"hidden",...v,children:[a&&h.jsx("rect",{width:x.width+2*c[0],x:-c[0],y:-c[1],height:x.height+2*c[1],className:"react-flow__edge-textbg",style:u,rx:f,ry:f}),h.jsx("text",{className:"react-flow__edge-text",y:x.height/2,dy:"0.3em",ref:_,style:s,children:o}),g]}):null}Kg.displayName="EdgeText";const CS=F.memo(Kg);function Fl({path:t,labelX:r,labelY:o,label:s,labelStyle:a,labelShowBg:u,labelBgStyle:c,labelBgPadding:f,labelBgBorderRadius:g,interactionWidth:y=20,...v}){return h.jsxs(h.Fragment,{children:[h.jsx("path",{...v,d:t,fill:"none",className:it(["react-flow__edge-path",v.className])}),y?h.jsx("path",{d:t,fill:"none",strokeOpacity:0,strokeWidth:y,className:"react-flow__edge-interaction"}):null,s&&nn(r)&&nn(o)?h.jsx(CS,{x:r,y:o,label:s,labelStyle:a,labelShowBg:u,labelBgStyle:c,labelBgPadding:f,labelBgBorderRadius:g}):null]})}function op({pos:t,x1:r,y1:o,x2:s,y2:a}){return t===Se.Left||t===Se.Right?[.5*(r+s),o]:[r,.5*(o+a)]}function Qg({sourceX:t,sourceY:r,sourcePosition:o=Se.Bottom,targetX:s,targetY:a,targetPosition:u=Se.Top}){const[c,f]=op({pos:o,x1:t,y1:r,x2:s,y2:a}),[g,y]=op({pos:u,x1:s,y1:a,x2:t,y2:r}),[v,x,m,S]=xg({sourceX:t,sourceY:r,targetX:s,targetY:a,sourceControlX:c,sourceControlY:f,targetControlX:g,targetControlY:y});return[`M${t},${r} C${c},${f} ${g},${y} ${s},${a}`,v,x,m,S]}function Zg(t){return F.memo(({id:r,sourceX:o,sourceY:s,targetX:a,targetY:u,sourcePosition:c,targetPosition:f,label:g,labelStyle:y,labelShowBg:v,labelBgStyle:x,labelBgPadding:m,labelBgBorderRadius:S,style:_,markerEnd:E,markerStart:b,interactionWidth:w})=>{const[P,N,j]=Qg({sourceX:o,sourceY:s,sourcePosition:c,targetX:a,targetY:u,targetPosition:f}),L=t.isInternal?void 0:r;return h.jsx(Fl,{id:L,path:P,labelX:N,labelY:j,label:g,labelStyle:y,labelShowBg:v,labelBgStyle:x,labelBgPadding:m,labelBgBorderRadius:S,style:_,markerEnd:E,markerStart:b,interactionWidth:w})})}const MS=Zg({isInternal:!1}),Jg=Zg({isInternal:!0});MS.displayName="SimpleBezierEdge";Jg.displayName="SimpleBezierEdgeInternal";function em(t){return F.memo(({id:r,sourceX:o,sourceY:s,targetX:a,targetY:u,label:c,labelStyle:f,labelShowBg:g,labelBgStyle:y,labelBgPadding:v,labelBgBorderRadius:x,style:m,sourcePosition:S=Se.Bottom,targetPosition:_=Se.Top,markerEnd:E,markerStart:b,pathOptions:w,interactionWidth:P})=>{const[N,j,L]=tc({sourceX:o,sourceY:s,sourcePosition:S,targetX:a,targetY:u,targetPosition:_,borderRadius:w==null?void 0:w.borderRadius,offset:w==null?void 0:w.offset,stepPosition:w==null?void 0:w.stepPosition}),z=t.isInternal?void 0:r;return h.jsx(Fl,{id:z,path:N,labelX:j,labelY:L,label:c,labelStyle:f,labelShowBg:g,labelBgStyle:y,labelBgPadding:v,labelBgBorderRadius:x,style:m,markerEnd:E,markerStart:b,interactionWidth:P})})}const tm=em({isInternal:!1}),nm=em({isInternal:!0});tm.displayName="SmoothStepEdge";nm.displayName="SmoothStepEdgeInternal";function rm(t){return F.memo(({id:r,...o})=>{var a;const s=t.isInternal?void 0:r;return h.jsx(tm,{...o,id:s,pathOptions:F.useMemo(()=>{var u;return{borderRadius:0,offset:(u=o.pathOptions)==null?void 0:u.offset}},[(a=o.pathOptions)==null?void 0:a.offset])})})}const PS=rm({isInternal:!1}),im=rm({isInternal:!0});PS.displayName="StepEdge";im.displayName="StepEdgeInternal";function om(t){return F.memo(({id:r,sourceX:o,sourceY:s,targetX:a,targetY:u,label:c,labelStyle:f,labelShowBg:g,labelBgStyle:y,labelBgPadding:v,labelBgBorderRadius:x,style:m,markerEnd:S,markerStart:_,interactionWidth:E})=>{const[b,w,P]=Sg({sourceX:o,sourceY:s,targetX:a,targetY:u}),N=t.isInternal?void 0:r;return h.jsx(Fl,{id:N,path:b,labelX:w,labelY:P,label:c,labelStyle:f,labelShowBg:g,labelBgStyle:y,labelBgPadding:v,labelBgBorderRadius:x,style:m,markerEnd:S,markerStart:_,interactionWidth:E})})}const IS=om({isInternal:!1}),sm=om({isInternal:!0});IS.displayName="StraightEdge";sm.displayName="StraightEdgeInternal";function lm(t){return F.memo(({id:r,sourceX:o,sourceY:s,targetX:a,targetY:u,sourcePosition:c=Se.Bottom,targetPosition:f=Se.Top,label:g,labelStyle:y,labelShowBg:v,labelBgStyle:x,labelBgPadding:m,labelBgBorderRadius:S,style:_,markerEnd:E,markerStart:b,pathOptions:w,interactionWidth:P})=>{const[N,j,L]=wg({sourceX:o,sourceY:s,sourcePosition:c,targetX:a,targetY:u,targetPosition:f,curvature:w==null?void 0:w.curvature}),z=t.isInternal?void 0:r;return h.jsx(Fl,{id:z,path:N,labelX:j,labelY:L,label:g,labelStyle:y,labelShowBg:v,labelBgStyle:x,labelBgPadding:m,labelBgBorderRadius:S,style:_,markerEnd:E,markerStart:b,interactionWidth:P})})}const TS=lm({isInternal:!1}),am=lm({isInternal:!0});TS.displayName="BezierEdge";am.displayName="BezierEdgeInternal";const sp={default:am,straight:sm,step:im,smoothstep:nm,simplebezier:Jg},lp={sourceX:null,sourceY:null,targetX:null,targetY:null,sourcePosition:null,targetPosition:null,zIndex:void 0},RS=(t,r,o)=>o===Se.Left?t-r:o===Se.Right?t+r:t,LS=(t,r,o)=>o===Se.Top?t-r:o===Se.Bottom?t+r:t,ap="react-flow__edgeupdater";function up({position:t,centerX:r,centerY:o,radius:s=10,onMouseDown:a,onMouseEnter:u,onMouseOut:c,type:f}){return h.jsx("circle",{onMouseDown:a,onMouseEnter:u,onMouseOut:c,className:it([ap,`${ap}-${f}`]),cx:RS(r,s,t),cy:LS(o,s,t),r:s,stroke:"transparent",fill:"transparent"})}function AS({isReconnectable:t,reconnectRadius:r,edge:o,sourceX:s,sourceY:a,targetX:u,targetY:c,sourcePosition:f,targetPosition:g,onReconnect:y,onReconnectStart:v,onReconnectEnd:x,setReconnecting:m,setUpdateHover:S}){const _=Ye(),E=(j,L)=>{if(j.button!==0)return;const{autoPanOnConnect:z,domNode:W,connectionMode:D,connectionRadius:G,lib:J,onConnectStart:K,cancelConnection:ne,nodeLookup:te,rfId:C,panBy:R,updateConnection:B}=_.getState(),Y=L.type==="target",T=(M,A)=>{m(!1),x==null||x(M,o,L.type,A)},H=M=>y==null?void 0:y(o,M),U=(M,A)=>{m(!0),v==null||v(j,o,L.type),K==null||K(M,A)};ic.onPointerDown(j.nativeEvent,{autoPanOnConnect:z,connectionMode:D,connectionRadius:G,domNode:W,handleId:L.id,nodeId:L.nodeId,nodeLookup:te,isTarget:Y,edgeUpdaterType:L.type,lib:J,flowId:C,cancelConnection:ne,panBy:R,isValidConnection:(...M)=>{var A,re;return((re=(A=_.getState()).isValidConnection)==null?void 0:re.call(A,...M))??!0},onConnect:H,onConnectStart:U,onConnectEnd:(...M)=>{var A,re;return(re=(A=_.getState()).onConnectEnd)==null?void 0:re.call(A,...M)},onReconnectEnd:T,updateConnection:B,getTransform:()=>_.getState().transform,getFromHandle:()=>_.getState().connection.fromHandle,dragThreshold:_.getState().connectionDragThreshold,handleDomNode:j.currentTarget})},b=j=>E(j,{nodeId:o.target,id:o.targetHandle??null,type:"target"}),w=j=>E(j,{nodeId:o.source,id:o.sourceHandle??null,type:"source"}),P=()=>S(!0),N=()=>S(!1);return h.jsxs(h.Fragment,{children:[(t===!0||t==="source")&&h.jsx(up,{position:f,centerX:s,centerY:a,radius:r,onMouseDown:b,onMouseEnter:P,onMouseOut:N,type:"source"}),(t===!0||t==="target")&&h.jsx(up,{position:g,centerX:u,centerY:c,radius:r,onMouseDown:w,onMouseEnter:P,onMouseOut:N,type:"target"})]})}function zS({id:t,edgesFocusable:r,edgesReconnectable:o,elementsSelectable:s,onClick:a,onDoubleClick:u,onContextMenu:c,onMouseEnter:f,onMouseMove:g,onMouseLeave:y,reconnectRadius:v,onReconnect:x,onReconnectStart:m,onReconnectEnd:S,rfId:_,edgeTypes:E,noPanClassName:b,onError:w,disableKeyboardA11y:P}){let N=ze(xe=>xe.edgeLookup.get(t));const j=ze(xe=>xe.defaultEdgeOptions);N=j?{...j,...N}:N;let L=N.type||"default",z=(E==null?void 0:E[L])||sp[L];z===void 0&&(w==null||w("011",on.error011(L)),L="default",z=(E==null?void 0:E.default)||sp.default);const W=!!(N.focusable||r&&typeof N.focusable>"u"),D=typeof x<"u"&&(N.reconnectable||o&&typeof N.reconnectable>"u"),G=!!(N.selectable||s&&typeof N.selectable>"u"),J=F.useRef(null),[K,ne]=F.useState(!1),[te,C]=F.useState(!1),R=Ye(),{zIndex:B=N.zIndex,sourceX:Y,sourceY:T,targetX:H,targetY:U,sourcePosition:M,targetPosition:A}=ze(F.useCallback(xe=>{const pe=xe.nodeLookup.get(N.source),be=xe.nodeLookup.get(N.target);if(!pe||!be)return lp;const Pe=S1({id:t,sourceNode:pe,targetNode:be,sourceHandle:N.sourceHandle||null,targetHandle:N.targetHandle||null,connectionMode:xe.connectionMode,onError:w}),Ce=p1({selected:N.selected,zIndex:N.zIndex,sourceNode:pe,targetNode:be,elevateOnSelect:xe.elevateEdgesOnSelect,zIndexMode:xe.zIndexMode});return{...Pe||lp,zIndex:Ce}},[N.source,N.target,N.sourceHandle,N.targetHandle,N.selected,N.zIndex,w]),Ke),re=F.useMemo(()=>N.markerStart?`url('#${nc(N.markerStart,_)}')`:void 0,[N.markerStart,_]),ie=F.useMemo(()=>N.markerEnd?`url('#${nc(N.markerEnd,_)}')`:void 0,[N.markerEnd,_]);if(N.hidden||Y===null||T===null||H===null||U===null)return null;const ce=xe=>{var Ce;const{addSelectedEdges:pe,unselectNodesAndEdges:be,multiSelectionActive:Pe}=R.getState();G&&(R.setState({nodesSelectionActive:!1}),N.selected&&Pe?(be({nodes:[],edges:[N]}),(Ce=J.current)==null||Ce.blur()):pe([t])),a&&a(xe,N)},fe=u?xe=>{u(xe,{...N})}:void 0,de=c?xe=>{c(xe,{...N})}:void 0,Q=f?xe=>{f(xe,{...N})}:void 0,le=g?xe=>{g(xe,{...N})}:void 0,me=y?xe=>{y(xe,{...N})}:void 0,ke=xe=>{var pe;if(!P&&ig.includes(xe.key)&&G){const{unselectNodesAndEdges:be,addSelectedEdges:Pe}=R.getState();xe.key==="Escape"?((pe=J.current)==null||pe.blur(),be({edges:[N]})):Pe([t])}};return h.jsx("svg",{style:{zIndex:B},children:h.jsxs("g",{className:it(["react-flow__edge",`react-flow__edge-${L}`,N.className,b,{selected:N.selected,animated:N.animated,inactive:!G&&!a,updating:K,selectable:G}]),onClick:ce,onDoubleClick:fe,onContextMenu:de,onMouseEnter:Q,onMouseMove:le,onMouseLeave:me,onKeyDown:W?ke:void 0,tabIndex:W?0:void 0,role:N.ariaRole??(W?"group":"img"),"aria-roledescription":"edge","data-id":t,"data-testid":`rf__edge-${t}`,"aria-label":N.ariaLabel===null?void 0:N.ariaLabel||`Edge from ${N.source} to ${N.target}`,"aria-describedby":W?`${Dg}-${_}`:void 0,ref:J,...N.domAttributes,children:[!te&&h.jsx(z,{id:t,source:N.source,target:N.target,type:N.type,selected:N.selected,animated:N.animated,selectable:G,deletable:N.deletable??!0,label:N.label,labelStyle:N.labelStyle,labelShowBg:N.labelShowBg,labelBgStyle:N.labelBgStyle,labelBgPadding:N.labelBgPadding,labelBgBorderRadius:N.labelBgBorderRadius,sourceX:Y,sourceY:T,targetX:H,targetY:U,sourcePosition:M,targetPosition:A,data:N.data,style:N.style,sourceHandleId:N.sourceHandle,targetHandleId:N.targetHandle,markerStart:re,markerEnd:ie,pathOptions:"pathOptions"in N?N.pathOptions:void 0,interactionWidth:N.interactionWidth}),D&&h.jsx(AS,{edge:N,isReconnectable:D,reconnectRadius:v,onReconnect:x,onReconnectStart:m,onReconnectEnd:S,sourceX:Y,sourceY:T,targetX:H,targetY:U,sourcePosition:M,targetPosition:A,setUpdateHover:ne,setReconnecting:C})]})})}var DS=F.memo(zS);const $S=t=>({edgesFocusable:t.edgesFocusable,edgesReconnectable:t.edgesReconnectable,elementsSelectable:t.elementsSelectable,connectionMode:t.connectionMode,onError:t.onError});function um({defaultMarkerColor:t,onlyRenderVisibleElements:r,rfId:o,edgeTypes:s,noPanClassName:a,onReconnect:u,onEdgeContextMenu:c,onEdgeMouseEnter:f,onEdgeMouseMove:g,onEdgeMouseLeave:y,onEdgeClick:v,reconnectRadius:x,onEdgeDoubleClick:m,onReconnectStart:S,onReconnectEnd:_,disableKeyboardA11y:E}){const{edgesFocusable:b,edgesReconnectable:w,elementsSelectable:P,onError:N}=ze($S,Ke),j=SS(r);return h.jsxs("div",{className:"react-flow__edges",children:[h.jsx(bS,{defaultColor:t,rfId:o}),j.map(L=>h.jsx(DS,{id:L,edgesFocusable:b,edgesReconnectable:w,elementsSelectable:P,noPanClassName:a,onReconnect:u,onContextMenu:c,onMouseEnter:f,onMouseMove:g,onMouseLeave:y,onClick:v,reconnectRadius:x,onDoubleClick:m,onReconnectStart:S,onReconnectEnd:_,rfId:o,onError:N,edgeTypes:s,disableKeyboardA11y:E},L))]})}um.displayName="EdgeRenderer";const OS=F.memo(um),cp=t=>`translate(${t[0]}px,${t[1]}px) scale(${t[2]})`;function FS({children:t}){const r=Ye(),o=F.useRef(null),[s]=F.useState(()=>r.getState().transform);return Hg(()=>{let a=null;const u=()=>{const c=r.getState().transform;a&&c[0]===a[0]&&c[1]===a[1]&&c[2]===a[2]||(a=c,o.current&&(o.current.style.transform=cp(c)))};return u(),r.subscribe(u)},[r]),h.jsx("div",{ref:o,className:"react-flow__viewport xyflow__viewport react-flow__container",style:{transform:cp(s)},children:t})}function HS(t){const r=$l(),o=F.useRef(!1);F.useEffect(()=>{!o.current&&r.viewportInitialized&&t&&(setTimeout(()=>t(r),1),o.current=!0)},[t,r.viewportInitialized])}const BS=t=>{var r;return(r=t.panZoom)==null?void 0:r.syncViewport};function VS(t){const r=ze(BS),o=Ye();return F.useEffect(()=>{t&&(r==null||r(t),o.setState({transform:[t.x,t.y,t.zoom]}))},[t,r]),null}function WS(t){return t.connection.inProgress?{...t.connection,to:Xo(t.connection.to,t.transform)}:{...t.connection}}function US(t){return WS}function YS(t){const r=US();return ze(r,Ke)}const GS=t=>({nodesConnectable:t.nodesConnectable,isValid:t.connection.isValid,inProgress:t.connection.inProgress,width:t.width,height:t.height});function XS({containerStyle:t,style:r,type:o,component:s}){const{nodesConnectable:a,width:u,height:c,isValid:f,inProgress:g}=ze(GS,Ke);return!(u&&a&&g)?null:h.jsx("svg",{style:t,width:u,height:c,className:"react-flow__connectionline react-flow__container",children:h.jsx("g",{className:it(["react-flow__connection",lg(f)]),children:h.jsx(cm,{style:r,type:o,CustomComponent:s,isValid:f})})})}const cm=({style:t,type:r=hr.Bezier,CustomComponent:o,isValid:s})=>{const{inProgress:a,from:u,fromNode:c,fromHandle:f,fromPosition:g,to:y,toNode:v,toHandle:x,toPosition:m,pointer:S}=YS();if(!a)return;if(o)return h.jsx(o,{connectionLineType:r,connectionLineStyle:t,fromNode:c,fromHandle:f,fromX:u.x,fromY:u.y,toX:y.x,toY:y.y,fromPosition:g,toPosition:m,connectionStatus:lg(s),toNode:v,toHandle:x,pointer:S});let _="";const E={sourceX:u.x,sourceY:u.y,sourcePosition:g,targetX:y.x,targetY:y.y,targetPosition:m};switch(r){case hr.Bezier:[_]=wg(E);break;case hr.SimpleBezier:[_]=Qg(E);break;case hr.Step:[_]=tc({...E,borderRadius:0});break;case hr.SmoothStep:[_]=tc(E);break;default:[_]=Sg(E)}return h.jsx("path",{d:_,fill:"none",className:"react-flow__connection-path",style:t})};cm.displayName="ConnectionLine";const qS={};function dp(t=qS){F.useRef(t),Ye(),F.useEffect(()=>{},[t])}function KS(){Ye(),F.useRef(!1),F.useEffect(()=>{},[])}function dm({nodeTypes:t,edgeTypes:r,onInit:o,onNodeClick:s,onEdgeClick:a,onNodeDoubleClick:u,onEdgeDoubleClick:c,onNodeMouseEnter:f,onNodeMouseMove:g,onNodeMouseLeave:y,onNodeContextMenu:v,onSelectionContextMenu:x,onSelectionStart:m,onSelectionEnd:S,connectionLineType:_,connectionLineStyle:E,connectionLineComponent:b,connectionLineContainerStyle:w,selectionKeyCode:P,selectionOnDrag:N,selectionMode:j,multiSelectionKeyCode:L,panActivationKeyCode:z,zoomActivationKeyCode:W,deleteKeyCode:D,onlyRenderVisibleElements:G,elementsSelectable:J,defaultViewport:K,translateExtent:ne,minZoom:te,maxZoom:C,preventScrolling:R,defaultMarkerColor:B,zoomOnScroll:Y,zoomOnPinch:T,panOnScroll:H,panOnScrollSpeed:U,panOnScrollMode:M,zoomOnDoubleClick:A,panOnDrag:re,autoPanOnSelection:ie,onPaneClick:ce,onPaneMouseEnter:fe,onPaneMouseMove:de,onPaneMouseLeave:Q,onPaneScroll:le,onPaneContextMenu:me,paneClickDistance:ke,nodeClickDistance:xe,onEdgeContextMenu:pe,onEdgeMouseEnter:be,onEdgeMouseMove:Pe,onEdgeMouseLeave:Ce,reconnectRadius:Re,onReconnect:tt,onReconnectStart:nt,onReconnectEnd:Je,noDragClassName:Qe,noWheelClassName:ot,noPanClassName:Pt,disableKeyboardA11y:st,nodeExtent:ft,rfId:He,viewport:Le,onViewportChange:mt,nodesDraggable:an}){return dp(t),dp(r),KS(),HS(o),VS(Le),h.jsx(fS,{onPaneClick:ce,onPaneMouseEnter:fe,onPaneMouseMove:de,onPaneMouseLeave:Q,onPaneContextMenu:me,onPaneScroll:le,paneClickDistance:ke,deleteKeyCode:D,selectionKeyCode:P,selectionOnDrag:N,selectionMode:j,onSelectionStart:m,onSelectionEnd:S,multiSelectionKeyCode:L,panActivationKeyCode:z,zoomActivationKeyCode:W,elementsSelectable:J,zoomOnScroll:Y,zoomOnPinch:T,zoomOnDoubleClick:A,panOnScroll:H,panOnScrollSpeed:U,panOnScrollMode:M,panOnDrag:re,autoPanOnSelection:ie,defaultViewport:K,translateExtent:ne,minZoom:te,maxZoom:C,onSelectionContextMenu:x,preventScrolling:R,noDragClassName:Qe,noWheelClassName:ot,noPanClassName:Pt,disableKeyboardA11y:st,onViewportChange:mt,isControlledViewport:!!Le,children:h.jsxs(FS,{children:[h.jsx(OS,{edgeTypes:r,onEdgeClick:a,onEdgeDoubleClick:c,onReconnect:tt,onReconnectStart:nt,onReconnectEnd:Je,onlyRenderVisibleElements:G,onEdgeContextMenu:pe,onEdgeMouseEnter:be,onEdgeMouseMove:Pe,onEdgeMouseLeave:Ce,reconnectRadius:Re,defaultMarkerColor:B,noPanClassName:Pt,disableKeyboardA11y:st,rfId:He}),h.jsx(XS,{style:E,type:_,component:b,containerStyle:w}),h.jsx("div",{className:"react-flow__edgelabel-renderer"}),h.jsx(_S,{nodeTypes:t,onNodeClick:s,onNodeDoubleClick:u,onNodeMouseEnter:f,onNodeMouseMove:g,onNodeMouseLeave:y,onNodeContextMenu:v,nodeClickDistance:xe,onlyRenderVisibleElements:G,noPanClassName:Pt,noDragClassName:Qe,disableKeyboardA11y:st,nodeExtent:ft,rfId:He,nodesDraggable:an}),h.jsx("div",{className:"react-flow__viewport-portal"})]})})}dm.displayName="GraphView";const QS=F.memo(dm),ZS=hg(),fp=({nodes:t,edges:r,defaultNodes:o,defaultEdges:s,width:a,height:u,fitView:c,fitViewOptions:f,minZoom:g=.5,maxZoom:y=2,nodeOrigin:v,nodeExtent:x,zIndexMode:m="basic"}={})=>{const S=new Map,_=new Map,E=new Map,b=new Map,w=s??r??[],P=o??t??[],N=v??[0,0],j=x??Ao;Eg(E,b,w);const{nodesInitialized:L}=rc(P,S,_,{nodeOrigin:N,nodeExtent:j,zIndexMode:m});let z=[0,0,1];if(c&&a&&u){const W=Yo(S,{filter:K=>!!((K.width||K.initialWidth)&&(K.height||K.initialHeight))}),{x:D,y:G,zoom:J}=yc(W,a,u,g,y,(f==null?void 0:f.padding)??.1);z=[D,G,J]}return{rfId:"1",width:a??0,height:u??0,transform:z,nodes:P,nodesInitialized:L,nodeLookup:S,parentLookup:_,edges:w,edgeLookup:b,connectionLookup:E,onNodesChange:null,onEdgesChange:null,hasDefaultNodes:o!==void 0,hasDefaultEdges:s!==void 0,panZoom:null,minZoom:g,maxZoom:y,translateExtent:Ao,nodeExtent:j,nodesSelectionActive:!1,userSelectionActive:!1,userSelectionRect:null,connectionMode:zi.Strict,domNode:null,paneDragging:!1,noPanClassName:"nopan",nodeOrigin:N,nodeDragThreshold:1,connectionDragThreshold:1,snapGrid:[15,15],snapToGrid:!1,nodesDraggable:!0,nodesConnectable:!0,nodesFocusable:!0,edgesFocusable:!0,edgesReconnectable:!0,elementsSelectable:!0,elevateNodesOnSelect:!0,elevateEdgesOnSelect:!0,selectNodesOnDrag:!0,multiSelectionActive:!1,fitViewQueued:c??!1,fitViewOptions:f,fitViewResolver:null,connection:{...sg},connectionClickStartHandle:null,connectOnClick:!0,ariaLiveMessage:"",autoPanOnConnect:!0,autoPanOnNodeDrag:!0,autoPanOnNodeFocus:!0,autoPanSpeed:15,connectionRadius:20,onError:ZS,isValidConnection:void 0,onSelectionChangeHandlers:[],lib:"react",debug:!1,ariaLabelConfig:og,zIndexMode:m,onNodesChangeMiddlewareMap:new Map,onEdgesChangeMiddlewareMap:new Map}},JS=({nodes:t,edges:r,defaultNodes:o,defaultEdges:s,width:a,height:u,fitView:c,fitViewOptions:f,minZoom:g,maxZoom:y,nodeOrigin:v,nodeExtent:x,zIndexMode:m})=>d_((S,_)=>{async function E(){const{nodeLookup:b,panZoom:w,fitViewOptions:P,fitViewResolver:N,width:j,height:L,minZoom:z,maxZoom:W}=_();w&&(await l1({nodes:b,width:j,height:L,panZoom:w,minZoom:z,maxZoom:W},P),N==null||N.resolve(!0),S({fitViewResolver:null}))}return{...fp({nodes:t,edges:r,width:a,height:u,fitView:c,fitViewOptions:f,minZoom:g,maxZoom:y,nodeOrigin:v,nodeExtent:x,defaultNodes:o,defaultEdges:s,zIndexMode:m}),setNodes:b=>{const{nodeLookup:w,parentLookup:P,nodeOrigin:N,nodeExtent:j,elevateNodesOnSelect:L,fitViewQueued:z,zIndexMode:W,nodesSelectionActive:D}=_(),{nodesInitialized:G,hasSelectedNodes:J}=rc(b,w,P,{nodeOrigin:N,nodeExtent:j,elevateNodesOnSelect:L,checkEquality:!0,zIndexMode:W}),K=D&&J;z&&G?(E(),S({nodes:b,nodesInitialized:G,fitViewQueued:!1,fitViewOptions:void 0,nodesSelectionActive:K})):S({nodes:b,nodesInitialized:G,nodesSelectionActive:K})},setEdges:b=>{const{connectionLookup:w,edgeLookup:P}=_();Eg(w,P,b),S({edges:b})},setDefaultNodesAndEdges:(b,w)=>{if(b){const{setNodes:P}=_();P(b),S({hasDefaultNodes:!0})}if(w){const{setEdges:P}=_();P(w),S({hasDefaultEdges:!0})}},updateNodeInternals:b=>{const{triggerNodeChanges:w,nodeLookup:P,parentLookup:N,domNode:j,nodeOrigin:L,nodeExtent:z,debug:W,fitViewQueued:D,zIndexMode:G}=_(),{changes:J,updatedInternals:K}=P1(b,P,N,j,L,z,G);K&&(j1(P,N,{nodeOrigin:L,nodeExtent:z,zIndexMode:G}),D?(E(),S({fitViewQueued:!1,fitViewOptions:void 0})):S({}),(J==null?void 0:J.length)>0&&(W&&console.log("React Flow: trigger node changes",J),w==null||w(J)))},updateNodePositions:(b,w=!1)=>{const P=[];let N=[];const{nodeLookup:j,triggerNodeChanges:L,connection:z,updateConnection:W,onNodesChangeMiddlewareMap:D}=_();for(const[G,J]of b){const K=j.get(G),ne=!!(K!=null&&K.expandParent&&(K!=null&&K.parentId)&&(J!=null&&J.position)),te={id:G,type:"position",position:ne?{x:Math.max(0,J.position.x),y:Math.max(0,J.position.y)}:J.position,dragging:w};if(K&&z.inProgress&&z.fromNode.id===K.id){const C=Yr(K,z.fromHandle,Se.Left,!0);W({...z,from:C})}ne&&K.parentId&&P.push({id:G,parentId:K.parentId,rect:{...J.internals.positionAbsolute,width:J.measured.width??0,height:J.measured.height??0}}),N.push(te)}if(P.length>0){const{parentLookup:G,nodeOrigin:J}=_(),K=kc(P,j,G,J);N.push(...K)}for(const G of D.values())N=G(N);L(N)},triggerNodeChanges:b=>{const{onNodesChange:w,setNodes:P,nodes:N,hasDefaultNodes:j,debug:L}=_();if(b!=null&&b.length){if(j){const z=T_(b,N);P(z)}L&&console.log("React Flow: trigger node changes",b),w==null||w(b)}},triggerEdgeChanges:b=>{const{onEdgesChange:w,setEdges:P,edges:N,hasDefaultEdges:j,debug:L}=_();if(b!=null&&b.length){if(j){const z=R_(b,N);P(z)}L&&console.log("React Flow: trigger edge changes",b),w==null||w(b)}},addSelectedNodes:b=>{const{multiSelectionActive:w,edgeLookup:P,nodeLookup:N,triggerNodeChanges:j,triggerEdgeChanges:L}=_();if(w){const z=b.map(W=>Dr(W,!0));j(z);return}j(Ii(N,new Set([...b]),!0)),L(Ii(P))},addSelectedEdges:b=>{const{multiSelectionActive:w,edgeLookup:P,nodeLookup:N,triggerNodeChanges:j,triggerEdgeChanges:L}=_();if(w){const z=b.map(W=>Dr(W,!0));L(z);return}L(Ii(P,new Set([...b]))),j(Ii(N,new Set,!0))},unselectNodesAndEdges:({nodes:b,edges:w}={})=>{const{edges:P,nodes:N,nodeLookup:j,triggerNodeChanges:L,triggerEdgeChanges:z}=_(),W=b||N,D=w||P,G=[];for(const K of W){if(!K.selected)continue;const ne=j.get(K.id);ne&&(ne.selected=!1),G.push(Dr(K.id,!1))}const J=[];for(const K of D)K.selected&&J.push(Dr(K.id,!1));L(G),z(J)},setMinZoom:b=>{const{panZoom:w,maxZoom:P}=_();w==null||w.setScaleExtent([b,P]),S({minZoom:b})},setMaxZoom:b=>{const{panZoom:w,minZoom:P}=_();w==null||w.setScaleExtent([P,b]),S({maxZoom:b})},setTranslateExtent:b=>{var w;(w=_().panZoom)==null||w.setTranslateExtent(b),S({translateExtent:b})},resetSelectedElements:()=>{const{edges:b,nodes:w,triggerNodeChanges:P,triggerEdgeChanges:N,elementsSelectable:j}=_();if(!j)return;const L=w.reduce((W,D)=>D.selected?[...W,Dr(D.id,!1)]:W,[]),z=b.reduce((W,D)=>D.selected?[...W,Dr(D.id,!1)]:W,[]);P(L),N(z)},setNodeExtent:b=>{const{nodes:w,nodeLookup:P,parentLookup:N,nodeOrigin:j,elevateNodesOnSelect:L,nodeExtent:z,zIndexMode:W}=_();b[0][0]===z[0][0]&&b[0][1]===z[0][1]&&b[1][0]===z[1][0]&&b[1][1]===z[1][1]||(rc(w,P,N,{nodeOrigin:j,nodeExtent:b,elevateNodesOnSelect:L,checkEquality:!1,zIndexMode:W}),S({nodeExtent:b}))},panBy:b=>{const{transform:w,width:P,height:N,panZoom:j,translateExtent:L}=_();return I1({delta:b,panZoom:j,transform:w,translateExtent:L,width:P,height:N})},setCenter:async(b,w,P)=>{const{width:N,height:j,maxZoom:L,panZoom:z}=_();if(!z)return!1;const W=typeof(P==null?void 0:P.zoom)<"u"?P.zoom:L;return await z.setViewport({x:N/2-b*W,y:j/2-w*W,zoom:W},{duration:P==null?void 0:P.duration,ease:P==null?void 0:P.ease,interpolate:P==null?void 0:P.interpolate}),!0},cancelConnection:()=>{S({connection:{...sg}})},updateConnection:b=>{S({connection:b})},reset:()=>S({...fp()})}},Object.is);function fm({initialNodes:t,initialEdges:r,defaultNodes:o,defaultEdges:s,initialWidth:a,initialHeight:u,initialMinZoom:c,initialMaxZoom:f,initialFitViewOptions:g,fitView:y,nodeOrigin:v,nodeExtent:x,zIndexMode:m,children:S}){const[_]=F.useState(()=>JS({nodes:t,edges:r,defaultNodes:o,defaultEdges:s,width:a,height:u,fitView:y,minZoom:c,maxZoom:f,fitViewOptions:g,nodeOrigin:v,nodeExtent:x,zIndexMode:m}));return h.jsx(f_,{value:_,children:h.jsx($_,{children:h.jsx(J_,{children:S})})})}function ek({children:t,nodes:r,edges:o,defaultNodes:s,defaultEdges:a,width:u,height:c,fitView:f,fitViewOptions:g,minZoom:y,maxZoom:v,nodeOrigin:x,nodeExtent:m,zIndexMode:S}){return F.useContext(zl)?h.jsx(h.Fragment,{children:t}):h.jsx(fm,{initialNodes:r,initialEdges:o,defaultNodes:s,defaultEdges:a,initialWidth:u,initialHeight:c,fitView:f,initialFitViewOptions:g,initialMinZoom:y,initialMaxZoom:v,nodeOrigin:x,nodeExtent:m,zIndexMode:S,children:t})}const tk={width:"100%",height:"100%",overflow:"hidden",position:"relative",zIndex:0};function nk({nodes:t,edges:r,defaultNodes:o,defaultEdges:s,className:a,nodeTypes:u,edgeTypes:c,onNodeClick:f,onEdgeClick:g,onInit:y,onMove:v,onMoveStart:x,onMoveEnd:m,onConnect:S,onConnectStart:_,onConnectEnd:E,onClickConnectStart:b,onClickConnectEnd:w,onNodeMouseEnter:P,onNodeMouseMove:N,onNodeMouseLeave:j,onNodeContextMenu:L,onNodeDoubleClick:z,onNodeDragStart:W,onNodeDrag:D,onNodeDragStop:G,onNodesDelete:J,onEdgesDelete:K,onDelete:ne,onSelectionChange:te,onSelectionDragStart:C,onSelectionDrag:R,onSelectionDragStop:B,onSelectionContextMenu:Y,onSelectionStart:T,onSelectionEnd:H,onBeforeDelete:U,connectionMode:M,connectionLineType:A=hr.Bezier,connectionLineStyle:re,connectionLineComponent:ie,connectionLineContainerStyle:ce,deleteKeyCode:fe="Backspace",selectionKeyCode:de="Shift",selectionOnDrag:Q=!1,selectionMode:le=zo.Full,panActivationKeyCode:me="Space",multiSelectionKeyCode:ke=Oo()?"Meta":"Control",zoomActivationKeyCode:xe=Oo()?"Meta":"Control",snapToGrid:pe,snapGrid:be,onlyRenderVisibleElements:Pe=!1,selectNodesOnDrag:Ce,nodesDraggable:Re,autoPanOnNodeFocus:tt,nodesConnectable:nt,nodesFocusable:Je,nodeOrigin:Qe=$g,edgesFocusable:ot,edgesReconnectable:Pt,elementsSelectable:st=!0,defaultViewport:ft=E_,minZoom:He=.5,maxZoom:Le=2,translateExtent:mt=Ao,preventScrolling:an=!0,nodeExtent:ht,defaultMarkerColor:Gt="#b1b1b7",zoomOnScroll:_n=!0,zoomOnPinch:zn=!0,panOnScroll:Xr=!1,panOnScrollSpeed:It=.5,panOnScrollMode:Sn=Hr.Free,zoomOnDoubleClick:Dn=!0,panOnDrag:un=!0,onPaneClick:$n,onPaneMouseEnter:mr,onPaneMouseMove:cn,onPaneMouseLeave:dn,onPaneScroll:qr,onPaneContextMenu:Kr,paneClickDistance:Qr=1,nodeClickDistance:Zr=0,children:On,onReconnect:yr,onReconnectStart:Fn,onReconnectEnd:kn,onEdgeContextMenu:vr,onEdgeDoubleClick:fn,onEdgeMouseEnter:xr,onEdgeMouseMove:hn,onEdgeMouseLeave:Hn,reconnectRadius:Bn=10,onNodesChange:wr,onEdgesChange:Jr,noDragClassName:ei="nodrag",noWheelClassName:ti="nowheel",noPanClassName:Tt="nopan",fitView:Vn,fitViewOptions:Wn,connectOnClick:ni,attributionPosition:_r,proOptions:$,defaultEdgeOptions:ee,elevateNodesOnSelect:_e=!0,elevateEdgesOnSelect:Ie=!1,disableKeyboardA11y:Me=!1,autoPanOnConnect:Fe,autoPanOnNodeDrag:Bl,autoPanOnSelection:Bi=!0,autoPanSpeed:qo,connectionRadius:ri,isValidConnection:Vl,onError:Ko,style:ii,id:Rt,nodeDragThreshold:Wl,connectionDragThreshold:Lt,viewport:Ul,onViewportChange:Yl,width:Gl,height:oi,colorMode:si="light",debug:Sr,onScroll:Nn,ariaLabelConfig:Xl,zIndexMode:Qo="basic",...Vi},Zo){const kr=Rt||"1",Nr=M_(si),ql=F.useCallback(li=>{li.currentTarget.scrollTo({top:0,left:0,behavior:"instant"}),Nn==null||Nn(li)},[Nn]);return h.jsx("div",{"data-testid":"rf__wrapper",...Vi,onScroll:ql,style:{...ii,...tk},ref:Zo,className:it(["react-flow",a,Nr]),id:Rt,role:"application",children:h.jsxs(ek,{nodes:t,edges:r,width:Gl,height:oi,fitView:Vn,fitViewOptions:Wn,minZoom:He,maxZoom:Le,nodeOrigin:Qe,nodeExtent:ht,zIndexMode:Qo,children:[h.jsx(C_,{nodes:t,edges:r,defaultNodes:o,defaultEdges:s,onConnect:S,onConnectStart:_,onConnectEnd:E,onClickConnectStart:b,onClickConnectEnd:w,nodesDraggable:Re,autoPanOnNodeFocus:tt,nodesConnectable:nt,nodesFocusable:Je,edgesFocusable:ot,edgesReconnectable:Pt,elementsSelectable:st,elevateNodesOnSelect:_e,elevateEdgesOnSelect:Ie,minZoom:He,maxZoom:Le,nodeExtent:ht,onNodesChange:wr,onEdgesChange:Jr,snapToGrid:pe,snapGrid:be,connectionMode:M,translateExtent:mt,connectOnClick:ni,defaultEdgeOptions:ee,fitView:Vn,fitViewOptions:Wn,onNodesDelete:J,onEdgesDelete:K,onDelete:ne,onNodeDragStart:W,onNodeDrag:D,onNodeDragStop:G,onSelectionDrag:R,onSelectionDragStart:C,onSelectionDragStop:B,onMove:v,onMoveStart:x,onMoveEnd:m,noPanClassName:Tt,nodeOrigin:Qe,rfId:kr,autoPanOnConnect:Fe,autoPanOnNodeDrag:Bl,autoPanSpeed:qo,onError:Ko,connectionRadius:ri,isValidConnection:Vl,selectNodesOnDrag:Ce,nodeDragThreshold:Wl,connectionDragThreshold:Lt,onBeforeDelete:U,debug:Sr,ariaLabelConfig:Xl,zIndexMode:Qo}),h.jsx(QS,{onInit:y,onNodeClick:f,onEdgeClick:g,onNodeMouseEnter:P,onNodeMouseMove:N,onNodeMouseLeave:j,onNodeContextMenu:L,onNodeDoubleClick:z,nodeTypes:u,edgeTypes:c,connectionLineType:A,connectionLineStyle:re,connectionLineComponent:ie,connectionLineContainerStyle:ce,selectionKeyCode:de,selectionOnDrag:Q,selectionMode:le,deleteKeyCode:fe,multiSelectionKeyCode:ke,panActivationKeyCode:me,zoomActivationKeyCode:xe,onlyRenderVisibleElements:Pe,defaultViewport:ft,translateExtent:mt,minZoom:He,maxZoom:Le,preventScrolling:an,zoomOnScroll:_n,zoomOnPinch:zn,zoomOnDoubleClick:Dn,panOnScroll:Xr,panOnScrollSpeed:It,panOnScrollMode:Sn,panOnDrag:un,autoPanOnSelection:Bi,onPaneClick:$n,onPaneMouseEnter:mr,onPaneMouseMove:cn,onPaneMouseLeave:dn,onPaneScroll:qr,onPaneContextMenu:Kr,paneClickDistance:Qr,nodeClickDistance:Zr,onSelectionContextMenu:Y,onSelectionStart:T,onSelectionEnd:H,onReconnect:yr,onReconnectStart:Fn,onReconnectEnd:kn,onEdgeContextMenu:vr,onEdgeDoubleClick:fn,onEdgeMouseEnter:xr,onEdgeMouseMove:hn,onEdgeMouseLeave:Hn,reconnectRadius:Bn,defaultMarkerColor:Gt,noDragClassName:ei,noWheelClassName:ti,noPanClassName:Tt,rfId:kr,disableKeyboardA11y:Me,nodeExtent:ht,viewport:Ul,onViewportChange:Yl,nodesDraggable:Re}),h.jsx(N_,{onSelectionChange:te}),On,h.jsx(x_,{proOptions:$,position:_r}),h.jsx(v_,{rfId:kr,disableKeyboardA11y:Me})]})})}var rk=Fg(nk);function ik({dimensions:t,lineWidth:r,variant:o,className:s}){return h.jsx("path",{strokeWidth:r,d:`M${t[0]/2} 0 V${t[1]} M0 ${t[1]/2} H${t[0]}`,className:it(["react-flow__background-pattern",o,s])})}function ok({radius:t,className:r}){return h.jsx("circle",{cx:t,cy:t,r:t,className:it(["react-flow__background-pattern","dots",r])})}var pr;(function(t){t.Lines="lines",t.Dots="dots",t.Cross="cross"})(pr||(pr={}));const sk={[pr.Dots]:1,[pr.Lines]:1,[pr.Cross]:6},lk=t=>({transform:t.transform,patternId:`pattern-${t.rfId}`});function hm({id:t,variant:r=pr.Dots,gap:o=20,size:s,lineWidth:a=1,offset:u=0,color:c,bgColor:f,style:g,className:y,patternClassName:v}){const x=F.useRef(null),{transform:m,patternId:S}=ze(lk,Ke),_=s||sk[r],E=r===pr.Dots,b=r===pr.Cross,w=Array.isArray(o)?o:[o,o],P=[w[0]*m[2]||1,w[1]*m[2]||1],N=_*m[2],j=Array.isArray(u)?u:[u,u],L=b?[N,N]:P,z=[j[0]*m[2]+L[0]/2,j[1]*m[2]+L[1]/2],W=`${S}${t||""}`;return h.jsxs("svg",{className:it(["react-flow__background",y]),style:{...g,...Ol,"--xy-background-color-props":f,"--xy-background-pattern-color-props":c},ref:x,"data-testid":"rf__background",children:[h.jsx("pattern",{id:W,x:m[0]%P[0],y:m[1]%P[1],width:P[0],height:P[1],patternUnits:"userSpaceOnUse",patternTransform:`translate(-${z[0]},-${z[1]})`,children:E?h.jsx(ok,{radius:N/2,className:v}):h.jsx(ik,{dimensions:L,lineWidth:a,variant:r,className:v})}),h.jsx("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:`url(#${W})`})]})}hm.displayName="Background";const ak=F.memo(hm);function uk(){return h.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32",children:h.jsx("path",{d:"M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z"})})}function ck(){return h.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 5",children:h.jsx("path",{d:"M0 0h32v4.2H0z"})})}function dk(){return h.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 30",children:h.jsx("path",{d:"M3.692 4.63c0-.53.4-.938.939-.938h5.215V0H4.708C2.13 0 0 2.054 0 4.63v5.216h3.692V4.631zM27.354 0h-5.2v3.692h5.17c.53 0 .984.4.984.939v5.215H32V4.631A4.624 4.624 0 0027.354 0zm.954 24.83c0 .532-.4.94-.939.94h-5.215v3.768h5.215c2.577 0 4.631-2.13 4.631-4.707v-5.139h-3.692v5.139zm-23.677.94c-.531 0-.939-.4-.939-.94v-5.138H0v5.139c0 2.577 2.13 4.707 4.708 4.707h5.138V25.77H4.631z"})})}function fk(){return h.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:h.jsx("path",{d:"M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0 8 0 4.571 3.429 4.571 7.619v3.048H3.048A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047zm4.724-13.866H7.467V7.619c0-2.59 2.133-4.724 4.723-4.724 2.591 0 4.724 2.133 4.724 4.724v3.048z"})})}function hk(){return h.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:h.jsx("path",{d:"M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0c-4.114 1.828-1.37 2.133.305 2.438 1.676.305 4.42 2.59 4.42 5.181v3.048H3.047A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047z"})})}function al({children:t,className:r,...o}){return h.jsx("button",{type:"button",className:it(["react-flow__controls-button",r]),...o,children:t})}const pk=t=>({isInteractive:t.nodesDraggable||t.nodesConnectable||t.elementsSelectable,minZoomReached:t.transform[2]<=t.minZoom,maxZoomReached:t.transform[2]>=t.maxZoom,ariaLabelConfig:t.ariaLabelConfig});function pm({style:t,showZoom:r=!0,showFitView:o=!0,showInteractive:s=!0,fitViewOptions:a,onZoomIn:u,onZoomOut:c,onFitView:f,onInteractiveChange:g,className:y,children:v,position:x="bottom-left",orientation:m="vertical","aria-label":S}){const _=Ye(),{isInteractive:E,minZoomReached:b,maxZoomReached:w,ariaLabelConfig:P}=ze(pk,Ke),{zoomIn:N,zoomOut:j,fitView:L}=$l(),z=()=>{N(),u==null||u()},W=()=>{j(),c==null||c()},D=()=>{L(a),f==null||f()},G=()=>{_.setState({nodesDraggable:!E,nodesConnectable:!E,elementsSelectable:!E}),g==null||g(!E)},J=m==="horizontal"?"horizontal":"vertical";return h.jsxs(Dl,{className:it(["react-flow__controls",J,y]),position:x,style:t,"data-testid":"rf__controls","aria-label":S??P["controls.ariaLabel"],children:[r&&h.jsxs(h.Fragment,{children:[h.jsx(al,{onClick:z,className:"react-flow__controls-zoomin",title:P["controls.zoomIn.ariaLabel"],"aria-label":P["controls.zoomIn.ariaLabel"],disabled:w,children:h.jsx(uk,{})}),h.jsx(al,{onClick:W,className:"react-flow__controls-zoomout",title:P["controls.zoomOut.ariaLabel"],"aria-label":P["controls.zoomOut.ariaLabel"],disabled:b,children:h.jsx(ck,{})})]}),o&&h.jsx(al,{className:"react-flow__controls-fitview",onClick:D,title:P["controls.fitView.ariaLabel"],"aria-label":P["controls.fitView.ariaLabel"],children:h.jsx(dk,{})}),s&&h.jsx(al,{className:"react-flow__controls-interactive",onClick:G,title:P["controls.interactive.ariaLabel"],"aria-label":P["controls.interactive.ariaLabel"],children:E?h.jsx(hk,{}):h.jsx(fk,{})}),v]})}pm.displayName="Controls";const gk=F.memo(pm);function mk({id:t,x:r,y:o,width:s,height:a,style:u,color:c,strokeColor:f,strokeWidth:g,className:y,borderRadius:v,shapeRendering:x,selected:m,onClick:S}){const{background:_,backgroundColor:E}=u||{},b=c||_||E;return h.jsx("rect",{className:it(["react-flow__minimap-node",{selected:m},y]),x:r,y:o,rx:v,ry:v,width:s,height:a,style:{fill:b,stroke:f,strokeWidth:g},shapeRendering:x,onClick:S?w=>S(w,t):void 0})}const yk=F.memo(mk),vk=t=>t.nodes.map(r=>r.id),Vu=t=>t instanceof Function?t:()=>t;function xk({nodeStrokeColor:t,nodeColor:r,nodeClassName:o="",nodeBorderRadius:s=5,nodeStrokeWidth:a,nodeComponent:u=yk,onClick:c}){const f=ze(vk,Ke),g=Vu(r),y=Vu(t),v=Vu(o),x=typeof window>"u"||window.chrome?"crispEdges":"geometricPrecision";return h.jsx(h.Fragment,{children:f.map(m=>h.jsx(_k,{id:m,nodeColorFunc:g,nodeStrokeColorFunc:y,nodeClassNameFunc:v,nodeBorderRadius:s,nodeStrokeWidth:a,NodeComponent:u,onClick:c,shapeRendering:x},m))})}function wk({id:t,nodeColorFunc:r,nodeStrokeColorFunc:o,nodeClassNameFunc:s,nodeBorderRadius:a,nodeStrokeWidth:u,shapeRendering:c,NodeComponent:f,onClick:g}){const{node:y,x:v,y:x,width:m,height:S}=ze(_=>{const E=_.nodeLookup.get(t);if(!E)return{node:void 0,x:0,y:0,width:0,height:0};const b=E.internals.userNode,{x:w,y:P}=E.internals.positionAbsolute,{width:N,height:j}=ln(b);return{node:b,x:w,y:P,width:N,height:j}},Ke);return!y||y.hidden||!pg(y)?null:h.jsx(f,{x:v,y:x,width:m,height:S,style:y.style,selected:!!y.selected,className:s(y),color:r(y),borderRadius:a,strokeColor:o(y),strokeWidth:u,shapeRendering:c,onClick:g,id:y.id})}const _k=F.memo(wk);var Sk=F.memo(xk);const kk=200,Nk=150,Ek=t=>!t.hidden,jk=t=>{const r={x:-t.transform[0]/t.transform[2],y:-t.transform[1]/t.transform[2],width:t.width/t.transform[2],height:t.height/t.transform[2]};return{viewBB:r,boundingRect:t.nodeLookup.size>0?dg(Yo(t.nodeLookup,{filter:Ek}),r):r,rfId:t.rfId,panZoom:t.panZoom,translateExtent:t.translateExtent,flowWidth:t.width,flowHeight:t.height,ariaLabelConfig:t.ariaLabelConfig}},hp=(t,r)=>t.x===r.x&&t.y===r.y&&t.width===r.width&&t.height===r.height,bk=(t,r)=>hp(t.viewBB,r.viewBB)&&hp(t.boundingRect,r.boundingRect)&&t.rfId===r.rfId&&t.panZoom===r.panZoom&&t.translateExtent===r.translateExtent&&t.flowWidth===r.flowWidth&&t.flowHeight===r.flowHeight&&t.ariaLabelConfig===r.ariaLabelConfig,Ck="react-flow__minimap-desc";function gm({style:t,className:r,nodeStrokeColor:o,nodeColor:s,nodeClassName:a="",nodeBorderRadius:u=5,nodeStrokeWidth:c,nodeComponent:f,bgColor:g,maskColor:y,maskStrokeColor:v,maskStrokeWidth:x,position:m="bottom-right",onClick:S,onNodeClick:_,pannable:E=!1,zoomable:b=!1,ariaLabel:w,inversePan:P,zoomStep:N=1,offsetScale:j=5}){const L=Ye(),z=F.useRef(null),{boundingRect:W,viewBB:D,rfId:G,panZoom:J,translateExtent:K,flowWidth:ne,flowHeight:te,ariaLabelConfig:C}=ze(jk,bk),R=(t==null?void 0:t.width)??kk,B=(t==null?void 0:t.height)??Nk,Y=W.width/R,T=W.height/B,H=Math.max(Y,T),U=H*R,M=H*B,A=j*H,re=W.x-(U-W.width)/2-A,ie=W.y-(M-W.height)/2-A,ce=U+A*2,fe=M+A*2,de=`${Ck}-${G}`,Q=F.useRef(0),le=F.useRef();Q.current=H,F.useEffect(()=>{if(z.current&&J)return le.current=F1({domNode:z.current,panZoom:J,getTransform:()=>L.getState().transform,getViewScale:()=>Q.current}),()=>{var pe;(pe=le.current)==null||pe.destroy()}},[J]),F.useEffect(()=>{var pe;(pe=le.current)==null||pe.update({translateExtent:K,width:ne,height:te,inversePan:P,pannable:E,zoomStep:N,zoomable:b})},[E,b,P,N,K,ne,te]);const me=S?pe=>{var Ce;const[be,Pe]=((Ce=le.current)==null?void 0:Ce.pointer(pe))||[0,0];S(pe,{x:be,y:Pe})}:void 0,ke=_?F.useCallback((pe,be)=>{const Pe=L.getState().nodeLookup.get(be).internals.userNode;_(pe,Pe)},[]):void 0,xe=w??C["minimap.ariaLabel"];return h.jsx(Dl,{position:m,style:{...t,"--xy-minimap-background-color-props":typeof g=="string"?g:void 0,"--xy-minimap-mask-background-color-props":typeof y=="string"?y:void 0,"--xy-minimap-mask-stroke-color-props":typeof v=="string"?v:void 0,"--xy-minimap-mask-stroke-width-props":typeof x=="number"?x*H:void 0,"--xy-minimap-node-background-color-props":typeof s=="string"?s:void 0,"--xy-minimap-node-stroke-color-props":typeof o=="string"?o:void 0,"--xy-minimap-node-stroke-width-props":typeof c=="number"?c:void 0},className:it(["react-flow__minimap",r]),"data-testid":"rf__minimap",children:h.jsxs("svg",{width:R,height:B,viewBox:`${re} ${ie} ${ce} ${fe}`,className:"react-flow__minimap-svg",role:"img","aria-labelledby":de,ref:z,onClick:me,children:[xe&&h.jsx("title",{id:de,children:xe}),h.jsx(Sk,{onClick:ke,nodeColor:s,nodeStrokeColor:o,nodeBorderRadius:u,nodeClassName:a,nodeStrokeWidth:c,nodeComponent:f}),h.jsx("path",{className:"react-flow__minimap-mask",d:`M${re-A},${ie-A}h${ce+A*2}v${fe+A*2}h${-ce-A*2}z + M${D.x},${D.y}h${D.width}v${D.height}h${-D.width}z`,fillRule:"evenodd",pointerEvents:"none"})]})})}gm.displayName="MiniMap";const Mk=F.memo(gm),Pk=t=>r=>t?`${Math.max(1/r.transform[2],1)}`:void 0,Ik={[Oi.Line]:"right",[Oi.Handle]:"bottom-right"};function Tk({nodeId:t,position:r,variant:o=Oi.Handle,className:s,style:a=void 0,children:u,color:c,minWidth:f=10,minHeight:g=10,maxWidth:y=Number.MAX_VALUE,maxHeight:v=Number.MAX_VALUE,keepAspectRatio:x=!1,resizeDirection:m,autoScale:S=!0,shouldResize:_,onResizeStart:E,onResize:b,onResizeEnd:w}){const P=Ug(),N=typeof t=="string"?t:P,j=Ye(),L=F.useRef(null),z=o===Oi.Handle,W=ze(F.useCallback(Pk(z&&S),[z,S]),Ke),D=F.useRef(null),G=r??Ik[o];F.useEffect(()=>{if(!(!L.current||!N))return D.current||(D.current=J1({domNode:L.current,nodeId:N,getStoreItems:()=>{const{nodeLookup:K,transform:ne,snapGrid:te,snapToGrid:C,nodeOrigin:R,domNode:B}=j.getState();return{nodeLookup:K,transform:ne,snapGrid:te,snapToGrid:C,nodeOrigin:R,paneDomNode:B}},onChange:(K,ne)=>{const{triggerNodeChanges:te,nodeLookup:C,parentLookup:R,nodeOrigin:B}=j.getState(),Y=[],T={x:K.x,y:K.y},H=C.get(N);if(H&&H.expandParent&&H.parentId){const U=H.origin??B,M=K.width??H.measured.width??0,A=K.height??H.measured.height??0,re={id:H.id,parentId:H.parentId,rect:{width:M,height:A,...gg({x:K.x??H.position.x,y:K.y??H.position.y},{width:M,height:A},H.parentId,C,U)}},ie=kc([re],C,R,B);Y.push(...ie),T.x=K.x?Math.max(U[0]*M,K.x):void 0,T.y=K.y?Math.max(U[1]*A,K.y):void 0}if(T.x!==void 0&&T.y!==void 0){const U={id:N,type:"position",position:{...T}};Y.push(U)}if(K.width!==void 0&&K.height!==void 0){const M={id:N,type:"dimensions",resizing:!0,setAttributes:m?m==="horizontal"?"width":"height":!0,dimensions:{width:K.width,height:K.height}};Y.push(M)}for(const U of ne){const M={...U,type:"position"};Y.push(M)}te(Y)},onEnd:({width:K,height:ne})=>{const te={id:N,type:"dimensions",resizing:!1,dimensions:{width:K,height:ne}};j.getState().triggerNodeChanges([te])}})),D.current.update({controlPosition:G,boundaries:{minWidth:f,minHeight:g,maxWidth:y,maxHeight:v},keepAspectRatio:x,resizeDirection:m,onResizeStart:E,onResize:b,onResizeEnd:w,shouldResize:_}),()=>{var K;(K=D.current)==null||K.destroy()}},[G,f,g,y,v,x,E,b,w,_]);const J=G.split("-");return h.jsx("div",{className:it(["react-flow__resize-control","nodrag",...J,o,s]),ref:L,style:{...a,scale:W,...c&&{[z?"backgroundColor":"borderColor"]:c}},children:u})}F.memo(Tk);const Rk={"arch.context":0,"django.app":0,"django.route":1,"django.websocket_route":1,"fastapi.route":1,"django.url_name":2,"django.view":3,"django.viewset_action":3,"django.permission":3,"django.throttle":3,"django.serializer":4,"django.form":4,"graphql.type":4,"fastapi.model":4,"django.serializer_field":5,"django.service":5,"graphql.field":5,"django.model":6,"django.field":7,"django.relation":7,"django.task":8,"django.receiver":8,"django.signal":8,"django.test":8,"django.migration_op":8,"django.admin":8,"django.management_command":8,"django.consumer":8,"django.cache_key":8,"django.feature_flag":8,"django.side_effect":8,"openapi.path":9,"graphql.operation":9,"react.api_client":10,"django.htmx":10,"react.query_key":11,"react.hook":11,"react.feature":11,"react.route":12,"react.page":12,"react.server_action":12,"django.template":12,"react.component":13,"react.context":13,"react.form_schema":14,"react.test":14};function Hi(t){return Rk[t]??8}const gr=208,Ho=64,Hl=88,Ec=28,Lk=8;function Ak(t){if(!t.length)return Number.NaN;const r=[...t].sort((s,a)=>s-a),o=Math.floor(r.length/2);return r.length%2?r[o]:(r[o-1]+r[o])/2}function zk(t,r=[]){const o=new Map;if(!t.length)return o;const s=new Map;for(const w of t){const P=Hi(w.type),N=s.get(P)??[];N.push(w),s.set(P,N)}const u=[...s.keys()].sort((w,P)=>w-P).map(w=>[...s.get(w)??[]].sort((P,N)=>P.name.localeCompare(N.name)||P.id.localeCompare(N.id))),c=new Set(t.map(w=>w.id)),f=new Map,g=new Map;for(const w of t)f.set(w.id,[]),g.set(w.id,[]);for(const w of r)!c.has(w.src)||!c.has(w.dst)||w.src===w.dst||(g.get(w.src).push(w.dst),f.get(w.dst).push(w.src));const y=new Map;u.forEach((w,P)=>{for(const N of w)y.set(N.id,P)});const v=new Map,x=()=>{for(const w of u)w.forEach((P,N)=>v.set(P.id,N))};x();const m=(w,P)=>{const N=w.map((j,L)=>{const z=P(j.id).map(D=>v.get(D)).filter(D=>D!==void 0),W=Ak(z);return{n:j,bary:Number.isNaN(W)?L:W,name:j.name,id:j.id}});return N.sort((j,L)=>j.bary-L.bary||j.name.localeCompare(L.name)||j.id.localeCompare(L.id)),N.map(j=>j.n)},S=w=>P=>y.get(P)===w;for(let w=0;w(f.get(N)??[]).filter(S(P-1))),x();for(let P=u.length-2;P>=0;P--)u[P]=m(u[P],N=>(g.get(N)??[]).filter(S(P+1))),x()}const _=gr+Hl,E=Ho+Ec,b=Math.max(...u.map(w=>w.length),1);return u.forEach((w,P)=>{const N=(b-w.length)*E/2;w.forEach((j,L)=>{o.set(j.id,{x:P*_,y:N+L*E})})}),o}const sc=[{id:"layers",label:"Architecture layers"},{id:"flow",label:"Edge flow"},{id:"radial",label:"Radial"},{id:"grid",label:"Compact grid"}],Dk=new Set(sc.map(t=>t.id)),mm="loadpath.graphLayout",$k=8,ym=90,Ok=new Set(["django.field","django.serializer_field","django.relation","django.test","react.test","graphql.field","django.url_name","django.throttle"]),pp={"arch.context":"#edf2f4","django.app":"#8d99ae","django.route":"#4cc9f0","django.url_name":"#4cc9f0","django.view":"#4895ef","django.viewset_action":"#4361ee","django.permission":"#7b8cde","django.serializer":"#f4a261","django.form":"#e9c46a","django.serializer_field":"#e9c46a","django.service":"#90be6d","django.model":"#2a9d8f","django.field":"#8ac926","django.task":"#e76f51","django.receiver":"#e85d04","django.signal":"#f4a261","django.test":"#6c757d","django.admin":"#adb5bd","django.migration_op":"#9d4edd","django.consumer":"#e76f51","django.websocket_route":"#4cc9f0","django.template":"#c77dff","django.htmx":"#ff6b6b","django.cache_key":"#6c757d","django.feature_flag":"#f4a261","django.side_effect":"#e85d04","graphql.type":"#00bbf9","graphql.operation":"#00bbf9","fastapi.route":"#4cc9f0","fastapi.model":"#f4a261","openapi.path":"#00bbf9","react.api_client":"#ff6b6b","react.query_key":"#adb5bd","react.hook":"#7b2cbf","react.feature":"#9d4edd","react.route":"#c77dff","react.page":"#c77dff","react.server_action":"#e76f51","react.component":"#9d4edd","react.form_schema":"#ffd166","react.test":"#6c757d"},Fk=Math.PI*(3-Math.sqrt(5)),vm=220,Hk=26,Bk={0:"context",1:"routes",2:"url names",3:"views",4:"serializers",5:"services",6:"models",7:"fields",8:"jobs / signals",9:"openapi",10:"api client",11:"hooks",12:"pages",13:"components",14:"forms / tests"};function xm(t){return t.startsWith("react.")?"react":t.startsWith("openapi.")||t.startsWith("graphql.")||t.startsWith("fastapi.")?"stitch":t.startsWith("arch.")?"arch":"django"}function AN(t){return pp[t]?pp[t]:t.startsWith("react.")?"#9d4edd":t.startsWith("openapi.")?"#00bbf9":"#4a5568"}function Vk(t){return t>=ym?"3d":"2d"}function Wk(t){return t>=ym?"overview":"full"}function Uk(t,r,o=1){const s=new Set([t]);let a=new Set([t]);for(let u=0;uo.families.has(xm(f.type)));o.detail==="overview"&&(s=s.filter(f=>!Ok.has(f.type)));const a=new Set(s.map(f=>f.id)),u=r.filter(f=>a.has(f.src)&&a.has(f.dst)),c=o.focusId?Uk(o.focusId,u,1):new Set;if(o.neighborhoodOnly&&o.focusId&&c.size){s=s.filter(g=>c.has(g.id));const f=new Set(s.map(g=>g.id));return{nodes:s,edges:u.filter(g=>f.has(g.src)&&f.has(g.dst)),neighborIds:c}}return{nodes:s,edges:u,neighborIds:c}}function zN(t){const r=new Map;for(const s of t){const a=Hi(s.type),u=r.get(a)??[];u.push(s),r.set(a,u)}const o=new Map;for(const[s,a]of r){a.sort((c,f)=>c.name.localeCompare(f.name));const u=s*vm;a.forEach((c,f)=>{if(a.length===1){o.set(c.id,{x:u,y:0,z:0});return}const g=Hk*Math.sqrt(f+1),y=f*Fk;o.set(c.id,{x:u,y:g*Math.cos(y),z:g*Math.sin(y)})})}return o}function DN(t){const r=new Map;for(const o of t){const s=Hi(o.type);r.set(s,(r.get(s)||0)+1)}return[...r.entries()].sort((o,s)=>o[0]-s[0]).map(([o,s])=>({layer:o,x:o*vm,count:s}))}function Gk(){if(typeof localStorage>"u")return"layers";const t=localStorage.getItem(mm);return t&&Dk.has(t)?t:"layers"}function Xk(t){typeof localStorage>"u"||localStorage.setItem(mm,t)}function qk(t){return t==="layers"||t==="flow"}function Kk(t){if(!t.length)return Number.NaN;const r=[...t].sort((s,a)=>s-a),o=Math.floor(r.length/2);return r.length%2?r[o]:(r[o-1]+r[o])/2}function Mo(t,r){return t.name.localeCompare(r.name)||t.id.localeCompare(r.id)}function Qk(t,r){const o=new Map;if(!t.length)return o;const s=new Set(t.flat().map(_=>_.id)),a=new Map,u=new Map;for(const _ of t.flat())a.set(_.id,[]),u.set(_.id,[]);for(const _ of r)!s.has(_.src)||!s.has(_.dst)||_.src===_.dst||(u.get(_.src).push(_.dst),a.get(_.dst).push(_.src));const c=new Map;t.forEach((_,E)=>{for(const b of _)c.set(b.id,E)});const f=new Map,g=()=>{for(const _ of t)_.forEach((E,b)=>f.set(E.id,b))};g();const y=(_,E)=>{const b=_.map((w,P)=>{const N=E(w.id).map(L=>f.get(L)).filter(L=>L!==void 0),j=Kk(N);return{n:w,bary:Number.isNaN(j)?P:j,name:w.name,id:w.id}});return b.sort((w,P)=>w.bary-P.bary||w.name.localeCompare(P.name)||w.id.localeCompare(P.id)),b.map(w=>w.n)},v=_=>E=>c.get(E)===_;for(let _=0;_<$k;_++){for(let E=1;E(a.get(b)??[]).filter(v(E-1))),g();for(let E=t.length-2;E>=0;E--)t[E]=y(t[E],b=>(u.get(b)??[]).filter(v(E+1))),g()}const x=gr+Hl,m=Ho+Ec,S=Math.max(...t.map(_=>_.length),1);return t.forEach((_,E)=>{const b=(S-_.length)*m/2;_.forEach((w,P)=>{o.set(w.id,{x:E*x,y:b+P*m})})}),o}function Zk(t,r){const o=new Set(t.map(c=>c.id)),s=new Map;for(const c of t)s.set(c.id,0);for(let c=0;c(s.get(g.dst)||0)&&(s.set(g.dst,y),f=!0)}if(!f)break}const a=new Map;for(const c of t){const f=s.get(c.id)||0,g=a.get(f)??[];g.push(c),a.set(f,g)}const u=[...a.keys()].sort((c,f)=>c-f).map(c=>(a.get(c)??[]).sort(Mo));return Qk(u,r)}function Jk(t,r){const o=new Map;if(!t.length)return o;const s=new Set(t.map(m=>m.id)),a=new Map,u=new Map;for(const m of t)a.set(m.id,[]),u.set(m.id,0);for(const m of r)!s.has(m.src)||!s.has(m.dst)||m.src===m.dst||(a.get(m.src).push(m.dst),a.get(m.dst).push(m.src),u.set(m.src,(u.get(m.src)||0)+1),u.set(m.dst,(u.get(m.dst)||0)+1));const c=[...t].sort((m,S)=>(u.get(S.id)||0)-(u.get(m.id)||0)||Mo(m,S))[0]??t[0],f=new Map,g=[[c]];f.set(c.id,0);const y=[c];for(;y.length;){const m=y.shift(),S=f.get(m.id)||0,_=(a.get(m.id)??[]).map(E=>t.find(b=>b.id===E)).filter(E=>!!E).sort(Mo);for(const E of _){if(f.has(E.id))continue;f.set(E.id,S+1);const b=g[S+1]??[];b.push(E),g[S+1]=b,y.push(E)}}const v=t.filter(m=>!f.has(m.id)).sort(Mo);v.length&&g.push(v);const x=gr+32;return g.forEach((m,S)=>{if(S===0&&m.length===1){o.set(m[0].id,{x:0,y:0});return}const _=Math.max(S*(gr+Hl),m.length<=1?gr:m.length*x/(2*Math.PI));m.forEach((E,b)=>{const w=-Math.PI/2+2*Math.PI*b/m.length;o.set(E.id,{x:Math.cos(w)*_,y:Math.sin(w)*_})})}),o}function eN(t){const r=new Map,o=[...t].sort((c,f)=>Hi(c.type)-Hi(f.type)||Mo(c,f)),s=Math.max(1,Math.ceil(Math.sqrt(o.length))),a=gr+Hl,u=Ho+Ec;return o.forEach((c,f)=>{r.set(c.id,{x:f%s*a,y:Math.floor(f/s)*u})}),r}function tN(t,r=[],o="layers"){return o==="flow"?Zk(t,r):o==="radial"?Jk(t,r):o==="grid"?eN(t):zk(t,r)}const ul=16,nN=12,rN=new Set(["django.route","react.route","react.page","react.server_action","django.task","django.migration_op","django.permission","django.throttle","django.admin","django.management_command","openapi.path","django.consumer","django.websocket_route","django.template","django.cache_key","django.feature_flag","django.side_effect","graphql.operation","fastapi.route"]),iN=new Set(["django.serializer","django.serializer_field","django.form","openapi.path","react.form_schema","django.route","graphql.type","graphql.field","graphql.operation","fastapi.model","fastapi.route"]),gp={"arch.context":"Ownership boundary from loadpath.yml — the context this code belongs to.","django.app":"Django app package that owns models, views, and jobs.","django.route":"HTTP URL that publishes a view. A sink: this is where a change becomes a public request.","django.url_name":"Named URL used by reverse() / {% url %} lookups.","django.view":"Request handler (class-based view, function view, or ViewSet).","django.viewset_action":"One ViewSet action (list, create, retrieve, update, destroy).","django.permission":"Auth gate on a view — who is allowed to hit this path.","django.throttle":"Rate-limit class attached to a view.","django.serializer":"Request/response contract: which fields go in and come out.","django.form":"Django form or django-filter FilterSet — the typed input contract.","django.serializer_field":"One field on a serializer or form — the typed slot on the contract.","django.service":"Internal service or use-case. Work that is not itself an HTTP sink.","django.model":"ORM model. Schema and relations live here.","django.field":"Model column. Type, indexes, and relations are the contract of the table.","django.relation":"Model-to-model relation (FK / M2M / O2O).","django.task":"Celery or Dramatiq job. Once enqueued, this is a sink.","django.receiver":"Signal handler that runs after a model event.","django.signal":"Django signal that receivers subscribe to.","django.test":"Backend test that mentions symbols on this path.","django.admin":"Django admin class for a model.","django.migration_op":"Schema migration operation (CreateModel, AlterField, …).","django.management_command":"manage.py command — an operational sink.","django.consumer":"Django Channels WebSocket/HTTP consumer. A sink once a client connects.","django.websocket_route":"ASGI WebSocket URL. A sink: this is where a change becomes a live connection.","django.template":"Django template. HTML (and HTMX) the server renders.","django.htmx":"HTMX call from a template to a URL — another published seam.","django.cache_key":"Cache get/set key. Invalidation is part of the load path.","django.feature_flag":"Feature flag checked on this path. The change may be dark-launched.","django.side_effect":"transaction.on_commit (or similar) side effect that runs after the request commits.","graphql.type":"GraphQL object/input type — a published contract.","graphql.field":"One field on a GraphQL type.","graphql.operation":"GraphQL query, mutation, or subscription. A published contract and a sink.","fastapi.route":"FastAPI path operation sitting next to Django in this repo.","fastapi.model":"Pydantic response/request model — the FastAPI contract.","openapi.path":"Generated OpenAPI operation. The typed HTTP contract between stacks.","react.api_client":"Frontend fetch or generated client call to an API path.","react.query_key":"React Query cache key. Invalidation and reads share this name.","react.hook":"Data hook wrapping query or mutation calls.","react.feature":"Frontend feature module (folder).","react.route":"Client-side route. A sink: this is a URL the user can open.","react.page":"Page or screen component rendered by a route.","react.server_action":"Next.js Server Action. A sink: the mutation runs on the server.","react.component":"UI component.","react.form_schema":"Zod (or similar) schema — typed form inputs on the client.","react.test":"Frontend test covering a page, hook, or component.","react.context":"React context provider."},oN={field_type:"Type",fields:"Fields",form_fields:"Form fields",permissions:"Permissions",throttles:"Throttles",authentication:"Authentication",pagination:"Pagination",filterset:"Filterset",bases:"Extends",on_delete:"on_delete",related_name:"related_name",unique:"Unique",db_index:"Indexed",relation:"Relation field",looks_idempotent_on_pk:"Idempotent on pk",broker:"Broker",route:"Route",url_name:"URL name",view:"View",include:"Includes",mounted_at:"Mounted at",full_path:"Full path",method:"Method",path:"Path",operation_id:"Operation",raw:"URL",kind:"Schema",exclude:"Excludes",queryset_in_serializer:"Queryset in serializer",get_queryset:"Custom get_queryset",get_serializer_class:"Dynamic serializer",dynamic:"Dynamic",fbv:"Function view",next_app:"Next.js App Router",next_pages:"Next.js Pages Router",next_kind:"Next file",next_layout:"Layout",server_action:"Server Action",typed_client:"Typed client",endpoint:"Endpoint",procedure:"Procedure",e2e:"E2E",visits:"Visits",nested_serializer:"Nested serializer",nested_serializers:"Nested serializers",method_field:"SerializerMethodField",method_fields:"Method fields",from_to_representation:"to_representation",to_representation_fields:"to_representation fields",to_representation:"Custom to_representation",serializer_classes:"get_serializer_class returns",get_serializer_class_resolved:"Serializer resolved",ninja_schema:"Ninja Schema",pydantic:"Pydantic",django_form:"Django form",mutation:"Mutation",has_error_boundary:"Error boundary",invalidation:"Cache invalidation",inferred:"Inferred stitch",generated:"Generated",shared:"Shared module",element:"Renders",model_name:"Model",field_name:"Field",op:"Operation",app:"App",feature:"Feature",from_view:"From view",mentions:"Mentions",nodeid:"Test id",task:"Task",to:"Related to",doc:"Summary",template:"Template",signal:"Signal",sender:"Sender",decorators:"Decorators",nplusone:"N+1 risk",lookups:"Lookups",null:"NULL",blank:"Blank",default:"Default",max_length:"max_length",max_digits:"max_digits",decimal_places:"decimal_places",primary_key:"Primary key",help_text:"Help text",choices:"Choices",auto_now:"auto_now",auto_now_add:"auto_now_add",basename:"Router basename",args:"Args",beat:"Beat",schedule_name:"Schedule",websocket:"WebSocket",htmx:"HTMX",blocks:"Blocks",db_table:"db_table"},mp=["doc","field_type","method","path","operation_id","raw","route","mounted_at","full_path","url_name","view","element","fields","form_fields","exclude","nested_serializer","nested_serializers","method_fields","to_representation_fields","serializer_classes","typed_client","endpoint","procedure","visits","kind","bases","permissions","authentication","throttles","pagination","filterset","on_delete","related_name","to","unique","db_index","null","blank","default","max_length","max_digits","decimal_places","primary_key","auto_now","auto_now_add","help_text","choices","relation","nplusone","lookups","template","signal","sender","decorators","basename","args","beat","schedule_name","websocket","htmx","blocks","db_table","looks_idempotent_on_pk","broker","task","model_name","field_name","op","app","feature","from_view","include","fbv","ninja","django_form","mutation","has_error_boundary","invalidation","inferred","generated","shared","queryset_in_serializer","get_queryset","get_serializer_class","dynamic","mentions","nodeid"],yp=new Set(["referenced","placeholder","booted","line","call","from","import","local","source","file","plain_handler","string_ref","pagination_sink","match","via","generated_client","django","react","superseded_by_generated","foreign_app","imported"]),sN=new Set(["looks_idempotent_on_pk","null","blank"]),lN=new Set(["inferred","generated","mutation","fbv","ninja","filterset","next_app","next_pages","server_action","e2e","ninja_schema","pydantic","method_field","trpc"]);function aN(t){return gp[t]?gp[t]:t.startsWith("react.")?"A React node on the load path.":t.startsWith("django.")?"A Django node on the load path.":t.startsWith("openapi.")?"A stitch node between Django and React.":"A node on the architecture graph."}function uN(t,r,o){const s=new Map(r.map(m=>[m.id,m])),a=[];rN.has(t.type)&&a.push("sink"),iN.has(t.type)&&a.push("contract");const u=t.extra??{};u.inferred&&a.push("inferred"),u.generated&&a.push("generated"),u.mutation&&a.push("mutation"),u.fbv&&a.push("function view"),u.ninja&&a.push("ninja"),u.ninja_schema&&a.push("ninja schema"),u.next_app&&a.push("app router"),u.typed_client&&a.push(String(u.typed_client)),u.e2e&&a.push("e2e"),u.filterset===!0&&a.push("filterset");const c=o.filter(m=>m.dst===t.id),f=o.filter(m=>m.src===t.id),g=c.slice(0,ul).map(m=>cl(m,s,m.src)),y=f.slice(0,ul).map(m=>cl(m,s,m.dst)),v=t.file_path?`${t.file_path}${t.start_line?`:${t.start_line}`:""}`:void 0,x={type:t.type,typeLabel:Po(bl(t.type)),layer:Bk[Hi(t.type)]??"other",purpose:aN(t.type),name:t.name,qualifiedName:t.qualified_name,file:v,context:t.context,roles:a,facts:dN(u).filter(m=>!(m.key==="app"&&m.value===t.context)),inputs:g,outputs:y,extraInputs:Math.max(0,c.length-ul),extraOutputs:Math.max(0,f.length-ul),degreeIn:c.length,degreeOut:f.length,inputKinds:vp(c.map(m=>cl(m,s,m.src))),outputKinds:vp(f.map(m=>cl(m,s,m.dst))),pathSummary:""};return x.pathSummary=cN(x),x}function vp(t){const r=new Map;for(const o of t){const s=o.edgeLabel||o.edgeType.replaceAll("_"," ");r.set(s,(r.get(s)||0)+1)}return[...r.entries()].sort((o,s)=>s[1]-o[1]||o[0].localeCompare(s[0])).map(([o,s])=>({label:o,count:s}))}function cN(t){const r=t.inputKinds.map(s=>`${s.label} ×${s.count}`).join(", "),o=t.outputKinds.map(s=>`${s.label} ×${s.count}`).join(", ");return r&&o?`${r} → this → ${o}`:o?`this → ${o}`:r?`${r} → this`:""}function cl(t,r,o){const s=r.get(o),a=o.includes(":")?o.slice(o.indexOf(":")+1):o;return{id:o,name:(s==null?void 0:s.name)||a,type:(s==null?void 0:s.type)||"",typeLabel:s?Po(bl(s.type)):"",edgeType:t.type,edgeLabel:Po(t.type),inferred:t.confidence<.8}}function dN(t){const r=[...mp.filter(a=>a in t),...Object.keys(t).filter(a=>!mp.includes(a)&&!yp.has(a))],o=[],s=new Set;for(const a of r){if(s.has(a)||yp.has(a)||lN.has(a))continue;s.add(a);const u=fN(a,t[a]);u!=null&&o.push({key:a,label:oN[a]??Po(a),value:u})}return o}function fN(t,r){if(r==null)return null;if(typeof r=="boolean")return!r&&!sN.has(t)?null:r?"yes":"no";if(typeof r=="number")return String(r);if(typeof r=="string")return r.trim()||null;if(Array.isArray(r)){if(r.some(u=>u&&typeof u=="object"))return hN(t,r);const o=r.map(u=>typeof u=="string"||typeof u=="number"?String(u):"").filter(Boolean);if(!o.length)return null;const s=o.slice(0,nN),a=o.length-s.length;return a>0?`${s.join(", ")} +${a} more`:s.join(", ")}return null}function hN(t,r){const o=r.slice(0,4).map(a=>{if(t==="nplusone"){const c=String(a.queryset||"queryset"),f=Array.isArray(a.accessed)?a.accessed.join("."):"",g=a.line?` L${a.line}`:"";return f?`${c} → ${f}${g}`:`${c}${g}`}if(t==="lookups"){const c=Array.isArray(a.fields)?a.fields.join(", "):"",f=String(a.kind||"filter");return c?`${f} ${c}`:f}return Object.entries(a).filter(([,c])=>c!=null&&(typeof c=="string"||typeof c=="number")).slice(0,3).map(([c,f])=>`${c}=${f}`).join(" ")});if(!o.some(Boolean))return null;const s=r.length-o.length;return s>0?`${o.join("; ")} +${s} more`:o.join("; ")}const pN=new Set,gN=F.lazy(()=>k0(()=>import("./LayeredGraph3D-DvLvDCuq.js"),[],import.meta.url).then(t=>({default:t.LayeredGraph3D}))),mN={cheap:"var(--edge-cheap)",expensive:"var(--edge-expensive)",critical:"var(--edge-critical)"};function yN({data:t,selected:r}){return h.jsxs("div",{className:r?"lp-node selected":"lp-node",children:[h.jsx(Fi,{type:"target",position:Se.Left,isConnectable:!1}),h.jsx("div",{className:"t",children:bl(t.type)}),h.jsx("div",{className:"n",title:t.name,children:$r(t.name)}),h.jsx(Fi,{type:"source",position:Se.Right,isConnectable:!1})]})}const vN={load:yN},xN=new Set(["django","react","stitch","arch"]);function wN({topologyKey:t}){const{fitView:r}=$l();return F.useEffect(()=>{let o=0;const s=requestAnimationFrame(()=>{o=requestAnimationFrame(()=>{r({padding:.2,maxZoom:1.15})})});return()=>{cancelAnimationFrame(s),cancelAnimationFrame(o)}},[r,t]),null}function _N(t,r,o=null,s="layers"){const a=new Map(t.map(y=>[y.id,y])),u=tN(t,r,s),c=qk(s)?"smoothstep":"default",f=t.map(y=>({id:y.id,type:"load",position:u.get(y.id)??{x:0,y:0},data:{name:y.name,type:y.type,file:y.file_path},selected:o===y.id,sourcePosition:Se.Right,targetPosition:Se.Left,width:gr,height:Ho,style:{width:gr,height:Ho}})),g=r.filter(y=>a.has(y.src)&&a.has(y.dst)).map(y=>{const v=mN[y.weight]||"var(--edge-cheap)",x=!!(o&&(y.src===o||y.dst===o));return{id:y.id,source:y.src,target:y.dst,type:c,animated:y.weight==="critical",style:{stroke:v,strokeWidth:y.weight==="critical"?2.4:1.2,strokeDasharray:y.confidence<.8?"6 4":void 0},markerEnd:{type:Do.ArrowClosed,width:14,height:14,color:v},label:x?y.type.replaceAll("_"," "):void 0,labelStyle:x?{fill:"var(--ink)",fontSize:10,fontWeight:600}:void 0,labelBgStyle:x?{fill:"var(--graph-bg)",fillOpacity:.92}:void 0,labelBgPadding:x?[3,5]:void 0,labelBgBorderRadius:x?4:void 0}});return{rfNodes:f,rfEdges:g}}function xp({node:t,nodes:r,edges:o,onClose:s,onWhatIf:a}){const u=uN(t,r,o);return F.useEffect(()=>{const c=f=>{f.key==="Escape"&&s()};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[s]),h.jsxs("aside",{className:"inspector","data-testid":"graph-inspector",children:[h.jsxs("div",{className:"inspector-head",children:[h.jsx("div",{className:"t",children:u.typeLabel}),h.jsx("div",{className:"inspector-roles",children:u.roles.map(c=>h.jsx("span",{className:"inspector-chip",children:c},c))}),h.jsx("button",{type:"button",className:"inspector-close","data-testid":"graph-inspector-close","aria-label":"Close inspector",onClick:s,children:"×"})]}),h.jsx("div",{className:"n",children:$r(u.name)}),h.jsx("p",{className:"inspector-purpose","data-testid":"graph-inspector-purpose",children:u.purpose}),u.context?h.jsx("div",{className:"muted",children:$r(u.context)}):null,u.file?h.jsx("div",{className:"file",children:$r(u.file)}):null,h.jsx("div",{className:"muted",children:$r(u.qualifiedName)}),h.jsxs("div",{className:"muted inspector-layer",children:["layer · ",u.layer]}),h.jsxs("div",{className:"muted inspector-degree","data-testid":"graph-inspector-degree",children:[u.degreeIn," in · ",u.degreeOut," out"]}),u.pathSummary?h.jsx("p",{className:"inspector-path","data-testid":"graph-inspector-path",children:u.pathSummary}):null,u.facts.length?h.jsx("dl",{className:"inspector-facts","data-testid":"graph-inspector-facts",children:u.facts.map(c=>h.jsxs("div",{className:"inspector-fact",children:[h.jsx("dt",{children:c.label}),h.jsx("dd",{children:$r(c.value)})]},c.key))}):null,h.jsx(wp,{title:"Inputs",testId:"graph-inspector-inputs",links:u.inputs,extra:u.extraInputs,empty:"Nothing in this graph points here."}),h.jsx(wp,{title:"Outputs",testId:"graph-inspector-outputs",links:u.outputs,extra:u.extraOutputs,empty:"This node does not point at anything in this graph."}),a?h.jsx("button",{type:"button",className:"btn","data-testid":"btn-whatif",onClick:()=>a(t.id),children:"What if this changes"}):null]})}function wp({title:t,testId:r,links:o,extra:s,empty:a}){return h.jsxs("section",{className:"inspector-section","data-testid":r,children:[h.jsxs("h3",{children:[t,h.jsx("span",{className:"count",children:o.length+s})]}),o.length?h.jsx("ul",{children:o.map((u,c)=>h.jsxs("li",{children:[h.jsx("span",{className:"inspector-link-name",title:u.name,children:$r(u.name)}),h.jsxs("span",{className:"inspector-link-meta",children:[u.typeLabel?`${u.typeLabel} · `:"",u.edgeLabel,u.inferred?" · inferred":""]})]},`${u.edgeType}:${u.id}:${c}`))}):h.jsx("p",{className:"muted",children:a}),s?h.jsxs("p",{className:"muted",children:["+",s," more"]}):null]})}function Wu({nodes:t,edges:r,onWhatIf:o,focusPath:s}){const[a,u]=F.useState(null),[c,f]=F.useState(null),[g,y]=F.useState(null),[v,x]=F.useState(()=>Gk()),[m,S]=F.useState(new Set(xN)),[_,E]=F.useState(!1),b=typeof window<"u"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches,w=c??Vk(t.length),P=g??Wk(t.length),N=_&&w==="3d"?a:null,j=F.useMemo(()=>Yk(t,r,{detail:P,families:m,focusId:N,neighborhoodOnly:!!N}),[t,r,P,m,N]),L=F.useMemo(()=>`${v}|${j.nodes.map(R=>R.id).join("\0")}|${j.edges.map(R=>R.id).join("\0")}`,[v,j.nodes,j.edges]),z=F.useMemo(()=>new Map(j.nodes.map(R=>[R.id,R])),[j.nodes]),W=a?z.get(a)??null:null,{rfNodes:D,rfEdges:G}=F.useMemo(()=>{const R=_N(j.nodes,j.edges,a,v);return b&&(R.rfEdges=R.rfEdges.map(B=>({...B,animated:!1}))),R},[j.nodes,j.edges,a,v,b]);F.useEffect(()=>{a&&!z.has(a)&&u(null)},[z,a]),F.useEffect(()=>{if(!s)return;const R=t.find(B=>B.file_path===s);R&&u(R.id)},[s,t]);const J=(R,B)=>{u(B.id)},K=()=>{u(null),E(!1)},ne=R=>{S(B=>{const Y=new Set(B);if(Y.has(R)){if(Y.size===1)return B;Y.delete(R)}else Y.add(R);return Y})},te=F.useMemo(()=>{const R=new Set;for(const B of t)R.add(xm(B.type));return R},[t]),C=t.length-j.nodes.length;return h.jsxs("div",{className:"impact-graph",style:{flex:1,minHeight:0,position:"relative",display:"flex",flexDirection:"column"},children:[h.jsxs("div",{className:"graph-toolbar","data-testid":"graph-toolbar",children:[h.jsxs("div",{className:"seg","aria-label":"Graph projection",children:[h.jsx("button",{type:"button","data-testid":"graph-view-2d",className:w==="2d"?"active":"","aria-pressed":w==="2d",onClick:()=>f("2d"),children:"2D map"}),h.jsx("button",{type:"button","data-testid":"graph-view-3d",className:w==="3d"?"active":"","aria-pressed":w==="3d",onClick:()=>f("3d"),children:"3D layers"})]}),h.jsxs("div",{className:"seg","aria-label":"Graph detail",children:[h.jsx("button",{type:"button","data-testid":"graph-detail-overview",className:P==="overview"?"active":"","aria-pressed":P==="overview",onClick:()=>y("overview"),children:"Overview"}),h.jsx("button",{type:"button","data-testid":"graph-detail-full",className:P==="full"?"active":"","aria-pressed":P==="full",onClick:()=>y("full"),children:"Full"})]}),h.jsx("div",{className:"seg","aria-label":"Graph families",children:["django","stitch","react"].filter(R=>te.has(R)).map(R=>h.jsx("button",{type:"button","data-testid":`graph-family-${R}`,className:m.has(R)?"active":"","aria-pressed":m.has(R),onClick:()=>ne(R),children:R},R))}),w==="2d"?h.jsxs("label",{className:"graph-layout",children:["Layout",h.jsx("select",{id:"graph-layout","data-testid":"graph-layout",value:v,"aria-label":"2D layout algorithm",onChange:R=>{var Y;const B=(Y=sc.find(T=>T.id===R.target.value))==null?void 0:Y.id;B&&(x(B),Xk(B))},children:sc.map(R=>h.jsx("option",{value:R.id,children:R.label},R.id))})]}):h.jsx("button",{type:"button",className:_?"chip-btn active":"chip-btn","data-testid":"graph-neighborhood",disabled:!a,onClick:()=>E(R=>!R),children:_?"Neighborhood":"Focus neighbors"}),h.jsxs("span",{className:"muted graph-count",children:[j.nodes.length," nodes · ",j.edges.length," edges",C?` · ${C} hidden`:""]})]}),h.jsx("div",{className:"graph-stage",children:w==="3d"?h.jsxs("div",{className:"graph-3d","data-testid":"graph-3d",children:[h.jsx("p",{className:"graph-3d-hint",children:"Architecture layers are stacked in depth (Django → stitch → React). Drag to orbit, scroll to zoom, click a node to inspect it."}),h.jsx(F.Suspense,{fallback:h.jsx("p",{className:"muted graph-3d-hint",children:"Loading 3D layers…"}),children:h.jsx(gN,{nodes:j.nodes,edges:j.edges,selectedId:a,neighborIds:N?j.neighborIds:pN,onSelect:R=>{u(R),R||E(!1)}})}),W?h.jsx(xp,{node:W,nodes:t,edges:r,onClose:K,onWhatIf:o}):null]}):h.jsxs(fm,{children:[h.jsxs(rk,{nodes:D,edges:G,nodeTypes:vN,fitView:!1,minZoom:.25,nodesDraggable:!1,nodesConnectable:!1,elementsSelectable:!0,deleteKeyCode:null,onNodeClick:J,onPaneClick:K,proOptions:{hideAttribution:!1},"data-testid":"impact-graph",children:[h.jsx(wN,{topologyKey:L}),h.jsx(ak,{}),h.jsx(Mk,{pannable:!0,zoomable:!0,ariaLabel:"Impact graph overview",nodeColor:"var(--muted)",nodeStrokeColor:"transparent",nodeStrokeWidth:0,maskColor:"rgba(0, 0, 0, 0.45)",maskStrokeColor:"var(--accent)",maskStrokeWidth:1.4,bgColor:"var(--graph-bg)",style:{width:184,height:128}}),h.jsx(gk,{})]}),W?h.jsx(xp,{node:W,nodes:t,edges:r,onClose:K,onWhatIf:o}):null]})})]})}const _p=[{value:"HEAD",label:"HEAD",group:"preset"},{value:"HEAD~1",label:"HEAD~1",group:"preset"}],SN=["preset","branch","tag","commit"];function kN(t){var a;if(!(t!=null&&t.git))return[..._p];const r=((a=t.presets)!=null&&a.length?t.presets:_p.map(u=>u.value)).map(u=>({value:u,label:u,group:"preset"})),o=new Set(r.map(u=>u.value)),s=[...r];for(const u of t.branches||[])o.has(u.name)||(o.add(u.name),s.push({value:u.name,label:u.current?`${u.name} (current)`:u.name,detail:u.subject,group:"branch"}));for(const u of t.tags||[])o.has(u.name)||(o.add(u.name),s.push({value:u.name,label:u.name,detail:u.subject,group:"tag"}));for(const u of t.commits||[])o.has(u.sha)||(o.add(u.sha),s.push({value:u.sha,label:u.short,detail:u.subject,group:"commit"}));return s}function NN(t,r){const o=r.trim().toLowerCase();return o?t.filter(s=>s.value.toLowerCase().includes(o)||s.label.toLowerCase().includes(o)||(s.detail||"").toLowerCase().includes(o)):t}function EN(t){return SN.map(r=>({group:r,items:t.filter(o=>o.group===r)})).filter(r=>r.items.length>0)}function jN(t){return t==="preset"?"Common":t==="branch"?"Branches":t==="tag"?"Tags":"Recent commits"}function Sp({value:t,onChange:r,placeholder:o,testId:s,menuTestId:a,refs:u,onNeedRefs:c}){const f=F.useId(),g=F.useRef(null),[y,v]=F.useState(!1),[x,m]=F.useState(null),[S,_]=F.useState(0),E=F.useMemo(()=>{const j=kN(u);return x===null?j:NN(j,x)},[u,x]),b=F.useMemo(()=>EN(E),[E]);F.useEffect(()=>{y&&c()},[y,c]),F.useEffect(()=>{_(0)},[x,y]);const w=()=>{v(!1),m(null)},P=j=>{r(j.value),w()},N=j=>{if(j.key==="ArrowDown"){if(j.preventDefault(),!y){v(!0);return}_(L=>Math.min(L+1,Math.max(E.length-1,0)))}else if(j.key==="ArrowUp"){if(j.preventDefault(),!y)return;_(L=>Math.max(L-1,0))}else if(j.key==="Enter"&&y){j.preventDefault();const L=E[S];L&&P(L)}else j.key==="Escape"&&y&&(j.preventDefault(),w())};return h.jsxs("div",{className:"combo",ref:g,onBlur:j=>{j.currentTarget.contains(j.relatedTarget)||w()},children:[h.jsxs("div",{className:"combo-row",children:[h.jsx("input",{"data-testid":s,value:t,placeholder:o,spellCheck:!1,role:"combobox","aria-expanded":y,"aria-controls":f,"aria-autocomplete":"list",onChange:j=>{r(j.target.value),y&&m(j.target.value)},onKeyDown:N}),h.jsx("button",{type:"button",className:"icon-btn combo-toggle","data-testid":`${s}-toggle`,"aria-label":"Show recent refs","aria-expanded":y,onMouseDown:j=>j.preventDefault(),onClick:()=>y?w():v(!0),children:h.jsx(w0,{})})]}),y?h.jsx("div",{className:"combo-menu",id:f,role:"listbox","data-testid":a,children:b.length===0?h.jsx("div",{className:"combo-empty muted",children:"No matching refs — the typed value is kept"}):b.map(j=>h.jsxs("div",{className:"combo-group",children:[h.jsx("div",{className:"combo-heading",children:jN(j.group)}),j.items.map(L=>{const z=E.indexOf(L);return h.jsxs("button",{type:"button",role:"option","aria-selected":z===S,className:z===S?"combo-option active":"combo-option","data-testid":`ref-option-${L.group}`,onMouseDown:W=>W.preventDefault(),onMouseEnter:()=>_(z),onClick:()=>P(L),children:[h.jsx("span",{className:"combo-label",children:L.label}),L.detail?h.jsx("span",{className:"combo-detail",children:L.detail}):null]},`${L.group}:${L.value}`)})]},j.group))}):null]})}function bN({initialPath:t,onSelect:r,onClose:o}){const[s,a]=F.useState(null),[u,c]=F.useState(t),[f,g]=F.useState(null),[y,v]=F.useState(""),[x,m]=F.useState(!1),S=F.useRef(null),_=F.useRef(0),E=async N=>{const j=_.current+1;_.current=j,m(!0);try{const L=await $e.browse(N);if(_.current!==j)return;a(L),c(L.path),g(L.is_git?L.path:null),v("")}catch(L){if(_.current!==j)return;v(L instanceof Error?L.message:String(L))}finally{_.current===j&&m(!1)}};F.useEffect(()=>{var N,j;E(t),(N=S.current)==null||N.focus(),(j=S.current)==null||j.select()},[t]);const b=f||(s==null?void 0:s.path)||u,w=f&&f!==(s==null?void 0:s.path)?f.split(/[\\/]/).filter(Boolean).pop():s!=null&&s.is_git?"this repository":"this folder",P=N=>{N.key==="Escape"&&(N.preventDefault(),o())};return h.jsx("div",{className:"modal-backdrop","data-testid":"repo-explorer","data-overlay":"true",onClick:o,onKeyDown:P,children:h.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-labelledby":"explorer-title",onClick:N=>N.stopPropagation(),children:[h.jsxs("div",{className:"modal-head",children:[h.jsxs("div",{children:[h.jsx("h2",{id:"explorer-title",children:"Select repository"}),h.jsx("p",{className:"muted",children:"Browse to a git root, or paste the full path."})]}),h.jsx("button",{type:"button",className:"btn ghost","data-testid":"explorer-cancel",onClick:o,children:"Cancel"})]}),h.jsxs("form",{className:"explorer-path",onSubmit:N=>{N.preventDefault(),E(u)},children:[h.jsx("input",{ref:S,"data-testid":"explorer-path",value:u,onChange:N=>c(N.target.value),spellCheck:!1,"aria-label":"Directory path"}),h.jsx("button",{type:"button",className:"btn",disabled:!(s!=null&&s.parent),onClick:()=>(s==null?void 0:s.parent)&&void E(s.parent),children:"Up"}),h.jsx("button",{type:"button",className:"btn",onClick:()=>s&&void E(s.home),children:"Home"}),h.jsx("button",{type:"submit",className:"btn",children:"Go"})]}),y?h.jsx("div",{className:"error",role:"alert",children:y}):null,h.jsx("div",{className:"explorer-list",role:"listbox","aria-label":"Folders","aria-busy":x,children:s!=null&&s.entries.length?s.entries.map(N=>{const j=f===N.path;return h.jsxs("button",{type:"button",role:"option","aria-selected":j,className:j?"explorer-row active":"explorer-row","data-testid":"explorer-entry","data-path":N.path,onClick:()=>g(N.path),onDoubleClick:()=>void E(N.path),children:[h.jsx(bp,{}),h.jsx("span",{className:"explorer-name",children:N.name}),N.is_git?h.jsx("span",{className:"chip git-badge",children:"git"}):null]},N.path)}):h.jsx("div",{className:"muted explorer-empty",children:x?"Loading…":"No folders here"})}),h.jsxs("div",{className:"modal-foot",children:[h.jsx("span",{className:"muted explorer-current",title:b,children:b}),h.jsxs("button",{type:"button",className:"btn primary","data-testid":"explorer-use",disabled:!b,onClick:()=>b&&r(b),children:["Use ",w]})]})]})})}const jl=[{id:"obsidian",label:"Obsidian",group:"dark"},{id:"nord",label:"Nord",group:"dark"},{id:"solarized-dark",label:"Solarized Dark",group:"dark"},{id:"forest",label:"Forest",group:"dark"},{id:"rose",label:"Rose Pine",group:"dark"},{id:"amber",label:"Midnight Amber",group:"dark"},{id:"volcano",label:"Volcano",group:"dark"},{id:"lavender",label:"Lavender",group:"dark"},{id:"neon-noir",label:"Neon Noir",group:"dark"},{id:"synthwave",label:"Synthwave",group:"dark"},{id:"phosphor",label:"Phosphor",group:"dark"},{id:"aurora",label:"Aurora",group:"dark"},{id:"biolume",label:"Biolume",group:"dark"},{id:"carbon",label:"Carbon",group:"dark"},{id:"paper",label:"Paper",group:"light"},{id:"solarized-light",label:"Solarized Light",group:"light"},{id:"seafoam",label:"Seafoam",group:"light"},{id:"high-contrast",label:"High Contrast",group:"light"},{id:"sakura",label:"Sakura",group:"light"},{id:"citrus",label:"Citrus",group:"light"},{id:"peach",label:"Peach Fuzz",group:"light"},{id:"candy",label:"Cotton Candy",group:"light"},{id:"sky",label:"Clear Sky",group:"light"},{id:"coral",label:"Coral Reef",group:"light"}],CN="obsidian",wm="loadpath.theme";function MN(t){return jl.some(r=>r.id===t)}function _m(){try{const t=localStorage.getItem(wm)||"";if(MN(t))return t}catch{}return CN}function PN(t){var r;return((r=jl.find(o=>o.id===t))==null?void 0:r.group)==="light"?"light":"dark"}function Sm(t){document.documentElement.dataset.theme=t,document.documentElement.style.colorScheme=PN(t);try{localStorage.setItem(wm,t)}catch{}}const kp=[{id:"review",label:"Review",testId:"tab-review",shortcut:"1",icon:g0},{id:"architecture",label:"Architecture",testId:"tab-architecture",shortcut:"2",icon:m0},{id:"graph",label:"Impact graph",testId:"tab-graph",shortcut:"3",icon:y0},{id:"prs",label:"Pull requests",testId:"tab-prs",shortcut:"4",icon:v0},{id:"settings",label:"Settings",testId:"tab-settings",shortcut:"5",icon:x0}];function IN(t){const r=t.total||0;return r<=0?null:Math.min(100,Math.round(100*(t.done||0)/r))}function Uu(t,r,o){let s;try{s=new URL(t)}catch{return}if(s.protocol!=="https:"||s.username||s.password)return;const a=s.hostname.toLowerCase();a!==r&&!a.endsWith(`.${r}`)||s.pathname.startsWith(o)&&window.open(s.toString(),"_blank","noopener,noreferrer")}function TN(){var Jr,ei,ti,Tt,Vn,Wn,ni,_r;const[t,r]=F.useState("review"),[o,s]=F.useState(localStorage.getItem("loadpath.repo")||""),[a,u]=F.useState(localStorage.getItem("loadpath.base")||"HEAD~1"),[c,f]=F.useState(localStorage.getItem("loadpath.head")||"HEAD"),[g,y]=F.useState(null),[v,x]=F.useState(null),[m,S]=F.useState([]),[_,E]=F.useState("review"),[b,w]=F.useState(""),[P,N]=F.useState(""),[j,L]=F.useState(null),[z,W]=F.useState(!1),[D,G]=F.useState(""),[J,K]=F.useState({}),[ne,te]=F.useState([]),[C,R]=F.useState([]),[B,Y]=F.useState(localStorage.getItem("loadpath.scmRepo")||""),[T,H]=F.useState(localStorage.getItem("loadpath.provider")||"github"),[U,M]=F.useState(localStorage.getItem("loadpath.prNumber")||""),[A,re]=F.useState(localStorage.getItem("loadpath.dirty")==="1"),[ie,ce]=F.useState(0),[fe,de]=F.useState(""),[Q,le]=F.useState(_m),[me,ke]=F.useState(!1),[xe,pe]=F.useState(!1),[be,Pe]=F.useState(null),[Ce,Re]=F.useState(null),[tt,nt]=F.useState(!1),[Je,Qe]=F.useState(!1),ot=F.useRef(o);ot.current=o;const Pt=F.useRef(!1);Pt.current=xe;const st=F.useRef(""),ft=$=>{le($),Sm($)},He=F.useRef(""),Le=$=>{He.current=$,N($)},mt=$=>{const ee=()=>{$e.indexProgress($).then(Ie=>{He.current&&(Ie.phase&&Ie.phase!=="idle"&&Ie.message&&Le(Ie.message),L(Ie.phase&&Ie.phase!=="idle"?IN(Ie):null))}).catch(()=>{})};ee();const _e=window.setInterval(ee,250);return()=>{window.clearInterval(_e),L(null)}};F.useEffect(()=>{$e.settings().then(K).catch(()=>{}).finally(()=>ke(!0)),$e.repos().then($=>S($.repos)).catch(()=>{})},[]);const an=()=>o.trim()?!0:(w("Point at a local repository path first."),!1);F.useEffect(()=>{if(t!=="architecture"||!o.trim())return;const $=o;let ee=!1;return $e.architecture($).then(_e=>{!ee&&ot.current===$&&x(_e)}).catch(()=>{}),()=>{ee=!0}},[t,o]);const ht=$=>{ot.current=$,s($),localStorage.setItem("loadpath.repo",$),$.trim()!==st.current&&(st.current="",Pe(null))},Gt=F.useCallback($=>{const ee=($??ot.current).trim();return!ee||st.current===ee?Promise.resolve():(st.current=ee,$e.gitRefs(ee).then(_e=>{ot.current.trim()===ee&&Pe(_e)}).catch(()=>{st.current===ee&&(st.current="",Pe(null))}))},[]),_n=($,ee)=>{u($),f(ee),localStorage.setItem("loadpath.base",$),localStorage.setItem("loadpath.head",ee)},zn=($,ee,_e)=>{H($),Y(ee),localStorage.setItem("loadpath.provider",$),localStorage.setItem("loadpath.scmRepo",ee),_e!==void 0&&(M(_e),localStorage.setItem("loadpath.prNumber",_e))},Xr=$=>$==="github"?!!J.github_token_set:$==="gitlab"?!!J.gitlab_token_set:!!J.bitbucket_token_set,It=F.useCallback(async($=T)=>{var ee;try{const _e=await $e.scmRepos($);R(_e.repos),(ee=_e.user)!=null&&ee.login&&K(Ie=>({...Ie,...$==="github"?{github_user:_e.user.login}:$==="gitlab"?{gitlab_user:_e.user.login}:{bitbucket_user:_e.user.login}}))}catch{R([])}},[T]);F.useEffect(()=>{if(t!=="prs")return;let $=!1;return It(T).catch(()=>{$||R([])}),()=>{$=!0}},[t,T,It]),F.useEffect(()=>{if(!Ce)return;let $=!1,ee=0;const _e=async()=>{try{const Ie=await $e.githubOAuthPoll(Ce.flow_id);if($)return;if(Ie.status==="complete"){Re(null);const Me=await $e.settings();K(Me),G(Ie.user?`Signed in to GitHub as ${Ie.user}`:"Signed in to GitHub"),It("github");return}if(Ie.status==="pending"||Ie.status==="slow_down"){ee=window.setTimeout(_e,Math.max(Ie.interval||Ce.interval,5)*1e3);return}Re(null),w(Ie.status==="denied"?"GitHub sign-in was denied.":"GitHub sign-in expired. Try again.")}catch(Ie){if($)return;Re(null),w(Ie instanceof Error?Ie.message:String(Ie))}};return ee=window.setTimeout(_e,Math.max(Ce.interval,5)*1e3),()=>{$=!0,window.clearTimeout(ee)}},[Ce,It]),F.useEffect(()=>{if(!tt)return;let $=!1,ee=0;const _e=Date.now(),Ie=async()=>{try{const Me=await $e.oauthStatus();if($)return;if(Me.bitbucket.connected){nt(!1);const Fe=await $e.settings();K(Fe),G(Me.bitbucket.user?`Signed in to Bitbucket as ${Me.bitbucket.user}`:"Signed in to Bitbucket"),It("bitbucket");return}if(Date.now()-_e>18e4){nt(!1),w("Bitbucket sign-in timed out. Finish in the browser, or try again.");return}ee=window.setTimeout(Ie,1500)}catch(Me){if($)return;nt(!1),w(Me instanceof Error?Me.message:String(Me))}};return ee=window.setTimeout(Ie,1500),()=>{$=!0,window.clearTimeout(ee)}},[tt,It]),F.useEffect(()=>{if(!Je)return;let $=!1,ee=0;const _e=Date.now(),Ie=async()=>{try{const Me=await $e.oauthStatus();if($)return;if(Me.gitlab.connected){Qe(!1);const Fe=await $e.settings();K(Fe),G(Me.gitlab.user?`Signed in to GitLab as ${Me.gitlab.user}`:"Signed in to GitLab"),It("gitlab");return}if(Date.now()-_e>18e4){Qe(!1),w("GitLab sign-in timed out. Finish in the browser, or try again.");return}ee=window.setTimeout(Ie,1500)}catch(Me){if($)return;Qe(!1),w(Me instanceof Error?Me.message:String(Me))}};return ee=window.setTimeout(Ie,1500),()=>{$=!0,window.clearTimeout(ee)}},[Je,It]);const Sn=async($=o)=>{if(!$.trim())return null;const ee=await $e.architecture($);return ot.current===$&&x(ee),ee},Dn=async $=>{const ee=$.trim();if(!(!ee||ee===ot.current)){if(He.current){w("Wait for the current job to finish before switching workspace.");return}w(""),G(""),y(null),x(null),E("architecture"),ht(ee),W(!0),Le(`Loading ${p0(ee)}…`);try{await Promise.all([Sn(ee),Gt(ee)])}catch(_e){ot.current===ee&&w(_e instanceof Error?_e.message:String(_e))}finally{ot.current===ee&&(Le(""),W(!1))}}},un=async()=>{if(He.current||!an())return;w(""),G(""),Le("Tracing load path…"),ht(o),_n(a,c);const $=mt(o);try{const ee=await $e.review(o,a,c,!0,A);y(ee),ce(0),E("review"),r("review"),await $e.repos().then(_e=>S(_e.repos)).catch(()=>{}),await Sn(o)}catch(ee){w(ee instanceof Error?ee.message:String(ee))}finally{$(),Le("")}},$n=async($=!0)=>{if(He.current||!an())return;w(""),G(""),Le($?"Indexing…":"Full reindex…"),ht(o);const ee=mt(o);try{await $e.index(o,$);const _e=await Sn(o);await $e.repos().then(Ie=>S(Ie.repos)).catch(()=>{}),_e!=null&&_e.indexed&&(E("architecture"),r("architecture"))}catch(_e){w(_e instanceof Error?_e.message:String(_e))}finally{ee(),Le("")}},mr=async()=>{if(!He.current&&an()){w(""),G(""),Le("Detecting layout…"),ht(o);try{const $=await $e.init(o);G($.message),await $e.repos().then(ee=>S(ee.repos)).catch(()=>{})}catch($){w($ instanceof Error?$.message:String($))}finally{Le("")}}},cn=async()=>{if(g!=null&&g.markdown)try{await navigator.clipboard.writeText(g.markdown),G("Copied markdown brief")}catch($){w($ instanceof Error?$.message:String($))}},dn=async()=>{if(!He.current){if(!(g!=null&&g.markdown)||!B||!U){w("Pick a pull request first (Pull requests tab), then post the brief.");return}Le("Posting Loadpath brief…");try{const $=await $e.postComment(T,B,Number(U),g.markdown);G($.updated?"Updated the Loadpath PR comment":"Posted the Loadpath PR comment")}catch($){w($ instanceof Error?$.message:String($))}finally{Le("")}}},qr=async()=>{if(!He.current){w(""),Le("Fetching pull requests…");try{const $=await $e.prs(T,B);te($.pull_requests);const ee=C.find(_e=>_e.slug.toLowerCase()===B.trim().toLowerCase());ee!=null&&ee.local_path&&ht(ee.local_path)}catch($){w($ instanceof Error?$.message:String($))}finally{Le("")}}},Kr=async()=>{w("");try{const $=await $e.githubOAuthStart();Re($),Uu($.verification_uri_complete,"github.com","/login/device")}catch($){w($ instanceof Error?$.message:String($))}},Qr=async()=>{w("");try{const $=await $e.bitbucketOAuthStart();nt(!0),Uu($.authorize_url,"bitbucket.org","/site/oauth2/authorize")}catch($){nt(!1),w($ instanceof Error?$.message:String($))}},Zr=async()=>{w("");try{const $=await $e.gitlabOAuthStart();Qe(!0),Uu($.authorize_url,new URL($.authorize_url).hostname,"/oauth/authorize")}catch($){Qe(!1),w($ instanceof Error?$.message:String($))}},On=async $=>{if(!(He.current||!o.trim())){w(""),Le("Walking what-if path…");try{const ee=await $e.whatIf(o,$);G(`${ee.title} — ${ee.confidence.level} · ${(ee.sinks||[]).length} sinks`),y({...ee,markdown:ee.markdown||"",index:ee.index||(g==null?void 0:g.index),workspace:ee.workspace||(g==null?void 0:g.workspace)}),ce(0),E("review"),r("review")}catch(ee){w(ee instanceof Error?ee.message:String(ee))}finally{Le("")}}},yr=async $=>{if(He.current)return;zn($.provider,$.repo,String($.number));const ee=C.find(Me=>Me.slug.toLowerCase()===$.repo.toLowerCase());ee!=null&&ee.local_path&&ht(ee.local_path),w(""),Le(`Fetching ${$.provider} #${$.number}…`);const _e=(ee==null?void 0:ee.local_path)||o,Ie=_e?mt(_e):()=>{};try{const Me=await $e.reviewPr($.provider,$.repo,$.number,(ee==null?void 0:ee.local_path)||o||void 0);y(Me),ce(0),Me.pull_request&&typeof Me.pull_request.repo_path=="string"&&ht(Me.pull_request.repo_path),_n(String(Me.base||$.target_branch),String(Me.head||$.source_branch)),E("review"),r("review")}catch(Me){_n($.base_sha||$.target_branch,$.head_sha||$.source_branch),r("review"),w(Me instanceof Error?Me.message:String(Me))}finally{Ie(),Le("")}},Fn=async $=>{w("");try{K(await $e.oauthDisconnect($)),T===$&&R([]),G(`Disconnected ${$}`)}catch(ee){w(ee instanceof Error?ee.message:String(ee))}},kn=async $=>{$.preventDefault();const ee=new FormData($.currentTarget),_e={github_token:String(ee.get("github_token")||""),github_oauth_client_id:String(ee.get("github_oauth_client_id")||""),github_host:String(ee.get("github_host")||""),gitlab_token:String(ee.get("gitlab_token")||""),gitlab_host:String(ee.get("gitlab_host")||""),gitlab_oauth_client_id:String(ee.get("gitlab_oauth_client_id")||""),gitlab_oauth_client_secret:String(ee.get("gitlab_oauth_client_secret")||""),bitbucket_token:String(ee.get("bitbucket_token")||""),bitbucket_username:String(ee.get("bitbucket_username")||""),bitbucket_oauth_client_id:String(ee.get("bitbucket_oauth_client_id")||""),bitbucket_oauth_client_secret:String(ee.get("bitbucket_oauth_client_secret")||""),ai_provider:String(ee.get("ai_provider")||"none"),ai_api_key:String(ee.get("ai_api_key")||""),ai_model:String(ee.get("ai_model")||""),ai_base_url:String(ee.get("ai_base_url")||"")},Ie=m.length?{..._e,workspaces:m.map(Me=>({path:Me.path,name:Me.name}))}:_e;try{K(await $e.saveSettings(Ie)),G("Settings saved on this machine")}catch(Me){w(Me instanceof Error?Me.message:String(Me))}},vr=async()=>{if(!(!g||He.current)){Le("Residual analysis…");try{const $=await $e.residual(g);de($.note)}catch($){w($ instanceof Error?$.message:String($))}finally{Le("")}}},fn=F.useRef(un);fn.current=un;const xr=F.useRef(t);xr.current=t,F.useEffect(()=>{const $=ee=>{if(Pt.current){ee.key==="Escape"&&(ee.preventDefault(),pe(!1));return}const _e=ee.target;if(_e&&(_e.tagName==="INPUT"||_e.tagName==="TEXTAREA"||_e.tagName==="SELECT"||_e.isContentEditable)){ee.key==="Escape"&&_e.blur();return}if(ee.key==="Escape"){w(""),G("");return}const Ie=kp.find(Me=>Me.shortcut===ee.key);if(Ie&&!ee.metaKey&&!ee.ctrlKey&&!ee.altKey&&r(Ie.id),(ee.metaKey||ee.ctrlKey)&&ee.key==="Enter"){if(xr.current==="settings"||xr.current==="prs"||He.current)return;ee.preventDefault(),fn.current()}};return window.addEventListener("keydown",$),()=>window.removeEventListener("keydown",$)},[]);const hn=F.useMemo(()=>_==="architecture"?(v==null?void 0:v.nodes)??[]:(g==null?void 0:g.nodes)??[],[_,v,g]),Hn=F.useMemo(()=>_==="architecture"?(v==null?void 0:v.edges)??[]:(g==null?void 0:g.edges)??[],[_,v,g]),Bn=g!=null&&g.index?`${g.index.counts.nodes} nodes · ${g.index.counts.edges} edges`:v!=null&&v.indexed?`${v.counts.nodes} nodes · ${v.counts.edges} edges`:"Not indexed",wr=((g==null?void 0:g.findings)||[]).filter($=>!$.waived);return h.jsxs("div",{className:"app",children:[h.jsx("a",{className:"skip",href:"#main",children:"Skip to content"}),h.jsxs("nav",{className:"rail","data-testid":"rail","aria-label":"Primary",children:[h.jsxs("div",{className:"brand",children:[h.jsx("div",{className:"brand-mark",children:"Loadpath"}),h.jsx("div",{className:"brand-sub",children:"Load-path review"})]}),kp.map($=>{const ee=$.icon,_e=t===$.id;return h.jsxs("button",{type:"button","data-testid":$.testId,className:_e?"nav-item active":"nav-item","aria-current":_e?"page":void 0,"aria-label":$.label,onClick:()=>r($.id),children:[h.jsx(ee,{}),h.jsx("span",{children:$.label})]},$.id)}),h.jsxs("div",{className:"theme-pick",children:[h.jsx("label",{htmlFor:"theme-select",children:"Theme"}),h.jsx("select",{id:"theme-select","data-testid":"theme-select",value:Q,onChange:$=>ft($.target.value),children:["dark","light"].map($=>h.jsx("optgroup",{label:$==="dark"?"Dark":"Light",children:jl.filter(ee=>ee.group===$).map(ee=>h.jsx("option",{value:ee.id,children:ee.label},ee.id))},$))})]}),h.jsxs("div",{className:"rail-foot",children:[h.jsx("div",{className:"muted",role:"status",children:P||Bn}),h.jsxs("div",{className:"kbd-hint",children:[h.jsx("kbd",{children:"1"}),"–",h.jsx("kbd",{children:"5"})," tabs · ",h.jsx("kbd",{children:"Ctrl"}),"+",h.jsx("kbd",{children:"Enter"})," review"]})]})]}),h.jsxs("div",{className:"main",id:"main",children:[P?h.jsxs("div",{className:j!=null?"progress determinate":"progress",role:"status","aria-live":"polite","aria-busy":"true","data-testid":"progress",children:[h.jsx("i",{style:j!=null?{width:`${j}%`}:void 0}),h.jsx("span",{className:"sr-only",children:P})]}):null,h.jsxs("header",{className:"topbar","data-testid":"topbar",children:[m.length>0?h.jsxs("label",{className:"field workspace",children:[h.jsx("span",{children:"Workspace"}),h.jsxs("select",{"data-testid":"workspace-select",value:m.some($=>$.path===o)?o:"",disabled:!!P,"aria-busy":z,onChange:$=>{$.target.value&&Dn($.target.value)},children:[h.jsx("option",{value:"",children:"Indexed repos…"}),m.map($=>h.jsxs("option",{value:$.path,children:[$.name,$.indexed?` (${$.counts.nodes})`:""]},$.path))]})]}):null,h.jsxs("label",{className:"field path",children:[h.jsx("span",{children:"Repository"}),h.jsxs("div",{className:"path-row",children:[h.jsx("input",{"data-testid":"repo-path",placeholder:"Local monorepo path",value:o,onChange:$=>{const ee=$.target.value;s(ee),ee.trim()!==st.current&&(st.current="",Pe(null))},spellCheck:!1}),h.jsx("button",{type:"button",className:"icon-btn","data-testid":"btn-browse-repo","aria-label":"Browse for a local repository",onClick:()=>pe(!0),children:h.jsx(bp,{})})]})]}),h.jsxs("label",{className:"field ref",children:[h.jsx("span",{children:"Base"}),h.jsx(Sp,{testId:"base-ref",menuTestId:"base-ref-menu",value:a,onChange:$=>_n($,c),placeholder:"base",refs:be,onNeedRefs:Gt})]}),h.jsxs("label",{className:"field ref",children:[h.jsx("span",{children:"Head"}),h.jsx(Sp,{testId:"head-ref",menuTestId:"head-ref-menu",value:c,onChange:$=>_n(a,$),placeholder:"head",refs:be,onNeedRefs:Gt})]}),h.jsxs("label",{className:"field dirty",children:[h.jsx("span",{children:"Working tree"}),h.jsx("button",{type:"button",className:A?"chip-btn active":"chip-btn","data-testid":"btn-dirty","aria-pressed":A,onClick:()=>{const $=!A;re($),localStorage.setItem("loadpath.dirty",$?"1":"0")},children:A?"Include uncommitted":"Committed range"})]}),h.jsxs("div",{className:"topbar-actions",children:[h.jsx("button",{type:"button","data-testid":"btn-init",disabled:!!P,onClick:mr,children:"Draft config"}),h.jsx("button",{type:"button","data-testid":"btn-index",disabled:!!P,onClick:()=>$n(!0),children:"Index"}),h.jsx("button",{type:"button","data-testid":"btn-review",className:"btn primary",disabled:!!P,onClick:un,children:"Review"})]})]}),h.jsxs("div",{className:"alerts",children:[b?h.jsxs("div",{className:"error","data-testid":"error",role:"alert",children:[h.jsx("span",{children:b}),h.jsx("button",{type:"button",className:"dismiss",onClick:()=>w(""),"aria-label":"Dismiss error",children:"×"})]}):null,D?h.jsxs("div",{className:"banner","data-testid":"status-note",children:[h.jsx("span",{children:D}),h.jsx("button",{type:"button",className:"dismiss",onClick:()=>G(""),"aria-label":"Dismiss",children:"×"})]}):null,((Jr=g==null?void 0:g.index)!=null&&Jr.stale||v!=null&&v.stale)&&(t==="review"||t==="architecture")?h.jsx("div",{className:"banner stale","data-testid":"index-stale",children:"Index is stale — files changed since the last extract. Index again before trusting this walk."}):null,((ei=g==null?void 0:g.index)==null?void 0:ei.django_boot)==="failed"||(v==null?void 0:v.django_boot)==="failed"?h.jsx("div",{className:"banner warn","data-testid":"django-boot-failed",children:((ti=g==null?void 0:g.index)==null?void 0:ti.django_boot_detail)||(v==null?void 0:v.django_boot_detail)||"django.setup() failed"}):null,(Tt=g==null?void 0:g.workspace)!=null&&Tt.dirty_overlaps_review&&t==="review"?h.jsxs("div",{className:"banner warn","data-testid":"dirty-tree",children:["Uncommitted files overlap this review: ",(g.workspace.dirty_overlap||[]).slice(0,6).join(", ")]}):null]}),h.jsxs("div",{className:"stage","aria-busy":z,children:[z?h.jsxs("div",{className:"empty workspace-loading","data-testid":"workspace-loading",children:[h.jsx("h2",{children:P}),h.jsx("p",{children:"Fetching the indexed graph for this repository."})]}):null,!z&&t==="review"&&h.jsxs("div",{className:"content","data-testid":"review-layout",children:[h.jsx("aside",{className:"brief","data-testid":"brief",children:g?h.jsx(RN,{review:g,findings:wr,aiNote:fe,busy:!!P,tourIndex:ie,onTour:ce,onAskAi:vr,onCopy:cn,onPost:dn}):h.jsxs("div",{className:"empty","data-testid":"review-empty",children:[h.jsx("h2",{children:"Trace the force of this diff"}),h.jsx("p",{children:"The graph is the architecture. The brief is where this change travels — not a hunk list."}),h.jsxs("ol",{children:[h.jsx("li",{children:"Point at a Django + React monorepo, or pick an indexed workspace."}),h.jsxs("li",{children:["Index it. Missing ",h.jsx("code",{children:"loadpath.yml"})," is drafted from ",h.jsx("code",{children:"manage.py"})," and"," ",h.jsx("code",{children:"src/features"}),"."]}),h.jsx("li",{children:"Review a git range, or open a pull request so base/head become a three-dot merge-base."})]})]})}),h.jsx("div",{className:"graph-wrap","data-testid":"review-graph",children:g?h.jsx(Wu,{nodes:g.nodes,edges:g.edges,onWhatIf:On,focusPath:(Vn=g.read_order[ie])==null?void 0:Vn.path}):null})]}),!z&&t==="architecture"&&h.jsxs("div",{className:"content","data-testid":"architecture-panel",children:[h.jsx("aside",{className:"brief","data-testid":"architecture-brief",children:v!=null&&v.indexed?h.jsx(LN,{architecture:v,busy:!!P,onReindex:()=>$n(!1),onReview:un}):h.jsx("p",{className:"muted","data-testid":"architecture-empty",children:"Index this repo to build the architecture graph. Review then walks that same graph for a git range — it does not start from a hunk list."})}),h.jsx("div",{className:"graph-wrap","data-testid":"architecture-graph",children:v!=null&&v.indexed?h.jsx(Wu,{nodes:v.nodes,edges:v.edges,onWhatIf:On}):null})]}),!z&&t==="graph"&&h.jsxs("div",{className:"graph-wrap","data-testid":"graph-full",style:{height:"100%"},children:[h.jsxs("div",{className:"graph-modes",children:[h.jsxs("div",{className:"seg","aria-label":"Graph scope",children:[h.jsx("button",{type:"button","aria-pressed":_==="review","data-testid":"graph-mode-review",className:_==="review"?"active":"",onClick:()=>E("review"),children:"This review"}),h.jsx("button",{type:"button","aria-pressed":_==="architecture","data-testid":"graph-mode-architecture",className:_==="architecture"?"active":"",onClick:()=>E("architecture"),children:"Indexed architecture"})]}),h.jsxs("div",{className:"legend","aria-hidden":"true",children:[h.jsxs("span",{children:[h.jsx("i",{})," cheap"]}),h.jsxs("span",{children:[h.jsx("i",{className:"exp"})," expensive"]}),h.jsxs("span",{children:[h.jsx("i",{className:"crit"})," critical"]}),h.jsxs("span",{children:[h.jsx("i",{className:"dash"})," inferred"]})]})]}),hn.length?h.jsx(Wu,{nodes:hn,edges:Hn,onWhatIf:On}):h.jsx("p",{className:"empty","data-testid":"graph-empty",children:"Index the repo or run a review first. Click a node to inspect it."})]}),!z&&t==="prs"&&h.jsxs("div",{className:"pr-list","data-testid":"pr-list",children:[h.jsxs("div",{className:"pr-toolbar",children:[h.jsxs("label",{className:"field provider",children:[h.jsx("span",{children:"Provider"}),h.jsxs("select",{"data-testid":"pr-provider",value:T,onChange:$=>zn($.target.value,B,U),children:[h.jsx("option",{value:"github",children:"GitHub"}),h.jsx("option",{value:"gitlab",children:"GitLab"}),h.jsx("option",{value:"bitbucket",children:"Bitbucket"})]})]}),h.jsxs("label",{className:"field",children:[h.jsx("span",{children:"Repository"}),h.jsx("input",{"data-testid":"pr-repo",placeholder:C.length?"Search your repos":"owner/repo",value:B,onChange:$=>zn(T,$.target.value,U),list:"scm-repos",spellCheck:!1}),h.jsx("datalist",{id:"scm-repos",children:C.map($=>h.jsxs("option",{value:$.slug,children:[$.private?"private":"public",$.local_path?" · local":""]},$.slug))})]}),h.jsx("button",{type:"button","data-testid":"btn-refresh-repos",className:"btn",disabled:!!P||!Xr(T),onClick:()=>{It(T)},children:"My repos"}),h.jsx("button",{type:"button","data-testid":"btn-list-prs",className:"btn",disabled:!!P,onClick:qr,children:"List PRs"})]}),C.length>0?h.jsxs("p",{className:"muted scm-count","data-testid":"scm-repo-count",children:[C.length," ",T," repositor",C.length===1?"y":"ies",T==="github"&&J.github_user?` · @${String(J.github_user)}`:"",T==="gitlab"&&J.gitlab_user?` · @${String(J.gitlab_user)}`:"",T==="bitbucket"&&J.bitbucket_user?` · ${String(J.bitbucket_user)}`:""]}):null,ne.length===0?h.jsxs("div",{className:"empty","data-testid":"pr-empty",children:[h.jsx("h2",{children:"No pull requests loaded"}),h.jsx("p",{children:"Sign in under Settings (or paste a token), load your repositories, then list open PRs. Reviewing a PR fills base and head from its SHAs."})]}):ne.map($=>h.jsxs("article",{className:"pr","data-testid":`pr-${$.number}`,children:[h.jsxs("h3",{children:["#",$.number," ",$.title]}),h.jsxs("div",{className:"pr-meta muted",children:[h.jsx("span",{className:`chip ${$.draft?"":"open"}`,children:$.draft?"draft":$.state}),h.jsx("span",{children:$.author}),h.jsxs("span",{children:[$.source_branch," → ",$.target_branch]})]}),h.jsxs("div",{className:"pr-actions",children:[h.jsxs("a",{href:$.url,target:"_blank",rel:"noreferrer",children:["Open on ",$.provider]}),h.jsx("button",{type:"button",className:"btn primary","data-testid":`pr-review-${$.number}`,onClick:()=>void yr($),children:"Review this PR"})]})]},`${$.provider}-${$.number}`))]}),!z&&t==="settings"&&me&&h.jsxs("form",{className:"settings","data-testid":"settings-form",onSubmit:kn,children:[h.jsxs("div",{children:[h.jsx("h1",{children:"Settings"}),h.jsx("p",{className:"muted",children:"Tokens stay on this machine in ~/.loadpath/settings.json. AI runs only on residual uncertainty the graph could not close."})]}),h.jsxs("section",{className:"settings-card",children:[h.jsx("h2",{children:"Appearance"}),h.jsx("p",{className:"muted",children:"Local to this browser. High contrast is a first-class theme, not an afterthought."}),h.jsx("div",{className:"theme-grid","data-testid":"theme-grid",children:jl.map($=>h.jsxs("button",{type:"button","data-theme":$.id,className:Q===$.id?"theme-swatch active":"theme-swatch","data-testid":`theme-${$.id}`,onClick:()=>ft($.id),children:[h.jsx("div",{className:"swatch-bar","aria-hidden":"true"}),h.jsx("div",{className:"name",children:$.label}),h.jsx("div",{className:"group",children:$.group})]},$.id))})]}),h.jsxs("section",{className:"settings-card",children:[h.jsx("h2",{children:"Source control"}),h.jsx("p",{className:"muted",children:"Sign in with OAuth to list every repository the account can access. Tokens stay in ~/.loadpath/settings.json. A classic PAT still works if you prefer not to register an OAuth app."}),h.jsxs("div",{className:"scm-login","data-testid":"scm-github",children:[h.jsxs("div",{children:[h.jsx("strong",{children:"GitHub"}),h.jsx("p",{className:"muted",children:J.github_token_set?J.github_user?`Signed in as @${String(J.github_user)}`:"Token saved on this machine":"Not connected"})]}),h.jsx("div",{className:"btn-row",children:J.github_token_set?h.jsx("button",{type:"button",className:"btn","data-testid":"btn-github-disconnect",onClick:()=>void Fn("github"),children:"Disconnect"}):h.jsx("button",{type:"button",className:"btn primary","data-testid":"btn-github-login",disabled:!!Ce||!J.github_oauth_ready,onClick:()=>void Kr(),children:Ce?"Waiting for GitHub…":"Sign in with GitHub"})})]}),Ce?h.jsxs("p",{className:"oauth-code","data-testid":"github-user-code",children:["Enter ",h.jsx("code",{children:Ce.user_code})," at GitHub if the browser did not fill it in."]}):null,J.github_oauth_ready?null:h.jsx("p",{className:"muted",children:"Sign-in needs a GitHub OAuth App with Device Flow enabled. Set LOADPATH_GITHUB_CLIENT_ID or paste the client ID below."}),h.jsx("label",{htmlFor:"github_oauth_client_id",children:"GitHub OAuth client ID"}),h.jsx("input",{id:"github_oauth_client_id",name:"github_oauth_client_id","data-testid":"github-oauth-client-id",placeholder:"Ov23…",defaultValue:String(J.github_oauth_client_id||""),autoComplete:"off"}),h.jsx("label",{htmlFor:"github_token",children:"GitHub token (optional PAT)"}),h.jsx("input",{id:"github_token",name:"github_token",type:"password",placeholder:"ghp_…",autoComplete:"off"}),h.jsx("label",{htmlFor:"github_host",children:"GitHub host (Enterprise)"}),h.jsx("input",{id:"github_host",name:"github_host","data-testid":"github-host",placeholder:"github.com",defaultValue:String(J.github_host||""),autoComplete:"off"}),h.jsxs("div",{className:"scm-login","data-testid":"scm-gitlab",children:[h.jsxs("div",{children:[h.jsx("strong",{children:"GitLab"}),h.jsx("p",{className:"muted",children:J.gitlab_token_set?J.gitlab_user?`Signed in as @${String(J.gitlab_user)}`:"Token saved on this machine":"Not connected"})]}),h.jsx("div",{className:"btn-row",children:J.gitlab_token_set?h.jsx("button",{type:"button",className:"btn","data-testid":"btn-gitlab-disconnect",onClick:()=>void Fn("gitlab"),children:"Disconnect"}):h.jsx("button",{type:"button",className:"btn primary","data-testid":"btn-gitlab-login",disabled:Je||!J.gitlab_oauth_ready,onClick:()=>void Zr(),children:Je?"Waiting for GitLab…":"Sign in with GitLab"})})]}),h.jsx("label",{htmlFor:"gitlab_host",children:"GitLab host"}),h.jsx("input",{id:"gitlab_host",name:"gitlab_host","data-testid":"gitlab-host",placeholder:"gitlab.com",defaultValue:String(J.gitlab_host||""),autoComplete:"off"}),h.jsx("label",{htmlFor:"gitlab_oauth_client_id",children:"GitLab OAuth application ID"}),h.jsx("input",{id:"gitlab_oauth_client_id",name:"gitlab_oauth_client_id","data-testid":"gitlab-oauth-client-id",defaultValue:String(J.gitlab_oauth_client_id||""),autoComplete:"off"}),h.jsx("label",{htmlFor:"gitlab_oauth_client_secret",children:"GitLab OAuth secret"}),h.jsx("input",{id:"gitlab_oauth_client_secret",name:"gitlab_oauth_client_secret",type:"password",autoComplete:"off"}),h.jsx("label",{htmlFor:"gitlab_token",children:"GitLab token (optional PAT)"}),h.jsx("input",{id:"gitlab_token",name:"gitlab_token",type:"password",placeholder:"glpat-…",autoComplete:"off"}),h.jsxs("div",{className:"scm-login","data-testid":"scm-bitbucket",children:[h.jsxs("div",{children:[h.jsx("strong",{children:"Bitbucket"}),h.jsx("p",{className:"muted",children:J.bitbucket_token_set?J.bitbucket_user?`Signed in as ${String(J.bitbucket_user)}`:"Token saved on this machine":"Not connected"})]}),h.jsx("div",{className:"btn-row",children:J.bitbucket_token_set?h.jsx("button",{type:"button",className:"btn","data-testid":"btn-bitbucket-disconnect",onClick:()=>void Fn("bitbucket"),children:"Disconnect"}):h.jsx("button",{type:"button",className:"btn primary","data-testid":"btn-bitbucket-login",disabled:tt||!J.bitbucket_oauth_ready,onClick:()=>void Qr(),children:tt?"Waiting for Bitbucket…":"Sign in with Bitbucket"})})]}),J.bitbucket_oauth_ready?null:h.jsxs("p",{className:"muted",children:["Sign-in needs a Bitbucket OAuth consumer (key + secret). Callback URL:"," ",h.jsx("code",{children:"/api/oauth/bitbucket/callback"})," on this app origin."]}),h.jsx("label",{htmlFor:"bitbucket_oauth_client_id",children:"Bitbucket OAuth key"}),h.jsx("input",{id:"bitbucket_oauth_client_id",name:"bitbucket_oauth_client_id","data-testid":"bitbucket-oauth-client-id",defaultValue:String(J.bitbucket_oauth_client_id||""),autoComplete:"off"}),h.jsx("label",{htmlFor:"bitbucket_oauth_client_secret",children:"Bitbucket OAuth secret"}),h.jsx("input",{id:"bitbucket_oauth_client_secret",name:"bitbucket_oauth_client_secret",type:"password",autoComplete:"off"}),h.jsx("label",{htmlFor:"bitbucket_token",children:"Bitbucket token (optional app password)"}),h.jsx("input",{id:"bitbucket_token",name:"bitbucket_token",type:"password",autoComplete:"off"}),h.jsx("label",{htmlFor:"bitbucket_username",children:"Bitbucket username (app passwords)"}),h.jsx("input",{id:"bitbucket_username",name:"bitbucket_username",defaultValue:String(J.bitbucket_username||"")})]}),h.jsxs("section",{className:"settings-card",children:[h.jsx("h2",{children:"Residual AI"}),h.jsx("label",{htmlFor:"ai_provider",children:"Provider"}),h.jsxs("select",{id:"ai_provider",name:"ai_provider",defaultValue:String(((Wn=J.ai)==null?void 0:Wn.provider)||"none"),children:[h.jsx("option",{value:"none",children:"none (graph only)"}),h.jsx("option",{value:"anthropic",children:"Anthropic"}),h.jsx("option",{value:"openai",children:"OpenAI"}),h.jsx("option",{value:"grok",children:"Grok / xAI"}),h.jsx("option",{value:"deepseek",children:"DeepSeek"}),h.jsx("option",{value:"cursor",children:"Cursor-compatible (OpenAI protocol)"}),h.jsx("option",{value:"ollama",children:"Ollama local"})]}),h.jsx("label",{htmlFor:"ai_api_key",children:"API key"}),h.jsx("input",{id:"ai_api_key",name:"ai_api_key",type:"password",autoComplete:"off"}),h.jsx("label",{htmlFor:"ai_model",children:"Model"}),h.jsx("input",{id:"ai_model",name:"ai_model","data-testid":"ai-model",placeholder:"optional override",defaultValue:String(((ni=J.ai)==null?void 0:ni.model)||"")}),h.jsx("label",{htmlFor:"ai_base_url",children:"Base URL"}),h.jsx("input",{id:"ai_base_url",name:"ai_base_url","data-testid":"ai-base-url",placeholder:"optional, OpenAI-compatible",defaultValue:String(((_r=J.ai)==null?void 0:_r.base_url)||"")}),h.jsx("button",{className:"btn primary",type:"submit","data-testid":"btn-save-settings",children:"Save"})]})]})]})]}),xe?h.jsx(bN,{initialPath:o,onClose:()=>pe(!1),onSelect:$=>{if(He.current){w("Wait for the current job to finish before switching workspace.");return}pe(!1),Dn($)}}):null]})}function RN({review:t,findings:r,aiNote:o,busy:s,tourIndex:a,onTour:u,onAskAi:c,onCopy:f,onPost:g}){var v,x,m,S,_,E,b,w,P,N,j,L,z,W;const y=[...new Set(t.confidence.reasons||[])];return h.jsxs(h.Fragment,{children:[h.jsxs("div",{className:`merge-box ${t.confidence.level}`,children:[h.jsxs("div",{className:`level ${t.confidence.level}`,children:[t.confidence.level.toUpperCase()," — ",t.title]}),y.length?h.jsx("ul",{className:"reasons",children:y.map(D=>h.jsx("li",{children:D},D))}):null,t.low_risk?h.jsx("span",{className:"chip",children:"low-risk"}):null,t.change_kinds.map(D=>h.jsx("span",{className:"chip",children:Po(D)},D)),(v=t.contract_break)!=null&&v.kind&&t.contract_break.kind!=="none"?h.jsxs("span",{className:`chip ${t.contract_break.kind==="breaking"?"blocker":""}`,"data-testid":"contract-kind",children:["contract ",t.contract_break.kind]}):null]}),h.jsxs("div",{className:"metrics",children:[h.jsxs("div",{className:"metric",children:[h.jsxs("div",{className:"n",children:[t.confidence.covered_sinks,"/",t.confidence.sinks]}),h.jsx("div",{className:"l",children:"Sinks tested"})]}),h.jsxs("div",{className:"metric",children:[h.jsx("div",{className:"n",children:r.length}),h.jsx("div",{className:"l",children:"Findings"})]}),h.jsxs("div",{className:"metric",children:[h.jsx("div",{className:"n",children:t.residuals.length}),h.jsx("div",{className:"l",children:"Residuals"})]})]}),h.jsx("pre",{className:"headline",children:t.headline}),t.index?h.jsxs("details",{className:"section",open:!0,children:[h.jsxs("summary",{children:["Index ",h.jsx("span",{className:"count",children:t.index.counts.nodes})]}),h.jsxs("div",{className:"muted",children:["Walked ",t.index.counts.nodes," nodes / ",t.index.counts.edges," edges",t.index.reindex_skipped?" from an unchanged index":t.index.reindexed?" after an incremental refresh":" from the existing index",t.index.django_boot&&t.index.django_boot!=="off"?` · Django boot ${t.index.django_boot}`:"",(x=t.workspace)!=null&&x.three_dot?" · three-dot range":""]})]}):null,h.jsxs("details",{className:"section",open:!0,children:[h.jsxs("summary",{children:["Read this ",h.jsx("span",{className:"count",children:t.read_order.length})]}),t.read_order.map((D,G)=>h.jsxs("div",{className:G===a?"read-item tour-current":"read-item",children:[h.jsxs("span",{className:"file",children:[G+1,". ",D.path]}),h.jsx("div",{className:"why",children:D.why})]},D.path)),t.read_order.length>0?h.jsxs("div",{className:"btn-row tour-row",children:[h.jsx("button",{type:"button",className:"btn","data-testid":"btn-tour-prev",disabled:a<=0,onClick:()=>u(Math.max(0,a-1)),children:"Previous"}),h.jsx("button",{type:"button",className:"btn primary","data-testid":"btn-tour-next",disabled:a>=t.read_order.length-1,onClick:()=>u(Math.min(t.read_order.length-1,a+1)),children:"Next in read order"}),h.jsxs("span",{className:"muted",children:[a+1,"/",t.read_order.length]})]}):null]}),h.jsxs("details",{className:"section",children:[h.jsxs("summary",{children:["Clusters ",h.jsx("span",{className:"count",children:t.clusters.length})]}),t.clusters.map(D=>h.jsxs("div",{className:"muted",children:[h.jsx("strong",{children:D.title})," — ",D.files.join(", ")]},D.id))]}),h.jsxs("details",{className:"section",open:!0,children:[h.jsxs("summary",{children:["Architecture ",h.jsx("span",{className:"count",children:r.length})]}),r.length===0?h.jsx("div",{className:"muted",children:t.architecture_note}):r.map(D=>h.jsxs("div",{className:"finding",children:[h.jsx("span",{className:`chip ${D.severity}`,children:D.severity}),D.message]},D.rule+D.message))]}),h.jsx(km,{cards:t.deepening}),(S=(m=t.contract_break)==null?void 0:m.reasons)!=null&&S.length?h.jsxs("details",{className:"section",open:!0,children:[h.jsxs("summary",{children:["Contract ",h.jsx("span",{className:"count",children:t.contract_break.kind})]}),t.contract_break.reasons.map(D=>h.jsx("div",{className:"muted",children:D},D))]}):null,(_=t.auth)!=null&&_.note?h.jsxs("details",{className:"section",open:!0,children:[h.jsx("summary",{children:"Auth"}),h.jsx("div",{className:"muted",children:t.auth.note}),(t.auth.missing_permissions||[]).map(D=>h.jsxs("div",{className:"finding",children:[h.jsx("span",{className:"chip warning",children:"missing"}),D.name]},D.id))]}):null,(t.suggested_tests||[]).length?h.jsxs("details",{className:"section",open:!0,children:[h.jsxs("summary",{children:["Suggested tests ",h.jsx("span",{className:"count",children:(E=t.suggested_tests)==null?void 0:E.length})]}),(t.suggested_tests||[]).map(D=>h.jsxs("div",{className:"residual",children:[h.jsx("strong",{children:D.title}),h.jsx("pre",{className:"headline",children:D.body})]},D.title))]}):null,(b=t.trend)!=null&&b.note?h.jsxs("details",{className:"section",children:[h.jsx("summary",{children:"Confidence trend"}),h.jsx("div",{className:"muted",children:t.trend.note}),(t.trend.points||[]).slice(0,6).map(D=>h.jsxs("div",{className:"muted",children:[D.level," · ",jp(D.created_at),D.sinks!=null?` · ${D.sinks} sinks`:""]},D.id))]}):null,h.jsxs("details",{className:"section",open:!0,children:[h.jsxs("summary",{children:["Residual ",h.jsx("span",{className:"count",children:t.residuals.length})]}),h.jsx("p",{className:"muted",children:"AI is only used here, on what the graph could not close."}),t.residuals.map(D=>h.jsx("div",{className:"residual muted",children:D},D))]}),(P=(w=t.evolution)==null?void 0:w.notes)!=null&&P.length||(j=(N=t.evolution)==null?void 0:N.hotspots)!=null&&j.some(D=>D.commits)?h.jsxs("details",{className:"section",children:[h.jsx("summary",{children:"Churn & coupling"}),(((L=t.evolution)==null?void 0:L.notes)||[]).map(D=>h.jsx("div",{className:"muted",children:D},D)),(((z=t.evolution)==null?void 0:z.hotspots)||[]).filter(D=>D.commits).slice(0,6).map(D=>h.jsxs("div",{className:"muted",children:[h.jsx("span",{className:"file",children:D.path})," — ",D.commits," commits, bus factor ",D.bus_factor]},D.path))]}):null,h.jsxs("div",{className:"btn-row",children:[h.jsx("button",{type:"button",className:"btn",disabled:s,onClick:c,children:"Ask configured model"}),h.jsx("button",{type:"button",className:"btn","data-testid":"btn-copy-markdown",onClick:f,children:"Copy markdown"}),h.jsx("button",{type:"button",className:"btn","data-testid":"btn-post-comment",onClick:g,children:"Post to PR"})]}),o?h.jsx("pre",{className:"headline",children:o}):null,h.jsx("div",{className:"kicker",children:"Reviewers"}),h.jsx("div",{className:"muted",children:t.suggested_reviewers.join(", ")||"—"}),(W=t.knowledge_owners)!=null&&W.length?h.jsxs("div",{className:"muted",children:["Knowledge: ",t.knowledge_owners.join(", ")]}):null]})}function LN({architecture:t,busy:r,onReindex:o,onReview:s}){const a=t.findings.filter(u=>!u.waived);return h.jsxs(h.Fragment,{children:[h.jsxs("div",{className:"merge-box high",children:[h.jsxs("div",{className:"level high",children:["INDEXED — ",t.counts.nodes," nodes"]}),h.jsxs("div",{className:"muted",style:{marginTop:8},children:[t.indexed_at?`Last index ${jp(t.indexed_at)}`:"Indexed",t.incremental?" · incremental":" · full",t.stale?" · stale":"",t.django_boot&&t.django_boot!=="off"?` · Django boot ${t.django_boot}`:""]}),h.jsxs("span",{className:"chip",children:[t.counts.edges," edges"]}),t.has_config?h.jsx("span",{className:"chip",children:"loadpath.yml"}):null]}),h.jsxs("details",{className:"section",open:!0,children:[h.jsx("summary",{children:"Bounded contexts"}),Object.values(t.contexts).map(u=>h.jsxs("div",{className:"muted",children:[h.jsx("strong",{children:u.name})," — ",(u.django_apps||[]).join(", ")||"no apps"," ·"," ",(u.owners||[]).join(", ")||"unowned"]},u.name))]}),h.jsxs("details",{className:"section",children:[h.jsxs("summary",{children:["Rules ",h.jsx("span",{className:"count",children:(t.rules||[]).length})]}),(t.rules||[]).map(u=>h.jsx("div",{className:"muted",children:u},u))]}),h.jsxs("details",{className:"section",open:!0,children:[h.jsxs("summary",{children:["Findings ",h.jsx("span",{className:"count",children:a.length})]}),a.length===0?h.jsx("div",{className:"muted",children:"No architecture rule hits on the full graph."}):a.map(u=>h.jsxs("div",{className:"finding",children:[h.jsx("span",{className:`chip ${u.severity}`,children:u.severity}),u.message]},u.rule+u.message))]}),h.jsx(km,{cards:t.deepening}),h.jsxs("details",{className:"section",open:!0,children:[h.jsx("summary",{children:"Types"}),h.jsx("table",{className:"type-table",children:h.jsx("tbody",{children:Object.entries(t.type_counts||{}).sort((u,c)=>c[1]-u[1]).slice(0,12).map(([u,c])=>h.jsxs("tr",{children:[h.jsx("td",{children:bl(u)}),h.jsx("td",{children:c})]},u))})})]}),h.jsxs("div",{className:"btn-row",children:[h.jsx("button",{type:"button",className:"btn",disabled:r,onClick:o,"data-testid":"btn-full-reindex",children:"Full reindex"}),h.jsx("button",{type:"button",className:"btn primary",disabled:r,onClick:s,children:"Review against this index"})]})]})}function km({cards:t}){const r=t||[];return r.length?h.jsxs("details",{className:"section",open:!0,"data-testid":"deepening-list",children:[h.jsxs("summary",{children:["Depth ",h.jsx("span",{className:"count",children:r.length})]}),h.jsx("p",{className:"muted",children:"Deepening opportunities: more behaviour behind a smaller interface, at a real seam."}),r.map(o=>h.jsxs("div",{className:"finding","data-testid":"deepening-card",children:[h.jsx("span",{className:`chip ${o.strength}`,children:h0(o.strength)}),o.top?h.jsx("span",{className:"chip",children:"top"}):null,h.jsx("strong",{children:o.title}),h.jsx("div",{className:"why",children:o.message}),o.deletion_test?h.jsxs("div",{className:"muted",children:["Deletion test: ",o.deletion_test]}):null,o.before&&o.after?h.jsxs("div",{className:"muted",children:[o.before," → ",o.after]}):null]},o.rule+o.title))]}):null}Sm(_m());c0.createRoot(document.getElementById("root")).render(h.jsx(F.StrictMode,{children:h.jsx(TN,{})}));export{Bk as L,DN as a,AN as c,h as j,zN as l,F as r,bl as t}; diff --git a/src/loadpath/static/assets/index-PXVMaQl_.js b/src/loadpath/static/assets/index-PXVMaQl_.js deleted file mode 100644 index 51281a4..0000000 --- a/src/loadpath/static/assets/index-PXVMaQl_.js +++ /dev/null @@ -1,62 +0,0 @@ -(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))s(a);new MutationObserver(a=>{for(const u of a)if(u.type==="childList")for(const c of u.addedNodes)c.tagName==="LINK"&&c.rel==="modulepreload"&&s(c)}).observe(document,{childList:!0,subtree:!0});function o(a){const u={};return a.integrity&&(u.integrity=a.integrity),a.referrerPolicy&&(u.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?u.credentials="include":a.crossOrigin==="anonymous"?u.credentials="omit":u.credentials="same-origin",u}function s(a){if(a.ep)return;a.ep=!0;const u=o(a);fetch(a.href,u)}})();function wp(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var Su={exports:{}},wo={},ku={exports:{}},Te={};/** - * @license React - * react.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Uf;function Qy(){if(Uf)return Te;Uf=1;var t=Symbol.for("react.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),s=Symbol.for("react.strict_mode"),a=Symbol.for("react.profiler"),u=Symbol.for("react.provider"),c=Symbol.for("react.context"),f=Symbol.for("react.forward_ref"),g=Symbol.for("react.suspense"),y=Symbol.for("react.memo"),v=Symbol.for("react.lazy"),x=Symbol.iterator;function m(M){return M===null||typeof M!="object"?null:(M=x&&M[x]||M["@@iterator"],typeof M=="function"?M:null)}var S={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},k=Object.assign,j={};function b(M,R,re){this.props=M,this.context=R,this.refs=j,this.updater=re||S}b.prototype.isReactComponent={},b.prototype.setState=function(M,R){if(typeof M!="object"&&typeof M!="function"&&M!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,M,R,"setState")},b.prototype.forceUpdate=function(M){this.updater.enqueueForceUpdate(this,M,"forceUpdate")};function _(){}_.prototype=b.prototype;function P(M,R,re){this.props=M,this.context=R,this.refs=j,this.updater=re||S}var N=P.prototype=new _;N.constructor=P,k(N,b.prototype),N.isPureReactComponent=!0;var E=Array.isArray,L=Object.prototype.hasOwnProperty,A={current:null},V={key:!0,ref:!0,__self:!0,__source:!0};function z(M,R,re){var ie,ce={},fe=null,de=null;if(R!=null)for(ie in R.ref!==void 0&&(de=R.ref),R.key!==void 0&&(fe=""+R.key),R)L.call(R,ie)&&!V.hasOwnProperty(ie)&&(ce[ie]=R[ie]);var Q=arguments.length-2;if(Q===1)ce.children=re;else if(1>>1,R=T[M];if(0>>1;Ma(ce,B))fea(de,ce)?(T[M]=de,T[fe]=B,M=fe):(T[M]=ce,T[ie]=B,M=ie);else if(fea(de,B))T[M]=de,T[fe]=B,M=fe;else break e}}return F}function a(T,F){var B=T.sortIndex-F.sortIndex;return B!==0?B:T.id-F.id}if(typeof performance=="object"&&typeof performance.now=="function"){var u=performance;t.unstable_now=function(){return u.now()}}else{var c=Date,f=c.now();t.unstable_now=function(){return c.now()-f}}var g=[],y=[],v=1,x=null,m=3,S=!1,k=!1,j=!1,b=typeof setTimeout=="function"?setTimeout:null,_=typeof clearTimeout=="function"?clearTimeout:null,P=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function N(T){for(var F=o(y);F!==null;){if(F.callback===null)s(y);else if(F.startTime<=T)s(y),F.sortIndex=F.expirationTime,r(g,F);else break;F=o(y)}}function E(T){if(j=!1,N(T),!k)if(o(g)!==null)k=!0,U(L);else{var F=o(y);F!==null&&Y(E,F.startTime-T)}}function L(T,F){k=!1,j&&(j=!1,_(z),z=-1),S=!0;var B=m;try{for(N(F),x=o(g);x!==null&&(!(x.expirationTime>F)||T&&!J());){var M=x.callback;if(typeof M=="function"){x.callback=null,m=x.priorityLevel;var R=M(x.expirationTime<=F);F=t.unstable_now(),typeof R=="function"?x.callback=R:x===o(g)&&s(g),N(F)}else s(g);x=o(g)}if(x!==null)var re=!0;else{var ie=o(y);ie!==null&&Y(E,ie.startTime-F),re=!1}return re}finally{x=null,m=B,S=!1}}var A=!1,V=null,z=-1,G=5,ee=-1;function J(){return!(t.unstable_now()-eeT||125M?(T.sortIndex=B,r(y,T),o(g)===null&&T===o(y)&&(j?(_(z),z=-1):j=!0,Y(E,B-M))):(T.sortIndex=R,r(g,T),k||S||(k=!0,U(L))),T},t.unstable_shouldYield=J,t.unstable_wrapCallback=function(T){var F=m;return function(){var B=m;m=F;try{return T.apply(this,arguments)}finally{m=B}}}})(ju)),ju}var Kf;function n0(){return Kf||(Kf=1,Eu.exports=t0()),Eu.exports}/** - * @license React - * react-dom.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Qf;function r0(){if(Qf)return Ct;Qf=1;var t=$o(),r=n0();function o(e){for(var n="https://reactjs.org/docs/error-decoder.html?invariant="+e,i=1;i"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),g=Object.prototype.hasOwnProperty,y=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,v={},x={};function m(e){return g.call(x,e)?!0:g.call(v,e)?!1:y.test(e)?x[e]=!0:(v[e]=!0,!1)}function S(e,n,i,l){if(i!==null&&i.type===0)return!1;switch(typeof n){case"function":case"symbol":return!0;case"boolean":return l?!1:i!==null?!i.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function k(e,n,i,l){if(n===null||typeof n>"u"||S(e,n,i,l))return!0;if(l)return!1;if(i!==null)switch(i.type){case 3:return!n;case 4:return n===!1;case 5:return isNaN(n);case 6:return isNaN(n)||1>n}return!1}function j(e,n,i,l,d,p,w){this.acceptsBooleans=n===2||n===3||n===4,this.attributeName=l,this.attributeNamespace=d,this.mustUseProperty=i,this.propertyName=e,this.type=n,this.sanitizeURL=p,this.removeEmptyString=w}var b={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){b[e]=new j(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var n=e[0];b[n]=new j(n,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){b[e]=new j(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){b[e]=new j(e,2,!1,e,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){b[e]=new j(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){b[e]=new j(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){b[e]=new j(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){b[e]=new j(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){b[e]=new j(e,5,!1,e.toLowerCase(),null,!1,!1)});var _=/[\-:]([a-z])/g;function P(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var n=e.replace(_,P);b[n]=new j(n,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var n=e.replace(_,P);b[n]=new j(n,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var n=e.replace(_,P);b[n]=new j(n,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){b[e]=new j(e,1,!1,e.toLowerCase(),null,!1,!1)}),b.xlinkHref=new j("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){b[e]=new j(e,1,!1,e.toLowerCase(),null,!0,!0)});function N(e,n,i,l){var d=b.hasOwnProperty(n)?b[n]:null;(d!==null?d.type!==0:l||!(2I||d[w]!==p[I]){var $=` -`+d[w].replace(" at new "," at ");return e.displayName&&$.includes("")&&($=$.replace("",e.displayName)),$}while(1<=w&&0<=I);break}}}finally{re=!1,Error.prepareStackTrace=i}return(e=e?e.displayName||e.name:"")?R(e):""}function ce(e){switch(e.tag){case 5:return R(e.type);case 16:return R("Lazy");case 13:return R("Suspense");case 19:return R("SuspenseList");case 0:case 2:case 15:return e=ie(e.type,!1),e;case 11:return e=ie(e.type.render,!1),e;case 1:return e=ie(e.type,!0),e;default:return""}}function fe(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case V:return"Fragment";case A:return"Portal";case G:return"Profiler";case z:return"StrictMode";case q:return"Suspense";case C:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case J:return(e.displayName||"Context")+".Consumer";case ee:return(e._context.displayName||"Context")+".Provider";case ne:var n=e.render;return e=e.displayName,e||(e=n.displayName||n.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case W:return n=e.displayName||null,n!==null?n:fe(e.type)||"Memo";case U:n=e._payload,e=e._init;try{return fe(e(n))}catch{}}return null}function de(e){var n=e.type;switch(e.tag){case 24:return"Cache";case 9:return(n.displayName||"Context")+".Consumer";case 10:return(n._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=n.render,e=e.displayName||e.name||"",n.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return n;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return fe(n);case 8:return n===z?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof n=="function")return n.displayName||n.name||null;if(typeof n=="string")return n}return null}function Q(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function le(e){var n=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(n==="checkbox"||n==="radio")}function me(e){var n=le(e)?"checked":"value",i=Object.getOwnPropertyDescriptor(e.constructor.prototype,n),l=""+e[n];if(!e.hasOwnProperty(n)&&typeof i<"u"&&typeof i.get=="function"&&typeof i.set=="function"){var d=i.get,p=i.set;return Object.defineProperty(e,n,{configurable:!0,get:function(){return d.call(this)},set:function(w){l=""+w,p.call(this,w)}}),Object.defineProperty(e,n,{enumerable:i.enumerable}),{getValue:function(){return l},setValue:function(w){l=""+w},stopTracking:function(){e._valueTracker=null,delete e[n]}}}}function ke(e){e._valueTracker||(e._valueTracker=me(e))}function xe(e){if(!e)return!1;var n=e._valueTracker;if(!n)return!0;var i=n.getValue(),l="";return e&&(l=le(e)?e.checked?"true":"false":e.value),e=l,e!==i?(n.setValue(e),!0):!1}function pe(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function be(e,n){var i=n.checked;return B({},n,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:i??e._wrapperState.initialChecked})}function Pe(e,n){var i=n.defaultValue==null?"":n.defaultValue,l=n.checked!=null?n.checked:n.defaultChecked;i=Q(n.value!=null?n.value:i),e._wrapperState={initialChecked:l,initialValue:i,controlled:n.type==="checkbox"||n.type==="radio"?n.checked!=null:n.value!=null}}function Ce(e,n){n=n.checked,n!=null&&N(e,"checked",n,!1)}function Re(e,n){Ce(e,n);var i=Q(n.value),l=n.type;if(i!=null)l==="number"?(i===0&&e.value===""||e.value!=i)&&(e.value=""+i):e.value!==""+i&&(e.value=""+i);else if(l==="submit"||l==="reset"){e.removeAttribute("value");return}n.hasOwnProperty("value")?nt(e,n.type,i):n.hasOwnProperty("defaultValue")&&nt(e,n.type,Q(n.defaultValue)),n.checked==null&&n.defaultChecked!=null&&(e.defaultChecked=!!n.defaultChecked)}function tt(e,n,i){if(n.hasOwnProperty("value")||n.hasOwnProperty("defaultValue")){var l=n.type;if(!(l!=="submit"&&l!=="reset"||n.value!==void 0&&n.value!==null))return;n=""+e._wrapperState.initialValue,i||n===e.value||(e.value=n),e.defaultValue=n}i=e.name,i!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,i!==""&&(e.name=i)}function nt(e,n,i){(n!=="number"||pe(e.ownerDocument)!==e)&&(i==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+i&&(e.defaultValue=""+i))}var Je=Array.isArray;function Qe(e,n,i,l){if(e=e.options,n){n={};for(var d=0;d"+n.valueOf().toString()+"",n=mt.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;n.firstChild;)e.appendChild(n.firstChild)}});function ht(e,n){if(n){var i=e.firstChild;if(i&&i===e.lastChild&&i.nodeType===3){i.nodeValue=n;return}}e.textContent=n}var Gt={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},_n=["Webkit","ms","Moz","O"];Object.keys(Gt).forEach(function(e){_n.forEach(function(n){n=n+e.charAt(0).toUpperCase()+e.substring(1),Gt[n]=Gt[e]})});function zn(e,n,i){return n==null||typeof n=="boolean"||n===""?"":i||typeof n!="number"||n===0||Gt.hasOwnProperty(e)&&Gt[e]?(""+n).trim():n+"px"}function Gr(e,n){e=e.style;for(var i in n)if(n.hasOwnProperty(i)){var l=i.indexOf("--")===0,d=zn(i,n[i],l);i==="float"&&(i="cssFloat"),l?e.setProperty(i,d):e[i]=d}}var It=B({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Sn(e,n){if(n){if(It[e]&&(n.children!=null||n.dangerouslySetInnerHTML!=null))throw Error(o(137,e));if(n.dangerouslySetInnerHTML!=null){if(n.children!=null)throw Error(o(60));if(typeof n.dangerouslySetInnerHTML!="object"||!("__html"in n.dangerouslySetInnerHTML))throw Error(o(61))}if(n.style!=null&&typeof n.style!="object")throw Error(o(62))}}function Dn(e,n){if(e.indexOf("-")===-1)return typeof n.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var un=null;function $n(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var gr=null,cn=null,dn=null;function Xr(e){if(e=io(e)){if(typeof gr!="function")throw Error(o(280));var n=e.stateNode;n&&(n=cs(n),gr(e.stateNode,e.type,n))}}function qr(e){cn?dn?dn.push(e):dn=[e]:cn=e}function Kr(){if(cn){var e=cn,n=dn;if(dn=cn=null,Xr(e),n)for(e=0;e>>=0,e===0?32:31-(Hl(e)/Bl|0)|0}var ii=64,oi=4194304;function _r(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Nn(e,n){var i=e.pendingLanes;if(i===0)return 0;var l=0,d=e.suspendedLanes,p=e.pingedLanes,w=i&268435455;if(w!==0){var I=w&~d;I!==0?l=_r(I):(p&=w,p!==0&&(l=_r(p)))}else w=i&~d,w!==0?l=_r(w):p!==0&&(l=_r(p));if(l===0)return 0;if(n!==0&&n!==l&&(n&d)===0&&(d=l&-l,p=n&-n,d>=p||d===16&&(p&4194240)!==0))return n;if((l&4)!==0&&(l|=i&16),n=e.entangledLanes,n!==0)for(e=e.entanglements,n&=l;0i;i++)n.push(e);return n}function kr(e,n,i){e.pendingLanes|=n,n!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,n=31-Lt(n),e[n]=i}function Ul(e,n){var i=e.pendingLanes&~n;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=n,e.mutableReadLanes&=n,e.entangledLanes&=n,n=e.entanglements;var l=e.eventTimes;for(e=e.expirationTimes;0=qi),Dc=" ",$c=!1;function Oc(e,n){switch(e){case"keyup":return Ym.indexOf(n.keyCode)!==-1;case"keydown":return n.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Fc(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var ui=!1;function Xm(e,n){switch(e){case"compositionend":return Fc(n);case"keypress":return n.which!==32?null:($c=!0,Dc);case"textInput":return e=n.data,e===Dc&&$c?null:e;default:return null}}function qm(e,n){if(ui)return e==="compositionend"||!na&&Oc(e,n)?(e=Ic(),Jo=Kl=qn=null,ui=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(n.ctrlKey||n.altKey||n.metaKey)||n.ctrlKey&&n.altKey){if(n.char&&1=n)return{node:i,offset:n-e};e=l}e:{for(;i;){if(i.nextSibling){i=i.nextSibling;break e}i=i.parentNode}i=void 0}i=Gc(i)}}function qc(e,n){return e&&n?e===n?!0:e&&e.nodeType===3?!1:n&&n.nodeType===3?qc(e,n.parentNode):"contains"in e?e.contains(n):e.compareDocumentPosition?!!(e.compareDocumentPosition(n)&16):!1:!1}function Kc(){for(var e=window,n=pe();n instanceof e.HTMLIFrameElement;){try{var i=typeof n.contentWindow.location.href=="string"}catch{i=!1}if(i)e=n.contentWindow;else break;n=pe(e.document)}return n}function oa(e){var n=e&&e.nodeName&&e.nodeName.toLowerCase();return n&&(n==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||n==="textarea"||e.contentEditable==="true")}function iy(e){var n=Kc(),i=e.focusedElem,l=e.selectionRange;if(n!==i&&i&&i.ownerDocument&&qc(i.ownerDocument.documentElement,i)){if(l!==null&&oa(i)){if(n=l.start,e=l.end,e===void 0&&(e=n),"selectionStart"in i)i.selectionStart=n,i.selectionEnd=Math.min(e,i.value.length);else if(e=(n=i.ownerDocument||document)&&n.defaultView||window,e.getSelection){e=e.getSelection();var d=i.textContent.length,p=Math.min(l.start,d);l=l.end===void 0?p:Math.min(l.end,d),!e.extend&&p>l&&(d=l,l=p,p=d),d=Xc(i,p);var w=Xc(i,l);d&&w&&(e.rangeCount!==1||e.anchorNode!==d.node||e.anchorOffset!==d.offset||e.focusNode!==w.node||e.focusOffset!==w.offset)&&(n=n.createRange(),n.setStart(d.node,d.offset),e.removeAllRanges(),p>l?(e.addRange(n),e.extend(w.node,w.offset)):(n.setEnd(w.node,w.offset),e.addRange(n)))}}for(n=[],e=i;e=e.parentNode;)e.nodeType===1&&n.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof i.focus=="function"&&i.focus(),i=0;i=document.documentMode,ci=null,sa=null,Ji=null,la=!1;function Qc(e,n,i){var l=i.window===i?i.document:i.nodeType===9?i:i.ownerDocument;la||ci==null||ci!==pe(l)||(l=ci,"selectionStart"in l&&oa(l)?l={start:l.selectionStart,end:l.selectionEnd}:(l=(l.ownerDocument&&l.ownerDocument.defaultView||window).getSelection(),l={anchorNode:l.anchorNode,anchorOffset:l.anchorOffset,focusNode:l.focusNode,focusOffset:l.focusOffset}),Ji&&Zi(Ji,l)||(Ji=l,l=ls(sa,"onSelect"),0gi||(e.current=xa[gi],xa[gi]=null,gi--)}function Be(e,n){gi++,xa[gi]=e.current,e.current=n}var Jn={},yt=Zn(Jn),kt=Zn(!1),Er=Jn;function mi(e,n){var i=e.type.contextTypes;if(!i)return Jn;var l=e.stateNode;if(l&&l.__reactInternalMemoizedUnmaskedChildContext===n)return l.__reactInternalMemoizedMaskedChildContext;var d={},p;for(p in i)d[p]=n[p];return l&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=n,e.__reactInternalMemoizedMaskedChildContext=d),d}function Nt(e){return e=e.childContextTypes,e!=null}function ds(){We(kt),We(yt)}function fd(e,n,i){if(yt.current!==Jn)throw Error(o(168));Be(yt,n),Be(kt,i)}function hd(e,n,i){var l=e.stateNode;if(n=n.childContextTypes,typeof l.getChildContext!="function")return i;l=l.getChildContext();for(var d in l)if(!(d in n))throw Error(o(108,de(e)||"Unknown",d));return B({},i,l)}function fs(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Jn,Er=yt.current,Be(yt,e),Be(kt,kt.current),!0}function pd(e,n,i){var l=e.stateNode;if(!l)throw Error(o(169));i?(e=hd(e,n,Er),l.__reactInternalMemoizedMergedChildContext=e,We(kt),We(yt),Be(yt,e)):We(kt),Be(kt,i)}var jn=null,hs=!1,wa=!1;function gd(e){jn===null?jn=[e]:jn.push(e)}function my(e){hs=!0,gd(e)}function er(){if(!wa&&jn!==null){wa=!0;var e=0,n=Oe;try{var i=jn;for(Oe=1;e>=w,d-=w,bn=1<<32-Lt(n)+d|i<je?(dt=Ee,Ee=null):dt=Ee.sibling;var De=oe(X,Ee,K[je],ue);if(De===null){Ee===null&&(Ee=dt);break}e&&Ee&&De.alternate===null&&n(X,Ee),H=p(De,H,je),Ne===null?we=De:Ne.sibling=De,Ne=De,Ee=dt}if(je===K.length)return i(X,Ee),Ge&&br(X,je),we;if(Ee===null){for(;jeje?(dt=Ee,Ee=null):dt=Ee.sibling;var ur=oe(X,Ee,De.value,ue);if(ur===null){Ee===null&&(Ee=dt);break}e&&Ee&&ur.alternate===null&&n(X,Ee),H=p(ur,H,je),Ne===null?we=ur:Ne.sibling=ur,Ne=ur,Ee=dt}if(De.done)return i(X,Ee),Ge&&br(X,je),we;if(Ee===null){for(;!De.done;je++,De=K.next())De=ae(X,De.value,ue),De!==null&&(H=p(De,H,je),Ne===null?we=De:Ne.sibling=De,Ne=De);return Ge&&br(X,je),we}for(Ee=l(X,Ee);!De.done;je++,De=K.next())De=he(Ee,X,je,De.value,ue),De!==null&&(e&&De.alternate!==null&&Ee.delete(De.key===null?je:De.key),H=p(De,H,je),Ne===null?we=De:Ne.sibling=De,Ne=De);return e&&Ee.forEach(function(Ky){return n(X,Ky)}),Ge&&br(X,je),we}function et(X,H,K,ue){if(typeof K=="object"&&K!==null&&K.type===V&&K.key===null&&(K=K.props.children),typeof K=="object"&&K!==null){switch(K.$$typeof){case L:e:{for(var we=K.key,Ne=H;Ne!==null;){if(Ne.key===we){if(we=K.type,we===V){if(Ne.tag===7){i(X,Ne.sibling),H=d(Ne,K.props.children),H.return=X,X=H;break e}}else if(Ne.elementType===we||typeof we=="object"&&we!==null&&we.$$typeof===U&&_d(we)===Ne.type){i(X,Ne.sibling),H=d(Ne,K.props),H.ref=oo(X,Ne,K),H.return=X,X=H;break e}i(X,Ne);break}else n(X,Ne);Ne=Ne.sibling}K.type===V?(H=Ar(K.props.children,X.mode,ue,K.key),H.return=X,X=H):(ue=Hs(K.type,K.key,K.props,null,X.mode,ue),ue.ref=oo(X,H,K),ue.return=X,X=ue)}return w(X);case A:e:{for(Ne=K.key;H!==null;){if(H.key===Ne)if(H.tag===4&&H.stateNode.containerInfo===K.containerInfo&&H.stateNode.implementation===K.implementation){i(X,H.sibling),H=d(H,K.children||[]),H.return=X,X=H;break e}else{i(X,H);break}else n(X,H);H=H.sibling}H=yu(K,X.mode,ue),H.return=X,X=H}return w(X);case U:return Ne=K._init,et(X,H,Ne(K._payload),ue)}if(Je(K))return ye(X,H,K,ue);if(F(K))return ve(X,H,K,ue);ys(X,K)}return typeof K=="string"&&K!==""||typeof K=="number"?(K=""+K,H!==null&&H.tag===6?(i(X,H.sibling),H=d(H,K),H.return=X,X=H):(i(X,H),H=mu(K,X.mode,ue),H.return=X,X=H),w(X)):i(X,H)}return et}var wi=Sd(!0),kd=Sd(!1),vs=Zn(null),xs=null,_i=null,ja=null;function ba(){ja=_i=xs=null}function Ca(e){var n=vs.current;We(vs),e._currentValue=n}function Ma(e,n,i){for(;e!==null;){var l=e.alternate;if((e.childLanes&n)!==n?(e.childLanes|=n,l!==null&&(l.childLanes|=n)):l!==null&&(l.childLanes&n)!==n&&(l.childLanes|=n),e===i)break;e=e.return}}function Si(e,n){xs=e,ja=_i=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&n)!==0&&(Et=!0),e.firstContext=null)}function Vt(e){var n=e._currentValue;if(ja!==e)if(e={context:e,memoizedValue:n,next:null},_i===null){if(xs===null)throw Error(o(308));_i=e,xs.dependencies={lanes:0,firstContext:e}}else _i=_i.next=e;return n}var Cr=null;function Pa(e){Cr===null?Cr=[e]:Cr.push(e)}function Nd(e,n,i,l){var d=n.interleaved;return d===null?(i.next=i,Pa(n)):(i.next=d.next,d.next=i),n.interleaved=i,Mn(e,l)}function Mn(e,n){e.lanes|=n;var i=e.alternate;for(i!==null&&(i.lanes|=n),i=e,e=e.return;e!==null;)e.childLanes|=n,i=e.alternate,i!==null&&(i.childLanes|=n),i=e,e=e.return;return i.tag===3?i.stateNode:null}var tr=!1;function Ia(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Ed(e,n){e=e.updateQueue,n.updateQueue===e&&(n.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Pn(e,n){return{eventTime:e,lane:n,tag:0,payload:null,callback:null,next:null}}function nr(e,n,i){var l=e.updateQueue;if(l===null)return null;if(l=l.shared,(Ae&2)!==0){var d=l.pending;return d===null?n.next=n:(n.next=d.next,d.next=n),l.pending=n,Mn(e,i)}return d=l.interleaved,d===null?(n.next=n,Pa(l)):(n.next=d.next,d.next=n),l.interleaved=n,Mn(e,i)}function ws(e,n,i){if(n=n.updateQueue,n!==null&&(n=n.shared,(i&4194240)!==0)){var l=n.lanes;l&=e.pendingLanes,i|=l,n.lanes=i,si(e,i)}}function jd(e,n){var i=e.updateQueue,l=e.alternate;if(l!==null&&(l=l.updateQueue,i===l)){var d=null,p=null;if(i=i.firstBaseUpdate,i!==null){do{var w={eventTime:i.eventTime,lane:i.lane,tag:i.tag,payload:i.payload,callback:i.callback,next:null};p===null?d=p=w:p=p.next=w,i=i.next}while(i!==null);p===null?d=p=n:p=p.next=n}else d=p=n;i={baseState:l.baseState,firstBaseUpdate:d,lastBaseUpdate:p,shared:l.shared,effects:l.effects},e.updateQueue=i;return}e=i.lastBaseUpdate,e===null?i.firstBaseUpdate=n:e.next=n,i.lastBaseUpdate=n}function _s(e,n,i,l){var d=e.updateQueue;tr=!1;var p=d.firstBaseUpdate,w=d.lastBaseUpdate,I=d.shared.pending;if(I!==null){d.shared.pending=null;var $=I,Z=$.next;$.next=null,w===null?p=Z:w.next=Z,w=$;var se=e.alternate;se!==null&&(se=se.updateQueue,I=se.lastBaseUpdate,I!==w&&(I===null?se.firstBaseUpdate=Z:I.next=Z,se.lastBaseUpdate=$))}if(p!==null){var ae=d.baseState;w=0,se=Z=$=null,I=p;do{var oe=I.lane,he=I.eventTime;if((l&oe)===oe){se!==null&&(se=se.next={eventTime:he,lane:0,tag:I.tag,payload:I.payload,callback:I.callback,next:null});e:{var ye=e,ve=I;switch(oe=n,he=i,ve.tag){case 1:if(ye=ve.payload,typeof ye=="function"){ae=ye.call(he,ae,oe);break e}ae=ye;break e;case 3:ye.flags=ye.flags&-65537|128;case 0:if(ye=ve.payload,oe=typeof ye=="function"?ye.call(he,ae,oe):ye,oe==null)break e;ae=B({},ae,oe);break e;case 2:tr=!0}}I.callback!==null&&I.lane!==0&&(e.flags|=64,oe=d.effects,oe===null?d.effects=[I]:oe.push(I))}else he={eventTime:he,lane:oe,tag:I.tag,payload:I.payload,callback:I.callback,next:null},se===null?(Z=se=he,$=ae):se=se.next=he,w|=oe;if(I=I.next,I===null){if(I=d.shared.pending,I===null)break;oe=I,I=oe.next,oe.next=null,d.lastBaseUpdate=oe,d.shared.pending=null}}while(!0);if(se===null&&($=ae),d.baseState=$,d.firstBaseUpdate=Z,d.lastBaseUpdate=se,n=d.shared.interleaved,n!==null){d=n;do w|=d.lane,d=d.next;while(d!==n)}else p===null&&(d.shared.lanes=0);Ir|=w,e.lanes=w,e.memoizedState=ae}}function bd(e,n,i){if(e=n.effects,n.effects=null,e!==null)for(n=0;ni?i:4,e(!0);var l=za.transition;za.transition={};try{e(!1),n()}finally{Oe=i,za.transition=l}}function Yd(){return Wt().memoizedState}function wy(e,n,i){var l=sr(e);if(i={lane:l,action:i,hasEagerState:!1,eagerState:null,next:null},Gd(e))Xd(n,i);else if(i=Nd(e,n,i,l),i!==null){var d=St();Jt(i,e,l,d),qd(i,n,l)}}function _y(e,n,i){var l=sr(e),d={lane:l,action:i,hasEagerState:!1,eagerState:null,next:null};if(Gd(e))Xd(n,d);else{var p=e.alternate;if(e.lanes===0&&(p===null||p.lanes===0)&&(p=n.lastRenderedReducer,p!==null))try{var w=n.lastRenderedState,I=p(w,i);if(d.hasEagerState=!0,d.eagerState=I,Xt(I,w)){var $=n.interleaved;$===null?(d.next=d,Pa(n)):(d.next=$.next,$.next=d),n.interleaved=d;return}}catch{}finally{}i=Nd(e,n,d,l),i!==null&&(d=St(),Jt(i,e,l,d),qd(i,n,l))}}function Gd(e){var n=e.alternate;return e===qe||n!==null&&n===qe}function Xd(e,n){uo=Ns=!0;var i=e.pending;i===null?n.next=n:(n.next=i.next,i.next=n),e.pending=n}function qd(e,n,i){if((i&4194240)!==0){var l=n.lanes;l&=e.pendingLanes,i|=l,n.lanes=i,si(e,i)}}var bs={readContext:Vt,useCallback:vt,useContext:vt,useEffect:vt,useImperativeHandle:vt,useInsertionEffect:vt,useLayoutEffect:vt,useMemo:vt,useReducer:vt,useRef:vt,useState:vt,useDebugValue:vt,useDeferredValue:vt,useTransition:vt,useMutableSource:vt,useSyncExternalStore:vt,useId:vt,unstable_isNewReconciler:!1},Sy={readContext:Vt,useCallback:function(e,n){return mn().memoizedState=[e,n===void 0?null:n],e},useContext:Vt,useEffect:$d,useImperativeHandle:function(e,n,i){return i=i!=null?i.concat([e]):null,Es(4194308,4,Hd.bind(null,n,e),i)},useLayoutEffect:function(e,n){return Es(4194308,4,e,n)},useInsertionEffect:function(e,n){return Es(4,2,e,n)},useMemo:function(e,n){var i=mn();return n=n===void 0?null:n,e=e(),i.memoizedState=[e,n],e},useReducer:function(e,n,i){var l=mn();return n=i!==void 0?i(n):n,l.memoizedState=l.baseState=n,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:n},l.queue=e,e=e.dispatch=wy.bind(null,qe,e),[l.memoizedState,e]},useRef:function(e){var n=mn();return e={current:e},n.memoizedState=e},useState:zd,useDebugValue:Va,useDeferredValue:function(e){return mn().memoizedState=e},useTransition:function(){var e=zd(!1),n=e[0];return e=xy.bind(null,e[1]),mn().memoizedState=e,[n,e]},useMutableSource:function(){},useSyncExternalStore:function(e,n,i){var l=qe,d=mn();if(Ge){if(i===void 0)throw Error(o(407));i=i()}else{if(i=n(),ct===null)throw Error(o(349));(Pr&30)!==0||Id(l,n,i)}d.memoizedState=i;var p={value:i,getSnapshot:n};return d.queue=p,$d(Rd.bind(null,l,p,e),[e]),l.flags|=2048,ho(9,Td.bind(null,l,p,i,n),void 0,null),i},useId:function(){var e=mn(),n=ct.identifierPrefix;if(Ge){var i=Cn,l=bn;i=(l&~(1<<32-Lt(l)-1)).toString(32)+i,n=":"+n+"R"+i,i=co++,0<\/script>",e=e.removeChild(e.firstChild)):typeof l.is=="string"?e=w.createElement(i,{is:l.is}):(e=w.createElement(i),i==="select"&&(w=e,l.multiple?w.multiple=!0:l.size&&(w.size=l.size))):e=w.createElementNS(e,i),e[pn]=n,e[ro]=l,mf(e,n,!1,!1),n.stateNode=e;e:{switch(w=Dn(i,l),i){case"dialog":Ve("cancel",e),Ve("close",e),d=l;break;case"iframe":case"object":case"embed":Ve("load",e),d=l;break;case"video":case"audio":for(d=0;dbi&&(n.flags|=128,l=!0,po(p,!1),n.lanes=4194304)}else{if(!l)if(e=Ss(w),e!==null){if(n.flags|=128,l=!0,i=e.updateQueue,i!==null&&(n.updateQueue=i,n.flags|=4),po(p,!0),p.tail===null&&p.tailMode==="hidden"&&!w.alternate&&!Ge)return xt(n),null}else 2*Fe()-p.renderingStartTime>bi&&i!==1073741824&&(n.flags|=128,l=!0,po(p,!1),n.lanes=4194304);p.isBackwards?(w.sibling=n.child,n.child=w):(i=p.last,i!==null?i.sibling=w:n.child=w,p.last=w)}return p.tail!==null?(n=p.tail,p.rendering=n,p.tail=n.sibling,p.renderingStartTime=Fe(),n.sibling=null,i=Xe.current,Be(Xe,l?i&1|2:i&1),n):(xt(n),null);case 22:case 23:return hu(),l=n.memoizedState!==null,e!==null&&e.memoizedState!==null!==l&&(n.flags|=8192),l&&(n.mode&1)!==0?($t&1073741824)!==0&&(xt(n),n.subtreeFlags&6&&(n.flags|=8192)):xt(n),null;case 24:return null;case 25:return null}throw Error(o(156,n.tag))}function Py(e,n){switch(Sa(n),n.tag){case 1:return Nt(n.type)&&ds(),e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 3:return ki(),We(kt),We(yt),Aa(),e=n.flags,(e&65536)!==0&&(e&128)===0?(n.flags=e&-65537|128,n):null;case 5:return Ra(n),null;case 13:if(We(Xe),e=n.memoizedState,e!==null&&e.dehydrated!==null){if(n.alternate===null)throw Error(o(340));xi()}return e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 19:return We(Xe),null;case 4:return ki(),null;case 10:return Ca(n.type._context),null;case 22:case 23:return hu(),null;case 24:return null;default:return null}}var Is=!1,wt=!1,Iy=typeof WeakSet=="function"?WeakSet:Set,ge=null;function Ei(e,n){var i=e.ref;if(i!==null)if(typeof i=="function")try{i(null)}catch(l){Ze(e,n,l)}else i.current=null}function tu(e,n,i){try{i()}catch(l){Ze(e,n,l)}}var xf=!1;function Ty(e,n){if(ha=Qo,e=Kc(),oa(e)){if("selectionStart"in e)var i={start:e.selectionStart,end:e.selectionEnd};else e:{i=(i=e.ownerDocument)&&i.defaultView||window;var l=i.getSelection&&i.getSelection();if(l&&l.rangeCount!==0){i=l.anchorNode;var d=l.anchorOffset,p=l.focusNode;l=l.focusOffset;try{i.nodeType,p.nodeType}catch{i=null;break e}var w=0,I=-1,$=-1,Z=0,se=0,ae=e,oe=null;t:for(;;){for(var he;ae!==i||d!==0&&ae.nodeType!==3||(I=w+d),ae!==p||l!==0&&ae.nodeType!==3||($=w+l),ae.nodeType===3&&(w+=ae.nodeValue.length),(he=ae.firstChild)!==null;)oe=ae,ae=he;for(;;){if(ae===e)break t;if(oe===i&&++Z===d&&(I=w),oe===p&&++se===l&&($=w),(he=ae.nextSibling)!==null)break;ae=oe,oe=ae.parentNode}ae=he}i=I===-1||$===-1?null:{start:I,end:$}}else i=null}i=i||{start:0,end:0}}else i=null;for(pa={focusedElem:e,selectionRange:i},Qo=!1,ge=n;ge!==null;)if(n=ge,e=n.child,(n.subtreeFlags&1028)!==0&&e!==null)e.return=n,ge=e;else for(;ge!==null;){n=ge;try{var ye=n.alternate;if((n.flags&1024)!==0)switch(n.tag){case 0:case 11:case 15:break;case 1:if(ye!==null){var ve=ye.memoizedProps,et=ye.memoizedState,X=n.stateNode,H=X.getSnapshotBeforeUpdate(n.elementType===n.type?ve:Kt(n.type,ve),et);X.__reactInternalSnapshotBeforeUpdate=H}break;case 3:var K=n.stateNode.containerInfo;K.nodeType===1?K.textContent="":K.nodeType===9&&K.documentElement&&K.removeChild(K.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(o(163))}}catch(ue){Ze(n,n.return,ue)}if(e=n.sibling,e!==null){e.return=n.return,ge=e;break}ge=n.return}return ye=xf,xf=!1,ye}function go(e,n,i){var l=n.updateQueue;if(l=l!==null?l.lastEffect:null,l!==null){var d=l=l.next;do{if((d.tag&e)===e){var p=d.destroy;d.destroy=void 0,p!==void 0&&tu(n,i,p)}d=d.next}while(d!==l)}}function Ts(e,n){if(n=n.updateQueue,n=n!==null?n.lastEffect:null,n!==null){var i=n=n.next;do{if((i.tag&e)===e){var l=i.create;i.destroy=l()}i=i.next}while(i!==n)}}function nu(e){var n=e.ref;if(n!==null){var i=e.stateNode;switch(e.tag){case 5:e=i;break;default:e=i}typeof n=="function"?n(e):n.current=e}}function wf(e){var n=e.alternate;n!==null&&(e.alternate=null,wf(n)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(n=e.stateNode,n!==null&&(delete n[pn],delete n[ro],delete n[va],delete n[py],delete n[gy])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function _f(e){return e.tag===5||e.tag===3||e.tag===4}function Sf(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||_f(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function ru(e,n,i){var l=e.tag;if(l===5||l===6)e=e.stateNode,n?i.nodeType===8?i.parentNode.insertBefore(e,n):i.insertBefore(e,n):(i.nodeType===8?(n=i.parentNode,n.insertBefore(e,i)):(n=i,n.appendChild(e)),i=i._reactRootContainer,i!=null||n.onclick!==null||(n.onclick=us));else if(l!==4&&(e=e.child,e!==null))for(ru(e,n,i),e=e.sibling;e!==null;)ru(e,n,i),e=e.sibling}function iu(e,n,i){var l=e.tag;if(l===5||l===6)e=e.stateNode,n?i.insertBefore(e,n):i.appendChild(e);else if(l!==4&&(e=e.child,e!==null))for(iu(e,n,i),e=e.sibling;e!==null;)iu(e,n,i),e=e.sibling}var pt=null,Qt=!1;function rr(e,n,i){for(i=i.child;i!==null;)kf(e,n,i),i=i.sibling}function kf(e,n,i){if(Rt&&typeof Rt.onCommitFiberUnmount=="function")try{Rt.onCommitFiberUnmount(ri,i)}catch{}switch(i.tag){case 5:wt||Ei(i,n);case 6:var l=pt,d=Qt;pt=null,rr(e,n,i),pt=l,Qt=d,pt!==null&&(Qt?(e=pt,i=i.stateNode,e.nodeType===8?e.parentNode.removeChild(i):e.removeChild(i)):pt.removeChild(i.stateNode));break;case 18:pt!==null&&(Qt?(e=pt,i=i.stateNode,e.nodeType===8?ya(e.parentNode,i):e.nodeType===1&&ya(e,i),Yi(e)):ya(pt,i.stateNode));break;case 4:l=pt,d=Qt,pt=i.stateNode.containerInfo,Qt=!0,rr(e,n,i),pt=l,Qt=d;break;case 0:case 11:case 14:case 15:if(!wt&&(l=i.updateQueue,l!==null&&(l=l.lastEffect,l!==null))){d=l=l.next;do{var p=d,w=p.destroy;p=p.tag,w!==void 0&&((p&2)!==0||(p&4)!==0)&&tu(i,n,w),d=d.next}while(d!==l)}rr(e,n,i);break;case 1:if(!wt&&(Ei(i,n),l=i.stateNode,typeof l.componentWillUnmount=="function"))try{l.props=i.memoizedProps,l.state=i.memoizedState,l.componentWillUnmount()}catch(I){Ze(i,n,I)}rr(e,n,i);break;case 21:rr(e,n,i);break;case 22:i.mode&1?(wt=(l=wt)||i.memoizedState!==null,rr(e,n,i),wt=l):rr(e,n,i);break;default:rr(e,n,i)}}function Nf(e){var n=e.updateQueue;if(n!==null){e.updateQueue=null;var i=e.stateNode;i===null&&(i=e.stateNode=new Iy),n.forEach(function(l){var d=Hy.bind(null,e,l);i.has(l)||(i.add(l),l.then(d,d))})}}function Zt(e,n){var i=n.deletions;if(i!==null)for(var l=0;ld&&(d=w),l&=~p}if(l=d,l=Fe()-l,l=(120>l?120:480>l?480:1080>l?1080:1920>l?1920:3e3>l?3e3:4320>l?4320:1960*Ly(l/1960))-l,10e?16:e,or===null)var l=!1;else{if(e=or,or=null,Ds=0,(Ae&6)!==0)throw Error(o(331));var d=Ae;for(Ae|=4,ge=e.current;ge!==null;){var p=ge,w=p.child;if((ge.flags&16)!==0){var I=p.deletions;if(I!==null){for(var $=0;$Fe()-lu?Rr(e,0):su|=i),bt(e,n)}function Df(e,n){n===0&&((e.mode&1)===0?n=1:(n=oi,oi<<=1,(oi&130023424)===0&&(oi=4194304)));var i=St();e=Mn(e,n),e!==null&&(kr(e,n,i),bt(e,i))}function Fy(e){var n=e.memoizedState,i=0;n!==null&&(i=n.retryLane),Df(e,i)}function Hy(e,n){var i=0;switch(e.tag){case 13:var l=e.stateNode,d=e.memoizedState;d!==null&&(i=d.retryLane);break;case 19:l=e.stateNode;break;default:throw Error(o(314))}l!==null&&l.delete(n),Df(e,i)}var $f;$f=function(e,n,i){if(e!==null)if(e.memoizedProps!==n.pendingProps||kt.current)Et=!0;else{if((e.lanes&i)===0&&(n.flags&128)===0)return Et=!1,Cy(e,n,i);Et=(e.flags&131072)!==0}else Et=!1,Ge&&(n.flags&1048576)!==0&&md(n,gs,n.index);switch(n.lanes=0,n.tag){case 2:var l=n.type;Ps(e,n),e=n.pendingProps;var d=mi(n,yt.current);Si(n,i),d=$a(null,n,l,e,d,i);var p=Oa();return n.flags|=1,typeof d=="object"&&d!==null&&typeof d.render=="function"&&d.$$typeof===void 0?(n.tag=1,n.memoizedState=null,n.updateQueue=null,Nt(l)?(p=!0,fs(n)):p=!1,n.memoizedState=d.state!==null&&d.state!==void 0?d.state:null,Ia(n),d.updater=Cs,n.stateNode=d,d._reactInternals=n,Ua(n,l,e,i),n=qa(null,n,l,!0,p,i)):(n.tag=0,Ge&&p&&_a(n),_t(null,n,d,i),n=n.child),n;case 16:l=n.elementType;e:{switch(Ps(e,n),e=n.pendingProps,d=l._init,l=d(l._payload),n.type=l,d=n.tag=Vy(l),e=Kt(l,e),d){case 0:n=Xa(null,n,l,e,i);break e;case 1:n=cf(null,n,l,e,i);break e;case 11:n=of(null,n,l,e,i);break e;case 14:n=sf(null,n,l,Kt(l.type,e),i);break e}throw Error(o(306,l,""))}return n;case 0:return l=n.type,d=n.pendingProps,d=n.elementType===l?d:Kt(l,d),Xa(e,n,l,d,i);case 1:return l=n.type,d=n.pendingProps,d=n.elementType===l?d:Kt(l,d),cf(e,n,l,d,i);case 3:e:{if(df(n),e===null)throw Error(o(387));l=n.pendingProps,p=n.memoizedState,d=p.element,Ed(e,n),_s(n,l,null,i);var w=n.memoizedState;if(l=w.element,p.isDehydrated)if(p={element:l,isDehydrated:!1,cache:w.cache,pendingSuspenseBoundaries:w.pendingSuspenseBoundaries,transitions:w.transitions},n.updateQueue.baseState=p,n.memoizedState=p,n.flags&256){d=Ni(Error(o(423)),n),n=ff(e,n,l,i,d);break e}else if(l!==d){d=Ni(Error(o(424)),n),n=ff(e,n,l,i,d);break e}else for(Dt=Qn(n.stateNode.containerInfo.firstChild),zt=n,Ge=!0,qt=null,i=kd(n,null,l,i),n.child=i;i;)i.flags=i.flags&-3|4096,i=i.sibling;else{if(xi(),l===d){n=In(e,n,i);break e}_t(e,n,l,i)}n=n.child}return n;case 5:return Cd(n),e===null&&Na(n),l=n.type,d=n.pendingProps,p=e!==null?e.memoizedProps:null,w=d.children,ga(l,d)?w=null:p!==null&&ga(l,p)&&(n.flags|=32),uf(e,n),_t(e,n,w,i),n.child;case 6:return e===null&&Na(n),null;case 13:return hf(e,n,i);case 4:return Ta(n,n.stateNode.containerInfo),l=n.pendingProps,e===null?n.child=wi(n,null,l,i):_t(e,n,l,i),n.child;case 11:return l=n.type,d=n.pendingProps,d=n.elementType===l?d:Kt(l,d),of(e,n,l,d,i);case 7:return _t(e,n,n.pendingProps,i),n.child;case 8:return _t(e,n,n.pendingProps.children,i),n.child;case 12:return _t(e,n,n.pendingProps.children,i),n.child;case 10:e:{if(l=n.type._context,d=n.pendingProps,p=n.memoizedProps,w=d.value,Be(vs,l._currentValue),l._currentValue=w,p!==null)if(Xt(p.value,w)){if(p.children===d.children&&!kt.current){n=In(e,n,i);break e}}else for(p=n.child,p!==null&&(p.return=n);p!==null;){var I=p.dependencies;if(I!==null){w=p.child;for(var $=I.firstContext;$!==null;){if($.context===l){if(p.tag===1){$=Pn(-1,i&-i),$.tag=2;var Z=p.updateQueue;if(Z!==null){Z=Z.shared;var se=Z.pending;se===null?$.next=$:($.next=se.next,se.next=$),Z.pending=$}}p.lanes|=i,$=p.alternate,$!==null&&($.lanes|=i),Ma(p.return,i,n),I.lanes|=i;break}$=$.next}}else if(p.tag===10)w=p.type===n.type?null:p.child;else if(p.tag===18){if(w=p.return,w===null)throw Error(o(341));w.lanes|=i,I=w.alternate,I!==null&&(I.lanes|=i),Ma(w,i,n),w=p.sibling}else w=p.child;if(w!==null)w.return=p;else for(w=p;w!==null;){if(w===n){w=null;break}if(p=w.sibling,p!==null){p.return=w.return,w=p;break}w=w.return}p=w}_t(e,n,d.children,i),n=n.child}return n;case 9:return d=n.type,l=n.pendingProps.children,Si(n,i),d=Vt(d),l=l(d),n.flags|=1,_t(e,n,l,i),n.child;case 14:return l=n.type,d=Kt(l,n.pendingProps),d=Kt(l.type,d),sf(e,n,l,d,i);case 15:return lf(e,n,n.type,n.pendingProps,i);case 17:return l=n.type,d=n.pendingProps,d=n.elementType===l?d:Kt(l,d),Ps(e,n),n.tag=1,Nt(l)?(e=!0,fs(n)):e=!1,Si(n,i),Qd(n,l,d),Ua(n,l,d,i),qa(null,n,l,!0,e,i);case 19:return gf(e,n,i);case 22:return af(e,n,i)}throw Error(o(156,n.tag))};function Of(e,n){return te(e,n)}function By(e,n,i,l){this.tag=e,this.key=i,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=n,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=l,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Yt(e,n,i,l){return new By(e,n,i,l)}function gu(e){return e=e.prototype,!(!e||!e.isReactComponent)}function Vy(e){if(typeof e=="function")return gu(e)?1:0;if(e!=null){if(e=e.$$typeof,e===ne)return 11;if(e===W)return 14}return 2}function ar(e,n){var i=e.alternate;return i===null?(i=Yt(e.tag,n,e.key,e.mode),i.elementType=e.elementType,i.type=e.type,i.stateNode=e.stateNode,i.alternate=e,e.alternate=i):(i.pendingProps=n,i.type=e.type,i.flags=0,i.subtreeFlags=0,i.deletions=null),i.flags=e.flags&14680064,i.childLanes=e.childLanes,i.lanes=e.lanes,i.child=e.child,i.memoizedProps=e.memoizedProps,i.memoizedState=e.memoizedState,i.updateQueue=e.updateQueue,n=e.dependencies,i.dependencies=n===null?null:{lanes:n.lanes,firstContext:n.firstContext},i.sibling=e.sibling,i.index=e.index,i.ref=e.ref,i}function Hs(e,n,i,l,d,p){var w=2;if(l=e,typeof e=="function")gu(e)&&(w=1);else if(typeof e=="string")w=5;else e:switch(e){case V:return Ar(i.children,d,p,n);case z:w=8,d|=8;break;case G:return e=Yt(12,i,n,d|2),e.elementType=G,e.lanes=p,e;case q:return e=Yt(13,i,n,d),e.elementType=q,e.lanes=p,e;case C:return e=Yt(19,i,n,d),e.elementType=C,e.lanes=p,e;case Y:return Bs(i,d,p,n);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case ee:w=10;break e;case J:w=9;break e;case ne:w=11;break e;case W:w=14;break e;case U:w=16,l=null;break e}throw Error(o(130,e==null?e:typeof e,""))}return n=Yt(w,i,n,d),n.elementType=e,n.type=l,n.lanes=p,n}function Ar(e,n,i,l){return e=Yt(7,e,l,n),e.lanes=i,e}function Bs(e,n,i,l){return e=Yt(22,e,l,n),e.elementType=Y,e.lanes=i,e.stateNode={isHidden:!1},e}function mu(e,n,i){return e=Yt(6,e,null,n),e.lanes=i,e}function yu(e,n,i){return n=Yt(4,e.children!==null?e.children:[],e.key,n),n.lanes=i,n.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},n}function Wy(e,n,i,l,d){this.tag=n,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Sr(0),this.expirationTimes=Sr(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Sr(0),this.identifierPrefix=l,this.onRecoverableError=d,this.mutableSourceEagerHydrationData=null}function vu(e,n,i,l,d,p,w,I,$){return e=new Wy(e,n,i,I,$),n===1?(n=1,p===!0&&(n|=8)):n=0,p=Yt(3,null,null,n),e.current=p,p.stateNode=e,p.memoizedState={element:l,isDehydrated:i,cache:null,transitions:null,pendingSuspenseBoundaries:null},Ia(p),e}function Uy(e,n,i){var l=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(r){console.error(r)}}return t(),Nu.exports=r0(),Nu.exports}var Jf;function i0(){if(Jf)return qs;Jf=1;var t=_p();return qs.createRoot=t.createRoot,qs.hydrateRoot=t.hydrateRoot,qs}var o0=i0();function s0(t,r="Request failed"){const o=(t||"").trim();if(!o)return r;try{const a=JSON.parse(o).detail;if(typeof a=="string"&&a.trim())return a;if(Array.isArray(a)){const u=a.map(c=>typeof c=="string"?c:c&&typeof c=="object"&&"msg"in c?String(c.msg):"").filter(Boolean);if(u.length)return u.join("; ")}}catch{}return o}async function Ue(t,r){const o=await fetch(t,{...r,headers:{"Content-Type":"application/json",...(r==null?void 0:r.headers)||{}}});if(!o.ok){const s=await o.text();throw new Error(s0(s,o.statusText||"Request failed"))}return o.json()}const l0=["github_token","gitlab_token","gitlab_oauth_client_secret","bitbucket_token","bitbucket_oauth_client_secret","ai_api_key","ai_model","ai_base_url"],$e={health:()=>Ue("/api/health"),settings:()=>Ue("/api/settings"),saveSettings:t=>{const r={...t};for(const o of l0)r[o]===""&&delete r[o];return Ue("/api/settings",{method:"PUT",body:JSON.stringify(r)})},repos:()=>Ue("/api/repos"),browse:t=>Ue(`/api/fs${t?`?path=${encodeURIComponent(t)}`:""}`),gitRefs:(t,r=50)=>Ue(`/api/git/refs?repo_path=${encodeURIComponent(t)}&limit=${r}`),index:(t,r=!0)=>Ue("/api/index",{method:"POST",body:JSON.stringify({repo_path:t,incremental:r})}),indexStatus:t=>Ue(`/api/index?repo_path=${encodeURIComponent(t)}`),indexProgress:t=>Ue(`/api/index/progress?repo_path=${encodeURIComponent(t)}`),architecture:t=>Ue(`/api/architecture?repo_path=${encodeURIComponent(t)}`),review:(t,r,o,s=!0,a=!1)=>Ue("/api/review",{method:"POST",body:JSON.stringify({repo_path:t,base:r,head:o||null,reindex:s,incremental:!0,three_dot:!0,dirty:a})}),whatIf:(t,r)=>Ue("/api/whatif",{method:"POST",body:JSON.stringify({repo_path:t,node_id:r})}),reviewPr:(t,r,o,s)=>Ue("/api/prs/review",{method:"POST",body:JSON.stringify({provider:t,repo:r,number:o,repo_path:s||null})}),init:(t,r=!1)=>Ue("/api/init",{method:"POST",body:JSON.stringify({repo_path:t,overwrite:r})}),postComment:(t,r,o,s)=>Ue("/api/prs/comment",{method:"POST",body:JSON.stringify({provider:t,repo:r,number:o,markdown:s})}),graph:(t,r="full")=>Ue(`/api/graph?repo_path=${encodeURIComponent(t)}&scope=${r}`),prs:(t,r,o="open")=>Ue("/api/prs",{method:"POST",body:JSON.stringify({provider:t,repo:r,state:o})}),scmRepos:t=>Ue(`/api/scm/repos?provider=${encodeURIComponent(t)}`),oauthStatus:()=>Ue("/api/oauth/status"),githubOAuthStart:()=>Ue("/api/oauth/github/start",{method:"POST",body:"{}"}),githubOAuthPoll:t=>Ue("/api/oauth/github/poll",{method:"POST",body:JSON.stringify({flow_id:t})}),bitbucketOAuthStart:()=>Ue("/api/oauth/bitbucket/start"),gitlabOAuthStart:()=>Ue("/api/oauth/gitlab/start"),oauthDisconnect:t=>Ue("/api/oauth/disconnect",{method:"POST",body:JSON.stringify({provider:t})}),residual:t=>Ue("/api/ai/residual",{method:"POST",body:JSON.stringify({review:t})})};function bo(t){return t.replaceAll("_"," ")}function a0(t){return t.replaceAll("_"," ")}function kl(t){return t.split(".").pop()||t}function Sp(t){if(!t)return"";const r=new Date(t);return Number.isNaN(r.getTime())?t:r.toLocaleString()}function u0(t){return t.split(/[\\/]/).filter(Boolean).pop()||t}function Dr(t){return t.replace(/([/\\._:@-])/g,"$1​")}function Yr({className:t,children:r}){return h.jsx("svg",{className:t,width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:r})}function c0({className:t}){return h.jsxs(Yr,{className:t,children:[h.jsx("path",{d:"M3 3.5h6.5L13 7v5.5H3z"}),h.jsx("path",{d:"M9.5 3.5V7H13"}),h.jsx("path",{d:"M5.5 9.5h5M5.5 11.5h3.5"})]})}function d0({className:t}){return h.jsxs(Yr,{className:t,children:[h.jsx("rect",{x:"2.5",y:"2.5",width:"4.5",height:"4.5",rx:"0.8"}),h.jsx("rect",{x:"9",y:"2.5",width:"4.5",height:"4.5",rx:"0.8"}),h.jsx("rect",{x:"2.5",y:"9",width:"4.5",height:"4.5",rx:"0.8"}),h.jsx("rect",{x:"9",y:"9",width:"4.5",height:"4.5",rx:"0.8"})]})}function f0({className:t}){return h.jsxs(Yr,{className:t,children:[h.jsx("circle",{cx:"4",cy:"8",r:"1.6"}),h.jsx("circle",{cx:"12",cy:"4",r:"1.6"}),h.jsx("circle",{cx:"12",cy:"12",r:"1.6"}),h.jsx("path",{d:"M5.5 7.2 10.4 4.8M5.5 8.8 10.4 11.2"})]})}function h0({className:t}){return h.jsxs(Yr,{className:t,children:[h.jsx("circle",{cx:"4.5",cy:"4",r:"1.4"}),h.jsx("circle",{cx:"4.5",cy:"12",r:"1.4"}),h.jsx("circle",{cx:"11.5",cy:"12",r:"1.4"}),h.jsx("path",{d:"M4.5 5.5v5M4.5 8h4.2a3 3 0 0 1 3 3"})]})}function p0({className:t}){return h.jsxs(Yr,{className:t,children:[h.jsx("circle",{cx:"8",cy:"8",r:"2.1"}),h.jsx("path",{d:"M8 2.5v1.6M8 11.9v1.6M2.5 8h1.6M11.9 8h1.6M4.1 4.1l1.1 1.1M10.8 10.8l1.1 1.1M11.9 4.1l-1.1 1.1M5.2 10.8l-1.1 1.1"})]})}function kp({className:t}){return h.jsx(Yr,{className:t,children:h.jsx("path",{d:"M2.5 4.5h4L8 6h5.5v6.5h-11z"})})}function g0({className:t}){return h.jsx(Yr,{className:t,children:h.jsx("path",{d:"M4 6.5 8 10.5 12 6.5"})})}const m0="modulepreload",y0=function(t,r){return new URL(t,r).href},eh={},v0=function(r,o,s){let a=Promise.resolve();if(o&&o.length>0){let c=function(v){return Promise.all(v.map(x=>Promise.resolve(x).then(m=>({status:"fulfilled",value:m}),m=>({status:"rejected",reason:m}))))};const f=document.getElementsByTagName("link"),g=document.querySelector("meta[property=csp-nonce]"),y=(g==null?void 0:g.nonce)||(g==null?void 0:g.getAttribute("nonce"));a=c(o.map(v=>{if(v=y0(v,s),v in eh)return;eh[v]=!0;const x=v.endsWith(".css"),m=x?'[rel="stylesheet"]':"";if(!!s)for(let j=f.length-1;j>=0;j--){const b=f[j];if(b.href===v&&(!x||b.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${v}"]${m}`))return;const k=document.createElement("link");if(k.rel=x?"stylesheet":m0,x||(k.as="script"),k.crossOrigin="",k.href=v,y&&k.setAttribute("nonce",y),document.head.appendChild(k),x)return new Promise((j,b)=>{k.addEventListener("load",j),k.addEventListener("error",()=>b(new Error(`Unable to preload CSS for ${v}`)))})}))}function u(c){const f=new Event("vite:preloadError",{cancelable:!0});if(f.payload=c,window.dispatchEvent(f),!f.defaultPrevented)throw c}return a.then(c=>{for(const f of c||[])f.status==="rejected"&&u(f.reason);return r().catch(u)})};function it(t){if(typeof t=="string"||typeof t=="number")return""+t;let r="";if(Array.isArray(t))for(let o=0,s;o{}};function Nl(){for(var t=0,r=arguments.length,o={},s;t=0&&(s=o.slice(a+1),o=o.slice(0,a)),o&&!r.hasOwnProperty(o))throw new Error("unknown type: "+o);return{type:o,name:s}})}ll.prototype=Nl.prototype={constructor:ll,on:function(t,r){var o=this._,s=w0(t+"",o),a,u=-1,c=s.length;if(arguments.length<2){for(;++u0)for(var o=new Array(a),s=0,a,u;s=0&&(r=t.slice(0,o))!=="xmlns"&&(t=t.slice(o+1)),nh.hasOwnProperty(r)?{space:nh[r],local:t}:t}function S0(t){return function(){var r=this.ownerDocument,o=this.namespaceURI;return o===Bu&&r.documentElement.namespaceURI===Bu?r.createElement(t):r.createElementNS(o,t)}}function k0(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function Np(t){var r=El(t);return(r.local?k0:S0)(r)}function N0(){}function ic(t){return t==null?N0:function(){return this.querySelector(t)}}function E0(t){typeof t!="function"&&(t=ic(t));for(var r=this._groups,o=r.length,s=new Array(o),a=0;a=N&&(N=P+1);!(L=b[N])&&++N=0;)(c=s[a])&&(u&&c.compareDocumentPosition(u)^4&&u.parentNode.insertBefore(c,u),u=c);return this}function K0(t){t||(t=Q0);function r(x,m){return x&&m?t(x.__data__,m.__data__):!x-!m}for(var o=this._groups,s=o.length,a=new Array(s),u=0;ur?1:t>=r?0:NaN}function Z0(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this}function J0(){return Array.from(this)}function ev(){for(var t=this._groups,r=0,o=t.length;r1?this.each((r==null?dv:typeof r=="function"?hv:fv)(t,r,o??"")):Ri(this.node(),t)}function Ri(t,r){return t.style.getPropertyValue(r)||Mp(t).getComputedStyle(t,null).getPropertyValue(r)}function gv(t){return function(){delete this[t]}}function mv(t,r){return function(){this[t]=r}}function yv(t,r){return function(){var o=r.apply(this,arguments);o==null?delete this[t]:this[t]=o}}function vv(t,r){return arguments.length>1?this.each((r==null?gv:typeof r=="function"?yv:mv)(t,r)):this.node()[t]}function Pp(t){return t.trim().split(/^|\s+/)}function oc(t){return t.classList||new Ip(t)}function Ip(t){this._node=t,this._names=Pp(t.getAttribute("class")||"")}Ip.prototype={add:function(t){var r=this._names.indexOf(t);r<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},remove:function(t){var r=this._names.indexOf(t);r>=0&&(this._names.splice(r,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};function Tp(t,r){for(var o=oc(t),s=-1,a=r.length;++s=0&&(o=r.slice(s+1),r=r.slice(0,s)),{type:r,name:o}})}function Yv(t){return function(){var r=this.__on;if(r){for(var o=0,s=-1,a=r.length,u;o()=>t;function Vu(t,{sourceEvent:r,subject:o,target:s,identifier:a,active:u,x:c,y:f,dx:g,dy:y,dispatch:v}){Object.defineProperties(this,{type:{value:t,enumerable:!0,configurable:!0},sourceEvent:{value:r,enumerable:!0,configurable:!0},subject:{value:o,enumerable:!0,configurable:!0},target:{value:s,enumerable:!0,configurable:!0},identifier:{value:a,enumerable:!0,configurable:!0},active:{value:u,enumerable:!0,configurable:!0},x:{value:c,enumerable:!0,configurable:!0},y:{value:f,enumerable:!0,configurable:!0},dx:{value:g,enumerable:!0,configurable:!0},dy:{value:y,enumerable:!0,configurable:!0},_:{value:v}})}Vu.prototype.on=function(){var t=this._.on.apply(this._,arguments);return t===this._?this:t};function nx(t){return!t.ctrlKey&&!t.button}function rx(){return this.parentNode}function ix(t,r){return r??{x:t.x,y:t.y}}function ox(){return navigator.maxTouchPoints||"ontouchstart"in this}function $p(){var t=nx,r=rx,o=ix,s=ox,a={},u=Nl("start","drag","end"),c=0,f,g,y,v,x=0;function m(E){E.on("mousedown.drag",S).filter(s).on("touchstart.drag",b).on("touchmove.drag",_,tx).on("touchend.drag touchcancel.drag",P).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function S(E,L){if(!(v||!t.call(this,E,L))){var A=N(this,r.call(this,E,L),E,L,"mouse");A&&(Ot(E.view).on("mousemove.drag",k,Co).on("mouseup.drag",j,Co),zp(E.view),bu(E),y=!1,f=E.clientX,g=E.clientY,A("start",E))}}function k(E){if(Ii(E),!y){var L=E.clientX-f,A=E.clientY-g;y=L*L+A*A>x}a.mouse("drag",E)}function j(E){Ot(E.view).on("mousemove.drag mouseup.drag",null),Dp(E.view,y),Ii(E),a.mouse("end",E)}function b(E,L){if(t.call(this,E,L)){var A=E.changedTouches,V=r.call(this,E,L),z=A.length,G,ee;for(G=0;G>8&15|r>>4&240,r>>4&15|r&240,(r&15)<<4|r&15,1):o===8?Qs(r>>24&255,r>>16&255,r>>8&255,(r&255)/255):o===4?Qs(r>>12&15|r>>8&240,r>>8&15|r>>4&240,r>>4&15|r&240,((r&15)<<4|r&15)/255):null):(r=lx.exec(t))?new Mt(r[1],r[2],r[3],1):(r=ax.exec(t))?new Mt(r[1]*255/100,r[2]*255/100,r[3]*255/100,1):(r=ux.exec(t))?Qs(r[1],r[2],r[3],r[4]):(r=cx.exec(t))?Qs(r[1]*255/100,r[2]*255/100,r[3]*255/100,r[4]):(r=dx.exec(t))?uh(r[1],r[2]/100,r[3]/100,1):(r=fx.exec(t))?uh(r[1],r[2]/100,r[3]/100,r[4]):rh.hasOwnProperty(t)?sh(rh[t]):t==="transparent"?new Mt(NaN,NaN,NaN,0):null}function sh(t){return new Mt(t>>16&255,t>>8&255,t&255,1)}function Qs(t,r,o,s){return s<=0&&(t=r=o=NaN),new Mt(t,r,o,s)}function gx(t){return t instanceof Fo||(t=Hr(t)),t?(t=t.rgb(),new Mt(t.r,t.g,t.b,t.opacity)):new Mt}function Wu(t,r,o,s){return arguments.length===1?gx(t):new Mt(t,r,o,s??1)}function Mt(t,r,o,s){this.r=+t,this.g=+r,this.b=+o,this.opacity=+s}sc(Mt,Wu,Op(Fo,{brighter(t){return t=t==null?hl:Math.pow(hl,t),new Mt(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=t==null?Mo:Math.pow(Mo,t),new Mt(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new Mt(Or(this.r),Or(this.g),Or(this.b),pl(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:lh,formatHex:lh,formatHex8:mx,formatRgb:ah,toString:ah}));function lh(){return`#${$r(this.r)}${$r(this.g)}${$r(this.b)}`}function mx(){return`#${$r(this.r)}${$r(this.g)}${$r(this.b)}${$r((isNaN(this.opacity)?1:this.opacity)*255)}`}function ah(){const t=pl(this.opacity);return`${t===1?"rgb(":"rgba("}${Or(this.r)}, ${Or(this.g)}, ${Or(this.b)}${t===1?")":`, ${t})`}`}function pl(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function Or(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function $r(t){return t=Or(t),(t<16?"0":"")+t.toString(16)}function uh(t,r,o,s){return s<=0?t=r=o=NaN:o<=0||o>=1?t=r=NaN:r<=0&&(t=NaN),new tn(t,r,o,s)}function Fp(t){if(t instanceof tn)return new tn(t.h,t.s,t.l,t.opacity);if(t instanceof Fo||(t=Hr(t)),!t)return new tn;if(t instanceof tn)return t;t=t.rgb();var r=t.r/255,o=t.g/255,s=t.b/255,a=Math.min(r,o,s),u=Math.max(r,o,s),c=NaN,f=u-a,g=(u+a)/2;return f?(r===u?c=(o-s)/f+(o0&&g<1?0:c,new tn(c,f,g,t.opacity)}function yx(t,r,o,s){return arguments.length===1?Fp(t):new tn(t,r,o,s??1)}function tn(t,r,o,s){this.h=+t,this.s=+r,this.l=+o,this.opacity=+s}sc(tn,yx,Op(Fo,{brighter(t){return t=t==null?hl:Math.pow(hl,t),new tn(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=t==null?Mo:Math.pow(Mo,t),new tn(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+(this.h<0)*360,r=isNaN(t)||isNaN(this.s)?0:this.s,o=this.l,s=o+(o<.5?o:1-o)*r,a=2*o-s;return new Mt(Cu(t>=240?t-240:t+120,a,s),Cu(t,a,s),Cu(t<120?t+240:t-120,a,s),this.opacity)},clamp(){return new tn(ch(this.h),Zs(this.s),Zs(this.l),pl(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=pl(this.opacity);return`${t===1?"hsl(":"hsla("}${ch(this.h)}, ${Zs(this.s)*100}%, ${Zs(this.l)*100}%${t===1?")":`, ${t})`}`}}));function ch(t){return t=(t||0)%360,t<0?t+360:t}function Zs(t){return Math.max(0,Math.min(1,t||0))}function Cu(t,r,o){return(t<60?r+(o-r)*t/60:t<180?o:t<240?r+(o-r)*(240-t)/60:r)*255}const lc=t=>()=>t;function vx(t,r){return function(o){return t+o*r}}function xx(t,r,o){return t=Math.pow(t,o),r=Math.pow(r,o)-t,o=1/o,function(s){return Math.pow(t+s*r,o)}}function wx(t){return(t=+t)==1?Hp:function(r,o){return o-r?xx(r,o,t):lc(isNaN(r)?o:r)}}function Hp(t,r){var o=r-t;return o?vx(t,o):lc(isNaN(t)?r:t)}const gl=(function t(r){var o=wx(r);function s(a,u){var c=o((a=Wu(a)).r,(u=Wu(u)).r),f=o(a.g,u.g),g=o(a.b,u.b),y=Hp(a.opacity,u.opacity);return function(v){return a.r=c(v),a.g=f(v),a.b=g(v),a.opacity=y(v),a+""}}return s.gamma=t,s})(1);function _x(t,r){r||(r=[]);var o=t?Math.min(r.length,t.length):0,s=r.slice(),a;return function(u){for(a=0;ao&&(u=r.slice(o,u),f[c]?f[c]+=u:f[++c]=u),(s=s[0])===(a=a[0])?f[c]?f[c]+=a:f[++c]=a:(f[++c]=null,g.push({i:c,x:vn(s,a)})),o=Mu.lastIndex;return o180?v+=360:v-y>180&&(y+=360),m.push({i:x.push(a(x)+"rotate(",null,s)-2,x:vn(y,v)})):v&&x.push(a(x)+"rotate("+v+s)}function f(y,v,x,m){y!==v?m.push({i:x.push(a(x)+"skewX(",null,s)-2,x:vn(y,v)}):v&&x.push(a(x)+"skewX("+v+s)}function g(y,v,x,m,S,k){if(y!==x||v!==m){var j=S.push(a(S)+"scale(",null,",",null,")");k.push({i:j-4,x:vn(y,x)},{i:j-2,x:vn(v,m)})}else(x!==1||m!==1)&&S.push(a(S)+"scale("+x+","+m+")")}return function(y,v){var x=[],m=[];return y=t(y),v=t(v),u(y.translateX,y.translateY,v.translateX,v.translateY,x,m),c(y.rotate,v.rotate,x,m),f(y.skewX,v.skewX,x,m),g(y.scaleX,y.scaleY,v.scaleX,v.scaleY,x,m),y=v=null,function(S){for(var k=-1,j=m.length,b;++k=0&&t._call.call(void 0,r),t=t._next;--Li}function hh(){Br=(yl=Io.now())+jl,Li=ko=0;try{zx()}finally{Li=0,$x(),Br=0}}function Dx(){var t=Io.now(),r=t-yl;r>Up&&(jl-=r,yl=t)}function $x(){for(var t,r=ml,o,s=1/0;r;)r._call?(s>r._time&&(s=r._time),t=r,r=r._next):(o=r._next,r._next=null,r=t?t._next=o:ml=o);No=t,Gu(s)}function Gu(t){if(!Li){ko&&(ko=clearTimeout(ko));var r=t-Br;r>24?(t<1/0&&(ko=setTimeout(hh,t-Io.now()-jl)),_o&&(_o=clearInterval(_o))):(_o||(yl=Io.now(),_o=setInterval(Dx,Up)),Li=1,Yp(hh))}}function ph(t,r,o){var s=new vl;return r=r==null?0:+r,s.restart(a=>{s.stop(),t(a+r)},r,o),s}var Ox=Nl("start","end","cancel","interrupt"),Fx=[],Xp=0,gh=1,Xu=2,ul=3,mh=4,qu=5,cl=6;function bl(t,r,o,s,a,u){var c=t.__transition;if(!c)t.__transition={};else if(o in c)return;Hx(t,o,{name:r,index:s,group:a,on:Ox,tween:Fx,time:u.time,delay:u.delay,duration:u.duration,ease:u.ease,timer:null,state:Xp})}function uc(t,r){var o=sn(t,r);if(o.state>Xp)throw new Error("too late; already scheduled");return o}function wn(t,r){var o=sn(t,r);if(o.state>ul)throw new Error("too late; already running");return o}function sn(t,r){var o=t.__transition;if(!o||!(o=o[r]))throw new Error("transition not found");return o}function Hx(t,r,o){var s=t.__transition,a;s[r]=o,o.timer=Gp(u,0,o.time);function u(y){o.state=gh,o.timer.restart(c,o.delay,o.time),o.delay<=y&&c(y-o.delay)}function c(y){var v,x,m,S;if(o.state!==gh)return g();for(v in s)if(S=s[v],S.name===o.name){if(S.state===ul)return ph(c);S.state===mh?(S.state=cl,S.timer.stop(),S.on.call("interrupt",t,t.__data__,S.index,S.group),delete s[v]):+vXu&&s.state=0&&(r=r.slice(0,o)),!r||r==="start"})}function yw(t,r,o){var s,a,u=mw(r)?uc:wn;return function(){var c=u(this,t),f=c.on;f!==s&&(a=(s=f).copy()).on(r,o),c.on=a}}function vw(t,r){var o=this._id;return arguments.length<2?sn(this.node(),o).on.on(t):this.each(yw(o,t,r))}function xw(t){return function(){var r=this.parentNode;for(var o in this.__transition)if(+o!==t)return;r&&r.removeChild(this)}}function ww(){return this.on("end.remove",xw(this._id))}function _w(t){var r=this._name,o=this._id;typeof t!="function"&&(t=ic(t));for(var s=this._groups,a=s.length,u=new Array(a),c=0;c()=>t;function Yw(t,{sourceEvent:r,target:o,transform:s,dispatch:a}){Object.defineProperties(this,{type:{value:t,enumerable:!0,configurable:!0},sourceEvent:{value:r,enumerable:!0,configurable:!0},target:{value:o,enumerable:!0,configurable:!0},transform:{value:s,enumerable:!0,configurable:!0},_:{value:a}})}function Ln(t,r,o){this.k=t,this.x=r,this.y=o}Ln.prototype={constructor:Ln,scale:function(t){return t===1?this:new Ln(this.k*t,this.x,this.y)},translate:function(t,r){return t===0&r===0?this:new Ln(this.k,this.x+this.k*t,this.y+this.k*r)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var Cl=new Ln(1,0,0);Zp.prototype=Ln.prototype;function Zp(t){for(;!t.__zoom;)if(!(t=t.parentNode))return Cl;return t.__zoom}function Pu(t){t.stopImmediatePropagation()}function So(t){t.preventDefault(),t.stopImmediatePropagation()}function Gw(t){return(!t.ctrlKey||t.type==="wheel")&&!t.button}function Xw(){var t=this;return t instanceof SVGElement?(t=t.ownerSVGElement||t,t.hasAttribute("viewBox")?(t=t.viewBox.baseVal,[[t.x,t.y],[t.x+t.width,t.y+t.height]]):[[0,0],[t.width.baseVal.value,t.height.baseVal.value]]):[[0,0],[t.clientWidth,t.clientHeight]]}function yh(){return this.__zoom||Cl}function qw(t){return-t.deltaY*(t.deltaMode===1?.05:t.deltaMode?1:.002)*(t.ctrlKey?10:1)}function Kw(){return navigator.maxTouchPoints||"ontouchstart"in this}function Qw(t,r,o){var s=t.invertX(r[0][0])-o[0][0],a=t.invertX(r[1][0])-o[1][0],u=t.invertY(r[0][1])-o[0][1],c=t.invertY(r[1][1])-o[1][1];return t.translate(a>s?(s+a)/2:Math.min(0,s)||Math.max(0,a),c>u?(u+c)/2:Math.min(0,u)||Math.max(0,c))}function Jp(){var t=Gw,r=Xw,o=Qw,s=qw,a=Kw,u=[0,1/0],c=[[-1/0,-1/0],[1/0,1/0]],f=250,g=al,y=Nl("start","zoom","end"),v,x,m,S=500,k=150,j=0,b=10;function _(C){C.property("__zoom",yh).on("wheel.zoom",z,{passive:!1}).on("mousedown.zoom",G).on("dblclick.zoom",ee).filter(a).on("touchstart.zoom",J).on("touchmove.zoom",ne).on("touchend.zoom touchcancel.zoom",q).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}_.transform=function(C,W,U,Y){var T=C.selection?C.selection():C;T.property("__zoom",yh),C!==T?L(C,W,U,Y):T.interrupt().each(function(){A(this,arguments).event(Y).start().zoom(null,typeof W=="function"?W.apply(this,arguments):W).end()})},_.scaleBy=function(C,W,U,Y){_.scaleTo(C,function(){var T=this.__zoom.k,F=typeof W=="function"?W.apply(this,arguments):W;return T*F},U,Y)},_.scaleTo=function(C,W,U,Y){_.transform(C,function(){var T=r.apply(this,arguments),F=this.__zoom,B=U==null?E(T):typeof U=="function"?U.apply(this,arguments):U,M=F.invert(B),R=typeof W=="function"?W.apply(this,arguments):W;return o(N(P(F,R),B,M),T,c)},U,Y)},_.translateBy=function(C,W,U,Y){_.transform(C,function(){return o(this.__zoom.translate(typeof W=="function"?W.apply(this,arguments):W,typeof U=="function"?U.apply(this,arguments):U),r.apply(this,arguments),c)},null,Y)},_.translateTo=function(C,W,U,Y,T){_.transform(C,function(){var F=r.apply(this,arguments),B=this.__zoom,M=Y==null?E(F):typeof Y=="function"?Y.apply(this,arguments):Y;return o(Cl.translate(M[0],M[1]).scale(B.k).translate(typeof W=="function"?-W.apply(this,arguments):-W,typeof U=="function"?-U.apply(this,arguments):-U),F,c)},Y,T)};function P(C,W){return W=Math.max(u[0],Math.min(u[1],W)),W===C.k?C:new Ln(W,C.x,C.y)}function N(C,W,U){var Y=W[0]-U[0]*C.k,T=W[1]-U[1]*C.k;return Y===C.x&&T===C.y?C:new Ln(C.k,Y,T)}function E(C){return[(+C[0][0]+ +C[1][0])/2,(+C[0][1]+ +C[1][1])/2]}function L(C,W,U,Y){C.on("start.zoom",function(){A(this,arguments).event(Y).start()}).on("interrupt.zoom end.zoom",function(){A(this,arguments).event(Y).end()}).tween("zoom",function(){var T=this,F=arguments,B=A(T,F).event(Y),M=r.apply(T,F),R=U==null?E(M):typeof U=="function"?U.apply(T,F):U,re=Math.max(M[1][0]-M[0][0],M[1][1]-M[0][1]),ie=T.__zoom,ce=typeof W=="function"?W.apply(T,F):W,fe=g(ie.invert(R).concat(re/ie.k),ce.invert(R).concat(re/ce.k));return function(de){if(de===1)de=ce;else{var Q=fe(de),le=re/Q[2];de=new Ln(le,R[0]-Q[0]*le,R[1]-Q[1]*le)}B.zoom(null,de)}})}function A(C,W,U){return!U&&C.__zooming||new V(C,W)}function V(C,W){this.that=C,this.args=W,this.active=0,this.sourceEvent=null,this.extent=r.apply(C,W),this.taps=0}V.prototype={event:function(C){return C&&(this.sourceEvent=C),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(C,W){return this.mouse&&C!=="mouse"&&(this.mouse[1]=W.invert(this.mouse[0])),this.touch0&&C!=="touch"&&(this.touch0[1]=W.invert(this.touch0[0])),this.touch1&&C!=="touch"&&(this.touch1[1]=W.invert(this.touch1[0])),this.that.__zoom=W,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(C){var W=Ot(this.that).datum();y.call(C,this.that,new Yw(C,{sourceEvent:this.sourceEvent,target:_,transform:this.that.__zoom,dispatch:y}),W)}};function z(C,...W){if(!t.apply(this,arguments))return;var U=A(this,W).event(C),Y=this.__zoom,T=Math.max(u[0],Math.min(u[1],Y.k*Math.pow(2,s.apply(this,arguments)))),F=en(C);if(U.wheel)(U.mouse[0][0]!==F[0]||U.mouse[0][1]!==F[1])&&(U.mouse[1]=Y.invert(U.mouse[0]=F)),clearTimeout(U.wheel);else{if(Y.k===T)return;U.mouse=[F,Y.invert(F)],dl(this),U.start()}So(C),U.wheel=setTimeout(B,k),U.zoom("mouse",o(N(P(Y,T),U.mouse[0],U.mouse[1]),U.extent,c));function B(){U.wheel=null,U.end()}}function G(C,...W){if(m||!t.apply(this,arguments))return;var U=C.currentTarget,Y=A(this,W,!0).event(C),T=Ot(C.view).on("mousemove.zoom",R,!0).on("mouseup.zoom",re,!0),F=en(C,U),B=C.clientX,M=C.clientY;zp(C.view),Pu(C),Y.mouse=[F,this.__zoom.invert(F)],dl(this),Y.start();function R(ie){if(So(ie),!Y.moved){var ce=ie.clientX-B,fe=ie.clientY-M;Y.moved=ce*ce+fe*fe>j}Y.event(ie).zoom("mouse",o(N(Y.that.__zoom,Y.mouse[0]=en(ie,U),Y.mouse[1]),Y.extent,c))}function re(ie){T.on("mousemove.zoom mouseup.zoom",null),Dp(ie.view,Y.moved),So(ie),Y.event(ie).end()}}function ee(C,...W){if(t.apply(this,arguments)){var U=this.__zoom,Y=en(C.changedTouches?C.changedTouches[0]:C,this),T=U.invert(Y),F=U.k*(C.shiftKey?.5:2),B=o(N(P(U,F),Y,T),r.apply(this,W),c);So(C),f>0?Ot(this).transition().duration(f).call(L,B,Y,C):Ot(this).call(_.transform,B,Y,C)}}function J(C,...W){if(t.apply(this,arguments)){var U=C.touches,Y=U.length,T=A(this,W,C.changedTouches.length===Y).event(C),F,B,M,R;for(Pu(C),B=0;B`Seems like you have not used ${t==="svelte"?"SvelteFlowProvider":"ReactFlowProvider"} as an ancestor. Help: https://${t}flow.dev/error#001`,error002:()=>"It looks like you've created a new nodeTypes or edgeTypes object. If this wasn't on purpose please define the nodeTypes/edgeTypes outside of the component or memoize them.",error003:t=>`Node type "${t}" not found. Using fallback type "default".`,error004:()=>"The parent container needs a width and a height to render the graph.",error005:()=>"Only child nodes can use a parent extent.",error006:()=>"Can't create edge. An edge needs a source and a target.",error007:t=>`The old edge with id=${t} does not exist.`,error009:t=>`Marker type "${t}" doesn't exist.`,error008:(t,{id:r,sourceHandle:o,targetHandle:s})=>`Couldn't create edge for ${t} handle id: "${t==="source"?o:s}", edge id: ${r}.`,error010:()=>"Handle: No node id found. Make sure to only use a Handle inside a custom Node.",error011:t=>`Edge type "${t}" not found. Using fallback type "default".`,error012:t=>`Node with id "${t}" does not exist, it may have been removed. This can happen when a node is deleted before the "onNodeClick" handler is called.`,error013:(t="react")=>`It seems that you haven't loaded the styles. Please import '@xyflow/${t}/dist/style.css' or base.css to make sure everything is working properly.`,error014:()=>"useNodeConnections: No node ID found. Call useNodeConnections inside a custom Node or provide a node ID.",error015:()=>"It seems that you are trying to drag a node that is not initialized. Please use onNodesChange as explained in the docs.",error016:t=>`Edge with id "${t}" does not exist, it may have been removed. This can happen when an edge is deleted before the "onEdgeClick" handler is called.`},To=[[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]],eg=["Enter"," ","Escape"],tg={"node.a11yDescription.default":"Press enter or space to select a node. Press delete to remove it and escape to cancel.","node.a11yDescription.keyboardDisabled":"Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.","node.a11yDescription.ariaLiveMessage":({direction:t,x:r,y:o})=>`Moved selected node ${t}. New position, x: ${r}, y: ${o}`,"edge.a11yDescription.default":"Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.","controls.ariaLabel":"Control Panel","controls.zoomIn.ariaLabel":"Zoom In","controls.zoomOut.ariaLabel":"Zoom Out","controls.fitView.ariaLabel":"Fit View","controls.interactive.ariaLabel":"Toggle Interactivity","minimap.ariaLabel":"Mini Map","handle.ariaLabel":"Handle"};var Ai;(function(t){t.Strict="strict",t.Loose="loose"})(Ai||(Ai={}));var Fr;(function(t){t.Free="free",t.Vertical="vertical",t.Horizontal="horizontal"})(Fr||(Fr={}));var Ro;(function(t){t.Partial="partial",t.Full="full"})(Ro||(Ro={}));const ng={inProgress:!1,isValid:null,from:null,fromHandle:null,fromPosition:null,fromNode:null,to:null,toHandle:null,toPosition:null,toNode:null,pointer:null};var hr;(function(t){t.Bezier="default",t.Straight="straight",t.Step="step",t.SmoothStep="smoothstep",t.SimpleBezier="simplebezier"})(hr||(hr={}));var Lo;(function(t){t.Arrow="arrow",t.ArrowClosed="arrowclosed"})(Lo||(Lo={}));var Se;(function(t){t.Left="left",t.Top="top",t.Right="right",t.Bottom="bottom"})(Se||(Se={}));const vh={[Se.Left]:Se.Right,[Se.Right]:Se.Left,[Se.Top]:Se.Bottom,[Se.Bottom]:Se.Top};function rg(t){return t===null?null:t?"valid":"invalid"}const ig=t=>!!t&&typeof t=="object"&&"id"in t&&"source"in t&&"target"in t,Zw=t=>!!t&&typeof t=="object"&&"id"in t&&"position"in t&&!("source"in t)&&!("target"in t),dc=t=>!!t&&typeof t=="object"&&"id"in t&&"internals"in t&&!("source"in t)&&!("target"in t),Ho=(t,r=[0,0])=>{const{width:o,height:s}=ln(t),a=t.origin??r,u=o*a[0],c=s*a[1];return{x:t.position.x-u,y:t.position.y-c}},Jw=(t,r={nodeOrigin:[0,0]})=>{if(t.length===0)return{x:0,y:0,width:0,height:0};let o=!1;const s=t.reduce((a,u)=>{const c=typeof u=="string";let f=!r.nodeLookup&&!c?u:void 0;return r.nodeLookup&&(f=c?r.nodeLookup.get(u):dc(u)?u:r.nodeLookup.get(u.id)),f?(o=!0,Ml(a,xl(f,r.nodeOrigin))):a},{x:1/0,y:1/0,x2:-1/0,y2:-1/0});return o?Pl(s):{x:0,y:0,width:0,height:0}},Bo=(t,r={})=>{let o={x:1/0,y:1/0,x2:-1/0,y2:-1/0},s=!1;return t.forEach(a=>{(r.filter===void 0||r.filter(a))&&(o=Ml(o,xl(a)),s=!0)}),s?Pl(o):{x:0,y:0,width:0,height:0}},fc=(t,r,[o,s,a]=[0,0,1],u=!1,c=!1)=>{const f=(r.x-o)/a,g=(r.y-s)/a,y=r.width/a,v=r.height/a,x=[];for(const m of t.values()){const{measured:S,selectable:k=!0,hidden:j=!1}=m;if(c&&!k||j)continue;const b=S.width??m.width??m.initialWidth??0,_=S.height??m.height??m.initialHeight??0,{x:P,y:N}=m.internals.positionAbsolute,E=ag(f,g,y,v,P,N,b,_),L=b*_,A=u&&E>0;(!m.internals.handleBounds||A||E>=L||m.dragging)&&x.push(m)}return x},e1=(t,r)=>{const o=new Set;return t.forEach(s=>{o.add(s.id)}),r.filter(s=>o.has(s.source)||o.has(s.target))};function t1(t,r){const o=new Map,s=r!=null&&r.nodes?new Set(r.nodes.map(a=>a.id)):null;return t.forEach(a=>{let u;if(r!=null&&r.includeHiddenNodes){const{width:c,height:f}=ln(a);u=c>0&&f>0}else u=!!(a.measured.width&&a.measured.height&&!a.hidden);u&&(!s||s.has(a.id))&&o.set(a.id,a)}),o}async function n1({nodes:t,width:r,height:o,panZoom:s,minZoom:a,maxZoom:u},c){if(t.size===0)return!0;const f=t1(t,c),g=Bo(f),y=pc(g,r,o,(c==null?void 0:c.minZoom)??a,(c==null?void 0:c.maxZoom)??u,(c==null?void 0:c.padding)??.1);return await s.setViewport(y,{duration:c==null?void 0:c.duration,ease:c==null?void 0:c.ease,interpolate:c==null?void 0:c.interpolate}),!0}function og({nodeId:t,nextPosition:r,nodeLookup:o,nodeOrigin:s=[0,0],nodeExtent:a,onError:u}){const c=o.get(t),f=c.parentId?o.get(c.parentId):void 0,{x:g,y}=f?f.internals.positionAbsolute:{x:0,y:0},v=c.origin??s;let x=c.extent||a;if(c.extent==="parent"&&!c.expandParent)if(!f)u==null||u("005",on.error005());else{const{width:S,height:k}=ln(f);S&&k&&(x=[[g,y],[g+S,y+k]])}else f&&Wr(c.extent)&&(x=[[c.extent[0][0]+g,c.extent[0][1]+y],[c.extent[1][0]+g,c.extent[1][1]+y]]);const m=Wr(x)?Vr(r,x,c.measured):r;return(c.measured.width===void 0||c.measured.height===void 0)&&(u==null||u("015",on.error015())),{position:{x:m.x-g+(c.measured.width??0)*v[0],y:m.y-y+(c.measured.height??0)*v[1]},positionAbsolute:m}}async function r1({nodesToRemove:t=[],edgesToRemove:r=[],nodes:o,edges:s,onBeforeDelete:a}){const u=new Set(t.map(m=>m.id)),c=[];for(const m of o){if(m.deletable===!1)continue;const S=u.has(m.id),k=!S&&m.parentId&&c.find(j=>j.id===m.parentId);(S||k)&&c.push(m)}const f=new Set(r.map(m=>m.id)),g=s.filter(m=>m.deletable!==!1),v=e1(c,g);for(const m of g)f.has(m.id)&&!v.find(k=>k.id===m.id)&&v.push(m);if(!a)return{edges:v,nodes:c};const x=await a({nodes:c,edges:v});return typeof x=="boolean"?x?{edges:v,nodes:c}:{edges:[],nodes:[]}:x}const zi=(t,r=0,o=1)=>Math.min(Math.max(t,r),o),Vr=(t={x:0,y:0},r,o)=>({x:zi(t.x,r[0][0],r[1][0]-((o==null?void 0:o.width)??0)),y:zi(t.y,r[0][1],r[1][1]-((o==null?void 0:o.height)??0))});function sg(t,r,o){const{width:s,height:a}=ln(o),{x:u,y:c}=o.internals.positionAbsolute;return Vr(t,[[u,c],[u+s,c+a]],r)}const xh=(t,r,o)=>to?-zi(Math.abs(t-o),1,r)/r:0,hc=(t,r,o=15,s=40)=>{const a=xh(t.x,s,r.width-s)*o,u=xh(t.y,s,r.height-s)*o;return[a,u]},Ml=(t,r)=>({x:Math.min(t.x,r.x),y:Math.min(t.y,r.y),x2:Math.max(t.x2,r.x2),y2:Math.max(t.y2,r.y2)}),Ku=({x:t,y:r,width:o,height:s})=>({x:t,y:r,x2:t+o,y2:r+s}),Pl=({x:t,y:r,x2:o,y2:s})=>({x:t,y:r,width:o-t,height:s-r}),Ao=(t,r=[0,0])=>{var a,u;const{x:o,y:s}=dc(t)?t.internals.positionAbsolute:Ho(t,r);return{x:o,y:s,width:((a=t.measured)==null?void 0:a.width)??t.width??t.initialWidth??0,height:((u=t.measured)==null?void 0:u.height)??t.height??t.initialHeight??0}},xl=(t,r=[0,0])=>{var a,u;const{x:o,y:s}=dc(t)?t.internals.positionAbsolute:Ho(t,r);return{x:o,y:s,x2:o+(((a=t.measured)==null?void 0:a.width)??t.width??t.initialWidth??0),y2:s+(((u=t.measured)==null?void 0:u.height)??t.height??t.initialHeight??0)}},lg=(t,r)=>Pl(Ml(Ku(t),Ku(r))),ag=(t,r,o,s,a,u,c,f)=>{const g=Math.max(0,Math.min(t+o,a+c)-Math.max(t,a)),y=Math.max(0,Math.min(r+s,u+f)-Math.max(r,u));return Math.ceil(g*y)},wl=(t,r)=>ag(t.x,t.y,t.width,t.height,r.x,r.y,r.width,r.height),wh=t=>nn(t.width)&&nn(t.height)&&nn(t.x)&&nn(t.y),nn=t=>!isNaN(t)&&isFinite(t),ug=(t,r)=>(o,s)=>{},Vo=(t,r=[1,1])=>({x:r[0]*Math.round(t.x/r[0]),y:r[1]*Math.round(t.y/r[1])}),Wo=({x:t,y:r},[o,s,a],u=!1,c=[1,1])=>{const f={x:(t-o)/a,y:(r-s)/a};return u?Vo(f,c):f},Di=({x:t,y:r},[o,s,a])=>({x:t*a+o,y:r*a+s});function Mi(t,r){if(typeof t=="number")return Math.floor((r-r/(1+t))*.5);if(typeof t=="string"&&t.endsWith("px")){const o=parseFloat(t);if(!Number.isNaN(o))return Math.floor(o)}if(typeof t=="string"&&t.endsWith("%")){const o=parseFloat(t);if(!Number.isNaN(o))return Math.floor(r*o*.01)}return console.error(`The padding value "${t}" is invalid. Please provide a number or a string with a valid unit (px or %).`),0}function i1(t,r,o){if(typeof t=="string"||typeof t=="number"){const s=Mi(t,o),a=Mi(t,r);return{top:s,right:a,bottom:s,left:a,x:a*2,y:s*2}}if(typeof t=="object"){const s=Mi(t.top??t.y??0,o),a=Mi(t.bottom??t.y??0,o),u=Mi(t.left??t.x??0,r),c=Mi(t.right??t.x??0,r);return{top:s,right:c,bottom:a,left:u,x:u+c,y:s+a}}return{top:0,right:0,bottom:0,left:0,x:0,y:0}}function o1(t,r,o,s,a,u){const{x:c,y:f}=Di(t,[r,o,s]),{x:g,y}=Di({x:t.x+t.width,y:t.y+t.height},[r,o,s]),v=a-g,x=u-y;return{left:Math.floor(c),top:Math.floor(f),right:Math.floor(v),bottom:Math.floor(x)}}const pc=(t,r,o,s,a,u)=>{const c=i1(u,r,o),f=(r-c.x)/t.width,g=(o-c.y)/t.height,y=Math.min(f,g),v=zi(y,s,a),x=t.x+t.width/2,m=t.y+t.height/2,S=r/2-x*v,k=o/2-m*v,j=o1(t,S,k,v,r,o),b={left:Math.min(j.left-c.left,0),top:Math.min(j.top-c.top,0),right:Math.min(j.right-c.right,0),bottom:Math.min(j.bottom-c.bottom,0)};return{x:S-b.left+b.right,y:k-b.top+b.bottom,zoom:v}},zo=()=>{var t;return typeof navigator<"u"&&((t=navigator==null?void 0:navigator.userAgent)==null?void 0:t.indexOf("Mac"))>=0};function Wr(t){return t!=null&&t!=="parent"}function ln(t){var r,o;return{width:((r=t.measured)==null?void 0:r.width)??t.width??t.initialWidth??0,height:((o=t.measured)==null?void 0:o.height)??t.height??t.initialHeight??0}}function cg(t){var r,o;return(((r=t.measured)==null?void 0:r.width)??t.width??t.initialWidth)!==void 0&&(((o=t.measured)==null?void 0:o.height)??t.height??t.initialHeight)!==void 0}function dg(t,r={width:0,height:0},o,s,a){const u={...t},c=s.get(o);if(c){const f=c.origin||a;u.x+=c.internals.positionAbsolute.x-(r.width??0)*f[0],u.y+=c.internals.positionAbsolute.y-(r.height??0)*f[1]}return u}function _h(t,r){if(t.size!==r.size)return!1;for(const o of t)if(!r.has(o))return!1;return!0}function s1(){let t,r;return{promise:new Promise((s,a)=>{t=s,r=a}),resolve:t,reject:r}}function l1(t){return{...tg,...t||{}}}function jo(t,{snapGrid:r=[0,0],snapToGrid:o=!1,transform:s,containerBounds:a}){const{x:u,y:c}=rn(t),f=Wo({x:u-((a==null?void 0:a.left)??0),y:c-((a==null?void 0:a.top)??0)},s),{x:g,y}=o?Vo(f,r):f;return{xSnapped:g,ySnapped:y,...f}}const gc=t=>({width:t.offsetWidth,height:t.offsetHeight}),fg=t=>{var r;return((r=t==null?void 0:t.getRootNode)==null?void 0:r.call(t))||(window==null?void 0:window.document)},a1=["INPUT","SELECT","TEXTAREA"];function hg(t){var s,a;const r=((a=(s=t.composedPath)==null?void 0:s.call(t))==null?void 0:a[0])||t.target;return(r==null?void 0:r.nodeType)!==1?!1:a1.includes(r.nodeName)||r.hasAttribute("contenteditable")||!!r.closest(".nokey")}const pg=t=>"clientX"in t,rn=(t,r)=>{var u,c;const o=pg(t),s=o?t.clientX:(u=t.touches)==null?void 0:u[0].clientX,a=o?t.clientY:(c=t.touches)==null?void 0:c[0].clientY;return{x:s-((r==null?void 0:r.left)??0),y:a-((r==null?void 0:r.top)??0)}},Sh=(t,r,o,s,a)=>{const u=r.querySelectorAll(`.${t}`);return!u||!u.length?null:Array.from(u).map(c=>{const f=c.getBoundingClientRect();return{id:c.getAttribute("data-handleid"),type:t,nodeId:a,position:c.getAttribute("data-handlepos"),x:(f.left-o.left)/s,y:(f.top-o.top)/s,...gc(c)}})};function gg({sourceX:t,sourceY:r,targetX:o,targetY:s,sourceControlX:a,sourceControlY:u,targetControlX:c,targetControlY:f}){const g=t*.125+a*.375+c*.375+o*.125,y=r*.125+u*.375+f*.375+s*.125,v=Math.abs(g-t),x=Math.abs(y-r);return[g,y,v,x]}function tl(t,r){return t>=0?.5*t:r*25*Math.sqrt(-t)}function kh({pos:t,x1:r,y1:o,x2:s,y2:a,c:u}){switch(t){case Se.Left:return[r-tl(r-s,u),o];case Se.Right:return[r+tl(s-r,u),o];case Se.Top:return[r,o-tl(o-a,u)];case Se.Bottom:return[r,o+tl(a-o,u)]}}function mg({sourceX:t,sourceY:r,sourcePosition:o=Se.Bottom,targetX:s,targetY:a,targetPosition:u=Se.Top,curvature:c=.25}){const[f,g]=kh({pos:o,x1:t,y1:r,x2:s,y2:a,c}),[y,v]=kh({pos:u,x1:s,y1:a,x2:t,y2:r,c}),[x,m,S,k]=gg({sourceX:t,sourceY:r,targetX:s,targetY:a,sourceControlX:f,sourceControlY:g,targetControlX:y,targetControlY:v});return[`M${t},${r} C${f},${g} ${y},${v} ${s},${a}`,x,m,S,k]}function yg({sourceX:t,sourceY:r,targetX:o,targetY:s}){const a=Math.abs(o-t)/2,u=o0}const d1=({source:t,sourceHandle:r,target:o,targetHandle:s})=>`xy-edge__${t}${r||""}-${o}${s||""}`,f1=(t,r)=>r.some(o=>o.source===t.source&&o.target===t.target&&(o.sourceHandle===t.sourceHandle||!o.sourceHandle&&!t.sourceHandle)&&(o.targetHandle===t.targetHandle||!o.targetHandle&&!t.targetHandle)),h1=(t,r,o={})=>{var u;if(!t.source||!t.target)return(u=o.onError)==null||u.call(o,"006",on.error006()),r;const s=o.getEdgeId||d1;let a;return ig(t)?a={...t}:a={...t,id:s(t)},f1(a,r)?r:(a.sourceHandle===null&&delete a.sourceHandle,a.targetHandle===null&&delete a.targetHandle,r.concat(a))};function vg({sourceX:t,sourceY:r,targetX:o,targetY:s}){const[a,u,c,f]=yg({sourceX:t,sourceY:r,targetX:o,targetY:s});return[`M ${t},${r}L ${o},${s}`,a,u,c,f]}const Nh={[Se.Left]:{x:-1,y:0},[Se.Right]:{x:1,y:0},[Se.Top]:{x:0,y:-1},[Se.Bottom]:{x:0,y:1}},p1=({source:t,sourcePosition:r=Se.Bottom,target:o})=>r===Se.Left||r===Se.Right?t.xMath.sqrt(Math.pow(r.x-t.x,2)+Math.pow(r.y-t.y,2));function g1({source:t,sourcePosition:r=Se.Bottom,target:o,targetPosition:s=Se.Top,center:a,offset:u,stepPosition:c}){const f=Nh[r],g=Nh[s],y={x:t.x+f.x*u,y:t.y+f.y*u},v={x:o.x+g.x*u,y:o.y+g.y*u},x=p1({source:y,sourcePosition:r,target:v}),m=x.x!==0?"x":"y",S=x[m];let k=[],j,b;const _={x:0,y:0},P={x:0,y:0},[,,N,E]=yg({sourceX:t.x,sourceY:t.y,targetX:o.x,targetY:o.y});if(f[m]*g[m]===-1){m==="x"?(j=a.x??y.x+(v.x-y.x)*c,b=a.y??(y.y+v.y)/2):(j=a.x??(y.x+v.x)/2,b=a.y??y.y+(v.y-y.y)*c);const z=[{x:j,y:y.y},{x:j,y:v.y}],G=[{x:y.x,y:b},{x:v.x,y:b}];f[m]===S?k=m==="x"?z:G:k=m==="x"?G:z}else{const z=[{x:y.x,y:v.y}],G=[{x:v.x,y:y.y}];if(m==="x"?k=f.x===S?G:z:k=f.y===S?z:G,r===s){const C=Math.abs(t[m]-o[m]);if(C<=u){const W=Math.min(u-1,u-C);f[m]===S?_[m]=(y[m]>t[m]?-1:1)*W:P[m]=(v[m]>o[m]?-1:1)*W}}if(r!==s){const C=m==="x"?"y":"x",W=f[m]===g[C],U=y[C]>v[C],Y=y[C]=q?(j=(ee.x+J.x)/2,b=k[0].y):(j=k[0].x,b=(ee.y+J.y)/2)}const L={x:y.x+_.x,y:y.y+_.y},A={x:v.x+P.x,y:v.y+P.y};return[[t,...L.x!==k[0].x||L.y!==k[0].y?[L]:[],...k,...A.x!==k[k.length-1].x||A.y!==k[k.length-1].y?[A]:[],o],j,b,N,E]}function m1(t,r,o,s){const a=Math.min(Eh(t,r)/2,Eh(r,o)/2,s),{x:u,y:c}=r;if(t.x===u&&u===o.x||t.y===c&&c===o.y)return`L${u} ${c}`;if(t.y===c){const y=t.xo.id===r):t[0])||null}function Zu(t,r){return t?typeof t=="string"?t:`${r?`${r}__`:""}${Object.keys(t).sort().map(s=>`${s}=${t[s]}`).join("&")}`:""}function v1(t,{id:r,defaultColor:o,defaultMarkerStart:s,defaultMarkerEnd:a}){const u=new Set;return t.reduce((c,f)=>([f.markerStart||s,f.markerEnd||a].forEach(g=>{if(g&&typeof g=="object"){const y=Zu(g,r);u.has(y)||(c.push({id:y,color:g.color||o,...g}),u.add(y))}}),c),[]).sort((c,f)=>c.id.localeCompare(f.id))}const xg=1e3,x1=10,mc={nodeOrigin:[0,0],nodeExtent:To,elevateNodesOnSelect:!0,zIndexMode:"basic",defaults:{}},w1={...mc,checkEquality:!0};function yc(t,r){const o={...t};for(const s in r)r[s]!==void 0&&(o[s]=r[s]);return o}function _1(t,r,o){const s=yc(mc,o);for(const a of t.values())if(a.parentId)xc(a,t,r,s);else{const u=Ho(a,s.nodeOrigin),c=Wr(a.extent)?a.extent:s.nodeExtent,f=Vr(u,c,ln(a));a.internals.positionAbsolute=f}}function S1(t,r){if(!t.handles)return t.measured?r==null?void 0:r.internals.handleBounds:void 0;const o=[],s=[];for(const a of t.handles){const u={id:a.id,width:a.width??1,height:a.height??1,nodeId:t.id,x:a.x,y:a.y,position:a.position,type:a.type};a.type==="source"?o.push(u):a.type==="target"&&s.push(u)}return{source:o,target:s}}function vc(t){return t==="manual"}function Ju(t,r,o,s={}){var v,x;const a=yc(w1,s),u={i:0},c=new Map(r),f=a!=null&&a.elevateNodesOnSelect&&!vc(a.zIndexMode)?xg:0;let g=t.length>0,y=!1;r.clear(),o.clear();for(const m of t){let S=c.get(m.id);if(a.checkEquality&&m===(S==null?void 0:S.internals.userNode))r.set(m.id,S);else{const k=Ho(m,a.nodeOrigin),j=Wr(m.extent)?m.extent:a.nodeExtent,b=Vr(k,j,ln(m));S={...a.defaults,...m,measured:{width:(v=m.measured)==null?void 0:v.width,height:(x=m.measured)==null?void 0:x.height},internals:{positionAbsolute:b,handleBounds:S1(m,S),z:wg(m,f,a.zIndexMode),userNode:m}},r.set(m.id,S)}(S.measured===void 0||S.measured.width===void 0||S.measured.height===void 0)&&!S.hidden&&(g=!1),m.parentId&&xc(S,r,o,s,u),y||(y=m.selected??!1)}return{nodesInitialized:g,hasSelectedNodes:y}}function k1(t,r){if(!t.parentId)return;const o=r.get(t.parentId);o?o.set(t.id,t):r.set(t.parentId,new Map([[t.id,t]]))}function xc(t,r,o,s,a){const{elevateNodesOnSelect:u,nodeOrigin:c,nodeExtent:f,zIndexMode:g}=yc(mc,s),y=t.parentId,v=r.get(y);if(!v){console.warn(`Parent node ${y} not found. Please make sure that parent nodes are in front of their child nodes in the nodes array.`);return}k1(t,o),a&&!v.parentId&&v.internals.rootParentIndex===void 0&&g==="auto"&&(v.internals.rootParentIndex=++a.i,v.internals.z=v.internals.z+a.i*x1),a&&v.internals.rootParentIndex!==void 0&&(a.i=v.internals.rootParentIndex);const x=u&&!vc(g)?xg:0,{x:m,y:S,z:k}=N1(t,v,c,f,x,g),{positionAbsolute:j}=t.internals,b=m!==j.x||S!==j.y;(b||k!==t.internals.z)&&r.set(t.id,{...t,internals:{...t.internals,positionAbsolute:b?{x:m,y:S}:j,z:k}})}function wg(t,r,o){const s=nn(t.zIndex)?t.zIndex:0;return vc(o)?s:s+(t.selected?r:0)}function N1(t,r,o,s,a,u){const{x:c,y:f}=r.internals.positionAbsolute,g=ln(t),y=Ho(t,o),v=Wr(t.extent)?Vr(y,t.extent,g):y;let x=Vr({x:c+v.x,y:f+v.y},s,g);t.extent==="parent"&&(x=sg(x,g,r));const m=wg(t,a,u),S=r.internals.z??0;return{x:x.x,y:x.y,z:S>=m?S+1:m}}function wc(t,r,o,s=[0,0]){var c;const a=[],u=new Map;for(const f of t){const g=r.get(f.parentId);if(!g)continue;const y=((c=u.get(f.parentId))==null?void 0:c.expandedRect)??Ao(g),v=lg(y,f.rect);u.set(f.parentId,{expandedRect:v,parent:g})}return u.size>0&&u.forEach(({expandedRect:f,parent:g},y)=>{var N;const v=g.internals.positionAbsolute,x=ln(g),m=g.origin??s,S=f.x0||k>0||_||P)&&(a.push({id:y,type:"position",position:{x:g.position.x-S+_,y:g.position.y-k+P}}),(N=o.get(y))==null||N.forEach(E=>{t.some(L=>L.id===E.id)||a.push({id:E.id,type:"position",position:{x:E.position.x+S,y:E.position.y+k}})})),(x.width0){const S=wc(m,r,o,a);y.push(...S)}return{changes:y,updatedInternals:g}}async function j1({delta:t,panZoom:r,transform:o,translateExtent:s,width:a,height:u}){if(!r||!t.x&&!t.y)return!1;const c=await r.setViewportConstrained({x:o[0]+t.x,y:o[1]+t.y,zoom:o[2]},[[0,0],[a,u]],s);return!!c&&(c.x!==o[0]||c.y!==o[1]||c.k!==o[2])}function Mh(t,r,o,s,a,u){let c=a;const f=s.get(c)||new Map;s.set(c,f.set(o,r)),c=`${a}-${t}`;const g=s.get(c)||new Map;if(s.set(c,g.set(o,r)),u){c=`${a}-${t}-${u}`;const y=s.get(c)||new Map;s.set(c,y.set(o,r))}}function _g(t,r,o){t.clear(),r.clear();for(const s of o){const{source:a,target:u,sourceHandle:c=null,targetHandle:f=null}=s,g={edgeId:s.id,source:a,target:u,sourceHandle:c,targetHandle:f},y=`${a}-${c}--${u}-${f}`,v=`${u}-${f}--${a}-${c}`;Mh("source",g,v,t,a,c),Mh("target",g,y,t,u,f),r.set(s.id,s)}}function Sg(t,r){if(!t.parentId)return!1;const o=r.get(t.parentId);return o?o.selected?!0:Sg(o,r):!1}function Ph(t,r,o){var a;let s=t;do{if((a=s==null?void 0:s.matches)!=null&&a.call(s,r))return!0;if(s===o)return!1;s=s==null?void 0:s.parentElement}while(s);return!1}function b1(t,r,o,s){const a=new Map;for(const[u,c]of t)if((c.selected||c.id===s)&&(!c.parentId||!Sg(c,t))&&(c.draggable||r&&typeof c.draggable>"u")){const f=t.get(u);f&&a.set(u,{id:u,position:f.position||{x:0,y:0},distance:{x:o.x-f.internals.positionAbsolute.x,y:o.y-f.internals.positionAbsolute.y},extent:f.extent,parentId:f.parentId,origin:f.origin,expandParent:f.expandParent,internals:{positionAbsolute:f.internals.positionAbsolute||{x:0,y:0}},measured:{width:f.measured.width??0,height:f.measured.height??0}})}return a}function Iu({nodeId:t,dragItems:r,nodeLookup:o,dragging:s=!0}){var c,f,g;const a=[];for(const[y,v]of r){const x=(c=o.get(y))==null?void 0:c.internals.userNode;x&&a.push({...x,position:v.position,dragging:s})}if(!t)return[a[0],a];const u=(f=o.get(t))==null?void 0:f.internals.userNode;return[u?{...u,position:((g=r.get(t))==null?void 0:g.position)||u.position,dragging:s}:a[0],a]}function C1({dragItems:t,snapGrid:r,x:o,y:s}){const a=t.values().next().value;if(!a)return null;const u={x:o-a.distance.x,y:s-a.distance.y},c=Vo(u,r);return{x:c.x-u.x,y:c.y-u.y}}function M1({onNodeMouseDown:t,getStoreItems:r,onDragStart:o,onDrag:s,onDragStop:a}){let u={x:null,y:null},c=0,f=new Map,g=!1,y={x:0,y:0},v=null,x=!1,m=null,S=!1,k=!1,j=null;function b({noDragClassName:P,handleSelector:N,domNode:E,isSelectable:L,nodeId:A,nodeClickDistance:V=0}){m=Ot(E);function z({x:ne,y:q}){const{nodeLookup:C,nodeExtent:W,snapGrid:U,snapToGrid:Y,nodeOrigin:T,onNodeDrag:F,onSelectionDrag:B,onError:M,updateNodePositions:R}=r();u={x:ne,y:q};let re=!1;const ie=f.size>1,ce=ie&&W?Ku(Bo(f)):null,fe=ie&&Y?C1({dragItems:f,snapGrid:U,x:ne,y:q}):null;for(const[de,Q]of f){if(!C.has(de))continue;let le={x:ne-Q.distance.x,y:q-Q.distance.y};Y&&(le=fe?{x:Math.round(le.x+fe.x),y:Math.round(le.y+fe.y)}:Vo(le,U));let me=null;if(ie&&W&&!Q.extent&&ce){const{positionAbsolute:pe}=Q.internals,be=pe.x-ce.x+W[0][0],Pe=pe.x+Q.measured.width-ce.x2+W[1][0],Ce=pe.y-ce.y+W[0][1],Re=pe.y+Q.measured.height-ce.y2+W[1][1];me=[[be,Ce],[Pe,Re]]}const{position:ke,positionAbsolute:xe}=og({nodeId:de,nextPosition:le,nodeLookup:C,nodeExtent:me||W,nodeOrigin:T,onError:M});re=re||Q.position.x!==ke.x||Q.position.y!==ke.y,Q.position=ke,Q.internals.positionAbsolute=xe}if(k=k||re,!!re&&(R(f,!0),j&&(s||F||!A&&B))){const[de,Q]=Iu({nodeId:A,dragItems:f,nodeLookup:C});s==null||s(j,f,de,Q),F==null||F(j,de,Q),A||B==null||B(j,Q)}}async function G(){if(!v)return;const{transform:ne,panBy:q,autoPanSpeed:C,autoPanOnNodeDrag:W}=r();if(!W){g=!1,cancelAnimationFrame(c);return}const[U,Y]=hc(y,v,C);(U!==0||Y!==0)&&(u.x=(u.x??0)-U/ne[2],u.y=(u.y??0)-Y/ne[2],await q({x:U,y:Y})&&z(u)),c=requestAnimationFrame(G)}function ee(ne){var ie;const{nodeLookup:q,multiSelectionActive:C,nodesDraggable:W,transform:U,snapGrid:Y,snapToGrid:T,selectNodesOnDrag:F,onNodeDragStart:B,onSelectionDragStart:M,unselectNodesAndEdges:R}=r();x=!0,(!F||!L)&&!C&&A&&((ie=q.get(A))!=null&&ie.selected||R()),L&&F&&A&&(t==null||t(A));const re=jo(ne.sourceEvent,{transform:U,snapGrid:Y,snapToGrid:T,containerBounds:v});if(u=re,f=b1(q,W,re,A),f.size>0&&(o||B||!A&&M)){const[ce,fe]=Iu({nodeId:A,dragItems:f,nodeLookup:q});o==null||o(ne.sourceEvent,f,ce,fe),B==null||B(ne.sourceEvent,ce,fe),A||M==null||M(ne.sourceEvent,fe)}}const J=$p().clickDistance(V).on("start",ne=>{const{domNode:q,nodeDragThreshold:C,transform:W,snapGrid:U,snapToGrid:Y}=r();v=(q==null?void 0:q.getBoundingClientRect())||null,S=!1,k=!1,j=ne.sourceEvent,C===0&&ee(ne),u=jo(ne.sourceEvent,{transform:W,snapGrid:U,snapToGrid:Y,containerBounds:v}),y=rn(ne.sourceEvent,v)}).on("drag",ne=>{const{autoPanOnNodeDrag:q,transform:C,snapGrid:W,snapToGrid:U,nodeDragThreshold:Y,nodeLookup:T}=r(),F=jo(ne.sourceEvent,{transform:C,snapGrid:W,snapToGrid:U,containerBounds:v});if(j=ne.sourceEvent,(ne.sourceEvent.type==="touchmove"&&ne.sourceEvent.touches.length>1||A&&!T.has(A))&&(S=!0),!S){if(!g&&q&&x&&(g=!0,G()),!x){const B=rn(ne.sourceEvent,v),M=B.x-y.x,R=B.y-y.y;Math.sqrt(M*M+R*R)>Y&&ee(ne)}(u.x!==F.xSnapped||u.y!==F.ySnapped)&&f&&x&&(y=rn(ne.sourceEvent,v),z(F))}}).on("end",ne=>{if(!x||S){S&&f.size>0&&r().updateNodePositions(f,!1);return}if(g=!1,x=!1,cancelAnimationFrame(c),f.size>0){const{nodeLookup:q,updateNodePositions:C,onNodeDragStop:W,onSelectionDragStop:U}=r();if(k&&(C(f,!1),k=!1),a||W||!A&&U){const[Y,T]=Iu({nodeId:A,dragItems:f,nodeLookup:q,dragging:!1});a==null||a(ne.sourceEvent,f,Y,T),W==null||W(ne.sourceEvent,Y,T),A||U==null||U(ne.sourceEvent,T)}}}).filter(ne=>{const q=ne.target;return!ne.button&&(!P||!Ph(q,`.${P}`,E))&&(!N||Ph(q,N,E))});m.call(J)}function _(){m==null||m.on(".drag",null)}return{update:b,destroy:_}}function P1(t,r,o){const s=[],a={x:t.x-o,y:t.y-o,width:o*2,height:o*2};for(const u of r.values())wl(a,Ao(u))>0&&s.push(u);return s}const I1=250;function T1(t,r,o,s){var f,g;let a=[],u=1/0;const c=P1(t,o,r+I1);for(const y of c){const v=[...((f=y.internals.handleBounds)==null?void 0:f.source)??[],...((g=y.internals.handleBounds)==null?void 0:g.target)??[]];for(const x of v){if(s.nodeId===x.nodeId&&s.type===x.type&&s.id===x.id)continue;const{x:m,y:S}=Ur(y,x,x.position,!0),k=Math.sqrt(Math.pow(m-t.x,2)+Math.pow(S-t.y,2));k>r||(k1){const y=s.type==="source"?"target":"source";return a.find(v=>v.type===y)??a[0]}return a[0]}function kg(t,r,o,s,a,u=!1){var y,v,x;const c=s.get(t);if(!c)return null;const f=a==="strict"?(y=c.internals.handleBounds)==null?void 0:y[r]:[...((v=c.internals.handleBounds)==null?void 0:v.source)??[],...((x=c.internals.handleBounds)==null?void 0:x.target)??[]],g=(o?f==null?void 0:f.find(m=>m.id===o):f==null?void 0:f[0])??null;return g&&u?{...g,...Ur(c,g,g.position,!0)}:g}function Ng(t,r){return t||(r!=null&&r.classList.contains("target")?"target":r!=null&&r.classList.contains("source")?"source":null)}function R1(t,r){let o=null;return r?o=!0:t&&!r&&(o=!1),o}const Eg=()=>!0;function L1(t,{connectionMode:r,connectionRadius:o,handleId:s,nodeId:a,edgeUpdaterType:u,isTarget:c,domNode:f,nodeLookup:g,lib:y,autoPanOnConnect:v,flowId:x,panBy:m,cancelConnection:S,onConnectStart:k,onConnect:j,onConnectEnd:b,isValidConnection:_=Eg,onReconnectEnd:P,updateConnection:N,getTransform:E,getFromHandle:L,autoPanSpeed:A,dragThreshold:V=1,handleDomNode:z}){const G=fg(t.target);let ee=0,J;const{x:ne,y:q}=rn(t),C=Ng(u,z),W=f==null?void 0:f.getBoundingClientRect();let U=!1;if(!W||!C)return;const Y=kg(a,C,s,g,r);if(!Y)return;let T=rn(t,W),F=!1,B=null,M=!1,R=null;function re(){if(!v||!W)return;const[ke,xe]=hc(T,W,A);m({x:ke,y:xe}),ee=requestAnimationFrame(re)}const ie={...Y,nodeId:a,type:C,position:Y.position},ce=g.get(a);let de={inProgress:!0,isValid:null,from:Ur(ce,ie,Se.Left,!0),fromHandle:ie,fromPosition:ie.position,fromNode:ce,to:T,toHandle:null,toPosition:vh[ie.position],toNode:null,pointer:T};function Q(){U=!0,N(de),k==null||k(t,{nodeId:a,handleId:s,handleType:C})}V===0&&Q();function le(ke){if(!U){const{x:Re,y:tt}=rn(ke),nt=Re-ne,Je=tt-q;if(!(nt*nt+Je*Je>V*V))return;Q()}if(!L()||!ie){me(ke);return}const xe=E();T=rn(ke,W),J=T1(Wo(T,xe,!1,[1,1]),o,g,ie),F||(re(),F=!0);const pe=jg(ke,{handle:J,connectionMode:r,fromNodeId:a,fromHandleId:s,fromType:c?"target":"source",isValidConnection:_,doc:G,lib:y,flowId:x,nodeLookup:g});R=pe.handleDomNode,B=pe.connection,M=R1(!!J,pe.isValid);const be=g.get(a),Pe=be?Ur(be,ie,Se.Left,!0):de.from,Ce={...de,from:Pe,isValid:M,to:pe.toHandle&&M?Di({x:pe.toHandle.x,y:pe.toHandle.y},xe):T,toHandle:pe.toHandle,toPosition:M&&pe.toHandle?pe.toHandle.position:vh[ie.position],toNode:pe.toHandle?g.get(pe.toHandle.nodeId):null,pointer:T};N(Ce),de=Ce}function me(ke){if(!("touches"in ke&&ke.touches.length>0)){if(U){(J||R)&&B&&M&&(j==null||j(B));const{inProgress:xe,...pe}=de,be={...pe,toPosition:de.toHandle?de.toPosition:null};b==null||b(ke,be),u&&(P==null||P(ke,be))}S(),cancelAnimationFrame(ee),F=!1,M=!1,B=null,R=null,G.removeEventListener("mousemove",le),G.removeEventListener("mouseup",me),G.removeEventListener("touchmove",le),G.removeEventListener("touchend",me)}}G.addEventListener("mousemove",le),G.addEventListener("mouseup",me),G.addEventListener("touchmove",le),G.addEventListener("touchend",me)}function jg(t,{handle:r,connectionMode:o,fromNodeId:s,fromHandleId:a,fromType:u,doc:c,lib:f,flowId:g,isValidConnection:y=Eg,nodeLookup:v}){const x=u==="target",m=r?c.querySelector(`.${f}-flow__handle[data-id="${g}-${r==null?void 0:r.nodeId}-${r==null?void 0:r.id}-${r==null?void 0:r.type}"]`):null,{x:S,y:k}=rn(t),j=c.elementFromPoint(S,k),b=j!=null&&j.classList.contains(`${f}-flow__handle`)?j:m,_={handleDomNode:b,isValid:!1,connection:null,toHandle:null};if(b){const P=Ng(void 0,b),N=b.getAttribute("data-nodeid"),E=b.getAttribute("data-handleid"),L=b.classList.contains("connectable"),A=b.classList.contains("connectableend");if(!N||!P)return _;const V={source:x?N:s,sourceHandle:x?E:a,target:x?s:N,targetHandle:x?a:E};_.connection=V;const G=L&&A&&(o===Ai.Strict?x&&P==="source"||!x&&P==="target":N!==s||E!==a);_.isValid=G&&y(V),_.toHandle=kg(N,P,E,v,o,!0)}return _}const ec={onPointerDown:L1,isValid:jg};function A1({domNode:t,panZoom:r,getTransform:o,getViewScale:s}){const a=Ot(t);function u({translateExtent:f,width:g,height:y,zoomStep:v=1,pannable:x=!0,zoomable:m=!0,inversePan:S=!1}){const k=N=>{if(N.sourceEvent.type!=="wheel"||!r)return;const E=o(),L=N.sourceEvent.ctrlKey&&zo()?10:1,A=-N.sourceEvent.deltaY*(N.sourceEvent.deltaMode===1?.05:N.sourceEvent.deltaMode?1:.002)*v,V=E[2]*Math.pow(2,A*L);r.scaleTo(V)};let j=[0,0];const b=N=>{(N.sourceEvent.type==="mousedown"||N.sourceEvent.type==="touchstart")&&(j=[N.sourceEvent.clientX??N.sourceEvent.touches[0].clientX,N.sourceEvent.clientY??N.sourceEvent.touches[0].clientY])},_=N=>{const E=o();if(N.sourceEvent.type!=="mousemove"&&N.sourceEvent.type!=="touchmove"||!r)return;const L=[N.sourceEvent.clientX??N.sourceEvent.touches[0].clientX,N.sourceEvent.clientY??N.sourceEvent.touches[0].clientY],A=[L[0]-j[0],L[1]-j[1]];j=L;const V=s()*Math.max(E[2],Math.log(E[2]))*(S?-1:1),z={x:E[0]-A[0]*V,y:E[1]-A[1]*V},G=[[0,0],[g,y]];r.setViewportConstrained({x:z.x,y:z.y,zoom:E[2]},G,f)},P=Jp().on("start",b).on("zoom",x?_:null).on("zoom.wheel",m?k:null);a.call(P,{})}function c(){a.on("zoom",null)}return{update:u,destroy:c,pointer:en}}const Il=t=>({x:t.x,y:t.y,zoom:t.k}),Tu=({x:t,y:r,zoom:o})=>Cl.translate(t,r).scale(o),fr=(t,r)=>t.target.closest(`.${r}`),bg=(t,r)=>r===2&&Array.isArray(t)&&t.includes(2),z1=t=>((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2,Ru=(t,r=0,o=z1,s=()=>{})=>{const a=typeof r=="number"&&r>0;return a||s(),a?t.transition().duration(r).ease(o).on("end",s):t},Cg=t=>{const r=t.ctrlKey&&zo()?10:1;return-t.deltaY*(t.deltaMode===1?.05:t.deltaMode?1:.002)*r};function D1({zoomPanValues:t,noWheelClassName:r,d3Selection:o,d3Zoom:s,panOnScrollMode:a,panOnScrollSpeed:u,zoomOnPinch:c,onPanZoomStart:f,onPanZoom:g,onPanZoomEnd:y}){return v=>{if(fr(v,r))return v.ctrlKey&&v.preventDefault(),!1;v.preventDefault(),v.stopImmediatePropagation();const x=o.property("__zoom").k||1;if(v.ctrlKey&&c){const b=en(v),_=Cg(v),P=x*Math.pow(2,_);s.scaleTo(o,P,b,v);return}const m=v.deltaMode===1?20:1;let S=a===Fr.Vertical?0:v.deltaX*m,k=a===Fr.Horizontal?0:v.deltaY*m;!zo()&&v.shiftKey&&a!==Fr.Vertical&&(S=v.deltaY*m,k=0),s.translateBy(o,-(S/x)*u,-(k/x)*u,{internal:!0});const j=Il(o.property("__zoom"));clearTimeout(t.panScrollTimeout),t.isPanScrolling?g==null||g(v,j):(t.isPanScrolling=!0,f==null||f(v,j)),t.panScrollTimeout=setTimeout(()=>{y==null||y(v,j),t.isPanScrolling=!1},150)}}function $1({noWheelClassName:t,preventScrolling:r,d3ZoomHandler:o}){return function(s,a){const u=s.type==="wheel",c=!r&&u&&!s.ctrlKey,f=fr(s,t);if(s.ctrlKey&&u&&f&&s.preventDefault(),c||f)return null;s.preventDefault(),o.call(this,s,a)}}function O1({zoomPanValues:t,onDraggingChange:r,onPanZoomStart:o}){return s=>{var u,c,f;if((u=s.sourceEvent)!=null&&u.internal)return;const a=Il(s.transform);t.mouseButton=((c=s.sourceEvent)==null?void 0:c.button)||0,t.isZoomingOrPanning=!0,t.prevViewport=a,((f=s.sourceEvent)==null?void 0:f.type)==="mousedown"&&r(!0),o&&(o==null||o(s.sourceEvent,a))}}function F1({zoomPanValues:t,panOnDrag:r,onPaneContextMenu:o,onTransformChange:s,onPanZoom:a}){return u=>{var c,f;t.usedRightMouseButton=!!(o&&bg(r,t.mouseButton??0)),(c=u.sourceEvent)!=null&&c.sync||s([u.transform.x,u.transform.y,u.transform.k]),a&&!((f=u.sourceEvent)!=null&&f.internal)&&(a==null||a(u.sourceEvent,Il(u.transform)))}}function H1({zoomPanValues:t,panOnDrag:r,panOnScroll:o,onDraggingChange:s,onPanZoomEnd:a,onPaneContextMenu:u}){return c=>{var f;if(!((f=c.sourceEvent)!=null&&f.internal)&&(t.isZoomingOrPanning=!1,u&&bg(r,t.mouseButton??0)&&!t.usedRightMouseButton&&c.sourceEvent&&u(c.sourceEvent),t.usedRightMouseButton=!1,s(!1),a)){const g=Il(c.transform);t.prevViewport=g,clearTimeout(t.timerId),t.timerId=setTimeout(()=>{a==null||a(c.sourceEvent,g)},o?150:0)}}}function B1({panActivationKeyPressed:t,zoomActivationKeyPressed:r,zoomOnScroll:o,zoomOnPinch:s,panOnDrag:a,panOnScroll:u,zoomOnDoubleClick:c,userSelectionActive:f,noWheelClassName:g,noPanClassName:y,lib:v,connectionInProgress:x}){return m=>{var _;const S=r||o,k=s&&m.ctrlKey,j=m.type==="wheel";if(m.button===1&&m.type==="mousedown"&&(fr(m,`${v}-flow__node`)||fr(m,`${v}-flow__edge`)||fr(m,`${v}-flow__selection`)||fr(m,`${v}-flow__nodesselection`)))return!0;if(!a&&!S&&!u&&!c&&!s||f||x&&!j||fr(m,g)&&j||fr(m,y)&&(!j||u&&j&&!r)||!s&&m.ctrlKey&&j)return!1;if(!s&&m.type==="touchstart"&&((_=m.touches)==null?void 0:_.length)>1)return m.preventDefault(),!1;if(!S&&!u&&!k&&j||!a&&(m.type==="mousedown"||m.type==="touchstart")||Array.isArray(a)&&!a.includes(m.button)&&m.type==="mousedown")return!1;const b=Array.isArray(a)&&a.includes(m.button)||!m.button||m.button<=1;return(!m.ctrlKey||j||t)&&b}}function V1({domNode:t,minZoom:r,maxZoom:o,translateExtent:s,viewport:a,onPanZoom:u,onPanZoomStart:c,onPanZoomEnd:f,onDraggingChange:g}){const y={isZoomingOrPanning:!1,usedRightMouseButton:!1,prevViewport:{},mouseButton:0,timerId:void 0,panScrollTimeout:void 0,isPanScrolling:!1},v=t.getBoundingClientRect();let x=[[0,0],[v.width,v.height]];const m=typeof ResizeObserver<"u"?new ResizeObserver(q=>{const C=q[0];C&&(x=[[0,0],[C.contentRect.width,C.contentRect.height]])}):null;m==null||m.observe(t);const S=Jp().extent(()=>x).scaleExtent([r,o]).translateExtent(s),k=Ot(t).call(S);E({x:a.x,y:a.y,zoom:zi(a.zoom,r,o)},[[0,0],[v.width,v.height]],s);const j=k.on("wheel.zoom"),b=k.on("dblclick.zoom");S.wheelDelta(Cg);async function _(q,C){return k?new Promise(W=>{S==null||S.interpolate((C==null?void 0:C.interpolate)==="linear"?Eo:al).transform(Ru(k,C==null?void 0:C.duration,C==null?void 0:C.ease,()=>W(!0)),q)}):!1}function P({noWheelClassName:q,noPanClassName:C,onPaneContextMenu:W,userSelectionActive:U,panOnScroll:Y,panOnDrag:T,panOnScrollMode:F,panOnScrollSpeed:B,preventScrolling:M,zoomOnPinch:R,zoomOnScroll:re,zoomOnDoubleClick:ie,panActivationKeyPressed:ce=!1,zoomActivationKeyPressed:fe,lib:de,onTransformChange:Q,connectionInProgress:le,paneClickDistance:me,selectionOnDrag:ke}){U&&!y.isZoomingOrPanning&&N();const xe=Y&&!fe&&!U;S.clickDistance(ke?1/0:!nn(me)||me<0?0:me);const pe=xe?D1({zoomPanValues:y,noWheelClassName:q,d3Selection:k,d3Zoom:S,panOnScrollMode:F,panOnScrollSpeed:B,zoomOnPinch:R,onPanZoomStart:c,onPanZoom:u,onPanZoomEnd:f}):$1({noWheelClassName:q,preventScrolling:M,d3ZoomHandler:j});k.on("wheel.zoom",pe,{passive:!1});const be=O1({zoomPanValues:y,onDraggingChange:g,onPanZoomStart:c});S.on("start",be);const Pe=F1({zoomPanValues:y,panOnDrag:T,onPaneContextMenu:!!W,onPanZoom:u,onTransformChange:Q});S.on("zoom",Pe);const Ce=H1({zoomPanValues:y,panOnDrag:T,panOnScroll:Y,onPaneContextMenu:W,onPanZoomEnd:f,onDraggingChange:g});S.on("end",Ce);const Re=B1({panActivationKeyPressed:ce,zoomActivationKeyPressed:fe,panOnDrag:T,zoomOnScroll:re,panOnScroll:Y,zoomOnDoubleClick:ie,zoomOnPinch:R,userSelectionActive:U,noPanClassName:C,noWheelClassName:q,lib:de,connectionInProgress:le});S.filter(Re),ie?k.on("dblclick.zoom",b):k.on("dblclick.zoom",null)}function N(){S.on("zoom",null)}async function E(q,C,W){const U=Tu(q),Y=S==null?void 0:S.constrain()(U,C,W);return Y&&await _(Y),Y}async function L(q,C){const W=Tu(q);return await _(W,C),W}function A(q){if(k){const C=Tu(q),W=k.property("__zoom");(W.k!==q.zoom||W.x!==q.x||W.y!==q.y)&&(S==null||S.transform(k,C,null,{sync:!0}))}}function V(){const q=k?Zp(k.node()):{x:0,y:0,k:1};return{x:q.x,y:q.y,zoom:q.k}}async function z(q,C){return k?new Promise(W=>{S==null||S.interpolate((C==null?void 0:C.interpolate)==="linear"?Eo:al).scaleTo(Ru(k,C==null?void 0:C.duration,C==null?void 0:C.ease,()=>W(!0)),q)}):!1}async function G(q,C){return k?new Promise(W=>{S==null||S.interpolate((C==null?void 0:C.interpolate)==="linear"?Eo:al).scaleBy(Ru(k,C==null?void 0:C.duration,C==null?void 0:C.ease,()=>W(!0)),q)}):!1}function ee(q){S==null||S.scaleExtent(q)}function J(q){S==null||S.translateExtent(q)}function ne(q){const C=!nn(q)||q<0?0:q;S==null||S.clickDistance(C)}return{update:P,destroy:N,setViewport:L,setViewportConstrained:E,getViewport:V,scaleTo:z,scaleBy:G,setScaleExtent:ee,setTranslateExtent:J,syncViewport:A,setClickDistance:ne}}var $i;(function(t){t.Line="line",t.Handle="handle"})($i||($i={}));function W1({width:t,prevWidth:r,height:o,prevHeight:s,affectsX:a,affectsY:u}){const c=t-r,f=o-s,g=[c>0?1:c<0?-1:0,f>0?1:f<0?-1:0];return c&&a&&(g[0]=g[0]*-1),f&&u&&(g[1]=g[1]*-1),g}function Ih(t){const r=t.includes("right")||t.includes("left"),o=t.includes("bottom")||t.includes("top"),s=t.includes("left"),a=t.includes("top");return{isHorizontal:r,isVertical:o,affectsX:s,affectsY:a}}function cr(t,r){return Math.max(0,r-t)}function dr(t,r){return Math.max(0,t-r)}function nl(t,r,o){return Math.max(0,r-t,t-o)}function Th(t,r){return t?!r:r}function U1(t,r,o,s,a,u,c,f){let{affectsX:g,affectsY:y}=r;const{isHorizontal:v,isVertical:x}=r,m=v&&x,{xSnapped:S,ySnapped:k}=o,{minWidth:j,maxWidth:b,minHeight:_,maxHeight:P}=s,{x:N,y:E,width:L,height:A,aspectRatio:V}=t;let z=Math.floor(v?S-t.pointerX:0),G=Math.floor(x?k-t.pointerY:0);const ee=L+(g?-z:z),J=A+(y?-G:G),ne=-u[0]*L,q=-u[1]*A;let C=nl(ee,j,b),W=nl(J,_,P);if(c){let T=0,F=0;g&&z<0?T=cr(N+z+ne,c[0][0]):!g&&z>0&&(T=dr(N+ee+ne,c[1][0])),y&&G<0?F=cr(E+G+q,c[0][1]):!y&&G>0&&(F=dr(E+J+q,c[1][1])),C=Math.max(C,T),W=Math.max(W,F)}if(f){let T=0,F=0;g&&z>0?T=dr(N+z,f[0][0]):!g&&z<0&&(T=cr(N+ee,f[1][0])),y&&G>0?F=dr(E+G,f[0][1]):!y&&G<0&&(F=cr(E+J,f[1][1])),C=Math.max(C,T),W=Math.max(W,F)}if(a){if(v){const T=nl(ee/V,_,P)*V;if(C=Math.max(C,T),c){let F=0;!g&&!y||g&&!y&&m?F=dr(E+q+ee/V,c[1][1])*V:F=cr(E+q+(g?z:-z)/V,c[0][1])*V,C=Math.max(C,F)}if(f){let F=0;!g&&!y||g&&!y&&m?F=cr(E+ee/V,f[1][1])*V:F=dr(E+(g?z:-z)/V,f[0][1])*V,C=Math.max(C,F)}}if(x){const T=nl(J*V,j,b)/V;if(W=Math.max(W,T),c){let F=0;!g&&!y||y&&!g&&m?F=dr(N+J*V+ne,c[1][0])/V:F=cr(N+(y?G:-G)*V+ne,c[0][0])/V,W=Math.max(W,F)}if(f){let F=0;!g&&!y||y&&!g&&m?F=cr(N+J*V,f[1][0])/V:F=dr(N+(y?G:-G)*V,f[0][0])/V,W=Math.max(W,F)}}}G=G+(G<0?W:-W),z=z+(z<0?C:-C),a&&(m?ee>J*V?G=(Th(g,y)?-z:z)/V:z=(Th(g,y)?-G:G)*V:v?(G=z/V,y=g):(z=G*V,g=y));const U=g?N+z:N,Y=y?E+G:E;return{width:L+(g?-z:z),height:A+(y?-G:G),x:u[0]*z*(g?-1:1)+U,y:u[1]*G*(y?-1:1)+Y}}const Mg={width:0,height:0,x:0,y:0},Y1={...Mg,pointerX:0,pointerY:0,aspectRatio:1};function G1(t,r,o){const s=r.position.x+t.position.x,a=r.position.y+t.position.y,u=t.measured.width??0,c=t.measured.height??0,f=o[0]*u,g=o[1]*c;return[[s-f,a-g],[s+u-f,a+c-g]]}function X1({domNode:t,nodeId:r,getStoreItems:o,onChange:s,onEnd:a}){const u=Ot(t);let c={controlDirection:Ih("bottom-right"),boundaries:{minWidth:0,minHeight:0,maxWidth:Number.MAX_VALUE,maxHeight:Number.MAX_VALUE},resizeDirection:void 0,keepAspectRatio:!1};function f({controlPosition:y,boundaries:v,keepAspectRatio:x,resizeDirection:m,onResizeStart:S,onResize:k,onResizeEnd:j,shouldResize:b}){let _={...Mg},P={...Y1};c={boundaries:v,resizeDirection:m,keepAspectRatio:x,controlDirection:Ih(y)};let N,E=null,L=[],A,V,z,G=!1;const ee=$p().on("start",J=>{const{nodeLookup:ne,transform:q,snapGrid:C,snapToGrid:W,nodeOrigin:U,paneDomNode:Y}=o();if(N=ne.get(r),!N)return;E=(Y==null?void 0:Y.getBoundingClientRect())??null;const{xSnapped:T,ySnapped:F}=jo(J.sourceEvent,{transform:q,snapGrid:C,snapToGrid:W,containerBounds:E});_={width:N.measured.width??0,height:N.measured.height??0,x:N.position.x??0,y:N.position.y??0},P={..._,pointerX:T,pointerY:F,aspectRatio:_.width/_.height},A=void 0,V=Wr(N.extent)?N.extent:void 0,N.parentId&&(N.extent==="parent"||N.expandParent)&&(A=ne.get(N.parentId)),A&&N.extent==="parent"&&(V=[[0,0],[A.measured.width,A.measured.height]]),L=[],z=void 0;for(const[B,M]of ne)if(M.parentId===r&&(L.push({id:B,position:{...M.position},extent:M.extent}),M.extent==="parent"||M.expandParent)){const R=G1(M,N,M.origin??U);z?z=[[Math.min(R[0][0],z[0][0]),Math.min(R[0][1],z[0][1])],[Math.max(R[1][0],z[1][0]),Math.max(R[1][1],z[1][1])]]:z=R}S==null||S(J,{..._})}).on("drag",J=>{const{transform:ne,snapGrid:q,snapToGrid:C,nodeOrigin:W}=o(),U=jo(J.sourceEvent,{transform:ne,snapGrid:q,snapToGrid:C,containerBounds:E}),Y=[];if(!N)return;const{x:T,y:F,width:B,height:M}=_,R={},re=N.origin??W,{width:ie,height:ce,x:fe,y:de}=U1(P,c.controlDirection,U,c.boundaries,c.keepAspectRatio,re,V,z),Q=ie!==B,le=ce!==M,me=fe!==T&&Q,ke=de!==F&≤if(!me&&!ke&&!Q&&!le)return;if((me||ke||re[0]===1||re[1]===1)&&(R.x=me?fe:_.x,R.y=ke?de:_.y,_.x=R.x,_.y=R.y,L.length>0)){const Pe=fe-T,Ce=de-F;for(const Re of L)Re.position={x:Re.position.x-Pe+re[0]*(ie-B),y:Re.position.y-Ce+re[1]*(ce-M)},Y.push(Re)}if((Q||le)&&(R.width=Q&&(!c.resizeDirection||c.resizeDirection==="horizontal")?ie:_.width,R.height=le&&(!c.resizeDirection||c.resizeDirection==="vertical")?ce:_.height,_.width=R.width,_.height=R.height),A&&N.expandParent){const Pe=re[0]*(R.width??0);R.x&&R.x{G&&(j==null||j(J,{..._}),a==null||a({..._}),G=!1)});u.call(ee)}function g(){u.on(".drag",null)}return{update:f,destroy:g}}var Lu={exports:{}},Au={},zu={exports:{}},Du={};/** - * @license React - * use-sync-external-store-shim.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Rh;function q1(){if(Rh)return Du;Rh=1;var t=$o();function r(x,m){return x===m&&(x!==0||1/x===1/m)||x!==x&&m!==m}var o=typeof Object.is=="function"?Object.is:r,s=t.useState,a=t.useEffect,u=t.useLayoutEffect,c=t.useDebugValue;function f(x,m){var S=m(),k=s({inst:{value:S,getSnapshot:m}}),j=k[0].inst,b=k[1];return u(function(){j.value=S,j.getSnapshot=m,g(j)&&b({inst:j})},[x,S,m]),a(function(){return g(j)&&b({inst:j}),x(function(){g(j)&&b({inst:j})})},[x]),c(S),S}function g(x){var m=x.getSnapshot;x=x.value;try{var S=m();return!o(x,S)}catch{return!0}}function y(x,m){return m()}var v=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?y:f;return Du.useSyncExternalStore=t.useSyncExternalStore!==void 0?t.useSyncExternalStore:v,Du}var Lh;function K1(){return Lh||(Lh=1,zu.exports=q1()),zu.exports}/** - * @license React - * use-sync-external-store-shim/with-selector.production.js - * - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var Ah;function Q1(){if(Ah)return Au;Ah=1;var t=$o(),r=K1();function o(y,v){return y===v&&(y!==0||1/y===1/v)||y!==y&&v!==v}var s=typeof Object.is=="function"?Object.is:o,a=r.useSyncExternalStore,u=t.useRef,c=t.useEffect,f=t.useMemo,g=t.useDebugValue;return Au.useSyncExternalStoreWithSelector=function(y,v,x,m,S){var k=u(null);if(k.current===null){var j={hasValue:!1,value:null};k.current=j}else j=k.current;k=f(function(){function _(A){if(!P){if(P=!0,N=A,A=m(A),S!==void 0&&j.hasValue){var V=j.value;if(S(V,A))return E=V}return E=A}if(V=E,s(N,A))return V;var z=m(A);return S!==void 0&&S(V,z)?(N=A,V):(N=A,E=z)}var P=!1,N,E,L=x===void 0?null:x;return[function(){return _(v())},L===null?void 0:function(){return _(L())}]},[v,x,m,S]);var b=a(y,k[0],k[1]);return c(function(){j.hasValue=!0,j.value=b},[b]),g(b),b},Au}var zh;function Z1(){return zh||(zh=1,Lu.exports=Q1()),Lu.exports}var J1=Z1();const e_=wp(J1),t_={},Dh=t=>{let r;const o=new Set,s=(v,x)=>{const m=typeof v=="function"?v(r):v;if(!Object.is(m,r)){const S=r;r=x??(typeof m!="object"||m===null)?m:Object.assign({},r,m),o.forEach(k=>k(r,S))}},a=()=>r,g={setState:s,getState:a,getInitialState:()=>y,subscribe:v=>(o.add(v),()=>o.delete(v)),destroy:()=>{(t_?"production":void 0)!=="production"&&console.warn("[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected."),o.clear()}},y=r=t(s,a,g);return g},n_=t=>t?Dh(t):Dh,{useDebugValue:r_}=e0,{useSyncExternalStoreWithSelector:i_}=e_,o_=t=>t;function Pg(t,r=o_,o){const s=i_(t.subscribe,t.getState,t.getServerState||t.getInitialState,r,o);return r_(s),s}const $h=(t,r)=>{const o=n_(t),s=(a,u=r)=>Pg(o,a,u);return Object.assign(s,o),s},s_=(t,r)=>t?$h(t,r):$h;function Ke(t,r){if(Object.is(t,r))return!0;if(typeof t!="object"||t===null||typeof r!="object"||r===null)return!1;if(t instanceof Map&&r instanceof Map){if(t.size!==r.size)return!1;for(const[s,a]of t)if(!Object.is(a,r.get(s)))return!1;return!0}if(t instanceof Set&&r instanceof Set){if(t.size!==r.size)return!1;for(const s of t)if(!r.has(s))return!1;return!0}const o=Object.keys(t);if(o.length!==Object.keys(r).length)return!1;for(const s of o)if(!Object.prototype.hasOwnProperty.call(r,s)||!Object.is(t[s],r[s]))return!1;return!0}_p();const Tl=O.createContext(null),l_=Tl.Provider,Ig=on.error001("react");function ze(t,r){const o=O.useContext(Tl);if(o===null)throw new Error(Ig);return Pg(o,t,r)}function Ye(){const t=O.useContext(Tl);if(t===null)throw new Error(Ig);return O.useMemo(()=>({getState:t.getState,setState:t.setState,subscribe:t.subscribe}),[t])}const Oh={display:"none"},a_={position:"absolute",width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0px, 0px, 0px, 0px)",clipPath:"inset(100%)"},Tg="react-flow__node-desc",Rg="react-flow__edge-desc",u_="react-flow__aria-live",c_=t=>t.ariaLiveMessage,d_=t=>t.ariaLabelConfig;function f_({rfId:t}){const r=ze(c_);return h.jsx("div",{id:`${u_}-${t}`,"aria-live":"assertive","aria-atomic":"true",style:a_,children:r})}function h_({rfId:t,disableKeyboardA11y:r}){const o=ze(d_);return h.jsxs(h.Fragment,{children:[h.jsx("div",{id:`${Tg}-${t}`,style:Oh,children:r?o["node.a11yDescription.default"]:o["node.a11yDescription.keyboardDisabled"]}),h.jsx("div",{id:`${Rg}-${t}`,style:Oh,children:o["edge.a11yDescription.default"]}),!r&&h.jsx(f_,{rfId:t})]})}const Rl=O.forwardRef(({position:t="top-left",children:r,className:o,style:s,...a},u)=>{const c=`${t}`.split("-");return h.jsx("div",{className:it(["react-flow__panel",o,...c]),style:s,ref:u,...a,children:r})});Rl.displayName="Panel";const Fh="https://reactflow.dev?utm_source=attribution";function p_({proOptions:t,position:r="bottom-right"}){return t!=null&&t.hideAttribution?null:h.jsx(Rl,{position:r,className:"react-flow__attribution","data-message":`Please only hide this attribution when you are subscribed to React Flow Pro: ${Fh}`,children:h.jsx("a",{href:Fh,target:"_blank",rel:"noopener noreferrer","aria-label":"React Flow attribution",children:"React Flow"})})}const g_=t=>{const r=[],o=[];for(const[,s]of t.nodeLookup)s.selected&&r.push(s.internals.userNode);for(const[,s]of t.edgeLookup)s.selected&&o.push(s);return{selectedNodes:r,selectedEdges:o}},rl=t=>t.id;function m_(t,r){return Ke(t.selectedNodes.map(rl),r.selectedNodes.map(rl))&&Ke(t.selectedEdges.map(rl),r.selectedEdges.map(rl))}function y_({onSelectionChange:t}){const r=Ye(),{selectedNodes:o,selectedEdges:s}=ze(g_,m_);return O.useEffect(()=>{const a={nodes:o,edges:s};t==null||t(a),r.getState().onSelectionChangeHandlers.forEach(u=>u(a))},[o,s,t]),null}const v_=t=>!!t.onSelectionChangeHandlers;function x_({onSelectionChange:t}){const r=ze(v_);return t||r?h.jsx(y_,{onSelectionChange:t}):null}const Lg=[0,0],w_={x:0,y:0,zoom:1},__=["nodes","edges","defaultNodes","defaultEdges","onConnect","onConnectStart","onConnectEnd","onClickConnectStart","onClickConnectEnd","nodesDraggable","autoPanOnNodeFocus","nodesConnectable","nodesFocusable","edgesFocusable","edgesReconnectable","elevateNodesOnSelect","elevateEdgesOnSelect","minZoom","maxZoom","nodeExtent","onNodesChange","onEdgesChange","elementsSelectable","connectionMode","snapGrid","snapToGrid","translateExtent","connectOnClick","defaultEdgeOptions","fitView","fitViewOptions","onNodesDelete","onEdgesDelete","onDelete","onNodeDrag","onNodeDragStart","onNodeDragStop","onSelectionDrag","onSelectionDragStart","onSelectionDragStop","onMoveStart","onMove","onMoveEnd","noPanClassName","nodeOrigin","autoPanOnConnect","autoPanOnNodeDrag","onError","connectionRadius","isValidConnection","selectNodesOnDrag","nodeDragThreshold","connectionDragThreshold","onBeforeDelete","debug","autoPanSpeed","ariaLabelConfig","zIndexMode"],Hh=[...__,"rfId"],S_=t=>({setNodes:t.setNodes,setEdges:t.setEdges,setMinZoom:t.setMinZoom,setMaxZoom:t.setMaxZoom,setTranslateExtent:t.setTranslateExtent,setNodeExtent:t.setNodeExtent,reset:t.reset,setDefaultNodesAndEdges:t.setDefaultNodesAndEdges}),Bh={translateExtent:To,nodeOrigin:Lg,minZoom:.5,maxZoom:2,elementsSelectable:!0,noPanClassName:"nopan",rfId:"1"};function k_(t){const{setNodes:r,setEdges:o,setMinZoom:s,setMaxZoom:a,setTranslateExtent:u,setNodeExtent:c,reset:f,setDefaultNodesAndEdges:g}=ze(S_,Ke),y=Ye();O.useEffect(()=>(g(t.defaultNodes,t.defaultEdges),()=>{v.current=Bh,f()}),[]);const v=O.useRef(Bh);return O.useEffect(()=>{for(const x of Hh){const m=t[x],S=v.current[x];m!==S&&(typeof t[x]>"u"||(x==="nodes"?r(m):x==="edges"?o(m):x==="minZoom"?s(m):x==="maxZoom"?a(m):x==="translateExtent"?u(m):x==="nodeExtent"?c(m):x==="ariaLabelConfig"?y.setState({ariaLabelConfig:l1(m)}):x==="fitView"?y.setState({fitViewQueued:m}):x==="fitViewOptions"?y.setState({fitViewOptions:m}):y.setState({[x]:m})))}v.current=t},Hh.map(x=>t[x])),null}function Vh(){return typeof window>"u"||!window.matchMedia?null:window.matchMedia("(prefers-color-scheme: dark)")}function N_(t){var s;const[r,o]=O.useState(t==="system"?null:t);return O.useEffect(()=>{if(t!=="system"){o(t);return}const a=Vh(),u=()=>o(a!=null&&a.matches?"dark":"light");return u(),a==null||a.addEventListener("change",u),()=>{a==null||a.removeEventListener("change",u)}},[t]),r!==null?r:(s=Vh())!=null&&s.matches?"dark":"light"}const Wh=typeof document<"u"?document:null;function Do(t=null,r={target:Wh,actInsideInputWithModifier:!0}){const[o,s]=O.useState(!1),a=O.useRef(!1),u=O.useRef(new Set([])),[c,f]=O.useMemo(()=>{if(t!==null){const y=(Array.isArray(t)?t:[t]).filter(x=>typeof x=="string").map(x=>x.replace(/\+/g,` -`).replace(` - -`,` -+`).split(` -`)),v=y.reduce((x,m)=>x.concat(...m),[]);return[y,v]}return[[],[]]},[t]);return O.useEffect(()=>{const g=(r==null?void 0:r.target)??Wh,y=(r==null?void 0:r.actInsideInputWithModifier)??!0;if(t!==null){const v=S=>{var b,_;if(a.current=S.ctrlKey||S.metaKey||S.shiftKey||S.altKey,(!a.current||a.current&&!y)&&hg(S))return!1;const j=Yh(S.code,f);if(u.current.add(S[j]),Uh(c,u.current,!1)){const P=((_=(b=S.composedPath)==null?void 0:b.call(S))==null?void 0:_[0])||S.target,N=(P==null?void 0:P.nodeName)==="BUTTON"||(P==null?void 0:P.nodeName)==="A";r.preventDefault!==!1&&(a.current||!N)&&S.preventDefault(),s(!0)}},x=S=>{const k=Yh(S.code,f);Uh(c,u.current,!0)?(s(!1),u.current.clear()):u.current.delete(S[k]),S.key==="Meta"&&u.current.clear(),a.current=!1},m=()=>{u.current.clear(),s(!1)};return g==null||g.addEventListener("keydown",v),g==null||g.addEventListener("keyup",x),window.addEventListener("blur",m),window.addEventListener("contextmenu",m),()=>{g==null||g.removeEventListener("keydown",v),g==null||g.removeEventListener("keyup",x),window.removeEventListener("blur",m),window.removeEventListener("contextmenu",m)}}},[t,s]),o}function Uh(t,r,o){return t.filter(s=>o||s.length===r.size).some(s=>s.every(a=>r.has(a)))}function Yh(t,r){return r.includes(t)?"code":"key"}const E_=()=>{const t=Ye();return O.useMemo(()=>({zoomIn:async r=>{const{panZoom:o}=t.getState();return o?o.scaleBy(1.2,r):!1},zoomOut:async r=>{const{panZoom:o}=t.getState();return o?o.scaleBy(1/1.2,r):!1},zoomTo:async(r,o)=>{const{panZoom:s}=t.getState();return s?s.scaleTo(r,o):!1},getZoom:()=>t.getState().transform[2],setViewport:async(r,o)=>{const{transform:[s,a,u],panZoom:c}=t.getState();return c?(await c.setViewport({x:r.x??s,y:r.y??a,zoom:r.zoom??u},o),!0):!1},getViewport:()=>{const[r,o,s]=t.getState().transform;return{x:r,y:o,zoom:s}},setCenter:async(r,o,s)=>t.getState().setCenter(r,o,s),fitBounds:async(r,o)=>{const{width:s,height:a,minZoom:u,maxZoom:c,panZoom:f}=t.getState(),g=pc(r,s,a,u,c,(o==null?void 0:o.padding)??.1);return f?(await f.setViewport(g,{duration:o==null?void 0:o.duration,ease:o==null?void 0:o.ease,interpolate:o==null?void 0:o.interpolate}),!0):!1},screenToFlowPosition:(r,o={})=>{const{transform:s,snapGrid:a,snapToGrid:u,domNode:c}=t.getState();if(!c)return r;const{x:f,y:g}=c.getBoundingClientRect(),y={x:r.x-f,y:r.y-g},v=o.snapGrid??a,x=o.snapToGrid??u;return Wo(y,s,x,v)},flowToScreenPosition:r=>{const{transform:o,domNode:s}=t.getState();if(!s)return r;const{x:a,y:u}=s.getBoundingClientRect(),c=Di(r,o);return{x:c.x+a,y:c.y+u}}}),[])};function Ag(t,r){const o=[],s=new Map,a=[];for(const u of t)if(u.type==="add"){a.push(u);continue}else if(u.type==="remove"||u.type==="replace")s.set(u.id,[u]);else{const c=s.get(u.id);c?c.push(u):s.set(u.id,[u])}for(const u of r){const c=s.get(u.id);if(!c){o.push(u);continue}if(c[0].type==="remove")continue;if(c[0].type==="replace"){o.push({...c[0].item});continue}const f={...u};for(const g of c)j_(g,f);o.push(f)}return a.length&&a.forEach(u=>{u.index!==void 0?o.splice(u.index,0,{...u.item}):o.push({...u.item})}),o}function j_(t,r){switch(t.type){case"select":{r.selected=t.selected;break}case"position":{typeof t.position<"u"&&(r.position=t.position),typeof t.dragging<"u"&&(r.dragging=t.dragging);break}case"dimensions":{typeof t.dimensions<"u"&&(r.measured={...t.dimensions},t.setAttributes&&((t.setAttributes===!0||t.setAttributes==="width")&&(r.width=t.dimensions.width),(t.setAttributes===!0||t.setAttributes==="height")&&(r.height=t.dimensions.height))),typeof t.resizing=="boolean"&&(r.resizing=t.resizing);break}}}function b_(t,r){return Ag(t,r)}function C_(t,r){return Ag(t,r)}function zr(t,r){return{id:t,type:"select",selected:r}}function Pi(t,r=new Set,o=!1){const s=[];for(const[a,u]of t){const c=r.has(a);!(u.selected===void 0&&!c)&&u.selected!==c&&(o&&(u.selected=c),s.push(zr(u.id,c)))}return s}function Gh({items:t=[],lookup:r}){var a;const o=[],s=new Map(t.map(u=>[u.id,u]));for(const[u,c]of t.entries()){const f=r.get(c.id),g=((a=f==null?void 0:f.internals)==null?void 0:a.userNode)??f;g!==void 0&&g!==c&&o.push({id:c.id,item:c,type:"replace"}),g===void 0&&o.push({item:c,type:"add",index:u})}for(const[u]of r)s.get(u)===void 0&&o.push({id:u,type:"remove"});return o}function Xh(t){return{id:t.id,type:"remove"}}const M_=ug();function P_(t,r,o={}){return h1(t,r,{...o,onError:o.onError??M_})}const qh=t=>Zw(t),I_=t=>ig(t);function zg(t){return O.forwardRef(t)}const Dg=typeof window<"u"?O.useLayoutEffect:O.useEffect;function Kh(t){const[r,o]=O.useState(BigInt(0)),[s]=O.useState(()=>T_(()=>o(a=>a+BigInt(1))));return Dg(()=>{const a=s.get();a.length&&(t(a),s.reset())},[r]),s}function T_(t){let r=[];return{get:()=>r,reset:()=>{r=[]},push:o=>{r.push(o),t()}}}const $g=O.createContext(null);function R_({children:t}){const r=Ye(),o=O.useCallback(f=>{const{nodes:g=[],setNodes:y,hasDefaultNodes:v,onNodesChange:x,nodeLookup:m,fitViewQueued:S,onNodesChangeMiddlewareMap:k}=r.getState();let j=g;for(const _ of f)j=typeof _=="function"?_(j):_;let b=Gh({items:j,lookup:m});for(const _ of k.values())b=_(b);v&&y(j),b.length>0?x==null||x(b):S&&window.requestAnimationFrame(()=>{const{fitViewQueued:_,nodes:P,setNodes:N}=r.getState();_&&N(P)})},[]),s=Kh(o),a=O.useCallback(f=>{const{edges:g=[],setEdges:y,hasDefaultEdges:v,onEdgesChange:x,edgeLookup:m}=r.getState();let S=g;for(const k of f)S=typeof k=="function"?k(S):k;v?y(S):x&&x(Gh({items:S,lookup:m}))},[]),u=Kh(a),c=O.useMemo(()=>({nodeQueue:s,edgeQueue:u}),[]);return h.jsx($g.Provider,{value:c,children:t})}function L_(){const t=O.useContext($g);if(!t)throw new Error("useBatchContext must be used within a BatchProvider");return t}const A_=t=>!!t.panZoom;function Ll(){const t=E_(),r=Ye(),o=L_(),s=ze(A_),a=O.useMemo(()=>{const u=x=>r.getState().nodeLookup.get(x),c=x=>{o.nodeQueue.push(x)},f=x=>{o.edgeQueue.push(x)},g=x=>{var _,P;const{nodeLookup:m,nodeOrigin:S}=r.getState(),k=qh(x)?x:m.get(x.id),j=k.parentId?dg(k.position,k.measured,k.parentId,m,S):k.position,b={...k,position:j,width:((_=k.measured)==null?void 0:_.width)??k.width,height:((P=k.measured)==null?void 0:P.height)??k.height};return Ao(b)},y=(x,m,S={replace:!1})=>{c(k=>k.map(j=>{if(j.id===x){const b=typeof m=="function"?m(j):m;return S.replace&&qh(b)?b:{...j,...b}}return j}))},v=(x,m,S={replace:!1})=>{f(k=>k.map(j=>{if(j.id===x){const b=typeof m=="function"?m(j):m;return S.replace&&I_(b)?b:{...j,...b}}return j}))};return{getNodes:()=>r.getState().nodes.map(x=>({...x})),getNode:x=>{var m;return(m=u(x))==null?void 0:m.internals.userNode},getInternalNode:u,getEdges:()=>{const{edges:x=[]}=r.getState();return x.map(m=>({...m}))},getEdge:x=>r.getState().edgeLookup.get(x),setNodes:c,setEdges:f,addNodes:x=>{const m=Array.isArray(x)?x:[x];o.nodeQueue.push(S=>[...S,...m])},addEdges:x=>{const m=Array.isArray(x)?x:[x];o.edgeQueue.push(S=>[...S,...m])},toObject:()=>{const{nodes:x=[],edges:m=[],transform:S}=r.getState(),[k,j,b]=S;return{nodes:x.map(_=>({..._})),edges:m.map(_=>({..._})),viewport:{x:k,y:j,zoom:b}}},deleteElements:async({nodes:x=[],edges:m=[]})=>{const{nodes:S,edges:k,onNodesDelete:j,onEdgesDelete:b,triggerNodeChanges:_,triggerEdgeChanges:P,onDelete:N,onBeforeDelete:E}=r.getState(),{nodes:L,edges:A}=await r1({nodesToRemove:x,edgesToRemove:m,nodes:S,edges:k,onBeforeDelete:E}),V=A.length>0,z=L.length>0;if(V){const G=A.map(Xh);b==null||b(A),P(G)}if(z){const G=L.map(Xh);j==null||j(L),_(G)}return(z||V)&&(N==null||N({nodes:L,edges:A})),{deletedNodes:L,deletedEdges:A}},getIntersectingNodes:(x,m=!0,S)=>{const k=wh(x),j=k?x:g(x),b=S!==void 0;return j?(S||r.getState().nodes).filter(_=>{const P=r.getState().nodeLookup.get(_.id);if(P&&!k&&(_.id===x.id||!P.internals.positionAbsolute))return!1;const N=Ao(b?_:P),E=wl(N,j);return m&&E>0||E>=N.width*N.height||E>=j.width*j.height}):[]},isNodeIntersecting:(x,m,S=!0)=>{const j=wh(x)?x:g(x);if(!j)return!1;const b=wl(j,m);return S&&b>0||b>=m.width*m.height||b>=j.width*j.height},updateNode:y,updateNodeData:(x,m,S={replace:!1})=>{y(x,k=>{const j=typeof m=="function"?m(k):m;return S.replace?{...k,data:j}:{...k,data:{...k.data,...j}}},S)},updateEdge:v,updateEdgeData:(x,m,S={replace:!1})=>{v(x,k=>{const j=typeof m=="function"?m(k):m;return S.replace?{...k,data:j}:{...k,data:{...k.data,...j}}},S)},getNodesBounds:x=>{const{nodeLookup:m,nodeOrigin:S}=r.getState();return Jw(x,{nodeLookup:m,nodeOrigin:S})},getHandleConnections:({type:x,id:m,nodeId:S})=>{var k;return Array.from(((k=r.getState().connectionLookup.get(`${S}-${x}${m?`-${m}`:""}`))==null?void 0:k.values())??[])},getNodeConnections:({type:x,handleId:m,nodeId:S})=>{var k;return Array.from(((k=r.getState().connectionLookup.get(`${S}${x?m?`-${x}-${m}`:`-${x}`:""}`))==null?void 0:k.values())??[])},fitView:async x=>{const m=r.getState().fitViewResolver??s1();return r.setState({fitViewQueued:!0,fitViewOptions:x,fitViewResolver:m}),o.nodeQueue.push(S=>[...S]),m.promise}}},[]);return O.useMemo(()=>({...a,...t,viewportInitialized:s}),[s])}const Qh=t=>t.selected,z_=typeof window<"u"?window:void 0;function D_({deleteKeyCode:t,multiSelectionKeyCode:r}){const o=Ye(),{deleteElements:s}=Ll(),a=Do(t,{actInsideInputWithModifier:!1}),u=Do(r,{target:z_});O.useEffect(()=>{if(a){const{edges:c,nodes:f}=o.getState();s({nodes:f.filter(Qh),edges:c.filter(Qh)}),o.setState({nodesSelectionActive:!1})}},[a]),O.useEffect(()=>{o.setState({multiSelectionActive:u})},[u])}function $_(t){const r=Ye();O.useEffect(()=>{const o=()=>{var a,u,c,f;if(!t.current||!(((u=(a=t.current).checkVisibility)==null?void 0:u.call(a))??!0))return!1;const s=gc(t.current);(s.height===0||s.width===0)&&((f=(c=r.getState()).onError)==null||f.call(c,"004",on.error004())),r.setState({width:s.width||500,height:s.height||500})};if(t.current){o(),window.addEventListener("resize",o);const s=new ResizeObserver(()=>o());return s.observe(t.current),()=>{window.removeEventListener("resize",o),s&&t.current&&s.unobserve(t.current)}}},[])}const Al={position:"absolute",width:"100%",height:"100%",top:0,left:0},O_=t=>({userSelectionActive:t.userSelectionActive,lib:t.lib,connectionInProgress:t.connection.inProgress});function F_({onPaneContextMenu:t,zoomOnScroll:r=!0,zoomOnPinch:o=!0,panOnScroll:s=!1,panActivationKeyPressed:a,panOnScrollSpeed:u=.5,panOnScrollMode:c=Fr.Free,zoomOnDoubleClick:f=!0,panOnDrag:g=!0,defaultViewport:y,translateExtent:v,minZoom:x,maxZoom:m,zoomActivationKeyCode:S,preventScrolling:k=!0,children:j,noWheelClassName:b,noPanClassName:_,onViewportChange:P,isControlledViewport:N,paneClickDistance:E,selectionOnDrag:L}){const A=Ye(),V=O.useRef(null),{userSelectionActive:z,lib:G,connectionInProgress:ee}=ze(O_,Ke),J=Do(S),ne=O.useRef();$_(V);const q=O.useCallback(C=>{P==null||P({x:C[0],y:C[1],zoom:C[2]}),N||A.setState({transform:C})},[P,N]);return O.useEffect(()=>{if(V.current){ne.current=V1({domNode:V.current,minZoom:x,maxZoom:m,translateExtent:v,viewport:y,onDraggingChange:Y=>A.setState(T=>T.paneDragging===Y?T:{paneDragging:Y}),onPanZoomStart:(Y,T)=>{const{onViewportChangeStart:F,onMoveStart:B}=A.getState();B==null||B(Y,T),F==null||F(T)},onPanZoom:(Y,T)=>{const{onViewportChange:F,onMove:B}=A.getState();B==null||B(Y,T),F==null||F(T)},onPanZoomEnd:(Y,T)=>{const{onViewportChangeEnd:F,onMoveEnd:B}=A.getState();B==null||B(Y,T),F==null||F(T)}});const{x:C,y:W,zoom:U}=ne.current.getViewport();return A.setState({panZoom:ne.current,transform:[C,W,U],domNode:V.current.closest(".react-flow")}),()=>{var Y;(Y=ne.current)==null||Y.destroy()}}},[]),O.useEffect(()=>{var C;(C=ne.current)==null||C.update({onPaneContextMenu:t,zoomOnScroll:r,zoomOnPinch:o,panOnScroll:s,panActivationKeyPressed:a,panOnScrollSpeed:u,panOnScrollMode:c,zoomOnDoubleClick:f,panOnDrag:g,zoomActivationKeyPressed:J,preventScrolling:k,noPanClassName:_,userSelectionActive:z,noWheelClassName:b,lib:G,onTransformChange:q,connectionInProgress:ee,selectionOnDrag:L,paneClickDistance:E})},[t,r,o,s,a,u,c,f,g,J,k,_,z,b,G,q,ee,L,E]),h.jsx("div",{className:"react-flow__renderer",ref:V,style:Al,children:j})}const H_=t=>({userSelectionActive:t.userSelectionActive,userSelectionRect:t.userSelectionRect});function B_(){const{userSelectionActive:t,userSelectionRect:r}=ze(H_,Ke);return t&&r?h.jsx("div",{className:"react-flow__selection react-flow__container",style:{width:r.width,height:r.height,transform:`translate(${r.x}px, ${r.y}px)`}}):null}const $u=(t,r)=>o=>{o.target===r.current&&(t==null||t(o))},V_=t=>({userSelectionActive:t.userSelectionActive,elementsSelectable:t.elementsSelectable,dragging:t.paneDragging,panBy:t.panBy,autoPanSpeed:t.autoPanSpeed});function W_({isSelecting:t,selectionKeyPressed:r,selectionMode:o=Ro.Full,panOnDrag:s,autoPanOnSelection:a,paneClickDistance:u,selectionOnDrag:c,onSelectionStart:f,onSelectionEnd:g,onPaneClick:y,onPaneContextMenu:v,onPaneScroll:x,onPaneMouseEnter:m,onPaneMouseMove:S,onPaneMouseLeave:k,children:j}){const b=O.useRef(0),_=Ye(),{userSelectionActive:P,elementsSelectable:N,dragging:E,panBy:L,autoPanSpeed:A}=ze(V_,Ke),V=N&&(t||P),z=O.useRef(null),G=O.useRef(),ee=O.useRef(new Set),J=O.useRef(new Set),ne=O.useRef(!1),q=O.useRef(!1),C=O.useRef({x:0,y:0}),W=O.useRef(!1),U=Q=>{if(q.current||ne.current||_.getState().connection.inProgress){q.current=!1,ne.current=!1;return}y==null||y(Q),_.getState().resetSelectedElements(),_.setState({nodesSelectionActive:!1})},Y=Q=>{if(Array.isArray(s)&&(s!=null&&s.includes(2))){Q.preventDefault();return}v==null||v(Q)},T=x?Q=>x(Q):void 0,F=Q=>{q.current&&(Q.stopPropagation(),q.current=!1)},B=Q=>{var Re,tt;if(Q.pointerType==="touch"&&s!==!1&&!r)return;const{domNode:le,transform:me}=_.getState();if(G.current=le==null?void 0:le.getBoundingClientRect(),!G.current)return;const ke=Q.target===z.current;if(!ke&&!!Q.target.closest(".nokey")||!t||!(c&&ke||r)||Q.button!==0||!Q.isPrimary)return;(tt=(Re=Q.target)==null?void 0:Re.setPointerCapture)==null||tt.call(Re,Q.pointerId),q.current=!1;const{x:be,y:Pe}=rn(Q.nativeEvent,G.current),Ce=Wo({x:be,y:Pe},me);_.setState({userSelectionRect:{width:0,height:0,startX:Ce.x,startY:Ce.y,x:be,y:Pe}}),ke||(Q.stopPropagation(),Q.preventDefault())};function M(Q,le){const{userSelectionRect:me}=_.getState();if(!me)return;const{transform:ke,nodeLookup:xe,edgeLookup:pe,connectionLookup:be,triggerNodeChanges:Pe,triggerEdgeChanges:Ce,defaultEdgeOptions:Re}=_.getState(),tt={x:me.startX,y:me.startY},{x:nt,y:Je}=Di(tt,ke),Qe={startX:tt.x,startY:tt.y,x:Qft.id)),J.current=new Set;const st=(Re==null?void 0:Re.selectable)??!0;for(const ft of ee.current){const He=be.get(ft);if(He)for(const{edgeId:Le}of He.values()){const mt=pe.get(Le);mt&&(mt.selectable??st)&&J.current.add(Le)}}if(!_h(ot,ee.current)){const ft=Pi(xe,ee.current,!0);Pe(ft)}if(!_h(Pt,J.current)){const ft=Pi(pe,J.current);Ce(ft)}_.setState({userSelectionRect:Qe,userSelectionActive:!0,nodesSelectionActive:!1})}function R(){if(!a||!G.current)return;const[Q,le]=hc(C.current,G.current,A);L({x:Q,y:le}).then(me=>{if(!q.current||!me){b.current=requestAnimationFrame(R);return}const{x:ke,y:xe}=C.current;M(ke,xe),b.current=requestAnimationFrame(R)})}const re=()=>{cancelAnimationFrame(b.current),b.current=0,W.current=!1};O.useEffect(()=>()=>re(),[]);const ie=Q=>{const{userSelectionRect:le,transform:me,resetSelectedElements:ke}=_.getState();if(!G.current||!le)return;const{x:xe,y:pe}=rn(Q.nativeEvent,G.current);C.current={x:xe,y:pe};const be=Di({x:le.startX,y:le.startY},me);if(!q.current){const Pe=r?0:u;if(Math.hypot(xe-be.x,pe-be.y)<=Pe)return;ke(),f==null||f(Q)}q.current=!0,W.current||(R(),W.current=!0),M(xe,pe)},ce=Q=>{var le,me;if(!V){Q.target===z.current&&_.getState().connection.inProgress&&(ne.current=!0);return}Q.button===0&&((me=(le=Q.target)==null?void 0:le.releasePointerCapture)==null||me.call(le,Q.pointerId),!P&&Q.target===z.current&&_.getState().userSelectionRect&&(U==null||U(Q)),_.setState({userSelectionActive:!1,userSelectionRect:null}),q.current&&(g==null||g(Q),_.setState({nodesSelectionActive:ee.current.size>0})),re())},fe=Q=>{var le,me;(me=(le=Q.target)==null?void 0:le.releasePointerCapture)==null||me.call(le,Q.pointerId),re()},de=s===!0||Array.isArray(s)&&s.includes(0);return h.jsxs("div",{className:it(["react-flow__pane",{draggable:de,dragging:E,selection:t}]),onClick:V?void 0:$u(U,z),onContextMenu:$u(Y,z),onWheel:$u(T,z),onPointerEnter:V?void 0:m,onPointerMove:V?ie:S,onPointerUp:ce,onPointerCancel:V?fe:void 0,onPointerDownCapture:V?B:void 0,onClickCapture:V?F:void 0,onPointerLeave:k,ref:z,style:Al,children:[j,h.jsx(B_,{})]})}function tc({id:t,store:r,unselect:o=!1,nodeRef:s}){const{addSelectedNodes:a,unselectNodesAndEdges:u,multiSelectionActive:c,nodeLookup:f,onError:g}=r.getState(),y=f.get(t);if(!y){g==null||g("012",on.error012(t));return}r.setState({nodesSelectionActive:!1}),y.selected?(o||y.selected&&c)&&(u({nodes:[y],edges:[]}),requestAnimationFrame(()=>{var v;return(v=s==null?void 0:s.current)==null?void 0:v.blur()})):a([t])}function Og({nodeRef:t,disabled:r=!1,noDragClassName:o,handleSelector:s,nodeId:a,isSelectable:u,nodeClickDistance:c}){const f=Ye(),[g,y]=O.useState(!1),v=O.useRef();return O.useEffect(()=>{if(!r)return v.current=M1({getStoreItems:()=>f.getState(),onNodeMouseDown:x=>{tc({id:x,store:f,nodeRef:t})},onDragStart:()=>{y(!0)},onDragStop:()=>{y(!1)}}),()=>{var x;(x=v.current)==null||x.destroy(),v.current=void 0}},[r,f,t]),O.useEffect(()=>{r||!t.current||!v.current||v.current.update({noDragClassName:o,handleSelector:s,domNode:t.current,isSelectable:u,nodeId:a,nodeClickDistance:c})},[o,s,r,u,t,a,c]),g}const U_=t=>r=>r.selected&&(r.draggable||t&&typeof r.draggable>"u");function Fg(){const t=Ye();return O.useCallback(o=>{const{nodeExtent:s,snapToGrid:a,snapGrid:u,nodesDraggable:c,onError:f,updateNodePositions:g,nodeLookup:y,nodeOrigin:v}=t.getState(),x=new Map,m=U_(c),S=a?u[0]:5,k=a?u[1]:5,j=o.direction.x*S*o.factor,b=o.direction.y*k*o.factor;for(const[,_]of y){if(!m(_))continue;let P={x:_.internals.positionAbsolute.x+j,y:_.internals.positionAbsolute.y+b};a&&(P=Vo(P,u));const{position:N,positionAbsolute:E}=og({nodeId:_.id,nextPosition:P,nodeLookup:y,nodeExtent:s,nodeOrigin:v,onError:f});_.position=N,_.internals.positionAbsolute=E,x.set(_.id,_)}g(x)},[])}const _c=O.createContext(null),Y_=_c.Provider;_c.Consumer;const Hg=()=>O.useContext(_c),G_=t=>({connectOnClick:t.connectOnClick,noPanClassName:t.noPanClassName,rfId:t.rfId}),Bg=O.createContext(null);function X_({children:t}){const r=ze(G_,Ke);return h.jsx(Bg.Provider,{value:r,children:t})}function q_(){const t=O.useContext(Bg);if(!t)throw new Error("useHandleConfig must be used within a HandleConfigProvider");return t}const K_={connectingFrom:!1,connectingTo:!1,clickConnecting:!1,isPossibleEndHandle:!0,connectionInProcess:!1,clickConnectionInProcess:!1,valid:!1},Q_=(t,r,o)=>s=>{const{connectionClickStartHandle:a,connectionMode:u,connection:c}=s,{fromHandle:f,toHandle:g,isValid:y}=c;if(!f&&!a)return K_;const v=(g==null?void 0:g.nodeId)===t&&(g==null?void 0:g.id)===r&&(g==null?void 0:g.type)===o;return{connectingFrom:(f==null?void 0:f.nodeId)===t&&(f==null?void 0:f.id)===r&&(f==null?void 0:f.type)===o,connectingTo:v,clickConnecting:(a==null?void 0:a.nodeId)===t&&(a==null?void 0:a.id)===r&&(a==null?void 0:a.type)===o,isPossibleEndHandle:u===Ai.Strict?(f==null?void 0:f.type)!==o:t!==(f==null?void 0:f.nodeId)||r!==(f==null?void 0:f.id),connectionInProcess:!!f,clickConnectionInProcess:!!a,valid:v&&y}};function Z_({type:t="source",position:r=Se.Top,isValidConnection:o,isConnectable:s=!0,isConnectableStart:a=!0,isConnectableEnd:u=!0,id:c,onConnect:f,children:g,className:y,onMouseDown:v,onTouchStart:x,...m},S){var W,U;const k=c||null,j=t==="target",b=Ye(),_=Hg(),{connectOnClick:P,noPanClassName:N,rfId:E}=q_(),{connectingFrom:L,connectingTo:A,clickConnecting:V,isPossibleEndHandle:z,connectionInProcess:G,clickConnectionInProcess:ee,valid:J}=ze(Q_(_,k,t),Ke);_||(U=(W=b.getState()).onError)==null||U.call(W,"010",on.error010());const ne=Y=>{const{defaultEdgeOptions:T,onConnect:F,hasDefaultEdges:B}=b.getState(),M={...T,...Y};if(B){const{edges:R,setEdges:re,onError:ie}=b.getState();re(P_(M,R,{onError:ie}))}F==null||F(M),f==null||f(M)},q=Y=>{if(!_)return;const T=pg(Y.nativeEvent);if(a&&(T&&Y.button===0||!T)){const F=b.getState();ec.onPointerDown(Y.nativeEvent,{handleDomNode:Y.currentTarget,autoPanOnConnect:F.autoPanOnConnect,connectionMode:F.connectionMode,connectionRadius:F.connectionRadius,domNode:F.domNode,nodeLookup:F.nodeLookup,lib:F.lib,isTarget:j,handleId:k,nodeId:_,flowId:F.rfId,panBy:F.panBy,cancelConnection:F.cancelConnection,onConnectStart:F.onConnectStart,onConnectEnd:(...B)=>{var M,R;return(R=(M=b.getState()).onConnectEnd)==null?void 0:R.call(M,...B)},updateConnection:F.updateConnection,onConnect:ne,isValidConnection:o||((...B)=>{var M,R;return((R=(M=b.getState()).isValidConnection)==null?void 0:R.call(M,...B))??!0}),getTransform:()=>b.getState().transform,getFromHandle:()=>b.getState().connection.fromHandle,autoPanSpeed:F.autoPanSpeed,dragThreshold:F.connectionDragThreshold})}T?v==null||v(Y):x==null||x(Y)},C=Y=>{const{onClickConnectStart:T,onClickConnectEnd:F,connectionClickStartHandle:B,connectionMode:M,isValidConnection:R,lib:re,rfId:ie,nodeLookup:ce,connection:fe}=b.getState();if(!_||!B&&!a)return;if(!B){T==null||T(Y.nativeEvent,{nodeId:_,handleId:k,handleType:t}),b.setState({connectionClickStartHandle:{nodeId:_,type:t,id:k}});return}const de=fg(Y.target),Q=o||R,{connection:le,isValid:me}=ec.isValid(Y.nativeEvent,{handle:{nodeId:_,id:k,type:t},connectionMode:M,fromNodeId:B.nodeId,fromHandleId:B.id||null,fromType:B.type,isValidConnection:Q,flowId:ie,doc:de,lib:re,nodeLookup:ce});me&&le&&ne(le);const ke=structuredClone(fe);delete ke.inProgress,ke.toPosition=ke.toHandle?ke.toHandle.position:null,F==null||F(Y,ke),b.setState({connectionClickStartHandle:null})};return h.jsx("div",{"data-handleid":k,"data-nodeid":_,"data-handlepos":r,"data-id":`${E}-${_}-${k}-${t}`,className:it(["react-flow__handle",`react-flow__handle-${r}`,"nodrag",N,y,{source:!j,target:j,connectable:s,connectablestart:a,connectableend:u,clickconnecting:V,connectingfrom:L,connectingto:A,valid:J,connectionindicator:s&&(!G||z)&&(G||ee?u:a)}]),onMouseDown:q,onTouchStart:q,onClick:P?C:void 0,ref:S,...m,children:g})}const Oi=O.memo(zg(Z_));function J_({data:t,isConnectable:r,sourcePosition:o=Se.Bottom}){return h.jsxs(h.Fragment,{children:[t==null?void 0:t.label,h.jsx(Oi,{type:"source",position:o,isConnectable:r})]})}function eS({data:t,isConnectable:r,targetPosition:o=Se.Top,sourcePosition:s=Se.Bottom}){return h.jsxs(h.Fragment,{children:[h.jsx(Oi,{type:"target",position:o,isConnectable:r}),t==null?void 0:t.label,h.jsx(Oi,{type:"source",position:s,isConnectable:r})]})}function tS(){return null}function nS({data:t,isConnectable:r,targetPosition:o=Se.Top}){return h.jsxs(h.Fragment,{children:[h.jsx(Oi,{type:"target",position:o,isConnectable:r}),t==null?void 0:t.label]})}const _l={ArrowUp:{x:0,y:-1},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0},ArrowRight:{x:1,y:0}},Zh={input:J_,default:eS,output:nS,group:tS};function rS(t){var r,o,s,a;return t.internals.handleBounds===void 0?{width:t.width??t.initialWidth??((r=t.style)==null?void 0:r.width),height:t.height??t.initialHeight??((o=t.style)==null?void 0:o.height)}:{width:t.width??((s=t.style)==null?void 0:s.width),height:t.height??((a=t.style)==null?void 0:a.height)}}const iS=t=>{const{width:r,height:o,x:s,y:a}=Bo(t.nodeLookup,{filter:u=>!!u.selected});return{width:nn(r)?r:null,height:nn(o)?o:null,userSelectionActive:t.userSelectionActive,transformString:`translate(${t.transform[0]}px,${t.transform[1]}px) scale(${t.transform[2]}) translate(${s}px,${a}px)`}};function oS({onSelectionContextMenu:t,noPanClassName:r,disableKeyboardA11y:o}){const s=Ye(),{width:a,height:u,transformString:c,userSelectionActive:f}=ze(iS,Ke),g=Fg(),y=O.useRef(null);O.useEffect(()=>{var S;o||(S=y.current)==null||S.focus({preventScroll:!0})},[o]);const v=!f&&a!==null&&u!==null;if(Og({nodeRef:y,disabled:!v}),!v)return null;const x=t?S=>{const k=s.getState().nodes.filter(j=>j.selected);t(S,k)}:void 0,m=S=>{Object.prototype.hasOwnProperty.call(_l,S.key)&&(S.preventDefault(),g({direction:_l[S.key],factor:S.shiftKey?4:1}))};return h.jsx("div",{className:it(["react-flow__nodesselection","react-flow__container",r]),style:{transform:c},children:h.jsx("div",{ref:y,className:"react-flow__nodesselection-rect",onContextMenu:x,tabIndex:o?void 0:-1,onKeyDown:o?void 0:m,style:{width:a,height:u}})})}const Jh=typeof window<"u"?window:void 0,sS=t=>({nodesSelectionActive:t.nodesSelectionActive,userSelectionActive:t.userSelectionActive});function Vg({children:t,onPaneClick:r,onPaneMouseEnter:o,onPaneMouseMove:s,onPaneMouseLeave:a,onPaneContextMenu:u,onPaneScroll:c,paneClickDistance:f,deleteKeyCode:g,selectionKeyCode:y,selectionOnDrag:v,selectionMode:x,onSelectionStart:m,onSelectionEnd:S,multiSelectionKeyCode:k,panActivationKeyCode:j,zoomActivationKeyCode:b,elementsSelectable:_,zoomOnScroll:P,zoomOnPinch:N,panOnScroll:E,panOnScrollSpeed:L,panOnScrollMode:A,zoomOnDoubleClick:V,panOnDrag:z,autoPanOnSelection:G,defaultViewport:ee,translateExtent:J,minZoom:ne,maxZoom:q,preventScrolling:C,onSelectionContextMenu:W,noWheelClassName:U,noPanClassName:Y,disableKeyboardA11y:T,onViewportChange:F,isControlledViewport:B}){const{nodesSelectionActive:M,userSelectionActive:R}=ze(sS,Ke),re=Do(y,{target:Jh}),ie=Do(j,{target:Jh}),ce=ie||z,fe=ie||E,de=v&&ce!==!0,Q=re||R||de;return D_({deleteKeyCode:g,multiSelectionKeyCode:k}),h.jsx(F_,{onPaneContextMenu:u,elementsSelectable:_,zoomOnScroll:P,zoomOnPinch:N,panOnScroll:fe,panActivationKeyPressed:ie,panOnScrollSpeed:L,panOnScrollMode:A,zoomOnDoubleClick:V,panOnDrag:!re&&ce,defaultViewport:ee,translateExtent:J,minZoom:ne,maxZoom:q,zoomActivationKeyCode:b,preventScrolling:C,noWheelClassName:U,noPanClassName:Y,onViewportChange:F,isControlledViewport:B,paneClickDistance:f,selectionOnDrag:de,children:h.jsxs(W_,{onSelectionStart:m,onSelectionEnd:S,onPaneClick:r,onPaneMouseEnter:o,onPaneMouseMove:s,onPaneMouseLeave:a,onPaneContextMenu:u,onPaneScroll:c,panOnDrag:ce,autoPanOnSelection:G,isSelecting:!!Q,selectionMode:x,selectionKeyPressed:re,paneClickDistance:f,selectionOnDrag:de,children:[t,M&&h.jsx(oS,{onSelectionContextMenu:W,noPanClassName:Y,disableKeyboardA11y:T})]})})}Vg.displayName="FlowRenderer";const lS=O.memo(Vg),aS=t=>r=>t?fc(r.nodeLookup,{x:0,y:0,width:r.width,height:r.height},r.transform,!0).map(o=>o.id):Array.from(r.nodeLookup.keys());function uS(t){return ze(O.useCallback(aS(t),[t]),Ke)}const cS=t=>t.updateNodeInternals;function dS(){const t=ze(cS),[r]=O.useState(()=>typeof ResizeObserver>"u"?null:new ResizeObserver(o=>{const s=new Map;o.forEach(a=>{const u=a.target.getAttribute("data-id");s.set(u,{id:u,nodeElement:a.target,force:!0})}),t(s)}));return O.useEffect(()=>()=>{r==null||r.disconnect()},[r]),r}function fS({node:t,nodeType:r,hasDimensions:o,resizeObserver:s}){const a=Ye(),u=O.useRef(null),c=O.useRef(null),f=O.useRef(t.sourcePosition),g=O.useRef(t.targetPosition),y=O.useRef(r),v=o&&!!t.internals.handleBounds;return O.useEffect(()=>{u.current&&!t.hidden&&(!v||c.current!==u.current)&&(c.current&&(s==null||s.unobserve(c.current)),s==null||s.observe(u.current),c.current=u.current)},[v,t.hidden]),O.useEffect(()=>()=>{c.current&&(s==null||s.unobserve(c.current),c.current=null)},[]),O.useEffect(()=>{if(u.current){const x=y.current!==r,m=f.current!==t.sourcePosition,S=g.current!==t.targetPosition;(x||m||S)&&(y.current=r,f.current=t.sourcePosition,g.current=t.targetPosition,a.getState().updateNodeInternals(new Map([[t.id,{id:t.id,nodeElement:u.current,force:!0}]])))}},[t.id,r,t.sourcePosition,t.targetPosition]),u}function hS({id:t,onClick:r,onMouseEnter:o,onMouseMove:s,onMouseLeave:a,onContextMenu:u,onDoubleClick:c,nodesDraggable:f,elementsSelectable:g,nodesConnectable:y,nodesFocusable:v,resizeObserver:x,noDragClassName:m,noPanClassName:S,disableKeyboardA11y:k,rfId:j,nodeTypes:b,nodeClickDistance:_,onError:P}){const{node:N,internals:E,isParent:L}=ze(Q=>{const le=Q.nodeLookup.get(t),me=Q.parentLookup.has(t);return{node:le,internals:le.internals,isParent:me}},Ke);let A=N.type||"default",V=(b==null?void 0:b[A])||Zh[A];V===void 0&&(P==null||P("003",on.error003(A)),A="default",V=(b==null?void 0:b.default)||Zh.default);const z=!!(N.draggable||f&&typeof N.draggable>"u"),G=!!(N.selectable||g&&typeof N.selectable>"u"),ee=!!(N.connectable||y&&typeof N.connectable>"u"),J=!!(N.focusable||v&&typeof N.focusable>"u"),ne=Ye(),q=cg(N),C=fS({node:N,nodeType:A,hasDimensions:q,resizeObserver:x}),W=Og({nodeRef:C,disabled:N.hidden||!z,noDragClassName:m,handleSelector:N.dragHandle,nodeId:t,isSelectable:G,nodeClickDistance:_}),U=Fg();if(N.hidden)return null;const Y=ln(N),T=rS(N),F=G||z||r||o||s||a,B=o?Q=>o(Q,{...E.userNode}):void 0,M=s?Q=>s(Q,{...E.userNode}):void 0,R=a?Q=>a(Q,{...E.userNode}):void 0,re=u?Q=>u(Q,{...E.userNode}):void 0,ie=c?Q=>c(Q,{...E.userNode}):void 0,ce=Q=>{const{selectNodesOnDrag:le,nodeDragThreshold:me}=ne.getState();G&&(!le||!z||me>0)&&tc({id:t,store:ne,nodeRef:C}),r&&r(Q,{...E.userNode})},fe=Q=>{if(!(hg(Q.nativeEvent)||k)){if(eg.includes(Q.key)&&G){const le=Q.key==="Escape";tc({id:t,store:ne,unselect:le,nodeRef:C})}else if(z&&N.selected&&Object.prototype.hasOwnProperty.call(_l,Q.key)){Q.preventDefault();const{ariaLabelConfig:le}=ne.getState();ne.setState({ariaLiveMessage:le["node.a11yDescription.ariaLiveMessage"]({direction:Q.key.replace("Arrow","").toLowerCase(),x:~~E.positionAbsolute.x,y:~~E.positionAbsolute.y})}),U({direction:_l[Q.key],factor:Q.shiftKey?4:1})}}},de=()=>{var be;if(k||!((be=C.current)!=null&&be.matches(":focus-visible")))return;const{transform:Q,width:le,height:me,autoPanOnNodeFocus:ke,setCenter:xe}=ne.getState();if(!ke)return;fc(new Map([[t,N]]),{x:0,y:0,width:le,height:me},Q,!0).length>0||xe(N.position.x+Y.width/2,N.position.y+Y.height/2,{zoom:Q[2]})};return h.jsx("div",{className:it(["react-flow__node",`react-flow__node-${A}`,{[S]:z},N.className,{selected:N.selected,selectable:G,parent:L,draggable:z,dragging:W}]),ref:C,style:{zIndex:E.z,transform:`translate(${E.positionAbsolute.x}px,${E.positionAbsolute.y}px)`,pointerEvents:F?"all":"none",visibility:q?"visible":"hidden",...N.style,...T},"data-id":t,"data-testid":`rf__node-${t}`,onMouseEnter:B,onMouseMove:M,onMouseLeave:R,onContextMenu:re,onClick:ce,onDoubleClick:ie,onKeyDown:J?fe:void 0,tabIndex:J?0:void 0,onFocus:J?de:void 0,role:N.ariaRole??(J?"group":void 0),"aria-roledescription":"node","aria-describedby":k?void 0:`${Tg}-${j}`,"aria-label":N.ariaLabel,...N.domAttributes,children:h.jsx(Y_,{value:t,children:h.jsx(V,{id:t,data:N.data,type:A,positionAbsoluteX:E.positionAbsolute.x,positionAbsoluteY:E.positionAbsolute.y,selected:N.selected??!1,selectable:G,draggable:z,deletable:N.deletable??!0,isConnectable:ee,sourcePosition:N.sourcePosition,targetPosition:N.targetPosition,dragging:W,dragHandle:N.dragHandle,zIndex:E.z,parentId:N.parentId,...Y})})})}var pS=O.memo(hS);const gS=t=>({nodesConnectable:t.nodesConnectable,nodesFocusable:t.nodesFocusable,elementsSelectable:t.elementsSelectable,onError:t.onError});function Wg(t){const{nodesConnectable:r,nodesFocusable:o,elementsSelectable:s,onError:a}=ze(gS,Ke),u=uS(t.onlyRenderVisibleElements),c=dS();return h.jsx("div",{className:"react-flow__nodes",style:Al,children:u.map(f=>h.jsx(pS,{id:f,nodeTypes:t.nodeTypes,nodeExtent:t.nodeExtent,onClick:t.onNodeClick,onMouseEnter:t.onNodeMouseEnter,onMouseMove:t.onNodeMouseMove,onMouseLeave:t.onNodeMouseLeave,onContextMenu:t.onNodeContextMenu,onDoubleClick:t.onNodeDoubleClick,noDragClassName:t.noDragClassName,noPanClassName:t.noPanClassName,rfId:t.rfId,disableKeyboardA11y:t.disableKeyboardA11y,resizeObserver:c,nodesDraggable:t.nodesDraggable??!0,nodesConnectable:r,nodesFocusable:o,elementsSelectable:s,nodeClickDistance:t.nodeClickDistance,onError:a},f))})}Wg.displayName="NodeRenderer";const mS=O.memo(Wg);function yS(t){return ze(O.useCallback(o=>{if(!t)return o.edges.map(a=>a.id);const s=[];if(o.width&&o.height)for(const a of o.edges){const u=o.nodeLookup.get(a.source),c=o.nodeLookup.get(a.target);u&&c&&c1({sourceNode:u,targetNode:c,width:o.width,height:o.height,transform:o.transform})&&s.push(a.id)}return s},[t]),Ke)}const vS=({color:t="none",strokeWidth:r=1})=>{const o={strokeWidth:r,...t&&{stroke:t}};return h.jsx("polyline",{className:"arrow",style:o,strokeLinecap:"round",fill:"none",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4"})},xS=({color:t="none",strokeWidth:r=1})=>{const o={strokeWidth:r,...t&&{stroke:t,fill:t}};return h.jsx("polyline",{className:"arrowclosed",style:o,strokeLinecap:"round",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4 -5,-4"})},ep={[Lo.Arrow]:vS,[Lo.ArrowClosed]:xS};function wS(t){const r=Ye();return O.useMemo(()=>{var a,u;return Object.prototype.hasOwnProperty.call(ep,t)?ep[t]:((u=(a=r.getState()).onError)==null||u.call(a,"009",on.error009(t)),null)},[t])}const _S=({id:t,type:r,color:o,width:s=12.5,height:a=12.5,markerUnits:u="strokeWidth",strokeWidth:c,orient:f="auto-start-reverse"})=>{const g=wS(r);return g?h.jsx("marker",{className:"react-flow__arrowhead",id:t,markerWidth:`${s}`,markerHeight:`${a}`,viewBox:"-10 -10 20 20",markerUnits:u,orient:f,refX:"0",refY:"0",children:h.jsx(g,{color:o,strokeWidth:c})}):null},Ug=({defaultColor:t,rfId:r})=>{const o=ze(u=>u.edges),s=ze(u=>u.defaultEdgeOptions),a=O.useMemo(()=>v1(o,{id:r,defaultColor:t,defaultMarkerStart:s==null?void 0:s.markerStart,defaultMarkerEnd:s==null?void 0:s.markerEnd}),[o,s,r,t]);return a.length?h.jsx("svg",{className:"react-flow__marker","aria-hidden":"true",children:h.jsx("defs",{children:a.map(u=>h.jsx(_S,{id:u.id,type:u.type,color:u.color,width:u.width,height:u.height,markerUnits:u.markerUnits,strokeWidth:u.strokeWidth,orient:u.orient},u.id))})}):null};Ug.displayName="MarkerDefinitions";var SS=O.memo(Ug);function Yg({x:t,y:r,label:o,labelStyle:s,labelShowBg:a=!0,labelBgStyle:u,labelBgPadding:c=[2,4],labelBgBorderRadius:f=2,children:g,className:y,...v}){const[x,m]=O.useState({x:1,y:0,width:0,height:0}),S=it(["react-flow__edge-textwrapper",y]),k=O.useRef(null);return O.useEffect(()=>{if(k.current){const j=k.current.getBBox();m({x:j.x,y:j.y,width:j.width,height:j.height})}},[o]),o?h.jsxs("g",{transform:`translate(${t-x.width/2} ${r-x.height/2})`,className:S,visibility:x.width?"visible":"hidden",...v,children:[a&&h.jsx("rect",{width:x.width+2*c[0],x:-c[0],y:-c[1],height:x.height+2*c[1],className:"react-flow__edge-textbg",style:u,rx:f,ry:f}),h.jsx("text",{className:"react-flow__edge-text",y:x.height/2,dy:"0.3em",ref:k,style:s,children:o}),g]}):null}Yg.displayName="EdgeText";const kS=O.memo(Yg);function zl({path:t,labelX:r,labelY:o,label:s,labelStyle:a,labelShowBg:u,labelBgStyle:c,labelBgPadding:f,labelBgBorderRadius:g,interactionWidth:y=20,...v}){return h.jsxs(h.Fragment,{children:[h.jsx("path",{...v,d:t,fill:"none",className:it(["react-flow__edge-path",v.className])}),y?h.jsx("path",{d:t,fill:"none",strokeOpacity:0,strokeWidth:y,className:"react-flow__edge-interaction"}):null,s&&nn(r)&&nn(o)?h.jsx(kS,{x:r,y:o,label:s,labelStyle:a,labelShowBg:u,labelBgStyle:c,labelBgPadding:f,labelBgBorderRadius:g}):null]})}function tp({pos:t,x1:r,y1:o,x2:s,y2:a}){return t===Se.Left||t===Se.Right?[.5*(r+s),o]:[r,.5*(o+a)]}function Gg({sourceX:t,sourceY:r,sourcePosition:o=Se.Bottom,targetX:s,targetY:a,targetPosition:u=Se.Top}){const[c,f]=tp({pos:o,x1:t,y1:r,x2:s,y2:a}),[g,y]=tp({pos:u,x1:s,y1:a,x2:t,y2:r}),[v,x,m,S]=gg({sourceX:t,sourceY:r,targetX:s,targetY:a,sourceControlX:c,sourceControlY:f,targetControlX:g,targetControlY:y});return[`M${t},${r} C${c},${f} ${g},${y} ${s},${a}`,v,x,m,S]}function Xg(t){return O.memo(({id:r,sourceX:o,sourceY:s,targetX:a,targetY:u,sourcePosition:c,targetPosition:f,label:g,labelStyle:y,labelShowBg:v,labelBgStyle:x,labelBgPadding:m,labelBgBorderRadius:S,style:k,markerEnd:j,markerStart:b,interactionWidth:_})=>{const[P,N,E]=Gg({sourceX:o,sourceY:s,sourcePosition:c,targetX:a,targetY:u,targetPosition:f}),L=t.isInternal?void 0:r;return h.jsx(zl,{id:L,path:P,labelX:N,labelY:E,label:g,labelStyle:y,labelShowBg:v,labelBgStyle:x,labelBgPadding:m,labelBgBorderRadius:S,style:k,markerEnd:j,markerStart:b,interactionWidth:_})})}const NS=Xg({isInternal:!1}),qg=Xg({isInternal:!0});NS.displayName="SimpleBezierEdge";qg.displayName="SimpleBezierEdgeInternal";function Kg(t){return O.memo(({id:r,sourceX:o,sourceY:s,targetX:a,targetY:u,label:c,labelStyle:f,labelShowBg:g,labelBgStyle:y,labelBgPadding:v,labelBgBorderRadius:x,style:m,sourcePosition:S=Se.Bottom,targetPosition:k=Se.Top,markerEnd:j,markerStart:b,pathOptions:_,interactionWidth:P})=>{const[N,E,L]=Qu({sourceX:o,sourceY:s,sourcePosition:S,targetX:a,targetY:u,targetPosition:k,borderRadius:_==null?void 0:_.borderRadius,offset:_==null?void 0:_.offset,stepPosition:_==null?void 0:_.stepPosition}),A=t.isInternal?void 0:r;return h.jsx(zl,{id:A,path:N,labelX:E,labelY:L,label:c,labelStyle:f,labelShowBg:g,labelBgStyle:y,labelBgPadding:v,labelBgBorderRadius:x,style:m,markerEnd:j,markerStart:b,interactionWidth:P})})}const Qg=Kg({isInternal:!1}),Zg=Kg({isInternal:!0});Qg.displayName="SmoothStepEdge";Zg.displayName="SmoothStepEdgeInternal";function Jg(t){return O.memo(({id:r,...o})=>{var a;const s=t.isInternal?void 0:r;return h.jsx(Qg,{...o,id:s,pathOptions:O.useMemo(()=>{var u;return{borderRadius:0,offset:(u=o.pathOptions)==null?void 0:u.offset}},[(a=o.pathOptions)==null?void 0:a.offset])})})}const ES=Jg({isInternal:!1}),em=Jg({isInternal:!0});ES.displayName="StepEdge";em.displayName="StepEdgeInternal";function tm(t){return O.memo(({id:r,sourceX:o,sourceY:s,targetX:a,targetY:u,label:c,labelStyle:f,labelShowBg:g,labelBgStyle:y,labelBgPadding:v,labelBgBorderRadius:x,style:m,markerEnd:S,markerStart:k,interactionWidth:j})=>{const[b,_,P]=vg({sourceX:o,sourceY:s,targetX:a,targetY:u}),N=t.isInternal?void 0:r;return h.jsx(zl,{id:N,path:b,labelX:_,labelY:P,label:c,labelStyle:f,labelShowBg:g,labelBgStyle:y,labelBgPadding:v,labelBgBorderRadius:x,style:m,markerEnd:S,markerStart:k,interactionWidth:j})})}const jS=tm({isInternal:!1}),nm=tm({isInternal:!0});jS.displayName="StraightEdge";nm.displayName="StraightEdgeInternal";function rm(t){return O.memo(({id:r,sourceX:o,sourceY:s,targetX:a,targetY:u,sourcePosition:c=Se.Bottom,targetPosition:f=Se.Top,label:g,labelStyle:y,labelShowBg:v,labelBgStyle:x,labelBgPadding:m,labelBgBorderRadius:S,style:k,markerEnd:j,markerStart:b,pathOptions:_,interactionWidth:P})=>{const[N,E,L]=mg({sourceX:o,sourceY:s,sourcePosition:c,targetX:a,targetY:u,targetPosition:f,curvature:_==null?void 0:_.curvature}),A=t.isInternal?void 0:r;return h.jsx(zl,{id:A,path:N,labelX:E,labelY:L,label:g,labelStyle:y,labelShowBg:v,labelBgStyle:x,labelBgPadding:m,labelBgBorderRadius:S,style:k,markerEnd:j,markerStart:b,interactionWidth:P})})}const bS=rm({isInternal:!1}),im=rm({isInternal:!0});bS.displayName="BezierEdge";im.displayName="BezierEdgeInternal";const np={default:im,straight:nm,step:em,smoothstep:Zg,simplebezier:qg},rp={sourceX:null,sourceY:null,targetX:null,targetY:null,sourcePosition:null,targetPosition:null,zIndex:void 0},CS=(t,r,o)=>o===Se.Left?t-r:o===Se.Right?t+r:t,MS=(t,r,o)=>o===Se.Top?t-r:o===Se.Bottom?t+r:t,ip="react-flow__edgeupdater";function op({position:t,centerX:r,centerY:o,radius:s=10,onMouseDown:a,onMouseEnter:u,onMouseOut:c,type:f}){return h.jsx("circle",{onMouseDown:a,onMouseEnter:u,onMouseOut:c,className:it([ip,`${ip}-${f}`]),cx:CS(r,s,t),cy:MS(o,s,t),r:s,stroke:"transparent",fill:"transparent"})}function PS({isReconnectable:t,reconnectRadius:r,edge:o,sourceX:s,sourceY:a,targetX:u,targetY:c,sourcePosition:f,targetPosition:g,onReconnect:y,onReconnectStart:v,onReconnectEnd:x,setReconnecting:m,setUpdateHover:S}){const k=Ye(),j=(E,L)=>{if(E.button!==0)return;const{autoPanOnConnect:A,domNode:V,connectionMode:z,connectionRadius:G,lib:ee,onConnectStart:J,cancelConnection:ne,nodeLookup:q,rfId:C,panBy:W,updateConnection:U}=k.getState(),Y=L.type==="target",T=(M,R)=>{m(!1),x==null||x(M,o,L.type,R)},F=M=>y==null?void 0:y(o,M),B=(M,R)=>{m(!0),v==null||v(E,o,L.type),J==null||J(M,R)};ec.onPointerDown(E.nativeEvent,{autoPanOnConnect:A,connectionMode:z,connectionRadius:G,domNode:V,handleId:L.id,nodeId:L.nodeId,nodeLookup:q,isTarget:Y,edgeUpdaterType:L.type,lib:ee,flowId:C,cancelConnection:ne,panBy:W,isValidConnection:(...M)=>{var R,re;return((re=(R=k.getState()).isValidConnection)==null?void 0:re.call(R,...M))??!0},onConnect:F,onConnectStart:B,onConnectEnd:(...M)=>{var R,re;return(re=(R=k.getState()).onConnectEnd)==null?void 0:re.call(R,...M)},onReconnectEnd:T,updateConnection:U,getTransform:()=>k.getState().transform,getFromHandle:()=>k.getState().connection.fromHandle,dragThreshold:k.getState().connectionDragThreshold,handleDomNode:E.currentTarget})},b=E=>j(E,{nodeId:o.target,id:o.targetHandle??null,type:"target"}),_=E=>j(E,{nodeId:o.source,id:o.sourceHandle??null,type:"source"}),P=()=>S(!0),N=()=>S(!1);return h.jsxs(h.Fragment,{children:[(t===!0||t==="source")&&h.jsx(op,{position:f,centerX:s,centerY:a,radius:r,onMouseDown:b,onMouseEnter:P,onMouseOut:N,type:"source"}),(t===!0||t==="target")&&h.jsx(op,{position:g,centerX:u,centerY:c,radius:r,onMouseDown:_,onMouseEnter:P,onMouseOut:N,type:"target"})]})}function IS({id:t,edgesFocusable:r,edgesReconnectable:o,elementsSelectable:s,onClick:a,onDoubleClick:u,onContextMenu:c,onMouseEnter:f,onMouseMove:g,onMouseLeave:y,reconnectRadius:v,onReconnect:x,onReconnectStart:m,onReconnectEnd:S,rfId:k,edgeTypes:j,noPanClassName:b,onError:_,disableKeyboardA11y:P}){let N=ze(xe=>xe.edgeLookup.get(t));const E=ze(xe=>xe.defaultEdgeOptions);N=E?{...E,...N}:N;let L=N.type||"default",A=(j==null?void 0:j[L])||np[L];A===void 0&&(_==null||_("011",on.error011(L)),L="default",A=(j==null?void 0:j.default)||np.default);const V=!!(N.focusable||r&&typeof N.focusable>"u"),z=typeof x<"u"&&(N.reconnectable||o&&typeof N.reconnectable>"u"),G=!!(N.selectable||s&&typeof N.selectable>"u"),ee=O.useRef(null),[J,ne]=O.useState(!1),[q,C]=O.useState(!1),W=Ye(),{zIndex:U=N.zIndex,sourceX:Y,sourceY:T,targetX:F,targetY:B,sourcePosition:M,targetPosition:R}=ze(O.useCallback(xe=>{const pe=xe.nodeLookup.get(N.source),be=xe.nodeLookup.get(N.target);if(!pe||!be)return rp;const Pe=y1({id:t,sourceNode:pe,targetNode:be,sourceHandle:N.sourceHandle||null,targetHandle:N.targetHandle||null,connectionMode:xe.connectionMode,onError:_}),Ce=u1({selected:N.selected,zIndex:N.zIndex,sourceNode:pe,targetNode:be,elevateOnSelect:xe.elevateEdgesOnSelect,zIndexMode:xe.zIndexMode});return{...Pe||rp,zIndex:Ce}},[N.source,N.target,N.sourceHandle,N.targetHandle,N.selected,N.zIndex,_]),Ke),re=O.useMemo(()=>N.markerStart?`url('#${Zu(N.markerStart,k)}')`:void 0,[N.markerStart,k]),ie=O.useMemo(()=>N.markerEnd?`url('#${Zu(N.markerEnd,k)}')`:void 0,[N.markerEnd,k]);if(N.hidden||Y===null||T===null||F===null||B===null)return null;const ce=xe=>{var Ce;const{addSelectedEdges:pe,unselectNodesAndEdges:be,multiSelectionActive:Pe}=W.getState();G&&(W.setState({nodesSelectionActive:!1}),N.selected&&Pe?(be({nodes:[],edges:[N]}),(Ce=ee.current)==null||Ce.blur()):pe([t])),a&&a(xe,N)},fe=u?xe=>{u(xe,{...N})}:void 0,de=c?xe=>{c(xe,{...N})}:void 0,Q=f?xe=>{f(xe,{...N})}:void 0,le=g?xe=>{g(xe,{...N})}:void 0,me=y?xe=>{y(xe,{...N})}:void 0,ke=xe=>{var pe;if(!P&&eg.includes(xe.key)&&G){const{unselectNodesAndEdges:be,addSelectedEdges:Pe}=W.getState();xe.key==="Escape"?((pe=ee.current)==null||pe.blur(),be({edges:[N]})):Pe([t])}};return h.jsx("svg",{style:{zIndex:U},children:h.jsxs("g",{className:it(["react-flow__edge",`react-flow__edge-${L}`,N.className,b,{selected:N.selected,animated:N.animated,inactive:!G&&!a,updating:J,selectable:G}]),onClick:ce,onDoubleClick:fe,onContextMenu:de,onMouseEnter:Q,onMouseMove:le,onMouseLeave:me,onKeyDown:V?ke:void 0,tabIndex:V?0:void 0,role:N.ariaRole??(V?"group":"img"),"aria-roledescription":"edge","data-id":t,"data-testid":`rf__edge-${t}`,"aria-label":N.ariaLabel===null?void 0:N.ariaLabel||`Edge from ${N.source} to ${N.target}`,"aria-describedby":V?`${Rg}-${k}`:void 0,ref:ee,...N.domAttributes,children:[!q&&h.jsx(A,{id:t,source:N.source,target:N.target,type:N.type,selected:N.selected,animated:N.animated,selectable:G,deletable:N.deletable??!0,label:N.label,labelStyle:N.labelStyle,labelShowBg:N.labelShowBg,labelBgStyle:N.labelBgStyle,labelBgPadding:N.labelBgPadding,labelBgBorderRadius:N.labelBgBorderRadius,sourceX:Y,sourceY:T,targetX:F,targetY:B,sourcePosition:M,targetPosition:R,data:N.data,style:N.style,sourceHandleId:N.sourceHandle,targetHandleId:N.targetHandle,markerStart:re,markerEnd:ie,pathOptions:"pathOptions"in N?N.pathOptions:void 0,interactionWidth:N.interactionWidth}),z&&h.jsx(PS,{edge:N,isReconnectable:z,reconnectRadius:v,onReconnect:x,onReconnectStart:m,onReconnectEnd:S,sourceX:Y,sourceY:T,targetX:F,targetY:B,sourcePosition:M,targetPosition:R,setUpdateHover:ne,setReconnecting:C})]})})}var TS=O.memo(IS);const RS=t=>({edgesFocusable:t.edgesFocusable,edgesReconnectable:t.edgesReconnectable,elementsSelectable:t.elementsSelectable,connectionMode:t.connectionMode,onError:t.onError});function om({defaultMarkerColor:t,onlyRenderVisibleElements:r,rfId:o,edgeTypes:s,noPanClassName:a,onReconnect:u,onEdgeContextMenu:c,onEdgeMouseEnter:f,onEdgeMouseMove:g,onEdgeMouseLeave:y,onEdgeClick:v,reconnectRadius:x,onEdgeDoubleClick:m,onReconnectStart:S,onReconnectEnd:k,disableKeyboardA11y:j}){const{edgesFocusable:b,edgesReconnectable:_,elementsSelectable:P,onError:N}=ze(RS,Ke),E=yS(r);return h.jsxs("div",{className:"react-flow__edges",children:[h.jsx(SS,{defaultColor:t,rfId:o}),E.map(L=>h.jsx(TS,{id:L,edgesFocusable:b,edgesReconnectable:_,elementsSelectable:P,noPanClassName:a,onReconnect:u,onContextMenu:c,onMouseEnter:f,onMouseMove:g,onMouseLeave:y,onClick:v,reconnectRadius:x,onDoubleClick:m,onReconnectStart:S,onReconnectEnd:k,rfId:o,onError:N,edgeTypes:s,disableKeyboardA11y:j},L))]})}om.displayName="EdgeRenderer";const LS=O.memo(om),sp=t=>`translate(${t[0]}px,${t[1]}px) scale(${t[2]})`;function AS({children:t}){const r=Ye(),o=O.useRef(null),[s]=O.useState(()=>r.getState().transform);return Dg(()=>{let a=null;const u=()=>{const c=r.getState().transform;a&&c[0]===a[0]&&c[1]===a[1]&&c[2]===a[2]||(a=c,o.current&&(o.current.style.transform=sp(c)))};return u(),r.subscribe(u)},[r]),h.jsx("div",{ref:o,className:"react-flow__viewport xyflow__viewport react-flow__container",style:{transform:sp(s)},children:t})}function zS(t){const r=Ll(),o=O.useRef(!1);O.useEffect(()=>{!o.current&&r.viewportInitialized&&t&&(setTimeout(()=>t(r),1),o.current=!0)},[t,r.viewportInitialized])}const DS=t=>{var r;return(r=t.panZoom)==null?void 0:r.syncViewport};function $S(t){const r=ze(DS),o=Ye();return O.useEffect(()=>{t&&(r==null||r(t),o.setState({transform:[t.x,t.y,t.zoom]}))},[t,r]),null}function OS(t){return t.connection.inProgress?{...t.connection,to:Wo(t.connection.to,t.transform)}:{...t.connection}}function FS(t){return OS}function HS(t){const r=FS();return ze(r,Ke)}const BS=t=>({nodesConnectable:t.nodesConnectable,isValid:t.connection.isValid,inProgress:t.connection.inProgress,width:t.width,height:t.height});function VS({containerStyle:t,style:r,type:o,component:s}){const{nodesConnectable:a,width:u,height:c,isValid:f,inProgress:g}=ze(BS,Ke);return!(u&&a&&g)?null:h.jsx("svg",{style:t,width:u,height:c,className:"react-flow__connectionline react-flow__container",children:h.jsx("g",{className:it(["react-flow__connection",rg(f)]),children:h.jsx(sm,{style:r,type:o,CustomComponent:s,isValid:f})})})}const sm=({style:t,type:r=hr.Bezier,CustomComponent:o,isValid:s})=>{const{inProgress:a,from:u,fromNode:c,fromHandle:f,fromPosition:g,to:y,toNode:v,toHandle:x,toPosition:m,pointer:S}=HS();if(!a)return;if(o)return h.jsx(o,{connectionLineType:r,connectionLineStyle:t,fromNode:c,fromHandle:f,fromX:u.x,fromY:u.y,toX:y.x,toY:y.y,fromPosition:g,toPosition:m,connectionStatus:rg(s),toNode:v,toHandle:x,pointer:S});let k="";const j={sourceX:u.x,sourceY:u.y,sourcePosition:g,targetX:y.x,targetY:y.y,targetPosition:m};switch(r){case hr.Bezier:[k]=mg(j);break;case hr.SimpleBezier:[k]=Gg(j);break;case hr.Step:[k]=Qu({...j,borderRadius:0});break;case hr.SmoothStep:[k]=Qu(j);break;default:[k]=vg(j)}return h.jsx("path",{d:k,fill:"none",className:"react-flow__connection-path",style:t})};sm.displayName="ConnectionLine";const WS={};function lp(t=WS){O.useRef(t),Ye(),O.useEffect(()=>{},[t])}function US(){Ye(),O.useRef(!1),O.useEffect(()=>{},[])}function lm({nodeTypes:t,edgeTypes:r,onInit:o,onNodeClick:s,onEdgeClick:a,onNodeDoubleClick:u,onEdgeDoubleClick:c,onNodeMouseEnter:f,onNodeMouseMove:g,onNodeMouseLeave:y,onNodeContextMenu:v,onSelectionContextMenu:x,onSelectionStart:m,onSelectionEnd:S,connectionLineType:k,connectionLineStyle:j,connectionLineComponent:b,connectionLineContainerStyle:_,selectionKeyCode:P,selectionOnDrag:N,selectionMode:E,multiSelectionKeyCode:L,panActivationKeyCode:A,zoomActivationKeyCode:V,deleteKeyCode:z,onlyRenderVisibleElements:G,elementsSelectable:ee,defaultViewport:J,translateExtent:ne,minZoom:q,maxZoom:C,preventScrolling:W,defaultMarkerColor:U,zoomOnScroll:Y,zoomOnPinch:T,panOnScroll:F,panOnScrollSpeed:B,panOnScrollMode:M,zoomOnDoubleClick:R,panOnDrag:re,autoPanOnSelection:ie,onPaneClick:ce,onPaneMouseEnter:fe,onPaneMouseMove:de,onPaneMouseLeave:Q,onPaneScroll:le,onPaneContextMenu:me,paneClickDistance:ke,nodeClickDistance:xe,onEdgeContextMenu:pe,onEdgeMouseEnter:be,onEdgeMouseMove:Pe,onEdgeMouseLeave:Ce,reconnectRadius:Re,onReconnect:tt,onReconnectStart:nt,onReconnectEnd:Je,noDragClassName:Qe,noWheelClassName:ot,noPanClassName:Pt,disableKeyboardA11y:st,nodeExtent:ft,rfId:He,viewport:Le,onViewportChange:mt,nodesDraggable:an}){return lp(t),lp(r),US(),zS(o),$S(Le),h.jsx(lS,{onPaneClick:ce,onPaneMouseEnter:fe,onPaneMouseMove:de,onPaneMouseLeave:Q,onPaneContextMenu:me,onPaneScroll:le,paneClickDistance:ke,deleteKeyCode:z,selectionKeyCode:P,selectionOnDrag:N,selectionMode:E,onSelectionStart:m,onSelectionEnd:S,multiSelectionKeyCode:L,panActivationKeyCode:A,zoomActivationKeyCode:V,elementsSelectable:ee,zoomOnScroll:Y,zoomOnPinch:T,zoomOnDoubleClick:R,panOnScroll:F,panOnScrollSpeed:B,panOnScrollMode:M,panOnDrag:re,autoPanOnSelection:ie,defaultViewport:J,translateExtent:ne,minZoom:q,maxZoom:C,onSelectionContextMenu:x,preventScrolling:W,noDragClassName:Qe,noWheelClassName:ot,noPanClassName:Pt,disableKeyboardA11y:st,onViewportChange:mt,isControlledViewport:!!Le,children:h.jsxs(AS,{children:[h.jsx(LS,{edgeTypes:r,onEdgeClick:a,onEdgeDoubleClick:c,onReconnect:tt,onReconnectStart:nt,onReconnectEnd:Je,onlyRenderVisibleElements:G,onEdgeContextMenu:pe,onEdgeMouseEnter:be,onEdgeMouseMove:Pe,onEdgeMouseLeave:Ce,reconnectRadius:Re,defaultMarkerColor:U,noPanClassName:Pt,disableKeyboardA11y:st,rfId:He}),h.jsx(VS,{style:j,type:k,component:b,containerStyle:_}),h.jsx("div",{className:"react-flow__edgelabel-renderer"}),h.jsx(mS,{nodeTypes:t,onNodeClick:s,onNodeDoubleClick:u,onNodeMouseEnter:f,onNodeMouseMove:g,onNodeMouseLeave:y,onNodeContextMenu:v,nodeClickDistance:xe,onlyRenderVisibleElements:G,noPanClassName:Pt,noDragClassName:Qe,disableKeyboardA11y:st,nodeExtent:ft,rfId:He,nodesDraggable:an}),h.jsx("div",{className:"react-flow__viewport-portal"})]})})}lm.displayName="GraphView";const YS=O.memo(lm),GS=ug(),ap=({nodes:t,edges:r,defaultNodes:o,defaultEdges:s,width:a,height:u,fitView:c,fitViewOptions:f,minZoom:g=.5,maxZoom:y=2,nodeOrigin:v,nodeExtent:x,zIndexMode:m="basic"}={})=>{const S=new Map,k=new Map,j=new Map,b=new Map,_=s??r??[],P=o??t??[],N=v??[0,0],E=x??To;_g(j,b,_);const{nodesInitialized:L}=Ju(P,S,k,{nodeOrigin:N,nodeExtent:E,zIndexMode:m});let A=[0,0,1];if(c&&a&&u){const V=Bo(S,{filter:J=>!!((J.width||J.initialWidth)&&(J.height||J.initialHeight))}),{x:z,y:G,zoom:ee}=pc(V,a,u,g,y,(f==null?void 0:f.padding)??.1);A=[z,G,ee]}return{rfId:"1",width:a??0,height:u??0,transform:A,nodes:P,nodesInitialized:L,nodeLookup:S,parentLookup:k,edges:_,edgeLookup:b,connectionLookup:j,onNodesChange:null,onEdgesChange:null,hasDefaultNodes:o!==void 0,hasDefaultEdges:s!==void 0,panZoom:null,minZoom:g,maxZoom:y,translateExtent:To,nodeExtent:E,nodesSelectionActive:!1,userSelectionActive:!1,userSelectionRect:null,connectionMode:Ai.Strict,domNode:null,paneDragging:!1,noPanClassName:"nopan",nodeOrigin:N,nodeDragThreshold:1,connectionDragThreshold:1,snapGrid:[15,15],snapToGrid:!1,nodesDraggable:!0,nodesConnectable:!0,nodesFocusable:!0,edgesFocusable:!0,edgesReconnectable:!0,elementsSelectable:!0,elevateNodesOnSelect:!0,elevateEdgesOnSelect:!0,selectNodesOnDrag:!0,multiSelectionActive:!1,fitViewQueued:c??!1,fitViewOptions:f,fitViewResolver:null,connection:{...ng},connectionClickStartHandle:null,connectOnClick:!0,ariaLiveMessage:"",autoPanOnConnect:!0,autoPanOnNodeDrag:!0,autoPanOnNodeFocus:!0,autoPanSpeed:15,connectionRadius:20,onError:GS,isValidConnection:void 0,onSelectionChangeHandlers:[],lib:"react",debug:!1,ariaLabelConfig:tg,zIndexMode:m,onNodesChangeMiddlewareMap:new Map,onEdgesChangeMiddlewareMap:new Map}},XS=({nodes:t,edges:r,defaultNodes:o,defaultEdges:s,width:a,height:u,fitView:c,fitViewOptions:f,minZoom:g,maxZoom:y,nodeOrigin:v,nodeExtent:x,zIndexMode:m})=>s_((S,k)=>{async function j(){const{nodeLookup:b,panZoom:_,fitViewOptions:P,fitViewResolver:N,width:E,height:L,minZoom:A,maxZoom:V}=k();_&&(await n1({nodes:b,width:E,height:L,panZoom:_,minZoom:A,maxZoom:V},P),N==null||N.resolve(!0),S({fitViewResolver:null}))}return{...ap({nodes:t,edges:r,width:a,height:u,fitView:c,fitViewOptions:f,minZoom:g,maxZoom:y,nodeOrigin:v,nodeExtent:x,defaultNodes:o,defaultEdges:s,zIndexMode:m}),setNodes:b=>{const{nodeLookup:_,parentLookup:P,nodeOrigin:N,nodeExtent:E,elevateNodesOnSelect:L,fitViewQueued:A,zIndexMode:V,nodesSelectionActive:z}=k(),{nodesInitialized:G,hasSelectedNodes:ee}=Ju(b,_,P,{nodeOrigin:N,nodeExtent:E,elevateNodesOnSelect:L,checkEquality:!0,zIndexMode:V}),J=z&ⅇA&&G?(j(),S({nodes:b,nodesInitialized:G,fitViewQueued:!1,fitViewOptions:void 0,nodesSelectionActive:J})):S({nodes:b,nodesInitialized:G,nodesSelectionActive:J})},setEdges:b=>{const{connectionLookup:_,edgeLookup:P}=k();_g(_,P,b),S({edges:b})},setDefaultNodesAndEdges:(b,_)=>{if(b){const{setNodes:P}=k();P(b),S({hasDefaultNodes:!0})}if(_){const{setEdges:P}=k();P(_),S({hasDefaultEdges:!0})}},updateNodeInternals:b=>{const{triggerNodeChanges:_,nodeLookup:P,parentLookup:N,domNode:E,nodeOrigin:L,nodeExtent:A,debug:V,fitViewQueued:z,zIndexMode:G}=k(),{changes:ee,updatedInternals:J}=E1(b,P,N,E,L,A,G);J&&(_1(P,N,{nodeOrigin:L,nodeExtent:A,zIndexMode:G}),z?(j(),S({fitViewQueued:!1,fitViewOptions:void 0})):S({}),(ee==null?void 0:ee.length)>0&&(V&&console.log("React Flow: trigger node changes",ee),_==null||_(ee)))},updateNodePositions:(b,_=!1)=>{const P=[];let N=[];const{nodeLookup:E,triggerNodeChanges:L,connection:A,updateConnection:V,onNodesChangeMiddlewareMap:z}=k();for(const[G,ee]of b){const J=E.get(G),ne=!!(J!=null&&J.expandParent&&(J!=null&&J.parentId)&&(ee!=null&&ee.position)),q={id:G,type:"position",position:ne?{x:Math.max(0,ee.position.x),y:Math.max(0,ee.position.y)}:ee.position,dragging:_};if(J&&A.inProgress&&A.fromNode.id===J.id){const C=Ur(J,A.fromHandle,Se.Left,!0);V({...A,from:C})}ne&&J.parentId&&P.push({id:G,parentId:J.parentId,rect:{...ee.internals.positionAbsolute,width:ee.measured.width??0,height:ee.measured.height??0}}),N.push(q)}if(P.length>0){const{parentLookup:G,nodeOrigin:ee}=k(),J=wc(P,E,G,ee);N.push(...J)}for(const G of z.values())N=G(N);L(N)},triggerNodeChanges:b=>{const{onNodesChange:_,setNodes:P,nodes:N,hasDefaultNodes:E,debug:L}=k();if(b!=null&&b.length){if(E){const A=b_(b,N);P(A)}L&&console.log("React Flow: trigger node changes",b),_==null||_(b)}},triggerEdgeChanges:b=>{const{onEdgesChange:_,setEdges:P,edges:N,hasDefaultEdges:E,debug:L}=k();if(b!=null&&b.length){if(E){const A=C_(b,N);P(A)}L&&console.log("React Flow: trigger edge changes",b),_==null||_(b)}},addSelectedNodes:b=>{const{multiSelectionActive:_,edgeLookup:P,nodeLookup:N,triggerNodeChanges:E,triggerEdgeChanges:L}=k();if(_){const A=b.map(V=>zr(V,!0));E(A);return}E(Pi(N,new Set([...b]),!0)),L(Pi(P))},addSelectedEdges:b=>{const{multiSelectionActive:_,edgeLookup:P,nodeLookup:N,triggerNodeChanges:E,triggerEdgeChanges:L}=k();if(_){const A=b.map(V=>zr(V,!0));L(A);return}L(Pi(P,new Set([...b]))),E(Pi(N,new Set,!0))},unselectNodesAndEdges:({nodes:b,edges:_}={})=>{const{edges:P,nodes:N,nodeLookup:E,triggerNodeChanges:L,triggerEdgeChanges:A}=k(),V=b||N,z=_||P,G=[];for(const J of V){if(!J.selected)continue;const ne=E.get(J.id);ne&&(ne.selected=!1),G.push(zr(J.id,!1))}const ee=[];for(const J of z)J.selected&&ee.push(zr(J.id,!1));L(G),A(ee)},setMinZoom:b=>{const{panZoom:_,maxZoom:P}=k();_==null||_.setScaleExtent([b,P]),S({minZoom:b})},setMaxZoom:b=>{const{panZoom:_,minZoom:P}=k();_==null||_.setScaleExtent([P,b]),S({maxZoom:b})},setTranslateExtent:b=>{var _;(_=k().panZoom)==null||_.setTranslateExtent(b),S({translateExtent:b})},resetSelectedElements:()=>{const{edges:b,nodes:_,triggerNodeChanges:P,triggerEdgeChanges:N,elementsSelectable:E}=k();if(!E)return;const L=_.reduce((V,z)=>z.selected?[...V,zr(z.id,!1)]:V,[]),A=b.reduce((V,z)=>z.selected?[...V,zr(z.id,!1)]:V,[]);P(L),N(A)},setNodeExtent:b=>{const{nodes:_,nodeLookup:P,parentLookup:N,nodeOrigin:E,elevateNodesOnSelect:L,nodeExtent:A,zIndexMode:V}=k();b[0][0]===A[0][0]&&b[0][1]===A[0][1]&&b[1][0]===A[1][0]&&b[1][1]===A[1][1]||(Ju(_,P,N,{nodeOrigin:E,nodeExtent:b,elevateNodesOnSelect:L,checkEquality:!1,zIndexMode:V}),S({nodeExtent:b}))},panBy:b=>{const{transform:_,width:P,height:N,panZoom:E,translateExtent:L}=k();return j1({delta:b,panZoom:E,transform:_,translateExtent:L,width:P,height:N})},setCenter:async(b,_,P)=>{const{width:N,height:E,maxZoom:L,panZoom:A}=k();if(!A)return!1;const V=typeof(P==null?void 0:P.zoom)<"u"?P.zoom:L;return await A.setViewport({x:N/2-b*V,y:E/2-_*V,zoom:V},{duration:P==null?void 0:P.duration,ease:P==null?void 0:P.ease,interpolate:P==null?void 0:P.interpolate}),!0},cancelConnection:()=>{S({connection:{...ng}})},updateConnection:b=>{S({connection:b})},reset:()=>S({...ap()})}},Object.is);function am({initialNodes:t,initialEdges:r,defaultNodes:o,defaultEdges:s,initialWidth:a,initialHeight:u,initialMinZoom:c,initialMaxZoom:f,initialFitViewOptions:g,fitView:y,nodeOrigin:v,nodeExtent:x,zIndexMode:m,children:S}){const[k]=O.useState(()=>XS({nodes:t,edges:r,defaultNodes:o,defaultEdges:s,width:a,height:u,fitView:y,minZoom:c,maxZoom:f,fitViewOptions:g,nodeOrigin:v,nodeExtent:x,zIndexMode:m}));return h.jsx(l_,{value:k,children:h.jsx(R_,{children:h.jsx(X_,{children:S})})})}function qS({children:t,nodes:r,edges:o,defaultNodes:s,defaultEdges:a,width:u,height:c,fitView:f,fitViewOptions:g,minZoom:y,maxZoom:v,nodeOrigin:x,nodeExtent:m,zIndexMode:S}){return O.useContext(Tl)?h.jsx(h.Fragment,{children:t}):h.jsx(am,{initialNodes:r,initialEdges:o,defaultNodes:s,defaultEdges:a,initialWidth:u,initialHeight:c,fitView:f,initialFitViewOptions:g,initialMinZoom:y,initialMaxZoom:v,nodeOrigin:x,nodeExtent:m,zIndexMode:S,children:t})}const KS={width:"100%",height:"100%",overflow:"hidden",position:"relative",zIndex:0};function QS({nodes:t,edges:r,defaultNodes:o,defaultEdges:s,className:a,nodeTypes:u,edgeTypes:c,onNodeClick:f,onEdgeClick:g,onInit:y,onMove:v,onMoveStart:x,onMoveEnd:m,onConnect:S,onConnectStart:k,onConnectEnd:j,onClickConnectStart:b,onClickConnectEnd:_,onNodeMouseEnter:P,onNodeMouseMove:N,onNodeMouseLeave:E,onNodeContextMenu:L,onNodeDoubleClick:A,onNodeDragStart:V,onNodeDrag:z,onNodeDragStop:G,onNodesDelete:ee,onEdgesDelete:J,onDelete:ne,onSelectionChange:q,onSelectionDragStart:C,onSelectionDrag:W,onSelectionDragStop:U,onSelectionContextMenu:Y,onSelectionStart:T,onSelectionEnd:F,onBeforeDelete:B,connectionMode:M,connectionLineType:R=hr.Bezier,connectionLineStyle:re,connectionLineComponent:ie,connectionLineContainerStyle:ce,deleteKeyCode:fe="Backspace",selectionKeyCode:de="Shift",selectionOnDrag:Q=!1,selectionMode:le=Ro.Full,panActivationKeyCode:me="Space",multiSelectionKeyCode:ke=zo()?"Meta":"Control",zoomActivationKeyCode:xe=zo()?"Meta":"Control",snapToGrid:pe,snapGrid:be,onlyRenderVisibleElements:Pe=!1,selectNodesOnDrag:Ce,nodesDraggable:Re,autoPanOnNodeFocus:tt,nodesConnectable:nt,nodesFocusable:Je,nodeOrigin:Qe=Lg,edgesFocusable:ot,edgesReconnectable:Pt,elementsSelectable:st=!0,defaultViewport:ft=w_,minZoom:He=.5,maxZoom:Le=2,translateExtent:mt=To,preventScrolling:an=!0,nodeExtent:ht,defaultMarkerColor:Gt="#b1b1b7",zoomOnScroll:_n=!0,zoomOnPinch:zn=!0,panOnScroll:Gr=!1,panOnScrollSpeed:It=.5,panOnScrollMode:Sn=Fr.Free,zoomOnDoubleClick:Dn=!0,panOnDrag:un=!0,onPaneClick:$n,onPaneMouseEnter:gr,onPaneMouseMove:cn,onPaneMouseLeave:dn,onPaneScroll:Xr,onPaneContextMenu:qr,paneClickDistance:Kr=1,nodeClickDistance:Qr=0,children:On,onReconnect:mr,onReconnectStart:Fn,onReconnectEnd:kn,onEdgeContextMenu:yr,onEdgeDoubleClick:fn,onEdgeMouseEnter:vr,onEdgeMouseMove:hn,onEdgeMouseLeave:Hn,reconnectRadius:Bn=10,onNodesChange:xr,onEdgesChange:Zr,noDragClassName:Jr="nodrag",noWheelClassName:ei="nowheel",noPanClassName:Tt="nopan",fitView:Vn,fitViewOptions:Wn,connectOnClick:ti,attributionPosition:wr,proOptions:D,defaultEdgeOptions:te,elevateNodesOnSelect:_e=!0,elevateEdgesOnSelect:Ie=!1,disableKeyboardA11y:Me=!1,autoPanOnConnect:Fe,autoPanOnNodeDrag:$l,autoPanOnSelection:Fi=!0,autoPanSpeed:Uo,connectionRadius:ni,isValidConnection:Ol,onError:Yo,style:ri,id:Rt,nodeDragThreshold:Fl,connectionDragThreshold:Lt,viewport:Hl,onViewportChange:Bl,width:Vl,height:ii,colorMode:oi="light",debug:_r,onScroll:Nn,ariaLabelConfig:Wl,zIndexMode:Go="basic",...Hi},Xo){const Sr=Rt||"1",kr=N_(oi),Ul=O.useCallback(si=>{si.currentTarget.scrollTo({top:0,left:0,behavior:"instant"}),Nn==null||Nn(si)},[Nn]);return h.jsx("div",{"data-testid":"rf__wrapper",...Hi,onScroll:Ul,style:{...ri,...KS},ref:Xo,className:it(["react-flow",a,kr]),id:Rt,role:"application",children:h.jsxs(qS,{nodes:t,edges:r,width:Vl,height:ii,fitView:Vn,fitViewOptions:Wn,minZoom:He,maxZoom:Le,nodeOrigin:Qe,nodeExtent:ht,zIndexMode:Go,children:[h.jsx(k_,{nodes:t,edges:r,defaultNodes:o,defaultEdges:s,onConnect:S,onConnectStart:k,onConnectEnd:j,onClickConnectStart:b,onClickConnectEnd:_,nodesDraggable:Re,autoPanOnNodeFocus:tt,nodesConnectable:nt,nodesFocusable:Je,edgesFocusable:ot,edgesReconnectable:Pt,elementsSelectable:st,elevateNodesOnSelect:_e,elevateEdgesOnSelect:Ie,minZoom:He,maxZoom:Le,nodeExtent:ht,onNodesChange:xr,onEdgesChange:Zr,snapToGrid:pe,snapGrid:be,connectionMode:M,translateExtent:mt,connectOnClick:ti,defaultEdgeOptions:te,fitView:Vn,fitViewOptions:Wn,onNodesDelete:ee,onEdgesDelete:J,onDelete:ne,onNodeDragStart:V,onNodeDrag:z,onNodeDragStop:G,onSelectionDrag:W,onSelectionDragStart:C,onSelectionDragStop:U,onMove:v,onMoveStart:x,onMoveEnd:m,noPanClassName:Tt,nodeOrigin:Qe,rfId:Sr,autoPanOnConnect:Fe,autoPanOnNodeDrag:$l,autoPanSpeed:Uo,onError:Yo,connectionRadius:ni,isValidConnection:Ol,selectNodesOnDrag:Ce,nodeDragThreshold:Fl,connectionDragThreshold:Lt,onBeforeDelete:B,debug:_r,ariaLabelConfig:Wl,zIndexMode:Go}),h.jsx(YS,{onInit:y,onNodeClick:f,onEdgeClick:g,onNodeMouseEnter:P,onNodeMouseMove:N,onNodeMouseLeave:E,onNodeContextMenu:L,onNodeDoubleClick:A,nodeTypes:u,edgeTypes:c,connectionLineType:R,connectionLineStyle:re,connectionLineComponent:ie,connectionLineContainerStyle:ce,selectionKeyCode:de,selectionOnDrag:Q,selectionMode:le,deleteKeyCode:fe,multiSelectionKeyCode:ke,panActivationKeyCode:me,zoomActivationKeyCode:xe,onlyRenderVisibleElements:Pe,defaultViewport:ft,translateExtent:mt,minZoom:He,maxZoom:Le,preventScrolling:an,zoomOnScroll:_n,zoomOnPinch:zn,zoomOnDoubleClick:Dn,panOnScroll:Gr,panOnScrollSpeed:It,panOnScrollMode:Sn,panOnDrag:un,autoPanOnSelection:Fi,onPaneClick:$n,onPaneMouseEnter:gr,onPaneMouseMove:cn,onPaneMouseLeave:dn,onPaneScroll:Xr,onPaneContextMenu:qr,paneClickDistance:Kr,nodeClickDistance:Qr,onSelectionContextMenu:Y,onSelectionStart:T,onSelectionEnd:F,onReconnect:mr,onReconnectStart:Fn,onReconnectEnd:kn,onEdgeContextMenu:yr,onEdgeDoubleClick:fn,onEdgeMouseEnter:vr,onEdgeMouseMove:hn,onEdgeMouseLeave:Hn,reconnectRadius:Bn,defaultMarkerColor:Gt,noDragClassName:Jr,noWheelClassName:ei,noPanClassName:Tt,rfId:Sr,disableKeyboardA11y:Me,nodeExtent:ht,viewport:Hl,onViewportChange:Bl,nodesDraggable:Re}),h.jsx(x_,{onSelectionChange:q}),On,h.jsx(p_,{proOptions:D,position:wr}),h.jsx(h_,{rfId:Sr,disableKeyboardA11y:Me})]})})}var ZS=zg(QS);function JS({dimensions:t,lineWidth:r,variant:o,className:s}){return h.jsx("path",{strokeWidth:r,d:`M${t[0]/2} 0 V${t[1]} M0 ${t[1]/2} H${t[0]}`,className:it(["react-flow__background-pattern",o,s])})}function ek({radius:t,className:r}){return h.jsx("circle",{cx:t,cy:t,r:t,className:it(["react-flow__background-pattern","dots",r])})}var pr;(function(t){t.Lines="lines",t.Dots="dots",t.Cross="cross"})(pr||(pr={}));const tk={[pr.Dots]:1,[pr.Lines]:1,[pr.Cross]:6},nk=t=>({transform:t.transform,patternId:`pattern-${t.rfId}`});function um({id:t,variant:r=pr.Dots,gap:o=20,size:s,lineWidth:a=1,offset:u=0,color:c,bgColor:f,style:g,className:y,patternClassName:v}){const x=O.useRef(null),{transform:m,patternId:S}=ze(nk,Ke),k=s||tk[r],j=r===pr.Dots,b=r===pr.Cross,_=Array.isArray(o)?o:[o,o],P=[_[0]*m[2]||1,_[1]*m[2]||1],N=k*m[2],E=Array.isArray(u)?u:[u,u],L=b?[N,N]:P,A=[E[0]*m[2]+L[0]/2,E[1]*m[2]+L[1]/2],V=`${S}${t||""}`;return h.jsxs("svg",{className:it(["react-flow__background",y]),style:{...g,...Al,"--xy-background-color-props":f,"--xy-background-pattern-color-props":c},ref:x,"data-testid":"rf__background",children:[h.jsx("pattern",{id:V,x:m[0]%P[0],y:m[1]%P[1],width:P[0],height:P[1],patternUnits:"userSpaceOnUse",patternTransform:`translate(-${A[0]},-${A[1]})`,children:j?h.jsx(ek,{radius:N/2,className:v}):h.jsx(JS,{dimensions:L,lineWidth:a,variant:r,className:v})}),h.jsx("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:`url(#${V})`})]})}um.displayName="Background";const rk=O.memo(um);function ik(){return h.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32",children:h.jsx("path",{d:"M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z"})})}function ok(){return h.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 5",children:h.jsx("path",{d:"M0 0h32v4.2H0z"})})}function sk(){return h.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 30",children:h.jsx("path",{d:"M3.692 4.63c0-.53.4-.938.939-.938h5.215V0H4.708C2.13 0 0 2.054 0 4.63v5.216h3.692V4.631zM27.354 0h-5.2v3.692h5.17c.53 0 .984.4.984.939v5.215H32V4.631A4.624 4.624 0 0027.354 0zm.954 24.83c0 .532-.4.94-.939.94h-5.215v3.768h5.215c2.577 0 4.631-2.13 4.631-4.707v-5.139h-3.692v5.139zm-23.677.94c-.531 0-.939-.4-.939-.94v-5.138H0v5.139c0 2.577 2.13 4.707 4.708 4.707h5.138V25.77H4.631z"})})}function lk(){return h.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:h.jsx("path",{d:"M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0 8 0 4.571 3.429 4.571 7.619v3.048H3.048A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047zm4.724-13.866H7.467V7.619c0-2.59 2.133-4.724 4.723-4.724 2.591 0 4.724 2.133 4.724 4.724v3.048z"})})}function ak(){return h.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:h.jsx("path",{d:"M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0c-4.114 1.828-1.37 2.133.305 2.438 1.676.305 4.42 2.59 4.42 5.181v3.048H3.047A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047z"})})}function il({children:t,className:r,...o}){return h.jsx("button",{type:"button",className:it(["react-flow__controls-button",r]),...o,children:t})}const uk=t=>({isInteractive:t.nodesDraggable||t.nodesConnectable||t.elementsSelectable,minZoomReached:t.transform[2]<=t.minZoom,maxZoomReached:t.transform[2]>=t.maxZoom,ariaLabelConfig:t.ariaLabelConfig});function cm({style:t,showZoom:r=!0,showFitView:o=!0,showInteractive:s=!0,fitViewOptions:a,onZoomIn:u,onZoomOut:c,onFitView:f,onInteractiveChange:g,className:y,children:v,position:x="bottom-left",orientation:m="vertical","aria-label":S}){const k=Ye(),{isInteractive:j,minZoomReached:b,maxZoomReached:_,ariaLabelConfig:P}=ze(uk,Ke),{zoomIn:N,zoomOut:E,fitView:L}=Ll(),A=()=>{N(),u==null||u()},V=()=>{E(),c==null||c()},z=()=>{L(a),f==null||f()},G=()=>{k.setState({nodesDraggable:!j,nodesConnectable:!j,elementsSelectable:!j}),g==null||g(!j)},ee=m==="horizontal"?"horizontal":"vertical";return h.jsxs(Rl,{className:it(["react-flow__controls",ee,y]),position:x,style:t,"data-testid":"rf__controls","aria-label":S??P["controls.ariaLabel"],children:[r&&h.jsxs(h.Fragment,{children:[h.jsx(il,{onClick:A,className:"react-flow__controls-zoomin",title:P["controls.zoomIn.ariaLabel"],"aria-label":P["controls.zoomIn.ariaLabel"],disabled:_,children:h.jsx(ik,{})}),h.jsx(il,{onClick:V,className:"react-flow__controls-zoomout",title:P["controls.zoomOut.ariaLabel"],"aria-label":P["controls.zoomOut.ariaLabel"],disabled:b,children:h.jsx(ok,{})})]}),o&&h.jsx(il,{className:"react-flow__controls-fitview",onClick:z,title:P["controls.fitView.ariaLabel"],"aria-label":P["controls.fitView.ariaLabel"],children:h.jsx(sk,{})}),s&&h.jsx(il,{className:"react-flow__controls-interactive",onClick:G,title:P["controls.interactive.ariaLabel"],"aria-label":P["controls.interactive.ariaLabel"],children:j?h.jsx(ak,{}):h.jsx(lk,{})}),v]})}cm.displayName="Controls";const ck=O.memo(cm);function dk({id:t,x:r,y:o,width:s,height:a,style:u,color:c,strokeColor:f,strokeWidth:g,className:y,borderRadius:v,shapeRendering:x,selected:m,onClick:S}){const{background:k,backgroundColor:j}=u||{},b=c||k||j;return h.jsx("rect",{className:it(["react-flow__minimap-node",{selected:m},y]),x:r,y:o,rx:v,ry:v,width:s,height:a,style:{fill:b,stroke:f,strokeWidth:g},shapeRendering:x,onClick:S?_=>S(_,t):void 0})}const fk=O.memo(dk),hk=t=>t.nodes.map(r=>r.id),Ou=t=>t instanceof Function?t:()=>t;function pk({nodeStrokeColor:t,nodeColor:r,nodeClassName:o="",nodeBorderRadius:s=5,nodeStrokeWidth:a,nodeComponent:u=fk,onClick:c}){const f=ze(hk,Ke),g=Ou(r),y=Ou(t),v=Ou(o),x=typeof window>"u"||window.chrome?"crispEdges":"geometricPrecision";return h.jsx(h.Fragment,{children:f.map(m=>h.jsx(mk,{id:m,nodeColorFunc:g,nodeStrokeColorFunc:y,nodeClassNameFunc:v,nodeBorderRadius:s,nodeStrokeWidth:a,NodeComponent:u,onClick:c,shapeRendering:x},m))})}function gk({id:t,nodeColorFunc:r,nodeStrokeColorFunc:o,nodeClassNameFunc:s,nodeBorderRadius:a,nodeStrokeWidth:u,shapeRendering:c,NodeComponent:f,onClick:g}){const{node:y,x:v,y:x,width:m,height:S}=ze(k=>{const j=k.nodeLookup.get(t);if(!j)return{node:void 0,x:0,y:0,width:0,height:0};const b=j.internals.userNode,{x:_,y:P}=j.internals.positionAbsolute,{width:N,height:E}=ln(b);return{node:b,x:_,y:P,width:N,height:E}},Ke);return!y||y.hidden||!cg(y)?null:h.jsx(f,{x:v,y:x,width:m,height:S,style:y.style,selected:!!y.selected,className:s(y),color:r(y),borderRadius:a,strokeColor:o(y),strokeWidth:u,shapeRendering:c,onClick:g,id:y.id})}const mk=O.memo(gk);var yk=O.memo(pk);const vk=200,xk=150,wk=t=>!t.hidden,_k=t=>{const r={x:-t.transform[0]/t.transform[2],y:-t.transform[1]/t.transform[2],width:t.width/t.transform[2],height:t.height/t.transform[2]};return{viewBB:r,boundingRect:t.nodeLookup.size>0?lg(Bo(t.nodeLookup,{filter:wk}),r):r,rfId:t.rfId,panZoom:t.panZoom,translateExtent:t.translateExtent,flowWidth:t.width,flowHeight:t.height,ariaLabelConfig:t.ariaLabelConfig}},up=(t,r)=>t.x===r.x&&t.y===r.y&&t.width===r.width&&t.height===r.height,Sk=(t,r)=>up(t.viewBB,r.viewBB)&&up(t.boundingRect,r.boundingRect)&&t.rfId===r.rfId&&t.panZoom===r.panZoom&&t.translateExtent===r.translateExtent&&t.flowWidth===r.flowWidth&&t.flowHeight===r.flowHeight&&t.ariaLabelConfig===r.ariaLabelConfig,kk="react-flow__minimap-desc";function dm({style:t,className:r,nodeStrokeColor:o,nodeColor:s,nodeClassName:a="",nodeBorderRadius:u=5,nodeStrokeWidth:c,nodeComponent:f,bgColor:g,maskColor:y,maskStrokeColor:v,maskStrokeWidth:x,position:m="bottom-right",onClick:S,onNodeClick:k,pannable:j=!1,zoomable:b=!1,ariaLabel:_,inversePan:P,zoomStep:N=1,offsetScale:E=5}){const L=Ye(),A=O.useRef(null),{boundingRect:V,viewBB:z,rfId:G,panZoom:ee,translateExtent:J,flowWidth:ne,flowHeight:q,ariaLabelConfig:C}=ze(_k,Sk),W=(t==null?void 0:t.width)??vk,U=(t==null?void 0:t.height)??xk,Y=V.width/W,T=V.height/U,F=Math.max(Y,T),B=F*W,M=F*U,R=E*F,re=V.x-(B-V.width)/2-R,ie=V.y-(M-V.height)/2-R,ce=B+R*2,fe=M+R*2,de=`${kk}-${G}`,Q=O.useRef(0),le=O.useRef();Q.current=F,O.useEffect(()=>{if(A.current&&ee)return le.current=A1({domNode:A.current,panZoom:ee,getTransform:()=>L.getState().transform,getViewScale:()=>Q.current}),()=>{var pe;(pe=le.current)==null||pe.destroy()}},[ee]),O.useEffect(()=>{var pe;(pe=le.current)==null||pe.update({translateExtent:J,width:ne,height:q,inversePan:P,pannable:j,zoomStep:N,zoomable:b})},[j,b,P,N,J,ne,q]);const me=S?pe=>{var Ce;const[be,Pe]=((Ce=le.current)==null?void 0:Ce.pointer(pe))||[0,0];S(pe,{x:be,y:Pe})}:void 0,ke=k?O.useCallback((pe,be)=>{const Pe=L.getState().nodeLookup.get(be).internals.userNode;k(pe,Pe)},[]):void 0,xe=_??C["minimap.ariaLabel"];return h.jsx(Rl,{position:m,style:{...t,"--xy-minimap-background-color-props":typeof g=="string"?g:void 0,"--xy-minimap-mask-background-color-props":typeof y=="string"?y:void 0,"--xy-minimap-mask-stroke-color-props":typeof v=="string"?v:void 0,"--xy-minimap-mask-stroke-width-props":typeof x=="number"?x*F:void 0,"--xy-minimap-node-background-color-props":typeof s=="string"?s:void 0,"--xy-minimap-node-stroke-color-props":typeof o=="string"?o:void 0,"--xy-minimap-node-stroke-width-props":typeof c=="number"?c:void 0},className:it(["react-flow__minimap",r]),"data-testid":"rf__minimap",children:h.jsxs("svg",{width:W,height:U,viewBox:`${re} ${ie} ${ce} ${fe}`,className:"react-flow__minimap-svg",role:"img","aria-labelledby":de,ref:A,onClick:me,children:[xe&&h.jsx("title",{id:de,children:xe}),h.jsx(yk,{onClick:ke,nodeColor:s,nodeStrokeColor:o,nodeBorderRadius:u,nodeClassName:a,nodeStrokeWidth:c,nodeComponent:f}),h.jsx("path",{className:"react-flow__minimap-mask",d:`M${re-R},${ie-R}h${ce+R*2}v${fe+R*2}h${-ce-R*2}z - M${z.x},${z.y}h${z.width}v${z.height}h${-z.width}z`,fillRule:"evenodd",pointerEvents:"none"})]})})}dm.displayName="MiniMap";const Nk=O.memo(dm),Ek=t=>r=>t?`${Math.max(1/r.transform[2],1)}`:void 0,jk={[$i.Line]:"right",[$i.Handle]:"bottom-right"};function bk({nodeId:t,position:r,variant:o=$i.Handle,className:s,style:a=void 0,children:u,color:c,minWidth:f=10,minHeight:g=10,maxWidth:y=Number.MAX_VALUE,maxHeight:v=Number.MAX_VALUE,keepAspectRatio:x=!1,resizeDirection:m,autoScale:S=!0,shouldResize:k,onResizeStart:j,onResize:b,onResizeEnd:_}){const P=Hg(),N=typeof t=="string"?t:P,E=Ye(),L=O.useRef(null),A=o===$i.Handle,V=ze(O.useCallback(Ek(A&&S),[A,S]),Ke),z=O.useRef(null),G=r??jk[o];O.useEffect(()=>{if(!(!L.current||!N))return z.current||(z.current=X1({domNode:L.current,nodeId:N,getStoreItems:()=>{const{nodeLookup:J,transform:ne,snapGrid:q,snapToGrid:C,nodeOrigin:W,domNode:U}=E.getState();return{nodeLookup:J,transform:ne,snapGrid:q,snapToGrid:C,nodeOrigin:W,paneDomNode:U}},onChange:(J,ne)=>{const{triggerNodeChanges:q,nodeLookup:C,parentLookup:W,nodeOrigin:U}=E.getState(),Y=[],T={x:J.x,y:J.y},F=C.get(N);if(F&&F.expandParent&&F.parentId){const B=F.origin??U,M=J.width??F.measured.width??0,R=J.height??F.measured.height??0,re={id:F.id,parentId:F.parentId,rect:{width:M,height:R,...dg({x:J.x??F.position.x,y:J.y??F.position.y},{width:M,height:R},F.parentId,C,B)}},ie=wc([re],C,W,U);Y.push(...ie),T.x=J.x?Math.max(B[0]*M,J.x):void 0,T.y=J.y?Math.max(B[1]*R,J.y):void 0}if(T.x!==void 0&&T.y!==void 0){const B={id:N,type:"position",position:{...T}};Y.push(B)}if(J.width!==void 0&&J.height!==void 0){const M={id:N,type:"dimensions",resizing:!0,setAttributes:m?m==="horizontal"?"width":"height":!0,dimensions:{width:J.width,height:J.height}};Y.push(M)}for(const B of ne){const M={...B,type:"position"};Y.push(M)}q(Y)},onEnd:({width:J,height:ne})=>{const q={id:N,type:"dimensions",resizing:!1,dimensions:{width:J,height:ne}};E.getState().triggerNodeChanges([q])}})),z.current.update({controlPosition:G,boundaries:{minWidth:f,minHeight:g,maxWidth:y,maxHeight:v},keepAspectRatio:x,resizeDirection:m,onResizeStart:j,onResize:b,onResizeEnd:_,shouldResize:k}),()=>{var J;(J=z.current)==null||J.destroy()}},[G,f,g,y,v,x,j,b,_,k]);const ee=G.split("-");return h.jsx("div",{className:it(["react-flow__resize-control","nodrag",...ee,o,s]),ref:L,style:{...a,scale:V,...c&&{[A?"backgroundColor":"borderColor"]:c}},children:u})}O.memo(bk);const Ck={"arch.context":0,"django.app":0,"django.route":1,"django.websocket_route":1,"fastapi.route":1,"django.url_name":2,"django.view":3,"django.viewset_action":3,"django.permission":3,"django.throttle":3,"django.serializer":4,"django.form":4,"graphql.type":4,"fastapi.model":4,"django.serializer_field":5,"django.service":5,"graphql.field":5,"django.model":6,"django.field":7,"django.relation":7,"django.task":8,"django.receiver":8,"django.signal":8,"django.test":8,"django.migration_op":8,"django.admin":8,"django.management_command":8,"django.consumer":8,"django.cache_key":8,"django.feature_flag":8,"django.side_effect":8,"openapi.path":9,"graphql.operation":9,"react.api_client":10,"django.htmx":10,"react.query_key":11,"react.hook":11,"react.feature":11,"react.route":12,"react.page":12,"django.template":12,"react.component":13,"react.context":13,"react.form_schema":14,"react.test":14};function Dl(t){return Ck[t]??8}const nc=208,rc=64,Mk=88,Pk=28,Ik=8;function Tk(t){if(!t.length)return Number.NaN;const r=[...t].sort((s,a)=>s-a),o=Math.floor(r.length/2);return r.length%2?r[o]:(r[o-1]+r[o])/2}function Rk(t,r=[]){const o=new Map;if(!t.length)return o;const s=new Map;for(const _ of t){const P=Dl(_.type),N=s.get(P)??[];N.push(_),s.set(P,N)}const u=[...s.keys()].sort((_,P)=>_-P).map(_=>[...s.get(_)??[]].sort((P,N)=>P.name.localeCompare(N.name)||P.id.localeCompare(N.id))),c=new Set(t.map(_=>_.id)),f=new Map,g=new Map;for(const _ of t)f.set(_.id,[]),g.set(_.id,[]);for(const _ of r)!c.has(_.src)||!c.has(_.dst)||_.src===_.dst||(g.get(_.src).push(_.dst),f.get(_.dst).push(_.src));const y=new Map;u.forEach((_,P)=>{for(const N of _)y.set(N.id,P)});const v=new Map,x=()=>{for(const _ of u)_.forEach((P,N)=>v.set(P.id,N))};x();const m=(_,P)=>{const N=_.map((E,L)=>{const A=P(E.id).map(z=>v.get(z)).filter(z=>z!==void 0),V=Tk(A);return{n:E,bary:Number.isNaN(V)?L:V,name:E.name,id:E.id}});return N.sort((E,L)=>E.bary-L.bary||E.name.localeCompare(L.name)||E.id.localeCompare(L.id)),N.map(E=>E.n)},S=_=>P=>y.get(P)===_;for(let _=0;_(f.get(N)??[]).filter(S(P-1))),x();for(let P=u.length-2;P>=0;P--)u[P]=m(u[P],N=>(g.get(N)??[]).filter(S(P+1))),x()}const k=nc+Mk,j=rc+Pk,b=Math.max(...u.map(_=>_.length),1);return u.forEach((_,P)=>{const N=(b-_.length)*j/2;_.forEach((E,L)=>{o.set(E.id,{x:P*k,y:N+L*j})})}),o}const fm=90,Lk=new Set(["django.field","django.serializer_field","django.relation","django.test","react.test","graphql.field","django.url_name","django.throttle"]),cp={"arch.context":"#edf2f4","django.app":"#8d99ae","django.route":"#4cc9f0","django.url_name":"#4cc9f0","django.view":"#4895ef","django.viewset_action":"#4361ee","django.permission":"#7b8cde","django.serializer":"#f4a261","django.form":"#e9c46a","django.serializer_field":"#e9c46a","django.service":"#90be6d","django.model":"#2a9d8f","django.field":"#8ac926","django.task":"#e76f51","django.receiver":"#e85d04","django.signal":"#f4a261","django.test":"#6c757d","django.admin":"#adb5bd","django.migration_op":"#9d4edd","django.consumer":"#e76f51","django.websocket_route":"#4cc9f0","django.template":"#c77dff","django.htmx":"#ff6b6b","django.cache_key":"#6c757d","django.feature_flag":"#f4a261","django.side_effect":"#e85d04","graphql.type":"#00bbf9","graphql.operation":"#00bbf9","fastapi.route":"#4cc9f0","fastapi.model":"#f4a261","openapi.path":"#00bbf9","react.api_client":"#ff6b6b","react.query_key":"#adb5bd","react.hook":"#7b2cbf","react.feature":"#9d4edd","react.route":"#c77dff","react.page":"#c77dff","react.component":"#9d4edd","react.form_schema":"#ffd166","react.test":"#6c757d"},Ak=Math.PI*(3-Math.sqrt(5)),hm=220,zk=26,Dk={0:"context",1:"routes",2:"url names",3:"views",4:"serializers",5:"services",6:"models",7:"fields",8:"jobs / signals",9:"openapi",10:"api client",11:"hooks",12:"pages",13:"components",14:"forms / tests"};function pm(t){return t.startsWith("react.")?"react":t.startsWith("openapi.")||t.startsWith("graphql.")||t.startsWith("fastapi.")?"stitch":t.startsWith("arch.")?"arch":"django"}function _N(t){return cp[t]?cp[t]:t.startsWith("react.")?"#9d4edd":t.startsWith("openapi.")?"#00bbf9":"#4a5568"}function $k(t){return t>=fm?"3d":"2d"}function Ok(t){return t>=fm?"overview":"full"}function Fk(t,r,o=1){const s=new Set([t]);let a=new Set([t]);for(let u=0;uo.families.has(pm(f.type)));o.detail==="overview"&&(s=s.filter(f=>!Lk.has(f.type)));const a=new Set(s.map(f=>f.id)),u=r.filter(f=>a.has(f.src)&&a.has(f.dst)),c=o.focusId?Fk(o.focusId,u,1):new Set;if(o.neighborhoodOnly&&o.focusId&&c.size){s=s.filter(g=>c.has(g.id));const f=new Set(s.map(g=>g.id));return{nodes:s,edges:u.filter(g=>f.has(g.src)&&f.has(g.dst)),neighborIds:c}}return{nodes:s,edges:u,neighborIds:c}}function SN(t){const r=new Map;for(const s of t){const a=Dl(s.type),u=r.get(a)??[];u.push(s),r.set(a,u)}const o=new Map;for(const[s,a]of r){a.sort((c,f)=>c.name.localeCompare(f.name));const u=s*hm;a.forEach((c,f)=>{if(a.length===1){o.set(c.id,{x:u,y:0,z:0});return}const g=zk*Math.sqrt(f+1),y=f*Ak;o.set(c.id,{x:u,y:g*Math.cos(y),z:g*Math.sin(y)})})}return o}function kN(t){const r=new Map;for(const o of t){const s=Dl(o.type);r.set(s,(r.get(s)||0)+1)}return[...r.entries()].sort((o,s)=>o[0]-s[0]).map(([o,s])=>({layer:o,x:o*hm,count:s}))}const ol=16,Bk=12,Vk=new Set(["django.route","react.route","react.page","django.task","django.migration_op","django.permission","django.throttle","django.admin","django.management_command","openapi.path","django.consumer","django.websocket_route","django.template","django.cache_key","django.feature_flag","django.side_effect","graphql.operation","fastapi.route"]),Wk=new Set(["django.serializer","django.serializer_field","django.form","openapi.path","react.form_schema","django.route","graphql.type","graphql.field","graphql.operation","fastapi.model","fastapi.route"]),dp={"arch.context":"Ownership boundary from loadpath.yml — the context this code belongs to.","django.app":"Django app package that owns models, views, and jobs.","django.route":"HTTP URL that publishes a view. A sink: this is where a change becomes a public request.","django.url_name":"Named URL used by reverse() / {% url %} lookups.","django.view":"Request handler (class-based view, function view, or ViewSet).","django.viewset_action":"One ViewSet action (list, create, retrieve, update, destroy).","django.permission":"Auth gate on a view — who is allowed to hit this path.","django.throttle":"Rate-limit class attached to a view.","django.serializer":"Request/response contract: which fields go in and come out.","django.form":"Django form or django-filter FilterSet — the typed input contract.","django.serializer_field":"One field on a serializer or form — the typed slot on the contract.","django.service":"Internal service or use-case. Work that is not itself an HTTP sink.","django.model":"ORM model. Schema and relations live here.","django.field":"Model column. Type, indexes, and relations are the contract of the table.","django.relation":"Model-to-model relation (FK / M2M / O2O).","django.task":"Celery or Dramatiq job. Once enqueued, this is a sink.","django.receiver":"Signal handler that runs after a model event.","django.signal":"Django signal that receivers subscribe to.","django.test":"Backend test that mentions symbols on this path.","django.admin":"Django admin class for a model.","django.migration_op":"Schema migration operation (CreateModel, AlterField, …).","django.management_command":"manage.py command — an operational sink.","django.consumer":"Django Channels WebSocket/HTTP consumer. A sink once a client connects.","django.websocket_route":"ASGI WebSocket URL. A sink: this is where a change becomes a live connection.","django.template":"Django template. HTML (and HTMX) the server renders.","django.htmx":"HTMX call from a template to a URL — another published seam.","django.cache_key":"Cache get/set key. Invalidation is part of the load path.","django.feature_flag":"Feature flag checked on this path. The change may be dark-launched.","django.side_effect":"transaction.on_commit (or similar) side effect that runs after the request commits.","graphql.type":"GraphQL object/input type — a published contract.","graphql.field":"One field on a GraphQL type.","graphql.operation":"GraphQL query, mutation, or subscription. A published contract and a sink.","fastapi.route":"FastAPI path operation sitting next to Django in this repo.","fastapi.model":"Pydantic response/request model — the FastAPI contract.","openapi.path":"Generated OpenAPI operation. The typed HTTP contract between stacks.","react.api_client":"Frontend fetch or generated client call to an API path.","react.query_key":"React Query cache key. Invalidation and reads share this name.","react.hook":"Data hook wrapping query or mutation calls.","react.feature":"Frontend feature module (folder).","react.route":"Client-side route. A sink: this is a URL the user can open.","react.page":"Page or screen component rendered by a route.","react.component":"UI component.","react.form_schema":"Zod (or similar) schema — typed form inputs on the client.","react.test":"Frontend test covering a page, hook, or component.","react.context":"React context provider."},Uk={field_type:"Type",fields:"Fields",form_fields:"Form fields",permissions:"Permissions",throttles:"Throttles",authentication:"Authentication",pagination:"Pagination",filterset:"Filterset",bases:"Extends",on_delete:"on_delete",related_name:"related_name",unique:"Unique",db_index:"Indexed",relation:"Relation field",looks_idempotent_on_pk:"Idempotent on pk",broker:"Broker",route:"Route",url_name:"URL name",view:"View",include:"Includes",mounted_at:"Mounted at",full_path:"Full path",method:"Method",path:"Path",operation_id:"Operation",raw:"URL",kind:"Schema",exclude:"Excludes",queryset_in_serializer:"Queryset in serializer",get_queryset:"Custom get_queryset",get_serializer_class:"Dynamic serializer",dynamic:"Dynamic",fbv:"Function view",ninja:"Django Ninja",django_form:"Django form",mutation:"Mutation",has_error_boundary:"Error boundary",invalidation:"Cache invalidation",inferred:"Inferred stitch",generated:"Generated",shared:"Shared module",element:"Renders",model_name:"Model",field_name:"Field",op:"Operation",app:"App",feature:"Feature",from_view:"From view",mentions:"Mentions",nodeid:"Test id",task:"Task",to:"Related to",doc:"Summary",template:"Template",signal:"Signal",sender:"Sender",decorators:"Decorators",nplusone:"N+1 risk",lookups:"Lookups",null:"NULL",blank:"Blank",default:"Default",max_length:"max_length",max_digits:"max_digits",decimal_places:"decimal_places",primary_key:"Primary key",help_text:"Help text",choices:"Choices",auto_now:"auto_now",auto_now_add:"auto_now_add",basename:"Router basename",args:"Args",beat:"Beat",schedule_name:"Schedule",websocket:"WebSocket",htmx:"HTMX",blocks:"Blocks",db_table:"db_table"},fp=["doc","field_type","method","path","operation_id","raw","route","mounted_at","full_path","url_name","view","element","fields","form_fields","exclude","kind","bases","permissions","authentication","throttles","pagination","filterset","on_delete","related_name","to","unique","db_index","null","blank","default","max_length","max_digits","decimal_places","primary_key","auto_now","auto_now_add","help_text","choices","relation","nplusone","lookups","template","signal","sender","decorators","basename","args","beat","schedule_name","websocket","htmx","blocks","db_table","looks_idempotent_on_pk","broker","task","model_name","field_name","op","app","feature","from_view","include","fbv","ninja","django_form","mutation","has_error_boundary","invalidation","inferred","generated","shared","queryset_in_serializer","get_queryset","get_serializer_class","dynamic","mentions","nodeid"],hp=new Set(["referenced","placeholder","booted","line","call","from","import","local","source","file","plain_handler","string_ref","pagination_sink","match","via","generated_client","django","react","superseded_by_generated","foreign_app","imported"]),Yk=new Set(["looks_idempotent_on_pk","null","blank"]),Gk=new Set(["inferred","generated","mutation","fbv","ninja","filterset"]);function Xk(t){return dp[t]?dp[t]:t.startsWith("react.")?"A React node on the load path.":t.startsWith("django.")?"A Django node on the load path.":t.startsWith("openapi.")?"A stitch node between Django and React.":"A node on the architecture graph."}function qk(t,r,o){const s=new Map(r.map(m=>[m.id,m])),a=[];Vk.has(t.type)&&a.push("sink"),Wk.has(t.type)&&a.push("contract");const u=t.extra??{};u.inferred&&a.push("inferred"),u.generated&&a.push("generated"),u.mutation&&a.push("mutation"),u.fbv&&a.push("function view"),u.ninja&&a.push("ninja"),u.filterset===!0&&a.push("filterset");const c=o.filter(m=>m.dst===t.id),f=o.filter(m=>m.src===t.id),g=c.slice(0,ol).map(m=>sl(m,s,m.src)),y=f.slice(0,ol).map(m=>sl(m,s,m.dst)),v=t.file_path?`${t.file_path}${t.start_line?`:${t.start_line}`:""}`:void 0,x={type:t.type,typeLabel:bo(kl(t.type)),layer:Dk[Dl(t.type)]??"other",purpose:Xk(t.type),name:t.name,qualifiedName:t.qualified_name,file:v,context:t.context,roles:a,facts:Qk(u).filter(m=>!(m.key==="app"&&m.value===t.context)),inputs:g,outputs:y,extraInputs:Math.max(0,c.length-ol),extraOutputs:Math.max(0,f.length-ol),degreeIn:c.length,degreeOut:f.length,inputKinds:pp(c.map(m=>sl(m,s,m.src))),outputKinds:pp(f.map(m=>sl(m,s,m.dst))),pathSummary:""};return x.pathSummary=Kk(x),x}function pp(t){const r=new Map;for(const o of t){const s=o.edgeLabel||o.edgeType.replaceAll("_"," ");r.set(s,(r.get(s)||0)+1)}return[...r.entries()].sort((o,s)=>s[1]-o[1]||o[0].localeCompare(s[0])).map(([o,s])=>({label:o,count:s}))}function Kk(t){const r=t.inputKinds.map(s=>`${s.label} ×${s.count}`).join(", "),o=t.outputKinds.map(s=>`${s.label} ×${s.count}`).join(", ");return r&&o?`${r} → this → ${o}`:o?`this → ${o}`:r?`${r} → this`:""}function sl(t,r,o){const s=r.get(o),a=o.includes(":")?o.slice(o.indexOf(":")+1):o;return{id:o,name:(s==null?void 0:s.name)||a,type:(s==null?void 0:s.type)||"",typeLabel:s?bo(kl(s.type)):"",edgeType:t.type,edgeLabel:bo(t.type),inferred:t.confidence<.8}}function Qk(t){const r=[...fp.filter(a=>a in t),...Object.keys(t).filter(a=>!fp.includes(a)&&!hp.has(a))],o=[],s=new Set;for(const a of r){if(s.has(a)||hp.has(a)||Gk.has(a))continue;s.add(a);const u=Zk(a,t[a]);u!=null&&o.push({key:a,label:Uk[a]??bo(a),value:u})}return o}function Zk(t,r){if(r==null)return null;if(typeof r=="boolean")return!r&&!Yk.has(t)?null:r?"yes":"no";if(typeof r=="number")return String(r);if(typeof r=="string")return r.trim()||null;if(Array.isArray(r)){if(r.some(u=>u&&typeof u=="object"))return Jk(t,r);const o=r.map(u=>typeof u=="string"||typeof u=="number"?String(u):"").filter(Boolean);if(!o.length)return null;const s=o.slice(0,Bk),a=o.length-s.length;return a>0?`${s.join(", ")} +${a} more`:s.join(", ")}return null}function Jk(t,r){const o=r.slice(0,4).map(a=>{if(t==="nplusone"){const c=String(a.queryset||"queryset"),f=Array.isArray(a.accessed)?a.accessed.join("."):"",g=a.line?` L${a.line}`:"";return f?`${c} → ${f}${g}`:`${c}${g}`}if(t==="lookups"){const c=Array.isArray(a.fields)?a.fields.join(", "):"",f=String(a.kind||"filter");return c?`${f} ${c}`:f}return Object.entries(a).filter(([,c])=>c!=null&&(typeof c=="string"||typeof c=="number")).slice(0,3).map(([c,f])=>`${c}=${f}`).join(" ")});if(!o.some(Boolean))return null;const s=r.length-o.length;return s>0?`${o.join("; ")} +${s} more`:o.join("; ")}const eN=new Set,tN=O.lazy(()=>v0(()=>import("./LayeredGraph3D-DBrjUozl.js"),[],import.meta.url).then(t=>({default:t.LayeredGraph3D}))),nN={cheap:"var(--edge-cheap)",expensive:"var(--edge-expensive)",critical:"var(--edge-critical)"};function rN({data:t,selected:r}){return h.jsxs("div",{className:r?"lp-node selected":"lp-node",children:[h.jsx(Oi,{type:"target",position:Se.Left,isConnectable:!1}),h.jsx("div",{className:"t",children:kl(t.type)}),h.jsx("div",{className:"n",title:t.name,children:Dr(t.name)}),h.jsx(Oi,{type:"source",position:Se.Right,isConnectable:!1})]})}const iN={load:rN},oN=new Set(["django","react","stitch","arch"]);function sN({topologyKey:t}){const{fitView:r}=Ll();return O.useEffect(()=>{let o=0;const s=requestAnimationFrame(()=>{o=requestAnimationFrame(()=>{r({padding:.2,maxZoom:1.15})})});return()=>{cancelAnimationFrame(s),cancelAnimationFrame(o)}},[r,t]),null}function lN(t,r,o=null){const s=new Map(t.map(f=>[f.id,f])),a=Rk(t,r),u=t.map(f=>({id:f.id,type:"load",position:a.get(f.id)??{x:0,y:0},data:{name:f.name,type:f.type,file:f.file_path},selected:o===f.id,sourcePosition:Se.Right,targetPosition:Se.Left,width:nc,height:rc,style:{width:nc,height:rc}})),c=r.filter(f=>s.has(f.src)&&s.has(f.dst)).map(f=>{const g=nN[f.weight]||"var(--edge-cheap)",y=!!(o&&(f.src===o||f.dst===o));return{id:f.id,source:f.src,target:f.dst,type:"smoothstep",animated:f.weight==="critical",style:{stroke:g,strokeWidth:f.weight==="critical"?2.4:1.2,strokeDasharray:f.confidence<.8?"6 4":void 0},markerEnd:{type:Lo.ArrowClosed,width:14,height:14,color:g},label:y?f.type.replaceAll("_"," "):void 0,labelStyle:y?{fill:"var(--ink)",fontSize:10,fontWeight:600}:void 0,labelBgStyle:y?{fill:"var(--graph-bg)",fillOpacity:.92}:void 0,labelBgPadding:y?[3,5]:void 0,labelBgBorderRadius:y?4:void 0}});return{rfNodes:u,rfEdges:c}}function gp({node:t,nodes:r,edges:o,onClose:s,onWhatIf:a}){const u=qk(t,r,o);return O.useEffect(()=>{const c=f=>{f.key==="Escape"&&s()};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[s]),h.jsxs("aside",{className:"inspector","data-testid":"graph-inspector",children:[h.jsxs("div",{className:"inspector-head",children:[h.jsx("div",{className:"t",children:u.typeLabel}),h.jsx("div",{className:"inspector-roles",children:u.roles.map(c=>h.jsx("span",{className:"inspector-chip",children:c},c))}),h.jsx("button",{type:"button",className:"inspector-close","data-testid":"graph-inspector-close","aria-label":"Close inspector",onClick:s,children:"×"})]}),h.jsx("div",{className:"n",children:Dr(u.name)}),h.jsx("p",{className:"inspector-purpose","data-testid":"graph-inspector-purpose",children:u.purpose}),u.context?h.jsx("div",{className:"muted",children:Dr(u.context)}):null,u.file?h.jsx("div",{className:"file",children:Dr(u.file)}):null,h.jsx("div",{className:"muted",children:Dr(u.qualifiedName)}),h.jsxs("div",{className:"muted inspector-layer",children:["layer · ",u.layer]}),h.jsxs("div",{className:"muted inspector-degree","data-testid":"graph-inspector-degree",children:[u.degreeIn," in · ",u.degreeOut," out"]}),u.pathSummary?h.jsx("p",{className:"inspector-path","data-testid":"graph-inspector-path",children:u.pathSummary}):null,u.facts.length?h.jsx("dl",{className:"inspector-facts","data-testid":"graph-inspector-facts",children:u.facts.map(c=>h.jsxs("div",{className:"inspector-fact",children:[h.jsx("dt",{children:c.label}),h.jsx("dd",{children:Dr(c.value)})]},c.key))}):null,h.jsx(mp,{title:"Inputs",testId:"graph-inspector-inputs",links:u.inputs,extra:u.extraInputs,empty:"Nothing in this graph points here."}),h.jsx(mp,{title:"Outputs",testId:"graph-inspector-outputs",links:u.outputs,extra:u.extraOutputs,empty:"This node does not point at anything in this graph."}),a?h.jsx("button",{type:"button",className:"btn","data-testid":"btn-whatif",onClick:()=>a(t.id),children:"What if this changes"}):null]})}function mp({title:t,testId:r,links:o,extra:s,empty:a}){return h.jsxs("section",{className:"inspector-section","data-testid":r,children:[h.jsxs("h3",{children:[t,h.jsx("span",{className:"count",children:o.length+s})]}),o.length?h.jsx("ul",{children:o.map((u,c)=>h.jsxs("li",{children:[h.jsx("span",{className:"inspector-link-name",title:u.name,children:Dr(u.name)}),h.jsxs("span",{className:"inspector-link-meta",children:[u.typeLabel?`${u.typeLabel} · `:"",u.edgeLabel,u.inferred?" · inferred":""]})]},`${u.edgeType}:${u.id}:${c}`))}):h.jsx("p",{className:"muted",children:a}),s?h.jsxs("p",{className:"muted",children:["+",s," more"]}):null]})}function Fu({nodes:t,edges:r,onWhatIf:o,focusPath:s}){const[a,u]=O.useState(null),[c,f]=O.useState(null),[g,y]=O.useState(null),[v,x]=O.useState(new Set(oN)),[m,S]=O.useState(!1),k=typeof window<"u"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches,j=c??$k(t.length),b=g??Ok(t.length),_=m&&j==="3d"?a:null,P=O.useMemo(()=>Hk(t,r,{detail:b,families:v,focusId:_,neighborhoodOnly:!!_}),[t,r,b,v,_]),N=O.useMemo(()=>`${P.nodes.map(q=>q.id).join("\0")}|${P.edges.map(q=>q.id).join("\0")}`,[P.nodes,P.edges]),E=O.useMemo(()=>new Map(P.nodes.map(q=>[q.id,q])),[P.nodes]),L=a?E.get(a)??null:null,{rfNodes:A,rfEdges:V}=O.useMemo(()=>{const q=lN(P.nodes,P.edges,a);return k&&(q.rfEdges=q.rfEdges.map(C=>({...C,animated:!1}))),q},[P.nodes,P.edges,a,k]);O.useEffect(()=>{a&&!E.has(a)&&u(null)},[E,a]),O.useEffect(()=>{if(!s)return;const q=t.find(C=>C.file_path===s);q&&u(q.id)},[s,t]);const z=(q,C)=>{u(C.id)},G=()=>{u(null),S(!1)},ee=q=>{x(C=>{const W=new Set(C);if(W.has(q)){if(W.size===1)return C;W.delete(q)}else W.add(q);return W})},J=O.useMemo(()=>{const q=new Set;for(const C of t)q.add(pm(C.type));return q},[t]),ne=t.length-P.nodes.length;return h.jsxs("div",{className:"impact-graph",style:{flex:1,minHeight:0,position:"relative",display:"flex",flexDirection:"column"},children:[h.jsxs("div",{className:"graph-toolbar","data-testid":"graph-toolbar",children:[h.jsxs("div",{className:"seg","aria-label":"Graph projection",children:[h.jsx("button",{type:"button","data-testid":"graph-view-2d",className:j==="2d"?"active":"","aria-pressed":j==="2d",onClick:()=>f("2d"),children:"2D map"}),h.jsx("button",{type:"button","data-testid":"graph-view-3d",className:j==="3d"?"active":"","aria-pressed":j==="3d",onClick:()=>f("3d"),children:"3D layers"})]}),h.jsxs("div",{className:"seg","aria-label":"Graph detail",children:[h.jsx("button",{type:"button","data-testid":"graph-detail-overview",className:b==="overview"?"active":"","aria-pressed":b==="overview",onClick:()=>y("overview"),children:"Overview"}),h.jsx("button",{type:"button","data-testid":"graph-detail-full",className:b==="full"?"active":"","aria-pressed":b==="full",onClick:()=>y("full"),children:"Full"})]}),h.jsx("div",{className:"seg","aria-label":"Graph families",children:["django","stitch","react"].filter(q=>J.has(q)).map(q=>h.jsx("button",{type:"button","data-testid":`graph-family-${q}`,className:v.has(q)?"active":"","aria-pressed":v.has(q),onClick:()=>ee(q),children:q},q))}),j==="3d"?h.jsx("button",{type:"button",className:m?"chip-btn active":"chip-btn","data-testid":"graph-neighborhood",disabled:!a,onClick:()=>S(q=>!q),children:m?"Neighborhood":"Focus neighbors"}):null,h.jsxs("span",{className:"muted graph-count",children:[P.nodes.length," nodes · ",P.edges.length," edges",ne?` · ${ne} hidden`:""]})]}),h.jsx("div",{className:"graph-stage",children:j==="3d"?h.jsxs("div",{className:"graph-3d","data-testid":"graph-3d",children:[h.jsx("p",{className:"graph-3d-hint",children:"Architecture layers are stacked in depth (Django → stitch → React). Drag to orbit, scroll to zoom, click a node to inspect it."}),h.jsx(O.Suspense,{fallback:h.jsx("p",{className:"muted graph-3d-hint",children:"Loading 3D layers…"}),children:h.jsx(tN,{nodes:P.nodes,edges:P.edges,selectedId:a,neighborIds:_?P.neighborIds:eN,onSelect:q=>{u(q),q||S(!1)}})}),L?h.jsx(gp,{node:L,nodes:t,edges:r,onClose:G,onWhatIf:o}):null]}):h.jsxs(am,{children:[h.jsxs(ZS,{nodes:A,edges:V,nodeTypes:iN,fitView:!1,minZoom:.25,nodesDraggable:!1,nodesConnectable:!1,elementsSelectable:!0,deleteKeyCode:null,onNodeClick:z,onPaneClick:G,proOptions:{hideAttribution:!1},"data-testid":"impact-graph",children:[h.jsx(sN,{topologyKey:N}),h.jsx(rk,{}),h.jsx(Nk,{pannable:!0,zoomable:!0,ariaLabel:"Impact graph overview",nodeColor:"var(--muted)",nodeStrokeColor:"transparent",nodeStrokeWidth:0,maskColor:"rgba(0, 0, 0, 0.45)",maskStrokeColor:"var(--accent)",maskStrokeWidth:1.4,bgColor:"var(--graph-bg)",style:{width:184,height:128}}),h.jsx(ck,{})]}),L?h.jsx(gp,{node:L,nodes:t,edges:r,onClose:G,onWhatIf:o}):null]})})]})}const yp=[{value:"HEAD",label:"HEAD",group:"preset"},{value:"HEAD~1",label:"HEAD~1",group:"preset"}],aN=["preset","branch","tag","commit"];function uN(t){var a;if(!(t!=null&&t.git))return[...yp];const r=((a=t.presets)!=null&&a.length?t.presets:yp.map(u=>u.value)).map(u=>({value:u,label:u,group:"preset"})),o=new Set(r.map(u=>u.value)),s=[...r];for(const u of t.branches||[])o.has(u.name)||(o.add(u.name),s.push({value:u.name,label:u.current?`${u.name} (current)`:u.name,detail:u.subject,group:"branch"}));for(const u of t.tags||[])o.has(u.name)||(o.add(u.name),s.push({value:u.name,label:u.name,detail:u.subject,group:"tag"}));for(const u of t.commits||[])o.has(u.sha)||(o.add(u.sha),s.push({value:u.sha,label:u.short,detail:u.subject,group:"commit"}));return s}function cN(t,r){const o=r.trim().toLowerCase();return o?t.filter(s=>s.value.toLowerCase().includes(o)||s.label.toLowerCase().includes(o)||(s.detail||"").toLowerCase().includes(o)):t}function dN(t){return aN.map(r=>({group:r,items:t.filter(o=>o.group===r)})).filter(r=>r.items.length>0)}function fN(t){return t==="preset"?"Common":t==="branch"?"Branches":t==="tag"?"Tags":"Recent commits"}function vp({value:t,onChange:r,placeholder:o,testId:s,menuTestId:a,refs:u,onNeedRefs:c}){const f=O.useId(),g=O.useRef(null),[y,v]=O.useState(!1),[x,m]=O.useState(null),[S,k]=O.useState(0),j=O.useMemo(()=>{const E=uN(u);return x===null?E:cN(E,x)},[u,x]),b=O.useMemo(()=>dN(j),[j]);O.useEffect(()=>{y&&c()},[y,c]),O.useEffect(()=>{k(0)},[x,y]);const _=()=>{v(!1),m(null)},P=E=>{r(E.value),_()},N=E=>{if(E.key==="ArrowDown"){if(E.preventDefault(),!y){v(!0);return}k(L=>Math.min(L+1,Math.max(j.length-1,0)))}else if(E.key==="ArrowUp"){if(E.preventDefault(),!y)return;k(L=>Math.max(L-1,0))}else if(E.key==="Enter"&&y){E.preventDefault();const L=j[S];L&&P(L)}else E.key==="Escape"&&y&&(E.preventDefault(),_())};return h.jsxs("div",{className:"combo",ref:g,onBlur:E=>{E.currentTarget.contains(E.relatedTarget)||_()},children:[h.jsxs("div",{className:"combo-row",children:[h.jsx("input",{"data-testid":s,value:t,placeholder:o,spellCheck:!1,role:"combobox","aria-expanded":y,"aria-controls":f,"aria-autocomplete":"list",onChange:E=>{r(E.target.value),y&&m(E.target.value)},onKeyDown:N}),h.jsx("button",{type:"button",className:"icon-btn combo-toggle","data-testid":`${s}-toggle`,"aria-label":"Show recent refs","aria-expanded":y,onMouseDown:E=>E.preventDefault(),onClick:()=>y?_():v(!0),children:h.jsx(g0,{})})]}),y?h.jsx("div",{className:"combo-menu",id:f,role:"listbox","data-testid":a,children:b.length===0?h.jsx("div",{className:"combo-empty muted",children:"No matching refs — the typed value is kept"}):b.map(E=>h.jsxs("div",{className:"combo-group",children:[h.jsx("div",{className:"combo-heading",children:fN(E.group)}),E.items.map(L=>{const A=j.indexOf(L);return h.jsxs("button",{type:"button",role:"option","aria-selected":A===S,className:A===S?"combo-option active":"combo-option","data-testid":`ref-option-${L.group}`,onMouseDown:V=>V.preventDefault(),onMouseEnter:()=>k(A),onClick:()=>P(L),children:[h.jsx("span",{className:"combo-label",children:L.label}),L.detail?h.jsx("span",{className:"combo-detail",children:L.detail}):null]},`${L.group}:${L.value}`)})]},E.group))}):null]})}function hN({initialPath:t,onSelect:r,onClose:o}){const[s,a]=O.useState(null),[u,c]=O.useState(t),[f,g]=O.useState(null),[y,v]=O.useState(""),[x,m]=O.useState(!1),S=O.useRef(null),k=O.useRef(0),j=async N=>{const E=k.current+1;k.current=E,m(!0);try{const L=await $e.browse(N);if(k.current!==E)return;a(L),c(L.path),g(L.is_git?L.path:null),v("")}catch(L){if(k.current!==E)return;v(L instanceof Error?L.message:String(L))}finally{k.current===E&&m(!1)}};O.useEffect(()=>{var N,E;j(t),(N=S.current)==null||N.focus(),(E=S.current)==null||E.select()},[t]);const b=f||(s==null?void 0:s.path)||u,_=f&&f!==(s==null?void 0:s.path)?f.split(/[\\/]/).filter(Boolean).pop():s!=null&&s.is_git?"this repository":"this folder",P=N=>{N.key==="Escape"&&(N.preventDefault(),o())};return h.jsx("div",{className:"modal-backdrop","data-testid":"repo-explorer","data-overlay":"true",onClick:o,onKeyDown:P,children:h.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-labelledby":"explorer-title",onClick:N=>N.stopPropagation(),children:[h.jsxs("div",{className:"modal-head",children:[h.jsxs("div",{children:[h.jsx("h2",{id:"explorer-title",children:"Select repository"}),h.jsx("p",{className:"muted",children:"Browse to a git root, or paste the full path."})]}),h.jsx("button",{type:"button",className:"btn ghost","data-testid":"explorer-cancel",onClick:o,children:"Cancel"})]}),h.jsxs("form",{className:"explorer-path",onSubmit:N=>{N.preventDefault(),j(u)},children:[h.jsx("input",{ref:S,"data-testid":"explorer-path",value:u,onChange:N=>c(N.target.value),spellCheck:!1,"aria-label":"Directory path"}),h.jsx("button",{type:"button",className:"btn",disabled:!(s!=null&&s.parent),onClick:()=>(s==null?void 0:s.parent)&&void j(s.parent),children:"Up"}),h.jsx("button",{type:"button",className:"btn",onClick:()=>s&&void j(s.home),children:"Home"}),h.jsx("button",{type:"submit",className:"btn",children:"Go"})]}),y?h.jsx("div",{className:"error",role:"alert",children:y}):null,h.jsx("div",{className:"explorer-list",role:"listbox","aria-label":"Folders","aria-busy":x,children:s!=null&&s.entries.length?s.entries.map(N=>{const E=f===N.path;return h.jsxs("button",{type:"button",role:"option","aria-selected":E,className:E?"explorer-row active":"explorer-row","data-testid":"explorer-entry","data-path":N.path,onClick:()=>g(N.path),onDoubleClick:()=>void j(N.path),children:[h.jsx(kp,{}),h.jsx("span",{className:"explorer-name",children:N.name}),N.is_git?h.jsx("span",{className:"chip git-badge",children:"git"}):null]},N.path)}):h.jsx("div",{className:"muted explorer-empty",children:x?"Loading…":"No folders here"})}),h.jsxs("div",{className:"modal-foot",children:[h.jsx("span",{className:"muted explorer-current",title:b,children:b}),h.jsxs("button",{type:"button",className:"btn primary","data-testid":"explorer-use",disabled:!b,onClick:()=>b&&r(b),children:["Use ",_]})]})]})})}const Sl=[{id:"obsidian",label:"Obsidian",group:"dark"},{id:"nord",label:"Nord",group:"dark"},{id:"solarized-dark",label:"Solarized Dark",group:"dark"},{id:"forest",label:"Forest",group:"dark"},{id:"rose",label:"Rose Pine",group:"dark"},{id:"amber",label:"Midnight Amber",group:"dark"},{id:"volcano",label:"Volcano",group:"dark"},{id:"lavender",label:"Lavender",group:"dark"},{id:"neon-noir",label:"Neon Noir",group:"dark"},{id:"synthwave",label:"Synthwave",group:"dark"},{id:"phosphor",label:"Phosphor",group:"dark"},{id:"aurora",label:"Aurora",group:"dark"},{id:"biolume",label:"Biolume",group:"dark"},{id:"carbon",label:"Carbon",group:"dark"},{id:"paper",label:"Paper",group:"light"},{id:"solarized-light",label:"Solarized Light",group:"light"},{id:"seafoam",label:"Seafoam",group:"light"},{id:"high-contrast",label:"High Contrast",group:"light"},{id:"sakura",label:"Sakura",group:"light"},{id:"citrus",label:"Citrus",group:"light"},{id:"peach",label:"Peach Fuzz",group:"light"},{id:"candy",label:"Cotton Candy",group:"light"},{id:"sky",label:"Clear Sky",group:"light"},{id:"coral",label:"Coral Reef",group:"light"}],pN="obsidian",gm="loadpath.theme";function gN(t){return Sl.some(r=>r.id===t)}function mm(){try{const t=localStorage.getItem(gm)||"";if(gN(t))return t}catch{}return pN}function mN(t){var r;return((r=Sl.find(o=>o.id===t))==null?void 0:r.group)==="light"?"light":"dark"}function ym(t){document.documentElement.dataset.theme=t,document.documentElement.style.colorScheme=mN(t);try{localStorage.setItem(gm,t)}catch{}}const xp=[{id:"review",label:"Review",testId:"tab-review",shortcut:"1",icon:c0},{id:"architecture",label:"Architecture",testId:"tab-architecture",shortcut:"2",icon:d0},{id:"graph",label:"Impact graph",testId:"tab-graph",shortcut:"3",icon:f0},{id:"prs",label:"Pull requests",testId:"tab-prs",shortcut:"4",icon:h0},{id:"settings",label:"Settings",testId:"tab-settings",shortcut:"5",icon:p0}];function yN(t){const r=t.total||0;return r<=0?null:Math.min(100,Math.round(100*(t.done||0)/r))}function Hu(t,r,o){let s;try{s=new URL(t)}catch{return}if(s.protocol!=="https:"||s.username||s.password)return;const a=s.hostname.toLowerCase();a!==r&&!a.endsWith(`.${r}`)||s.pathname.startsWith(o)&&window.open(s.toString(),"_blank","noopener,noreferrer")}function vN(){var Zr,Jr,ei,Tt,Vn,Wn,ti,wr;const[t,r]=O.useState("review"),[o,s]=O.useState(localStorage.getItem("loadpath.repo")||""),[a,u]=O.useState(localStorage.getItem("loadpath.base")||"HEAD~1"),[c,f]=O.useState(localStorage.getItem("loadpath.head")||"HEAD"),[g,y]=O.useState(null),[v,x]=O.useState(null),[m,S]=O.useState([]),[k,j]=O.useState("review"),[b,_]=O.useState(""),[P,N]=O.useState(""),[E,L]=O.useState(null),[A,V]=O.useState(!1),[z,G]=O.useState(""),[ee,J]=O.useState({}),[ne,q]=O.useState([]),[C,W]=O.useState([]),[U,Y]=O.useState(localStorage.getItem("loadpath.scmRepo")||""),[T,F]=O.useState(localStorage.getItem("loadpath.provider")||"github"),[B,M]=O.useState(localStorage.getItem("loadpath.prNumber")||""),[R,re]=O.useState(localStorage.getItem("loadpath.dirty")==="1"),[ie,ce]=O.useState(0),[fe,de]=O.useState(""),[Q,le]=O.useState(mm),[me,ke]=O.useState(!1),[xe,pe]=O.useState(!1),[be,Pe]=O.useState(null),[Ce,Re]=O.useState(null),[tt,nt]=O.useState(!1),[Je,Qe]=O.useState(!1),ot=O.useRef(o);ot.current=o;const Pt=O.useRef(!1);Pt.current=xe;const st=O.useRef(""),ft=D=>{le(D),ym(D)},He=O.useRef(""),Le=D=>{He.current=D,N(D)},mt=D=>{const te=()=>{$e.indexProgress(D).then(Ie=>{He.current&&(Ie.phase&&Ie.phase!=="idle"&&Ie.message&&Le(Ie.message),L(Ie.phase&&Ie.phase!=="idle"?yN(Ie):null))}).catch(()=>{})};te();const _e=window.setInterval(te,250);return()=>{window.clearInterval(_e),L(null)}};O.useEffect(()=>{$e.settings().then(J).catch(()=>{}).finally(()=>ke(!0)),$e.repos().then(D=>S(D.repos)).catch(()=>{})},[]);const an=()=>o.trim()?!0:(_("Point at a local repository path first."),!1);O.useEffect(()=>{if(t!=="architecture"||!o.trim())return;const D=o;let te=!1;return $e.architecture(D).then(_e=>{!te&&ot.current===D&&x(_e)}).catch(()=>{}),()=>{te=!0}},[t,o]);const ht=D=>{ot.current=D,s(D),localStorage.setItem("loadpath.repo",D),D.trim()!==st.current&&(st.current="",Pe(null))},Gt=O.useCallback(D=>{const te=(D??ot.current).trim();return!te||st.current===te?Promise.resolve():(st.current=te,$e.gitRefs(te).then(_e=>{ot.current.trim()===te&&Pe(_e)}).catch(()=>{st.current===te&&(st.current="",Pe(null))}))},[]),_n=(D,te)=>{u(D),f(te),localStorage.setItem("loadpath.base",D),localStorage.setItem("loadpath.head",te)},zn=(D,te,_e)=>{F(D),Y(te),localStorage.setItem("loadpath.provider",D),localStorage.setItem("loadpath.scmRepo",te),_e!==void 0&&(M(_e),localStorage.setItem("loadpath.prNumber",_e))},Gr=D=>D==="github"?!!ee.github_token_set:D==="gitlab"?!!ee.gitlab_token_set:!!ee.bitbucket_token_set,It=O.useCallback(async(D=T)=>{var te;try{const _e=await $e.scmRepos(D);W(_e.repos),(te=_e.user)!=null&&te.login&&J(Ie=>({...Ie,...D==="github"?{github_user:_e.user.login}:D==="gitlab"?{gitlab_user:_e.user.login}:{bitbucket_user:_e.user.login}}))}catch{W([])}},[T]);O.useEffect(()=>{if(t!=="prs")return;let D=!1;return It(T).catch(()=>{D||W([])}),()=>{D=!0}},[t,T,It]),O.useEffect(()=>{if(!Ce)return;let D=!1,te=0;const _e=async()=>{try{const Ie=await $e.githubOAuthPoll(Ce.flow_id);if(D)return;if(Ie.status==="complete"){Re(null);const Me=await $e.settings();J(Me),G(Ie.user?`Signed in to GitHub as ${Ie.user}`:"Signed in to GitHub"),It("github");return}if(Ie.status==="pending"||Ie.status==="slow_down"){te=window.setTimeout(_e,Math.max(Ie.interval||Ce.interval,5)*1e3);return}Re(null),_(Ie.status==="denied"?"GitHub sign-in was denied.":"GitHub sign-in expired. Try again.")}catch(Ie){if(D)return;Re(null),_(Ie instanceof Error?Ie.message:String(Ie))}};return te=window.setTimeout(_e,Math.max(Ce.interval,5)*1e3),()=>{D=!0,window.clearTimeout(te)}},[Ce,It]),O.useEffect(()=>{if(!tt)return;let D=!1,te=0;const _e=Date.now(),Ie=async()=>{try{const Me=await $e.oauthStatus();if(D)return;if(Me.bitbucket.connected){nt(!1);const Fe=await $e.settings();J(Fe),G(Me.bitbucket.user?`Signed in to Bitbucket as ${Me.bitbucket.user}`:"Signed in to Bitbucket"),It("bitbucket");return}if(Date.now()-_e>18e4){nt(!1),_("Bitbucket sign-in timed out. Finish in the browser, or try again.");return}te=window.setTimeout(Ie,1500)}catch(Me){if(D)return;nt(!1),_(Me instanceof Error?Me.message:String(Me))}};return te=window.setTimeout(Ie,1500),()=>{D=!0,window.clearTimeout(te)}},[tt,It]),O.useEffect(()=>{if(!Je)return;let D=!1,te=0;const _e=Date.now(),Ie=async()=>{try{const Me=await $e.oauthStatus();if(D)return;if(Me.gitlab.connected){Qe(!1);const Fe=await $e.settings();J(Fe),G(Me.gitlab.user?`Signed in to GitLab as ${Me.gitlab.user}`:"Signed in to GitLab"),It("gitlab");return}if(Date.now()-_e>18e4){Qe(!1),_("GitLab sign-in timed out. Finish in the browser, or try again.");return}te=window.setTimeout(Ie,1500)}catch(Me){if(D)return;Qe(!1),_(Me instanceof Error?Me.message:String(Me))}};return te=window.setTimeout(Ie,1500),()=>{D=!0,window.clearTimeout(te)}},[Je,It]);const Sn=async(D=o)=>{if(!D.trim())return null;const te=await $e.architecture(D);return ot.current===D&&x(te),te},Dn=async D=>{const te=D.trim();if(!(!te||te===ot.current)){if(He.current){_("Wait for the current job to finish before switching workspace.");return}_(""),G(""),y(null),x(null),j("architecture"),ht(te),V(!0),Le(`Loading ${u0(te)}…`);try{await Promise.all([Sn(te),Gt(te)])}catch(_e){ot.current===te&&_(_e instanceof Error?_e.message:String(_e))}finally{ot.current===te&&(Le(""),V(!1))}}},un=async()=>{if(He.current||!an())return;_(""),G(""),Le("Tracing load path…"),ht(o),_n(a,c);const D=mt(o);try{const te=await $e.review(o,a,c,!0,R);y(te),ce(0),j("review"),r("review"),await $e.repos().then(_e=>S(_e.repos)).catch(()=>{}),await Sn(o)}catch(te){_(te instanceof Error?te.message:String(te))}finally{D(),Le("")}},$n=async(D=!0)=>{if(He.current||!an())return;_(""),G(""),Le(D?"Indexing…":"Full reindex…"),ht(o);const te=mt(o);try{await $e.index(o,D);const _e=await Sn(o);await $e.repos().then(Ie=>S(Ie.repos)).catch(()=>{}),_e!=null&&_e.indexed&&(j("architecture"),r("architecture"))}catch(_e){_(_e instanceof Error?_e.message:String(_e))}finally{te(),Le("")}},gr=async()=>{if(!He.current&&an()){_(""),G(""),Le("Detecting layout…"),ht(o);try{const D=await $e.init(o);G(D.message),await $e.repos().then(te=>S(te.repos)).catch(()=>{})}catch(D){_(D instanceof Error?D.message:String(D))}finally{Le("")}}},cn=async()=>{if(g!=null&&g.markdown)try{await navigator.clipboard.writeText(g.markdown),G("Copied markdown brief")}catch(D){_(D instanceof Error?D.message:String(D))}},dn=async()=>{if(!He.current){if(!(g!=null&&g.markdown)||!U||!B){_("Pick a pull request first (Pull requests tab), then post the brief.");return}Le("Posting Loadpath brief…");try{const D=await $e.postComment(T,U,Number(B),g.markdown);G(D.updated?"Updated the Loadpath PR comment":"Posted the Loadpath PR comment")}catch(D){_(D instanceof Error?D.message:String(D))}finally{Le("")}}},Xr=async()=>{if(!He.current){_(""),Le("Fetching pull requests…");try{const D=await $e.prs(T,U);q(D.pull_requests);const te=C.find(_e=>_e.slug.toLowerCase()===U.trim().toLowerCase());te!=null&&te.local_path&&ht(te.local_path)}catch(D){_(D instanceof Error?D.message:String(D))}finally{Le("")}}},qr=async()=>{_("");try{const D=await $e.githubOAuthStart();Re(D),Hu(D.verification_uri_complete,"github.com","/login/device")}catch(D){_(D instanceof Error?D.message:String(D))}},Kr=async()=>{_("");try{const D=await $e.bitbucketOAuthStart();nt(!0),Hu(D.authorize_url,"bitbucket.org","/site/oauth2/authorize")}catch(D){nt(!1),_(D instanceof Error?D.message:String(D))}},Qr=async()=>{_("");try{const D=await $e.gitlabOAuthStart();Qe(!0),Hu(D.authorize_url,new URL(D.authorize_url).hostname,"/oauth/authorize")}catch(D){Qe(!1),_(D instanceof Error?D.message:String(D))}},On=async D=>{if(!(He.current||!o.trim())){_(""),Le("Walking what-if path…");try{const te=await $e.whatIf(o,D);G(`${te.title} — ${te.confidence.level} · ${(te.sinks||[]).length} sinks`),y({...te,markdown:te.markdown||"",index:te.index||(g==null?void 0:g.index),workspace:te.workspace||(g==null?void 0:g.workspace)}),ce(0),j("review"),r("review")}catch(te){_(te instanceof Error?te.message:String(te))}finally{Le("")}}},mr=async D=>{if(He.current)return;zn(D.provider,D.repo,String(D.number));const te=C.find(Me=>Me.slug.toLowerCase()===D.repo.toLowerCase());te!=null&&te.local_path&&ht(te.local_path),_(""),Le(`Fetching ${D.provider} #${D.number}…`);const _e=(te==null?void 0:te.local_path)||o,Ie=_e?mt(_e):()=>{};try{const Me=await $e.reviewPr(D.provider,D.repo,D.number,(te==null?void 0:te.local_path)||o||void 0);y(Me),ce(0),Me.pull_request&&typeof Me.pull_request.repo_path=="string"&&ht(Me.pull_request.repo_path),_n(String(Me.base||D.target_branch),String(Me.head||D.source_branch)),j("review"),r("review")}catch(Me){_n(D.base_sha||D.target_branch,D.head_sha||D.source_branch),r("review"),_(Me instanceof Error?Me.message:String(Me))}finally{Ie(),Le("")}},Fn=async D=>{_("");try{J(await $e.oauthDisconnect(D)),T===D&&W([]),G(`Disconnected ${D}`)}catch(te){_(te instanceof Error?te.message:String(te))}},kn=async D=>{D.preventDefault();const te=new FormData(D.currentTarget),_e={github_token:String(te.get("github_token")||""),github_oauth_client_id:String(te.get("github_oauth_client_id")||""),github_host:String(te.get("github_host")||""),gitlab_token:String(te.get("gitlab_token")||""),gitlab_host:String(te.get("gitlab_host")||""),gitlab_oauth_client_id:String(te.get("gitlab_oauth_client_id")||""),gitlab_oauth_client_secret:String(te.get("gitlab_oauth_client_secret")||""),bitbucket_token:String(te.get("bitbucket_token")||""),bitbucket_username:String(te.get("bitbucket_username")||""),bitbucket_oauth_client_id:String(te.get("bitbucket_oauth_client_id")||""),bitbucket_oauth_client_secret:String(te.get("bitbucket_oauth_client_secret")||""),ai_provider:String(te.get("ai_provider")||"none"),ai_api_key:String(te.get("ai_api_key")||""),ai_model:String(te.get("ai_model")||""),ai_base_url:String(te.get("ai_base_url")||"")},Ie=m.length?{..._e,workspaces:m.map(Me=>({path:Me.path,name:Me.name}))}:_e;try{J(await $e.saveSettings(Ie)),G("Settings saved on this machine")}catch(Me){_(Me instanceof Error?Me.message:String(Me))}},yr=async()=>{if(!(!g||He.current)){Le("Residual analysis…");try{const D=await $e.residual(g);de(D.note)}catch(D){_(D instanceof Error?D.message:String(D))}finally{Le("")}}},fn=O.useRef(un);fn.current=un;const vr=O.useRef(t);vr.current=t,O.useEffect(()=>{const D=te=>{if(Pt.current){te.key==="Escape"&&(te.preventDefault(),pe(!1));return}const _e=te.target;if(_e&&(_e.tagName==="INPUT"||_e.tagName==="TEXTAREA"||_e.tagName==="SELECT"||_e.isContentEditable)){te.key==="Escape"&&_e.blur();return}if(te.key==="Escape"){_(""),G("");return}const Ie=xp.find(Me=>Me.shortcut===te.key);if(Ie&&!te.metaKey&&!te.ctrlKey&&!te.altKey&&r(Ie.id),(te.metaKey||te.ctrlKey)&&te.key==="Enter"){if(vr.current==="settings"||vr.current==="prs"||He.current)return;te.preventDefault(),fn.current()}};return window.addEventListener("keydown",D),()=>window.removeEventListener("keydown",D)},[]);const hn=O.useMemo(()=>k==="architecture"?(v==null?void 0:v.nodes)??[]:(g==null?void 0:g.nodes)??[],[k,v,g]),Hn=O.useMemo(()=>k==="architecture"?(v==null?void 0:v.edges)??[]:(g==null?void 0:g.edges)??[],[k,v,g]),Bn=g!=null&&g.index?`${g.index.counts.nodes} nodes · ${g.index.counts.edges} edges`:v!=null&&v.indexed?`${v.counts.nodes} nodes · ${v.counts.edges} edges`:"Not indexed",xr=((g==null?void 0:g.findings)||[]).filter(D=>!D.waived);return h.jsxs("div",{className:"app",children:[h.jsx("a",{className:"skip",href:"#main",children:"Skip to content"}),h.jsxs("nav",{className:"rail","data-testid":"rail","aria-label":"Primary",children:[h.jsxs("div",{className:"brand",children:[h.jsx("div",{className:"brand-mark",children:"Loadpath"}),h.jsx("div",{className:"brand-sub",children:"Load-path review"})]}),xp.map(D=>{const te=D.icon,_e=t===D.id;return h.jsxs("button",{type:"button","data-testid":D.testId,className:_e?"nav-item active":"nav-item","aria-current":_e?"page":void 0,"aria-label":D.label,onClick:()=>r(D.id),children:[h.jsx(te,{}),h.jsx("span",{children:D.label})]},D.id)}),h.jsxs("div",{className:"theme-pick",children:[h.jsx("label",{htmlFor:"theme-select",children:"Theme"}),h.jsx("select",{id:"theme-select","data-testid":"theme-select",value:Q,onChange:D=>ft(D.target.value),children:["dark","light"].map(D=>h.jsx("optgroup",{label:D==="dark"?"Dark":"Light",children:Sl.filter(te=>te.group===D).map(te=>h.jsx("option",{value:te.id,children:te.label},te.id))},D))})]}),h.jsxs("div",{className:"rail-foot",children:[h.jsx("div",{className:"muted",role:"status",children:P||Bn}),h.jsxs("div",{className:"kbd-hint",children:[h.jsx("kbd",{children:"1"}),"–",h.jsx("kbd",{children:"5"})," tabs · ",h.jsx("kbd",{children:"Ctrl"}),"+",h.jsx("kbd",{children:"Enter"})," review"]})]})]}),h.jsxs("div",{className:"main",id:"main",children:[P?h.jsxs("div",{className:E!=null?"progress determinate":"progress",role:"status","aria-live":"polite","aria-busy":"true","data-testid":"progress",children:[h.jsx("i",{style:E!=null?{width:`${E}%`}:void 0}),h.jsx("span",{className:"sr-only",children:P})]}):null,h.jsxs("header",{className:"topbar","data-testid":"topbar",children:[m.length>0?h.jsxs("label",{className:"field workspace",children:[h.jsx("span",{children:"Workspace"}),h.jsxs("select",{"data-testid":"workspace-select",value:m.some(D=>D.path===o)?o:"",disabled:!!P,"aria-busy":A,onChange:D=>{D.target.value&&Dn(D.target.value)},children:[h.jsx("option",{value:"",children:"Indexed repos…"}),m.map(D=>h.jsxs("option",{value:D.path,children:[D.name,D.indexed?` (${D.counts.nodes})`:""]},D.path))]})]}):null,h.jsxs("label",{className:"field path",children:[h.jsx("span",{children:"Repository"}),h.jsxs("div",{className:"path-row",children:[h.jsx("input",{"data-testid":"repo-path",placeholder:"Local monorepo path",value:o,onChange:D=>{const te=D.target.value;s(te),te.trim()!==st.current&&(st.current="",Pe(null))},spellCheck:!1}),h.jsx("button",{type:"button",className:"icon-btn","data-testid":"btn-browse-repo","aria-label":"Browse for a local repository",onClick:()=>pe(!0),children:h.jsx(kp,{})})]})]}),h.jsxs("label",{className:"field ref",children:[h.jsx("span",{children:"Base"}),h.jsx(vp,{testId:"base-ref",menuTestId:"base-ref-menu",value:a,onChange:D=>_n(D,c),placeholder:"base",refs:be,onNeedRefs:Gt})]}),h.jsxs("label",{className:"field ref",children:[h.jsx("span",{children:"Head"}),h.jsx(vp,{testId:"head-ref",menuTestId:"head-ref-menu",value:c,onChange:D=>_n(a,D),placeholder:"head",refs:be,onNeedRefs:Gt})]}),h.jsxs("label",{className:"field dirty",children:[h.jsx("span",{children:"Working tree"}),h.jsx("button",{type:"button",className:R?"chip-btn active":"chip-btn","data-testid":"btn-dirty","aria-pressed":R,onClick:()=>{const D=!R;re(D),localStorage.setItem("loadpath.dirty",D?"1":"0")},children:R?"Include uncommitted":"Committed range"})]}),h.jsxs("div",{className:"topbar-actions",children:[h.jsx("button",{type:"button","data-testid":"btn-init",disabled:!!P,onClick:gr,children:"Draft config"}),h.jsx("button",{type:"button","data-testid":"btn-index",disabled:!!P,onClick:()=>$n(!0),children:"Index"}),h.jsx("button",{type:"button","data-testid":"btn-review",className:"btn primary",disabled:!!P,onClick:un,children:"Review"})]})]}),h.jsxs("div",{className:"alerts",children:[b?h.jsxs("div",{className:"error","data-testid":"error",role:"alert",children:[h.jsx("span",{children:b}),h.jsx("button",{type:"button",className:"dismiss",onClick:()=>_(""),"aria-label":"Dismiss error",children:"×"})]}):null,z?h.jsxs("div",{className:"banner","data-testid":"status-note",children:[h.jsx("span",{children:z}),h.jsx("button",{type:"button",className:"dismiss",onClick:()=>G(""),"aria-label":"Dismiss",children:"×"})]}):null,((Zr=g==null?void 0:g.index)!=null&&Zr.stale||v!=null&&v.stale)&&(t==="review"||t==="architecture")?h.jsx("div",{className:"banner stale","data-testid":"index-stale",children:"Index is stale — files changed since the last extract. Index again before trusting this walk."}):null,((Jr=g==null?void 0:g.index)==null?void 0:Jr.django_boot)==="failed"||(v==null?void 0:v.django_boot)==="failed"?h.jsx("div",{className:"banner warn","data-testid":"django-boot-failed",children:((ei=g==null?void 0:g.index)==null?void 0:ei.django_boot_detail)||(v==null?void 0:v.django_boot_detail)||"django.setup() failed"}):null,(Tt=g==null?void 0:g.workspace)!=null&&Tt.dirty_overlaps_review&&t==="review"?h.jsxs("div",{className:"banner warn","data-testid":"dirty-tree",children:["Uncommitted files overlap this review: ",(g.workspace.dirty_overlap||[]).slice(0,6).join(", ")]}):null]}),h.jsxs("div",{className:"stage","aria-busy":A,children:[A?h.jsxs("div",{className:"empty workspace-loading","data-testid":"workspace-loading",children:[h.jsx("h2",{children:P}),h.jsx("p",{children:"Fetching the indexed graph for this repository."})]}):null,!A&&t==="review"&&h.jsxs("div",{className:"content","data-testid":"review-layout",children:[h.jsx("aside",{className:"brief","data-testid":"brief",children:g?h.jsx(xN,{review:g,findings:xr,aiNote:fe,busy:!!P,tourIndex:ie,onTour:ce,onAskAi:yr,onCopy:cn,onPost:dn}):h.jsxs("div",{className:"empty","data-testid":"review-empty",children:[h.jsx("h2",{children:"Trace the force of this diff"}),h.jsx("p",{children:"The graph is the architecture. The brief is where this change travels — not a hunk list."}),h.jsxs("ol",{children:[h.jsx("li",{children:"Point at a Django + React monorepo, or pick an indexed workspace."}),h.jsxs("li",{children:["Index it. Missing ",h.jsx("code",{children:"loadpath.yml"})," is drafted from ",h.jsx("code",{children:"manage.py"})," and"," ",h.jsx("code",{children:"src/features"}),"."]}),h.jsx("li",{children:"Review a git range, or open a pull request so base/head become a three-dot merge-base."})]})]})}),h.jsx("div",{className:"graph-wrap","data-testid":"review-graph",children:g?h.jsx(Fu,{nodes:g.nodes,edges:g.edges,onWhatIf:On,focusPath:(Vn=g.read_order[ie])==null?void 0:Vn.path}):null})]}),!A&&t==="architecture"&&h.jsxs("div",{className:"content","data-testid":"architecture-panel",children:[h.jsx("aside",{className:"brief","data-testid":"architecture-brief",children:v!=null&&v.indexed?h.jsx(wN,{architecture:v,busy:!!P,onReindex:()=>$n(!1),onReview:un}):h.jsx("p",{className:"muted","data-testid":"architecture-empty",children:"Index this repo to build the architecture graph. Review then walks that same graph for a git range — it does not start from a hunk list."})}),h.jsx("div",{className:"graph-wrap","data-testid":"architecture-graph",children:v!=null&&v.indexed?h.jsx(Fu,{nodes:v.nodes,edges:v.edges,onWhatIf:On}):null})]}),!A&&t==="graph"&&h.jsxs("div",{className:"graph-wrap","data-testid":"graph-full",style:{height:"100%"},children:[h.jsxs("div",{className:"graph-modes",children:[h.jsxs("div",{className:"seg","aria-label":"Graph scope",children:[h.jsx("button",{type:"button","aria-pressed":k==="review","data-testid":"graph-mode-review",className:k==="review"?"active":"",onClick:()=>j("review"),children:"This review"}),h.jsx("button",{type:"button","aria-pressed":k==="architecture","data-testid":"graph-mode-architecture",className:k==="architecture"?"active":"",onClick:()=>j("architecture"),children:"Indexed architecture"})]}),h.jsxs("div",{className:"legend","aria-hidden":"true",children:[h.jsxs("span",{children:[h.jsx("i",{})," cheap"]}),h.jsxs("span",{children:[h.jsx("i",{className:"exp"})," expensive"]}),h.jsxs("span",{children:[h.jsx("i",{className:"crit"})," critical"]}),h.jsxs("span",{children:[h.jsx("i",{className:"dash"})," inferred"]})]})]}),hn.length?h.jsx(Fu,{nodes:hn,edges:Hn,onWhatIf:On}):h.jsx("p",{className:"empty","data-testid":"graph-empty",children:"Index the repo or run a review first. Click a node to inspect it."})]}),!A&&t==="prs"&&h.jsxs("div",{className:"pr-list","data-testid":"pr-list",children:[h.jsxs("div",{className:"pr-toolbar",children:[h.jsxs("label",{className:"field provider",children:[h.jsx("span",{children:"Provider"}),h.jsxs("select",{"data-testid":"pr-provider",value:T,onChange:D=>zn(D.target.value,U,B),children:[h.jsx("option",{value:"github",children:"GitHub"}),h.jsx("option",{value:"gitlab",children:"GitLab"}),h.jsx("option",{value:"bitbucket",children:"Bitbucket"})]})]}),h.jsxs("label",{className:"field",children:[h.jsx("span",{children:"Repository"}),h.jsx("input",{"data-testid":"pr-repo",placeholder:C.length?"Search your repos":"owner/repo",value:U,onChange:D=>zn(T,D.target.value,B),list:"scm-repos",spellCheck:!1}),h.jsx("datalist",{id:"scm-repos",children:C.map(D=>h.jsxs("option",{value:D.slug,children:[D.private?"private":"public",D.local_path?" · local":""]},D.slug))})]}),h.jsx("button",{type:"button","data-testid":"btn-refresh-repos",className:"btn",disabled:!!P||!Gr(T),onClick:()=>{It(T)},children:"My repos"}),h.jsx("button",{type:"button","data-testid":"btn-list-prs",className:"btn",disabled:!!P,onClick:Xr,children:"List PRs"})]}),C.length>0?h.jsxs("p",{className:"muted scm-count","data-testid":"scm-repo-count",children:[C.length," ",T," repositor",C.length===1?"y":"ies",T==="github"&&ee.github_user?` · @${String(ee.github_user)}`:"",T==="gitlab"&&ee.gitlab_user?` · @${String(ee.gitlab_user)}`:"",T==="bitbucket"&&ee.bitbucket_user?` · ${String(ee.bitbucket_user)}`:""]}):null,ne.length===0?h.jsxs("div",{className:"empty","data-testid":"pr-empty",children:[h.jsx("h2",{children:"No pull requests loaded"}),h.jsx("p",{children:"Sign in under Settings (or paste a token), load your repositories, then list open PRs. Reviewing a PR fills base and head from its SHAs."})]}):ne.map(D=>h.jsxs("article",{className:"pr","data-testid":`pr-${D.number}`,children:[h.jsxs("h3",{children:["#",D.number," ",D.title]}),h.jsxs("div",{className:"pr-meta muted",children:[h.jsx("span",{className:`chip ${D.draft?"":"open"}`,children:D.draft?"draft":D.state}),h.jsx("span",{children:D.author}),h.jsxs("span",{children:[D.source_branch," → ",D.target_branch]})]}),h.jsxs("div",{className:"pr-actions",children:[h.jsxs("a",{href:D.url,target:"_blank",rel:"noreferrer",children:["Open on ",D.provider]}),h.jsx("button",{type:"button",className:"btn primary","data-testid":`pr-review-${D.number}`,onClick:()=>void mr(D),children:"Review this PR"})]})]},`${D.provider}-${D.number}`))]}),!A&&t==="settings"&&me&&h.jsxs("form",{className:"settings","data-testid":"settings-form",onSubmit:kn,children:[h.jsxs("div",{children:[h.jsx("h1",{children:"Settings"}),h.jsx("p",{className:"muted",children:"Tokens stay on this machine in ~/.loadpath/settings.json. AI runs only on residual uncertainty the graph could not close."})]}),h.jsxs("section",{className:"settings-card",children:[h.jsx("h2",{children:"Appearance"}),h.jsx("p",{className:"muted",children:"Local to this browser. High contrast is a first-class theme, not an afterthought."}),h.jsx("div",{className:"theme-grid","data-testid":"theme-grid",children:Sl.map(D=>h.jsxs("button",{type:"button","data-theme":D.id,className:Q===D.id?"theme-swatch active":"theme-swatch","data-testid":`theme-${D.id}`,onClick:()=>ft(D.id),children:[h.jsx("div",{className:"swatch-bar","aria-hidden":"true"}),h.jsx("div",{className:"name",children:D.label}),h.jsx("div",{className:"group",children:D.group})]},D.id))})]}),h.jsxs("section",{className:"settings-card",children:[h.jsx("h2",{children:"Source control"}),h.jsx("p",{className:"muted",children:"Sign in with OAuth to list every repository the account can access. Tokens stay in ~/.loadpath/settings.json. A classic PAT still works if you prefer not to register an OAuth app."}),h.jsxs("div",{className:"scm-login","data-testid":"scm-github",children:[h.jsxs("div",{children:[h.jsx("strong",{children:"GitHub"}),h.jsx("p",{className:"muted",children:ee.github_token_set?ee.github_user?`Signed in as @${String(ee.github_user)}`:"Token saved on this machine":"Not connected"})]}),h.jsx("div",{className:"btn-row",children:ee.github_token_set?h.jsx("button",{type:"button",className:"btn","data-testid":"btn-github-disconnect",onClick:()=>void Fn("github"),children:"Disconnect"}):h.jsx("button",{type:"button",className:"btn primary","data-testid":"btn-github-login",disabled:!!Ce||!ee.github_oauth_ready,onClick:()=>void qr(),children:Ce?"Waiting for GitHub…":"Sign in with GitHub"})})]}),Ce?h.jsxs("p",{className:"oauth-code","data-testid":"github-user-code",children:["Enter ",h.jsx("code",{children:Ce.user_code})," at GitHub if the browser did not fill it in."]}):null,ee.github_oauth_ready?null:h.jsx("p",{className:"muted",children:"Sign-in needs a GitHub OAuth App with Device Flow enabled. Set LOADPATH_GITHUB_CLIENT_ID or paste the client ID below."}),h.jsx("label",{htmlFor:"github_oauth_client_id",children:"GitHub OAuth client ID"}),h.jsx("input",{id:"github_oauth_client_id",name:"github_oauth_client_id","data-testid":"github-oauth-client-id",placeholder:"Ov23…",defaultValue:String(ee.github_oauth_client_id||""),autoComplete:"off"}),h.jsx("label",{htmlFor:"github_token",children:"GitHub token (optional PAT)"}),h.jsx("input",{id:"github_token",name:"github_token",type:"password",placeholder:"ghp_…",autoComplete:"off"}),h.jsx("label",{htmlFor:"github_host",children:"GitHub host (Enterprise)"}),h.jsx("input",{id:"github_host",name:"github_host","data-testid":"github-host",placeholder:"github.com",defaultValue:String(ee.github_host||""),autoComplete:"off"}),h.jsxs("div",{className:"scm-login","data-testid":"scm-gitlab",children:[h.jsxs("div",{children:[h.jsx("strong",{children:"GitLab"}),h.jsx("p",{className:"muted",children:ee.gitlab_token_set?ee.gitlab_user?`Signed in as @${String(ee.gitlab_user)}`:"Token saved on this machine":"Not connected"})]}),h.jsx("div",{className:"btn-row",children:ee.gitlab_token_set?h.jsx("button",{type:"button",className:"btn","data-testid":"btn-gitlab-disconnect",onClick:()=>void Fn("gitlab"),children:"Disconnect"}):h.jsx("button",{type:"button",className:"btn primary","data-testid":"btn-gitlab-login",disabled:Je||!ee.gitlab_oauth_ready,onClick:()=>void Qr(),children:Je?"Waiting for GitLab…":"Sign in with GitLab"})})]}),h.jsx("label",{htmlFor:"gitlab_host",children:"GitLab host"}),h.jsx("input",{id:"gitlab_host",name:"gitlab_host","data-testid":"gitlab-host",placeholder:"gitlab.com",defaultValue:String(ee.gitlab_host||""),autoComplete:"off"}),h.jsx("label",{htmlFor:"gitlab_oauth_client_id",children:"GitLab OAuth application ID"}),h.jsx("input",{id:"gitlab_oauth_client_id",name:"gitlab_oauth_client_id","data-testid":"gitlab-oauth-client-id",defaultValue:String(ee.gitlab_oauth_client_id||""),autoComplete:"off"}),h.jsx("label",{htmlFor:"gitlab_oauth_client_secret",children:"GitLab OAuth secret"}),h.jsx("input",{id:"gitlab_oauth_client_secret",name:"gitlab_oauth_client_secret",type:"password",autoComplete:"off"}),h.jsx("label",{htmlFor:"gitlab_token",children:"GitLab token (optional PAT)"}),h.jsx("input",{id:"gitlab_token",name:"gitlab_token",type:"password",placeholder:"glpat-…",autoComplete:"off"}),h.jsxs("div",{className:"scm-login","data-testid":"scm-bitbucket",children:[h.jsxs("div",{children:[h.jsx("strong",{children:"Bitbucket"}),h.jsx("p",{className:"muted",children:ee.bitbucket_token_set?ee.bitbucket_user?`Signed in as ${String(ee.bitbucket_user)}`:"Token saved on this machine":"Not connected"})]}),h.jsx("div",{className:"btn-row",children:ee.bitbucket_token_set?h.jsx("button",{type:"button",className:"btn","data-testid":"btn-bitbucket-disconnect",onClick:()=>void Fn("bitbucket"),children:"Disconnect"}):h.jsx("button",{type:"button",className:"btn primary","data-testid":"btn-bitbucket-login",disabled:tt||!ee.bitbucket_oauth_ready,onClick:()=>void Kr(),children:tt?"Waiting for Bitbucket…":"Sign in with Bitbucket"})})]}),ee.bitbucket_oauth_ready?null:h.jsxs("p",{className:"muted",children:["Sign-in needs a Bitbucket OAuth consumer (key + secret). Callback URL:"," ",h.jsx("code",{children:"/api/oauth/bitbucket/callback"})," on this app origin."]}),h.jsx("label",{htmlFor:"bitbucket_oauth_client_id",children:"Bitbucket OAuth key"}),h.jsx("input",{id:"bitbucket_oauth_client_id",name:"bitbucket_oauth_client_id","data-testid":"bitbucket-oauth-client-id",defaultValue:String(ee.bitbucket_oauth_client_id||""),autoComplete:"off"}),h.jsx("label",{htmlFor:"bitbucket_oauth_client_secret",children:"Bitbucket OAuth secret"}),h.jsx("input",{id:"bitbucket_oauth_client_secret",name:"bitbucket_oauth_client_secret",type:"password",autoComplete:"off"}),h.jsx("label",{htmlFor:"bitbucket_token",children:"Bitbucket token (optional app password)"}),h.jsx("input",{id:"bitbucket_token",name:"bitbucket_token",type:"password",autoComplete:"off"}),h.jsx("label",{htmlFor:"bitbucket_username",children:"Bitbucket username (app passwords)"}),h.jsx("input",{id:"bitbucket_username",name:"bitbucket_username",defaultValue:String(ee.bitbucket_username||"")})]}),h.jsxs("section",{className:"settings-card",children:[h.jsx("h2",{children:"Residual AI"}),h.jsx("label",{htmlFor:"ai_provider",children:"Provider"}),h.jsxs("select",{id:"ai_provider",name:"ai_provider",defaultValue:String(((Wn=ee.ai)==null?void 0:Wn.provider)||"none"),children:[h.jsx("option",{value:"none",children:"none (graph only)"}),h.jsx("option",{value:"anthropic",children:"Anthropic"}),h.jsx("option",{value:"openai",children:"OpenAI"}),h.jsx("option",{value:"grok",children:"Grok / xAI"}),h.jsx("option",{value:"deepseek",children:"DeepSeek"}),h.jsx("option",{value:"cursor",children:"Cursor-compatible (OpenAI protocol)"}),h.jsx("option",{value:"ollama",children:"Ollama local"})]}),h.jsx("label",{htmlFor:"ai_api_key",children:"API key"}),h.jsx("input",{id:"ai_api_key",name:"ai_api_key",type:"password",autoComplete:"off"}),h.jsx("label",{htmlFor:"ai_model",children:"Model"}),h.jsx("input",{id:"ai_model",name:"ai_model","data-testid":"ai-model",placeholder:"optional override",defaultValue:String(((ti=ee.ai)==null?void 0:ti.model)||"")}),h.jsx("label",{htmlFor:"ai_base_url",children:"Base URL"}),h.jsx("input",{id:"ai_base_url",name:"ai_base_url","data-testid":"ai-base-url",placeholder:"optional, OpenAI-compatible",defaultValue:String(((wr=ee.ai)==null?void 0:wr.base_url)||"")}),h.jsx("button",{className:"btn primary",type:"submit","data-testid":"btn-save-settings",children:"Save"})]})]})]})]}),xe?h.jsx(hN,{initialPath:o,onClose:()=>pe(!1),onSelect:D=>{if(He.current){_("Wait for the current job to finish before switching workspace.");return}pe(!1),Dn(D)}}):null]})}function xN({review:t,findings:r,aiNote:o,busy:s,tourIndex:a,onTour:u,onAskAi:c,onCopy:f,onPost:g}){var v,x,m,S,k,j,b,_,P,N,E,L,A,V;const y=[...new Set(t.confidence.reasons||[])];return h.jsxs(h.Fragment,{children:[h.jsxs("div",{className:`merge-box ${t.confidence.level}`,children:[h.jsxs("div",{className:`level ${t.confidence.level}`,children:[t.confidence.level.toUpperCase()," — ",t.title]}),y.length?h.jsx("ul",{className:"reasons",children:y.map(z=>h.jsx("li",{children:z},z))}):null,t.low_risk?h.jsx("span",{className:"chip",children:"low-risk"}):null,t.change_kinds.map(z=>h.jsx("span",{className:"chip",children:bo(z)},z)),(v=t.contract_break)!=null&&v.kind&&t.contract_break.kind!=="none"?h.jsxs("span",{className:`chip ${t.contract_break.kind==="breaking"?"blocker":""}`,"data-testid":"contract-kind",children:["contract ",t.contract_break.kind]}):null]}),h.jsxs("div",{className:"metrics",children:[h.jsxs("div",{className:"metric",children:[h.jsxs("div",{className:"n",children:[t.confidence.covered_sinks,"/",t.confidence.sinks]}),h.jsx("div",{className:"l",children:"Sinks tested"})]}),h.jsxs("div",{className:"metric",children:[h.jsx("div",{className:"n",children:r.length}),h.jsx("div",{className:"l",children:"Findings"})]}),h.jsxs("div",{className:"metric",children:[h.jsx("div",{className:"n",children:t.residuals.length}),h.jsx("div",{className:"l",children:"Residuals"})]})]}),h.jsx("pre",{className:"headline",children:t.headline}),t.index?h.jsxs("details",{className:"section",open:!0,children:[h.jsxs("summary",{children:["Index ",h.jsx("span",{className:"count",children:t.index.counts.nodes})]}),h.jsxs("div",{className:"muted",children:["Walked ",t.index.counts.nodes," nodes / ",t.index.counts.edges," edges",t.index.reindex_skipped?" from an unchanged index":t.index.reindexed?" after an incremental refresh":" from the existing index",t.index.django_boot&&t.index.django_boot!=="off"?` · Django boot ${t.index.django_boot}`:"",(x=t.workspace)!=null&&x.three_dot?" · three-dot range":""]})]}):null,h.jsxs("details",{className:"section",open:!0,children:[h.jsxs("summary",{children:["Read this ",h.jsx("span",{className:"count",children:t.read_order.length})]}),t.read_order.map((z,G)=>h.jsxs("div",{className:G===a?"read-item tour-current":"read-item",children:[h.jsxs("span",{className:"file",children:[G+1,". ",z.path]}),h.jsx("div",{className:"why",children:z.why})]},z.path)),t.read_order.length>0?h.jsxs("div",{className:"btn-row tour-row",children:[h.jsx("button",{type:"button",className:"btn","data-testid":"btn-tour-prev",disabled:a<=0,onClick:()=>u(Math.max(0,a-1)),children:"Previous"}),h.jsx("button",{type:"button",className:"btn primary","data-testid":"btn-tour-next",disabled:a>=t.read_order.length-1,onClick:()=>u(Math.min(t.read_order.length-1,a+1)),children:"Next in read order"}),h.jsxs("span",{className:"muted",children:[a+1,"/",t.read_order.length]})]}):null]}),h.jsxs("details",{className:"section",children:[h.jsxs("summary",{children:["Clusters ",h.jsx("span",{className:"count",children:t.clusters.length})]}),t.clusters.map(z=>h.jsxs("div",{className:"muted",children:[h.jsx("strong",{children:z.title})," — ",z.files.join(", ")]},z.id))]}),h.jsxs("details",{className:"section",open:!0,children:[h.jsxs("summary",{children:["Architecture ",h.jsx("span",{className:"count",children:r.length})]}),r.length===0?h.jsx("div",{className:"muted",children:t.architecture_note}):r.map(z=>h.jsxs("div",{className:"finding",children:[h.jsx("span",{className:`chip ${z.severity}`,children:z.severity}),z.message]},z.rule+z.message))]}),h.jsx(vm,{cards:t.deepening}),(S=(m=t.contract_break)==null?void 0:m.reasons)!=null&&S.length?h.jsxs("details",{className:"section",open:!0,children:[h.jsxs("summary",{children:["Contract ",h.jsx("span",{className:"count",children:t.contract_break.kind})]}),t.contract_break.reasons.map(z=>h.jsx("div",{className:"muted",children:z},z))]}):null,(k=t.auth)!=null&&k.note?h.jsxs("details",{className:"section",open:!0,children:[h.jsx("summary",{children:"Auth"}),h.jsx("div",{className:"muted",children:t.auth.note}),(t.auth.missing_permissions||[]).map(z=>h.jsxs("div",{className:"finding",children:[h.jsx("span",{className:"chip warning",children:"missing"}),z.name]},z.id))]}):null,(t.suggested_tests||[]).length?h.jsxs("details",{className:"section",open:!0,children:[h.jsxs("summary",{children:["Suggested tests ",h.jsx("span",{className:"count",children:(j=t.suggested_tests)==null?void 0:j.length})]}),(t.suggested_tests||[]).map(z=>h.jsxs("div",{className:"residual",children:[h.jsx("strong",{children:z.title}),h.jsx("pre",{className:"headline",children:z.body})]},z.title))]}):null,(b=t.trend)!=null&&b.note?h.jsxs("details",{className:"section",children:[h.jsx("summary",{children:"Confidence trend"}),h.jsx("div",{className:"muted",children:t.trend.note}),(t.trend.points||[]).slice(0,6).map(z=>h.jsxs("div",{className:"muted",children:[z.level," · ",Sp(z.created_at),z.sinks!=null?` · ${z.sinks} sinks`:""]},z.id))]}):null,h.jsxs("details",{className:"section",open:!0,children:[h.jsxs("summary",{children:["Residual ",h.jsx("span",{className:"count",children:t.residuals.length})]}),h.jsx("p",{className:"muted",children:"AI is only used here, on what the graph could not close."}),t.residuals.map(z=>h.jsx("div",{className:"residual muted",children:z},z))]}),(P=(_=t.evolution)==null?void 0:_.notes)!=null&&P.length||(E=(N=t.evolution)==null?void 0:N.hotspots)!=null&&E.some(z=>z.commits)?h.jsxs("details",{className:"section",children:[h.jsx("summary",{children:"Churn & coupling"}),(((L=t.evolution)==null?void 0:L.notes)||[]).map(z=>h.jsx("div",{className:"muted",children:z},z)),(((A=t.evolution)==null?void 0:A.hotspots)||[]).filter(z=>z.commits).slice(0,6).map(z=>h.jsxs("div",{className:"muted",children:[h.jsx("span",{className:"file",children:z.path})," — ",z.commits," commits, bus factor ",z.bus_factor]},z.path))]}):null,h.jsxs("div",{className:"btn-row",children:[h.jsx("button",{type:"button",className:"btn",disabled:s,onClick:c,children:"Ask configured model"}),h.jsx("button",{type:"button",className:"btn","data-testid":"btn-copy-markdown",onClick:f,children:"Copy markdown"}),h.jsx("button",{type:"button",className:"btn","data-testid":"btn-post-comment",onClick:g,children:"Post to PR"})]}),o?h.jsx("pre",{className:"headline",children:o}):null,h.jsx("div",{className:"kicker",children:"Reviewers"}),h.jsx("div",{className:"muted",children:t.suggested_reviewers.join(", ")||"—"}),(V=t.knowledge_owners)!=null&&V.length?h.jsxs("div",{className:"muted",children:["Knowledge: ",t.knowledge_owners.join(", ")]}):null]})}function wN({architecture:t,busy:r,onReindex:o,onReview:s}){const a=t.findings.filter(u=>!u.waived);return h.jsxs(h.Fragment,{children:[h.jsxs("div",{className:"merge-box high",children:[h.jsxs("div",{className:"level high",children:["INDEXED — ",t.counts.nodes," nodes"]}),h.jsxs("div",{className:"muted",style:{marginTop:8},children:[t.indexed_at?`Last index ${Sp(t.indexed_at)}`:"Indexed",t.incremental?" · incremental":" · full",t.stale?" · stale":"",t.django_boot&&t.django_boot!=="off"?` · Django boot ${t.django_boot}`:""]}),h.jsxs("span",{className:"chip",children:[t.counts.edges," edges"]}),t.has_config?h.jsx("span",{className:"chip",children:"loadpath.yml"}):null]}),h.jsxs("details",{className:"section",open:!0,children:[h.jsx("summary",{children:"Bounded contexts"}),Object.values(t.contexts).map(u=>h.jsxs("div",{className:"muted",children:[h.jsx("strong",{children:u.name})," — ",(u.django_apps||[]).join(", ")||"no apps"," ·"," ",(u.owners||[]).join(", ")||"unowned"]},u.name))]}),h.jsxs("details",{className:"section",children:[h.jsxs("summary",{children:["Rules ",h.jsx("span",{className:"count",children:(t.rules||[]).length})]}),(t.rules||[]).map(u=>h.jsx("div",{className:"muted",children:u},u))]}),h.jsxs("details",{className:"section",open:!0,children:[h.jsxs("summary",{children:["Findings ",h.jsx("span",{className:"count",children:a.length})]}),a.length===0?h.jsx("div",{className:"muted",children:"No architecture rule hits on the full graph."}):a.map(u=>h.jsxs("div",{className:"finding",children:[h.jsx("span",{className:`chip ${u.severity}`,children:u.severity}),u.message]},u.rule+u.message))]}),h.jsx(vm,{cards:t.deepening}),h.jsxs("details",{className:"section",open:!0,children:[h.jsx("summary",{children:"Types"}),h.jsx("table",{className:"type-table",children:h.jsx("tbody",{children:Object.entries(t.type_counts||{}).sort((u,c)=>c[1]-u[1]).slice(0,12).map(([u,c])=>h.jsxs("tr",{children:[h.jsx("td",{children:kl(u)}),h.jsx("td",{children:c})]},u))})})]}),h.jsxs("div",{className:"btn-row",children:[h.jsx("button",{type:"button",className:"btn",disabled:r,onClick:o,"data-testid":"btn-full-reindex",children:"Full reindex"}),h.jsx("button",{type:"button",className:"btn primary",disabled:r,onClick:s,children:"Review against this index"})]})]})}function vm({cards:t}){const r=t||[];return r.length?h.jsxs("details",{className:"section",open:!0,"data-testid":"deepening-list",children:[h.jsxs("summary",{children:["Depth ",h.jsx("span",{className:"count",children:r.length})]}),h.jsx("p",{className:"muted",children:"Deepening opportunities: more behaviour behind a smaller interface, at a real seam."}),r.map(o=>h.jsxs("div",{className:"finding","data-testid":"deepening-card",children:[h.jsx("span",{className:`chip ${o.strength}`,children:a0(o.strength)}),o.top?h.jsx("span",{className:"chip",children:"top"}):null,h.jsx("strong",{children:o.title}),h.jsx("div",{className:"why",children:o.message}),o.deletion_test?h.jsxs("div",{className:"muted",children:["Deletion test: ",o.deletion_test]}):null,o.before&&o.after?h.jsxs("div",{className:"muted",children:[o.before," → ",o.after]}):null]},o.rule+o.title))]}):null}ym(mm());o0.createRoot(document.getElementById("root")).render(h.jsx(O.StrictMode,{children:h.jsx(vN,{})}));export{Dk as L,kN as a,_N as c,h as j,SN as l,O as r,kl as t}; diff --git a/src/loadpath/static/assets/index-C3YNVD8c.css b/src/loadpath/static/assets/index-ZWkTndM6.css similarity index 73% rename from src/loadpath/static/assets/index-C3YNVD8c.css rename to src/loadpath/static/assets/index-ZWkTndM6.css index a7121cf..efae619 100644 --- a/src/loadpath/static/assets/index-C3YNVD8c.css +++ b/src/loadpath/static/assets/index-ZWkTndM6.css @@ -1 +1 @@ -.react-flow{direction:ltr;--xy-edge-stroke-default: #b1b1b7;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #555;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(255, 255, 255, .5);--xy-minimap-background-color-default: #fff;--xy-minimap-mask-background-color-default: rgba(240, 240, 240, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #e2e2e2;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: transparent;--xy-background-pattern-dots-color-default: #91919a;--xy-background-pattern-lines-color-default: #eee;--xy-background-pattern-cross-color-default: #e2e2e2;background-color:var(--xy-background-color, var(--xy-background-color-default));--xy-node-color-default: inherit;--xy-node-border-default: 1px solid #1a192b;--xy-node-background-color-default: #fff;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(0, 0, 0, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #1a192b;--xy-node-border-radius-default: 3px;--xy-handle-background-color-default: #1a192b;--xy-handle-border-color-default: #fff;--xy-selection-background-color-default: rgba(0, 89, 220, .08);--xy-selection-border-default: 1px dotted rgba(0, 89, 220, .8);--xy-controls-button-background-color-default: #fefefe;--xy-controls-button-background-color-hover-default: #f4f4f4;--xy-controls-button-color-default: inherit;--xy-controls-button-color-hover-default: inherit;--xy-controls-button-border-color-default: #eee;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #ffffff;--xy-edge-label-color-default: inherit;--xy-resize-background-color-default: #3367d9}.react-flow.dark{--xy-edge-stroke-default: #3e3e3e;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #727272;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(150, 150, 150, .25);--xy-minimap-background-color-default: #141414;--xy-minimap-mask-background-color-default: rgba(60, 60, 60, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #2b2b2b;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: #141414;--xy-background-pattern-dots-color-default: #555;--xy-background-pattern-lines-color-default: #333;--xy-background-pattern-cross-color-default: #333;--xy-node-color-default: #f8f8f8;--xy-node-border-default: 1px solid #3c3c3c;--xy-node-background-color-default: #1e1e1e;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(255, 255, 255, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #999;--xy-handle-background-color-default: #bebebe;--xy-handle-border-color-default: #1e1e1e;--xy-selection-background-color-default: rgba(200, 200, 220, .08);--xy-selection-border-default: 1px dotted rgba(200, 200, 220, .8);--xy-controls-button-background-color-default: #2b2b2b;--xy-controls-button-background-color-hover-default: #3e3e3e;--xy-controls-button-color-default: #f8f8f8;--xy-controls-button-color-hover-default: #fff;--xy-controls-button-border-color-default: #5b5b5b;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #141414;--xy-edge-label-color-default: #f8f8f8}.react-flow__background{background-color:var(--xy-background-color-props, var(--xy-background-color, var(--xy-background-color-default)));pointer-events:none;z-index:-1}.react-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.react-flow__pane{z-index:1;touch-action:none}.react-flow__pane.draggable{cursor:grab}.react-flow__pane.dragging{cursor:grabbing}.react-flow__pane.selection{cursor:pointer}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow__edge-path{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width, var(--xy-edge-stroke-width-default));fill:none}.react-flow__connection-path{stroke:var(--xy-connectionline-stroke, var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width, var(--xy-connectionline-stroke-width-default));fill:none}.react-flow .react-flow__edges{position:absolute}.react-flow .react-flow__edges svg{overflow:visible;position:absolute;pointer-events:none}.react-flow__edge{pointer-events:visibleStroke}.react-flow__edge.selectable{cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selectable:focus .react-flow__edge-path,.react-flow__edge.selectable:focus-visible .react-flow__edge-path{stroke:var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default))}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__arrowhead polyline{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:dashdraw .5s linear infinite}svg.react-flow__connectionline{z-index:1001;overflow:visible;position:absolute}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default}.react-flow__node.selectable{cursor:pointer}.react-flow__node.draggable{cursor:grab;pointer-events:all}.react-flow__node.draggable.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.react-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:grab}.react-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;width:6px;height:6px;background-color:var(--xy-handle-background-color, var(--xy-handle-background-color-default));border:1px solid var(--xy-handle-border-color, var(--xy-handle-border-color-default));border-radius:100%}.react-flow__handle.connectingfrom{pointer-events:all}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;left:50%;bottom:0;transform:translate(-50%,50%)}.react-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.react-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.react-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__pane.selection .react-flow__panel{pointer-events:none}.react-flow__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.top.center,.react-flow__panel.bottom.center{left:50%;transform:translate(-15px) translate(-50%)}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.left.center,.react-flow__panel.right.center{top:50%;transform:translateY(-15px) translateY(-50%)}.react-flow__attribution{font-size:10px;background:var(--xy-attribution-background-color, var(--xy-attribution-background-color-default));padding:2px 3px;margin:0}.react-flow__attribution a{text-decoration:none;color:#999}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;left:0;top:0}.react-flow__viewport-portal{position:absolute;width:100%;height:100%;left:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__minimap{background:var( --xy-minimap-background-color-props, var(--xy-minimap-background-color, var(--xy-minimap-background-color-default)) )}.react-flow__minimap-svg{display:block}.react-flow__minimap-mask{fill:var( --xy-minimap-mask-background-color-props, var(--xy-minimap-mask-background-color, var(--xy-minimap-mask-background-color-default)) );stroke:var( --xy-minimap-mask-stroke-color-props, var(--xy-minimap-mask-stroke-color, var(--xy-minimap-mask-stroke-color-default)) );stroke-width:var( --xy-minimap-mask-stroke-width-props, var(--xy-minimap-mask-stroke-width, var(--xy-minimap-mask-stroke-width-default)) )}.react-flow__minimap-node{fill:var( --xy-minimap-node-background-color-props, var(--xy-minimap-node-background-color, var(--xy-minimap-node-background-color-default)) );stroke:var( --xy-minimap-node-stroke-color-props, var(--xy-minimap-node-stroke-color, var(--xy-minimap-node-stroke-color-default)) );stroke-width:var( --xy-minimap-node-stroke-width-props, var(--xy-minimap-node-stroke-width, var(--xy-minimap-node-stroke-width-default)) )}.react-flow__background-pattern.dots{fill:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-dots-color-default)) )}.react-flow__background-pattern.lines{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-lines-color-default)) )}.react-flow__background-pattern.cross{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-cross-color-default)) )}.react-flow__controls{display:flex;flex-direction:column;box-shadow:var(--xy-controls-box-shadow, var(--xy-controls-box-shadow-default))}.react-flow__controls.horizontal{flex-direction:row}.react-flow__controls-button{display:flex;justify-content:center;align-items:center;height:26px;width:26px;padding:4px;border:none;background:var(--xy-controls-button-background-color, var(--xy-controls-button-background-color-default));border-bottom:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) );color:var( --xy-controls-button-color-props, var(--xy-controls-button-color, var(--xy-controls-button-color-default)) );cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px;fill:currentColor}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-input,.react-flow__node-default,.react-flow__node-output,.react-flow__node-group{padding:10px;border-radius:var(--xy-node-border-radius, var(--xy-node-border-radius-default));width:150px;font-size:12px;color:var(--xy-node-color, var(--xy-node-color-default));text-align:center;border:var(--xy-node-border, var(--xy-node-border-default));background-color:var(--xy-node-background-color, var(--xy-node-background-color-default))}.react-flow__node-input.selectable:hover,.react-flow__node-default.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:var(--xy-node-boxshadow-hover, var(--xy-node-boxshadow-hover-default))}.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:var(--xy-node-boxshadow-selected, var(--xy-node-boxshadow-selected-default))}.react-flow__node-group{background-color:var(--xy-node-group-background-color, var(--xy-node-group-background-color-default))}.react-flow__nodesselection-rect,.react-flow__selection{background:var(--xy-selection-background-color, var(--xy-selection-background-color-default));border:var(--xy-selection-border, var(--xy-selection-border-default))}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls-button:hover{background:var( --xy-controls-button-background-color-hover-props, var(--xy-controls-button-background-color-hover, var(--xy-controls-button-background-color-hover-default)) );color:var( --xy-controls-button-color-hover-props, var(--xy-controls-button-color-hover, var(--xy-controls-button-color-hover-default)) )}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__controls-button:last-child{border-bottom:none}.react-flow__controls.horizontal .react-flow__controls-button{border-bottom:none;border-right:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) )}.react-flow__controls.horizontal .react-flow__controls-button:last-child{border-right:none}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{width:5px;height:5px;border:1px solid #fff;border-radius:1px;background-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));translate:-50% -50%}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));border-width:0;border-style:solid}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.react-flow__resize-control.line.left{left:0;border-left-width:1px}.react-flow__resize-control.line.right{left:100%;border-right-width:1px}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.react-flow__resize-control.line.top{top:0;border-top-width:1px}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.react-flow__edge-textbg{fill:var(--xy-edge-label-background-color, var(--xy-edge-label-background-color-default))}.react-flow__edge-text{fill:var(--xy-edge-label-color, var(--xy-edge-label-color-default))}:root,[data-theme=obsidian]{--bg: #070b10;--bg-2: #0d141c;--surface: #121a24;--line: #1e2c3c;--ink: #e7eef6;--muted: #8b9bb0;--high: #2a9d8f;--medium: #e9c46a;--low: #e76f51;--critical: #e85d04;--accent: #4cc9f0;--rail-from: #0b1219;--rail-to: #070b10;--rail-active: #15202c;--btn: #173044;--btn-line: #24506c;--btn-primary: #134e4a;--btn-primary-line: #2a9d8f;--node-bg: #101822;--node-line: #2a3d52;--graph-bg: #070b10;--graph-grid: rgba(42, 80, 120, .09);--edge-cheap: #4a5568;--edge-expensive: #f4a261;--edge-critical: #e85d04;--shadow: rgba(76, 201, 240, .08)}[data-theme=nord]{--bg: #2e3440;--bg-2: #3b4252;--surface: #434c5e;--line: #4c566a;--ink: #eceff4;--muted: #d8dee9;--high: #a3be8c;--medium: #ebcb8b;--low: #bf616a;--critical: #d08770;--accent: #88c0d0;--rail-from: #3b4252;--rail-to: #2e3440;--rail-active: #4c566a;--btn: #434c5e;--btn-line: #81a1c1;--btn-primary: #5e81ac;--btn-primary-line: #88c0d0;--node-bg: #3b4252;--node-line: #81a1c1;--graph-bg: #2e3440;--graph-grid: rgba(136, 192, 208, .12);--edge-cheap: #4c566a;--edge-expensive: #d08770;--edge-critical: #bf616a;--shadow: rgba(136, 192, 208, .12)}[data-theme=solarized-dark]{--bg: #002b36;--bg-2: #073642;--surface: #0a3944;--line: #16444f;--ink: #eee8d5;--muted: #93a1a1;--high: #859900;--medium: #b58900;--low: #dc322f;--critical: #cb4b16;--accent: #2aa198;--rail-from: #073642;--rail-to: #002b36;--rail-active: #16444f;--btn: #073642;--btn-line: #268bd2;--btn-primary: #0a4a42;--btn-primary-line: #2aa198;--node-bg: #073642;--node-line: #268bd2;--graph-bg: #002b36;--graph-grid: rgba(42, 161, 152, .12);--edge-cheap: #586e75;--edge-expensive: #cb4b16;--edge-critical: #dc322f;--shadow: rgba(42, 161, 152, .12)}[data-theme=forest]{--bg: #0e1510;--bg-2: #152019;--surface: #1b2a20;--line: #2c4334;--ink: #e4f0e6;--muted: #8eaa96;--high: #6ab04c;--medium: #c8a951;--low: #e17055;--critical: #d35400;--accent: #7bed9f;--rail-from: #152019;--rail-to: #0e1510;--rail-active: #1f3326;--btn: #1f3326;--btn-line: #3d6b4f;--btn-primary: #1e4d32;--btn-primary-line: #6ab04c;--node-bg: #16241b;--node-line: #3d6b4f;--graph-bg: #0e1510;--graph-grid: rgba(123, 237, 159, .1);--edge-cheap: #3d6b4f;--edge-expensive: #c8a951;--edge-critical: #d35400;--shadow: rgba(123, 237, 159, .1)}[data-theme=rose]{--bg: #191724;--bg-2: #1f1d2e;--surface: #26233a;--line: #403d52;--ink: #e0def4;--muted: #908caa;--high: #9ccfd8;--medium: #f6c177;--low: #eb6f92;--critical: #eb6f92;--accent: #c4a7e7;--rail-from: #1f1d2e;--rail-to: #191724;--rail-active: #26233a;--btn: #26233a;--btn-line: #c4a7e7;--btn-primary: #3a2f4d;--btn-primary-line: #c4a7e7;--node-bg: #1f1d2e;--node-line: #524f67;--graph-bg: #191724;--graph-grid: rgba(196, 167, 231, .12);--edge-cheap: #524f67;--edge-expensive: #f6c177;--edge-critical: #eb6f92;--shadow: rgba(196, 167, 231, .12)}[data-theme=amber]{--bg: #120e0a;--bg-2: #1c1610;--surface: #261e16;--line: #3d2f22;--ink: #f4e6d0;--muted: #b59a78;--high: #c4d6a0;--medium: #e9b44c;--low: #d8572a;--critical: #c0392b;--accent: #f0a05a;--rail-from: #1c1610;--rail-to: #120e0a;--rail-active: #2b2218;--btn: #2b2218;--btn-line: #8a5a2b;--btn-primary: #4a3418;--btn-primary-line: #f0a05a;--node-bg: #1c1610;--node-line: #8a5a2b;--graph-bg: #120e0a;--graph-grid: rgba(240, 160, 90, .12);--edge-cheap: #5c4a38;--edge-expensive: #e9b44c;--edge-critical: #d8572a;--shadow: rgba(240, 160, 90, .12)}[data-theme=volcano]{--bg: #14090a;--bg-2: #1e0e10;--surface: #2a1416;--line: #4a2226;--ink: #fde8e4;--muted: #c48b86;--high: #7bed9f;--medium: #f6c90e;--low: #ff6b6b;--critical: #ff3b3b;--accent: #ff7b54;--rail-from: #1e0e10;--rail-to: #14090a;--rail-active: #32181b;--btn: #32181b;--btn-line: #ff7b54;--btn-primary: #5a1f18;--btn-primary-line: #ff7b54;--node-bg: #1e0e10;--node-line: #7a3330;--graph-bg: #14090a;--graph-grid: rgba(255, 123, 84, .12);--edge-cheap: #5a3330;--edge-expensive: #ff7b54;--edge-critical: #ff3b3b;--shadow: rgba(255, 123, 84, .14)}[data-theme=lavender]{--bg: #12101c;--bg-2: #1a1730;--surface: #221e3c;--line: #3b3560;--ink: #efeaff;--muted: #b3a7d6;--high: #80ffdb;--medium: #ffd166;--low: #ff6b9d;--critical: #ff4d6d;--accent: #c77dff;--rail-from: #1a1730;--rail-to: #12101c;--rail-active: #2a2550;--btn: #2a2550;--btn-line: #c77dff;--btn-primary: #3d2a66;--btn-primary-line: #c77dff;--node-bg: #1a1730;--node-line: #5a4d8a;--graph-bg: #12101c;--graph-grid: rgba(199, 125, 255, .12);--edge-cheap: #5a4d8a;--edge-expensive: #ffd166;--edge-critical: #ff4d6d;--shadow: rgba(199, 125, 255, .14)}[data-theme=neon-noir]{--bg: #05060a;--bg-2: #0a0c14;--surface: #10131c;--line: #1e2436;--ink: #f0f4ff;--muted: #8b93b0;--high: #39ff88;--medium: #ffe66d;--low: #ff2d95;--critical: #ff3d5a;--accent: #00f0ff;--rail-from: #0a0c14;--rail-to: #05060a;--rail-active: #151a2a;--btn: #151a2a;--btn-line: #00f0ff;--btn-primary: #063a40;--btn-primary-line: #00f0ff;--node-bg: #0a0c14;--node-line: #2a3550;--graph-bg: #05060a;--graph-grid: rgba(0, 240, 255, .12);--edge-cheap: #3a4560;--edge-expensive: #ff2d95;--edge-critical: #ff3d5a;--shadow: rgba(0, 240, 255, .22)}[data-theme=synthwave]{--bg: #1a0a2e;--bg-2: #240b3d;--surface: #2d1250;--line: #4a1d7a;--ink: #ffe6fb;--muted: #c49ad8;--high: #00f5d4;--medium: #ffd60a;--low: #ff6b9d;--critical: #ff006e;--accent: #ff2bd6;--rail-from: #240b3d;--rail-to: #1a0a2e;--rail-active: #3a1570;--btn: #3a1570;--btn-line: #ff2bd6;--btn-primary: #5a0a4a;--btn-primary-line: #ff2bd6;--node-bg: #240b3d;--node-line: #7b2cbf;--graph-bg: #1a0a2e;--graph-grid: rgba(255, 43, 214, .16);--edge-cheap: #5a3a80;--edge-expensive: #ff9e00;--edge-critical: #ff006e;--shadow: rgba(255, 43, 214, .24)}[data-theme=phosphor]{--bg: #020804;--bg-2: #061208;--surface: #0a1a0e;--line: #163c1e;--ink: #c8ffc8;--muted: #5aaa5a;--high: #39ff14;--medium: #c8f542;--low: #ffb000;--critical: #ff5e00;--accent: #00ff66;--rail-from: #061208;--rail-to: #020804;--rail-active: #0e2414;--btn: #0e2414;--btn-line: #00ff66;--btn-primary: #0a3a18;--btn-primary-line: #00ff66;--node-bg: #061208;--node-line: #1e6a32;--graph-bg: #020804;--graph-grid: rgba(0, 255, 102, .12);--edge-cheap: #1e5a2a;--edge-expensive: #c8f542;--edge-critical: #ff5e00;--shadow: rgba(0, 255, 102, .2)}[data-theme=aurora]{--bg: #071018;--bg-2: #0c1c28;--surface: #122636;--line: #1e3d52;--ink: #e8fff6;--muted: #7eb8a8;--high: #5fffcf;--medium: #ffe566;--low: #ff7eb6;--critical: #ff4d6d;--accent: #7cffb2;--rail-from: #0c1c28;--rail-to: #071018;--rail-active: #163044;--btn: #163044;--btn-line: #7cffb2;--btn-primary: #0e3d3a;--btn-primary-line: #7cffb2;--node-bg: #0c1c28;--node-line: #2a6a78;--graph-bg: #071018;--graph-grid: rgba(124, 255, 178, .12);--edge-cheap: #2a5a68;--edge-expensive: #c9a0ff;--edge-critical: #ff4d6d;--shadow: rgba(124, 255, 178, .18)}[data-theme=biolume]{--bg: #02141c;--bg-2: #042430;--surface: #073040;--line: #0a4a5c;--ink: #e6fffb;--muted: #6eb8b0;--high: #5dffb0;--medium: #ffe066;--low: #ff79c6;--critical: #ff4d6d;--accent: #18e7d4;--rail-from: #042430;--rail-to: #02141c;--rail-active: #0a3848;--btn: #0a3848;--btn-line: #18e7d4;--btn-primary: #0a4a48;--btn-primary-line: #18e7d4;--node-bg: #042430;--node-line: #1a7080;--graph-bg: #02141c;--graph-grid: rgba(24, 231, 212, .12);--edge-cheap: #1a5a68;--edge-expensive: #ff79c6;--edge-critical: #ff4d6d;--shadow: rgba(24, 231, 212, .2)}[data-theme=carbon]{--bg: #0d0d0f;--bg-2: #16161a;--surface: #1e1e24;--line: #33333c;--ink: #f2f2f4;--muted: #9a9aa8;--high: #3dd68c;--medium: #f0c040;--low: #ff5a5a;--critical: #ff2a2a;--accent: #ff2a2a;--rail-from: #16161a;--rail-to: #0d0d0f;--rail-active: #24242c;--btn: #24242c;--btn-line: #ff2a2a;--btn-primary: #4a1212;--btn-primary-line: #ff2a2a;--node-bg: #16161a;--node-line: #4a4a55;--graph-bg: #0d0d0f;--graph-grid: rgba(255, 42, 42, .1);--edge-cheap: #4a4a55;--edge-expensive: #ff8a3d;--edge-critical: #ff2a2a;--shadow: rgba(255, 42, 42, .18)}[data-theme=paper]{--bg: #f6f1e8;--bg-2: #efe6d6;--surface: #fffaf2;--line: #d9cbb6;--ink: #2b241c;--muted: #6f6456;--high: #2a7a4b;--medium: #b5811a;--low: #c0392b;--critical: #a93226;--accent: #1d6a7a;--rail-from: #efe6d6;--rail-to: #e7dcc8;--rail-active: #e2d3bb;--btn: #fffaf2;--btn-line: #c9b79a;--btn-primary: #d7eee0;--btn-primary-line: #2a7a4b;--node-bg: #fffaf2;--node-line: #c9b79a;--graph-bg: #f6f1e8;--graph-grid: rgba(29, 106, 122, .1);--edge-cheap: #b7a48c;--edge-expensive: #c0392b;--edge-critical: #a93226;--shadow: rgba(43, 36, 28, .08)}[data-theme=solarized-light]{--bg: #fdf6e3;--bg-2: #eee8d5;--surface: #f5efdc;--line: #d6cba9;--ink: #657b83;--muted: #93a1a1;--high: #859900;--medium: #b58900;--low: #dc322f;--critical: #cb4b16;--accent: #268bd2;--rail-from: #eee8d5;--rail-to: #e6dfc8;--rail-active: #e0d9c0;--btn: #fdf6e3;--btn-line: #93a1a1;--btn-primary: #e8efc8;--btn-primary-line: #859900;--node-bg: #fdf6e3;--node-line: #93a1a1;--graph-bg: #fdf6e3;--graph-grid: rgba(38, 139, 210, .12);--edge-cheap: #93a1a1;--edge-expensive: #cb4b16;--edge-critical: #dc322f;--shadow: rgba(101, 123, 131, .1)}[data-theme=seafoam]{--bg: #eef7f4;--bg-2: #dff0ea;--surface: #ffffff;--line: #b7d5cc;--ink: #17332c;--muted: #4d7268;--high: #1b8a5a;--medium: #c48a14;--low: #c44536;--critical: #9b2d22;--accent: #1d9a8a;--rail-from: #dff0ea;--rail-to: #cfe6de;--rail-active: #c4ddd4;--btn: #ffffff;--btn-line: #8fbfb2;--btn-primary: #d4f0e4;--btn-primary-line: #1b8a5a;--node-bg: #ffffff;--node-line: #8fbfb2;--graph-bg: #eef7f4;--graph-grid: rgba(29, 154, 138, .12);--edge-cheap: #8fbfb2;--edge-expensive: #c48a14;--edge-critical: #c44536;--shadow: rgba(23, 51, 44, .08)}[data-theme=high-contrast]{--bg: #ffffff;--bg-2: #f2f2f2;--surface: #ffffff;--line: #111111;--ink: #000000;--muted: #222222;--high: #007a33;--medium: #8a5a00;--low: #b00000;--critical: #9b0000;--accent: #0033cc;--rail-from: #f2f2f2;--rail-to: #e6e6e6;--rail-active: #d9d9d9;--btn: #ffffff;--btn-line: #000000;--btn-primary: #d9f2e3;--btn-primary-line: #007a33;--node-bg: #ffffff;--node-line: #000000;--graph-bg: #ffffff;--graph-grid: rgba(0, 0, 0, .12);--edge-cheap: #444444;--edge-expensive: #8a5a00;--edge-critical: #b00000;--shadow: rgba(0, 0, 0, .12)}[data-theme=sakura]{--bg: #fff0f5;--bg-2: #ffe4ee;--surface: #fff7fa;--line: #f5b8cc;--ink: #4a1830;--muted: #a05a78;--high: #1a8a5c;--medium: #c48a14;--low: #d63d6e;--critical: #b01040;--accent: #e84a8a;--rail-from: #ffe4ee;--rail-to: #f8d4e0;--rail-active: #f5c8d8;--btn: #fff7fa;--btn-line: #e89ab0;--btn-primary: #ffd6e6;--btn-primary-line: #e84a8a;--node-bg: #fff7fa;--node-line: #e89ab0;--graph-bg: #fff0f5;--graph-grid: rgba(232, 74, 138, .12);--edge-cheap: #d4a0b0;--edge-expensive: #d63d6e;--edge-critical: #b01040;--shadow: rgba(74, 24, 48, .1)}[data-theme=citrus]{--bg: #fffce8;--bg-2: #fff3b0;--surface: #fffef5;--line: #e8d44a;--ink: #2a2a08;--muted: #6a6a20;--high: #2a8a20;--medium: #d4a000;--low: #e85d04;--critical: #c0392b;--accent: #5aad14;--rail-from: #fff3b0;--rail-to: #ffe98a;--rail-active: #ffe066;--btn: #fffef5;--btn-line: #d4c030;--btn-primary: #e8f5b8;--btn-primary-line: #5aad14;--node-bg: #fffef5;--node-line: #d4c030;--graph-bg: #fffce8;--graph-grid: rgba(90, 173, 20, .14);--edge-cheap: #c4b040;--edge-expensive: #e85d04;--edge-critical: #c0392b;--shadow: rgba(42, 42, 8, .1)}[data-theme=peach]{--bg: #fff3eb;--bg-2: #ffe0cc;--surface: #fffaf6;--line: #f0c4a8;--ink: #3a2218;--muted: #8a5a48;--high: #2a8a5c;--medium: #d48a14;--low: #e85d3a;--critical: #c0392b;--accent: #ff6b35;--rail-from: #ffe0cc;--rail-to: #ffd4b8;--rail-active: #ffc8a8;--btn: #fffaf6;--btn-line: #e8a888;--btn-primary: #ffe0cc;--btn-primary-line: #ff6b35;--node-bg: #fffaf6;--node-line: #e8a888;--graph-bg: #fff3eb;--graph-grid: rgba(255, 107, 53, .12);--edge-cheap: #d4a088;--edge-expensive: #e85d3a;--edge-critical: #c0392b;--shadow: rgba(58, 34, 24, .1)}[data-theme=candy]{--bg: #f4f0ff;--bg-2: #e8dcff;--surface: #fbf8ff;--line: #d4c0f0;--ink: #2a1848;--muted: #6a5890;--high: #1a8a6a;--medium: #c48a14;--low: #e84a8a;--critical: #c01060;--accent: #ff5eb1;--rail-from: #e8dcff;--rail-to: #ddd0ff;--rail-active: #d4c4ff;--btn: #fbf8ff;--btn-line: #c4a8e8;--btn-primary: #ffd6ec;--btn-primary-line: #ff5eb1;--node-bg: #fbf8ff;--node-line: #c4a8e8;--graph-bg: #f4f0ff;--graph-grid: rgba(255, 94, 177, .14);--edge-cheap: #b0a0d0;--edge-expensive: #e84a8a;--edge-critical: #c01060;--shadow: rgba(42, 24, 72, .1)}[data-theme=sky]{--bg: #e8f4ff;--bg-2: #cfe8ff;--surface: #f5faff;--line: #90c8f0;--ink: #0a2848;--muted: #3a6080;--high: #0a8a4a;--medium: #c48a14;--low: #e85d3a;--critical: #c0392b;--accent: #0077ff;--rail-from: #cfe8ff;--rail-to: #b8dcff;--rail-active: #a8d4ff;--btn: #f5faff;--btn-line: #70b0e0;--btn-primary: #cfe8ff;--btn-primary-line: #0077ff;--node-bg: #f5faff;--node-line: #70b0e0;--graph-bg: #e8f4ff;--graph-grid: rgba(0, 119, 255, .12);--edge-cheap: #80b0d0;--edge-expensive: #e85d3a;--edge-critical: #c0392b;--shadow: rgba(10, 40, 72, .1)}[data-theme=coral]{--bg: #fff1ee;--bg-2: #ffddd6;--surface: #fff8f6;--line: #f0b0a4;--ink: #3a1814;--muted: #8a5048;--high: #0d9488;--medium: #d48a14;--low: #e85d4a;--critical: #c0392b;--accent: #0d9488;--rail-from: #ffddd6;--rail-to: #ffd0c6;--rail-active: #ffc4b8;--btn: #fff8f6;--btn-line: #e89888;--btn-primary: #d4f4ee;--btn-primary-line: #0d9488;--node-bg: #fff8f6;--node-line: #e89888;--graph-bg: #fff1ee;--graph-grid: rgba(13, 148, 136, .14);--edge-cheap: #d4a098;--edge-expensive: #e85d4a;--edge-critical: #c0392b;--shadow: rgba(58, 24, 20, .1)}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}:root{--radius: 6px;--radius-lg: 10px;--control-h: 32px;--font: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;--mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;--focus-ring: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent);--space: 8px}body{background:var(--bg);color:var(--ink);font-family:var(--font);font-size:13px;line-height:1.45;-webkit-font-smoothing:antialiased}button,input,select,textarea{font-family:inherit;font-size:inherit;color:inherit}button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,a:focus-visible,summary:focus-visible{outline:none;box-shadow:var(--focus-ring)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.skip{position:absolute;left:12px;top:-40px;z-index:50;background:var(--surface);color:var(--ink);border:1px solid var(--accent);border-radius:var(--radius);padding:8px 12px}.skip:focus{top:12px}.app{display:grid;grid-template-columns:232px 1fr;height:100%}.rail{border-right:1px solid var(--line);background:linear-gradient(180deg,var(--rail-from),var(--rail-to));padding:16px 12px;display:flex;flex-direction:column;gap:2px;min-width:0}.brand{display:flex;flex-direction:column;gap:2px;padding:4px 8px 16px}.brand-mark{font-family:var(--mono);letter-spacing:.16em;font-size:11px;text-transform:uppercase;color:var(--accent);font-weight:600}.brand-sub{font-size:11px;color:var(--muted)}.nav-item{display:flex;align-items:center;gap:10px;background:transparent;border:0;text-align:left;padding:8px 10px;border-radius:var(--radius);color:var(--muted);cursor:pointer;width:100%}.nav-item:hover{background:color-mix(in srgb,var(--rail-active) 70%,transparent);color:var(--ink)}.nav-item.active{background:var(--rail-active);color:var(--ink);font-weight:500}.nav-item svg{flex-shrink:0}.theme-pick{margin-top:14px;display:grid;gap:4px;padding:0 2px}.theme-pick label{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);font-weight:500}.theme-pick select,.field select,.field input,.topbar input,.topbar select,.settings input,.settings select,.explorer-path input{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:0 10px;height:var(--control-h);width:100%}.rail-foot{margin-top:auto;padding:12px 8px 4px;border-top:1px solid var(--line);display:grid;gap:6px}.kbd-hint{font-size:11px;color:var(--muted)}kbd{font-family:var(--mono);font-size:10px;border:1px solid var(--line);border-radius:4px;padding:0 4px;background:var(--surface)}.main{display:flex;flex-direction:column;min-width:0;min-height:0;position:relative;background:var(--bg)}.progress{position:absolute;top:0;left:0;right:0;height:2px;overflow:hidden;z-index:30;background:color-mix(in srgb,var(--accent) 20%,transparent)}.progress i{display:block;height:100%;width:32%;background:var(--accent);animation:indeterminate 1.1s ease-in-out infinite}.progress.determinate i{width:0;animation:none;transform:none;transition:width .2s ease-out}@keyframes indeterminate{0%{transform:translate(-120%)}to{transform:translate(400%)}}.topbar{display:flex;gap:10px;align-items:flex-end;padding:10px 16px;border-bottom:1px solid var(--line);background:var(--bg-2);flex-wrap:wrap}.field{display:grid;gap:4px;min-width:0}.field>span{font-size:11px;color:var(--muted);font-weight:500}.field.path{flex:1;min-width:180px}.field.ref{width:188px;flex:0 0 188px}.field.workspace{width:180px;flex:0 0 180px}.path-row,.combo-row{display:flex;min-width:0}.path-row input,.combo-row input{flex:1;min-width:0}.combo{position:relative;min-width:0}.combo-row input{border-top-right-radius:0;border-bottom-right-radius:0}.topbar .icon-btn{width:var(--control-h);padding:0;flex:0 0 var(--control-h)}.combo-toggle{border-top-left-radius:0;border-bottom-left-radius:0;border-left:0}.combo-menu{position:absolute;top:calc(100% + 4px);right:0;left:auto;min-width:340px;max-width:min(480px,70vw);max-height:360px;overflow:auto;z-index:40;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);box-shadow:0 12px 32px var(--shadow);padding:6px 0}.combo-heading{font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);font-weight:600;padding:8px 12px 4px}.combo-menu .combo-option{display:flex;flex-direction:column;align-items:flex-start;gap:2px;width:100%;text-align:left;background:transparent;border:0;border-radius:0;height:auto;padding:6px 12px;color:var(--ink);cursor:pointer}.combo-menu .combo-option:hover,.combo-menu .combo-option.active{background:var(--rail-active)}.combo-label{font-family:var(--mono);font-size:12px}.combo-detail{color:var(--muted);font-size:12px;line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.combo-empty{padding:10px 12px}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:50;background:color-mix(in srgb,var(--bg) 72%,transparent);display:grid;place-items:center;padding:24px}.modal{width:min(720px,100%);max-height:min(640px,90vh);background:var(--bg-2);border:1px solid var(--line);border-radius:var(--radius-lg);box-shadow:0 16px 48px var(--shadow);display:flex;flex-direction:column;overflow:hidden}.modal-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:14px 16px 10px;border-bottom:1px solid var(--line)}.modal-head h2{font-size:15px}.modal-head .muted{margin:4px 0 0}.explorer-path{display:flex;gap:8px;padding:12px 16px;border-bottom:1px solid var(--line)}.explorer-path input{flex:1;min-width:0}.explorer-list{flex:1;overflow:auto;padding:8px;min-height:220px}.explorer-row{display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:transparent;border:0;border-radius:var(--radius);padding:8px 10px;color:var(--ink);cursor:pointer;height:auto}.explorer-row:hover,.explorer-row.active{background:var(--rail-active)}.explorer-name{min-width:0;overflow:hidden;text-overflow:ellipsis}.git-badge{margin-left:auto;margin-bottom:0}.explorer-empty{padding:18px 10px}.modal-foot{display:flex;align-items:center;gap:12px;padding:12px 16px;border-top:1px solid var(--line)}.explorer-current{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--mono);font-size:12px}.topbar input,.topbar select{min-width:0}.topbar-actions{display:flex;gap:8px;margin-left:auto;align-items:center;padding-bottom:0}.btn,.topbar button{background:var(--btn);border:1px solid var(--btn-line);border-radius:var(--radius);height:var(--control-h);padding:0 12px;cursor:pointer;font-weight:500;display:inline-flex;align-items:center;justify-content:center;gap:6px;white-space:nowrap}.btn:hover,.topbar button:hover{filter:brightness(1.08)}.btn:disabled,.topbar button:disabled{opacity:.55;cursor:not-allowed;filter:none}.btn.primary{background:var(--btn-primary);border-color:var(--btn-primary-line)}.btn.ghost{background:transparent}.alerts{display:grid;gap:8px;padding:10px 16px 0}.alerts:empty{display:none;padding:0}.stage{flex:1;min-height:0;display:flex;flex-direction:column}.content{flex:1;min-height:0;display:grid;grid-template-columns:minmax(340px,420px) 1fr}.brief{overflow:auto;border-right:1px solid var(--line);padding:16px 18px 24px;background:radial-gradient(circle at 0 0,color-mix(in srgb,var(--accent) 8%,transparent),transparent 42%),var(--bg)}.graph-wrap{position:relative;min-height:0;display:flex;flex-direction:column}.impact-graph{flex:1;min-height:0;position:relative;display:flex;flex-direction:column}.graph-toolbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:8px 14px;border-bottom:1px solid var(--line);background:var(--bg-2)}.graph-count{margin-left:auto;font-size:11px}.chip-btn{background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:4px 12px;color:var(--muted);cursor:pointer;height:26px}.chip-btn:hover{color:var(--ink)}.chip-btn.active{background:var(--rail-active);color:var(--ink)}.chip-btn:disabled{opacity:.45;cursor:not-allowed}.graph-stage{flex:1;min-height:0;position:relative;display:flex;flex-direction:column}.graph-stage .react-flow,.graph-3d,.graph-3d-host,.graph-3d-canvas-host{flex:1;width:100%;height:100%;min-height:280px}.graph-3d{position:relative;background:var(--graph-bg);display:flex;flex-direction:column}.graph-3d-host{position:relative;min-height:0;display:flex;flex-direction:column}.graph-3d-canvas-host{position:relative;min-height:0;background:var(--graph-bg)}.graph-3d canvas{display:block;width:100%;height:100%}.graph-3d-tip{position:absolute;pointer-events:none;z-index:2;max-width:320px;padding:6px 8px;border-radius:var(--radius);background:var(--surface);border:1px solid var(--line);color:var(--ink);font-size:11px;line-height:1.35;box-shadow:0 8px 24px var(--shadow)}.graph-3d-tip .t{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.08em}.graph-3d-tip .n{font-weight:600}.graph-3d-hint{position:absolute;left:10px;bottom:10px;z-index:2;margin:0;font-size:11px;color:var(--muted);max-width:min(420px,calc(100% - 24px));pointer-events:none}.graph-wrap .react-flow{background-color:var(--graph-bg);background-image:linear-gradient(var(--graph-grid) 1px,transparent 1px),linear-gradient(90deg,var(--graph-grid) 1px,transparent 1px);background-size:24px 24px}.react-flow__minimap{background:var(--graph-bg)!important;border:1px solid var(--line)!important;border-radius:var(--radius);overflow:hidden;box-shadow:0 8px 24px var(--shadow)}.react-flow__minimap-node{fill:var(--muted);stroke:none}.react-flow__minimap-node.selected{fill:var(--accent)}.react-flow__minimap-mask{fill:#00000073!important;stroke:var(--accent)!important}.react-flow__controls{box-shadow:none!important}.react-flow__controls-button{background:var(--surface)!important;border-bottom:1px solid var(--line)!important;fill:var(--ink)!important}h1{font-size:18px;margin:0 0 6px;font-weight:600}h2{font-size:13px;margin:0;font-weight:600}.merge-box{border:1px solid var(--line);background:var(--surface);border-radius:var(--radius-lg);padding:12px 14px;margin-bottom:12px}.merge-box.high{border-color:color-mix(in srgb,var(--high) 55%,var(--line))}.merge-box.medium{border-color:color-mix(in srgb,var(--medium) 55%,var(--line))}.merge-box.low{border-color:color-mix(in srgb,var(--low) 55%,var(--line))}.level{font-family:var(--mono);font-weight:600;font-size:14px}.level.high{color:var(--high)}.level.medium{color:var(--medium)}.level.low{color:var(--low)}.merge-title{margin-top:4px;font-size:13px;color:var(--ink)}.reasons{margin:10px 0 0;padding:0 0 0 18px;color:var(--muted)}.reasons li{margin:0 0 4px}.metrics{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:0 0 14px}.metric{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:8px 10px}.metric .n{font-family:var(--mono);font-size:16px;font-weight:600;font-variant-numeric:tabular-nums}.metric .l{font-size:11px;color:var(--muted);margin-top:2px}.section{border-top:1px solid var(--line);padding:8px 0 4px}.section>summary{cursor:pointer;list-style:none;display:flex;align-items:center;justify-content:space-between;color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.07em;font-weight:600;padding:6px 0}.section>summary::-webkit-details-marker{display:none}.section>summary .count{font-family:var(--mono);letter-spacing:0;text-transform:none;border:1px solid var(--line);border-radius:999px;padding:0 7px;height:18px;display:inline-flex;align-items:center;font-size:11px}.kicker{color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.08em;margin:16px 0 6px;font-weight:600}.chip{display:inline-flex;align-items:center;font-size:11px;padding:2px 8px;border-radius:999px;border:1px solid var(--line);margin:0 6px 6px 0;color:var(--muted);background:var(--surface)}.chip.blocker{color:var(--low);border-color:var(--low)}.chip.warning{color:var(--medium);border-color:var(--medium)}.chip.strong{color:var(--low);border-color:var(--low)}.chip.worth_exploring{color:var(--medium);border-color:var(--medium)}.chip.speculative{color:var(--muted);border-color:var(--line)}.chip.open{color:var(--high);border-color:color-mix(in srgb,var(--high) 50%,var(--line))}.file{font-family:var(--mono);font-size:12px;color:var(--accent)}.read-item,.finding,.residual{padding:8px 0;border-bottom:1px solid color-mix(in srgb,var(--line) 70%,transparent)}.read-item:last-child,.finding:last-child{border-bottom:0}.read-item.tour-current{background:color-mix(in srgb,var(--accent) 12%,var(--surface));border-color:var(--accent)}.tour-row{margin-top:8px;align-items:center}.field.dirty .chip-btn{height:32px}.muted{color:var(--muted);font-size:13px;line-height:1.45}.error{color:var(--low);padding:8px 12px;border:1px solid var(--low);background:color-mix(in srgb,var(--low) 10%,var(--surface));border-radius:var(--radius);display:flex;justify-content:space-between;gap:12px;align-items:flex-start}.banner{padding:8px 12px;border-radius:var(--radius);border:1px solid var(--line);background:var(--surface);font-size:13px;line-height:1.45;display:flex;justify-content:space-between;gap:12px;align-items:flex-start}.banner.warn{border-color:var(--medium);color:var(--medium)}.banner.stale{border-color:var(--low);color:var(--low)}.banner .dismiss{background:transparent;border:0;color:inherit;cursor:pointer;height:auto;padding:0 2px;opacity:.7}.empty{padding:24px 8px;color:var(--muted);font-size:13px;line-height:1.55}.workspace-loading{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;min-height:220px;padding:48px 16px}.empty h2{font-size:16px;color:var(--ink);margin-bottom:8px}.empty ol{margin:12px 0 0 18px;padding:0}.empty code,code{font-family:var(--mono);font-size:12px;color:var(--accent)}.btn-row{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.pr-list{padding:16px;overflow:auto}.pr-toolbar{display:flex;gap:8px;align-items:flex-end;margin-bottom:14px}.pr-toolbar .field{flex:1}.pr-toolbar .field.provider{flex:0 0 140px}.scm-count{margin:0 0 12px;font-size:12px}.scm-login{display:flex;justify-content:space-between;gap:12px;align-items:center;padding:10px 0;border-top:1px solid var(--line)}.scm-login:first-of-type{border-top:0;padding-top:0}.scm-login .btn-row{margin-top:0}.scm-login p{margin:2px 0 0}.oauth-code{font-size:13px;margin:0}.oauth-code code{font-size:14px;letter-spacing:.08em}.pr{border:1px solid var(--line);background:var(--surface);padding:12px 14px;border-radius:var(--radius-lg);margin-bottom:10px}.pr h3{margin:0 0 4px;font-size:14px;font-weight:600}.pr-meta{display:flex;flex-wrap:wrap;gap:8px 12px;align-items:center;margin:6px 0 10px}.pr-actions{display:flex;gap:8px;align-items:center}.settings{padding:24px;max-width:760px;overflow:auto;display:grid;gap:16px}.settings-card{border:1px solid var(--line);background:var(--surface);border-radius:var(--radius-lg);padding:16px;display:grid;gap:8px}.settings-card h2{font-size:14px;margin-bottom:2px}.settings label{font-size:12px;color:var(--muted);font-weight:500}.theme-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:8px}.theme-swatch{border:1px solid var(--line);background:var(--bg);color:var(--ink);border-radius:var(--radius);padding:10px;text-align:left;cursor:pointer;height:auto;box-shadow:0 1px 8px var(--shadow)}.theme-swatch.active{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent),0 1px 8px var(--shadow)}.theme-swatch .swatch-bar{height:6px;border-radius:3px;margin-bottom:8px;background:linear-gradient(90deg,var(--accent),var(--high),var(--medium),var(--low))}.theme-swatch .name{font-size:13px;font-weight:600}.theme-swatch .group{font-size:11px;color:var(--muted)}.headline{white-space:pre-wrap;font-family:var(--mono);font-size:12px;color:var(--muted);margin:8px 0 0}.graph-modes{display:flex;gap:8px;align-items:center;padding:8px 14px;border-bottom:1px solid var(--line);background:var(--bg-2)}.seg{display:inline-flex;border:1px solid var(--line);border-radius:999px;padding:2px;background:var(--surface)}.seg button,.graph-modes button{background:transparent;border:0;border-radius:999px;padding:4px 12px;color:var(--muted);cursor:pointer;height:26px}.seg button.active,.graph-modes button.active{background:var(--rail-active);color:var(--ink)}.legend{margin-left:auto;display:flex;gap:12px;color:var(--muted);font-size:11px}.legend i{display:inline-block;width:14px;height:2px;margin-right:6px;vertical-align:middle;background:var(--edge-cheap)}.legend i.exp{background:var(--edge-expensive)}.legend i.crit{background:var(--edge-critical);height:3px}.legend i.dash{border-top:2px dashed var(--muted);background:none;height:0}.inspector{position:absolute;top:12px;right:12px;z-index:5;width:300px;max-width:calc(100% - 24px);max-height:calc(100% - 24px);overflow-x:hidden;overflow-y:auto;overflow-wrap:break-word;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);padding:10px 12px;box-shadow:0 8px 24px var(--shadow);font-size:12px}.inspector .t{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.06em}.inspector .n,.inspector .file,.inspector .muted{overflow-wrap:break-word}.inspector .n{font-weight:600;margin:4px 0}.inspector-head{display:flex;align-items:flex-start;gap:8px}.inspector-roles{display:flex;flex-wrap:wrap;justify-content:flex-end;flex:1;gap:4px}.inspector-chip{font-size:10px;text-transform:uppercase;letter-spacing:.04em;padding:1px 6px;border-radius:999px;border:1px solid var(--line);color:var(--muted);white-space:nowrap}.inspector-close{flex:0 0 auto;width:24px;height:24px;padding:0;border:1px solid var(--line);border-radius:var(--radius);background:transparent;color:var(--muted);font-size:16px;line-height:1;cursor:pointer}.inspector-close:hover{color:var(--ink)}.inspector-purpose{margin:6px 0 8px;color:var(--ink);font-size:12px;line-height:1.4}.inspector-layer{margin-top:4px;font-size:11px}.inspector-degree{font-size:11px}.inspector-path{margin:6px 0 0;font-size:12px;line-height:1.4;color:var(--muted)}.inspector-facts{margin:10px 0 0;padding-top:8px;border-top:1px solid var(--line)}.inspector-fact{display:grid;grid-template-columns:minmax(64px,92px) minmax(0,1fr);gap:8px;padding:3px 0;align-items:start}.inspector-fact dt{color:var(--muted);font-size:11px;margin:0}.inspector-fact dd{margin:0;overflow-wrap:break-word}.inspector-section{margin-top:10px;padding-top:8px;border-top:1px solid var(--line)}.inspector-section h3{margin:0 0 6px;display:flex;align-items:center;justify-content:space-between;color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.07em;font-weight:600}.inspector-section .count{font-family:var(--mono);letter-spacing:0;text-transform:none;border:1px solid var(--line);border-radius:999px;padding:0 7px;height:18px;display:inline-flex;align-items:center;font-size:11px}.inspector-section ul{list-style:none;margin:0;padding:0}.inspector-section li{padding:4px 0;border-bottom:1px solid color-mix(in srgb,var(--line) 70%,transparent)}.inspector-section li:last-child{border-bottom:0}.inspector-link-name{display:block;font-weight:600;overflow-wrap:break-word}.inspector-link-meta{display:block;color:var(--muted);font-size:11px}.lp-node{padding:8px 10px;border-radius:var(--radius);border:1px solid var(--node-line);background:var(--node-bg);width:208px;max-width:100%;height:64px;box-sizing:border-box;box-shadow:0 0 0 1px var(--shadow);overflow:visible;position:relative}.lp-node .t{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.08em}.lp-node .n{font-size:13px;font-weight:600;line-height:1.2;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow-wrap:anywhere}.lp-node.selected{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}.react-flow__node-load .react-flow__handle{width:8px;height:8px;border:none;background:transparent;opacity:0}.type-table{width:100%;border-collapse:collapse;font-size:12px}.type-table td{padding:3px 0}.type-table td:last-child{text-align:right;font-family:var(--mono);font-variant-numeric:tabular-nums;color:var(--muted)}@media(prefers-reduced-motion:reduce){.progress i{animation:none;width:100%}.progress.determinate i{width:var(--progress, 100%)}*{scroll-behavior:auto!important}}@media(max-width:960px){.app{grid-template-columns:56px 1fr}.brand-sub,.nav-item span,.theme-pick,.kbd-hint,.rail-foot .muted{display:none}.nav-item{justify-content:center;padding:10px}.content{grid-template-columns:1fr}.brief{border-right:0;border-bottom:1px solid var(--line);max-height:42vh}} +.react-flow{direction:ltr;--xy-edge-stroke-default: #b1b1b7;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #555;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(255, 255, 255, .5);--xy-minimap-background-color-default: #fff;--xy-minimap-mask-background-color-default: rgba(240, 240, 240, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #e2e2e2;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: transparent;--xy-background-pattern-dots-color-default: #91919a;--xy-background-pattern-lines-color-default: #eee;--xy-background-pattern-cross-color-default: #e2e2e2;background-color:var(--xy-background-color, var(--xy-background-color-default));--xy-node-color-default: inherit;--xy-node-border-default: 1px solid #1a192b;--xy-node-background-color-default: #fff;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(0, 0, 0, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #1a192b;--xy-node-border-radius-default: 3px;--xy-handle-background-color-default: #1a192b;--xy-handle-border-color-default: #fff;--xy-selection-background-color-default: rgba(0, 89, 220, .08);--xy-selection-border-default: 1px dotted rgba(0, 89, 220, .8);--xy-controls-button-background-color-default: #fefefe;--xy-controls-button-background-color-hover-default: #f4f4f4;--xy-controls-button-color-default: inherit;--xy-controls-button-color-hover-default: inherit;--xy-controls-button-border-color-default: #eee;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #ffffff;--xy-edge-label-color-default: inherit;--xy-resize-background-color-default: #3367d9}.react-flow.dark{--xy-edge-stroke-default: #3e3e3e;--xy-edge-stroke-width-default: 1;--xy-edge-stroke-selected-default: #727272;--xy-connectionline-stroke-default: #b1b1b7;--xy-connectionline-stroke-width-default: 1;--xy-attribution-background-color-default: rgba(150, 150, 150, .25);--xy-minimap-background-color-default: #141414;--xy-minimap-mask-background-color-default: rgba(60, 60, 60, .6);--xy-minimap-mask-stroke-color-default: transparent;--xy-minimap-mask-stroke-width-default: 1;--xy-minimap-node-background-color-default: #2b2b2b;--xy-minimap-node-stroke-color-default: transparent;--xy-minimap-node-stroke-width-default: 2;--xy-background-color-default: #141414;--xy-background-pattern-dots-color-default: #555;--xy-background-pattern-lines-color-default: #333;--xy-background-pattern-cross-color-default: #333;--xy-node-color-default: #f8f8f8;--xy-node-border-default: 1px solid #3c3c3c;--xy-node-background-color-default: #1e1e1e;--xy-node-group-background-color-default: rgba(240, 240, 240, .25);--xy-node-boxshadow-hover-default: 0 1px 4px 1px rgba(255, 255, 255, .08);--xy-node-boxshadow-selected-default: 0 0 0 .5px #999;--xy-handle-background-color-default: #bebebe;--xy-handle-border-color-default: #1e1e1e;--xy-selection-background-color-default: rgba(200, 200, 220, .08);--xy-selection-border-default: 1px dotted rgba(200, 200, 220, .8);--xy-controls-button-background-color-default: #2b2b2b;--xy-controls-button-background-color-hover-default: #3e3e3e;--xy-controls-button-color-default: #f8f8f8;--xy-controls-button-color-hover-default: #fff;--xy-controls-button-border-color-default: #5b5b5b;--xy-controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, .08);--xy-edge-label-background-color-default: #141414;--xy-edge-label-color-default: #f8f8f8}.react-flow__background{background-color:var(--xy-background-color-props, var(--xy-background-color, var(--xy-background-color-default)));pointer-events:none;z-index:-1}.react-flow__container{position:absolute;width:100%;height:100%;top:0;left:0}.react-flow__pane{z-index:1;touch-action:none}.react-flow__pane.draggable{cursor:grab}.react-flow__pane.dragging{cursor:grabbing}.react-flow__pane.selection{cursor:pointer}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow__edge-path{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width, var(--xy-edge-stroke-width-default));fill:none}.react-flow__connection-path{stroke:var(--xy-connectionline-stroke, var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width, var(--xy-connectionline-stroke-width-default));fill:none}.react-flow .react-flow__edges{position:absolute}.react-flow .react-flow__edges svg{overflow:visible;position:absolute;pointer-events:none}.react-flow__edge{pointer-events:visibleStroke}.react-flow__edge.selectable{cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selectable:focus .react-flow__edge-path,.react-flow__edge.selectable:focus-visible .react-flow__edge-path{stroke:var(--xy-edge-stroke-selected, var(--xy-edge-stroke-selected-default))}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__arrowhead polyline{stroke:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke, var(--xy-edge-stroke-default))}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:dashdraw .5s linear infinite}svg.react-flow__connectionline{z-index:1001;overflow:visible;position:absolute}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{position:absolute;-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default}.react-flow__node.selectable{cursor:pointer}.react-flow__node.draggable{cursor:grab;pointer-events:all}.react-flow__node.draggable.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:left top;pointer-events:none}.react-flow__nodesselection-rect{position:absolute;pointer-events:all;cursor:grab}.react-flow__handle{position:absolute;pointer-events:none;min-width:5px;min-height:5px;width:6px;height:6px;background-color:var(--xy-handle-background-color, var(--xy-handle-background-color-default));border:1px solid var(--xy-handle-border-color, var(--xy-handle-border-color-default));border-radius:100%}.react-flow__handle.connectingfrom{pointer-events:all}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;left:50%;bottom:0;transform:translate(-50%,50%)}.react-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.react-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.react-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__pane.selection .react-flow__panel{pointer-events:none}.react-flow__panel{position:absolute;z-index:5;margin:15px}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.top.center,.react-flow__panel.bottom.center{left:50%;transform:translate(-15px) translate(-50%)}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.left.center,.react-flow__panel.right.center{top:50%;transform:translateY(-15px) translateY(-50%)}.react-flow__attribution{font-size:10px;background:var(--xy-attribution-background-color, var(--xy-attribution-background-color-default));padding:2px 3px;margin:0}.react-flow__attribution a{text-decoration:none;color:#999}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{position:absolute;width:100%;height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;left:0;top:0}.react-flow__viewport-portal{position:absolute;width:100%;height:100%;left:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__minimap{background:var( --xy-minimap-background-color-props, var(--xy-minimap-background-color, var(--xy-minimap-background-color-default)) )}.react-flow__minimap-svg{display:block}.react-flow__minimap-mask{fill:var( --xy-minimap-mask-background-color-props, var(--xy-minimap-mask-background-color, var(--xy-minimap-mask-background-color-default)) );stroke:var( --xy-minimap-mask-stroke-color-props, var(--xy-minimap-mask-stroke-color, var(--xy-minimap-mask-stroke-color-default)) );stroke-width:var( --xy-minimap-mask-stroke-width-props, var(--xy-minimap-mask-stroke-width, var(--xy-minimap-mask-stroke-width-default)) )}.react-flow__minimap-node{fill:var( --xy-minimap-node-background-color-props, var(--xy-minimap-node-background-color, var(--xy-minimap-node-background-color-default)) );stroke:var( --xy-minimap-node-stroke-color-props, var(--xy-minimap-node-stroke-color, var(--xy-minimap-node-stroke-color-default)) );stroke-width:var( --xy-minimap-node-stroke-width-props, var(--xy-minimap-node-stroke-width, var(--xy-minimap-node-stroke-width-default)) )}.react-flow__background-pattern.dots{fill:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-dots-color-default)) )}.react-flow__background-pattern.lines{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-lines-color-default)) )}.react-flow__background-pattern.cross{stroke:var( --xy-background-pattern-color-props, var(--xy-background-pattern-color, var(--xy-background-pattern-cross-color-default)) )}.react-flow__controls{display:flex;flex-direction:column;box-shadow:var(--xy-controls-box-shadow, var(--xy-controls-box-shadow-default))}.react-flow__controls.horizontal{flex-direction:row}.react-flow__controls-button{display:flex;justify-content:center;align-items:center;height:26px;width:26px;padding:4px;border:none;background:var(--xy-controls-button-background-color, var(--xy-controls-button-background-color-default));border-bottom:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) );color:var( --xy-controls-button-color-props, var(--xy-controls-button-color, var(--xy-controls-button-color-default)) );cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none}.react-flow__controls-button svg{width:100%;max-width:12px;max-height:12px;fill:currentColor}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-input,.react-flow__node-default,.react-flow__node-output,.react-flow__node-group{padding:10px;border-radius:var(--xy-node-border-radius, var(--xy-node-border-radius-default));width:150px;font-size:12px;color:var(--xy-node-color, var(--xy-node-color-default));text-align:center;border:var(--xy-node-border, var(--xy-node-border-default));background-color:var(--xy-node-background-color, var(--xy-node-background-color-default))}.react-flow__node-input.selectable:hover,.react-flow__node-default.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:var(--xy-node-boxshadow-hover, var(--xy-node-boxshadow-hover-default))}.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:var(--xy-node-boxshadow-selected, var(--xy-node-boxshadow-selected-default))}.react-flow__node-group{background-color:var(--xy-node-group-background-color, var(--xy-node-group-background-color-default))}.react-flow__nodesselection-rect,.react-flow__selection{background:var(--xy-selection-background-color, var(--xy-selection-background-color-default));border:var(--xy-selection-border, var(--xy-selection-border-default))}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls-button:hover{background:var( --xy-controls-button-background-color-hover-props, var(--xy-controls-button-background-color-hover, var(--xy-controls-button-background-color-hover-default)) );color:var( --xy-controls-button-color-hover-props, var(--xy-controls-button-color-hover, var(--xy-controls-button-color-hover-default)) )}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__controls-button:last-child{border-bottom:none}.react-flow__controls.horizontal .react-flow__controls-button{border-bottom:none;border-right:1px solid var( --xy-controls-button-border-color-props, var(--xy-controls-button-border-color, var(--xy-controls-button-border-color-default)) )}.react-flow__controls.horizontal .react-flow__controls-button:last-child{border-right:none}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{width:5px;height:5px;border:1px solid #fff;border-radius:1px;background-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));translate:-50% -50%}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:var(--xy-resize-background-color, var(--xy-resize-background-color-default));border-width:0;border-style:solid}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;transform:translate(-50%);top:0;height:100%}.react-flow__resize-control.line.left{left:0;border-left-width:1px}.react-flow__resize-control.line.right{left:100%;border-right-width:1px}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{height:1px;transform:translateY(-50%);left:0;width:100%}.react-flow__resize-control.line.top{top:0;border-top-width:1px}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.react-flow__edge-textbg{fill:var(--xy-edge-label-background-color, var(--xy-edge-label-background-color-default))}.react-flow__edge-text{fill:var(--xy-edge-label-color, var(--xy-edge-label-color-default))}:root,[data-theme=obsidian]{--bg: #070b10;--bg-2: #0d141c;--surface: #121a24;--line: #1e2c3c;--ink: #e7eef6;--muted: #8b9bb0;--high: #2a9d8f;--medium: #e9c46a;--low: #e76f51;--critical: #e85d04;--accent: #4cc9f0;--rail-from: #0b1219;--rail-to: #070b10;--rail-active: #15202c;--btn: #173044;--btn-line: #24506c;--btn-primary: #134e4a;--btn-primary-line: #2a9d8f;--node-bg: #101822;--node-line: #2a3d52;--graph-bg: #070b10;--graph-grid: rgba(42, 80, 120, .09);--edge-cheap: #4a5568;--edge-expensive: #f4a261;--edge-critical: #e85d04;--shadow: rgba(76, 201, 240, .08)}[data-theme=nord]{--bg: #2e3440;--bg-2: #3b4252;--surface: #434c5e;--line: #4c566a;--ink: #eceff4;--muted: #d8dee9;--high: #a3be8c;--medium: #ebcb8b;--low: #bf616a;--critical: #d08770;--accent: #88c0d0;--rail-from: #3b4252;--rail-to: #2e3440;--rail-active: #4c566a;--btn: #434c5e;--btn-line: #81a1c1;--btn-primary: #5e81ac;--btn-primary-line: #88c0d0;--node-bg: #3b4252;--node-line: #81a1c1;--graph-bg: #2e3440;--graph-grid: rgba(136, 192, 208, .12);--edge-cheap: #4c566a;--edge-expensive: #d08770;--edge-critical: #bf616a;--shadow: rgba(136, 192, 208, .12)}[data-theme=solarized-dark]{--bg: #002b36;--bg-2: #073642;--surface: #0a3944;--line: #16444f;--ink: #eee8d5;--muted: #93a1a1;--high: #859900;--medium: #b58900;--low: #dc322f;--critical: #cb4b16;--accent: #2aa198;--rail-from: #073642;--rail-to: #002b36;--rail-active: #16444f;--btn: #073642;--btn-line: #268bd2;--btn-primary: #0a4a42;--btn-primary-line: #2aa198;--node-bg: #073642;--node-line: #268bd2;--graph-bg: #002b36;--graph-grid: rgba(42, 161, 152, .12);--edge-cheap: #586e75;--edge-expensive: #cb4b16;--edge-critical: #dc322f;--shadow: rgba(42, 161, 152, .12)}[data-theme=forest]{--bg: #0e1510;--bg-2: #152019;--surface: #1b2a20;--line: #2c4334;--ink: #e4f0e6;--muted: #8eaa96;--high: #6ab04c;--medium: #c8a951;--low: #e17055;--critical: #d35400;--accent: #7bed9f;--rail-from: #152019;--rail-to: #0e1510;--rail-active: #1f3326;--btn: #1f3326;--btn-line: #3d6b4f;--btn-primary: #1e4d32;--btn-primary-line: #6ab04c;--node-bg: #16241b;--node-line: #3d6b4f;--graph-bg: #0e1510;--graph-grid: rgba(123, 237, 159, .1);--edge-cheap: #3d6b4f;--edge-expensive: #c8a951;--edge-critical: #d35400;--shadow: rgba(123, 237, 159, .1)}[data-theme=rose]{--bg: #191724;--bg-2: #1f1d2e;--surface: #26233a;--line: #403d52;--ink: #e0def4;--muted: #908caa;--high: #9ccfd8;--medium: #f6c177;--low: #eb6f92;--critical: #eb6f92;--accent: #c4a7e7;--rail-from: #1f1d2e;--rail-to: #191724;--rail-active: #26233a;--btn: #26233a;--btn-line: #c4a7e7;--btn-primary: #3a2f4d;--btn-primary-line: #c4a7e7;--node-bg: #1f1d2e;--node-line: #524f67;--graph-bg: #191724;--graph-grid: rgba(196, 167, 231, .12);--edge-cheap: #524f67;--edge-expensive: #f6c177;--edge-critical: #eb6f92;--shadow: rgba(196, 167, 231, .12)}[data-theme=amber]{--bg: #120e0a;--bg-2: #1c1610;--surface: #261e16;--line: #3d2f22;--ink: #f4e6d0;--muted: #b59a78;--high: #c4d6a0;--medium: #e9b44c;--low: #d8572a;--critical: #c0392b;--accent: #f0a05a;--rail-from: #1c1610;--rail-to: #120e0a;--rail-active: #2b2218;--btn: #2b2218;--btn-line: #8a5a2b;--btn-primary: #4a3418;--btn-primary-line: #f0a05a;--node-bg: #1c1610;--node-line: #8a5a2b;--graph-bg: #120e0a;--graph-grid: rgba(240, 160, 90, .12);--edge-cheap: #5c4a38;--edge-expensive: #e9b44c;--edge-critical: #d8572a;--shadow: rgba(240, 160, 90, .12)}[data-theme=volcano]{--bg: #14090a;--bg-2: #1e0e10;--surface: #2a1416;--line: #4a2226;--ink: #fde8e4;--muted: #c48b86;--high: #7bed9f;--medium: #f6c90e;--low: #ff6b6b;--critical: #ff3b3b;--accent: #ff7b54;--rail-from: #1e0e10;--rail-to: #14090a;--rail-active: #32181b;--btn: #32181b;--btn-line: #ff7b54;--btn-primary: #5a1f18;--btn-primary-line: #ff7b54;--node-bg: #1e0e10;--node-line: #7a3330;--graph-bg: #14090a;--graph-grid: rgba(255, 123, 84, .12);--edge-cheap: #5a3330;--edge-expensive: #ff7b54;--edge-critical: #ff3b3b;--shadow: rgba(255, 123, 84, .14)}[data-theme=lavender]{--bg: #12101c;--bg-2: #1a1730;--surface: #221e3c;--line: #3b3560;--ink: #efeaff;--muted: #b3a7d6;--high: #80ffdb;--medium: #ffd166;--low: #ff6b9d;--critical: #ff4d6d;--accent: #c77dff;--rail-from: #1a1730;--rail-to: #12101c;--rail-active: #2a2550;--btn: #2a2550;--btn-line: #c77dff;--btn-primary: #3d2a66;--btn-primary-line: #c77dff;--node-bg: #1a1730;--node-line: #5a4d8a;--graph-bg: #12101c;--graph-grid: rgba(199, 125, 255, .12);--edge-cheap: #5a4d8a;--edge-expensive: #ffd166;--edge-critical: #ff4d6d;--shadow: rgba(199, 125, 255, .14)}[data-theme=neon-noir]{--bg: #05060a;--bg-2: #0a0c14;--surface: #10131c;--line: #1e2436;--ink: #f0f4ff;--muted: #8b93b0;--high: #39ff88;--medium: #ffe66d;--low: #ff2d95;--critical: #ff3d5a;--accent: #00f0ff;--rail-from: #0a0c14;--rail-to: #05060a;--rail-active: #151a2a;--btn: #151a2a;--btn-line: #00f0ff;--btn-primary: #063a40;--btn-primary-line: #00f0ff;--node-bg: #0a0c14;--node-line: #2a3550;--graph-bg: #05060a;--graph-grid: rgba(0, 240, 255, .12);--edge-cheap: #3a4560;--edge-expensive: #ff2d95;--edge-critical: #ff3d5a;--shadow: rgba(0, 240, 255, .22)}[data-theme=synthwave]{--bg: #1a0a2e;--bg-2: #240b3d;--surface: #2d1250;--line: #4a1d7a;--ink: #ffe6fb;--muted: #c49ad8;--high: #00f5d4;--medium: #ffd60a;--low: #ff6b9d;--critical: #ff006e;--accent: #ff2bd6;--rail-from: #240b3d;--rail-to: #1a0a2e;--rail-active: #3a1570;--btn: #3a1570;--btn-line: #ff2bd6;--btn-primary: #5a0a4a;--btn-primary-line: #ff2bd6;--node-bg: #240b3d;--node-line: #7b2cbf;--graph-bg: #1a0a2e;--graph-grid: rgba(255, 43, 214, .16);--edge-cheap: #5a3a80;--edge-expensive: #ff9e00;--edge-critical: #ff006e;--shadow: rgba(255, 43, 214, .24)}[data-theme=phosphor]{--bg: #020804;--bg-2: #061208;--surface: #0a1a0e;--line: #163c1e;--ink: #c8ffc8;--muted: #5aaa5a;--high: #39ff14;--medium: #c8f542;--low: #ffb000;--critical: #ff5e00;--accent: #00ff66;--rail-from: #061208;--rail-to: #020804;--rail-active: #0e2414;--btn: #0e2414;--btn-line: #00ff66;--btn-primary: #0a3a18;--btn-primary-line: #00ff66;--node-bg: #061208;--node-line: #1e6a32;--graph-bg: #020804;--graph-grid: rgba(0, 255, 102, .12);--edge-cheap: #1e5a2a;--edge-expensive: #c8f542;--edge-critical: #ff5e00;--shadow: rgba(0, 255, 102, .2)}[data-theme=aurora]{--bg: #071018;--bg-2: #0c1c28;--surface: #122636;--line: #1e3d52;--ink: #e8fff6;--muted: #7eb8a8;--high: #5fffcf;--medium: #ffe566;--low: #ff7eb6;--critical: #ff4d6d;--accent: #7cffb2;--rail-from: #0c1c28;--rail-to: #071018;--rail-active: #163044;--btn: #163044;--btn-line: #7cffb2;--btn-primary: #0e3d3a;--btn-primary-line: #7cffb2;--node-bg: #0c1c28;--node-line: #2a6a78;--graph-bg: #071018;--graph-grid: rgba(124, 255, 178, .12);--edge-cheap: #2a5a68;--edge-expensive: #c9a0ff;--edge-critical: #ff4d6d;--shadow: rgba(124, 255, 178, .18)}[data-theme=biolume]{--bg: #02141c;--bg-2: #042430;--surface: #073040;--line: #0a4a5c;--ink: #e6fffb;--muted: #6eb8b0;--high: #5dffb0;--medium: #ffe066;--low: #ff79c6;--critical: #ff4d6d;--accent: #18e7d4;--rail-from: #042430;--rail-to: #02141c;--rail-active: #0a3848;--btn: #0a3848;--btn-line: #18e7d4;--btn-primary: #0a4a48;--btn-primary-line: #18e7d4;--node-bg: #042430;--node-line: #1a7080;--graph-bg: #02141c;--graph-grid: rgba(24, 231, 212, .12);--edge-cheap: #1a5a68;--edge-expensive: #ff79c6;--edge-critical: #ff4d6d;--shadow: rgba(24, 231, 212, .2)}[data-theme=carbon]{--bg: #0d0d0f;--bg-2: #16161a;--surface: #1e1e24;--line: #33333c;--ink: #f2f2f4;--muted: #9a9aa8;--high: #3dd68c;--medium: #f0c040;--low: #ff5a5a;--critical: #ff2a2a;--accent: #ff2a2a;--rail-from: #16161a;--rail-to: #0d0d0f;--rail-active: #24242c;--btn: #24242c;--btn-line: #ff2a2a;--btn-primary: #4a1212;--btn-primary-line: #ff2a2a;--node-bg: #16161a;--node-line: #4a4a55;--graph-bg: #0d0d0f;--graph-grid: rgba(255, 42, 42, .1);--edge-cheap: #4a4a55;--edge-expensive: #ff8a3d;--edge-critical: #ff2a2a;--shadow: rgba(255, 42, 42, .18)}[data-theme=paper]{--bg: #f6f1e8;--bg-2: #efe6d6;--surface: #fffaf2;--line: #d9cbb6;--ink: #2b241c;--muted: #6f6456;--high: #2a7a4b;--medium: #b5811a;--low: #c0392b;--critical: #a93226;--accent: #1d6a7a;--rail-from: #efe6d6;--rail-to: #e7dcc8;--rail-active: #e2d3bb;--btn: #fffaf2;--btn-line: #c9b79a;--btn-primary: #d7eee0;--btn-primary-line: #2a7a4b;--node-bg: #fffaf2;--node-line: #c9b79a;--graph-bg: #f6f1e8;--graph-grid: rgba(29, 106, 122, .1);--edge-cheap: #b7a48c;--edge-expensive: #c0392b;--edge-critical: #a93226;--shadow: rgba(43, 36, 28, .08)}[data-theme=solarized-light]{--bg: #fdf6e3;--bg-2: #eee8d5;--surface: #f5efdc;--line: #d6cba9;--ink: #657b83;--muted: #93a1a1;--high: #859900;--medium: #b58900;--low: #dc322f;--critical: #cb4b16;--accent: #268bd2;--rail-from: #eee8d5;--rail-to: #e6dfc8;--rail-active: #e0d9c0;--btn: #fdf6e3;--btn-line: #93a1a1;--btn-primary: #e8efc8;--btn-primary-line: #859900;--node-bg: #fdf6e3;--node-line: #93a1a1;--graph-bg: #fdf6e3;--graph-grid: rgba(38, 139, 210, .12);--edge-cheap: #93a1a1;--edge-expensive: #cb4b16;--edge-critical: #dc322f;--shadow: rgba(101, 123, 131, .1)}[data-theme=seafoam]{--bg: #eef7f4;--bg-2: #dff0ea;--surface: #ffffff;--line: #b7d5cc;--ink: #17332c;--muted: #4d7268;--high: #1b8a5a;--medium: #c48a14;--low: #c44536;--critical: #9b2d22;--accent: #1d9a8a;--rail-from: #dff0ea;--rail-to: #cfe6de;--rail-active: #c4ddd4;--btn: #ffffff;--btn-line: #8fbfb2;--btn-primary: #d4f0e4;--btn-primary-line: #1b8a5a;--node-bg: #ffffff;--node-line: #8fbfb2;--graph-bg: #eef7f4;--graph-grid: rgba(29, 154, 138, .12);--edge-cheap: #8fbfb2;--edge-expensive: #c48a14;--edge-critical: #c44536;--shadow: rgba(23, 51, 44, .08)}[data-theme=high-contrast]{--bg: #ffffff;--bg-2: #f2f2f2;--surface: #ffffff;--line: #111111;--ink: #000000;--muted: #222222;--high: #007a33;--medium: #8a5a00;--low: #b00000;--critical: #9b0000;--accent: #0033cc;--rail-from: #f2f2f2;--rail-to: #e6e6e6;--rail-active: #d9d9d9;--btn: #ffffff;--btn-line: #000000;--btn-primary: #d9f2e3;--btn-primary-line: #007a33;--node-bg: #ffffff;--node-line: #000000;--graph-bg: #ffffff;--graph-grid: rgba(0, 0, 0, .12);--edge-cheap: #444444;--edge-expensive: #8a5a00;--edge-critical: #b00000;--shadow: rgba(0, 0, 0, .12)}[data-theme=sakura]{--bg: #fff0f5;--bg-2: #ffe4ee;--surface: #fff7fa;--line: #f5b8cc;--ink: #4a1830;--muted: #a05a78;--high: #1a8a5c;--medium: #c48a14;--low: #d63d6e;--critical: #b01040;--accent: #e84a8a;--rail-from: #ffe4ee;--rail-to: #f8d4e0;--rail-active: #f5c8d8;--btn: #fff7fa;--btn-line: #e89ab0;--btn-primary: #ffd6e6;--btn-primary-line: #e84a8a;--node-bg: #fff7fa;--node-line: #e89ab0;--graph-bg: #fff0f5;--graph-grid: rgba(232, 74, 138, .12);--edge-cheap: #d4a0b0;--edge-expensive: #d63d6e;--edge-critical: #b01040;--shadow: rgba(74, 24, 48, .1)}[data-theme=citrus]{--bg: #fffce8;--bg-2: #fff3b0;--surface: #fffef5;--line: #e8d44a;--ink: #2a2a08;--muted: #6a6a20;--high: #2a8a20;--medium: #d4a000;--low: #e85d04;--critical: #c0392b;--accent: #5aad14;--rail-from: #fff3b0;--rail-to: #ffe98a;--rail-active: #ffe066;--btn: #fffef5;--btn-line: #d4c030;--btn-primary: #e8f5b8;--btn-primary-line: #5aad14;--node-bg: #fffef5;--node-line: #d4c030;--graph-bg: #fffce8;--graph-grid: rgba(90, 173, 20, .14);--edge-cheap: #c4b040;--edge-expensive: #e85d04;--edge-critical: #c0392b;--shadow: rgba(42, 42, 8, .1)}[data-theme=peach]{--bg: #fff3eb;--bg-2: #ffe0cc;--surface: #fffaf6;--line: #f0c4a8;--ink: #3a2218;--muted: #8a5a48;--high: #2a8a5c;--medium: #d48a14;--low: #e85d3a;--critical: #c0392b;--accent: #ff6b35;--rail-from: #ffe0cc;--rail-to: #ffd4b8;--rail-active: #ffc8a8;--btn: #fffaf6;--btn-line: #e8a888;--btn-primary: #ffe0cc;--btn-primary-line: #ff6b35;--node-bg: #fffaf6;--node-line: #e8a888;--graph-bg: #fff3eb;--graph-grid: rgba(255, 107, 53, .12);--edge-cheap: #d4a088;--edge-expensive: #e85d3a;--edge-critical: #c0392b;--shadow: rgba(58, 34, 24, .1)}[data-theme=candy]{--bg: #f4f0ff;--bg-2: #e8dcff;--surface: #fbf8ff;--line: #d4c0f0;--ink: #2a1848;--muted: #6a5890;--high: #1a8a6a;--medium: #c48a14;--low: #e84a8a;--critical: #c01060;--accent: #ff5eb1;--rail-from: #e8dcff;--rail-to: #ddd0ff;--rail-active: #d4c4ff;--btn: #fbf8ff;--btn-line: #c4a8e8;--btn-primary: #ffd6ec;--btn-primary-line: #ff5eb1;--node-bg: #fbf8ff;--node-line: #c4a8e8;--graph-bg: #f4f0ff;--graph-grid: rgba(255, 94, 177, .14);--edge-cheap: #b0a0d0;--edge-expensive: #e84a8a;--edge-critical: #c01060;--shadow: rgba(42, 24, 72, .1)}[data-theme=sky]{--bg: #e8f4ff;--bg-2: #cfe8ff;--surface: #f5faff;--line: #90c8f0;--ink: #0a2848;--muted: #3a6080;--high: #0a8a4a;--medium: #c48a14;--low: #e85d3a;--critical: #c0392b;--accent: #0077ff;--rail-from: #cfe8ff;--rail-to: #b8dcff;--rail-active: #a8d4ff;--btn: #f5faff;--btn-line: #70b0e0;--btn-primary: #cfe8ff;--btn-primary-line: #0077ff;--node-bg: #f5faff;--node-line: #70b0e0;--graph-bg: #e8f4ff;--graph-grid: rgba(0, 119, 255, .12);--edge-cheap: #80b0d0;--edge-expensive: #e85d3a;--edge-critical: #c0392b;--shadow: rgba(10, 40, 72, .1)}[data-theme=coral]{--bg: #fff1ee;--bg-2: #ffddd6;--surface: #fff8f6;--line: #f0b0a4;--ink: #3a1814;--muted: #8a5048;--high: #0d9488;--medium: #d48a14;--low: #e85d4a;--critical: #c0392b;--accent: #0d9488;--rail-from: #ffddd6;--rail-to: #ffd0c6;--rail-active: #ffc4b8;--btn: #fff8f6;--btn-line: #e89888;--btn-primary: #d4f4ee;--btn-primary-line: #0d9488;--node-bg: #fff8f6;--node-line: #e89888;--graph-bg: #fff1ee;--graph-grid: rgba(13, 148, 136, .14);--edge-cheap: #d4a098;--edge-expensive: #e85d4a;--edge-critical: #c0392b;--shadow: rgba(58, 24, 20, .1)}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}:root{--radius: 6px;--radius-lg: 10px;--control-h: 32px;--font: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;--mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;--focus-ring: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent);--space: 8px}body{background:var(--bg);color:var(--ink);font-family:var(--font);font-size:13px;line-height:1.45;-webkit-font-smoothing:antialiased}button,input,select,textarea{font-family:inherit;font-size:inherit;color:inherit}button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,a:focus-visible,summary:focus-visible{outline:none;box-shadow:var(--focus-ring)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.skip{position:absolute;left:12px;top:-40px;z-index:50;background:var(--surface);color:var(--ink);border:1px solid var(--accent);border-radius:var(--radius);padding:8px 12px}.skip:focus{top:12px}.app{display:grid;grid-template-columns:232px 1fr;height:100%}.rail{border-right:1px solid var(--line);background:linear-gradient(180deg,var(--rail-from),var(--rail-to));padding:16px 12px;display:flex;flex-direction:column;gap:2px;min-width:0}.brand{display:flex;flex-direction:column;gap:2px;padding:4px 8px 16px}.brand-mark{font-family:var(--mono);letter-spacing:.16em;font-size:11px;text-transform:uppercase;color:var(--accent);font-weight:600}.brand-sub{font-size:11px;color:var(--muted)}.nav-item{display:flex;align-items:center;gap:10px;background:transparent;border:0;text-align:left;padding:8px 10px;border-radius:var(--radius);color:var(--muted);cursor:pointer;width:100%}.nav-item:hover{background:color-mix(in srgb,var(--rail-active) 70%,transparent);color:var(--ink)}.nav-item.active{background:var(--rail-active);color:var(--ink);font-weight:500}.nav-item svg{flex-shrink:0}.theme-pick{margin-top:14px;display:grid;gap:4px;padding:0 2px}.theme-pick label{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);font-weight:500}.theme-pick select,.field select,.field input,.topbar input,.topbar select,.settings input,.settings select,.explorer-path input{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:0 10px;height:var(--control-h);width:100%}.rail-foot{margin-top:auto;padding:12px 8px 4px;border-top:1px solid var(--line);display:grid;gap:6px}.kbd-hint{font-size:11px;color:var(--muted)}kbd{font-family:var(--mono);font-size:10px;border:1px solid var(--line);border-radius:4px;padding:0 4px;background:var(--surface)}.main{display:flex;flex-direction:column;min-width:0;min-height:0;position:relative;background:var(--bg)}.progress{position:absolute;top:0;left:0;right:0;height:2px;overflow:hidden;z-index:30;background:color-mix(in srgb,var(--accent) 20%,transparent)}.progress i{display:block;height:100%;width:32%;background:var(--accent);animation:indeterminate 1.1s ease-in-out infinite}.progress.determinate i{width:0;animation:none;transform:none;transition:width .2s ease-out}@keyframes indeterminate{0%{transform:translate(-120%)}to{transform:translate(400%)}}.topbar{display:flex;gap:10px;align-items:flex-end;padding:10px 16px;border-bottom:1px solid var(--line);background:var(--bg-2);flex-wrap:wrap}.field{display:grid;gap:4px;min-width:0}.field>span{font-size:11px;color:var(--muted);font-weight:500}.field.path{flex:1;min-width:180px}.field.ref{width:188px;flex:0 0 188px}.field.workspace{width:180px;flex:0 0 180px}.path-row,.combo-row{display:flex;min-width:0}.path-row input,.combo-row input{flex:1;min-width:0}.combo{position:relative;min-width:0}.combo-row input{border-top-right-radius:0;border-bottom-right-radius:0}.topbar .icon-btn{width:var(--control-h);padding:0;flex:0 0 var(--control-h)}.combo-toggle{border-top-left-radius:0;border-bottom-left-radius:0;border-left:0}.combo-menu{position:absolute;top:calc(100% + 4px);right:0;left:auto;min-width:340px;max-width:min(480px,70vw);max-height:360px;overflow:auto;z-index:40;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);box-shadow:0 12px 32px var(--shadow);padding:6px 0}.combo-heading{font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);font-weight:600;padding:8px 12px 4px}.combo-menu .combo-option{display:flex;flex-direction:column;align-items:flex-start;gap:2px;width:100%;text-align:left;background:transparent;border:0;border-radius:0;height:auto;padding:6px 12px;color:var(--ink);cursor:pointer}.combo-menu .combo-option:hover,.combo-menu .combo-option.active{background:var(--rail-active)}.combo-label{font-family:var(--mono);font-size:12px}.combo-detail{color:var(--muted);font-size:12px;line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.combo-empty{padding:10px 12px}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:50;background:color-mix(in srgb,var(--bg) 72%,transparent);display:grid;place-items:center;padding:24px}.modal{width:min(720px,100%);max-height:min(640px,90vh);background:var(--bg-2);border:1px solid var(--line);border-radius:var(--radius-lg);box-shadow:0 16px 48px var(--shadow);display:flex;flex-direction:column;overflow:hidden}.modal-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:14px 16px 10px;border-bottom:1px solid var(--line)}.modal-head h2{font-size:15px}.modal-head .muted{margin:4px 0 0}.explorer-path{display:flex;gap:8px;padding:12px 16px;border-bottom:1px solid var(--line)}.explorer-path input{flex:1;min-width:0}.explorer-list{flex:1;overflow:auto;padding:8px;min-height:220px}.explorer-row{display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:transparent;border:0;border-radius:var(--radius);padding:8px 10px;color:var(--ink);cursor:pointer;height:auto}.explorer-row:hover,.explorer-row.active{background:var(--rail-active)}.explorer-name{min-width:0;overflow:hidden;text-overflow:ellipsis}.git-badge{margin-left:auto;margin-bottom:0}.explorer-empty{padding:18px 10px}.modal-foot{display:flex;align-items:center;gap:12px;padding:12px 16px;border-top:1px solid var(--line)}.explorer-current{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--mono);font-size:12px}.topbar input,.topbar select{min-width:0}.topbar-actions{display:flex;gap:8px;margin-left:auto;align-items:center;padding-bottom:0}.btn,.topbar button{background:var(--btn);border:1px solid var(--btn-line);border-radius:var(--radius);height:var(--control-h);padding:0 12px;cursor:pointer;font-weight:500;display:inline-flex;align-items:center;justify-content:center;gap:6px;white-space:nowrap}.btn:hover,.topbar button:hover{filter:brightness(1.08)}.btn:disabled,.topbar button:disabled{opacity:.55;cursor:not-allowed;filter:none}.btn.primary{background:var(--btn-primary);border-color:var(--btn-primary-line)}.btn.ghost{background:transparent}.alerts{display:grid;gap:8px;padding:10px 16px 0}.alerts:empty{display:none;padding:0}.stage{flex:1;min-height:0;display:flex;flex-direction:column}.content{flex:1;min-height:0;display:grid;grid-template-columns:minmax(340px,420px) 1fr}.brief{overflow:auto;border-right:1px solid var(--line);padding:16px 18px 24px;background:radial-gradient(circle at 0 0,color-mix(in srgb,var(--accent) 8%,transparent),transparent 42%),var(--bg)}.graph-wrap{position:relative;min-height:0;display:flex;flex-direction:column}.impact-graph{flex:1;min-height:0;position:relative;display:flex;flex-direction:column}.graph-toolbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:8px 14px;border-bottom:1px solid var(--line);background:var(--bg-2)}.graph-count{margin-left:auto;font-size:11px}.graph-layout{display:inline-flex;align-items:center;gap:6px;font-size:11px;color:var(--muted);letter-spacing:.04em}.graph-layout select{background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:0 10px;height:26px;color:var(--ink);font:inherit;font-size:12px;letter-spacing:0;cursor:pointer}.chip-btn{background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:4px 12px;color:var(--muted);cursor:pointer;height:26px}.chip-btn:hover{color:var(--ink)}.chip-btn.active{background:var(--rail-active);color:var(--ink)}.chip-btn:disabled{opacity:.45;cursor:not-allowed}.graph-stage{flex:1;min-height:0;position:relative;display:flex;flex-direction:column}.graph-stage .react-flow,.graph-3d,.graph-3d-host,.graph-3d-canvas-host{flex:1;width:100%;height:100%;min-height:280px}.graph-3d{position:relative;background:var(--graph-bg);display:flex;flex-direction:column}.graph-3d-host{position:relative;min-height:0;display:flex;flex-direction:column}.graph-3d-canvas-host{position:relative;min-height:0;background:var(--graph-bg)}.graph-3d canvas{display:block;width:100%;height:100%}.graph-3d-tip{position:absolute;pointer-events:none;z-index:2;max-width:320px;padding:6px 8px;border-radius:var(--radius);background:var(--surface);border:1px solid var(--line);color:var(--ink);font-size:11px;line-height:1.35;box-shadow:0 8px 24px var(--shadow)}.graph-3d-tip .t{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.08em}.graph-3d-tip .n{font-weight:600}.graph-3d-hint{position:absolute;left:10px;bottom:10px;z-index:2;margin:0;font-size:11px;color:var(--muted);max-width:min(420px,calc(100% - 24px));pointer-events:none}.graph-wrap .react-flow{background-color:var(--graph-bg);background-image:linear-gradient(var(--graph-grid) 1px,transparent 1px),linear-gradient(90deg,var(--graph-grid) 1px,transparent 1px);background-size:24px 24px}.react-flow__minimap{background:var(--graph-bg)!important;border:1px solid var(--line)!important;border-radius:var(--radius);overflow:hidden;box-shadow:0 8px 24px var(--shadow)}.react-flow__minimap-node{fill:var(--muted);stroke:none}.react-flow__minimap-node.selected{fill:var(--accent)}.react-flow__minimap-mask{fill:#00000073!important;stroke:var(--accent)!important}.react-flow__controls{box-shadow:none!important}.react-flow__controls-button{background:var(--surface)!important;border-bottom:1px solid var(--line)!important;fill:var(--ink)!important}h1{font-size:18px;margin:0 0 6px;font-weight:600}h2{font-size:13px;margin:0;font-weight:600}.merge-box{border:1px solid var(--line);background:var(--surface);border-radius:var(--radius-lg);padding:12px 14px;margin-bottom:12px}.merge-box.high{border-color:color-mix(in srgb,var(--high) 55%,var(--line))}.merge-box.medium{border-color:color-mix(in srgb,var(--medium) 55%,var(--line))}.merge-box.low{border-color:color-mix(in srgb,var(--low) 55%,var(--line))}.level{font-family:var(--mono);font-weight:600;font-size:14px}.level.high{color:var(--high)}.level.medium{color:var(--medium)}.level.low{color:var(--low)}.merge-title{margin-top:4px;font-size:13px;color:var(--ink)}.reasons{margin:10px 0 0;padding:0 0 0 18px;color:var(--muted)}.reasons li{margin:0 0 4px}.metrics{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:0 0 14px}.metric{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:8px 10px}.metric .n{font-family:var(--mono);font-size:16px;font-weight:600;font-variant-numeric:tabular-nums}.metric .l{font-size:11px;color:var(--muted);margin-top:2px}.section{border-top:1px solid var(--line);padding:8px 0 4px}.section>summary{cursor:pointer;list-style:none;display:flex;align-items:center;justify-content:space-between;color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.07em;font-weight:600;padding:6px 0}.section>summary::-webkit-details-marker{display:none}.section>summary .count{font-family:var(--mono);letter-spacing:0;text-transform:none;border:1px solid var(--line);border-radius:999px;padding:0 7px;height:18px;display:inline-flex;align-items:center;font-size:11px}.kicker{color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.08em;margin:16px 0 6px;font-weight:600}.chip{display:inline-flex;align-items:center;font-size:11px;padding:2px 8px;border-radius:999px;border:1px solid var(--line);margin:0 6px 6px 0;color:var(--muted);background:var(--surface)}.chip.blocker{color:var(--low);border-color:var(--low)}.chip.warning{color:var(--medium);border-color:var(--medium)}.chip.strong{color:var(--low);border-color:var(--low)}.chip.worth_exploring{color:var(--medium);border-color:var(--medium)}.chip.speculative{color:var(--muted);border-color:var(--line)}.chip.open{color:var(--high);border-color:color-mix(in srgb,var(--high) 50%,var(--line))}.file{font-family:var(--mono);font-size:12px;color:var(--accent)}.read-item,.finding,.residual{padding:8px 0;border-bottom:1px solid color-mix(in srgb,var(--line) 70%,transparent)}.read-item:last-child,.finding:last-child{border-bottom:0}.read-item.tour-current{background:color-mix(in srgb,var(--accent) 12%,var(--surface));border-color:var(--accent)}.tour-row{margin-top:8px;align-items:center}.field.dirty .chip-btn{height:32px}.muted{color:var(--muted);font-size:13px;line-height:1.45}.error{color:var(--low);padding:8px 12px;border:1px solid var(--low);background:color-mix(in srgb,var(--low) 10%,var(--surface));border-radius:var(--radius);display:flex;justify-content:space-between;gap:12px;align-items:flex-start}.banner{padding:8px 12px;border-radius:var(--radius);border:1px solid var(--line);background:var(--surface);font-size:13px;line-height:1.45;display:flex;justify-content:space-between;gap:12px;align-items:flex-start}.banner.warn{border-color:var(--medium);color:var(--medium)}.banner.stale{border-color:var(--low);color:var(--low)}.banner .dismiss{background:transparent;border:0;color:inherit;cursor:pointer;height:auto;padding:0 2px;opacity:.7}.empty{padding:24px 8px;color:var(--muted);font-size:13px;line-height:1.55}.workspace-loading{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;min-height:220px;padding:48px 16px}.empty h2{font-size:16px;color:var(--ink);margin-bottom:8px}.empty ol{margin:12px 0 0 18px;padding:0}.empty code,code{font-family:var(--mono);font-size:12px;color:var(--accent)}.btn-row{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.pr-list{padding:16px;overflow:auto}.pr-toolbar{display:flex;gap:8px;align-items:flex-end;margin-bottom:14px}.pr-toolbar .field{flex:1}.pr-toolbar .field.provider{flex:0 0 140px}.scm-count{margin:0 0 12px;font-size:12px}.scm-login{display:flex;justify-content:space-between;gap:12px;align-items:center;padding:10px 0;border-top:1px solid var(--line)}.scm-login:first-of-type{border-top:0;padding-top:0}.scm-login .btn-row{margin-top:0}.scm-login p{margin:2px 0 0}.oauth-code{font-size:13px;margin:0}.oauth-code code{font-size:14px;letter-spacing:.08em}.pr{border:1px solid var(--line);background:var(--surface);padding:12px 14px;border-radius:var(--radius-lg);margin-bottom:10px}.pr h3{margin:0 0 4px;font-size:14px;font-weight:600}.pr-meta{display:flex;flex-wrap:wrap;gap:8px 12px;align-items:center;margin:6px 0 10px}.pr-actions{display:flex;gap:8px;align-items:center}.settings{padding:24px;max-width:760px;overflow:auto;display:grid;gap:16px}.settings-card{border:1px solid var(--line);background:var(--surface);border-radius:var(--radius-lg);padding:16px;display:grid;gap:8px}.settings-card h2{font-size:14px;margin-bottom:2px}.settings label{font-size:12px;color:var(--muted);font-weight:500}.theme-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:8px}.theme-swatch{border:1px solid var(--line);background:var(--bg);color:var(--ink);border-radius:var(--radius);padding:10px;text-align:left;cursor:pointer;height:auto;box-shadow:0 1px 8px var(--shadow)}.theme-swatch.active{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent),0 1px 8px var(--shadow)}.theme-swatch .swatch-bar{height:6px;border-radius:3px;margin-bottom:8px;background:linear-gradient(90deg,var(--accent),var(--high),var(--medium),var(--low))}.theme-swatch .name{font-size:13px;font-weight:600}.theme-swatch .group{font-size:11px;color:var(--muted)}.headline{white-space:pre-wrap;font-family:var(--mono);font-size:12px;color:var(--muted);margin:8px 0 0}.graph-modes{display:flex;gap:8px;align-items:center;padding:8px 14px;border-bottom:1px solid var(--line);background:var(--bg-2)}.seg{display:inline-flex;border:1px solid var(--line);border-radius:999px;padding:2px;background:var(--surface)}.seg button,.graph-modes button{background:transparent;border:0;border-radius:999px;padding:4px 12px;color:var(--muted);cursor:pointer;height:26px}.seg button.active,.graph-modes button.active{background:var(--rail-active);color:var(--ink)}.legend{margin-left:auto;display:flex;gap:12px;color:var(--muted);font-size:11px}.legend i{display:inline-block;width:14px;height:2px;margin-right:6px;vertical-align:middle;background:var(--edge-cheap)}.legend i.exp{background:var(--edge-expensive)}.legend i.crit{background:var(--edge-critical);height:3px}.legend i.dash{border-top:2px dashed var(--muted);background:none;height:0}.inspector{position:absolute;top:12px;right:12px;z-index:5;width:300px;max-width:calc(100% - 24px);max-height:calc(100% - 24px);overflow-x:hidden;overflow-y:auto;overflow-wrap:break-word;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);padding:10px 12px;box-shadow:0 8px 24px var(--shadow);font-size:12px}.inspector .t{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.06em}.inspector .n,.inspector .file,.inspector .muted{overflow-wrap:break-word}.inspector .n{font-weight:600;margin:4px 0}.inspector-head{display:flex;align-items:flex-start;gap:8px}.inspector-roles{display:flex;flex-wrap:wrap;justify-content:flex-end;flex:1;gap:4px}.inspector-chip{font-size:10px;text-transform:uppercase;letter-spacing:.04em;padding:1px 6px;border-radius:999px;border:1px solid var(--line);color:var(--muted);white-space:nowrap}.inspector-close{flex:0 0 auto;width:24px;height:24px;padding:0;border:1px solid var(--line);border-radius:var(--radius);background:transparent;color:var(--muted);font-size:16px;line-height:1;cursor:pointer}.inspector-close:hover{color:var(--ink)}.inspector-purpose{margin:6px 0 8px;color:var(--ink);font-size:12px;line-height:1.4}.inspector-layer{margin-top:4px;font-size:11px}.inspector-degree{font-size:11px}.inspector-path{margin:6px 0 0;font-size:12px;line-height:1.4;color:var(--muted)}.inspector-facts{margin:10px 0 0;padding-top:8px;border-top:1px solid var(--line)}.inspector-fact{display:grid;grid-template-columns:minmax(64px,92px) minmax(0,1fr);gap:8px;padding:3px 0;align-items:start}.inspector-fact dt{color:var(--muted);font-size:11px;margin:0}.inspector-fact dd{margin:0;overflow-wrap:break-word}.inspector-section{margin-top:10px;padding-top:8px;border-top:1px solid var(--line)}.inspector-section h3{margin:0 0 6px;display:flex;align-items:center;justify-content:space-between;color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.07em;font-weight:600}.inspector-section .count{font-family:var(--mono);letter-spacing:0;text-transform:none;border:1px solid var(--line);border-radius:999px;padding:0 7px;height:18px;display:inline-flex;align-items:center;font-size:11px}.inspector-section ul{list-style:none;margin:0;padding:0}.inspector-section li{padding:4px 0;border-bottom:1px solid color-mix(in srgb,var(--line) 70%,transparent)}.inspector-section li:last-child{border-bottom:0}.inspector-link-name{display:block;font-weight:600;overflow-wrap:break-word}.inspector-link-meta{display:block;color:var(--muted);font-size:11px}.lp-node{padding:8px 10px;border-radius:var(--radius);border:1px solid var(--node-line);background:var(--node-bg);width:208px;max-width:100%;height:64px;box-sizing:border-box;box-shadow:0 0 0 1px var(--shadow);overflow:visible;position:relative}.lp-node .t{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.08em}.lp-node .n{font-size:13px;font-weight:600;line-height:1.2;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow-wrap:anywhere}.lp-node.selected{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}.react-flow__node-load .react-flow__handle{width:8px;height:8px;border:none;background:transparent;opacity:0}.type-table{width:100%;border-collapse:collapse;font-size:12px}.type-table td{padding:3px 0}.type-table td:last-child{text-align:right;font-family:var(--mono);font-variant-numeric:tabular-nums;color:var(--muted)}@media(prefers-reduced-motion:reduce){.progress i{animation:none;width:100%}.progress.determinate i{width:var(--progress, 100%)}*{scroll-behavior:auto!important}}@media(max-width:960px){.app{grid-template-columns:56px 1fr}.brand-sub,.nav-item span,.theme-pick,.kbd-hint,.rail-foot .muted{display:none}.nav-item{justify-content:center;padding:10px}.content{grid-template-columns:1fr}.brief{border-right:0;border-bottom:1px solid var(--line);max-height:42vh}} diff --git a/src/loadpath/static/index.html b/src/loadpath/static/index.html index 4b5036a..d28ef4c 100644 --- a/src/loadpath/static/index.html +++ b/src/loadpath/static/index.html @@ -17,8 +17,8 @@ - - + +