From bc68c7c7434445cd1998a89d588b663930d68668 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 14 Aug 2026 12:56:45 +0000 Subject: [PATCH 1/5] Add Loadpath: Django+React architecture impact graphs for PR review Index a monorepo into a typed SQLite graph, cluster a git diff by load path, and score merge confidence from sink tests, contract stitch, and architecture rules. Includes CLI, local app with GitHub/Bitbucket PR list and layered graph, plus a fixture proving serializer-field changes reach the React form. Co-authored-by: Damon --- .github/workflows/ci.yml | 30 + .gitignore | 25 + README.md | 91 +- .../backend/accounts/__init__.py | 0 .../demo_monorepo/backend/accounts/apps.py | 5 + .../demo_monorepo/backend/accounts/models.py | 9 + .../backend/accounts/serializers.py | 9 + .../demo_monorepo/backend/accounts/urls.py | 8 + .../demo_monorepo/backend/accounts/views.py | 13 + .../demo_monorepo/backend/billing/__init__.py | 0 .../demo_monorepo/backend/billing/admin.py | 8 + .../demo_monorepo/backend/billing/apps.py | 8 + .../billing/migrations/0001_initial.py | 14 + .../backend/billing/migrations/__init__.py | 0 .../demo_monorepo/backend/billing/models.py | 11 + .../backend/billing/serializers.py | 9 + .../demo_monorepo/backend/billing/services.py | 7 + .../demo_monorepo/backend/billing/signals.py | 10 + .../demo_monorepo/backend/billing/tasks.py | 9 + .../demo_monorepo/backend/billing/tests.py | 16 + .../demo_monorepo/backend/billing/urls.py | 16 + .../demo_monorepo/backend/billing/views.py | 17 + fixtures/demo_monorepo/backend/config/urls.py | 8 + fixtures/demo_monorepo/frontend/src/App.tsx | 11 + .../frontend/src/features/auth/MePage.tsx | 13 + .../src/features/billing/InvoiceForm.tsx | 14 + .../src/features/billing/InvoicePage.tsx | 12 + .../frontend/src/features/billing/api.ts | 12 + .../src/features/billing/invoiceSchema.ts | 7 + .../src/features/billing/useInvoice.ts | 9 + .../frontend/src/generated/invoices.ts | 2 + .../demo_monorepo/frontend/src/shared/api.ts | 4 + fixtures/demo_monorepo/loadpath.yml | 31 + fixtures/demo_monorepo/openapi.yaml | 39 + loadpath.yml.example | 29 + pyproject.toml | 49 + src/loadpath/__init__.py | 3 + src/loadpath/ai/__init__.py | 3 + src/loadpath/ai/providers.py | 124 + src/loadpath/architecture/__init__.py | 3 + src/loadpath/architecture/rules.py | 281 ++ src/loadpath/cli.py | 79 + src/loadpath/config.py | 139 + src/loadpath/extractors/__init__.py | 6 + src/loadpath/extractors/django.py | 722 +++ src/loadpath/extractors/react.py | 316 ++ src/loadpath/graph/__init__.py | 3 + src/loadpath/graph/store.py | 297 ++ src/loadpath/index.py | 148 + src/loadpath/providers/__init__.py | 3 + src/loadpath/providers/scm.py | 206 + src/loadpath/report/graph.html | 109 + src/loadpath/review/__init__.py | 4 + src/loadpath/review/cluster.py | 215 + src/loadpath/review/confidence.py | 146 + src/loadpath/review/diff.py | 101 + src/loadpath/review/engine.py | 355 ++ src/loadpath/review/render.py | 57 + src/loadpath/server/__init__.py | 3 + src/loadpath/server/app.py | 216 + src/loadpath/settings.py | 83 + src/loadpath/static/assets/index-COnAStm3.css | 1 + src/loadpath/static/assets/index-DigBKCrc.js | 62 + src/loadpath/static/index.html | 16 + src/loadpath/stitch/__init__.py | 3 + src/loadpath/stitch/openapi.py | 324 ++ src/loadpath/types.py | 244 + tests/__init__.py | 0 tests/conftest.py | 26 + tests/e2e/__init__.py | 0 tests/e2e/test_cli_review.py | 22 + tests/integration/__init__.py | 0 .../integration/test_review_vertical_slice.py | 109 + tests/unit/__init__.py | 0 tests/unit/test_ai.py | 37 + tests/unit/test_architecture_rules.py | 56 + tests/unit/test_django_extractors.py | 138 + tests/unit/test_index_and_stitch.py | 40 + tests/unit/test_providers_and_api.py | 75 + tests/unit/test_react_extractors.py | 73 + ui/index.html | 15 + ui/package-lock.json | 4266 +++++++++++++++++ ui/package.json | 26 + ui/src/App.tsx | 287 ++ ui/src/ImpactGraph.tsx | 53 + ui/src/api.ts | 44 + ui/src/main.tsx | 10 + ui/src/styles.css | 146 + ui/src/types.test.ts | 18 + ui/src/types.ts | 127 + ui/src/vite-env.d.ts | 1 + ui/tsconfig.json | 21 + ui/vite.config.ts | 20 + 93 files changed, 10436 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 fixtures/demo_monorepo/backend/accounts/__init__.py create mode 100644 fixtures/demo_monorepo/backend/accounts/apps.py create mode 100644 fixtures/demo_monorepo/backend/accounts/models.py create mode 100644 fixtures/demo_monorepo/backend/accounts/serializers.py create mode 100644 fixtures/demo_monorepo/backend/accounts/urls.py create mode 100644 fixtures/demo_monorepo/backend/accounts/views.py create mode 100644 fixtures/demo_monorepo/backend/billing/__init__.py create mode 100644 fixtures/demo_monorepo/backend/billing/admin.py create mode 100644 fixtures/demo_monorepo/backend/billing/apps.py create mode 100644 fixtures/demo_monorepo/backend/billing/migrations/0001_initial.py create mode 100644 fixtures/demo_monorepo/backend/billing/migrations/__init__.py create mode 100644 fixtures/demo_monorepo/backend/billing/models.py create mode 100644 fixtures/demo_monorepo/backend/billing/serializers.py create mode 100644 fixtures/demo_monorepo/backend/billing/services.py create mode 100644 fixtures/demo_monorepo/backend/billing/signals.py create mode 100644 fixtures/demo_monorepo/backend/billing/tasks.py create mode 100644 fixtures/demo_monorepo/backend/billing/tests.py create mode 100644 fixtures/demo_monorepo/backend/billing/urls.py create mode 100644 fixtures/demo_monorepo/backend/billing/views.py create mode 100644 fixtures/demo_monorepo/backend/config/urls.py create mode 100644 fixtures/demo_monorepo/frontend/src/App.tsx create mode 100644 fixtures/demo_monorepo/frontend/src/features/auth/MePage.tsx create mode 100644 fixtures/demo_monorepo/frontend/src/features/billing/InvoiceForm.tsx create mode 100644 fixtures/demo_monorepo/frontend/src/features/billing/InvoicePage.tsx create mode 100644 fixtures/demo_monorepo/frontend/src/features/billing/api.ts create mode 100644 fixtures/demo_monorepo/frontend/src/features/billing/invoiceSchema.ts create mode 100644 fixtures/demo_monorepo/frontend/src/features/billing/useInvoice.ts create mode 100644 fixtures/demo_monorepo/frontend/src/generated/invoices.ts create mode 100644 fixtures/demo_monorepo/frontend/src/shared/api.ts create mode 100644 fixtures/demo_monorepo/loadpath.yml create mode 100644 fixtures/demo_monorepo/openapi.yaml create mode 100644 loadpath.yml.example create mode 100644 pyproject.toml create mode 100644 src/loadpath/__init__.py create mode 100644 src/loadpath/ai/__init__.py create mode 100644 src/loadpath/ai/providers.py create mode 100644 src/loadpath/architecture/__init__.py create mode 100644 src/loadpath/architecture/rules.py create mode 100644 src/loadpath/cli.py create mode 100644 src/loadpath/config.py create mode 100644 src/loadpath/extractors/__init__.py create mode 100644 src/loadpath/extractors/django.py create mode 100644 src/loadpath/extractors/react.py create mode 100644 src/loadpath/graph/__init__.py create mode 100644 src/loadpath/graph/store.py create mode 100644 src/loadpath/index.py create mode 100644 src/loadpath/providers/__init__.py create mode 100644 src/loadpath/providers/scm.py create mode 100644 src/loadpath/report/graph.html create mode 100644 src/loadpath/review/__init__.py create mode 100644 src/loadpath/review/cluster.py create mode 100644 src/loadpath/review/confidence.py create mode 100644 src/loadpath/review/diff.py create mode 100644 src/loadpath/review/engine.py create mode 100644 src/loadpath/review/render.py create mode 100644 src/loadpath/server/__init__.py create mode 100644 src/loadpath/server/app.py create mode 100644 src/loadpath/settings.py create mode 100644 src/loadpath/static/assets/index-COnAStm3.css create mode 100644 src/loadpath/static/assets/index-DigBKCrc.js create mode 100644 src/loadpath/static/index.html create mode 100644 src/loadpath/stitch/__init__.py create mode 100644 src/loadpath/stitch/openapi.py create mode 100644 src/loadpath/types.py create mode 100644 tests/__init__.py create mode 100644 tests/conftest.py create mode 100644 tests/e2e/__init__.py create mode 100644 tests/e2e/test_cli_review.py create mode 100644 tests/integration/__init__.py create mode 100644 tests/integration/test_review_vertical_slice.py create mode 100644 tests/unit/__init__.py create mode 100644 tests/unit/test_ai.py create mode 100644 tests/unit/test_architecture_rules.py create mode 100644 tests/unit/test_django_extractors.py create mode 100644 tests/unit/test_index_and_stitch.py create mode 100644 tests/unit/test_providers_and_api.py create mode 100644 tests/unit/test_react_extractors.py create mode 100644 ui/index.html create mode 100644 ui/package-lock.json create mode 100644 ui/package.json create mode 100644 ui/src/App.tsx create mode 100644 ui/src/ImpactGraph.tsx create mode 100644 ui/src/api.ts create mode 100644 ui/src/main.tsx create mode 100644 ui/src/styles.css create mode 100644 ui/src/types.test.ts create mode 100644 ui/src/types.ts create mode 100644 ui/src/vite-env.d.ts create mode 100644 ui/tsconfig.json create mode 100644 ui/vite.config.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..221feea --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,30 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - uses: actions/setup-node@v4 + with: + node-version: "22" + cache: npm + cache-dependency-path: ui/package-lock.json + - name: Python tests + run: | + python -m pip install -e ".[dev]" + pytest + - name: UI tests + working-directory: ui + run: | + npm install + npm test + npm run build diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e179c39 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +.venv/ +venv/ +__pycache__/ +*.py[cod] +*.egg-info/ +.pytest_cache/ +.mypy_cache/ +.ruff_cache/ +.coverage +htmlcov/ +dist/ +build/ +node_modules/ +ui/dist/ +*.db +*.sqlite3 +.loadpath/ +.env +.DS_Store +.idea/ +.vscode/ +*.log +.playwright-mcp/ +ui/playwright-report/ +ui/test-results/ diff --git a/README.md b/README.md index deb3007..7e52cf2 100644 --- a/README.md +++ b/README.md @@ -1 +1,90 @@ -# PR-Reviewer \ No newline at end of file +# Loadpath + +Review as **load-path inspection** on a Django + React architecture graph. Not another hunk-comment bot. + +A change is a force. Loadpath traces where that force travels until it hits a sink (HTTP response, UI, job, migration, permission) — then scores whether you have enough evidence to merge. + +## What you get on every PR + +1. **Clustered diff** — one cluster is one load path, not one file +2. **Impact graph** — real Django/React node types, typed weighted edges +3. **Confidence brief** — sink tests, contract coverage, architecture rules, residual unknowns + +``` +Loadpath: MEDIUM — Invoice.total field change +Sinks: GET/POST /api/invoices, Celery send_invoice_email, React InvoicePage + InvoiceForm +Tests: pytest hits serializer and view; no RTL test on InvoiceForm +Architecture: stays inside billing +Residual: total also formatted in a Signal update_ledger — no test +Suggested reviewers: billing-team +``` + +## Install + +Python 3.12+ and Node 22+ (UI). + +```bash +pip install -e ".[dev]" +cd ui && npm install && npm run build && cd .. +loadpath --help +``` + +## CLI + +```bash +# Index a monorepo (SQLite graph, incremental on file hashes) +loadpath index /path/to/repo + +# Review a git range → markdown brief (also --format html|json) +loadpath review /path/to/repo --base origin/main --head HEAD + +# Cross-platform app (API + visual graph + PR list) +loadpath serve --port 7345 +``` + +Put `loadpath.yml` at the repo root (see `loadpath.yml.example` and `fixtures/demo_monorepo/loadpath.yml`). The tool is opinionated about *your* architecture, not a generic module graph. + +## App + +`loadpath serve` opens a local desktop-style UI: + +- **Review** — confidence, read-order, clusters, architecture blockers, residual list +- **Impact graph** — layered load path (Django → OpenAPI stitch → React) +- **Pull requests** — GitHub and Bitbucket via API tokens in Settings +- **Settings** — GitHub/Bitbucket tokens; AI providers (Anthropic, OpenAI, Grok/xAI, DeepSeek, Cursor-compatible, Ollama) + +Tokens live in `~/.loadpath/settings.json` on the machine running the app. AI is used **only** for residual uncertainty the graph cannot close (`getattr`, raw SQL, `get_serializer_class`, `AppConfig.ready()` signals, string model refs, inferred URL stitches). It does not comment every hunk. + +## How confidence is scored + +Line coverage on changed files is the wrong metric. Loadpath scores the **impact subgraph**: + +| Signal | High | Low | +| --- | --- | --- | +| Tests | Sinks in the radius are hit by tests that still reach the changed symbol | Serializer changed, tests only on the view happy path | +| Contract | OpenAPI/client types track the serializer | React path/Zod field still old | +| Architecture | No new cross-context edges | `crosses_context` with no waiver | +| Graph | Resolved edges | Many inferred/dynamic edges | + +`high` / `medium` / `low` plus three reasons. Isolated leaf UI with green tests and no rule hits is labeled `loadpath:low-risk`. + +## Extractors + +**Django (framework overlay, not just imports):** `urls.py` / DRF router, `serializer_class` / `get_serializer_class`, `Meta.fields`, permissions, model `_meta`-shaped AST (FK/`on_delete`), `@receiver`, `@shared_task` / `.delay(`, `apps.get_model("app.Model")`, migration ops, pytest node ids as `tested_by`. + +**React:** react-router tables, composition, TanStack Query `queryKey` + fetch/axios URL templates, Zod schemas, feature-folder imports, RTL `render()` as `tested_by`. + +**Stitch (the moat):** OpenAPI from Spectacular/schema files first; generated clients (`generated/`, orval, openapi-typescript) as high-confidence `consumed_by_client`; fallback URL-template matching and serializer/Zod field overlap marked **inferred**. + +## Tests + +```bash +pytest +cd ui && npm test +``` + +The vertical slice in `tests/integration/test_review_vertical_slice.py` indexes `fixtures/demo_monorepo`, changes one serializer field, and asserts the path reaches the React form with a medium/low confidence reason. + +## What this is not + +Not CodeRabbit (comments without a closed impact set). Not CodeScene (historical coupling). Not django-orm-lens (models only). Not a generic SCIP call graph. The product is review as load-path inspection. diff --git a/fixtures/demo_monorepo/backend/accounts/__init__.py b/fixtures/demo_monorepo/backend/accounts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/fixtures/demo_monorepo/backend/accounts/apps.py b/fixtures/demo_monorepo/backend/accounts/apps.py new file mode 100644 index 0000000..fb0257e --- /dev/null +++ b/fixtures/demo_monorepo/backend/accounts/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class AccountsConfig(AppConfig): + name = "accounts" diff --git a/fixtures/demo_monorepo/backend/accounts/models.py b/fixtures/demo_monorepo/backend/accounts/models.py new file mode 100644 index 0000000..68cb07e --- /dev/null +++ b/fixtures/demo_monorepo/backend/accounts/models.py @@ -0,0 +1,9 @@ +from django.db import models + + +class UserProfile(models.Model): + email = models.EmailField() + display_name = models.CharField(max_length=120) + + class Meta: + app_label = "accounts" diff --git a/fixtures/demo_monorepo/backend/accounts/serializers.py b/fixtures/demo_monorepo/backend/accounts/serializers.py new file mode 100644 index 0000000..5ad60d7 --- /dev/null +++ b/fixtures/demo_monorepo/backend/accounts/serializers.py @@ -0,0 +1,9 @@ +from rest_framework import serializers + +from accounts.models import UserProfile + + +class MeSerializer(serializers.ModelSerializer): + class Meta: + model = UserProfile + fields = ["id", "email", "display_name"] diff --git a/fixtures/demo_monorepo/backend/accounts/urls.py b/fixtures/demo_monorepo/backend/accounts/urls.py new file mode 100644 index 0000000..dd9bba6 --- /dev/null +++ b/fixtures/demo_monorepo/backend/accounts/urls.py @@ -0,0 +1,8 @@ +from django.urls import path + +from accounts.views import MeView + +urlpatterns = [ + path("me/", MeView.as_view(), name="me"), + path("login/", MeView.as_view(), name="login"), +] diff --git a/fixtures/demo_monorepo/backend/accounts/views.py b/fixtures/demo_monorepo/backend/accounts/views.py new file mode 100644 index 0000000..6fe9276 --- /dev/null +++ b/fixtures/demo_monorepo/backend/accounts/views.py @@ -0,0 +1,13 @@ +from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response +from rest_framework.views import APIView + +from accounts.serializers import MeSerializer + + +class MeView(APIView): + permission_classes = [IsAuthenticated] + serializer_class = MeSerializer + + def get(self, request): + return Response({"email": request.user.email}) diff --git a/fixtures/demo_monorepo/backend/billing/__init__.py b/fixtures/demo_monorepo/backend/billing/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/fixtures/demo_monorepo/backend/billing/admin.py b/fixtures/demo_monorepo/backend/billing/admin.py new file mode 100644 index 0000000..c72ca2c --- /dev/null +++ b/fixtures/demo_monorepo/backend/billing/admin.py @@ -0,0 +1,8 @@ +from django.contrib import admin + +from billing.models import Invoice + + +@admin.register(Invoice) +class InvoiceAdmin(admin.ModelAdmin): + list_display = ["id", "total", "status"] diff --git a/fixtures/demo_monorepo/backend/billing/apps.py b/fixtures/demo_monorepo/backend/billing/apps.py new file mode 100644 index 0000000..e057ee3 --- /dev/null +++ b/fixtures/demo_monorepo/backend/billing/apps.py @@ -0,0 +1,8 @@ +from django.apps import AppConfig + + +class BillingConfig(AppConfig): + name = "billing" + + def ready(self): + from billing import signals # noqa: F401 diff --git a/fixtures/demo_monorepo/backend/billing/migrations/0001_initial.py b/fixtures/demo_monorepo/backend/billing/migrations/0001_initial.py new file mode 100644 index 0000000..3b4489f --- /dev/null +++ b/fixtures/demo_monorepo/backend/billing/migrations/0001_initial.py @@ -0,0 +1,14 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + operations = [ + migrations.CreateModel( + name="Invoice", + fields=[ + ("id", models.AutoField(primary_key=True)), + ("total", models.DecimalField(max_digits=10, decimal_places=2)), + ], + ), + ] diff --git a/fixtures/demo_monorepo/backend/billing/migrations/__init__.py b/fixtures/demo_monorepo/backend/billing/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/fixtures/demo_monorepo/backend/billing/models.py b/fixtures/demo_monorepo/backend/billing/models.py new file mode 100644 index 0000000..bae1123 --- /dev/null +++ b/fixtures/demo_monorepo/backend/billing/models.py @@ -0,0 +1,11 @@ +from django.db import models + + +class Invoice(models.Model): + customer_id = models.IntegerField() + total = models.DecimalField(max_digits=10, decimal_places=2) + status = models.CharField(max_length=32, default="draft") + created_at = models.DateTimeField(auto_now_add=True) + + class Meta: + app_label = "billing" diff --git a/fixtures/demo_monorepo/backend/billing/serializers.py b/fixtures/demo_monorepo/backend/billing/serializers.py new file mode 100644 index 0000000..485530b --- /dev/null +++ b/fixtures/demo_monorepo/backend/billing/serializers.py @@ -0,0 +1,9 @@ +from rest_framework import serializers + +from billing.models import Invoice + + +class InvoiceSerializer(serializers.ModelSerializer): + class Meta: + model = Invoice + fields = ["id", "customer_id", "total", "status"] diff --git a/fixtures/demo_monorepo/backend/billing/services.py b/fixtures/demo_monorepo/backend/billing/services.py new file mode 100644 index 0000000..6cdffeb --- /dev/null +++ b/fixtures/demo_monorepo/backend/billing/services.py @@ -0,0 +1,7 @@ +from billing.models import Invoice + + +def recalculate_total(invoice: Invoice) -> Invoice: + invoice.total = invoice.total + invoice.save(update_fields=["total"]) + return invoice diff --git a/fixtures/demo_monorepo/backend/billing/signals.py b/fixtures/demo_monorepo/backend/billing/signals.py new file mode 100644 index 0000000..371aa81 --- /dev/null +++ b/fixtures/demo_monorepo/backend/billing/signals.py @@ -0,0 +1,10 @@ +from django.db.models.signals import post_save +from django.dispatch import receiver + +from billing.models import Invoice + + +@receiver(post_save, sender=Invoice) +def update_ledger(sender, instance, **kwargs): + # Formats Invoice.total into a ledger row — no test covers this. + _ = f"{instance.total:.2f}" diff --git a/fixtures/demo_monorepo/backend/billing/tasks.py b/fixtures/demo_monorepo/backend/billing/tasks.py new file mode 100644 index 0000000..ccbfbae --- /dev/null +++ b/fixtures/demo_monorepo/backend/billing/tasks.py @@ -0,0 +1,9 @@ +from celery import shared_task + +from billing.models import Invoice + + +@shared_task +def send_invoice_email(invoice_id): + invoice = Invoice.objects.get(pk=invoice_id) + return invoice.total diff --git a/fixtures/demo_monorepo/backend/billing/tests.py b/fixtures/demo_monorepo/backend/billing/tests.py new file mode 100644 index 0000000..f72ec71 --- /dev/null +++ b/fixtures/demo_monorepo/backend/billing/tests.py @@ -0,0 +1,16 @@ +from rest_framework.test import APITestCase + +from billing.models import Invoice +from billing.serializers import InvoiceSerializer +from billing.views import InvoiceViewSet + + +class InvoiceSerializerTests(APITestCase): + def test_serializer_includes_total(self): + data = InvoiceSerializer(Invoice(customer_id=1, total="10.00", status="draft")).data + assert "total" in data + + +class InvoiceViewTests(APITestCase): + def test_viewset_uses_invoice_serializer(self): + assert InvoiceViewSet.serializer_class is InvoiceSerializer diff --git a/fixtures/demo_monorepo/backend/billing/urls.py b/fixtures/demo_monorepo/backend/billing/urls.py new file mode 100644 index 0000000..42c0cb5 --- /dev/null +++ b/fixtures/demo_monorepo/backend/billing/urls.py @@ -0,0 +1,16 @@ +from django.urls import include, path +from rest_framework.routers import DefaultRouter + +from billing.views import InvoiceViewSet + +router = DefaultRouter() +router.register("invoices", InvoiceViewSet, basename="invoice") + +urlpatterns = [ + path("", include(router.urls)), + path( + "invoices//", + InvoiceViewSet.as_view({"get": "retrieve", "put": "update"}), + name="invoice-detail", + ), +] diff --git a/fixtures/demo_monorepo/backend/billing/views.py b/fixtures/demo_monorepo/backend/billing/views.py new file mode 100644 index 0000000..f1c49b2 --- /dev/null +++ b/fixtures/demo_monorepo/backend/billing/views.py @@ -0,0 +1,17 @@ +from rest_framework import viewsets +from rest_framework.permissions import IsAuthenticated + +from billing.models import Invoice +from billing.serializers import InvoiceSerializer +from billing.tasks import send_invoice_email + + +class InvoiceViewSet(viewsets.ModelViewSet): + serializer_class = InvoiceSerializer + permission_classes = [IsAuthenticated] + queryset = Invoice.objects.all() + + def perform_create(self, serializer): + invoice = serializer.save() + send_invoice_email.delay(invoice.id) + return invoice diff --git a/fixtures/demo_monorepo/backend/config/urls.py b/fixtures/demo_monorepo/backend/config/urls.py new file mode 100644 index 0000000..8b56684 --- /dev/null +++ b/fixtures/demo_monorepo/backend/config/urls.py @@ -0,0 +1,8 @@ +from django.contrib import admin +from django.urls import include, path + +urlpatterns = [ + path("admin/", admin.site.urls), + path("api/", include("billing.urls")), + path("api/", include("accounts.urls")), +] diff --git a/fixtures/demo_monorepo/frontend/src/App.tsx b/fixtures/demo_monorepo/frontend/src/App.tsx new file mode 100644 index 0000000..0771b52 --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/App.tsx @@ -0,0 +1,11 @@ +import { InvoicePage } from "./features/billing/InvoicePage"; +import { MePage } from "./features/auth/MePage"; + +export function App() { + return ( + + } /> + } /> + + ); +} diff --git a/fixtures/demo_monorepo/frontend/src/features/auth/MePage.tsx b/fixtures/demo_monorepo/frontend/src/features/auth/MePage.tsx new file mode 100644 index 0000000..c73e9a2 --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/features/auth/MePage.tsx @@ -0,0 +1,13 @@ +import { useQuery } from "@tanstack/react-query"; + +export function useMe() { + return useQuery({ + queryKey: ["me"], + queryFn: () => fetch("/api/me").then((r) => r.json()), + }); +} + +export function MePage() { + const { data } = useMe(); + return
{data?.email}
; +} diff --git a/fixtures/demo_monorepo/frontend/src/features/billing/InvoiceForm.tsx b/fixtures/demo_monorepo/frontend/src/features/billing/InvoiceForm.tsx new file mode 100644 index 0000000..78dae27 --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/features/billing/InvoiceForm.tsx @@ -0,0 +1,14 @@ +import { invoiceSchema } from "./invoiceSchema"; + +export function InvoiceForm({ invoice }) { + const parsed = invoiceSchema.parse({ + customer_id: invoice?.customer_id, + total: invoice?.total, + status: invoice?.status, + }); + return ( +
+ +
+ ); +} diff --git a/fixtures/demo_monorepo/frontend/src/features/billing/InvoicePage.tsx b/fixtures/demo_monorepo/frontend/src/features/billing/InvoicePage.tsx new file mode 100644 index 0000000..b73f66f --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/features/billing/InvoicePage.tsx @@ -0,0 +1,12 @@ +import { InvoiceForm } from "./InvoiceForm"; +import { useInvoice } from "./useInvoice"; + +export function InvoicePage() { + const { data } = useInvoice("1"); + return ( +
+

Invoice {data?.id}

+ +
+ ); +} diff --git a/fixtures/demo_monorepo/frontend/src/features/billing/api.ts b/fixtures/demo_monorepo/frontend/src/features/billing/api.ts new file mode 100644 index 0000000..63be4b2 --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/features/billing/api.ts @@ -0,0 +1,12 @@ +export async function fetchInvoice(id: string) { + const res = await fetch(`/api/invoices/${id}`); + return res.json(); +} + +export async function updateInvoice(id: string, body: unknown) { + const res = await fetch(`/api/invoices/${id}`, { + method: "PUT", + body: JSON.stringify(body), + }); + return res.json(); +} diff --git a/fixtures/demo_monorepo/frontend/src/features/billing/invoiceSchema.ts b/fixtures/demo_monorepo/frontend/src/features/billing/invoiceSchema.ts new file mode 100644 index 0000000..c3ca8e4 --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/features/billing/invoiceSchema.ts @@ -0,0 +1,7 @@ +import { z } from "zod"; + +export const invoiceSchema = z.object({ + customer_id: z.number(), + total: z.string(), + status: z.string(), +}); diff --git a/fixtures/demo_monorepo/frontend/src/features/billing/useInvoice.ts b/fixtures/demo_monorepo/frontend/src/features/billing/useInvoice.ts new file mode 100644 index 0000000..bbb496e --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/features/billing/useInvoice.ts @@ -0,0 +1,9 @@ +import { useQuery } from "@tanstack/react-query"; +import { fetchInvoice } from "./api"; + +export function useInvoice(id: string) { + return useQuery({ + queryKey: ["invoice", id], + queryFn: () => fetchInvoice(id), + }); +} diff --git a/fixtures/demo_monorepo/frontend/src/generated/invoices.ts b/fixtures/demo_monorepo/frontend/src/generated/invoices.ts new file mode 100644 index 0000000..7bebdd3 --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/generated/invoices.ts @@ -0,0 +1,2 @@ +/** Generated from OpenAPI — high-confidence stitch when used. */ +export const getInvoice = (id: string) => fetch(`/api/invoices/${id}`); diff --git a/fixtures/demo_monorepo/frontend/src/shared/api.ts b/fixtures/demo_monorepo/frontend/src/shared/api.ts new file mode 100644 index 0000000..74aeb3c --- /dev/null +++ b/fixtures/demo_monorepo/frontend/src/shared/api.ts @@ -0,0 +1,4 @@ +export async function apiGet(path: string) { + const res = await fetch(path); + return res.json(); +} diff --git a/fixtures/demo_monorepo/loadpath.yml b/fixtures/demo_monorepo/loadpath.yml new file mode 100644 index 0000000..12ad543 --- /dev/null +++ b/fixtures/demo_monorepo/loadpath.yml @@ -0,0 +1,31 @@ +# Loadpath architecture manifest — demo billing/identity split. +contexts: + billing: + django_apps: [billing] + react: [src/features/billing, frontend/src/features/billing] + public_api: + - "GET /api/invoices" + - "POST /api/invoices" + - "GET /api/invoices/{id}" + - "PUT /api/invoices/{id}" + owners: [billing-team] + identity: + django_apps: [accounts] + react: [src/features/auth, frontend/src/features/auth] + public_api: + - "POST /api/login" + - "GET /api/me" + owners: [identity-team] +layers: + django: [route, view, service, model] + react: [route, page, feature, shared] +rules: + - views_cannot_import_other_context_models + - react_feature_may_only_call_own_or_shared_api + - serializers_are_the_only_published_contract + - no_queryset_in_serializer + - celery_tasks_must_be_idempotent_on_model_pk +django_root: backend +react_root: frontend/src +openapi_paths: + - openapi.yaml diff --git a/fixtures/demo_monorepo/openapi.yaml b/fixtures/demo_monorepo/openapi.yaml new file mode 100644 index 0000000..4749932 --- /dev/null +++ b/fixtures/demo_monorepo/openapi.yaml @@ -0,0 +1,39 @@ +openapi: 3.0.3 +info: + title: Demo API + version: "1.0.0" +paths: + /api/invoices: + get: + operationId: listInvoices + responses: + "200": + description: ok + post: + operationId: createInvoice + responses: + "201": + description: created + /api/invoices/{id}: + get: + operationId: getInvoice + responses: + "200": + description: ok + put: + operationId: updateInvoice + responses: + "200": + description: ok + /api/me: + get: + operationId: getMe + responses: + "200": + description: ok + /api/login: + post: + operationId: login + responses: + "200": + description: ok diff --git a/loadpath.yml.example b/loadpath.yml.example new file mode 100644 index 0000000..33c8e8b --- /dev/null +++ b/loadpath.yml.example @@ -0,0 +1,29 @@ +# Loadpath architecture manifest +contexts: + billing: + django_apps: [billing] + react: [frontend/src/features/billing] + public_api: + - "GET /api/invoices" + - "POST /api/invoices" + - "GET /api/invoices/{id}" + owners: [billing-team] + identity: + django_apps: [accounts] + react: [frontend/src/features/auth] + public_api: + - "POST /api/login" + - "GET /api/me" + owners: [identity-team] +layers: + django: [route, view, service, model] + react: [route, page, feature, shared] +rules: + - views_cannot_import_other_context_models + - react_feature_may_only_call_own_or_shared_api + - serializers_are_the_only_published_contract + - no_queryset_in_serializer + - celery_tasks_must_be_idempotent_on_model_pk +django_root: backend +react_root: frontend/src +openapi_paths: [] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..4de8b0c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,49 @@ +[build-system] +requires = ["setuptools>=68", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "loadpath" +version = "0.1.0" +description = "Architecture-typed impact graphs for Django + React pull requests." +readme = "README.md" +requires-python = ">=3.12" +authors = [{ name = "Loadpath" }] +dependencies = [ + "fastapi>=0.115.0", + "uvicorn[standard]>=0.32.0", + "pydantic>=2.9.0", + "pydantic-settings>=2.6.0", + "pyyaml>=6.0.2", + "httpx>=0.27.0", + "jinja2>=3.1.4", + "typer>=0.15.0", + "rich>=13.9.0", + "python-multipart>=0.0.12", +] + +[project.optional-dependencies] +dev = [ + "pytest>=8.3.0", + "pytest-asyncio>=0.24.0", + "respx>=0.21.0", +] + +[project.scripts] +loadpath = "loadpath.cli:app" + +[tool.setuptools.packages.find] +where = ["src"] + +[tool.setuptools.package-data] +loadpath = ["report/*.html", "static/**/*"] + +[tool.pytest.ini_options] +testpaths = ["tests"] +pythonpath = ["src"] +addopts = "-q --tb=short" +filterwarnings = ["ignore::DeprecationWarning"] + +[tool.ruff] +line-length = 100 +target-version = "py312" diff --git a/src/loadpath/__init__.py b/src/loadpath/__init__.py new file mode 100644 index 0000000..8238ae1 --- /dev/null +++ b/src/loadpath/__init__.py @@ -0,0 +1,3 @@ +"""Loadpath: architecture-typed impact graphs for Django + React PRs.""" + +__version__ = "0.1.0" diff --git a/src/loadpath/ai/__init__.py b/src/loadpath/ai/__init__.py new file mode 100644 index 0000000..1809198 --- /dev/null +++ b/src/loadpath/ai/__init__.py @@ -0,0 +1,3 @@ +from loadpath.ai.providers import client_for, residual_prompt + +__all__ = ["client_for", "residual_prompt"] diff --git a/src/loadpath/ai/providers.py b/src/loadpath/ai/providers.py new file mode 100644 index 0000000..f4a1103 --- /dev/null +++ b/src/loadpath/ai/providers.py @@ -0,0 +1,124 @@ +from __future__ import annotations + +from typing import Protocol + +import httpx + +RESIDUAL_SYSTEM = """You are Loadpath's residual-uncertainty analyst. +You do NOT comment on every hunk. You only inspect dynamic/inferred coupling +the deterministic graph could not close: getattr, raw SQL, get_serializer_class, +AppConfig.ready() signal registration, string model refs, inferred URL stitches. +Return a short markdown note: what might still be coupled, how sure you are, and +what a reviewer should verify. No style nits. No generic praise. +""" + + +class CompletionClient(Protocol): + name: str + + def complete(self, prompt: str, system: str = RESIDUAL_SYSTEM) -> str: ... + + +class OpenAICompatible: + name = "openai" + + def __init__( + self, + api_key: str, + model: str, + base_url: str = "https://api.openai.com/v1", + client: httpx.Client | None = None, + ) -> None: + self.api_key = api_key + self.model = model + self.base_url = base_url.rstrip("/") + self.client = client or httpx.Client(timeout=60.0) + + def complete(self, prompt: str, system: str = RESIDUAL_SYSTEM) -> str: + r = self.client.post( + f"{self.base_url}/chat/completions", + headers={"Authorization": f"Bearer {self.api_key}"}, + json={ + "model": self.model, + "temperature": 0.1, + "messages": [ + {"role": "system", "content": system}, + {"role": "user", "content": prompt}, + ], + }, + ) + r.raise_for_status() + data = r.json() + return data["choices"][0]["message"]["content"] + + +class AnthropicClient: + name = "anthropic" + + def __init__( + self, + api_key: str, + model: str = "claude-sonnet-4-20250514", + client: httpx.Client | None = None, + ) -> None: + self.api_key = api_key + self.model = model + self.client = client or httpx.Client(timeout=60.0) + + def complete(self, prompt: str, system: str = RESIDUAL_SYSTEM) -> str: + r = self.client.post( + "https://api.anthropic.com/v1/messages", + headers={ + "x-api-key": self.api_key, + "anthropic-version": "2023-06-01", + "content-type": "application/json", + }, + json={ + "model": self.model, + "max_tokens": 800, + "system": system, + "messages": [{"role": "user", "content": prompt}], + }, + ) + r.raise_for_status() + data = r.json() + parts = data.get("content") or [] + return "".join(p.get("text", "") for p in parts if p.get("type") == "text") + + +PROVIDERS = { + "openai": ("https://api.openai.com/v1", "gpt-4.1-mini"), + "grok": ("https://api.x.ai/v1", "grok-3"), + "xai": ("https://api.x.ai/v1", "grok-3"), + "deepseek": ("https://api.deepseek.com/v1", "deepseek-chat"), + "cursor": ("https://api.openai.com/v1", "gpt-4.1-mini"), + "ollama": ("http://127.0.0.1:11434/v1", "llama3.1"), +} + + +def client_for(provider: str, api_key: str, model: str = "", base_url: str = "") -> CompletionClient: + name = provider.lower().strip() + if name in {"none", "", "off"}: + raise ValueError("No AI provider configured") + if name == "anthropic": + return AnthropicClient(api_key, model=model or "claude-sonnet-4-20250514") + url, default_model = PROVIDERS.get(name, (base_url or "https://api.openai.com/v1", "gpt-4.1-mini")) + return OpenAICompatible(api_key, model=model or default_model, base_url=base_url or url) + + +def residual_prompt(review: dict) -> str: + residuals = review.get("residuals") or [] + findings = [f for f in review.get("findings") or [] if not f.get("waived")] + path = [] + for n in review.get("nodes") or []: + path.append(f"- {n.get('type')} {n.get('qualified_name')} ({n.get('file_path')})") + return ( + f"Change: {review.get('title')}\n" + f"Confidence: {review.get('confidence', {}).get('level')}\n" + f"Kinds: {review.get('change_kinds')}\n\n" + f"Residuals:\n" + "\n".join(f"- {r}" for r in residuals) + "\n\n" + f"Architecture findings:\n" + + "\n".join(f"- {f.get('rule')}: {f.get('message')}" for f in findings) + + "\n\nImpact nodes:\n" + + "\n".join(path[:80]) + ) diff --git a/src/loadpath/architecture/__init__.py b/src/loadpath/architecture/__init__.py new file mode 100644 index 0000000..77121f8 --- /dev/null +++ b/src/loadpath/architecture/__init__.py @@ -0,0 +1,3 @@ +from loadpath.architecture.rules import Finding, evaluate + +__all__ = ["Finding", "evaluate"] diff --git a/src/loadpath/architecture/rules.py b/src/loadpath/architecture/rules.py new file mode 100644 index 0000000..cd4291d --- /dev/null +++ b/src/loadpath/architecture/rules.py @@ -0,0 +1,281 @@ +from __future__ import annotations + +from dataclasses import dataclass, field + +from loadpath.config import LoadpathConfig +from loadpath.extractors.react import normalize_url_template +from loadpath.graph.store import GraphStore +from loadpath.stitch.openapi import django_route_to_template, parse_public_api +from loadpath.types import Edge, EdgeType, Node, NodeType, RuleSeverity, node_id + +RULE_DOCS = { + "views_cannot_import_other_context_models": "Views must not import models from another bounded context.", + "react_feature_may_only_call_own_or_shared_api": "A React feature may only call its own public API or shared clients.", + "serializers_are_the_only_published_contract": "Serializers (and OpenAPI) are the only published contract; React must not drift.", + "no_queryset_in_serializer": "Serializers must not run querysets.", + "celery_tasks_must_be_idempotent_on_model_pk": "Celery tasks must take a model pk/id, not a full object payload.", +} + + +@dataclass +class Finding: + rule: str + severity: RuleSeverity + message: str + node_id: str | None = None + file_path: str | None = None + waived: bool = False + extra: dict = field(default_factory=dict) + + def to_dict(self) -> dict: + return { + "rule": self.rule, + "severity": self.severity.value, + "message": self.message, + "node_id": self.node_id, + "file_path": self.file_path, + "waived": self.waived, + "extra": self.extra, + } + + +def _waived(config: LoadpathConfig, rule: str, node: str | None) -> bool: + for w in config.waivers: + if w.rule != rule: + continue + if w.node is None or w.node == node: + return True + return False + + +def evaluate(store: GraphStore, config: LoadpathConfig, changed_ids: set[str] | None = None) -> list[Finding]: + findings: list[Finding] = [] + enabled = set(config.rules) + + if "views_cannot_import_other_context_models" in enabled: + findings.extend(_views_foreign_models(store, config)) + if "react_feature_may_only_call_own_or_shared_api" in enabled: + findings.extend(_react_own_api(store, config)) + if "serializers_are_the_only_published_contract" in enabled: + findings.extend(_contract_drift(store, config)) + if "no_queryset_in_serializer" in enabled: + findings.extend(_queryset_in_serializer(store)) + if "celery_tasks_must_be_idempotent_on_model_pk" in enabled: + findings.extend(_task_idempotency(store, changed_ids)) + + for f in findings: + f.waived = _waived(config, f.rule, f.node_id) + if f.waived: + continue + if f.node_id and f.extra.get("other_context"): + store.upsert_edge( + Edge( + src=f.node_id, + dst=node_id(NodeType.BOUNDED_CONTEXT, f.extra["other_context"]), + type=EdgeType.CROSSES_CONTEXT, + extra={"rule": f.rule, "message": f.message}, + ) + ) + store.conn.commit() + return findings + + +def _views_foreign_models(store: GraphStore, config: LoadpathConfig) -> list[Finding]: + out: list[Finding] = [] + views = {n["id"]: n for n in store.nodes([NodeType.VIEW, NodeType.SERVICE])} + models = {n["id"]: n for n in store.nodes([NodeType.MODEL])} + for edge in store.edges(): + if edge["type"] != EdgeType.QUERIES_MODEL.value: + continue + view = views.get(edge["src"]) + model = models.get(edge["dst"]) or store.get_node(edge["dst"]) + if not view or not model: + continue + vctx = view.get("context") + mctx = model.get("context") + if not mctx: + qn = model.get("qualified_name") or "" + app = qn.split(".")[0] if "." in qn else None + mctx = config.context_for_django_app(app) if app else None + if vctx and mctx and vctx != mctx: + store.upsert_node( + Node( + id=node_id(NodeType.BOUNDED_CONTEXT, mctx), + type=NodeType.BOUNDED_CONTEXT, + name=mctx, + qualified_name=mctx, + ) + ) + out.append( + Finding( + rule="views_cannot_import_other_context_models", + severity=RuleSeverity.BLOCKER, + message=( + f"{view['name']} ({vctx}) talks to {model.get('qualified_name')} " + f"({mctx}), skipping that context's service layer" + ), + node_id=view["id"], + file_path=view.get("file_path"), + extra={"other_context": mctx, "model": model.get("qualified_name")}, + ) + ) + return out + + +def _react_own_api(store: GraphStore, config: LoadpathConfig) -> list[Finding]: + out: list[Finding] = [] + clients = {n["id"]: n for n in store.nodes([NodeType.API_CLIENT])} + features = {n["id"]: n for n in store.nodes([NodeType.FEATURE_MODULE, NodeType.HOOK, NodeType.PAGE, NodeType.COMPONENT])} + allowed_by_context: dict[str, set[str]] = {} + for name, ctx in config.contexts.items(): + allowed_by_context[name] = set() + for spec in ctx.public_api: + _, path = parse_public_api(spec) + allowed_by_context[name].add(path) + allowed_by_context[name].add(normalize_url_template(path)) + + for edge in store.edges(): + if edge["type"] not in {EdgeType.CALLS.value, EdgeType.CONSUMED_BY_CLIENT.value}: + continue + src = features.get(edge["src"]) + dst = clients.get(edge["dst"]) + if not src or not dst: + continue + ctx = src.get("context") + if not ctx or config.is_shared_react(src.get("file_path") or ""): + continue + tmpl = normalize_url_template(dst.get("name") or "") + allowed = allowed_by_context.get(ctx) or set() + if not allowed: + continue + if any(_path_belongs(tmpl, a) for a in allowed): + continue + # calling another context's public API? + other = None + for oname, paths in allowed_by_context.items(): + if oname != ctx and any(_path_belongs(tmpl, a) for a in paths): + other = oname + break + if other: + out.append( + Finding( + rule="react_feature_may_only_call_own_or_shared_api", + severity=RuleSeverity.BLOCKER, + message=( + f"React feature '{ctx}' called {tmpl} (owned by {other}) " + f"from {src.get('file_path')}" + ), + node_id=src["id"], + file_path=src.get("file_path"), + extra={"other_context": other, "url": tmpl}, + ) + ) + return out + + +def _path_belongs(url: str, allowed: str) -> bool: + u = normalize_url_template(url) + a = django_route_to_template(allowed) + if u == a: + return True + u_base = u.rstrip("/").rsplit("/{id}", 1)[0] + a_base = a.rstrip("/").rsplit("/{id}", 1)[0] + return u_base == a_base or u.startswith(a_base + "/") + + +def _contract_drift(store: GraphStore, config: LoadpathConfig) -> list[Finding]: + out: list[Finding] = [] + # If a serializer field has no matching zod field on a MATCHES_SCHEMA partner, warn + schemas = {n["id"]: n for n in store.nodes([NodeType.FORM_SCHEMA])} + fields = {n["id"]: n for n in store.nodes([NodeType.SERIALIZER_FIELD])} + serializers = {n["id"]: n for n in store.nodes([NodeType.SERIALIZER])} + matched_serializers: dict[str, list[dict]] = {} + for edge in store.edges(): + if edge["type"] != EdgeType.MATCHES_SCHEMA.value: + continue + ser = serializers.get(edge["src"]) + schema = schemas.get(edge["dst"]) + if ser and schema: + matched_serializers.setdefault(ser["id"], []).append(schema) + for ser_id, schema_list in matched_serializers.items(): + ser = serializers[ser_id] + ser_field_names = { + f["name"] + for f in fields.values() + if f["qualified_name"].startswith(ser["qualified_name"] + ".") + } + for schema in schema_list: + zod = set((schema.get("extra") or {}).get("fields") or []) + extra_in_react = zod - ser_field_names + missing_in_react = ser_field_names - zod + if extra_in_react: + out.append( + Finding( + rule="serializers_are_the_only_published_contract", + severity=RuleSeverity.BLOCKER, + message=( + f"Serializer field removed or missing; React form {schema['name']} " + f"still posts {sorted(extra_in_react)}" + ), + node_id=schema["id"], + file_path=schema.get("file_path"), + extra={"fields": sorted(extra_in_react), "serializer": ser["name"]}, + ) + ) + if missing_in_react and extra_in_react: + # already covered; extra missing is a warning unless changed + pass + return out + + +def _queryset_in_serializer(store: GraphStore) -> list[Finding]: + out = [] + for ser in store.nodes([NodeType.SERIALIZER]): + if (ser.get("extra") or {}).get("queryset_in_serializer"): + out.append( + Finding( + rule="no_queryset_in_serializer", + severity=RuleSeverity.BLOCKER, + message=f"Serializer {ser['name']} appears to run a queryset", + node_id=ser["id"], + file_path=ser.get("file_path"), + ) + ) + return out + + +def _task_idempotency(store: GraphStore, changed_ids: set[str] | None) -> list[Finding]: + out = [] + for task in store.nodes([NodeType.TASK]): + extra = task.get("extra") or {} + if extra.get("referenced") and extra.get("looks_idempotent_on_pk") is None: + continue + if extra.get("looks_idempotent_on_pk") is False or ( + extra.get("looks_idempotent_on_pk") is None and extra.get("args") + ): + if extra.get("looks_idempotent_on_pk"): + continue + args = extra.get("args") or [] + if not args: + continue + if extra.get("looks_idempotent_on_pk"): + continue + if changed_ids and task["id"] not in changed_ids: + # still report if task is in radius — caller filters + pass + if extra.get("looks_idempotent_on_pk") is True: + continue + out.append( + Finding( + rule="celery_tasks_must_be_idempotent_on_model_pk", + severity=RuleSeverity.WARNING, + message=( + f"Celery task {task['name']} args {args} do not look like a model pk; " + "tasks must be idempotent on model pk" + ), + node_id=task["id"], + file_path=task.get("file_path"), + extra={"args": args}, + ) + ) + return out diff --git a/src/loadpath/cli.py b/src/loadpath/cli.py new file mode 100644 index 0000000..6ca51d8 --- /dev/null +++ b/src/loadpath/cli.py @@ -0,0 +1,79 @@ +from __future__ import annotations + +from pathlib import Path +from typing import Optional + +import typer +from rich.console import Console +from rich.markdown import Markdown + +from loadpath import __version__ +from loadpath.index import default_db_path, index_repo +from loadpath.review.engine import run_review +from loadpath.review.render import render_html, render_markdown + +app = typer.Typer(add_completion=False, no_args_is_help=True, help="Loadpath — Django+React PR load-path reviewer.") +console = Console() + + +@app.callback() +def _version(version: bool = typer.Option(False, "--version", help="Show version")) -> None: + if version: + console.print(__version__) + raise typer.Exit() + + +@app.command() +def index( + repo: Path = typer.Argument(Path("."), exists=True, file_okay=False), + full: bool = typer.Option(False, "--full", help="Re-extract every file"), +) -> None: + """Index a Django + React monorepo into a SQLite graph.""" + store = index_repo(repo, incremental=not full) + counts = store.counts() + console.print(f"Indexed {counts['nodes']} nodes / {counts['edges']} edges → {default_db_path(repo)}") + store.close() + + +@app.command() +def review( + repo: Path = typer.Argument(Path("."), exists=True, file_okay=False), + base: str = typer.Option("origin/main", "--base", "-b"), + head: Optional[str] = typer.Option(None, "--head"), + format: str = typer.Option("markdown", "--format", "-f", help="markdown|json|html"), + out: Optional[Path] = typer.Option(None, "--out", "-o"), +) -> None: + """Review a git range as clustered load paths + confidence brief.""" + payload = run_review(repo, base=base, head=head) + if format == "json": + import json + + text = json.dumps(payload, indent=2, default=str) + elif format == "html": + text = render_html(payload) + else: + text = render_markdown(payload) + console.print(Markdown(text)) + if out is None: + return + if out: + out.write_text(text, encoding="utf-8") + console.print(f"Wrote {out}") + elif format != "markdown": + console.print(text) + + +@app.command() +def serve( + host: str = typer.Option("127.0.0.1", "--host"), + port: int = typer.Option(7345, "--port"), + open_browser: bool = typer.Option(True, "--open/--no-open"), +) -> None: + """Start the Loadpath app (API + UI).""" + from loadpath.server.app import serve as run_server + + run_server(host=host, port=port, open_browser=open_browser) + + +if __name__ == "__main__": + app() diff --git a/src/loadpath/config.py b/src/loadpath/config.py new file mode 100644 index 0000000..cff1896 --- /dev/null +++ b/src/loadpath/config.py @@ -0,0 +1,139 @@ +from __future__ import annotations + +from dataclasses import dataclass, field +from pathlib import Path +from typing import Any + +import yaml + +DEFAULT_RULES = [ + "views_cannot_import_other_context_models", + "react_feature_may_only_call_own_or_shared_api", + "serializers_are_the_only_published_contract", + "no_queryset_in_serializer", + "celery_tasks_must_be_idempotent_on_model_pk", +] + + +@dataclass +class ContextDef: + name: str + django_apps: list[str] = field(default_factory=list) + react: list[str] = field(default_factory=list) + public_api: list[str] = field(default_factory=list) + owners: list[str] = field(default_factory=list) + + +@dataclass +class Waiver: + rule: str + node: str | None = None + reason: str = "" + + +@dataclass +class LoadpathConfig: + repo_root: Path + contexts: dict[str, ContextDef] = field(default_factory=dict) + django_layers: list[str] = field(default_factory=lambda: ["route", "view", "service", "model"]) + react_layers: list[str] = field( + default_factory=lambda: ["route", "page", "feature", "shared"] + ) + rules: list[str] = field(default_factory=lambda: list(DEFAULT_RULES)) + waivers: list[Waiver] = field(default_factory=list) + django_root: str = "backend" + react_root: str = "frontend/src" + openapi_paths: list[str] = field(default_factory=list) + generated_client_globs: list[str] = field( + default_factory=lambda: [ + "**/generated/**/*.{ts,tsx,js}", + "**/*openapi*.{ts,js}", + "**/orval/**/*.{ts,js}", + ] + ) + extra: dict[str, Any] = field(default_factory=dict) + + def context_for_django_app(self, app: str) -> str | None: + for name, ctx in self.contexts.items(): + if app in ctx.django_apps: + return name + return None + + def context_for_react_path(self, rel_path: str) -> str | None: + normalized = rel_path.replace("\\", "/") + for name, ctx in self.contexts.items(): + for prefix in ctx.react: + if normalized.startswith(prefix.rstrip("/") + "/") or normalized.startswith( + prefix.rstrip("/") + ): + return name + # also match when react_root is prepended in stored paths + if prefix.rstrip("/") in normalized: + # feature folder name match + feature = prefix.rstrip("/").split("/")[-1] + if f"/features/{feature}/" in f"/{normalized}/": + return name + return None + + def is_shared_react(self, rel_path: str) -> bool: + n = rel_path.replace("\\", "/") + return "/shared/" in f"/{n}/" or n.startswith("shared/") + + def owners_for_context(self, context: str | None) -> list[str]: + if not context: + return [] + ctx = self.contexts.get(context) + return list(ctx.owners) if ctx else [] + + +def find_config(start: Path) -> Path | None: + cur = start.resolve() + for candidate in [cur, *cur.parents]: + path = candidate / "loadpath.yml" + if path.is_file(): + return path + return None + + +def load_config(repo_root: Path, config_path: Path | None = None) -> LoadpathConfig: + path = config_path or find_config(repo_root) or (repo_root / "loadpath.yml") + if not path.is_file(): + return LoadpathConfig(repo_root=repo_root.resolve()) + + raw = yaml.safe_load(path.read_text(encoding="utf-8")) or {} + contexts: dict[str, ContextDef] = {} + for name, data in (raw.get("contexts") or {}).items(): + data = data or {} + contexts[name] = ContextDef( + name=name, + django_apps=list(data.get("django_apps") or []), + react=list(data.get("react") or []), + public_api=list(data.get("public_api") or []), + owners=list(data.get("owners") or []), + ) + + layers = raw.get("layers") or {} + waivers = [ + Waiver(rule=w.get("rule", ""), node=w.get("node"), reason=w.get("reason", "")) + for w in (raw.get("waivers") or []) + ] + return LoadpathConfig( + repo_root=repo_root.resolve(), + contexts=contexts, + django_layers=list(layers.get("django") or ["route", "view", "service", "model"]), + react_layers=list(layers.get("react") or ["route", "page", "feature", "shared"]), + rules=list(raw.get("rules") or DEFAULT_RULES), + waivers=waivers, + django_root=raw.get("django_root", "backend"), + react_root=raw.get("react_root", "frontend/src"), + openapi_paths=list(raw.get("openapi_paths") or []), + generated_client_globs=list( + raw.get("generated_client_globs") + or [ + "**/generated/**/*.{ts,tsx,js}", + "**/*openapi*.{ts,js}", + "**/orval/**/*.{ts,js}", + ] + ), + extra=raw, + ) diff --git a/src/loadpath/extractors/__init__.py b/src/loadpath/extractors/__init__.py new file mode 100644 index 0000000..1eaca3e --- /dev/null +++ b/src/loadpath/extractors/__init__.py @@ -0,0 +1,6 @@ +from __future__ import annotations + +from loadpath.extractors.django import extract_django_file, extract_django_paths +from loadpath.extractors.react import extract_react_file + +__all__ = ["extract_django_file", "extract_django_paths", "extract_react_file"] diff --git a/src/loadpath/extractors/django.py b/src/loadpath/extractors/django.py new file mode 100644 index 0000000..b225993 --- /dev/null +++ b/src/loadpath/extractors/django.py @@ -0,0 +1,722 @@ +from __future__ import annotations + +import ast +import re +from pathlib import Path +from typing import Iterable + +from loadpath.config import LoadpathConfig +from loadpath.types import Edge, EdgeType, ExtractedGraph, Node, NodeType, node_id + +DJANGO_VIEW_BASES = { + "View", + "APIView", + "GenericAPIView", + "ViewSet", + "GenericViewSet", + "ModelViewSet", + "ReadOnlyModelViewSet", + "ListAPIView", + "RetrieveAPIView", + "CreateAPIView", + "UpdateAPIView", + "DestroyAPIView", + "ListCreateAPIView", + "RetrieveUpdateAPIView", + "RetrieveUpdateDestroyAPIView", + "TemplateView", + "FormView", + "RedirectView", +} + +SERIALIZER_BASES = {"Serializer", "ModelSerializer", "HyperlinkedModelSerializer", "ListSerializer"} +MODEL_BASES = {"Model"} +ADMIN_BASES = {"ModelAdmin", "StackedInline", "TabularInline"} +TASK_DECORATORS = {"shared_task", "task", "periodic_task"} +SIGNAL_NAMES = { + "pre_save", + "post_save", + "pre_delete", + "post_delete", + "m2m_changed", + "pre_init", + "post_init", + "class_prepared", +} +DESTRUCTIVE_MIGRATION_OPS = {"DeleteModel", "RemoveField", "AlterField", "RunPython", "RenameField"} +ON_DELETE_ATTRS = {"CASCADE", "PROTECT", "RESTRICT", "SET_NULL", "SET_DEFAULT", "DO_NOTHING", "SET"} + + +def _name(node: ast.AST | None) -> str | None: + if node is None: + return None + if isinstance(node, ast.Name): + return node.id + if isinstance(node, ast.Attribute): + parent = _name(node.value) + return f"{parent}.{node.attr}" if parent else node.attr + if isinstance(node, ast.Constant) and isinstance(node.value, str): + return node.value + return None + + +def _const_str(node: ast.AST | None) -> str | None: + if isinstance(node, ast.Constant) and isinstance(node.value, str): + return node.value + if isinstance(node, ast.JoinedStr): + parts: list[str] = [] + for v in node.values: + if isinstance(v, ast.Constant) and isinstance(v.value, str): + parts.append(v.value) + else: + parts.append("{}") + return "".join(parts) + return None + + +def _list_names(node: ast.AST | None) -> list[str]: + if isinstance(node, (ast.List, ast.Tuple)): + names = [] + for elt in node.elts: + n = _name(elt) + if n: + names.append(n.split(".")[-1]) + return names + n = _name(node) + return [n.split(".")[-1]] if n else [] + + +def _bases(node: ast.ClassDef) -> list[str]: + return [b for b in (_name(base) for base in node.bases) if b] + + +def _has_base(node: ast.ClassDef, names: set[str]) -> bool: + return any((b.split(".")[-1] in names) for b in _bases(node)) + + +def _decorator_names(node: ast.FunctionDef | ast.ClassDef | ast.AsyncFunctionDef) -> list[str]: + out = [] + for dec in node.decorator_list: + if isinstance(dec, ast.Call): + n = _name(dec.func) + else: + n = _name(dec) + if n: + out.append(n) + return out + + +def _kw(call: ast.Call, key: str) -> ast.AST | None: + for kw in call.keywords: + if kw.arg == key: + return kw.value + return None + + +def _app_from_path(rel: str) -> str | None: + parts = Path(rel).parts + # backend/billing/models.py → billing + if "migrations" in parts: + idx = parts.index("migrations") + if idx > 0: + return parts[idx - 1] + for i, part in enumerate(parts): + if part in {"models.py", "views.py", "serializers.py", "urls.py", "signals.py", "tasks.py", "admin.py", "apps.py"}: + return parts[i - 1] if i > 0 else None + if part == "management" and i > 0: + return parts[i - 1] + if len(parts) >= 2 and parts[-1].endswith(".py"): + return parts[-2] + return None + + +def _module_qual(rel: str) -> str: + p = Path(rel) + if p.suffix == ".py": + p = p.with_suffix("") + return ".".join(p.parts) + + +class DjangoExtractor(ast.NodeVisitor): + def __init__(self, rel_path: str, source: str, config: LoadpathConfig) -> None: + self.rel_path = rel_path.replace("\\", "/") + self.source = source + self.config = config + self.app = _app_from_path(self.rel_path) or "unknown" + self.context = config.context_for_django_app(self.app) + self.graph = ExtractedGraph() + self.imports: dict[str, str] = {} # local name → module.qual + self.from_imports: dict[str, str] = {} + self.class_stack: list[str] = [] + + def add_node(self, ntype: NodeType, name: str, qname: str, lineno: int, extra: dict | None = None) -> Node: + node = Node( + id=node_id(ntype, qname), + type=ntype, + name=name, + qualified_name=qname, + file_path=self.rel_path, + start_line=lineno, + context=self.context, + extra=extra or {}, + ) + self.graph.nodes.append(node) + return node + + def add_edge(self, src: str, dst: str, etype: EdgeType, confidence: float = 1.0, extra: dict | None = None) -> None: + self.graph.edges.append(Edge(src=src, dst=dst, type=etype, confidence=confidence, extra=extra or {})) + + def visit_Import(self, node: ast.Import) -> None: + for alias in node.names: + self.imports[alias.asname or alias.name.split(".")[-1]] = alias.name + self.generic_visit(node) + + def visit_ImportFrom(self, node: ast.ImportFrom) -> None: + mod = node.module or "" + for alias in node.names: + local = alias.asname or alias.name + self.from_imports[local] = f"{mod}.{alias.name}" if mod else alias.name + self.generic_visit(node) + + def _resolve(self, name: str) -> str: + if name in self.from_imports: + return self.from_imports[name] + if name in self.imports: + return self.imports[name] + root = name.split(".")[0] + if root in self.from_imports: + return self.from_imports[root] + name[len(root) :] + if root in self.imports: + return self.imports[root] + name[len(root) :] + return name + + def visit_ClassDef(self, node: ast.ClassDef) -> None: + self.class_stack.append(node.name) + if _has_base(node, MODEL_BASES): + self._model(node) + elif _has_base(node, SERIALIZER_BASES): + self._serializer(node) + elif _has_base(node, DJANGO_VIEW_BASES) or node.name.endswith(("View", "ViewSet")): + self._view(node) + 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"): + self._app_config(node) + elif "Service" in node.name or "UseCase" in node.name: + self._service_class(node) + self.generic_visit(node) + self.class_stack.pop() + + def visit_FunctionDef(self, node: ast.FunctionDef) -> None: + self._maybe_task(node) + self._maybe_receiver(node) + self._maybe_command(node) + self._maybe_test(node) + self._maybe_service_fn(node) + self.generic_visit(node) + + visit_AsyncFunctionDef = visit_FunctionDef # type: ignore[assignment] + + def visit_Call(self, node: ast.Call) -> None: + fname = _name(node.func) or "" + short = fname.split(".")[-1] + if short in {"path", "re_path", "url"}: + self._url_path(node) + elif short == "register" and "router" in fname.lower(): + self._router_register(node) + elif short == "include": + pass + elif short == "get_model": + self._get_model(node) + elif short in {"delay", "apply_async"}: + self._enqueue(node, fname) + elif short == "connect" and any(s in fname for s in SIGNAL_NAMES | {"signal"}): + self._signal_connect(node, fname) + elif short == "reverse": + self._reverse(node) + self.generic_visit(node) + + def visit_Assign(self, node: ast.Assign) -> None: + # urlpatterns = [...] + for target in node.targets: + if isinstance(target, ast.Name) and target.id == "urlpatterns" and isinstance(node.value, (ast.List, ast.Tuple)): + for elt in node.value.elts: + if isinstance(elt, ast.Call): + self.visit_Call(elt) + self.generic_visit(node) + + def _model(self, node: ast.ClassDef) -> None: + qname = f"{self.app}.{node.name}" + model = self.add_node(NodeType.MODEL, node.name, qname, node.lineno, {"app": self.app}) + app_node = self.add_node(NodeType.APP, self.app, self.app, 1) + self.add_edge(model.id, app_node.id, EdgeType.BELONGS_TO) + for stmt in node.body: + if isinstance(stmt, ast.Assign) and stmt.targets and isinstance(stmt.targets[0], ast.Name): + fname = stmt.targets[0].id + if fname.startswith("_"): + continue + field_q = f"{qname}.{fname}" + extra: dict = {"app": self.app} + rel_to = None + on_delete = None + if isinstance(stmt.value, ast.Call): + call_name = _name(stmt.value.func) or "" + extra["field_type"] = call_name.split(".")[-1] + to_arg = stmt.value.args[0] if stmt.value.args else _kw(stmt.value, "to") + rel_to = _const_str(to_arg) or _name(to_arg) + od = _kw(stmt.value, "on_delete") + on_delete = _name(od) + extra["on_delete"] = on_delete.split(".")[-1] if on_delete else None + extra["related_name"] = _const_str(_kw(stmt.value, "related_name")) + field_node = self.add_node(NodeType.FIELD, fname, field_q, stmt.lineno, extra) + self.add_edge(model.id, field_node.id, EdgeType.HAS_FIELD) + if rel_to: + target = rel_to if "." in rel_to else f"{self.app}.{rel_to.split('.')[-1]}" + rel_id = node_id(NodeType.MODEL, target) + rel_node = Node( + id=rel_id, + type=NodeType.MODEL, + name=target.split(".")[-1], + qualified_name=target, + extra={"placeholder": True}, + ) + self.graph.nodes.append(rel_node) + self.add_edge( + field_node.id, + rel_id, + EdgeType.RELATES_TO, + extra={"on_delete": extra.get("on_delete")}, + ) + if extra.get("on_delete") == "CASCADE": + self.add_edge(model.id, rel_id, EdgeType.RELATES_TO, extra={"cascade": True}) + + def _serializer(self, node: ast.ClassDef) -> None: + qname = f"{self.app}.{node.name}" + ser = self.add_node(NodeType.SERIALIZER, node.name, qname, node.lineno, {"app": self.app}) + meta_model = None + meta_fields: list[str] | None = None + meta_exclude: list[str] | None = None + declared: list[tuple[str, int]] = [] + queryset_in_serializer = False + 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): + key = m.targets[0].id + if key == "model": + meta_model = _name(m.value) + elif key == "fields": + if isinstance(m.value, ast.Constant) and m.value.value == "__all__": + meta_fields = ["__all__"] + else: + meta_fields = [ + elt.value + for elt in (m.value.elts if isinstance(m.value, (ast.List, ast.Tuple)) else []) + if isinstance(elt, ast.Constant) and isinstance(elt.value, str) + ] + elif key == "exclude": + meta_exclude = [ + elt.value + for elt in (m.value.elts if isinstance(m.value, (ast.List, ast.Tuple)) else []) + if isinstance(elt, ast.Constant) and isinstance(elt.value, str) + ] + if isinstance(stmt, ast.Assign) and stmt.targets and isinstance(stmt.targets[0], ast.Name): + fname = stmt.targets[0].id + if not fname.startswith("_") and fname[0].islower(): + declared.append((fname, stmt.lineno)) + if isinstance(stmt, ast.FunctionDef) and "queryset" in ast.dump(stmt): + queryset_in_serializer = True + body = self._slice(node) + if queryset_in_serializer or ".objects." in body or "objects.filter" in body: + ser.extra["queryset_in_serializer"] = True + fields = declared[:] + if meta_fields and meta_fields != ["__all__"]: + existing = {n for n, _ in fields} + for f in meta_fields: + if f not in existing: + fields.append((f, node.lineno)) + for fname, lineno in fields: + fq = f"{qname}.{fname}" + fn = self.add_node(NodeType.SERIALIZER_FIELD, fname, fq, lineno, {"app": self.app}) + self.add_edge(ser.id, fn.id, EdgeType.HAS_FIELD) + 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) + if meta_model: + model_q = meta_model if "." in meta_model else f"{self.app}.{meta_model.split('.')[-1]}" + self.add_edge(ser.id, node_id(NodeType.MODEL, model_q), EdgeType.SERIALIZES) + if meta_exclude: + ser.extra["exclude"] = meta_exclude + + def _view(self, node: ast.ClassDef) -> None: + qname = f"{self.app}.{node.name}" + extra: dict = {"app": self.app, "bases": _bases(node)} + serializer_class = None + permissions: list[str] = [] + queryset_model = None + dynamic_serializer = False + for stmt in node.body: + if isinstance(stmt, ast.Assign) and stmt.targets and isinstance(stmt.targets[0], ast.Name): + key = stmt.targets[0].id + if key == "serializer_class": + serializer_class = _name(stmt.value) + elif key == "permission_classes": + permissions = _list_names(stmt.value) + elif key == "throttle_classes": + extra["throttles"] = _list_names(stmt.value) + elif key == "queryset": + dumped = ast.dump(stmt.value) + m = re.search(r"id='([A-Z][A-Za-z0-9_]+)'", dumped) + if m: + queryset_model = m.group(1) + 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})" + ) + if isinstance(stmt, ast.FunctionDef) and stmt.name in { + "list", + "create", + "retrieve", + "update", + "partial_update", + "destroy", + }: + action_q = f"{qname}.{stmt.name}" + action = self.add_node( + NodeType.VIEWSET_ACTION, stmt.name, action_q, stmt.lineno, {"app": self.app} + ) + self.add_edge(node_id(NodeType.VIEW, qname), action.id, EdgeType.CALLS) + extra["permissions"] = permissions + view = self.add_node(NodeType.VIEW, node.name, qname, node.lineno, extra) + if serializer_class: + ser_q = ( + serializer_class + if "." in serializer_class and not serializer_class.startswith("serializers") + else f"{self.app}.{serializer_class.split('.')[-1]}" + ) + self.add_edge(view.id, node_id(NodeType.SERIALIZER, ser_q), EdgeType.USES_SERIALIZER) + for perm in permissions: + pid = node_id(NodeType.PERMISSION, perm) + self.graph.nodes.append( + Node(id=pid, type=NodeType.PERMISSION, name=perm, qualified_name=perm, extra={"from_view": qname}) + ) + self.add_edge(view.id, pid, EdgeType.HAS_PERMISSION) + if queryset_model: + self.add_edge( + view.id, + node_id(NodeType.MODEL, f"{self.app}.{queryset_model}"), + EdgeType.QUERIES_MODEL, + ) + if dynamic_serializer: + extra["dynamic"] = True + # foreign model imports used in this view file + self._note_cross_app_model_imports(view.id) + + def _note_cross_app_model_imports(self, view_id: str) -> None: + for local, target in self.from_imports.items(): + # accounts.models.UserProfile + parts = target.split(".") + if "models" in parts: + idx = parts.index("models") + app = parts[idx - 1] if idx > 0 else None + model = parts[idx + 1] if idx + 1 < len(parts) else local + if app and app != self.app and model[:1].isupper(): + self.add_edge( + view_id, + node_id(NodeType.MODEL, f"{app}.{model}"), + EdgeType.QUERIES_MODEL, + extra={"imported": True, "foreign_app": app}, + ) + + def _admin(self, node: ast.ClassDef) -> None: + qname = f"{self.app}.{node.name}" + self.add_node(NodeType.ADMIN, node.name, qname, node.lineno, {"app": self.app}) + + def _service_class(self, node: ast.ClassDef) -> None: + qname = f"{self.app}.{node.name}" + self.add_node(NodeType.SERVICE, node.name, qname, node.lineno, {"app": self.app}) + + def _maybe_service_fn(self, node: ast.FunctionDef) -> None: + if Path(self.rel_path).name in {"services.py", "use_cases.py", "usecases.py"}: + qname = f"{self.app}.{node.name}" + self.add_node(NodeType.SERVICE, node.name, qname, node.lineno, {"app": self.app}) + + def _app_config(self, node: ast.ClassDef) -> None: + for stmt in node.body: + if isinstance(stmt, ast.FunctionDef) and stmt.name == "ready": + text = self._slice(stmt) + if "import" in text or "connect" in text or "receiver" in text: + self.graph.residuals.append( + f"Signal/import registration in AppConfig.ready() {self.rel_path}:{stmt.lineno}" + ) + + def _maybe_task(self, node: ast.FunctionDef) -> None: + decs = _decorator_names(node) + if not any(d.split(".")[-1] in TASK_DECORATORS for d in decs): + if "tasks.py" not in self.rel_path: + return + if not node.name.endswith("task") and "task" not in node.name: + return + qname = f"{self.app}.{node.name}" + args = [a.arg for a in node.args.args] + extra = {"app": self.app, "args": args} + extra["looks_idempotent_on_pk"] = any( + a in {"pk", "id", "invoice_id", "object_id", "model_id"} or a.endswith("_id") or a.endswith("_pk") + for a in args + ) + self.add_node(NodeType.TASK, node.name, qname, node.lineno, extra) + + def _maybe_receiver(self, node: ast.FunctionDef) -> None: + for dec in node.decorator_list: + dname = _name(dec.func if isinstance(dec, ast.Call) else dec) or "" + if dname.split(".")[-1] != "receiver": + continue + sender = None + signal = None + if isinstance(dec, ast.Call): + if dec.args: + signal = _name(dec.args[0]) + sender_node = _kw(dec, "sender") + sender = _name(sender_node) + qname = f"{self.app}.{node.name}" + extra = {"app": self.app, "signal": signal, "sender": sender} + recv = self.add_node(NodeType.RECEIVER, node.name, qname, node.lineno, extra) + if signal: + sig_id = node_id(NodeType.SIGNAL, signal.split(".")[-1]) + self.graph.nodes.append( + Node( + id=sig_id, + type=NodeType.SIGNAL, + name=signal.split(".")[-1], + qualified_name=signal.split(".")[-1], + ) + ) + self.add_edge(sig_id, recv.id, EdgeType.RECEIVES) + if sender: + model_q = sender if "." in sender else f"{self.app}.{sender.split('.')[-1]}" + self.add_edge(recv.id, node_id(NodeType.MODEL, model_q), EdgeType.EMITS_SIGNAL) + + def _maybe_command(self, node: ast.FunctionDef) -> None: + if "management/commands" in self.rel_path and node.name == "handle": + cmd = Path(self.rel_path).stem + self.add_node(NodeType.MANAGEMENT_COMMAND, cmd, f"{self.app}.{cmd}", node.lineno, {"app": self.app}) + + def _maybe_test(self, node: ast.FunctionDef) -> None: + is_test_file = ( + Path(self.rel_path).name.startswith("test") + or "/tests/" in f"/{self.rel_path}/" + or Path(self.rel_path).name == "tests.py" + ) + if not is_test_file: + return + if not (node.name.startswith("test_") or node.name.startswith("test")): + return + qname = f"{self.app}.{node.name}" + extra = {"app": self.app, "nodeid": f"{self.rel_path}::{node.name}"} + test = self.add_node(NodeType.TEST, node.name, qname, node.lineno, extra) + # crude: referenced class names in the test become tested_by + for child in ast.walk(node): + if isinstance(child, ast.Name) and child.id[:1].isupper(): + for ntype in (NodeType.SERIALIZER, NodeType.VIEW, NodeType.MODEL, NodeType.SERVICE): + self.add_edge( + node_id(ntype, f"{self.app}.{child.id}"), + test.id, + EdgeType.TESTED_BY, + confidence=0.7, + ) + + def _url_path(self, node: ast.Call) -> None: + if not node.args: + return + route = _const_str(node.args[0]) + if route is None: + return + view_name = None + if len(node.args) > 1: + view_expr = node.args[1] + if isinstance(view_expr, ast.Call) and _name(view_expr.func) and "as_view" in (_name(view_expr.func) or ""): + view_name = (_name(view_expr.func) or "").replace(".as_view", "") + # mapping dict for viewsets + if view_expr.args and isinstance(view_expr.args[0], ast.Dict): + for k, v in zip(view_expr.args[0].keys, view_expr.args[0].values): + method = _const_str(k) + action = _name(v) + if method and action: + pass + else: + view_name = _name(view_expr) + name = _const_str(_kw(node, "name")) + include_mod = None + if len(node.args) > 1: + view_expr = node.args[1] + if isinstance(view_expr, ast.Call): + fn = _name(view_expr.func) or "" + if fn.split(".")[-1] == "include": + include_mod = _const_str(view_expr.args[0]) if view_expr.args else _name(view_expr.args[0] if view_expr.args else None) + view_name = None + extra = { + "app": self.app, + "route": route, + "url_name": name, + "view": view_name, + "include": include_mod, + } + route_node = self.add_node(NodeType.ROUTE, f"{route}", f"{self.app}:{route}", node.lineno, extra) + if name: + un = self.add_node(NodeType.URL_NAME, name, name, node.lineno, extra) + self.add_edge(route_node.id, un.id, EdgeType.BELONGS_TO) + if view_name: + vq = view_name if "." in view_name else f"{self.app}.{view_name.split('.')[-1]}" + self.add_edge(route_node.id, node_id(NodeType.VIEW, vq), EdgeType.PUBLISHES_ROUTE) + + def _router_register(self, node: ast.Call) -> None: + if len(node.args) < 2: + return + prefix = _const_str(node.args[0]) or "" + viewset = _name(node.args[1]) + basename = _const_str(_kw(node, "basename")) + route = prefix if prefix.startswith("/") else f"/{prefix}" + extra = {"app": self.app, "router": True, "basename": basename, "view": viewset} + route_node = self.add_node( + NodeType.ROUTE, f"{route}", f"{self.app}:{route}", node.lineno, extra + ) + if viewset: + vq = viewset if "." in viewset else f"{self.app}.{viewset.split('.')[-1]}" + self.add_edge(route_node.id, node_id(NodeType.VIEW, vq), EdgeType.PUBLISHES_ROUTE) + + def _get_model(self, node: ast.Call) -> None: + arg = node.args[0] if node.args else None + label = _const_str(arg) + if not label: + if len(node.args) >= 2: + app = _const_str(node.args[0]) + model = _const_str(node.args[1]) + label = f"{app}.{model}" if app and model else None + if label: + self.graph.residuals.append( + f'string model ref apps.get_model("{label}") in {self.rel_path}:{node.lineno}' + ) + self.add_node(NodeType.MODEL, label.split(".")[-1], label, node.lineno, {"string_ref": True}) + + def _enqueue(self, node: ast.Call, fname: str) -> None: + task_name = fname.rsplit(".", 1)[0] + short = task_name.split(".")[-1] + qname = f"{self.app}.{short}" + owner = self.class_stack[-1] if self.class_stack else Path(self.rel_path).stem + owner_type = NodeType.VIEW + if owner.endswith("Serializer"): + owner_type = NodeType.SERIALIZER + elif "Service" in owner or owner.endswith("UseCase"): + owner_type = NodeType.SERVICE + self.add_edge( + node_id(owner_type, f"{self.app}.{owner}"), + node_id(NodeType.TASK, qname), + EdgeType.ENQUEUES, + confidence=0.9, + extra={"call": fname, "line": node.lineno}, + ) + self.add_node(NodeType.TASK, short, qname, node.lineno, {"referenced": True, "app": self.app}) + + def _signal_connect(self, node: ast.Call, fname: str) -> None: + self.graph.residuals.append(f"signal.connect() at {self.rel_path}:{node.lineno} ({fname})") + + def _reverse(self, node: ast.Call) -> None: + name = _const_str(node.args[0]) if node.args else None + if name: + self.add_node(NodeType.URL_NAME, name, name, node.lineno, {"via": "reverse"}) + + def _slice(self, node: ast.AST) -> str: + try: + return ast.get_source_segment(self.source, node) or "" + except Exception: + return "" + + +def extract_migrations(rel_path: str, source: str, config: LoadpathConfig) -> ExtractedGraph: + graph = ExtractedGraph() + app = _app_from_path(rel_path) or "unknown" + context = config.context_for_django_app(app) + try: + tree = ast.parse(source) + except SyntaxError: + return graph + for node in ast.walk(tree): + if not isinstance(node, ast.Call): + continue + op = _name(node.func) or "" + short = op.split(".")[-1] + if short not in DESTRUCTIVE_MIGRATION_OPS and short not in { + "CreateModel", + "AddField", + "RenameModel", + "AlterUniqueTogether", + }: + continue + args_repr = [] + for a in node.args: + s = _const_str(a) or _name(a) + if s: + args_repr.append(s) + for kw in node.keywords: + if kw.arg in {"name", "model_name"}: + s = _const_str(kw.value) or _name(kw.value) + if s: + args_repr.append(s) + label = f"{short}({', '.join(args_repr[:3])})" + qname = f"{app}.{Path(rel_path).stem}.{label}" + extra = {"op": short, "app": app, "args": args_repr} + n = Node( + id=node_id(NodeType.MIGRATION_OP, qname), + type=NodeType.MIGRATION_OP, + name=label, + qualified_name=qname, + file_path=rel_path, + start_line=node.lineno, + context=context, + extra=extra, + ) + graph.nodes.append(n) + if short in {"DeleteModel", "RemoveField", "RunPython"}: + graph.edges.append( + Edge( + src=n.id, + dst=n.id, + type=EdgeType.DESTRUCTIVE_MIGRATION, + extra={"op": short}, + ) + ) + if short == "RemoveField" and args_repr: + model = args_repr[0] + field = args_repr[1] if len(args_repr) > 1 else "?" + graph.edges.append( + Edge( + src=n.id, + dst=node_id(NodeType.FIELD, f"{app}.{model}.{field}"), + type=EdgeType.DESTRUCTIVE_MIGRATION, + ) + ) + return graph + + +def extract_django_file(rel_path: str, source: str, config: LoadpathConfig) -> ExtractedGraph: + rel = rel_path.replace("\\", "/") + if "/migrations/" in f"/{rel}/" and rel.endswith(".py"): + return extract_migrations(rel, source, config) + try: + tree = ast.parse(source) + except SyntaxError as exc: + g = ExtractedGraph() + g.residuals.append(f"Python syntax error in {rel}: {exc}") + return g + extractor = DjangoExtractor(rel, source, config) + extractor.visit(tree) + return extractor.graph + + +def extract_django_paths(paths: Iterable[tuple[str, str]], config: LoadpathConfig) -> ExtractedGraph: + combined = ExtractedGraph() + for rel, source in paths: + combined.extend(extract_django_file(rel, source, config)) + return combined diff --git a/src/loadpath/extractors/react.py b/src/loadpath/extractors/react.py new file mode 100644 index 0000000..b8322a0 --- /dev/null +++ b/src/loadpath/extractors/react.py @@ -0,0 +1,316 @@ +from __future__ import annotations + +import re +from pathlib import Path + +from loadpath.config import LoadpathConfig +from loadpath.types import Edge, EdgeType, ExtractedGraph, Node, NodeType, node_id + +IMPORT_RE = re.compile( + r"""^\s*import\s+(?:type\s+)?\{([^}]+)\}\s+from\s+['"]([^'"]+)['"]""" + r"""|^\s*import\s+(?:type\s+)?(\w+)\s+from\s+['"]([^'"]+)['"]""" + r"""|^\s*import\s+['"]([^'"]+)['"]""", + re.M, +) +COMPONENT_RE = re.compile( + r"""(?:export\s+)?(?:default\s+)?(?:function|const|let)\s+([A-Z][A-Za-z0-9_]*)\s*(?:=|\()""" +) +HOOK_RE = re.compile( + r"""(?:export\s+)?(?:function|const|let)\s+(use[A-Z][A-Za-z0-9_]*)\s*(?:=|\()""" +) +USE_QUERY_RE = re.compile( + r"""use(?:Query|Mutation|InfiniteQuery|SuspenseQuery)\s*\(\s*\{(?P.*?)\}\s*\)""", + re.S, +) +QUERY_KEY_RE = re.compile(r"""queryKey\s*:\s*(\[[^\]]*\])""") +FETCH_RE = re.compile( + r"""(?:fetch|axios\.(?:get|post|put|patch|delete)|api\.(?:get|post|put|patch|delete))\s*\(\s*(['"`])(?P.*?)\1""", + re.S, +) +TEMPLATE_FETCH_RE = re.compile( + r"""(?:fetch|axios\.(?:get|post|put|patch|delete)|api\.(?:get|post|put|patch|delete))\s*\(\s*(`(?P[^`]+)`|'([^']+)'|"([^"]+)")""" +) +ROUTE_JSX_RE = re.compile( + r"""]*)>""", + re.S, +) +ROUTE_ATTR_PATH = re.compile(r"""path\s*=\s*{?\s*['"]([^'"]+)['"]""") +ROUTE_ATTR_ELEMENT = re.compile(r"""element\s*=\s*\{\s*<([A-Z][A-Za-z0-9_]*)""") +ZOD_RE = re.compile( + r"""(?:export\s+)?const\s+(\w+)\s*=\s*z\.object\(\s*\{(.*?)\}\s*\)""", + re.S, +) +ZOD_FIELD_RE = re.compile(r"""^\s*([A-Za-z_][A-Za-z0-9_]*)\s*:""", re.M) +CONTEXT_RE = re.compile( + r"""(?:createContext|React\.createContext)\s*\(""" +) +PROVIDER_RE = re.compile( + r"""(?:export\s+)?(?:function|const)\s+(\w*Provider)\b""" +) +TEST_IMPORT_RE = re.compile( + r"""from\s+['"]([^'"]+)['"]""" +) +RTL_RENDER_RE = re.compile(r"""\brender\s*\(\s*<([A-Z][A-Za-z0-9_]*)""") +ROUTER_OBJ_RE = re.compile( + r"""(?:createBrowserRouter|createHashRouter|createRoutesFromElements)\s*\(""", +) +PATH_OBJ_RE = re.compile( + r"""path\s*:\s*['"]([^'"]+)['"][^}]*?(?:element|Component)\s*:\s* str | None: + m = FEATURE_FOLDER_RE.search(rel.replace("\\", "/")) + return m.group(1) if m else None + + +def normalize_url_template(url: str) -> str: + url = url.strip() + url = re.sub(r"""\$\{[^}]+\}""", "{id}", url) + url = re.sub(r""":[A-Za-z_][A-Za-z0-9_]*""", "{id}", url) + url = re.sub(r"""<[^>]+>""", "{id}", url) + if not url.startswith("/"): + if url.startswith("http"): + # strip origin + url = re.sub(r"""https?://[^/]+""", "", url) + else: + url = "/" + url + url = re.sub(r"""/+""", "/", url) + return url.rstrip("/") or "/" + + +def extract_react_file(rel_path: str, source: str, config: LoadpathConfig) -> ExtractedGraph: + rel = rel_path.replace("\\", "/") + graph = ExtractedGraph() + feature = _feature_from_path(rel) + 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) + stem = Path(rel).stem + + def add(ntype: NodeType, name: str, qname: str, line: int = 1, extra: dict | None = None) -> Node: + n = Node( + id=node_id(ntype, qname), + type=ntype, + name=name, + qualified_name=qname, + file_path=rel, + start_line=line, + context=context, + extra=extra or {}, + ) + graph.nodes.append(n) + return n + + 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 feature: + feat = add(NodeType.FEATURE_MODULE, feature, f"features.{feature}", extra={"shared": is_shared}) + + imports: list[tuple[str, str]] = [] + import_feature: dict[str, str] = {} + for m in IMPORT_RE.finditer(source): + if m.group(1) and m.group(2): + names = [n.strip().split(" as ")[-1] for n in m.group(1).split(",") if n.strip()] + for name in names: + imports.append((name, m.group(2))) + feat = _feature_from_path(m.group(2)) + if feat: + import_feature[name] = feat + elif m.group(3) and m.group(4): + imports.append((m.group(3), m.group(4))) + feat = _feature_from_path(m.group(4)) + if feat: + import_feature[m.group(3)] = feat + + for local, source_mod in imports: + if feature and ("/shared/" in source_mod or source_mod.startswith("shared") or "/features/" in source_mod): + other = _feature_from_path(source_mod) + if other and other != feature: + edge( + node_id(NodeType.FEATURE_MODULE, f"features.{feature}"), + node_id(NodeType.FEATURE_MODULE, f"features.{other}"), + EdgeType.IMPORTS, + extra={"from": rel, "import": source_mod}, + ) + edge_src = node_id(NodeType.FEATURE_MODULE, f"features.{feature}") if feature else node_id( + NodeType.COMPONENT, f"{rel}:{stem}" + ) + graph.edges.append( + Edge( + src=edge_src, + dst=node_id(NodeType.COMPONENT, source_mod), + type=EdgeType.IMPORTS, + confidence=0.6, + extra={"local": local, "placeholder": True}, + ) + ) + + components: list[Node] = [] + 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") + ntype = NodeType.PAGE if is_page else NodeType.COMPONENT + n = add(ntype, name, f"{feature or 'app'}.{name}", line, {"feature": feature}) + components.append(n) + if feature: + edge(n.id, node_id(NodeType.FEATURE_MODULE, f"features.{feature}"), EdgeType.BELONGS_TO) + + hooks: list[Node] = [] + for m in HOOK_RE.finditer(source): + name = m.group(1) + line = source[: m.start()].count("\n") + 1 + n = add(NodeType.HOOK, name, f"{feature or 'app'}.{name}", line, {"feature": feature}) + hooks.append(n) + if feature: + edge(n.id, node_id(NodeType.FEATURE_MODULE, f"features.{feature}"), EdgeType.BELONGS_TO) + + for m in re.finditer(r"""\b(use[A-Z][A-Za-z0-9_]*)\s*\(""", source): + hook_name = m.group(1) + if hook_name in {"useQuery", "useMutation", "useEffect", "useState", "useMemo", "useCallback", "useRef"}: + continue + for owner in components: + edge( + owner.id, + node_id(NodeType.HOOK, f"{feature or 'app'}.{hook_name}"), + EdgeType.CALLS, + confidence=0.9, + ) + + for m in USE_QUERY_RE.finditer(source): + body = m.group("body") + line = source[: m.start()].count("\n") + 1 + km = QUERY_KEY_RE.search(body) + key_raw = km.group(1) if km else None + if key_raw: + key_name = re.sub(r"""\s+""", "", key_raw) + qn = add( + NodeType.QUERY_KEY, + key_name, + f"{feature or 'app'}.queryKey.{key_name}", + line, + {"raw": key_raw, "feature": feature}, + ) + for h in hooks or components: + edge(h.id, qn.id, EdgeType.USES_QUERY_KEY) + + for m in TEMPLATE_FETCH_RE.finditer(source): + url = m.group("turl") or m.group(3) or m.group(4) + if not url: + continue + if "/api/" not in url and not url.startswith("/"): + continue + line = source[: m.start()].count("\n") + 1 + norm = normalize_url_template(url) + client = add( + NodeType.API_CLIENT, + norm, + f"client:{norm}", + line, + {"raw": url, "inferred": True, "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) + + # also catch fetch(`/api/...`) missed by grouping + for m in re.finditer(r"""[`'"](/api/[^`'"]+)[`'"]""", source): + url = m.group(1) + line = source[: m.start()].count("\n") + 1 + norm = normalize_url_template(url) + if any(n.qualified_name == f"client:{norm}" for n in graph.nodes): + continue + add( + NodeType.API_CLIENT, + norm, + f"client:{norm}", + line, + {"raw": url, "inferred": True, "feature": feature, "file": rel}, + ) + + for m in ROUTE_JSX_RE.finditer(source): + attrs = m.group(1) + path_m = ROUTE_ATTR_PATH.search(attrs) + el_m = ROUTE_ATTR_ELEMENT.search(attrs) + if not path_m: + continue + rpath = path_m.group(1) + line = source[: m.start()].count("\n") + 1 + page_name = el_m.group(1) if el_m else rpath + rn = add(NodeType.REACT_ROUTE, rpath, f"react.route:{rpath}", line, {"element": page_name}) + if el_m: + feat = import_feature.get(page_name) or feature or "app" + page = add(NodeType.PAGE, page_name, f"{feat}.{page_name}", line, {"feature": feat, "from_route": True}) + edge(rn.id, page.id, EdgeType.PUBLISHES_ROUTE) + edge(rn.id, node_id(NodeType.COMPONENT, f"{feat}.{page_name}"), EdgeType.RENDERS) + + for m in PATH_OBJ_RE.finditer(source): + rpath, page_name = m.group(1), m.group(2) + line = source[: m.start()].count("\n") + 1 + rn = add(NodeType.REACT_ROUTE, rpath, f"react.route:{rpath}", line, {"element": page_name}) + edge(rn.id, node_id(NodeType.PAGE, f"{feature or 'app'}.{page_name}"), EdgeType.PUBLISHES_ROUTE) + + for m in ZOD_RE.finditer(source): + name, body = m.group(1), m.group(2) + line = source[: m.start()].count("\n") + 1 + fields = ZOD_FIELD_RE.findall(body) + schema = add( + NodeType.FORM_SCHEMA, + name, + f"{feature or 'app'}.{name}", + line, + {"fields": fields, "kind": "zod", "feature": feature}, + ) + for owner in components: + edge(owner.id, schema.id, EdgeType.CALLS, confidence=0.7) + + if CONTEXT_RE.search(source): + for m in PROVIDER_RE.finditer(source): + name = m.group(1) + line = source[: m.start()].count("\n") + 1 + add(NodeType.CONTEXT_PROVIDER, name, f"{feature or 'app'}.{name}", line) + + if is_test: + line = 1 + tn = add(NodeType.REACT_TEST, stem, f"test.{rel}", line, {"file": rel}) + for m in RTL_RENDER_RE.finditer(source): + name = m.group(1) + edge(node_id(NodeType.PAGE, f"{feature or 'app'}.{name}"), tn.id, EdgeType.TESTED_BY) + edge(node_id(NodeType.COMPONENT, f"{feature or 'app'}.{name}"), tn.id, EdgeType.TESTED_BY) + for m in TEST_IMPORT_RE.finditer(source): + spec = m.group(1) + if spec.startswith(".") or "features/" in spec: + base = Path(spec).stem + if base[0:1].isupper() or base.startswith("use"): + ntype = NodeType.HOOK if base.startswith("use") else NodeType.COMPONENT + edge(node_id(ntype, f"{feature or 'app'}.{base}"), tn.id, EdgeType.TESTED_BY, confidence=0.75) + + # composition: JSX usage of other components + defined = {n.name for n in components} + for other in re.findall(r"""<([A-Z][A-Za-z0-9_]*)\b""", source): + if other in {"Route", "Routes", "BrowserRouter", "QueryClientProvider"}: + continue + if other in defined: + continue + for owner in components: + edge( + owner.id, + node_id(NodeType.COMPONENT, f"{feature or 'app'}.{other}"), + EdgeType.RENDERS, + confidence=0.8, + ) + edge( + owner.id, + node_id(NodeType.PAGE, f"{feature or 'app'}.{other}"), + EdgeType.RENDERS, + confidence=0.5, + ) + + return graph diff --git a/src/loadpath/graph/__init__.py b/src/loadpath/graph/__init__.py new file mode 100644 index 0000000..24476dd --- /dev/null +++ b/src/loadpath/graph/__init__.py @@ -0,0 +1,3 @@ +from loadpath.graph.store import GraphStore + +__all__ = ["GraphStore"] diff --git a/src/loadpath/graph/store.py b/src/loadpath/graph/store.py new file mode 100644 index 0000000..e4a7cc6 --- /dev/null +++ b/src/loadpath/graph/store.py @@ -0,0 +1,297 @@ +from __future__ import annotations + +import json +import sqlite3 +from pathlib import Path +from typing import Any, Iterable, Iterator + +from loadpath.types import Edge, ExtractedGraph, Node, NodeType + +SCHEMA = """ +CREATE TABLE IF NOT EXISTS meta ( + key TEXT PRIMARY KEY, + value TEXT NOT NULL +); + +CREATE TABLE IF NOT EXISTS files ( + path TEXT PRIMARY KEY, + hash TEXT NOT NULL, + language TEXT +); + +CREATE TABLE IF NOT EXISTS nodes ( + id TEXT PRIMARY KEY, + type TEXT NOT NULL, + name TEXT NOT NULL, + qualified_name TEXT NOT NULL, + file_path TEXT, + start_line INTEGER, + end_line INTEGER, + context TEXT, + extra TEXT NOT NULL DEFAULT '{}' +); + +CREATE TABLE IF NOT EXISTS edges ( + id TEXT PRIMARY KEY, + src TEXT NOT NULL, + dst TEXT NOT NULL, + type TEXT NOT NULL, + weight TEXT NOT NULL, + confidence REAL NOT NULL, + extra TEXT NOT NULL DEFAULT '{}' +); + +CREATE INDEX IF NOT EXISTS idx_nodes_file ON nodes(file_path); +CREATE INDEX IF NOT EXISTS idx_nodes_type ON nodes(type); +CREATE INDEX IF NOT EXISTS idx_nodes_context ON nodes(context); +CREATE INDEX IF NOT EXISTS idx_edges_src ON edges(src); +CREATE INDEX IF NOT EXISTS idx_edges_dst ON edges(dst); +CREATE INDEX IF NOT EXISTS idx_edges_type ON edges(type); + +CREATE TABLE IF NOT EXISTS reviews ( + id TEXT PRIMARY KEY, + created_at TEXT NOT NULL, + repo_root TEXT NOT NULL, + base_ref TEXT, + head_ref TEXT, + payload TEXT NOT NULL +); +""" + + +class GraphStore: + def __init__(self, db_path: Path) -> None: + self.db_path = Path(db_path) + self.db_path.parent.mkdir(parents=True, exist_ok=True) + self.conn = sqlite3.connect(str(self.db_path)) + self.conn.row_factory = sqlite3.Row + self.conn.execute("PRAGMA foreign_keys = ON") + self.conn.executescript(SCHEMA) + self.conn.commit() + + def close(self) -> None: + self.conn.close() + + def __enter__(self) -> GraphStore: + return self + + def __exit__(self, *args: object) -> None: + self.close() + + def set_meta(self, key: str, value: str) -> None: + self.conn.execute( + "INSERT INTO meta(key, value) VALUES(?, ?) ON CONFLICT(key) DO UPDATE SET value=excluded.value", + (key, value), + ) + self.conn.commit() + + def get_meta(self, key: str) -> str | None: + row = self.conn.execute("SELECT value FROM meta WHERE key=?", (key,)).fetchone() + return row["value"] if row else None + + def file_hash(self, path: str) -> str | None: + row = self.conn.execute("SELECT hash FROM files WHERE path=?", (path,)).fetchone() + return row["hash"] if row else None + + def upsert_file(self, path: str, digest: str, language: str | None) -> None: + self.conn.execute( + "INSERT INTO files(path, hash, language) VALUES(?,?,?) " + "ON CONFLICT(path) DO UPDATE SET hash=excluded.hash, language=excluded.language", + (path, digest, language), + ) + + def delete_file_nodes(self, path: str) -> None: + ids = [ + r["id"] + for r in self.conn.execute("SELECT id FROM nodes WHERE file_path=?", (path,)).fetchall() + ] + if not ids: + self.conn.execute("DELETE FROM files WHERE path=?", (path,)) + return + placeholders = ",".join("?" * len(ids)) + self.conn.execute(f"DELETE FROM edges WHERE src IN ({placeholders}) OR dst IN ({placeholders})", ids + ids) + self.conn.execute("DELETE FROM nodes WHERE file_path=?", (path,)) + self.conn.execute("DELETE FROM files WHERE path=?", (path,)) + + def upsert_graph(self, graph: ExtractedGraph) -> None: + for node in graph.nodes: + self.upsert_node(node) + for edge in graph.edges: + self.upsert_edge(edge) + self.conn.commit() + + def upsert_node(self, node: Node) -> None: + self.conn.execute( + """ + INSERT INTO nodes(id, type, name, qualified_name, file_path, start_line, end_line, context, extra) + VALUES(?,?,?,?,?,?,?,?,?) + ON CONFLICT(id) DO UPDATE SET + type=excluded.type, + name=excluded.name, + qualified_name=excluded.qualified_name, + file_path=excluded.file_path, + start_line=excluded.start_line, + end_line=excluded.end_line, + context=excluded.context, + extra=excluded.extra + """, + ( + node.id, + node.type.value, + node.name, + node.qualified_name, + node.file_path, + node.start_line, + node.end_line, + node.context, + json.dumps(node.extra), + ), + ) + + def upsert_edge(self, edge: Edge) -> None: + row = edge.to_row() + self.conn.execute( + """ + INSERT INTO edges(id, src, dst, type, weight, confidence, extra) + VALUES(?,?,?,?,?,?,?) + ON CONFLICT(id) DO UPDATE SET + weight=excluded.weight, + confidence=excluded.confidence, + extra=excluded.extra + """, + ( + row["id"], + row["src"], + row["dst"], + row["type"], + row["weight"], + row["confidence"], + json.dumps(row["extra"]), + ), + ) + + def get_node(self, node_id: str) -> dict[str, Any] | None: + row = self.conn.execute("SELECT * FROM nodes WHERE id=?", (node_id,)).fetchone() + return self._node_from_row(row) if row else None + + def nodes(self, types: Iterable[NodeType] | None = None) -> list[dict[str, Any]]: + if types: + values = [t.value for t in types] + placeholders = ",".join("?" * len(values)) + rows = self.conn.execute( + f"SELECT * FROM nodes WHERE type IN ({placeholders})", values + ).fetchall() + else: + rows = self.conn.execute("SELECT * FROM nodes").fetchall() + return [self._node_from_row(r) for r in rows] + + def edges(self) -> list[dict[str, Any]]: + rows = self.conn.execute("SELECT * FROM edges").fetchall() + return [self._edge_from_row(r) for r in rows] + + def neighbors(self, node_id: str, direction: str = "both") -> list[dict[str, Any]]: + clauses = [] + args: list[str] = [] + if direction in ("out", "both"): + clauses.append("src=?") + args.append(node_id) + if direction in ("in", "both"): + clauses.append("dst=?") + args.append(node_id) + rows = self.conn.execute( + f"SELECT * FROM edges WHERE {' OR '.join(clauses)}", args + ).fetchall() + return [self._edge_from_row(r) for r in rows] + + def nodes_in_files(self, paths: Iterable[str]) -> list[dict[str, Any]]: + path_list = list(paths) + if not path_list: + return [] + placeholders = ",".join("?" * len(path_list)) + rows = self.conn.execute( + f"SELECT * FROM nodes WHERE file_path IN ({placeholders})", path_list + ).fetchall() + return [self._node_from_row(r) for r in rows] + + def subgraph(self, seed_ids: Iterable[str], hops: int = 6) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]: + frontier = set(seed_ids) + seen_nodes = set(frontier) + seen_edges: dict[str, dict[str, Any]] = {} + for _ in range(hops): + if not frontier: + break + nxt: set[str] = set() + for nid in frontier: + for edge in self.neighbors(nid, "both"): + seen_edges[edge["id"]] = edge + other = edge["dst"] if edge["src"] == nid else edge["src"] + if other not in seen_nodes: + seen_nodes.add(other) + nxt.add(other) + frontier = nxt + nodes = [self.get_node(i) for i in seen_nodes] + return [n for n in nodes if n], list(seen_edges.values()) + + def iter_nodes(self) -> Iterator[dict[str, Any]]: + for row in self.conn.execute("SELECT * FROM nodes"): + yield self._node_from_row(row) + + def save_review(self, review_id: str, created_at: str, repo_root: str, base_ref: str, head_ref: str, payload: dict[str, Any]) -> None: + self.conn.execute( + "INSERT INTO reviews(id, created_at, repo_root, base_ref, head_ref, payload) VALUES(?,?,?,?,?,?) " + "ON CONFLICT(id) DO UPDATE SET payload=excluded.payload", + (review_id, created_at, repo_root, base_ref, head_ref, json.dumps(payload)), + ) + self.conn.commit() + + def get_review(self, review_id: str) -> dict[str, Any] | None: + row = self.conn.execute("SELECT * FROM reviews WHERE id=?", (review_id,)).fetchone() + if not row: + return None + return { + "id": row["id"], + "created_at": row["created_at"], + "repo_root": row["repo_root"], + "base_ref": row["base_ref"], + "head_ref": row["head_ref"], + "payload": json.loads(row["payload"]), + } + + def list_reviews(self) -> list[dict[str, Any]]: + rows = self.conn.execute( + "SELECT id, created_at, repo_root, base_ref, head_ref FROM reviews ORDER BY created_at DESC" + ).fetchall() + return [dict(r) for r in rows] + + def counts(self) -> dict[str, int]: + n = self.conn.execute("SELECT COUNT(*) AS c FROM nodes").fetchone()["c"] + e = self.conn.execute("SELECT COUNT(*) AS c FROM edges").fetchone()["c"] + return {"nodes": n, "edges": e} + + @staticmethod + def _node_from_row(row: sqlite3.Row) -> dict[str, Any]: + extra = json.loads(row["extra"] or "{}") + return { + "id": row["id"], + "type": row["type"], + "name": row["name"], + "qualified_name": row["qualified_name"], + "file_path": row["file_path"], + "start_line": row["start_line"], + "end_line": row["end_line"], + "context": row["context"], + "extra": extra, + } + + @staticmethod + def _edge_from_row(row: sqlite3.Row) -> dict[str, Any]: + extra = json.loads(row["extra"] or "{}") + return { + "id": row["id"], + "src": row["src"], + "dst": row["dst"], + "type": row["type"], + "weight": row["weight"], + "confidence": row["confidence"], + "extra": extra, + } diff --git a/src/loadpath/index.py b/src/loadpath/index.py new file mode 100644 index 0000000..993a7f8 --- /dev/null +++ b/src/loadpath/index.py @@ -0,0 +1,148 @@ +from __future__ import annotations + +import hashlib +from pathlib import Path + +from loadpath.config import LoadpathConfig, load_config +from loadpath.extractors.django import extract_django_file +from loadpath.extractors.react import extract_react_file +from loadpath.graph.store import GraphStore +from loadpath.stitch.openapi import stitch +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"} + + +def default_db_path(repo_root: Path) -> Path: + return repo_root / ".loadpath" / "graph.sqlite3" + + +def iter_source_files(repo_root: Path, config: LoadpathConfig) -> list[Path]: + files: list[Path] = [] + skip_dirs = { + ".git", + "node_modules", + ".venv", + "venv", + "__pycache__", + ".loadpath", + "dist", + "build", + ".mypy_cache", + ".pytest_cache", + } + for path in repo_root.rglob("*"): + if not path.is_file() or path.suffix not in INDEX_EXTENSIONS: + continue + rel = path.relative_to(repo_root).as_posix() + if any(part in skip_dirs for part in path.parts): + continue + if any(m in rel for m in GENERATED_PATH_MARKERS if m.endswith("/") and m not in {"generated/"}): + # still index generated clients + pass + if path.name in {"package-lock.json"}: + continue + files.append(path) + return files + + +def file_hash(path: Path) -> str: + return hashlib.sha256(path.read_bytes()).hexdigest() + + +def language_for(path: Path) -> str: + if path.suffix == ".py": + return "python" + if path.suffix in {".ts", ".tsx"}: + return "typescript" + return "javascript" + + +def index_repo( + repo_root: Path, + db_path: Path | None = None, + config: LoadpathConfig | None = None, + incremental: bool = True, +) -> GraphStore: + repo_root = repo_root.resolve() + config = config or load_config(repo_root) + db_path = db_path or default_db_path(repo_root) + store = GraphStore(db_path) + store.set_meta("repo_root", str(repo_root)) + + residuals: list[str] = [] + for path in iter_source_files(repo_root, config): + rel = path.relative_to(repo_root).as_posix() + digest = file_hash(path) + if incremental and store.file_hash(rel) == digest: + continue + store.delete_file_nodes(rel) + source = path.read_text(encoding="utf-8", errors="replace") + if path.suffix == ".py": + graph = extract_django_file(rel, source, config) + else: + graph = extract_react_file(rel, source, config) + _assign_contexts(graph, config, rel) + store.upsert_file(rel, digest, language_for(path)) + store.upsert_graph(graph) + residuals.extend(graph.residuals) + + _ensure_context_nodes(store, config) + stitch_residuals = stitch(store, config, repo_root) + residuals.extend(stitch_residuals) + if residuals: + store.set_meta("residuals", "\n".join(residuals)) + store.conn.commit() + return store + + +def _assign_contexts(graph: ExtractedGraph, config: LoadpathConfig, rel: str) -> None: + for node in graph.nodes: + if node.context: + continue + if node.type.value.startswith("django.") or node.type.value.startswith("react."): + if rel.endswith(".py"): + app = (node.extra or {}).get("app") + if app: + node.context = config.context_for_django_app(app) + else: + node.context = config.context_for_react_path(rel) + + +def _ensure_context_nodes(store: GraphStore, config: LoadpathConfig) -> None: + for name, ctx in config.contexts.items(): + store.upsert_node( + Node( + id=node_id(NodeType.BOUNDED_CONTEXT, name), + type=NodeType.BOUNDED_CONTEXT, + name=name, + qualified_name=name, + extra={"django_apps": ctx.django_apps, "react": ctx.react, "public_api": ctx.public_api}, + ) + ) + for app in ctx.django_apps: + store.upsert_node( + Node( + id=node_id(NodeType.APP, app), + type=NodeType.APP, + name=app, + qualified_name=app, + context=name, + ) + ) + store.conn.execute( + """ + INSERT OR IGNORE INTO edges(id, src, dst, type, weight, confidence, extra) + VALUES(?,?,?,?,?,?,?) + """, + ( + f"{node_id(NodeType.APP, app)}|belongs_to|{node_id(NodeType.BOUNDED_CONTEXT, name)}", + node_id(NodeType.APP, app), + node_id(NodeType.BOUNDED_CONTEXT, name), + "belongs_to", + "cheap", + 1.0, + "{}", + ), + ) diff --git a/src/loadpath/providers/__init__.py b/src/loadpath/providers/__init__.py new file mode 100644 index 0000000..9f62a5e --- /dev/null +++ b/src/loadpath/providers/__init__.py @@ -0,0 +1,3 @@ +from loadpath.providers.scm import BitbucketProvider, GitHubProvider, PullRequest, provider_for + +__all__ = ["BitbucketProvider", "GitHubProvider", "PullRequest", "provider_for"] diff --git a/src/loadpath/providers/scm.py b/src/loadpath/providers/scm.py new file mode 100644 index 0000000..595b0d8 --- /dev/null +++ b/src/loadpath/providers/scm.py @@ -0,0 +1,206 @@ +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any, Protocol + +import httpx + + +@dataclass +class PullRequest: + provider: str + id: str + number: int + title: str + url: str + author: str + source_branch: str + target_branch: str + repo: str + state: str + updated_at: str + draft: bool = False + + def to_dict(self) -> dict[str, Any]: + return self.__dict__.copy() + + +class SCMProvider(Protocol): + name: str + + def list_pull_requests(self, repo: str, state: str = "open") -> list[PullRequest]: ... + + def get_pull_request(self, repo: str, number: int) -> PullRequest: ... + + def get_diff(self, repo: str, number: int) -> str: ... + + +class GitHubProvider: + name = "github" + + def __init__(self, token: str, client: httpx.Client | None = None) -> None: + self.token = token + self.client = client or httpx.Client(timeout=30.0) + self.base = "https://api.github.com" + + def _headers(self) -> dict[str, str]: + return { + "Authorization": f"Bearer {self.token}", + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28", + } + + def list_pull_requests(self, repo: str, state: str = "open") -> list[PullRequest]: + r = self.client.get( + f"{self.base}/repos/{repo}/pulls", + params={"state": state, "per_page": 50, "sort": "updated"}, + headers=self._headers(), + ) + r.raise_for_status() + out = [] + for item in r.json(): + out.append( + PullRequest( + provider="github", + id=str(item["id"]), + number=item["number"], + title=item["title"], + url=item["html_url"], + author=(item.get("user") or {}).get("login") or "", + source_branch=(item.get("head") or {}).get("ref") or "", + target_branch=(item.get("base") or {}).get("ref") or "", + repo=repo, + state=item.get("state") or "open", + updated_at=item.get("updated_at") or "", + draft=bool(item.get("draft")), + ) + ) + return out + + def get_pull_request(self, repo: str, number: int) -> PullRequest: + r = self.client.get(f"{self.base}/repos/{repo}/pulls/{number}", headers=self._headers()) + r.raise_for_status() + item = r.json() + return PullRequest( + provider="github", + id=str(item["id"]), + number=item["number"], + title=item["title"], + url=item["html_url"], + author=(item.get("user") or {}).get("login") or "", + source_branch=(item.get("head") or {}).get("ref") or "", + target_branch=(item.get("base") or {}).get("ref") or "", + repo=repo, + state=item.get("state") or "open", + updated_at=item.get("updated_at") or "", + draft=bool(item.get("draft")), + ) + + def get_diff(self, repo: str, number: int) -> str: + r = self.client.get( + f"{self.base}/repos/{repo}/pulls/{number}", + headers={**self._headers(), "Accept": "application/vnd.github.diff"}, + ) + r.raise_for_status() + return r.text + + +class BitbucketProvider: + name = "bitbucket" + + def __init__( + self, + token: str, + username: str = "", + client: httpx.Client | None = None, + ) -> None: + self.token = token + self.username = username + self.client = client or httpx.Client(timeout=30.0) + self.base = "https://api.bitbucket.org/2.0" + + def _auth(self) -> tuple[str, str] | None: + if self.username: + return (self.username, self.token) + return None + + def _headers(self) -> dict[str, str]: + if self.username: + return {} + return {"Authorization": f"Bearer {self.token}"} + + def list_pull_requests(self, repo: str, state: str = "open") -> list[PullRequest]: + bb_state = "OPEN" if state == "open" else state.upper() + r = self.client.get( + f"{self.base}/repositories/{repo}/pullrequests", + params={"state": bb_state, "pagelen": 50}, + headers=self._headers(), + auth=self._auth(), + ) + r.raise_for_status() + out = [] + for item in r.json().get("values") or []: + src = ((item.get("source") or {}).get("branch") or {}).get("name") or "" + dst = ((item.get("destination") or {}).get("branch") or {}).get("name") or "" + links = item.get("links") or {} + html = (links.get("html") or {}).get("href") or "" + author = ((item.get("author") or {}).get("display_name")) or "" + out.append( + PullRequest( + provider="bitbucket", + id=str(item.get("id")), + number=int(item.get("id")), + title=item.get("title") or "", + url=html, + author=author, + source_branch=src, + target_branch=dst, + repo=repo, + state=(item.get("state") or "").lower(), + updated_at=item.get("updated_on") or "", + draft=False, + ) + ) + return out + + def get_pull_request(self, repo: str, number: int) -> PullRequest: + r = self.client.get( + f"{self.base}/repositories/{repo}/pullrequests/{number}", + headers=self._headers(), + auth=self._auth(), + ) + r.raise_for_status() + item = r.json() + src = ((item.get("source") or {}).get("branch") or {}).get("name") or "" + dst = ((item.get("destination") or {}).get("branch") or {}).get("name") or "" + html = ((item.get("links") or {}).get("html") or {}).get("href") or "" + return PullRequest( + provider="bitbucket", + id=str(item.get("id")), + number=int(item.get("id")), + title=item.get("title") or "", + url=html, + author=((item.get("author") or {}).get("display_name")) or "", + source_branch=src, + target_branch=dst, + repo=repo, + state=(item.get("state") or "").lower(), + updated_at=item.get("updated_on") or "", + ) + + def get_diff(self, repo: str, number: int) -> str: + r = self.client.get( + f"{self.base}/repositories/{repo}/pullrequests/{number}/diff", + headers=self._headers(), + auth=self._auth(), + ) + r.raise_for_status() + return r.text + + +def provider_for(name: str, token: str, username: str = "", client: httpx.Client | None = None) -> SCMProvider: + if name == "github": + return GitHubProvider(token, client=client) + if name == "bitbucket": + return BitbucketProvider(token, username=username, client=client) + raise ValueError(f"Unknown SCM provider: {name}") diff --git a/src/loadpath/report/graph.html b/src/loadpath/report/graph.html new file mode 100644 index 0000000..27fc3a1 --- /dev/null +++ b/src/loadpath/report/graph.html @@ -0,0 +1,109 @@ + + + + + Loadpath — {{ review.title }} + + + + + +
+ + + diff --git a/src/loadpath/review/__init__.py b/src/loadpath/review/__init__.py new file mode 100644 index 0000000..7532f76 --- /dev/null +++ b/src/loadpath/review/__init__.py @@ -0,0 +1,4 @@ +from loadpath.review.engine import run_review +from loadpath.review.render import render_html, render_markdown + +__all__ = ["run_review", "render_html", "render_markdown"] diff --git a/src/loadpath/review/cluster.py b/src/loadpath/review/cluster.py new file mode 100644 index 0000000..99af277 --- /dev/null +++ b/src/loadpath/review/cluster.py @@ -0,0 +1,215 @@ +from __future__ import annotations + +from collections import defaultdict + +from loadpath.graph.store import GraphStore +from loadpath.review.diff import DiffSet +from loadpath.types import NodeType, SINK_TYPES + +CLUSTER_SEED_PRIORITY = [ + NodeType.SERIALIZER, + NodeType.SERIALIZER_FIELD, + NodeType.MODEL, + NodeType.FIELD, + NodeType.ROUTE, + NodeType.VIEW, + NodeType.TASK, + NodeType.RECEIVER, + NodeType.PAGE, + NodeType.FORM_SCHEMA, + NodeType.HOOK, + NodeType.COMPONENT, +] + +# Shared hubs that connect unrelated contexts if traversed. +BRIDGE_TYPES = { + NodeType.PERMISSION.value, + NodeType.THROTTLE.value, + NodeType.APP.value, + NodeType.BOUNDED_CONTEXT.value, + NodeType.URL_NAME.value, +} + +FORWARD_TYPES = { + "has_field", + "serializes", + "uses_serializer", + "publishes_route", + "consumed_by_client", + "matches_schema", + "enqueues", + "emits_signal", + "receives", + "calls", + "renders", + "queries_model", + "uses_query_key", + "serves", + "relates_to", + "tested_by", + "has_permission", + "belongs_to", +} + +BACKWARD_TYPES = { + "uses_serializer", + "publishes_route", + "consumed_by_client", + "has_field", + "serializes", + "calls", + "matches_schema", + "enqueues", + "tested_by", + "queries_model", + "emits_signal", + "receives", + "uses_query_key", + "belongs_to", +} + + +def impact_walk(store: GraphStore, seed_ids: set[str], hops: int = 8) -> tuple[list[dict], list[dict]]: + if not seed_ids: + return [], [] + by_id = {n["id"]: n for n in store.nodes()} + outgoing: dict[str, list[dict]] = defaultdict(list) + incoming: dict[str, list[dict]] = defaultdict(list) + for e in store.edges(): + outgoing[e["src"]].append(e) + incoming[e["dst"]].append(e) + + seen = set(seed_ids) + kept_edges: dict[str, dict] = {} + frontier = set(seed_ids) + + def include(nid: str, expand: bool) -> None: + if nid not in by_id: + return + if nid not in seen: + seen.add(nid) + if expand: + frontier.add(nid) + + for _ in range(hops): + nxt: set[str] = set() + working = set(frontier) + frontier.clear() + for nid in working: + node = by_id.get(nid) or {} + if node.get("type") in BRIDGE_TYPES: + continue + for e in outgoing.get(nid, []): + if e["type"] not in FORWARD_TYPES: + continue + other = e["dst"] + other_node = by_id.get(other) or {} + expand = other_node.get("type") not in BRIDGE_TYPES + include(other, expand) + kept_edges[e["id"]] = e + if expand and other not in working: + nxt.add(other) + for e in incoming.get(nid, []): + if e["type"] not in BACKWARD_TYPES: + continue + if e["type"] == "renders": + continue + if e["type"] == "belongs_to" and node.get("type") != NodeType.FEATURE_MODULE.value: + continue + other = e["src"] + other_node = by_id.get(other) or {} + if other_node.get("type") in BRIDGE_TYPES: + kept_edges[e["id"]] = e + include(other, False) + continue + include(other, True) + kept_edges[e["id"]] = e + if other not in working: + nxt.add(other) + frontier = {i for i in nxt if i not in working} + + nodes = [by_id[i] for i in seen if i in by_id] + return nodes, list(kept_edges.values()) + + +def cluster_diff( + store: GraphStore, + diff: DiffSet, + hops: int = 8, +) -> tuple[list[dict], list[dict], list[dict]]: + """Return (clusters, impact_nodes, impact_edges).""" + changed_paths = [f.path for f in diff.files if not f.skip] + seeds = store.nodes_in_files(changed_paths) + seed_ids = {n["id"] for n in seeds} + nodes, edges = impact_walk(store, seed_ids, hops=hops) if seed_ids else ([], []) + + parent: dict[str, str] = {} + + def find(x: str) -> str: + parent.setdefault(x, x) + while parent[x] != x: + parent[x] = parent[parent[x]] + x = parent[x] + return x + + def union(a: str, b: str) -> None: + ra, rb = find(a), find(b) + if ra != rb: + parent[rb] = ra + + for n in seeds: + find(n["id"]) + for e in edges: + if e["src"] in seed_ids: + union(e["src"], e["dst"]) + if e["dst"] in seed_ids: + union(e["dst"], e["src"]) + + seed_groups: dict[str, list[dict]] = defaultdict(list) + for n in seeds: + seed_groups[find(n["id"])].append(n) + + clusters = [] + for cid, members in seed_groups.items(): + files = sorted({m["file_path"] for m in members if m.get("file_path")}) + title = _cluster_title(members) + related = _related_nodes(members, nodes) + clusters.append( + { + "id": cid, + "title": title, + "files": files, + "seed_ids": [m["id"] for m in members], + "node_ids": [n["id"] for n in related], + "kinds": sorted({m["type"] for m in members}), + "contexts": sorted({m["context"] for m in members if m.get("context")}), + } + ) + clusters.sort(key=lambda c: (-len(c["files"]), c["title"])) + return clusters, nodes, edges + + +def _cluster_title(members: list[dict]) -> str: + by_type = {m["type"]: m for m in members} + for ntype in CLUSTER_SEED_PRIORITY: + if ntype.value in by_type: + m = by_type[ntype.value] + return f"{m['name']} ({ntype.value.split('.')[-1]})" + if members: + ctx = members[0].get("context") or "change" + return f"{ctx} cluster" + return "Unclustered" + + +def _related_nodes(members: list[dict], all_nodes: list[dict]) -> list[dict]: + ids = {m["id"] for m in members} + prefixes = {m["qualified_name"].split(".")[0] for m in members} + related = [] + for n in all_nodes: + if n["id"] in ids: + related.append(n) + continue + q = n.get("qualified_name") or "" + if q.split(".")[0] in prefixes and n.get("type") in {t.value for t in SINK_TYPES}: + related.append(n) + return related diff --git a/src/loadpath/review/confidence.py b/src/loadpath/review/confidence.py new file mode 100644 index 0000000..faa3005 --- /dev/null +++ b/src/loadpath/review/confidence.py @@ -0,0 +1,146 @@ +from __future__ import annotations + +from loadpath.architecture.rules import Finding, RuleSeverity +from loadpath.graph.store import GraphStore +from loadpath.types import ( + CONTRACT_TYPES, + ConfidenceLevel, + EdgeType, + NodeType, + SINK_TYPES, +) + +SINK_TYPE_VALUES = {t.value for t in SINK_TYPES} +CONTRACT_TYPE_VALUES = {t.value for t in CONTRACT_TYPES} +TEST_TYPES = {NodeType.TEST.value, NodeType.REACT_TEST.value} + + +def score_confidence( + store: GraphStore, + impact_nodes: list[dict], + impact_edges: list[dict], + findings: list[Finding], + residuals: list[str], +) -> dict: + sinks = [n for n in impact_nodes if n["type"] in SINK_TYPE_VALUES] + if not sinks: + # pages / forms / routes still count + sinks = [ + n + for n in impact_nodes + if n["type"] + in { + NodeType.PAGE.value, + NodeType.ROUTE.value, + NodeType.TASK.value, + NodeType.FORM_SCHEMA.value, + NodeType.OPENAPI_PATH.value, + } + ] + + tested_ids: set[str] = set() + impact_ids = {n["id"] for n in impact_nodes} + all_edges = list(store.edges()) + for e in list(impact_edges) + all_edges: + if e["type"] == EdgeType.TESTED_BY.value: + tested_ids.add(e["src"]) + + # A sink is covered if it, or a producer within two hops (view/serializer/hook/page), is tested. + inbound: dict[str, list[str]] = {} + for e in all_edges: + inbound.setdefault(e["dst"], []).append(e["src"]) + inbound.setdefault(e["src"], []).append(e["dst"]) + + def reachable_tested(nid: str, depth: int = 2) -> bool: + if nid in tested_ids: + return True + seen = {nid} + frontier = [nid] + for _ in range(depth): + nxt = [] + for cur in frontier: + for other in inbound.get(cur, []): + if other in seen: + continue + seen.add(other) + if other in tested_ids: + return True + nxt.append(other) + frontier = nxt + return False + + covered = [s for s in sinks if reachable_tested(s["id"])] + sink_ratio = (len(covered) / len(sinks)) if sinks else 1.0 + + blockers = [f for f in findings if f.severity == RuleSeverity.BLOCKER and not f.waived] + warnings = [f for f in findings if f.severity == RuleSeverity.WARNING and not f.waived] + + inferred = [e for e in impact_edges if e.get("confidence", 1) < 0.8] + unresolved_ratio = (len(inferred) / len(impact_edges)) if impact_edges else 0.0 + + contract_nodes = [n for n in impact_nodes if n["type"] in CONTRACT_TYPE_VALUES] + contract_ok = True + for f in blockers: + if f.rule == "serializers_are_the_only_published_contract": + contract_ok = False + + reasons: list[str] = [] + level = ConfidenceLevel.HIGH + + if blockers: + level = ConfidenceLevel.LOW + reasons.append(f"{len(blockers)} architecture blocker(s)") + elif sinks and sink_ratio < 0.2: + level = ConfidenceLevel.LOW + reasons.append(f"only {len(covered)}/{len(sinks)} sinks have tests that hit the changed radius") + elif sink_ratio < 0.85 or warnings or unresolved_ratio > 0.35: + level = ConfidenceLevel.MEDIUM + if sink_ratio < 0.85: + reasons.append(f"tests cover {len(covered)}/{len(sinks)} sinks") + if warnings: + reasons.append(f"{len(warnings)} architecture warning(s)") + if unresolved_ratio > 0.35: + reasons.append(f"{len(inferred)} inferred/unresolved edges on the path") + else: + reasons.append(f"tests cover {len(covered)}/{len(sinks) or 0} sinks") + reasons.append("no architecture blockers") + reasons.append("edges resolved") + + if not contract_ok and level == ConfidenceLevel.HIGH: + level = ConfidenceLevel.MEDIUM + reasons.append("contract drift between serializer and client/form") + + if residuals and level == ConfidenceLevel.HIGH: + level = ConfidenceLevel.MEDIUM + reasons.append(f"{len(residuals)} residual dynamic/inferred item(s)") + + while len(reasons) < 3: + if unresolved_ratio > 0: + reasons.append(f"{len(inferred)} inferred edges remain") + elif contract_nodes: + reasons.append(f"{len(contract_nodes)} contract node(s) in radius") + else: + reasons.append("impact radius is small") + if len(reasons) >= 3: + break + + return { + "level": level.value, + "score": round(sink_ratio - 0.15 * len(blockers) - 0.05 * unresolved_ratio, 3), + "reasons": reasons[:3], + "sinks": len(sinks), + "covered_sinks": len(covered), + "sink_ratio": round(sink_ratio, 3), + "blockers": len(blockers), + "warnings": len(warnings), + "inferred_edges": len(inferred), + "unresolved_ratio": round(unresolved_ratio, 3), + "contract_ok": contract_ok, + "tested_ids": sorted(tested_ids), + "sink_ids": [s["id"] for s in sinks], + "untested_sinks": [ + {"id": s["id"], "name": s["name"], "type": s["type"], "file_path": s.get("file_path")} + for s in sinks + if not reachable_tested(s["id"]) + ], + } diff --git a/src/loadpath/review/diff.py b/src/loadpath/review/diff.py new file mode 100644 index 0000000..8bcf4b2 --- /dev/null +++ b/src/loadpath/review/diff.py @@ -0,0 +1,101 @@ +from __future__ import annotations + +import subprocess +from dataclasses import dataclass, field +from pathlib import Path + +from loadpath.types import GENERATED_PATH_MARKERS + + +@dataclass +class FileDiff: + path: str + status: str # A, M, D + added: int = 0 + deleted: int = 0 + patch: str = "" + skip: bool = False + + +@dataclass +class DiffSet: + files: list[FileDiff] = field(default_factory=list) + base: str = "HEAD" + head: str = "WORKTREE" + + @property + def paths(self) -> list[str]: + return [f.path for f in self.files if not f.skip] + + +def is_skippable(path: str) -> bool: + n = path.replace("\\", "/") + if n.endswith(("lock", ".min.js", ".map", ".svg", ".png", ".jpg", ".woff", ".woff2")): + return True + return any(m in n for m in GENERATED_PATH_MARKERS if m != "generated/") + + +def git_diff(repo_root: Path, base: str, head: str | None = None) -> DiffSet: + repo_root = repo_root.resolve() + args = ["git", "-C", str(repo_root), "diff", "--numstat", "-M", base] + if head: + args.append(head) + numstat = subprocess.check_output(args, text=True, stderr=subprocess.DEVNULL) + name_args = ["git", "-C", str(repo_root), "diff", "--name-status", "-M", base] + if head: + name_args.append(head) + namestat = subprocess.check_output(name_args, text=True, stderr=subprocess.DEVNULL) + patch_args = ["git", "-C", str(repo_root), "diff", "-U3", base] + if head: + patch_args.append(head) + patch = subprocess.check_output(patch_args, text=True, stderr=subprocess.DEVNULL, errors="replace") + patches = _split_patches(patch) + + added_map: dict[str, tuple[int, int]] = {} + for line in numstat.splitlines(): + if not line.strip(): + continue + parts = line.split("\t") + if len(parts) < 3: + continue + a, d, path = parts[0], parts[1], parts[2] + added_map[path] = (int(a) if a.isdigit() else 0, int(d) if d.isdigit() else 0) + + files: list[FileDiff] = [] + for line in namestat.splitlines(): + if not line.strip(): + continue + parts = line.split("\t") + status = parts[0][0] + path = parts[-1] + a, d = added_map.get(path, (0, 0)) + files.append( + FileDiff( + path=path, + status=status, + added=a, + deleted=d, + patch=patches.get(path, ""), + skip=is_skippable(path), + ) + ) + return DiffSet(files=files, base=base, head=head or "WORKTREE") + + +def _split_patches(patch: str) -> dict[str, str]: + out: dict[str, str] = {} + current: list[str] = [] + path = None + for line in patch.splitlines(keepends=True): + if line.startswith("diff --git "): + if path and current: + out[path] = "".join(current) + current = [line] + # diff --git a/foo b/foo + bits = line.strip().split(" ") + path = bits[-1][2:] if bits[-1].startswith("b/") else bits[-1] + else: + current.append(line) + if path and current: + out[path] = "".join(current) + return out diff --git a/src/loadpath/review/engine.py b/src/loadpath/review/engine.py new file mode 100644 index 0000000..75f2cb2 --- /dev/null +++ b/src/loadpath/review/engine.py @@ -0,0 +1,355 @@ +from __future__ import annotations + +from datetime import datetime, timezone +from pathlib import Path +from uuid import uuid4 + +from loadpath.architecture.rules import evaluate +from loadpath.config import LoadpathConfig, load_config +from loadpath.graph.store import GraphStore +from loadpath.index import default_db_path, index_repo +from loadpath.review.cluster import cluster_diff +from loadpath.review.confidence import score_confidence +from loadpath.review.diff import DiffSet, git_diff +from loadpath.types import ( + ChangeKind, + GENERATED_PATH_MARKERS, + NodeType, +) + +READ_ORDER = [ + NodeType.SERIALIZER, + NodeType.SERIALIZER_FIELD, + NodeType.ROUTE, + NodeType.OPENAPI_PATH, + NodeType.FORM_SCHEMA, + NodeType.PERMISSION, + NodeType.VIEW, + NodeType.VIEWSET_ACTION, + NodeType.SERVICE, + NodeType.MODEL, + NodeType.FIELD, + NodeType.MIGRATION_OP, + NodeType.RECEIVER, + NodeType.SIGNAL, + NodeType.TASK, + NodeType.PAGE, + NodeType.HOOK, + NodeType.API_CLIENT, + NodeType.QUERY_KEY, + NodeType.COMPONENT, + NodeType.TEST, + NodeType.REACT_TEST, +] + + +def classify_change(impact_nodes: list[dict], findings: list, seeds: list[dict] | None = None) -> list[str]: + kinds: set[str] = set() + types = {n["type"] for n in impact_nodes} + seed_types = {n["type"] for n in (seeds or [])} or types + if ( + NodeType.SERIALIZER.value in seed_types + or NodeType.SERIALIZER_FIELD.value in seed_types + or NodeType.OPENAPI_PATH.value in seed_types + or NodeType.FORM_SCHEMA.value in seed_types + or NodeType.ROUTE.value in seed_types + ): + kinds.add(ChangeKind.PUBLIC_CONTRACT.value) + if ( + NodeType.MIGRATION_OP.value in seed_types + or NodeType.MODEL.value in seed_types + or NodeType.FIELD.value in seed_types + ): + kinds.add(ChangeKind.SCHEMA_MIGRATION.value) + if NodeType.PERMISSION.value in seed_types: + kinds.add(ChangeKind.AUTH.value) + if any(getattr(f, "rule", "") in { + "views_cannot_import_other_context_models", + "react_feature_may_only_call_own_or_shared_api", + } and not getattr(f, "waived", False) for f in findings): + kinds.add(ChangeKind.CROSS_CONTEXT.value) + if NodeType.SERVICE.value in types and ChangeKind.PUBLIC_CONTRACT.value not in kinds: + kinds.add(ChangeKind.INTERNAL_SERVICE.value) + ui_only = types <= { + NodeType.COMPONENT.value, + NodeType.PAGE.value, + NodeType.REACT_ROUTE.value, + NodeType.REACT_TEST.value, + NodeType.FEATURE_MODULE.value, + } + if ui_only and NodeType.API_CLIENT.value not in types: + kinds.add(ChangeKind.LEAF_UI.value) + if NodeType.COMPONENT.value in types or NodeType.PAGE.value in types: + if ChangeKind.PUBLIC_CONTRACT.value in kinds or NodeType.HOOK.value in types: + pass + elif ChangeKind.LEAF_UI.value not in kinds and len(kinds) == 0: + kinds.add(ChangeKind.LEAF_UI.value) + if not kinds: + kinds.add(ChangeKind.INTERNAL_SERVICE.value) + if len(kinds) > 1 and ChangeKind.LEAF_UI.value in kinds: + kinds.discard(ChangeKind.LEAF_UI.value) + return sorted(kinds) + + +def read_order_files(diff: DiffSet, impact_nodes: list[dict]) -> tuple[list[dict], list[str]]: + nodes_by_file: dict[str, list[dict]] = {} + for n in impact_nodes: + if n.get("file_path"): + nodes_by_file.setdefault(n["file_path"], []).append(n) + rank = {t: i for i, t in enumerate(READ_ORDER)} + + def file_rank(path: str) -> int: + nodes = nodes_by_file.get(path, []) + if not nodes: + return 50 + return min(rank.get(NodeType(n["type"]), 40) if n["type"] in {t.value for t in NodeType} else 40 for n in nodes) + + read: list[dict] = [] + skip: list[str] = [] + for f in diff.files: + if f.skip or any(m in f.path for m in GENERATED_PATH_MARKERS if m != "generated/"): + skip.append(f.path) + continue + nodes = nodes_by_file.get(f.path, []) + if not nodes and f.path.endswith((".md", ".txt", ".lock")): + skip.append(f.path) + continue + read.append( + { + "path": f.path, + "status": f.status, + "added": f.added, + "deleted": f.deleted, + "rank": file_rank(f.path), + "why": _why(nodes), + } + ) + read.sort(key=lambda r: (r["rank"], r["path"])) + return read, skip + + +def _why(nodes: list[dict]) -> str: + if not nodes: + return "changed file outside typed graph" + types = [n["type"].split(".")[-1] for n in nodes] + return ", ".join(sorted(set(types))[:4]) + + +def collect_residuals(store: GraphStore, impact_nodes: list[dict]) -> list[str]: + residuals = [] + tested = { + e["src"] + for e in store.edges() + if e["type"] == "tested_by" + } + for n in impact_nodes: + if n["type"] == NodeType.RECEIVER.value and n["id"] not in tested: + loc = f"{n.get('file_path')}:{n.get('start_line')}" if n.get("file_path") else n["qualified_name"] + residuals.append(f"{n['name']} ({loc}) — no test") + stored = store.get_meta("residuals") or "" + impact_files = {n.get("file_path") for n in impact_nodes if n.get("file_path")} + impact_names = {n.get("name") for n in impact_nodes} + for line in stored.splitlines(): + if any(f and f in line for f in impact_files) or any(n and str(n) in line for n in impact_names): + residuals.append(line) + for n in impact_nodes: + extra = n.get("extra") or {} + if extra.get("get_serializer_class"): + 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']}") + if extra.get("inferred"): + residuals.append(f"Inferred client {n.get('name')} in {n.get('file_path')}") + if extra.get("queryset_in_serializer"): + residuals.append(f"Queryset inside serializer {n['qualified_name']}") + seen = set() + out = [] + for r in residuals: + if r not in seen: + seen.add(r) + out.append(r) + return out + + +def suggested_reviewers(config: LoadpathConfig, impact_nodes: list[dict]) -> list[str]: + owners: list[str] = [] + for n in impact_nodes: + owners.extend(config.owners_for_context(n.get("context"))) + # unique preserve order + seen = set() + out = [] + for o in owners: + if o not in seen: + seen.add(o) + out.append(o) + return out + + +def is_low_risk(kinds: list[str], confidence: dict, findings: list) -> bool: + if any(not f.waived and f.severity.value == "blocker" for f in findings): + return False + if confidence["level"] == "low": + return False + if ChangeKind.CROSS_CONTEXT.value in kinds or ChangeKind.PUBLIC_CONTRACT.value in kinds: + return False + if ChangeKind.SCHEMA_MIGRATION.value in kinds or ChangeKind.AUTH.value in kinds: + return False + return confidence["level"] == "high" or ChangeKind.LEAF_UI.value in kinds + + +def run_review( + repo_root: Path, + base: str = "origin/main", + head: str | None = None, + db_path: Path | None = None, + config: LoadpathConfig | None = None, + diff: DiffSet | None = None, + reindex: bool = True, +) -> dict: + repo_root = repo_root.resolve() + config = config or load_config(repo_root) + if reindex: + store = index_repo(repo_root, db_path=db_path, config=config) + else: + store = GraphStore(db_path or default_db_path(repo_root)) + + diff = diff or git_diff(repo_root, base, head) + clusters, impact_nodes, impact_edges = cluster_diff(store, diff) + seed_ids = {n["id"] for n in store.nodes_in_files(diff.paths)} + findings = evaluate(store, config, changed_ids=seed_ids) + # keep findings that touch the impact subgraph or changed files + impact_ids = {n["id"] for n in impact_nodes} + impact_files = set(diff.paths) + scoped = [ + f + for f in findings + if (f.node_id and f.node_id in impact_ids) + or (f.file_path and f.file_path in impact_files) + or not impact_ids + ] + residuals = collect_residuals(store, impact_nodes) + confidence = score_confidence(store, impact_nodes, impact_edges, scoped, residuals) + kinds = classify_change(impact_nodes, scoped, seeds=store.nodes_in_files(diff.paths)) + read, skip = read_order_files(diff, impact_nodes) + reviewers = suggested_reviewers(config, impact_nodes) + low_risk = is_low_risk(kinds, confidence, scoped) + labels = ["loadpath:" + confidence["level"]] + if low_risk: + labels.append("loadpath:low-risk") + if ChangeKind.CROSS_CONTEXT.value in kinds: + labels.append("loadpath:cross-context") + if ChangeKind.PUBLIC_CONTRACT.value in kinds: + labels.append("loadpath:contract") + + title = _title(clusters, kinds) + sinks = _sink_summaries(impact_nodes, store) + tests_note = _tests_note(confidence, impact_nodes) + arch_note = _arch_note(scoped, kinds, impact_nodes) + + payload = { + "id": str(uuid4()), + "created_at": datetime.now(timezone.utc).isoformat(), + "repo_root": str(repo_root), + "base": diff.base, + "head": diff.head, + "title": title, + "change_kinds": kinds, + "confidence": confidence, + "labels": labels, + "low_risk": low_risk, + "clusters": clusters, + "read_order": read, + "skip": skip, + "findings": [f.to_dict() for f in scoped], + "residuals": residuals, + "suggested_reviewers": reviewers, + "sinks": sinks, + "tests_note": tests_note, + "architecture_note": arch_note, + "nodes": impact_nodes, + "edges": impact_edges, + "counts": store.counts(), + "headline": _headline(confidence, title, sinks, tests_note, arch_note, residuals, reviewers), + } + store.save_review(payload["id"], payload["created_at"], str(repo_root), diff.base, diff.head, payload) + store.close() + return payload + + +def _title(clusters: list[dict], kinds: list[str]) -> str: + if clusters: + return clusters[0]["title"] + if kinds: + return kinds[0].replace("_", " ") + return "change" + + +def _sink_summaries(nodes: list[dict], store: GraphStore) -> list[dict]: + interesting = { + NodeType.ROUTE.value, + NodeType.OPENAPI_PATH.value, + NodeType.TASK.value, + NodeType.PAGE.value, + NodeType.FORM_SCHEMA.value, + NodeType.PERMISSION.value, + NodeType.MIGRATION_OP.value, + NodeType.RECEIVER.value, + } + out = [] + for n in nodes: + if n["type"] in interesting: + out.append( + { + "id": n["id"], + "type": n["type"], + "name": n["name"], + "file_path": n.get("file_path"), + "context": n.get("context"), + } + ) + return out + + +def _tests_note(confidence: dict, nodes: list[dict]) -> str: + untested = confidence.get("untested_sinks") or [] + covered = confidence.get("covered_sinks", 0) + sinks = confidence.get("sinks", 0) + if not untested: + return f"pytest/RTL hits {covered}/{sinks} sinks in the radius" + names = ", ".join(u["name"] for u in untested[:4]) + return f"{covered}/{sinks} sinks tested; missing tests on {names}" + + +def _arch_note(findings: list, kinds: list[str], impact_nodes: list[dict] | None = None) -> str: + blockers = [f for f in findings if not f.waived and f.severity.value == "blocker"] + if blockers: + return blockers[0].message + if ChangeKind.CROSS_CONTEXT.value in kinds: + return "cross-context edges present" + ctxs = sorted({n.get("context") for n in (impact_nodes or []) if n.get("context")}) + if ctxs: + return "stays inside " + " / ".join(ctxs) + return "no cross-context rule hits" + + +def _headline(confidence, title, sinks, tests_note, arch_note, residuals, reviewers) -> str: + sink_bits = [] + routes = [s["name"] for s in sinks if s["type"] == NodeType.ROUTE.value] + tasks = [s["name"] for s in sinks if s["type"] == NodeType.TASK.value] + pages = [s["name"] for s in sinks if s["type"] in {NodeType.PAGE.value, NodeType.FORM_SCHEMA.value}] + if routes: + sink_bits.append(", ".join(routes[:4])) + if tasks: + sink_bits.append("Celery " + ", ".join(tasks[:3])) + if pages: + sink_bits.append("React " + ", ".join(pages[:4])) + residual = residuals[0] if residuals else "none" + owners = ", ".join(reviewers) if reviewers else "context owners" + return ( + f"Loadpath: {confidence['level'].upper()} — {title}\n" + f"Sinks: {'; '.join(sink_bits) or 'none typed'}\n" + f"Tests: {tests_note}\n" + f"Architecture: {arch_note}\n" + f"Residual: {residual}\n" + f"Suggested reviewers: {owners}" + ) diff --git a/src/loadpath/review/render.py b/src/loadpath/review/render.py new file mode 100644 index 0000000..e0b68be --- /dev/null +++ b/src/loadpath/review/render.py @@ -0,0 +1,57 @@ +from __future__ import annotations + +from pathlib import Path + +from jinja2 import Environment, FileSystemLoader, select_autoescape + +TEMPLATE_DIR = Path(__file__).resolve().parent.parent / "report" + + +def render_markdown(review: dict) -> str: + conf = review["confidence"] + lines = [ + f"## Loadpath: {conf['level'].upper()} — {review['title']}", + "", + review["headline"], + "", + "### What kind of change is this?", + ", ".join(k.replace("_", " ") for k in review["change_kinds"]) or "unknown", + "", + "### Read this, skip that", + ] + for item in review["read_order"]: + lines.append(f"- `{item['path']}` — {item['why']}") + if review["skip"]: + lines.append("") + lines.append("Skip: " + ", ".join(f"`{p}`" for p in review["skip"][:20])) + lines += ["", "### Clusters"] + for c in review["clusters"]: + files = ", ".join(f"`{f}`" for f in c["files"][:12]) + lines.append(f"- **{c['title']}** ({', '.join(c['contexts']) or 'unscoped'}): {files}") + lines += ["", "### Architecture"] + findings = review["findings"] + active = [f for f in findings if not f.get("waived")] + if not active: + lines.append("No rule hits on the impact path.") + for f in active: + flag = "BLOCKER" if f["severity"] == "blocker" else "warn" + lines.append(f"- [{flag}] `{f['rule']}`: {f['message']}") + lines += ["", "### Confidence"] + for r in conf["reasons"]: + lines.append(f"- {r}") + if review["residuals"]: + lines += ["", "### Residual uncertainty (AI-eligible)"] + for r in review["residuals"][:12]: + lines.append(f"- {r}") + if review["low_risk"]: + lines += ["", "_Fast-track: `loadpath:low-risk`. Human review can be a glance._"] + return "\n".join(lines) + "\n" + + +def render_html(review: dict) -> str: + env = Environment( + loader=FileSystemLoader(str(TEMPLATE_DIR)), + autoescape=select_autoescape(["html"]), + ) + template = env.get_template("graph.html") + return template.render(review=review, markdown=render_markdown(review)) diff --git a/src/loadpath/server/__init__.py b/src/loadpath/server/__init__.py new file mode 100644 index 0000000..ee38a59 --- /dev/null +++ b/src/loadpath/server/__init__.py @@ -0,0 +1,3 @@ +from loadpath.server.app import app, create_app, serve + +__all__ = ["app", "create_app", "serve"] diff --git a/src/loadpath/server/app.py b/src/loadpath/server/app.py new file mode 100644 index 0000000..54d4f90 --- /dev/null +++ b/src/loadpath/server/app.py @@ -0,0 +1,216 @@ +from __future__ import annotations + +import webbrowser +from pathlib import Path +from typing import Any + +from fastapi import FastAPI, HTTPException +from fastapi.middleware.cors import CORSMiddleware +from fastapi.staticfiles import StaticFiles +from pydantic import BaseModel, Field + +from loadpath import __version__ +from loadpath.ai.providers import client_for, residual_prompt +from loadpath.config import load_config +from loadpath.graph.store import GraphStore +from loadpath.index import default_db_path, index_repo +from loadpath.providers.scm import provider_for +from loadpath.review.engine import run_review +from loadpath.review.render import render_html, render_markdown +from loadpath.settings import AppSettings, public_settings, settings_path + + +class IndexRequest(BaseModel): + repo_path: str + incremental: bool = True + + +class ReviewRequest(BaseModel): + repo_path: str + base: str = "origin/main" + head: str | None = None + reindex: bool = True + + +class SettingsUpdate(BaseModel): + github_token: str | None = None + bitbucket_token: str | None = None + bitbucket_username: str | None = None + bitbucket_workspace: str | None = None + ai_provider: str | None = None + ai_api_key: str | None = None + ai_model: str | None = None + ai_base_url: str | None = None + workspaces: list[dict[str, Any]] | None = None + + +class PRListRequest(BaseModel): + provider: str + repo: str + state: str = "open" + token: str | None = None + username: str | None = None + + +class ResidualRequest(BaseModel): + review: dict[str, Any] = Field(default_factory=dict) + + +def create_app() -> FastAPI: + app = FastAPI(title="Loadpath", version=__version__) + app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_methods=["*"], + allow_headers=["*"], + ) + + @app.get("/api/health") + def health() -> dict[str, str]: + return {"status": "ok", "version": __version__} + + @app.get("/api/settings") + def get_settings() -> dict[str, Any]: + return public_settings(AppSettings.load()) + + @app.put("/api/settings") + def put_settings(body: SettingsUpdate) -> dict[str, Any]: + current = AppSettings.load() + if body.github_token is not None and body.github_token not in {"", current.github_token} and "…" not in body.github_token: + current.github_token = body.github_token + if body.bitbucket_token is not None and "…" not in (body.bitbucket_token or ""): + current.bitbucket_token = body.bitbucket_token + if body.bitbucket_username is not None: + current.bitbucket_username = body.bitbucket_username + if body.bitbucket_workspace is not None: + current.bitbucket_workspace = body.bitbucket_workspace + if body.ai_provider is not None: + current.ai.provider = body.ai_provider + if body.ai_api_key is not None and "…" not in body.ai_api_key: + current.ai.api_key = body.ai_api_key + if body.ai_model is not None: + current.ai.model = body.ai_model + if body.ai_base_url is not None: + current.ai.base_url = body.ai_base_url + if body.workspaces is not None: + from loadpath.settings import Workspace + + current.workspaces = [Workspace.model_validate(w) for w in body.workspaces] + current.save() + return public_settings(current) + + @app.post("/api/index") + def api_index(body: IndexRequest) -> dict[str, Any]: + root = Path(body.repo_path).expanduser().resolve() + if not root.is_dir(): + raise HTTPException(404, f"Repo not found: {root}") + store = index_repo(root, incremental=body.incremental) + counts = store.counts() + store.close() + return {"ok": True, "counts": counts, "db": str(default_db_path(root))} + + @app.post("/api/review") + def api_review(body: ReviewRequest) -> dict[str, Any]: + root = Path(body.repo_path).expanduser().resolve() + if not root.is_dir(): + raise HTTPException(404, f"Repo not found: {root}") + try: + review = run_review(root, base=body.base, head=body.head, reindex=body.reindex) + except Exception as exc: # noqa: BLE001 + raise HTTPException(400, str(exc)) from exc + review["markdown"] = render_markdown(review) + return review + + @app.get("/api/reviews") + def api_reviews(repo_path: str) -> dict[str, Any]: + root = Path(repo_path).expanduser().resolve() + db = default_db_path(root) + if not db.is_file(): + return {"reviews": []} + store = GraphStore(db) + items = store.list_reviews() + store.close() + return {"reviews": items} + + @app.get("/api/reviews/{review_id}") + def api_review_get(review_id: str, repo_path: str) -> dict[str, Any]: + root = Path(repo_path).expanduser().resolve() + store = GraphStore(default_db_path(root)) + item = store.get_review(review_id) + store.close() + if not item: + raise HTTPException(404, "Review not found") + return item + + @app.get("/api/graph") + def api_graph(repo_path: str) -> dict[str, Any]: + root = Path(repo_path).expanduser().resolve() + db = default_db_path(root) + if not db.is_file(): + raise HTTPException(404, "Index the repo first") + store = GraphStore(db) + payload = {"nodes": store.nodes(), "edges": store.edges(), "counts": store.counts()} + store.close() + return payload + + @app.get("/api/config") + def api_config(repo_path: str) -> dict[str, Any]: + root = Path(repo_path).expanduser().resolve() + cfg = load_config(root) + return { + "contexts": {k: vars(v) for k, v in cfg.contexts.items()}, + "rules": cfg.rules, + "django_root": cfg.django_root, + "react_root": cfg.react_root, + } + + @app.post("/api/prs") + def api_prs(body: PRListRequest) -> dict[str, Any]: + settings = AppSettings.load() + token = body.token + username = body.username or settings.bitbucket_username + if not token: + token = settings.github_token if body.provider == "github" else settings.bitbucket_token + if not token: + raise HTTPException(400, f"No {body.provider} token configured") + try: + scm = provider_for(body.provider, token, username=username) + prs = scm.list_pull_requests(body.repo, state=body.state) + except Exception as exc: # noqa: BLE001 + raise HTTPException(502, str(exc)) from exc + return {"pull_requests": [p.to_dict() for p in prs]} + + @app.post("/api/ai/residual") + def api_residual(body: ResidualRequest) -> dict[str, Any]: + settings = AppSettings.load() + if settings.ai.provider in {"", "none"} or not settings.ai.api_key: + raise HTTPException(400, "Configure an AI provider in settings first") + try: + client = client_for( + settings.ai.provider, + settings.ai.api_key, + model=settings.ai.model, + base_url=settings.ai.base_url, + ) + text = client.complete(residual_prompt(body.review)) + except Exception as exc: # noqa: BLE001 + raise HTTPException(502, str(exc)) from exc + return {"note": text} + + static_dir = Path(__file__).resolve().parent.parent / "static" + if static_dir.is_dir(): + app.mount("/", StaticFiles(directory=str(static_dir), html=True), name="static") + + return app + + +app = create_app() + + +def serve(host: str = "127.0.0.1", port: int = 7345, open_browser: bool = True) -> None: + import uvicorn + + settings_path().parent.mkdir(parents=True, exist_ok=True) + if open_browser: + webbrowser.open(f"http://{host}:{port}") + uvicorn.run("loadpath.server.app:app", host=host, port=port, reload=False) diff --git a/src/loadpath/settings.py b/src/loadpath/settings.py new file mode 100644 index 0000000..99d89cc --- /dev/null +++ b/src/loadpath/settings.py @@ -0,0 +1,83 @@ +from __future__ import annotations + +import json +from pathlib import Path +from typing import Any + +from pydantic import BaseModel, Field + + +def settings_path() -> Path: + return Path.home() / ".loadpath" / "settings.json" + + +class AISettings(BaseModel): + provider: str = "none" + api_key: str = "" + model: str = "" + base_url: str = "" + + +class SCMConnection(BaseModel): + provider: str # github | bitbucket + token: str = "" + username: str = "" + workspace: str = "" + repos: list[str] = Field(default_factory=list) + + +class Workspace(BaseModel): + path: str + name: str = "" + remote: str | None = None + + +class AppSettings(BaseModel): + github_token: str = "" + bitbucket_token: str = "" + bitbucket_username: str = "" + bitbucket_workspace: str = "" + ai: AISettings = Field(default_factory=AISettings) + workspaces: list[Workspace] = Field(default_factory=list) + connections: list[SCMConnection] = Field(default_factory=list) + + def save(self, path: Path | None = None) -> None: + p = path or settings_path() + p.parent.mkdir(parents=True, exist_ok=True) + p.write_text(self.model_dump_json(indent=2), encoding="utf-8") + + @classmethod + def load(cls, path: Path | None = None) -> AppSettings: + p = path or settings_path() + if not p.is_file(): + return cls() + data = json.loads(p.read_text(encoding="utf-8")) + return cls.model_validate(data) + + +def mask_secret(value: str) -> str: + if not value: + return "" + if len(value) <= 8: + return "••••" + return value[:4] + "…" + value[-2:] + + +def public_settings(settings: AppSettings) -> dict[str, Any]: + data = settings.model_dump() + data["github_token"] = mask_secret(settings.github_token) + data["bitbucket_token"] = mask_secret(settings.bitbucket_token) + data["github_token_set"] = bool(settings.github_token) + data["bitbucket_token_set"] = bool(settings.bitbucket_token) + data["ai"] = { + "provider": settings.ai.provider, + "model": settings.ai.model, + "base_url": settings.ai.base_url, + "api_key_set": bool(settings.ai.api_key), + "api_key": mask_secret(settings.ai.api_key), + } + for conn in data.get("connections") or []: + token = conn.get("token") or "" + conn["token_set"] = bool(token) + conn["token"] = mask_secret(token) + return data diff --git a/src/loadpath/static/assets/index-COnAStm3.css b/src/loadpath/static/assets/index-COnAStm3.css new file mode 100644 index 0000000..13ea2bc --- /dev/null +++ b/src/loadpath/static/assets/index-COnAStm3.css @@ -0,0 +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{--bg: #070b10;--bg-2: #0d141c;--surface: #121a24;--line: #1e2c3c;--ink: #e7eef6;--muted: #8b9bb0;--high: #2a9d8f;--medium: #e9c46a;--low: #e76f51;--critical: #e85d04;--accent: #4cc9f0}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{background:var(--bg);color:var(--ink);font-family:IBM Plex Sans,Segoe UI,sans-serif}button,input,select,textarea{font-family:inherit;color:inherit}.app{display:grid;grid-template-columns:220px 1fr;height:100%}.rail{border-right:1px solid var(--line);background:linear-gradient(180deg,#0b1219,#070b10);padding:20px 14px;display:flex;flex-direction:column;gap:6px}.brand{font-family:IBM Plex Mono,monospace;letter-spacing:.18em;font-size:12px;text-transform:uppercase;color:var(--accent);margin:0 0 18px}.rail button,.tab{background:transparent;border:0;text-align:left;padding:8px 10px;border-radius:6px;color:var(--muted);cursor:pointer}.rail button.active,.tab.active{background:#15202c;color:var(--ink)}.main{display:flex;flex-direction:column;min-width:0}.topbar{display:flex;gap:8px;align-items:center;padding:12px 16px;border-bottom:1px solid var(--line);background:var(--bg-2)}.topbar input,.topbar select{background:var(--surface);border:1px solid var(--line);border-radius:6px;padding:8px 10px;min-width:160px}.topbar input.path{flex:1}.topbar button,.btn{background:#173044;border:1px solid #24506c;border-radius:6px;padding:8px 12px;cursor:pointer}.btn.primary{background:#134e4a;border-color:#2a9d8f}.content{flex:1;min-height:0;display:grid;grid-template-columns:420px 1fr}.brief{overflow:auto;border-right:1px solid var(--line);padding:18px;background:radial-gradient(circle at 0 0,rgba(76,201,240,.05),transparent 40%),var(--bg)}.graph-wrap{position:relative;min-height:0}.graph-wrap .react-flow{background-color:#070b10;background-image:linear-gradient(rgba(42,80,120,.09) 1px,transparent 1px),linear-gradient(90deg,rgba(42,80,120,.09) 1px,transparent 1px);background-size:24px 24px}h1{font-size:18px;margin:0 0 6px}.level{font-family:IBM Plex Mono,monospace;font-weight:600}.level.high{color:var(--high)}.level.medium{color:var(--medium)}.level.low{color:var(--low)}.kicker{color:var(--muted);font-size:12px;text-transform:uppercase;letter-spacing:.08em;margin:16px 0 6px}.chip{display:inline-block;font-size:11px;padding:2px 8px;border-radius:999px;border:1px solid var(--line);margin:0 6px 6px 0;color:var(--muted)}.chip.blocker{color:var(--low);border-color:var(--low)}.file{font-family:IBM Plex Mono,monospace;font-size:12px;color:var(--accent)}.muted{color:var(--muted);font-size:13px;line-height:1.45}.error{color:var(--low);padding:8px 16px}.pr-list{padding:16px;overflow:auto}.pr{border:1px solid var(--line);background:var(--surface);padding:12px 14px;border-radius:8px;margin-bottom:10px}.pr h3{margin:0 0 4px;font-size:14px}.settings{padding:24px;max-width:640px;display:grid;gap:10px}.settings label{font-size:12px;color:var(--muted)}.settings input,.settings select{background:var(--surface);border:1px solid var(--line);border-radius:6px;padding:8px 10px;width:100%}.headline{white-space:pre-wrap;font-family:IBM Plex Mono,monospace;font-size:12px;color:var(--muted)}.lp-node{padding:8px 10px;border-radius:8px;border:1px solid #2a3d52;background:#101822;min-width:150px;box-shadow:0 0 0 1px #4cc9f014}.lp-node .t{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.08em}.lp-node .n{font-size:13px;font-weight:600} diff --git a/src/loadpath/static/assets/index-DigBKCrc.js b/src/loadpath/static/assets/index-DigBKCrc.js new file mode 100644 index 0000000..5be5f50 --- /dev/null +++ b/src/loadpath/static/assets/index-DigBKCrc.js @@ -0,0 +1,62 @@ +(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const u of document.querySelectorAll('link[rel="modulepreload"]'))l(u);new MutationObserver(u=>{for(const c of u)if(c.type==="childList")for(const f of c.addedNodes)f.tagName==="LINK"&&f.rel==="modulepreload"&&l(f)}).observe(document,{childList:!0,subtree:!0});function i(u){const c={};return u.integrity&&(c.integrity=u.integrity),u.referrerPolicy&&(c.referrerPolicy=u.referrerPolicy),u.crossOrigin==="use-credentials"?c.credentials="include":u.crossOrigin==="anonymous"?c.credentials="omit":c.credentials="same-origin",c}function l(u){if(u.ep)return;u.ep=!0;const c=i(u);fetch(u.href,c)}})();function Zh(n){return n&&n.__esModule&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n}var ha={exports:{}},Ko={},pa={exports:{}},Ne={};/** + * @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 Rd;function x0(){if(Rd)return Ne;Rd=1;var n=Symbol.for("react.element"),r=Symbol.for("react.portal"),i=Symbol.for("react.fragment"),l=Symbol.for("react.strict_mode"),u=Symbol.for("react.profiler"),c=Symbol.for("react.provider"),f=Symbol.for("react.context"),h=Symbol.for("react.forward_ref"),p=Symbol.for("react.suspense"),m=Symbol.for("react.memo"),v=Symbol.for("react.lazy"),y=Symbol.iterator;function g(C){return C===null||typeof C!="object"?null:(C=y&&C[y]||C["@@iterator"],typeof C=="function"?C:null)}var w={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},S=Object.assign,M={};function N(C,R,te){this.props=C,this.context=R,this.refs=M,this.updater=te||w}N.prototype.isReactComponent={},N.prototype.setState=function(C,R){if(typeof C!="object"&&typeof C!="function"&&C!=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,C,R,"setState")},N.prototype.forceUpdate=function(C){this.updater.enqueueForceUpdate(this,C,"forceUpdate")};function E(){}E.prototype=N.prototype;function L(C,R,te){this.props=C,this.context=R,this.refs=M,this.updater=te||w}var _=L.prototype=new E;_.constructor=L,S(_,N.prototype),_.isPureReactComponent=!0;var P=Array.isArray,U=Object.prototype.hasOwnProperty,D={current:null},V={key:!0,ref:!0,__self:!0,__source:!0};function X(C,R,te){var re,ue={},ce=null,ae=null;if(R!=null)for(re in R.ref!==void 0&&(ae=R.ref),R.key!==void 0&&(ce=""+R.key),R)U.call(R,re)&&!V.hasOwnProperty(re)&&(ue[re]=R[re]);var G=arguments.length-2;if(G===1)ue.children=te;else if(1>>1,R=j[C];if(0>>1;Cu(ue,F))ceu(ae,ue)?(j[C]=ae,j[ce]=F,C=ce):(j[C]=ue,j[re]=F,C=re);else if(ceu(ae,F))j[C]=ae,j[ce]=F,C=ce;else break e}}return $}function u(j,$){var F=j.sortIndex-$.sortIndex;return F!==0?F:j.id-$.id}if(typeof performance=="object"&&typeof performance.now=="function"){var c=performance;n.unstable_now=function(){return c.now()}}else{var f=Date,h=f.now();n.unstable_now=function(){return f.now()-h}}var p=[],m=[],v=1,y=null,g=3,w=!1,S=!1,M=!1,N=typeof setTimeout=="function"?setTimeout:null,E=typeof clearTimeout=="function"?clearTimeout:null,L=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function _(j){for(var $=i(m);$!==null;){if($.callback===null)l(m);else if($.startTime<=j)l(m),$.sortIndex=$.expirationTime,r(p,$);else break;$=i(m)}}function P(j){if(M=!1,_(j),!S)if(i(p)!==null)S=!0,z(U);else{var $=i(m);$!==null&&H(P,$.startTime-j)}}function U(j,$){S=!1,M&&(M=!1,E(X),X=-1),w=!0;var F=g;try{for(_($),y=i(p);y!==null&&(!(y.expirationTime>$)||j&&!q());){var C=y.callback;if(typeof C=="function"){y.callback=null,g=y.priorityLevel;var R=C(y.expirationTime<=$);$=n.unstable_now(),typeof R=="function"?y.callback=R:y===i(p)&&l(p),_($)}else l(p);y=i(p)}if(y!==null)var te=!0;else{var re=i(m);re!==null&&H(P,re.startTime-$),te=!1}return te}finally{y=null,g=F,w=!1}}var D=!1,V=null,X=-1,b=5,ee=-1;function q(){return!(n.unstable_now()-eej||125C?(j.sortIndex=F,r(m,j),i(p)===null&&j===i(m)&&(M?(E(X),X=-1):M=!0,H(P,F-C))):(j.sortIndex=R,r(p,j),S||w||(S=!0,z(U))),j},n.unstable_shouldYield=q,n.unstable_wrapCallback=function(j){var $=g;return function(){var F=g;g=$;try{return j.apply(this,arguments)}finally{g=F}}}})(ya)),ya}var Od;function k0(){return Od||(Od=1,ma.exports=E0()),ma.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 Fd;function N0(){if(Fd)return gt;Fd=1;var n=di(),r=k0();function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,o=1;o"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),p=Object.prototype.hasOwnProperty,m=/^[: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={},y={};function g(e){return p.call(y,e)?!0:p.call(v,e)?!1:m.test(e)?y[e]=!0:(v[e]=!0,!1)}function w(e,t,o,s){if(o!==null&&o.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return s?!1:o!==null?!o.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function S(e,t,o,s){if(t===null||typeof t>"u"||w(e,t,o,s))return!0;if(s)return!1;if(o!==null)switch(o.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function M(e,t,o,s,a,d,x){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=s,this.attributeNamespace=a,this.mustUseProperty=o,this.propertyName=e,this.type=t,this.sanitizeURL=d,this.removeEmptyString=x}var N={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){N[e]=new M(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];N[t]=new M(t,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){N[e]=new M(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){N[e]=new M(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){N[e]=new M(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){N[e]=new M(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){N[e]=new M(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){N[e]=new M(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){N[e]=new M(e,5,!1,e.toLowerCase(),null,!1,!1)});var E=/[\-:]([a-z])/g;function L(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 t=e.replace(E,L);N[t]=new M(t,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(E,L);N[t]=new M(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(E,L);N[t]=new M(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){N[e]=new M(e,1,!1,e.toLowerCase(),null,!1,!1)}),N.xlinkHref=new M("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){N[e]=new M(e,1,!1,e.toLowerCase(),null,!0,!0)});function _(e,t,o,s){var a=N.hasOwnProperty(t)?N[t]:null;(a!==null?a.type!==0:s||!(2I||a[x]!==d[I]){var A=` +`+a[x].replace(" at new "," at ");return e.displayName&&A.includes("")&&(A=A.replace("",e.displayName)),A}while(1<=x&&0<=I);break}}}finally{te=!1,Error.prepareStackTrace=o}return(e=e?e.displayName||e.name:"")?R(e):""}function ue(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=re(e.type,!1),e;case 11:return e=re(e.type.render,!1),e;case 1:return e=re(e.type,!0),e;default:return""}}function ce(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 D:return"Portal";case b:return"Profiler";case X:return"StrictMode";case Z:return"Suspense";case k:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case q:return(e.displayName||"Context")+".Consumer";case ee:return(e._context.displayName||"Context")+".Provider";case J:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case B:return t=e.displayName||null,t!==null?t:ce(e.type)||"Memo";case z:t=e._payload,e=e._init;try{return ce(e(t))}catch{}}return null}function ae(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return ce(t);case 8:return t===X?"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 t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function G(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function se(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function pe(e){var t=se(e)?"checked":"value",o=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),s=""+e[t];if(!e.hasOwnProperty(t)&&typeof o<"u"&&typeof o.get=="function"&&typeof o.set=="function"){var a=o.get,d=o.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return a.call(this)},set:function(x){s=""+x,d.call(this,x)}}),Object.defineProperty(e,t,{enumerable:o.enumerable}),{getValue:function(){return s},setValue:function(x){s=""+x},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function we(e){e._valueTracker||(e._valueTracker=pe(e))}function ve(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var o=t.getValue(),s="";return e&&(s=se(e)?e.checked?"true":"false":e.value),e=s,e!==o?(t.setValue(e),!0):!1}function me(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 ke(e,t){var o=t.checked;return F({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:o??e._wrapperState.initialChecked})}function Ce(e,t){var o=t.defaultValue==null?"":t.defaultValue,s=t.checked!=null?t.checked:t.defaultChecked;o=G(t.value!=null?t.value:o),e._wrapperState={initialChecked:s,initialValue:o,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function Me(e,t){t=t.checked,t!=null&&_(e,"checked",t,!1)}function Le(e,t){Me(e,t);var o=G(t.value),s=t.type;if(o!=null)s==="number"?(o===0&&e.value===""||e.value!=o)&&(e.value=""+o):e.value!==""+o&&(e.value=""+o);else if(s==="submit"||s==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?ut(e,t.type,o):t.hasOwnProperty("defaultValue")&&ut(e,t.type,G(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function it(e,t,o){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var s=t.type;if(!(s!=="submit"&&s!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,o||t===e.value||(e.value=t),e.defaultValue=t}o=e.name,o!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,o!==""&&(e.name=o)}function ut(e,t,o){(t!=="number"||me(e.ownerDocument)!==e)&&(o==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+o&&(e.defaultValue=""+o))}var Je=Array.isArray;function et(e,t,o,s){if(e=e.options,t){t={};for(var a=0;a"+t.valueOf().toString()+"",t=Mt.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function on(e,t){if(t){var o=e.firstChild;if(o&&o===e.lastChild&&o.nodeType===3){o.nodeValue=t;return}}e.textContent=t}var Yn={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},Sl=["Webkit","ms","Moz","O"];Object.keys(Yn).forEach(function(e){Sl.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),Yn[t]=Yn[e]})});function xi(e,t,o){return t==null||typeof t=="boolean"||t===""?"":o||typeof t!="number"||t===0||Yn.hasOwnProperty(e)&&Yn[e]?(""+t).trim():t+"px"}function wi(e,t){e=e.style;for(var o in t)if(t.hasOwnProperty(o)){var s=o.indexOf("--")===0,a=xi(o,t[o],s);o==="float"&&(o="cssFloat"),s?e.setProperty(o,a):e[o]=a}}var _l=F({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 so(e,t){if(t){if(_l[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(i(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(i(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(i(61))}if(t.style!=null&&typeof t.style!="object")throw Error(i(62))}}function lo(e,t){if(e.indexOf("-")===-1)return typeof t.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 uo=null;function ao(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var co=null,vn=null,xn=null;function Si(e){if(e=jo(e)){if(typeof co!="function")throw Error(i(280));var t=e.stateNode;t&&(t=qi(t),co(e.stateNode,e.type,t))}}function _i(e){vn?xn?xn.push(e):xn=[e]:vn=e}function Ei(){if(vn){var e=vn,t=xn;if(xn=vn=null,Si(e),t)for(e=0;e>>=0,e===0?32:31-(Ll(e)/Rl|0)|0}var kr=64,Nr=4194304;function Gn(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 sn(e,t){var o=e.pendingLanes;if(o===0)return 0;var s=0,a=e.suspendedLanes,d=e.pingedLanes,x=o&268435455;if(x!==0){var I=x&~a;I!==0?s=Gn(I):(d&=x,d!==0&&(s=Gn(d)))}else x=o&~a,x!==0?s=Gn(x):d!==0&&(s=Gn(d));if(s===0)return 0;if(t!==0&&t!==s&&(t&a)===0&&(a=s&-s,d=t&-t,a>=d||a===16&&(d&4194240)!==0))return t;if((s&4)!==0&&(s|=o&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=s;0o;o++)t.push(e);return t}function qn(e,t,o){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-xt(t),e[t]=o}function $l(e,t){var o=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var s=e.eventTimes;for(e=e.expirationTimes;0=Co),Nc=" ",Cc=!1;function Mc(e,t){switch(e){case"keyup":return pm.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Pc(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Ir=!1;function mm(e,t){switch(e){case"compositionend":return Pc(t);case"keypress":return t.which!==32?null:(Cc=!0,Nc);case"textInput":return e=t.data,e===Nc&&Cc?null:e;default:return null}}function ym(e,t){if(Ir)return e==="compositionend"||!bl&&Mc(e,t)?(e=xc(),Hi=Vl=kn=null,Ir=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:o,offset:t-e};e=s}e:{for(;o;){if(o.nextSibling){o=o.nextSibling;break e}o=o.parentNode}o=void 0}o=jc(o)}}function Dc(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Dc(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Oc(){for(var e=window,t=me();t instanceof e.HTMLIFrameElement;){try{var o=typeof t.contentWindow.location.href=="string"}catch{o=!1}if(o)e=t.contentWindow;else break;t=me(e.document)}return t}function Kl(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}function Cm(e){var t=Oc(),o=e.focusedElem,s=e.selectionRange;if(t!==o&&o&&o.ownerDocument&&Dc(o.ownerDocument.documentElement,o)){if(s!==null&&Kl(o)){if(t=s.start,e=s.end,e===void 0&&(e=t),"selectionStart"in o)o.selectionStart=t,o.selectionEnd=Math.min(e,o.value.length);else if(e=(t=o.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var a=o.textContent.length,d=Math.min(s.start,a);s=s.end===void 0?d:Math.min(s.end,a),!e.extend&&d>s&&(a=s,s=d,d=a),a=$c(o,d);var x=$c(o,s);a&&x&&(e.rangeCount!==1||e.anchorNode!==a.node||e.anchorOffset!==a.offset||e.focusNode!==x.node||e.focusOffset!==x.offset)&&(t=t.createRange(),t.setStart(a.node,a.offset),e.removeAllRanges(),d>s?(e.addRange(t),e.extend(x.node,x.offset)):(t.setEnd(x.node,x.offset),e.addRange(t)))}}for(t=[],e=o;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof o.focus=="function"&&o.focus(),o=0;o=document.documentMode,zr=null,ql=null,zo=null,Zl=!1;function Fc(e,t,o){var s=o.window===o?o.document:o.nodeType===9?o:o.ownerDocument;Zl||zr==null||zr!==me(s)||(s=zr,"selectionStart"in s&&Kl(s)?s={start:s.selectionStart,end:s.selectionEnd}:(s=(s.ownerDocument&&s.ownerDocument.defaultView||window).getSelection(),s={anchorNode:s.anchorNode,anchorOffset:s.anchorOffset,focusNode:s.focusNode,focusOffset:s.focusOffset}),zo&&Io(zo,s)||(zo=s,s=Qi(ql,"onSelect"),0jr||(e.current=cu[jr],cu[jr]=null,jr--)}function Re(e,t){jr++,cu[jr]=e.current,e.current=t}var Pn={},tt=Mn(Pn),ct=Mn(!1),Jn=Pn;function $r(e,t){var o=e.type.contextTypes;if(!o)return Pn;var s=e.stateNode;if(s&&s.__reactInternalMemoizedUnmaskedChildContext===t)return s.__reactInternalMemoizedMaskedChildContext;var a={},d;for(d in o)a[d]=t[d];return s&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=a),a}function ft(e){return e=e.childContextTypes,e!=null}function Zi(){je(ct),je(tt)}function ef(e,t,o){if(tt.current!==Pn)throw Error(i(168));Re(tt,t),Re(ct,o)}function tf(e,t,o){var s=e.stateNode;if(t=t.childContextTypes,typeof s.getChildContext!="function")return o;s=s.getChildContext();for(var a in s)if(!(a in t))throw Error(i(108,ae(e)||"Unknown",a));return F({},o,s)}function Ji(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Pn,Jn=tt.current,Re(tt,e),Re(ct,ct.current),!0}function nf(e,t,o){var s=e.stateNode;if(!s)throw Error(i(169));o?(e=tf(e,t,Jn),s.__reactInternalMemoizedMergedChildContext=e,je(ct),je(tt),Re(tt,e)):je(ct),Re(ct,o)}var un=null,es=!1,fu=!1;function rf(e){un===null?un=[e]:un.push(e)}function Om(e){es=!0,rf(e)}function In(){if(!fu&&un!==null){fu=!0;var e=0,t=Te;try{var o=un;for(Te=1;e>=x,a-=x,an=1<<32-xt(t)+a|o<Ee?(Ke=_e,_e=null):Ke=_e.sibling;var ze=ne(W,_e,Y[Ee],le);if(ze===null){_e===null&&(_e=Ke);break}e&&_e&&ze.alternate===null&&t(W,_e),O=d(ze,O,Ee),Se===null?ye=ze:Se.sibling=ze,Se=ze,_e=Ke}if(Ee===Y.length)return o(W,_e),De&&tr(W,Ee),ye;if(_e===null){for(;EeEe?(Ke=_e,_e=null):Ke=_e.sibling;var On=ne(W,_e,ze.value,le);if(On===null){_e===null&&(_e=Ke);break}e&&_e&&On.alternate===null&&t(W,_e),O=d(On,O,Ee),Se===null?ye=On:Se.sibling=On,Se=On,_e=Ke}if(ze.done)return o(W,_e),De&&tr(W,Ee),ye;if(_e===null){for(;!ze.done;Ee++,ze=Y.next())ze=ie(W,ze.value,le),ze!==null&&(O=d(ze,O,Ee),Se===null?ye=ze:Se.sibling=ze,Se=ze);return De&&tr(W,Ee),ye}for(_e=s(W,_e);!ze.done;Ee++,ze=Y.next())ze=fe(_e,W,Ee,ze.value,le),ze!==null&&(e&&ze.alternate!==null&&_e.delete(ze.key===null?Ee:ze.key),O=d(ze,O,Ee),Se===null?ye=ze:Se.sibling=ze,Se=ze);return e&&_e.forEach(function(v0){return t(W,v0)}),De&&tr(W,Ee),ye}function Ue(W,O,Y,le){if(typeof Y=="object"&&Y!==null&&Y.type===V&&Y.key===null&&(Y=Y.props.children),typeof Y=="object"&&Y!==null){switch(Y.$$typeof){case U:e:{for(var ye=Y.key,Se=O;Se!==null;){if(Se.key===ye){if(ye=Y.type,ye===V){if(Se.tag===7){o(W,Se.sibling),O=a(Se,Y.props.children),O.return=W,W=O;break e}}else if(Se.elementType===ye||typeof ye=="object"&&ye!==null&&ye.$$typeof===z&&cf(ye)===Se.type){o(W,Se.sibling),O=a(Se,Y.props),O.ref=$o(W,Se,Y),O.return=W,W=O;break e}o(W,Se);break}else t(W,Se);Se=Se.sibling}Y.type===V?(O=ar(Y.props.children,W.mode,le,Y.key),O.return=W,W=O):(le=Ps(Y.type,Y.key,Y.props,null,W.mode,le),le.ref=$o(W,O,Y),le.return=W,W=le)}return x(W);case D:e:{for(Se=Y.key;O!==null;){if(O.key===Se)if(O.tag===4&&O.stateNode.containerInfo===Y.containerInfo&&O.stateNode.implementation===Y.implementation){o(W,O.sibling),O=a(O,Y.children||[]),O.return=W,W=O;break e}else{o(W,O);break}else t(W,O);O=O.sibling}O=ua(Y,W.mode,le),O.return=W,W=O}return x(W);case z:return Se=Y._init,Ue(W,O,Se(Y._payload),le)}if(Je(Y))return he(W,O,Y,le);if($(Y))return ge(W,O,Y,le);os(W,Y)}return typeof Y=="string"&&Y!==""||typeof Y=="number"?(Y=""+Y,O!==null&&O.tag===6?(o(W,O.sibling),O=a(O,Y),O.return=W,W=O):(o(W,O),O=la(Y,W.mode,le),O.return=W,W=O),x(W)):o(W,O)}return Ue}var Hr=ff(!0),df=ff(!1),is=Mn(null),ss=null,Vr=null,yu=null;function vu(){yu=Vr=ss=null}function xu(e){var t=is.current;je(is),e._currentValue=t}function wu(e,t,o){for(;e!==null;){var s=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,s!==null&&(s.childLanes|=t)):s!==null&&(s.childLanes&t)!==t&&(s.childLanes|=t),e===o)break;e=e.return}}function Br(e,t){ss=e,yu=Vr=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&t)!==0&&(dt=!0),e.firstContext=null)}function zt(e){var t=e._currentValue;if(yu!==e)if(e={context:e,memoizedValue:t,next:null},Vr===null){if(ss===null)throw Error(i(308));Vr=e,ss.dependencies={lanes:0,firstContext:e}}else Vr=Vr.next=e;return t}var nr=null;function Su(e){nr===null?nr=[e]:nr.push(e)}function hf(e,t,o,s){var a=t.interleaved;return a===null?(o.next=o,Su(t)):(o.next=a.next,a.next=o),t.interleaved=o,fn(e,s)}function fn(e,t){e.lanes|=t;var o=e.alternate;for(o!==null&&(o.lanes|=t),o=e,e=e.return;e!==null;)e.childLanes|=t,o=e.alternate,o!==null&&(o.childLanes|=t),o=e,e=e.return;return o.tag===3?o.stateNode:null}var zn=!1;function _u(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function pf(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function dn(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function Tn(e,t,o){var s=e.updateQueue;if(s===null)return null;if(s=s.shared,(Pe&2)!==0){var a=s.pending;return a===null?t.next=t:(t.next=a.next,a.next=t),s.pending=t,fn(e,o)}return a=s.interleaved,a===null?(t.next=t,Su(s)):(t.next=a.next,a.next=t),s.interleaved=t,fn(e,o)}function ls(e,t,o){if(t=t.updateQueue,t!==null&&(t=t.shared,(o&4194240)!==0)){var s=t.lanes;s&=e.pendingLanes,o|=s,t.lanes=o,Cr(e,o)}}function gf(e,t){var o=e.updateQueue,s=e.alternate;if(s!==null&&(s=s.updateQueue,o===s)){var a=null,d=null;if(o=o.firstBaseUpdate,o!==null){do{var x={eventTime:o.eventTime,lane:o.lane,tag:o.tag,payload:o.payload,callback:o.callback,next:null};d===null?a=d=x:d=d.next=x,o=o.next}while(o!==null);d===null?a=d=t:d=d.next=t}else a=d=t;o={baseState:s.baseState,firstBaseUpdate:a,lastBaseUpdate:d,shared:s.shared,effects:s.effects},e.updateQueue=o;return}e=o.lastBaseUpdate,e===null?o.firstBaseUpdate=t:e.next=t,o.lastBaseUpdate=t}function us(e,t,o,s){var a=e.updateQueue;zn=!1;var d=a.firstBaseUpdate,x=a.lastBaseUpdate,I=a.shared.pending;if(I!==null){a.shared.pending=null;var A=I,Q=A.next;A.next=null,x===null?d=Q:x.next=Q,x=A;var oe=e.alternate;oe!==null&&(oe=oe.updateQueue,I=oe.lastBaseUpdate,I!==x&&(I===null?oe.firstBaseUpdate=Q:I.next=Q,oe.lastBaseUpdate=A))}if(d!==null){var ie=a.baseState;x=0,oe=Q=A=null,I=d;do{var ne=I.lane,fe=I.eventTime;if((s&ne)===ne){oe!==null&&(oe=oe.next={eventTime:fe,lane:0,tag:I.tag,payload:I.payload,callback:I.callback,next:null});e:{var he=e,ge=I;switch(ne=t,fe=o,ge.tag){case 1:if(he=ge.payload,typeof he=="function"){ie=he.call(fe,ie,ne);break e}ie=he;break e;case 3:he.flags=he.flags&-65537|128;case 0:if(he=ge.payload,ne=typeof he=="function"?he.call(fe,ie,ne):he,ne==null)break e;ie=F({},ie,ne);break e;case 2:zn=!0}}I.callback!==null&&I.lane!==0&&(e.flags|=64,ne=a.effects,ne===null?a.effects=[I]:ne.push(I))}else fe={eventTime:fe,lane:ne,tag:I.tag,payload:I.payload,callback:I.callback,next:null},oe===null?(Q=oe=fe,A=ie):oe=oe.next=fe,x|=ne;if(I=I.next,I===null){if(I=a.shared.pending,I===null)break;ne=I,I=ne.next,ne.next=null,a.lastBaseUpdate=ne,a.shared.pending=null}}while(!0);if(oe===null&&(A=ie),a.baseState=A,a.firstBaseUpdate=Q,a.lastBaseUpdate=oe,t=a.shared.interleaved,t!==null){a=t;do x|=a.lane,a=a.next;while(a!==t)}else d===null&&(a.shared.lanes=0);ir|=x,e.lanes=x,e.memoizedState=ie}}function mf(e,t,o){if(e=t.effects,t.effects=null,e!==null)for(t=0;to?o:4,e(!0);var s=Mu.transition;Mu.transition={};try{e(!1),t()}finally{Te=o,Mu.transition=s}}function jf(){return Tt().memoizedState}function Bm(e,t,o){var s=jn(e);if(o={lane:s,action:o,hasEagerState:!1,eagerState:null,next:null},$f(e))Df(t,o);else if(o=hf(e,t,o,s),o!==null){var a=lt();Ft(o,e,s,a),Of(o,t,s)}}function Um(e,t,o){var s=jn(e),a={lane:s,action:o,hasEagerState:!1,eagerState:null,next:null};if($f(e))Df(t,a);else{var d=e.alternate;if(e.lanes===0&&(d===null||d.lanes===0)&&(d=t.lastRenderedReducer,d!==null))try{var x=t.lastRenderedState,I=d(x,o);if(a.hasEagerState=!0,a.eagerState=I,At(I,x)){var A=t.interleaved;A===null?(a.next=a,Su(t)):(a.next=A.next,A.next=a),t.interleaved=a;return}}catch{}finally{}o=hf(e,t,a,s),o!==null&&(a=lt(),Ft(o,e,s,a),Of(o,t,s))}}function $f(e){var t=e.alternate;return e===He||t!==null&&t===He}function Df(e,t){Ho=fs=!0;var o=e.pending;o===null?t.next=t:(t.next=o.next,o.next=t),e.pending=t}function Of(e,t,o){if((o&4194240)!==0){var s=t.lanes;s&=e.pendingLanes,o|=s,t.lanes=o,Cr(e,o)}}var ps={readContext:zt,useCallback:nt,useContext:nt,useEffect:nt,useImperativeHandle:nt,useInsertionEffect:nt,useLayoutEffect:nt,useMemo:nt,useReducer:nt,useRef:nt,useState:nt,useDebugValue:nt,useDeferredValue:nt,useTransition:nt,useMutableSource:nt,useSyncExternalStore:nt,useId:nt,unstable_isNewReconciler:!1},Wm={readContext:zt,useCallback:function(e,t){return Zt().memoizedState=[e,t===void 0?null:t],e},useContext:zt,useEffect:Mf,useImperativeHandle:function(e,t,o){return o=o!=null?o.concat([e]):null,ds(4194308,4,zf.bind(null,t,e),o)},useLayoutEffect:function(e,t){return ds(4194308,4,e,t)},useInsertionEffect:function(e,t){return ds(4,2,e,t)},useMemo:function(e,t){var o=Zt();return t=t===void 0?null:t,e=e(),o.memoizedState=[e,t],e},useReducer:function(e,t,o){var s=Zt();return t=o!==void 0?o(t):t,s.memoizedState=s.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},s.queue=e,e=e.dispatch=Bm.bind(null,He,e),[s.memoizedState,e]},useRef:function(e){var t=Zt();return e={current:e},t.memoizedState=e},useState:Nf,useDebugValue:Au,useDeferredValue:function(e){return Zt().memoizedState=e},useTransition:function(){var e=Nf(!1),t=e[0];return e=Vm.bind(null,e[1]),Zt().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,o){var s=He,a=Zt();if(De){if(o===void 0)throw Error(i(407));o=o()}else{if(o=t(),Ge===null)throw Error(i(349));(or&30)!==0||wf(s,t,o)}a.memoizedState=o;var d={value:o,getSnapshot:t};return a.queue=d,Mf(_f.bind(null,s,d,e),[e]),s.flags|=2048,Uo(9,Sf.bind(null,s,d,o,t),void 0,null),o},useId:function(){var e=Zt(),t=Ge.identifierPrefix;if(De){var o=cn,s=an;o=(s&~(1<<32-xt(s)-1)).toString(32)+o,t=":"+t+"R"+o,o=Vo++,0<\/script>",e=e.removeChild(e.firstChild)):typeof s.is=="string"?e=x.createElement(o,{is:s.is}):(e=x.createElement(o),o==="select"&&(x=e,s.multiple?x.multiple=!0:s.size&&(x.size=s.size))):e=x.createElementNS(e,o),e[Kt]=t,e[Ao]=s,od(e,t,!1,!1),t.stateNode=e;e:{switch(x=lo(o,s),o){case"dialog":Ae("cancel",e),Ae("close",e),a=s;break;case"iframe":case"object":case"embed":Ae("load",e),a=s;break;case"video":case"audio":for(a=0;abr&&(t.flags|=128,s=!0,Wo(d,!1),t.lanes=4194304)}else{if(!s)if(e=as(x),e!==null){if(t.flags|=128,s=!0,o=e.updateQueue,o!==null&&(t.updateQueue=o,t.flags|=4),Wo(d,!0),d.tail===null&&d.tailMode==="hidden"&&!x.alternate&&!De)return rt(t),null}else 2*Oe()-d.renderingStartTime>br&&o!==1073741824&&(t.flags|=128,s=!0,Wo(d,!1),t.lanes=4194304);d.isBackwards?(x.sibling=t.child,t.child=x):(o=d.last,o!==null?o.sibling=x:t.child=x,d.last=x)}return d.tail!==null?(t=d.tail,d.rendering=t,d.tail=t.sibling,d.renderingStartTime=Oe(),t.sibling=null,o=Fe.current,Re(Fe,s?o&1|2:o&1),t):(rt(t),null);case 22:case 23:return oa(),s=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==s&&(t.flags|=8192),s&&(t.mode&1)!==0?(Et&1073741824)!==0&&(rt(t),t.subtreeFlags&6&&(t.flags|=8192)):rt(t),null;case 24:return null;case 25:return null}throw Error(i(156,t.tag))}function Zm(e,t){switch(hu(t),t.tag){case 1:return ft(t.type)&&Zi(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Ur(),je(ct),je(tt),Cu(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 5:return ku(t),null;case 13:if(je(Fe),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));Fr()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return je(Fe),null;case 4:return Ur(),null;case 10:return xu(t.type._context),null;case 22:case 23:return oa(),null;case 24:return null;default:return null}}var vs=!1,ot=!1,Jm=typeof WeakSet=="function"?WeakSet:Set,de=null;function Yr(e,t){var o=e.ref;if(o!==null)if(typeof o=="function")try{o(null)}catch(s){Be(e,t,s)}else o.current=null}function Xu(e,t,o){try{o()}catch(s){Be(e,t,s)}}var ld=!1;function e0(e,t){if(ou=Oi,e=Oc(),Kl(e)){if("selectionStart"in e)var o={start:e.selectionStart,end:e.selectionEnd};else e:{o=(o=e.ownerDocument)&&o.defaultView||window;var s=o.getSelection&&o.getSelection();if(s&&s.rangeCount!==0){o=s.anchorNode;var a=s.anchorOffset,d=s.focusNode;s=s.focusOffset;try{o.nodeType,d.nodeType}catch{o=null;break e}var x=0,I=-1,A=-1,Q=0,oe=0,ie=e,ne=null;t:for(;;){for(var fe;ie!==o||a!==0&&ie.nodeType!==3||(I=x+a),ie!==d||s!==0&&ie.nodeType!==3||(A=x+s),ie.nodeType===3&&(x+=ie.nodeValue.length),(fe=ie.firstChild)!==null;)ne=ie,ie=fe;for(;;){if(ie===e)break t;if(ne===o&&++Q===a&&(I=x),ne===d&&++oe===s&&(A=x),(fe=ie.nextSibling)!==null)break;ie=ne,ne=ie.parentNode}ie=fe}o=I===-1||A===-1?null:{start:I,end:A}}else o=null}o=o||{start:0,end:0}}else o=null;for(iu={focusedElem:e,selectionRange:o},Oi=!1,de=t;de!==null;)if(t=de,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,de=e;else for(;de!==null;){t=de;try{var he=t.alternate;if((t.flags&1024)!==0)switch(t.tag){case 0:case 11:case 15:break;case 1:if(he!==null){var ge=he.memoizedProps,Ue=he.memoizedState,W=t.stateNode,O=W.getSnapshotBeforeUpdate(t.elementType===t.type?ge:$t(t.type,ge),Ue);W.__reactInternalSnapshotBeforeUpdate=O}break;case 3:var Y=t.stateNode.containerInfo;Y.nodeType===1?Y.textContent="":Y.nodeType===9&&Y.documentElement&&Y.removeChild(Y.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(i(163))}}catch(le){Be(t,t.return,le)}if(e=t.sibling,e!==null){e.return=t.return,de=e;break}de=t.return}return he=ld,ld=!1,he}function Yo(e,t,o){var s=t.updateQueue;if(s=s!==null?s.lastEffect:null,s!==null){var a=s=s.next;do{if((a.tag&e)===e){var d=a.destroy;a.destroy=void 0,d!==void 0&&Xu(t,o,d)}a=a.next}while(a!==s)}}function xs(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var o=t=t.next;do{if((o.tag&e)===e){var s=o.create;o.destroy=s()}o=o.next}while(o!==t)}}function bu(e){var t=e.ref;if(t!==null){var o=e.stateNode;switch(e.tag){case 5:e=o;break;default:e=o}typeof t=="function"?t(e):t.current=e}}function ud(e){var t=e.alternate;t!==null&&(e.alternate=null,ud(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[Kt],delete t[Ao],delete t[au],delete t[$m],delete t[Dm])),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 ad(e){return e.tag===5||e.tag===3||e.tag===4}function cd(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||ad(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 Qu(e,t,o){var s=e.tag;if(s===5||s===6)e=e.stateNode,t?o.nodeType===8?o.parentNode.insertBefore(e,t):o.insertBefore(e,t):(o.nodeType===8?(t=o.parentNode,t.insertBefore(e,o)):(t=o,t.appendChild(e)),o=o._reactRootContainer,o!=null||t.onclick!==null||(t.onclick=Ki));else if(s!==4&&(e=e.child,e!==null))for(Qu(e,t,o),e=e.sibling;e!==null;)Qu(e,t,o),e=e.sibling}function Gu(e,t,o){var s=e.tag;if(s===5||s===6)e=e.stateNode,t?o.insertBefore(e,t):o.appendChild(e);else if(s!==4&&(e=e.child,e!==null))for(Gu(e,t,o),e=e.sibling;e!==null;)Gu(e,t,o),e=e.sibling}var qe=null,Dt=!1;function Ln(e,t,o){for(o=o.child;o!==null;)fd(e,t,o),o=o.sibling}function fd(e,t,o){if(vt&&typeof vt.onCommitFiberUnmount=="function")try{vt.onCommitFiberUnmount(Er,o)}catch{}switch(o.tag){case 5:ot||Yr(o,t);case 6:var s=qe,a=Dt;qe=null,Ln(e,t,o),qe=s,Dt=a,qe!==null&&(Dt?(e=qe,o=o.stateNode,e.nodeType===8?e.parentNode.removeChild(o):e.removeChild(o)):qe.removeChild(o.stateNode));break;case 18:qe!==null&&(Dt?(e=qe,o=o.stateNode,e.nodeType===8?uu(e.parentNode,o):e.nodeType===1&&uu(e,o),Eo(e)):uu(qe,o.stateNode));break;case 4:s=qe,a=Dt,qe=o.stateNode.containerInfo,Dt=!0,Ln(e,t,o),qe=s,Dt=a;break;case 0:case 11:case 14:case 15:if(!ot&&(s=o.updateQueue,s!==null&&(s=s.lastEffect,s!==null))){a=s=s.next;do{var d=a,x=d.destroy;d=d.tag,x!==void 0&&((d&2)!==0||(d&4)!==0)&&Xu(o,t,x),a=a.next}while(a!==s)}Ln(e,t,o);break;case 1:if(!ot&&(Yr(o,t),s=o.stateNode,typeof s.componentWillUnmount=="function"))try{s.props=o.memoizedProps,s.state=o.memoizedState,s.componentWillUnmount()}catch(I){Be(o,t,I)}Ln(e,t,o);break;case 21:Ln(e,t,o);break;case 22:o.mode&1?(ot=(s=ot)||o.memoizedState!==null,Ln(e,t,o),ot=s):Ln(e,t,o);break;default:Ln(e,t,o)}}function dd(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var o=e.stateNode;o===null&&(o=e.stateNode=new Jm),t.forEach(function(s){var a=a0.bind(null,e,s);o.has(s)||(o.add(s),s.then(a,a))})}}function Ot(e,t){var o=t.deletions;if(o!==null)for(var s=0;sa&&(a=x),s&=~d}if(s=a,s=Oe()-s,s=(120>s?120:480>s?480:1080>s?1080:1920>s?1920:3e3>s?3e3:4320>s?4320:1960*n0(s/1960))-s,10e?16:e,An===null)var s=!1;else{if(e=An,An=null,ks=0,(Pe&6)!==0)throw Error(i(331));var a=Pe;for(Pe|=4,de=e.current;de!==null;){var d=de,x=d.child;if((de.flags&16)!==0){var I=d.deletions;if(I!==null){for(var A=0;AOe()-Zu?lr(e,0):qu|=o),pt(e,t)}function Nd(e,t){t===0&&((e.mode&1)===0?t=1:(t=Nr,Nr<<=1,(Nr&130023424)===0&&(Nr=4194304)));var o=lt();e=fn(e,t),e!==null&&(qn(e,t,o),pt(e,o))}function u0(e){var t=e.memoizedState,o=0;t!==null&&(o=t.retryLane),Nd(e,o)}function a0(e,t){var o=0;switch(e.tag){case 13:var s=e.stateNode,a=e.memoizedState;a!==null&&(o=a.retryLane);break;case 19:s=e.stateNode;break;default:throw Error(i(314))}s!==null&&s.delete(t),Nd(e,o)}var Cd;Cd=function(e,t,o){if(e!==null)if(e.memoizedProps!==t.pendingProps||ct.current)dt=!0;else{if((e.lanes&o)===0&&(t.flags&128)===0)return dt=!1,Km(e,t,o);dt=(e.flags&131072)!==0}else dt=!1,De&&(t.flags&1048576)!==0&&of(t,ns,t.index);switch(t.lanes=0,t.tag){case 2:var s=t.type;ys(e,t),e=t.pendingProps;var a=$r(t,tt.current);Br(t,o),a=Iu(null,t,s,e,a,o);var d=zu();return t.flags|=1,typeof a=="object"&&a!==null&&typeof a.render=="function"&&a.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,ft(s)?(d=!0,Ji(t)):d=!1,t.memoizedState=a.state!==null&&a.state!==void 0?a.state:null,_u(t),a.updater=gs,t.stateNode=a,a._reactInternals=t,$u(t,s,e,o),t=Hu(null,t,s,!0,d,o)):(t.tag=0,De&&d&&du(t),st(null,t,a,o),t=t.child),t;case 16:s=t.elementType;e:{switch(ys(e,t),e=t.pendingProps,a=s._init,s=a(s._payload),t.type=s,a=t.tag=f0(s),e=$t(s,e),a){case 0:t=Fu(null,t,s,e,o);break e;case 1:t=Zf(null,t,s,e,o);break e;case 11:t=bf(null,t,s,e,o);break e;case 14:t=Qf(null,t,s,$t(s.type,e),o);break e}throw Error(i(306,s,""))}return t;case 0:return s=t.type,a=t.pendingProps,a=t.elementType===s?a:$t(s,a),Fu(e,t,s,a,o);case 1:return s=t.type,a=t.pendingProps,a=t.elementType===s?a:$t(s,a),Zf(e,t,s,a,o);case 3:e:{if(Jf(t),e===null)throw Error(i(387));s=t.pendingProps,d=t.memoizedState,a=d.element,pf(e,t),us(t,s,null,o);var x=t.memoizedState;if(s=x.element,d.isDehydrated)if(d={element:s,isDehydrated:!1,cache:x.cache,pendingSuspenseBoundaries:x.pendingSuspenseBoundaries,transitions:x.transitions},t.updateQueue.baseState=d,t.memoizedState=d,t.flags&256){a=Wr(Error(i(423)),t),t=ed(e,t,s,o,a);break e}else if(s!==a){a=Wr(Error(i(424)),t),t=ed(e,t,s,o,a);break e}else for(_t=Cn(t.stateNode.containerInfo.firstChild),St=t,De=!0,jt=null,o=df(t,null,s,o),t.child=o;o;)o.flags=o.flags&-3|4096,o=o.sibling;else{if(Fr(),s===a){t=hn(e,t,o);break e}st(e,t,s,o)}t=t.child}return t;case 5:return yf(t),e===null&&gu(t),s=t.type,a=t.pendingProps,d=e!==null?e.memoizedProps:null,x=a.children,su(s,a)?x=null:d!==null&&su(s,d)&&(t.flags|=32),qf(e,t),st(e,t,x,o),t.child;case 6:return e===null&&gu(t),null;case 13:return td(e,t,o);case 4:return Eu(t,t.stateNode.containerInfo),s=t.pendingProps,e===null?t.child=Hr(t,null,s,o):st(e,t,s,o),t.child;case 11:return s=t.type,a=t.pendingProps,a=t.elementType===s?a:$t(s,a),bf(e,t,s,a,o);case 7:return st(e,t,t.pendingProps,o),t.child;case 8:return st(e,t,t.pendingProps.children,o),t.child;case 12:return st(e,t,t.pendingProps.children,o),t.child;case 10:e:{if(s=t.type._context,a=t.pendingProps,d=t.memoizedProps,x=a.value,Re(is,s._currentValue),s._currentValue=x,d!==null)if(At(d.value,x)){if(d.children===a.children&&!ct.current){t=hn(e,t,o);break e}}else for(d=t.child,d!==null&&(d.return=t);d!==null;){var I=d.dependencies;if(I!==null){x=d.child;for(var A=I.firstContext;A!==null;){if(A.context===s){if(d.tag===1){A=dn(-1,o&-o),A.tag=2;var Q=d.updateQueue;if(Q!==null){Q=Q.shared;var oe=Q.pending;oe===null?A.next=A:(A.next=oe.next,oe.next=A),Q.pending=A}}d.lanes|=o,A=d.alternate,A!==null&&(A.lanes|=o),wu(d.return,o,t),I.lanes|=o;break}A=A.next}}else if(d.tag===10)x=d.type===t.type?null:d.child;else if(d.tag===18){if(x=d.return,x===null)throw Error(i(341));x.lanes|=o,I=x.alternate,I!==null&&(I.lanes|=o),wu(x,o,t),x=d.sibling}else x=d.child;if(x!==null)x.return=d;else for(x=d;x!==null;){if(x===t){x=null;break}if(d=x.sibling,d!==null){d.return=x.return,x=d;break}x=x.return}d=x}st(e,t,a.children,o),t=t.child}return t;case 9:return a=t.type,s=t.pendingProps.children,Br(t,o),a=zt(a),s=s(a),t.flags|=1,st(e,t,s,o),t.child;case 14:return s=t.type,a=$t(s,t.pendingProps),a=$t(s.type,a),Qf(e,t,s,a,o);case 15:return Gf(e,t,t.type,t.pendingProps,o);case 17:return s=t.type,a=t.pendingProps,a=t.elementType===s?a:$t(s,a),ys(e,t),t.tag=1,ft(s)?(e=!0,Ji(t)):e=!1,Br(t,o),Hf(t,s,a),$u(t,s,a,o),Hu(null,t,s,!0,e,o);case 19:return rd(e,t,o);case 22:return Kf(e,t,o)}throw Error(i(156,t.tag))};function Md(e,t){return Ii(e,t)}function c0(e,t,o,s){this.tag=e,this.key=o,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=s,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Rt(e,t,o,s){return new c0(e,t,o,s)}function sa(e){return e=e.prototype,!(!e||!e.isReactComponent)}function f0(e){if(typeof e=="function")return sa(e)?1:0;if(e!=null){if(e=e.$$typeof,e===J)return 11;if(e===B)return 14}return 2}function Dn(e,t){var o=e.alternate;return o===null?(o=Rt(e.tag,t,e.key,e.mode),o.elementType=e.elementType,o.type=e.type,o.stateNode=e.stateNode,o.alternate=e,e.alternate=o):(o.pendingProps=t,o.type=e.type,o.flags=0,o.subtreeFlags=0,o.deletions=null),o.flags=e.flags&14680064,o.childLanes=e.childLanes,o.lanes=e.lanes,o.child=e.child,o.memoizedProps=e.memoizedProps,o.memoizedState=e.memoizedState,o.updateQueue=e.updateQueue,t=e.dependencies,o.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},o.sibling=e.sibling,o.index=e.index,o.ref=e.ref,o}function Ps(e,t,o,s,a,d){var x=2;if(s=e,typeof e=="function")sa(e)&&(x=1);else if(typeof e=="string")x=5;else e:switch(e){case V:return ar(o.children,a,d,t);case X:x=8,a|=8;break;case b:return e=Rt(12,o,t,a|2),e.elementType=b,e.lanes=d,e;case Z:return e=Rt(13,o,t,a),e.elementType=Z,e.lanes=d,e;case k:return e=Rt(19,o,t,a),e.elementType=k,e.lanes=d,e;case H:return Is(o,a,d,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case ee:x=10;break e;case q:x=9;break e;case J:x=11;break e;case B:x=14;break e;case z:x=16,s=null;break e}throw Error(i(130,e==null?e:typeof e,""))}return t=Rt(x,o,t,a),t.elementType=e,t.type=s,t.lanes=d,t}function ar(e,t,o,s){return e=Rt(7,e,s,t),e.lanes=o,e}function Is(e,t,o,s){return e=Rt(22,e,s,t),e.elementType=H,e.lanes=o,e.stateNode={isHidden:!1},e}function la(e,t,o){return e=Rt(6,e,null,t),e.lanes=o,e}function ua(e,t,o){return t=Rt(4,e.children!==null?e.children:[],e.key,t),t.lanes=o,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function d0(e,t,o,s,a){this.tag=t,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=Kn(0),this.expirationTimes=Kn(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Kn(0),this.identifierPrefix=s,this.onRecoverableError=a,this.mutableSourceEagerHydrationData=null}function aa(e,t,o,s,a,d,x,I,A){return e=new d0(e,t,o,I,A),t===1?(t=1,d===!0&&(t|=8)):t=0,d=Rt(3,null,null,t),e.current=d,d.stateNode=e,d.memoizedState={element:s,isDehydrated:o,cache:null,transitions:null,pendingSuspenseBoundaries:null},_u(d),e}function h0(e,t,o){var s=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(r){console.error(r)}}return n(),ga.exports=N0(),ga.exports}var Vd;function C0(){if(Vd)return $s;Vd=1;var n=Jh();return $s.createRoot=n.createRoot,$s.hydrateRoot=n.hydrateRoot,$s}var M0=C0();async function Fn(n,r){const i=await fetch(n,{...r,headers:{"Content-Type":"application/json",...(r==null?void 0:r.headers)||{}}});if(!i.ok){const l=await i.text();throw new Error(l||i.statusText)}return i.json()}const Gr={health:()=>Fn("/api/health"),settings:()=>Fn("/api/settings"),saveSettings:n=>Fn("/api/settings",{method:"PUT",body:JSON.stringify(n)}),index:n=>Fn("/api/index",{method:"POST",body:JSON.stringify({repo_path:n,incremental:!0})}),review:(n,r,i)=>Fn("/api/review",{method:"POST",body:JSON.stringify({repo_path:n,base:r,head:i||null,reindex:!0})}),graph:n=>Fn(`/api/graph?repo_path=${encodeURIComponent(n)}`),prs:(n,r,i="open")=>Fn("/api/prs",{method:"POST",body:JSON.stringify({provider:n,repo:r,state:i})}),residual:n=>Fn("/api/ai/residual",{method:"POST",body:JSON.stringify({review:n})})};function Ye(n){if(typeof n=="string"||typeof n=="number")return""+n;let r="";if(Array.isArray(n))for(let i=0,l;i{}};function al(){for(var n=0,r=arguments.length,i={},l;n=0&&(l=i.slice(u+1),i=i.slice(0,u)),i&&!r.hasOwnProperty(i))throw new Error("unknown type: "+i);return{type:i,name:l}})}Xs.prototype=al.prototype={constructor:Xs,on:function(n,r){var i=this._,l=I0(n+"",i),u,c=-1,f=l.length;if(arguments.length<2){for(;++c0)for(var i=new Array(u),l=0,u,c;l=0&&(r=n.slice(0,i))!=="xmlns"&&(n=n.slice(i+1)),Ud.hasOwnProperty(r)?{space:Ud[r],local:n}:n}function T0(n){return function(){var r=this.ownerDocument,i=this.namespaceURI;return i===Ta&&r.documentElement.namespaceURI===Ta?r.createElement(n):r.createElementNS(i,n)}}function L0(n){return function(){return this.ownerDocument.createElementNS(n.space,n.local)}}function ep(n){var r=cl(n);return(r.local?L0:T0)(r)}function R0(){}function Ya(n){return n==null?R0:function(){return this.querySelector(n)}}function A0(n){typeof n!="function"&&(n=Ya(n));for(var r=this._groups,i=r.length,l=new Array(i),u=0;u=_&&(_=L+1);!(U=N[_])&&++_=0;)(f=l[u])&&(c&&f.compareDocumentPosition(c)^4&&c.parentNode.insertBefore(f,c),c=f);return this}function iy(n){n||(n=sy);function r(y,g){return y&&g?n(y.__data__,g.__data__):!y-!g}for(var i=this._groups,l=i.length,u=new Array(l),c=0;cr?1:n>=r?0:NaN}function ly(){var n=arguments[0];return arguments[0]=this,n.apply(null,arguments),this}function uy(){return Array.from(this)}function ay(){for(var n=this._groups,r=0,i=n.length;r1?this.each((r==null?wy:typeof r=="function"?_y:Sy)(n,r,i??"")):eo(this.node(),n)}function eo(n,r){return n.style.getPropertyValue(r)||ip(n).getComputedStyle(n,null).getPropertyValue(r)}function ky(n){return function(){delete this[n]}}function Ny(n,r){return function(){this[n]=r}}function Cy(n,r){return function(){var i=r.apply(this,arguments);i==null?delete this[n]:this[n]=i}}function My(n,r){return arguments.length>1?this.each((r==null?ky:typeof r=="function"?Cy:Ny)(n,r)):this.node()[n]}function sp(n){return n.trim().split(/^|\s+/)}function Xa(n){return n.classList||new lp(n)}function lp(n){this._node=n,this._names=sp(n.getAttribute("class")||"")}lp.prototype={add:function(n){var r=this._names.indexOf(n);r<0&&(this._names.push(n),this._node.setAttribute("class",this._names.join(" ")))},remove:function(n){var r=this._names.indexOf(n);r>=0&&(this._names.splice(r,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(n){return this._names.indexOf(n)>=0}};function up(n,r){for(var i=Xa(n),l=-1,u=r.length;++l=0&&(i=r.slice(l+1),r=r.slice(0,l)),{type:r,name:i}})}function tv(n){return function(){var r=this.__on;if(r){for(var i=0,l=-1,u=r.length,c;i()=>n;function La(n,{sourceEvent:r,subject:i,target:l,identifier:u,active:c,x:f,y:h,dx:p,dy:m,dispatch:v}){Object.defineProperties(this,{type:{value:n,enumerable:!0,configurable:!0},sourceEvent:{value:r,enumerable:!0,configurable:!0},subject:{value:i,enumerable:!0,configurable:!0},target:{value:l,enumerable:!0,configurable:!0},identifier:{value:u,enumerable:!0,configurable:!0},active:{value:c,enumerable:!0,configurable:!0},x:{value:f,enumerable:!0,configurable:!0},y:{value:h,enumerable:!0,configurable:!0},dx:{value:p,enumerable:!0,configurable:!0},dy:{value:m,enumerable:!0,configurable:!0},_:{value:v}})}La.prototype.on=function(){var n=this._.on.apply(this._,arguments);return n===this._?this:n};function fv(n){return!n.ctrlKey&&!n.button}function dv(){return this.parentNode}function hv(n,r){return r??{x:n.x,y:n.y}}function pv(){return navigator.maxTouchPoints||"ontouchstart"in this}function pp(){var n=fv,r=dv,i=hv,l=pv,u={},c=al("start","drag","end"),f=0,h,p,m,v,y=0;function g(P){P.on("mousedown.drag",w).filter(l).on("touchstart.drag",N).on("touchmove.drag",E,cv).on("touchend.drag touchcancel.drag",L).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function w(P,U){if(!(v||!n.call(this,P,U))){var D=_(this,r.call(this,P,U),P,U,"mouse");D&&(kt(P.view).on("mousemove.drag",S,ri).on("mouseup.drag",M,ri),dp(P.view),va(P),m=!1,h=P.clientX,p=P.clientY,D("start",P))}}function S(P){if(Zr(P),!m){var U=P.clientX-h,D=P.clientY-p;m=U*U+D*D>y}u.mouse("drag",P)}function M(P){kt(P.view).on("mousemove.drag mouseup.drag",null),hp(P.view,m),Zr(P),u.mouse("end",P)}function N(P,U){if(n.call(this,P,U)){var D=P.changedTouches,V=r.call(this,P,U),X=D.length,b,ee;for(b=0;b>8&15|r>>4&240,r>>4&15|r&240,(r&15)<<4|r&15,1):i===8?Os(r>>24&255,r>>16&255,r>>8&255,(r&255)/255):i===4?Os(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=mv.exec(n))?new mt(r[1],r[2],r[3],1):(r=yv.exec(n))?new mt(r[1]*255/100,r[2]*255/100,r[3]*255/100,1):(r=vv.exec(n))?Os(r[1],r[2],r[3],r[4]):(r=xv.exec(n))?Os(r[1]*255/100,r[2]*255/100,r[3]*255/100,r[4]):(r=wv.exec(n))?Kd(r[1],r[2]/100,r[3]/100,1):(r=Sv.exec(n))?Kd(r[1],r[2]/100,r[3]/100,r[4]):Wd.hasOwnProperty(n)?bd(Wd[n]):n==="transparent"?new mt(NaN,NaN,NaN,0):null}function bd(n){return new mt(n>>16&255,n>>8&255,n&255,1)}function Os(n,r,i,l){return l<=0&&(n=r=i=NaN),new mt(n,r,i,l)}function kv(n){return n instanceof pi||(n=pr(n)),n?(n=n.rgb(),new mt(n.r,n.g,n.b,n.opacity)):new mt}function Ra(n,r,i,l){return arguments.length===1?kv(n):new mt(n,r,i,l??1)}function mt(n,r,i,l){this.r=+n,this.g=+r,this.b=+i,this.opacity=+l}ba(mt,Ra,gp(pi,{brighter(n){return n=n==null?Zs:Math.pow(Zs,n),new mt(this.r*n,this.g*n,this.b*n,this.opacity)},darker(n){return n=n==null?oi:Math.pow(oi,n),new mt(this.r*n,this.g*n,this.b*n,this.opacity)},rgb(){return this},clamp(){return new mt(dr(this.r),dr(this.g),dr(this.b),Js(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:Qd,formatHex:Qd,formatHex8:Nv,formatRgb:Gd,toString:Gd}));function Qd(){return`#${fr(this.r)}${fr(this.g)}${fr(this.b)}`}function Nv(){return`#${fr(this.r)}${fr(this.g)}${fr(this.b)}${fr((isNaN(this.opacity)?1:this.opacity)*255)}`}function Gd(){const n=Js(this.opacity);return`${n===1?"rgb(":"rgba("}${dr(this.r)}, ${dr(this.g)}, ${dr(this.b)}${n===1?")":`, ${n})`}`}function Js(n){return isNaN(n)?1:Math.max(0,Math.min(1,n))}function dr(n){return Math.max(0,Math.min(255,Math.round(n)||0))}function fr(n){return n=dr(n),(n<16?"0":"")+n.toString(16)}function Kd(n,r,i,l){return l<=0?n=r=i=NaN:i<=0||i>=1?n=r=NaN:r<=0&&(n=NaN),new Vt(n,r,i,l)}function mp(n){if(n instanceof Vt)return new Vt(n.h,n.s,n.l,n.opacity);if(n instanceof pi||(n=pr(n)),!n)return new Vt;if(n instanceof Vt)return n;n=n.rgb();var r=n.r/255,i=n.g/255,l=n.b/255,u=Math.min(r,i,l),c=Math.max(r,i,l),f=NaN,h=c-u,p=(c+u)/2;return h?(r===c?f=(i-l)/h+(i0&&p<1?0:f,new Vt(f,h,p,n.opacity)}function Cv(n,r,i,l){return arguments.length===1?mp(n):new Vt(n,r,i,l??1)}function Vt(n,r,i,l){this.h=+n,this.s=+r,this.l=+i,this.opacity=+l}ba(Vt,Cv,gp(pi,{brighter(n){return n=n==null?Zs:Math.pow(Zs,n),new Vt(this.h,this.s,this.l*n,this.opacity)},darker(n){return n=n==null?oi:Math.pow(oi,n),new Vt(this.h,this.s,this.l*n,this.opacity)},rgb(){var n=this.h%360+(this.h<0)*360,r=isNaN(n)||isNaN(this.s)?0:this.s,i=this.l,l=i+(i<.5?i:1-i)*r,u=2*i-l;return new mt(xa(n>=240?n-240:n+120,u,l),xa(n,u,l),xa(n<120?n+240:n-120,u,l),this.opacity)},clamp(){return new Vt(qd(this.h),Fs(this.s),Fs(this.l),Js(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 n=Js(this.opacity);return`${n===1?"hsl(":"hsla("}${qd(this.h)}, ${Fs(this.s)*100}%, ${Fs(this.l)*100}%${n===1?")":`, ${n})`}`}}));function qd(n){return n=(n||0)%360,n<0?n+360:n}function Fs(n){return Math.max(0,Math.min(1,n||0))}function xa(n,r,i){return(n<60?r+(i-r)*n/60:n<180?i:n<240?r+(i-r)*(240-n)/60:r)*255}const Qa=n=>()=>n;function Mv(n,r){return function(i){return n+i*r}}function Pv(n,r,i){return n=Math.pow(n,i),r=Math.pow(r,i)-n,i=1/i,function(l){return Math.pow(n+l*r,i)}}function Iv(n){return(n=+n)==1?yp:function(r,i){return i-r?Pv(r,i,n):Qa(isNaN(r)?i:r)}}function yp(n,r){var i=r-n;return i?Mv(n,i):Qa(isNaN(n)?r:n)}const el=(function n(r){var i=Iv(r);function l(u,c){var f=i((u=Ra(u)).r,(c=Ra(c)).r),h=i(u.g,c.g),p=i(u.b,c.b),m=yp(u.opacity,c.opacity);return function(v){return u.r=f(v),u.g=h(v),u.b=p(v),u.opacity=m(v),u+""}}return l.gamma=n,l})(1);function zv(n,r){r||(r=[]);var i=n?Math.min(r.length,n.length):0,l=r.slice(),u;return function(c){for(u=0;ui&&(c=r.slice(i,c),h[f]?h[f]+=c:h[++f]=c),(l=l[0])===(u=u[0])?h[f]?h[f]+=u:h[++f]=u:(h[++f]=null,p.push({i:f,x:en(l,u)})),i=wa.lastIndex;return i180?v+=360:v-m>180&&(m+=360),g.push({i:y.push(u(y)+"rotate(",null,l)-2,x:en(m,v)})):v&&y.push(u(y)+"rotate("+v+l)}function h(m,v,y,g){m!==v?g.push({i:y.push(u(y)+"skewX(",null,l)-2,x:en(m,v)}):v&&y.push(u(y)+"skewX("+v+l)}function p(m,v,y,g,w,S){if(m!==y||v!==g){var M=w.push(u(w)+"scale(",null,",",null,")");S.push({i:M-4,x:en(m,y)},{i:M-2,x:en(v,g)})}else(y!==1||g!==1)&&w.push(u(w)+"scale("+y+","+g+")")}return function(m,v){var y=[],g=[];return m=n(m),v=n(v),c(m.translateX,m.translateY,v.translateX,v.translateY,y,g),f(m.rotate,v.rotate,y,g),h(m.skewX,v.skewX,y,g),p(m.scaleX,m.scaleY,v.scaleX,v.scaleY,y,g),m=v=null,function(w){for(var S=-1,M=g.length,N;++S=0&&n._call.call(void 0,r),n=n._next;--to}function eh(){gr=(nl=si.now())+fl,to=Jo=0;try{Yv()}finally{to=0,bv(),gr=0}}function Xv(){var n=si.now(),r=n-nl;r>Sp&&(fl-=r,nl=n)}function bv(){for(var n,r=tl,i,l=1/0;r;)r._call?(l>r._time&&(l=r._time),n=r,r=r._next):(i=r._next,r._next=null,r=n?n._next=i:tl=i);ei=n,$a(l)}function $a(n){if(!to){Jo&&(Jo=clearTimeout(Jo));var r=n-gr;r>24?(n<1/0&&(Jo=setTimeout(eh,n-si.now()-fl)),qo&&(qo=clearInterval(qo))):(qo||(nl=si.now(),qo=setInterval(Xv,Sp)),to=1,_p(eh))}}function th(n,r,i){var l=new rl;return r=r==null?0:+r,l.restart(u=>{l.stop(),n(u+r)},r,i),l}var Qv=al("start","end","cancel","interrupt"),Gv=[],kp=0,nh=1,Da=2,Qs=3,rh=4,Oa=5,Gs=6;function dl(n,r,i,l,u,c){var f=n.__transition;if(!f)n.__transition={};else if(i in f)return;Kv(n,i,{name:r,index:l,group:u,on:Qv,tween:Gv,time:c.time,delay:c.delay,duration:c.duration,ease:c.ease,timer:null,state:kp})}function Ka(n,r){var i=Yt(n,r);if(i.state>kp)throw new Error("too late; already scheduled");return i}function nn(n,r){var i=Yt(n,r);if(i.state>Qs)throw new Error("too late; already running");return i}function Yt(n,r){var i=n.__transition;if(!i||!(i=i[r]))throw new Error("transition not found");return i}function Kv(n,r,i){var l=n.__transition,u;l[r]=i,i.timer=Ep(c,0,i.time);function c(m){i.state=nh,i.timer.restart(f,i.delay,i.time),i.delay<=m&&f(m-i.delay)}function f(m){var v,y,g,w;if(i.state!==nh)return p();for(v in l)if(w=l[v],w.name===i.name){if(w.state===Qs)return th(f);w.state===rh?(w.state=Gs,w.timer.stop(),w.on.call("interrupt",n,n.__data__,w.index,w.group),delete l[v]):+vDa&&l.state=0&&(r=r.slice(0,i)),!r||r==="start"})}function Cx(n,r,i){var l,u,c=Nx(r)?Ka:nn;return function(){var f=c(this,n),h=f.on;h!==l&&(u=(l=h).copy()).on(r,i),f.on=u}}function Mx(n,r){var i=this._id;return arguments.length<2?Yt(this.node(),i).on.on(n):this.each(Cx(i,n,r))}function Px(n){return function(){var r=this.parentNode;for(var i in this.__transition)if(+i!==n)return;r&&r.removeChild(this)}}function Ix(){return this.on("end.remove",Px(this._id))}function zx(n){var r=this._name,i=this._id;typeof n!="function"&&(n=Ya(n));for(var l=this._groups,u=l.length,c=new Array(u),f=0;f()=>n;function tw(n,{sourceEvent:r,target:i,transform:l,dispatch:u}){Object.defineProperties(this,{type:{value:n,enumerable:!0,configurable:!0},sourceEvent:{value:r,enumerable:!0,configurable:!0},target:{value:i,enumerable:!0,configurable:!0},transform:{value:l,enumerable:!0,configurable:!0},_:{value:u}})}function mn(n,r,i){this.k=n,this.x=r,this.y=i}mn.prototype={constructor:mn,scale:function(n){return n===1?this:new mn(this.k*n,this.x,this.y)},translate:function(n,r){return n===0&r===0?this:new mn(this.k,this.x+this.k*n,this.y+this.k*r)},apply:function(n){return[n[0]*this.k+this.x,n[1]*this.k+this.y]},applyX:function(n){return n*this.k+this.x},applyY:function(n){return n*this.k+this.y},invert:function(n){return[(n[0]-this.x)/this.k,(n[1]-this.y)/this.k]},invertX:function(n){return(n-this.x)/this.k},invertY:function(n){return(n-this.y)/this.k},rescaleX:function(n){return n.copy().domain(n.range().map(this.invertX,this).map(n.invert,n))},rescaleY:function(n){return n.copy().domain(n.range().map(this.invertY,this).map(n.invert,n))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var hl=new mn(1,0,0);Pp.prototype=mn.prototype;function Pp(n){for(;!n.__zoom;)if(!(n=n.parentNode))return hl;return n.__zoom}function Sa(n){n.stopImmediatePropagation()}function Zo(n){n.preventDefault(),n.stopImmediatePropagation()}function nw(n){return(!n.ctrlKey||n.type==="wheel")&&!n.button}function rw(){var n=this;return n instanceof SVGElement?(n=n.ownerSVGElement||n,n.hasAttribute("viewBox")?(n=n.viewBox.baseVal,[[n.x,n.y],[n.x+n.width,n.y+n.height]]):[[0,0],[n.width.baseVal.value,n.height.baseVal.value]]):[[0,0],[n.clientWidth,n.clientHeight]]}function oh(){return this.__zoom||hl}function ow(n){return-n.deltaY*(n.deltaMode===1?.05:n.deltaMode?1:.002)*(n.ctrlKey?10:1)}function iw(){return navigator.maxTouchPoints||"ontouchstart"in this}function sw(n,r,i){var l=n.invertX(r[0][0])-i[0][0],u=n.invertX(r[1][0])-i[1][0],c=n.invertY(r[0][1])-i[0][1],f=n.invertY(r[1][1])-i[1][1];return n.translate(u>l?(l+u)/2:Math.min(0,l)||Math.max(0,u),f>c?(c+f)/2:Math.min(0,c)||Math.max(0,f))}function Ip(){var n=nw,r=rw,i=sw,l=ow,u=iw,c=[0,1/0],f=[[-1/0,-1/0],[1/0,1/0]],h=250,p=bs,m=al("start","zoom","end"),v,y,g,w=500,S=150,M=0,N=10;function E(k){k.property("__zoom",oh).on("wheel.zoom",X,{passive:!1}).on("mousedown.zoom",b).on("dblclick.zoom",ee).filter(u).on("touchstart.zoom",q).on("touchmove.zoom",J).on("touchend.zoom touchcancel.zoom",Z).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}E.transform=function(k,B,z,H){var j=k.selection?k.selection():k;j.property("__zoom",oh),k!==j?U(k,B,z,H):j.interrupt().each(function(){D(this,arguments).event(H).start().zoom(null,typeof B=="function"?B.apply(this,arguments):B).end()})},E.scaleBy=function(k,B,z,H){E.scaleTo(k,function(){var j=this.__zoom.k,$=typeof B=="function"?B.apply(this,arguments):B;return j*$},z,H)},E.scaleTo=function(k,B,z,H){E.transform(k,function(){var j=r.apply(this,arguments),$=this.__zoom,F=z==null?P(j):typeof z=="function"?z.apply(this,arguments):z,C=$.invert(F),R=typeof B=="function"?B.apply(this,arguments):B;return i(_(L($,R),F,C),j,f)},z,H)},E.translateBy=function(k,B,z,H){E.transform(k,function(){return i(this.__zoom.translate(typeof B=="function"?B.apply(this,arguments):B,typeof z=="function"?z.apply(this,arguments):z),r.apply(this,arguments),f)},null,H)},E.translateTo=function(k,B,z,H,j){E.transform(k,function(){var $=r.apply(this,arguments),F=this.__zoom,C=H==null?P($):typeof H=="function"?H.apply(this,arguments):H;return i(hl.translate(C[0],C[1]).scale(F.k).translate(typeof B=="function"?-B.apply(this,arguments):-B,typeof z=="function"?-z.apply(this,arguments):-z),$,f)},H,j)};function L(k,B){return B=Math.max(c[0],Math.min(c[1],B)),B===k.k?k:new mn(B,k.x,k.y)}function _(k,B,z){var H=B[0]-z[0]*k.k,j=B[1]-z[1]*k.k;return H===k.x&&j===k.y?k:new mn(k.k,H,j)}function P(k){return[(+k[0][0]+ +k[1][0])/2,(+k[0][1]+ +k[1][1])/2]}function U(k,B,z,H){k.on("start.zoom",function(){D(this,arguments).event(H).start()}).on("interrupt.zoom end.zoom",function(){D(this,arguments).event(H).end()}).tween("zoom",function(){var j=this,$=arguments,F=D(j,$).event(H),C=r.apply(j,$),R=z==null?P(C):typeof z=="function"?z.apply(j,$):z,te=Math.max(C[1][0]-C[0][0],C[1][1]-C[0][1]),re=j.__zoom,ue=typeof B=="function"?B.apply(j,$):B,ce=p(re.invert(R).concat(te/re.k),ue.invert(R).concat(te/ue.k));return function(ae){if(ae===1)ae=ue;else{var G=ce(ae),se=te/G[2];ae=new mn(se,R[0]-G[0]*se,R[1]-G[1]*se)}F.zoom(null,ae)}})}function D(k,B,z){return!z&&k.__zooming||new V(k,B)}function V(k,B){this.that=k,this.args=B,this.active=0,this.sourceEvent=null,this.extent=r.apply(k,B),this.taps=0}V.prototype={event:function(k){return k&&(this.sourceEvent=k),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(k,B){return this.mouse&&k!=="mouse"&&(this.mouse[1]=B.invert(this.mouse[0])),this.touch0&&k!=="touch"&&(this.touch0[1]=B.invert(this.touch0[0])),this.touch1&&k!=="touch"&&(this.touch1[1]=B.invert(this.touch1[0])),this.that.__zoom=B,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(k){var B=kt(this.that).datum();m.call(k,this.that,new tw(k,{sourceEvent:this.sourceEvent,target:E,transform:this.that.__zoom,dispatch:m}),B)}};function X(k,...B){if(!n.apply(this,arguments))return;var z=D(this,B).event(k),H=this.__zoom,j=Math.max(c[0],Math.min(c[1],H.k*Math.pow(2,l.apply(this,arguments)))),$=Ht(k);if(z.wheel)(z.mouse[0][0]!==$[0]||z.mouse[0][1]!==$[1])&&(z.mouse[1]=H.invert(z.mouse[0]=$)),clearTimeout(z.wheel);else{if(H.k===j)return;z.mouse=[$,H.invert($)],Ks(this),z.start()}Zo(k),z.wheel=setTimeout(F,S),z.zoom("mouse",i(_(L(H,j),z.mouse[0],z.mouse[1]),z.extent,f));function F(){z.wheel=null,z.end()}}function b(k,...B){if(g||!n.apply(this,arguments))return;var z=k.currentTarget,H=D(this,B,!0).event(k),j=kt(k.view).on("mousemove.zoom",R,!0).on("mouseup.zoom",te,!0),$=Ht(k,z),F=k.clientX,C=k.clientY;dp(k.view),Sa(k),H.mouse=[$,this.__zoom.invert($)],Ks(this),H.start();function R(re){if(Zo(re),!H.moved){var ue=re.clientX-F,ce=re.clientY-C;H.moved=ue*ue+ce*ce>M}H.event(re).zoom("mouse",i(_(H.that.__zoom,H.mouse[0]=Ht(re,z),H.mouse[1]),H.extent,f))}function te(re){j.on("mousemove.zoom mouseup.zoom",null),hp(re.view,H.moved),Zo(re),H.event(re).end()}}function ee(k,...B){if(n.apply(this,arguments)){var z=this.__zoom,H=Ht(k.changedTouches?k.changedTouches[0]:k,this),j=z.invert(H),$=z.k*(k.shiftKey?.5:2),F=i(_(L(z,$),H,j),r.apply(this,B),f);Zo(k),h>0?kt(this).transition().duration(h).call(U,F,H,k):kt(this).call(E.transform,F,H,k)}}function q(k,...B){if(n.apply(this,arguments)){var z=k.touches,H=z.length,j=D(this,B,k.changedTouches.length===H).event(k),$,F,C,R;for(Sa(k),F=0;F`Seems like you have not used ${n==="svelte"?"SvelteFlowProvider":"ReactFlowProvider"} as an ancestor. Help: https://${n}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:n=>`Node type "${n}" 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:n=>`The old edge with id=${n} does not exist.`,error009:n=>`Marker type "${n}" doesn't exist.`,error008:(n,{id:r,sourceHandle:i,targetHandle:l})=>`Couldn't create edge for ${n} handle id: "${n==="source"?i:l}", edge id: ${r}.`,error010:()=>"Handle: No node id found. Make sure to only use a Handle inside a custom Node.",error011:n=>`Edge type "${n}" not found. Using fallback type "default".`,error012:n=>`Node with id "${n}" does not exist, it may have been removed. This can happen when a node is deleted before the "onNodeClick" handler is called.`,error013:(n="react")=>`It seems that you haven't loaded the styles. Please import '@xyflow/${n}/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:n=>`Edge with id "${n}" does not exist, it may have been removed. This can happen when an edge is deleted before the "onEdgeClick" handler is called.`},li=[[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]],zp=["Enter"," ","Escape"],Tp={"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:n,x:r,y:i})=>`Moved selected node ${n}. New position, x: ${r}, y: ${i}`,"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 no;(function(n){n.Strict="strict",n.Loose="loose"})(no||(no={}));var hr;(function(n){n.Free="free",n.Vertical="vertical",n.Horizontal="horizontal"})(hr||(hr={}));var ui;(function(n){n.Partial="partial",n.Full="full"})(ui||(ui={}));const Lp={inProgress:!1,isValid:null,from:null,fromHandle:null,fromPosition:null,fromNode:null,to:null,toHandle:null,toPosition:null,toNode:null,pointer:null};var Un;(function(n){n.Bezier="default",n.Straight="straight",n.Step="step",n.SmoothStep="smoothstep",n.SimpleBezier="simplebezier"})(Un||(Un={}));var ol;(function(n){n.Arrow="arrow",n.ArrowClosed="arrowclosed"})(ol||(ol={}));var xe;(function(n){n.Left="left",n.Top="top",n.Right="right",n.Bottom="bottom"})(xe||(xe={}));const ih={[xe.Left]:xe.Right,[xe.Right]:xe.Left,[xe.Top]:xe.Bottom,[xe.Bottom]:xe.Top};function Rp(n){return n===null?null:n?"valid":"invalid"}const Ap=n=>!!n&&typeof n=="object"&&"id"in n&&"source"in n&&"target"in n,lw=n=>!!n&&typeof n=="object"&&"id"in n&&"position"in n&&!("source"in n)&&!("target"in n),Za=n=>!!n&&typeof n=="object"&&"id"in n&&"internals"in n&&!("source"in n)&&!("target"in n),gi=(n,r=[0,0])=>{const{width:i,height:l}=Xt(n),u=n.origin??r,c=i*u[0],f=l*u[1];return{x:n.position.x-c,y:n.position.y-f}},uw=(n,r={nodeOrigin:[0,0]})=>{if(n.length===0)return{x:0,y:0,width:0,height:0};let i=!1;const l=n.reduce((u,c)=>{const f=typeof c=="string";let h=!r.nodeLookup&&!f?c:void 0;return r.nodeLookup&&(h=f?r.nodeLookup.get(c):Za(c)?c:r.nodeLookup.get(c.id)),h?(i=!0,pl(u,il(h,r.nodeOrigin))):u},{x:1/0,y:1/0,x2:-1/0,y2:-1/0});return i?gl(l):{x:0,y:0,width:0,height:0}},mi=(n,r={})=>{let i={x:1/0,y:1/0,x2:-1/0,y2:-1/0},l=!1;return n.forEach(u=>{(r.filter===void 0||r.filter(u))&&(i=pl(i,il(u)),l=!0)}),l?gl(i):{x:0,y:0,width:0,height:0}},Ja=(n,r,[i,l,u]=[0,0,1],c=!1,f=!1)=>{const h=(r.x-i)/u,p=(r.y-l)/u,m=r.width/u,v=r.height/u,y=[];for(const g of n.values()){const{measured:w,selectable:S=!0,hidden:M=!1}=g;if(f&&!S||M)continue;const N=w.width??g.width??g.initialWidth??0,E=w.height??g.height??g.initialHeight??0,{x:L,y:_}=g.internals.positionAbsolute,P=Op(h,p,m,v,L,_,N,E),U=N*E,D=c&&P>0;(!g.internals.handleBounds||D||P>=U||g.dragging)&&y.push(g)}return y},aw=(n,r)=>{const i=new Set;return n.forEach(l=>{i.add(l.id)}),r.filter(l=>i.has(l.source)||i.has(l.target))};function cw(n,r){const i=new Map,l=r!=null&&r.nodes?new Set(r.nodes.map(u=>u.id)):null;return n.forEach(u=>{let c;if(r!=null&&r.includeHiddenNodes){const{width:f,height:h}=Xt(u);c=f>0&&h>0}else c=!!(u.measured.width&&u.measured.height&&!u.hidden);c&&(!l||l.has(u.id))&&i.set(u.id,u)}),i}async function fw({nodes:n,width:r,height:i,panZoom:l,minZoom:u,maxZoom:c},f){if(n.size===0)return!0;const h=cw(n,f),p=mi(h),m=tc(p,r,i,(f==null?void 0:f.minZoom)??u,(f==null?void 0:f.maxZoom)??c,(f==null?void 0:f.padding)??.1);return await l.setViewport(m,{duration:f==null?void 0:f.duration,ease:f==null?void 0:f.ease,interpolate:f==null?void 0:f.interpolate}),!0}function jp({nodeId:n,nextPosition:r,nodeLookup:i,nodeOrigin:l=[0,0],nodeExtent:u,onError:c}){const f=i.get(n),h=f.parentId?i.get(f.parentId):void 0,{x:p,y:m}=h?h.internals.positionAbsolute:{x:0,y:0},v=f.origin??l;let y=f.extent||u;if(f.extent==="parent"&&!f.expandParent)if(!h)c==null||c("005",Wt.error005());else{const{width:w,height:S}=Xt(h);w&&S&&(y=[[p,m],[p+w,m+S]])}else h&&yr(f.extent)&&(y=[[f.extent[0][0]+p,f.extent[0][1]+m],[f.extent[1][0]+p,f.extent[1][1]+m]]);const g=yr(y)?mr(r,y,f.measured):r;return(f.measured.width===void 0||f.measured.height===void 0)&&(c==null||c("015",Wt.error015())),{position:{x:g.x-p+(f.measured.width??0)*v[0],y:g.y-m+(f.measured.height??0)*v[1]},positionAbsolute:g}}async function dw({nodesToRemove:n=[],edgesToRemove:r=[],nodes:i,edges:l,onBeforeDelete:u}){const c=new Set(n.map(g=>g.id)),f=[];for(const g of i){if(g.deletable===!1)continue;const w=c.has(g.id),S=!w&&g.parentId&&f.find(M=>M.id===g.parentId);(w||S)&&f.push(g)}const h=new Set(r.map(g=>g.id)),p=l.filter(g=>g.deletable!==!1),v=aw(f,p);for(const g of p)h.has(g.id)&&!v.find(S=>S.id===g.id)&&v.push(g);if(!u)return{edges:v,nodes:f};const y=await u({nodes:f,edges:v});return typeof y=="boolean"?y?{edges:v,nodes:f}:{edges:[],nodes:[]}:y}const ro=(n,r=0,i=1)=>Math.min(Math.max(n,r),i),mr=(n={x:0,y:0},r,i)=>({x:ro(n.x,r[0][0],r[1][0]-((i==null?void 0:i.width)??0)),y:ro(n.y,r[0][1],r[1][1]-((i==null?void 0:i.height)??0))});function $p(n,r,i){const{width:l,height:u}=Xt(i),{x:c,y:f}=i.internals.positionAbsolute;return mr(n,[[c,f],[c+l,f+u]],r)}const sh=(n,r,i)=>ni?-ro(Math.abs(n-i),1,r)/r:0,ec=(n,r,i=15,l=40)=>{const u=sh(n.x,l,r.width-l)*i,c=sh(n.y,l,r.height-l)*i;return[u,c]},pl=(n,r)=>({x:Math.min(n.x,r.x),y:Math.min(n.y,r.y),x2:Math.max(n.x2,r.x2),y2:Math.max(n.y2,r.y2)}),Fa=({x:n,y:r,width:i,height:l})=>({x:n,y:r,x2:n+i,y2:r+l}),gl=({x:n,y:r,x2:i,y2:l})=>({x:n,y:r,width:i-n,height:l-r}),ai=(n,r=[0,0])=>{var u,c;const{x:i,y:l}=Za(n)?n.internals.positionAbsolute:gi(n,r);return{x:i,y:l,width:((u=n.measured)==null?void 0:u.width)??n.width??n.initialWidth??0,height:((c=n.measured)==null?void 0:c.height)??n.height??n.initialHeight??0}},il=(n,r=[0,0])=>{var u,c;const{x:i,y:l}=Za(n)?n.internals.positionAbsolute:gi(n,r);return{x:i,y:l,x2:i+(((u=n.measured)==null?void 0:u.width)??n.width??n.initialWidth??0),y2:l+(((c=n.measured)==null?void 0:c.height)??n.height??n.initialHeight??0)}},Dp=(n,r)=>gl(pl(Fa(n),Fa(r))),Op=(n,r,i,l,u,c,f,h)=>{const p=Math.max(0,Math.min(n+i,u+f)-Math.max(n,u)),m=Math.max(0,Math.min(r+l,c+h)-Math.max(r,c));return Math.ceil(p*m)},sl=(n,r)=>Op(n.x,n.y,n.width,n.height,r.x,r.y,r.width,r.height),lh=n=>Bt(n.width)&&Bt(n.height)&&Bt(n.x)&&Bt(n.y),Bt=n=>!isNaN(n)&&isFinite(n),Fp=(n,r)=>(i,l)=>{},yi=(n,r=[1,1])=>({x:r[0]*Math.round(n.x/r[0]),y:r[1]*Math.round(n.y/r[1])}),vi=({x:n,y:r},[i,l,u],c=!1,f=[1,1])=>{const h={x:(n-i)/u,y:(r-l)/u};return c?yi(h,f):h},oo=({x:n,y:r},[i,l,u])=>({x:n*u+i,y:r*u+l});function Kr(n,r){if(typeof n=="number")return Math.floor((r-r/(1+n))*.5);if(typeof n=="string"&&n.endsWith("px")){const i=parseFloat(n);if(!Number.isNaN(i))return Math.floor(i)}if(typeof n=="string"&&n.endsWith("%")){const i=parseFloat(n);if(!Number.isNaN(i))return Math.floor(r*i*.01)}return console.error(`The padding value "${n}" is invalid. Please provide a number or a string with a valid unit (px or %).`),0}function hw(n,r,i){if(typeof n=="string"||typeof n=="number"){const l=Kr(n,i),u=Kr(n,r);return{top:l,right:u,bottom:l,left:u,x:u*2,y:l*2}}if(typeof n=="object"){const l=Kr(n.top??n.y??0,i),u=Kr(n.bottom??n.y??0,i),c=Kr(n.left??n.x??0,r),f=Kr(n.right??n.x??0,r);return{top:l,right:f,bottom:u,left:c,x:c+f,y:l+u}}return{top:0,right:0,bottom:0,left:0,x:0,y:0}}function pw(n,r,i,l,u,c){const{x:f,y:h}=oo(n,[r,i,l]),{x:p,y:m}=oo({x:n.x+n.width,y:n.y+n.height},[r,i,l]),v=u-p,y=c-m;return{left:Math.floor(f),top:Math.floor(h),right:Math.floor(v),bottom:Math.floor(y)}}const tc=(n,r,i,l,u,c)=>{const f=hw(c,r,i),h=(r-f.x)/n.width,p=(i-f.y)/n.height,m=Math.min(h,p),v=ro(m,l,u),y=n.x+n.width/2,g=n.y+n.height/2,w=r/2-y*v,S=i/2-g*v,M=pw(n,w,S,v,r,i),N={left:Math.min(M.left-f.left,0),top:Math.min(M.top-f.top,0),right:Math.min(M.right-f.right,0),bottom:Math.min(M.bottom-f.bottom,0)};return{x:w-N.left+N.right,y:S-N.top+N.bottom,zoom:v}},ci=()=>{var n;return typeof navigator<"u"&&((n=navigator==null?void 0:navigator.userAgent)==null?void 0:n.indexOf("Mac"))>=0};function yr(n){return n!=null&&n!=="parent"}function Xt(n){var r,i;return{width:((r=n.measured)==null?void 0:r.width)??n.width??n.initialWidth??0,height:((i=n.measured)==null?void 0:i.height)??n.height??n.initialHeight??0}}function Hp(n){var r,i;return(((r=n.measured)==null?void 0:r.width)??n.width??n.initialWidth)!==void 0&&(((i=n.measured)==null?void 0:i.height)??n.height??n.initialHeight)!==void 0}function Vp(n,r={width:0,height:0},i,l,u){const c={...n},f=l.get(i);if(f){const h=f.origin||u;c.x+=f.internals.positionAbsolute.x-(r.width??0)*h[0],c.y+=f.internals.positionAbsolute.y-(r.height??0)*h[1]}return c}function uh(n,r){if(n.size!==r.size)return!1;for(const i of n)if(!r.has(i))return!1;return!0}function gw(){let n,r;return{promise:new Promise((l,u)=>{n=l,r=u}),resolve:n,reject:r}}function mw(n){return{...Tp,...n||{}}}function ni(n,{snapGrid:r=[0,0],snapToGrid:i=!1,transform:l,containerBounds:u}){const{x:c,y:f}=Ut(n),h=vi({x:c-((u==null?void 0:u.left)??0),y:f-((u==null?void 0:u.top)??0)},l),{x:p,y:m}=i?yi(h,r):h;return{xSnapped:p,ySnapped:m,...h}}const nc=n=>({width:n.offsetWidth,height:n.offsetHeight}),Bp=n=>{var r;return((r=n==null?void 0:n.getRootNode)==null?void 0:r.call(n))||(window==null?void 0:window.document)},yw=["INPUT","SELECT","TEXTAREA"];function Up(n){var l,u;const r=((u=(l=n.composedPath)==null?void 0:l.call(n))==null?void 0:u[0])||n.target;return(r==null?void 0:r.nodeType)!==1?!1:yw.includes(r.nodeName)||r.hasAttribute("contenteditable")||!!r.closest(".nokey")}const Wp=n=>"clientX"in n,Ut=(n,r)=>{var c,f;const i=Wp(n),l=i?n.clientX:(c=n.touches)==null?void 0:c[0].clientX,u=i?n.clientY:(f=n.touches)==null?void 0:f[0].clientY;return{x:l-((r==null?void 0:r.left)??0),y:u-((r==null?void 0:r.top)??0)}},ah=(n,r,i,l,u)=>{const c=r.querySelectorAll(`.${n}`);return!c||!c.length?null:Array.from(c).map(f=>{const h=f.getBoundingClientRect();return{id:f.getAttribute("data-handleid"),type:n,nodeId:u,position:f.getAttribute("data-handlepos"),x:(h.left-i.left)/l,y:(h.top-i.top)/l,...nc(f)}})};function Yp({sourceX:n,sourceY:r,targetX:i,targetY:l,sourceControlX:u,sourceControlY:c,targetControlX:f,targetControlY:h}){const p=n*.125+u*.375+f*.375+i*.125,m=r*.125+c*.375+h*.375+l*.125,v=Math.abs(p-n),y=Math.abs(m-r);return[p,m,v,y]}function Bs(n,r){return n>=0?.5*n:r*25*Math.sqrt(-n)}function ch({pos:n,x1:r,y1:i,x2:l,y2:u,c}){switch(n){case xe.Left:return[r-Bs(r-l,c),i];case xe.Right:return[r+Bs(l-r,c),i];case xe.Top:return[r,i-Bs(i-u,c)];case xe.Bottom:return[r,i+Bs(u-i,c)]}}function Xp({sourceX:n,sourceY:r,sourcePosition:i=xe.Bottom,targetX:l,targetY:u,targetPosition:c=xe.Top,curvature:f=.25}){const[h,p]=ch({pos:i,x1:n,y1:r,x2:l,y2:u,c:f}),[m,v]=ch({pos:c,x1:l,y1:u,x2:n,y2:r,c:f}),[y,g,w,S]=Yp({sourceX:n,sourceY:r,targetX:l,targetY:u,sourceControlX:h,sourceControlY:p,targetControlX:m,targetControlY:v});return[`M${n},${r} C${h},${p} ${m},${v} ${l},${u}`,y,g,w,S]}function bp({sourceX:n,sourceY:r,targetX:i,targetY:l}){const u=Math.abs(i-n)/2,c=i0}const ww=({source:n,sourceHandle:r,target:i,targetHandle:l})=>`xy-edge__${n}${r||""}-${i}${l||""}`,Sw=(n,r)=>r.some(i=>i.source===n.source&&i.target===n.target&&(i.sourceHandle===n.sourceHandle||!i.sourceHandle&&!n.sourceHandle)&&(i.targetHandle===n.targetHandle||!i.targetHandle&&!n.targetHandle)),_w=(n,r,i={})=>{var c;if(!n.source||!n.target)return(c=i.onError)==null||c.call(i,"006",Wt.error006()),r;const l=i.getEdgeId||ww;let u;return Ap(n)?u={...n}:u={...n,id:l(n)},Sw(u,r)?r:(u.sourceHandle===null&&delete u.sourceHandle,u.targetHandle===null&&delete u.targetHandle,r.concat(u))};function Qp({sourceX:n,sourceY:r,targetX:i,targetY:l}){const[u,c,f,h]=bp({sourceX:n,sourceY:r,targetX:i,targetY:l});return[`M ${n},${r}L ${i},${l}`,u,c,f,h]}const fh={[xe.Left]:{x:-1,y:0},[xe.Right]:{x:1,y:0},[xe.Top]:{x:0,y:-1},[xe.Bottom]:{x:0,y:1}},Ew=({source:n,sourcePosition:r=xe.Bottom,target:i})=>r===xe.Left||r===xe.Right?n.xMath.sqrt(Math.pow(r.x-n.x,2)+Math.pow(r.y-n.y,2));function kw({source:n,sourcePosition:r=xe.Bottom,target:i,targetPosition:l=xe.Top,center:u,offset:c,stepPosition:f}){const h=fh[r],p=fh[l],m={x:n.x+h.x*c,y:n.y+h.y*c},v={x:i.x+p.x*c,y:i.y+p.y*c},y=Ew({source:m,sourcePosition:r,target:v}),g=y.x!==0?"x":"y",w=y[g];let S=[],M,N;const E={x:0,y:0},L={x:0,y:0},[,,_,P]=bp({sourceX:n.x,sourceY:n.y,targetX:i.x,targetY:i.y});if(h[g]*p[g]===-1){g==="x"?(M=u.x??m.x+(v.x-m.x)*f,N=u.y??(m.y+v.y)/2):(M=u.x??(m.x+v.x)/2,N=u.y??m.y+(v.y-m.y)*f);const X=[{x:M,y:m.y},{x:M,y:v.y}],b=[{x:m.x,y:N},{x:v.x,y:N}];h[g]===w?S=g==="x"?X:b:S=g==="x"?b:X}else{const X=[{x:m.x,y:v.y}],b=[{x:v.x,y:m.y}];if(g==="x"?S=h.x===w?b:X:S=h.y===w?X:b,r===l){const k=Math.abs(n[g]-i[g]);if(k<=c){const B=Math.min(c-1,c-k);h[g]===w?E[g]=(m[g]>n[g]?-1:1)*B:L[g]=(v[g]>i[g]?-1:1)*B}}if(r!==l){const k=g==="x"?"y":"x",B=h[g]===p[k],z=m[k]>v[k],H=m[k]=Z?(M=(ee.x+q.x)/2,N=S[0].y):(M=S[0].x,N=(ee.y+q.y)/2)}const U={x:m.x+E.x,y:m.y+E.y},D={x:v.x+L.x,y:v.y+L.y};return[[n,...U.x!==S[0].x||U.y!==S[0].y?[U]:[],...S,...D.x!==S[S.length-1].x||D.y!==S[S.length-1].y?[D]:[],i],M,N,_,P]}function Nw(n,r,i,l){const u=Math.min(dh(n,r)/2,dh(r,i)/2,l),{x:c,y:f}=r;if(n.x===c&&c===i.x||n.y===f&&f===i.y)return`L${c} ${f}`;if(n.y===f){const m=n.xi.id===r):n[0])||null}function Va(n,r){return n?typeof n=="string"?n:`${r?`${r}__`:""}${Object.keys(n).sort().map(l=>`${l}=${n[l]}`).join("&")}`:""}function Mw(n,{id:r,defaultColor:i,defaultMarkerStart:l,defaultMarkerEnd:u}){const c=new Set;return n.reduce((f,h)=>([h.markerStart||l,h.markerEnd||u].forEach(p=>{if(p&&typeof p=="object"){const m=Va(p,r);c.has(m)||(f.push({id:m,color:p.color||i,...p}),c.add(m))}}),f),[]).sort((f,h)=>f.id.localeCompare(h.id))}const Gp=1e3,Pw=10,rc={nodeOrigin:[0,0],nodeExtent:li,elevateNodesOnSelect:!0,zIndexMode:"basic",defaults:{}},Iw={...rc,checkEquality:!0};function oc(n,r){const i={...n};for(const l in r)r[l]!==void 0&&(i[l]=r[l]);return i}function zw(n,r,i){const l=oc(rc,i);for(const u of n.values())if(u.parentId)sc(u,n,r,l);else{const c=gi(u,l.nodeOrigin),f=yr(u.extent)?u.extent:l.nodeExtent,h=mr(c,f,Xt(u));u.internals.positionAbsolute=h}}function Tw(n,r){if(!n.handles)return n.measured?r==null?void 0:r.internals.handleBounds:void 0;const i=[],l=[];for(const u of n.handles){const c={id:u.id,width:u.width??1,height:u.height??1,nodeId:n.id,x:u.x,y:u.y,position:u.position,type:u.type};u.type==="source"?i.push(c):u.type==="target"&&l.push(c)}return{source:i,target:l}}function ic(n){return n==="manual"}function Ba(n,r,i,l={}){var v,y;const u=oc(Iw,l),c={i:0},f=new Map(r),h=u!=null&&u.elevateNodesOnSelect&&!ic(u.zIndexMode)?Gp:0;let p=n.length>0,m=!1;r.clear(),i.clear();for(const g of n){let w=f.get(g.id);if(u.checkEquality&&g===(w==null?void 0:w.internals.userNode))r.set(g.id,w);else{const S=gi(g,u.nodeOrigin),M=yr(g.extent)?g.extent:u.nodeExtent,N=mr(S,M,Xt(g));w={...u.defaults,...g,measured:{width:(v=g.measured)==null?void 0:v.width,height:(y=g.measured)==null?void 0:y.height},internals:{positionAbsolute:N,handleBounds:Tw(g,w),z:Kp(g,h,u.zIndexMode),userNode:g}},r.set(g.id,w)}(w.measured===void 0||w.measured.width===void 0||w.measured.height===void 0)&&!w.hidden&&(p=!1),g.parentId&&sc(w,r,i,l,c),m||(m=g.selected??!1)}return{nodesInitialized:p,hasSelectedNodes:m}}function Lw(n,r){if(!n.parentId)return;const i=r.get(n.parentId);i?i.set(n.id,n):r.set(n.parentId,new Map([[n.id,n]]))}function sc(n,r,i,l,u){const{elevateNodesOnSelect:c,nodeOrigin:f,nodeExtent:h,zIndexMode:p}=oc(rc,l),m=n.parentId,v=r.get(m);if(!v){console.warn(`Parent node ${m} not found. Please make sure that parent nodes are in front of their child nodes in the nodes array.`);return}Lw(n,i),u&&!v.parentId&&v.internals.rootParentIndex===void 0&&p==="auto"&&(v.internals.rootParentIndex=++u.i,v.internals.z=v.internals.z+u.i*Pw),u&&v.internals.rootParentIndex!==void 0&&(u.i=v.internals.rootParentIndex);const y=c&&!ic(p)?Gp:0,{x:g,y:w,z:S}=Rw(n,v,f,h,y,p),{positionAbsolute:M}=n.internals,N=g!==M.x||w!==M.y;(N||S!==n.internals.z)&&r.set(n.id,{...n,internals:{...n.internals,positionAbsolute:N?{x:g,y:w}:M,z:S}})}function Kp(n,r,i){const l=Bt(n.zIndex)?n.zIndex:0;return ic(i)?l:l+(n.selected?r:0)}function Rw(n,r,i,l,u,c){const{x:f,y:h}=r.internals.positionAbsolute,p=Xt(n),m=gi(n,i),v=yr(n.extent)?mr(m,n.extent,p):m;let y=mr({x:f+v.x,y:h+v.y},l,p);n.extent==="parent"&&(y=$p(y,p,r));const g=Kp(n,u,c),w=r.internals.z??0;return{x:y.x,y:y.y,z:w>=g?w+1:g}}function lc(n,r,i,l=[0,0]){var f;const u=[],c=new Map;for(const h of n){const p=r.get(h.parentId);if(!p)continue;const m=((f=c.get(h.parentId))==null?void 0:f.expandedRect)??ai(p),v=Dp(m,h.rect);c.set(h.parentId,{expandedRect:v,parent:p})}return c.size>0&&c.forEach(({expandedRect:h,parent:p},m)=>{var _;const v=p.internals.positionAbsolute,y=Xt(p),g=p.origin??l,w=h.x0||S>0||E||L)&&(u.push({id:m,type:"position",position:{x:p.position.x-w+E,y:p.position.y-S+L}}),(_=i.get(m))==null||_.forEach(P=>{n.some(U=>U.id===P.id)||u.push({id:P.id,type:"position",position:{x:P.position.x+w,y:P.position.y+S}})})),(y.width0){const w=lc(g,r,i,u);m.push(...w)}return{changes:m,updatedInternals:p}}async function jw({delta:n,panZoom:r,transform:i,translateExtent:l,width:u,height:c}){if(!r||!n.x&&!n.y)return!1;const f=await r.setViewportConstrained({x:i[0]+n.x,y:i[1]+n.y,zoom:i[2]},[[0,0],[u,c]],l);return!!f&&(f.x!==i[0]||f.y!==i[1]||f.k!==i[2])}function mh(n,r,i,l,u,c){let f=u;const h=l.get(f)||new Map;l.set(f,h.set(i,r)),f=`${u}-${n}`;const p=l.get(f)||new Map;if(l.set(f,p.set(i,r)),c){f=`${u}-${n}-${c}`;const m=l.get(f)||new Map;l.set(f,m.set(i,r))}}function qp(n,r,i){n.clear(),r.clear();for(const l of i){const{source:u,target:c,sourceHandle:f=null,targetHandle:h=null}=l,p={edgeId:l.id,source:u,target:c,sourceHandle:f,targetHandle:h},m=`${u}-${f}--${c}-${h}`,v=`${c}-${h}--${u}-${f}`;mh("source",p,v,n,u,f),mh("target",p,m,n,c,h),r.set(l.id,l)}}function Zp(n,r){if(!n.parentId)return!1;const i=r.get(n.parentId);return i?i.selected?!0:Zp(i,r):!1}function yh(n,r,i){var u;let l=n;do{if((u=l==null?void 0:l.matches)!=null&&u.call(l,r))return!0;if(l===i)return!1;l=l==null?void 0:l.parentElement}while(l);return!1}function $w(n,r,i,l){const u=new Map;for(const[c,f]of n)if((f.selected||f.id===l)&&(!f.parentId||!Zp(f,n))&&(f.draggable||r&&typeof f.draggable>"u")){const h=n.get(c);h&&u.set(c,{id:c,position:h.position||{x:0,y:0},distance:{x:i.x-h.internals.positionAbsolute.x,y:i.y-h.internals.positionAbsolute.y},extent:h.extent,parentId:h.parentId,origin:h.origin,expandParent:h.expandParent,internals:{positionAbsolute:h.internals.positionAbsolute||{x:0,y:0}},measured:{width:h.measured.width??0,height:h.measured.height??0}})}return u}function _a({nodeId:n,dragItems:r,nodeLookup:i,dragging:l=!0}){var f,h,p;const u=[];for(const[m,v]of r){const y=(f=i.get(m))==null?void 0:f.internals.userNode;y&&u.push({...y,position:v.position,dragging:l})}if(!n)return[u[0],u];const c=(h=i.get(n))==null?void 0:h.internals.userNode;return[c?{...c,position:((p=r.get(n))==null?void 0:p.position)||c.position,dragging:l}:u[0],u]}function Dw({dragItems:n,snapGrid:r,x:i,y:l}){const u=n.values().next().value;if(!u)return null;const c={x:i-u.distance.x,y:l-u.distance.y},f=yi(c,r);return{x:f.x-c.x,y:f.y-c.y}}function Ow({onNodeMouseDown:n,getStoreItems:r,onDragStart:i,onDrag:l,onDragStop:u}){let c={x:null,y:null},f=0,h=new Map,p=!1,m={x:0,y:0},v=null,y=!1,g=null,w=!1,S=!1,M=null;function N({noDragClassName:L,handleSelector:_,domNode:P,isSelectable:U,nodeId:D,nodeClickDistance:V=0}){g=kt(P);function X({x:J,y:Z}){const{nodeLookup:k,nodeExtent:B,snapGrid:z,snapToGrid:H,nodeOrigin:j,onNodeDrag:$,onSelectionDrag:F,onError:C,updateNodePositions:R}=r();c={x:J,y:Z};let te=!1;const re=h.size>1,ue=re&&B?Fa(mi(h)):null,ce=re&&H?Dw({dragItems:h,snapGrid:z,x:J,y:Z}):null;for(const[ae,G]of h){if(!k.has(ae))continue;let se={x:J-G.distance.x,y:Z-G.distance.y};H&&(se=ce?{x:Math.round(se.x+ce.x),y:Math.round(se.y+ce.y)}:yi(se,z));let pe=null;if(re&&B&&!G.extent&&ue){const{positionAbsolute:me}=G.internals,ke=me.x-ue.x+B[0][0],Ce=me.x+G.measured.width-ue.x2+B[1][0],Me=me.y-ue.y+B[0][1],Le=me.y+G.measured.height-ue.y2+B[1][1];pe=[[ke,Me],[Ce,Le]]}const{position:we,positionAbsolute:ve}=jp({nodeId:ae,nextPosition:se,nodeLookup:k,nodeExtent:pe||B,nodeOrigin:j,onError:C});te=te||G.position.x!==we.x||G.position.y!==we.y,G.position=we,G.internals.positionAbsolute=ve}if(S=S||te,!!te&&(R(h,!0),M&&(l||$||!D&&F))){const[ae,G]=_a({nodeId:D,dragItems:h,nodeLookup:k});l==null||l(M,h,ae,G),$==null||$(M,ae,G),D||F==null||F(M,G)}}async function b(){if(!v)return;const{transform:J,panBy:Z,autoPanSpeed:k,autoPanOnNodeDrag:B}=r();if(!B){p=!1,cancelAnimationFrame(f);return}const[z,H]=ec(m,v,k);(z!==0||H!==0)&&(c.x=(c.x??0)-z/J[2],c.y=(c.y??0)-H/J[2],await Z({x:z,y:H})&&X(c)),f=requestAnimationFrame(b)}function ee(J){var re;const{nodeLookup:Z,multiSelectionActive:k,nodesDraggable:B,transform:z,snapGrid:H,snapToGrid:j,selectNodesOnDrag:$,onNodeDragStart:F,onSelectionDragStart:C,unselectNodesAndEdges:R}=r();y=!0,(!$||!U)&&!k&&D&&((re=Z.get(D))!=null&&re.selected||R()),U&&$&&D&&(n==null||n(D));const te=ni(J.sourceEvent,{transform:z,snapGrid:H,snapToGrid:j,containerBounds:v});if(c=te,h=$w(Z,B,te,D),h.size>0&&(i||F||!D&&C)){const[ue,ce]=_a({nodeId:D,dragItems:h,nodeLookup:Z});i==null||i(J.sourceEvent,h,ue,ce),F==null||F(J.sourceEvent,ue,ce),D||C==null||C(J.sourceEvent,ce)}}const q=pp().clickDistance(V).on("start",J=>{const{domNode:Z,nodeDragThreshold:k,transform:B,snapGrid:z,snapToGrid:H}=r();v=(Z==null?void 0:Z.getBoundingClientRect())||null,w=!1,S=!1,M=J.sourceEvent,k===0&&ee(J),c=ni(J.sourceEvent,{transform:B,snapGrid:z,snapToGrid:H,containerBounds:v}),m=Ut(J.sourceEvent,v)}).on("drag",J=>{const{autoPanOnNodeDrag:Z,transform:k,snapGrid:B,snapToGrid:z,nodeDragThreshold:H,nodeLookup:j}=r(),$=ni(J.sourceEvent,{transform:k,snapGrid:B,snapToGrid:z,containerBounds:v});if(M=J.sourceEvent,(J.sourceEvent.type==="touchmove"&&J.sourceEvent.touches.length>1||D&&!j.has(D))&&(w=!0),!w){if(!p&&Z&&y&&(p=!0,b()),!y){const F=Ut(J.sourceEvent,v),C=F.x-m.x,R=F.y-m.y;Math.sqrt(C*C+R*R)>H&&ee(J)}(c.x!==$.xSnapped||c.y!==$.ySnapped)&&h&&y&&(m=Ut(J.sourceEvent,v),X($))}}).on("end",J=>{if(!y||w){w&&h.size>0&&r().updateNodePositions(h,!1);return}if(p=!1,y=!1,cancelAnimationFrame(f),h.size>0){const{nodeLookup:Z,updateNodePositions:k,onNodeDragStop:B,onSelectionDragStop:z}=r();if(S&&(k(h,!1),S=!1),u||B||!D&&z){const[H,j]=_a({nodeId:D,dragItems:h,nodeLookup:Z,dragging:!1});u==null||u(J.sourceEvent,h,H,j),B==null||B(J.sourceEvent,H,j),D||z==null||z(J.sourceEvent,j)}}}).filter(J=>{const Z=J.target;return!J.button&&(!L||!yh(Z,`.${L}`,P))&&(!_||yh(Z,_,P))});g.call(q)}function E(){g==null||g.on(".drag",null)}return{update:N,destroy:E}}function Fw(n,r,i){const l=[],u={x:n.x-i,y:n.y-i,width:i*2,height:i*2};for(const c of r.values())sl(u,ai(c))>0&&l.push(c);return l}const Hw=250;function Vw(n,r,i,l){var h,p;let u=[],c=1/0;const f=Fw(n,i,r+Hw);for(const m of f){const v=[...((h=m.internals.handleBounds)==null?void 0:h.source)??[],...((p=m.internals.handleBounds)==null?void 0:p.target)??[]];for(const y of v){if(l.nodeId===y.nodeId&&l.type===y.type&&l.id===y.id)continue;const{x:g,y:w}=vr(m,y,y.position,!0),S=Math.sqrt(Math.pow(g-n.x,2)+Math.pow(w-n.y,2));S>r||(S1){const m=l.type==="source"?"target":"source";return u.find(v=>v.type===m)??u[0]}return u[0]}function Jp(n,r,i,l,u,c=!1){var m,v,y;const f=l.get(n);if(!f)return null;const h=u==="strict"?(m=f.internals.handleBounds)==null?void 0:m[r]:[...((v=f.internals.handleBounds)==null?void 0:v.source)??[],...((y=f.internals.handleBounds)==null?void 0:y.target)??[]],p=(i?h==null?void 0:h.find(g=>g.id===i):h==null?void 0:h[0])??null;return p&&c?{...p,...vr(f,p,p.position,!0)}:p}function eg(n,r){return n||(r!=null&&r.classList.contains("target")?"target":r!=null&&r.classList.contains("source")?"source":null)}function Bw(n,r){let i=null;return r?i=!0:n&&!r&&(i=!1),i}const tg=()=>!0;function Uw(n,{connectionMode:r,connectionRadius:i,handleId:l,nodeId:u,edgeUpdaterType:c,isTarget:f,domNode:h,nodeLookup:p,lib:m,autoPanOnConnect:v,flowId:y,panBy:g,cancelConnection:w,onConnectStart:S,onConnect:M,onConnectEnd:N,isValidConnection:E=tg,onReconnectEnd:L,updateConnection:_,getTransform:P,getFromHandle:U,autoPanSpeed:D,dragThreshold:V=1,handleDomNode:X}){const b=Bp(n.target);let ee=0,q;const{x:J,y:Z}=Ut(n),k=eg(c,X),B=h==null?void 0:h.getBoundingClientRect();let z=!1;if(!B||!k)return;const H=Jp(u,k,l,p,r);if(!H)return;let j=Ut(n,B),$=!1,F=null,C=!1,R=null;function te(){if(!v||!B)return;const[we,ve]=ec(j,B,D);g({x:we,y:ve}),ee=requestAnimationFrame(te)}const re={...H,nodeId:u,type:k,position:H.position},ue=p.get(u);let ae={inProgress:!0,isValid:null,from:vr(ue,re,xe.Left,!0),fromHandle:re,fromPosition:re.position,fromNode:ue,to:j,toHandle:null,toPosition:ih[re.position],toNode:null,pointer:j};function G(){z=!0,_(ae),S==null||S(n,{nodeId:u,handleId:l,handleType:k})}V===0&&G();function se(we){if(!z){const{x:Le,y:it}=Ut(we),ut=Le-J,Je=it-Z;if(!(ut*ut+Je*Je>V*V))return;G()}if(!U()||!re){pe(we);return}const ve=P();j=Ut(we,B),q=Vw(vi(j,ve,!1,[1,1]),i,p,re),$||(te(),$=!0);const me=ng(we,{handle:q,connectionMode:r,fromNodeId:u,fromHandleId:l,fromType:f?"target":"source",isValidConnection:E,doc:b,lib:m,flowId:y,nodeLookup:p});R=me.handleDomNode,F=me.connection,C=Bw(!!q,me.isValid);const ke=p.get(u),Ce=ke?vr(ke,re,xe.Left,!0):ae.from,Me={...ae,from:Ce,isValid:C,to:me.toHandle&&C?oo({x:me.toHandle.x,y:me.toHandle.y},ve):j,toHandle:me.toHandle,toPosition:C&&me.toHandle?me.toHandle.position:ih[re.position],toNode:me.toHandle?p.get(me.toHandle.nodeId):null,pointer:j};_(Me),ae=Me}function pe(we){if(!("touches"in we&&we.touches.length>0)){if(z){(q||R)&&F&&C&&(M==null||M(F));const{inProgress:ve,...me}=ae,ke={...me,toPosition:ae.toHandle?ae.toPosition:null};N==null||N(we,ke),c&&(L==null||L(we,ke))}w(),cancelAnimationFrame(ee),$=!1,C=!1,F=null,R=null,b.removeEventListener("mousemove",se),b.removeEventListener("mouseup",pe),b.removeEventListener("touchmove",se),b.removeEventListener("touchend",pe)}}b.addEventListener("mousemove",se),b.addEventListener("mouseup",pe),b.addEventListener("touchmove",se),b.addEventListener("touchend",pe)}function ng(n,{handle:r,connectionMode:i,fromNodeId:l,fromHandleId:u,fromType:c,doc:f,lib:h,flowId:p,isValidConnection:m=tg,nodeLookup:v}){const y=c==="target",g=r?f.querySelector(`.${h}-flow__handle[data-id="${p}-${r==null?void 0:r.nodeId}-${r==null?void 0:r.id}-${r==null?void 0:r.type}"]`):null,{x:w,y:S}=Ut(n),M=f.elementFromPoint(w,S),N=M!=null&&M.classList.contains(`${h}-flow__handle`)?M:g,E={handleDomNode:N,isValid:!1,connection:null,toHandle:null};if(N){const L=eg(void 0,N),_=N.getAttribute("data-nodeid"),P=N.getAttribute("data-handleid"),U=N.classList.contains("connectable"),D=N.classList.contains("connectableend");if(!_||!L)return E;const V={source:y?_:l,sourceHandle:y?P:u,target:y?l:_,targetHandle:y?u:P};E.connection=V;const b=U&&D&&(i===no.Strict?y&&L==="source"||!y&&L==="target":_!==l||P!==u);E.isValid=b&&m(V),E.toHandle=Jp(_,L,P,v,i,!0)}return E}const Ua={onPointerDown:Uw,isValid:ng};function Ww({domNode:n,panZoom:r,getTransform:i,getViewScale:l}){const u=kt(n);function c({translateExtent:h,width:p,height:m,zoomStep:v=1,pannable:y=!0,zoomable:g=!0,inversePan:w=!1}){const S=_=>{if(_.sourceEvent.type!=="wheel"||!r)return;const P=i(),U=_.sourceEvent.ctrlKey&&ci()?10:1,D=-_.sourceEvent.deltaY*(_.sourceEvent.deltaMode===1?.05:_.sourceEvent.deltaMode?1:.002)*v,V=P[2]*Math.pow(2,D*U);r.scaleTo(V)};let M=[0,0];const N=_=>{(_.sourceEvent.type==="mousedown"||_.sourceEvent.type==="touchstart")&&(M=[_.sourceEvent.clientX??_.sourceEvent.touches[0].clientX,_.sourceEvent.clientY??_.sourceEvent.touches[0].clientY])},E=_=>{const P=i();if(_.sourceEvent.type!=="mousemove"&&_.sourceEvent.type!=="touchmove"||!r)return;const U=[_.sourceEvent.clientX??_.sourceEvent.touches[0].clientX,_.sourceEvent.clientY??_.sourceEvent.touches[0].clientY],D=[U[0]-M[0],U[1]-M[1]];M=U;const V=l()*Math.max(P[2],Math.log(P[2]))*(w?-1:1),X={x:P[0]-D[0]*V,y:P[1]-D[1]*V},b=[[0,0],[p,m]];r.setViewportConstrained({x:X.x,y:X.y,zoom:P[2]},b,h)},L=Ip().on("start",N).on("zoom",y?E:null).on("zoom.wheel",g?S:null);u.call(L,{})}function f(){u.on("zoom",null)}return{update:c,destroy:f,pointer:Ht}}const ml=n=>({x:n.x,y:n.y,zoom:n.k}),Ea=({x:n,y:r,zoom:i})=>hl.translate(n,r).scale(i),Bn=(n,r)=>n.target.closest(`.${r}`),rg=(n,r)=>r===2&&Array.isArray(n)&&n.includes(2),Yw=n=>((n*=2)<=1?n*n*n:(n-=2)*n*n+2)/2,ka=(n,r=0,i=Yw,l=()=>{})=>{const u=typeof r=="number"&&r>0;return u||l(),u?n.transition().duration(r).ease(i).on("end",l):n},og=n=>{const r=n.ctrlKey&&ci()?10:1;return-n.deltaY*(n.deltaMode===1?.05:n.deltaMode?1:.002)*r};function Xw({zoomPanValues:n,noWheelClassName:r,d3Selection:i,d3Zoom:l,panOnScrollMode:u,panOnScrollSpeed:c,zoomOnPinch:f,onPanZoomStart:h,onPanZoom:p,onPanZoomEnd:m}){return v=>{if(Bn(v,r))return v.ctrlKey&&v.preventDefault(),!1;v.preventDefault(),v.stopImmediatePropagation();const y=i.property("__zoom").k||1;if(v.ctrlKey&&f){const N=Ht(v),E=og(v),L=y*Math.pow(2,E);l.scaleTo(i,L,N,v);return}const g=v.deltaMode===1?20:1;let w=u===hr.Vertical?0:v.deltaX*g,S=u===hr.Horizontal?0:v.deltaY*g;!ci()&&v.shiftKey&&u!==hr.Vertical&&(w=v.deltaY*g,S=0),l.translateBy(i,-(w/y)*c,-(S/y)*c,{internal:!0});const M=ml(i.property("__zoom"));clearTimeout(n.panScrollTimeout),n.isPanScrolling?p==null||p(v,M):(n.isPanScrolling=!0,h==null||h(v,M)),n.panScrollTimeout=setTimeout(()=>{m==null||m(v,M),n.isPanScrolling=!1},150)}}function bw({noWheelClassName:n,preventScrolling:r,d3ZoomHandler:i}){return function(l,u){const c=l.type==="wheel",f=!r&&c&&!l.ctrlKey,h=Bn(l,n);if(l.ctrlKey&&c&&h&&l.preventDefault(),f||h)return null;l.preventDefault(),i.call(this,l,u)}}function Qw({zoomPanValues:n,onDraggingChange:r,onPanZoomStart:i}){return l=>{var c,f,h;if((c=l.sourceEvent)!=null&&c.internal)return;const u=ml(l.transform);n.mouseButton=((f=l.sourceEvent)==null?void 0:f.button)||0,n.isZoomingOrPanning=!0,n.prevViewport=u,((h=l.sourceEvent)==null?void 0:h.type)==="mousedown"&&r(!0),i&&(i==null||i(l.sourceEvent,u))}}function Gw({zoomPanValues:n,panOnDrag:r,onPaneContextMenu:i,onTransformChange:l,onPanZoom:u}){return c=>{var f,h;n.usedRightMouseButton=!!(i&&rg(r,n.mouseButton??0)),(f=c.sourceEvent)!=null&&f.sync||l([c.transform.x,c.transform.y,c.transform.k]),u&&!((h=c.sourceEvent)!=null&&h.internal)&&(u==null||u(c.sourceEvent,ml(c.transform)))}}function Kw({zoomPanValues:n,panOnDrag:r,panOnScroll:i,onDraggingChange:l,onPanZoomEnd:u,onPaneContextMenu:c}){return f=>{var h;if(!((h=f.sourceEvent)!=null&&h.internal)&&(n.isZoomingOrPanning=!1,c&&rg(r,n.mouseButton??0)&&!n.usedRightMouseButton&&f.sourceEvent&&c(f.sourceEvent),n.usedRightMouseButton=!1,l(!1),u)){const p=ml(f.transform);n.prevViewport=p,clearTimeout(n.timerId),n.timerId=setTimeout(()=>{u==null||u(f.sourceEvent,p)},i?150:0)}}}function qw({panActivationKeyPressed:n,zoomActivationKeyPressed:r,zoomOnScroll:i,zoomOnPinch:l,panOnDrag:u,panOnScroll:c,zoomOnDoubleClick:f,userSelectionActive:h,noWheelClassName:p,noPanClassName:m,lib:v,connectionInProgress:y}){return g=>{var E;const w=r||i,S=l&&g.ctrlKey,M=g.type==="wheel";if(g.button===1&&g.type==="mousedown"&&(Bn(g,`${v}-flow__node`)||Bn(g,`${v}-flow__edge`)||Bn(g,`${v}-flow__selection`)||Bn(g,`${v}-flow__nodesselection`)))return!0;if(!u&&!w&&!c&&!f&&!l||h||y&&!M||Bn(g,p)&&M||Bn(g,m)&&(!M||c&&M&&!r)||!l&&g.ctrlKey&&M)return!1;if(!l&&g.type==="touchstart"&&((E=g.touches)==null?void 0:E.length)>1)return g.preventDefault(),!1;if(!w&&!c&&!S&&M||!u&&(g.type==="mousedown"||g.type==="touchstart")||Array.isArray(u)&&!u.includes(g.button)&&g.type==="mousedown")return!1;const N=Array.isArray(u)&&u.includes(g.button)||!g.button||g.button<=1;return(!g.ctrlKey||M||n)&&N}}function Zw({domNode:n,minZoom:r,maxZoom:i,translateExtent:l,viewport:u,onPanZoom:c,onPanZoomStart:f,onPanZoomEnd:h,onDraggingChange:p}){const m={isZoomingOrPanning:!1,usedRightMouseButton:!1,prevViewport:{},mouseButton:0,timerId:void 0,panScrollTimeout:void 0,isPanScrolling:!1},v=n.getBoundingClientRect();let y=[[0,0],[v.width,v.height]];const g=typeof ResizeObserver<"u"?new ResizeObserver(Z=>{const k=Z[0];k&&(y=[[0,0],[k.contentRect.width,k.contentRect.height]])}):null;g==null||g.observe(n);const w=Ip().extent(()=>y).scaleExtent([r,i]).translateExtent(l),S=kt(n).call(w);P({x:u.x,y:u.y,zoom:ro(u.zoom,r,i)},[[0,0],[v.width,v.height]],l);const M=S.on("wheel.zoom"),N=S.on("dblclick.zoom");w.wheelDelta(og);async function E(Z,k){return S?new Promise(B=>{w==null||w.interpolate((k==null?void 0:k.interpolate)==="linear"?ti:bs).transform(ka(S,k==null?void 0:k.duration,k==null?void 0:k.ease,()=>B(!0)),Z)}):!1}function L({noWheelClassName:Z,noPanClassName:k,onPaneContextMenu:B,userSelectionActive:z,panOnScroll:H,panOnDrag:j,panOnScrollMode:$,panOnScrollSpeed:F,preventScrolling:C,zoomOnPinch:R,zoomOnScroll:te,zoomOnDoubleClick:re,panActivationKeyPressed:ue=!1,zoomActivationKeyPressed:ce,lib:ae,onTransformChange:G,connectionInProgress:se,paneClickDistance:pe,selectionOnDrag:we}){z&&!m.isZoomingOrPanning&&_();const ve=H&&!ce&&!z;w.clickDistance(we?1/0:!Bt(pe)||pe<0?0:pe);const me=ve?Xw({zoomPanValues:m,noWheelClassName:Z,d3Selection:S,d3Zoom:w,panOnScrollMode:$,panOnScrollSpeed:F,zoomOnPinch:R,onPanZoomStart:f,onPanZoom:c,onPanZoomEnd:h}):bw({noWheelClassName:Z,preventScrolling:C,d3ZoomHandler:M});S.on("wheel.zoom",me,{passive:!1});const ke=Qw({zoomPanValues:m,onDraggingChange:p,onPanZoomStart:f});w.on("start",ke);const Ce=Gw({zoomPanValues:m,panOnDrag:j,onPaneContextMenu:!!B,onPanZoom:c,onTransformChange:G});w.on("zoom",Ce);const Me=Kw({zoomPanValues:m,panOnDrag:j,panOnScroll:H,onPaneContextMenu:B,onPanZoomEnd:h,onDraggingChange:p});w.on("end",Me);const Le=qw({panActivationKeyPressed:ue,zoomActivationKeyPressed:ce,panOnDrag:j,zoomOnScroll:te,panOnScroll:H,zoomOnDoubleClick:re,zoomOnPinch:R,userSelectionActive:z,noPanClassName:k,noWheelClassName:Z,lib:ae,connectionInProgress:se});w.filter(Le),re?S.on("dblclick.zoom",N):S.on("dblclick.zoom",null)}function _(){w.on("zoom",null)}async function P(Z,k,B){const z=Ea(Z),H=w==null?void 0:w.constrain()(z,k,B);return H&&await E(H),H}async function U(Z,k){const B=Ea(Z);return await E(B,k),B}function D(Z){if(S){const k=Ea(Z),B=S.property("__zoom");(B.k!==Z.zoom||B.x!==Z.x||B.y!==Z.y)&&(w==null||w.transform(S,k,null,{sync:!0}))}}function V(){const Z=S?Pp(S.node()):{x:0,y:0,k:1};return{x:Z.x,y:Z.y,zoom:Z.k}}async function X(Z,k){return S?new Promise(B=>{w==null||w.interpolate((k==null?void 0:k.interpolate)==="linear"?ti:bs).scaleTo(ka(S,k==null?void 0:k.duration,k==null?void 0:k.ease,()=>B(!0)),Z)}):!1}async function b(Z,k){return S?new Promise(B=>{w==null||w.interpolate((k==null?void 0:k.interpolate)==="linear"?ti:bs).scaleBy(ka(S,k==null?void 0:k.duration,k==null?void 0:k.ease,()=>B(!0)),Z)}):!1}function ee(Z){w==null||w.scaleExtent(Z)}function q(Z){w==null||w.translateExtent(Z)}function J(Z){const k=!Bt(Z)||Z<0?0:Z;w==null||w.clickDistance(k)}return{update:L,destroy:_,setViewport:U,setViewportConstrained:P,getViewport:V,scaleTo:X,scaleBy:b,setScaleExtent:ee,setTranslateExtent:q,syncViewport:D,setClickDistance:J}}var io;(function(n){n.Line="line",n.Handle="handle"})(io||(io={}));function Jw({width:n,prevWidth:r,height:i,prevHeight:l,affectsX:u,affectsY:c}){const f=n-r,h=i-l,p=[f>0?1:f<0?-1:0,h>0?1:h<0?-1:0];return f&&u&&(p[0]=p[0]*-1),h&&c&&(p[1]=p[1]*-1),p}function vh(n){const r=n.includes("right")||n.includes("left"),i=n.includes("bottom")||n.includes("top"),l=n.includes("left"),u=n.includes("top");return{isHorizontal:r,isVertical:i,affectsX:l,affectsY:u}}function Hn(n,r){return Math.max(0,r-n)}function Vn(n,r){return Math.max(0,n-r)}function Us(n,r,i){return Math.max(0,r-n,n-i)}function xh(n,r){return n?!r:r}function e1(n,r,i,l,u,c,f,h){let{affectsX:p,affectsY:m}=r;const{isHorizontal:v,isVertical:y}=r,g=v&&y,{xSnapped:w,ySnapped:S}=i,{minWidth:M,maxWidth:N,minHeight:E,maxHeight:L}=l,{x:_,y:P,width:U,height:D,aspectRatio:V}=n;let X=Math.floor(v?w-n.pointerX:0),b=Math.floor(y?S-n.pointerY:0);const ee=U+(p?-X:X),q=D+(m?-b:b),J=-c[0]*U,Z=-c[1]*D;let k=Us(ee,M,N),B=Us(q,E,L);if(f){let j=0,$=0;p&&X<0?j=Hn(_+X+J,f[0][0]):!p&&X>0&&(j=Vn(_+ee+J,f[1][0])),m&&b<0?$=Hn(P+b+Z,f[0][1]):!m&&b>0&&($=Vn(P+q+Z,f[1][1])),k=Math.max(k,j),B=Math.max(B,$)}if(h){let j=0,$=0;p&&X>0?j=Vn(_+X,h[0][0]):!p&&X<0&&(j=Hn(_+ee,h[1][0])),m&&b>0?$=Vn(P+b,h[0][1]):!m&&b<0&&($=Hn(P+q,h[1][1])),k=Math.max(k,j),B=Math.max(B,$)}if(u){if(v){const j=Us(ee/V,E,L)*V;if(k=Math.max(k,j),f){let $=0;!p&&!m||p&&!m&&g?$=Vn(P+Z+ee/V,f[1][1])*V:$=Hn(P+Z+(p?X:-X)/V,f[0][1])*V,k=Math.max(k,$)}if(h){let $=0;!p&&!m||p&&!m&&g?$=Hn(P+ee/V,h[1][1])*V:$=Vn(P+(p?X:-X)/V,h[0][1])*V,k=Math.max(k,$)}}if(y){const j=Us(q*V,M,N)/V;if(B=Math.max(B,j),f){let $=0;!p&&!m||m&&!p&&g?$=Vn(_+q*V+J,f[1][0])/V:$=Hn(_+(m?b:-b)*V+J,f[0][0])/V,B=Math.max(B,$)}if(h){let $=0;!p&&!m||m&&!p&&g?$=Hn(_+q*V,h[1][0])/V:$=Vn(_+(m?b:-b)*V,h[0][0])/V,B=Math.max(B,$)}}}b=b+(b<0?B:-B),X=X+(X<0?k:-k),u&&(g?ee>q*V?b=(xh(p,m)?-X:X)/V:X=(xh(p,m)?-b:b)*V:v?(b=X/V,m=p):(X=b*V,p=m));const z=p?_+X:_,H=m?P+b:P;return{width:U+(p?-X:X),height:D+(m?-b:b),x:c[0]*X*(p?-1:1)+z,y:c[1]*b*(m?-1:1)+H}}const ig={width:0,height:0,x:0,y:0},t1={...ig,pointerX:0,pointerY:0,aspectRatio:1};function n1(n,r,i){const l=r.position.x+n.position.x,u=r.position.y+n.position.y,c=n.measured.width??0,f=n.measured.height??0,h=i[0]*c,p=i[1]*f;return[[l-h,u-p],[l+c-h,u+f-p]]}function r1({domNode:n,nodeId:r,getStoreItems:i,onChange:l,onEnd:u}){const c=kt(n);let f={controlDirection:vh("bottom-right"),boundaries:{minWidth:0,minHeight:0,maxWidth:Number.MAX_VALUE,maxHeight:Number.MAX_VALUE},resizeDirection:void 0,keepAspectRatio:!1};function h({controlPosition:m,boundaries:v,keepAspectRatio:y,resizeDirection:g,onResizeStart:w,onResize:S,onResizeEnd:M,shouldResize:N}){let E={...ig},L={...t1};f={boundaries:v,resizeDirection:g,keepAspectRatio:y,controlDirection:vh(m)};let _,P=null,U=[],D,V,X,b=!1;const ee=pp().on("start",q=>{const{nodeLookup:J,transform:Z,snapGrid:k,snapToGrid:B,nodeOrigin:z,paneDomNode:H}=i();if(_=J.get(r),!_)return;P=(H==null?void 0:H.getBoundingClientRect())??null;const{xSnapped:j,ySnapped:$}=ni(q.sourceEvent,{transform:Z,snapGrid:k,snapToGrid:B,containerBounds:P});E={width:_.measured.width??0,height:_.measured.height??0,x:_.position.x??0,y:_.position.y??0},L={...E,pointerX:j,pointerY:$,aspectRatio:E.width/E.height},D=void 0,V=yr(_.extent)?_.extent:void 0,_.parentId&&(_.extent==="parent"||_.expandParent)&&(D=J.get(_.parentId)),D&&_.extent==="parent"&&(V=[[0,0],[D.measured.width,D.measured.height]]),U=[],X=void 0;for(const[F,C]of J)if(C.parentId===r&&(U.push({id:F,position:{...C.position},extent:C.extent}),C.extent==="parent"||C.expandParent)){const R=n1(C,_,C.origin??z);X?X=[[Math.min(R[0][0],X[0][0]),Math.min(R[0][1],X[0][1])],[Math.max(R[1][0],X[1][0]),Math.max(R[1][1],X[1][1])]]:X=R}w==null||w(q,{...E})}).on("drag",q=>{const{transform:J,snapGrid:Z,snapToGrid:k,nodeOrigin:B}=i(),z=ni(q.sourceEvent,{transform:J,snapGrid:Z,snapToGrid:k,containerBounds:P}),H=[];if(!_)return;const{x:j,y:$,width:F,height:C}=E,R={},te=_.origin??B,{width:re,height:ue,x:ce,y:ae}=e1(L,f.controlDirection,z,f.boundaries,f.keepAspectRatio,te,V,X),G=re!==F,se=ue!==C,pe=ce!==j&&G,we=ae!==$&&se;if(!pe&&!we&&!G&&!se)return;if((pe||we||te[0]===1||te[1]===1)&&(R.x=pe?ce:E.x,R.y=we?ae:E.y,E.x=R.x,E.y=R.y,U.length>0)){const Ce=ce-j,Me=ae-$;for(const Le of U)Le.position={x:Le.position.x-Ce+te[0]*(re-F),y:Le.position.y-Me+te[1]*(ue-C)},H.push(Le)}if((G||se)&&(R.width=G&&(!f.resizeDirection||f.resizeDirection==="horizontal")?re:E.width,R.height=se&&(!f.resizeDirection||f.resizeDirection==="vertical")?ue:E.height,E.width=R.width,E.height=R.height),D&&_.expandParent){const Ce=te[0]*(R.width??0);R.x&&R.x{b&&(M==null||M(q,{...E}),u==null||u({...E}),b=!1)});c.call(ee)}function p(){c.on(".drag",null)}return{update:h,destroy:p}}var Na={exports:{}},Ca={},Ma={exports:{}},Pa={};/** + * @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 wh;function o1(){if(wh)return Pa;wh=1;var n=di();function r(y,g){return y===g&&(y!==0||1/y===1/g)||y!==y&&g!==g}var i=typeof Object.is=="function"?Object.is:r,l=n.useState,u=n.useEffect,c=n.useLayoutEffect,f=n.useDebugValue;function h(y,g){var w=g(),S=l({inst:{value:w,getSnapshot:g}}),M=S[0].inst,N=S[1];return c(function(){M.value=w,M.getSnapshot=g,p(M)&&N({inst:M})},[y,w,g]),u(function(){return p(M)&&N({inst:M}),y(function(){p(M)&&N({inst:M})})},[y]),f(w),w}function p(y){var g=y.getSnapshot;y=y.value;try{var w=g();return!i(y,w)}catch{return!0}}function m(y,g){return g()}var v=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?m:h;return Pa.useSyncExternalStore=n.useSyncExternalStore!==void 0?n.useSyncExternalStore:v,Pa}var Sh;function i1(){return Sh||(Sh=1,Ma.exports=o1()),Ma.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 _h;function s1(){if(_h)return Ca;_h=1;var n=di(),r=i1();function i(m,v){return m===v&&(m!==0||1/m===1/v)||m!==m&&v!==v}var l=typeof Object.is=="function"?Object.is:i,u=r.useSyncExternalStore,c=n.useRef,f=n.useEffect,h=n.useMemo,p=n.useDebugValue;return Ca.useSyncExternalStoreWithSelector=function(m,v,y,g,w){var S=c(null);if(S.current===null){var M={hasValue:!1,value:null};S.current=M}else M=S.current;S=h(function(){function E(D){if(!L){if(L=!0,_=D,D=g(D),w!==void 0&&M.hasValue){var V=M.value;if(w(V,D))return P=V}return P=D}if(V=P,l(_,D))return V;var X=g(D);return w!==void 0&&w(V,X)?(_=D,V):(_=D,P=X)}var L=!1,_,P,U=y===void 0?null:y;return[function(){return E(v())},U===null?void 0:function(){return E(U())}]},[v,y,g,w]);var N=u(m,S[0],S[1]);return f(function(){M.hasValue=!0,M.value=N},[N]),p(N),N},Ca}var Eh;function l1(){return Eh||(Eh=1,Na.exports=s1()),Na.exports}var u1=l1();const a1=Zh(u1),c1={},kh=n=>{let r;const i=new Set,l=(v,y)=>{const g=typeof v=="function"?v(r):v;if(!Object.is(g,r)){const w=r;r=y??(typeof g!="object"||g===null)?g:Object.assign({},r,g),i.forEach(S=>S(r,w))}},u=()=>r,p={setState:l,getState:u,getInitialState:()=>m,subscribe:v=>(i.add(v),()=>i.delete(v)),destroy:()=>{(c1?"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."),i.clear()}},m=r=n(l,u,p);return p},f1=n=>n?kh(n):kh,{useDebugValue:d1}=_0,{useSyncExternalStoreWithSelector:h1}=a1,p1=n=>n;function sg(n,r=p1,i){const l=h1(n.subscribe,n.getState,n.getServerState||n.getInitialState,r,i);return d1(l),l}const Nh=(n,r)=>{const i=f1(n),l=(u,c=r)=>sg(i,u,c);return Object.assign(l,i),l},g1=(n,r)=>n?Nh(n,r):Nh;function Ve(n,r){if(Object.is(n,r))return!0;if(typeof n!="object"||n===null||typeof r!="object"||r===null)return!1;if(n instanceof Map&&r instanceof Map){if(n.size!==r.size)return!1;for(const[l,u]of n)if(!Object.is(u,r.get(l)))return!1;return!0}if(n instanceof Set&&r instanceof Set){if(n.size!==r.size)return!1;for(const l of n)if(!r.has(l))return!1;return!0}const i=Object.keys(n);if(i.length!==Object.keys(r).length)return!1;for(const l of i)if(!Object.prototype.hasOwnProperty.call(r,l)||!Object.is(n[l],r[l]))return!1;return!0}Jh();const yl=K.createContext(null),m1=yl.Provider,lg=Wt.error001("react");function Ie(n,r){const i=K.useContext(yl);if(i===null)throw new Error(lg);return sg(i,n,r)}function $e(){const n=K.useContext(yl);if(n===null)throw new Error(lg);return K.useMemo(()=>({getState:n.getState,setState:n.setState,subscribe:n.subscribe}),[n])}const Ch={display:"none"},y1={position:"absolute",width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0px, 0px, 0px, 0px)",clipPath:"inset(100%)"},ug="react-flow__node-desc",ag="react-flow__edge-desc",v1="react-flow__aria-live",x1=n=>n.ariaLiveMessage,w1=n=>n.ariaLabelConfig;function S1({rfId:n}){const r=Ie(x1);return T.jsx("div",{id:`${v1}-${n}`,"aria-live":"assertive","aria-atomic":"true",style:y1,children:r})}function _1({rfId:n,disableKeyboardA11y:r}){const i=Ie(w1);return T.jsxs(T.Fragment,{children:[T.jsx("div",{id:`${ug}-${n}`,style:Ch,children:r?i["node.a11yDescription.default"]:i["node.a11yDescription.keyboardDisabled"]}),T.jsx("div",{id:`${ag}-${n}`,style:Ch,children:i["edge.a11yDescription.default"]}),!r&&T.jsx(S1,{rfId:n})]})}const vl=K.forwardRef(({position:n="top-left",children:r,className:i,style:l,...u},c)=>{const f=`${n}`.split("-");return T.jsx("div",{className:Ye(["react-flow__panel",i,...f]),style:l,ref:c,...u,children:r})});vl.displayName="Panel";const Mh="https://reactflow.dev?utm_source=attribution";function E1({proOptions:n,position:r="bottom-right"}){return n!=null&&n.hideAttribution?null:T.jsx(vl,{position:r,className:"react-flow__attribution","data-message":`Please only hide this attribution when you are subscribed to React Flow Pro: ${Mh}`,children:T.jsx("a",{href:Mh,target:"_blank",rel:"noopener noreferrer","aria-label":"React Flow attribution",children:"React Flow"})})}const k1=n=>{const r=[],i=[];for(const[,l]of n.nodeLookup)l.selected&&r.push(l.internals.userNode);for(const[,l]of n.edgeLookup)l.selected&&i.push(l);return{selectedNodes:r,selectedEdges:i}},Ws=n=>n.id;function N1(n,r){return Ve(n.selectedNodes.map(Ws),r.selectedNodes.map(Ws))&&Ve(n.selectedEdges.map(Ws),r.selectedEdges.map(Ws))}function C1({onSelectionChange:n}){const r=$e(),{selectedNodes:i,selectedEdges:l}=Ie(k1,N1);return K.useEffect(()=>{const u={nodes:i,edges:l};n==null||n(u),r.getState().onSelectionChangeHandlers.forEach(c=>c(u))},[i,l,n]),null}const M1=n=>!!n.onSelectionChangeHandlers;function P1({onSelectionChange:n}){const r=Ie(M1);return n||r?T.jsx(C1,{onSelectionChange:n}):null}const cg=[0,0],I1={x:0,y:0,zoom:1},z1=["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"],Ph=[...z1,"rfId"],T1=n=>({setNodes:n.setNodes,setEdges:n.setEdges,setMinZoom:n.setMinZoom,setMaxZoom:n.setMaxZoom,setTranslateExtent:n.setTranslateExtent,setNodeExtent:n.setNodeExtent,reset:n.reset,setDefaultNodesAndEdges:n.setDefaultNodesAndEdges}),Ih={translateExtent:li,nodeOrigin:cg,minZoom:.5,maxZoom:2,elementsSelectable:!0,noPanClassName:"nopan",rfId:"1"};function L1(n){const{setNodes:r,setEdges:i,setMinZoom:l,setMaxZoom:u,setTranslateExtent:c,setNodeExtent:f,reset:h,setDefaultNodesAndEdges:p}=Ie(T1,Ve),m=$e();K.useEffect(()=>(p(n.defaultNodes,n.defaultEdges),()=>{v.current=Ih,h()}),[]);const v=K.useRef(Ih);return K.useEffect(()=>{for(const y of Ph){const g=n[y],w=v.current[y];g!==w&&(typeof n[y]>"u"||(y==="nodes"?r(g):y==="edges"?i(g):y==="minZoom"?l(g):y==="maxZoom"?u(g):y==="translateExtent"?c(g):y==="nodeExtent"?f(g):y==="ariaLabelConfig"?m.setState({ariaLabelConfig:mw(g)}):y==="fitView"?m.setState({fitViewQueued:g}):y==="fitViewOptions"?m.setState({fitViewOptions:g}):m.setState({[y]:g})))}v.current=n},Ph.map(y=>n[y])),null}function zh(){return typeof window>"u"||!window.matchMedia?null:window.matchMedia("(prefers-color-scheme: dark)")}function R1(n){var l;const[r,i]=K.useState(n==="system"?null:n);return K.useEffect(()=>{if(n!=="system"){i(n);return}const u=zh(),c=()=>i(u!=null&&u.matches?"dark":"light");return c(),u==null||u.addEventListener("change",c),()=>{u==null||u.removeEventListener("change",c)}},[n]),r!==null?r:(l=zh())!=null&&l.matches?"dark":"light"}const Th=typeof document<"u"?document:null;function fi(n=null,r={target:Th,actInsideInputWithModifier:!0}){const[i,l]=K.useState(!1),u=K.useRef(!1),c=K.useRef(new Set([])),[f,h]=K.useMemo(()=>{if(n!==null){const m=(Array.isArray(n)?n:[n]).filter(y=>typeof y=="string").map(y=>y.replace(/\+/g,` +`).replace(` + +`,` ++`).split(` +`)),v=m.reduce((y,g)=>y.concat(...g),[]);return[m,v]}return[[],[]]},[n]);return K.useEffect(()=>{const p=(r==null?void 0:r.target)??Th,m=(r==null?void 0:r.actInsideInputWithModifier)??!0;if(n!==null){const v=w=>{var N,E;if(u.current=w.ctrlKey||w.metaKey||w.shiftKey||w.altKey,(!u.current||u.current&&!m)&&Up(w))return!1;const M=Rh(w.code,h);if(c.current.add(w[M]),Lh(f,c.current,!1)){const L=((E=(N=w.composedPath)==null?void 0:N.call(w))==null?void 0:E[0])||w.target,_=(L==null?void 0:L.nodeName)==="BUTTON"||(L==null?void 0:L.nodeName)==="A";r.preventDefault!==!1&&(u.current||!_)&&w.preventDefault(),l(!0)}},y=w=>{const S=Rh(w.code,h);Lh(f,c.current,!0)?(l(!1),c.current.clear()):c.current.delete(w[S]),w.key==="Meta"&&c.current.clear(),u.current=!1},g=()=>{c.current.clear(),l(!1)};return p==null||p.addEventListener("keydown",v),p==null||p.addEventListener("keyup",y),window.addEventListener("blur",g),window.addEventListener("contextmenu",g),()=>{p==null||p.removeEventListener("keydown",v),p==null||p.removeEventListener("keyup",y),window.removeEventListener("blur",g),window.removeEventListener("contextmenu",g)}}},[n,l]),i}function Lh(n,r,i){return n.filter(l=>i||l.length===r.size).some(l=>l.every(u=>r.has(u)))}function Rh(n,r){return r.includes(n)?"code":"key"}const A1=()=>{const n=$e();return K.useMemo(()=>({zoomIn:async r=>{const{panZoom:i}=n.getState();return i?i.scaleBy(1.2,r):!1},zoomOut:async r=>{const{panZoom:i}=n.getState();return i?i.scaleBy(1/1.2,r):!1},zoomTo:async(r,i)=>{const{panZoom:l}=n.getState();return l?l.scaleTo(r,i):!1},getZoom:()=>n.getState().transform[2],setViewport:async(r,i)=>{const{transform:[l,u,c],panZoom:f}=n.getState();return f?(await f.setViewport({x:r.x??l,y:r.y??u,zoom:r.zoom??c},i),!0):!1},getViewport:()=>{const[r,i,l]=n.getState().transform;return{x:r,y:i,zoom:l}},setCenter:async(r,i,l)=>n.getState().setCenter(r,i,l),fitBounds:async(r,i)=>{const{width:l,height:u,minZoom:c,maxZoom:f,panZoom:h}=n.getState(),p=tc(r,l,u,c,f,(i==null?void 0:i.padding)??.1);return h?(await h.setViewport(p,{duration:i==null?void 0:i.duration,ease:i==null?void 0:i.ease,interpolate:i==null?void 0:i.interpolate}),!0):!1},screenToFlowPosition:(r,i={})=>{const{transform:l,snapGrid:u,snapToGrid:c,domNode:f}=n.getState();if(!f)return r;const{x:h,y:p}=f.getBoundingClientRect(),m={x:r.x-h,y:r.y-p},v=i.snapGrid??u,y=i.snapToGrid??c;return vi(m,l,y,v)},flowToScreenPosition:r=>{const{transform:i,domNode:l}=n.getState();if(!l)return r;const{x:u,y:c}=l.getBoundingClientRect(),f=oo(r,i);return{x:f.x+u,y:f.y+c}}}),[])};function fg(n,r){const i=[],l=new Map,u=[];for(const c of n)if(c.type==="add"){u.push(c);continue}else if(c.type==="remove"||c.type==="replace")l.set(c.id,[c]);else{const f=l.get(c.id);f?f.push(c):l.set(c.id,[c])}for(const c of r){const f=l.get(c.id);if(!f){i.push(c);continue}if(f[0].type==="remove")continue;if(f[0].type==="replace"){i.push({...f[0].item});continue}const h={...c};for(const p of f)j1(p,h);i.push(h)}return u.length&&u.forEach(c=>{c.index!==void 0?i.splice(c.index,0,{...c.item}):i.push({...c.item})}),i}function j1(n,r){switch(n.type){case"select":{r.selected=n.selected;break}case"position":{typeof n.position<"u"&&(r.position=n.position),typeof n.dragging<"u"&&(r.dragging=n.dragging);break}case"dimensions":{typeof n.dimensions<"u"&&(r.measured={...n.dimensions},n.setAttributes&&((n.setAttributes===!0||n.setAttributes==="width")&&(r.width=n.dimensions.width),(n.setAttributes===!0||n.setAttributes==="height")&&(r.height=n.dimensions.height))),typeof n.resizing=="boolean"&&(r.resizing=n.resizing);break}}}function $1(n,r){return fg(n,r)}function D1(n,r){return fg(n,r)}function cr(n,r){return{id:n,type:"select",selected:r}}function qr(n,r=new Set,i=!1){const l=[];for(const[u,c]of n){const f=r.has(u);!(c.selected===void 0&&!f)&&c.selected!==f&&(i&&(c.selected=f),l.push(cr(c.id,f)))}return l}function Ah({items:n=[],lookup:r}){var u;const i=[],l=new Map(n.map(c=>[c.id,c]));for(const[c,f]of n.entries()){const h=r.get(f.id),p=((u=h==null?void 0:h.internals)==null?void 0:u.userNode)??h;p!==void 0&&p!==f&&i.push({id:f.id,item:f,type:"replace"}),p===void 0&&i.push({item:f,type:"add",index:c})}for(const[c]of r)l.get(c)===void 0&&i.push({id:c,type:"remove"});return i}function jh(n){return{id:n.id,type:"remove"}}const O1=Fp();function F1(n,r,i={}){return _w(n,r,{...i,onError:i.onError??O1})}const $h=n=>lw(n),H1=n=>Ap(n);function dg(n){return K.forwardRef(n)}const hg=typeof window<"u"?K.useLayoutEffect:K.useEffect;function Dh(n){const[r,i]=K.useState(BigInt(0)),[l]=K.useState(()=>V1(()=>i(u=>u+BigInt(1))));return hg(()=>{const u=l.get();u.length&&(n(u),l.reset())},[r]),l}function V1(n){let r=[];return{get:()=>r,reset:()=>{r=[]},push:i=>{r.push(i),n()}}}const pg=K.createContext(null);function B1({children:n}){const r=$e(),i=K.useCallback(h=>{const{nodes:p=[],setNodes:m,hasDefaultNodes:v,onNodesChange:y,nodeLookup:g,fitViewQueued:w,onNodesChangeMiddlewareMap:S}=r.getState();let M=p;for(const E of h)M=typeof E=="function"?E(M):E;let N=Ah({items:M,lookup:g});for(const E of S.values())N=E(N);v&&m(M),N.length>0?y==null||y(N):w&&window.requestAnimationFrame(()=>{const{fitViewQueued:E,nodes:L,setNodes:_}=r.getState();E&&_(L)})},[]),l=Dh(i),u=K.useCallback(h=>{const{edges:p=[],setEdges:m,hasDefaultEdges:v,onEdgesChange:y,edgeLookup:g}=r.getState();let w=p;for(const S of h)w=typeof S=="function"?S(w):S;v?m(w):y&&y(Ah({items:w,lookup:g}))},[]),c=Dh(u),f=K.useMemo(()=>({nodeQueue:l,edgeQueue:c}),[]);return T.jsx(pg.Provider,{value:f,children:n})}function U1(){const n=K.useContext(pg);if(!n)throw new Error("useBatchContext must be used within a BatchProvider");return n}const W1=n=>!!n.panZoom;function uc(){const n=A1(),r=$e(),i=U1(),l=Ie(W1),u=K.useMemo(()=>{const c=y=>r.getState().nodeLookup.get(y),f=y=>{i.nodeQueue.push(y)},h=y=>{i.edgeQueue.push(y)},p=y=>{var E,L;const{nodeLookup:g,nodeOrigin:w}=r.getState(),S=$h(y)?y:g.get(y.id),M=S.parentId?Vp(S.position,S.measured,S.parentId,g,w):S.position,N={...S,position:M,width:((E=S.measured)==null?void 0:E.width)??S.width,height:((L=S.measured)==null?void 0:L.height)??S.height};return ai(N)},m=(y,g,w={replace:!1})=>{f(S=>S.map(M=>{if(M.id===y){const N=typeof g=="function"?g(M):g;return w.replace&&$h(N)?N:{...M,...N}}return M}))},v=(y,g,w={replace:!1})=>{h(S=>S.map(M=>{if(M.id===y){const N=typeof g=="function"?g(M):g;return w.replace&&H1(N)?N:{...M,...N}}return M}))};return{getNodes:()=>r.getState().nodes.map(y=>({...y})),getNode:y=>{var g;return(g=c(y))==null?void 0:g.internals.userNode},getInternalNode:c,getEdges:()=>{const{edges:y=[]}=r.getState();return y.map(g=>({...g}))},getEdge:y=>r.getState().edgeLookup.get(y),setNodes:f,setEdges:h,addNodes:y=>{const g=Array.isArray(y)?y:[y];i.nodeQueue.push(w=>[...w,...g])},addEdges:y=>{const g=Array.isArray(y)?y:[y];i.edgeQueue.push(w=>[...w,...g])},toObject:()=>{const{nodes:y=[],edges:g=[],transform:w}=r.getState(),[S,M,N]=w;return{nodes:y.map(E=>({...E})),edges:g.map(E=>({...E})),viewport:{x:S,y:M,zoom:N}}},deleteElements:async({nodes:y=[],edges:g=[]})=>{const{nodes:w,edges:S,onNodesDelete:M,onEdgesDelete:N,triggerNodeChanges:E,triggerEdgeChanges:L,onDelete:_,onBeforeDelete:P}=r.getState(),{nodes:U,edges:D}=await dw({nodesToRemove:y,edgesToRemove:g,nodes:w,edges:S,onBeforeDelete:P}),V=D.length>0,X=U.length>0;if(V){const b=D.map(jh);N==null||N(D),L(b)}if(X){const b=U.map(jh);M==null||M(U),E(b)}return(X||V)&&(_==null||_({nodes:U,edges:D})),{deletedNodes:U,deletedEdges:D}},getIntersectingNodes:(y,g=!0,w)=>{const S=lh(y),M=S?y:p(y),N=w!==void 0;return M?(w||r.getState().nodes).filter(E=>{const L=r.getState().nodeLookup.get(E.id);if(L&&!S&&(E.id===y.id||!L.internals.positionAbsolute))return!1;const _=ai(N?E:L),P=sl(_,M);return g&&P>0||P>=_.width*_.height||P>=M.width*M.height}):[]},isNodeIntersecting:(y,g,w=!0)=>{const M=lh(y)?y:p(y);if(!M)return!1;const N=sl(M,g);return w&&N>0||N>=g.width*g.height||N>=M.width*M.height},updateNode:m,updateNodeData:(y,g,w={replace:!1})=>{m(y,S=>{const M=typeof g=="function"?g(S):g;return w.replace?{...S,data:M}:{...S,data:{...S.data,...M}}},w)},updateEdge:v,updateEdgeData:(y,g,w={replace:!1})=>{v(y,S=>{const M=typeof g=="function"?g(S):g;return w.replace?{...S,data:M}:{...S,data:{...S.data,...M}}},w)},getNodesBounds:y=>{const{nodeLookup:g,nodeOrigin:w}=r.getState();return uw(y,{nodeLookup:g,nodeOrigin:w})},getHandleConnections:({type:y,id:g,nodeId:w})=>{var S;return Array.from(((S=r.getState().connectionLookup.get(`${w}-${y}${g?`-${g}`:""}`))==null?void 0:S.values())??[])},getNodeConnections:({type:y,handleId:g,nodeId:w})=>{var S;return Array.from(((S=r.getState().connectionLookup.get(`${w}${y?g?`-${y}-${g}`:`-${y}`:""}`))==null?void 0:S.values())??[])},fitView:async y=>{const g=r.getState().fitViewResolver??gw();return r.setState({fitViewQueued:!0,fitViewOptions:y,fitViewResolver:g}),i.nodeQueue.push(w=>[...w]),g.promise}}},[]);return K.useMemo(()=>({...u,...n,viewportInitialized:l}),[l])}const Oh=n=>n.selected,Y1=typeof window<"u"?window:void 0;function X1({deleteKeyCode:n,multiSelectionKeyCode:r}){const i=$e(),{deleteElements:l}=uc(),u=fi(n,{actInsideInputWithModifier:!1}),c=fi(r,{target:Y1});K.useEffect(()=>{if(u){const{edges:f,nodes:h}=i.getState();l({nodes:h.filter(Oh),edges:f.filter(Oh)}),i.setState({nodesSelectionActive:!1})}},[u]),K.useEffect(()=>{i.setState({multiSelectionActive:c})},[c])}function b1(n){const r=$e();K.useEffect(()=>{const i=()=>{var u,c,f,h;if(!n.current||!(((c=(u=n.current).checkVisibility)==null?void 0:c.call(u))??!0))return!1;const l=nc(n.current);(l.height===0||l.width===0)&&((h=(f=r.getState()).onError)==null||h.call(f,"004",Wt.error004())),r.setState({width:l.width||500,height:l.height||500})};if(n.current){i(),window.addEventListener("resize",i);const l=new ResizeObserver(()=>i());return l.observe(n.current),()=>{window.removeEventListener("resize",i),l&&n.current&&l.unobserve(n.current)}}},[])}const xl={position:"absolute",width:"100%",height:"100%",top:0,left:0},Q1=n=>({userSelectionActive:n.userSelectionActive,lib:n.lib,connectionInProgress:n.connection.inProgress});function G1({onPaneContextMenu:n,zoomOnScroll:r=!0,zoomOnPinch:i=!0,panOnScroll:l=!1,panActivationKeyPressed:u,panOnScrollSpeed:c=.5,panOnScrollMode:f=hr.Free,zoomOnDoubleClick:h=!0,panOnDrag:p=!0,defaultViewport:m,translateExtent:v,minZoom:y,maxZoom:g,zoomActivationKeyCode:w,preventScrolling:S=!0,children:M,noWheelClassName:N,noPanClassName:E,onViewportChange:L,isControlledViewport:_,paneClickDistance:P,selectionOnDrag:U}){const D=$e(),V=K.useRef(null),{userSelectionActive:X,lib:b,connectionInProgress:ee}=Ie(Q1,Ve),q=fi(w),J=K.useRef();b1(V);const Z=K.useCallback(k=>{L==null||L({x:k[0],y:k[1],zoom:k[2]}),_||D.setState({transform:k})},[L,_]);return K.useEffect(()=>{if(V.current){J.current=Zw({domNode:V.current,minZoom:y,maxZoom:g,translateExtent:v,viewport:m,onDraggingChange:H=>D.setState(j=>j.paneDragging===H?j:{paneDragging:H}),onPanZoomStart:(H,j)=>{const{onViewportChangeStart:$,onMoveStart:F}=D.getState();F==null||F(H,j),$==null||$(j)},onPanZoom:(H,j)=>{const{onViewportChange:$,onMove:F}=D.getState();F==null||F(H,j),$==null||$(j)},onPanZoomEnd:(H,j)=>{const{onViewportChangeEnd:$,onMoveEnd:F}=D.getState();F==null||F(H,j),$==null||$(j)}});const{x:k,y:B,zoom:z}=J.current.getViewport();return D.setState({panZoom:J.current,transform:[k,B,z],domNode:V.current.closest(".react-flow")}),()=>{var H;(H=J.current)==null||H.destroy()}}},[]),K.useEffect(()=>{var k;(k=J.current)==null||k.update({onPaneContextMenu:n,zoomOnScroll:r,zoomOnPinch:i,panOnScroll:l,panActivationKeyPressed:u,panOnScrollSpeed:c,panOnScrollMode:f,zoomOnDoubleClick:h,panOnDrag:p,zoomActivationKeyPressed:q,preventScrolling:S,noPanClassName:E,userSelectionActive:X,noWheelClassName:N,lib:b,onTransformChange:Z,connectionInProgress:ee,selectionOnDrag:U,paneClickDistance:P})},[n,r,i,l,u,c,f,h,p,q,S,E,X,N,b,Z,ee,U,P]),T.jsx("div",{className:"react-flow__renderer",ref:V,style:xl,children:M})}const K1=n=>({userSelectionActive:n.userSelectionActive,userSelectionRect:n.userSelectionRect});function q1(){const{userSelectionActive:n,userSelectionRect:r}=Ie(K1,Ve);return n&&r?T.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 Ia=(n,r)=>i=>{i.target===r.current&&(n==null||n(i))},Z1=n=>({userSelectionActive:n.userSelectionActive,elementsSelectable:n.elementsSelectable,dragging:n.paneDragging,panBy:n.panBy,autoPanSpeed:n.autoPanSpeed});function J1({isSelecting:n,selectionKeyPressed:r,selectionMode:i=ui.Full,panOnDrag:l,autoPanOnSelection:u,paneClickDistance:c,selectionOnDrag:f,onSelectionStart:h,onSelectionEnd:p,onPaneClick:m,onPaneContextMenu:v,onPaneScroll:y,onPaneMouseEnter:g,onPaneMouseMove:w,onPaneMouseLeave:S,children:M}){const N=K.useRef(0),E=$e(),{userSelectionActive:L,elementsSelectable:_,dragging:P,panBy:U,autoPanSpeed:D}=Ie(Z1,Ve),V=_&&(n||L),X=K.useRef(null),b=K.useRef(),ee=K.useRef(new Set),q=K.useRef(new Set),J=K.useRef(!1),Z=K.useRef(!1),k=K.useRef({x:0,y:0}),B=K.useRef(!1),z=G=>{if(Z.current||J.current||E.getState().connection.inProgress){Z.current=!1,J.current=!1;return}m==null||m(G),E.getState().resetSelectedElements(),E.setState({nodesSelectionActive:!1})},H=G=>{if(Array.isArray(l)&&(l!=null&&l.includes(2))){G.preventDefault();return}v==null||v(G)},j=y?G=>y(G):void 0,$=G=>{Z.current&&(G.stopPropagation(),Z.current=!1)},F=G=>{var Le,it;if(G.pointerType==="touch"&&l!==!1&&!r)return;const{domNode:se,transform:pe}=E.getState();if(b.current=se==null?void 0:se.getBoundingClientRect(),!b.current)return;const we=G.target===X.current;if(!we&&!!G.target.closest(".nokey")||!n||!(f&&we||r)||G.button!==0||!G.isPrimary)return;(it=(Le=G.target)==null?void 0:Le.setPointerCapture)==null||it.call(Le,G.pointerId),Z.current=!1;const{x:ke,y:Ce}=Ut(G.nativeEvent,b.current),Me=vi({x:ke,y:Ce},pe);E.setState({userSelectionRect:{width:0,height:0,startX:Me.x,startY:Me.y,x:ke,y:Ce}}),we||(G.stopPropagation(),G.preventDefault())};function C(G,se){const{userSelectionRect:pe}=E.getState();if(!pe)return;const{transform:we,nodeLookup:ve,edgeLookup:me,connectionLookup:ke,triggerNodeChanges:Ce,triggerEdgeChanges:Me,defaultEdgeOptions:Le}=E.getState(),it={x:pe.startX,y:pe.startY},{x:ut,y:Je}=oo(it,we),et={startX:it.x,startY:it.y,x:Gat.id)),q.current=new Set;const Qt=(Le==null?void 0:Le.selectable)??!0;for(const at of ee.current){const Ct=ke.get(at);if(Ct)for(const{edgeId:yt}of Ct.values()){const Mt=me.get(yt);Mt&&(Mt.selectable??Qt)&&q.current.add(yt)}}if(!uh(rn,ee.current)){const at=qr(ve,ee.current,!0);Ce(at)}if(!uh(bt,q.current)){const at=qr(me,q.current);Me(at)}E.setState({userSelectionRect:et,userSelectionActive:!0,nodesSelectionActive:!1})}function R(){if(!u||!b.current)return;const[G,se]=ec(k.current,b.current,D);U({x:G,y:se}).then(pe=>{if(!Z.current||!pe){N.current=requestAnimationFrame(R);return}const{x:we,y:ve}=k.current;C(we,ve),N.current=requestAnimationFrame(R)})}const te=()=>{cancelAnimationFrame(N.current),N.current=0,B.current=!1};K.useEffect(()=>()=>te(),[]);const re=G=>{const{userSelectionRect:se,transform:pe,resetSelectedElements:we}=E.getState();if(!b.current||!se)return;const{x:ve,y:me}=Ut(G.nativeEvent,b.current);k.current={x:ve,y:me};const ke=oo({x:se.startX,y:se.startY},pe);if(!Z.current){const Ce=r?0:c;if(Math.hypot(ve-ke.x,me-ke.y)<=Ce)return;we(),h==null||h(G)}Z.current=!0,B.current||(R(),B.current=!0),C(ve,me)},ue=G=>{var se,pe;if(!V){G.target===X.current&&E.getState().connection.inProgress&&(J.current=!0);return}G.button===0&&((pe=(se=G.target)==null?void 0:se.releasePointerCapture)==null||pe.call(se,G.pointerId),!L&&G.target===X.current&&E.getState().userSelectionRect&&(z==null||z(G)),E.setState({userSelectionActive:!1,userSelectionRect:null}),Z.current&&(p==null||p(G),E.setState({nodesSelectionActive:ee.current.size>0})),te())},ce=G=>{var se,pe;(pe=(se=G.target)==null?void 0:se.releasePointerCapture)==null||pe.call(se,G.pointerId),te()},ae=l===!0||Array.isArray(l)&&l.includes(0);return T.jsxs("div",{className:Ye(["react-flow__pane",{draggable:ae,dragging:P,selection:n}]),onClick:V?void 0:Ia(z,X),onContextMenu:Ia(H,X),onWheel:Ia(j,X),onPointerEnter:V?void 0:g,onPointerMove:V?re:w,onPointerUp:ue,onPointerCancel:V?ce:void 0,onPointerDownCapture:V?F:void 0,onClickCapture:V?$:void 0,onPointerLeave:S,ref:X,style:xl,children:[M,T.jsx(q1,{})]})}function Wa({id:n,store:r,unselect:i=!1,nodeRef:l}){const{addSelectedNodes:u,unselectNodesAndEdges:c,multiSelectionActive:f,nodeLookup:h,onError:p}=r.getState(),m=h.get(n);if(!m){p==null||p("012",Wt.error012(n));return}r.setState({nodesSelectionActive:!1}),m.selected?(i||m.selected&&f)&&(c({nodes:[m],edges:[]}),requestAnimationFrame(()=>{var v;return(v=l==null?void 0:l.current)==null?void 0:v.blur()})):u([n])}function gg({nodeRef:n,disabled:r=!1,noDragClassName:i,handleSelector:l,nodeId:u,isSelectable:c,nodeClickDistance:f}){const h=$e(),[p,m]=K.useState(!1),v=K.useRef();return K.useEffect(()=>{if(!r)return v.current=Ow({getStoreItems:()=>h.getState(),onNodeMouseDown:y=>{Wa({id:y,store:h,nodeRef:n})},onDragStart:()=>{m(!0)},onDragStop:()=>{m(!1)}}),()=>{var y;(y=v.current)==null||y.destroy(),v.current=void 0}},[r,h,n]),K.useEffect(()=>{r||!n.current||!v.current||v.current.update({noDragClassName:i,handleSelector:l,domNode:n.current,isSelectable:c,nodeId:u,nodeClickDistance:f})},[i,l,r,c,n,u,f]),p}const eS=n=>r=>r.selected&&(r.draggable||n&&typeof r.draggable>"u");function mg(){const n=$e();return K.useCallback(i=>{const{nodeExtent:l,snapToGrid:u,snapGrid:c,nodesDraggable:f,onError:h,updateNodePositions:p,nodeLookup:m,nodeOrigin:v}=n.getState(),y=new Map,g=eS(f),w=u?c[0]:5,S=u?c[1]:5,M=i.direction.x*w*i.factor,N=i.direction.y*S*i.factor;for(const[,E]of m){if(!g(E))continue;let L={x:E.internals.positionAbsolute.x+M,y:E.internals.positionAbsolute.y+N};u&&(L=yi(L,c));const{position:_,positionAbsolute:P}=jp({nodeId:E.id,nextPosition:L,nodeLookup:m,nodeExtent:l,nodeOrigin:v,onError:h});E.position=_,E.internals.positionAbsolute=P,y.set(E.id,E)}p(y)},[])}const ac=K.createContext(null),tS=ac.Provider;ac.Consumer;const yg=()=>K.useContext(ac),nS=n=>({connectOnClick:n.connectOnClick,noPanClassName:n.noPanClassName,rfId:n.rfId}),vg=K.createContext(null);function rS({children:n}){const r=Ie(nS,Ve);return T.jsx(vg.Provider,{value:r,children:n})}function oS(){const n=K.useContext(vg);if(!n)throw new Error("useHandleConfig must be used within a HandleConfigProvider");return n}const iS={connectingFrom:!1,connectingTo:!1,clickConnecting:!1,isPossibleEndHandle:!0,connectionInProcess:!1,clickConnectionInProcess:!1,valid:!1},sS=(n,r,i)=>l=>{const{connectionClickStartHandle:u,connectionMode:c,connection:f}=l,{fromHandle:h,toHandle:p,isValid:m}=f;if(!h&&!u)return iS;const v=(p==null?void 0:p.nodeId)===n&&(p==null?void 0:p.id)===r&&(p==null?void 0:p.type)===i;return{connectingFrom:(h==null?void 0:h.nodeId)===n&&(h==null?void 0:h.id)===r&&(h==null?void 0:h.type)===i,connectingTo:v,clickConnecting:(u==null?void 0:u.nodeId)===n&&(u==null?void 0:u.id)===r&&(u==null?void 0:u.type)===i,isPossibleEndHandle:c===no.Strict?(h==null?void 0:h.type)!==i:n!==(h==null?void 0:h.nodeId)||r!==(h==null?void 0:h.id),connectionInProcess:!!h,clickConnectionInProcess:!!u,valid:v&&m}};function lS({type:n="source",position:r=xe.Top,isValidConnection:i,isConnectable:l=!0,isConnectableStart:u=!0,isConnectableEnd:c=!0,id:f,onConnect:h,children:p,className:m,onMouseDown:v,onTouchStart:y,...g},w){var B,z;const S=f||null,M=n==="target",N=$e(),E=yg(),{connectOnClick:L,noPanClassName:_,rfId:P}=oS(),{connectingFrom:U,connectingTo:D,clickConnecting:V,isPossibleEndHandle:X,connectionInProcess:b,clickConnectionInProcess:ee,valid:q}=Ie(sS(E,S,n),Ve);E||(z=(B=N.getState()).onError)==null||z.call(B,"010",Wt.error010());const J=H=>{const{defaultEdgeOptions:j,onConnect:$,hasDefaultEdges:F}=N.getState(),C={...j,...H};if(F){const{edges:R,setEdges:te,onError:re}=N.getState();te(F1(C,R,{onError:re}))}$==null||$(C),h==null||h(C)},Z=H=>{if(!E)return;const j=Wp(H.nativeEvent);if(u&&(j&&H.button===0||!j)){const $=N.getState();Ua.onPointerDown(H.nativeEvent,{handleDomNode:H.currentTarget,autoPanOnConnect:$.autoPanOnConnect,connectionMode:$.connectionMode,connectionRadius:$.connectionRadius,domNode:$.domNode,nodeLookup:$.nodeLookup,lib:$.lib,isTarget:M,handleId:S,nodeId:E,flowId:$.rfId,panBy:$.panBy,cancelConnection:$.cancelConnection,onConnectStart:$.onConnectStart,onConnectEnd:(...F)=>{var C,R;return(R=(C=N.getState()).onConnectEnd)==null?void 0:R.call(C,...F)},updateConnection:$.updateConnection,onConnect:J,isValidConnection:i||((...F)=>{var C,R;return((R=(C=N.getState()).isValidConnection)==null?void 0:R.call(C,...F))??!0}),getTransform:()=>N.getState().transform,getFromHandle:()=>N.getState().connection.fromHandle,autoPanSpeed:$.autoPanSpeed,dragThreshold:$.connectionDragThreshold})}j?v==null||v(H):y==null||y(H)},k=H=>{const{onClickConnectStart:j,onClickConnectEnd:$,connectionClickStartHandle:F,connectionMode:C,isValidConnection:R,lib:te,rfId:re,nodeLookup:ue,connection:ce}=N.getState();if(!E||!F&&!u)return;if(!F){j==null||j(H.nativeEvent,{nodeId:E,handleId:S,handleType:n}),N.setState({connectionClickStartHandle:{nodeId:E,type:n,id:S}});return}const ae=Bp(H.target),G=i||R,{connection:se,isValid:pe}=Ua.isValid(H.nativeEvent,{handle:{nodeId:E,id:S,type:n},connectionMode:C,fromNodeId:F.nodeId,fromHandleId:F.id||null,fromType:F.type,isValidConnection:G,flowId:re,doc:ae,lib:te,nodeLookup:ue});pe&&se&&J(se);const we=structuredClone(ce);delete we.inProgress,we.toPosition=we.toHandle?we.toHandle.position:null,$==null||$(H,we),N.setState({connectionClickStartHandle:null})};return T.jsx("div",{"data-handleid":S,"data-nodeid":E,"data-handlepos":r,"data-id":`${P}-${E}-${S}-${n}`,className:Ye(["react-flow__handle",`react-flow__handle-${r}`,"nodrag",_,m,{source:!M,target:M,connectable:l,connectablestart:u,connectableend:c,clickconnecting:V,connectingfrom:U,connectingto:D,valid:q,connectionindicator:l&&(!b||X)&&(b||ee?c:u)}]),onMouseDown:Z,onTouchStart:Z,onClick:L?k:void 0,ref:w,...g,children:p})}const ll=K.memo(dg(lS));function uS({data:n,isConnectable:r,sourcePosition:i=xe.Bottom}){return T.jsxs(T.Fragment,{children:[n==null?void 0:n.label,T.jsx(ll,{type:"source",position:i,isConnectable:r})]})}function aS({data:n,isConnectable:r,targetPosition:i=xe.Top,sourcePosition:l=xe.Bottom}){return T.jsxs(T.Fragment,{children:[T.jsx(ll,{type:"target",position:i,isConnectable:r}),n==null?void 0:n.label,T.jsx(ll,{type:"source",position:l,isConnectable:r})]})}function cS(){return null}function fS({data:n,isConnectable:r,targetPosition:i=xe.Top}){return T.jsxs(T.Fragment,{children:[T.jsx(ll,{type:"target",position:i,isConnectable:r}),n==null?void 0:n.label]})}const ul={ArrowUp:{x:0,y:-1},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0},ArrowRight:{x:1,y:0}},Fh={input:uS,default:aS,output:fS,group:cS};function dS(n){var r,i,l,u;return n.internals.handleBounds===void 0?{width:n.width??n.initialWidth??((r=n.style)==null?void 0:r.width),height:n.height??n.initialHeight??((i=n.style)==null?void 0:i.height)}:{width:n.width??((l=n.style)==null?void 0:l.width),height:n.height??((u=n.style)==null?void 0:u.height)}}const hS=n=>{const{width:r,height:i,x:l,y:u}=mi(n.nodeLookup,{filter:c=>!!c.selected});return{width:Bt(r)?r:null,height:Bt(i)?i:null,userSelectionActive:n.userSelectionActive,transformString:`translate(${n.transform[0]}px,${n.transform[1]}px) scale(${n.transform[2]}) translate(${l}px,${u}px)`}};function pS({onSelectionContextMenu:n,noPanClassName:r,disableKeyboardA11y:i}){const l=$e(),{width:u,height:c,transformString:f,userSelectionActive:h}=Ie(hS,Ve),p=mg(),m=K.useRef(null);K.useEffect(()=>{var w;i||(w=m.current)==null||w.focus({preventScroll:!0})},[i]);const v=!h&&u!==null&&c!==null;if(gg({nodeRef:m,disabled:!v}),!v)return null;const y=n?w=>{const S=l.getState().nodes.filter(M=>M.selected);n(w,S)}:void 0,g=w=>{Object.prototype.hasOwnProperty.call(ul,w.key)&&(w.preventDefault(),p({direction:ul[w.key],factor:w.shiftKey?4:1}))};return T.jsx("div",{className:Ye(["react-flow__nodesselection","react-flow__container",r]),style:{transform:f},children:T.jsx("div",{ref:m,className:"react-flow__nodesselection-rect",onContextMenu:y,tabIndex:i?void 0:-1,onKeyDown:i?void 0:g,style:{width:u,height:c}})})}const Hh=typeof window<"u"?window:void 0,gS=n=>({nodesSelectionActive:n.nodesSelectionActive,userSelectionActive:n.userSelectionActive});function xg({children:n,onPaneClick:r,onPaneMouseEnter:i,onPaneMouseMove:l,onPaneMouseLeave:u,onPaneContextMenu:c,onPaneScroll:f,paneClickDistance:h,deleteKeyCode:p,selectionKeyCode:m,selectionOnDrag:v,selectionMode:y,onSelectionStart:g,onSelectionEnd:w,multiSelectionKeyCode:S,panActivationKeyCode:M,zoomActivationKeyCode:N,elementsSelectable:E,zoomOnScroll:L,zoomOnPinch:_,panOnScroll:P,panOnScrollSpeed:U,panOnScrollMode:D,zoomOnDoubleClick:V,panOnDrag:X,autoPanOnSelection:b,defaultViewport:ee,translateExtent:q,minZoom:J,maxZoom:Z,preventScrolling:k,onSelectionContextMenu:B,noWheelClassName:z,noPanClassName:H,disableKeyboardA11y:j,onViewportChange:$,isControlledViewport:F}){const{nodesSelectionActive:C,userSelectionActive:R}=Ie(gS,Ve),te=fi(m,{target:Hh}),re=fi(M,{target:Hh}),ue=re||X,ce=re||P,ae=v&&ue!==!0,G=te||R||ae;return X1({deleteKeyCode:p,multiSelectionKeyCode:S}),T.jsx(G1,{onPaneContextMenu:c,elementsSelectable:E,zoomOnScroll:L,zoomOnPinch:_,panOnScroll:ce,panActivationKeyPressed:re,panOnScrollSpeed:U,panOnScrollMode:D,zoomOnDoubleClick:V,panOnDrag:!te&&ue,defaultViewport:ee,translateExtent:q,minZoom:J,maxZoom:Z,zoomActivationKeyCode:N,preventScrolling:k,noWheelClassName:z,noPanClassName:H,onViewportChange:$,isControlledViewport:F,paneClickDistance:h,selectionOnDrag:ae,children:T.jsxs(J1,{onSelectionStart:g,onSelectionEnd:w,onPaneClick:r,onPaneMouseEnter:i,onPaneMouseMove:l,onPaneMouseLeave:u,onPaneContextMenu:c,onPaneScroll:f,panOnDrag:ue,autoPanOnSelection:b,isSelecting:!!G,selectionMode:y,selectionKeyPressed:te,paneClickDistance:h,selectionOnDrag:ae,children:[n,C&&T.jsx(pS,{onSelectionContextMenu:B,noPanClassName:H,disableKeyboardA11y:j})]})})}xg.displayName="FlowRenderer";const mS=K.memo(xg),yS=n=>r=>n?Ja(r.nodeLookup,{x:0,y:0,width:r.width,height:r.height},r.transform,!0).map(i=>i.id):Array.from(r.nodeLookup.keys());function vS(n){return Ie(K.useCallback(yS(n),[n]),Ve)}const xS=n=>n.updateNodeInternals;function wS(){const n=Ie(xS),[r]=K.useState(()=>typeof ResizeObserver>"u"?null:new ResizeObserver(i=>{const l=new Map;i.forEach(u=>{const c=u.target.getAttribute("data-id");l.set(c,{id:c,nodeElement:u.target,force:!0})}),n(l)}));return K.useEffect(()=>()=>{r==null||r.disconnect()},[r]),r}function SS({node:n,nodeType:r,hasDimensions:i,resizeObserver:l}){const u=$e(),c=K.useRef(null),f=K.useRef(null),h=K.useRef(n.sourcePosition),p=K.useRef(n.targetPosition),m=K.useRef(r),v=i&&!!n.internals.handleBounds;return K.useEffect(()=>{c.current&&!n.hidden&&(!v||f.current!==c.current)&&(f.current&&(l==null||l.unobserve(f.current)),l==null||l.observe(c.current),f.current=c.current)},[v,n.hidden]),K.useEffect(()=>()=>{f.current&&(l==null||l.unobserve(f.current),f.current=null)},[]),K.useEffect(()=>{if(c.current){const y=m.current!==r,g=h.current!==n.sourcePosition,w=p.current!==n.targetPosition;(y||g||w)&&(m.current=r,h.current=n.sourcePosition,p.current=n.targetPosition,u.getState().updateNodeInternals(new Map([[n.id,{id:n.id,nodeElement:c.current,force:!0}]])))}},[n.id,r,n.sourcePosition,n.targetPosition]),c}function _S({id:n,onClick:r,onMouseEnter:i,onMouseMove:l,onMouseLeave:u,onContextMenu:c,onDoubleClick:f,nodesDraggable:h,elementsSelectable:p,nodesConnectable:m,nodesFocusable:v,resizeObserver:y,noDragClassName:g,noPanClassName:w,disableKeyboardA11y:S,rfId:M,nodeTypes:N,nodeClickDistance:E,onError:L}){const{node:_,internals:P,isParent:U}=Ie(G=>{const se=G.nodeLookup.get(n),pe=G.parentLookup.has(n);return{node:se,internals:se.internals,isParent:pe}},Ve);let D=_.type||"default",V=(N==null?void 0:N[D])||Fh[D];V===void 0&&(L==null||L("003",Wt.error003(D)),D="default",V=(N==null?void 0:N.default)||Fh.default);const X=!!(_.draggable||h&&typeof _.draggable>"u"),b=!!(_.selectable||p&&typeof _.selectable>"u"),ee=!!(_.connectable||m&&typeof _.connectable>"u"),q=!!(_.focusable||v&&typeof _.focusable>"u"),J=$e(),Z=Hp(_),k=SS({node:_,nodeType:D,hasDimensions:Z,resizeObserver:y}),B=gg({nodeRef:k,disabled:_.hidden||!X,noDragClassName:g,handleSelector:_.dragHandle,nodeId:n,isSelectable:b,nodeClickDistance:E}),z=mg();if(_.hidden)return null;const H=Xt(_),j=dS(_),$=b||X||r||i||l||u,F=i?G=>i(G,{...P.userNode}):void 0,C=l?G=>l(G,{...P.userNode}):void 0,R=u?G=>u(G,{...P.userNode}):void 0,te=c?G=>c(G,{...P.userNode}):void 0,re=f?G=>f(G,{...P.userNode}):void 0,ue=G=>{const{selectNodesOnDrag:se,nodeDragThreshold:pe}=J.getState();b&&(!se||!X||pe>0)&&Wa({id:n,store:J,nodeRef:k}),r&&r(G,{...P.userNode})},ce=G=>{if(!(Up(G.nativeEvent)||S)){if(zp.includes(G.key)&&b){const se=G.key==="Escape";Wa({id:n,store:J,unselect:se,nodeRef:k})}else if(X&&_.selected&&Object.prototype.hasOwnProperty.call(ul,G.key)){G.preventDefault();const{ariaLabelConfig:se}=J.getState();J.setState({ariaLiveMessage:se["node.a11yDescription.ariaLiveMessage"]({direction:G.key.replace("Arrow","").toLowerCase(),x:~~P.positionAbsolute.x,y:~~P.positionAbsolute.y})}),z({direction:ul[G.key],factor:G.shiftKey?4:1})}}},ae=()=>{var ke;if(S||!((ke=k.current)!=null&&ke.matches(":focus-visible")))return;const{transform:G,width:se,height:pe,autoPanOnNodeFocus:we,setCenter:ve}=J.getState();if(!we)return;Ja(new Map([[n,_]]),{x:0,y:0,width:se,height:pe},G,!0).length>0||ve(_.position.x+H.width/2,_.position.y+H.height/2,{zoom:G[2]})};return T.jsx("div",{className:Ye(["react-flow__node",`react-flow__node-${D}`,{[w]:X},_.className,{selected:_.selected,selectable:b,parent:U,draggable:X,dragging:B}]),ref:k,style:{zIndex:P.z,transform:`translate(${P.positionAbsolute.x}px,${P.positionAbsolute.y}px)`,pointerEvents:$?"all":"none",visibility:Z?"visible":"hidden",..._.style,...j},"data-id":n,"data-testid":`rf__node-${n}`,onMouseEnter:F,onMouseMove:C,onMouseLeave:R,onContextMenu:te,onClick:ue,onDoubleClick:re,onKeyDown:q?ce:void 0,tabIndex:q?0:void 0,onFocus:q?ae:void 0,role:_.ariaRole??(q?"group":void 0),"aria-roledescription":"node","aria-describedby":S?void 0:`${ug}-${M}`,"aria-label":_.ariaLabel,..._.domAttributes,children:T.jsx(tS,{value:n,children:T.jsx(V,{id:n,data:_.data,type:D,positionAbsoluteX:P.positionAbsolute.x,positionAbsoluteY:P.positionAbsolute.y,selected:_.selected??!1,selectable:b,draggable:X,deletable:_.deletable??!0,isConnectable:ee,sourcePosition:_.sourcePosition,targetPosition:_.targetPosition,dragging:B,dragHandle:_.dragHandle,zIndex:P.z,parentId:_.parentId,...H})})})}var ES=K.memo(_S);const kS=n=>({nodesConnectable:n.nodesConnectable,nodesFocusable:n.nodesFocusable,elementsSelectable:n.elementsSelectable,onError:n.onError});function wg(n){const{nodesConnectable:r,nodesFocusable:i,elementsSelectable:l,onError:u}=Ie(kS,Ve),c=vS(n.onlyRenderVisibleElements),f=wS();return T.jsx("div",{className:"react-flow__nodes",style:xl,children:c.map(h=>T.jsx(ES,{id:h,nodeTypes:n.nodeTypes,nodeExtent:n.nodeExtent,onClick:n.onNodeClick,onMouseEnter:n.onNodeMouseEnter,onMouseMove:n.onNodeMouseMove,onMouseLeave:n.onNodeMouseLeave,onContextMenu:n.onNodeContextMenu,onDoubleClick:n.onNodeDoubleClick,noDragClassName:n.noDragClassName,noPanClassName:n.noPanClassName,rfId:n.rfId,disableKeyboardA11y:n.disableKeyboardA11y,resizeObserver:f,nodesDraggable:n.nodesDraggable??!0,nodesConnectable:r,nodesFocusable:i,elementsSelectable:l,nodeClickDistance:n.nodeClickDistance,onError:u},h))})}wg.displayName="NodeRenderer";const NS=K.memo(wg);function CS(n){return Ie(K.useCallback(i=>{if(!n)return i.edges.map(u=>u.id);const l=[];if(i.width&&i.height)for(const u of i.edges){const c=i.nodeLookup.get(u.source),f=i.nodeLookup.get(u.target);c&&f&&xw({sourceNode:c,targetNode:f,width:i.width,height:i.height,transform:i.transform})&&l.push(u.id)}return l},[n]),Ve)}const MS=({color:n="none",strokeWidth:r=1})=>{const i={strokeWidth:r,...n&&{stroke:n}};return T.jsx("polyline",{className:"arrow",style:i,strokeLinecap:"round",fill:"none",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4"})},PS=({color:n="none",strokeWidth:r=1})=>{const i={strokeWidth:r,...n&&{stroke:n,fill:n}};return T.jsx("polyline",{className:"arrowclosed",style:i,strokeLinecap:"round",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4 -5,-4"})},Vh={[ol.Arrow]:MS,[ol.ArrowClosed]:PS};function IS(n){const r=$e();return K.useMemo(()=>{var u,c;return Object.prototype.hasOwnProperty.call(Vh,n)?Vh[n]:((c=(u=r.getState()).onError)==null||c.call(u,"009",Wt.error009(n)),null)},[n])}const zS=({id:n,type:r,color:i,width:l=12.5,height:u=12.5,markerUnits:c="strokeWidth",strokeWidth:f,orient:h="auto-start-reverse"})=>{const p=IS(r);return p?T.jsx("marker",{className:"react-flow__arrowhead",id:n,markerWidth:`${l}`,markerHeight:`${u}`,viewBox:"-10 -10 20 20",markerUnits:c,orient:h,refX:"0",refY:"0",children:T.jsx(p,{color:i,strokeWidth:f})}):null},Sg=({defaultColor:n,rfId:r})=>{const i=Ie(c=>c.edges),l=Ie(c=>c.defaultEdgeOptions),u=K.useMemo(()=>Mw(i,{id:r,defaultColor:n,defaultMarkerStart:l==null?void 0:l.markerStart,defaultMarkerEnd:l==null?void 0:l.markerEnd}),[i,l,r,n]);return u.length?T.jsx("svg",{className:"react-flow__marker","aria-hidden":"true",children:T.jsx("defs",{children:u.map(c=>T.jsx(zS,{id:c.id,type:c.type,color:c.color,width:c.width,height:c.height,markerUnits:c.markerUnits,strokeWidth:c.strokeWidth,orient:c.orient},c.id))})}):null};Sg.displayName="MarkerDefinitions";var TS=K.memo(Sg);function _g({x:n,y:r,label:i,labelStyle:l,labelShowBg:u=!0,labelBgStyle:c,labelBgPadding:f=[2,4],labelBgBorderRadius:h=2,children:p,className:m,...v}){const[y,g]=K.useState({x:1,y:0,width:0,height:0}),w=Ye(["react-flow__edge-textwrapper",m]),S=K.useRef(null);return K.useEffect(()=>{if(S.current){const M=S.current.getBBox();g({x:M.x,y:M.y,width:M.width,height:M.height})}},[i]),i?T.jsxs("g",{transform:`translate(${n-y.width/2} ${r-y.height/2})`,className:w,visibility:y.width?"visible":"hidden",...v,children:[u&&T.jsx("rect",{width:y.width+2*f[0],x:-f[0],y:-f[1],height:y.height+2*f[1],className:"react-flow__edge-textbg",style:c,rx:h,ry:h}),T.jsx("text",{className:"react-flow__edge-text",y:y.height/2,dy:"0.3em",ref:S,style:l,children:i}),p]}):null}_g.displayName="EdgeText";const LS=K.memo(_g);function wl({path:n,labelX:r,labelY:i,label:l,labelStyle:u,labelShowBg:c,labelBgStyle:f,labelBgPadding:h,labelBgBorderRadius:p,interactionWidth:m=20,...v}){return T.jsxs(T.Fragment,{children:[T.jsx("path",{...v,d:n,fill:"none",className:Ye(["react-flow__edge-path",v.className])}),m?T.jsx("path",{d:n,fill:"none",strokeOpacity:0,strokeWidth:m,className:"react-flow__edge-interaction"}):null,l&&Bt(r)&&Bt(i)?T.jsx(LS,{x:r,y:i,label:l,labelStyle:u,labelShowBg:c,labelBgStyle:f,labelBgPadding:h,labelBgBorderRadius:p}):null]})}function Bh({pos:n,x1:r,y1:i,x2:l,y2:u}){return n===xe.Left||n===xe.Right?[.5*(r+l),i]:[r,.5*(i+u)]}function Eg({sourceX:n,sourceY:r,sourcePosition:i=xe.Bottom,targetX:l,targetY:u,targetPosition:c=xe.Top}){const[f,h]=Bh({pos:i,x1:n,y1:r,x2:l,y2:u}),[p,m]=Bh({pos:c,x1:l,y1:u,x2:n,y2:r}),[v,y,g,w]=Yp({sourceX:n,sourceY:r,targetX:l,targetY:u,sourceControlX:f,sourceControlY:h,targetControlX:p,targetControlY:m});return[`M${n},${r} C${f},${h} ${p},${m} ${l},${u}`,v,y,g,w]}function kg(n){return K.memo(({id:r,sourceX:i,sourceY:l,targetX:u,targetY:c,sourcePosition:f,targetPosition:h,label:p,labelStyle:m,labelShowBg:v,labelBgStyle:y,labelBgPadding:g,labelBgBorderRadius:w,style:S,markerEnd:M,markerStart:N,interactionWidth:E})=>{const[L,_,P]=Eg({sourceX:i,sourceY:l,sourcePosition:f,targetX:u,targetY:c,targetPosition:h}),U=n.isInternal?void 0:r;return T.jsx(wl,{id:U,path:L,labelX:_,labelY:P,label:p,labelStyle:m,labelShowBg:v,labelBgStyle:y,labelBgPadding:g,labelBgBorderRadius:w,style:S,markerEnd:M,markerStart:N,interactionWidth:E})})}const RS=kg({isInternal:!1}),Ng=kg({isInternal:!0});RS.displayName="SimpleBezierEdge";Ng.displayName="SimpleBezierEdgeInternal";function Cg(n){return K.memo(({id:r,sourceX:i,sourceY:l,targetX:u,targetY:c,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:m,labelBgPadding:v,labelBgBorderRadius:y,style:g,sourcePosition:w=xe.Bottom,targetPosition:S=xe.Top,markerEnd:M,markerStart:N,pathOptions:E,interactionWidth:L})=>{const[_,P,U]=Ha({sourceX:i,sourceY:l,sourcePosition:w,targetX:u,targetY:c,targetPosition:S,borderRadius:E==null?void 0:E.borderRadius,offset:E==null?void 0:E.offset,stepPosition:E==null?void 0:E.stepPosition}),D=n.isInternal?void 0:r;return T.jsx(wl,{id:D,path:_,labelX:P,labelY:U,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:m,labelBgPadding:v,labelBgBorderRadius:y,style:g,markerEnd:M,markerStart:N,interactionWidth:L})})}const Mg=Cg({isInternal:!1}),Pg=Cg({isInternal:!0});Mg.displayName="SmoothStepEdge";Pg.displayName="SmoothStepEdgeInternal";function Ig(n){return K.memo(({id:r,...i})=>{var u;const l=n.isInternal?void 0:r;return T.jsx(Mg,{...i,id:l,pathOptions:K.useMemo(()=>{var c;return{borderRadius:0,offset:(c=i.pathOptions)==null?void 0:c.offset}},[(u=i.pathOptions)==null?void 0:u.offset])})})}const AS=Ig({isInternal:!1}),zg=Ig({isInternal:!0});AS.displayName="StepEdge";zg.displayName="StepEdgeInternal";function Tg(n){return K.memo(({id:r,sourceX:i,sourceY:l,targetX:u,targetY:c,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:m,labelBgPadding:v,labelBgBorderRadius:y,style:g,markerEnd:w,markerStart:S,interactionWidth:M})=>{const[N,E,L]=Qp({sourceX:i,sourceY:l,targetX:u,targetY:c}),_=n.isInternal?void 0:r;return T.jsx(wl,{id:_,path:N,labelX:E,labelY:L,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:m,labelBgPadding:v,labelBgBorderRadius:y,style:g,markerEnd:w,markerStart:S,interactionWidth:M})})}const jS=Tg({isInternal:!1}),Lg=Tg({isInternal:!0});jS.displayName="StraightEdge";Lg.displayName="StraightEdgeInternal";function Rg(n){return K.memo(({id:r,sourceX:i,sourceY:l,targetX:u,targetY:c,sourcePosition:f=xe.Bottom,targetPosition:h=xe.Top,label:p,labelStyle:m,labelShowBg:v,labelBgStyle:y,labelBgPadding:g,labelBgBorderRadius:w,style:S,markerEnd:M,markerStart:N,pathOptions:E,interactionWidth:L})=>{const[_,P,U]=Xp({sourceX:i,sourceY:l,sourcePosition:f,targetX:u,targetY:c,targetPosition:h,curvature:E==null?void 0:E.curvature}),D=n.isInternal?void 0:r;return T.jsx(wl,{id:D,path:_,labelX:P,labelY:U,label:p,labelStyle:m,labelShowBg:v,labelBgStyle:y,labelBgPadding:g,labelBgBorderRadius:w,style:S,markerEnd:M,markerStart:N,interactionWidth:L})})}const $S=Rg({isInternal:!1}),Ag=Rg({isInternal:!0});$S.displayName="BezierEdge";Ag.displayName="BezierEdgeInternal";const Uh={default:Ag,straight:Lg,step:zg,smoothstep:Pg,simplebezier:Ng},Wh={sourceX:null,sourceY:null,targetX:null,targetY:null,sourcePosition:null,targetPosition:null,zIndex:void 0},DS=(n,r,i)=>i===xe.Left?n-r:i===xe.Right?n+r:n,OS=(n,r,i)=>i===xe.Top?n-r:i===xe.Bottom?n+r:n,Yh="react-flow__edgeupdater";function Xh({position:n,centerX:r,centerY:i,radius:l=10,onMouseDown:u,onMouseEnter:c,onMouseOut:f,type:h}){return T.jsx("circle",{onMouseDown:u,onMouseEnter:c,onMouseOut:f,className:Ye([Yh,`${Yh}-${h}`]),cx:DS(r,l,n),cy:OS(i,l,n),r:l,stroke:"transparent",fill:"transparent"})}function FS({isReconnectable:n,reconnectRadius:r,edge:i,sourceX:l,sourceY:u,targetX:c,targetY:f,sourcePosition:h,targetPosition:p,onReconnect:m,onReconnectStart:v,onReconnectEnd:y,setReconnecting:g,setUpdateHover:w}){const S=$e(),M=(P,U)=>{if(P.button!==0)return;const{autoPanOnConnect:D,domNode:V,connectionMode:X,connectionRadius:b,lib:ee,onConnectStart:q,cancelConnection:J,nodeLookup:Z,rfId:k,panBy:B,updateConnection:z}=S.getState(),H=U.type==="target",j=(C,R)=>{g(!1),y==null||y(C,i,U.type,R)},$=C=>m==null?void 0:m(i,C),F=(C,R)=>{g(!0),v==null||v(P,i,U.type),q==null||q(C,R)};Ua.onPointerDown(P.nativeEvent,{autoPanOnConnect:D,connectionMode:X,connectionRadius:b,domNode:V,handleId:U.id,nodeId:U.nodeId,nodeLookup:Z,isTarget:H,edgeUpdaterType:U.type,lib:ee,flowId:k,cancelConnection:J,panBy:B,isValidConnection:(...C)=>{var R,te;return((te=(R=S.getState()).isValidConnection)==null?void 0:te.call(R,...C))??!0},onConnect:$,onConnectStart:F,onConnectEnd:(...C)=>{var R,te;return(te=(R=S.getState()).onConnectEnd)==null?void 0:te.call(R,...C)},onReconnectEnd:j,updateConnection:z,getTransform:()=>S.getState().transform,getFromHandle:()=>S.getState().connection.fromHandle,dragThreshold:S.getState().connectionDragThreshold,handleDomNode:P.currentTarget})},N=P=>M(P,{nodeId:i.target,id:i.targetHandle??null,type:"target"}),E=P=>M(P,{nodeId:i.source,id:i.sourceHandle??null,type:"source"}),L=()=>w(!0),_=()=>w(!1);return T.jsxs(T.Fragment,{children:[(n===!0||n==="source")&&T.jsx(Xh,{position:h,centerX:l,centerY:u,radius:r,onMouseDown:N,onMouseEnter:L,onMouseOut:_,type:"source"}),(n===!0||n==="target")&&T.jsx(Xh,{position:p,centerX:c,centerY:f,radius:r,onMouseDown:E,onMouseEnter:L,onMouseOut:_,type:"target"})]})}function HS({id:n,edgesFocusable:r,edgesReconnectable:i,elementsSelectable:l,onClick:u,onDoubleClick:c,onContextMenu:f,onMouseEnter:h,onMouseMove:p,onMouseLeave:m,reconnectRadius:v,onReconnect:y,onReconnectStart:g,onReconnectEnd:w,rfId:S,edgeTypes:M,noPanClassName:N,onError:E,disableKeyboardA11y:L}){let _=Ie(ve=>ve.edgeLookup.get(n));const P=Ie(ve=>ve.defaultEdgeOptions);_=P?{...P,..._}:_;let U=_.type||"default",D=(M==null?void 0:M[U])||Uh[U];D===void 0&&(E==null||E("011",Wt.error011(U)),U="default",D=(M==null?void 0:M.default)||Uh.default);const V=!!(_.focusable||r&&typeof _.focusable>"u"),X=typeof y<"u"&&(_.reconnectable||i&&typeof _.reconnectable>"u"),b=!!(_.selectable||l&&typeof _.selectable>"u"),ee=K.useRef(null),[q,J]=K.useState(!1),[Z,k]=K.useState(!1),B=$e(),{zIndex:z=_.zIndex,sourceX:H,sourceY:j,targetX:$,targetY:F,sourcePosition:C,targetPosition:R}=Ie(K.useCallback(ve=>{const me=ve.nodeLookup.get(_.source),ke=ve.nodeLookup.get(_.target);if(!me||!ke)return Wh;const Ce=Cw({id:n,sourceNode:me,targetNode:ke,sourceHandle:_.sourceHandle||null,targetHandle:_.targetHandle||null,connectionMode:ve.connectionMode,onError:E}),Me=vw({selected:_.selected,zIndex:_.zIndex,sourceNode:me,targetNode:ke,elevateOnSelect:ve.elevateEdgesOnSelect,zIndexMode:ve.zIndexMode});return{...Ce||Wh,zIndex:Me}},[_.source,_.target,_.sourceHandle,_.targetHandle,_.selected,_.zIndex,E]),Ve),te=K.useMemo(()=>_.markerStart?`url('#${Va(_.markerStart,S)}')`:void 0,[_.markerStart,S]),re=K.useMemo(()=>_.markerEnd?`url('#${Va(_.markerEnd,S)}')`:void 0,[_.markerEnd,S]);if(_.hidden||H===null||j===null||$===null||F===null)return null;const ue=ve=>{var Me;const{addSelectedEdges:me,unselectNodesAndEdges:ke,multiSelectionActive:Ce}=B.getState();b&&(B.setState({nodesSelectionActive:!1}),_.selected&&Ce?(ke({nodes:[],edges:[_]}),(Me=ee.current)==null||Me.blur()):me([n])),u&&u(ve,_)},ce=c?ve=>{c(ve,{..._})}:void 0,ae=f?ve=>{f(ve,{..._})}:void 0,G=h?ve=>{h(ve,{..._})}:void 0,se=p?ve=>{p(ve,{..._})}:void 0,pe=m?ve=>{m(ve,{..._})}:void 0,we=ve=>{var me;if(!L&&zp.includes(ve.key)&&b){const{unselectNodesAndEdges:ke,addSelectedEdges:Ce}=B.getState();ve.key==="Escape"?((me=ee.current)==null||me.blur(),ke({edges:[_]})):Ce([n])}};return T.jsx("svg",{style:{zIndex:z},children:T.jsxs("g",{className:Ye(["react-flow__edge",`react-flow__edge-${U}`,_.className,N,{selected:_.selected,animated:_.animated,inactive:!b&&!u,updating:q,selectable:b}]),onClick:ue,onDoubleClick:ce,onContextMenu:ae,onMouseEnter:G,onMouseMove:se,onMouseLeave:pe,onKeyDown:V?we:void 0,tabIndex:V?0:void 0,role:_.ariaRole??(V?"group":"img"),"aria-roledescription":"edge","data-id":n,"data-testid":`rf__edge-${n}`,"aria-label":_.ariaLabel===null?void 0:_.ariaLabel||`Edge from ${_.source} to ${_.target}`,"aria-describedby":V?`${ag}-${S}`:void 0,ref:ee,..._.domAttributes,children:[!Z&&T.jsx(D,{id:n,source:_.source,target:_.target,type:_.type,selected:_.selected,animated:_.animated,selectable:b,deletable:_.deletable??!0,label:_.label,labelStyle:_.labelStyle,labelShowBg:_.labelShowBg,labelBgStyle:_.labelBgStyle,labelBgPadding:_.labelBgPadding,labelBgBorderRadius:_.labelBgBorderRadius,sourceX:H,sourceY:j,targetX:$,targetY:F,sourcePosition:C,targetPosition:R,data:_.data,style:_.style,sourceHandleId:_.sourceHandle,targetHandleId:_.targetHandle,markerStart:te,markerEnd:re,pathOptions:"pathOptions"in _?_.pathOptions:void 0,interactionWidth:_.interactionWidth}),X&&T.jsx(FS,{edge:_,isReconnectable:X,reconnectRadius:v,onReconnect:y,onReconnectStart:g,onReconnectEnd:w,sourceX:H,sourceY:j,targetX:$,targetY:F,sourcePosition:C,targetPosition:R,setUpdateHover:J,setReconnecting:k})]})})}var VS=K.memo(HS);const BS=n=>({edgesFocusable:n.edgesFocusable,edgesReconnectable:n.edgesReconnectable,elementsSelectable:n.elementsSelectable,connectionMode:n.connectionMode,onError:n.onError});function jg({defaultMarkerColor:n,onlyRenderVisibleElements:r,rfId:i,edgeTypes:l,noPanClassName:u,onReconnect:c,onEdgeContextMenu:f,onEdgeMouseEnter:h,onEdgeMouseMove:p,onEdgeMouseLeave:m,onEdgeClick:v,reconnectRadius:y,onEdgeDoubleClick:g,onReconnectStart:w,onReconnectEnd:S,disableKeyboardA11y:M}){const{edgesFocusable:N,edgesReconnectable:E,elementsSelectable:L,onError:_}=Ie(BS,Ve),P=CS(r);return T.jsxs("div",{className:"react-flow__edges",children:[T.jsx(TS,{defaultColor:n,rfId:i}),P.map(U=>T.jsx(VS,{id:U,edgesFocusable:N,edgesReconnectable:E,elementsSelectable:L,noPanClassName:u,onReconnect:c,onContextMenu:f,onMouseEnter:h,onMouseMove:p,onMouseLeave:m,onClick:v,reconnectRadius:y,onDoubleClick:g,onReconnectStart:w,onReconnectEnd:S,rfId:i,onError:_,edgeTypes:l,disableKeyboardA11y:M},U))]})}jg.displayName="EdgeRenderer";const US=K.memo(jg),bh=n=>`translate(${n[0]}px,${n[1]}px) scale(${n[2]})`;function WS({children:n}){const r=$e(),i=K.useRef(null),[l]=K.useState(()=>r.getState().transform);return hg(()=>{let u=null;const c=()=>{const f=r.getState().transform;u&&f[0]===u[0]&&f[1]===u[1]&&f[2]===u[2]||(u=f,i.current&&(i.current.style.transform=bh(f)))};return c(),r.subscribe(c)},[r]),T.jsx("div",{ref:i,className:"react-flow__viewport xyflow__viewport react-flow__container",style:{transform:bh(l)},children:n})}function YS(n){const r=uc(),i=K.useRef(!1);K.useEffect(()=>{!i.current&&r.viewportInitialized&&n&&(setTimeout(()=>n(r),1),i.current=!0)},[n,r.viewportInitialized])}const XS=n=>{var r;return(r=n.panZoom)==null?void 0:r.syncViewport};function bS(n){const r=Ie(XS),i=$e();return K.useEffect(()=>{n&&(r==null||r(n),i.setState({transform:[n.x,n.y,n.zoom]}))},[n,r]),null}function QS(n){return n.connection.inProgress?{...n.connection,to:vi(n.connection.to,n.transform)}:{...n.connection}}function GS(n){return QS}function KS(n){const r=GS();return Ie(r,Ve)}const qS=n=>({nodesConnectable:n.nodesConnectable,isValid:n.connection.isValid,inProgress:n.connection.inProgress,width:n.width,height:n.height});function ZS({containerStyle:n,style:r,type:i,component:l}){const{nodesConnectable:u,width:c,height:f,isValid:h,inProgress:p}=Ie(qS,Ve);return!(c&&u&&p)?null:T.jsx("svg",{style:n,width:c,height:f,className:"react-flow__connectionline react-flow__container",children:T.jsx("g",{className:Ye(["react-flow__connection",Rp(h)]),children:T.jsx($g,{style:r,type:i,CustomComponent:l,isValid:h})})})}const $g=({style:n,type:r=Un.Bezier,CustomComponent:i,isValid:l})=>{const{inProgress:u,from:c,fromNode:f,fromHandle:h,fromPosition:p,to:m,toNode:v,toHandle:y,toPosition:g,pointer:w}=KS();if(!u)return;if(i)return T.jsx(i,{connectionLineType:r,connectionLineStyle:n,fromNode:f,fromHandle:h,fromX:c.x,fromY:c.y,toX:m.x,toY:m.y,fromPosition:p,toPosition:g,connectionStatus:Rp(l),toNode:v,toHandle:y,pointer:w});let S="";const M={sourceX:c.x,sourceY:c.y,sourcePosition:p,targetX:m.x,targetY:m.y,targetPosition:g};switch(r){case Un.Bezier:[S]=Xp(M);break;case Un.SimpleBezier:[S]=Eg(M);break;case Un.Step:[S]=Ha({...M,borderRadius:0});break;case Un.SmoothStep:[S]=Ha(M);break;default:[S]=Qp(M)}return T.jsx("path",{d:S,fill:"none",className:"react-flow__connection-path",style:n})};$g.displayName="ConnectionLine";const JS={};function Qh(n=JS){K.useRef(n),$e(),K.useEffect(()=>{},[n])}function e_(){$e(),K.useRef(!1),K.useEffect(()=>{},[])}function Dg({nodeTypes:n,edgeTypes:r,onInit:i,onNodeClick:l,onEdgeClick:u,onNodeDoubleClick:c,onEdgeDoubleClick:f,onNodeMouseEnter:h,onNodeMouseMove:p,onNodeMouseLeave:m,onNodeContextMenu:v,onSelectionContextMenu:y,onSelectionStart:g,onSelectionEnd:w,connectionLineType:S,connectionLineStyle:M,connectionLineComponent:N,connectionLineContainerStyle:E,selectionKeyCode:L,selectionOnDrag:_,selectionMode:P,multiSelectionKeyCode:U,panActivationKeyCode:D,zoomActivationKeyCode:V,deleteKeyCode:X,onlyRenderVisibleElements:b,elementsSelectable:ee,defaultViewport:q,translateExtent:J,minZoom:Z,maxZoom:k,preventScrolling:B,defaultMarkerColor:z,zoomOnScroll:H,zoomOnPinch:j,panOnScroll:$,panOnScrollSpeed:F,panOnScrollMode:C,zoomOnDoubleClick:R,panOnDrag:te,autoPanOnSelection:re,onPaneClick:ue,onPaneMouseEnter:ce,onPaneMouseMove:ae,onPaneMouseLeave:G,onPaneScroll:se,onPaneContextMenu:pe,paneClickDistance:we,nodeClickDistance:ve,onEdgeContextMenu:me,onEdgeMouseEnter:ke,onEdgeMouseMove:Ce,onEdgeMouseLeave:Me,reconnectRadius:Le,onReconnect:it,onReconnectStart:ut,onReconnectEnd:Je,noDragClassName:et,noWheelClassName:rn,noPanClassName:bt,disableKeyboardA11y:Qt,nodeExtent:at,rfId:Ct,viewport:yt,onViewportChange:Mt,nodesDraggable:xr}){return Qh(n),Qh(r),e_(),YS(i),bS(yt),T.jsx(mS,{onPaneClick:ue,onPaneMouseEnter:ce,onPaneMouseMove:ae,onPaneMouseLeave:G,onPaneContextMenu:pe,onPaneScroll:se,paneClickDistance:we,deleteKeyCode:X,selectionKeyCode:L,selectionOnDrag:_,selectionMode:P,onSelectionStart:g,onSelectionEnd:w,multiSelectionKeyCode:U,panActivationKeyCode:D,zoomActivationKeyCode:V,elementsSelectable:ee,zoomOnScroll:H,zoomOnPinch:j,zoomOnDoubleClick:R,panOnScroll:$,panOnScrollSpeed:F,panOnScrollMode:C,panOnDrag:te,autoPanOnSelection:re,defaultViewport:q,translateExtent:J,minZoom:Z,maxZoom:k,onSelectionContextMenu:y,preventScrolling:B,noDragClassName:et,noWheelClassName:rn,noPanClassName:bt,disableKeyboardA11y:Qt,onViewportChange:Mt,isControlledViewport:!!yt,children:T.jsxs(WS,{children:[T.jsx(US,{edgeTypes:r,onEdgeClick:u,onEdgeDoubleClick:f,onReconnect:it,onReconnectStart:ut,onReconnectEnd:Je,onlyRenderVisibleElements:b,onEdgeContextMenu:me,onEdgeMouseEnter:ke,onEdgeMouseMove:Ce,onEdgeMouseLeave:Me,reconnectRadius:Le,defaultMarkerColor:z,noPanClassName:bt,disableKeyboardA11y:Qt,rfId:Ct}),T.jsx(ZS,{style:M,type:S,component:N,containerStyle:E}),T.jsx("div",{className:"react-flow__edgelabel-renderer"}),T.jsx(NS,{nodeTypes:n,onNodeClick:l,onNodeDoubleClick:c,onNodeMouseEnter:h,onNodeMouseMove:p,onNodeMouseLeave:m,onNodeContextMenu:v,nodeClickDistance:ve,onlyRenderVisibleElements:b,noPanClassName:bt,noDragClassName:et,disableKeyboardA11y:Qt,nodeExtent:at,rfId:Ct,nodesDraggable:xr}),T.jsx("div",{className:"react-flow__viewport-portal"})]})})}Dg.displayName="GraphView";const t_=K.memo(Dg),n_=Fp(),Gh=({nodes:n,edges:r,defaultNodes:i,defaultEdges:l,width:u,height:c,fitView:f,fitViewOptions:h,minZoom:p=.5,maxZoom:m=2,nodeOrigin:v,nodeExtent:y,zIndexMode:g="basic"}={})=>{const w=new Map,S=new Map,M=new Map,N=new Map,E=l??r??[],L=i??n??[],_=v??[0,0],P=y??li;qp(M,N,E);const{nodesInitialized:U}=Ba(L,w,S,{nodeOrigin:_,nodeExtent:P,zIndexMode:g});let D=[0,0,1];if(f&&u&&c){const V=mi(w,{filter:q=>!!((q.width||q.initialWidth)&&(q.height||q.initialHeight))}),{x:X,y:b,zoom:ee}=tc(V,u,c,p,m,(h==null?void 0:h.padding)??.1);D=[X,b,ee]}return{rfId:"1",width:u??0,height:c??0,transform:D,nodes:L,nodesInitialized:U,nodeLookup:w,parentLookup:S,edges:E,edgeLookup:N,connectionLookup:M,onNodesChange:null,onEdgesChange:null,hasDefaultNodes:i!==void 0,hasDefaultEdges:l!==void 0,panZoom:null,minZoom:p,maxZoom:m,translateExtent:li,nodeExtent:P,nodesSelectionActive:!1,userSelectionActive:!1,userSelectionRect:null,connectionMode:no.Strict,domNode:null,paneDragging:!1,noPanClassName:"nopan",nodeOrigin:_,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:f??!1,fitViewOptions:h,fitViewResolver:null,connection:{...Lp},connectionClickStartHandle:null,connectOnClick:!0,ariaLiveMessage:"",autoPanOnConnect:!0,autoPanOnNodeDrag:!0,autoPanOnNodeFocus:!0,autoPanSpeed:15,connectionRadius:20,onError:n_,isValidConnection:void 0,onSelectionChangeHandlers:[],lib:"react",debug:!1,ariaLabelConfig:Tp,zIndexMode:g,onNodesChangeMiddlewareMap:new Map,onEdgesChangeMiddlewareMap:new Map}},r_=({nodes:n,edges:r,defaultNodes:i,defaultEdges:l,width:u,height:c,fitView:f,fitViewOptions:h,minZoom:p,maxZoom:m,nodeOrigin:v,nodeExtent:y,zIndexMode:g})=>g1((w,S)=>{async function M(){const{nodeLookup:N,panZoom:E,fitViewOptions:L,fitViewResolver:_,width:P,height:U,minZoom:D,maxZoom:V}=S();E&&(await fw({nodes:N,width:P,height:U,panZoom:E,minZoom:D,maxZoom:V},L),_==null||_.resolve(!0),w({fitViewResolver:null}))}return{...Gh({nodes:n,edges:r,width:u,height:c,fitView:f,fitViewOptions:h,minZoom:p,maxZoom:m,nodeOrigin:v,nodeExtent:y,defaultNodes:i,defaultEdges:l,zIndexMode:g}),setNodes:N=>{const{nodeLookup:E,parentLookup:L,nodeOrigin:_,nodeExtent:P,elevateNodesOnSelect:U,fitViewQueued:D,zIndexMode:V,nodesSelectionActive:X}=S(),{nodesInitialized:b,hasSelectedNodes:ee}=Ba(N,E,L,{nodeOrigin:_,nodeExtent:P,elevateNodesOnSelect:U,checkEquality:!0,zIndexMode:V}),q=X&ⅇD&&b?(M(),w({nodes:N,nodesInitialized:b,fitViewQueued:!1,fitViewOptions:void 0,nodesSelectionActive:q})):w({nodes:N,nodesInitialized:b,nodesSelectionActive:q})},setEdges:N=>{const{connectionLookup:E,edgeLookup:L}=S();qp(E,L,N),w({edges:N})},setDefaultNodesAndEdges:(N,E)=>{if(N){const{setNodes:L}=S();L(N),w({hasDefaultNodes:!0})}if(E){const{setEdges:L}=S();L(E),w({hasDefaultEdges:!0})}},updateNodeInternals:N=>{const{triggerNodeChanges:E,nodeLookup:L,parentLookup:_,domNode:P,nodeOrigin:U,nodeExtent:D,debug:V,fitViewQueued:X,zIndexMode:b}=S(),{changes:ee,updatedInternals:q}=Aw(N,L,_,P,U,D,b);q&&(zw(L,_,{nodeOrigin:U,nodeExtent:D,zIndexMode:b}),X?(M(),w({fitViewQueued:!1,fitViewOptions:void 0})):w({}),(ee==null?void 0:ee.length)>0&&(V&&console.log("React Flow: trigger node changes",ee),E==null||E(ee)))},updateNodePositions:(N,E=!1)=>{const L=[];let _=[];const{nodeLookup:P,triggerNodeChanges:U,connection:D,updateConnection:V,onNodesChangeMiddlewareMap:X}=S();for(const[b,ee]of N){const q=P.get(b),J=!!(q!=null&&q.expandParent&&(q!=null&&q.parentId)&&(ee!=null&&ee.position)),Z={id:b,type:"position",position:J?{x:Math.max(0,ee.position.x),y:Math.max(0,ee.position.y)}:ee.position,dragging:E};if(q&&D.inProgress&&D.fromNode.id===q.id){const k=vr(q,D.fromHandle,xe.Left,!0);V({...D,from:k})}J&&q.parentId&&L.push({id:b,parentId:q.parentId,rect:{...ee.internals.positionAbsolute,width:ee.measured.width??0,height:ee.measured.height??0}}),_.push(Z)}if(L.length>0){const{parentLookup:b,nodeOrigin:ee}=S(),q=lc(L,P,b,ee);_.push(...q)}for(const b of X.values())_=b(_);U(_)},triggerNodeChanges:N=>{const{onNodesChange:E,setNodes:L,nodes:_,hasDefaultNodes:P,debug:U}=S();if(N!=null&&N.length){if(P){const D=$1(N,_);L(D)}U&&console.log("React Flow: trigger node changes",N),E==null||E(N)}},triggerEdgeChanges:N=>{const{onEdgesChange:E,setEdges:L,edges:_,hasDefaultEdges:P,debug:U}=S();if(N!=null&&N.length){if(P){const D=D1(N,_);L(D)}U&&console.log("React Flow: trigger edge changes",N),E==null||E(N)}},addSelectedNodes:N=>{const{multiSelectionActive:E,edgeLookup:L,nodeLookup:_,triggerNodeChanges:P,triggerEdgeChanges:U}=S();if(E){const D=N.map(V=>cr(V,!0));P(D);return}P(qr(_,new Set([...N]),!0)),U(qr(L))},addSelectedEdges:N=>{const{multiSelectionActive:E,edgeLookup:L,nodeLookup:_,triggerNodeChanges:P,triggerEdgeChanges:U}=S();if(E){const D=N.map(V=>cr(V,!0));U(D);return}U(qr(L,new Set([...N]))),P(qr(_,new Set,!0))},unselectNodesAndEdges:({nodes:N,edges:E}={})=>{const{edges:L,nodes:_,nodeLookup:P,triggerNodeChanges:U,triggerEdgeChanges:D}=S(),V=N||_,X=E||L,b=[];for(const q of V){if(!q.selected)continue;const J=P.get(q.id);J&&(J.selected=!1),b.push(cr(q.id,!1))}const ee=[];for(const q of X)q.selected&&ee.push(cr(q.id,!1));U(b),D(ee)},setMinZoom:N=>{const{panZoom:E,maxZoom:L}=S();E==null||E.setScaleExtent([N,L]),w({minZoom:N})},setMaxZoom:N=>{const{panZoom:E,minZoom:L}=S();E==null||E.setScaleExtent([L,N]),w({maxZoom:N})},setTranslateExtent:N=>{var E;(E=S().panZoom)==null||E.setTranslateExtent(N),w({translateExtent:N})},resetSelectedElements:()=>{const{edges:N,nodes:E,triggerNodeChanges:L,triggerEdgeChanges:_,elementsSelectable:P}=S();if(!P)return;const U=E.reduce((V,X)=>X.selected?[...V,cr(X.id,!1)]:V,[]),D=N.reduce((V,X)=>X.selected?[...V,cr(X.id,!1)]:V,[]);L(U),_(D)},setNodeExtent:N=>{const{nodes:E,nodeLookup:L,parentLookup:_,nodeOrigin:P,elevateNodesOnSelect:U,nodeExtent:D,zIndexMode:V}=S();N[0][0]===D[0][0]&&N[0][1]===D[0][1]&&N[1][0]===D[1][0]&&N[1][1]===D[1][1]||(Ba(E,L,_,{nodeOrigin:P,nodeExtent:N,elevateNodesOnSelect:U,checkEquality:!1,zIndexMode:V}),w({nodeExtent:N}))},panBy:N=>{const{transform:E,width:L,height:_,panZoom:P,translateExtent:U}=S();return jw({delta:N,panZoom:P,transform:E,translateExtent:U,width:L,height:_})},setCenter:async(N,E,L)=>{const{width:_,height:P,maxZoom:U,panZoom:D}=S();if(!D)return!1;const V=typeof(L==null?void 0:L.zoom)<"u"?L.zoom:U;return await D.setViewport({x:_/2-N*V,y:P/2-E*V,zoom:V},{duration:L==null?void 0:L.duration,ease:L==null?void 0:L.ease,interpolate:L==null?void 0:L.interpolate}),!0},cancelConnection:()=>{w({connection:{...Lp}})},updateConnection:N=>{w({connection:N})},reset:()=>w({...Gh()})}},Object.is);function o_({initialNodes:n,initialEdges:r,defaultNodes:i,defaultEdges:l,initialWidth:u,initialHeight:c,initialMinZoom:f,initialMaxZoom:h,initialFitViewOptions:p,fitView:m,nodeOrigin:v,nodeExtent:y,zIndexMode:g,children:w}){const[S]=K.useState(()=>r_({nodes:n,edges:r,defaultNodes:i,defaultEdges:l,width:u,height:c,fitView:m,minZoom:f,maxZoom:h,fitViewOptions:p,nodeOrigin:v,nodeExtent:y,zIndexMode:g}));return T.jsx(m1,{value:S,children:T.jsx(B1,{children:T.jsx(rS,{children:w})})})}function i_({children:n,nodes:r,edges:i,defaultNodes:l,defaultEdges:u,width:c,height:f,fitView:h,fitViewOptions:p,minZoom:m,maxZoom:v,nodeOrigin:y,nodeExtent:g,zIndexMode:w}){return K.useContext(yl)?T.jsx(T.Fragment,{children:n}):T.jsx(o_,{initialNodes:r,initialEdges:i,defaultNodes:l,defaultEdges:u,initialWidth:c,initialHeight:f,fitView:h,initialFitViewOptions:p,initialMinZoom:m,initialMaxZoom:v,nodeOrigin:y,nodeExtent:g,zIndexMode:w,children:n})}const s_={width:"100%",height:"100%",overflow:"hidden",position:"relative",zIndex:0};function l_({nodes:n,edges:r,defaultNodes:i,defaultEdges:l,className:u,nodeTypes:c,edgeTypes:f,onNodeClick:h,onEdgeClick:p,onInit:m,onMove:v,onMoveStart:y,onMoveEnd:g,onConnect:w,onConnectStart:S,onConnectEnd:M,onClickConnectStart:N,onClickConnectEnd:E,onNodeMouseEnter:L,onNodeMouseMove:_,onNodeMouseLeave:P,onNodeContextMenu:U,onNodeDoubleClick:D,onNodeDragStart:V,onNodeDrag:X,onNodeDragStop:b,onNodesDelete:ee,onEdgesDelete:q,onDelete:J,onSelectionChange:Z,onSelectionDragStart:k,onSelectionDrag:B,onSelectionDragStop:z,onSelectionContextMenu:H,onSelectionStart:j,onSelectionEnd:$,onBeforeDelete:F,connectionMode:C,connectionLineType:R=Un.Bezier,connectionLineStyle:te,connectionLineComponent:re,connectionLineContainerStyle:ue,deleteKeyCode:ce="Backspace",selectionKeyCode:ae="Shift",selectionOnDrag:G=!1,selectionMode:se=ui.Full,panActivationKeyCode:pe="Space",multiSelectionKeyCode:we=ci()?"Meta":"Control",zoomActivationKeyCode:ve=ci()?"Meta":"Control",snapToGrid:me,snapGrid:ke,onlyRenderVisibleElements:Ce=!1,selectNodesOnDrag:Me,nodesDraggable:Le,autoPanOnNodeFocus:it,nodesConnectable:ut,nodesFocusable:Je,nodeOrigin:et=cg,edgesFocusable:rn,edgesReconnectable:bt,elementsSelectable:Qt=!0,defaultViewport:at=I1,minZoom:Ct=.5,maxZoom:yt=2,translateExtent:Mt=li,preventScrolling:xr=!0,nodeExtent:on,defaultMarkerColor:Yn="#b1b1b7",zoomOnScroll:Sl=!0,zoomOnPinch:xi=!0,panOnScroll:wi=!1,panOnScrollSpeed:_l=.5,panOnScrollMode:so=hr.Free,zoomOnDoubleClick:lo=!0,panOnDrag:uo=!0,onPaneClick:ao,onPaneMouseEnter:co,onPaneMouseMove:vn,onPaneMouseLeave:xn,onPaneScroll:Si,onPaneContextMenu:_i,paneClickDistance:Ei=1,nodeClickDistance:ki=0,children:Ni,onReconnect:fo,onReconnectStart:Ci,onReconnectEnd:Xn,onEdgeContextMenu:ho,onEdgeDoubleClick:bn,onEdgeMouseEnter:El,onEdgeMouseMove:Qn,onEdgeMouseLeave:wr,reconnectRadius:Sr=10,onNodesChange:po,onEdgesChange:kl,noDragClassName:Nl="nodrag",noWheelClassName:Cl="nowheel",noPanClassName:Gt="nopan",fitView:go,fitViewOptions:mo,connectOnClick:Ml,attributionPosition:Mi,proOptions:Pi,defaultEdgeOptions:Ii,elevateNodesOnSelect:zi=!0,elevateEdgesOnSelect:Pl=!1,disableKeyboardA11y:Ti=!1,autoPanOnConnect:Oe,autoPanOnNodeDrag:Il,autoPanOnSelection:yo=!0,autoPanSpeed:Li,connectionRadius:_r,isValidConnection:zl,onError:Ri,style:Er,id:vt,nodeDragThreshold:Tl,connectionDragThreshold:xt,viewport:Ll,onViewportChange:Rl,width:Al,height:kr,colorMode:Nr="light",debug:Gn,onScroll:sn,ariaLabelConfig:jl,zIndexMode:Ai="basic",...vo},ji){const Kn=vt||"1",qn=R1(Nr),$l=K.useCallback(Cr=>{Cr.currentTarget.scrollTo({top:0,left:0,behavior:"instant"}),sn==null||sn(Cr)},[sn]);return T.jsx("div",{"data-testid":"rf__wrapper",...vo,onScroll:$l,style:{...Er,...s_},ref:ji,className:Ye(["react-flow",u,qn]),id:vt,role:"application",children:T.jsxs(i_,{nodes:n,edges:r,width:Al,height:kr,fitView:go,fitViewOptions:mo,minZoom:Ct,maxZoom:yt,nodeOrigin:et,nodeExtent:on,zIndexMode:Ai,children:[T.jsx(L1,{nodes:n,edges:r,defaultNodes:i,defaultEdges:l,onConnect:w,onConnectStart:S,onConnectEnd:M,onClickConnectStart:N,onClickConnectEnd:E,nodesDraggable:Le,autoPanOnNodeFocus:it,nodesConnectable:ut,nodesFocusable:Je,edgesFocusable:rn,edgesReconnectable:bt,elementsSelectable:Qt,elevateNodesOnSelect:zi,elevateEdgesOnSelect:Pl,minZoom:Ct,maxZoom:yt,nodeExtent:on,onNodesChange:po,onEdgesChange:kl,snapToGrid:me,snapGrid:ke,connectionMode:C,translateExtent:Mt,connectOnClick:Ml,defaultEdgeOptions:Ii,fitView:go,fitViewOptions:mo,onNodesDelete:ee,onEdgesDelete:q,onDelete:J,onNodeDragStart:V,onNodeDrag:X,onNodeDragStop:b,onSelectionDrag:B,onSelectionDragStart:k,onSelectionDragStop:z,onMove:v,onMoveStart:y,onMoveEnd:g,noPanClassName:Gt,nodeOrigin:et,rfId:Kn,autoPanOnConnect:Oe,autoPanOnNodeDrag:Il,autoPanSpeed:Li,onError:Ri,connectionRadius:_r,isValidConnection:zl,selectNodesOnDrag:Me,nodeDragThreshold:Tl,connectionDragThreshold:xt,onBeforeDelete:F,debug:Gn,ariaLabelConfig:jl,zIndexMode:Ai}),T.jsx(t_,{onInit:m,onNodeClick:h,onEdgeClick:p,onNodeMouseEnter:L,onNodeMouseMove:_,onNodeMouseLeave:P,onNodeContextMenu:U,onNodeDoubleClick:D,nodeTypes:c,edgeTypes:f,connectionLineType:R,connectionLineStyle:te,connectionLineComponent:re,connectionLineContainerStyle:ue,selectionKeyCode:ae,selectionOnDrag:G,selectionMode:se,deleteKeyCode:ce,multiSelectionKeyCode:we,panActivationKeyCode:pe,zoomActivationKeyCode:ve,onlyRenderVisibleElements:Ce,defaultViewport:at,translateExtent:Mt,minZoom:Ct,maxZoom:yt,preventScrolling:xr,zoomOnScroll:Sl,zoomOnPinch:xi,zoomOnDoubleClick:lo,panOnScroll:wi,panOnScrollSpeed:_l,panOnScrollMode:so,panOnDrag:uo,autoPanOnSelection:yo,onPaneClick:ao,onPaneMouseEnter:co,onPaneMouseMove:vn,onPaneMouseLeave:xn,onPaneScroll:Si,onPaneContextMenu:_i,paneClickDistance:Ei,nodeClickDistance:ki,onSelectionContextMenu:H,onSelectionStart:j,onSelectionEnd:$,onReconnect:fo,onReconnectStart:Ci,onReconnectEnd:Xn,onEdgeContextMenu:ho,onEdgeDoubleClick:bn,onEdgeMouseEnter:El,onEdgeMouseMove:Qn,onEdgeMouseLeave:wr,reconnectRadius:Sr,defaultMarkerColor:Yn,noDragClassName:Nl,noWheelClassName:Cl,noPanClassName:Gt,rfId:Kn,disableKeyboardA11y:Ti,nodeExtent:on,viewport:Ll,onViewportChange:Rl,nodesDraggable:Le}),T.jsx(P1,{onSelectionChange:Z}),Ni,T.jsx(E1,{proOptions:Pi,position:Mi}),T.jsx(_1,{rfId:Kn,disableKeyboardA11y:Ti})]})})}var u_=dg(l_);function a_({dimensions:n,lineWidth:r,variant:i,className:l}){return T.jsx("path",{strokeWidth:r,d:`M${n[0]/2} 0 V${n[1]} M0 ${n[1]/2} H${n[0]}`,className:Ye(["react-flow__background-pattern",i,l])})}function c_({radius:n,className:r}){return T.jsx("circle",{cx:n,cy:n,r:n,className:Ye(["react-flow__background-pattern","dots",r])})}var Wn;(function(n){n.Lines="lines",n.Dots="dots",n.Cross="cross"})(Wn||(Wn={}));const f_={[Wn.Dots]:1,[Wn.Lines]:1,[Wn.Cross]:6},d_=n=>({transform:n.transform,patternId:`pattern-${n.rfId}`});function Og({id:n,variant:r=Wn.Dots,gap:i=20,size:l,lineWidth:u=1,offset:c=0,color:f,bgColor:h,style:p,className:m,patternClassName:v}){const y=K.useRef(null),{transform:g,patternId:w}=Ie(d_,Ve),S=l||f_[r],M=r===Wn.Dots,N=r===Wn.Cross,E=Array.isArray(i)?i:[i,i],L=[E[0]*g[2]||1,E[1]*g[2]||1],_=S*g[2],P=Array.isArray(c)?c:[c,c],U=N?[_,_]:L,D=[P[0]*g[2]+U[0]/2,P[1]*g[2]+U[1]/2],V=`${w}${n||""}`;return T.jsxs("svg",{className:Ye(["react-flow__background",m]),style:{...p,...xl,"--xy-background-color-props":h,"--xy-background-pattern-color-props":f},ref:y,"data-testid":"rf__background",children:[T.jsx("pattern",{id:V,x:g[0]%L[0],y:g[1]%L[1],width:L[0],height:L[1],patternUnits:"userSpaceOnUse",patternTransform:`translate(-${D[0]},-${D[1]})`,children:M?T.jsx(c_,{radius:_/2,className:v}):T.jsx(a_,{dimensions:U,lineWidth:u,variant:r,className:v})}),T.jsx("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:`url(#${V})`})]})}Og.displayName="Background";const h_=K.memo(Og);function p_(){return T.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32",children:T.jsx("path",{d:"M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z"})})}function g_(){return T.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 5",children:T.jsx("path",{d:"M0 0h32v4.2H0z"})})}function m_(){return T.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 30",children:T.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 y_(){return T.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:T.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 v_(){return T.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:T.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 Ys({children:n,className:r,...i}){return T.jsx("button",{type:"button",className:Ye(["react-flow__controls-button",r]),...i,children:n})}const x_=n=>({isInteractive:n.nodesDraggable||n.nodesConnectable||n.elementsSelectable,minZoomReached:n.transform[2]<=n.minZoom,maxZoomReached:n.transform[2]>=n.maxZoom,ariaLabelConfig:n.ariaLabelConfig});function Fg({style:n,showZoom:r=!0,showFitView:i=!0,showInteractive:l=!0,fitViewOptions:u,onZoomIn:c,onZoomOut:f,onFitView:h,onInteractiveChange:p,className:m,children:v,position:y="bottom-left",orientation:g="vertical","aria-label":w}){const S=$e(),{isInteractive:M,minZoomReached:N,maxZoomReached:E,ariaLabelConfig:L}=Ie(x_,Ve),{zoomIn:_,zoomOut:P,fitView:U}=uc(),D=()=>{_(),c==null||c()},V=()=>{P(),f==null||f()},X=()=>{U(u),h==null||h()},b=()=>{S.setState({nodesDraggable:!M,nodesConnectable:!M,elementsSelectable:!M}),p==null||p(!M)},ee=g==="horizontal"?"horizontal":"vertical";return T.jsxs(vl,{className:Ye(["react-flow__controls",ee,m]),position:y,style:n,"data-testid":"rf__controls","aria-label":w??L["controls.ariaLabel"],children:[r&&T.jsxs(T.Fragment,{children:[T.jsx(Ys,{onClick:D,className:"react-flow__controls-zoomin",title:L["controls.zoomIn.ariaLabel"],"aria-label":L["controls.zoomIn.ariaLabel"],disabled:E,children:T.jsx(p_,{})}),T.jsx(Ys,{onClick:V,className:"react-flow__controls-zoomout",title:L["controls.zoomOut.ariaLabel"],"aria-label":L["controls.zoomOut.ariaLabel"],disabled:N,children:T.jsx(g_,{})})]}),i&&T.jsx(Ys,{className:"react-flow__controls-fitview",onClick:X,title:L["controls.fitView.ariaLabel"],"aria-label":L["controls.fitView.ariaLabel"],children:T.jsx(m_,{})}),l&&T.jsx(Ys,{className:"react-flow__controls-interactive",onClick:b,title:L["controls.interactive.ariaLabel"],"aria-label":L["controls.interactive.ariaLabel"],children:M?T.jsx(v_,{}):T.jsx(y_,{})}),v]})}Fg.displayName="Controls";const w_=K.memo(Fg);function S_({id:n,x:r,y:i,width:l,height:u,style:c,color:f,strokeColor:h,strokeWidth:p,className:m,borderRadius:v,shapeRendering:y,selected:g,onClick:w}){const{background:S,backgroundColor:M}=c||{},N=f||S||M;return T.jsx("rect",{className:Ye(["react-flow__minimap-node",{selected:g},m]),x:r,y:i,rx:v,ry:v,width:l,height:u,style:{fill:N,stroke:h,strokeWidth:p},shapeRendering:y,onClick:w?E=>w(E,n):void 0})}const __=K.memo(S_),E_=n=>n.nodes.map(r=>r.id),za=n=>n instanceof Function?n:()=>n;function k_({nodeStrokeColor:n,nodeColor:r,nodeClassName:i="",nodeBorderRadius:l=5,nodeStrokeWidth:u,nodeComponent:c=__,onClick:f}){const h=Ie(E_,Ve),p=za(r),m=za(n),v=za(i),y=typeof window>"u"||window.chrome?"crispEdges":"geometricPrecision";return T.jsx(T.Fragment,{children:h.map(g=>T.jsx(C_,{id:g,nodeColorFunc:p,nodeStrokeColorFunc:m,nodeClassNameFunc:v,nodeBorderRadius:l,nodeStrokeWidth:u,NodeComponent:c,onClick:f,shapeRendering:y},g))})}function N_({id:n,nodeColorFunc:r,nodeStrokeColorFunc:i,nodeClassNameFunc:l,nodeBorderRadius:u,nodeStrokeWidth:c,shapeRendering:f,NodeComponent:h,onClick:p}){const{node:m,x:v,y,width:g,height:w}=Ie(S=>{const M=S.nodeLookup.get(n);if(!M)return{node:void 0,x:0,y:0,width:0,height:0};const N=M.internals.userNode,{x:E,y:L}=M.internals.positionAbsolute,{width:_,height:P}=Xt(N);return{node:N,x:E,y:L,width:_,height:P}},Ve);return!m||m.hidden||!Hp(m)?null:T.jsx(h,{x:v,y,width:g,height:w,style:m.style,selected:!!m.selected,className:l(m),color:r(m),borderRadius:u,strokeColor:i(m),strokeWidth:c,shapeRendering:f,onClick:p,id:m.id})}const C_=K.memo(N_);var M_=K.memo(k_);const P_=200,I_=150,z_=n=>!n.hidden,T_=n=>{const r={x:-n.transform[0]/n.transform[2],y:-n.transform[1]/n.transform[2],width:n.width/n.transform[2],height:n.height/n.transform[2]};return{viewBB:r,boundingRect:n.nodeLookup.size>0?Dp(mi(n.nodeLookup,{filter:z_}),r):r,rfId:n.rfId,panZoom:n.panZoom,translateExtent:n.translateExtent,flowWidth:n.width,flowHeight:n.height,ariaLabelConfig:n.ariaLabelConfig}},Kh=(n,r)=>n.x===r.x&&n.y===r.y&&n.width===r.width&&n.height===r.height,L_=(n,r)=>Kh(n.viewBB,r.viewBB)&&Kh(n.boundingRect,r.boundingRect)&&n.rfId===r.rfId&&n.panZoom===r.panZoom&&n.translateExtent===r.translateExtent&&n.flowWidth===r.flowWidth&&n.flowHeight===r.flowHeight&&n.ariaLabelConfig===r.ariaLabelConfig,R_="react-flow__minimap-desc";function Hg({style:n,className:r,nodeStrokeColor:i,nodeColor:l,nodeClassName:u="",nodeBorderRadius:c=5,nodeStrokeWidth:f,nodeComponent:h,bgColor:p,maskColor:m,maskStrokeColor:v,maskStrokeWidth:y,position:g="bottom-right",onClick:w,onNodeClick:S,pannable:M=!1,zoomable:N=!1,ariaLabel:E,inversePan:L,zoomStep:_=1,offsetScale:P=5}){const U=$e(),D=K.useRef(null),{boundingRect:V,viewBB:X,rfId:b,panZoom:ee,translateExtent:q,flowWidth:J,flowHeight:Z,ariaLabelConfig:k}=Ie(T_,L_),B=(n==null?void 0:n.width)??P_,z=(n==null?void 0:n.height)??I_,H=V.width/B,j=V.height/z,$=Math.max(H,j),F=$*B,C=$*z,R=P*$,te=V.x-(F-V.width)/2-R,re=V.y-(C-V.height)/2-R,ue=F+R*2,ce=C+R*2,ae=`${R_}-${b}`,G=K.useRef(0),se=K.useRef();G.current=$,K.useEffect(()=>{if(D.current&&ee)return se.current=Ww({domNode:D.current,panZoom:ee,getTransform:()=>U.getState().transform,getViewScale:()=>G.current}),()=>{var me;(me=se.current)==null||me.destroy()}},[ee]),K.useEffect(()=>{var me;(me=se.current)==null||me.update({translateExtent:q,width:J,height:Z,inversePan:L,pannable:M,zoomStep:_,zoomable:N})},[M,N,L,_,q,J,Z]);const pe=w?me=>{var Me;const[ke,Ce]=((Me=se.current)==null?void 0:Me.pointer(me))||[0,0];w(me,{x:ke,y:Ce})}:void 0,we=S?K.useCallback((me,ke)=>{const Ce=U.getState().nodeLookup.get(ke).internals.userNode;S(me,Ce)},[]):void 0,ve=E??k["minimap.ariaLabel"];return T.jsx(vl,{position:g,style:{...n,"--xy-minimap-background-color-props":typeof p=="string"?p:void 0,"--xy-minimap-mask-background-color-props":typeof m=="string"?m:void 0,"--xy-minimap-mask-stroke-color-props":typeof v=="string"?v:void 0,"--xy-minimap-mask-stroke-width-props":typeof y=="number"?y*$:void 0,"--xy-minimap-node-background-color-props":typeof l=="string"?l:void 0,"--xy-minimap-node-stroke-color-props":typeof i=="string"?i:void 0,"--xy-minimap-node-stroke-width-props":typeof f=="number"?f:void 0},className:Ye(["react-flow__minimap",r]),"data-testid":"rf__minimap",children:T.jsxs("svg",{width:B,height:z,viewBox:`${te} ${re} ${ue} ${ce}`,className:"react-flow__minimap-svg",role:"img","aria-labelledby":ae,ref:D,onClick:pe,children:[ve&&T.jsx("title",{id:ae,children:ve}),T.jsx(M_,{onClick:we,nodeColor:l,nodeStrokeColor:i,nodeBorderRadius:c,nodeClassName:u,nodeStrokeWidth:f,nodeComponent:h}),T.jsx("path",{className:"react-flow__minimap-mask",d:`M${te-R},${re-R}h${ue+R*2}v${ce+R*2}h${-ue-R*2}z + M${X.x},${X.y}h${X.width}v${X.height}h${-X.width}z`,fillRule:"evenodd",pointerEvents:"none"})]})})}Hg.displayName="MiniMap";const A_=K.memo(Hg),j_=n=>r=>n?`${Math.max(1/r.transform[2],1)}`:void 0,$_={[io.Line]:"right",[io.Handle]:"bottom-right"};function D_({nodeId:n,position:r,variant:i=io.Handle,className:l,style:u=void 0,children:c,color:f,minWidth:h=10,minHeight:p=10,maxWidth:m=Number.MAX_VALUE,maxHeight:v=Number.MAX_VALUE,keepAspectRatio:y=!1,resizeDirection:g,autoScale:w=!0,shouldResize:S,onResizeStart:M,onResize:N,onResizeEnd:E}){const L=yg(),_=typeof n=="string"?n:L,P=$e(),U=K.useRef(null),D=i===io.Handle,V=Ie(K.useCallback(j_(D&&w),[D,w]),Ve),X=K.useRef(null),b=r??$_[i];K.useEffect(()=>{if(!(!U.current||!_))return X.current||(X.current=r1({domNode:U.current,nodeId:_,getStoreItems:()=>{const{nodeLookup:q,transform:J,snapGrid:Z,snapToGrid:k,nodeOrigin:B,domNode:z}=P.getState();return{nodeLookup:q,transform:J,snapGrid:Z,snapToGrid:k,nodeOrigin:B,paneDomNode:z}},onChange:(q,J)=>{const{triggerNodeChanges:Z,nodeLookup:k,parentLookup:B,nodeOrigin:z}=P.getState(),H=[],j={x:q.x,y:q.y},$=k.get(_);if($&&$.expandParent&&$.parentId){const F=$.origin??z,C=q.width??$.measured.width??0,R=q.height??$.measured.height??0,te={id:$.id,parentId:$.parentId,rect:{width:C,height:R,...Vp({x:q.x??$.position.x,y:q.y??$.position.y},{width:C,height:R},$.parentId,k,F)}},re=lc([te],k,B,z);H.push(...re),j.x=q.x?Math.max(F[0]*C,q.x):void 0,j.y=q.y?Math.max(F[1]*R,q.y):void 0}if(j.x!==void 0&&j.y!==void 0){const F={id:_,type:"position",position:{...j}};H.push(F)}if(q.width!==void 0&&q.height!==void 0){const C={id:_,type:"dimensions",resizing:!0,setAttributes:g?g==="horizontal"?"width":"height":!0,dimensions:{width:q.width,height:q.height}};H.push(C)}for(const F of J){const C={...F,type:"position"};H.push(C)}Z(H)},onEnd:({width:q,height:J})=>{const Z={id:_,type:"dimensions",resizing:!1,dimensions:{width:q,height:J}};P.getState().triggerNodeChanges([Z])}})),X.current.update({controlPosition:b,boundaries:{minWidth:h,minHeight:p,maxWidth:m,maxHeight:v},keepAspectRatio:y,resizeDirection:g,onResizeStart:M,onResize:N,onResizeEnd:E,shouldResize:S}),()=>{var q;(q=X.current)==null||q.destroy()}},[b,h,p,m,v,y,M,N,E,S]);const ee=b.split("-");return T.jsx("div",{className:Ye(["react-flow__resize-control","nodrag",...ee,i,l]),ref:U,style:{...u,scale:V,...f&&{[D?"backgroundColor":"borderColor"]:f}},children:c})}K.memo(D_);const O_={"arch.context":0,"django.app":0,"django.route":1,"django.url_name":1,"django.view":2,"django.viewset_action":2,"django.permission":2,"django.serializer":3,"django.serializer_field":4,"django.service":4,"django.model":5,"django.field":6,"django.relation":6,"django.task":7,"django.receiver":7,"django.signal":7,"django.test":7,"django.migration_op":7,"django.admin":7,"openapi.path":8,"react.api_client":9,"react.query_key":10,"react.hook":10,"react.feature":10,"react.route":11,"react.page":11,"react.component":12,"react.form_schema":13,"react.test":13,"react.context":12};function F_(n){return O_[n]??8}function H_(n){const r=new Map;for(const l of n){const u=F_(l.type),c=r.get(u)??[];c.push(l),r.set(u,c)}const i=new Map;for(const[l,u]of r)u.sort((c,f)=>c.name.localeCompare(f.name)),u.forEach((c,f)=>{i.set(c.id,{x:l*240,y:f*92})});return i}const V_={cheap:"#4a5568",expensive:"#f4a261",critical:"#e85d04"};function B_({data:n}){return T.jsxs("div",{className:"lp-node",children:[T.jsx("div",{className:"t",children:n.type.split(".").pop()}),T.jsx("div",{className:"n",children:n.name})]})}const U_={load:B_};function qh({nodes:n,edges:r}){const i=H_(n),l=n.map(c=>({id:c.id,type:"load",position:i.get(c.id)??{x:0,y:0},data:{name:c.name,type:c.type,file:c.file_path}})),u=r.filter(c=>n.some(f=>f.id===c.src)&&n.some(f=>f.id===c.dst)).map(c=>({id:c.id,source:c.src,target:c.dst,animated:c.weight==="critical",style:{stroke:V_[c.weight]||"#4a5568",strokeWidth:c.weight==="critical"?2.4:1.2,strokeDasharray:c.confidence<.8?"6 4":void 0},label:c.type.replaceAll("_"," "),labelStyle:{fill:"#8b9bb0",fontSize:9}}));return T.jsxs(u_,{nodes:l,edges:u,nodeTypes:U_,fitView:!0,minZoom:.2,children:[T.jsx(h_,{}),T.jsx(A_,{pannable:!0,zoomable:!0}),T.jsx(w_,{})]})}function W_(){var B;const[n,r]=K.useState("review"),[i,l]=K.useState(localStorage.getItem("loadpath.repo")||""),[u,c]=K.useState("HEAD~1"),[f,h]=K.useState("HEAD"),[p,m]=K.useState(null),[v,y]=K.useState(""),[g,w]=K.useState(""),[S,M]=K.useState({}),[N,E]=K.useState([]),[L,_]=K.useState(""),[P,U]=K.useState("github"),[D,V]=K.useState("");K.useEffect(()=>{Gr.settings().then(M).catch(()=>{})},[]);const X=async()=>{y(""),w("Tracing load path…"),localStorage.setItem("loadpath.repo",i);try{const z=await Gr.review(i,u,f);m(z),r("review")}catch(z){y(z instanceof Error?z.message:String(z))}finally{w("")}},b=async()=>{y(""),w("Indexing…");try{await Gr.index(i)}catch(z){y(z instanceof Error?z.message:String(z))}finally{w("")}},ee=async()=>{y(""),w("Fetching pull requests…");try{const z=await Gr.prs(P,L);E(z.pull_requests)}catch(z){y(z instanceof Error?z.message:String(z))}finally{w("")}},q=async z=>{z.preventDefault();const H=new FormData(z.currentTarget),j={github_token:String(H.get("github_token")||""),bitbucket_token:String(H.get("bitbucket_token")||""),bitbucket_username:String(H.get("bitbucket_username")||""),ai_provider:String(H.get("ai_provider")||"none"),ai_api_key:String(H.get("ai_api_key")||""),ai_model:String(H.get("ai_model")||""),ai_base_url:String(H.get("ai_base_url")||""),workspaces:i?[{path:i,name:i.split(/[\\/]/).pop()}]:[]};M(await Gr.saveSettings(j))},J=async()=>{if(p){w("Residual analysis…");try{const z=await Gr.residual(p);V(z.note)}catch(z){y(z instanceof Error?z.message:String(z))}finally{w("")}}},Z=K.useMemo(()=>(p==null?void 0:p.nodes)??[],[p]),k=K.useMemo(()=>(p==null?void 0:p.edges)??[],[p]);return T.jsxs("div",{className:"app",children:[T.jsxs("nav",{className:"rail",children:[T.jsx("div",{className:"brand",children:"Loadpath"}),T.jsx("button",{className:n==="review"?"active":"",onClick:()=>r("review"),children:"Review"}),T.jsx("button",{className:n==="graph"?"active":"",onClick:()=>r("graph"),children:"Impact graph"}),T.jsx("button",{className:n==="prs"?"active":"",onClick:()=>r("prs"),children:"Pull requests"}),T.jsx("button",{className:n==="settings"?"active":"",onClick:()=>r("settings"),children:"Settings"}),T.jsx("div",{style:{flex:1}}),T.jsx("div",{className:"muted",children:g||"Django + React load paths"})]}),T.jsxs("div",{className:"main",children:[T.jsxs("div",{className:"topbar",children:[T.jsx("input",{className:"path",placeholder:"Local monorepo path",value:i,onChange:z=>l(z.target.value)}),T.jsx("input",{value:u,onChange:z=>c(z.target.value),placeholder:"base"}),T.jsx("input",{value:f,onChange:z=>h(z.target.value),placeholder:"head"}),T.jsx("button",{onClick:b,children:"Index"}),T.jsx("button",{className:"btn primary",onClick:X,children:"Review"})]}),v?T.jsx("div",{className:"error",children:v}):null,n==="review"&&T.jsxs("div",{className:"content",children:[T.jsx("aside",{className:"brief",children:p?T.jsxs(T.Fragment,{children:[T.jsxs("div",{className:`level ${p.confidence.level}`,children:[p.confidence.level.toUpperCase()," — ",p.title]}),p.low_risk?T.jsx("span",{className:"chip",children:"loadpath:low-risk"}):null,p.change_kinds.map(z=>T.jsx("span",{className:"chip",children:z.replaceAll("_"," ")},z)),T.jsx("pre",{className:"headline",children:p.headline}),T.jsx("div",{className:"kicker",children:"Read this"}),p.read_order.map(z=>T.jsxs("div",{children:[T.jsx("span",{className:"file",children:z.path}),T.jsx("div",{className:"muted",children:z.why})]},z.path)),T.jsx("div",{className:"kicker",children:"Clusters"}),p.clusters.map(z=>T.jsxs("div",{className:"muted",children:[T.jsx("strong",{children:z.title})," — ",z.files.join(", ")]},z.id)),T.jsx("div",{className:"kicker",children:"Architecture"}),p.findings.filter(z=>!z.waived).length===0?T.jsx("div",{className:"muted",children:p.architecture_note}):p.findings.filter(z=>!z.waived).map(z=>T.jsxs("div",{className:"muted",children:[T.jsx("span",{className:`chip ${z.severity}`,children:z.severity}),z.message]},z.rule+z.message)),T.jsx("div",{className:"kicker",children:"Residual (AI only here)"}),p.residuals.map(z=>T.jsx("div",{className:"muted",children:z},z)),T.jsx("button",{className:"btn",onClick:J,style:{marginTop:12},children:"Ask configured model"}),D?T.jsx("pre",{className:"headline",children:D}):null,T.jsx("div",{className:"kicker",children:"Reviewers"}),T.jsx("div",{className:"muted",children:p.suggested_reviewers.join(", ")||"—"})]}):T.jsxs("p",{className:"muted",children:["Point at a Django + React monorepo with ",T.jsx("code",{children:"loadpath.yml"}),", then review a git range. The graph — not hunk comments — is the artifact."]})}),T.jsx("div",{className:"graph-wrap",children:p?T.jsx(qh,{nodes:Z,edges:k}):null})]}),n==="graph"&&T.jsx("div",{className:"graph-wrap",style:{height:"100%"},children:p?T.jsx(qh,{nodes:Z,edges:k}):T.jsx("p",{className:"muted",children:"Run a review first."})}),n==="prs"&&T.jsxs("div",{className:"pr-list",children:[T.jsxs("div",{className:"topbar",style:{border:0,padding:0,marginBottom:12},children:[T.jsxs("select",{value:P,onChange:z=>U(z.target.value),children:[T.jsx("option",{value:"github",children:"GitHub"}),T.jsx("option",{value:"bitbucket",children:"Bitbucket"})]}),T.jsx("input",{className:"path",placeholder:"owner/repo",value:L,onChange:z=>_(z.target.value)}),T.jsx("button",{onClick:ee,children:"List PRs"})]}),N.map(z=>T.jsxs("article",{className:"pr",children:[T.jsxs("h3",{children:["#",z.number," ",z.title]}),T.jsxs("div",{className:"muted",children:[z.author," · ",z.source_branch," → ",z.target_branch," · ",z.provider]}),T.jsxs("a",{href:z.url,target:"_blank",rel:"noreferrer",children:["Open on ",z.provider]}),T.jsx("div",{children:T.jsx("button",{className:"btn",onClick:()=>{c(z.target_branch),h(z.source_branch),r("review")},children:"Review this branch range"})})]},`${z.provider}-${z.number}`))]}),n==="settings"&&T.jsxs("form",{className:"settings",onSubmit:q,children:[T.jsx("h1",{children:"Keys & providers"}),T.jsx("p",{className:"muted",children:"Tokens stay on this machine in ~/.loadpath/settings.json. GitHub and Bitbucket power the PR list. AI is used only for residual uncertainty the graph could not close."}),T.jsx("label",{children:"GitHub token"}),T.jsx("input",{name:"github_token",type:"password",placeholder:"ghp_…"}),T.jsx("label",{children:"Bitbucket token"}),T.jsx("input",{name:"bitbucket_token",type:"password"}),T.jsx("label",{children:"Bitbucket username (app passwords)"}),T.jsx("input",{name:"bitbucket_username",defaultValue:String(S.bitbucket_username||"")}),T.jsx("label",{children:"AI provider"}),T.jsxs("select",{name:"ai_provider",defaultValue:String(((B=S.ai)==null?void 0:B.provider)||"none"),children:[T.jsx("option",{value:"none",children:"none (graph only)"}),T.jsx("option",{value:"anthropic",children:"Anthropic"}),T.jsx("option",{value:"openai",children:"OpenAI"}),T.jsx("option",{value:"grok",children:"Grok / xAI"}),T.jsx("option",{value:"deepseek",children:"DeepSeek"}),T.jsx("option",{value:"cursor",children:"Cursor-compatible (OpenAI protocol)"}),T.jsx("option",{value:"ollama",children:"Ollama local"})]}),T.jsx("label",{children:"AI API key"}),T.jsx("input",{name:"ai_api_key",type:"password"}),T.jsx("label",{children:"Model"}),T.jsx("input",{name:"ai_model",placeholder:"optional override"}),T.jsx("label",{children:"Base URL"}),T.jsx("input",{name:"ai_base_url",placeholder:"optional, OpenAI-compatible"}),T.jsx("button",{className:"btn primary",type:"submit",children:"Save"})]})]})]})}M0.createRoot(document.getElementById("root")).render(T.jsx(K.StrictMode,{children:T.jsx(W_,{})})); diff --git a/src/loadpath/static/index.html b/src/loadpath/static/index.html new file mode 100644 index 0000000..e0095b2 --- /dev/null +++ b/src/loadpath/static/index.html @@ -0,0 +1,16 @@ + + + + + + Loadpath + + + + + + + +
+ + diff --git a/src/loadpath/stitch/__init__.py b/src/loadpath/stitch/__init__.py new file mode 100644 index 0000000..839e4d8 --- /dev/null +++ b/src/loadpath/stitch/__init__.py @@ -0,0 +1,3 @@ +from loadpath.stitch.openapi import stitch + +__all__ = ["stitch"] diff --git a/src/loadpath/stitch/openapi.py b/src/loadpath/stitch/openapi.py new file mode 100644 index 0000000..8b8f20c --- /dev/null +++ b/src/loadpath/stitch/openapi.py @@ -0,0 +1,324 @@ +from __future__ import annotations + +import json +import re +from pathlib import Path + +from loadpath.config import LoadpathConfig +from loadpath.extractors.react import normalize_url_template +from loadpath.graph.store import GraphStore +from loadpath.types import Edge, EdgeType, Node, NodeType, node_id + +DJANGO_PATH_PARAM = re.compile(r"""<(?:(?:int|str|slug|uuid|path):)?([^>]+)>""") +METHOD_PREFIX = re.compile(r"""^(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\s+""", re.I) + + +def django_route_to_template(route: str) -> str: + route = route.strip() + if not route.startswith("/"): + route = "/" + route + route = DJANGO_PATH_PARAM.sub("{id}", route) + route = re.sub(r"""/+""", "/", route) + return route.rstrip("/") or "/" + + +def parse_public_api(spec: str) -> tuple[str | None, str]: + m = METHOD_PREFIX.match(spec.strip()) + method = m.group(1).upper() if m else None + path = spec[m.end() :].strip() if m else spec.strip() + return method, django_route_to_template(path) + + +def load_openapi(repo_root: Path, config: LoadpathConfig) -> list[dict]: + paths: list[dict] = [] + candidates = list(config.openapi_paths) + if not candidates: + for pattern in ( + "**/schema.yml", + "**/schema.yaml", + "**/openapi.yaml", + "**/openapi.yml", + "**/openapi.json", + "**/schema.json", + "**/swagger.json", + ): + candidates.extend(str(p.relative_to(repo_root)) for p in repo_root.glob(pattern)) + for rel in candidates: + path = repo_root / rel + if not path.is_file(): + continue + text = path.read_text(encoding="utf-8") + if path.suffix in {".json"}: + data = json.loads(text) + else: + import yaml + + data = yaml.safe_load(text) or {} + for pth, methods in (data.get("paths") or {}).items(): + if not isinstance(methods, dict): + continue + for method, op in methods.items(): + if method.startswith("x-") or not isinstance(op, dict): + continue + paths.append( + { + "path": django_route_to_template(pth), + "method": method.upper(), + "operation_id": op.get("operationId"), + "source": rel, + "generated": True, + } + ) + return paths + + +def _join(prefix: str, route: str) -> str: + prefix = prefix.strip("/") + route = route.strip("/") + if not prefix: + return django_route_to_template(route) + if not route: + return django_route_to_template(prefix) + return django_route_to_template(prefix + "/" + route) + + +def apply_url_includes(store: GraphStore) -> None: + """Compose path('api/', include('billing.urls')) onto child routes.""" + includes: list[tuple[str, str]] = [] + for route in store.nodes([NodeType.ROUTE]): + extra = route.get("extra") or {} + inc = extra.get("include") + if not inc: + continue + prefix = extra.get("route") or route["name"] + includes.append((str(prefix), str(inc))) + if not includes: + return + for route in store.nodes([NodeType.ROUTE]): + extra = dict(route.get("extra") or {}) + if extra.get("include"): + continue + app = extra.get("app") + raw = extra.get("route") or route["name"] + mounted = None + for prefix, inc in includes: + target_app = inc.split(".")[0] + if app and app == target_app: + mounted = _join(prefix, str(raw)) + break + if mounted: + extra["mounted_at"] = mounted + extra["full_path"] = mounted + store.upsert_node( + Node( + id=route["id"], + type=NodeType.ROUTE, + name=mounted, + qualified_name=route["qualified_name"], + file_path=route.get("file_path"), + start_line=route.get("start_line"), + context=route.get("context"), + extra=extra, + ) + ) + store.conn.commit() + + +def stitch(store: GraphStore, config: LoadpathConfig, repo_root: Path) -> list[str]: + residuals: list[str] = [] + apply_url_includes(store) + openapi = load_openapi(repo_root, config) + openapi_by_path: dict[str, list[dict]] = {} + for item in openapi: + openapi_by_path.setdefault(item["path"], []).append(item) + nid = node_id(NodeType.OPENAPI_PATH, f"{item['method']} {item['path']}") + store.upsert_node( + Node( + id=nid, + type=NodeType.OPENAPI_PATH, + name=f"{item['method']} {item['path']}", + qualified_name=f"{item['method']} {item['path']}", + file_path=item.get("source"), + extra=item, + ) + ) + + routes = [n for n in store.nodes([NodeType.ROUTE])] + clients = [n for n in store.nodes([NodeType.API_CLIENT])] + serializers = [n for n in store.nodes([NodeType.SERIALIZER])] + ser_fields = [n for n in store.nodes([NodeType.SERIALIZER_FIELD])] + schemas = [n for n in store.nodes([NodeType.FORM_SCHEMA])] + generated_files = _generated_client_files(repo_root, config) + + # Route → OpenAPI + for route in routes: + extra = route.get("extra") or {} + if extra.get("include"): + continue + raw = extra.get("mounted_at") or extra.get("full_path") or extra.get("route") or route["name"] + tmpl = django_route_to_template(str(raw)) + ops = openapi_by_path.get(tmpl, []) + if not ops: + ops = [item for p, items in openapi_by_path.items() if _paths_match(tmpl, p) for item in items] + for op in ops: + store.upsert_edge( + Edge( + src=route["id"], + dst=node_id(NodeType.OPENAPI_PATH, f"{op['method']} {op['path']}"), + type=EdgeType.PUBLISHES_ROUTE, + confidence=1.0, + extra={"via": "openapi"}, + ) + ) + + # Clients consumed_by matching routes / openapi + for client in clients: + raw = (client.get("extra") or {}).get("raw") or client["name"] + tmpl = normalize_url_template(str(raw)) + matched = False + generated = any( + client.get("file_path") and str(client["file_path"]).replace("\\", "/").endswith(g.replace("\\", "/")) + or (client.get("file_path") and g.replace("\\", "/") in str(client["file_path"]).replace("\\", "/")) + for g in generated_files + ) + if client.get("file_path"): + fp = str(client["file_path"]).replace("\\", "/") + generated = generated or "/generated/" in f"/{fp}/" or "openapi" in Path(fp).name.lower() + + for route in routes: + extra = route.get("extra") or {} + if extra.get("include"): + continue + rraw = extra.get("mounted_at") or extra.get("full_path") or extra.get("route") or route["name"] + rtmpl = django_route_to_template(str(rraw)) + if _paths_match(tmpl, rtmpl): + conf = 0.95 if generated else 0.55 + store.upsert_edge( + Edge( + src=route["id"], + dst=client["id"], + type=EdgeType.CONSUMED_BY_CLIENT, + confidence=conf, + extra={"match": "url_template", "generated_client": generated, "django": rtmpl, "react": tmpl}, + ) + ) + matched = True + if not generated: + residuals.append( + f"Inferred client stitch {tmpl} ↔ {rtmpl} from string URL in {client.get('file_path')} " + "(not a generated OpenAPI client)" + ) + for op in openapi_by_path.get(tmpl, []): + store.upsert_edge( + Edge( + src=node_id(NodeType.OPENAPI_PATH, f"{op['method']} {op['path']}"), + dst=client["id"], + type=EdgeType.CONSUMED_BY_CLIENT, + confidence=1.0 if generated else 0.7, + extra={"via": "openapi", "generated_client": generated}, + ) + ) + matched = True + if not matched and tmpl.startswith("/api/"): + residuals.append(f"React client {tmpl} has no matching Django route ({client.get('file_path')})") + + # Serializer field ↔ Zod field overlap + fields_by_serializer: dict[str, list[dict]] = {} + for f in ser_fields: + parent = f["qualified_name"].rsplit(".", 1)[0] + fields_by_serializer.setdefault(parent, []).append(f) + + for schema in schemas: + zod_fields = set((schema.get("extra") or {}).get("fields") or []) + if not zod_fields: + continue + 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"], [])} + if not names: + continue + overlap = zod_fields & names + union = zod_fields | names + score = len(overlap) / len(union) if union else 0 + if score >= 0.4 and (best is None or score > best[0]): + best = (score, ser, overlap) + if best: + score, ser, overlap = best + 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}, + ) + ) + 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"], [])} + for fname in overlap: + if fname in ser_fields_map: + store.upsert_edge( + Edge( + src=ser_fields_map[fname]["id"], + dst=schema["id"], + type=EdgeType.MATCHES_SCHEMA, + confidence=0.6, + extra={"field": fname, "inferred": True}, + ) + ) + + # Public API from manifest + for ctx in config.contexts.values(): + for spec in ctx.public_api: + method, path = parse_public_api(spec) + for route in routes: + rraw = (route.get("extra") or {}).get("route") or route["name"] + if _paths_match(django_route_to_template(str(rraw)), path): + if route.get("context") and route["context"] != ctx.name: + store.upsert_edge( + Edge( + src=route["id"], + dst=node_id(NodeType.BOUNDED_CONTEXT, ctx.name), + type=EdgeType.CROSSES_CONTEXT, + extra={"declared_public_api": spec}, + ) + ) + + store.conn.commit() + return residuals + + +def _paths_match(a: str, b: str) -> bool: + a = normalize_url_template(a) + b = django_route_to_template(b) + if a == b: + return True + a_base = re.sub(r"""/\{id\}$""", "", a) + b_base = re.sub(r"""/\{id\}$""", "", b) + if a_base == b_base: + return True + # included Django urls often omit the /api mount until composed + a_tail = a.rsplit("/", 2)[-2:] + b_tail = b.rsplit("/", 2)[-2:] + if a.endswith(b) or b.endswith(a): + return True + return "/".join(a_tail) == "/".join(b_tail) and len(a_tail[-1]) > 2 + + +def _generated_client_files(repo_root: Path, config: LoadpathConfig) -> list[str]: + found: list[str] = [] + for pattern in config.generated_client_globs: + # pathlib doesn't expand {ts,tsx} + if "{" in pattern: + pre, rest = pattern.split("{", 1) + exts = rest.split("}", 1)[0].split(",") + suffix = rest.split("}", 1)[1] if "}" in rest else "" + for ext in exts: + found.extend(str(p.relative_to(repo_root)) for p in repo_root.glob(pre + ext + suffix)) + else: + found.extend(str(p.relative_to(repo_root)) for p in repo_root.glob(pattern)) + return found diff --git a/src/loadpath/types.py b/src/loadpath/types.py new file mode 100644 index 0000000..c605122 --- /dev/null +++ b/src/loadpath/types.py @@ -0,0 +1,244 @@ +from __future__ import annotations + +from dataclasses import dataclass, field +from enum import StrEnum +from typing import Any + + +class Layer(StrEnum): + DJANGO = "django" + REACT = "react" + STITCH = "stitch" + ARCH = "arch" + TEST = "test" + + +class NodeType(StrEnum): + # Architecture + BOUNDED_CONTEXT = "arch.context" + # Django + APP = "django.app" + ROUTE = "django.route" + URL_NAME = "django.url_name" + VIEW = "django.view" + VIEWSET_ACTION = "django.viewset_action" + SERIALIZER = "django.serializer" + SERIALIZER_FIELD = "django.serializer_field" + SERVICE = "django.service" + MODEL = "django.model" + FIELD = "django.field" + RELATION = "django.relation" + SIGNAL = "django.signal" + RECEIVER = "django.receiver" + TASK = "django.task" + PERMISSION = "django.permission" + THROTTLE = "django.throttle" + MIGRATION_OP = "django.migration_op" + ADMIN = "django.admin" + MANAGEMENT_COMMAND = "django.management_command" + TEST = "django.test" + # React + REACT_ROUTE = "react.route" + PAGE = "react.page" + FEATURE_MODULE = "react.feature" + COMPONENT = "react.component" + HOOK = "react.hook" + API_CLIENT = "react.api_client" + QUERY_KEY = "react.query_key" + FORM_SCHEMA = "react.form_schema" + CONTEXT_PROVIDER = "react.context" + REACT_TEST = "react.test" + # Stitch + OPENAPI_PATH = "openapi.path" + + +class EdgeType(StrEnum): + CALLS = "calls" + IMPORTS = "imports" + RENDERS = "renders" + BELONGS_TO = "belongs_to" + HAS_FIELD = "has_field" + SERIALIZES = "serializes" + QUERIES_MODEL = "queries_model" + ENQUEUES = "enqueues" + EMITS_SIGNAL = "emits_signal" + RECEIVES = "receives" + PUBLISHES_ROUTE = "publishes_route" + CONSUMED_BY_CLIENT = "consumed_by_client" + CROSSES_CONTEXT = "crosses_context" + CHANGES_PERMISSION = "changes_permission" + DESTRUCTIVE_MIGRATION = "destructive_migration" + TESTED_BY = "tested_by" + USES_QUERY_KEY = "uses_query_key" + MATCHES_SCHEMA = "matches_schema" + USES_SERIALIZER = "uses_serializer" + HAS_PERMISSION = "has_permission" + SERVES = "serves" + RELATES_TO = "relates_to" + + +class EdgeWeight(StrEnum): + CHEAP = "cheap" + EXPENSIVE = "expensive" + CRITICAL = "critical" + + +CHEAP_EDGES = { + EdgeType.CALLS, + EdgeType.IMPORTS, + EdgeType.RENDERS, + EdgeType.BELONGS_TO, + EdgeType.HAS_FIELD, + EdgeType.SERVES, + EdgeType.USES_QUERY_KEY, + EdgeType.RELATES_TO, +} +EXPENSIVE_EDGES = { + EdgeType.SERIALIZES, + EdgeType.QUERIES_MODEL, + EdgeType.ENQUEUES, + EdgeType.EMITS_SIGNAL, + EdgeType.RECEIVES, + EdgeType.USES_SERIALIZER, + EdgeType.HAS_PERMISSION, + EdgeType.TESTED_BY, + EdgeType.MATCHES_SCHEMA, +} +CRITICAL_EDGES = { + EdgeType.PUBLISHES_ROUTE, + EdgeType.CONSUMED_BY_CLIENT, + EdgeType.CROSSES_CONTEXT, + EdgeType.CHANGES_PERMISSION, + EdgeType.DESTRUCTIVE_MIGRATION, +} + +SINK_TYPES = { + NodeType.ROUTE, + NodeType.REACT_ROUTE, + NodeType.PAGE, + NodeType.TASK, + NodeType.MIGRATION_OP, + NodeType.PERMISSION, + NodeType.ADMIN, + NodeType.MANAGEMENT_COMMAND, + NodeType.OPENAPI_PATH, +} + +CONTRACT_TYPES = { + NodeType.SERIALIZER, + NodeType.SERIALIZER_FIELD, + NodeType.OPENAPI_PATH, + NodeType.FORM_SCHEMA, + NodeType.ROUTE, +} + +GENERATED_PATH_MARKERS = ( + "node_modules/", + "package-lock.json", + "yarn.lock", + "pnpm-lock.yaml", + "poetry.lock", + ".min.js", + "generated/", + "__pycache__/", + ".egg-info/", +) + + +class ChangeKind(StrEnum): + LEAF_UI = "leaf_ui" + INTERNAL_SERVICE = "internal_service" + PUBLIC_CONTRACT = "public_contract" + SCHEMA_MIGRATION = "schema_migration" + AUTH = "auth" + CROSS_CONTEXT = "cross_context" + MIXED = "mixed" + + +class ConfidenceLevel(StrEnum): + HIGH = "high" + MEDIUM = "medium" + LOW = "low" + + +class RuleSeverity(StrEnum): + BLOCKER = "blocker" + WARNING = "warning" + + +def weight_for(edge_type: EdgeType) -> EdgeWeight: + if edge_type in CRITICAL_EDGES: + return EdgeWeight.CRITICAL + if edge_type in EXPENSIVE_EDGES: + return EdgeWeight.EXPENSIVE + return EdgeWeight.CHEAP + + +def node_id(node_type: NodeType, qualified_name: str) -> str: + return f"{node_type}:{qualified_name}" + + +@dataclass +class Node: + id: str + type: NodeType + name: str + qualified_name: str + file_path: str | None = None + start_line: int | None = None + end_line: int | None = None + context: str | None = None + extra: dict[str, Any] = field(default_factory=dict) + + def to_row(self) -> dict[str, Any]: + return { + "id": self.id, + "type": self.type.value, + "name": self.name, + "qualified_name": self.qualified_name, + "file_path": self.file_path, + "start_line": self.start_line, + "end_line": self.end_line, + "context": self.context, + "extra": self.extra, + } + + +@dataclass +class Edge: + src: str + dst: str + type: EdgeType + confidence: float = 1.0 + extra: dict[str, Any] = field(default_factory=dict) + + @property + def weight(self) -> EdgeWeight: + return weight_for(self.type) + + @property + def id(self) -> str: + return f"{self.src}|{self.type}|{self.dst}" + + def to_row(self) -> dict[str, Any]: + return { + "id": self.id, + "src": self.src, + "dst": self.dst, + "type": self.type.value, + "weight": self.weight.value, + "confidence": self.confidence, + "extra": self.extra, + } + + +@dataclass +class ExtractedGraph: + nodes: list[Node] = field(default_factory=list) + edges: list[Edge] = field(default_factory=list) + residuals: list[str] = field(default_factory=list) + + def extend(self, other: ExtractedGraph) -> None: + self.nodes.extend(other.nodes) + self.edges.extend(other.edges) + self.residuals.extend(other.residuals) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..e0e149a --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,26 @@ +from __future__ import annotations + +import shutil +import subprocess +from pathlib import Path + +FIXTURE_ROOT = Path(__file__).resolve().parents[1] / "fixtures" / "demo_monorepo" + + +def copy_fixture(dest: Path) -> Path: + root = dest / "demo" + shutil.copytree(FIXTURE_ROOT, root) + return root + + +def git_init_with_main(repo: Path) -> None: + subprocess.check_call(["git", "init", "-b", "main"], cwd=repo, stdout=subprocess.DEVNULL) + subprocess.check_call(["git", "config", "user.email", "loadpath@test"], cwd=repo) + subprocess.check_call(["git", "config", "user.name", "Loadpath Tests"], cwd=repo) + subprocess.check_call(["git", "add", "-A"], cwd=repo) + subprocess.check_call(["git", "commit", "-m", "baseline"], cwd=repo, stdout=subprocess.DEVNULL) + + +def git_commit_all(repo: Path, message: str) -> None: + subprocess.check_call(["git", "add", "-A"], cwd=repo) + subprocess.check_call(["git", "commit", "-m", message], cwd=repo, stdout=subprocess.DEVNULL) diff --git a/tests/e2e/__init__.py b/tests/e2e/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/e2e/test_cli_review.py b/tests/e2e/test_cli_review.py new file mode 100644 index 0000000..61334ea --- /dev/null +++ b/tests/e2e/test_cli_review.py @@ -0,0 +1,22 @@ +from __future__ import annotations + +from typer.testing import CliRunner + +from loadpath.cli import app +from tests.conftest import copy_fixture, git_commit_all, git_init_with_main + +runner = CliRunner() + + +def test_cli_index_and_review(tmp_path): + repo = copy_fixture(tmp_path) + git_init_with_main(repo) + ser = repo / "backend/billing/serializers.py" + ser.write_text(ser.read_text() + "\n# touch\n") + git_commit_all(repo, "touch serializer") + result = runner.invoke(app, ["index", str(repo)]) + assert result.exit_code == 0, result.output + assert "nodes" in result.output + result = runner.invoke(app, ["review", str(repo), "--base", "HEAD~1", "--head", "HEAD"]) + assert result.exit_code == 0, result.output + assert "Loadpath" in result.output diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/integration/test_review_vertical_slice.py b/tests/integration/test_review_vertical_slice.py new file mode 100644 index 0000000..7ef7f3f --- /dev/null +++ b/tests/integration/test_review_vertical_slice.py @@ -0,0 +1,109 @@ +from __future__ import annotations + +from pathlib import Path + +from fastapi.testclient import TestClient + +from loadpath.review.engine import run_review +from loadpath.review.render import render_html, render_markdown +from loadpath.server.app import create_app +from tests.conftest import copy_fixture, git_commit_all, git_init_with_main + + +def _change_serializer_total(repo: Path) -> None: + path = repo / "backend/billing/serializers.py" + text = path.read_text() + path.write_text( + text.replace( + 'fields = ["id", "customer_id", "total", "status"]', + 'fields = ["id", "customer_id", "total", "status"]\n extra_kwargs = {"total": {"required": True}}', + ) + ) + + +def test_serializer_field_change_traces_to_react_form(tmp_path: Path): + repo = copy_fixture(tmp_path) + git_init_with_main(repo) + _change_serializer_total(repo) + git_commit_all(repo, "tighten Invoice.total contract") + + review = run_review(repo, base="HEAD~1", head="HEAD") + node_types = {n["type"] for n in review["nodes"]} + names = {n["name"] for n in review["nodes"]} + + assert "django.serializer" in node_types or "django.serializer_field" in node_types + assert "total" in names or any("total" in (n.get("qualified_name") or "") for n in review["nodes"]) + assert any(n["type"] == "django.route" for n in review["nodes"]) + assert any(n["type"] == "react.api_client" for n in review["nodes"]) + assert any(n["name"] in {"useInvoice", "InvoicePage", "InvoiceForm", "invoiceSchema"} for n in review["nodes"]) + assert any(n["type"] == "react.form_schema" for n in review["nodes"]) + assert any(n["type"] == "django.task" and "send_invoice_email" in n["name"] for n in review["nodes"]) + assert any(n["type"] == "react.page" and n["name"] == "InvoicePage" for n in review["nodes"]) + assert not any(n["name"] in {"MePage", "MeView", "MeSerializer"} for n in review["nodes"]) + assert review["suggested_reviewers"] == ["billing-team"] + assert any(e["type"] == "consumed_by_client" for e in review["edges"]) + assert any(e["type"] == "matches_schema" for e in review["edges"]) + + assert review["confidence"]["level"] in {"medium", "low"} + assert "cross_context" not in review["change_kinds"] + assert "public_contract" in review["change_kinds"] + assert any("billing" in (r.lower()) for r in review["suggested_reviewers"]) or review["suggested_reviewers"] == [ + "billing-team" + ] + + md = render_markdown(review) + assert "Loadpath:" in md + assert "Invoice" in md or "total" in md.lower() + html = render_html(review) + assert "vis-network" in html + assert review["nodes"] + + # residual: signal and/or inferred client stitch + blob = " ".join(review["residuals"]) + review["tests_note"] + review["headline"] + assert "InvoiceForm" in blob or "update_ledger" in blob or "inferred" in blob.lower() or "RTL" in blob or "test" in blob.lower() + assert "update_ledger" in " ".join(review["residuals"]) + + +def test_leaf_css_is_low_risk(tmp_path: Path): + repo = copy_fixture(tmp_path) + git_init_with_main(repo) + css = repo / "frontend/src/features/billing/InvoiceForm.module.css" + css.write_text(".form { padding: 8px; }\n") + git_commit_all(repo, "leaf padding") + review = run_review(repo, base="HEAD~1", head="HEAD") + # css is skipped as non-source; remaining empty / low + assert review["low_risk"] or not review["clusters"] or review["confidence"]["level"] == "high" + + +def test_contract_drift_when_serializer_drops_field(tmp_path: Path): + repo = copy_fixture(tmp_path) + git_init_with_main(repo) + path = repo / "backend/billing/serializers.py" + path.write_text(path.read_text().replace('"total", ', "")) + git_commit_all(repo, "remove total from serializer") + review = run_review(repo, base="HEAD~1", head="HEAD") + rules = [f["rule"] for f in review["findings"] if not f.get("waived")] + assert "serializers_are_the_only_published_contract" in rules + assert review["confidence"]["level"] == "low" + + +def test_api_review_endpoint(tmp_path: Path): + repo = copy_fixture(tmp_path) + git_init_with_main(repo) + _change_serializer_total(repo) + git_commit_all(repo, "total") + client = TestClient(create_app()) + r = client.post("/api/index", json={"repo_path": str(repo), "incremental": False}) + assert r.status_code == 200, r.text + assert r.json()["counts"]["nodes"] > 10 + r = client.post( + "/api/review", + json={"repo_path": str(repo), "base": "HEAD~1", "head": "HEAD", "reindex": False}, + ) + assert r.status_code == 200, r.text + body = r.json() + assert body["confidence"]["level"] in {"high", "medium", "low"} + assert "markdown" in body + g = client.get("/api/graph", params={"repo_path": str(repo)}) + assert g.status_code == 200 + assert g.json()["counts"]["nodes"] > 0 diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/test_ai.py b/tests/unit/test_ai.py new file mode 100644 index 0000000..8d52174 --- /dev/null +++ b/tests/unit/test_ai.py @@ -0,0 +1,37 @@ +from __future__ import annotations + +import json + +from loadpath.ai.providers import OpenAICompatible, residual_prompt + + +def test_openai_compatible_completion(): + import httpx + + def handler(request: httpx.Request) -> httpx.Response: + payload = json.loads(request.content) + assert payload["messages"][0]["role"] == "system" + return httpx.Response( + 200, + json={"choices": [{"message": {"content": "Signal update_ledger still formats total."}}]}, + ) + + client = httpx.Client(transport=httpx.MockTransport(handler)) + ai = OpenAICompatible("sk-test", "grok-3", base_url="https://api.x.ai/v1", client=client) + note = ai.complete("residuals: update_ledger") + assert "update_ledger" in note + + +def test_residual_prompt_includes_graph(): + prompt = residual_prompt( + { + "title": "Invoice.total", + "confidence": {"level": "medium"}, + "change_kinds": ["public_contract"], + "residuals": ["inferred client /api/invoices/{id}"], + "findings": [], + "nodes": [{"type": "django.serializer", "qualified_name": "billing.InvoiceSerializer", "file_path": "s.py"}], + } + ) + assert "Invoice.total" in prompt + assert "inferred client" in prompt diff --git a/tests/unit/test_architecture_rules.py b/tests/unit/test_architecture_rules.py new file mode 100644 index 0000000..eed8251 --- /dev/null +++ b/tests/unit/test_architecture_rules.py @@ -0,0 +1,56 @@ +from __future__ import annotations + +from pathlib import Path + +from loadpath.architecture.rules import evaluate +from loadpath.config import load_config +from loadpath.index import index_repo +from loadpath.types import NodeType + +from tests.conftest import FIXTURE_ROOT as FIXTURE + + +def test_queryset_rule_and_task_rule(tmp_path: Path): + store = index_repo(FIXTURE, db_path=tmp_path / "g.sqlite3", incremental=False) + cfg = load_config(FIXTURE) + findings = evaluate(store, cfg) + # healthy fixture: task uses invoice_id, no queryset in serializer + assert not any(f.rule == "no_queryset_in_serializer" and not f.waived for f in findings) + assert not any( + f.rule == "celery_tasks_must_be_idempotent_on_model_pk" and not f.waived for f in findings + ) + store.close() + + +def test_foreign_model_import_is_blocker(tmp_path: Path): + # mutate a copy + import shutil + + root = tmp_path / "repo" + shutil.copytree(FIXTURE, root) + leak = root / "backend/billing/views.py" + text = leak.read_text() + leak.write_text("from accounts.models import UserProfile\n" + text) + store = index_repo(root, db_path=tmp_path / "g.sqlite3", incremental=False) + findings = evaluate(store, load_config(root)) + hits = [f for f in findings if f.rule == "views_cannot_import_other_context_models" and not f.waived] + assert hits, findings + store.close() + + +def test_react_feature_calling_other_context_api(tmp_path: Path): + import shutil + + root = tmp_path / "repo" + shutil.copytree(FIXTURE, root) + api = root / "frontend/src/features/billing/api.ts" + api.write_text(api.read_text() + "\nexport const me = () => fetch('/api/me');\n") + store = index_repo(root, db_path=tmp_path / "g.sqlite3", incremental=False) + findings = evaluate(store, load_config(root)) + hits = [ + f + for f in findings + if f.rule == "react_feature_may_only_call_own_or_shared_api" and not f.waived + ] + assert hits, [f.message for f in findings] + store.close() diff --git a/tests/unit/test_django_extractors.py b/tests/unit/test_django_extractors.py new file mode 100644 index 0000000..03943bd --- /dev/null +++ b/tests/unit/test_django_extractors.py @@ -0,0 +1,138 @@ +from __future__ import annotations + +from loadpath.config import load_config +from loadpath.extractors.django import extract_django_file +from loadpath.types import NodeType + +from tests.conftest import FIXTURE_ROOT as FIXTURE + + +def _cfg(): + return load_config(FIXTURE) + + +def test_extracts_model_fields_and_relations(): + source = (FIXTURE / "backend/billing/models.py").read_text() + g = extract_django_file("backend/billing/models.py", source, _cfg()) + names = {n.qualified_name: n for n in g.nodes} + assert "billing.Invoice" in names + assert "billing.Invoice.total" in names + assert names["billing.Invoice.total"].type is NodeType.FIELD + + +def test_extracts_serializer_fields_and_model_link(): + source = (FIXTURE / "backend/billing/serializers.py").read_text() + g = extract_django_file("backend/billing/serializers.py", source, _cfg()) + fields = [n for n in g.nodes if n.type is NodeType.SERIALIZER_FIELD] + assert {f.name for f in fields} >= {"id", "customer_id", "total", "status"} + assert any(e.type.value == "serializes" for e in g.edges) + + +def test_extracts_view_serializer_permissions_and_enqueue(): + source = (FIXTURE / "backend/billing/views.py").read_text() + g = extract_django_file("backend/billing/views.py", source, _cfg()) + views = [n for n in g.nodes if n.type is NodeType.VIEW] + assert any(v.name == "InvoiceViewSet" for v in views) + assert any(e.type.value == "uses_serializer" for e in g.edges) + assert any(e.type.value == "enqueues" for e in g.edges) + assert any( + e.type.value == "enqueues" and "InvoiceViewSet" in e.src for e in g.edges + ) + perms = [n for n in g.nodes if n.type is NodeType.PERMISSION] + assert any(p.name == "IsAuthenticated" for p in perms) + + +def test_extracts_router_and_path_routes(): + source = (FIXTURE / "backend/billing/urls.py").read_text() + g = extract_django_file("backend/billing/urls.py", source, _cfg()) + routes = [n for n in g.nodes if n.type is NodeType.ROUTE] + assert routes + assert any(e.type.value == "publishes_route" for e in g.edges) + + +def test_extracts_signal_receiver(): + source = (FIXTURE / "backend/billing/signals.py").read_text() + g = extract_django_file("backend/billing/signals.py", source, _cfg()) + rec = [n for n in g.nodes if n.type is NodeType.RECEIVER] + assert rec[0].name == "update_ledger" + assert rec[0].extra.get("sender") in {"Invoice", "billing.Invoice"} + + +def test_extracts_celery_task_pk_idempotency(): + source = (FIXTURE / "backend/billing/tasks.py").read_text() + g = extract_django_file("backend/billing/tasks.py", source, _cfg()) + tasks = [n for n in g.nodes if n.type is NodeType.TASK] + assert tasks[0].name == "send_invoice_email" + assert tasks[0].extra["looks_idempotent_on_pk"] is True + + +def test_extracts_service_and_admin_and_tests(): + cfg = _cfg() + svc = extract_django_file( + "backend/billing/services.py", + (FIXTURE / "backend/billing/services.py").read_text(), + cfg, + ) + assert any(n.type is NodeType.SERVICE and n.name == "recalculate_total" for n in svc.nodes) + admin = extract_django_file( + "backend/billing/admin.py", + (FIXTURE / "backend/billing/admin.py").read_text(), + cfg, + ) + assert any(n.type is NodeType.ADMIN for n in admin.nodes) + tests = extract_django_file( + "backend/billing/tests.py", + (FIXTURE / "backend/billing/tests.py").read_text(), + cfg, + ) + assert any(n.type is NodeType.TEST for n in tests.nodes) + assert any(e.type.value == "tested_by" for e in tests.edges) + + +def test_extracts_migration_ops(): + source = (FIXTURE / "backend/billing/migrations/0001_initial.py").read_text() + g = extract_django_file("backend/billing/migrations/0001_initial.py", source, _cfg()) + assert any(n.type is NodeType.MIGRATION_OP and "CreateModel" in n.name for n in g.nodes) + + +def test_appconfig_ready_is_residual(): + source = (FIXTURE / "backend/billing/apps.py").read_text() + g = extract_django_file("backend/billing/apps.py", source, _cfg()) + assert any("AppConfig.ready" in r for r in g.residuals) + + +def test_get_model_string_ref_is_residual(): + src = 'from django.apps import apps\nm = apps.get_model("billing.Invoice")\n' + g = extract_django_file("backend/billing/dynamic.py", src, _cfg()) + assert any("get_model" in r for r in g.residuals) + + +def test_cross_app_model_import_on_view(): + src = """ +from rest_framework.views import APIView +from accounts.models import UserProfile + +class LeakView(APIView): + def get(self, request): + return UserProfile.objects.all() +""" + g = extract_django_file("backend/billing/legacy.py", src, _cfg()) + assert any(e.extra.get("foreign_app") == "accounts" for e in g.edges) + + +def test_queryset_in_serializer_flagged(): + src = """ +from rest_framework import serializers +from billing.models import Invoice + +class BadSerializer(serializers.ModelSerializer): + def validate(self, attrs): + Invoice.objects.filter(total=attrs["total"]) + return attrs + class Meta: + model = Invoice + fields = ["total"] +""" + g = extract_django_file("backend/billing/serializers.py", src, _cfg()) + ser = next(n for n in g.nodes if n.type is NodeType.SERIALIZER) + assert ser.extra.get("queryset_in_serializer") is True diff --git a/tests/unit/test_index_and_stitch.py b/tests/unit/test_index_and_stitch.py new file mode 100644 index 0000000..dc448ea --- /dev/null +++ b/tests/unit/test_index_and_stitch.py @@ -0,0 +1,40 @@ +from __future__ import annotations + +from pathlib import Path + +from loadpath.config import load_config +from loadpath.index import index_repo +from loadpath.types import NodeType + +from tests.conftest import FIXTURE_ROOT as FIXTURE + + +def test_index_stitches_django_route_to_react_client(tmp_path: Path): + db = tmp_path / "graph.sqlite3" + store = index_repo(FIXTURE, db_path=db, incremental=False) + edges = store.edges() + consumed = [e for e in edges if e["type"] == "consumed_by_client"] + assert consumed, "expected URL stitch between Django routes and React fetch" + inferred = [e for e in consumed if e["confidence"] < 0.9] + assert inferred, "string-matched fetch must be marked inferred (lower confidence)" + schema_edges = [e for e in edges if e["type"] == "matches_schema"] + assert schema_edges, "serializer fields should overlap invoiceSchema" + store.close() + + +def test_index_is_incremental(tmp_path: Path): + db = tmp_path / "graph.sqlite3" + store = index_repo(FIXTURE, db_path=db, incremental=False) + first = store.counts() + store.close() + store = index_repo(FIXTURE, db_path=db, incremental=True) + second = store.counts() + store.close() + assert first["nodes"] == second["nodes"] + + +def test_contexts_assigned(tmp_path: Path): + store = index_repo(FIXTURE, db_path=tmp_path / "g.sqlite3", incremental=False) + invoice = next(n for n in store.nodes([NodeType.MODEL]) if n["name"] == "Invoice") + assert invoice["context"] == "billing" + store.close() diff --git a/tests/unit/test_providers_and_api.py b/tests/unit/test_providers_and_api.py new file mode 100644 index 0000000..b5cbb1c --- /dev/null +++ b/tests/unit/test_providers_and_api.py @@ -0,0 +1,75 @@ +from __future__ import annotations + +from pathlib import Path + +from fastapi.testclient import TestClient + +from loadpath.providers.scm import BitbucketProvider, GitHubProvider +from loadpath.server.app import create_app +from loadpath.settings import AppSettings + + +def test_github_lists_pull_requests(): + import httpx + + client = httpx.Client(transport=httpx.MockTransport(lambda r: httpx.Response( + 200, + json=[ + { + "id": 9, + "number": 12, + "title": "Invoice total", + "html_url": "https://github.com/acme/demo/pull/12", + "user": {"login": "ada"}, + "head": {"ref": "feat/total"}, + "base": {"ref": "main"}, + "state": "open", + "updated_at": "2026-08-14T00:00:00Z", + "draft": False, + } + ], + ))) + gh = GitHubProvider("tok", client=client) + prs = gh.list_pull_requests("acme/demo") + assert prs[0].number == 12 + assert prs[0].source_branch == "feat/total" + + +def test_bitbucket_lists_pull_requests(): + import httpx + + payload = { + "values": [ + { + "id": 3, + "title": "auth", + "links": {"html": {"href": "https://bitbucket.org/acme/demo/pull-requests/3"}}, + "author": {"display_name": "bob"}, + "source": {"branch": {"name": "feat"}}, + "destination": {"branch": {"name": "main"}}, + "state": "OPEN", + "updated_on": "2026-08-14T00:00:00Z", + } + ] + } + + def handler(request: httpx.Request) -> httpx.Response: + return httpx.Response(200, json=payload) + + client = httpx.Client(transport=httpx.MockTransport(handler)) + bb = BitbucketProvider("tok", username="bob", client=client) + prs = bb.list_pull_requests("acme/demo") + assert prs[0].number == 3 + assert prs[0].provider == "bitbucket" + + +def test_health_and_settings(tmp_path, monkeypatch): + monkeypatch.setenv("HOME", str(tmp_path)) + app = create_app() + c = TestClient(app) + assert c.get("/api/health").json()["status"] == "ok" + r = c.put("/api/settings", json={"github_token": "ghp_secret_token", "ai_provider": "anthropic"}) + body = r.json() + assert body["github_token_set"] is True + assert "secret" not in body["github_token"] + assert body["ai"]["provider"] == "anthropic" diff --git a/tests/unit/test_react_extractors.py b/tests/unit/test_react_extractors.py new file mode 100644 index 0000000..66a8586 --- /dev/null +++ b/tests/unit/test_react_extractors.py @@ -0,0 +1,73 @@ +from __future__ import annotations + +from loadpath.config import load_config +from loadpath.extractors.react import extract_react_file, normalize_url_template +from loadpath.types import NodeType + +from tests.conftest import FIXTURE_ROOT as FIXTURE + + +def _cfg(): + return load_config(FIXTURE) + + +def test_normalize_url_templates(): + assert normalize_url_template("/api/invoices/${id}") == "/api/invoices/{id}" + assert normalize_url_template("`/api/invoices/${id}`".strip("`")) == "/api/invoices/{id}" + + +def test_extracts_react_routes_and_pages(): + source = (FIXTURE / "frontend/src/App.tsx").read_text() + g = extract_react_file("frontend/src/App.tsx", source, _cfg()) + routes = [n for n in g.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.name == "InvoicePage" for n in g.nodes) + + +def test_extracts_hook_query_key_and_fetch_url(): + hook = extract_react_file( + "frontend/src/features/billing/useInvoice.ts", + (FIXTURE / "frontend/src/features/billing/useInvoice.ts").read_text(), + _cfg(), + ) + assert any(n.type is NodeType.HOOK and n.name == "useInvoice" for n in hook.nodes) + assert any(n.type is NodeType.QUERY_KEY for n in hook.nodes) + api = extract_react_file( + "frontend/src/features/billing/api.ts", + (FIXTURE / "frontend/src/features/billing/api.ts").read_text(), + _cfg(), + ) + clients = [n for n in api.nodes if n.type is NodeType.API_CLIENT] + assert any(c.name == "/api/invoices/{id}" for c in clients) + + +def test_extracts_zod_schema_fields(): + g = extract_react_file( + "frontend/src/features/billing/invoiceSchema.ts", + (FIXTURE / "frontend/src/features/billing/invoiceSchema.ts").read_text(), + _cfg(), + ) + schema = next(n for n in g.nodes if n.type is NodeType.FORM_SCHEMA) + assert schema.name == "invoiceSchema" + assert set(schema.extra["fields"]) >= {"customer_id", "total", "status"} + + +def test_extracts_page_renders_form(): + g = extract_react_file( + "frontend/src/features/billing/InvoicePage.tsx", + (FIXTURE / "frontend/src/features/billing/InvoicePage.tsx").read_text(), + _cfg(), + ) + assert any(n.type is NodeType.PAGE and n.name == "InvoicePage" for n in g.nodes) + assert any(e.type.value == "renders" for e in g.edges) + + +def test_feature_context_from_path(): + cfg = _cfg() + g = extract_react_file( + "frontend/src/features/auth/MePage.tsx", + (FIXTURE / "frontend/src/features/auth/MePage.tsx").read_text(), + cfg, + ) + pages = [n for n in g.nodes if n.type in {NodeType.PAGE, NodeType.HOOK}] + assert any(n.context == "identity" for n in pages) diff --git a/ui/index.html b/ui/index.html new file mode 100644 index 0000000..b325dab --- /dev/null +++ b/ui/index.html @@ -0,0 +1,15 @@ + + + + + + Loadpath + + + + + +
+ + + diff --git a/ui/package-lock.json b/ui/package-lock.json new file mode 100644 index 0000000..3f9fa0b --- /dev/null +++ b/ui/package-lock.json @@ -0,0 +1,4266 @@ +{ + "name": "loadpath-ui", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "loadpath-ui", + "version": "0.1.0", + "dependencies": { + "@xyflow/react": "^12.6.0", + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react": "^4.3.4", + "jsdom": "^25.0.1", + "typescript": "^5.6.3", + "vite": "^6.0.3", + "vitest": "^2.1.8" + } + }, + "node_modules/@asamuzakjp/css-color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", + "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.3", + "@csstools/css-color-parser": "^3.0.9", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.8", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/lzma-linux-x64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", + "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.4.tgz", + "integrity": "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.4.tgz", + "integrity": "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.4.tgz", + "integrity": "sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.4.tgz", + "integrity": "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.4.tgz", + "integrity": "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.4.tgz", + "integrity": "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.4.tgz", + "integrity": "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.4.tgz", + "integrity": "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.4.tgz", + "integrity": "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.4.tgz", + "integrity": "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.4.tgz", + "integrity": "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.4.tgz", + "integrity": "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.4.tgz", + "integrity": "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.4.tgz", + "integrity": "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.4.tgz", + "integrity": "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.4.tgz", + "integrity": "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.4.tgz", + "integrity": "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.4.tgz", + "integrity": "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.4.tgz", + "integrity": "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.4.tgz", + "integrity": "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.4.tgz", + "integrity": "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.4.tgz", + "integrity": "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.4.tgz", + "integrity": "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.4.tgz", + "integrity": "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.4.tgz", + "integrity": "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "license": "MIT" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "license": "MIT", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.31", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.31.tgz", + "integrity": "sha512-vfEqpXTvwT91yhmwdfouStN2hSKwTvyRs8qpLfADyrq/kxDw0hZM7Wk9Ug1FELj8hIby+S/+kQCSRFF32nv2Qw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "devOptional": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@vitest/expect": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz", + "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", + "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz", + "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.1.9", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", + "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz", + "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", + "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@xyflow/react": { + "version": "12.11.3", + "resolved": "https://registry.npmjs.org/@xyflow/react/-/react-12.11.3.tgz", + "integrity": "sha512-G3jogHz2GWUtIOkhavUGno2YzY9u6fILIJBttfsBendb0/HWB90JG+sOTAvlIMEwyvq9zgy9V9ZQSwyQjR5QzQ==", + "license": "MIT", + "dependencies": { + "@xyflow/system": "0.0.80", + "classcat": "^5.0.3", + "zustand": "^4.4.0" + }, + "peerDependencies": { + "@types/react": ">=17", + "@types/react-dom": ">=17", + "react": ">=17", + "react-dom": ">=17" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@xyflow/system": { + "version": "0.0.80", + "resolved": "https://registry.npmjs.org/@xyflow/system/-/system-0.0.80.tgz", + "integrity": "sha512-ywc3ZqG91brzWrH1WlwMdIX4goOfrpBy6AbLdVSaof/Xx9l138ijIKRExM6EkMro2F+OImGmSiA/WKcXvKVcfA==", + "license": "MIT", + "dependencies": { + "@types/d3-drag": "^3.0.7", + "@types/d3-interpolate": "^3.0.4", + "@types/d3-selection": "^3.0.10", + "@types/d3-transition": "^3.0.8", + "@types/d3-zoom": "^3.0.8", + "d3-drag": "^3.0.0", + "d3-interpolate": "^3.0.1", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.14", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.14.tgz", + "integrity": "sha512-JyJ954WzuIR8/FFzX0o5krdSTrBAkcCSRfWSleRsIHSWV+cZe2FI1PKggVkFke1hBldRs+LRxUczzE9iPmgZww==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz", + "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.11.12", + "caniuse-lite": "^1.0.30001809", + "electron-to-chromium": "^1.5.402", + "node-releases": "^2.0.53", + "update-browserslist-db": "^1.3.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001809", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001809.tgz", + "integrity": "sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/classcat": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz", + "integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==", + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", + "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^3.2.0", + "rrweb-cssom": "^0.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cssstyle/node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.406", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.406.tgz", + "integrity": "sha512-hWH5ORBi3d0IipnMh7BN5GDTaAmrSSSWmznwt2zltdiRNEWoEQyTwF0FFSBxzHO7hLSRT6loQu3IQGV0wg/Tvg==", + "dev": true, + "license": "ISC" + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.4", + "mime-types": "^2.1.35" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/jsdom": { + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", + "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssstyle": "^4.1.0", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.12", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.7.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^2.11.2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.53.tgz", + "integrity": "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/nwsapi": { + "version": "2.2.24", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.24.tgz", + "integrity": "sha512-7YRhZ3jS45LwmSCT4b2sVFHt/WuovaktDU07QrtOBY2PXskss5a9jfmR9jptyumwXST+rFjrmppMY1KT/yn35A==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", + "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.17", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.4.tgz", + "integrity": "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@napi-rs/lzma-linux-x64-gnu": "1.5.1", + "@rollup/rollup-android-arm-eabi": "4.62.4", + "@rollup/rollup-android-arm64": "4.62.4", + "@rollup/rollup-darwin-arm64": "4.62.4", + "@rollup/rollup-darwin-x64": "4.62.4", + "@rollup/rollup-freebsd-arm64": "4.62.4", + "@rollup/rollup-freebsd-x64": "4.62.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.4", + "@rollup/rollup-linux-arm-musleabihf": "4.62.4", + "@rollup/rollup-linux-arm64-gnu": "4.62.4", + "@rollup/rollup-linux-arm64-musl": "4.62.4", + "@rollup/rollup-linux-loong64-gnu": "4.62.4", + "@rollup/rollup-linux-loong64-musl": "4.62.4", + "@rollup/rollup-linux-ppc64-gnu": "4.62.4", + "@rollup/rollup-linux-ppc64-musl": "4.62.4", + "@rollup/rollup-linux-riscv64-gnu": "4.62.4", + "@rollup/rollup-linux-riscv64-musl": "4.62.4", + "@rollup/rollup-linux-s390x-gnu": "4.62.4", + "@rollup/rollup-linux-x64-gnu": "4.62.4", + "@rollup/rollup-linux-x64-musl": "4.62.4", + "@rollup/rollup-openbsd-x64": "4.62.4", + "@rollup/rollup-openharmony-arm64": "4.62.4", + "@rollup/rollup-win32-arm64-msvc": "4.62.4", + "@rollup/rollup-win32-ia32-msvc": "4.62.4", + "@rollup/rollup-win32-x64-gnu": "4.62.4", + "@rollup/rollup-win32-x64-msvc": "4.62.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/rrweb-cssom": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", + "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.86" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", + "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tough-cookie": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^6.1.32" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.1.tgz", + "integrity": "sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/vite": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz", + "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.9.tgz", + "integrity": "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-node/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite-node/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vite-node/node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.9.tgz", + "integrity": "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.9", + "@vitest/mocker": "2.1.9", + "@vitest/pretty-format": "^2.1.9", + "@vitest/runner": "2.1.9", + "@vitest/snapshot": "2.1.9", + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.9", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.9", + "@vitest/ui": "2.1.9", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vitest/node_modules/@vitest/mocker": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz", + "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vitest/node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ws": { + "version": "8.21.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", + "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/zustand": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz", + "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + } + } +} diff --git a/ui/package.json b/ui/package.json new file mode 100644 index 0000000..ef0c542 --- /dev/null +++ b/ui/package.json @@ -0,0 +1,26 @@ +{ + "name": "loadpath-ui", + "private": true, + "version": "0.1.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc --noEmit && vite build", + "preview": "vite preview", + "test": "vitest run" + }, + "dependencies": { + "@xyflow/react": "^12.6.0", + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react": "^4.3.4", + "jsdom": "^25.0.1", + "typescript": "^5.6.3", + "vite": "^6.0.3", + "vitest": "^2.1.8" + } +} diff --git a/ui/src/App.tsx b/ui/src/App.tsx new file mode 100644 index 0000000..5eb161e --- /dev/null +++ b/ui/src/App.tsx @@ -0,0 +1,287 @@ +import { useEffect, useMemo, useState } from "react"; +import { api } from "./api"; +import { ImpactGraph } from "./ImpactGraph"; +import type { PullRequest, Review } from "./types"; + +type Tab = "review" | "prs" | "graph" | "settings"; + +export function App() { + const [tab, setTab] = useState("review"); + const [repo, setRepo] = useState(localStorage.getItem("loadpath.repo") || ""); + const [base, setBase] = useState("HEAD~1"); + const [head, setHead] = useState("HEAD"); + const [review, setReview] = useState(null); + const [error, setError] = useState(""); + const [busy, setBusy] = useState(""); + const [settings, setSettings] = useState>({}); + const [prs, setPrs] = useState([]); + const [scmRepo, setScmRepo] = useState(""); + const [provider, setProvider] = useState("github"); + const [aiNote, setAiNote] = useState(""); + + useEffect(() => { + api.settings().then(setSettings).catch(() => undefined); + }, []); + + const runReview = async () => { + setError(""); + setBusy("Tracing load path…"); + localStorage.setItem("loadpath.repo", repo); + try { + const r = await api.review(repo, base, head); + setReview(r); + setTab("review"); + } catch (e) { + setError(e instanceof Error ? e.message : String(e)); + } finally { + setBusy(""); + } + }; + + const runIndex = async () => { + setError(""); + setBusy("Indexing…"); + try { + await api.index(repo); + } catch (e) { + setError(e instanceof Error ? e.message : String(e)); + } finally { + setBusy(""); + } + }; + + const loadPrs = async () => { + setError(""); + setBusy("Fetching pull requests…"); + try { + const r = await api.prs(provider, scmRepo); + setPrs(r.pull_requests); + } catch (e) { + setError(e instanceof Error ? e.message : String(e)); + } finally { + setBusy(""); + } + }; + + const saveSettings = async (evt: React.FormEvent) => { + evt.preventDefault(); + const fd = new FormData(evt.currentTarget); + const body = { + github_token: String(fd.get("github_token") || ""), + bitbucket_token: String(fd.get("bitbucket_token") || ""), + bitbucket_username: String(fd.get("bitbucket_username") || ""), + ai_provider: String(fd.get("ai_provider") || "none"), + ai_api_key: String(fd.get("ai_api_key") || ""), + ai_model: String(fd.get("ai_model") || ""), + ai_base_url: String(fd.get("ai_base_url") || ""), + workspaces: repo ? [{ path: repo, name: repo.split(/[\\/]/).pop() }] : [], + }; + setSettings(await api.saveSettings(body)); + }; + + const askAi = async () => { + if (!review) return; + setBusy("Residual analysis…"); + try { + const r = await api.residual(review); + setAiNote(r.note); + } catch (e) { + setError(e instanceof Error ? e.message : String(e)); + } finally { + setBusy(""); + } + }; + + const graphNodes = useMemo(() => review?.nodes ?? [], [review]); + const graphEdges = useMemo(() => review?.edges ?? [], [review]); + + return ( +
+ +
+
+ setRepo(e.target.value)} + /> + setBase(e.target.value)} placeholder="base" /> + setHead(e.target.value)} placeholder="head" /> + + +
+ {error ?
{error}
: null} + + {tab === "review" && ( +
+ +
+ {review ? : null} +
+
+ )} + + {tab === "graph" && ( +
+ {review ? :

Run a review first.

} +
+ )} + + {tab === "prs" && ( +
+
+ + setScmRepo(e.target.value)} + /> + +
+ {prs.map((p) => ( +
+

+ #{p.number} {p.title} +

+
+ {p.author} · {p.source_branch} → {p.target_branch} · {p.provider} +
+ + Open on {p.provider} + +
+ +
+
+ ))} +
+ )} + + {tab === "settings" && ( +
+

Keys & providers

+

+ Tokens stay on this machine in ~/.loadpath/settings.json. GitHub and Bitbucket power the + PR list. AI is used only for residual uncertainty the graph could not close. +

+ + + + + + + + + + + + + + + +
+ )} +
+
+ ); +} diff --git a/ui/src/ImpactGraph.tsx b/ui/src/ImpactGraph.tsx new file mode 100644 index 0000000..5dccb45 --- /dev/null +++ b/ui/src/ImpactGraph.tsx @@ -0,0 +1,53 @@ +import { Background, Controls, MiniMap, ReactFlow, type Edge, type Node } from "@xyflow/react"; +import "@xyflow/react/dist/style.css"; +import { layoutNodes, type GraphEdge, type GraphNode } from "./types"; + +const WEIGHT_COLOR: Record = { + cheap: "#4a5568", + expensive: "#f4a261", + critical: "#e85d04", +}; + +function LoadNode({ data }: { data: { name: string; type: string } }) { + return ( +
+
{data.type.split(".").pop()}
+
{data.name}
+
+ ); +} + +const nodeTypes = { load: LoadNode }; + +export function ImpactGraph({ nodes, edges }: { nodes: GraphNode[]; edges: GraphEdge[] }) { + const pos = layoutNodes(nodes); + const rfNodes: Node[] = nodes.map((n) => ({ + id: n.id, + type: "load", + position: pos.get(n.id) ?? { x: 0, y: 0 }, + data: { name: n.name, type: n.type, file: n.file_path }, + })); + const rfEdges: Edge[] = edges + .filter((e) => nodes.some((n) => n.id === e.src) && nodes.some((n) => n.id === e.dst)) + .map((e) => ({ + id: e.id, + source: e.src, + target: e.dst, + animated: e.weight === "critical", + style: { + stroke: WEIGHT_COLOR[e.weight] || "#4a5568", + strokeWidth: e.weight === "critical" ? 2.4 : 1.2, + strokeDasharray: e.confidence < 0.8 ? "6 4" : undefined, + }, + label: e.type.replaceAll("_", " "), + labelStyle: { fill: "#8b9bb0", fontSize: 9 }, + })); + + return ( + + + + + + ); +} diff --git a/ui/src/api.ts b/ui/src/api.ts new file mode 100644 index 0000000..92a76ed --- /dev/null +++ b/ui/src/api.ts @@ -0,0 +1,44 @@ +import type { PullRequest, Review } from "./types"; + +async function req(path: string, init?: RequestInit): Promise { + const res = await fetch(path, { + ...init, + headers: { "Content-Type": "application/json", ...(init?.headers || {}) }, + }); + if (!res.ok) { + const text = await res.text(); + throw new Error(text || res.statusText); + } + return res.json() as Promise; +} + +export const api = { + health: () => req<{ status: string; version: string }>("/api/health"), + settings: () => req>("/api/settings"), + saveSettings: (body: Record) => + req>("/api/settings", { method: "PUT", body: JSON.stringify(body) }), + index: (repo_path: string) => + req<{ ok: boolean; counts: { nodes: number; edges: number } }>("/api/index", { + method: "POST", + body: JSON.stringify({ repo_path, incremental: true }), + }), + review: (repo_path: string, base: string, head?: string) => + req("/api/review", { + method: "POST", + body: JSON.stringify({ repo_path, base, head: head || null, reindex: true }), + }), + graph: (repo_path: string) => + req<{ nodes: unknown[]; edges: unknown[]; counts: { nodes: number; edges: number } }>( + `/api/graph?repo_path=${encodeURIComponent(repo_path)}`, + ), + prs: (provider: string, repo: string, state = "open") => + req<{ pull_requests: PullRequest[] }>("/api/prs", { + method: "POST", + body: JSON.stringify({ provider, repo, state }), + }), + residual: (review: Review) => + req<{ note: string }>("/api/ai/residual", { + method: "POST", + body: JSON.stringify({ review }), + }), +}; diff --git a/ui/src/main.tsx b/ui/src/main.tsx new file mode 100644 index 0000000..9891129 --- /dev/null +++ b/ui/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import { App } from "./App"; +import "./styles.css"; + +createRoot(document.getElementById("root")!).render( + + + , +); diff --git a/ui/src/styles.css b/ui/src/styles.css new file mode 100644 index 0000000..d112b3b --- /dev/null +++ b/ui/src/styles.css @@ -0,0 +1,146 @@ +:root { + --bg: #070b10; + --bg-2: #0d141c; + --surface: #121a24; + --line: #1e2c3c; + --ink: #e7eef6; + --muted: #8b9bb0; + --high: #2a9d8f; + --medium: #e9c46a; + --low: #e76f51; + --critical: #e85d04; + --accent: #4cc9f0; +} +* { box-sizing: border-box; } +html, body, #root { height: 100%; margin: 0; } +body { + background: var(--bg); + color: var(--ink); + font-family: "IBM Plex Sans", "Segoe UI", sans-serif; +} +button, input, select, textarea { + font-family: inherit; + color: inherit; +} +.app { + display: grid; + grid-template-columns: 220px 1fr; + height: 100%; +} +.rail { + border-right: 1px solid var(--line); + background: linear-gradient(180deg, #0b1219, #070b10); + padding: 20px 14px; + display: flex; + flex-direction: column; + gap: 6px; +} +.brand { + font-family: "IBM Plex Mono", monospace; + letter-spacing: 0.18em; + font-size: 12px; + text-transform: uppercase; + color: var(--accent); + margin: 0 0 18px; +} +.rail button, .tab { + background: transparent; + border: 0; + text-align: left; + padding: 8px 10px; + border-radius: 6px; + color: var(--muted); + cursor: pointer; +} +.rail button.active, .tab.active { + background: #15202c; + color: var(--ink); +} +.main { display: flex; flex-direction: column; min-width: 0; } +.topbar { + display: flex; + gap: 8px; + align-items: center; + padding: 12px 16px; + border-bottom: 1px solid var(--line); + background: var(--bg-2); +} +.topbar input, .topbar select { + background: var(--surface); + border: 1px solid var(--line); + border-radius: 6px; + padding: 8px 10px; + min-width: 160px; +} +.topbar input.path { flex: 1; } +.topbar button, .btn { + background: #173044; + border: 1px solid #24506c; + border-radius: 6px; + padding: 8px 12px; + cursor: pointer; +} +.btn.primary { background: #134e4a; border-color: #2a9d8f; } +.content { flex: 1; min-height: 0; display: grid; grid-template-columns: 420px 1fr; } +.brief { + overflow: auto; + border-right: 1px solid var(--line); + padding: 18px; + background: radial-gradient(circle at 0 0, rgba(76, 201, 240, 0.05), transparent 40%), var(--bg); +} +.graph-wrap { position: relative; min-height: 0; } +.graph-wrap .react-flow { + background-color: #070b10; + background-image: + linear-gradient(rgba(42, 80, 120, 0.09) 1px, transparent 1px), + linear-gradient(90deg, rgba(42, 80, 120, 0.09) 1px, transparent 1px); + background-size: 24px 24px; +} +h1 { font-size: 18px; margin: 0 0 6px; } +.level { font-family: "IBM Plex Mono", monospace; font-weight: 600; } +.level.high { color: var(--high); } +.level.medium { color: var(--medium); } +.level.low { color: var(--low); } +.kicker { color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: 0.08em; margin: 16px 0 6px; } +.chip { + display: inline-block; + font-size: 11px; + padding: 2px 8px; + border-radius: 999px; + border: 1px solid var(--line); + margin: 0 6px 6px 0; + color: var(--muted); +} +.chip.blocker { color: var(--low); border-color: var(--low); } +.file { font-family: "IBM Plex Mono", monospace; font-size: 12px; color: var(--accent); } +.muted { color: var(--muted); font-size: 13px; line-height: 1.45; } +.error { color: var(--low); padding: 8px 16px; } +.pr-list { padding: 16px; overflow: auto; } +.pr { + border: 1px solid var(--line); + background: var(--surface); + padding: 12px 14px; + border-radius: 8px; + margin-bottom: 10px; +} +.pr h3 { margin: 0 0 4px; font-size: 14px; } +.settings { padding: 24px; max-width: 640px; display: grid; gap: 10px; } +.settings label { font-size: 12px; color: var(--muted); } +.settings input, .settings select { + background: var(--surface); + border: 1px solid var(--line); + border-radius: 6px; + padding: 8px 10px; + width: 100%; +} +.headline { white-space: pre-wrap; font-family: "IBM Plex Mono", monospace; font-size: 12px; color: var(--muted); } +.lp-node { + padding: 8px 10px; + border-radius: 8px; + border: 1px solid #2a3d52; + background: #101822; + min-width: 150px; + box-shadow: 0 0 0 1px rgba(76, 201, 240, 0.08); +} +.lp-node .t { font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; } +.lp-node .n { font-size: 13px; font-weight: 600; } diff --git a/ui/src/types.test.ts b/ui/src/types.test.ts new file mode 100644 index 0000000..12ff0c7 --- /dev/null +++ b/ui/src/types.test.ts @@ -0,0 +1,18 @@ +import { describe, expect, it } from "vitest"; +import { layerFor, layoutNodes, type GraphNode } from "./types"; + +describe("load-path layout", () => { + it("places Django left of the React stitch", () => { + const nodes: GraphNode[] = [ + { id: "r", type: "django.route", name: "/api/invoices", qualified_name: "r" }, + { id: "c", type: "react.api_client", name: "/api/invoices/{id}", qualified_name: "c" }, + { id: "p", type: "react.page", name: "InvoicePage", qualified_name: "p" }, + { id: "f", type: "react.form_schema", name: "invoiceSchema", qualified_name: "f" }, + ]; + const pos = layoutNodes(nodes); + expect(pos.get("r")!.x).toBeLessThan(pos.get("c")!.x); + expect(pos.get("c")!.x).toBeLessThan(pos.get("p")!.x); + expect(pos.get("p")!.x).toBeLessThan(pos.get("f")!.x); + expect(layerFor("django.serializer_field")).toBeLessThan(layerFor("react.form_schema")); + }); +}); diff --git a/ui/src/types.ts b/ui/src/types.ts new file mode 100644 index 0000000..b3e8c0c --- /dev/null +++ b/ui/src/types.ts @@ -0,0 +1,127 @@ +export type GraphNode = { + id: string; + type: string; + name: string; + qualified_name: string; + file_path?: string | null; + start_line?: number | null; + context?: string | null; + extra?: Record; +}; + +export type GraphEdge = { + id: string; + src: string; + dst: string; + type: string; + weight: string; + confidence: number; + extra?: Record; +}; + +export type Finding = { + rule: string; + severity: string; + message: string; + node_id?: string | null; + file_path?: string | null; + waived: boolean; +}; + +export type Review = { + id: string; + title: string; + headline: string; + change_kinds: string[]; + confidence: { + level: "high" | "medium" | "low"; + reasons: string[]; + sinks: number; + covered_sinks: number; + untested_sinks: { id: string; name: string; type: string }[]; + }; + labels: string[]; + low_risk: boolean; + clusters: { id: string; title: string; files: string[]; contexts: string[] }[]; + read_order: { path: string; why: string; status: string }[]; + skip: string[]; + findings: Finding[]; + residuals: string[]; + suggested_reviewers: string[]; + sinks: { id: string; type: string; name: string }[]; + tests_note: string; + architecture_note: string; + nodes: GraphNode[]; + edges: GraphEdge[]; + markdown?: string; +}; + +export type PullRequest = { + provider: string; + id: string; + number: number; + title: string; + url: string; + author: string; + source_branch: string; + target_branch: string; + repo: string; + state: string; + updated_at: string; + draft: boolean; +}; + +export const LAYER_ORDER: Record = { + "arch.context": 0, + "django.app": 0, + "django.route": 1, + "django.url_name": 1, + "django.view": 2, + "django.viewset_action": 2, + "django.permission": 2, + "django.serializer": 3, + "django.serializer_field": 4, + "django.service": 4, + "django.model": 5, + "django.field": 6, + "django.relation": 6, + "django.task": 7, + "django.receiver": 7, + "django.signal": 7, + "django.test": 7, + "django.migration_op": 7, + "django.admin": 7, + "openapi.path": 8, + "react.api_client": 9, + "react.query_key": 10, + "react.hook": 10, + "react.feature": 10, + "react.route": 11, + "react.page": 11, + "react.component": 12, + "react.form_schema": 13, + "react.test": 13, + "react.context": 12, +}; + +export function layerFor(type: string): number { + return LAYER_ORDER[type] ?? 8; +} + +export function layoutNodes(nodes: GraphNode[]): Map { + const columns = new Map(); + for (const n of nodes) { + const layer = layerFor(n.type); + const list = columns.get(layer) ?? []; + list.push(n); + columns.set(layer, list); + } + const pos = new Map(); + for (const [layer, list] of columns) { + list.sort((a, b) => a.name.localeCompare(b.name)); + list.forEach((n, i) => { + pos.set(n.id, { x: layer * 240, y: i * 92 }); + }); + } + return pos; +} diff --git a/ui/src/vite-env.d.ts b/ui/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/ui/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/ui/tsconfig.json b/ui/tsconfig.json new file mode 100644 index 0000000..8a35f7c --- /dev/null +++ b/ui/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ES2022", + "useDefineForClassFields": true, + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + "strict": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noFallthroughCasesInSwitch": true, + "types": ["vite/client"] + }, + "include": ["src"] +} diff --git a/ui/vite.config.ts b/ui/vite.config.ts new file mode 100644 index 0000000..3867620 --- /dev/null +++ b/ui/vite.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from "vitest/config"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [react()], + base: "./", + build: { + outDir: "../src/loadpath/static", + emptyOutDir: true, + }, + server: { + port: 5173, + proxy: { + "/api": "http://127.0.0.1:7345", + }, + }, + test: { + environment: "jsdom", + }, +}); From 32850a013be4c39485e1d887b04d2dfcae728267 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 14 Aug 2026 12:57:52 +0000 Subject: [PATCH 2/5] Prefer mounted /api paths in sink summaries and smoke-test the UI Review briefs now show include()-composed routes (e.g. /api/invoices/{id}) and the API suite asserts the bundled SPA is served at /. Co-authored-by: Damon --- pyproject.toml | 5 ++++- src/loadpath/review/engine.py | 4 +++- tests/integration/test_review_vertical_slice.py | 3 +++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4de8b0c..383d15f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,7 +42,10 @@ loadpath = ["report/*.html", "static/**/*"] testpaths = ["tests"] pythonpath = ["src"] addopts = "-q --tb=short" -filterwarnings = ["ignore::DeprecationWarning"] +filterwarnings = [ + "ignore::DeprecationWarning", + "ignore:Using `httpx` with `starlette.testclient`:DeprecationWarning", +] [tool.ruff] line-length = 100 diff --git a/src/loadpath/review/engine.py b/src/loadpath/review/engine.py index 75f2cb2..7e902a9 100644 --- a/src/loadpath/review/engine.py +++ b/src/loadpath/review/engine.py @@ -298,11 +298,13 @@ def _sink_summaries(nodes: list[dict], store: GraphStore) -> list[dict]: out = [] for n in nodes: if n["type"] in interesting: + extra = n.get("extra") or {} + name = extra.get("mounted_at") or extra.get("full_path") or n["name"] out.append( { "id": n["id"], "type": n["type"], - "name": n["name"], + "name": name, "file_path": n.get("file_path"), "context": n.get("context"), } diff --git a/tests/integration/test_review_vertical_slice.py b/tests/integration/test_review_vertical_slice.py index 7ef7f3f..4b763bb 100644 --- a/tests/integration/test_review_vertical_slice.py +++ b/tests/integration/test_review_vertical_slice.py @@ -107,3 +107,6 @@ def test_api_review_endpoint(tmp_path: Path): g = client.get("/api/graph", params={"repo_path": str(repo)}) assert g.status_code == 200 assert g.json()["counts"]["nodes"] > 0 + home = client.get("/") + assert home.status_code == 200 + assert b"Loadpath" in home.content From f8d243074d7867102c162590f32a2e9fe0526ab8 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 14 Aug 2026 13:23:38 +0000 Subject: [PATCH 3/5] Harden Django Celery/Dramatiq extractors, add e2e suite and README screenshots Trace Celery and Dramatiq (decorators, Task/GenericActor, delay/send, canvas, beat, on_commit) without letting call-site placeholders overwrite task definitions. Expand the demo fixture and cover CLI, API, brokers, and Playwright UI screenshots in the README. Co-authored-by: Damon --- .github/workflows/ci.yml | 1 + README.md | 140 ++++++-- docs/screenshots/graph.png | Bin 0 -> 172740 bytes docs/screenshots/pull-requests.png | Bin 0 -> 39198 bytes docs/screenshots/review.png | Bin 0 -> 314719 bytes docs/screenshots/settings.png | Bin 0 -> 51943 bytes .../demo_monorepo/backend/billing/actors.py | 15 + fixtures/demo_monorepo/backend/billing/api.py | 11 + .../backend/billing/management/__init__.py | 0 .../billing/management/commands/__init__.py | 0 .../management/commands/resend_invoices.py | 12 + .../demo_monorepo/backend/billing/models.py | 1 + .../demo_monorepo/backend/billing/tasks.py | 27 +- .../demo_monorepo/backend/billing/urls.py | 3 +- .../demo_monorepo/backend/billing/views.py | 19 + .../demo_monorepo/backend/config/__init__.py | 0 .../demo_monorepo/backend/config/settings.py | 21 ++ fixtures/demo_monorepo/loadpath.yml | 1 + loadpath.yml.example | 1 + pyproject.toml | 5 +- src/loadpath/architecture/rules.py | 11 +- src/loadpath/config.py | 2 + src/loadpath/extractors/django.py | 332 +++++++++++++++--- src/loadpath/extractors/django_boot.py | 121 +++++++ src/loadpath/graph/store.py | 30 +- src/loadpath/index.py | 7 + src/loadpath/review/cluster.py | 26 ++ src/loadpath/review/engine.py | 35 +- .../{index-DigBKCrc.js => index-BA8TjmLZ.js} | 24 +- src/loadpath/static/index.html | 2 +- tests/conftest.py | 19 + tests/e2e/test_api_flow.py | 113 ++++++ tests/e2e/test_brokers_and_django.py | 137 ++++++++ tests/e2e/test_cli_review.py | 51 ++- tests/e2e/test_ui_screenshots.py | 134 +++++++ tests/unit/test_django_extractors.py | 113 +++++- ui/src/App.tsx | 40 ++- ui/src/ImpactGraph.tsx | 2 +- 38 files changed, 1319 insertions(+), 137 deletions(-) create mode 100644 docs/screenshots/graph.png create mode 100644 docs/screenshots/pull-requests.png create mode 100644 docs/screenshots/review.png create mode 100644 docs/screenshots/settings.png create mode 100644 fixtures/demo_monorepo/backend/billing/actors.py create mode 100644 fixtures/demo_monorepo/backend/billing/api.py create mode 100644 fixtures/demo_monorepo/backend/billing/management/__init__.py create mode 100644 fixtures/demo_monorepo/backend/billing/management/commands/__init__.py create mode 100644 fixtures/demo_monorepo/backend/billing/management/commands/resend_invoices.py create mode 100644 fixtures/demo_monorepo/backend/config/__init__.py create mode 100644 fixtures/demo_monorepo/backend/config/settings.py create mode 100644 src/loadpath/extractors/django_boot.py rename src/loadpath/static/assets/{index-DigBKCrc.js => index-BA8TjmLZ.js} (68%) create mode 100644 tests/e2e/test_api_flow.py create mode 100644 tests/e2e/test_brokers_and_django.py create mode 100644 tests/e2e/test_ui_screenshots.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 221feea..8ab5288 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,7 @@ jobs: - name: Python tests run: | python -m pip install -e ".[dev]" + python -m playwright install chromium pytest - name: UI tests working-directory: ui diff --git a/README.md b/README.md index 7e52cf2..fecac8d 100644 --- a/README.md +++ b/README.md @@ -2,29 +2,58 @@ Review as **load-path inspection** on a Django + React architecture graph. Not another hunk-comment bot. -A change is a force. Loadpath traces where that force travels until it hits a sink (HTTP response, UI, job, migration, permission) — then scores whether you have enough evidence to merge. - -## What you get on every PR - -1. **Clustered diff** — one cluster is one load path, not one file -2. **Impact graph** — real Django/React node types, typed weighted edges -3. **Confidence brief** — sink tests, contract coverage, architecture rules, residual unknowns +A change is a force. Loadpath traces where that force travels until it hits a sink — HTTP response, UI, Celery/Dramatiq job, migration, permission — then scores whether you have enough evidence to merge. ``` Loadpath: MEDIUM — Invoice.total field change -Sinks: GET/POST /api/invoices, Celery send_invoice_email, React InvoicePage + InvoiceForm +Sinks: GET/POST /api/invoices/{id}; Celery send_invoice_email, apply_credit; Dramatiq rebuild_ledger; React InvoicePage + InvoiceForm Tests: pytest hits serializer and view; no RTL test on InvoiceForm Architecture: stays inside billing Residual: total also formatted in a Signal update_ledger — no test Suggested reviewers: billing-team ``` +On the demo monorepo that path is: + +`Invoice.total → InvoiceSerializer → InvoiceViewSet → /api/invoices/{id} → OpenAPI → fetch → useInvoice → InvoicePage → InvoiceForm / Zod` + +plus the jobs the view enqueues (`send_invoice_email.delay`, `rebuild_ledger.send`). + +## App + +`loadpath serve --port 7345` opens a local desktop-style UI. Tokens stay on the machine in `~/.loadpath/settings.json`. AI is used **only** for residual uncertainty the graph cannot close. + +### Review + +Confidence brief, read-order, clusters, architecture findings, residual list, and the impact subgraph for the git range. + +![Review](docs/screenshots/review.png) + +### Impact graph + +Full-canvas layered graph: Django models and serializers on the left, views/tasks in the middle, OpenAPI stitch, React hooks and pages on the right. Dashed edges are inferred (URL/Zod overlap); solid edges are extracted or generated-client stitches. + +![Impact graph](docs/screenshots/graph.png) + +### Pull requests + +GitHub and Bitbucket via API tokens from Settings. Pick a PR and jump to a branch-range review. + +![Pull requests](docs/screenshots/pull-requests.png) + +### Settings + +GitHub / Bitbucket tokens; AI providers (Anthropic, OpenAI, Grok/xAI, DeepSeek, Cursor-compatible, Ollama). Residual analysis only — Loadpath does not comment every hunk. + +![Settings](docs/screenshots/settings.png) + ## Install Python 3.12+ and Node 22+ (UI). ```bash pip install -e ".[dev]" +python -m playwright install chromium # optional, for UI screenshot tests cd ui && npm install && npm run build && cd .. loadpath --help ``` @@ -32,28 +61,80 @@ loadpath --help ## CLI ```bash -# Index a monorepo (SQLite graph, incremental on file hashes) +# Index a monorepo (SQLite graph at .loadpath/graph.sqlite3, incremental on file hashes) loadpath index /path/to/repo -# Review a git range → markdown brief (also --format html|json) +# Review a git range → markdown (also --format html|json) loadpath review /path/to/repo --base origin/main --head HEAD # Cross-platform app (API + visual graph + PR list) loadpath serve --port 7345 ``` -Put `loadpath.yml` at the repo root (see `loadpath.yml.example` and `fixtures/demo_monorepo/loadpath.yml`). The tool is opinionated about *your* architecture, not a generic module graph. +Put `loadpath.yml` at the repo root (see [`loadpath.yml.example`](loadpath.yml.example) and [`fixtures/demo_monorepo/loadpath.yml`](fixtures/demo_monorepo/loadpath.yml)). The tool is opinionated about *your* architecture, not a generic module graph. -## App +## Django support + +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` | +| Function views | `@api_view`, `@login_required`, `@csrf_exempt`, … | +| Django Ninja | `@router.get/post/…` routes and views | +| URLs | `path` / `re_path`, DRF `router.register`, `include()` mount composition (`/api` + `invoices//` → `/api/invoices/{id}`) | +| Signals | `@receiver`, `signal.connect()` residual, `AppConfig.ready()` residual | +| Management commands | `BaseCommand` + `handle()`, including `.delay(` / `.send(` enqueue edges | +| Migrations | `CreateModel` / `AddField` / `RemoveField` / `DeleteModel` / `RunPython` as `destructive_migration` | +| Tests | `test_*` in `tests.py` / `tests/` as `tested_by` | + +### Celery -`loadpath serve` opens a local desktop-style UI: +- `@shared_task`, `@app.task`, `@periodic_task` +- `celery.Task` subclasses (`run(self, invoice_id)`) +- Enqueue: `.delay(`, `.apply_async(` +- Signatures / canvas: `.s(`, `.si(`, `chain` / `group` / `chord` (canvas is a residual; inner signatures are `enqueues` edges) +- `current_app.send_task("billing.tasks.send_invoice_email")` — residual + inferred enqueue +- `transaction.on_commit(lambda: task.apply_async(...))` — residual, nested enqueue walked +- `CELERY_BEAT_SCHEDULE` / `beat_schedule` in settings -- **Review** — confidence, read-order, clusters, architecture blockers, residual list -- **Impact graph** — layered load path (Django → OpenAPI stitch → React) -- **Pull requests** — GitHub and Bitbucket via API tokens in Settings -- **Settings** — GitHub/Bitbucket tokens; AI providers (Anthropic, OpenAI, Grok/xAI, DeepSeek, Cursor-compatible, Ollama) +### Dramatiq -Tokens live in `~/.loadpath/settings.json` on the machine running the app. AI is used **only** for residual uncertainty the graph cannot close (`getattr`, raw SQL, `get_serializer_class`, `AppConfig.ready()` signals, string model refs, inferred URL stitches). It does not comment every hunk. +- `@dramatiq.actor` +- `dramatiq.GenericActor` subclasses (`perform(self, invoice_id)`) +- Enqueue: `.send(`, `.send_with_options(` (heuristic: dramatiq import or `actors` / `tasks` module) + +Call-site placeholders (`rebuild_ledger.send` in a view) do **not** overwrite the actor definition’s file. The graph keeps `actors.py` / `tasks.py` as the node home. + +### Idempotency rule + +`celery_tasks_must_be_idempotent_on_model_pk` (alias `async_tasks_must_be_idempotent_on_model_pk`) warns when a Celery **or** Dramatiq task takes a full object payload instead of `pk` / `*_id`. Message names the broker. + +### Optional `django.setup()` overlay + +AST is enough for review. If you need live `_meta` (db_table, resolved relations), set `boot_django: true` in `loadpath.yml`. Loadpath then imports Django, calls `django.setup()`, and merges model/field nodes. Failures become residuals; the AST graph still stands. Leave it `false` in CI unless the fixture is a bootable project. + +## React + stitch + +**React:** react-router tables, composition, TanStack Query `queryKey` + fetch/axios URL templates, Zod schemas, feature-folder imports, RTL `render()` as `tested_by`. + +**Stitch (the moat):** OpenAPI from Spectacular/schema files first; generated clients (`generated/`, orval, openapi-typescript) as high-confidence `consumed_by_client`; fallback URL-template matching and serializer/Zod field overlap marked **inferred**. + +## Architecture rules (`loadpath.yml`) + +| Rule | Meaning | +| --- | --- | +| `views_cannot_import_other_context_models` | A billing view must not import `accounts.UserProfile` | +| `react_feature_may_only_call_own_or_shared_api` | Billing UI may not `fetch('/api/me')` | +| `serializers_are_the_only_published_contract` | Zod/form fields must not drift from the serializer | +| `no_queryset_in_serializer` | Serializers must not run querysets | +| `celery_tasks_must_be_idempotent_on_model_pk` | Celery and Dramatiq tasks take a model pk | + +Waivers live under `waivers:` in the same file. Reviewers are the `owners` of the bounded contexts in the impact subgraph. + +Impact walk skips permission/app/context hubs, does not climb `renders` into the App shell, and does not follow cross-context `relates_to` (an Invoice FK to UserProfile does not pull identity into a billing review). ## How confidence is scored @@ -68,14 +149,6 @@ Line coverage on changed files is the wrong metric. Loadpath scores the **impact `high` / `medium` / `low` plus three reasons. Isolated leaf UI with green tests and no rule hits is labeled `loadpath:low-risk`. -## Extractors - -**Django (framework overlay, not just imports):** `urls.py` / DRF router, `serializer_class` / `get_serializer_class`, `Meta.fields`, permissions, model `_meta`-shaped AST (FK/`on_delete`), `@receiver`, `@shared_task` / `.delay(`, `apps.get_model("app.Model")`, migration ops, pytest node ids as `tested_by`. - -**React:** react-router tables, composition, TanStack Query `queryKey` + fetch/axios URL templates, Zod schemas, feature-folder imports, RTL `render()` as `tested_by`. - -**Stitch (the moat):** OpenAPI from Spectacular/schema files first; generated clients (`generated/`, orval, openapi-typescript) as high-confidence `consumed_by_client`; fallback URL-template matching and serializer/Zod field overlap marked **inferred**. - ## Tests ```bash @@ -83,7 +156,20 @@ pytest cd ui && npm test ``` -The vertical slice in `tests/integration/test_review_vertical_slice.py` indexes `fixtures/demo_monorepo`, changes one serializer field, and asserts the path reaches the React form with a medium/low confidence reason. +| Suite | What it covers | +| --- | --- | +| `tests/unit/` | Django/React extractors, architecture rules, stitch, SCM/AI providers | +| `tests/integration/test_review_vertical_slice.py` | Serializer field change reaches InvoicePage/Zod, not MePage; reviewers `billing-team` | +| `tests/e2e/test_cli_review.py` | `loadpath index` / `review` markdown, JSON, HTML | +| `tests/e2e/test_api_flow.py` | health, index, review, graph, settings, GitHub + Bitbucket PR list | +| `tests/e2e/test_brokers_and_django.py` | Celery + Dramatiq sinks, actor-only PR, non-idempotent Dramatiq warning, destructive migration, cross-context blocker, boot overlay, management commands, beat/canvas | +| `tests/e2e/test_ui_screenshots.py` | Playwright: Review, Impact graph, Pull requests, Settings → `docs/screenshots/` | + +CI installs Chromium and runs the full suite. + +## Demo fixture + +[`fixtures/demo_monorepo`](fixtures/demo_monorepo) is a billing/identity split: DRF ViewSet, FBV, Ninja ledger route, Celery tasks + beat + canvas, Dramatiq actor + GenericActor, management command, signal, FK string ref, React InvoicePage/Zod. ## What this is not diff --git a/docs/screenshots/graph.png b/docs/screenshots/graph.png new file mode 100644 index 0000000000000000000000000000000000000000..1c91bd7b1fa942ff3785301646135613321874e3 GIT binary patch literal 172740 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

wTc8d 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

%bje>Aj~rnm1uX`{ z|H3Pbsv9jI6t{8Tf*%tE>n$Ce<;9E+v+xtNt~2Dc1oHV&_uR=IGw8BGbHE zt72`Y1VT)-0t2qg;PhJ96ZkC4UBb}S!`!;@2C&NpMGQajfbB^U!z!Et=1~Z0b{cFH z{OoLOr}wpHjr41sM9Vhibw3fPPh;ygW1*#~|AgX6fIb)^4Ka9B^3mvn4qeP@REKq$ zwSGrZJJ!SZ`Hwj?r#KcKom6S`_a@0AEex`UF8GF~#LVG@)<{^DE(3Mch8`U zP8W8mfB96l7r>@b1xIGw51Ae-3CKd8!Qs1?Kl>y?Eg&SBXCiCos~Y4wArVUa7ft>+`e*qA9^XlH zmn8FmTeed!jm*db6ijs%1oD0cFc4ic0FRnA(OooW*R~6D&1T;!!37q5)9pPV8JHva zZEg+x-qStp4r$Yg{-I8oJg8C{+WU-hDi`&QC_gSiFqEs|S)2-Zh<*c1+qpzmp@b|! z9za!VKah+8)XIEYZ%}#Q#sAR2Efb)~2cJI50NM`P)*eD}&HitIgxf(#Mih7-H(|9) zOj@q}d+TBZ|4Q@$uajcw^%Xf+fNkIVR7op1`}tSRCTEFP`J0$EK0fFZ4_*i+rlDc6 zQ;!UTT5OQr6#CPQnltg!WXn{0>)!pyiw}76@13myTUx)iNXBpvOQd|P?phVDfpaa@ z?YzkjH{EgDkxj-uxJ81y-##+y7jN(cRv!CjT7*1f@^HbfrCuG0R&+w1%`aa?>3I4C zlpT|ZFOs3l^8mOHYDr`w2$BuoYb6!^HS zmvs`|2@?U%<(CW^w`>?sy#Ghf^d%$U$WoUdur8jtJHF)y*R(K$wh)#YAz!}oer)j= zz0_@UHM$j2dO2*ldDi^)L^X;vm#gwEw1PRPzx}R_Sc|umjWwZ6Gg<+&>pE;2J%Hka zlUX1Y?B1{7m6+mZS{mc5o}SNNBbyd_6po1?7KH6%?q#nFIjys;Uh^t|qa96!8As7) zHAd896>SBG5)0yLCbUJ=e6;r2jxxlU@+}V-@x|>5FT^y_>Cwd3YzE}SeL$xsn-b`? z*}C6GRIGM1A_k4P`a7m(%>6RJK#y|tEy2f$ocCu>{UPGu`DgA4E_`MIE%Jnhx5cI4 z7_^IE%#iI15J6lB9H#zEFpbKRHC2#7fo1e*q_RE8|EFwsz&M}UF9QfD2duiVWnom- zK;*&4atoo|bl#vPiyrNZk1n<0|DZrQ21)O7#o*VF?qsaCzSS5z$bkr0V$cN{mOw#Gl?<@lwxV z8NNKZKs4HbAUG&RAmvg3j69aWOOxU~Lujb+TtWDWqkKtxFIEAMt8(jT_u;(Zj?=2l zHL^U`7dXm$8Sy(0WR>?wTT_Fwu0FMo zRUc?)R$|lWYxgiaf->dhrTLV|kdJT)l!{N1_7PsH<@L-<9hVxKQ0$v?o+=Mye+^i) zsDGRtr)kvgItGZ=*IuJSeCO8n#>Dy33K+D+e~z|(Az|fpAm5R1vp02ZsZ`m`lrb{z zi*!5OTR5hzvU+K;E$_>MJbpsB-R><}tdiI1OkwfTJlpqZ$*;7wal?CF6$Y zJ&A*0KN8eN`8^Tia=Chcx7#ow^=aUKX+Vr%h-M1|YRkFs+#~UX{^vK3lcA}3e)6o) zDS_xNuhD_^*h`Qopfh>AT9Onb&vORAc7RNGofHMqOW0bScoXXv?kX?d!R)-gmmX}5 zy6#UL#GIVyOZrK2WRsv{INH|J4E0dDF+#+k#vFFoc@x2yD2TMIS-Wg`e4C;+d{Ruy z3Irgi5x^(J9cK$@9H-J~Fo(tgDn*g_bG4DMMucC?I8*b)*|YvGv9cy}Hd8OdmOv+-2jEgA}R1)xKQ!&+St0O{*W&5%(=tPayOyd!+gO z80m;dx@D#4+gbyn`xqc+4we6TP3h}vj_YTJ2En`3EuAi8^!q8>=C*n|nZ&}Hy!Z9_ zeL$d)8i9Nxv0sRo)^0~;7`6k7goGn%Z$}6ra!O*`v|p(fs=7M3iFW5fke8 z{JxV&ecRb^Rl|aNtHObFr+6JcZ4FjXM@#6G3N-`}(8N3&b3%N#S(wO!0J*ygI*;ah zexrzMO2)rCBm~t|IKP<5mH-8y*&F!q(^gTxj}P4wQ7Vs@wL8(SM>MYf;tX?KIa(^Q zKb0V1jkHk__~5KXjGuYA%w`OL!;FZ8`|y?Ort7&Wy9c|A9ELuwPMwK~ z{yN^U4(!cAo>>T_8w-2J>u?4HeN_bJJiN{bopq}0|9l%~wcaS3y_JI(!RiTwK$4$4 zyFr19HkS0b8(Mg;o3DQ@v3{v+%f3!}wg;Zi-=9#heXfhaJ9}jD3Ff<&UZGyI0u@EA0^Y)*jq=5h4OASS3NLnI<>*xZcq9-|Ogr#Sy(!ge`Yr?h51Q09>)4P1MA z92FF#jL|}PT5uRqKc-NyhJiN2uro#b0sx#ACvu!e^7@nkAk>>TFLCrBMTDFVIBubG zss5$ht0iU|k^k(Qv~Zuk1Ssw~^-B5D%`AUazZ-!^*Ip<2^~J`lPp`QK*H|x)vzp^! zBQSr_PZXUoGNy4B06CZNb|3P5bE0UAqyir+%O=djg<}OZCe-U$aL*GqDP!b}$gMF) z46~O<=2j%?It)w3u~z|8YNw0w4ibx#@xlN?l3|wrE3$bzspz67ojla!5^YH!V!huF zNEy{m2Z$4zD}tY?BVQ8WgYem}IsHSdn0~VoJ6y$i0fOok-lo`M7Nw23Qr~@Nh@GWb zS=+mcM;sb7okia8N+Sbt)-gc!k~w%+cG z1Mcmix2SaVIC}Cxn76S`P2Y*?ad5=}SAMs%@9^kfDElRFMQzeiqISU=;pyj|L^dot zBKD3O)8N{BS+J=uC0QyiJ>67_5f4Qmwm(z9QvJA8{0WJ<2p`flUp>8~#dtH#H2usN zCsq4^ef$s*@Gz<$pmB#Wig*KDt!(aCh9Qp`mHL0LZ$jOqWpmBtMdvV7Td#`^TNz_J zyf|iMbMw+ybc$CxG8E5VsLxbqHCM_0Kzf9JU%R0Ie=W-`Oi-{@!M!{EUBXV_H5ZyG zylXr4H1RKKTUjPc8(aNKdR@_Yb4$&57a8X5CYdL?GZz-x{ zVSI{Q&ClIiLE`5w;5JP-*{$%U$k^%3XjPGL_anxEEGjczE4ycV0qPh!TF7RqHs(`4`g6WjD~dLM)*N`qXHOek+&8b2FF`z6k*?|x6iV-nOIuH&l2z&x zR~`Xud!AVx3oN@QG^VWNdOVH#~*exG>iIz8kAIm9}3AoCY3 z)1@TsHM~|E2I73>gyh5@5`SV9;y>)$k_xGWqW`Du2cM7+GNMWVOCjhYIAPeu zH1x9rm9Nb)soSUUUm(hOqCF>4$gN>e1Z6-ZR`j;MBF^Y^e@4q1Xw+1lA{K9&0i z392?$(dKl;W}q&=UmG|6!6ea4bjE5yRdp^b;T0iTclkf?IY5M5TJ&KnAJ7p%gNPY_ z%GnV|av4&P2QLIhqIbP$l&a3RwAJT#S*YwKJbstxYf*@$CXVsIxE+w0a}~MBD@^Y( zGbiGyFv^cORE5TXK-*XTrn*WLmWU1g?_R(VC(Jwc+|JU*E{38%7FaQ1El^#GVe@?* zU&FYdx|4e=#y@KW`ag-m9uHXi?O7LnBptv8yIecN%IM9SoR0FmMqQmW9$xFIKewEy3XMo zJ+viP_n&iPl7+mpBpZbF(_Jkd!?gc<`-kCKDfWB7l6f;%CP2i3G={O9M83K%t14Y~ zWb(_+P1brj>@F~+KyH88K~l%AX5Ie51$Ez3QzLg{>M;iAPY-8@L|*y)ghwPBO=m_GEj^OwHF** zMDbaQE7DCJ~WJM%) z;1v594k_*7K{8bdh@-UUVZIBr=7fTE2z2?#(IiPCF#JJlOD=J^d?xqBw=_032!{U- z6Z}?*U8@N+YBBVS{w4KpHPhCIkI!47PWYOk+>Cv|g!}o{K_>y($N1k>HjePylw9lc zUGyrAiSVxNz{ze4Gqhic+IuY^!8bJ!82vr4v*3d~ZVQhUZ@f-mgA}T(oZ&A4@w&DY zkkv^j$4-u?*noTe_Geyl@wc8sQ3gth9BhJ@5aU`ijZ?v&F;d5mQyz(Du}6;%bbPUn zLRYeG&lgJ|Ai#$b6dPbl@Oao5!%B{aoR|{AeE--8bth5hR;Vc~wXNJnItb6LGM!_W zeDPpH537OD-smPNSWfv>=I!1Pco>$1ip&_e+fCg8!cE<|uD*@oV6>9e7+5zsbfDS>e_){iayLUKMbOKp zDOjgq(H{zt7}zM-f&eDEym~;pOi)*5JYdJ)bu|c#OO#~9MvxJ!&~E|UrI>cLAqvC8 z3XE2?*TC?l(@>nML`J_>r#ob(p(mM{cdS+5j~(&fKd_@xUl<87yP3;iHW!t{k@gL&h4LvTmk4_^5{@wyFa`1%a9pkZQ@HXuobQG(e-P& z^7UoxP_CGGL+$=*s2Tev9_;S%-FD!D?oZF*f3kNRQE%^J#nhrRoKvtjlSy#;P~ zrLR<9*Q?`uGr(Il_o!w_F+=3sL3Y|dgi=Uj26L}A-xm+vP4$@+n`FK|`EF6J?f-yH zAIea!CIk;$g51t;4UU{nNQ-RR3381flEi5&llFR`$d9dxVArAov@Fu;K2w z+xsfqm65<(!?z*S)kvRdeXL@woBc^l*qIFEl^J`WmcV%6Sb%L4A~((o5WmTgaZLmn zIT$QMMLLowiso=;5bA$+u;p1U^=Uv3F4nVu4`eF+S`kT^eyRx~1+g)sF5`#B9O&rn zAfs1ka{?31eCXkp{G)RSbTqko_tVNrv zp`-f^WOx8b%iiO`LC}*)DiF0D`qCM|!Aw)#HDL0+52VGSwu#3dJ3zBE2B7#3uZM#Q ztufQBg=AJ&a_*x{9OzwzWKI=1SwH~gUyi9+`t5PQ#b=2EgUu}uQ^MO>lyp(r49Yhz zvZ>JUFz5{68zIF2^z^4U08%%Nh0vC(_T;l=x@wegxk&2*jf@NbM$^CV;%32dJwuCu z;pqC0nC!~TS)Al=VfT6xU-mhWL;mZkVV-A)JJQ4nAwq3AABpn|icmdg|KhP8e&iJ4 zm^y4!GV1YYy=SUhI?+LNhWfE$9J6~?p0$KZjd}+iP2Eqe8Llszfq!#S%L33a6#@-1 zTe`ZrD3W*XB3pSIvJ6 zg0no57_YemtlYyPn}|N4CsI_0G|i}nxoi@iN4j!E!e4lbf8maWVV5o48Y})12d_B$ z(dl7LY48nVt=+EgG@k>zletZ9VPjlozbbPQG^{3HXfB(RX|0ZE-#XNbCpR2|fU62Sa| zx*=QNoXNJk{GR~&yN*vWXReLr_<-R?cF>Z)u` z_$iR)U3P~yc$dh}Hzn}Y`=C+cXyNxTD+)27;@3K@nGAjwb~?douJH-~Ze&tbz;01% zuH^bfIpM_6OvfM>NM}(9@!}@y&C&@6a1JClyb^*mqLNS?IatPSXWACrJbiQTT-l5# z(?2G}u{{R?J(WR{#J*W;pV12+hvUE;SmaB`4{{*ENS9-Tf;bo;Z?^KCF4wg0<`XwB z27v{7b_rbDdnlP<0^pvsBVk+SPgzEE`a;5}D{qom7OEa4u8KOtzV{U0eUwxooD;xa;ltJQ44x1Ab-dH&>%ix3~+ zbR0BG1Gg4(P>I`nZ~Y(v|MLdi^Tt!=_b6hkl(WIznRW^Z|HY*RhDAH9Wop;evWZzi ztYir=Z#hNU$ak9pOyG5dZ&o}&#!w^f5;^cy48ltga@U=f{Rif{t)b97r9e7$3Ce@Jt|q9>l9xSRj@ILl;<?Q~FHczLP%(`~82kB8~@qo#vgu@rOI6^BXuNM;uG3bQLAL>aR7J}hz` zjnwK!*9{@}_=L6!+skn(IU%DA?%h{Msw0l|U^(w213J={Rh?{$Pr90wm1^)hy`4BK zujS;ArnaW16EpA2OOKA$b2HsD?#9UP=MYz%*VNn0_b;wlH}?L#E=nrpkvzX_zV3I} z)f$D(Mm`3Ok$9iwAf3(|^gqCd-PKIJSb@phz4zvB|LC;V{Ms`!A;0y-AaPl1qiRZE z)?QX&s;zB*4gceLm4UJ1eL7LQU0$x=oKaAw-C#RnJRQMc%*=&hdc0C48C(1WzxE{d zd-fA&_%)Hxo0~<3v^Og2TW_%*nwn)qU||yBksDhw40Ol^v@)}}v0=&01E(n}A9zP^ zJA`pW1%u!k>;bj3TfoepUY~r}jj5|^u!HYIh=ke<9VI0J8*(BMd7_GbevP}d#_-QP zlahV;X=@D}9n&vM&IQc9$nb*@Y9wUv2swW3mW^_|)^gv{)go8x7tU(hkyX9O@Zb_) z9KpSCl;Ee>dTEo)4?Ihjf=dYQVGEmKv~=+|od93S4lj_ta6|B%I!V*4vyWj&K&}@#H{p)o6Q09NIW%iQ5+Gavw*LC%Tmr!!B@hmb@b;WIu)w}%d zZu7F89FHX7bQ`wneUe|ysAo^@7&QB z4Ej4DYF6)0n-Gs~)*mv-2Ss7yuh9i}GSIjGydG&v*Q2k#=1d9A@m{_}HW81#-UN-= zEEzrQlV_~FT#>e?@B(Yh@5N=4Tz64%fww<^o2mKr(Ya&}Cb!e(<>Ap=s~$_7%D*QaHf03VLXR PP3#`d@m@p+xj+ryJRQbXlwX|cL?x`thihEHqT>1f1Y zPOG^Su(!DQ=OT<6Sa6eQTs0ru&Dn;GYpo?_r>1n4{euB3QhlZeA&B4O8=Fx%)mC1o z0jZ;#hByu_k==h6*nvQyYa)Um2foRyea6{e65On!ezX5(E%effk?5w4Mtgj6J2jep zD=VG4^-IW{!c`W4(TXaJFcm^mO`lQyBNrXoNTsR;cWf(a7plBR~$!)cYHbB$46ABZpd}ZMC zx-Ny`a5liOqt`;*w*WkbZ^z&LI#MM|VC=}nSML%n_|zw15IA$fEiAuflzFhK&5bTs z5Y%O9so+cXf5Y2eKts{g5L@G;MU1S}s0EcRubl&iAg$)VF1n`H2B_HCa8NvoFnk3G zN%-?)e4X7h@ThF64sqEaMDBRTfL~9_KPg4stB6B`Na!3;OD20y=>mWeETF!`!|Y0cK=UEXYooY;7{}`43_H2EOq93b*&Kp>kbq2nv}0?4w{$ z5-N9N_>ZJ6kaljKy^Wl+zmW<_E5`250@_Z8zyXL%vzd~u0b=c+=38;be&CG$@kNd0 z1b&CWp(avv2loqzYD=XCa6j!$Z0~%}7I-ImkM~K}4`OXw17uP~xsu0H!bEPE)HuO{ zavQ(jumz9;JDlprhKFiuOq8}V7bec+L(jB8PPcy|tYl1JcK1jo#F>*AB^V z;#v!#;U3T?W&>SDAh6K_$A1k;U2|7+^S8kPE-rFofLw2L;gRU}!VNG6yb=U1L4&KT zE63lF|5ND8x!qt`Pv+F;qbJcjAhI2QMD%rc2MQKrTo-6?E_8MvD(acf1WsSKh4ieA zi-X1D-Gr#Lyg4yj4b8$8LRz)-b83-SzBZ)AT$>^l8e8yt`E9ZK;-zx) ze8txMz$ffYOdt2P@s$OgCJP?gw?4bn`$d}C7+iR|OglOb%W9bujVsC7_Fq&mKpt)N z^h!5v%OJKOR*1DJV<0w0@sUJG1Ze9k)h>Ynm$ALf`2w1C*>cAM4T(Wgz=V4FGL*$J zf~W;I2LhJ1AJ9Euv@o=1f|ZaIjGK_3XtMzZbIZ$6;@mxNacgM(O{kV0P-lKo>`rN13y^>k!*UKH+UyojKB; zB_Bsm_zL;qm7OP_MnPyGYD)^umI*G#2{7I@BdGqBa!PNDOSSm|3tXc1ho2fdZ?=G$ z4iI+3IJfHkl6LEw^LD#So&KoS+V#V!YfV&OORjs0!jA5DfsRS@Bw!`w(ih^kM~e79 zOmmE3NEIH?m>g8qWGKZs1gM#!H`wLa_8YY(j|WG9^+j|m<8N2@2_xvZtiQTgVF`%5 zG^Rr3@M?3X6Fh6c)$(18i|ZcWyHEd4aGR;2)1{uj@5P1T3S72i-T3#Tk`7u6N=dgV zY~^yB3zxzNdBLsYRbvuuc1wxtu(N{q#hNd(wPrI@<)qJ*EMBjEhdQToFezP&okECG zDF|eqONhFS&xId7{7cIP&+>c8U-KQ>RLp;`^tLx|!Uqq+wq9R9WD;gHXDR<)p=ob6 zAS<_ayZVDN_R^zP#v(G7=gMxQ*?<=a{g3;}QG2<`Y-nviKNZb+`7Zy*eSFGondf@t zwMnYi4Sv0)#^vCodbk|4Y3z%}Vp#>xqkR^~&CY!&({fOM?qafD@n1t}BViG@!#aPea00DJ@s1mb~?TX+(qc3b*)pQzh>Isrp7J2}r`c@?{2 zcDcn_9Afqlhd=h)ofI zZL~zhP>};Ysc?k7d`B<8T8q)KWO-a;2|n^0nhUSlMGRHEeTfPl;~&<6K8~>qe^KAG zwj;tkTakNMux#uM4edp|rz6s<#?bP|?-OJ67}xH?w-dQmKpDlRKF0+l_vw*d2>pZt zOgJ3UPO@n&f2FE3oG=wicBXZ7-iJIAh`BKj*)ukjD}b%G^ej)-`_O zX?C^-G5~(!5T$wZxCC*s%gUIAm#gaL1gp3S9)|$a1`^Qd%;G5z0$~JyrP1fmh~>Fb zm8C_@Vv=vcDTALl9y(Fjb12FFvG1A!#N9 zqr&MbjHu`E9g*6Xi0m}n4W8Oa-Vb|FRdQc;(n&VAJAg4@En6ho2`NBxwB-6i6RTA( zjh!)}{!SD@4SJijVOXE1vOXf|4k=O`fLX8Lqq!t1h}WK08{cPX7@=JKMBeuO@ALJ) zQaus1+-+I?->T7ri>P=8zbG^t4~H4xf4i|AC=2E61iRIINMH=(2a9qkgt}8~7w?mO zH{PYM9r%n+;zHu5l|=r)<#IR2+6-N#f7K)-EIz&Yz(cof*9kV@YDIm4)A87hjG zG2AGX@i6WeRP3_6dKo-sJ=ETj__W%RMssGxD9>62k)vOw6P0K3q0bpo*AI~1w}4bI1!3gGKZNdFwf!> z5RAJ)`w$?!zx-6P>A)JKXpWg|Fk+C%zD3f#-i&VBNO}hY&T|Tp$r1}}oF0xy8r*^E zcfKb1re&ocC-%A0n4q4+C$!r!FxWSAF^$KF+g8+%fIs%<_^=7vZ>dz5;(bkjO?3wq zR91j}RWv=BGoT`H#5SB%gktcen2XVii21QHCIj^{hCbdLHTC{Jo>9y2$FN|x)QaGw z$6`LbQ+R80DEP*#*I%1pMD*ZfFI)OA=@iW=S3DB)`|#HJmd8I_za(pi><84!Pv!Oc ziXhEthFQ`bHFhnpTB-oJ$b=5{j(d6dO%?ctCBnUEjPhf3%D(yw)DYup(w)7P^iahL~&>MsZM%h-$AgQK|OFIG_+J<&}+XlUBMaj1rL#VmX z@X-2iZy^~80!Yp-fS}oAO}{F6V+`iIpKyE#HxhVRk{nyl%FlS*n0z%km0ipJIQhDs zzr%_|y~OQL42?tmvBCd6E*6b~yu1i}i}s(@lcocmvf`8VgR(<1oquI?K`;y-KZ?L? zNRIzQlFowr4nzHg0tp&BspBeV<)kdTcx*ojY3*h8Wb9-!p(s5+-R(eg=2AdgsWLU6 znb*?gq(S$J1OeUul>UU*(i(DPlHkwgHE26my_vPE7rpF8Fm4rrXH>HN@)C3Ue0;y0 zcp~q)y_0*o{ajCJ=_>sALAw3K@8pwL@f?mxWBcy?t=6pF%!Ug8SK)W=FWzcD5(jcH zo%g?fa`5l6C!~wy?p_}iL?9Ea$#_!j-Kkz^wou|FsLY<84puKG3yBshBC3m5kJ0PW zNM+Q2N1I!7m}AIIoqNgwc8XpA>K%uHn_a)<6*M-MFKU9HkT{ZOXo91Vl#n=5{w0~l z`k*#*mE_I@_;aR1FydwQr^B77?6WHL+pb2AQf z3?S6Ok;`epAS$l0v~Mz19w!Z373+I@ zQfnMFhjCPRWw3vEF!kG|#wBRJlV=jUKdj9n~HaEk>522p;7oR z=WQ@c*ur$K2-M-ML&UCqNXO`dnO&DGLR9uI;bA)2VLAm+iHg6-8P6unvt)-()N_mKq5Cyq2Lu3!#z zi9unN$xic#Z8>BtGjjPom7ha8;3~0JpSLy3ZqdALd@Ja0eX@Q;vGwD7Sm91eURW-! z26O4Y0T&k3bMM)y&HeK$7dHXHbTYX=`F&FcZ7@)QENLOqxs~6$%NBMdwfXCOr>o1F zFMkjA%6T>l|AuYtTeWk)9eX|h(KyM~uG=A#m(KZIw-3l67Uqs_j96M*HZ+$mmqHqq z5FBMiBI3kcKed(c;3A|>I(OwNv5-!bdm7w>?dhxC?^__kE5ttpAz8gl5t7DezCT1q zGh938!mnzw<1~ftKeV%&9f(2<>!2G>eJ65lo*(xo!OVW6?Zz8(;X-B-PFD9v)lZJw zXjn@RWS2R#^rWU+NMBJu#KL}y_!&vI;4H4F$-5?JHYF1I>iGioB@*XNd8CbhT6*;!Ai~7|1JxwsFzNnh^(T8F8U-<&T-md@m z`2mkp``BCVzk30|qwRnH<>(X3YZ236!_YG+;*|{gu?>&0w{V3$tM_#R3yCSDT2pof z1>?l}-N1chVRc^J^3#KKxf%^d>rNA4b&77rtK;6VBsi7Z~ z1!2rUQDA~@xfBuKrG{8{%VZ6GjCgl~jX*o%8hoDhN$tV>2=ljZDgshCGGm~ck4Za7T%f{n>Ytse3hF`~&*X5hnV;85j4&+BAM>>cQw1 z1;4$%uSP*H6FV&u@RTI?x`BeY2S$I3iPT=0kyxi!%z zi@p2h71rOj4d;)i#F5s^@|k7S(9b5_1YLi@2C`@pQo?1HvbwHw2sp-ds*!%JNxKB$ zJj@|S(l9o&Xw<~kOg@SIVHQ%}sLj2Xye@gR#1`Z5*WG3Iq1{K0# zMki9V&>_B9Yen@i25K9!9Z{R2U83x>PEvpVULt8pFB0?R0zVd4o#NdrHFiVrRrIzH z<`CvS%{YPPbt$a~U8lduQeS5d7xFZoWh&J_;AFJyLZC-w_^dCDu5=R`5e34h!Lwu3 znvo`sk>z0!X2YWiob9)U+RVILhPi4N;(S3^%#)hUejQe6~Z*F=_=uBf0j77hn_@L3}CBFEHoq}75o#rTd z?WVu-)WQ3f*-_~6&3>4@!_0=W$o4V%%Q~j(Ga!7kNgxq6YcS}6!l9cDveL4wm_OpDikNinBgM=@2 zMmAXn|8o@?zq<$54bLH9e%9uN8$H800T=Y`Ht7n(2|xab$?#0hFu0NX;C0iu2N}3w z=OgtJKYy5i7KoS`E7ixSsms_*$rpk=NiLDCN}fPoGa%hl*GuPVwEy|$S7(SQpzQf+ zV*8GU?gQo(3QKC`%>#N;1>X52WC9tT+(uxsCf{&>2uOxKPOmdDmiV0(14|&Og<->n ziFpJq);$3hv_K^?bk!S5DYtf|O60TMsv)M6d#ZDrArtw-D9Wjc*WR{`=579}FlF83 zqQ9^60#OlgwWkL8;e}98GEBr-5cH~*NjYJ3$GWoVXD9VT$28{a%Sfx=n(_87C{KcF zwIj~NQTc|CrZ>3B8vo{CyCb4&;N~lIEG2P`>E}Tv(B_OS$&`l+G>8+9r=Ahgsyh_87i|` z>Z3w$8>i2DvIf;@ODgV^$SU76aYuL>(A`Hx7b((}@MH}B-_;bXIT_sFM8(I2<)(&v zd6fc(*&e%ArDyuqz?;KwFXBkAO=cZW)g7WR_w5nQC{BoAE!L{$r}><+-5;&%d4IKG zWgofJ;75ss`Lsuu;P}vwAfEzKJE6_PvSaaJ2h77nRJxhPMC<=$fv&bg5xh0PNAnQf zg?0nhC6BF!QL+W=#qh%&9pPNvKA-6&0_;J#_;P^~_#EnA>~JdjjXsrO_9&J#X3AqR zz9g_*pzsLegA~PVCA@465MJj+Kc2rmC0QMqAUv^mu_MdclREq_8Hyc$r==XSx<1is zwLln|5|UduDkVEgmRXoy7o#<9rC3FA_dkmW-8uilpa3|iooEwVj^S)mM#JCzduJt4 zUvLbwP+^4fzSCiiNFq%%kWJOW4Y%xWAy{^Cq=EndX+F%@Ar6g;-m=AdrMr+T=8V4vvCrU(`w|WH`)6M+Fsj@%YQh(xEF3*0$;eH zvZs^frIW8Ktm-UZr^0%eXKz9m-W}dt_4?_mtaz1Lu&C`?avM->qUAZ0C}LHFyuwss zX~}D6>s%Wv1UgZHXbIMxRzAxfFLHUb8mSpbhfV53F7tG`u0tox!`3gx+KU&OO(2yk z_`^wM<^?NP)*vyZJyU~4;2j-iW^m|arCwi#TH@dl3R9J+T&Xy+V>d!76v_{k>6xWp+6^jDE_u`NNn;A5C&9w!Ya6zRHGjuSzS~1MIw>U z2)4~jinmUe|jy=FC3DX%wFysnR!4;k9Y?_sJ0TNuonom8p>tH?6Oc{ppsv|_MnMzQ>>1j?*}aWHy^i;P*m}#T zHsfaPmjXqKLkq#(iZoE%3q^vL7T4hJQXGnVad#{3?k>UIDXzg?Px`!PulMY|&tmZ< zE6Gak{O^%#els&9*MigykQEg|6KbJ^#gpd_VeiRK}^6U{))Vb>G? zNt%a`z+o>H02s1|3Hvlv+BKP5pBb@bcgIPCVWDPH@4bO# zgWLca#c}FgW*_u(d56t$d!o)`>qKD5eGgLLcNVEHq% z&2EKT8ORv>h1R)Tz*#aMS9V4K^6PjtPC_1n;&{T-$p&T;M(<*{7JK^reeb7XI)1GA<>gv-uW%hi7k;Z<+nB-gn^H0Av%HXtq%p|JG#zh%Rc zjC;CPv!7m;2ox(;n1oq&-u-wPHTaCN9IvUTOvHxI*6SDX$ocz3u%4yBj-pS5?b$O3 zGxpDjzpsIL6qz69=hV7846`Pr2`cW$AeIaW1$PqHANC?IqL~sYbfi$oPi6k!5-K$+qZp=<*91F@MOG4f1+K z*dp}4^rrQ5C4H@->L;loMSSpwgWqVY)#%!E7DTe@@bNJlQDB|{hI~t=%>vcW1$VLI z({f@`;!vaIzTrn~kuY-t<5(b|3Roay8QH=mvyH!0?uZ9FMT>Cz%i>hyiyJV7)K+1q676c46=(>ZK#VnV;|!Al_x^TlrK0b<&n8Y>5#uKac!ax|~Cr zP7d(D&xbmIFN5u8^{PqnFTcZIizI!5m!KHIk+MWazEoh+`hPW%|9dFx@Av0T&n>u7 zbX#6chNI%z&x2kq|AanOES<)qbpfz=G&CjF2fC<0{FbyhD5tSdS}ySD2R`Pn-S7p@ zL{)TM8s^{FsuPzg0RAq2VZwvH1l%!=Vu)-~8wD8;U9NP;MTCd0npaR zE$t%HpjUD>L?|gny>-B^`Y$cOGM~3@r&k9klRKmr6rDZ;UDZqegwxPnqkbK7fv0~? zQ0Ob-W3b~=BZ~j&?`@c}$M=}hflogeJIMBw2i5ZHtS#rG7Fy4X64ODO#ta?tps!K6 zAR%tLx6f{>z1A_hWulfR#B#Vx*N-`=G)HWak!!x?vPza0X3%D0Qpm@tPqCm$R0Bmo za1@YlN6HGorrIk35c{yKZ#fIMvDCWs@qPy2hd5<0UxV2HaZUP|vm-8B! z5-wkTmyx=0ZVn7SkGN?9Dh%za4sr?6h2u`mrvhD1Yu9*=n5hc?1UIh z7!*1n*FNKHBXCtQ;d({sg>j;C$crs`VF)6T&TR@}L#qbna78?j%NHf^(I&t*;fT!; zA8;=a_&u0@G^q{2rISJ*D21CF(|-lHypB8-n*@f*V=U8Vns=t2QKLE;*EiiW>hRm>XW|rm-`S} zv~u3faV;Bdnuz}Mco!N$)VN64)3husEF=b=WclKEiE4gNZ@d^%vWL$Uf{GLHnUA8O z+0dob_sYDJTh-cyA2Tx-{++ar74P9{-RR1(aU|qs<*{SmURkPVc3g?ZDq1Arpw$M8 ze694PQr#-t{xb!H%&s<2ASL!)Y%s`JNDQ6M3_5&MD+PuWC&g)A@M6aP5Dwbfu2jp< zEUbry5|zqsdO6qZ^CoY*336P`>nZ*6nyU!ffcY^Xi0mh~m-Y4a#2C$`+x|+q_J>eU z!CI}WeK!Cy_&Adv+iJ4rGpfcl%yW_PIjG%6t9YKk4$GuQ@DWT67Ods->**mA@&xz{ zbedCQ2m$)B+XU>GzdA1Qn-hmS?gZX0NXTvphF=3@A33GM-`%)#iv%SH6gU<(Sa8nNP^;Tig zsA!h~m*0COyy!eaw66cB!KNu6@IVR*67=A!>Xshae3$hG8HEys3u(H*-oIB-f|*+~ zM30b-Dm#t)R~4#(`v{e?U;z$uNG}I^?PEfcgf+ae9cSgfMvoLz_G$C%JDT1Rt(c!{ z{{O5tA|>745lW&y4>~N=r|JJTay*$<4(=573B%}O9hX#-DnawZ_r55NI22?W$x*?G z)rJ%GfK&odQ!5j0ajFsq@!0etK?Nf|+KpfKa9LjS!O})JHQ%OUi95xmeXuHj&vX%S z*^!~ge4Ne`40;>xlr&B~QtgF=c}Wu5WysHL`@tcBD!PPj?LtefJ8@9yKkD`WwbTj< zn{Fc}wm%no3h|gq^QuCH?qFks95#N8<*;9pVHh&ZCoUvR4}R~Qgqi3v$bU>U-8pe( zQiP;q=a#ue$d`_&o-b2>$b7Lk(4vJm0sri@KZ;6Xk|>4V$G2itW2UlOR)#AT8#HCC zh#F5rpE+gqsr!*o^$ji7T6~?(D;24>JrPGPs5zpMH!D7N)<%i_=1cV1$3?rvex)X* z%Yb8nQ2ZwTYClcfMMtO?w**HG)RVFPt`ZjE!>Ak}r}pIMJSSZc6WCd=_ZaCNMX7J5TF4G1d86 zZN5TH8?0`mldjK!8uENWYZZDS$YCCDuPlc7X2w?85U%Ak%Bw7P3V!E6)_83 z565T>xfQkmqz>`vu=36J^ds+=*iB8WQE0OkR_@0rcR>!Jjaz`XV`8BNV7{UtuWngCVS1a|q0+GE%?tD}6SZt(*A;4@ z`xc*M9IF4)Z*X@4Uq5=-E=Od|+0ge0lY?`N)uW2EEAQjJYi4N7$5^`{_%nhtix}T9YLo`d~lHj-X&VV_1oM!Bw$88M15qw)@nKkdLY|Ez&&pJ1&`n4s;_E1 z-ohPq(1lj?wc1xa#U&!B_nImG(j7 z3=BWa8n4O9Fai3Jq`t#EM2?`ar2hM0$rruOtR5QOP89|b(c{p&;l7Oi<1(H~k2kbnP^>tE2KSqyGeNML!e8s>sK+Ke*a^U6 z8?qO4G@maRt|aTXf*l(v7u%!`XZIbQdoxCQ*aDl-+W1O*LJgS_ed5R}{%}XYRgxhh z1AcR4khj33?NzbSsnw z2>l%#U4+1#)E|yC=uD2hptZ>-JtxQaE=eX2Oj$#%mqkd<*`A+F5lX13CX2c2Nzy8g z?QH8)?}AV{y@v5-xf#)swTln+tGQhpPAn!I$_xQXP?-`u65|LCaQy9@%LI=?Qg~OT zA41NVdZ%OS?+N@pApXx1ka>Y=HJJh4+_?(G+^)RZHE*Xoi<9;EzgI}N4$PDVg)V4` zMed4OT44(s+b+Iql~=|{+BMGFa)fY<)vp=!vKvi1Y*f^-R5NRpxX40}c$c&gT=hv7@O zebw&@oGmc3^uOSLiX#me17mA~_+KqFN*#P1AY<(Jmb-vPwotd!KI0JzeD zV96_~BmmJI@|9ibt=?!IIIZw_PiZj%TG@rW7*d}f#LxL%VBLddQkp~db|tbiyc zq*K{&XjY{;c-`Z$4-LT=ZU9r+tHW6@yOjR#Et;~I4lP25;s+E{wX!KjlPy34s8%~? zfIJbDV-I_{j|QwbLWkpy4kHq1KF-T3JsnSd5L&g1(I<}#_k(wB@iZOPNM!?tlw#&I;`F?x2nOXh|2%CGNEj` zsmmDHE8ko_s1&^;IocqZO5jZHyj#Ok(DY&QHLfRkwC+!f{>6cC>s=clg%=STIQOpbK9@l~&2o?>Gjf?$tE3f!O1NnV*=6t# zrg?EKsi-d0lHGR;SMtQ+rw!3$u??fUF00JBV84T9uL-bm2q6N-^L`lW7k#{bDPW2T zMrjSPhuAOD-9({^Uvf#2@bxj~>(_wja3m%i;5q6RF7D5O@JF7zMop=S8wO#~c4&S^z2UbH?LOf^}=b?Mj?*Oqq(F0p!!CIR}hl~0oKP;_%|iQXuXW7 zbHALM)JPTGg7=xi!Y?gVZSW|+@q>_C3|FrTGsk%=SjHpI_epzY)8cDwQE_Px+7iB_ zI1)Pc3C`Do`@AdZEhKr;Vy6Sw<7-W@e%_$^@-&`E{=DqB z*!JYX%5aEqG4N_Xj-*Xiss@1ySk!^&M&aX*57m*B#oU9WyGp zMl=h4ePE5Qbj0iP>X*OuGV*Xn9*GkE{MH2o#=`g zEm>PoR3SLvupSfS#sF=&%zbD-GhLfJZsNvd@o?2S0Q*0~fSvnTRts`nykxsQQfV2|S86D67RUl%gq)2-f5i(o~kp^TECHh#ZJ)7{tfewkF>8Mu2v`MZd}SBkto z50|wel4^(o8*URGS%hi9OIk3n?l4jpJ3fB6-XeFoRvj~*=>0>@iG=sna=4pejc*5+ zP#0rM3i?3c-GZ5KsN?01*$@;}cVS0@B8twU0pf#$pQ~0im#19t94WQiaDoVb6vkX} zG)91I>7~ZOwXAYP{gPfs$QmUDhsR+_)g9^F$q7l5v0c;iW^J`D;XgNi??Au&5hYG2 zr1Y?h%-EpAb)Dw2_OR2ZMWM?d!-Syrt{s90tG{eE&2nCLtFRz`h7zE5~HZxk)U!^)`>0 zOmuV~kDoThhzXvv;Tm9uq@J-(Ci5wWE(dX5`%9SpK@PRS(!}p6We~ws;O`rB>Il6< zKo&oz+SZKLE*Cy3_j_iKJUAuL(d(T@M=uo^j`E|5GKyX9n-V3>Sk#2WFx?krwtZIr z->B4q2mL;Jh2#nuNjeP=MIUyYe65oW=;TQq&g#Z*NyJ3Q&?Y?)fg`-R`sy-`?RWXQ z_&CrwtX7qU0bguliyd+es!#TR_VXXZzO1xluMd1_HL>-3ySqpdiPLkKRDeMm>*}}_ z6GO-K#*}v;d^gR5YIhN1RUqc^Wz(}SE0w=<4@D*jC=1)Sl_mAe{b^0}t9G|*xe=j{ zP(Q3hlYln^E^6OzvkB7nbgn2Pz72TeZ`6sIn)t3?bM8YV4pMZ99!b(%qsBP~(%duN z=I1KT<1dzd(}cL0%Nl*cQZv*`lzQ9cq<)!rK#*3&*YRF1$Ff0k(+DQ8pojU?Tc$21 zA$LdWUw0`9ovqTajvHK>LmaD6_4}c}mj_e1F1?H=iQxC)VQXeLQDb}&;|$>3&6^tV z~u=-U}&24joJ)2`lXU- z?^M-S!dldI`3;^!fjr?{N!v_i8;$otip@;bc!6sv(@eMi`l<~!5R5L(2j`-N) zhI6_wQbs{Y<^FotSYPSlcTs~pR^0q8fWLr#26}f9@!>vyUGjZ;tV00b#PBtbkQQa)x1pNX;aYutm?ec1Y|y=w3RJ~|zJL-Y)u z_pBEs*?MTT>w16sZ?>I>WlBYLt)*NvEb-CPWM#SNEoA5IPcN;fb&6%4#Fe5Nt%wr$HYLBrA)i91&1G4O)@ zYxj!Q9a*InH@O3Qd&<(q4|)ToA)gDP$Y$OW4RclKJbg3MMpRUSE$U^mXMc2x7H)Tf zPI2n0Zq2|ZK0bu5D$9+coU)F1dw#B(+Z@YCT)U_#nexM4OK&L78@LOTa9U{CPM((z zTD<{UJXg7vFj1Qyy-T!rkhqFz`f;_0Ec1cY%q!PZ)noHC!}FHCb}eAg_wS5}S!ag-wDyUtkOe|U-Nuo9rizv=+)g|6T{hk$I# zU(B%%JqbC@=8>h>m18s9z|d%vZY5~B{UBk6PNVL1;ctj-%;W+wC+e~W0aAv^3@h|G z@aUs@l-g|0YuwMm8hi4;Nid+9>Uk=81~&>6oggI(T~Y?meQE=3T2UZXus)MCfYjy_ zmM7U%lmC$bEREu&_6o3=JU?>_2s(FYCBZN0^`h0sy>!T-tNWYK=*jd0tb26Nd)|k9 z1%qzJ&+XN?6*POsL&}5FfV*COCQ7YG*;U%cSdHpefAdO%nw=Ha90uA%&ok*^N_8MG zkYDqt32#7Pb`>d&qwHqIPLMIpy5`aWZh`4*iPa_9%~?@@=Nj2GDc(|xevmze#c6Da zrTg6W0YRa)_fg$jW#7-AGVRZgs~%tOUB#kCE~hLmUYo4RuQENB`v{DoT8a}h;M%lm z)0d}w6E3U72OY2LWae>F)7X`>Ig2RPBX;}4xU^(E$ji-3yF9hmOat93`OyvK&K90z z{HKLR_r6nd^^McdJ1>lt$90@7G}Z5E8e(&8Ojqu19FE+h+PoeDz9ZRW>P}^i^lyED zWZXZq6WKBLo4a#=MOBg;+MD`IT#Z$sp|xmXOi;1f0d4owV z9y!P5U&B{Vd73u#F}oa|1_^1ZAoN}cGe5g5GXQy==j5zdJYLWw`Ui&RJ9uw&s$D&q zkgp&<5%V|xib{4;U7F*ir?G||4=og1IS>iXo!71NYPWqpx5H9(Jc~@ox~k&L*(KqvkXK`NL9^r5Tp4Z4VG88| z^UheEf>3)KS#x-@8?-b88TQng-9F^GJfjt_OIpEZF0YGz-Q8Ix!cPlVBdc$*rBpQw z4HDBbc)8k)p|SUmdY!Zl3hkydWAj{GmEruW9U@X>yozTd+Nl%^?n?+wj=eb6teV%i z%PNcw^~7lo5PvRR4;QIlap7nVMzJq13-xaMbg7QeUWD=8(;@fs2G^ow;ijFK4DCp- zr~cgWq54Y?0#XY;i3@K((g)`R%sKy`TI7H@&&5BxQ5koVUtGU0RpR)G#Dv9urXTiv zJqsCl|0yEbZM6;$s~F>%?vqn5X@k~OZrIALu&}C&);Gnot91MIN3C-`*2<=Y6_>Bh z>nT{7gX=-aT5g3ax1<%;0_cIHB<4tR#f(26Ft4{d#&`I?ZnwWe6XHYbo&7$wIEfAu ztk20X1SDNGbXb;1u8ya=L7fOlJ&d8{uW1W z+tLG5q*QCeueWZp`3UY+!Bqj4vqwR1>AJs8ZhHkuo{f!~MM{|J#o@_^tOuW_BiK*Y^Z;$nY1bhA;gY zeWH2%JS&c8ihu6a?hB&oBU(8)d41w1VxaR`?o^ed87Sh~rne7HuAC9HPK<3opi=iC z(l3zLJ4;=)O9|XC`VelP69^m_89A)B2Tm%i`O9+APmgiQdsoi&L^A2aqB5dG!I3e{ zMF(%E>EBskj3TDA*FEKULkOB)yNjQsAIExc3k`o>`Tft!v0vBA)dhKUkJ%d&GAM!CFQfoB@&8W0kgZntFqna&E4?Nwe2?XfR_rdMjT+j+s11s8Gt9*1ojEZg} zgSUw`qWOHqAI0JCNJi*naf?n9TU!Th8^i6SPc64LUeDwFQ^=yv%MzKt@^6|Rng|^+$2GGp(>wK3&FveTwAR2bX?CKoYTDzj= zrhbnKV5_S_SGOw4TD#Nu9moovy@eX(l5~~t#V3gb`{$aqZF$Ves;Xa!z-VW3&A5g7M@@dD>s6oEtIO@?aI{^t=I zk?{YEC&*vn_v?ujW=0j+1as2uJ+fQgSflKOPuFTSO2*JQE6|j#k?*tbKQRqtrm|&e z64UxG)x@n4Vpf$RDo2Qf5g!P$V>%Mqzg%6`MXA1t*aW&8RDczG)IS7$f$u0Lxbwom zaR71g!No>DoVMTnh}=R3=R^+#NyQ1zaS;5M7Qm4a_l#}1E`*VC1=l)td4VfUh?5J|WT9^`<3W|A&jL^S0&|_gX)l-W{56K%!Gr9#4 z8AH~HOg6AA9c|AEt>v?LI6^ORQk;*3lI*<2jJ4v)sJ*{JHL+o9UK=@t4*Kq#wJHKR zl&KrsEw(GAB6n%=F~KGV{)-N4gK`HHN{@*}#AZ0r$x2<`W~8(l_$ts6&vCWVtv%qh z^=FJdpAwYhVp%>(7VXOMvs)RjKO8Wj4Sg)<9-NXaMiTC@RWZ9IR z+EonJJxxEk38svS&L$LBIJHnY?0TQV$fGO{Il4mJyxw}g@JX%*rGHF^3VPvMtU*lK z>q15fc^Q80R;qd4=YhS2(!`!{_WfdI_kJtQV&yOFz`I4)fGQZ7M!Pd=wf!?}G>0Bb zk!I7}$f1VpP*Spenw*WrZP*Qf$!n|Deyqw>sf*fWoDRZ^7$C>W@dLpDJQeg;16H8o}-vMx(86$LW z(J<>~I?u{e9u!zei?4Ak2mt z9ys)<4Cm?UU}YvpvDIBg-QsdQ=Y17d)fRbNTs$B+pddu>PN(rUdi~XHjX3j1P+UQN zGc;&gB8oh9l6Nt4$x1KC&{!$UGfHRmJ3O={s`curT@g0H;X2Lsys7da;E~MhO!ad8 zu9oksflRN9EnLLFPs4#6Y8_0_!L-fmv%!4Ev|uNdiCi^MdQc8U9gD97WLXNTQwzyi z#!Lbh7>v$U^F44YE?{Ef8i@TVkdP+#^pcpbW%aCPB};HN^zK2$4^V>mYPY88TP7q) z=Or`gE5r9m1!G|}R+XCS?%^1G0z^tToS+TS4tKu&OmA#*y}uwv)_ANV$#gpd(zDwz zP>v7ciz3R5CW7-0isr2`!Gijv-o~qZ>A#!wjM>%#RoEr2^SG-K(WLVp-RQnUno_ye>f}n;Er8>2TtGCYn%~$)_am2+j#C)H$ z=~`AMW>R-CEllERuy@}d{r>gbw$q*)aq0CiQE}?&+!c6e>_lhoiVr^HeY+t1qjb6D zOGDug2wem~xF9NRL;8@{dWpp$D8D+KGL-$oodoiOWnyX4L42zItF>-!*^07(w>I&%oAq&-_Pb_WkTR^SaQ~z+%AFP^&nzK{C z(s`KcAW*zGJ)3Tm%x){=Fl0zk{Hpg0K&)jW7#t8XO|$li z`yaQ3B>b-r>fq9P>?> zWI>(+jfuy{`IlBn-G{qnrxKwyj|VH4J;dy)9N=k$++%n2_Gs$I^5iE7L3vR16Sq+D z!O!K<`5EEYUDYEYGFziDZQ;xuGWI3eHF3zNxG0cz;mVc!_3ueJ8;{mP^>^>Bi<4Z> zKV^2v-`_o?L^iDFd3ea+`A7Yj$y<9!4f=o(CniCVaNddl89aL?8m7!;R8kB}yT?by zK^T$)RFgG-=81gYb~V_dY|kKI`=pRbr0^npJlvNLYh|=MUeR5VeN`;6_txIH^!Dn= zX*Qj{0rR@N%C>WQaSi@p!Sz)hybrDaRsgoS^nM&5KcYkRDe9fpev zEi|pD^mnFCX39at0~}>u)sY_KX3V4Br?Ewp{ZN@{IbvXCtqh59Ie%lY4HrZ2w4w`o??2Vr;x|o(2FxA^E_r5W6vU*!w&kRkI zB`vhbV0YJv%dD*^eF`|5XBo#k(fYVfc+44)wvTGN_UxUGR%rqiCVzd>OFV8NGcJ2Q z!O6e&9`~-O%<`C{?eH?=iYwEuwe~K|T(P%$Mzi1_Z$4dewBPc)bl4c=e!YJVy}&dG zh!Pe6z1(%|!p6j|G>*JsOujXF{mN4DXud|SsvKAD$^U8ZQ1|&nx-YLAE8*BO?lU8A z!&6#{q)3ZT_fV!9@bc2zqZ^mjt+}H^-Mh-m(#MKi&)1zW>2=+^)zFKZ#pB=KeAb2S ztDeriKYG5N2ftyY_ToK}U%E9RS6BWP^E!8!X5sbt*Ks!Qc70{h|4Gon=J_q#f#j{Q zU9RO+koW85-ecSz`8!9bFp6{eI$k}jbfo|37Xt}h3s+Jv660CD6DwQh{{Jiv!TNa2 zr>pqeeBW{fdx<0cyIHPxwB4}ER~veg5JN!l?k%Z2DlehKGl4q_o>ju#YeUOY4%HGp zG}YBG=o}Y~5aY8ohS{>Naq7>Lzz1?ZJ?4WPurcvO!wLi4F-3@A9vFNCr{`>q0(Tuk zR)QncrKK=3)z9#^iT?Q%PTP*69G|r5OTTaaTjh~z;*Xflyn2D#i9Oa~0DI|DfL9WP{G!X^G3)%dUG6=HimxasrEu=JlZvMUAtK zDVH-L7sh=XwuZg6kM~h4H_qp!joTD(01WxbIdW^K2P@R~bXFBFH!}7y zxJn@SA0zD`4Gf0k^e_|j+_HsZk>UAQi)@SqGSKGe~IE%ChBb^?4`ffMwZ4 z9SN|w^g5GTkV#hkzREs8D)}}kHf=|DX^H&^6k1FbanGzNHk{%3W%uGp3lO62kR2T& z*fJx-vetYKu+>jh;YX?}6@TLnL-iiRkL+Os%e*sYh-me|+6On2EV{9)`tVN#g-t@!d) zSWS-oj@LTY<3`ynHiv=!`GOvXiJ1fk00Tdsn0WsOGkPK^1PQ&rEJT6XZeyXAy-KgK zht1u}lS~y4XE7MYySarADNMpxqP-a4KrD}Yd@Ib)H!(yb$D4JB;-{~R1?54f6Q;M0 zfm~0-^ib`3$xqPS9%Xxtes%y|*2rK!Lg&S9>E5WNzF&73u<0P{mj+Bk$(IPYkj(Y` z@n=hVADj72>j=zDN7-@>gnKICdZa2()M--nl7{$xU1ex@Ic3f3b2oNh)Vg_bSk7J9 zs*OTWQ|W%zbhEuZdDy-tRlAD(`Snnbc%khmvZ{vucV zmMemG#j%b*wOmhN1a)PM|4jiFIBOo4Pf-y=<%7nYBt#p)-YwQ_PlHK{g3%l2i z|7xLE_7sa>mWgo_^tvTb|JLdv90T!hto7P;5eO?m`gjGr(WX<*9f5YINU-8(=b3-a zZ^PA%+-zwY*q?qgW-4DU2*z+pZ?Q|MQR+i=w->3UU~OUSCb*@vt}&BiCB}zrTy)64 z>%KCF6A71TeAU2Iqqv1AHT%%gyzwRNKyFDuGFSWmNFVL zv2ktgr*TWQZTyFPKPNQ!rq7eSh@mITB>?HeYtjVLRPBq9EKG)ysy z8zvZ8@nW|7xpB90ffZ01F;62SG@y@5O1k+Uz*7FM#1_=fexmy4# zgI!n3AEuR*2J~?7!miZ9c5qCih0Jh#B6yC%&%Sx;`>e}Xah;)GqRLeEtx%E|ydZN? zAeAO^K(=CDRg$Sa>4S&dO1CN_$2Cy7jTv_%0|Bs+p`kmljhMNhu3In6OhAH-Wgu(T9H6d8DyBIaZgsL%Py2g9A4XV<{W@q^;O1mFPzUmb>`hwM`g~z)HT*DkGfEbA1f)enwXIV=1#76Ni+qxsP`yum@+S2 zhMUi$gsICcK=9fWXk6~x;W4_tW1(Yw76Dc-^-7^m?BO`?u+U zoE+@YbP`d@PUEBFa+pt?PmQ9<6K)A%=ACEm?+FYTk6ElBl{iMAqIvYE%?=J)1>yj1 z?9$T0fWv#!q?Gt5h&(q%^h)oPn|q#qwkynS-C8KK?<%tcf7pfpuF@8Q%s5-g;a-Nn z`Nms9<%Y{WL_U!@dN4-QW>4-;rB(|O&QrP1NrAP;M97oS-G7-cZ<)j?_9zX#f=tqM zz?Oat|Al2h9WX?UJQu{k7t~jelDV~2Dc@v$(zsQrTOwM@GG@~DuaCx*fOpIhxf`I> z^=xT6ZzBfak2Msub5P?L+MD~ZIiZ=m#rre5mC|`d3np)?ym@|r%EO4=i!cva2xo3FI z?S9yDzC~_%y)*gF?^$VUv}ku-BM4(h)CZKqRG}zCb#nY%WdcM+R@Q>c0{6nyFn10} zUB@EMuM${zUa_Fd%$)5|P2KfemJ!l@IiGh=b$ud~0tJdFW(!84ni(VZ0%nm6Af6;C zhKiON-^o;@0zt(NMlqv5kM2Ht<-Xw%=FeSG2rt~H#ndRpSkRWrPSmEkxKmcl1 zs}ly_FM;qO?%YZ8MB{$))sSsm8rTOJJNkJRR-CIh$n5iG zngbQ8M8Wd;amiu;>xhs?L+7fiyLD7K=7v&E!hF8%F4gIG4Da;~Ni-sC?!W@rI)+Ut zKRCHpPu8_*OBnxt+yN9Q?}I97!pQ~hV)mG-Chk-#d-M~#iUy7!I2w4D%br@F6MEE zhmTb*^sEBR79OdX|FoYX%(Mk#6w4BV=Tw;e**@+iry|O+pYg&NhHA`@jAYZ#dffXQ*nE!}PaVsIyHPE%@+{)fF9Jn#Z+fEO;zCDMg=83bLPBvT&r<9#y(YTmz?R|p#284}y zQd}PMEG;)DXf&N)cY3OG89P>dirQ0!#^BbhGrju8Awc-`uycqA7S`F^F9HsnU=)p} z-QfClDH~p4hWlCFr{a`&_dGH2il=7SHuG%INRHwK1l}qtP%%<{SG1GyV0v$br9Tc+!9Zw}xM7-0SXq1AxZYvPI@h)|!g;0rQ-Zu`? z7QMpHk_zo`Tr3|KNR_0w=X4*8a4PLK-0{Mn-grysm=bv(Bs~LH_@B@2YUM6?dpZBIZ%=i`*{jL#anmg6eJ5 zt8$Y(S>z8mcYmeH1UXvx5i`|qw`nSR>EA_oxAN6sbUtH+v${U6qn*tNYvn#&wj)a< zwqI8i%H)SLS+_ksei+{-Cj!EzSAklN_>GOOeNwFMD=O|vH+e*@khOT9i;qvttft^4 z8(2NJn_kJfU*yI5$6NI*CES)Khc^}4)ov#v#Wqw966qDH5Gex@!wou%(qr=2i*FeEV>B9O{*?8e{0#O7_az-3ubWbjMFrsOH?VyNL>}q_tJdXyzMBp zoO8B9Hw(0QO zpouD)LHW4AVxX3FvGqJE?OOR5b@G!TF_}ZSLMg;67HNBh>vK~cyAube*=&Jy(NW%! zaeyF+7G*>LtDnLs=pu_CbCynUA(cm*D2S%^rN1bud3-yvnRoW3K!q9dSFI z%jc$_*xzN9V^djc(tz3KnYzv?U-H?(IyGKPBbv`m>(#JHGR!o}IG>>PWob-ehx<#e z$$DJ7YsOseTB&4eNxn!_m5Y6P6hwzgeO<5c8{Q5XhLU@&#>uzz6_x6hTr<(A?I?pZ zF4KO_8V97>Sod1pgGqPdBPxyp3`aqWpIMu^Z3BbWnBsT*Sjj*p6U)7n@r3duUM>Jp_z12N#oe>VGK zm%dr0N5Ly@j3T!-r2gUCUMrU2r=cC+^4#)tA?UyX4s*H^dxIg>J~4+qA$DVz zwL>hSBI_T75++E9%@F`HhF4RY&mlW(**PnUzh4K@{O-{s<;5f&OPJKI*2es*sfE?K zDrhE3kKsTEE?>qzG*Lf5%9rb}duUw)lyO&Yy1v6BZf$!J5S{qzG&QU^IJseWw+N{z zPdPm0Iq)5OUIuVN%Nqq6Z~ACk;>K!;y;jF1;ya#Hz!8QuE(i-GU_$a=IA*GlFAK-3 za2b<8J;NXz{5x4C2|ghMoM}U>wAv%@orco?QLB7qa(n8E`=OMX6_+QH=|GqMIZJLj zT5KStU3jwFe44#r1=zMa7huEee!5)n`BRFs4rJ`t=C3FhT9d1V%c+`A+c2Z#WeX`h z&Mdhd(hVEm=Q>{btl)8LB>rcs^3p3#qsnkH=eC{{B)k`M%+>OaDKgV_C`|?-^XW03 zd+qh+YrjAF?Sg7+9k1s@IA}C2B zCgFw379**fdxRqy?)eOiqFFwMu0#(i3vqE~oEf3s>DaZ*59n z3y>b8=I3X~1`g@Ud-8S5Uu_|4r_}YQ`Az6o0^BYl(1%~4xz$ZPQ?(618!@l7vACMY zh9?)9`;B1SXJ-svDmNGK8}>mPa`yBkzK=ZFg^9SxWeE_MdV?_Ub*J zL0~bZT_cAI(}v4*7yOP}?eDJ+bP;mJclNi@x$fL(d@f|)c6GBL!AI8o+)sV(VLFec zR6lq3Ka24XVF(~9mX_{r zq@+8Ap}V`0?i@OX^W(qwe$H9@d3#>U8V1*z_{QhHuS?5p1tJwy9~dm(R5}OE4K?(l z*5al#pF%>?(Y#fd@Ws}JvXSLuH-n|v8 zJ(}gDk5X+K4FyHbRe@tY9?g%#;O$7>;wW*|uvV&hH?vA)ny~<# zkBow>xtlu+-`zx@n04pntl8e3w4dwU97*oNAqm}=UVoqFHK=oikx`?rOX$Le5WMT- zTZnc3&s~7hLE|ySI)w@MH(>ie$43z3=+rO4#(a?fNR?u&9PRF_oN(KsvV}(C+*0^C z;eJ!CN=k_ds;F=R8M+p;#Ca{oDp@ZvyIHUOP~46u$v7F3td*m37p`0kf@3Gp*4GY< zC+^r(ljs|l*yf%O1?kt|DTqs`=2JnZy?cNukS6pmUbhfBJ+RGWdx5458FCD?n*zh4 z)b|JuLVe=6tw5=~g(AFat|Z~ z1=};SQ-3N~;)#G?UoBzBG|x&qDy++(B{l08vwI>{$V)56PjbT@mp=Hj%p(EN{0ELn z`Z5Hw%7|kb$v_2t;15yr4huj|Ngu1i=skPccxnS+^)bR=;F9K^S?~q@lcT+3s_RE} z=PwLh_EiHKJ4ukfahsCkzwHs4g5RMjIlq`cvO{t#CnIO#v9~I8DEn-zA572?a4Kku z1c-!3mINOij-JTJj;ivn(TjwCUk^s&!d?ancv%;Dx>Zy#Rq!%#s^V1KyI+Eyn(GmR z+?^!Lnag-6*6qCR8iM;!zeo#ns(GK{CPorHKoWX-NJL3A?;o);14qh)A zvKZ`tTK5w=l_8!lwC$}dO>tyGwf5ewu%r{=x(QB0oefSE-A)r+BvYT-dbyQg~jpktrg4Sw6BxxHSS;X-7Jwx(lD$v zbnJFO(>H4Rs9_s8Io=MHG0>kExOB1qPomwsM8E+38BGO}1 zkAg+7TBM@F2l&|QN_mt|CNeo^BB~`#uMmbni&~7-+`um5-_a+hpxSj3v@q;5L{H9sv%gS%i^*r;^`~#~lAKEB!3{=BiQh2m>4&5T+t*>b*2on)CbY83*!TMr>yl~q| zl0fOx|BI1uNofJ{Hs6D=0#17|U7!MIla#n*KjgpN zM^_d%okBTt^jLh7&PvW_^FYPxsARX~(ejbg0^xF^-%kc2Ld|$>W5&-D9p*(qVnA`S zsfQVciN8fV-{D(zi$u9;t5T)+LoIM7?9d#;2CJlU)w>idTN<125U?gfjvvPoX%jok z%zeD5x{j^=VN%o5CP^7jyF*^p(ehiEbHaw{%HE#fu2F0oV*qI}-p<5?DyiNJP+0t_ zGr3m`w@T{iV;DoR0r$YLsdmeWtOG9}1B~hC zOagV*ZhZ{R3p_1!xYGL%IKfx)Zuo+t9GwWt&E7pyxGX}hK!49G!3GrW%L2!cPH19} zkBbA+&S-nrBY_K352@Klj)b*qtjgWm9E^>68UV42?+*XDD88T5SwlEptUFGyziL&d zkd9lf%5W+wBR&w;_TvB*PjQ5+MF$B_5u*<6Z1fg4?;Ne}0~n0R`crNaUZp8JWNz+1 zV6x{yT36^ps@(Y3Ht17Ni3^ux*$gvUmK3tpO#6l;Joc_}^3YSqkLk+7OS_o{O|TmK zWAg*EK#fGUfok%qC;}YvlzON=U`xYd0BiHsdVjX>-J)feIC&bw<~8uYum12XAn>=8 z)E~}iAlVHPc!jT%dE=ZBPAjR`kGAn8f~y=PfNesfYszK@wBb9zEh70ge+j;8j?wub7twZ1d?q zfv=VnF{f^{%Hs?l0=#%uv+*D0csG*BsPyL))|9HnC0n9?sp`0a z3OCdwYa3jC3%iDU;J|QLyj=wPTt&-3`Y|aM>*rA>7f-+RZKFRBC`;O9UMv%uylrvK z6cFHXJZtyWW;Zp~RRXW)y9L50WR=w&d+22CY*e61QVjh-^{KnhAZkil@$vvWms|+` z=A%>4jj_*x=HX5u{|xU^+s7c}uUBi5T(7EyF<>K@WI3(4V5)_jN$<*yTBt%Ma#6Nq z(8CoUA|%ngYMO*M>i5PLD?2UXCacJ0eO(9@VaAIpx#!Cr|EjfqYrEM@+GSk+@Fp{i zG_=Zu#w*~9hw%w>F*4$=O(idl_+2Og=Puu`xrJ6skzAo|SvAx!M6fofaiDkrN~CHvH$l;*L+f z-c!T;JSRHA%otONjCYV4=MPJvmfw8p-jS;7k{6E4?= zWA+su?U(or{I1c+K2QldWDH9Fn=`dzD^RcVO z$7hQe4SKXTG!zL*Leq+}NDE>`>D`l7T}*VBheSG`TFYl$&D%a-RJ1T5+vv2JoZ2^C z&-*gkwq4)K6F*G}3E2*(3fO;jD7hNyDtr&))n{4f>YwOu>^7LfZVTXJZk4#^`4e~?(yq7K@tOmhl1f2l z2!AN_#&z^@B4GV%v-28j6F3KklCvWmsW0+qp-KYm$TV`|THzUO#qor&t>$ zqsBX(RH6JPyb<=z6qZat^fr31_8z{Nx*{-sHH0eE1`(1eD4`1;X2mU)?NN zyK#5$ z!E(?0FzkI<3tZWZ!oyiVYO%z9jg-GLAwt-{#@L*Sf4jfT61bQ<6n8}%Z~VB|@3#|s z=3Cu$+?y`M^-J0z+j`EIQ1Oe9zc!o6irrd8Z{Y_gt#@~Y(YMOv$mrRgX2P(@N-h9%0DXME# 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

3X@ zkjL^5r0qP~hU;U7^cA&<_(f3P$2!dKH5K2;#u8AH@->-VfOHJTrBz9V;Sm9UZ^Zw+ z$n`Bqx)~yW$Rfv}JZ+iS3xCN!>_~h5a?}>zE|nwb_<3TCGMJ2=h(yBXsy`XNIJKj* zKX&p9vPTTzFjn%nueN7(0&n%dXQorBrBFokMDh5Eq7--I!qc`0_I;`NhG?jr{rib8 zLIOpQJcMHDeTH?kWVa+T)%uV@U9{4v;SOGuw3ZYbw|BiWJkn#~Yrpbx=dMFfJrUxs zF@ChZ(OSJrp78e>^m?y?hF>i$puq&umR-nCD4*WZpVeiXU_Jj{5t5~w=49HA^~Qeg z<*#^S&$Bww*G8|^?X{UQ{JJK#nBpte;jTTM|8uc}a=nCFLzj+HYnrsqd#11QrcT~z zn?y%+LX_j9C}_^G6);){+!7w9GuQ-B_%X!;vtC06iRsrDa(9>@bIbXZUGREb;MH(Yq((5nXTz z>E;B*R9dtUmxUWs8F$`!?xU%TD6YUobf;^*&V#hXpSU1W(@P$W?&b_p0{oC4Z_h<@ zv?)Gk9!uHfQ7E_2OZ`ey{FFV(zy48AD}zrqFy?f34vrGHVtJEo0*xSp?##h0ZYivz zr`)6+S@h`8T0u%iAZrc|hyIrlTo-Em!0(X6oP zJl}7>!DS5w+QIjBc_GBm>Qxf#WJcUpF;R;O&}MbhwEPg93SIvZFz$A;ClF(>-4&Ea z#os26o>PAxs3e&H)+p(SH&)q%hj$|i%|XZK>niOys1nI2Mv*tM zJ0Wm$YJ2W7fzWG@Z$jFM*PKbj*urA zJ2?@P@XPj-0TY`3gv)RbYVIMY+R?n~3e&}z>S+_)a4YfpvhqH$%v=ox_Ylk5=!kl9 zR+~o=cO|F8c&o+GchI(9O6EHi-{k2%wJ0DwC(7#|7tz-hX{Zfog+=^?5>YzNWM_*mY>B%bi z6lqnUCGyRNd-$uzO}h6c0Yfn;q-a{8ou@MJ^OX+acbjX1%l*^mUE@4u)=R8*gKHmN zMjB+T=kZG+*dHwAxk;Y)&k5S&=W+#Y4B12Ue*R7*uZ9=UzEzY!r+BuQ$vp%R;J+VX z$j8qapFE&57+)t|mcoWVO|LAVtP^%K8jCA2h|)Dw-dq>;$9}B7>W)kE(^{Rbk6c!+?j?%7A|_}o zx;fH`Iz3Gp4KVL+$*k+A7O_Loa%K`o1s2EiCsZ*zsp6O+hW-w5*S<0?FVGu zWE?0mKRw{XNSYq`l=PQ|89i1i1ck1TLxkXy9*+fSIC?Huwn_ru=m z!Myk1?ekkfT>p=Y^6%Qj%vU_k8n<^8u|E=7{m*4t$H@M1xB87|W3EkeLu+WT-aWm| z$0O?L0pf z6YS9{lk+@fom+nYeX4ep|+xZZe5Fu@cTSJ)?ggOMM!mt+c~!o*if_MfH(Iga~sTJrFJU$ODl)9C z2VbJa`I1y~e^a7~ks*F`(p{UeDB+sj`_^=B)cMqVnck_z**DlTw0gW`);V+p2`se8 zi7P$LP(6DuIDa1qAKE?YeEH7(nyj>9Wi3;-JKPbxL;%^t2W zLzUNEBk~h02a#wCZ zK;{CQhvSFNW&=(%2D=$U9{A+vw*J3grh|P^K3x#=piYYsdlPWUa=A1<*!Ag_I&epS z+JW{XIp3mXcKb>3-mYAMKr+)-=(;OjDu1IJPdL!I42&%IEZa-fH=F4M5vJ=6lw10Z zzq%wSg-Eb}3De%Nun>r^Z3fEx(SSHxtq%Ky59y@AwkE>W_c*{0oa`kvP3~!ewHVc< z?uU`1j9PZ>M6AzMyGVo75Z9d?2uVLY^%pA@)W2>$SHqpFf(@<9wUExBcV%Uok4<^M ztw$%Za77jm9>xdohXt%8Fy^Z4_nUbAQgL6fWAY(=(IG*fw1@=>Gf2pE zJVcw2t%ND=ixXwz43$S}I&i_HGWTKobnxTOW z&N%Z~2X00bBXMR^w*pO<2s?sZHTbTpp&yNVW*8xn!{vJBa0PBXLS z_uBh&y~~xn;aXsP9~wETYwl5Sd&dm;C+>Y8cT1@Ce>#;Uf!E&{S}`A6n}NM*k8=b9 z28GG%n8`gA!d=`pbDI~Fj0Bn547Zy!^)%W_XDYSdi{#0H^7I|shJDaZn_r$b!->%s zc9qdU76-Js5o9Xx^PWk%&ClXxR+Wc^0>L%+bIrZ7Z@O20=?uFPTqZ)f&k6h>>^*7A zuS|4&yCnR5pMQ2}7Qn50qzzl>ohqTilo)tyPkyYQ2@~TI7@xC@A>!U&zI)4Wh8n2N zzopkU6JFc?qRwO4X6r};_A3f`MV}^hSb0C^%(EGN9q`#T&;qIYFrI)GSod^8*Sj>X z3+LW?F{#_M->|4=UpV+Be0&C>GuqlMa4YA@Z4sFY9{G#mZ%4d0wY;$Ag!*s^40$Zr`aq zs^_a3XYA3ORv&rIHh<^u9{oxtx4)csWTzI;bPE<|oF=#qJlK zq5&9$$Gv8T1J?x@Atz_5`>q9DY5eIa7@TRRnCfLAB|Dx(hYek1c%G(4D@-CpzzHNP z7wJ6DXqgi$Wi;n46{zS>KAc zNL$?SYAAmU7H@?ajfe}WuiBn(#k&aBm4XN+?nxHv7_H4=GRtEJ*RY>e=7Jito*tWE zQ)dx2&e#(jj}B2vhceLhC3T5%o-7$e494j&YvXa=p{bK!*m6@?C3iG`^I+&AFy`LB zb07T>z>0+TvIV_$78!wYKW~K6p4LOgeHtGECU!~)yaGnl1mVt8ICu3x- z>fNWR-$4t_-8Q0EZRFCP1_I0y(ps-ixNBQZ7pfm*+ZudI$0cs_Th=zB?^V+t<~LHN z4fB${#M(F=xYOmyh4N0?f03_N*yA7Y-o#chrB-gXzR~pf{*z#`b?+pNNqtep^I|Up z@T`gVC-Y>^P^6)Gwb62l-|C!J|Lh$>LvCJWYK*Yp$*X<7)?Ji? zq9xmnBln3Gx^aoUJw(Xl7BJAWxk(}^^v<=1%_$I#Fi58lkx6|lI7&}Etnmt^LDo;GVg z(<#q0wrRE3JNAQH)O{NNRpQ!DD=6e7wOlBUcUti<>uF$K_dD<;rKM!DUz#bE?K<0q zOee*~s`ajmy!y!A6541q7y&F6)55Prz=RdfzVUNu!+t+u38h#sZs_}UStvxd*=@$* z7Rz9EFvoG6O;OjPaxU-WsrVH7$p`*1JLl$A3_%&MUK%gKZf9Ghd7p?XU;ch{0)A4X zzT!2O3lW-*w2QNNf~vpeE93;E3l}rwUgBp5?~`ccN~_td&AecMsIvIZUsf8{_;W9T z2K~s|N;GP*&TMn%M$7sV_T)4kMS+7ft!BZ!{Rz%p5qCv*xxVP6dZCmdiQc?VjUi1F z@aqD#mvoWKj(*?JXz}$a|Hp+@3yqnjgJH3?kk+gKw31`qD`@ZvC{dI9 z%ukO0d#Skvc<0&}%B!hbYw|dWBl-}m zS?-|f@z}v>)3U_2b5sZ=oSSU)>S?VY2Q|2FR~BMr(Q`ppo5@wtOO8`CSs}ukxz1l; zAeVuD=14NN%bA&Dw+#u6qHu;l)S{JXp4}W}{>z_zLk_b%4{{$DR6nosoDV~P8$VK{ z1!@U;oPAjo?%%m^dxZQLkDO~xs%oG}aC2%6geq|cCro5{lD0H z4`8_BxBWXpkmx0P?tzM%AiPd}WEY@1f zyZJrO^MC)(JMWAcGduPiXLirIzxVaIuKSxge-hys^{PYm=1h>|JDcw^i34riN|5SN z;Bg~1WhU**r5``oII@^)^k#JC$D*sKU2)R*=Gma>ntMUY^7Wn)*^RXl)USQ?n`cDT zDA3l24d~uRt1u&)+aaVxAbUwz%^=kTM%O|7wmaSVFFV3;k1St*%kD`c82)?gLBXZtQ)&O=Tgwp_OZ4+j%?k91eu5E*%sTGsYURWk=L|6CRlQT zel}hE?rP%O_ee74cY1-RfAxHy0#7nD{A8BV24oCy!2F-)lCKwm?Z?l?ahg)Y-I9GX zfXf7I2!+sNSQd5IVixHj=Wt)3>22V6gkBVK&Or36*++QJJYK*|cr#d4%HmOOw{?j? z?3&eb{LL3-vPFPn@Rtdri_6QEnRjgQ-sgs+wQ97Q46?wJn4|dGThS5%ulZ~XYz)Zf z&IkP|DY&C}7Zo+#sKnhYahwAaV(cMf?g;BiOeLQ#m&~PFDcJtnAy@0HtuIwbh^zH6 zy(sz&C*&C)h3uxDjo4S@XaI*gH>T2r`ckZiFQ#C)$eZiN>`NEt`nDZ@-q;J~2|n!R zlMJt#M`W4*fV8a0(e4UTWe+-ti%R;$XLLYXU&y%CYSwRZu?pklzA+%<#SppzTaRP- z({~+rc7lxC3)sC2_ITvq>dDw(rIUo!gbT4(OC@E$-7CYM1HS`Wfgg``m~JF0VyZxn zxjqa}P=Afwp{RcJ-O1ioC0J`KVktP#$e8#17NV`mgjdD*4&nR8Fhe02?X7NvynT=9 z4gKBf;Ws9Zr}^dlz!CoZX}Bn@`5*9jil5&`slruE!OFpw4>a)4o60J6+lu+jYYk!M zSrU&5ksHK3q01C0xOrrWuRtEB@Lbl%Xt*2Xwu7j-Rz+f3Xp% zX3N-*T!grNU+3QPJt6*j`DP#a=g%7k^YkW|_Xo_TQQQIPVNQ-@*N&Pkfj(R5j+k}7 zfl)%`nUD$y<~Efa%&Ey3OS62}XWDU^j%G1$m|gt+z#f?U%z9&NR&w#WvEuk@HE~P) zxUR-&d2I%}`=(;CYyI(ngIRFjpukD%9IXCT9KWx9Oe5p@?7^v?O;LAUBO?pxcIe72 zhF9k5ufbBX=jDv;n6>&4i;KQ??1F1|1jmpQ`7h$OQ~eW-=xoZ#uhee;)}P8wOOMsn zOJA8cn73BHm7bctr}MQ}`mO!j&aod(pE9(@Ru6_u6xtyky7WJ!TYbK_jVJn~ zLC~c0QM1+bdo*yz_Dno^|bae+uKeVKM&fn3-MFYZ0dXN?%Zq(_Pc9yi1IYtG#vz6XcuOg&~4Q^!B= ztISn%i9Tt4>BOFU&cP>&60zu1+}(yg+YJq)d}#(<>laA_wyWaDweh7tw~Cn32mKI~ z%7kcW{Ua>q@*#G?5s@R<-Lq1}X|-Xy@Qm(X55WEbfk@|?*7tB+ulgj}%wwNR14sZm zMriKO(NSgkDDphr9pf<(8E#l3R&)KU4|h-?u4ZZZ9vT~MLW>EK-4|%6c3DvP>9wDd zPQW3x0TB*78p;QMN%HCZ&J)t;D`gludhTdG!*zl6{j=cA&u;9G7wHpP;=n_oa&m0~&~}$~jxVo6irl$K9Jdy)5^J35E9RO(!}PQkUhp_#JHHwe znB7s~UxGYQFL>%*75dUo;=on~esmL??jcEkap$TJRfdZ-7C6Cg>(Q*>c@NJX+71`l zmQ&X?yUEaWa~HU)^EFxpTwyXh7kb1BU30z#P@yj@wK?xJ4`_~;Ex1GXt1upQhoC@} z!hM5vQn@=_LDYsV7}4Ev7^>4G92H&%GOu%hB_P&u9~zw`_bH8{De$P2>XAq==rpK?sEIL z$;6X+fMO;%{PpH&733KIdOK(F9$4rxVua|E6>Zg9o!aFukctlXC`_uLCs`f`bV;8< zaF2xVu{d9{Z@M-=>*k|K-DJT>a1HS4M3FvuY)Df@sYV%{@RnrvxOY%+tDHX)EaLe4S4ZmZ^euoult_r$v8c<#dfD= z9FZ?xK8)p7;ybjlGp$m=tBWD4|4riR&*^wtK>E^-@No`Zm(2 zQRHj70@ShPIUF>_X(QuJEIvnbf?ZaVuQ?NwDtEzWV^1q&M!q6yN;Q|okol5LkM9R> zM(-A2Hu77L?LWo06JyEg+oNi|yfHhC8M#eoWy>AY3`>)U9&hX`7e<<9$Uij}Gu0bT z5WcC42ImrF5DL5L#r*D0ihpEZAs(tTO_4@S{Gn8tU5BZfpX{O6R3Pm9PaCq14JG+j z&7RbL^z%@t3p{xBmzr}y8~FCp-@MW!^m?*x^u2}4g=_QmXNqA~aH&TRsPrg!az>C5 zABNgFkVJ0Td#gu=(=nWZ6D2krq!awCE{ZTeB0c^`3m625Dp&2yI+=|5*OJIVl0mz7RygK9|j zuiEpFGNxHF5+C0$lW6}4Ok_$oLH_FZjYc^KJ*1Zw<*)&dh4q0@+Q>2YUv@54eon;1;Lv~3RH#J|wkgc`DMe!F*4IcT zYM#S{4UOd$k1&4OzCl6#8Q>+Wb4Q7p8s z1t`797Fweu<}&7K309%Ff<{C-Qr&!}(6tVbsx>b;urObK^h_Uz>)k@31Qnb-P{mtA zj)|VfO)8{An7KtF(_nRaV&{2r`saf znwFT4sW28Wg_XfAZ=C#+f_Y3|iK2qi#S`=fk}Y4VzxAZKv+dx^8`oRshrH7S=~(Zp ztCZ<&??;1^%AzZMO)Y&J1N z&AH9lRl(7R&ASKeWe7b_SOnm;i(&ztRMPv$6DJfJW0ov)Y(IUt-2U@K?8+2EnsZ?JetUWFi@s4>#v@g`M$*A7eA=u-$jd3`+ zf|+Oc9Ikt$1%I}?jHspOXLL4<18fqdUziPaRXek7^PuA8)x(%@@fiB$SrU@itafQh zel;?79yNAZzqPfO3aJYW4>kxzLp;Mx9=`~SUL4!X4a=fxEOzX#VHQ<5EiNJGH=^9l zPJ8p<)vrNuYVw#eGE`0*-j{Qu-*5^_;~Q;%EK0q2G4EzJSnqB{zO4uTtTQLDMWzuO z0pR@Xvfjj;qdf#Pp*kp8X^5DasFW-xEPlxP+xNi<>qwycYfY&4-cy0kF0!APwjJN7 z+rSi9qbFn!oXntrQmBUF+=~X8mUkhlAJI=a^Fa1luSlT1(q=xGjGxa%?NH%2#89kAV zD6x&g2zPr`7$A9ayiaP#kO9#BgGDB-8zs_eVL+j~q2%=MQyGm?;}bn47PZafzt6+k zPeivmz7s^pc_#)+cr4OgkY6y|JO$&N_y-CesR?hwbnag+KR0p00=7RFD~ZI5gBPM= zghcxir;IZEQmCnkrWnB#CqUNd!%43euSu&}F#<-EO7=w;`h2oKRo zdo^;EOD~NJ`0Q}bg0*=t-T(G6$wwAz3!wzqYTH;%rw|&`%p`{gHhLokFMfO?bl`Fd ziRuv(cH>?`zU9)CI?!P1&L7{EXBhc-s(b4G<7$#9z-gT=LQN?kMk>Z6CiE^_(|-=* z#eA^n`hR&>{#jVk+X`y_m!XBq6T8QuP zhh%lkC?Z_aa^2@ilp0YQUDyOr1m0<#`0!pdC4bayX4dVgNbO8sW2lt?xt>yVmh}to z+fVop_ZC3iomb{jxc5Z9H*BzONDF_$?*DA08@Wxf6vkggFlSs_w}|p^u_jz*LO>}%uSLx$VKfQh!h;4~2 zqbKdx6Z~3Y_QgYPfyc+YY?biWel^fNw3gphZnzJVd4DeQZ%#k5?s@B?WzB?B@40aB zI^f#aq6|*!R%W1w%sK||o_P#Fffev9_~ONHB;(-)GUh19Pj* za=m0OnRx7&JRK-Tft|`)al4!$#A^Cjid*hCvV`ZJvbE7?XUR@y;>0{(|1Aov8fH;I=jP2O3ufmTN7bf;*oq4BB)SU>Me@2l_3_^ zg#tq@_;fe$6wAGFbh7ZU(MX}sFVq}zE$#8i!zmr*m^UBU>(JF7PJT<%eOq@}BomgR zHAc%{%#{|MCzVFsucK}t%<90+H{r`2ZN0M2Ytl)0QFr*6vFD&*)n7}6fAc^jNhGpG z%pQ9)W0zI2?>jzyw$ZV{FiA$v0w1H^?&H4zqTY7EbWr4d->LJ+F8GU6@#8{@Pg6f@ z^UJXA>FI9vq+tCqDAZe#>PlK_J ze{tvdjg#F2)f1K74!-aSM$FF%^v@yEwsVia(c?iEN9gK1e}D#%wDco?)~=bg{rw!P zi~O4lXKb&&5dTB2HX1fOm8&2n*rvj%%OR~|{iJgJ9-*PDaqy1?e^-o}VJ#d#%Y=stB%kkns8TDW2$_d9 zGLlrb@t%|iiQV~9vx7|>i9DgBuPEYzW>fxMm6%@RU@N< z3ihsv?tt8)60SO|1`DnmXz_xtv{!@4er>KhzFubfseMqoY+krz|R$Kt3+Zo#5kpGlAqT zLWzc96_DSQySv#|9%toZQZPE?%7+Ox{bLyfi|Hj2qYW|l>MCUsrF=P)x+FtNSS##m zjR-o~e`6tvp^P{u+T!ww;x+dH8BK*-I_p|;y{;HHF#@foEHSdc?vjm=TWlW=@x_jD zzs`koX71~#jo82o>~0A)>|=r@!xkmGvB&jmQTKF~lsixx83Lb$FI>D-;_y?_cX{@x zYYfrt)Lk&qKLw&uSBW{2QJE{QhTj&@a91wnyvay$X5WMec0aBpc>~}rrpAsKIM-_C zJJ^o++1sb#sjds){mOMcYn>ULqEZmX5jo3IR^Sn|PTrzZn4-Jmt0j07$IgOX5A_v^ zj?nx>I!T*bYAM)xyi$m>H{)fc5$B@-@a|mOq2A62J=cu6mVQCZI~+BUSoEwwcIeC+ zulVdgzjcz&Wj6kCcny5wM#T}oKmV$y3IVa|L&bEms%Sq=&UiWel(>YH_Y0=N zWr5{P{_4x&!?Z%XCV<-_3t{*9?BR2Hbh+>tQ&Q+cBx<~BN6h0av)Z(v83_>vzm<15 z8$oC@zQYYP6v{(JDGT~;E>7tG{k>~sCbwGj%N)yY5pc+KqbW@L?xu<)JU97n%;+d+ z<&%%JnY91be?a%~*Btj8o8j<^+Y^jx#$h>=R2is$wlVy}8PrHZILPL9a`X~Uqjf%$ zAEX>VK8~6P)M0uu#!*WLjln;_*9Upp3-xxYq&{WPlls(Y%<3)A{z%0g;(lU~*Kv&A zUaMR14Q&TD3F&Cl({fQ%xJi`nzY3Pvj$y6TRJPv^nmc9fKhN;hF(k_iShc?hhbjs| zT@iJ(`4|noixvnf&Fx#-0gVBf{C;I*y()5)X=dj9x{a3sJ3vi3jXvvBN3f0gbam}; zbZq;_y*bropyV$Zck_k$Oyw&Sp}54Xn8?!2GXM z)3#~McD=;7b=xSQqlM@~8go6rvxx+BG_5r7E!MkDqr?;>zMieL_Cw|u9cI2wICavK zY@;lIr>C^Hj(Q0o)6jcjGbkGSk-w4)BGp)j!#laaqp-&WE4`xEND?kR(*ka+ZOpt1EsO- z>zK0dQGXSEm$zs;(BI+m`Ky^^Yi5zy47mSO1M3)KbV(ZC*0L_YXed>e>XPux9hr^q zV|&pX1Z#{D-v4XU{V%t!F6q z3nmK?^?jXKYzoKdp$IW%U%%K>g+C9Xz`>ymvg=Dqt#yWxa+RUQ}ueBHvv8rn;ibuN`?}K zUX|A#DremIkfLyFS~e*3IE&c@Jgd{^k4-^%BP(4hTlLYMWvh+&+X1ux4$)^_2PHsd%`Hfe2rnc2|k`&o%1t z!mDl<*W^uUB<*X;87J*ApE0}Hq9wk|(^Bq%T@0SBwupZec7OIf=u_tDQxoXvZHnbW zZSRF6?nL0SxZTJ3HD2(k?!QeZb9DhOo592LaybBxfCQHNV`eHK>hdkN|Iq^GQ!LFo z@Jw;XV8u%$)KK%RqxC(;5A)bDit@2WG+NmntFI*)Wa6`LhFY6wkK22W5-e;TN3t(Y znLEsyMThZ7AJzVC@f@cj10zqfMa3A#vcv;6$?{DRw<&=&e*XD^8sT@xCFJb~Ps~m> z35ROE`3jcXH)snW0hfT|d6G`z)4Y3uh@n85%e$G!zGB)SxZ74ptG4Fh^w|ll9%2yJ zwo%Bhr~Luw?_(;m$y>e17KwEOULk~w1PC3-xn^>{P>9qY<9}Z8!$mFO`jU~};Tu{P zb*~0vpW5RGCv>-oBX0MyXvO|lTQBM>GnUZT#)m61gSCy%?7%`uK!(#_9>bgoI{RCy zqI_A6TY}Frb$6#2iq~V^ME34+d;$s0$7h`Q0BDC1P*|V{u!WLXv z-$sa|k#IoE=66RUgLk#OWW}T}TMLg%t(BYuNnu`vC1X{LGktSnR{j^&{eZTH4~{H{ zK>8jb*0~O9mf578^~NzfcZu{UPZlxO21QHoS2A zM%HSiH%l+DYO$%fW%KxMCKaJt-@g4&DR=RFniZ^S1}zVm>g7*&B6@3$E-$X~v31rq zp4FFb9s3aAi^0j+z8#hQI`*>#`{UA=-&XsB?a2@^;guk%C+op`*KroJ`i)}0fj>qD z4pvA78?S6zuYloaIlNPkmM4-}zAb>PE~0~&zbS1|9% zhtvHoFY2_q@)KvU#JT@6$PF>+Xi0yWt`-h_=PW_Pr`;h*&UO^5E_9jsmYl1??|x+? z=B@8VPEi&O)8HmshC9Ij>mggi_8F=NC5NX6x{)FESd18{Fx&KSXB#zOjLtg#Z3d-q z;I^iNT;36RF>w_RHko?+*z?$KdRlBze10Rye*`E#?M`YYRZ!mWx|V7d?*@- z?u)m!Ss<+n`ldKn%-A!g<=2(snc(`XMg6fzb9C(I5Q@EGtd!DIDd-|QbYGD5Xzizc`G8^$Rh!ov!ryqY0!)n+e+Ck=FzWMU&Er?!M>_ z3B}sSwSjwqyl)C*J#ba{I1aHB1vFt!g31^((&80`c&rox3oH1ZYVm5|XP_GP6kl{_ z#*Y%(*xmpskO{%b!M4=v1aUn$1TfBv`YOlEm3!1yhW|K(0W6T5T*L5O!M-<10p`~B zi5TORr@eRiVP8vl8Zp+BD!u&Z2=R4tW$;D5Ece=1;kT%#H3~NsfJ%4AU*!afJW>Ox zeEyppGs)7B=j&q~CysO2b&1(mN8sa8ljS4XQ9n)r_O5iOY5wi$l67NGB=N3E;OP}V zlt$j)a(ygF@$*rm^#z@b$5zqL#_&KNU%9$fk7pc<@Uy)iF=GAkA>|Y;es>N0+ar1h zKzNgMgYV4SB?o^biApQtUFJkm7SUQj)HYOm8RoaMW35Dhtjyb-yTP`KZL$(Pn4LGz zq{e>P^Y?=?wjei$-_YBY0K87$8dFg!LT}}J^QqNKRh@xGXCe;36iq^%J6!lE-3G&f zm*QnZq!^UA<#5=-es&?J!*7IEMK;g^PN&-R92jX+-Sg05flu zWJaRuL+RyQrTgk*P%ZYIh5NSb?r(uQim_ZB;%^M)z&Wdk*0h zMu*@3IQp)MwE&+e;(5PBve|XBjqbYSPz9zd|n7D&A}>UKT)-B z<0wSBoG4IlIjz{z$fyQHyxy?~GwD*NW97i;UhO(Mhr1^mu^*a5`6hxg*{~hu1Ar>8 zd_qbl*$ZI07IA%AHz=X`1xKt1^i%x5uJMJ!#{L^oVWhGD@;|6d1Kj$1k3HCI!ude0 z_Fzc18hZF+-wlciBx<^pvVR{hsn$hej^ijHi4V;! z4M+f(h3ngvbobG_o_cVAn@^MK@e%!XAC3qn=_s(j;b-ktsPM8c0)Cu>*xP!tE7E!B zoPj0W^+HD-fv3=;5yEPPfHqe#_xW7Jfo1-Mi;QbeXfKDa;EOmG9oW>8z`TRfo!Kz9 zgs#jUeEG)d>M7d1j<`V!B7Ny)PtSGa1*^*Qm0AsCK1DT2xQETDt>f!kna#R)pO2e? z)M*F6BZLLdXZ{+S1CfV%)&|J3ih}3lzHaYFl}@_SB*RyQi zLUlEx=Ti3F(Rp6&r+GEz!2^j$`O6D?3`7pvBI2Pt#2O*=y9H6~aTJ3kctfoZX;jsA zZ)+BeUe`s|VPzpw!&5vuorBQ<3aW!K+2}lc%r;;I()d3)t^Zm8GCN1jhvV9YlPFAQ z<|PoSv~hdbkCw7ePt#5xd!(ZdD>4olWcN0xny?EzSp5)R=SpXNC@4}jHQ;cIdRoX>p_LxGv}h%Kb@uW)?Sw`6ceYj(7LaAYhiY@g+14NHm(zca!LL5m=q23M0nHt=tu z!Sf1U*`oV#=xcKcRQ!Ll(6$Z3bJuqhAaG559CWBu7P6A4F_f9q<(f0?D!pFle3YFW zdT`WO@nyukL1Mp2vcqw-soXjIjfx}WxsZw1X#>^~NMC6tvR!<*SOdLYGe_Q8&k`iL zy9NZJdw=C=7=jdo9yhh{#17p&NVk)7c>s+_A$fy*etUD)7YM>Ukd(Fn zcC>gbtyf&)o;XXIaaQwyMV2dW_l|)%aYAz+$zAd#e}8Tdp3l-!?f?}d?Jc2p_a=fd zMkKYzdCNiQ7I{`^wt)MMxQ;^o7GA4rSupDGa?|~8#Es_!!K~G}?P*dfeNoPuw@1Bk z>GJ;F8GPVNSU0EaJ zhN9;5{~a#*=S}(r377GcrwD^viOj6n#yVe&SnzI9QX|_-&;2$09izm)#rEM2!Q-7jwNfGX11#R@xJ( z8}Dkb|5^s4qBj!(3(eN7-n(9tPDam(fryD&_oJt5Z}N4vY|*^!aqtBZ2)Hj;a_1j2 z%QKy(CUYDracuB8FuKlGE?XC12S?Ks>qcXumS+IpSn-H;C{#UMX*SjPw&NCaUqs94)IBwKEDe3RYZO1^$ZI+#!yNGU4V03m4Wexd=Ei9 zT7vz@zp(n*0=z>?Z9#OeG&6Oj|M`7p(UO|G*bwfyZ6*d0t>E|EHq+-_l$;+n z`sp;eU%IX3t}z6^WTWMab*4yGGmtW7+#JQ^1t_k9d6k7kAqkvZp*@PeeCM^2 z-&d_q)|G``aO)7FDUD-73nn_d-!FQR#AdC0rOZfiAfOM zcQAi%E3fx1CXtWzW%$f0Klg4k>1iV3<<`88PPc`{(@|ch8*7^4OkaN3tK+|~6_Rc` zbGcVO7~bHhh9nlD2%A^Qqjf4Y__M&>@*J^_il?r;N5bt&X{T{Eo}cN*e-ZceX&1`o zoyGVl@EtKrf|?O4ug_uz1%4iQQ?stfvUB892*etfU3F1%eec~+BDTLOZvda?r^M8^ z2^Hw#tYd~|c9UwPIc~zm`5w3@4zT5aXIYpKlxh=u!D5Hc7 z9G2NLBYv>Rqrh|8uPMUO4XyfI2vxBke!yeW(K$ zZ@{M_(C>`@Clvj!*m_sy>7UrV(NY>=Z2gbqE~_f?w~KXiCm;?F#;de1B}e}*qf7l0 zOVl`V4dokYrvK3b)|09x6uVw)^Rq{=w^@XzuU;@zrtPptn7fy9lUjpZMqba#kj|De zDm{G2PF(K8Mz>Qm%iQ=8@(&XEGU|O#|w8$3g7sW7WlT<-h^6}x_F8|yV6B= z*E^eEoj^HSu#WD4`n2E4@QLz6e!hSUO4-)5Ckd3M?)|?)A_bXV5~`7;0G&wTKYHmL z`DT5e2dWnJ!gF5oJHed3`RS+K0M(%0xRE8js-KEIm1Uk`%_vScT+!A|LX_j#qD&JH zcGKoUOJ8B#Ay{rf-V;Pygk9U33SZRwb`J8-`ce*vXbdH=Hbs|EbJnMiM3sk7@Xe0? z)y6huS3$-yR{Cj4dafzh7ayYD0<0o9oD}rAVTAu^G`$E1w^ghS;1TDU^{dI)5s}bO z*shUU4e?E@lQ4}5P?CzL$+uhPRzdlXseptsQu4@B`>>~G1iYNoa1$Oz=H8c2Vks+k#vUkJN4L~xRy0j+G!T!(+*S5Zt1_Q@^_KL&}vX1;>AIH z1O^p-5B>dFSe1oi@TII|f#2o%P^zl^a?330EgJ4w-nyo zZ#6pvDLj5`n-st1BXOP&0(^PV^)7~K}>RiatudN+{r1|8d!u5{T`fP2iix}= z67do|ir+vAmpU9(=Ihm9j;gjLb0s%NCT1VUO0sr#E_@r<8T4ij?o)OwXx@j3qY=MD zRSh5(tPO|#pX7YW${mq9i9&^R#Z@-9wGFSY>gja!pUnBXC~)uFyT0b9kUa>{N&EbZ zBThGh>^=0Q$m`EDzPma$afm~K4Jp9BF6G_@imPY?t}&O+X4MPSb21woid}nK2og$7 zAs;8_jg*E>Rk!6nwf)9b{826(YisIvRp<-SDp~qSTn|=Xr!O>P7xu*DYS3XNfVhJ7 zei74Gm|QL_Wl#WpR^vZKkyGk<9&TW<|364q`DrJFqV_pRA8Vh|m16Zws}@d<%Y*1LQn042pwa>tdO(KK5Yp>Rc2V|fTdNY=_32{=ly_O5M3JPP z7J+MR8H@8*_C#qxn~@XdW(L(hi>BHNV(zm`ZP(Z(u8ff)52rLiGN6-n_M3C2)pz&O>P@{7!_78-h)a~ckCfVv@x#>=CTE>{&5Ye-Amz0S=1UQLSg_;`>Gs8Qa*^mDe)FeWTM~GWi|ENm>T9Le zBMLXKMLKL(-P>Ep1wNEm!tdSY>WAt8sc+~72^?Q@1&YRnqu3m72@9v)yz2wn?;=N2 z$BaW8OpczWMy}xZdzt~U7V)u99qmpy`U&}`Ene@*iN@4<5(7sBW}=) zMlj4xn9=fV&iJAE?La^}{CUvXpB8PH*FBjtE3fSTHTfdpr(Qd=#;uKOZP&mfGy%jy z>60j=9d~Y8$bSc$@u8U%XLW53a=?_nNyG%xl2-AbsJ7IlQ=rV>bih35Q!-Kn(%~wv zBcCSc;pc)k9s5}_{l@j~5FnxIM#{;K?W_Qt7e55W6x+y!NK|T<79uq7XVI>lQ&hIy zuAT2HI9desR4y?(08XIr%Z-SNw2}0>553KE!Lh9Fx19yJXWN|jNk?3W?u+~4rksoW zOKoKPPl~PAoDQASOZ*sag2S2a$!y*;UU6Cva-MQ;ztkE;fEu7%p8{A_Y*o)>J8nOu z?g-kmVuMf6Gop<1rIVdtvZr%KA1@@vTdA60O-)Z%c${rO@Ve!oV*W}9JH z^j}D=8cFJ_r4_@yFUw@|KKOXCN~F=9cK;Y!`NHwfxD?d)?HdsC*VZTP5zAI-veFNO zC|V0cKr_)s-MoZw;A)FwM#IbF)BlQqo-Lz(<&j~N@O}r59~6M6C@~)5Qn_X~CtIi~ zw|-*w>2AHB!YKmcOY;>tqFj*Ia72cDx@c0$;JNiDvfdf(KNx&UU=Co{-$-lh{4Ow&6;ANZ=xG*W z1j~-j3={oF00i*~{H;)(%s^<}0dO6U0 zwi+7^9aDgSo}W&J@oqg`)Q_HX4!@q;Z`Z=*70)%*&TR|oS{Ht@m>cdr-l`D(CM%SC)PqKl!5$J+|mCK-lII!6^Bn;~Ie}x^g~vcgRgH((5e!hff63LkrJbflOQC zD_hhEyc!8c`nNaV+&iZS_xLetc`BW5vM$`+F!(X+ia>Gx+`ZU4zXagR%CQE!4b4?Dv-kXXgX#S<(ev7G;kL&}twT0AyD8wEv&B+S z(ujot8Rn0&QU3bkvtzltjDPqLSaAF4I8R9cxQj;0cSsyBP5%9tV-3u9M0}bDUCsRn z>Pw0gw)pku7VSt|)3~TB?lRY)oiEl}u*iJeb_oYaR0H@b;a{6S%zUD)Zv-GzD$bpg ze=fhkA~iHB~JAJnA&~$Z6&Xh zwpf?Hm2j$mMn0PP8=vu~BNiFuqm2I7@7&G)sqXxu&N)^3*+L^EI_i%fDZf!aFH4T2 z6i--yvFle`@fYiA(dg=^f1@^6HznnstmacM(|){!Eq_Q3#uC*72OFDCVT!6d()vim#&ktXWC zH?P;Fg}DDCk5bIjr1XnusHKyw>%O#Te5WSNQLntwW1Lo6u#Qjs`s|w<*3cF~_peG0 zM*-Ew`Ol~bJb}@}QOf<}*H~zvEAQuRlUZf-g)IGF$;FOgqQM>*4^|>(nzn_ow!s$L z_btM+UGJ%85-0!7BMDu)tD2Wzv(mi%XxA6A3VTK{eGvXxCzY|E$@nT&_T4+3nx9j` z?fz#8Xj&I(kD#8+OJ%>i^C}-#1KvcI$g|5v)S(8*qsNqQ3VaRO8(Mt7%(B=&EgAO# zjFCjPUs$-UoX4tMT`tZOpgWvooAvJIPH~%_Vriu7PEi?LGtUgN=NF57&@qI2(xKxB zmphF$&F?J+jry9ts{VA(H2ra)1@NjPf5$}fd;9I$kl=AH1X|s--ttWHV`R^if&jrE zY=9Tt%__WbKfJ_T7MrKsTNbuJo{vK0T`!!Q%dpcm{FmOj(|q^*GcaC;w(3eeHf|Zd zoaDt`)UO0Ijmt=DRnHnjyw!s!%eh@ny|FT9(~rnJLBI9}@{dHLo3euz(vwvi= zpewbzK*X$0IElOWBkynHX0qkT?9%Q=tgsBC^2IQVNoq~rf)yNuWPa*)h~1!j_H_6G z;}*alakH*!?sw6kAdbGfoFO}!&w4O9bO6Ld0<=_pm}fXUyaHvffFBja%NG#6JpuvzzpOF!-TqeRTX$GY3${Zv(o4*M6KQ4PIV={91-%xn zwV4&r7R}0#0QQ%WA5Pn{QWN>;wx>YjGgO|l{mIz z`O{UK5TsmdmFGq=ZJxC2$0?KFw->d%5RNf;dSFeGcQT|`?|bN8E&bbmW5=3Yyf10j>}Oz?66E&h)*r+e zYNJ^1UHjd^wdB%}g`VU=gwHV21g2HB-(GdP=-T@dy$4wGnqm!iu76qsYdEbhxI4w$ zP7L4AM-QDbd&5+YIuoWxA`}d!vti7VJ?xmxQ1oj9se%H`H*l+ay0Oo@hzHdcye4W_ zgM6#+|LY-z^R`pn=+)r@MIm;@9jALz`SVWTgN}{mc@KVUvvGNA!E z63+$gSQc%2^F1_WyhkGnJ6xz8eavp0L|6^gAUpH>!+RAVy(YWsv{IM)zzXMqcwpqiR+`1 z$UJn_SN$U?MW1x!Ee2(BS$VI~Q~!%gWRNxP_Yr%AOr8=K-&etT{I&3Zw1BVQfk!)d zyiwe!w}RO7Qy`t5V9yer#KYY`9)j(U6N^v7M_HKg!GpDcRn-J3x)&EoPL_dI+2Lev zrV_}k$Iz;FM-s+&^Iki7R4^~Eef<2S*_kFMg19XIu0Iye5LfewI+s2RByZp=g5L^F z!1&UC`Qi8u$Q&TdJ+MYx_TG->Bk6&>^^YgtM%_mPBFvz`zO9&4!MstjvrK7%sS8x+ zQBBvL$9pizNn|aykyvi9p8EC@Qs>VkCB5^ zORGODJ@-&APRI8X8eomRb{3VnsA4|y->vS{2zL>-_v(^fyJfJ5H8Yz4H|%e)YCRG< z1}>21OwM~*I?ov>`a2J6MWrlO2eEjf4!W8!tcrm`1;evozdhLxSG9BbJ)ptMP?xJ!BBm*L2##zL((9x;+sP*FbL(~m+{78WPj1ezMFJ@LRU^~8J+L1-wROiQa-P< zjEjNW@{bEfvROICyPIFXYu+%-aMoX2<)cW6ZW4PU{Ny1EG!pSV(OQrgcG0)7- z<&Rc_yjGz;B!Bb7nx7hlm0Pkf9P2dg*C*EyoqYg$-El!Tgw)G7hPLAGaH~=>K zw$I{I$Mz0xtPEGacmxobqQ7h&OFT`?wyDMJo(H-i=D{HQ88|OV9Xfcu9Ac`?EZMpb zJ=Tv?_zOgi@6T;yyo2$K=Pqq8S}xxF#&;C3n?x1lH?8xI3oUP(Ht~|kn*L5EI4kis z;htt>ubpYqivt@p^KGh{XQg!?syiexAEzlj9GXk-w2DGY({o?TfVggQ(^A6qRQtz= z_*d(m++zhayQqg~kg<4wURx@$lcE&bBL|=#_d@rgucc@I3H0B-Bdk%N$b>QM95Q;! zO{MH}4lUVVsM?~_?*(MTNbF#&_5}ticSX8nnRUkj z4YCmvxYpJa4(>eH(67P=!>p~~%Sa`hyIhdxz(2 zo9eXVx5<3MxiiU<%O_Bop7q_hB=(~1BJ=NJMr*gYAG(BCKu2~CkDfpi6|fk0u8S8K zyn*UG%Nxudv$H~WJ7#|<$rr0|+po!4^4pSf$@dk5JF-VlYbmj1Mi0JVnViYX9Afnz zKczLlLKqr^_md7vz+kcjFCtRgzs@AmT$+sO4>|?aaf#r(I!*?%8{;W3wTT6kY0JAIctc73WXkA5GF z9D-gFGs*|e{LcR_ocGaiU$CPU;-MM`6S-`9GUweNu&xzauIG8I(4r$Qulv{C8*(6v zFm#u-D)_mYw`n@&L^oYxgHkxo5ti+&Bal5`)(HhSy4(EkJ~g2sFHJIJ!{S@`Y9dww z)`15KJ`3}qZ^IV_7!RMLV1iphb2_pMX-}cQI z4cTAbhqC34#bSSxcm4YROr4}y25&aG2V-ufYuv`p0zcflw{;0GWqOX7Gd*thc5x?~ z`pd*_GSe|oR>~7UwRrt^x>+_{23Vm{pa2uB65<6lfF{}AFa8GlM~!+NVDBBEcb#1R z<;V7M`l8&Fv~Zz_^sZce^!&wUlSziI{Zj$DmA<}Al4^Ibma(8Xb8 zooltBipzfPX2si?j#0QA8aMM*r%jvx>FJ*F^G@`ZQ#^h8RGz@E!W)YH!f)*I9_J!P zO*=rN%zn%AH7$R!hxS77l;&aM-H-6{t~E13e>XYH+a3}C32pr?<~UDomg1q6`7pt@ zMM*QKyx&mw<45}uR0Dss83<*ui;s5J0$}!GlJMg7Xw8x&+TE8``mdd2^|GFxdbFkLoW-w> z(!gBMLUT{>w7p7<9@gB zt=&;agG4&;k~GHask{8$PCfV*QSR~vYkFwf4Q;>%!MmCQ*8SRn>8@TD2%(WAhgRxI z439P=K`a>c>3HFM)AAOSOjU58$q}fZ$OOKX#yxwgaeIw+Eb#bnJSDHBE`V=-)pCrv zn)C<``}8=A>iT@&78!Wl>SYFQ&GE5=w@u;sWLU^pAsLUKiE(ys9zr3T&;p=(2UYHT z33_mX*M6?)H%#G~0qldP=|W3lf-E__;{U^Vv|4N!(k;+mR?;Ztp5*JZygoYzrOF&p|r$MQX(PJNHZcG(h5k2Akxwe(j5*0(hbt0 zATe~ObPQcXBh4_xZ_oRD&iVe%`NOq_C2P4|Gi+Y_dG71F=Puv@<$70VH`fmx{ttYP z9R=4k4okgXzpk)0^c>C<;7?eDx}O`2HvhQJkz{acYz5K^&+A_U9VV9x_g%1uRD`0f zcVRq2ztcUejF5=oK@)ugkEu(?Cbapwa>Ad)?NDTe$G zgT9uhvLD*|6auGeQT4*u@DPC%`K`AP8Y;sYO+3!ajV?!RuF+0>rtQiar)^l~EL|^_ zb-6sf{bg1PduL{i$u1Y2oQh`jb^YuqXYz0zGhyR5;}fT&Eh{~au$0#2X4j=hWf$uh z9}WMWB&5N86LUitQ*6V(X;)pZmX4e^NYZ}$Dsg{hV5`e@GjS89zIb+UdNWTv3)Kub zPvLfYMss=2V2obv+^&A;X<@K*8Q<#OneGyVNxQTp+EVG^Ht`Mf4o@_o+R40g3P>7K z-@?K!n$H0aK1CI|DZz~&EX3>73YtPNeBl=Y zW}`6h?fEl5Zsav<7Toa$ILCST`wiAM-LKaQM-5m{XEnOO+^IU53mORCpcF__0m%U-V+evpe^0;B-d9BsdS}|qC zhFe#P`9pdud=Xh78c=4p~{hyPy z{D*aJt#`F4b$7d=-}Hrzc7JUb;f~fAoRy`+>+B5cLrZUmi!*4y(%o?9I%LLy!AL*H zFJrpXUj$q#j_xk&1jOoF<~nZ0t8O+AXtM&=8cs)U&m^c`urL%qClK@e$3eB+i@FN0G9^;wLXGMQs@6S_Zk1p1 zGI*rLF(HG@Mwgs5Wc#f>DI|li-`AutLsBCs7cv5W*a(pT!va1*CeH_=?ZjU}=?Y!N zOxR!d&kaolFu3@zC8v_vr2G*Nbgt293yIPg%QjF2kS2!-g#aZLV5&nJ3Af}Maz|H2 z#KqC_`T`v2*Cb%ib}rU*!v|Zj(fWZI=D;cK9ge~!YM~Y|XNy#ax)S=%9mpPjwieA8 z@+aND@}1lC$h)-*{z*b0X~~DE=2EsaDzF-l?&EzWHJSV5wf8t&4MSN?N|ln=H!Sx! zgE1^f$$J$Z2PlFeS~1xwPoX8nPoBh^y)X@d`?!u{o@vulsj7NJu;W#yWKV!V~;nc*w3O5)G`CWA1FD~2)SNBTD4|e)1c1@_2kUfdf)3B?r1lhvYx0lo-WR)E4ya;=>bwUIHq%56&Rm# zGt}H1htmr0D;RkbiycITNjpl3`5d>rsy4=~0d9Zje9^4oQ$9EFA~z&#!Rr~(hhN53 zpY_zZ%*J=cE?fk>p=TSX&kvjlY|d@UNuJ*B-Kanbv!S25?xikZg|slIH%IO3m3E-B zp8WWh*gYw5{>*2#Y!ffVe0>bH%U||!u67Qy@n!bu*>(1JcVog(BY}uhbufNOk{Ge%@#1W-B{M(iW=k{`;cu5qE-aSL)cb(hd ze8+0A#zmr3W$pj$Lojm|f;&xv<4JKG0bIKh%Rv`gj6imXT=^%KcTwvSdQKNNZKZ_& z5TQw9b7hherMOAcdXV+Z=D-Kd!`q@Fdh4O9adq1L?8!?ikD~;nWG9rqZn!^VSU2TpxI5y} z_TPMDfT7o^5L;(YH}Ngs+`jzGSjvkS!&Bw(5r>3MUjy6!0!Sxn+%@2p(6)fWr&Xmu zXoSF79r(X9)E`0=ROvX*XWlYS-{}Dfiqe56N~5a#NO(Bu>Ol_*w!q|bs@@YD?CYdv-n1@l&@(Ov0RmDy248&NG>3YfARh$)tI{N-FqT3 z+Korr-&Knz$iaVDDpk=v{{J;04-6{{*9}K7+4gI0*9PocL6X7Vhn3wUacD^N+mbpNf!nzFudq8 zS=IgQ&PG)qtK-Wk`uHafwK%d`1m}J`p>1Te*B2YhjyrR8M3a3#K~tUb)_Chv!#?)+-~#Q{t{%t!^!%=Q-gWORC9IBytne025Tsh*S^ zp*Sl?ayQ%fXkk?%J$o`oIC05sITg>^>d$8ZpaF5abuIAvRYnB;BIs>)PmfE#GK=zh zPyB$ttVC~K!N-&q>}54q35CRt1;6ipCbI8lb}l2dwxnV&h^M)7+{v_04j_Nytx9T- zwTW0WJ>Ny3)c3*O&o!iRHC9D4yA(}+?;cpNYkIJEo#*Q^z zujywA9?5;UX_sHFqsA0BKXLgV8ENy-_<2%hcF+oS|fAg{&K5|+q*8`GO(q~u}B-73b=j1PEZ1H9rX1gQW{ohCl<>={E zwVPx457h!MNdF$guY3vanwg;Z=gxl&alW)*w&G&O1e!FhULLhB?Bj@THIBVYzr(CipsZXb>0 zP`ag4QgV>kw;m3}r$|23rU!_}JuHHdL+v-3T*{o_-a_)0Wg$#?-jN=4QHb)E%WXR4-WZAwF#EVK;QAcZ}q5PE9kDpHQlJrQPBr+o7qveX(^-a3!6L=`-KUDBB{BgnOC-bSj912bQuM7a|7oi4D<)NVFj{p4f|@#x=z*EZ8c9#8ep3+Q z7cF4gx3W@Zo{9}4!KvB#Ot5wG@Ra1MW=E;x0YN$^B7 zHo|-txL_wwJFD}oPwT(VgP&WSv1j2g&=9_5w#>XbrmeCEWrUI03Q7nA96axMH&bMx zNOK&fGwN;r5U6Y_Kh{=0uc3@*=I9m{9@PC(r4WP-x=|u$#bF2*(NkdBR~cG0wF>Ec zX|0Z?E%W%|8_iHFqyNXzbSjT3v(nHSOM2YfSDdN3d8ZDby@RIJRi_C_{FNycJ|_?^ zO%y3wYg};ZOM=A!AoaEJcRfUWR$ZMXio`Me+1hhia{OW?L|0A-hSb>kN3G8hWJbz( zz+OyA>930{bPS>gR?y-!lh}txc;`oHkQ-Dgz7JZ(JO*Hv2S|NzSfMW?4yzLMA69n3 zB$A`_hAu_x%3oa`e=>*$H5%{tjW}bMgUcj`Iwh(}P40Y7LTJ2a(!mkaO)e<-0(@F# zWxx#b+G|JJ8b*ab+D?LG(J{vm8gAd_MFw%tk{*|Exb?Z8Q_6%YMF)1LDZ@V{aY{hRgUR!G zdp?!d7-QZn&)(K>#|Opvw_nC%V1_Sp-kO!C4|)=i#moXK5c8Zu|F#m|EA9(K86Osz z!dhDa{FI&G?mHn+lWfHt4&Gmgb(MKX#g3Mx)xQQgAywNNNT6%nC_YBheX^f&p5eAXw+~xK&#{^tcz+Auyjd! zBw@w;iL~?QPCI)7(YkSA<23!rUZ@%KFNez;rO{%h{9a^(&bao{2uA^hRjHP`Qe^fo z3q8*k+w(ZCu(S!S2Vjpk<}5tas+66P=+D92w7T zTLC(&bw`o||n!*@t- zvAYz-zw&iA9#}(S(Z9(AT9-Tu9GSjTG$z$6%}|+EQml-Uvpd^_e`V#XC1Z+FIe`~C zf{?W!jk@Kv0X-s(lNh5akK@*j{}(yW-Dhz#Ec~BiuLZ-`XRK9=XT@r$EJ`UZziw}3 z>o#aerTR}$xB4Pd>mENP8;sareRkwH;%7OJZT;q##Btw|us)l5Rkk}~$Kc4{!uE0M zFA(=gWx(|oEUWHXXkij99?b7(l%-Jx5^69T!hPuP+dE)X0-xOhOu#31egKb?^@q2} zZ)_24^rNoAyK6f)p?8i@ec5+!VmdG^eRpxtrQ^3IXRuaRjDV&uwQ*1^IQR4*&liTQI0&EDeePennScI<;;mf${89tODHZo3 zq3!S6P&0C^lBu2JGz;eR57? zb$}zOQKbD1x;zK6IJ(sGwxs^A{4Yp6Zt3LC>3+>$MHt|!UU=tNusJ;mW;tu38f|%x zf3=4f@%Sc!s%rC0Gy^wURd>VXP?#f5DjV}JAN`E;tR!zO7h~(@RCs`pHMB`>0NRjY zu{i;m!zlW3v*XT)MD-wEsvC71L7ToL0!b zwfJ|u8mr0LoLm<7;!Cx`a|~17A{umys6;FQTj9V;03>nt6p(#s{Tt&2nsST|NHaDN z-$q^CDu5A>+-}<83U`E_lg{1B)V`iP8mL#Y)_=>C%_fqpJa@=>-J)DP0d!1I&UueV z+8B@%QQR^k1z|KCuMWdELtpXPNtet3AXGI14KYNK`|2e}=BUc<`K~#81FOivyxATZ zJ5$RNvkX4p`QsF226u#K4?2ja@S#_YacPR3AHbCMJ~!V59wjybZ$pV^LT-iC`lT&uzG#WuZ^X~((pT+&Y& zAodAlHOWS2V?n?rESYiWXE<9sMgZ+uV|<1YXJoN(^O~2+0Lf7yY+;h*7>}2lWXy~% zb2Nd)H>C9g7J7Q%{+N^emv?xBht><-d2wn;-ldHz0TsmflX>b@gJoEvcjPed*IQqX zpHvSE_cmeC8OZcwtpwurE+-LU7|O8K2<@b;XN7*(=Jbo`4`)5Cwq3Xrcy0+=gC|kT zC*L2Ga8N?wM4WV-L55Cul3L?D|F}n;hG9%fJU0uG1D(DEwdzV24Ubj}bt1H~ z)V(?8{Jv8I+$%5?5!u;%7^OgV50Sld!96>vo)K>`34yEWJl@*Fej27<=f1>#HA;_% zO>nMtrk&(>h{vbuzW3MUH~MUfBkCBPd)d2t_szX4CXsAMS^~FOA2aHJ6XsDli;}hG z9(Gki)oBdCEz5Uq>F%4nSi$<}KJ^L0yMqokOQ=o9iyRE;;+98Nz@~$A3e8AO3c&f$ z5y>iB!(NAT@VD=M&UO-+QgHY|To$bdDWklos!cB)0n=27ax?|dwnigmN^e1mLX5mB0!wXzqX8zR6E zDBHf^c!1GOcNW)^+Cn{x>!*Zq`5Ie5K>DnK`=8P)T3or*mh1@15bw;g8-I={$b%Zd z6%2%o-$72WM<^mW#>CZf3cl;U*@(eKcze~ogFH~vPo&`q2L@^+ymGMs=6TW`0))`V zu9W^YNs~qIq^Ykmp9cv5AH^4MC++_|3!oYODJuXZ=pRO6gf&ep2Iis?Ra~qd1@E{h zEpTJ#nYaplYsz5{ZUUJOlu3BotU<^-Ws=Sj`+gsezVJ=W4z*wNmF(;Ss+A=7V}Yzn z>emZnF~F=W!?z^!ECghwp6?G#@6cJhfdYZBxj?gQaZPk>pz{i4Y;T`h(Di9%n-}tPzKMMe-Nf%Va^MM^$2R7l;11SS$NVgRJ)_2SwQlD2hkjC=;|wcB8Z4Vy zD?J7y2N{cF3s*OfZ0GkM30EwC>It1$5MsfcTeQ{XNo)GxHf`_jpY4Mm93zuPkZm55>8E8o#4ldgs z73ELGf9Uf2lFPNr?7yZ%7WY_!b zL^QJvoH4g!9Gt`{doZl=`?t&?N=Op=TY1yJJ^k-e(?ZehBZKiD#k0jjHO0c))9vsq z_D|u+ktz}y^0@WR*;~DF>URr2MXvlvO?kt8QUm0=|Lga0apyt7O?$8(V=&tS}LfvUx$g5p@p`^kxTY9+`g1%ivD@qJ3#iIJ^2iQ2MiG&T0(<+Dq8? zE{7)H{U+nk+c!8Qvicl!smIsMA;HNs4xMOY(V{3JRF17M36{M)K`5`hR1Y}|zSUcM zG^1bbl`DU(BbvP^XL1EAAs{*Poq0lnp$9~&HQ+~B(t4?#;65JWx-S~lUsbz?Om-*G zN`V%}q)E9iysti!!lR znKxu>s;(0SKjWO@`>m-J~?m}6CQasRovm>nl z@2q|%_Gc8o@`1MU3QD)#r?vYRxcfnAAV4Q0?iv<>E|$V>gEmg#xc@XqR5CFOJMefL z)Q5yD|1;y1#Bn4zicdM?rT^s49(DyP0IBe5#B~0KocV|2QuMT6;z{5TvCt0(Ec5*plddej_fVa7yUDFPRe@>(l z3FZ9Gy)q9(N(wY%-=QHej7{J!)G6^P$(B>*g8^MXx1g`U-~q58DXohRU}%#X zR5=AW^Tn8JXm!^DNcnl#k%v^6+u~!=(cQpA4f89Anm5Uqd_g*KC;;Tt+(lCGVmv*L zIZHC`Iv9$>)ue`ekgyfie%(JD-l)Wr7ZGc%!?`1;adKjIV;$RO7-3DGb_RhAG^x)` zSRxWCbhF7IsdgC5cwcIkFSy*kf0&g8jFv{n6O%3zi7$x<;n|G~=JUt)sDfZsNlmQO^ zN~R;0+c_i`tZ!HUc*nBit4b(Z?l@R3GVV2M0fH18>2ICj|C^JAX5{pKgrmC6d#HXdqAqzJ4Dh8R83i7N$Rhngnf1di?f{I6ui9 zz!=0`1IDUP2E%h2mEY4%B6zu3y`*&XB632;>Hnf;HXK`<1_|E7tLdd{ zc9;HRR$dTnJ4AfA(?~#x8NH)Si1SG1&YO_(bevE2Q>6zX4(TabY4vFM8aw`vhUeY; zVatYXdU0t*;@C_>D&!gpL(Mq+wX{DlWqPl={_8H*JIfSajf?w_D<*Y2?Km0Sb1FY} zecc5TJVU>jG3V7&AvTNA`~bya-0>z<<7o#@zYb8GxFr*r&wz#yJ?teWN#SLUu&6Ar z6)yuCaPYN|<;!f-FtwtOGEoX7O(HzJO`{i*N5^6K@gmmz%rvS5TN#d4ZilFGm#3M2)3w0LLS2PxsU*?C}>F>TV{@0YA-lEuIKUGqM z;I7)tR9@p{xMJYi_Fz{|Zt)~Sh=$~Y2*-?Wfa{j7qXg9Y8^TR8fzhN2Jy6A*+_bFd zaANs>d~-cc_wX0Gl+~6ii9kSCe7&^P#nzcrkMa&;w3~vZIAEtI((n2B(o08+GM`0j zyOZKK4bOjgzlI)GhPT{*32zCQ8D2+PDPHPHj-Dmg#~fMI&|?Dj#L=5p9wWZGs3Ts@ zB;%e{Yyyzwp2+qM>5evzIF*a7u&*Q^^-pRaGU+bh&1-UBJ7|(_ehqI3+4^3yK-gBf z*mmM4tQXVeMz@tf|Kyd{p>*=s_nLH?5VgWtM^`|Is{v7)V1}#cv_zOUDe|fX;B&~~ z_j4csYVaF`OQ`T?G7h0`f!4xO>{r%lm8%e=+ycvf0P{mpgHK%1F>Ii(jtVAN^FIH4 zCf$bTRyfWv9H^v#!x_t9q--O~N;V1@VD>TOavGWFD0p8%1+&(1Vl=91_iV;NR(pm1 zMA)kD%nXfr+%F+x1?0|01*tD%X*=zJVO7ZkP*9Rzzz!P#2l`5JB?3~7#A2r(pg2I3 z2;9o##(n$VDeh=KfOkd!vk$=P<^VV{R((^aCv<&%oJoFTp@!v4f5WAoFRA(4?X7;d8#7SM;P3x>Niuna)hjhE?W9H>H?*3E zPquR1blO%{$#ljRa1}I*@>ik`J%W-OIDd7mt5bmywUTO~ev{^j(>hjEH*?t#{1hNY zDN>nXYPlMCQ6M`cI4|OW9_D%ddtG^&R<2)IZN5;6qpC=!kIHqIkRtNDs9993T!n+D z*s@+_g2J5CgvU?jnH;_XE!)2&$K9_I>uRuA>Et3u7Czv{WB|||klUY(j$)>8 za+0tG-f|vp^Sa$G$bQN_ULF7X?C7y!;=1(#C@vz3c_JRzEkEZ32G-~-rcD*ssHCl$ z)W+@`jUTW#sx+M$$0aDYt;#8rZM)S&8i?|S%z*;%Soa$^frp-&NsEVt`u0(*hCm7s z8Ug@)5SRT0VE7AJJ_SBOzxzzyC@Mzw#3!6_9l0&Uy5CP_Bm(zQ1%uI; zE)s!sjR(a|uTx*VZySLhd0D--ZPY#Z%`u@4JMN>Ut-TYyTR@MW@Ed79xz>jY5BaZL zRvq+vU8}YVR9!XaH{W|y9Xw;NA~aLfwKBXDNj?AT^x+*_oAD{jXrkHcwB^OKm6;T5 z7PD14)3Cfq)(eGs%Zi|hr=OqU7&~nO*83qO;!7;7nHpUdtdN(w=kgb}o!VE=?E|s)I@4{F@E_*umiXS@5#7v+3V(mp zTu+S(mjcPRg8Z^)YbDQxk#b^<*PHk_J843EOybuSNitTtjGyT?=>C7ba~sut)#1%+ z-aKc(u9C}{cMXFMS9eBd;W`=;Zv8Vp+3U|Vw1FU&J)cSs0$M4V{Rql6GYT%HKavpB^9*w68zzGyhlza4}>U(^d!jpwVi8cF3vng4*8@Ca-BJR#n+?dIB5x4i5 z>erJVVDTW=V-E-L#KD?^V}R@2VU)DHhhU6U|Ap4z2^B;7@^4Yc-o@%t?NJ-hB9Dt{ zr+5|keilaiNwW7IK9pF2+ZbQ@!OM>n|rq)TXeRN9~h&}VYT^|&1r*lE0QEg)?=?Xb#@2;e+zZ z=kYh@BNu8c+$|pl(tz~$kEh~JLqBU9e@T2g%CJvnu`&|b9BLo*ujjl>?1xYOdj1R5Le;+oV}n~P-ap$FJ^a7=H{JOjK|z2RBGF|&`S&aUfKa%-c!Zs<zYFs$RWne`e_imo1t=v)pf>L8@&Z7DPyS^cJcSzlhR;&hTKW0*R((AfdgD=6 zIzk*MiRAQ|(%JMjuzv;{&)*jy=CxL@!EEjdb#_&cw=NyfMD8aBWq!&{MhqkQn`YysPo z0r4z@+Qp}>SjEWf%LAO^iBxV6x-g~)7Gp9$Gh~vFR4bPLt@ZB|T)3s_eY*NmQ}zAT zGpj6ppq?*f7#C+6)ftyeye!~jyV9Vo`gshtw^=>lG?Ch9iDa(^(S zw>i^tGg%}6*4I6r>D_v#t42EqKTk&1vQ9fg*eKMZlIVwVhjOK=g|#=fB$stdbvX50 z4D#@h^%!vb_S5}rjt#D_Z>fu0L!K1LT2F^~=d%}T)Ua2jEXptuv5qjhKX@X@%+Vif z;W3JFu%xMt;RSUD5Ox5_OJrmqmB|m?k^`n-0@0EnR;E(FmF2@uTMLf3$nWyfa9)gm~ z-3`sRt#)-42aJ|32*Z|yT71s|;`tx4X@k=5TgN)XrZ4EOJC&9yAO^xEw%+R~d!oY{ z_JsF8{>Arm;ERpLbi8IS*(mYzGWtV9|Cz3plSiEHF(n^;kZCjbEfXytVLsxunCQ$N z)74eBCJp<5vvG&(RkeK_jZ}FZoOjxa%69z%Ad_P01x~J#k91HhtoW!rsMg`? zWHQU4Q&-Y`kb%|%&L=;a5ncl@tKqSSqWcchD$`-F9f$o>Z=fF$J(1S#?jBMDo0s*6 zFm#_B?un&Fm%WzernZowriOU5m-KZhK@f zVUH)AkJ*7@HfXXAHI8&%pi&pxE@jbidG=Y-3F()A8lNC&5&-Gqhe}g&P zlUsU}8(!S7?9JPY!_p}Q=LTSg?*Rd!5(Fh)fWL9vn4ajclW&i~p(4 zWBA0~=jeNrRV5kb3!DVahQ~aenq8Ok_h6Cri~ME1)k@jl1l`Y89*M)O;nQGBjh-yo zmIt;6?W883Ex#);$Ny=eRWf0}pCbCkr^njFkz$o-AO4)I?wpg~;JG}lI>M3sy%zI< zmS#tDBHntaIn!I{cjoJd@kv_DV77cq4}}NSc_oIxOPw}3AsArW2uxZ*eaP%INmHg4 ze=6<*VW7|9&YA)zh%(5f4Z>fI4*0v=X4nHyAk5Nb1H?H~f<&4R|~TSEEywZW?HwV6u^t$Q#X!@YRcvQQCx)ry09Ggk~EAwWALFM#Ogy z@c4<&cvr}-2S{rxp*znWg=Zz;^tsaVH(PJD#odau2JpC2OXWPp1fuoR7v-*Z_L`Pc zF%o{Vdl`<4-s`_S?zVeR-|m0fFYw9ublnGN0Nr4*GfT($46W7X_4cQKzHYtd{Wv}w zbfF6PW8(cz1X8lKVx7+W*GKKQvrQT-?-;Uf2W!h}CA~dHb4&>cTqQCV$D64?vc(;k z;FoAG<4;sIn#&3So_$Bh^V!HpAANKR%6te9-r={EujI@$rVcH7sxjpc?0?-%w@WWR zulfmBzK+ZO2eDYNg}p-+^Z8v<7r#8ccaYr9K3YcHCDi(rE#{%*hprtOV;&uBU_V43 zcLHqr+X4SZ!LDD0c>U4P`Qrs*_rp;y>o~X3eR!6Btgpq-!3DVcdEYU78r8|Sfe;88<`oWR3>Tn56cmynzCfE%SITIN$b7^#YekF z2AUt>d^LSSuy(6;DNO%yh+&}E$Jer>FSEAQd2dF_r4-7RQEmUj`gcJNj<6C{WouSV!c%{GlzT*oYgx)I!TxKL6KR zIM6wm%;Tnob|pMiRGDG3DwWsW^}hm{cW(Q7tIOm6{xs~r!w=}{{*r1KFE?EP%U73%ef@=df=iD?bRPW4Km6Xbn=${%=Y`<& zv`Zk&|4Dz_dH0P+CJlSG-j5aCSJSz9}ckr}Vu&#*w3=S`Jpv%go^Jeq3`7#`jWwytUmFMi5$JVg_2 zwLd+1ZB#|$v4UvwXvj{?Q9YWdx_m*6{d==cz)XF8^f16T6qc8sK?y~H3+rWhrwn%GxIK%TskhT>J&$<^h!*z} zgv#i{>CUc0?fAbP!}?xJc#ikKMgV94p>Dto%+hr%%-uajBhYc#;Y$G0y483R`J>8+ zKXAL{ZVzYna>TLacHuDI=+?~`vF8Y`y$JbNKXJMLuhh5#jqstu6cjhp-K#UFJHWGH5IaR=ppf=*eRnBXy{Xy% z&)S>|bTChD9_0tD zktqMUZT2d2yq(gWy}ff<54+XyTT`;A0utm~`L$F>!ye7+eaU2NL&8G44LBxWBWgUk z*4>&4(D|db{)ns58NwRh+pqp@*Wtt-+8t2s8Q5$N7%^i1!4-X{ajPCq8Db+_k1B<^S<}_|JpSAXWb<_8K|T#=m7Ea&K!Wi;5!?<*wYDw7NSRn!i4)hMC%s{@^?b zmr9tT_2l|SRywm~QI8rI%KfJxD=2A^n+&YP;Wb$dw_TATWUw87(@RW%Vu54@8FpG=fJQ;k;`r1YA49D;*z!~ua<|YE8toP`E zL}a53VU})UOAfk#ahHQ45m-)OtBO&mc{@lAec$_4^$=A}`GVmqiv9K}Zs1crHTw*F zqnw0Cjt)Vs5^-@e%5p|B5Dr{ZMg2dOU{Fu)aI)cWG1Q=H#rl$?R3S1zxhSq|=vRQo zI0b8Vk{K8^@;Y*+cyr-W4Fa3msd7Kql*!UU1<>iXuKv&o-KsCul(J6G6F%=(E7fC* zgWfz7_?Q`RB2XUyyNEp!g5ISR(#C-ge(;Qf4xR~@+j*}y^avrlY`?7LGYR$dG>#+b zAJ-rqNcM@GsQ0J1+dIl*!4dJn7DI+1a6I4rYAp+bk=F0XDVJb>M;q@0{ifw0!~ zW zjL)0HZa27aQ3$kB*myc))Z^kJJO|Q`{?_O^zGS08N;rE~5mH)2NfNai%7DJ4G4g~d zDPX%$10k1G*{1lKWyIqPB&o{fB5y6N5)rv<=KmzYCeYorawSOv|2Ywus4Ljgb0?Bn zkOnKqTbLE}ybSPB4}n%u1nQHvnMHKubcwY6)b8M4NM7h;2m%*T@>yAxq@ugx$?&q{ z{sH|E&`Zct+U0sIvm#6Pp*ivej?bwO!B$x}Q_PfJhTEsT6RXl$>Syulc&$Mc|DFX@ zzha9q!Z&w0cUr+gNAjtzp;oxLprL*FButNl<^O+13zgXVRFKMG7b|$u$=IIhC-R9* zg*VBZt3A>(!;Oxyn+g9N8FP(n9?4fFQ$8ZW$L?i`=Kjvu8ie%5G9M0bo;kl#vI<2@ zAh4jsC3_{3+K#U&10-;hbwqv|vnXS94DIVFM#bXL$LNqblZ98a@v#jjZZoz@Fka>; zpA3KZ_-u?i>Y3O4wf^aRt)iF)iJ*6buK3p&%zKI@$Gvd`K=5QHB~nKw3P7yNQAmP} z{^EZW65ZhsG$>^PwXHx|3$Ql3$w<|D(A~nx`Yh>MG&yH4Gnx!rRik6EcoQiK^e#ca zaI*kSm!D3UJiduB^za*7Np0Mgr=JashL>sqsu-XQ)1V-mINuS@a=D-+UwQ+N3oz+! zQkQ{rTdT)A0J265i>_-+0Vh$+<$d% zJsmJbxi?*=N15nMdYn?f)rKegMkt52(~$5W<*q-mA?U=to@z4@gf=N)rvFX)AMiA8(aOeVp_KFh|;=Jeh| z9d~wwcjT>L1=WpV&x|e1c~@&H{nOEdR%1p#PJ74s(^`$H;9GC~fUsNDUDktFaWhfl z-V-)hp*hC;`)5yWcxK(>0P~%ozm^@e&n4zN^rw*xS?5pVn07}hX2NsWLtmf7BkLDg zGR}iN$u2eDp>YA#Gu*O2(oL#d*bo;JzCO`$8@q(PwIpDhmVkx}{_`ZHWXViRImx8T zn(@5xlgV@`Zo1LWU~I6(hBI<|UI!oDVBY zCw}jxmwaD{;H5|mr$8(ZhhMz0GybF&?SBXv3fJHyE<0(>CPp-4seOv^KMXlpbso8E zl65p0+%jXkw~)J|I(14QMtEm}zE0B)+yi=$`vuYy-W1}{8^$u-2x}()5V)Nz)K|)N zG-0z-r&NM2?irIm7T93uVI??%A22S5E75$ZtPqLvCNPsEI~$_H(iyGjj)<0yynRE< z{gek=ifD()S55KAVsw4=7wrzSwHw%)9IA80A zod*`Ke^eVa+r2?UlD$f$<~d~v&{S8reK`}%>++y&)w0tS2RBJxTXvNhugP;OL05UD&~AM;54G@gsCjiOH_kEWhFVbff$?-_kV?U9MQD#iIO@JD zL9nIhUD84?^k3;%KKG~s2*bFnqSiSKk z1{AL}-hUEz4+8=0kA?c)LOwny)046DgF7^gT^b@1;>MaOd2AJ}H>5bU9gN@zB*F0q z?#!Ba6JCWR7nUEO@{o;b+mOOpS3EPkJ1^FTgm92lq%4)*?eNE+E?cRief8P<%R?L|4@gzp{zheqGzzEe^O@5GYWyJx!PvDrkPoMOLZtnl#j;i1D$unz(cbc5MEJr#kuZcg zDpUQB*ZNsXf)<2C8xV^DVY`2J%YqgX-^hd>=RxG}ZXdgcCMB^JTf)Zn>4TDHvGEGd zA3)cA`?-VK$=3V8Hw5(OSC`wm)P?f zs8bFSWcUso2Me8~CIMIs5BDgq5H-fKky3pbiE2jeqyk0@K;=VF(qCV7)yPa-4L0bw zx)N%h`l-H6i43@n)`6+PwZeGH2AOdROV+b^xH4P}w7^lx==Rvi+qXJ^>SgtPXgpu= zn`rZ&Da?n$ zYrxqULlV(g7LPHXZ+>77QvA`t+O4go8`bF<4 zxj?QC+@D5Fg?*fpmPV&W|-j)~H0DMe2cgzxN z%?{)ONY7o;Ap1xa0Th68!eo&P46J951sK5HvXBs9(a*jHf&elL)L8KUnou_}X;8;+ zL58O}T|EL_F=j=0IzU{eaND;;J<{*6E7t5neR;J1$n}#5BH`Gj9JB?KyB*4Ux)_Yf zhiWnUu$S3ZU@ORY(E@VjW9Qp_Ng(AO9z_&jMNr<66D=L8!u9nSAc=T8QUGg`Io6Fg zVGd9z`daiQ;T4(9`b+-WCqXicUA-39_M`wO1gM|SGDu$U3%z>Cg5LDP;;;$G)1mdC z^Hndr2}GRJ@W-_6H#vt86VR_K{d>`c()I&C*x_{Ffz%0#p9yij9DG@GIjCW#Va{a= z{Ap*xuVIy4BjevUPQ#+K@Xx4PFp=qsNDIl)7HK0WMbCRew8|cdK{r%@_P|UY$Hf3` z9Qs19G$#^5CbJ$kHymN zI)JF$?k``bo=+Xq&N${2q>H_6=)*Vtd{UofLcAeN zZ3>>9AAx^j!s>xs{;enn>jkIPmaX!B)2c}@(}Pp88WFv!RSWVJc4|HsHs=^vD`{%x z+chW8WkQ}xMa<720i*-nYOw#qifeXZ9dh5nZ)=w;reK%%ml7mWaqnw1y8H)eg0+-i zMgCLM%N`3kFKVc=pUcyUAhXwfr5uyZ;-i2FZT=v^K2`|Xiq-?O;el$ndx9m(=0IQ?I%Rf}jn zeD46Tv_sm&DOIp-3fR!T44x`q-2RK{RjZm|F&D3c9+;^^){WEmSJ5 zdx%zpob`}1t=*}Kc{i4m?9Rvsn-v-LA^0aCoJ7plv0TI@X+fl?n;M}k;;}!U$(FhT zi6Hd#wxkgV&E*8aN%R`F>Te^U$EhU6FCXsBX7vQnM2=%9?os&L#83b*@OMvcYTzEf zY9a;Dj_iQl?R{GxJGQSN0H2AE`6sbOnUSDUinN_1QK)$Uot;z+kXS4_juApV#4|DM z;;I7FYOL8iB5A1@zijzlfjCufPG!5MH5>wnZ%f&itSB;^MdZ&Xta4J28Cq%lmzPrA z-lHDvqa0hl3tmrc`Pw0Ty5qNxP(%lE#q}yiO99+Ubn*a9p5&Bw0g2+b=L!h=vOXuVOL+s9cM# zp<&@coQMcM3`iJy8exYlv$cq7-2{tir_CiI)HgZ^uhN)g} z+T{4sM*LQOOSOq9Rz>xl`N)AYU5nIKom!TLXUBRt55+T^TZ;_jJ~>)KI zVEP?6a8D)yJ3kMcAMFRkc>@g<+t~mb$QuDA0leu0qa?{cAeW_oE|nUkG^Gfd@-S~R zR=)EVV)^6z%FeY@roUU@2u|u{OT$)#5IdI^Z;XwGkJXVEIDHMm|QfN!@;=v`jQ=qsNEmELpaBXpl6?bjy)cTJaF{atEn5gVlI9ky2{OePExinU>=t&ed zb%ngd>>LbWShQDN3Ym)(lRk76x^7H{bnlRAR6&y*7kGFTZ`AZe!de3=76@Ff`ZZ%R znE*~nT6Ii1(gNC^c2eAA=WTBRB_DeRVU!x~Rj}k&ZvhCq{1u7T|Jq0k$wgR}lPK!5 zf}xtPQ{8 zz<2wPyk733s??m_+_XxduG`GCYIBmS2YCaM6hN4gtk4BUt2SC-2b*tnTWZv<%B6b? zRFXRrz4k=d`H}cPajAA)4W*o`!~PF~_-~L;kLrx8Mw~b%*{7q?-UY#*s~5jVIt9yk z3;MACg9Th#ant~|+9M+fa9Dlfu3>Uj3NZVn4rr0HKKpARfVt$Xtv8@91~7Lg&?1C) zwJYHwQAzV!wY0SFmEc}zvY6{dc@Ke=x#LZRF<@Iza=b&}`1$Jqe__3dn;&>rk8L)F zgy%&Wa+SfRDZHM;ky*Bba1`I_qU0P zVO`Du(iZ8gnE$8qYnBtF8b!_0Yn{t+%wPzYif zHKm1pknl^*am7%ocv~SWfe?r+u%W7V!Pi2Lx&HW}I>m$8Hf%dGB<2OyU+}HZ=3F-H z!>!*d9hzzVyhL8$c)QLkF{l9jbzPOBM5+gAUW<)QD^H8-M~>-m`wAXtFVoIO_ZEsO zb*ZkXeMCuDB7(>a`?ipEx{s8f01*w?%~>-<7U0Wk36DetAb=i6;Wj;ecrfW=f_Jk`?i1nM0UfDs5~AC5D$}ISaO+RfV>y5vj9EdH8IEkELh1 zpa7To)!o2mry+2j#T);_rb*Ab0@C|lh#R41E>!roK@+b44|?!^Lpn0gyx0QB$Td$H zhEd$k5rlXBTd`QYQVNQVECneFt`OEZVgVE3>Po<*BH^4mS4`D&xd9wMk>M3kqJJ`V zvS84v@;xFMll-p@O7Eg0N^qr$Ip&}?+Ua|lz%`93V`)ZNYd<_W{}9I*Y9I}?`mhJK z&b2s6`d^cJk4YU}rOk12ltf_-i|HsYbbWE?Wh~Aiq^x3Gp7>{apgbg=yp1J9bUnfj zwex+JV8t>0-L*Kcv%gSe9#<^(-N%k;I(733T;s!TJqdo&)3JRymAu5E3>vHQ*BpW8 zq|}RUDBUw|f!%vDM6lY6`J;CuIKa9tqS%;y`(N8lMs#h$*wvF6ppq=wNhPrG0LO0u z4gQQLRq5sEn{EG5l+xbphAH%jRCVX(J3fgk0ZqSD?>BfYai1$GQ|Q6lW-DFzAzWYf zY9-H8(wLCLtFU=aHF4zPQWAp5zU((W=_tV^2bS-1x@R1zF8|Xfe&BdXIB!_?%&C zxX4gx2#;kQ_<#f4IADd+y3qvyb^8mo8VroAv(R_Fu4A*|+?l2zyjTW!y_Z8#JmuIz zAl-?p>b9ucXG+DeQyL9>8g)ECyOP4HsOSrd1|k=FTrQWG&lA}jFkqFnQA5CCav2xq zqf~OSRN0m6j_D)E4@_Y)dLCJ0uk@Fw^R%8#G#(f`0Ks4{p|{Hgvp-ZnB&%=UZR)D+ ztJ3+Jj0Y~J&c>gY??aZuD~#rSJ3BAMf4G}STG>AQ)MhjG-tTU;6^z~dsB#Gi==N~~ zU$v3jzHSA0kRPBu(u&mM_Hj4P=~%bnL++cBia)h;m(vEbp~!=#z&<^AAl zD%%BvwtDlne6~Wh^4)QUgxOZxyWN;!@9)=v$kj0@TnIicgi>rAJE7axrL)nL=nrDv zi4p77&j79GrHUh;q*03gYd>j(e&0Fv!%=*NQW?L07qj_d6zZ!g5oNB(m+j>8y8z-E zN>%(kLW5j=4eI{;z8_31TvH?%MV!N{^Q=2p=5N7`)2yr>Oe05cDO_oSje9FTyY;A& z3MpcdX>}|SRlFKEQnG(p3uk9twR6ldsan2=L`=Yv4{7?mJ=+@RY)Xvr~&oA1| z#a*74^C9A+-i+EVv1oE+dU$NafQA;0j}(MowR-o%r#Pz$y%3o$>t!?%RJX5{$>4Qc zw%Y=~diQNM?j2n(cJ$#U9&2$E2iH1_Avfb90)y8T@^$28Te<>{zv`C<+0w`vxdCl= z%WurH0`B^!ILKn{PFMv%)=#bF)O)1%av7ROct;uF5=AeHbMT)R&PsW*o9o`#2q2Tk zGhF<|pR%hYlmcsc=EvU}ld)gWha6Fo``bE`A4}it7ajd5(6pRY{Arfs@K&jZ=?TLa z2f3``Z+98`j~X2~z-SF`ru1 zC3k%G<(cAL84;IMoI~p_2JrLm2#Pb+D>;!y?^}OR7rK6P(r5 zP()_!?~Ork0iKIL39OP0G3d-^dwWQ35ciArl0Cz?#X9HSpCG(_d!y4jYf5PT2l=6< z=Udtuk;ns)(R>$w-T-kXW|ys>cce{dt@xRW!cE!DF_*KSYJ<(*>KA(p%$+u$V=nN4 zbGdUY1#n?+}TYD>L=5W*fOv7*cQBi^$WQ(2q{0vXZS!O>CJ z_0P%w8fYoB*iU&zF6UF9Pf{_EMF2(>d*l5s#$U|za@JM|uma8@YCS6r>+<}0-Jf*} zy*8G&KQEy$f^XN>k^#xwYUz5j7X9B$qtLl7oDmlrJb_KFKRK;-qUJP$zK;qy?Y_PG zE(iU&52RNgw0ztU@O3x+{Z~7xf}g`?CQYrf6+L2GfiF^$gwAvTWy`D!XIw~S;Dgzk z#oloB5x5y|i5sc)Fr>~E#RFB$4yOm0Pvj9|pLIjg+;i-_cM}Nr7Eq|THbH6d5K75A zp(yTBz+eNu@#K3h+)myuV8-v0l|b|k&0Y7a6=|BEp`Ak}C%K`e9kLn_Eap-B=HK~= zQpL1>a&W`7kf`cKcc$F68Is$wRqPMI?qQiI`mPU%=EL$)RZ-m8LFpTyx*iZkE5yvg~5@R5)B=1^U4 z+cjbb3k!J<$tkOcV~W*pAS^O?fwLu|AS zT)*c8tC470%v|IFEiKsA1-UiDn853iw=7AtGRDzVxt2&@$U*xAFVCt?$lP&NEl32Sa)B7!0w0~nK(K78 z>(NAFAAUB$$Xf?R0WL8=N0s#X>8rvf5<4-ovog-e`NmK1CZ-~{Xf0P#LC=9u$ekS2 ztJ$q-pPc8Y7ME>Sk%i0po7&dfR3KL)yFxOO;+Yj6CU_tzpyI<~^Uk>tkUmP~H9;Z= zD)}%oj!p5n)M!TB^;ji295H*7(GSFQvMc!~Hzc+kEwklF*vc zBIV+2R@ReG%9Ew6x%RH_G@Nb+NMxrm54qzg?J+t_8dV{Oa0b*I z0&^~_&$y2@6-WWt+7#~jl;Oe-r?=V%n1S+>^e*hpPW;mCj0{Y@5TQltaVC7j=4K8% zzww#;mjAbj;MD8IPA``U=OD}xMXt>f6b!&7mMOWpPggWpujfYd0q| z0@aKQbe6u)#l(L6FXDwl-aby;9K`qtFhpiHUs!N{%@7BZ7Z;vlfKNmg4MzkIa-A6~ zJl6^)o4xSr=z3b*d`>g0b);HjqWzN8%4QFZT(Z|Ev^6=X#L9l}Sjh*o!BlVf$!iw> zg9V&aFwQVH*=moMI&a?E8blZW{!ZezlI?1IIOydEbL<{@%F(#AilRC&P>=n5C=(7< zYw;eu^_bxKHh9y1eW%*D_Es0p?=||>_2F${+`nL9$TS!O)#GdALT^z%sn zoR_ivAT?!lJc%@)*suJr1kP)-1I4x39e_q(QmfU|ivLkabGQ3(m+|rm@ z=y3wi^`2!o&wv2F=6a@uOd3!)1?LwMaUmCcE*x@gTIsD!F$*t_%mP_F<}lik4An9L z5f|~XAOH$?K>G*2W^TAXsI(_Xk@ol%z4dGH{eKsgXLyk|t zmq{5hout4Ks1H_n^{}G+t&Sd6$T=GLBg9MxFo)X_9&}8MF0q6Eu=R3m*9XgG9pm43 zB{l@joB6*~1SY%JK*|w8;&kDkR)11tsSy{%11#2{CtW!8I|7JIRtn*G`446xpCJnK zb5RDP)#A?~wz}qkcWsV+eBgMvXHT41?CJHE=1Nq8tH-08Mn{&EXdr~4<>{WQIuJ|5 zLOvWD8oz4&%?P*>#K2%Z9)mBZgqLZmc-eub(P~*1Uq#0&r9Z=Z6~<))uor_+<{I5> zt#4T~?i?S1;Z$7eAgJCCV{LUH8U8O>#~^GS;x_Hh5lA@V$`D}&p+ffw(NI*A#S*?~ z$QyzY02g~_dQ&yP&))$O`7j6It}NTX#h8t69`~G@1u?GELPBXnG5WTv&?VDP{ZQv+ z-(YqA5F{dNcWuX%1m+;`uoq$*XL=+k5mn0Jy_7;$-byS33J;z*>HvmWAaCrG52ks- z6JO4qBPgY0$d(GBP02_xH|*Q?hvo$8@AafCf`bCS(N?@*|7K(tZQ-$mw}bY-)-{Zr zWjUBKK)~|RT_)QNWS8~ySxCL7f?piYsuOpSLnTKZ%Ei=?6@EYtkMt7>5S^9akeN9L zWzT*3(-@ja1~1!6y&tY9+-IHOey%SoV1!*CcPPS6Vu^nQ;4Wc6eR^r#uGh8Djp~(& z>I}ui^QB1m-%J&^t46!BD8k7euO`!|PcMWq`5i z1b~c6O`N{`LYPP!RlScK{!G z=AwLzv>r-x&jm=Nd>`~jcbU+v--Y=n&W4X(0ln@({adcfL-mC>Q;>?5TZ5+j5tJtw z%l)%FOc6@e`GytXKmof)WewKN29&T98did$cVcc586b69rFHSgC${PF@GSs=uIgH< za1*2@{MA#AdOe*sj>4lf)oXc6wM9@0%l^};@z~5RUupa>MtQ>$sZXweY1VH{RxeW> zt6~1^+re4kw1eL};Ku@TlMCiN@WaHy{zo!aB@>|Ebi6E_-zo}tTdZx;U3�gu{so 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
-
+ {repos.length > 0 ? ( + + ) : null} setBase(e.target.value)} placeholder="base" /> setHead(e.target.value)} placeholder="head" /> - + @@ -147,6 +221,15 @@ export function App() { ))}
{review.headline}
+ {review.index ? ( + <> +
Index
+
+ Walked {review.index.counts.nodes} nodes / {review.index.counts.edges} edges + {review.index.reindexed ? " after an incremental refresh" : " from the existing index"}. +
+ + ) : null}
Read this
{review.read_order.map((f) => (
@@ -188,20 +271,112 @@ export function App() { ) : (

- Point at a Django + React monorepo with loadpath.yml, then review a git - range. The graph — not hunk comments — is the artifact. + Index a Django + React monorepo with loadpath.yml, inspect architecture, then review a + git range against that graph.

)}
- {review ? : null} + {review ? : null} +
+
+ )} + + {tab === "architecture" && ( +
+ +
+ {architecture?.indexed ? ( + + ) : null}
)} {tab === "graph" && ( -
- {review ? :

Run a review first.

} +
+
+ + +
+ {graphNodes.length ? ( +
+ +
+ ) : ( +

Index the repo or run a review first.

+ )}
)} @@ -219,7 +394,9 @@ export function App() { value={scmRepo} onChange={(e) => setScmRepo(e.target.value)} /> - +
{prs.map((p) => (
@@ -253,8 +430,8 @@ export function App() {

Keys & providers

- Tokens stay on this machine in ~/.loadpath/settings.json. GitHub and Bitbucket power the - PR list. AI is used only for residual uncertainty the graph could not close. + Tokens stay on this machine in ~/.loadpath/settings.json. GitHub and Bitbucket power the PR list. Indexed + repos are remembered as workspaces. AI is used only for residual uncertainty the graph could not close.

diff --git a/ui/src/api.ts b/ui/src/api.ts index 92a76ed..87af4d6 100644 --- a/ui/src/api.ts +++ b/ui/src/api.ts @@ -1,4 +1,4 @@ -import type { PullRequest, Review } from "./types"; +import type { ArchitectureReport, IndexedRepo, PullRequest, Review } from "./types"; async function req(path: string, init?: RequestInit): Promise { const res = await fetch(path, { @@ -17,19 +17,24 @@ export const api = { settings: () => req>("/api/settings"), saveSettings: (body: Record) => req>("/api/settings", { method: "PUT", body: JSON.stringify(body) }), - index: (repo_path: string) => - req<{ ok: boolean; counts: { nodes: number; edges: number } }>("/api/index", { + repos: () => req<{ repos: IndexedRepo[] }>("/api/repos"), + index: (repo_path: string, incremental = true) => + req("/api/index", { method: "POST", - body: JSON.stringify({ repo_path, incremental: true }), + body: JSON.stringify({ repo_path, incremental }), }), - review: (repo_path: string, base: string, head?: string) => + indexStatus: (repo_path: string) => + req(`/api/index?repo_path=${encodeURIComponent(repo_path)}`), + architecture: (repo_path: string) => + req(`/api/architecture?repo_path=${encodeURIComponent(repo_path)}`), + review: (repo_path: string, base: string, head?: string, reindex = true) => req("/api/review", { method: "POST", - body: JSON.stringify({ repo_path, base, head: head || null, reindex: true }), + body: JSON.stringify({ repo_path, base, head: head || null, reindex, incremental: true }), }), - graph: (repo_path: string) => + graph: (repo_path: string, scope: "full" | "architecture" = "full") => req<{ nodes: unknown[]; edges: unknown[]; counts: { nodes: number; edges: number } }>( - `/api/graph?repo_path=${encodeURIComponent(repo_path)}`, + `/api/graph?repo_path=${encodeURIComponent(repo_path)}&scope=${scope}`, ), prs: (provider: string, repo: string, state = "open") => req<{ pull_requests: PullRequest[] }>("/api/prs", { diff --git a/ui/src/styles.css b/ui/src/styles.css index d112b3b..923ac4d 100644 --- a/ui/src/styles.css +++ b/ui/src/styles.css @@ -134,6 +134,26 @@ h1 { font-size: 18px; margin: 0 0 6px; } width: 100%; } .headline { white-space: pre-wrap; font-family: "IBM Plex Mono", monospace; font-size: 12px; color: var(--muted); } +.graph-modes { + display: flex; + gap: 6px; + padding: 10px 14px; + border-bottom: 1px solid var(--line); + background: var(--bg-2); +} +.graph-modes button { + background: transparent; + border: 1px solid var(--line); + border-radius: 999px; + padding: 4px 10px; + color: var(--muted); + cursor: pointer; +} +.graph-modes button.active { + background: #15202c; + color: var(--ink); + border-color: #2a9d8f; +} .lp-node { padding: 8px 10px; border-radius: 8px; diff --git a/ui/src/types.ts b/ui/src/types.ts index b3e8c0c..c74b1ca 100644 --- a/ui/src/types.ts +++ b/ui/src/types.ts @@ -54,6 +54,47 @@ export type Review = { nodes: GraphNode[]; edges: GraphEdge[]; markdown?: string; + index?: { + db: string; + counts: { nodes: number; edges: number }; + type_counts?: Record; + indexed_at?: string | null; + reindexed: boolean; + incremental: boolean; + }; +}; + +export type ArchitectureReport = { + ok: boolean; + indexed: boolean; + repo_root: string; + db?: string; + indexed_at?: string | null; + incremental?: boolean; + counts: { nodes: number; edges: number }; + type_counts: Record; + file_count?: number; + contexts: Record< + string, + { name: string; django_apps: string[]; react: string[]; public_api: string[]; owners: string[] } + >; + rules: string[]; + findings: Finding[]; + residuals: string[]; + has_config?: boolean; + nodes: GraphNode[]; + edges: GraphEdge[]; +}; + +export type IndexedRepo = { + path: string; + name: string; + exists: boolean; + indexed: boolean; + counts: { nodes: number; edges: number }; + indexed_at?: string | null; + contexts?: string[]; + has_config?: boolean; }; export type PullRequest = { From 7b2548e6b8dbe47628ff7e69f048c2f3d3f25f39 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 14 Aug 2026 22:13:46 +0000 Subject: [PATCH 5/5] Fix review findings from PR scrutiny Preserve GitHub/AI tokens when Settings saves empty or masked fields, write settings atomically with 0600 perms, and reject unsafe SCM repo slugs. Resolve Django boot settings as config.settings relative to django_root, qualify cross-app enqueue targets from imports, prune deleted files on incremental index without dropping enqueue edges from unchanged views, and ignore stale architecture responses when the selected repo changes. Co-authored-by: Damon --- src/loadpath/extractors/django.py | 26 +++++--- src/loadpath/extractors/django_boot.py | 21 +++++-- src/loadpath/graph/store.py | 19 +++++- src/loadpath/index.py | 31 +++++++++- src/loadpath/providers/scm.py | 16 +++++ src/loadpath/server/app.py | 23 +++++--- src/loadpath/settings.py | 41 ++++++++++--- src/loadpath/static/assets/index-BlJPyDt6.js | 62 ++++++++++++++++++++ src/loadpath/static/assets/index-CfK4f0dK.js | 62 -------------------- src/loadpath/static/index.html | 2 +- tests/e2e/test_ui_screenshots.py | 14 ++--- tests/unit/test_django_extractors.py | 21 +++++++ tests/unit/test_index_and_stitch.py | 33 +++++++++++ tests/unit/test_providers_and_api.py | 10 ++++ ui/src/App.tsx | 18 +++++- ui/src/ImpactGraph.tsx | 14 +++-- 16 files changed, 299 insertions(+), 114 deletions(-) create mode 100644 src/loadpath/static/assets/index-BlJPyDt6.js delete mode 100644 src/loadpath/static/assets/index-CfK4f0dK.js diff --git a/src/loadpath/extractors/django.py b/src/loadpath/extractors/django.py index b903c65..742102f 100644 --- a/src/loadpath/extractors/django.py +++ b/src/loadpath/extractors/django.py @@ -588,9 +588,7 @@ def _looks_like_dramatiq_send(self, fname: str) -> bool: return any(part in target for part in ("actors", "tasks", "dramatiq")) def _enqueue(self, node: ast.Call, fname: str, broker: str = "celery") -> None: - task_name = fname.rsplit(".", 1)[0] - short = task_name.split(".")[-1] - qname = f"{self.app}.{short}" + app, short, qname = self._task_qname(fname) owner = self.class_stack[-1] if self.class_stack else Path(self.rel_path).stem owner_type = NodeType.VIEW if "management/commands" in self.rel_path: @@ -612,9 +610,23 @@ def _enqueue(self, node: ast.Call, fname: str, broker: str = "celery") -> None: short, qname, node.lineno, - {"referenced": True, "app": self.app, "broker": broker}, + {"referenced": True, "app": app, "broker": broker}, ) + def _task_qname(self, fname: str) -> tuple[str, str, str]: + task_name = fname.rsplit(".", 1)[0] if "." in fname else fname + resolved = self._resolve(task_name) + parts = [p for p in resolved.split(".") if p] + short = parts[-1] if parts else task_name.split(".")[-1] + app = self.app + for marker in ("tasks", "actors", "jobs"): + if marker in parts: + idx = parts.index(marker) + if idx > 0: + app = parts[idx - 1] + break + return app, short, f"{app}.{short}" + def _enqueue_from_on_commit(self, node: ast.Call) -> None: for arg in list(node.args) + [kw.value for kw in node.keywords]: for child in ast.walk(arg): @@ -659,11 +671,11 @@ def _send_task(self, node: ast.Call) -> None: def _beat_schedule(self, value: ast.AST) -> None: if not isinstance(value, ast.Dict): return - for key, val in zip(value.keys, value.values): + for key, val in zip(value.keys, value.values, strict=True): entry_name = _const_str(key) or _name(key) or "beat" task_name = None if isinstance(val, ast.Dict): - for k, v in zip(val.keys, val.values): + for k, v in zip(val.keys, val.values, strict=True): label = _const_str(k) or _name(k) if label == "task": task_name = _const_str(v) or _name(v) @@ -802,7 +814,7 @@ def _url_path(self, node: ast.Call) -> None: view_name = (_name(view_expr.func) or "").replace(".as_view", "") # mapping dict for viewsets if view_expr.args and isinstance(view_expr.args[0], ast.Dict): - for k, v in zip(view_expr.args[0].keys, view_expr.args[0].values): + for k, v in zip(view_expr.args[0].keys, view_expr.args[0].values, strict=True): method = _const_str(k) action = _name(v) if method and action: diff --git a/src/loadpath/extractors/django_boot.py b/src/loadpath/extractors/django_boot.py index 150d9a9..a969356 100644 --- a/src/loadpath/extractors/django_boot.py +++ b/src/loadpath/extractors/django_boot.py @@ -12,7 +12,7 @@ def try_boot_models(repo_root: Path, config: LoadpathConfig) -> ExtractedGraph: graph = ExtractedGraph() - settings_mod = _discover_settings_module(repo_root) + settings_mod = _discover_settings_module(repo_root, config.django_root) if not settings_mod: return graph try: @@ -107,15 +107,26 @@ def try_boot_models(repo_root: Path, config: LoadpathConfig) -> ExtractedGraph: return graph -def _discover_settings_module(repo_root: Path) -> str | None: +def _discover_settings_module(repo_root: Path, django_root: str = "backend") -> str | None: env = os.environ.get("DJANGO_SETTINGS_MODULE") if env: return env + django_path = (repo_root / django_root).resolve() + candidates: list[Path] = [] for settings in repo_root.rglob("settings.py"): - rel = settings.relative_to(repo_root).with_suffix("") + rel = settings.relative_to(repo_root) if any(part.startswith(".") for part in rel.parts): continue if "site-packages" in rel.parts: continue - return ".".join(rel.parts) - return None + candidates.append(settings) + if not candidates: + return None + for settings in candidates: + try: + rel = settings.resolve().relative_to(django_path).with_suffix("") + return ".".join(rel.parts) + except ValueError: + continue + rel = candidates[0].relative_to(repo_root).with_suffix("") + return ".".join(rel.parts) diff --git a/src/loadpath/graph/store.py b/src/loadpath/graph/store.py index 3fec1a3..2252872 100644 --- a/src/loadpath/graph/store.py +++ b/src/loadpath/graph/store.py @@ -100,7 +100,7 @@ def upsert_file(self, path: str, digest: str, language: str | None) -> None: (path, digest, language), ) - def delete_file_nodes(self, path: str) -> None: + def delete_file_nodes(self, path: str, *, drop_incoming: bool = True) -> None: ids = [ r["id"] for r in self.conn.execute("SELECT id FROM nodes WHERE file_path=?", (path,)).fetchall() @@ -109,10 +109,22 @@ def delete_file_nodes(self, path: str) -> None: self.conn.execute("DELETE FROM files WHERE path=?", (path,)) return placeholders = ",".join("?" * len(ids)) - self.conn.execute(f"DELETE FROM edges WHERE src IN ({placeholders}) OR dst IN ({placeholders})", ids + ids) + if drop_incoming: + self.conn.execute( + f"DELETE FROM edges WHERE src IN ({placeholders}) OR dst IN ({placeholders})", + ids + ids, + ) + else: + # Reindex: keep edges from other files (e.g. view ENQUEUES → task). + self.conn.execute(f"DELETE FROM edges WHERE src IN ({placeholders})", ids) self.conn.execute("DELETE FROM nodes WHERE file_path=?", (path,)) self.conn.execute("DELETE FROM files WHERE path=?", (path,)) + def prune_dangling_edges(self) -> None: + self.conn.execute( + "DELETE FROM edges WHERE src NOT IN (SELECT id FROM nodes) OR dst NOT IN (SELECT id FROM nodes)" + ) + def upsert_graph(self, graph: ExtractedGraph) -> None: for node in graph.nodes: self.upsert_node(node) @@ -297,6 +309,9 @@ def type_counts(self) -> dict[str, int]: def file_count(self) -> int: return self.conn.execute("SELECT COUNT(*) AS c FROM files").fetchone()["c"] + def indexed_paths(self) -> list[str]: + return [r["path"] for r in self.conn.execute("SELECT path FROM files").fetchall()] + @staticmethod def _node_from_row(row: sqlite3.Row) -> dict[str, Any]: extra = json.loads(row["extra"] or "{}") diff --git a/src/loadpath/index.py b/src/loadpath/index.py index 2cff5a7..47ca038 100644 --- a/src/loadpath/index.py +++ b/src/loadpath/index.py @@ -74,12 +74,19 @@ def index_repo( store.set_meta("repo_root", str(repo_root)) residuals: list[str] = [] - for path in iter_source_files(repo_root, config): + skipped: set[str] = set() + files = iter_source_files(repo_root, config) + present = {path.relative_to(repo_root).as_posix() for path in files} + for stale in store.indexed_paths(): + if stale not in present: + store.delete_file_nodes(stale) + for path in files: rel = path.relative_to(repo_root).as_posix() digest = file_hash(path) if incremental and store.file_hash(rel) == digest: + skipped.add(rel) continue - store.delete_file_nodes(rel) + store.delete_file_nodes(rel, drop_incoming=False) source = path.read_text(encoding="utf-8", errors="replace") if path.suffix == ".py": graph = extract_django_file(rel, source, config) @@ -98,7 +105,25 @@ def index_repo( _ensure_context_nodes(store, config) stitch_residuals = stitch(store, config, repo_root) - residuals.extend(stitch_residuals) + store.prune_dangling_edges() + if incremental: + old = [line for line in (store.get_meta("residuals") or "").splitlines() if line] + changed = present - skipped + preserved = [ + line + for line in old + if any(rel in line for rel in skipped) and not any(rel in line for rel in changed) + ] + residuals = preserved + residuals + stitch_residuals + seen: set[str] = set() + deduped: list[str] = [] + for line in residuals: + if line not in seen: + seen.add(line) + deduped.append(line) + residuals = deduped + else: + residuals.extend(stitch_residuals) store.set_meta("residuals", "\n".join(residuals)) store.set_meta("indexed_at", datetime.now(timezone.utc).isoformat()) store.set_meta("incremental", "1" if incremental else "0") diff --git a/src/loadpath/providers/scm.py b/src/loadpath/providers/scm.py index 595b0d8..6a91210 100644 --- a/src/loadpath/providers/scm.py +++ b/src/loadpath/providers/scm.py @@ -1,10 +1,20 @@ from __future__ import annotations +import re from dataclasses import dataclass from typing import Any, Protocol import httpx +REPO_SLUG = re.compile(r"^[\w.-]+/[\w.-]+$") + + +def require_repo_slug(repo: str) -> str: + slug = repo.strip().strip("/") + if not REPO_SLUG.match(slug): + raise ValueError("repo must be owner/name") + return slug + @dataclass class PullRequest: @@ -51,6 +61,7 @@ def _headers(self) -> dict[str, str]: } def list_pull_requests(self, repo: str, state: str = "open") -> list[PullRequest]: + repo = require_repo_slug(repo) r = self.client.get( f"{self.base}/repos/{repo}/pulls", params={"state": state, "per_page": 50, "sort": "updated"}, @@ -78,6 +89,7 @@ def list_pull_requests(self, repo: str, state: str = "open") -> list[PullRequest return out def get_pull_request(self, repo: str, number: int) -> PullRequest: + repo = require_repo_slug(repo) r = self.client.get(f"{self.base}/repos/{repo}/pulls/{number}", headers=self._headers()) r.raise_for_status() item = r.json() @@ -97,6 +109,7 @@ def get_pull_request(self, repo: str, number: int) -> PullRequest: ) def get_diff(self, repo: str, number: int) -> str: + repo = require_repo_slug(repo) r = self.client.get( f"{self.base}/repos/{repo}/pulls/{number}", headers={**self._headers(), "Accept": "application/vnd.github.diff"}, @@ -130,6 +143,7 @@ def _headers(self) -> dict[str, str]: return {"Authorization": f"Bearer {self.token}"} def list_pull_requests(self, repo: str, state: str = "open") -> list[PullRequest]: + repo = require_repo_slug(repo) bb_state = "OPEN" if state == "open" else state.upper() r = self.client.get( f"{self.base}/repositories/{repo}/pullrequests", @@ -164,6 +178,7 @@ def list_pull_requests(self, repo: str, state: str = "open") -> list[PullRequest return out def get_pull_request(self, repo: str, number: int) -> PullRequest: + repo = require_repo_slug(repo) r = self.client.get( f"{self.base}/repositories/{repo}/pullrequests/{number}", headers=self._headers(), @@ -189,6 +204,7 @@ def get_pull_request(self, repo: str, number: int) -> PullRequest: ) def get_diff(self, repo: str, number: int) -> str: + repo = require_repo_slug(repo) r = self.client.get( f"{self.base}/repositories/{repo}/pullrequests/{number}/diff", headers=self._headers(), diff --git a/src/loadpath/server/app.py b/src/loadpath/server/app.py index fcb586d..5c61cd4 100644 --- a/src/loadpath/server/app.py +++ b/src/loadpath/server/app.py @@ -18,7 +18,7 @@ from loadpath.providers.scm import provider_for from loadpath.review.engine import run_review from loadpath.review.render import render_html, render_markdown -from loadpath.settings import AppSettings, public_settings, register_workspace, settings_path +from loadpath.settings import AppSettings, public_settings, register_workspace, settings_path, _should_update_secret class IndexRequest(BaseModel): @@ -62,7 +62,12 @@ def create_app() -> FastAPI: app = FastAPI(title="Loadpath", version=__version__) app.add_middleware( CORSMiddleware, - allow_origins=["*"], + allow_origins=[ + "http://127.0.0.1:7345", + "http://localhost:7345", + "http://127.0.0.1:5173", + "http://localhost:5173", + ], allow_methods=["*"], allow_headers=["*"], ) @@ -78,18 +83,18 @@ def get_settings() -> dict[str, Any]: @app.put("/api/settings") def put_settings(body: SettingsUpdate) -> dict[str, Any]: current = AppSettings.load() - if body.github_token is not None and body.github_token not in {"", current.github_token} and "…" not in body.github_token: - current.github_token = body.github_token - if body.bitbucket_token is not None and "…" not in (body.bitbucket_token or ""): - current.bitbucket_token = body.bitbucket_token + if _should_update_secret(body.github_token, current.github_token): + current.github_token = body.github_token or "" + if _should_update_secret(body.bitbucket_token, current.bitbucket_token): + current.bitbucket_token = body.bitbucket_token or "" if body.bitbucket_username is not None: current.bitbucket_username = body.bitbucket_username if body.bitbucket_workspace is not None: current.bitbucket_workspace = body.bitbucket_workspace if body.ai_provider is not None: current.ai.provider = body.ai_provider - if body.ai_api_key is not None and "…" not in body.ai_api_key: - current.ai.api_key = body.ai_api_key + if _should_update_secret(body.ai_api_key, current.ai.api_key): + current.ai.api_key = body.ai_api_key or "" if body.ai_model is not None: current.ai.model = body.ai_model if body.ai_base_url is not None: @@ -236,6 +241,8 @@ def api_prs(body: PRListRequest) -> dict[str, Any]: try: scm = provider_for(body.provider, token, username=username) prs = scm.list_pull_requests(body.repo, state=body.state) + except ValueError as exc: + raise HTTPException(400, str(exc)) from exc except Exception as exc: # noqa: BLE001 raise HTTPException(502, str(exc)) from exc return {"pull_requests": [p.to_dict() for p in prs]} diff --git a/src/loadpath/settings.py b/src/loadpath/settings.py index 6cad650..f8c142a 100644 --- a/src/loadpath/settings.py +++ b/src/loadpath/settings.py @@ -1,11 +1,15 @@ from __future__ import annotations import json +import os +import threading from pathlib import Path from typing import Any from pydantic import BaseModel, Field +_SETTINGS_LOCK = threading.RLock() + def settings_path() -> Path: return Path.home() / ".loadpath" / "settings.json" @@ -42,9 +46,25 @@ class AppSettings(BaseModel): connections: list[SCMConnection] = Field(default_factory=list) def save(self, path: Path | None = None) -> None: + with _SETTINGS_LOCK: + self._write(path) + + def _write(self, path: Path | None = None) -> None: p = path or settings_path() p.parent.mkdir(parents=True, exist_ok=True) - p.write_text(self.model_dump_json(indent=2), encoding="utf-8") + try: + os.chmod(p.parent, 0o700) + except OSError: + pass + payload = self.model_dump_json(indent=2) + tmp = p.with_suffix(p.suffix + ".tmp") + tmp.write_text(payload, encoding="utf-8") + os.chmod(tmp, 0o600) + tmp.replace(p) + try: + os.chmod(p, 0o600) + except OSError: + pass @classmethod def load(cls, path: Path | None = None) -> AppSettings: @@ -63,13 +83,20 @@ def mask_secret(value: str) -> str: return value[:4] + "…" + value[-2:] +def _should_update_secret(value: str | None, current: str) -> bool: + if value is None or value == "" or "…" in value: + return False + return value != current + + def register_workspace(path: Path, name: str | None = None) -> AppSettings: - settings = AppSettings.load() - resolved = str(path.expanduser().resolve()) - if not any(w.path == resolved for w in settings.workspaces): - settings.workspaces.append(Workspace(path=resolved, name=name or Path(resolved).name)) - settings.save() - return settings + with _SETTINGS_LOCK: + settings = AppSettings.load() + resolved = str(path.expanduser().resolve()) + if not any(w.path == resolved for w in settings.workspaces): + settings.workspaces.append(Workspace(path=resolved, name=name or Path(resolved).name)) + settings._write() + return settings def public_settings(settings: AppSettings) -> dict[str, Any]: diff --git a/src/loadpath/static/assets/index-BlJPyDt6.js b/src/loadpath/static/assets/index-BlJPyDt6.js new file mode 100644 index 0000000..b60ce67 --- /dev/null +++ b/src/loadpath/static/assets/index-BlJPyDt6.js @@ -0,0 +1,62 @@ +(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const u of document.querySelectorAll('link[rel="modulepreload"]'))l(u);new MutationObserver(u=>{for(const c of u)if(c.type==="childList")for(const f of c.addedNodes)f.tagName==="LINK"&&f.rel==="modulepreload"&&l(f)}).observe(document,{childList:!0,subtree:!0});function o(u){const c={};return u.integrity&&(c.integrity=u.integrity),u.referrerPolicy&&(c.referrerPolicy=u.referrerPolicy),u.crossOrigin==="use-credentials"?c.credentials="include":u.crossOrigin==="anonymous"?c.credentials="omit":c.credentials="same-origin",c}function l(u){if(u.ep)return;u.ep=!0;const c=o(u);fetch(u.href,c)}})();function Zh(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var ha={exports:{}},Gi={},pa={exports:{}},Ne={};/** + * @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 jd;function w0(){if(jd)return Ne;jd=1;var t=Symbol.for("react.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),l=Symbol.for("react.strict_mode"),u=Symbol.for("react.profiler"),c=Symbol.for("react.provider"),f=Symbol.for("react.context"),h=Symbol.for("react.forward_ref"),p=Symbol.for("react.suspense"),y=Symbol.for("react.memo"),m=Symbol.for("react.lazy"),v=Symbol.iterator;function g(C){return C===null||typeof C!="object"?null:(C=v&&C[v]||C["@@iterator"],typeof C=="function"?C:null)}var w={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},S=Object.assign,M={};function N(C,z,ne){this.props=C,this.context=z,this.refs=M,this.updater=ne||w}N.prototype.isReactComponent={},N.prototype.setState=function(C,z){if(typeof C!="object"&&typeof C!="function"&&C!=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,C,z,"setState")},N.prototype.forceUpdate=function(C){this.updater.enqueueForceUpdate(this,C,"forceUpdate")};function E(){}E.prototype=N.prototype;function R(C,z,ne){this.props=C,this.context=z,this.refs=M,this.updater=ne||w}var _=R.prototype=new E;_.constructor=R,S(_,N.prototype),_.isPureReactComponent=!0;var I=Array.isArray,W=Object.prototype.hasOwnProperty,$={current:null},V={key:!0,ref:!0,__self:!0,__source:!0};function X(C,z,ne){var ie,ce={},O=null,re=null;if(z!=null)for(ie in z.ref!==void 0&&(re=z.ref),z.key!==void 0&&(O=""+z.key),z)W.call(z,ie)&&!V.hasOwnProperty(ie)&&(ce[ie]=z[ie]);var Q=arguments.length-2;if(Q===1)ce.children=ne;else if(1>>1,z=A[C];if(0>>1;Cu(ce,F))Ou(re,ce)?(A[C]=re,A[O]=F,C=O):(A[C]=ce,A[ie]=F,C=ie);else if(Ou(re,F))A[C]=re,A[O]=F,C=O;else break e}}return j}function u(A,j){var F=A.sortIndex-j.sortIndex;return F!==0?F:A.id-j.id}if(typeof performance=="object"&&typeof performance.now=="function"){var c=performance;t.unstable_now=function(){return c.now()}}else{var f=Date,h=f.now();t.unstable_now=function(){return f.now()-h}}var p=[],y=[],m=1,v=null,g=3,w=!1,S=!1,M=!1,N=typeof setTimeout=="function"?setTimeout:null,E=typeof clearTimeout=="function"?clearTimeout:null,R=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function _(A){for(var j=o(y);j!==null;){if(j.callback===null)l(y);else if(j.startTime<=A)l(y),j.sortIndex=j.expirationTime,r(p,j);else break;j=o(y)}}function I(A){if(M=!1,_(A),!S)if(o(p)!==null)S=!0,H(W);else{var j=o(y);j!==null&&U(I,j.startTime-A)}}function W(A,j){S=!1,M&&(M=!1,E(X),X=-1),w=!0;var F=g;try{for(_(j),v=o(p);v!==null&&(!(v.expirationTime>j)||A&&!Z());){var C=v.callback;if(typeof C=="function"){v.callback=null,g=v.priorityLevel;var z=C(v.expirationTime<=j);j=t.unstable_now(),typeof z=="function"?v.callback=z:v===o(p)&&l(p),_(j)}else l(p);v=o(p)}if(v!==null)var ne=!0;else{var ie=o(y);ie!==null&&U(I,ie.startTime-j),ne=!1}return ne}finally{v=null,g=F,w=!1}}var $=!1,V=null,X=-1,K=5,te=-1;function Z(){return!(t.unstable_now()-teA||125C?(A.sortIndex=F,r(y,A),o(p)===null&&A===o(y)&&(M?(E(X),X=-1):M=!0,U(I,F-C))):(A.sortIndex=z,r(p,A),S||w||(S=!0,H(W))),A},t.unstable_shouldYield=Z,t.unstable_wrapCallback=function(A){var j=g;return function(){var F=g;g=j;try{return A.apply(this,arguments)}finally{g=F}}}})(ya)),ya}var Fd;function N0(){return Fd||(Fd=1,ma.exports=k0()),ma.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 Hd;function C0(){if(Hd)return gt;Hd=1;var t=fo(),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"),p=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]*$/,m={},v={};function g(e){return p.call(v,e)?!0:p.call(m,e)?!1:y.test(e)?v[e]=!0:(m[e]=!0,!1)}function w(e,n,i,s){if(i!==null&&i.type===0)return!1;switch(typeof n){case"function":case"symbol":return!0;case"boolean":return s?!1:i!==null?!i.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function S(e,n,i,s){if(n===null||typeof n>"u"||w(e,n,i,s))return!0;if(s)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 M(e,n,i,s,a,d,x){this.acceptsBooleans=n===2||n===3||n===4,this.attributeName=s,this.attributeNamespace=a,this.mustUseProperty=i,this.propertyName=e,this.type=n,this.sanitizeURL=d,this.removeEmptyString=x}var N={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){N[e]=new M(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var n=e[0];N[n]=new M(n,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){N[e]=new M(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){N[e]=new M(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){N[e]=new M(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){N[e]=new M(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){N[e]=new M(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){N[e]=new M(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){N[e]=new M(e,5,!1,e.toLowerCase(),null,!1,!1)});var E=/[\-:]([a-z])/g;function R(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(E,R);N[n]=new M(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(E,R);N[n]=new M(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(E,R);N[n]=new M(n,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){N[e]=new M(e,1,!1,e.toLowerCase(),null,!1,!1)}),N.xlinkHref=new M("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){N[e]=new M(e,1,!1,e.toLowerCase(),null,!0,!0)});function _(e,n,i,s){var a=N.hasOwnProperty(n)?N[n]:null;(a!==null?a.type!==0:s||!(2T||a[x]!==d[T]){var L=` +`+a[x].replace(" at new "," at ");return e.displayName&&L.includes("")&&(L=L.replace("",e.displayName)),L}while(1<=x&&0<=T);break}}}finally{ne=!1,Error.prepareStackTrace=i}return(e=e?e.displayName||e.name:"")?z(e):""}function ce(e){switch(e.tag){case 5:return z(e.type);case 16:return z("Lazy");case 13:return z("Suspense");case 19:return z("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 O(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 $:return"Portal";case K:return"Profiler";case X:return"StrictMode";case J:return"Suspense";case k:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case Z:return(e.displayName||"Context")+".Consumer";case te:return(e._context.displayName||"Context")+".Provider";case ee:var n=e.render;return e=e.displayName,e||(e=n.displayName||n.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case B:return n=e.displayName||null,n!==null?n:O(e.type)||"Memo";case H:n=e._payload,e=e._init;try{return O(e(n))}catch{}}return null}function re(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 O(n);case 8:return n===X?"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 pe(e){var n=le(e)?"checked":"value",i=Object.getOwnPropertyDescriptor(e.constructor.prototype,n),s=""+e[n];if(!e.hasOwnProperty(n)&&typeof i<"u"&&typeof i.get=="function"&&typeof i.set=="function"){var a=i.get,d=i.set;return Object.defineProperty(e,n,{configurable:!0,get:function(){return a.call(this)},set:function(x){s=""+x,d.call(this,x)}}),Object.defineProperty(e,n,{enumerable:i.enumerable}),{getValue:function(){return s},setValue:function(x){s=""+x},stopTracking:function(){e._valueTracker=null,delete e[n]}}}}function we(e){e._valueTracker||(e._valueTracker=pe(e))}function ve(e){if(!e)return!1;var n=e._valueTracker;if(!n)return!0;var i=n.getValue(),s="";return e&&(s=le(e)?e.checked?"true":"false":e.value),e=s,e!==i?(n.setValue(e),!0):!1}function me(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 ke(e,n){var i=n.checked;return F({},n,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:i??e._wrapperState.initialChecked})}function Ce(e,n){var i=n.defaultValue==null?"":n.defaultValue,s=n.checked!=null?n.checked:n.defaultChecked;i=Q(n.value!=null?n.value:i),e._wrapperState={initialChecked:s,initialValue:i,controlled:n.type==="checkbox"||n.type==="radio"?n.checked!=null:n.value!=null}}function Me(e,n){n=n.checked,n!=null&&_(e,"checked",n,!1)}function Re(e,n){Me(e,n);var i=Q(n.value),s=n.type;if(i!=null)s==="number"?(i===0&&e.value===""||e.value!=i)&&(e.value=""+i):e.value!==""+i&&(e.value=""+i);else if(s==="submit"||s==="reset"){e.removeAttribute("value");return}n.hasOwnProperty("value")?ut(e,n.type,i):n.hasOwnProperty("defaultValue")&&ut(e,n.type,Q(n.defaultValue)),n.checked==null&&n.defaultChecked!=null&&(e.defaultChecked=!!n.defaultChecked)}function ot(e,n,i){if(n.hasOwnProperty("value")||n.hasOwnProperty("defaultValue")){var s=n.type;if(!(s!=="submit"&&s!=="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 ut(e,n,i){(n!=="number"||me(e.ownerDocument)!==e)&&(i==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+i&&(e.defaultValue=""+i))}var Je=Array.isArray;function et(e,n,i,s){if(e=e.options,n){n={};for(var a=0;a"+n.valueOf().toString()+"",n=Mt.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;n.firstChild;)e.appendChild(n.firstChild)}});function ln(e,n){if(n){var i=e.firstChild;if(i&&i===e.lastChild&&i.nodeType===3){i.nodeValue=n;return}}e.textContent=n}var Yn={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},Sl=["Webkit","ms","Moz","O"];Object.keys(Yn).forEach(function(e){Sl.forEach(function(n){n=n+e.charAt(0).toUpperCase()+e.substring(1),Yn[n]=Yn[e]})});function xo(e,n,i){return n==null||typeof n=="boolean"||n===""?"":i||typeof n!="number"||n===0||Yn.hasOwnProperty(e)&&Yn[e]?(""+n).trim():n+"px"}function wo(e,n){e=e.style;for(var i in n)if(n.hasOwnProperty(i)){var s=i.indexOf("--")===0,a=xo(i,n[i],s);i==="float"&&(i="cssFloat"),s?e.setProperty(i,a):e[i]=a}}var _l=F({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 si(e,n){if(n){if(_l[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 li(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 ui=null;function ai(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var ci=null,wn=null,Sn=null;function So(e){if(e=ji(e)){if(typeof ci!="function")throw Error(o(280));var n=e.stateNode;n&&(n=qo(n),ci(e.stateNode,e.type,n))}}function _o(e){wn?Sn?Sn.push(e):Sn=[e]:wn=e}function Eo(){if(wn){var e=wn,n=Sn;if(Sn=wn=null,So(e),n)for(e=0;e>>=0,e===0?32:31-(Rl(e)/Ll|0)|0}var Nr=64,Cr=4194304;function Kn(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 un(e,n){var i=e.pendingLanes;if(i===0)return 0;var s=0,a=e.suspendedLanes,d=e.pingedLanes,x=i&268435455;if(x!==0){var T=x&~a;T!==0?s=Kn(T):(d&=x,d!==0&&(s=Kn(d)))}else x=i&~a,x!==0?s=Kn(x):d!==0&&(s=Kn(d));if(s===0)return 0;if(n!==0&&n!==s&&(n&a)===0&&(a=s&-s,d=n&-n,a>=d||a===16&&(d&4194240)!==0))return n;if((s&4)!==0&&(s|=i&16),n=e.entangledLanes,n!==0)for(e=e.entanglements,n&=s;0i;i++)n.push(e);return n}function Zn(e,n,i){e.pendingLanes|=n,n!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,n=31-xt(n),e[n]=i}function $l(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 s=e.eventTimes;for(e=e.expirationTimes;0=Ni),Cc=" ",Mc=!1;function Pc(e,n){switch(e){case"keyup":return gm.indexOf(n.keyCode)!==-1;case"keydown":return n.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Ic(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Tr=!1;function ym(e,n){switch(e){case"compositionend":return Ic(n);case"keypress":return n.which!==32?null:(Mc=!0,Cc);case"textInput":return e=n.data,e===Cc&&Mc?null:e;default:return null}}function vm(e,n){if(Tr)return e==="compositionend"||!Xl&&Pc(e,n)?(e=wc(),Ho=Vl=Cn=null,Tr=!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=s}e:{for(;i;){if(i.nextSibling){i=i.nextSibling;break e}i=i.parentNode}i=void 0}i=$c(i)}}function Oc(e,n){return e&&n?e===n?!0:e&&e.nodeType===3?!1:n&&n.nodeType===3?Oc(e,n.parentNode):"contains"in e?e.contains(n):e.compareDocumentPosition?!!(e.compareDocumentPosition(n)&16):!1:!1}function Fc(){for(var e=window,n=me();n instanceof e.HTMLIFrameElement;){try{var i=typeof n.contentWindow.location.href=="string"}catch{i=!1}if(i)e=n.contentWindow;else break;n=me(e.document)}return n}function Kl(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 Mm(e){var n=Fc(),i=e.focusedElem,s=e.selectionRange;if(n!==i&&i&&i.ownerDocument&&Oc(i.ownerDocument.documentElement,i)){if(s!==null&&Kl(i)){if(n=s.start,e=s.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 a=i.textContent.length,d=Math.min(s.start,a);s=s.end===void 0?d:Math.min(s.end,a),!e.extend&&d>s&&(a=s,s=d,d=a),a=Dc(i,d);var x=Dc(i,s);a&&x&&(e.rangeCount!==1||e.anchorNode!==a.node||e.anchorOffset!==a.offset||e.focusNode!==x.node||e.focusOffset!==x.offset)&&(n=n.createRange(),n.setStart(a.node,a.offset),e.removeAllRanges(),d>s?(e.addRange(n),e.extend(x.node,x.offset)):(n.setEnd(x.node,x.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,zr=null,ql=null,Ii=null,Zl=!1;function Hc(e,n,i){var s=i.window===i?i.document:i.nodeType===9?i:i.ownerDocument;Zl||zr==null||zr!==me(s)||(s=zr,"selectionStart"in s&&Kl(s)?s={start:s.selectionStart,end:s.selectionEnd}:(s=(s.ownerDocument&&s.ownerDocument.defaultView||window).getSelection(),s={anchorNode:s.anchorNode,anchorOffset:s.anchorOffset,focusNode:s.focusNode,focusOffset:s.focusOffset}),Ii&&Pi(Ii,s)||(Ii=s,s=Qo(ql,"onSelect"),0$r||(e.current=cu[$r],cu[$r]=null,$r--)}function Le(e,n){$r++,cu[$r]=e.current,e.current=n}var Tn={},tt=In(Tn),ct=In(!1),er=Tn;function Dr(e,n){var i=e.type.contextTypes;if(!i)return Tn;var s=e.stateNode;if(s&&s.__reactInternalMemoizedUnmaskedChildContext===n)return s.__reactInternalMemoizedMaskedChildContext;var a={},d;for(d in i)a[d]=n[d];return s&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=n,e.__reactInternalMemoizedMaskedChildContext=a),a}function ft(e){return e=e.childContextTypes,e!=null}function Zo(){Ae(ct),Ae(tt)}function tf(e,n,i){if(tt.current!==Tn)throw Error(o(168));Le(tt,n),Le(ct,i)}function nf(e,n,i){var s=e.stateNode;if(n=n.childContextTypes,typeof s.getChildContext!="function")return i;s=s.getChildContext();for(var a in s)if(!(a in n))throw Error(o(108,re(e)||"Unknown",a));return F({},i,s)}function Jo(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Tn,er=tt.current,Le(tt,e),Le(ct,ct.current),!0}function rf(e,n,i){var s=e.stateNode;if(!s)throw Error(o(169));i?(e=nf(e,n,er),s.__reactInternalMemoizedMergedChildContext=e,Ae(ct),Ae(tt),Le(tt,e)):Ae(ct),Le(ct,i)}var cn=null,es=!1,fu=!1;function of(e){cn===null?cn=[e]:cn.push(e)}function Fm(e){es=!0,of(e)}function zn(){if(!fu&&cn!==null){fu=!0;var e=0,n=ze;try{var i=cn;for(ze=1;e>=x,a-=x,fn=1<<32-xt(n)+a|i<Ee?(Ke=_e,_e=null):Ke=_e.sibling;var Te=oe(b,_e,Y[Ee],ae);if(Te===null){_e===null&&(_e=Ke);break}e&&_e&&Te.alternate===null&&n(b,_e),D=d(Te,D,Ee),Se===null?ye=Te:Se.sibling=Te,Se=Te,_e=Ke}if(Ee===Y.length)return i(b,_e),De&&nr(b,Ee),ye;if(_e===null){for(;EeEe?(Ke=_e,_e=null):Ke=_e.sibling;var Hn=oe(b,_e,Te.value,ae);if(Hn===null){_e===null&&(_e=Ke);break}e&&_e&&Hn.alternate===null&&n(b,_e),D=d(Hn,D,Ee),Se===null?ye=Hn:Se.sibling=Hn,Se=Hn,_e=Ke}if(Te.done)return i(b,_e),De&&nr(b,Ee),ye;if(_e===null){for(;!Te.done;Ee++,Te=Y.next())Te=ue(b,Te.value,ae),Te!==null&&(D=d(Te,D,Ee),Se===null?ye=Te:Se.sibling=Te,Se=Te);return De&&nr(b,Ee),ye}for(_e=s(b,_e);!Te.done;Ee++,Te=Y.next())Te=fe(_e,b,Ee,Te.value,ae),Te!==null&&(e&&Te.alternate!==null&&_e.delete(Te.key===null?Ee:Te.key),D=d(Te,D,Ee),Se===null?ye=Te:Se.sibling=Te,Se=Te);return e&&_e.forEach(function(x0){return n(b,x0)}),De&&nr(b,Ee),ye}function Ue(b,D,Y,ae){if(typeof Y=="object"&&Y!==null&&Y.type===V&&Y.key===null&&(Y=Y.props.children),typeof Y=="object"&&Y!==null){switch(Y.$$typeof){case W:e:{for(var ye=Y.key,Se=D;Se!==null;){if(Se.key===ye){if(ye=Y.type,ye===V){if(Se.tag===7){i(b,Se.sibling),D=a(Se,Y.props.children),D.return=b,b=D;break e}}else if(Se.elementType===ye||typeof ye=="object"&&ye!==null&&ye.$$typeof===H&&ff(ye)===Se.type){i(b,Se.sibling),D=a(Se,Y.props),D.ref=Ai(b,Se,Y),D.return=b,b=D;break e}i(b,Se);break}else n(b,Se);Se=Se.sibling}Y.type===V?(D=cr(Y.props.children,b.mode,ae,Y.key),D.return=b,b=D):(ae=Ps(Y.type,Y.key,Y.props,null,b.mode,ae),ae.ref=Ai(b,D,Y),ae.return=b,b=ae)}return x(b);case $:e:{for(Se=Y.key;D!==null;){if(D.key===Se)if(D.tag===4&&D.stateNode.containerInfo===Y.containerInfo&&D.stateNode.implementation===Y.implementation){i(b,D.sibling),D=a(D,Y.children||[]),D.return=b,b=D;break e}else{i(b,D);break}else n(b,D);D=D.sibling}D=ua(Y,b.mode,ae),D.return=b,b=D}return x(b);case H:return Se=Y._init,Ue(b,D,Se(Y._payload),ae)}if(Je(Y))return he(b,D,Y,ae);if(j(Y))return ge(b,D,Y,ae);is(b,Y)}return typeof Y=="string"&&Y!==""||typeof Y=="number"?(Y=""+Y,D!==null&&D.tag===6?(i(b,D.sibling),D=a(D,Y),D.return=b,b=D):(i(b,D),D=la(Y,b.mode,ae),D.return=b,b=D),x(b)):i(b,D)}return Ue}var Vr=df(!0),hf=df(!1),os=In(null),ss=null,Br=null,yu=null;function vu(){yu=Br=ss=null}function xu(e){var n=os.current;Ae(os),e._currentValue=n}function wu(e,n,i){for(;e!==null;){var s=e.alternate;if((e.childLanes&n)!==n?(e.childLanes|=n,s!==null&&(s.childLanes|=n)):s!==null&&(s.childLanes&n)!==n&&(s.childLanes|=n),e===i)break;e=e.return}}function Ur(e,n){ss=e,yu=Br=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&n)!==0&&(dt=!0),e.firstContext=null)}function Tt(e){var n=e._currentValue;if(yu!==e)if(e={context:e,memoizedValue:n,next:null},Br===null){if(ss===null)throw Error(o(308));Br=e,ss.dependencies={lanes:0,firstContext:e}}else Br=Br.next=e;return n}var rr=null;function Su(e){rr===null?rr=[e]:rr.push(e)}function pf(e,n,i,s){var a=n.interleaved;return a===null?(i.next=i,Su(n)):(i.next=a.next,a.next=i),n.interleaved=i,hn(e,s)}function hn(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 Rn=!1;function _u(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function gf(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 Ln(e,n,i){var s=e.updateQueue;if(s===null)return null;if(s=s.shared,(Pe&2)!==0){var a=s.pending;return a===null?n.next=n:(n.next=a.next,a.next=n),s.pending=n,hn(e,i)}return a=s.interleaved,a===null?(n.next=n,Su(s)):(n.next=a.next,a.next=n),s.interleaved=n,hn(e,i)}function ls(e,n,i){if(n=n.updateQueue,n!==null&&(n=n.shared,(i&4194240)!==0)){var s=n.lanes;s&=e.pendingLanes,i|=s,n.lanes=i,Mr(e,i)}}function mf(e,n){var i=e.updateQueue,s=e.alternate;if(s!==null&&(s=s.updateQueue,i===s)){var a=null,d=null;if(i=i.firstBaseUpdate,i!==null){do{var x={eventTime:i.eventTime,lane:i.lane,tag:i.tag,payload:i.payload,callback:i.callback,next:null};d===null?a=d=x:d=d.next=x,i=i.next}while(i!==null);d===null?a=d=n:d=d.next=n}else a=d=n;i={baseState:s.baseState,firstBaseUpdate:a,lastBaseUpdate:d,shared:s.shared,effects:s.effects},e.updateQueue=i;return}e=i.lastBaseUpdate,e===null?i.firstBaseUpdate=n:e.next=n,i.lastBaseUpdate=n}function us(e,n,i,s){var a=e.updateQueue;Rn=!1;var d=a.firstBaseUpdate,x=a.lastBaseUpdate,T=a.shared.pending;if(T!==null){a.shared.pending=null;var L=T,q=L.next;L.next=null,x===null?d=q:x.next=q,x=L;var se=e.alternate;se!==null&&(se=se.updateQueue,T=se.lastBaseUpdate,T!==x&&(T===null?se.firstBaseUpdate=q:T.next=q,se.lastBaseUpdate=L))}if(d!==null){var ue=a.baseState;x=0,se=q=L=null,T=d;do{var oe=T.lane,fe=T.eventTime;if((s&oe)===oe){se!==null&&(se=se.next={eventTime:fe,lane:0,tag:T.tag,payload:T.payload,callback:T.callback,next:null});e:{var he=e,ge=T;switch(oe=n,fe=i,ge.tag){case 1:if(he=ge.payload,typeof he=="function"){ue=he.call(fe,ue,oe);break e}ue=he;break e;case 3:he.flags=he.flags&-65537|128;case 0:if(he=ge.payload,oe=typeof he=="function"?he.call(fe,ue,oe):he,oe==null)break e;ue=F({},ue,oe);break e;case 2:Rn=!0}}T.callback!==null&&T.lane!==0&&(e.flags|=64,oe=a.effects,oe===null?a.effects=[T]:oe.push(T))}else fe={eventTime:fe,lane:oe,tag:T.tag,payload:T.payload,callback:T.callback,next:null},se===null?(q=se=fe,L=ue):se=se.next=fe,x|=oe;if(T=T.next,T===null){if(T=a.shared.pending,T===null)break;oe=T,T=oe.next,oe.next=null,a.lastBaseUpdate=oe,a.shared.pending=null}}while(!0);if(se===null&&(L=ue),a.baseState=L,a.firstBaseUpdate=q,a.lastBaseUpdate=se,n=a.shared.interleaved,n!==null){a=n;do x|=a.lane,a=a.next;while(a!==n)}else d===null&&(a.shared.lanes=0);sr|=x,e.lanes=x,e.memoizedState=ue}}function yf(e,n,i){if(e=n.effects,n.effects=null,e!==null)for(n=0;ni?i:4,e(!0);var s=Mu.transition;Mu.transition={};try{e(!1),n()}finally{ze=i,Mu.transition=s}}function $f(){return zt().memoizedState}function Um(e,n,i){var s=Dn(e);if(i={lane:s,action:i,hasEagerState:!1,eagerState:null,next:null},Df(e))Of(n,i);else if(i=pf(e,n,i,s),i!==null){var a=lt();Ft(i,e,s,a),Ff(i,n,s)}}function Wm(e,n,i){var s=Dn(e),a={lane:s,action:i,hasEagerState:!1,eagerState:null,next:null};if(Df(e))Of(n,a);else{var d=e.alternate;if(e.lanes===0&&(d===null||d.lanes===0)&&(d=n.lastRenderedReducer,d!==null))try{var x=n.lastRenderedState,T=d(x,i);if(a.hasEagerState=!0,a.eagerState=T,jt(T,x)){var L=n.interleaved;L===null?(a.next=a,Su(n)):(a.next=L.next,L.next=a),n.interleaved=a;return}}catch{}finally{}i=pf(e,n,a,s),i!==null&&(a=lt(),Ft(i,e,s,a),Ff(i,n,s))}}function Df(e){var n=e.alternate;return e===He||n!==null&&n===He}function Of(e,n){Fi=fs=!0;var i=e.pending;i===null?n.next=n:(n.next=i.next,i.next=n),e.pending=n}function Ff(e,n,i){if((i&4194240)!==0){var s=n.lanes;s&=e.pendingLanes,i|=s,n.lanes=i,Mr(e,i)}}var ps={readContext:Tt,useCallback:nt,useContext:nt,useEffect:nt,useImperativeHandle:nt,useInsertionEffect:nt,useLayoutEffect:nt,useMemo:nt,useReducer:nt,useRef:nt,useState:nt,useDebugValue:nt,useDeferredValue:nt,useTransition:nt,useMutableSource:nt,useSyncExternalStore:nt,useId:nt,unstable_isNewReconciler:!1},bm={readContext:Tt,useCallback:function(e,n){return en().memoizedState=[e,n===void 0?null:n],e},useContext:Tt,useEffect:Pf,useImperativeHandle:function(e,n,i){return i=i!=null?i.concat([e]):null,ds(4194308,4,zf.bind(null,n,e),i)},useLayoutEffect:function(e,n){return ds(4194308,4,e,n)},useInsertionEffect:function(e,n){return ds(4,2,e,n)},useMemo:function(e,n){var i=en();return n=n===void 0?null:n,e=e(),i.memoizedState=[e,n],e},useReducer:function(e,n,i){var s=en();return n=i!==void 0?i(n):n,s.memoizedState=s.baseState=n,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:n},s.queue=e,e=e.dispatch=Um.bind(null,He,e),[s.memoizedState,e]},useRef:function(e){var n=en();return e={current:e},n.memoizedState=e},useState:Cf,useDebugValue:ju,useDeferredValue:function(e){return en().memoizedState=e},useTransition:function(){var e=Cf(!1),n=e[0];return e=Bm.bind(null,e[1]),en().memoizedState=e,[n,e]},useMutableSource:function(){},useSyncExternalStore:function(e,n,i){var s=He,a=en();if(De){if(i===void 0)throw Error(o(407));i=i()}else{if(i=n(),Ge===null)throw Error(o(349));(or&30)!==0||Sf(s,n,i)}a.memoizedState=i;var d={value:i,getSnapshot:n};return a.queue=d,Pf(Ef.bind(null,s,d,e),[e]),s.flags|=2048,Bi(9,_f.bind(null,s,d,i,n),void 0,null),i},useId:function(){var e=en(),n=Ge.identifierPrefix;if(De){var i=dn,s=fn;i=(s&~(1<<32-xt(s)-1)).toString(32)+i,n=":"+n+"R"+i,i=Hi++,0<\/script>",e=e.removeChild(e.firstChild)):typeof s.is=="string"?e=x.createElement(i,{is:s.is}):(e=x.createElement(i),i==="select"&&(x=e,s.multiple?x.multiple=!0:s.size&&(x.size=s.size))):e=x.createElementNS(e,i),e[Zt]=n,e[Li]=s,od(e,n,!1,!1),n.stateNode=e;e:{switch(x=li(i,s),i){case"dialog":je("cancel",e),je("close",e),a=s;break;case"iframe":case"object":case"embed":je("load",e),a=s;break;case"video":case"audio":for(a=0;aQr&&(n.flags|=128,s=!0,Ui(d,!1),n.lanes=4194304)}else{if(!s)if(e=as(x),e!==null){if(n.flags|=128,s=!0,i=e.updateQueue,i!==null&&(n.updateQueue=i,n.flags|=4),Ui(d,!0),d.tail===null&&d.tailMode==="hidden"&&!x.alternate&&!De)return rt(n),null}else 2*Oe()-d.renderingStartTime>Qr&&i!==1073741824&&(n.flags|=128,s=!0,Ui(d,!1),n.lanes=4194304);d.isBackwards?(x.sibling=n.child,n.child=x):(i=d.last,i!==null?i.sibling=x:n.child=x,d.last=x)}return d.tail!==null?(n=d.tail,d.rendering=n,d.tail=n.sibling,d.renderingStartTime=Oe(),n.sibling=null,i=Fe.current,Le(Fe,s?i&1|2:i&1),n):(rt(n),null);case 22:case 23:return ia(),s=n.memoizedState!==null,e!==null&&e.memoizedState!==null!==s&&(n.flags|=8192),s&&(n.mode&1)!==0?(Et&1073741824)!==0&&(rt(n),n.subtreeFlags&6&&(n.flags|=8192)):rt(n),null;case 24:return null;case 25:return null}throw Error(o(156,n.tag))}function Jm(e,n){switch(hu(n),n.tag){case 1:return ft(n.type)&&Zo(),e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 3:return Wr(),Ae(ct),Ae(tt),Cu(),e=n.flags,(e&65536)!==0&&(e&128)===0?(n.flags=e&-65537|128,n):null;case 5:return ku(n),null;case 13:if(Ae(Fe),e=n.memoizedState,e!==null&&e.dehydrated!==null){if(n.alternate===null)throw Error(o(340));Hr()}return e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 19:return Ae(Fe),null;case 4:return Wr(),null;case 10:return xu(n.type._context),null;case 22:case 23:return ia(),null;case 24:return null;default:return null}}var vs=!1,it=!1,e0=typeof WeakSet=="function"?WeakSet:Set,de=null;function Yr(e,n){var i=e.ref;if(i!==null)if(typeof i=="function")try{i(null)}catch(s){Be(e,n,s)}else i.current=null}function Yu(e,n,i){try{i()}catch(s){Be(e,n,s)}}var ud=!1;function t0(e,n){if(iu=Oo,e=Fc(),Kl(e)){if("selectionStart"in e)var i={start:e.selectionStart,end:e.selectionEnd};else e:{i=(i=e.ownerDocument)&&i.defaultView||window;var s=i.getSelection&&i.getSelection();if(s&&s.rangeCount!==0){i=s.anchorNode;var a=s.anchorOffset,d=s.focusNode;s=s.focusOffset;try{i.nodeType,d.nodeType}catch{i=null;break e}var x=0,T=-1,L=-1,q=0,se=0,ue=e,oe=null;t:for(;;){for(var fe;ue!==i||a!==0&&ue.nodeType!==3||(T=x+a),ue!==d||s!==0&&ue.nodeType!==3||(L=x+s),ue.nodeType===3&&(x+=ue.nodeValue.length),(fe=ue.firstChild)!==null;)oe=ue,ue=fe;for(;;){if(ue===e)break t;if(oe===i&&++q===a&&(T=x),oe===d&&++se===s&&(L=x),(fe=ue.nextSibling)!==null)break;ue=oe,oe=ue.parentNode}ue=fe}i=T===-1||L===-1?null:{start:T,end:L}}else i=null}i=i||{start:0,end:0}}else i=null;for(ou={focusedElem:e,selectionRange:i},Oo=!1,de=n;de!==null;)if(n=de,e=n.child,(n.subtreeFlags&1028)!==0&&e!==null)e.return=n,de=e;else for(;de!==null;){n=de;try{var he=n.alternate;if((n.flags&1024)!==0)switch(n.tag){case 0:case 11:case 15:break;case 1:if(he!==null){var ge=he.memoizedProps,Ue=he.memoizedState,b=n.stateNode,D=b.getSnapshotBeforeUpdate(n.elementType===n.type?ge:$t(n.type,ge),Ue);b.__reactInternalSnapshotBeforeUpdate=D}break;case 3:var Y=n.stateNode.containerInfo;Y.nodeType===1?Y.textContent="":Y.nodeType===9&&Y.documentElement&&Y.removeChild(Y.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(o(163))}}catch(ae){Be(n,n.return,ae)}if(e=n.sibling,e!==null){e.return=n.return,de=e;break}de=n.return}return he=ud,ud=!1,he}function Wi(e,n,i){var s=n.updateQueue;if(s=s!==null?s.lastEffect:null,s!==null){var a=s=s.next;do{if((a.tag&e)===e){var d=a.destroy;a.destroy=void 0,d!==void 0&&Yu(n,i,d)}a=a.next}while(a!==s)}}function xs(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 s=i.create;i.destroy=s()}i=i.next}while(i!==n)}}function Xu(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 ad(e){var n=e.alternate;n!==null&&(e.alternate=null,ad(n)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(n=e.stateNode,n!==null&&(delete n[Zt],delete n[Li],delete n[au],delete n[Dm],delete n[Om])),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 cd(e){return e.tag===5||e.tag===3||e.tag===4}function fd(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||cd(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 Qu(e,n,i){var s=e.tag;if(s===5||s===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=Ko));else if(s!==4&&(e=e.child,e!==null))for(Qu(e,n,i),e=e.sibling;e!==null;)Qu(e,n,i),e=e.sibling}function Gu(e,n,i){var s=e.tag;if(s===5||s===6)e=e.stateNode,n?i.insertBefore(e,n):i.appendChild(e);else if(s!==4&&(e=e.child,e!==null))for(Gu(e,n,i),e=e.sibling;e!==null;)Gu(e,n,i),e=e.sibling}var qe=null,Dt=!1;function jn(e,n,i){for(i=i.child;i!==null;)dd(e,n,i),i=i.sibling}function dd(e,n,i){if(vt&&typeof vt.onCommitFiberUnmount=="function")try{vt.onCommitFiberUnmount(kr,i)}catch{}switch(i.tag){case 5:it||Yr(i,n);case 6:var s=qe,a=Dt;qe=null,jn(e,n,i),qe=s,Dt=a,qe!==null&&(Dt?(e=qe,i=i.stateNode,e.nodeType===8?e.parentNode.removeChild(i):e.removeChild(i)):qe.removeChild(i.stateNode));break;case 18:qe!==null&&(Dt?(e=qe,i=i.stateNode,e.nodeType===8?uu(e.parentNode,i):e.nodeType===1&&uu(e,i),_i(e)):uu(qe,i.stateNode));break;case 4:s=qe,a=Dt,qe=i.stateNode.containerInfo,Dt=!0,jn(e,n,i),qe=s,Dt=a;break;case 0:case 11:case 14:case 15:if(!it&&(s=i.updateQueue,s!==null&&(s=s.lastEffect,s!==null))){a=s=s.next;do{var d=a,x=d.destroy;d=d.tag,x!==void 0&&((d&2)!==0||(d&4)!==0)&&Yu(i,n,x),a=a.next}while(a!==s)}jn(e,n,i);break;case 1:if(!it&&(Yr(i,n),s=i.stateNode,typeof s.componentWillUnmount=="function"))try{s.props=i.memoizedProps,s.state=i.memoizedState,s.componentWillUnmount()}catch(T){Be(i,n,T)}jn(e,n,i);break;case 21:jn(e,n,i);break;case 22:i.mode&1?(it=(s=it)||i.memoizedState!==null,jn(e,n,i),it=s):jn(e,n,i);break;default:jn(e,n,i)}}function hd(e){var n=e.updateQueue;if(n!==null){e.updateQueue=null;var i=e.stateNode;i===null&&(i=e.stateNode=new e0),n.forEach(function(s){var a=c0.bind(null,e,s);i.has(s)||(i.add(s),s.then(a,a))})}}function Ot(e,n){var i=n.deletions;if(i!==null)for(var s=0;sa&&(a=x),s&=~d}if(s=a,s=Oe()-s,s=(120>s?120:480>s?480:1080>s?1080:1920>s?1920:3e3>s?3e3:4320>s?4320:1960*r0(s/1960))-s,10e?16:e,$n===null)var s=!1;else{if(e=$n,$n=null,ks=0,(Pe&6)!==0)throw Error(o(331));var a=Pe;for(Pe|=4,de=e.current;de!==null;){var d=de,x=d.child;if((de.flags&16)!==0){var T=d.deletions;if(T!==null){for(var L=0;LOe()-Zu?ur(e,0):qu|=i),pt(e,n)}function Cd(e,n){n===0&&((e.mode&1)===0?n=1:(n=Cr,Cr<<=1,(Cr&130023424)===0&&(Cr=4194304)));var i=lt();e=hn(e,n),e!==null&&(Zn(e,n,i),pt(e,i))}function a0(e){var n=e.memoizedState,i=0;n!==null&&(i=n.retryLane),Cd(e,i)}function c0(e,n){var i=0;switch(e.tag){case 13:var s=e.stateNode,a=e.memoizedState;a!==null&&(i=a.retryLane);break;case 19:s=e.stateNode;break;default:throw Error(o(314))}s!==null&&s.delete(n),Cd(e,i)}var Md;Md=function(e,n,i){if(e!==null)if(e.memoizedProps!==n.pendingProps||ct.current)dt=!0;else{if((e.lanes&i)===0&&(n.flags&128)===0)return dt=!1,qm(e,n,i);dt=(e.flags&131072)!==0}else dt=!1,De&&(n.flags&1048576)!==0&&sf(n,ns,n.index);switch(n.lanes=0,n.tag){case 2:var s=n.type;ys(e,n),e=n.pendingProps;var a=Dr(n,tt.current);Ur(n,i),a=Iu(null,n,s,e,a,i);var d=Tu();return n.flags|=1,typeof a=="object"&&a!==null&&typeof a.render=="function"&&a.$$typeof===void 0?(n.tag=1,n.memoizedState=null,n.updateQueue=null,ft(s)?(d=!0,Jo(n)):d=!1,n.memoizedState=a.state!==null&&a.state!==void 0?a.state:null,_u(n),a.updater=gs,n.stateNode=a,a._reactInternals=n,$u(n,s,e,i),n=Hu(null,n,s,!0,d,i)):(n.tag=0,De&&d&&du(n),st(null,n,a,i),n=n.child),n;case 16:s=n.elementType;e:{switch(ys(e,n),e=n.pendingProps,a=s._init,s=a(s._payload),n.type=s,a=n.tag=d0(s),e=$t(s,e),a){case 0:n=Fu(null,n,s,e,i);break e;case 1:n=Jf(null,n,s,e,i);break e;case 11:n=Qf(null,n,s,e,i);break e;case 14:n=Gf(null,n,s,$t(s.type,e),i);break e}throw Error(o(306,s,""))}return n;case 0:return s=n.type,a=n.pendingProps,a=n.elementType===s?a:$t(s,a),Fu(e,n,s,a,i);case 1:return s=n.type,a=n.pendingProps,a=n.elementType===s?a:$t(s,a),Jf(e,n,s,a,i);case 3:e:{if(ed(n),e===null)throw Error(o(387));s=n.pendingProps,d=n.memoizedState,a=d.element,gf(e,n),us(n,s,null,i);var x=n.memoizedState;if(s=x.element,d.isDehydrated)if(d={element:s,isDehydrated:!1,cache:x.cache,pendingSuspenseBoundaries:x.pendingSuspenseBoundaries,transitions:x.transitions},n.updateQueue.baseState=d,n.memoizedState=d,n.flags&256){a=br(Error(o(423)),n),n=td(e,n,s,i,a);break e}else if(s!==a){a=br(Error(o(424)),n),n=td(e,n,s,i,a);break e}else for(_t=Pn(n.stateNode.containerInfo.firstChild),St=n,De=!0,At=null,i=hf(n,null,s,i),n.child=i;i;)i.flags=i.flags&-3|4096,i=i.sibling;else{if(Hr(),s===a){n=gn(e,n,i);break e}st(e,n,s,i)}n=n.child}return n;case 5:return vf(n),e===null&&gu(n),s=n.type,a=n.pendingProps,d=e!==null?e.memoizedProps:null,x=a.children,su(s,a)?x=null:d!==null&&su(s,d)&&(n.flags|=32),Zf(e,n),st(e,n,x,i),n.child;case 6:return e===null&&gu(n),null;case 13:return nd(e,n,i);case 4:return Eu(n,n.stateNode.containerInfo),s=n.pendingProps,e===null?n.child=Vr(n,null,s,i):st(e,n,s,i),n.child;case 11:return s=n.type,a=n.pendingProps,a=n.elementType===s?a:$t(s,a),Qf(e,n,s,a,i);case 7:return st(e,n,n.pendingProps,i),n.child;case 8:return st(e,n,n.pendingProps.children,i),n.child;case 12:return st(e,n,n.pendingProps.children,i),n.child;case 10:e:{if(s=n.type._context,a=n.pendingProps,d=n.memoizedProps,x=a.value,Le(os,s._currentValue),s._currentValue=x,d!==null)if(jt(d.value,x)){if(d.children===a.children&&!ct.current){n=gn(e,n,i);break e}}else for(d=n.child,d!==null&&(d.return=n);d!==null;){var T=d.dependencies;if(T!==null){x=d.child;for(var L=T.firstContext;L!==null;){if(L.context===s){if(d.tag===1){L=pn(-1,i&-i),L.tag=2;var q=d.updateQueue;if(q!==null){q=q.shared;var se=q.pending;se===null?L.next=L:(L.next=se.next,se.next=L),q.pending=L}}d.lanes|=i,L=d.alternate,L!==null&&(L.lanes|=i),wu(d.return,i,n),T.lanes|=i;break}L=L.next}}else if(d.tag===10)x=d.type===n.type?null:d.child;else if(d.tag===18){if(x=d.return,x===null)throw Error(o(341));x.lanes|=i,T=x.alternate,T!==null&&(T.lanes|=i),wu(x,i,n),x=d.sibling}else x=d.child;if(x!==null)x.return=d;else for(x=d;x!==null;){if(x===n){x=null;break}if(d=x.sibling,d!==null){d.return=x.return,x=d;break}x=x.return}d=x}st(e,n,a.children,i),n=n.child}return n;case 9:return a=n.type,s=n.pendingProps.children,Ur(n,i),a=Tt(a),s=s(a),n.flags|=1,st(e,n,s,i),n.child;case 14:return s=n.type,a=$t(s,n.pendingProps),a=$t(s.type,a),Gf(e,n,s,a,i);case 15:return Kf(e,n,n.type,n.pendingProps,i);case 17:return s=n.type,a=n.pendingProps,a=n.elementType===s?a:$t(s,a),ys(e,n),n.tag=1,ft(s)?(e=!0,Jo(n)):e=!1,Ur(n,i),Vf(n,s,a),$u(n,s,a,i),Hu(null,n,s,!0,e,i);case 19:return id(e,n,i);case 22:return qf(e,n,i)}throw Error(o(156,n.tag))};function Pd(e,n){return Io(e,n)}function f0(e,n,i,s){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=s,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Lt(e,n,i,s){return new f0(e,n,i,s)}function sa(e){return e=e.prototype,!(!e||!e.isReactComponent)}function d0(e){if(typeof e=="function")return sa(e)?1:0;if(e!=null){if(e=e.$$typeof,e===ee)return 11;if(e===B)return 14}return 2}function Fn(e,n){var i=e.alternate;return i===null?(i=Lt(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 Ps(e,n,i,s,a,d){var x=2;if(s=e,typeof e=="function")sa(e)&&(x=1);else if(typeof e=="string")x=5;else e:switch(e){case V:return cr(i.children,a,d,n);case X:x=8,a|=8;break;case K:return e=Lt(12,i,n,a|2),e.elementType=K,e.lanes=d,e;case J:return e=Lt(13,i,n,a),e.elementType=J,e.lanes=d,e;case k:return e=Lt(19,i,n,a),e.elementType=k,e.lanes=d,e;case U:return Is(i,a,d,n);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case te:x=10;break e;case Z:x=9;break e;case ee:x=11;break e;case B:x=14;break e;case H:x=16,s=null;break e}throw Error(o(130,e==null?e:typeof e,""))}return n=Lt(x,i,n,a),n.elementType=e,n.type=s,n.lanes=d,n}function cr(e,n,i,s){return e=Lt(7,e,s,n),e.lanes=i,e}function Is(e,n,i,s){return e=Lt(22,e,s,n),e.elementType=U,e.lanes=i,e.stateNode={isHidden:!1},e}function la(e,n,i){return e=Lt(6,e,null,n),e.lanes=i,e}function ua(e,n,i){return n=Lt(4,e.children!==null?e.children:[],e.key,n),n.lanes=i,n.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},n}function h0(e,n,i,s,a){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=qn(0),this.expirationTimes=qn(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=qn(0),this.identifierPrefix=s,this.onRecoverableError=a,this.mutableSourceEagerHydrationData=null}function aa(e,n,i,s,a,d,x,T,L){return e=new h0(e,n,i,T,L),n===1?(n=1,d===!0&&(n|=8)):n=0,d=Lt(3,null,null,n),e.current=d,d.stateNode=e,d.memoizedState={element:s,isDehydrated:i,cache:null,transitions:null,pendingSuspenseBoundaries:null},_u(d),e}function p0(e,n,i){var s=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(r){console.error(r)}}return t(),ga.exports=C0(),ga.exports}var Bd;function M0(){if(Bd)return $s;Bd=1;var t=Jh();return $s.createRoot=t.createRoot,$s.hydrateRoot=t.hydrateRoot,$s}var P0=M0();async function Ht(t,r){const o=await fetch(t,{...r,headers:{"Content-Type":"application/json",...(r==null?void 0:r.headers)||{}}});if(!o.ok){const l=await o.text();throw new Error(l||o.statusText)}return o.json()}const Vt={health:()=>Ht("/api/health"),settings:()=>Ht("/api/settings"),saveSettings:t=>Ht("/api/settings",{method:"PUT",body:JSON.stringify(t)}),repos:()=>Ht("/api/repos"),index:(t,r=!0)=>Ht("/api/index",{method:"POST",body:JSON.stringify({repo_path:t,incremental:r})}),indexStatus:t=>Ht(`/api/index?repo_path=${encodeURIComponent(t)}`),architecture:t=>Ht(`/api/architecture?repo_path=${encodeURIComponent(t)}`),review:(t,r,o,l=!0)=>Ht("/api/review",{method:"POST",body:JSON.stringify({repo_path:t,base:r,head:o||null,reindex:l,incremental:!0})}),graph:(t,r="full")=>Ht(`/api/graph?repo_path=${encodeURIComponent(t)}&scope=${r}`),prs:(t,r,o="open")=>Ht("/api/prs",{method:"POST",body:JSON.stringify({provider:t,repo:r,state:o})}),residual:t=>Ht("/api/ai/residual",{method:"POST",body:JSON.stringify({review:t})})};function be(t){if(typeof t=="string"||typeof t=="number")return""+t;let r="";if(Array.isArray(t))for(let o=0,l;o{}};function al(){for(var t=0,r=arguments.length,o={},l;t=0&&(l=o.slice(u+1),o=o.slice(0,u)),o&&!r.hasOwnProperty(o))throw new Error("unknown type: "+o);return{type:o,name:l}})}Ys.prototype=al.prototype={constructor:Ys,on:function(t,r){var o=this._,l=T0(t+"",o),u,c=-1,f=l.length;if(arguments.length<2){for(;++c0)for(var o=new Array(u),l=0,u,c;l=0&&(r=t.slice(0,o))!=="xmlns"&&(t=t.slice(o+1)),Wd.hasOwnProperty(r)?{space:Wd[r],local:t}:t}function R0(t){return function(){var r=this.ownerDocument,o=this.namespaceURI;return o===Ra&&r.documentElement.namespaceURI===Ra?r.createElement(t):r.createElementNS(o,t)}}function L0(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function ep(t){var r=cl(t);return(r.local?L0:R0)(r)}function j0(){}function Ya(t){return t==null?j0:function(){return this.querySelector(t)}}function A0(t){typeof t!="function"&&(t=Ya(t));for(var r=this._groups,o=r.length,l=new Array(o),u=0;u=_&&(_=R+1);!(W=N[_])&&++_=0;)(f=l[u])&&(c&&f.compareDocumentPosition(c)^4&&c.parentNode.insertBefore(f,c),c=f);return this}function sy(t){t||(t=ly);function r(v,g){return v&&g?t(v.__data__,g.__data__):!v-!g}for(var o=this._groups,l=o.length,u=new Array(l),c=0;cr?1:t>=r?0:NaN}function uy(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this}function ay(){return Array.from(this)}function cy(){for(var t=this._groups,r=0,o=t.length;r1?this.each((r==null?Sy:typeof r=="function"?Ey:_y)(t,r,o??"")):ei(this.node(),t)}function ei(t,r){return t.style.getPropertyValue(r)||op(t).getComputedStyle(t,null).getPropertyValue(r)}function Ny(t){return function(){delete this[t]}}function Cy(t,r){return function(){this[t]=r}}function My(t,r){return function(){var o=r.apply(this,arguments);o==null?delete this[t]:this[t]=o}}function Py(t,r){return arguments.length>1?this.each((r==null?Ny:typeof r=="function"?My:Cy)(t,r)):this.node()[t]}function sp(t){return t.trim().split(/^|\s+/)}function Xa(t){return t.classList||new lp(t)}function lp(t){this._node=t,this._names=sp(t.getAttribute("class")||"")}lp.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 up(t,r){for(var o=Xa(t),l=-1,u=r.length;++l=0&&(o=r.slice(l+1),r=r.slice(0,l)),{type:r,name:o}})}function nv(t){return function(){var r=this.__on;if(r){for(var o=0,l=-1,u=r.length,c;o()=>t;function La(t,{sourceEvent:r,subject:o,target:l,identifier:u,active:c,x:f,y:h,dx:p,dy:y,dispatch:m}){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:l,enumerable:!0,configurable:!0},identifier:{value:u,enumerable:!0,configurable:!0},active:{value:c,enumerable:!0,configurable:!0},x:{value:f,enumerable:!0,configurable:!0},y:{value:h,enumerable:!0,configurable:!0},dx:{value:p,enumerable:!0,configurable:!0},dy:{value:y,enumerable:!0,configurable:!0},_:{value:m}})}La.prototype.on=function(){var t=this._.on.apply(this._,arguments);return t===this._?this:t};function dv(t){return!t.ctrlKey&&!t.button}function hv(){return this.parentNode}function pv(t,r){return r??{x:t.x,y:t.y}}function gv(){return navigator.maxTouchPoints||"ontouchstart"in this}function pp(){var t=dv,r=hv,o=pv,l=gv,u={},c=al("start","drag","end"),f=0,h,p,y,m,v=0;function g(I){I.on("mousedown.drag",w).filter(l).on("touchstart.drag",N).on("touchmove.drag",E,fv).on("touchend.drag touchcancel.drag",R).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function w(I,W){if(!(m||!t.call(this,I,W))){var $=_(this,r.call(this,I,W),I,W,"mouse");$&&(kt(I.view).on("mousemove.drag",S,no).on("mouseup.drag",M,no),dp(I.view),va(I),y=!1,h=I.clientX,p=I.clientY,$("start",I))}}function S(I){if(Zr(I),!y){var W=I.clientX-h,$=I.clientY-p;y=W*W+$*$>v}u.mouse("drag",I)}function M(I){kt(I.view).on("mousemove.drag mouseup.drag",null),hp(I.view,y),Zr(I),u.mouse("end",I)}function N(I,W){if(t.call(this,I,W)){var $=I.changedTouches,V=r.call(this,I,W),X=$.length,K,te;for(K=0;K>8&15|r>>4&240,r>>4&15|r&240,(r&15)<<4|r&15,1):o===8?Os(r>>24&255,r>>16&255,r>>8&255,(r&255)/255):o===4?Os(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=yv.exec(t))?new mt(r[1],r[2],r[3],1):(r=vv.exec(t))?new mt(r[1]*255/100,r[2]*255/100,r[3]*255/100,1):(r=xv.exec(t))?Os(r[1],r[2],r[3],r[4]):(r=wv.exec(t))?Os(r[1]*255/100,r[2]*255/100,r[3]*255/100,r[4]):(r=Sv.exec(t))?qd(r[1],r[2]/100,r[3]/100,1):(r=_v.exec(t))?qd(r[1],r[2]/100,r[3]/100,r[4]):bd.hasOwnProperty(t)?Qd(bd[t]):t==="transparent"?new mt(NaN,NaN,NaN,0):null}function Qd(t){return new mt(t>>16&255,t>>8&255,t&255,1)}function Os(t,r,o,l){return l<=0&&(t=r=o=NaN),new mt(t,r,o,l)}function Nv(t){return t instanceof po||(t=gr(t)),t?(t=t.rgb(),new mt(t.r,t.g,t.b,t.opacity)):new mt}function ja(t,r,o,l){return arguments.length===1?Nv(t):new mt(t,r,o,l??1)}function mt(t,r,o,l){this.r=+t,this.g=+r,this.b=+o,this.opacity=+l}Qa(mt,ja,gp(po,{brighter(t){return t=t==null?Zs:Math.pow(Zs,t),new mt(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=t==null?ro:Math.pow(ro,t),new mt(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new mt(hr(this.r),hr(this.g),hr(this.b),Js(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:Gd,formatHex:Gd,formatHex8:Cv,formatRgb:Kd,toString:Kd}));function Gd(){return`#${dr(this.r)}${dr(this.g)}${dr(this.b)}`}function Cv(){return`#${dr(this.r)}${dr(this.g)}${dr(this.b)}${dr((isNaN(this.opacity)?1:this.opacity)*255)}`}function Kd(){const t=Js(this.opacity);return`${t===1?"rgb(":"rgba("}${hr(this.r)}, ${hr(this.g)}, ${hr(this.b)}${t===1?")":`, ${t})`}`}function Js(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function hr(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function dr(t){return t=hr(t),(t<16?"0":"")+t.toString(16)}function qd(t,r,o,l){return l<=0?t=r=o=NaN:o<=0||o>=1?t=r=NaN:r<=0&&(t=NaN),new Ut(t,r,o,l)}function mp(t){if(t instanceof Ut)return new Ut(t.h,t.s,t.l,t.opacity);if(t instanceof po||(t=gr(t)),!t)return new Ut;if(t instanceof Ut)return t;t=t.rgb();var r=t.r/255,o=t.g/255,l=t.b/255,u=Math.min(r,o,l),c=Math.max(r,o,l),f=NaN,h=c-u,p=(c+u)/2;return h?(r===c?f=(o-l)/h+(o0&&p<1?0:f,new Ut(f,h,p,t.opacity)}function Mv(t,r,o,l){return arguments.length===1?mp(t):new Ut(t,r,o,l??1)}function Ut(t,r,o,l){this.h=+t,this.s=+r,this.l=+o,this.opacity=+l}Qa(Ut,Mv,gp(po,{brighter(t){return t=t==null?Zs:Math.pow(Zs,t),new Ut(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=t==null?ro:Math.pow(ro,t),new Ut(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,l=o+(o<.5?o:1-o)*r,u=2*o-l;return new mt(xa(t>=240?t-240:t+120,u,l),xa(t,u,l),xa(t<120?t+240:t-120,u,l),this.opacity)},clamp(){return new Ut(Zd(this.h),Fs(this.s),Fs(this.l),Js(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=Js(this.opacity);return`${t===1?"hsl(":"hsla("}${Zd(this.h)}, ${Fs(this.s)*100}%, ${Fs(this.l)*100}%${t===1?")":`, ${t})`}`}}));function Zd(t){return t=(t||0)%360,t<0?t+360:t}function Fs(t){return Math.max(0,Math.min(1,t||0))}function xa(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 Ga=t=>()=>t;function Pv(t,r){return function(o){return t+o*r}}function Iv(t,r,o){return t=Math.pow(t,o),r=Math.pow(r,o)-t,o=1/o,function(l){return Math.pow(t+l*r,o)}}function Tv(t){return(t=+t)==1?yp:function(r,o){return o-r?Iv(r,o,t):Ga(isNaN(r)?o:r)}}function yp(t,r){var o=r-t;return o?Pv(t,o):Ga(isNaN(t)?r:t)}const el=(function t(r){var o=Tv(r);function l(u,c){var f=o((u=ja(u)).r,(c=ja(c)).r),h=o(u.g,c.g),p=o(u.b,c.b),y=yp(u.opacity,c.opacity);return function(m){return u.r=f(m),u.g=h(m),u.b=p(m),u.opacity=y(m),u+""}}return l.gamma=t,l})(1);function zv(t,r){r||(r=[]);var o=t?Math.min(r.length,t.length):0,l=r.slice(),u;return function(c){for(u=0;uo&&(c=r.slice(o,c),h[f]?h[f]+=c:h[++f]=c),(l=l[0])===(u=u[0])?h[f]?h[f]+=u:h[++f]=u:(h[++f]=null,p.push({i:f,x:nn(l,u)})),o=wa.lastIndex;return o180?m+=360:m-y>180&&(y+=360),g.push({i:v.push(u(v)+"rotate(",null,l)-2,x:nn(y,m)})):m&&v.push(u(v)+"rotate("+m+l)}function h(y,m,v,g){y!==m?g.push({i:v.push(u(v)+"skewX(",null,l)-2,x:nn(y,m)}):m&&v.push(u(v)+"skewX("+m+l)}function p(y,m,v,g,w,S){if(y!==v||m!==g){var M=w.push(u(w)+"scale(",null,",",null,")");S.push({i:M-4,x:nn(y,v)},{i:M-2,x:nn(m,g)})}else(v!==1||g!==1)&&w.push(u(w)+"scale("+v+","+g+")")}return function(y,m){var v=[],g=[];return y=t(y),m=t(m),c(y.translateX,y.translateY,m.translateX,m.translateY,v,g),f(y.rotate,m.rotate,v,g),h(y.skewX,m.skewX,v,g),p(y.scaleX,y.scaleY,m.scaleX,m.scaleY,v,g),y=m=null,function(w){for(var S=-1,M=g.length,N;++S=0&&t._call.call(void 0,r),t=t._next;--ti}function th(){mr=(nl=oo.now())+fl,ti=Zi=0;try{Yv()}finally{ti=0,Qv(),mr=0}}function Xv(){var t=oo.now(),r=t-nl;r>Sp&&(fl-=r,nl=t)}function Qv(){for(var t,r=tl,o,l=1/0;r;)r._call?(l>r._time&&(l=r._time),t=r,r=r._next):(o=r._next,r._next=null,r=t?t._next=o:tl=o);Ji=t,Da(l)}function Da(t){if(!ti){Zi&&(Zi=clearTimeout(Zi));var r=t-mr;r>24?(t<1/0&&(Zi=setTimeout(th,t-oo.now()-fl)),Ki&&(Ki=clearInterval(Ki))):(Ki||(nl=oo.now(),Ki=setInterval(Xv,Sp)),ti=1,_p(th))}}function nh(t,r,o){var l=new rl;return r=r==null?0:+r,l.restart(u=>{l.stop(),t(u+r)},r,o),l}var Gv=al("start","end","cancel","interrupt"),Kv=[],kp=0,rh=1,Oa=2,Qs=3,ih=4,Fa=5,Gs=6;function dl(t,r,o,l,u,c){var f=t.__transition;if(!f)t.__transition={};else if(o in f)return;qv(t,o,{name:r,index:l,group:u,on:Gv,tween:Kv,time:c.time,delay:c.delay,duration:c.duration,ease:c.ease,timer:null,state:kp})}function qa(t,r){var o=Xt(t,r);if(o.state>kp)throw new Error("too late; already scheduled");return o}function on(t,r){var o=Xt(t,r);if(o.state>Qs)throw new Error("too late; already running");return o}function Xt(t,r){var o=t.__transition;if(!o||!(o=o[r]))throw new Error("transition not found");return o}function qv(t,r,o){var l=t.__transition,u;l[r]=o,o.timer=Ep(c,0,o.time);function c(y){o.state=rh,o.timer.restart(f,o.delay,o.time),o.delay<=y&&f(y-o.delay)}function f(y){var m,v,g,w;if(o.state!==rh)return p();for(m in l)if(w=l[m],w.name===o.name){if(w.state===Qs)return nh(f);w.state===ih?(w.state=Gs,w.timer.stop(),w.on.call("interrupt",t,t.__data__,w.index,w.group),delete l[m]):+mOa&&l.state=0&&(r=r.slice(0,o)),!r||r==="start"})}function Mx(t,r,o){var l,u,c=Cx(r)?qa:on;return function(){var f=c(this,t),h=f.on;h!==l&&(u=(l=h).copy()).on(r,o),f.on=u}}function Px(t,r){var o=this._id;return arguments.length<2?Xt(this.node(),o).on.on(t):this.each(Mx(o,t,r))}function Ix(t){return function(){var r=this.parentNode;for(var o in this.__transition)if(+o!==t)return;r&&r.removeChild(this)}}function Tx(){return this.on("end.remove",Ix(this._id))}function zx(t){var r=this._name,o=this._id;typeof t!="function"&&(t=Ya(t));for(var l=this._groups,u=l.length,c=new Array(u),f=0;f()=>t;function nw(t,{sourceEvent:r,target:o,transform:l,dispatch:u}){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:l,enumerable:!0,configurable:!0},_:{value:u}})}function vn(t,r,o){this.k=t,this.x=r,this.y=o}vn.prototype={constructor:vn,scale:function(t){return t===1?this:new vn(this.k*t,this.x,this.y)},translate:function(t,r){return t===0&r===0?this:new vn(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 hl=new vn(1,0,0);Pp.prototype=vn.prototype;function Pp(t){for(;!t.__zoom;)if(!(t=t.parentNode))return hl;return t.__zoom}function Sa(t){t.stopImmediatePropagation()}function qi(t){t.preventDefault(),t.stopImmediatePropagation()}function rw(t){return(!t.ctrlKey||t.type==="wheel")&&!t.button}function iw(){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 oh(){return this.__zoom||hl}function ow(t){return-t.deltaY*(t.deltaMode===1?.05:t.deltaMode?1:.002)*(t.ctrlKey?10:1)}function sw(){return navigator.maxTouchPoints||"ontouchstart"in this}function lw(t,r,o){var l=t.invertX(r[0][0])-o[0][0],u=t.invertX(r[1][0])-o[1][0],c=t.invertY(r[0][1])-o[0][1],f=t.invertY(r[1][1])-o[1][1];return t.translate(u>l?(l+u)/2:Math.min(0,l)||Math.max(0,u),f>c?(c+f)/2:Math.min(0,c)||Math.max(0,f))}function Ip(){var t=rw,r=iw,o=lw,l=ow,u=sw,c=[0,1/0],f=[[-1/0,-1/0],[1/0,1/0]],h=250,p=Xs,y=al("start","zoom","end"),m,v,g,w=500,S=150,M=0,N=10;function E(k){k.property("__zoom",oh).on("wheel.zoom",X,{passive:!1}).on("mousedown.zoom",K).on("dblclick.zoom",te).filter(u).on("touchstart.zoom",Z).on("touchmove.zoom",ee).on("touchend.zoom touchcancel.zoom",J).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}E.transform=function(k,B,H,U){var A=k.selection?k.selection():k;A.property("__zoom",oh),k!==A?W(k,B,H,U):A.interrupt().each(function(){$(this,arguments).event(U).start().zoom(null,typeof B=="function"?B.apply(this,arguments):B).end()})},E.scaleBy=function(k,B,H,U){E.scaleTo(k,function(){var A=this.__zoom.k,j=typeof B=="function"?B.apply(this,arguments):B;return A*j},H,U)},E.scaleTo=function(k,B,H,U){E.transform(k,function(){var A=r.apply(this,arguments),j=this.__zoom,F=H==null?I(A):typeof H=="function"?H.apply(this,arguments):H,C=j.invert(F),z=typeof B=="function"?B.apply(this,arguments):B;return o(_(R(j,z),F,C),A,f)},H,U)},E.translateBy=function(k,B,H,U){E.transform(k,function(){return o(this.__zoom.translate(typeof B=="function"?B.apply(this,arguments):B,typeof H=="function"?H.apply(this,arguments):H),r.apply(this,arguments),f)},null,U)},E.translateTo=function(k,B,H,U,A){E.transform(k,function(){var j=r.apply(this,arguments),F=this.__zoom,C=U==null?I(j):typeof U=="function"?U.apply(this,arguments):U;return o(hl.translate(C[0],C[1]).scale(F.k).translate(typeof B=="function"?-B.apply(this,arguments):-B,typeof H=="function"?-H.apply(this,arguments):-H),j,f)},U,A)};function R(k,B){return B=Math.max(c[0],Math.min(c[1],B)),B===k.k?k:new vn(B,k.x,k.y)}function _(k,B,H){var U=B[0]-H[0]*k.k,A=B[1]-H[1]*k.k;return U===k.x&&A===k.y?k:new vn(k.k,U,A)}function I(k){return[(+k[0][0]+ +k[1][0])/2,(+k[0][1]+ +k[1][1])/2]}function W(k,B,H,U){k.on("start.zoom",function(){$(this,arguments).event(U).start()}).on("interrupt.zoom end.zoom",function(){$(this,arguments).event(U).end()}).tween("zoom",function(){var A=this,j=arguments,F=$(A,j).event(U),C=r.apply(A,j),z=H==null?I(C):typeof H=="function"?H.apply(A,j):H,ne=Math.max(C[1][0]-C[0][0],C[1][1]-C[0][1]),ie=A.__zoom,ce=typeof B=="function"?B.apply(A,j):B,O=p(ie.invert(z).concat(ne/ie.k),ce.invert(z).concat(ne/ce.k));return function(re){if(re===1)re=ce;else{var Q=O(re),le=ne/Q[2];re=new vn(le,z[0]-Q[0]*le,z[1]-Q[1]*le)}F.zoom(null,re)}})}function $(k,B,H){return!H&&k.__zooming||new V(k,B)}function V(k,B){this.that=k,this.args=B,this.active=0,this.sourceEvent=null,this.extent=r.apply(k,B),this.taps=0}V.prototype={event:function(k){return k&&(this.sourceEvent=k),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(k,B){return this.mouse&&k!=="mouse"&&(this.mouse[1]=B.invert(this.mouse[0])),this.touch0&&k!=="touch"&&(this.touch0[1]=B.invert(this.touch0[0])),this.touch1&&k!=="touch"&&(this.touch1[1]=B.invert(this.touch1[0])),this.that.__zoom=B,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(k){var B=kt(this.that).datum();y.call(k,this.that,new nw(k,{sourceEvent:this.sourceEvent,target:E,transform:this.that.__zoom,dispatch:y}),B)}};function X(k,...B){if(!t.apply(this,arguments))return;var H=$(this,B).event(k),U=this.__zoom,A=Math.max(c[0],Math.min(c[1],U.k*Math.pow(2,l.apply(this,arguments)))),j=Bt(k);if(H.wheel)(H.mouse[0][0]!==j[0]||H.mouse[0][1]!==j[1])&&(H.mouse[1]=U.invert(H.mouse[0]=j)),clearTimeout(H.wheel);else{if(U.k===A)return;H.mouse=[j,U.invert(j)],Ks(this),H.start()}qi(k),H.wheel=setTimeout(F,S),H.zoom("mouse",o(_(R(U,A),H.mouse[0],H.mouse[1]),H.extent,f));function F(){H.wheel=null,H.end()}}function K(k,...B){if(g||!t.apply(this,arguments))return;var H=k.currentTarget,U=$(this,B,!0).event(k),A=kt(k.view).on("mousemove.zoom",z,!0).on("mouseup.zoom",ne,!0),j=Bt(k,H),F=k.clientX,C=k.clientY;dp(k.view),Sa(k),U.mouse=[j,this.__zoom.invert(j)],Ks(this),U.start();function z(ie){if(qi(ie),!U.moved){var ce=ie.clientX-F,O=ie.clientY-C;U.moved=ce*ce+O*O>M}U.event(ie).zoom("mouse",o(_(U.that.__zoom,U.mouse[0]=Bt(ie,H),U.mouse[1]),U.extent,f))}function ne(ie){A.on("mousemove.zoom mouseup.zoom",null),hp(ie.view,U.moved),qi(ie),U.event(ie).end()}}function te(k,...B){if(t.apply(this,arguments)){var H=this.__zoom,U=Bt(k.changedTouches?k.changedTouches[0]:k,this),A=H.invert(U),j=H.k*(k.shiftKey?.5:2),F=o(_(R(H,j),U,A),r.apply(this,B),f);qi(k),h>0?kt(this).transition().duration(h).call(W,F,U,k):kt(this).call(E.transform,F,U,k)}}function Z(k,...B){if(t.apply(this,arguments)){var H=k.touches,U=H.length,A=$(this,B,k.changedTouches.length===U).event(k),j,F,C,z;for(Sa(k),F=0;F`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:l})=>`Couldn't create edge for ${t} handle id: "${t==="source"?o:l}", 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.`},so=[[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]],Tp=["Enter"," ","Escape"],zp={"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 ni;(function(t){t.Strict="strict",t.Loose="loose"})(ni||(ni={}));var pr;(function(t){t.Free="free",t.Vertical="vertical",t.Horizontal="horizontal"})(pr||(pr={}));var lo;(function(t){t.Partial="partial",t.Full="full"})(lo||(lo={}));const Rp={inProgress:!1,isValid:null,from:null,fromHandle:null,fromPosition:null,fromNode:null,to:null,toHandle:null,toPosition:null,toNode:null,pointer:null};var Wn;(function(t){t.Bezier="default",t.Straight="straight",t.Step="step",t.SmoothStep="smoothstep",t.SimpleBezier="simplebezier"})(Wn||(Wn={}));var il;(function(t){t.Arrow="arrow",t.ArrowClosed="arrowclosed"})(il||(il={}));var xe;(function(t){t.Left="left",t.Top="top",t.Right="right",t.Bottom="bottom"})(xe||(xe={}));const sh={[xe.Left]:xe.Right,[xe.Right]:xe.Left,[xe.Top]:xe.Bottom,[xe.Bottom]:xe.Top};function Lp(t){return t===null?null:t?"valid":"invalid"}const jp=t=>!!t&&typeof t=="object"&&"id"in t&&"source"in t&&"target"in t,uw=t=>!!t&&typeof t=="object"&&"id"in t&&"position"in t&&!("source"in t)&&!("target"in t),Ja=t=>!!t&&typeof t=="object"&&"id"in t&&"internals"in t&&!("source"in t)&&!("target"in t),go=(t,r=[0,0])=>{const{width:o,height:l}=Qt(t),u=t.origin??r,c=o*u[0],f=l*u[1];return{x:t.position.x-c,y:t.position.y-f}},aw=(t,r={nodeOrigin:[0,0]})=>{if(t.length===0)return{x:0,y:0,width:0,height:0};let o=!1;const l=t.reduce((u,c)=>{const f=typeof c=="string";let h=!r.nodeLookup&&!f?c:void 0;return r.nodeLookup&&(h=f?r.nodeLookup.get(c):Ja(c)?c:r.nodeLookup.get(c.id)),h?(o=!0,pl(u,ol(h,r.nodeOrigin))):u},{x:1/0,y:1/0,x2:-1/0,y2:-1/0});return o?gl(l):{x:0,y:0,width:0,height:0}},mo=(t,r={})=>{let o={x:1/0,y:1/0,x2:-1/0,y2:-1/0},l=!1;return t.forEach(u=>{(r.filter===void 0||r.filter(u))&&(o=pl(o,ol(u)),l=!0)}),l?gl(o):{x:0,y:0,width:0,height:0}},ec=(t,r,[o,l,u]=[0,0,1],c=!1,f=!1)=>{const h=(r.x-o)/u,p=(r.y-l)/u,y=r.width/u,m=r.height/u,v=[];for(const g of t.values()){const{measured:w,selectable:S=!0,hidden:M=!1}=g;if(f&&!S||M)continue;const N=w.width??g.width??g.initialWidth??0,E=w.height??g.height??g.initialHeight??0,{x:R,y:_}=g.internals.positionAbsolute,I=Op(h,p,y,m,R,_,N,E),W=N*E,$=c&&I>0;(!g.internals.handleBounds||$||I>=W||g.dragging)&&v.push(g)}return v},cw=(t,r)=>{const o=new Set;return t.forEach(l=>{o.add(l.id)}),r.filter(l=>o.has(l.source)||o.has(l.target))};function fw(t,r){const o=new Map,l=r!=null&&r.nodes?new Set(r.nodes.map(u=>u.id)):null;return t.forEach(u=>{let c;if(r!=null&&r.includeHiddenNodes){const{width:f,height:h}=Qt(u);c=f>0&&h>0}else c=!!(u.measured.width&&u.measured.height&&!u.hidden);c&&(!l||l.has(u.id))&&o.set(u.id,u)}),o}async function dw({nodes:t,width:r,height:o,panZoom:l,minZoom:u,maxZoom:c},f){if(t.size===0)return!0;const h=fw(t,f),p=mo(h),y=nc(p,r,o,(f==null?void 0:f.minZoom)??u,(f==null?void 0:f.maxZoom)??c,(f==null?void 0:f.padding)??.1);return await l.setViewport(y,{duration:f==null?void 0:f.duration,ease:f==null?void 0:f.ease,interpolate:f==null?void 0:f.interpolate}),!0}function Ap({nodeId:t,nextPosition:r,nodeLookup:o,nodeOrigin:l=[0,0],nodeExtent:u,onError:c}){const f=o.get(t),h=f.parentId?o.get(f.parentId):void 0,{x:p,y}=h?h.internals.positionAbsolute:{x:0,y:0},m=f.origin??l;let v=f.extent||u;if(f.extent==="parent"&&!f.expandParent)if(!h)c==null||c("005",Yt.error005());else{const{width:w,height:S}=Qt(h);w&&S&&(v=[[p,y],[p+w,y+S]])}else h&&vr(f.extent)&&(v=[[f.extent[0][0]+p,f.extent[0][1]+y],[f.extent[1][0]+p,f.extent[1][1]+y]]);const g=vr(v)?yr(r,v,f.measured):r;return(f.measured.width===void 0||f.measured.height===void 0)&&(c==null||c("015",Yt.error015())),{position:{x:g.x-p+(f.measured.width??0)*m[0],y:g.y-y+(f.measured.height??0)*m[1]},positionAbsolute:g}}async function hw({nodesToRemove:t=[],edgesToRemove:r=[],nodes:o,edges:l,onBeforeDelete:u}){const c=new Set(t.map(g=>g.id)),f=[];for(const g of o){if(g.deletable===!1)continue;const w=c.has(g.id),S=!w&&g.parentId&&f.find(M=>M.id===g.parentId);(w||S)&&f.push(g)}const h=new Set(r.map(g=>g.id)),p=l.filter(g=>g.deletable!==!1),m=cw(f,p);for(const g of p)h.has(g.id)&&!m.find(S=>S.id===g.id)&&m.push(g);if(!u)return{edges:m,nodes:f};const v=await u({nodes:f,edges:m});return typeof v=="boolean"?v?{edges:m,nodes:f}:{edges:[],nodes:[]}:v}const ri=(t,r=0,o=1)=>Math.min(Math.max(t,r),o),yr=(t={x:0,y:0},r,o)=>({x:ri(t.x,r[0][0],r[1][0]-((o==null?void 0:o.width)??0)),y:ri(t.y,r[0][1],r[1][1]-((o==null?void 0:o.height)??0))});function $p(t,r,o){const{width:l,height:u}=Qt(o),{x:c,y:f}=o.internals.positionAbsolute;return yr(t,[[c,f],[c+l,f+u]],r)}const lh=(t,r,o)=>to?-ri(Math.abs(t-o),1,r)/r:0,tc=(t,r,o=15,l=40)=>{const u=lh(t.x,l,r.width-l)*o,c=lh(t.y,l,r.height-l)*o;return[u,c]},pl=(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)}),Ha=({x:t,y:r,width:o,height:l})=>({x:t,y:r,x2:t+o,y2:r+l}),gl=({x:t,y:r,x2:o,y2:l})=>({x:t,y:r,width:o-t,height:l-r}),uo=(t,r=[0,0])=>{var u,c;const{x:o,y:l}=Ja(t)?t.internals.positionAbsolute:go(t,r);return{x:o,y:l,width:((u=t.measured)==null?void 0:u.width)??t.width??t.initialWidth??0,height:((c=t.measured)==null?void 0:c.height)??t.height??t.initialHeight??0}},ol=(t,r=[0,0])=>{var u,c;const{x:o,y:l}=Ja(t)?t.internals.positionAbsolute:go(t,r);return{x:o,y:l,x2:o+(((u=t.measured)==null?void 0:u.width)??t.width??t.initialWidth??0),y2:l+(((c=t.measured)==null?void 0:c.height)??t.height??t.initialHeight??0)}},Dp=(t,r)=>gl(pl(Ha(t),Ha(r))),Op=(t,r,o,l,u,c,f,h)=>{const p=Math.max(0,Math.min(t+o,u+f)-Math.max(t,u)),y=Math.max(0,Math.min(r+l,c+h)-Math.max(r,c));return Math.ceil(p*y)},sl=(t,r)=>Op(t.x,t.y,t.width,t.height,r.x,r.y,r.width,r.height),uh=t=>Wt(t.width)&&Wt(t.height)&&Wt(t.x)&&Wt(t.y),Wt=t=>!isNaN(t)&&isFinite(t),Fp=(t,r)=>(o,l)=>{},yo=(t,r=[1,1])=>({x:r[0]*Math.round(t.x/r[0]),y:r[1]*Math.round(t.y/r[1])}),vo=({x:t,y:r},[o,l,u],c=!1,f=[1,1])=>{const h={x:(t-o)/u,y:(r-l)/u};return c?yo(h,f):h},ii=({x:t,y:r},[o,l,u])=>({x:t*u+o,y:r*u+l});function Kr(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 pw(t,r,o){if(typeof t=="string"||typeof t=="number"){const l=Kr(t,o),u=Kr(t,r);return{top:l,right:u,bottom:l,left:u,x:u*2,y:l*2}}if(typeof t=="object"){const l=Kr(t.top??t.y??0,o),u=Kr(t.bottom??t.y??0,o),c=Kr(t.left??t.x??0,r),f=Kr(t.right??t.x??0,r);return{top:l,right:f,bottom:u,left:c,x:c+f,y:l+u}}return{top:0,right:0,bottom:0,left:0,x:0,y:0}}function gw(t,r,o,l,u,c){const{x:f,y:h}=ii(t,[r,o,l]),{x:p,y}=ii({x:t.x+t.width,y:t.y+t.height},[r,o,l]),m=u-p,v=c-y;return{left:Math.floor(f),top:Math.floor(h),right:Math.floor(m),bottom:Math.floor(v)}}const nc=(t,r,o,l,u,c)=>{const f=pw(c,r,o),h=(r-f.x)/t.width,p=(o-f.y)/t.height,y=Math.min(h,p),m=ri(y,l,u),v=t.x+t.width/2,g=t.y+t.height/2,w=r/2-v*m,S=o/2-g*m,M=gw(t,w,S,m,r,o),N={left:Math.min(M.left-f.left,0),top:Math.min(M.top-f.top,0),right:Math.min(M.right-f.right,0),bottom:Math.min(M.bottom-f.bottom,0)};return{x:w-N.left+N.right,y:S-N.top+N.bottom,zoom:m}},ao=()=>{var t;return typeof navigator<"u"&&((t=navigator==null?void 0:navigator.userAgent)==null?void 0:t.indexOf("Mac"))>=0};function vr(t){return t!=null&&t!=="parent"}function Qt(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 Hp(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 Vp(t,r={width:0,height:0},o,l,u){const c={...t},f=l.get(o);if(f){const h=f.origin||u;c.x+=f.internals.positionAbsolute.x-(r.width??0)*h[0],c.y+=f.internals.positionAbsolute.y-(r.height??0)*h[1]}return c}function ah(t,r){if(t.size!==r.size)return!1;for(const o of t)if(!r.has(o))return!1;return!0}function mw(){let t,r;return{promise:new Promise((l,u)=>{t=l,r=u}),resolve:t,reject:r}}function yw(t){return{...zp,...t||{}}}function to(t,{snapGrid:r=[0,0],snapToGrid:o=!1,transform:l,containerBounds:u}){const{x:c,y:f}=bt(t),h=vo({x:c-((u==null?void 0:u.left)??0),y:f-((u==null?void 0:u.top)??0)},l),{x:p,y}=o?yo(h,r):h;return{xSnapped:p,ySnapped:y,...h}}const rc=t=>({width:t.offsetWidth,height:t.offsetHeight}),Bp=t=>{var r;return((r=t==null?void 0:t.getRootNode)==null?void 0:r.call(t))||(window==null?void 0:window.document)},vw=["INPUT","SELECT","TEXTAREA"];function Up(t){var l,u;const r=((u=(l=t.composedPath)==null?void 0:l.call(t))==null?void 0:u[0])||t.target;return(r==null?void 0:r.nodeType)!==1?!1:vw.includes(r.nodeName)||r.hasAttribute("contenteditable")||!!r.closest(".nokey")}const Wp=t=>"clientX"in t,bt=(t,r)=>{var c,f;const o=Wp(t),l=o?t.clientX:(c=t.touches)==null?void 0:c[0].clientX,u=o?t.clientY:(f=t.touches)==null?void 0:f[0].clientY;return{x:l-((r==null?void 0:r.left)??0),y:u-((r==null?void 0:r.top)??0)}},ch=(t,r,o,l,u)=>{const c=r.querySelectorAll(`.${t}`);return!c||!c.length?null:Array.from(c).map(f=>{const h=f.getBoundingClientRect();return{id:f.getAttribute("data-handleid"),type:t,nodeId:u,position:f.getAttribute("data-handlepos"),x:(h.left-o.left)/l,y:(h.top-o.top)/l,...rc(f)}})};function bp({sourceX:t,sourceY:r,targetX:o,targetY:l,sourceControlX:u,sourceControlY:c,targetControlX:f,targetControlY:h}){const p=t*.125+u*.375+f*.375+o*.125,y=r*.125+c*.375+h*.375+l*.125,m=Math.abs(p-t),v=Math.abs(y-r);return[p,y,m,v]}function Bs(t,r){return t>=0?.5*t:r*25*Math.sqrt(-t)}function fh({pos:t,x1:r,y1:o,x2:l,y2:u,c}){switch(t){case xe.Left:return[r-Bs(r-l,c),o];case xe.Right:return[r+Bs(l-r,c),o];case xe.Top:return[r,o-Bs(o-u,c)];case xe.Bottom:return[r,o+Bs(u-o,c)]}}function Yp({sourceX:t,sourceY:r,sourcePosition:o=xe.Bottom,targetX:l,targetY:u,targetPosition:c=xe.Top,curvature:f=.25}){const[h,p]=fh({pos:o,x1:t,y1:r,x2:l,y2:u,c:f}),[y,m]=fh({pos:c,x1:l,y1:u,x2:t,y2:r,c:f}),[v,g,w,S]=bp({sourceX:t,sourceY:r,targetX:l,targetY:u,sourceControlX:h,sourceControlY:p,targetControlX:y,targetControlY:m});return[`M${t},${r} C${h},${p} ${y},${m} ${l},${u}`,v,g,w,S]}function Xp({sourceX:t,sourceY:r,targetX:o,targetY:l}){const u=Math.abs(o-t)/2,c=o0}const Sw=({source:t,sourceHandle:r,target:o,targetHandle:l})=>`xy-edge__${t}${r||""}-${o}${l||""}`,_w=(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)),Ew=(t,r,o={})=>{var c;if(!t.source||!t.target)return(c=o.onError)==null||c.call(o,"006",Yt.error006()),r;const l=o.getEdgeId||Sw;let u;return jp(t)?u={...t}:u={...t,id:l(t)},_w(u,r)?r:(u.sourceHandle===null&&delete u.sourceHandle,u.targetHandle===null&&delete u.targetHandle,r.concat(u))};function Qp({sourceX:t,sourceY:r,targetX:o,targetY:l}){const[u,c,f,h]=Xp({sourceX:t,sourceY:r,targetX:o,targetY:l});return[`M ${t},${r}L ${o},${l}`,u,c,f,h]}const dh={[xe.Left]:{x:-1,y:0},[xe.Right]:{x:1,y:0},[xe.Top]:{x:0,y:-1},[xe.Bottom]:{x:0,y:1}},kw=({source:t,sourcePosition:r=xe.Bottom,target:o})=>r===xe.Left||r===xe.Right?t.xMath.sqrt(Math.pow(r.x-t.x,2)+Math.pow(r.y-t.y,2));function Nw({source:t,sourcePosition:r=xe.Bottom,target:o,targetPosition:l=xe.Top,center:u,offset:c,stepPosition:f}){const h=dh[r],p=dh[l],y={x:t.x+h.x*c,y:t.y+h.y*c},m={x:o.x+p.x*c,y:o.y+p.y*c},v=kw({source:y,sourcePosition:r,target:m}),g=v.x!==0?"x":"y",w=v[g];let S=[],M,N;const E={x:0,y:0},R={x:0,y:0},[,,_,I]=Xp({sourceX:t.x,sourceY:t.y,targetX:o.x,targetY:o.y});if(h[g]*p[g]===-1){g==="x"?(M=u.x??y.x+(m.x-y.x)*f,N=u.y??(y.y+m.y)/2):(M=u.x??(y.x+m.x)/2,N=u.y??y.y+(m.y-y.y)*f);const X=[{x:M,y:y.y},{x:M,y:m.y}],K=[{x:y.x,y:N},{x:m.x,y:N}];h[g]===w?S=g==="x"?X:K:S=g==="x"?K:X}else{const X=[{x:y.x,y:m.y}],K=[{x:m.x,y:y.y}];if(g==="x"?S=h.x===w?K:X:S=h.y===w?X:K,r===l){const k=Math.abs(t[g]-o[g]);if(k<=c){const B=Math.min(c-1,c-k);h[g]===w?E[g]=(y[g]>t[g]?-1:1)*B:R[g]=(m[g]>o[g]?-1:1)*B}}if(r!==l){const k=g==="x"?"y":"x",B=h[g]===p[k],H=y[k]>m[k],U=y[k]=J?(M=(te.x+Z.x)/2,N=S[0].y):(M=S[0].x,N=(te.y+Z.y)/2)}const W={x:y.x+E.x,y:y.y+E.y},$={x:m.x+R.x,y:m.y+R.y};return[[t,...W.x!==S[0].x||W.y!==S[0].y?[W]:[],...S,...$.x!==S[S.length-1].x||$.y!==S[S.length-1].y?[$]:[],o],M,N,_,I]}function Cw(t,r,o,l){const u=Math.min(hh(t,r)/2,hh(r,o)/2,l),{x:c,y:f}=r;if(t.x===c&&c===o.x||t.y===f&&f===o.y)return`L${c} ${f}`;if(t.y===f){const y=t.xo.id===r):t[0])||null}function Ba(t,r){return t?typeof t=="string"?t:`${r?`${r}__`:""}${Object.keys(t).sort().map(l=>`${l}=${t[l]}`).join("&")}`:""}function Pw(t,{id:r,defaultColor:o,defaultMarkerStart:l,defaultMarkerEnd:u}){const c=new Set;return t.reduce((f,h)=>([h.markerStart||l,h.markerEnd||u].forEach(p=>{if(p&&typeof p=="object"){const y=Ba(p,r);c.has(y)||(f.push({id:y,color:p.color||o,...p}),c.add(y))}}),f),[]).sort((f,h)=>f.id.localeCompare(h.id))}const Gp=1e3,Iw=10,ic={nodeOrigin:[0,0],nodeExtent:so,elevateNodesOnSelect:!0,zIndexMode:"basic",defaults:{}},Tw={...ic,checkEquality:!0};function oc(t,r){const o={...t};for(const l in r)r[l]!==void 0&&(o[l]=r[l]);return o}function zw(t,r,o){const l=oc(ic,o);for(const u of t.values())if(u.parentId)lc(u,t,r,l);else{const c=go(u,l.nodeOrigin),f=vr(u.extent)?u.extent:l.nodeExtent,h=yr(c,f,Qt(u));u.internals.positionAbsolute=h}}function Rw(t,r){if(!t.handles)return t.measured?r==null?void 0:r.internals.handleBounds:void 0;const o=[],l=[];for(const u of t.handles){const c={id:u.id,width:u.width??1,height:u.height??1,nodeId:t.id,x:u.x,y:u.y,position:u.position,type:u.type};u.type==="source"?o.push(c):u.type==="target"&&l.push(c)}return{source:o,target:l}}function sc(t){return t==="manual"}function Ua(t,r,o,l={}){var m,v;const u=oc(Tw,l),c={i:0},f=new Map(r),h=u!=null&&u.elevateNodesOnSelect&&!sc(u.zIndexMode)?Gp:0;let p=t.length>0,y=!1;r.clear(),o.clear();for(const g of t){let w=f.get(g.id);if(u.checkEquality&&g===(w==null?void 0:w.internals.userNode))r.set(g.id,w);else{const S=go(g,u.nodeOrigin),M=vr(g.extent)?g.extent:u.nodeExtent,N=yr(S,M,Qt(g));w={...u.defaults,...g,measured:{width:(m=g.measured)==null?void 0:m.width,height:(v=g.measured)==null?void 0:v.height},internals:{positionAbsolute:N,handleBounds:Rw(g,w),z:Kp(g,h,u.zIndexMode),userNode:g}},r.set(g.id,w)}(w.measured===void 0||w.measured.width===void 0||w.measured.height===void 0)&&!w.hidden&&(p=!1),g.parentId&&lc(w,r,o,l,c),y||(y=g.selected??!1)}return{nodesInitialized:p,hasSelectedNodes:y}}function Lw(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 lc(t,r,o,l,u){const{elevateNodesOnSelect:c,nodeOrigin:f,nodeExtent:h,zIndexMode:p}=oc(ic,l),y=t.parentId,m=r.get(y);if(!m){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}Lw(t,o),u&&!m.parentId&&m.internals.rootParentIndex===void 0&&p==="auto"&&(m.internals.rootParentIndex=++u.i,m.internals.z=m.internals.z+u.i*Iw),u&&m.internals.rootParentIndex!==void 0&&(u.i=m.internals.rootParentIndex);const v=c&&!sc(p)?Gp:0,{x:g,y:w,z:S}=jw(t,m,f,h,v,p),{positionAbsolute:M}=t.internals,N=g!==M.x||w!==M.y;(N||S!==t.internals.z)&&r.set(t.id,{...t,internals:{...t.internals,positionAbsolute:N?{x:g,y:w}:M,z:S}})}function Kp(t,r,o){const l=Wt(t.zIndex)?t.zIndex:0;return sc(o)?l:l+(t.selected?r:0)}function jw(t,r,o,l,u,c){const{x:f,y:h}=r.internals.positionAbsolute,p=Qt(t),y=go(t,o),m=vr(t.extent)?yr(y,t.extent,p):y;let v=yr({x:f+m.x,y:h+m.y},l,p);t.extent==="parent"&&(v=$p(v,p,r));const g=Kp(t,u,c),w=r.internals.z??0;return{x:v.x,y:v.y,z:w>=g?w+1:g}}function uc(t,r,o,l=[0,0]){var f;const u=[],c=new Map;for(const h of t){const p=r.get(h.parentId);if(!p)continue;const y=((f=c.get(h.parentId))==null?void 0:f.expandedRect)??uo(p),m=Dp(y,h.rect);c.set(h.parentId,{expandedRect:m,parent:p})}return c.size>0&&c.forEach(({expandedRect:h,parent:p},y)=>{var _;const m=p.internals.positionAbsolute,v=Qt(p),g=p.origin??l,w=h.x0||S>0||E||R)&&(u.push({id:y,type:"position",position:{x:p.position.x-w+E,y:p.position.y-S+R}}),(_=o.get(y))==null||_.forEach(I=>{t.some(W=>W.id===I.id)||u.push({id:I.id,type:"position",position:{x:I.position.x+w,y:I.position.y+S}})})),(v.width0){const w=uc(g,r,o,u);y.push(...w)}return{changes:y,updatedInternals:p}}async function $w({delta:t,panZoom:r,transform:o,translateExtent:l,width:u,height:c}){if(!r||!t.x&&!t.y)return!1;const f=await r.setViewportConstrained({x:o[0]+t.x,y:o[1]+t.y,zoom:o[2]},[[0,0],[u,c]],l);return!!f&&(f.x!==o[0]||f.y!==o[1]||f.k!==o[2])}function yh(t,r,o,l,u,c){let f=u;const h=l.get(f)||new Map;l.set(f,h.set(o,r)),f=`${u}-${t}`;const p=l.get(f)||new Map;if(l.set(f,p.set(o,r)),c){f=`${u}-${t}-${c}`;const y=l.get(f)||new Map;l.set(f,y.set(o,r))}}function qp(t,r,o){t.clear(),r.clear();for(const l of o){const{source:u,target:c,sourceHandle:f=null,targetHandle:h=null}=l,p={edgeId:l.id,source:u,target:c,sourceHandle:f,targetHandle:h},y=`${u}-${f}--${c}-${h}`,m=`${c}-${h}--${u}-${f}`;yh("source",p,m,t,u,f),yh("target",p,y,t,c,h),r.set(l.id,l)}}function Zp(t,r){if(!t.parentId)return!1;const o=r.get(t.parentId);return o?o.selected?!0:Zp(o,r):!1}function vh(t,r,o){var u;let l=t;do{if((u=l==null?void 0:l.matches)!=null&&u.call(l,r))return!0;if(l===o)return!1;l=l==null?void 0:l.parentElement}while(l);return!1}function Dw(t,r,o,l){const u=new Map;for(const[c,f]of t)if((f.selected||f.id===l)&&(!f.parentId||!Zp(f,t))&&(f.draggable||r&&typeof f.draggable>"u")){const h=t.get(c);h&&u.set(c,{id:c,position:h.position||{x:0,y:0},distance:{x:o.x-h.internals.positionAbsolute.x,y:o.y-h.internals.positionAbsolute.y},extent:h.extent,parentId:h.parentId,origin:h.origin,expandParent:h.expandParent,internals:{positionAbsolute:h.internals.positionAbsolute||{x:0,y:0}},measured:{width:h.measured.width??0,height:h.measured.height??0}})}return u}function _a({nodeId:t,dragItems:r,nodeLookup:o,dragging:l=!0}){var f,h,p;const u=[];for(const[y,m]of r){const v=(f=o.get(y))==null?void 0:f.internals.userNode;v&&u.push({...v,position:m.position,dragging:l})}if(!t)return[u[0],u];const c=(h=o.get(t))==null?void 0:h.internals.userNode;return[c?{...c,position:((p=r.get(t))==null?void 0:p.position)||c.position,dragging:l}:u[0],u]}function Ow({dragItems:t,snapGrid:r,x:o,y:l}){const u=t.values().next().value;if(!u)return null;const c={x:o-u.distance.x,y:l-u.distance.y},f=yo(c,r);return{x:f.x-c.x,y:f.y-c.y}}function Fw({onNodeMouseDown:t,getStoreItems:r,onDragStart:o,onDrag:l,onDragStop:u}){let c={x:null,y:null},f=0,h=new Map,p=!1,y={x:0,y:0},m=null,v=!1,g=null,w=!1,S=!1,M=null;function N({noDragClassName:R,handleSelector:_,domNode:I,isSelectable:W,nodeId:$,nodeClickDistance:V=0}){g=kt(I);function X({x:ee,y:J}){const{nodeLookup:k,nodeExtent:B,snapGrid:H,snapToGrid:U,nodeOrigin:A,onNodeDrag:j,onSelectionDrag:F,onError:C,updateNodePositions:z}=r();c={x:ee,y:J};let ne=!1;const ie=h.size>1,ce=ie&&B?Ha(mo(h)):null,O=ie&&U?Ow({dragItems:h,snapGrid:H,x:ee,y:J}):null;for(const[re,Q]of h){if(!k.has(re))continue;let le={x:ee-Q.distance.x,y:J-Q.distance.y};U&&(le=O?{x:Math.round(le.x+O.x),y:Math.round(le.y+O.y)}:yo(le,H));let pe=null;if(ie&&B&&!Q.extent&&ce){const{positionAbsolute:me}=Q.internals,ke=me.x-ce.x+B[0][0],Ce=me.x+Q.measured.width-ce.x2+B[1][0],Me=me.y-ce.y+B[0][1],Re=me.y+Q.measured.height-ce.y2+B[1][1];pe=[[ke,Me],[Ce,Re]]}const{position:we,positionAbsolute:ve}=Ap({nodeId:re,nextPosition:le,nodeLookup:k,nodeExtent:pe||B,nodeOrigin:A,onError:C});ne=ne||Q.position.x!==we.x||Q.position.y!==we.y,Q.position=we,Q.internals.positionAbsolute=ve}if(S=S||ne,!!ne&&(z(h,!0),M&&(l||j||!$&&F))){const[re,Q]=_a({nodeId:$,dragItems:h,nodeLookup:k});l==null||l(M,h,re,Q),j==null||j(M,re,Q),$||F==null||F(M,Q)}}async function K(){if(!m)return;const{transform:ee,panBy:J,autoPanSpeed:k,autoPanOnNodeDrag:B}=r();if(!B){p=!1,cancelAnimationFrame(f);return}const[H,U]=tc(y,m,k);(H!==0||U!==0)&&(c.x=(c.x??0)-H/ee[2],c.y=(c.y??0)-U/ee[2],await J({x:H,y:U})&&X(c)),f=requestAnimationFrame(K)}function te(ee){var ie;const{nodeLookup:J,multiSelectionActive:k,nodesDraggable:B,transform:H,snapGrid:U,snapToGrid:A,selectNodesOnDrag:j,onNodeDragStart:F,onSelectionDragStart:C,unselectNodesAndEdges:z}=r();v=!0,(!j||!W)&&!k&&$&&((ie=J.get($))!=null&&ie.selected||z()),W&&j&&$&&(t==null||t($));const ne=to(ee.sourceEvent,{transform:H,snapGrid:U,snapToGrid:A,containerBounds:m});if(c=ne,h=Dw(J,B,ne,$),h.size>0&&(o||F||!$&&C)){const[ce,O]=_a({nodeId:$,dragItems:h,nodeLookup:J});o==null||o(ee.sourceEvent,h,ce,O),F==null||F(ee.sourceEvent,ce,O),$||C==null||C(ee.sourceEvent,O)}}const Z=pp().clickDistance(V).on("start",ee=>{const{domNode:J,nodeDragThreshold:k,transform:B,snapGrid:H,snapToGrid:U}=r();m=(J==null?void 0:J.getBoundingClientRect())||null,w=!1,S=!1,M=ee.sourceEvent,k===0&&te(ee),c=to(ee.sourceEvent,{transform:B,snapGrid:H,snapToGrid:U,containerBounds:m}),y=bt(ee.sourceEvent,m)}).on("drag",ee=>{const{autoPanOnNodeDrag:J,transform:k,snapGrid:B,snapToGrid:H,nodeDragThreshold:U,nodeLookup:A}=r(),j=to(ee.sourceEvent,{transform:k,snapGrid:B,snapToGrid:H,containerBounds:m});if(M=ee.sourceEvent,(ee.sourceEvent.type==="touchmove"&&ee.sourceEvent.touches.length>1||$&&!A.has($))&&(w=!0),!w){if(!p&&J&&v&&(p=!0,K()),!v){const F=bt(ee.sourceEvent,m),C=F.x-y.x,z=F.y-y.y;Math.sqrt(C*C+z*z)>U&&te(ee)}(c.x!==j.xSnapped||c.y!==j.ySnapped)&&h&&v&&(y=bt(ee.sourceEvent,m),X(j))}}).on("end",ee=>{if(!v||w){w&&h.size>0&&r().updateNodePositions(h,!1);return}if(p=!1,v=!1,cancelAnimationFrame(f),h.size>0){const{nodeLookup:J,updateNodePositions:k,onNodeDragStop:B,onSelectionDragStop:H}=r();if(S&&(k(h,!1),S=!1),u||B||!$&&H){const[U,A]=_a({nodeId:$,dragItems:h,nodeLookup:J,dragging:!1});u==null||u(ee.sourceEvent,h,U,A),B==null||B(ee.sourceEvent,U,A),$||H==null||H(ee.sourceEvent,A)}}}).filter(ee=>{const J=ee.target;return!ee.button&&(!R||!vh(J,`.${R}`,I))&&(!_||vh(J,_,I))});g.call(Z)}function E(){g==null||g.on(".drag",null)}return{update:N,destroy:E}}function Hw(t,r,o){const l=[],u={x:t.x-o,y:t.y-o,width:o*2,height:o*2};for(const c of r.values())sl(u,uo(c))>0&&l.push(c);return l}const Vw=250;function Bw(t,r,o,l){var h,p;let u=[],c=1/0;const f=Hw(t,o,r+Vw);for(const y of f){const m=[...((h=y.internals.handleBounds)==null?void 0:h.source)??[],...((p=y.internals.handleBounds)==null?void 0:p.target)??[]];for(const v of m){if(l.nodeId===v.nodeId&&l.type===v.type&&l.id===v.id)continue;const{x:g,y:w}=xr(y,v,v.position,!0),S=Math.sqrt(Math.pow(g-t.x,2)+Math.pow(w-t.y,2));S>r||(S1){const y=l.type==="source"?"target":"source";return u.find(m=>m.type===y)??u[0]}return u[0]}function Jp(t,r,o,l,u,c=!1){var y,m,v;const f=l.get(t);if(!f)return null;const h=u==="strict"?(y=f.internals.handleBounds)==null?void 0:y[r]:[...((m=f.internals.handleBounds)==null?void 0:m.source)??[],...((v=f.internals.handleBounds)==null?void 0:v.target)??[]],p=(o?h==null?void 0:h.find(g=>g.id===o):h==null?void 0:h[0])??null;return p&&c?{...p,...xr(f,p,p.position,!0)}:p}function eg(t,r){return t||(r!=null&&r.classList.contains("target")?"target":r!=null&&r.classList.contains("source")?"source":null)}function Uw(t,r){let o=null;return r?o=!0:t&&!r&&(o=!1),o}const tg=()=>!0;function Ww(t,{connectionMode:r,connectionRadius:o,handleId:l,nodeId:u,edgeUpdaterType:c,isTarget:f,domNode:h,nodeLookup:p,lib:y,autoPanOnConnect:m,flowId:v,panBy:g,cancelConnection:w,onConnectStart:S,onConnect:M,onConnectEnd:N,isValidConnection:E=tg,onReconnectEnd:R,updateConnection:_,getTransform:I,getFromHandle:W,autoPanSpeed:$,dragThreshold:V=1,handleDomNode:X}){const K=Bp(t.target);let te=0,Z;const{x:ee,y:J}=bt(t),k=eg(c,X),B=h==null?void 0:h.getBoundingClientRect();let H=!1;if(!B||!k)return;const U=Jp(u,k,l,p,r);if(!U)return;let A=bt(t,B),j=!1,F=null,C=!1,z=null;function ne(){if(!m||!B)return;const[we,ve]=tc(A,B,$);g({x:we,y:ve}),te=requestAnimationFrame(ne)}const ie={...U,nodeId:u,type:k,position:U.position},ce=p.get(u);let re={inProgress:!0,isValid:null,from:xr(ce,ie,xe.Left,!0),fromHandle:ie,fromPosition:ie.position,fromNode:ce,to:A,toHandle:null,toPosition:sh[ie.position],toNode:null,pointer:A};function Q(){H=!0,_(re),S==null||S(t,{nodeId:u,handleId:l,handleType:k})}V===0&&Q();function le(we){if(!H){const{x:Re,y:ot}=bt(we),ut=Re-ee,Je=ot-J;if(!(ut*ut+Je*Je>V*V))return;Q()}if(!W()||!ie){pe(we);return}const ve=I();A=bt(we,B),Z=Bw(vo(A,ve,!1,[1,1]),o,p,ie),j||(ne(),j=!0);const me=ng(we,{handle:Z,connectionMode:r,fromNodeId:u,fromHandleId:l,fromType:f?"target":"source",isValidConnection:E,doc:K,lib:y,flowId:v,nodeLookup:p});z=me.handleDomNode,F=me.connection,C=Uw(!!Z,me.isValid);const ke=p.get(u),Ce=ke?xr(ke,ie,xe.Left,!0):re.from,Me={...re,from:Ce,isValid:C,to:me.toHandle&&C?ii({x:me.toHandle.x,y:me.toHandle.y},ve):A,toHandle:me.toHandle,toPosition:C&&me.toHandle?me.toHandle.position:sh[ie.position],toNode:me.toHandle?p.get(me.toHandle.nodeId):null,pointer:A};_(Me),re=Me}function pe(we){if(!("touches"in we&&we.touches.length>0)){if(H){(Z||z)&&F&&C&&(M==null||M(F));const{inProgress:ve,...me}=re,ke={...me,toPosition:re.toHandle?re.toPosition:null};N==null||N(we,ke),c&&(R==null||R(we,ke))}w(),cancelAnimationFrame(te),j=!1,C=!1,F=null,z=null,K.removeEventListener("mousemove",le),K.removeEventListener("mouseup",pe),K.removeEventListener("touchmove",le),K.removeEventListener("touchend",pe)}}K.addEventListener("mousemove",le),K.addEventListener("mouseup",pe),K.addEventListener("touchmove",le),K.addEventListener("touchend",pe)}function ng(t,{handle:r,connectionMode:o,fromNodeId:l,fromHandleId:u,fromType:c,doc:f,lib:h,flowId:p,isValidConnection:y=tg,nodeLookup:m}){const v=c==="target",g=r?f.querySelector(`.${h}-flow__handle[data-id="${p}-${r==null?void 0:r.nodeId}-${r==null?void 0:r.id}-${r==null?void 0:r.type}"]`):null,{x:w,y:S}=bt(t),M=f.elementFromPoint(w,S),N=M!=null&&M.classList.contains(`${h}-flow__handle`)?M:g,E={handleDomNode:N,isValid:!1,connection:null,toHandle:null};if(N){const R=eg(void 0,N),_=N.getAttribute("data-nodeid"),I=N.getAttribute("data-handleid"),W=N.classList.contains("connectable"),$=N.classList.contains("connectableend");if(!_||!R)return E;const V={source:v?_:l,sourceHandle:v?I:u,target:v?l:_,targetHandle:v?u:I};E.connection=V;const K=W&&$&&(o===ni.Strict?v&&R==="source"||!v&&R==="target":_!==l||I!==u);E.isValid=K&&y(V),E.toHandle=Jp(_,R,I,m,o,!0)}return E}const Wa={onPointerDown:Ww,isValid:ng};function bw({domNode:t,panZoom:r,getTransform:o,getViewScale:l}){const u=kt(t);function c({translateExtent:h,width:p,height:y,zoomStep:m=1,pannable:v=!0,zoomable:g=!0,inversePan:w=!1}){const S=_=>{if(_.sourceEvent.type!=="wheel"||!r)return;const I=o(),W=_.sourceEvent.ctrlKey&&ao()?10:1,$=-_.sourceEvent.deltaY*(_.sourceEvent.deltaMode===1?.05:_.sourceEvent.deltaMode?1:.002)*m,V=I[2]*Math.pow(2,$*W);r.scaleTo(V)};let M=[0,0];const N=_=>{(_.sourceEvent.type==="mousedown"||_.sourceEvent.type==="touchstart")&&(M=[_.sourceEvent.clientX??_.sourceEvent.touches[0].clientX,_.sourceEvent.clientY??_.sourceEvent.touches[0].clientY])},E=_=>{const I=o();if(_.sourceEvent.type!=="mousemove"&&_.sourceEvent.type!=="touchmove"||!r)return;const W=[_.sourceEvent.clientX??_.sourceEvent.touches[0].clientX,_.sourceEvent.clientY??_.sourceEvent.touches[0].clientY],$=[W[0]-M[0],W[1]-M[1]];M=W;const V=l()*Math.max(I[2],Math.log(I[2]))*(w?-1:1),X={x:I[0]-$[0]*V,y:I[1]-$[1]*V},K=[[0,0],[p,y]];r.setViewportConstrained({x:X.x,y:X.y,zoom:I[2]},K,h)},R=Ip().on("start",N).on("zoom",v?E:null).on("zoom.wheel",g?S:null);u.call(R,{})}function f(){u.on("zoom",null)}return{update:c,destroy:f,pointer:Bt}}const ml=t=>({x:t.x,y:t.y,zoom:t.k}),Ea=({x:t,y:r,zoom:o})=>hl.translate(t,r).scale(o),Un=(t,r)=>t.target.closest(`.${r}`),rg=(t,r)=>r===2&&Array.isArray(t)&&t.includes(2),Yw=t=>((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2,ka=(t,r=0,o=Yw,l=()=>{})=>{const u=typeof r=="number"&&r>0;return u||l(),u?t.transition().duration(r).ease(o).on("end",l):t},ig=t=>{const r=t.ctrlKey&&ao()?10:1;return-t.deltaY*(t.deltaMode===1?.05:t.deltaMode?1:.002)*r};function Xw({zoomPanValues:t,noWheelClassName:r,d3Selection:o,d3Zoom:l,panOnScrollMode:u,panOnScrollSpeed:c,zoomOnPinch:f,onPanZoomStart:h,onPanZoom:p,onPanZoomEnd:y}){return m=>{if(Un(m,r))return m.ctrlKey&&m.preventDefault(),!1;m.preventDefault(),m.stopImmediatePropagation();const v=o.property("__zoom").k||1;if(m.ctrlKey&&f){const N=Bt(m),E=ig(m),R=v*Math.pow(2,E);l.scaleTo(o,R,N,m);return}const g=m.deltaMode===1?20:1;let w=u===pr.Vertical?0:m.deltaX*g,S=u===pr.Horizontal?0:m.deltaY*g;!ao()&&m.shiftKey&&u!==pr.Vertical&&(w=m.deltaY*g,S=0),l.translateBy(o,-(w/v)*c,-(S/v)*c,{internal:!0});const M=ml(o.property("__zoom"));clearTimeout(t.panScrollTimeout),t.isPanScrolling?p==null||p(m,M):(t.isPanScrolling=!0,h==null||h(m,M)),t.panScrollTimeout=setTimeout(()=>{y==null||y(m,M),t.isPanScrolling=!1},150)}}function Qw({noWheelClassName:t,preventScrolling:r,d3ZoomHandler:o}){return function(l,u){const c=l.type==="wheel",f=!r&&c&&!l.ctrlKey,h=Un(l,t);if(l.ctrlKey&&c&&h&&l.preventDefault(),f||h)return null;l.preventDefault(),o.call(this,l,u)}}function Gw({zoomPanValues:t,onDraggingChange:r,onPanZoomStart:o}){return l=>{var c,f,h;if((c=l.sourceEvent)!=null&&c.internal)return;const u=ml(l.transform);t.mouseButton=((f=l.sourceEvent)==null?void 0:f.button)||0,t.isZoomingOrPanning=!0,t.prevViewport=u,((h=l.sourceEvent)==null?void 0:h.type)==="mousedown"&&r(!0),o&&(o==null||o(l.sourceEvent,u))}}function Kw({zoomPanValues:t,panOnDrag:r,onPaneContextMenu:o,onTransformChange:l,onPanZoom:u}){return c=>{var f,h;t.usedRightMouseButton=!!(o&&rg(r,t.mouseButton??0)),(f=c.sourceEvent)!=null&&f.sync||l([c.transform.x,c.transform.y,c.transform.k]),u&&!((h=c.sourceEvent)!=null&&h.internal)&&(u==null||u(c.sourceEvent,ml(c.transform)))}}function qw({zoomPanValues:t,panOnDrag:r,panOnScroll:o,onDraggingChange:l,onPanZoomEnd:u,onPaneContextMenu:c}){return f=>{var h;if(!((h=f.sourceEvent)!=null&&h.internal)&&(t.isZoomingOrPanning=!1,c&&rg(r,t.mouseButton??0)&&!t.usedRightMouseButton&&f.sourceEvent&&c(f.sourceEvent),t.usedRightMouseButton=!1,l(!1),u)){const p=ml(f.transform);t.prevViewport=p,clearTimeout(t.timerId),t.timerId=setTimeout(()=>{u==null||u(f.sourceEvent,p)},o?150:0)}}}function Zw({panActivationKeyPressed:t,zoomActivationKeyPressed:r,zoomOnScroll:o,zoomOnPinch:l,panOnDrag:u,panOnScroll:c,zoomOnDoubleClick:f,userSelectionActive:h,noWheelClassName:p,noPanClassName:y,lib:m,connectionInProgress:v}){return g=>{var E;const w=r||o,S=l&&g.ctrlKey,M=g.type==="wheel";if(g.button===1&&g.type==="mousedown"&&(Un(g,`${m}-flow__node`)||Un(g,`${m}-flow__edge`)||Un(g,`${m}-flow__selection`)||Un(g,`${m}-flow__nodesselection`)))return!0;if(!u&&!w&&!c&&!f&&!l||h||v&&!M||Un(g,p)&&M||Un(g,y)&&(!M||c&&M&&!r)||!l&&g.ctrlKey&&M)return!1;if(!l&&g.type==="touchstart"&&((E=g.touches)==null?void 0:E.length)>1)return g.preventDefault(),!1;if(!w&&!c&&!S&&M||!u&&(g.type==="mousedown"||g.type==="touchstart")||Array.isArray(u)&&!u.includes(g.button)&&g.type==="mousedown")return!1;const N=Array.isArray(u)&&u.includes(g.button)||!g.button||g.button<=1;return(!g.ctrlKey||M||t)&&N}}function Jw({domNode:t,minZoom:r,maxZoom:o,translateExtent:l,viewport:u,onPanZoom:c,onPanZoomStart:f,onPanZoomEnd:h,onDraggingChange:p}){const y={isZoomingOrPanning:!1,usedRightMouseButton:!1,prevViewport:{},mouseButton:0,timerId:void 0,panScrollTimeout:void 0,isPanScrolling:!1},m=t.getBoundingClientRect();let v=[[0,0],[m.width,m.height]];const g=typeof ResizeObserver<"u"?new ResizeObserver(J=>{const k=J[0];k&&(v=[[0,0],[k.contentRect.width,k.contentRect.height]])}):null;g==null||g.observe(t);const w=Ip().extent(()=>v).scaleExtent([r,o]).translateExtent(l),S=kt(t).call(w);I({x:u.x,y:u.y,zoom:ri(u.zoom,r,o)},[[0,0],[m.width,m.height]],l);const M=S.on("wheel.zoom"),N=S.on("dblclick.zoom");w.wheelDelta(ig);async function E(J,k){return S?new Promise(B=>{w==null||w.interpolate((k==null?void 0:k.interpolate)==="linear"?eo:Xs).transform(ka(S,k==null?void 0:k.duration,k==null?void 0:k.ease,()=>B(!0)),J)}):!1}function R({noWheelClassName:J,noPanClassName:k,onPaneContextMenu:B,userSelectionActive:H,panOnScroll:U,panOnDrag:A,panOnScrollMode:j,panOnScrollSpeed:F,preventScrolling:C,zoomOnPinch:z,zoomOnScroll:ne,zoomOnDoubleClick:ie,panActivationKeyPressed:ce=!1,zoomActivationKeyPressed:O,lib:re,onTransformChange:Q,connectionInProgress:le,paneClickDistance:pe,selectionOnDrag:we}){H&&!y.isZoomingOrPanning&&_();const ve=U&&!O&&!H;w.clickDistance(we?1/0:!Wt(pe)||pe<0?0:pe);const me=ve?Xw({zoomPanValues:y,noWheelClassName:J,d3Selection:S,d3Zoom:w,panOnScrollMode:j,panOnScrollSpeed:F,zoomOnPinch:z,onPanZoomStart:f,onPanZoom:c,onPanZoomEnd:h}):Qw({noWheelClassName:J,preventScrolling:C,d3ZoomHandler:M});S.on("wheel.zoom",me,{passive:!1});const ke=Gw({zoomPanValues:y,onDraggingChange:p,onPanZoomStart:f});w.on("start",ke);const Ce=Kw({zoomPanValues:y,panOnDrag:A,onPaneContextMenu:!!B,onPanZoom:c,onTransformChange:Q});w.on("zoom",Ce);const Me=qw({zoomPanValues:y,panOnDrag:A,panOnScroll:U,onPaneContextMenu:B,onPanZoomEnd:h,onDraggingChange:p});w.on("end",Me);const Re=Zw({panActivationKeyPressed:ce,zoomActivationKeyPressed:O,panOnDrag:A,zoomOnScroll:ne,panOnScroll:U,zoomOnDoubleClick:ie,zoomOnPinch:z,userSelectionActive:H,noPanClassName:k,noWheelClassName:J,lib:re,connectionInProgress:le});w.filter(Re),ie?S.on("dblclick.zoom",N):S.on("dblclick.zoom",null)}function _(){w.on("zoom",null)}async function I(J,k,B){const H=Ea(J),U=w==null?void 0:w.constrain()(H,k,B);return U&&await E(U),U}async function W(J,k){const B=Ea(J);return await E(B,k),B}function $(J){if(S){const k=Ea(J),B=S.property("__zoom");(B.k!==J.zoom||B.x!==J.x||B.y!==J.y)&&(w==null||w.transform(S,k,null,{sync:!0}))}}function V(){const J=S?Pp(S.node()):{x:0,y:0,k:1};return{x:J.x,y:J.y,zoom:J.k}}async function X(J,k){return S?new Promise(B=>{w==null||w.interpolate((k==null?void 0:k.interpolate)==="linear"?eo:Xs).scaleTo(ka(S,k==null?void 0:k.duration,k==null?void 0:k.ease,()=>B(!0)),J)}):!1}async function K(J,k){return S?new Promise(B=>{w==null||w.interpolate((k==null?void 0:k.interpolate)==="linear"?eo:Xs).scaleBy(ka(S,k==null?void 0:k.duration,k==null?void 0:k.ease,()=>B(!0)),J)}):!1}function te(J){w==null||w.scaleExtent(J)}function Z(J){w==null||w.translateExtent(J)}function ee(J){const k=!Wt(J)||J<0?0:J;w==null||w.clickDistance(k)}return{update:R,destroy:_,setViewport:W,setViewportConstrained:I,getViewport:V,scaleTo:X,scaleBy:K,setScaleExtent:te,setTranslateExtent:Z,syncViewport:$,setClickDistance:ee}}var oi;(function(t){t.Line="line",t.Handle="handle"})(oi||(oi={}));function e1({width:t,prevWidth:r,height:o,prevHeight:l,affectsX:u,affectsY:c}){const f=t-r,h=o-l,p=[f>0?1:f<0?-1:0,h>0?1:h<0?-1:0];return f&&u&&(p[0]=p[0]*-1),h&&c&&(p[1]=p[1]*-1),p}function xh(t){const r=t.includes("right")||t.includes("left"),o=t.includes("bottom")||t.includes("top"),l=t.includes("left"),u=t.includes("top");return{isHorizontal:r,isVertical:o,affectsX:l,affectsY:u}}function Vn(t,r){return Math.max(0,r-t)}function Bn(t,r){return Math.max(0,t-r)}function Us(t,r,o){return Math.max(0,r-t,t-o)}function wh(t,r){return t?!r:r}function t1(t,r,o,l,u,c,f,h){let{affectsX:p,affectsY:y}=r;const{isHorizontal:m,isVertical:v}=r,g=m&&v,{xSnapped:w,ySnapped:S}=o,{minWidth:M,maxWidth:N,minHeight:E,maxHeight:R}=l,{x:_,y:I,width:W,height:$,aspectRatio:V}=t;let X=Math.floor(m?w-t.pointerX:0),K=Math.floor(v?S-t.pointerY:0);const te=W+(p?-X:X),Z=$+(y?-K:K),ee=-c[0]*W,J=-c[1]*$;let k=Us(te,M,N),B=Us(Z,E,R);if(f){let A=0,j=0;p&&X<0?A=Vn(_+X+ee,f[0][0]):!p&&X>0&&(A=Bn(_+te+ee,f[1][0])),y&&K<0?j=Vn(I+K+J,f[0][1]):!y&&K>0&&(j=Bn(I+Z+J,f[1][1])),k=Math.max(k,A),B=Math.max(B,j)}if(h){let A=0,j=0;p&&X>0?A=Bn(_+X,h[0][0]):!p&&X<0&&(A=Vn(_+te,h[1][0])),y&&K>0?j=Bn(I+K,h[0][1]):!y&&K<0&&(j=Vn(I+Z,h[1][1])),k=Math.max(k,A),B=Math.max(B,j)}if(u){if(m){const A=Us(te/V,E,R)*V;if(k=Math.max(k,A),f){let j=0;!p&&!y||p&&!y&&g?j=Bn(I+J+te/V,f[1][1])*V:j=Vn(I+J+(p?X:-X)/V,f[0][1])*V,k=Math.max(k,j)}if(h){let j=0;!p&&!y||p&&!y&&g?j=Vn(I+te/V,h[1][1])*V:j=Bn(I+(p?X:-X)/V,h[0][1])*V,k=Math.max(k,j)}}if(v){const A=Us(Z*V,M,N)/V;if(B=Math.max(B,A),f){let j=0;!p&&!y||y&&!p&&g?j=Bn(_+Z*V+ee,f[1][0])/V:j=Vn(_+(y?K:-K)*V+ee,f[0][0])/V,B=Math.max(B,j)}if(h){let j=0;!p&&!y||y&&!p&&g?j=Vn(_+Z*V,h[1][0])/V:j=Bn(_+(y?K:-K)*V,h[0][0])/V,B=Math.max(B,j)}}}K=K+(K<0?B:-B),X=X+(X<0?k:-k),u&&(g?te>Z*V?K=(wh(p,y)?-X:X)/V:X=(wh(p,y)?-K:K)*V:m?(K=X/V,y=p):(X=K*V,p=y));const H=p?_+X:_,U=y?I+K:I;return{width:W+(p?-X:X),height:$+(y?-K:K),x:c[0]*X*(p?-1:1)+H,y:c[1]*K*(y?-1:1)+U}}const og={width:0,height:0,x:0,y:0},n1={...og,pointerX:0,pointerY:0,aspectRatio:1};function r1(t,r,o){const l=r.position.x+t.position.x,u=r.position.y+t.position.y,c=t.measured.width??0,f=t.measured.height??0,h=o[0]*c,p=o[1]*f;return[[l-h,u-p],[l+c-h,u+f-p]]}function i1({domNode:t,nodeId:r,getStoreItems:o,onChange:l,onEnd:u}){const c=kt(t);let f={controlDirection:xh("bottom-right"),boundaries:{minWidth:0,minHeight:0,maxWidth:Number.MAX_VALUE,maxHeight:Number.MAX_VALUE},resizeDirection:void 0,keepAspectRatio:!1};function h({controlPosition:y,boundaries:m,keepAspectRatio:v,resizeDirection:g,onResizeStart:w,onResize:S,onResizeEnd:M,shouldResize:N}){let E={...og},R={...n1};f={boundaries:m,resizeDirection:g,keepAspectRatio:v,controlDirection:xh(y)};let _,I=null,W=[],$,V,X,K=!1;const te=pp().on("start",Z=>{const{nodeLookup:ee,transform:J,snapGrid:k,snapToGrid:B,nodeOrigin:H,paneDomNode:U}=o();if(_=ee.get(r),!_)return;I=(U==null?void 0:U.getBoundingClientRect())??null;const{xSnapped:A,ySnapped:j}=to(Z.sourceEvent,{transform:J,snapGrid:k,snapToGrid:B,containerBounds:I});E={width:_.measured.width??0,height:_.measured.height??0,x:_.position.x??0,y:_.position.y??0},R={...E,pointerX:A,pointerY:j,aspectRatio:E.width/E.height},$=void 0,V=vr(_.extent)?_.extent:void 0,_.parentId&&(_.extent==="parent"||_.expandParent)&&($=ee.get(_.parentId)),$&&_.extent==="parent"&&(V=[[0,0],[$.measured.width,$.measured.height]]),W=[],X=void 0;for(const[F,C]of ee)if(C.parentId===r&&(W.push({id:F,position:{...C.position},extent:C.extent}),C.extent==="parent"||C.expandParent)){const z=r1(C,_,C.origin??H);X?X=[[Math.min(z[0][0],X[0][0]),Math.min(z[0][1],X[0][1])],[Math.max(z[1][0],X[1][0]),Math.max(z[1][1],X[1][1])]]:X=z}w==null||w(Z,{...E})}).on("drag",Z=>{const{transform:ee,snapGrid:J,snapToGrid:k,nodeOrigin:B}=o(),H=to(Z.sourceEvent,{transform:ee,snapGrid:J,snapToGrid:k,containerBounds:I}),U=[];if(!_)return;const{x:A,y:j,width:F,height:C}=E,z={},ne=_.origin??B,{width:ie,height:ce,x:O,y:re}=t1(R,f.controlDirection,H,f.boundaries,f.keepAspectRatio,ne,V,X),Q=ie!==F,le=ce!==C,pe=O!==A&&Q,we=re!==j&≤if(!pe&&!we&&!Q&&!le)return;if((pe||we||ne[0]===1||ne[1]===1)&&(z.x=pe?O:E.x,z.y=we?re:E.y,E.x=z.x,E.y=z.y,W.length>0)){const Ce=O-A,Me=re-j;for(const Re of W)Re.position={x:Re.position.x-Ce+ne[0]*(ie-F),y:Re.position.y-Me+ne[1]*(ce-C)},U.push(Re)}if((Q||le)&&(z.width=Q&&(!f.resizeDirection||f.resizeDirection==="horizontal")?ie:E.width,z.height=le&&(!f.resizeDirection||f.resizeDirection==="vertical")?ce:E.height,E.width=z.width,E.height=z.height),$&&_.expandParent){const Ce=ne[0]*(z.width??0);z.x&&z.x{K&&(M==null||M(Z,{...E}),u==null||u({...E}),K=!1)});c.call(te)}function p(){c.on(".drag",null)}return{update:h,destroy:p}}var Na={exports:{}},Ca={},Ma={exports:{}},Pa={};/** + * @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 Sh;function o1(){if(Sh)return Pa;Sh=1;var t=fo();function r(v,g){return v===g&&(v!==0||1/v===1/g)||v!==v&&g!==g}var o=typeof Object.is=="function"?Object.is:r,l=t.useState,u=t.useEffect,c=t.useLayoutEffect,f=t.useDebugValue;function h(v,g){var w=g(),S=l({inst:{value:w,getSnapshot:g}}),M=S[0].inst,N=S[1];return c(function(){M.value=w,M.getSnapshot=g,p(M)&&N({inst:M})},[v,w,g]),u(function(){return p(M)&&N({inst:M}),v(function(){p(M)&&N({inst:M})})},[v]),f(w),w}function p(v){var g=v.getSnapshot;v=v.value;try{var w=g();return!o(v,w)}catch{return!0}}function y(v,g){return g()}var m=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?y:h;return Pa.useSyncExternalStore=t.useSyncExternalStore!==void 0?t.useSyncExternalStore:m,Pa}var _h;function s1(){return _h||(_h=1,Ma.exports=o1()),Ma.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 Eh;function l1(){if(Eh)return Ca;Eh=1;var t=fo(),r=s1();function o(y,m){return y===m&&(y!==0||1/y===1/m)||y!==y&&m!==m}var l=typeof Object.is=="function"?Object.is:o,u=r.useSyncExternalStore,c=t.useRef,f=t.useEffect,h=t.useMemo,p=t.useDebugValue;return Ca.useSyncExternalStoreWithSelector=function(y,m,v,g,w){var S=c(null);if(S.current===null){var M={hasValue:!1,value:null};S.current=M}else M=S.current;S=h(function(){function E($){if(!R){if(R=!0,_=$,$=g($),w!==void 0&&M.hasValue){var V=M.value;if(w(V,$))return I=V}return I=$}if(V=I,l(_,$))return V;var X=g($);return w!==void 0&&w(V,X)?(_=$,V):(_=$,I=X)}var R=!1,_,I,W=v===void 0?null:v;return[function(){return E(m())},W===null?void 0:function(){return E(W())}]},[m,v,g,w]);var N=u(y,S[0],S[1]);return f(function(){M.hasValue=!0,M.value=N},[N]),p(N),N},Ca}var kh;function u1(){return kh||(kh=1,Na.exports=l1()),Na.exports}var a1=u1();const c1=Zh(a1),f1={},Nh=t=>{let r;const o=new Set,l=(m,v)=>{const g=typeof m=="function"?m(r):m;if(!Object.is(g,r)){const w=r;r=v??(typeof g!="object"||g===null)?g:Object.assign({},r,g),o.forEach(S=>S(r,w))}},u=()=>r,p={setState:l,getState:u,getInitialState:()=>y,subscribe:m=>(o.add(m),()=>o.delete(m)),destroy:()=>{(f1?"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(l,u,p);return p},d1=t=>t?Nh(t):Nh,{useDebugValue:h1}=E0,{useSyncExternalStoreWithSelector:p1}=c1,g1=t=>t;function sg(t,r=g1,o){const l=p1(t.subscribe,t.getState,t.getServerState||t.getInitialState,r,o);return h1(l),l}const Ch=(t,r)=>{const o=d1(t),l=(u,c=r)=>sg(o,u,c);return Object.assign(l,o),l},m1=(t,r)=>t?Ch(t,r):Ch;function Ve(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[l,u]of t)if(!Object.is(u,r.get(l)))return!1;return!0}if(t instanceof Set&&r instanceof Set){if(t.size!==r.size)return!1;for(const l of t)if(!r.has(l))return!1;return!0}const o=Object.keys(t);if(o.length!==Object.keys(r).length)return!1;for(const l of o)if(!Object.prototype.hasOwnProperty.call(r,l)||!Object.is(t[l],r[l]))return!1;return!0}Jh();const yl=G.createContext(null),y1=yl.Provider,lg=Yt.error001("react");function Ie(t,r){const o=G.useContext(yl);if(o===null)throw new Error(lg);return sg(o,t,r)}function $e(){const t=G.useContext(yl);if(t===null)throw new Error(lg);return G.useMemo(()=>({getState:t.getState,setState:t.setState,subscribe:t.subscribe}),[t])}const Mh={display:"none"},v1={position:"absolute",width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0px, 0px, 0px, 0px)",clipPath:"inset(100%)"},ug="react-flow__node-desc",ag="react-flow__edge-desc",x1="react-flow__aria-live",w1=t=>t.ariaLiveMessage,S1=t=>t.ariaLabelConfig;function _1({rfId:t}){const r=Ie(w1);return P.jsx("div",{id:`${x1}-${t}`,"aria-live":"assertive","aria-atomic":"true",style:v1,children:r})}function E1({rfId:t,disableKeyboardA11y:r}){const o=Ie(S1);return P.jsxs(P.Fragment,{children:[P.jsx("div",{id:`${ug}-${t}`,style:Mh,children:r?o["node.a11yDescription.default"]:o["node.a11yDescription.keyboardDisabled"]}),P.jsx("div",{id:`${ag}-${t}`,style:Mh,children:o["edge.a11yDescription.default"]}),!r&&P.jsx(_1,{rfId:t})]})}const vl=G.forwardRef(({position:t="top-left",children:r,className:o,style:l,...u},c)=>{const f=`${t}`.split("-");return P.jsx("div",{className:be(["react-flow__panel",o,...f]),style:l,ref:c,...u,children:r})});vl.displayName="Panel";const Ph="https://reactflow.dev?utm_source=attribution";function k1({proOptions:t,position:r="bottom-right"}){return t!=null&&t.hideAttribution?null:P.jsx(vl,{position:r,className:"react-flow__attribution","data-message":`Please only hide this attribution when you are subscribed to React Flow Pro: ${Ph}`,children:P.jsx("a",{href:Ph,target:"_blank",rel:"noopener noreferrer","aria-label":"React Flow attribution",children:"React Flow"})})}const N1=t=>{const r=[],o=[];for(const[,l]of t.nodeLookup)l.selected&&r.push(l.internals.userNode);for(const[,l]of t.edgeLookup)l.selected&&o.push(l);return{selectedNodes:r,selectedEdges:o}},Ws=t=>t.id;function C1(t,r){return Ve(t.selectedNodes.map(Ws),r.selectedNodes.map(Ws))&&Ve(t.selectedEdges.map(Ws),r.selectedEdges.map(Ws))}function M1({onSelectionChange:t}){const r=$e(),{selectedNodes:o,selectedEdges:l}=Ie(N1,C1);return G.useEffect(()=>{const u={nodes:o,edges:l};t==null||t(u),r.getState().onSelectionChangeHandlers.forEach(c=>c(u))},[o,l,t]),null}const P1=t=>!!t.onSelectionChangeHandlers;function I1({onSelectionChange:t}){const r=Ie(P1);return t||r?P.jsx(M1,{onSelectionChange:t}):null}const cg=[0,0],T1={x:0,y:0,zoom:1},z1=["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"],Ih=[...z1,"rfId"],R1=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}),Th={translateExtent:so,nodeOrigin:cg,minZoom:.5,maxZoom:2,elementsSelectable:!0,noPanClassName:"nopan",rfId:"1"};function L1(t){const{setNodes:r,setEdges:o,setMinZoom:l,setMaxZoom:u,setTranslateExtent:c,setNodeExtent:f,reset:h,setDefaultNodesAndEdges:p}=Ie(R1,Ve),y=$e();G.useEffect(()=>(p(t.defaultNodes,t.defaultEdges),()=>{m.current=Th,h()}),[]);const m=G.useRef(Th);return G.useEffect(()=>{for(const v of Ih){const g=t[v],w=m.current[v];g!==w&&(typeof t[v]>"u"||(v==="nodes"?r(g):v==="edges"?o(g):v==="minZoom"?l(g):v==="maxZoom"?u(g):v==="translateExtent"?c(g):v==="nodeExtent"?f(g):v==="ariaLabelConfig"?y.setState({ariaLabelConfig:yw(g)}):v==="fitView"?y.setState({fitViewQueued:g}):v==="fitViewOptions"?y.setState({fitViewOptions:g}):y.setState({[v]:g})))}m.current=t},Ih.map(v=>t[v])),null}function zh(){return typeof window>"u"||!window.matchMedia?null:window.matchMedia("(prefers-color-scheme: dark)")}function j1(t){var l;const[r,o]=G.useState(t==="system"?null:t);return G.useEffect(()=>{if(t!=="system"){o(t);return}const u=zh(),c=()=>o(u!=null&&u.matches?"dark":"light");return c(),u==null||u.addEventListener("change",c),()=>{u==null||u.removeEventListener("change",c)}},[t]),r!==null?r:(l=zh())!=null&&l.matches?"dark":"light"}const Rh=typeof document<"u"?document:null;function co(t=null,r={target:Rh,actInsideInputWithModifier:!0}){const[o,l]=G.useState(!1),u=G.useRef(!1),c=G.useRef(new Set([])),[f,h]=G.useMemo(()=>{if(t!==null){const y=(Array.isArray(t)?t:[t]).filter(v=>typeof v=="string").map(v=>v.replace(/\+/g,` +`).replace(` + +`,` ++`).split(` +`)),m=y.reduce((v,g)=>v.concat(...g),[]);return[y,m]}return[[],[]]},[t]);return G.useEffect(()=>{const p=(r==null?void 0:r.target)??Rh,y=(r==null?void 0:r.actInsideInputWithModifier)??!0;if(t!==null){const m=w=>{var N,E;if(u.current=w.ctrlKey||w.metaKey||w.shiftKey||w.altKey,(!u.current||u.current&&!y)&&Up(w))return!1;const M=jh(w.code,h);if(c.current.add(w[M]),Lh(f,c.current,!1)){const R=((E=(N=w.composedPath)==null?void 0:N.call(w))==null?void 0:E[0])||w.target,_=(R==null?void 0:R.nodeName)==="BUTTON"||(R==null?void 0:R.nodeName)==="A";r.preventDefault!==!1&&(u.current||!_)&&w.preventDefault(),l(!0)}},v=w=>{const S=jh(w.code,h);Lh(f,c.current,!0)?(l(!1),c.current.clear()):c.current.delete(w[S]),w.key==="Meta"&&c.current.clear(),u.current=!1},g=()=>{c.current.clear(),l(!1)};return p==null||p.addEventListener("keydown",m),p==null||p.addEventListener("keyup",v),window.addEventListener("blur",g),window.addEventListener("contextmenu",g),()=>{p==null||p.removeEventListener("keydown",m),p==null||p.removeEventListener("keyup",v),window.removeEventListener("blur",g),window.removeEventListener("contextmenu",g)}}},[t,l]),o}function Lh(t,r,o){return t.filter(l=>o||l.length===r.size).some(l=>l.every(u=>r.has(u)))}function jh(t,r){return r.includes(t)?"code":"key"}const A1=()=>{const t=$e();return G.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:l}=t.getState();return l?l.scaleTo(r,o):!1},getZoom:()=>t.getState().transform[2],setViewport:async(r,o)=>{const{transform:[l,u,c],panZoom:f}=t.getState();return f?(await f.setViewport({x:r.x??l,y:r.y??u,zoom:r.zoom??c},o),!0):!1},getViewport:()=>{const[r,o,l]=t.getState().transform;return{x:r,y:o,zoom:l}},setCenter:async(r,o,l)=>t.getState().setCenter(r,o,l),fitBounds:async(r,o)=>{const{width:l,height:u,minZoom:c,maxZoom:f,panZoom:h}=t.getState(),p=nc(r,l,u,c,f,(o==null?void 0:o.padding)??.1);return h?(await h.setViewport(p,{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:l,snapGrid:u,snapToGrid:c,domNode:f}=t.getState();if(!f)return r;const{x:h,y:p}=f.getBoundingClientRect(),y={x:r.x-h,y:r.y-p},m=o.snapGrid??u,v=o.snapToGrid??c;return vo(y,l,v,m)},flowToScreenPosition:r=>{const{transform:o,domNode:l}=t.getState();if(!l)return r;const{x:u,y:c}=l.getBoundingClientRect(),f=ii(r,o);return{x:f.x+u,y:f.y+c}}}),[])};function fg(t,r){const o=[],l=new Map,u=[];for(const c of t)if(c.type==="add"){u.push(c);continue}else if(c.type==="remove"||c.type==="replace")l.set(c.id,[c]);else{const f=l.get(c.id);f?f.push(c):l.set(c.id,[c])}for(const c of r){const f=l.get(c.id);if(!f){o.push(c);continue}if(f[0].type==="remove")continue;if(f[0].type==="replace"){o.push({...f[0].item});continue}const h={...c};for(const p of f)$1(p,h);o.push(h)}return u.length&&u.forEach(c=>{c.index!==void 0?o.splice(c.index,0,{...c.item}):o.push({...c.item})}),o}function $1(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 D1(t,r){return fg(t,r)}function O1(t,r){return fg(t,r)}function fr(t,r){return{id:t,type:"select",selected:r}}function qr(t,r=new Set,o=!1){const l=[];for(const[u,c]of t){const f=r.has(u);!(c.selected===void 0&&!f)&&c.selected!==f&&(o&&(c.selected=f),l.push(fr(c.id,f)))}return l}function Ah({items:t=[],lookup:r}){var u;const o=[],l=new Map(t.map(c=>[c.id,c]));for(const[c,f]of t.entries()){const h=r.get(f.id),p=((u=h==null?void 0:h.internals)==null?void 0:u.userNode)??h;p!==void 0&&p!==f&&o.push({id:f.id,item:f,type:"replace"}),p===void 0&&o.push({item:f,type:"add",index:c})}for(const[c]of r)l.get(c)===void 0&&o.push({id:c,type:"remove"});return o}function $h(t){return{id:t.id,type:"remove"}}const F1=Fp();function H1(t,r,o={}){return Ew(t,r,{...o,onError:o.onError??F1})}const Dh=t=>uw(t),V1=t=>jp(t);function dg(t){return G.forwardRef(t)}const hg=typeof window<"u"?G.useLayoutEffect:G.useEffect;function Oh(t){const[r,o]=G.useState(BigInt(0)),[l]=G.useState(()=>B1(()=>o(u=>u+BigInt(1))));return hg(()=>{const u=l.get();u.length&&(t(u),l.reset())},[r]),l}function B1(t){let r=[];return{get:()=>r,reset:()=>{r=[]},push:o=>{r.push(o),t()}}}const pg=G.createContext(null);function U1({children:t}){const r=$e(),o=G.useCallback(h=>{const{nodes:p=[],setNodes:y,hasDefaultNodes:m,onNodesChange:v,nodeLookup:g,fitViewQueued:w,onNodesChangeMiddlewareMap:S}=r.getState();let M=p;for(const E of h)M=typeof E=="function"?E(M):E;let N=Ah({items:M,lookup:g});for(const E of S.values())N=E(N);m&&y(M),N.length>0?v==null||v(N):w&&window.requestAnimationFrame(()=>{const{fitViewQueued:E,nodes:R,setNodes:_}=r.getState();E&&_(R)})},[]),l=Oh(o),u=G.useCallback(h=>{const{edges:p=[],setEdges:y,hasDefaultEdges:m,onEdgesChange:v,edgeLookup:g}=r.getState();let w=p;for(const S of h)w=typeof S=="function"?S(w):S;m?y(w):v&&v(Ah({items:w,lookup:g}))},[]),c=Oh(u),f=G.useMemo(()=>({nodeQueue:l,edgeQueue:c}),[]);return P.jsx(pg.Provider,{value:f,children:t})}function W1(){const t=G.useContext(pg);if(!t)throw new Error("useBatchContext must be used within a BatchProvider");return t}const b1=t=>!!t.panZoom;function ac(){const t=A1(),r=$e(),o=W1(),l=Ie(b1),u=G.useMemo(()=>{const c=v=>r.getState().nodeLookup.get(v),f=v=>{o.nodeQueue.push(v)},h=v=>{o.edgeQueue.push(v)},p=v=>{var E,R;const{nodeLookup:g,nodeOrigin:w}=r.getState(),S=Dh(v)?v:g.get(v.id),M=S.parentId?Vp(S.position,S.measured,S.parentId,g,w):S.position,N={...S,position:M,width:((E=S.measured)==null?void 0:E.width)??S.width,height:((R=S.measured)==null?void 0:R.height)??S.height};return uo(N)},y=(v,g,w={replace:!1})=>{f(S=>S.map(M=>{if(M.id===v){const N=typeof g=="function"?g(M):g;return w.replace&&Dh(N)?N:{...M,...N}}return M}))},m=(v,g,w={replace:!1})=>{h(S=>S.map(M=>{if(M.id===v){const N=typeof g=="function"?g(M):g;return w.replace&&V1(N)?N:{...M,...N}}return M}))};return{getNodes:()=>r.getState().nodes.map(v=>({...v})),getNode:v=>{var g;return(g=c(v))==null?void 0:g.internals.userNode},getInternalNode:c,getEdges:()=>{const{edges:v=[]}=r.getState();return v.map(g=>({...g}))},getEdge:v=>r.getState().edgeLookup.get(v),setNodes:f,setEdges:h,addNodes:v=>{const g=Array.isArray(v)?v:[v];o.nodeQueue.push(w=>[...w,...g])},addEdges:v=>{const g=Array.isArray(v)?v:[v];o.edgeQueue.push(w=>[...w,...g])},toObject:()=>{const{nodes:v=[],edges:g=[],transform:w}=r.getState(),[S,M,N]=w;return{nodes:v.map(E=>({...E})),edges:g.map(E=>({...E})),viewport:{x:S,y:M,zoom:N}}},deleteElements:async({nodes:v=[],edges:g=[]})=>{const{nodes:w,edges:S,onNodesDelete:M,onEdgesDelete:N,triggerNodeChanges:E,triggerEdgeChanges:R,onDelete:_,onBeforeDelete:I}=r.getState(),{nodes:W,edges:$}=await hw({nodesToRemove:v,edgesToRemove:g,nodes:w,edges:S,onBeforeDelete:I}),V=$.length>0,X=W.length>0;if(V){const K=$.map($h);N==null||N($),R(K)}if(X){const K=W.map($h);M==null||M(W),E(K)}return(X||V)&&(_==null||_({nodes:W,edges:$})),{deletedNodes:W,deletedEdges:$}},getIntersectingNodes:(v,g=!0,w)=>{const S=uh(v),M=S?v:p(v),N=w!==void 0;return M?(w||r.getState().nodes).filter(E=>{const R=r.getState().nodeLookup.get(E.id);if(R&&!S&&(E.id===v.id||!R.internals.positionAbsolute))return!1;const _=uo(N?E:R),I=sl(_,M);return g&&I>0||I>=_.width*_.height||I>=M.width*M.height}):[]},isNodeIntersecting:(v,g,w=!0)=>{const M=uh(v)?v:p(v);if(!M)return!1;const N=sl(M,g);return w&&N>0||N>=g.width*g.height||N>=M.width*M.height},updateNode:y,updateNodeData:(v,g,w={replace:!1})=>{y(v,S=>{const M=typeof g=="function"?g(S):g;return w.replace?{...S,data:M}:{...S,data:{...S.data,...M}}},w)},updateEdge:m,updateEdgeData:(v,g,w={replace:!1})=>{m(v,S=>{const M=typeof g=="function"?g(S):g;return w.replace?{...S,data:M}:{...S,data:{...S.data,...M}}},w)},getNodesBounds:v=>{const{nodeLookup:g,nodeOrigin:w}=r.getState();return aw(v,{nodeLookup:g,nodeOrigin:w})},getHandleConnections:({type:v,id:g,nodeId:w})=>{var S;return Array.from(((S=r.getState().connectionLookup.get(`${w}-${v}${g?`-${g}`:""}`))==null?void 0:S.values())??[])},getNodeConnections:({type:v,handleId:g,nodeId:w})=>{var S;return Array.from(((S=r.getState().connectionLookup.get(`${w}${v?g?`-${v}-${g}`:`-${v}`:""}`))==null?void 0:S.values())??[])},fitView:async v=>{const g=r.getState().fitViewResolver??mw();return r.setState({fitViewQueued:!0,fitViewOptions:v,fitViewResolver:g}),o.nodeQueue.push(w=>[...w]),g.promise}}},[]);return G.useMemo(()=>({...u,...t,viewportInitialized:l}),[l])}const Fh=t=>t.selected,Y1=typeof window<"u"?window:void 0;function X1({deleteKeyCode:t,multiSelectionKeyCode:r}){const o=$e(),{deleteElements:l}=ac(),u=co(t,{actInsideInputWithModifier:!1}),c=co(r,{target:Y1});G.useEffect(()=>{if(u){const{edges:f,nodes:h}=o.getState();l({nodes:h.filter(Fh),edges:f.filter(Fh)}),o.setState({nodesSelectionActive:!1})}},[u]),G.useEffect(()=>{o.setState({multiSelectionActive:c})},[c])}function Q1(t){const r=$e();G.useEffect(()=>{const o=()=>{var u,c,f,h;if(!t.current||!(((c=(u=t.current).checkVisibility)==null?void 0:c.call(u))??!0))return!1;const l=rc(t.current);(l.height===0||l.width===0)&&((h=(f=r.getState()).onError)==null||h.call(f,"004",Yt.error004())),r.setState({width:l.width||500,height:l.height||500})};if(t.current){o(),window.addEventListener("resize",o);const l=new ResizeObserver(()=>o());return l.observe(t.current),()=>{window.removeEventListener("resize",o),l&&t.current&&l.unobserve(t.current)}}},[])}const xl={position:"absolute",width:"100%",height:"100%",top:0,left:0},G1=t=>({userSelectionActive:t.userSelectionActive,lib:t.lib,connectionInProgress:t.connection.inProgress});function K1({onPaneContextMenu:t,zoomOnScroll:r=!0,zoomOnPinch:o=!0,panOnScroll:l=!1,panActivationKeyPressed:u,panOnScrollSpeed:c=.5,panOnScrollMode:f=pr.Free,zoomOnDoubleClick:h=!0,panOnDrag:p=!0,defaultViewport:y,translateExtent:m,minZoom:v,maxZoom:g,zoomActivationKeyCode:w,preventScrolling:S=!0,children:M,noWheelClassName:N,noPanClassName:E,onViewportChange:R,isControlledViewport:_,paneClickDistance:I,selectionOnDrag:W}){const $=$e(),V=G.useRef(null),{userSelectionActive:X,lib:K,connectionInProgress:te}=Ie(G1,Ve),Z=co(w),ee=G.useRef();Q1(V);const J=G.useCallback(k=>{R==null||R({x:k[0],y:k[1],zoom:k[2]}),_||$.setState({transform:k})},[R,_]);return G.useEffect(()=>{if(V.current){ee.current=Jw({domNode:V.current,minZoom:v,maxZoom:g,translateExtent:m,viewport:y,onDraggingChange:U=>$.setState(A=>A.paneDragging===U?A:{paneDragging:U}),onPanZoomStart:(U,A)=>{const{onViewportChangeStart:j,onMoveStart:F}=$.getState();F==null||F(U,A),j==null||j(A)},onPanZoom:(U,A)=>{const{onViewportChange:j,onMove:F}=$.getState();F==null||F(U,A),j==null||j(A)},onPanZoomEnd:(U,A)=>{const{onViewportChangeEnd:j,onMoveEnd:F}=$.getState();F==null||F(U,A),j==null||j(A)}});const{x:k,y:B,zoom:H}=ee.current.getViewport();return $.setState({panZoom:ee.current,transform:[k,B,H],domNode:V.current.closest(".react-flow")}),()=>{var U;(U=ee.current)==null||U.destroy()}}},[]),G.useEffect(()=>{var k;(k=ee.current)==null||k.update({onPaneContextMenu:t,zoomOnScroll:r,zoomOnPinch:o,panOnScroll:l,panActivationKeyPressed:u,panOnScrollSpeed:c,panOnScrollMode:f,zoomOnDoubleClick:h,panOnDrag:p,zoomActivationKeyPressed:Z,preventScrolling:S,noPanClassName:E,userSelectionActive:X,noWheelClassName:N,lib:K,onTransformChange:J,connectionInProgress:te,selectionOnDrag:W,paneClickDistance:I})},[t,r,o,l,u,c,f,h,p,Z,S,E,X,N,K,J,te,W,I]),P.jsx("div",{className:"react-flow__renderer",ref:V,style:xl,children:M})}const q1=t=>({userSelectionActive:t.userSelectionActive,userSelectionRect:t.userSelectionRect});function Z1(){const{userSelectionActive:t,userSelectionRect:r}=Ie(q1,Ve);return t&&r?P.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 Ia=(t,r)=>o=>{o.target===r.current&&(t==null||t(o))},J1=t=>({userSelectionActive:t.userSelectionActive,elementsSelectable:t.elementsSelectable,dragging:t.paneDragging,panBy:t.panBy,autoPanSpeed:t.autoPanSpeed});function eS({isSelecting:t,selectionKeyPressed:r,selectionMode:o=lo.Full,panOnDrag:l,autoPanOnSelection:u,paneClickDistance:c,selectionOnDrag:f,onSelectionStart:h,onSelectionEnd:p,onPaneClick:y,onPaneContextMenu:m,onPaneScroll:v,onPaneMouseEnter:g,onPaneMouseMove:w,onPaneMouseLeave:S,children:M}){const N=G.useRef(0),E=$e(),{userSelectionActive:R,elementsSelectable:_,dragging:I,panBy:W,autoPanSpeed:$}=Ie(J1,Ve),V=_&&(t||R),X=G.useRef(null),K=G.useRef(),te=G.useRef(new Set),Z=G.useRef(new Set),ee=G.useRef(!1),J=G.useRef(!1),k=G.useRef({x:0,y:0}),B=G.useRef(!1),H=Q=>{if(J.current||ee.current||E.getState().connection.inProgress){J.current=!1,ee.current=!1;return}y==null||y(Q),E.getState().resetSelectedElements(),E.setState({nodesSelectionActive:!1})},U=Q=>{if(Array.isArray(l)&&(l!=null&&l.includes(2))){Q.preventDefault();return}m==null||m(Q)},A=v?Q=>v(Q):void 0,j=Q=>{J.current&&(Q.stopPropagation(),J.current=!1)},F=Q=>{var Re,ot;if(Q.pointerType==="touch"&&l!==!1&&!r)return;const{domNode:le,transform:pe}=E.getState();if(K.current=le==null?void 0:le.getBoundingClientRect(),!K.current)return;const we=Q.target===X.current;if(!we&&!!Q.target.closest(".nokey")||!t||!(f&&we||r)||Q.button!==0||!Q.isPrimary)return;(ot=(Re=Q.target)==null?void 0:Re.setPointerCapture)==null||ot.call(Re,Q.pointerId),J.current=!1;const{x:ke,y:Ce}=bt(Q.nativeEvent,K.current),Me=vo({x:ke,y:Ce},pe);E.setState({userSelectionRect:{width:0,height:0,startX:Me.x,startY:Me.y,x:ke,y:Ce}}),we||(Q.stopPropagation(),Q.preventDefault())};function C(Q,le){const{userSelectionRect:pe}=E.getState();if(!pe)return;const{transform:we,nodeLookup:ve,edgeLookup:me,connectionLookup:ke,triggerNodeChanges:Ce,triggerEdgeChanges:Me,defaultEdgeOptions:Re}=E.getState(),ot={x:pe.startX,y:pe.startY},{x:ut,y:Je}=ii(ot,we),et={startX:ot.x,startY:ot.y,x:Qat.id)),Z.current=new Set;const Kt=(Re==null?void 0:Re.selectable)??!0;for(const at of te.current){const Ct=ke.get(at);if(Ct)for(const{edgeId:yt}of Ct.values()){const Mt=me.get(yt);Mt&&(Mt.selectable??Kt)&&Z.current.add(yt)}}if(!ah(sn,te.current)){const at=qr(ve,te.current,!0);Ce(at)}if(!ah(Gt,Z.current)){const at=qr(me,Z.current);Me(at)}E.setState({userSelectionRect:et,userSelectionActive:!0,nodesSelectionActive:!1})}function z(){if(!u||!K.current)return;const[Q,le]=tc(k.current,K.current,$);W({x:Q,y:le}).then(pe=>{if(!J.current||!pe){N.current=requestAnimationFrame(z);return}const{x:we,y:ve}=k.current;C(we,ve),N.current=requestAnimationFrame(z)})}const ne=()=>{cancelAnimationFrame(N.current),N.current=0,B.current=!1};G.useEffect(()=>()=>ne(),[]);const ie=Q=>{const{userSelectionRect:le,transform:pe,resetSelectedElements:we}=E.getState();if(!K.current||!le)return;const{x:ve,y:me}=bt(Q.nativeEvent,K.current);k.current={x:ve,y:me};const ke=ii({x:le.startX,y:le.startY},pe);if(!J.current){const Ce=r?0:c;if(Math.hypot(ve-ke.x,me-ke.y)<=Ce)return;we(),h==null||h(Q)}J.current=!0,B.current||(z(),B.current=!0),C(ve,me)},ce=Q=>{var le,pe;if(!V){Q.target===X.current&&E.getState().connection.inProgress&&(ee.current=!0);return}Q.button===0&&((pe=(le=Q.target)==null?void 0:le.releasePointerCapture)==null||pe.call(le,Q.pointerId),!R&&Q.target===X.current&&E.getState().userSelectionRect&&(H==null||H(Q)),E.setState({userSelectionActive:!1,userSelectionRect:null}),J.current&&(p==null||p(Q),E.setState({nodesSelectionActive:te.current.size>0})),ne())},O=Q=>{var le,pe;(pe=(le=Q.target)==null?void 0:le.releasePointerCapture)==null||pe.call(le,Q.pointerId),ne()},re=l===!0||Array.isArray(l)&&l.includes(0);return P.jsxs("div",{className:be(["react-flow__pane",{draggable:re,dragging:I,selection:t}]),onClick:V?void 0:Ia(H,X),onContextMenu:Ia(U,X),onWheel:Ia(A,X),onPointerEnter:V?void 0:g,onPointerMove:V?ie:w,onPointerUp:ce,onPointerCancel:V?O:void 0,onPointerDownCapture:V?F:void 0,onClickCapture:V?j:void 0,onPointerLeave:S,ref:X,style:xl,children:[M,P.jsx(Z1,{})]})}function ba({id:t,store:r,unselect:o=!1,nodeRef:l}){const{addSelectedNodes:u,unselectNodesAndEdges:c,multiSelectionActive:f,nodeLookup:h,onError:p}=r.getState(),y=h.get(t);if(!y){p==null||p("012",Yt.error012(t));return}r.setState({nodesSelectionActive:!1}),y.selected?(o||y.selected&&f)&&(c({nodes:[y],edges:[]}),requestAnimationFrame(()=>{var m;return(m=l==null?void 0:l.current)==null?void 0:m.blur()})):u([t])}function gg({nodeRef:t,disabled:r=!1,noDragClassName:o,handleSelector:l,nodeId:u,isSelectable:c,nodeClickDistance:f}){const h=$e(),[p,y]=G.useState(!1),m=G.useRef();return G.useEffect(()=>{if(!r)return m.current=Fw({getStoreItems:()=>h.getState(),onNodeMouseDown:v=>{ba({id:v,store:h,nodeRef:t})},onDragStart:()=>{y(!0)},onDragStop:()=>{y(!1)}}),()=>{var v;(v=m.current)==null||v.destroy(),m.current=void 0}},[r,h,t]),G.useEffect(()=>{r||!t.current||!m.current||m.current.update({noDragClassName:o,handleSelector:l,domNode:t.current,isSelectable:c,nodeId:u,nodeClickDistance:f})},[o,l,r,c,t,u,f]),p}const tS=t=>r=>r.selected&&(r.draggable||t&&typeof r.draggable>"u");function mg(){const t=$e();return G.useCallback(o=>{const{nodeExtent:l,snapToGrid:u,snapGrid:c,nodesDraggable:f,onError:h,updateNodePositions:p,nodeLookup:y,nodeOrigin:m}=t.getState(),v=new Map,g=tS(f),w=u?c[0]:5,S=u?c[1]:5,M=o.direction.x*w*o.factor,N=o.direction.y*S*o.factor;for(const[,E]of y){if(!g(E))continue;let R={x:E.internals.positionAbsolute.x+M,y:E.internals.positionAbsolute.y+N};u&&(R=yo(R,c));const{position:_,positionAbsolute:I}=Ap({nodeId:E.id,nextPosition:R,nodeLookup:y,nodeExtent:l,nodeOrigin:m,onError:h});E.position=_,E.internals.positionAbsolute=I,v.set(E.id,E)}p(v)},[])}const cc=G.createContext(null),nS=cc.Provider;cc.Consumer;const yg=()=>G.useContext(cc),rS=t=>({connectOnClick:t.connectOnClick,noPanClassName:t.noPanClassName,rfId:t.rfId}),vg=G.createContext(null);function iS({children:t}){const r=Ie(rS,Ve);return P.jsx(vg.Provider,{value:r,children:t})}function oS(){const t=G.useContext(vg);if(!t)throw new Error("useHandleConfig must be used within a HandleConfigProvider");return t}const sS={connectingFrom:!1,connectingTo:!1,clickConnecting:!1,isPossibleEndHandle:!0,connectionInProcess:!1,clickConnectionInProcess:!1,valid:!1},lS=(t,r,o)=>l=>{const{connectionClickStartHandle:u,connectionMode:c,connection:f}=l,{fromHandle:h,toHandle:p,isValid:y}=f;if(!h&&!u)return sS;const m=(p==null?void 0:p.nodeId)===t&&(p==null?void 0:p.id)===r&&(p==null?void 0:p.type)===o;return{connectingFrom:(h==null?void 0:h.nodeId)===t&&(h==null?void 0:h.id)===r&&(h==null?void 0:h.type)===o,connectingTo:m,clickConnecting:(u==null?void 0:u.nodeId)===t&&(u==null?void 0:u.id)===r&&(u==null?void 0:u.type)===o,isPossibleEndHandle:c===ni.Strict?(h==null?void 0:h.type)!==o:t!==(h==null?void 0:h.nodeId)||r!==(h==null?void 0:h.id),connectionInProcess:!!h,clickConnectionInProcess:!!u,valid:m&&y}};function uS({type:t="source",position:r=xe.Top,isValidConnection:o,isConnectable:l=!0,isConnectableStart:u=!0,isConnectableEnd:c=!0,id:f,onConnect:h,children:p,className:y,onMouseDown:m,onTouchStart:v,...g},w){var B,H;const S=f||null,M=t==="target",N=$e(),E=yg(),{connectOnClick:R,noPanClassName:_,rfId:I}=oS(),{connectingFrom:W,connectingTo:$,clickConnecting:V,isPossibleEndHandle:X,connectionInProcess:K,clickConnectionInProcess:te,valid:Z}=Ie(lS(E,S,t),Ve);E||(H=(B=N.getState()).onError)==null||H.call(B,"010",Yt.error010());const ee=U=>{const{defaultEdgeOptions:A,onConnect:j,hasDefaultEdges:F}=N.getState(),C={...A,...U};if(F){const{edges:z,setEdges:ne,onError:ie}=N.getState();ne(H1(C,z,{onError:ie}))}j==null||j(C),h==null||h(C)},J=U=>{if(!E)return;const A=Wp(U.nativeEvent);if(u&&(A&&U.button===0||!A)){const j=N.getState();Wa.onPointerDown(U.nativeEvent,{handleDomNode:U.currentTarget,autoPanOnConnect:j.autoPanOnConnect,connectionMode:j.connectionMode,connectionRadius:j.connectionRadius,domNode:j.domNode,nodeLookup:j.nodeLookup,lib:j.lib,isTarget:M,handleId:S,nodeId:E,flowId:j.rfId,panBy:j.panBy,cancelConnection:j.cancelConnection,onConnectStart:j.onConnectStart,onConnectEnd:(...F)=>{var C,z;return(z=(C=N.getState()).onConnectEnd)==null?void 0:z.call(C,...F)},updateConnection:j.updateConnection,onConnect:ee,isValidConnection:o||((...F)=>{var C,z;return((z=(C=N.getState()).isValidConnection)==null?void 0:z.call(C,...F))??!0}),getTransform:()=>N.getState().transform,getFromHandle:()=>N.getState().connection.fromHandle,autoPanSpeed:j.autoPanSpeed,dragThreshold:j.connectionDragThreshold})}A?m==null||m(U):v==null||v(U)},k=U=>{const{onClickConnectStart:A,onClickConnectEnd:j,connectionClickStartHandle:F,connectionMode:C,isValidConnection:z,lib:ne,rfId:ie,nodeLookup:ce,connection:O}=N.getState();if(!E||!F&&!u)return;if(!F){A==null||A(U.nativeEvent,{nodeId:E,handleId:S,handleType:t}),N.setState({connectionClickStartHandle:{nodeId:E,type:t,id:S}});return}const re=Bp(U.target),Q=o||z,{connection:le,isValid:pe}=Wa.isValid(U.nativeEvent,{handle:{nodeId:E,id:S,type:t},connectionMode:C,fromNodeId:F.nodeId,fromHandleId:F.id||null,fromType:F.type,isValidConnection:Q,flowId:ie,doc:re,lib:ne,nodeLookup:ce});pe&&le&&ee(le);const we=structuredClone(O);delete we.inProgress,we.toPosition=we.toHandle?we.toHandle.position:null,j==null||j(U,we),N.setState({connectionClickStartHandle:null})};return P.jsx("div",{"data-handleid":S,"data-nodeid":E,"data-handlepos":r,"data-id":`${I}-${E}-${S}-${t}`,className:be(["react-flow__handle",`react-flow__handle-${r}`,"nodrag",_,y,{source:!M,target:M,connectable:l,connectablestart:u,connectableend:c,clickconnecting:V,connectingfrom:W,connectingto:$,valid:Z,connectionindicator:l&&(!K||X)&&(K||te?c:u)}]),onMouseDown:J,onTouchStart:J,onClick:R?k:void 0,ref:w,...g,children:p})}const ll=G.memo(dg(uS));function aS({data:t,isConnectable:r,sourcePosition:o=xe.Bottom}){return P.jsxs(P.Fragment,{children:[t==null?void 0:t.label,P.jsx(ll,{type:"source",position:o,isConnectable:r})]})}function cS({data:t,isConnectable:r,targetPosition:o=xe.Top,sourcePosition:l=xe.Bottom}){return P.jsxs(P.Fragment,{children:[P.jsx(ll,{type:"target",position:o,isConnectable:r}),t==null?void 0:t.label,P.jsx(ll,{type:"source",position:l,isConnectable:r})]})}function fS(){return null}function dS({data:t,isConnectable:r,targetPosition:o=xe.Top}){return P.jsxs(P.Fragment,{children:[P.jsx(ll,{type:"target",position:o,isConnectable:r}),t==null?void 0:t.label]})}const ul={ArrowUp:{x:0,y:-1},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0},ArrowRight:{x:1,y:0}},Hh={input:aS,default:cS,output:dS,group:fS};function hS(t){var r,o,l,u;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??((l=t.style)==null?void 0:l.width),height:t.height??((u=t.style)==null?void 0:u.height)}}const pS=t=>{const{width:r,height:o,x:l,y:u}=mo(t.nodeLookup,{filter:c=>!!c.selected});return{width:Wt(r)?r:null,height:Wt(o)?o:null,userSelectionActive:t.userSelectionActive,transformString:`translate(${t.transform[0]}px,${t.transform[1]}px) scale(${t.transform[2]}) translate(${l}px,${u}px)`}};function gS({onSelectionContextMenu:t,noPanClassName:r,disableKeyboardA11y:o}){const l=$e(),{width:u,height:c,transformString:f,userSelectionActive:h}=Ie(pS,Ve),p=mg(),y=G.useRef(null);G.useEffect(()=>{var w;o||(w=y.current)==null||w.focus({preventScroll:!0})},[o]);const m=!h&&u!==null&&c!==null;if(gg({nodeRef:y,disabled:!m}),!m)return null;const v=t?w=>{const S=l.getState().nodes.filter(M=>M.selected);t(w,S)}:void 0,g=w=>{Object.prototype.hasOwnProperty.call(ul,w.key)&&(w.preventDefault(),p({direction:ul[w.key],factor:w.shiftKey?4:1}))};return P.jsx("div",{className:be(["react-flow__nodesselection","react-flow__container",r]),style:{transform:f},children:P.jsx("div",{ref:y,className:"react-flow__nodesselection-rect",onContextMenu:v,tabIndex:o?void 0:-1,onKeyDown:o?void 0:g,style:{width:u,height:c}})})}const Vh=typeof window<"u"?window:void 0,mS=t=>({nodesSelectionActive:t.nodesSelectionActive,userSelectionActive:t.userSelectionActive});function xg({children:t,onPaneClick:r,onPaneMouseEnter:o,onPaneMouseMove:l,onPaneMouseLeave:u,onPaneContextMenu:c,onPaneScroll:f,paneClickDistance:h,deleteKeyCode:p,selectionKeyCode:y,selectionOnDrag:m,selectionMode:v,onSelectionStart:g,onSelectionEnd:w,multiSelectionKeyCode:S,panActivationKeyCode:M,zoomActivationKeyCode:N,elementsSelectable:E,zoomOnScroll:R,zoomOnPinch:_,panOnScroll:I,panOnScrollSpeed:W,panOnScrollMode:$,zoomOnDoubleClick:V,panOnDrag:X,autoPanOnSelection:K,defaultViewport:te,translateExtent:Z,minZoom:ee,maxZoom:J,preventScrolling:k,onSelectionContextMenu:B,noWheelClassName:H,noPanClassName:U,disableKeyboardA11y:A,onViewportChange:j,isControlledViewport:F}){const{nodesSelectionActive:C,userSelectionActive:z}=Ie(mS,Ve),ne=co(y,{target:Vh}),ie=co(M,{target:Vh}),ce=ie||X,O=ie||I,re=m&&ce!==!0,Q=ne||z||re;return X1({deleteKeyCode:p,multiSelectionKeyCode:S}),P.jsx(K1,{onPaneContextMenu:c,elementsSelectable:E,zoomOnScroll:R,zoomOnPinch:_,panOnScroll:O,panActivationKeyPressed:ie,panOnScrollSpeed:W,panOnScrollMode:$,zoomOnDoubleClick:V,panOnDrag:!ne&&ce,defaultViewport:te,translateExtent:Z,minZoom:ee,maxZoom:J,zoomActivationKeyCode:N,preventScrolling:k,noWheelClassName:H,noPanClassName:U,onViewportChange:j,isControlledViewport:F,paneClickDistance:h,selectionOnDrag:re,children:P.jsxs(eS,{onSelectionStart:g,onSelectionEnd:w,onPaneClick:r,onPaneMouseEnter:o,onPaneMouseMove:l,onPaneMouseLeave:u,onPaneContextMenu:c,onPaneScroll:f,panOnDrag:ce,autoPanOnSelection:K,isSelecting:!!Q,selectionMode:v,selectionKeyPressed:ne,paneClickDistance:h,selectionOnDrag:re,children:[t,C&&P.jsx(gS,{onSelectionContextMenu:B,noPanClassName:U,disableKeyboardA11y:A})]})})}xg.displayName="FlowRenderer";const yS=G.memo(xg),vS=t=>r=>t?ec(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 xS(t){return Ie(G.useCallback(vS(t),[t]),Ve)}const wS=t=>t.updateNodeInternals;function SS(){const t=Ie(wS),[r]=G.useState(()=>typeof ResizeObserver>"u"?null:new ResizeObserver(o=>{const l=new Map;o.forEach(u=>{const c=u.target.getAttribute("data-id");l.set(c,{id:c,nodeElement:u.target,force:!0})}),t(l)}));return G.useEffect(()=>()=>{r==null||r.disconnect()},[r]),r}function _S({node:t,nodeType:r,hasDimensions:o,resizeObserver:l}){const u=$e(),c=G.useRef(null),f=G.useRef(null),h=G.useRef(t.sourcePosition),p=G.useRef(t.targetPosition),y=G.useRef(r),m=o&&!!t.internals.handleBounds;return G.useEffect(()=>{c.current&&!t.hidden&&(!m||f.current!==c.current)&&(f.current&&(l==null||l.unobserve(f.current)),l==null||l.observe(c.current),f.current=c.current)},[m,t.hidden]),G.useEffect(()=>()=>{f.current&&(l==null||l.unobserve(f.current),f.current=null)},[]),G.useEffect(()=>{if(c.current){const v=y.current!==r,g=h.current!==t.sourcePosition,w=p.current!==t.targetPosition;(v||g||w)&&(y.current=r,h.current=t.sourcePosition,p.current=t.targetPosition,u.getState().updateNodeInternals(new Map([[t.id,{id:t.id,nodeElement:c.current,force:!0}]])))}},[t.id,r,t.sourcePosition,t.targetPosition]),c}function ES({id:t,onClick:r,onMouseEnter:o,onMouseMove:l,onMouseLeave:u,onContextMenu:c,onDoubleClick:f,nodesDraggable:h,elementsSelectable:p,nodesConnectable:y,nodesFocusable:m,resizeObserver:v,noDragClassName:g,noPanClassName:w,disableKeyboardA11y:S,rfId:M,nodeTypes:N,nodeClickDistance:E,onError:R}){const{node:_,internals:I,isParent:W}=Ie(Q=>{const le=Q.nodeLookup.get(t),pe=Q.parentLookup.has(t);return{node:le,internals:le.internals,isParent:pe}},Ve);let $=_.type||"default",V=(N==null?void 0:N[$])||Hh[$];V===void 0&&(R==null||R("003",Yt.error003($)),$="default",V=(N==null?void 0:N.default)||Hh.default);const X=!!(_.draggable||h&&typeof _.draggable>"u"),K=!!(_.selectable||p&&typeof _.selectable>"u"),te=!!(_.connectable||y&&typeof _.connectable>"u"),Z=!!(_.focusable||m&&typeof _.focusable>"u"),ee=$e(),J=Hp(_),k=_S({node:_,nodeType:$,hasDimensions:J,resizeObserver:v}),B=gg({nodeRef:k,disabled:_.hidden||!X,noDragClassName:g,handleSelector:_.dragHandle,nodeId:t,isSelectable:K,nodeClickDistance:E}),H=mg();if(_.hidden)return null;const U=Qt(_),A=hS(_),j=K||X||r||o||l||u,F=o?Q=>o(Q,{...I.userNode}):void 0,C=l?Q=>l(Q,{...I.userNode}):void 0,z=u?Q=>u(Q,{...I.userNode}):void 0,ne=c?Q=>c(Q,{...I.userNode}):void 0,ie=f?Q=>f(Q,{...I.userNode}):void 0,ce=Q=>{const{selectNodesOnDrag:le,nodeDragThreshold:pe}=ee.getState();K&&(!le||!X||pe>0)&&ba({id:t,store:ee,nodeRef:k}),r&&r(Q,{...I.userNode})},O=Q=>{if(!(Up(Q.nativeEvent)||S)){if(Tp.includes(Q.key)&&K){const le=Q.key==="Escape";ba({id:t,store:ee,unselect:le,nodeRef:k})}else if(X&&_.selected&&Object.prototype.hasOwnProperty.call(ul,Q.key)){Q.preventDefault();const{ariaLabelConfig:le}=ee.getState();ee.setState({ariaLiveMessage:le["node.a11yDescription.ariaLiveMessage"]({direction:Q.key.replace("Arrow","").toLowerCase(),x:~~I.positionAbsolute.x,y:~~I.positionAbsolute.y})}),H({direction:ul[Q.key],factor:Q.shiftKey?4:1})}}},re=()=>{var ke;if(S||!((ke=k.current)!=null&&ke.matches(":focus-visible")))return;const{transform:Q,width:le,height:pe,autoPanOnNodeFocus:we,setCenter:ve}=ee.getState();if(!we)return;ec(new Map([[t,_]]),{x:0,y:0,width:le,height:pe},Q,!0).length>0||ve(_.position.x+U.width/2,_.position.y+U.height/2,{zoom:Q[2]})};return P.jsx("div",{className:be(["react-flow__node",`react-flow__node-${$}`,{[w]:X},_.className,{selected:_.selected,selectable:K,parent:W,draggable:X,dragging:B}]),ref:k,style:{zIndex:I.z,transform:`translate(${I.positionAbsolute.x}px,${I.positionAbsolute.y}px)`,pointerEvents:j?"all":"none",visibility:J?"visible":"hidden",..._.style,...A},"data-id":t,"data-testid":`rf__node-${t}`,onMouseEnter:F,onMouseMove:C,onMouseLeave:z,onContextMenu:ne,onClick:ce,onDoubleClick:ie,onKeyDown:Z?O:void 0,tabIndex:Z?0:void 0,onFocus:Z?re:void 0,role:_.ariaRole??(Z?"group":void 0),"aria-roledescription":"node","aria-describedby":S?void 0:`${ug}-${M}`,"aria-label":_.ariaLabel,..._.domAttributes,children:P.jsx(nS,{value:t,children:P.jsx(V,{id:t,data:_.data,type:$,positionAbsoluteX:I.positionAbsolute.x,positionAbsoluteY:I.positionAbsolute.y,selected:_.selected??!1,selectable:K,draggable:X,deletable:_.deletable??!0,isConnectable:te,sourcePosition:_.sourcePosition,targetPosition:_.targetPosition,dragging:B,dragHandle:_.dragHandle,zIndex:I.z,parentId:_.parentId,...U})})})}var kS=G.memo(ES);const NS=t=>({nodesConnectable:t.nodesConnectable,nodesFocusable:t.nodesFocusable,elementsSelectable:t.elementsSelectable,onError:t.onError});function wg(t){const{nodesConnectable:r,nodesFocusable:o,elementsSelectable:l,onError:u}=Ie(NS,Ve),c=xS(t.onlyRenderVisibleElements),f=SS();return P.jsx("div",{className:"react-flow__nodes",style:xl,children:c.map(h=>P.jsx(kS,{id:h,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:f,nodesDraggable:t.nodesDraggable??!0,nodesConnectable:r,nodesFocusable:o,elementsSelectable:l,nodeClickDistance:t.nodeClickDistance,onError:u},h))})}wg.displayName="NodeRenderer";const CS=G.memo(wg);function MS(t){return Ie(G.useCallback(o=>{if(!t)return o.edges.map(u=>u.id);const l=[];if(o.width&&o.height)for(const u of o.edges){const c=o.nodeLookup.get(u.source),f=o.nodeLookup.get(u.target);c&&f&&ww({sourceNode:c,targetNode:f,width:o.width,height:o.height,transform:o.transform})&&l.push(u.id)}return l},[t]),Ve)}const PS=({color:t="none",strokeWidth:r=1})=>{const o={strokeWidth:r,...t&&{stroke:t}};return P.jsx("polyline",{className:"arrow",style:o,strokeLinecap:"round",fill:"none",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4"})},IS=({color:t="none",strokeWidth:r=1})=>{const o={strokeWidth:r,...t&&{stroke:t,fill:t}};return P.jsx("polyline",{className:"arrowclosed",style:o,strokeLinecap:"round",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4 -5,-4"})},Bh={[il.Arrow]:PS,[il.ArrowClosed]:IS};function TS(t){const r=$e();return G.useMemo(()=>{var u,c;return Object.prototype.hasOwnProperty.call(Bh,t)?Bh[t]:((c=(u=r.getState()).onError)==null||c.call(u,"009",Yt.error009(t)),null)},[t])}const zS=({id:t,type:r,color:o,width:l=12.5,height:u=12.5,markerUnits:c="strokeWidth",strokeWidth:f,orient:h="auto-start-reverse"})=>{const p=TS(r);return p?P.jsx("marker",{className:"react-flow__arrowhead",id:t,markerWidth:`${l}`,markerHeight:`${u}`,viewBox:"-10 -10 20 20",markerUnits:c,orient:h,refX:"0",refY:"0",children:P.jsx(p,{color:o,strokeWidth:f})}):null},Sg=({defaultColor:t,rfId:r})=>{const o=Ie(c=>c.edges),l=Ie(c=>c.defaultEdgeOptions),u=G.useMemo(()=>Pw(o,{id:r,defaultColor:t,defaultMarkerStart:l==null?void 0:l.markerStart,defaultMarkerEnd:l==null?void 0:l.markerEnd}),[o,l,r,t]);return u.length?P.jsx("svg",{className:"react-flow__marker","aria-hidden":"true",children:P.jsx("defs",{children:u.map(c=>P.jsx(zS,{id:c.id,type:c.type,color:c.color,width:c.width,height:c.height,markerUnits:c.markerUnits,strokeWidth:c.strokeWidth,orient:c.orient},c.id))})}):null};Sg.displayName="MarkerDefinitions";var RS=G.memo(Sg);function _g({x:t,y:r,label:o,labelStyle:l,labelShowBg:u=!0,labelBgStyle:c,labelBgPadding:f=[2,4],labelBgBorderRadius:h=2,children:p,className:y,...m}){const[v,g]=G.useState({x:1,y:0,width:0,height:0}),w=be(["react-flow__edge-textwrapper",y]),S=G.useRef(null);return G.useEffect(()=>{if(S.current){const M=S.current.getBBox();g({x:M.x,y:M.y,width:M.width,height:M.height})}},[o]),o?P.jsxs("g",{transform:`translate(${t-v.width/2} ${r-v.height/2})`,className:w,visibility:v.width?"visible":"hidden",...m,children:[u&&P.jsx("rect",{width:v.width+2*f[0],x:-f[0],y:-f[1],height:v.height+2*f[1],className:"react-flow__edge-textbg",style:c,rx:h,ry:h}),P.jsx("text",{className:"react-flow__edge-text",y:v.height/2,dy:"0.3em",ref:S,style:l,children:o}),p]}):null}_g.displayName="EdgeText";const LS=G.memo(_g);function wl({path:t,labelX:r,labelY:o,label:l,labelStyle:u,labelShowBg:c,labelBgStyle:f,labelBgPadding:h,labelBgBorderRadius:p,interactionWidth:y=20,...m}){return P.jsxs(P.Fragment,{children:[P.jsx("path",{...m,d:t,fill:"none",className:be(["react-flow__edge-path",m.className])}),y?P.jsx("path",{d:t,fill:"none",strokeOpacity:0,strokeWidth:y,className:"react-flow__edge-interaction"}):null,l&&Wt(r)&&Wt(o)?P.jsx(LS,{x:r,y:o,label:l,labelStyle:u,labelShowBg:c,labelBgStyle:f,labelBgPadding:h,labelBgBorderRadius:p}):null]})}function Uh({pos:t,x1:r,y1:o,x2:l,y2:u}){return t===xe.Left||t===xe.Right?[.5*(r+l),o]:[r,.5*(o+u)]}function Eg({sourceX:t,sourceY:r,sourcePosition:o=xe.Bottom,targetX:l,targetY:u,targetPosition:c=xe.Top}){const[f,h]=Uh({pos:o,x1:t,y1:r,x2:l,y2:u}),[p,y]=Uh({pos:c,x1:l,y1:u,x2:t,y2:r}),[m,v,g,w]=bp({sourceX:t,sourceY:r,targetX:l,targetY:u,sourceControlX:f,sourceControlY:h,targetControlX:p,targetControlY:y});return[`M${t},${r} C${f},${h} ${p},${y} ${l},${u}`,m,v,g,w]}function kg(t){return G.memo(({id:r,sourceX:o,sourceY:l,targetX:u,targetY:c,sourcePosition:f,targetPosition:h,label:p,labelStyle:y,labelShowBg:m,labelBgStyle:v,labelBgPadding:g,labelBgBorderRadius:w,style:S,markerEnd:M,markerStart:N,interactionWidth:E})=>{const[R,_,I]=Eg({sourceX:o,sourceY:l,sourcePosition:f,targetX:u,targetY:c,targetPosition:h}),W=t.isInternal?void 0:r;return P.jsx(wl,{id:W,path:R,labelX:_,labelY:I,label:p,labelStyle:y,labelShowBg:m,labelBgStyle:v,labelBgPadding:g,labelBgBorderRadius:w,style:S,markerEnd:M,markerStart:N,interactionWidth:E})})}const jS=kg({isInternal:!1}),Ng=kg({isInternal:!0});jS.displayName="SimpleBezierEdge";Ng.displayName="SimpleBezierEdgeInternal";function Cg(t){return G.memo(({id:r,sourceX:o,sourceY:l,targetX:u,targetY:c,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:y,labelBgPadding:m,labelBgBorderRadius:v,style:g,sourcePosition:w=xe.Bottom,targetPosition:S=xe.Top,markerEnd:M,markerStart:N,pathOptions:E,interactionWidth:R})=>{const[_,I,W]=Va({sourceX:o,sourceY:l,sourcePosition:w,targetX:u,targetY:c,targetPosition:S,borderRadius:E==null?void 0:E.borderRadius,offset:E==null?void 0:E.offset,stepPosition:E==null?void 0:E.stepPosition}),$=t.isInternal?void 0:r;return P.jsx(wl,{id:$,path:_,labelX:I,labelY:W,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:y,labelBgPadding:m,labelBgBorderRadius:v,style:g,markerEnd:M,markerStart:N,interactionWidth:R})})}const Mg=Cg({isInternal:!1}),Pg=Cg({isInternal:!0});Mg.displayName="SmoothStepEdge";Pg.displayName="SmoothStepEdgeInternal";function Ig(t){return G.memo(({id:r,...o})=>{var u;const l=t.isInternal?void 0:r;return P.jsx(Mg,{...o,id:l,pathOptions:G.useMemo(()=>{var c;return{borderRadius:0,offset:(c=o.pathOptions)==null?void 0:c.offset}},[(u=o.pathOptions)==null?void 0:u.offset])})})}const AS=Ig({isInternal:!1}),Tg=Ig({isInternal:!0});AS.displayName="StepEdge";Tg.displayName="StepEdgeInternal";function zg(t){return G.memo(({id:r,sourceX:o,sourceY:l,targetX:u,targetY:c,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:y,labelBgPadding:m,labelBgBorderRadius:v,style:g,markerEnd:w,markerStart:S,interactionWidth:M})=>{const[N,E,R]=Qp({sourceX:o,sourceY:l,targetX:u,targetY:c}),_=t.isInternal?void 0:r;return P.jsx(wl,{id:_,path:N,labelX:E,labelY:R,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:y,labelBgPadding:m,labelBgBorderRadius:v,style:g,markerEnd:w,markerStart:S,interactionWidth:M})})}const $S=zg({isInternal:!1}),Rg=zg({isInternal:!0});$S.displayName="StraightEdge";Rg.displayName="StraightEdgeInternal";function Lg(t){return G.memo(({id:r,sourceX:o,sourceY:l,targetX:u,targetY:c,sourcePosition:f=xe.Bottom,targetPosition:h=xe.Top,label:p,labelStyle:y,labelShowBg:m,labelBgStyle:v,labelBgPadding:g,labelBgBorderRadius:w,style:S,markerEnd:M,markerStart:N,pathOptions:E,interactionWidth:R})=>{const[_,I,W]=Yp({sourceX:o,sourceY:l,sourcePosition:f,targetX:u,targetY:c,targetPosition:h,curvature:E==null?void 0:E.curvature}),$=t.isInternal?void 0:r;return P.jsx(wl,{id:$,path:_,labelX:I,labelY:W,label:p,labelStyle:y,labelShowBg:m,labelBgStyle:v,labelBgPadding:g,labelBgBorderRadius:w,style:S,markerEnd:M,markerStart:N,interactionWidth:R})})}const DS=Lg({isInternal:!1}),jg=Lg({isInternal:!0});DS.displayName="BezierEdge";jg.displayName="BezierEdgeInternal";const Wh={default:jg,straight:Rg,step:Tg,smoothstep:Pg,simplebezier:Ng},bh={sourceX:null,sourceY:null,targetX:null,targetY:null,sourcePosition:null,targetPosition:null,zIndex:void 0},OS=(t,r,o)=>o===xe.Left?t-r:o===xe.Right?t+r:t,FS=(t,r,o)=>o===xe.Top?t-r:o===xe.Bottom?t+r:t,Yh="react-flow__edgeupdater";function Xh({position:t,centerX:r,centerY:o,radius:l=10,onMouseDown:u,onMouseEnter:c,onMouseOut:f,type:h}){return P.jsx("circle",{onMouseDown:u,onMouseEnter:c,onMouseOut:f,className:be([Yh,`${Yh}-${h}`]),cx:OS(r,l,t),cy:FS(o,l,t),r:l,stroke:"transparent",fill:"transparent"})}function HS({isReconnectable:t,reconnectRadius:r,edge:o,sourceX:l,sourceY:u,targetX:c,targetY:f,sourcePosition:h,targetPosition:p,onReconnect:y,onReconnectStart:m,onReconnectEnd:v,setReconnecting:g,setUpdateHover:w}){const S=$e(),M=(I,W)=>{if(I.button!==0)return;const{autoPanOnConnect:$,domNode:V,connectionMode:X,connectionRadius:K,lib:te,onConnectStart:Z,cancelConnection:ee,nodeLookup:J,rfId:k,panBy:B,updateConnection:H}=S.getState(),U=W.type==="target",A=(C,z)=>{g(!1),v==null||v(C,o,W.type,z)},j=C=>y==null?void 0:y(o,C),F=(C,z)=>{g(!0),m==null||m(I,o,W.type),Z==null||Z(C,z)};Wa.onPointerDown(I.nativeEvent,{autoPanOnConnect:$,connectionMode:X,connectionRadius:K,domNode:V,handleId:W.id,nodeId:W.nodeId,nodeLookup:J,isTarget:U,edgeUpdaterType:W.type,lib:te,flowId:k,cancelConnection:ee,panBy:B,isValidConnection:(...C)=>{var z,ne;return((ne=(z=S.getState()).isValidConnection)==null?void 0:ne.call(z,...C))??!0},onConnect:j,onConnectStart:F,onConnectEnd:(...C)=>{var z,ne;return(ne=(z=S.getState()).onConnectEnd)==null?void 0:ne.call(z,...C)},onReconnectEnd:A,updateConnection:H,getTransform:()=>S.getState().transform,getFromHandle:()=>S.getState().connection.fromHandle,dragThreshold:S.getState().connectionDragThreshold,handleDomNode:I.currentTarget})},N=I=>M(I,{nodeId:o.target,id:o.targetHandle??null,type:"target"}),E=I=>M(I,{nodeId:o.source,id:o.sourceHandle??null,type:"source"}),R=()=>w(!0),_=()=>w(!1);return P.jsxs(P.Fragment,{children:[(t===!0||t==="source")&&P.jsx(Xh,{position:h,centerX:l,centerY:u,radius:r,onMouseDown:N,onMouseEnter:R,onMouseOut:_,type:"source"}),(t===!0||t==="target")&&P.jsx(Xh,{position:p,centerX:c,centerY:f,radius:r,onMouseDown:E,onMouseEnter:R,onMouseOut:_,type:"target"})]})}function VS({id:t,edgesFocusable:r,edgesReconnectable:o,elementsSelectable:l,onClick:u,onDoubleClick:c,onContextMenu:f,onMouseEnter:h,onMouseMove:p,onMouseLeave:y,reconnectRadius:m,onReconnect:v,onReconnectStart:g,onReconnectEnd:w,rfId:S,edgeTypes:M,noPanClassName:N,onError:E,disableKeyboardA11y:R}){let _=Ie(ve=>ve.edgeLookup.get(t));const I=Ie(ve=>ve.defaultEdgeOptions);_=I?{...I,..._}:_;let W=_.type||"default",$=(M==null?void 0:M[W])||Wh[W];$===void 0&&(E==null||E("011",Yt.error011(W)),W="default",$=(M==null?void 0:M.default)||Wh.default);const V=!!(_.focusable||r&&typeof _.focusable>"u"),X=typeof v<"u"&&(_.reconnectable||o&&typeof _.reconnectable>"u"),K=!!(_.selectable||l&&typeof _.selectable>"u"),te=G.useRef(null),[Z,ee]=G.useState(!1),[J,k]=G.useState(!1),B=$e(),{zIndex:H=_.zIndex,sourceX:U,sourceY:A,targetX:j,targetY:F,sourcePosition:C,targetPosition:z}=Ie(G.useCallback(ve=>{const me=ve.nodeLookup.get(_.source),ke=ve.nodeLookup.get(_.target);if(!me||!ke)return bh;const Ce=Mw({id:t,sourceNode:me,targetNode:ke,sourceHandle:_.sourceHandle||null,targetHandle:_.targetHandle||null,connectionMode:ve.connectionMode,onError:E}),Me=xw({selected:_.selected,zIndex:_.zIndex,sourceNode:me,targetNode:ke,elevateOnSelect:ve.elevateEdgesOnSelect,zIndexMode:ve.zIndexMode});return{...Ce||bh,zIndex:Me}},[_.source,_.target,_.sourceHandle,_.targetHandle,_.selected,_.zIndex,E]),Ve),ne=G.useMemo(()=>_.markerStart?`url('#${Ba(_.markerStart,S)}')`:void 0,[_.markerStart,S]),ie=G.useMemo(()=>_.markerEnd?`url('#${Ba(_.markerEnd,S)}')`:void 0,[_.markerEnd,S]);if(_.hidden||U===null||A===null||j===null||F===null)return null;const ce=ve=>{var Me;const{addSelectedEdges:me,unselectNodesAndEdges:ke,multiSelectionActive:Ce}=B.getState();K&&(B.setState({nodesSelectionActive:!1}),_.selected&&Ce?(ke({nodes:[],edges:[_]}),(Me=te.current)==null||Me.blur()):me([t])),u&&u(ve,_)},O=c?ve=>{c(ve,{..._})}:void 0,re=f?ve=>{f(ve,{..._})}:void 0,Q=h?ve=>{h(ve,{..._})}:void 0,le=p?ve=>{p(ve,{..._})}:void 0,pe=y?ve=>{y(ve,{..._})}:void 0,we=ve=>{var me;if(!R&&Tp.includes(ve.key)&&K){const{unselectNodesAndEdges:ke,addSelectedEdges:Ce}=B.getState();ve.key==="Escape"?((me=te.current)==null||me.blur(),ke({edges:[_]})):Ce([t])}};return P.jsx("svg",{style:{zIndex:H},children:P.jsxs("g",{className:be(["react-flow__edge",`react-flow__edge-${W}`,_.className,N,{selected:_.selected,animated:_.animated,inactive:!K&&!u,updating:Z,selectable:K}]),onClick:ce,onDoubleClick:O,onContextMenu:re,onMouseEnter:Q,onMouseMove:le,onMouseLeave:pe,onKeyDown:V?we:void 0,tabIndex:V?0:void 0,role:_.ariaRole??(V?"group":"img"),"aria-roledescription":"edge","data-id":t,"data-testid":`rf__edge-${t}`,"aria-label":_.ariaLabel===null?void 0:_.ariaLabel||`Edge from ${_.source} to ${_.target}`,"aria-describedby":V?`${ag}-${S}`:void 0,ref:te,..._.domAttributes,children:[!J&&P.jsx($,{id:t,source:_.source,target:_.target,type:_.type,selected:_.selected,animated:_.animated,selectable:K,deletable:_.deletable??!0,label:_.label,labelStyle:_.labelStyle,labelShowBg:_.labelShowBg,labelBgStyle:_.labelBgStyle,labelBgPadding:_.labelBgPadding,labelBgBorderRadius:_.labelBgBorderRadius,sourceX:U,sourceY:A,targetX:j,targetY:F,sourcePosition:C,targetPosition:z,data:_.data,style:_.style,sourceHandleId:_.sourceHandle,targetHandleId:_.targetHandle,markerStart:ne,markerEnd:ie,pathOptions:"pathOptions"in _?_.pathOptions:void 0,interactionWidth:_.interactionWidth}),X&&P.jsx(HS,{edge:_,isReconnectable:X,reconnectRadius:m,onReconnect:v,onReconnectStart:g,onReconnectEnd:w,sourceX:U,sourceY:A,targetX:j,targetY:F,sourcePosition:C,targetPosition:z,setUpdateHover:ee,setReconnecting:k})]})})}var BS=G.memo(VS);const US=t=>({edgesFocusable:t.edgesFocusable,edgesReconnectable:t.edgesReconnectable,elementsSelectable:t.elementsSelectable,connectionMode:t.connectionMode,onError:t.onError});function Ag({defaultMarkerColor:t,onlyRenderVisibleElements:r,rfId:o,edgeTypes:l,noPanClassName:u,onReconnect:c,onEdgeContextMenu:f,onEdgeMouseEnter:h,onEdgeMouseMove:p,onEdgeMouseLeave:y,onEdgeClick:m,reconnectRadius:v,onEdgeDoubleClick:g,onReconnectStart:w,onReconnectEnd:S,disableKeyboardA11y:M}){const{edgesFocusable:N,edgesReconnectable:E,elementsSelectable:R,onError:_}=Ie(US,Ve),I=MS(r);return P.jsxs("div",{className:"react-flow__edges",children:[P.jsx(RS,{defaultColor:t,rfId:o}),I.map(W=>P.jsx(BS,{id:W,edgesFocusable:N,edgesReconnectable:E,elementsSelectable:R,noPanClassName:u,onReconnect:c,onContextMenu:f,onMouseEnter:h,onMouseMove:p,onMouseLeave:y,onClick:m,reconnectRadius:v,onDoubleClick:g,onReconnectStart:w,onReconnectEnd:S,rfId:o,onError:_,edgeTypes:l,disableKeyboardA11y:M},W))]})}Ag.displayName="EdgeRenderer";const WS=G.memo(Ag),Qh=t=>`translate(${t[0]}px,${t[1]}px) scale(${t[2]})`;function bS({children:t}){const r=$e(),o=G.useRef(null),[l]=G.useState(()=>r.getState().transform);return hg(()=>{let u=null;const c=()=>{const f=r.getState().transform;u&&f[0]===u[0]&&f[1]===u[1]&&f[2]===u[2]||(u=f,o.current&&(o.current.style.transform=Qh(f)))};return c(),r.subscribe(c)},[r]),P.jsx("div",{ref:o,className:"react-flow__viewport xyflow__viewport react-flow__container",style:{transform:Qh(l)},children:t})}function YS(t){const r=ac(),o=G.useRef(!1);G.useEffect(()=>{!o.current&&r.viewportInitialized&&t&&(setTimeout(()=>t(r),1),o.current=!0)},[t,r.viewportInitialized])}const XS=t=>{var r;return(r=t.panZoom)==null?void 0:r.syncViewport};function QS(t){const r=Ie(XS),o=$e();return G.useEffect(()=>{t&&(r==null||r(t),o.setState({transform:[t.x,t.y,t.zoom]}))},[t,r]),null}function GS(t){return t.connection.inProgress?{...t.connection,to:vo(t.connection.to,t.transform)}:{...t.connection}}function KS(t){return GS}function qS(t){const r=KS();return Ie(r,Ve)}const ZS=t=>({nodesConnectable:t.nodesConnectable,isValid:t.connection.isValid,inProgress:t.connection.inProgress,width:t.width,height:t.height});function JS({containerStyle:t,style:r,type:o,component:l}){const{nodesConnectable:u,width:c,height:f,isValid:h,inProgress:p}=Ie(ZS,Ve);return!(c&&u&&p)?null:P.jsx("svg",{style:t,width:c,height:f,className:"react-flow__connectionline react-flow__container",children:P.jsx("g",{className:be(["react-flow__connection",Lp(h)]),children:P.jsx($g,{style:r,type:o,CustomComponent:l,isValid:h})})})}const $g=({style:t,type:r=Wn.Bezier,CustomComponent:o,isValid:l})=>{const{inProgress:u,from:c,fromNode:f,fromHandle:h,fromPosition:p,to:y,toNode:m,toHandle:v,toPosition:g,pointer:w}=qS();if(!u)return;if(o)return P.jsx(o,{connectionLineType:r,connectionLineStyle:t,fromNode:f,fromHandle:h,fromX:c.x,fromY:c.y,toX:y.x,toY:y.y,fromPosition:p,toPosition:g,connectionStatus:Lp(l),toNode:m,toHandle:v,pointer:w});let S="";const M={sourceX:c.x,sourceY:c.y,sourcePosition:p,targetX:y.x,targetY:y.y,targetPosition:g};switch(r){case Wn.Bezier:[S]=Yp(M);break;case Wn.SimpleBezier:[S]=Eg(M);break;case Wn.Step:[S]=Va({...M,borderRadius:0});break;case Wn.SmoothStep:[S]=Va(M);break;default:[S]=Qp(M)}return P.jsx("path",{d:S,fill:"none",className:"react-flow__connection-path",style:t})};$g.displayName="ConnectionLine";const e_={};function Gh(t=e_){G.useRef(t),$e(),G.useEffect(()=>{},[t])}function t_(){$e(),G.useRef(!1),G.useEffect(()=>{},[])}function Dg({nodeTypes:t,edgeTypes:r,onInit:o,onNodeClick:l,onEdgeClick:u,onNodeDoubleClick:c,onEdgeDoubleClick:f,onNodeMouseEnter:h,onNodeMouseMove:p,onNodeMouseLeave:y,onNodeContextMenu:m,onSelectionContextMenu:v,onSelectionStart:g,onSelectionEnd:w,connectionLineType:S,connectionLineStyle:M,connectionLineComponent:N,connectionLineContainerStyle:E,selectionKeyCode:R,selectionOnDrag:_,selectionMode:I,multiSelectionKeyCode:W,panActivationKeyCode:$,zoomActivationKeyCode:V,deleteKeyCode:X,onlyRenderVisibleElements:K,elementsSelectable:te,defaultViewport:Z,translateExtent:ee,minZoom:J,maxZoom:k,preventScrolling:B,defaultMarkerColor:H,zoomOnScroll:U,zoomOnPinch:A,panOnScroll:j,panOnScrollSpeed:F,panOnScrollMode:C,zoomOnDoubleClick:z,panOnDrag:ne,autoPanOnSelection:ie,onPaneClick:ce,onPaneMouseEnter:O,onPaneMouseMove:re,onPaneMouseLeave:Q,onPaneScroll:le,onPaneContextMenu:pe,paneClickDistance:we,nodeClickDistance:ve,onEdgeContextMenu:me,onEdgeMouseEnter:ke,onEdgeMouseMove:Ce,onEdgeMouseLeave:Me,reconnectRadius:Re,onReconnect:ot,onReconnectStart:ut,onReconnectEnd:Je,noDragClassName:et,noWheelClassName:sn,noPanClassName:Gt,disableKeyboardA11y:Kt,nodeExtent:at,rfId:Ct,viewport:yt,onViewportChange:Mt,nodesDraggable:wr}){return Gh(t),Gh(r),t_(),YS(o),QS(yt),P.jsx(yS,{onPaneClick:ce,onPaneMouseEnter:O,onPaneMouseMove:re,onPaneMouseLeave:Q,onPaneContextMenu:pe,onPaneScroll:le,paneClickDistance:we,deleteKeyCode:X,selectionKeyCode:R,selectionOnDrag:_,selectionMode:I,onSelectionStart:g,onSelectionEnd:w,multiSelectionKeyCode:W,panActivationKeyCode:$,zoomActivationKeyCode:V,elementsSelectable:te,zoomOnScroll:U,zoomOnPinch:A,zoomOnDoubleClick:z,panOnScroll:j,panOnScrollSpeed:F,panOnScrollMode:C,panOnDrag:ne,autoPanOnSelection:ie,defaultViewport:Z,translateExtent:ee,minZoom:J,maxZoom:k,onSelectionContextMenu:v,preventScrolling:B,noDragClassName:et,noWheelClassName:sn,noPanClassName:Gt,disableKeyboardA11y:Kt,onViewportChange:Mt,isControlledViewport:!!yt,children:P.jsxs(bS,{children:[P.jsx(WS,{edgeTypes:r,onEdgeClick:u,onEdgeDoubleClick:f,onReconnect:ot,onReconnectStart:ut,onReconnectEnd:Je,onlyRenderVisibleElements:K,onEdgeContextMenu:me,onEdgeMouseEnter:ke,onEdgeMouseMove:Ce,onEdgeMouseLeave:Me,reconnectRadius:Re,defaultMarkerColor:H,noPanClassName:Gt,disableKeyboardA11y:Kt,rfId:Ct}),P.jsx(JS,{style:M,type:S,component:N,containerStyle:E}),P.jsx("div",{className:"react-flow__edgelabel-renderer"}),P.jsx(CS,{nodeTypes:t,onNodeClick:l,onNodeDoubleClick:c,onNodeMouseEnter:h,onNodeMouseMove:p,onNodeMouseLeave:y,onNodeContextMenu:m,nodeClickDistance:ve,onlyRenderVisibleElements:K,noPanClassName:Gt,noDragClassName:et,disableKeyboardA11y:Kt,nodeExtent:at,rfId:Ct,nodesDraggable:wr}),P.jsx("div",{className:"react-flow__viewport-portal"})]})})}Dg.displayName="GraphView";const n_=G.memo(Dg),r_=Fp(),Kh=({nodes:t,edges:r,defaultNodes:o,defaultEdges:l,width:u,height:c,fitView:f,fitViewOptions:h,minZoom:p=.5,maxZoom:y=2,nodeOrigin:m,nodeExtent:v,zIndexMode:g="basic"}={})=>{const w=new Map,S=new Map,M=new Map,N=new Map,E=l??r??[],R=o??t??[],_=m??[0,0],I=v??so;qp(M,N,E);const{nodesInitialized:W}=Ua(R,w,S,{nodeOrigin:_,nodeExtent:I,zIndexMode:g});let $=[0,0,1];if(f&&u&&c){const V=mo(w,{filter:Z=>!!((Z.width||Z.initialWidth)&&(Z.height||Z.initialHeight))}),{x:X,y:K,zoom:te}=nc(V,u,c,p,y,(h==null?void 0:h.padding)??.1);$=[X,K,te]}return{rfId:"1",width:u??0,height:c??0,transform:$,nodes:R,nodesInitialized:W,nodeLookup:w,parentLookup:S,edges:E,edgeLookup:N,connectionLookup:M,onNodesChange:null,onEdgesChange:null,hasDefaultNodes:o!==void 0,hasDefaultEdges:l!==void 0,panZoom:null,minZoom:p,maxZoom:y,translateExtent:so,nodeExtent:I,nodesSelectionActive:!1,userSelectionActive:!1,userSelectionRect:null,connectionMode:ni.Strict,domNode:null,paneDragging:!1,noPanClassName:"nopan",nodeOrigin:_,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:f??!1,fitViewOptions:h,fitViewResolver:null,connection:{...Rp},connectionClickStartHandle:null,connectOnClick:!0,ariaLiveMessage:"",autoPanOnConnect:!0,autoPanOnNodeDrag:!0,autoPanOnNodeFocus:!0,autoPanSpeed:15,connectionRadius:20,onError:r_,isValidConnection:void 0,onSelectionChangeHandlers:[],lib:"react",debug:!1,ariaLabelConfig:zp,zIndexMode:g,onNodesChangeMiddlewareMap:new Map,onEdgesChangeMiddlewareMap:new Map}},i_=({nodes:t,edges:r,defaultNodes:o,defaultEdges:l,width:u,height:c,fitView:f,fitViewOptions:h,minZoom:p,maxZoom:y,nodeOrigin:m,nodeExtent:v,zIndexMode:g})=>m1((w,S)=>{async function M(){const{nodeLookup:N,panZoom:E,fitViewOptions:R,fitViewResolver:_,width:I,height:W,minZoom:$,maxZoom:V}=S();E&&(await dw({nodes:N,width:I,height:W,panZoom:E,minZoom:$,maxZoom:V},R),_==null||_.resolve(!0),w({fitViewResolver:null}))}return{...Kh({nodes:t,edges:r,width:u,height:c,fitView:f,fitViewOptions:h,minZoom:p,maxZoom:y,nodeOrigin:m,nodeExtent:v,defaultNodes:o,defaultEdges:l,zIndexMode:g}),setNodes:N=>{const{nodeLookup:E,parentLookup:R,nodeOrigin:_,nodeExtent:I,elevateNodesOnSelect:W,fitViewQueued:$,zIndexMode:V,nodesSelectionActive:X}=S(),{nodesInitialized:K,hasSelectedNodes:te}=Ua(N,E,R,{nodeOrigin:_,nodeExtent:I,elevateNodesOnSelect:W,checkEquality:!0,zIndexMode:V}),Z=X&&te;$&&K?(M(),w({nodes:N,nodesInitialized:K,fitViewQueued:!1,fitViewOptions:void 0,nodesSelectionActive:Z})):w({nodes:N,nodesInitialized:K,nodesSelectionActive:Z})},setEdges:N=>{const{connectionLookup:E,edgeLookup:R}=S();qp(E,R,N),w({edges:N})},setDefaultNodesAndEdges:(N,E)=>{if(N){const{setNodes:R}=S();R(N),w({hasDefaultNodes:!0})}if(E){const{setEdges:R}=S();R(E),w({hasDefaultEdges:!0})}},updateNodeInternals:N=>{const{triggerNodeChanges:E,nodeLookup:R,parentLookup:_,domNode:I,nodeOrigin:W,nodeExtent:$,debug:V,fitViewQueued:X,zIndexMode:K}=S(),{changes:te,updatedInternals:Z}=Aw(N,R,_,I,W,$,K);Z&&(zw(R,_,{nodeOrigin:W,nodeExtent:$,zIndexMode:K}),X?(M(),w({fitViewQueued:!1,fitViewOptions:void 0})):w({}),(te==null?void 0:te.length)>0&&(V&&console.log("React Flow: trigger node changes",te),E==null||E(te)))},updateNodePositions:(N,E=!1)=>{const R=[];let _=[];const{nodeLookup:I,triggerNodeChanges:W,connection:$,updateConnection:V,onNodesChangeMiddlewareMap:X}=S();for(const[K,te]of N){const Z=I.get(K),ee=!!(Z!=null&&Z.expandParent&&(Z!=null&&Z.parentId)&&(te!=null&&te.position)),J={id:K,type:"position",position:ee?{x:Math.max(0,te.position.x),y:Math.max(0,te.position.y)}:te.position,dragging:E};if(Z&&$.inProgress&&$.fromNode.id===Z.id){const k=xr(Z,$.fromHandle,xe.Left,!0);V({...$,from:k})}ee&&Z.parentId&&R.push({id:K,parentId:Z.parentId,rect:{...te.internals.positionAbsolute,width:te.measured.width??0,height:te.measured.height??0}}),_.push(J)}if(R.length>0){const{parentLookup:K,nodeOrigin:te}=S(),Z=uc(R,I,K,te);_.push(...Z)}for(const K of X.values())_=K(_);W(_)},triggerNodeChanges:N=>{const{onNodesChange:E,setNodes:R,nodes:_,hasDefaultNodes:I,debug:W}=S();if(N!=null&&N.length){if(I){const $=D1(N,_);R($)}W&&console.log("React Flow: trigger node changes",N),E==null||E(N)}},triggerEdgeChanges:N=>{const{onEdgesChange:E,setEdges:R,edges:_,hasDefaultEdges:I,debug:W}=S();if(N!=null&&N.length){if(I){const $=O1(N,_);R($)}W&&console.log("React Flow: trigger edge changes",N),E==null||E(N)}},addSelectedNodes:N=>{const{multiSelectionActive:E,edgeLookup:R,nodeLookup:_,triggerNodeChanges:I,triggerEdgeChanges:W}=S();if(E){const $=N.map(V=>fr(V,!0));I($);return}I(qr(_,new Set([...N]),!0)),W(qr(R))},addSelectedEdges:N=>{const{multiSelectionActive:E,edgeLookup:R,nodeLookup:_,triggerNodeChanges:I,triggerEdgeChanges:W}=S();if(E){const $=N.map(V=>fr(V,!0));W($);return}W(qr(R,new Set([...N]))),I(qr(_,new Set,!0))},unselectNodesAndEdges:({nodes:N,edges:E}={})=>{const{edges:R,nodes:_,nodeLookup:I,triggerNodeChanges:W,triggerEdgeChanges:$}=S(),V=N||_,X=E||R,K=[];for(const Z of V){if(!Z.selected)continue;const ee=I.get(Z.id);ee&&(ee.selected=!1),K.push(fr(Z.id,!1))}const te=[];for(const Z of X)Z.selected&&te.push(fr(Z.id,!1));W(K),$(te)},setMinZoom:N=>{const{panZoom:E,maxZoom:R}=S();E==null||E.setScaleExtent([N,R]),w({minZoom:N})},setMaxZoom:N=>{const{panZoom:E,minZoom:R}=S();E==null||E.setScaleExtent([R,N]),w({maxZoom:N})},setTranslateExtent:N=>{var E;(E=S().panZoom)==null||E.setTranslateExtent(N),w({translateExtent:N})},resetSelectedElements:()=>{const{edges:N,nodes:E,triggerNodeChanges:R,triggerEdgeChanges:_,elementsSelectable:I}=S();if(!I)return;const W=E.reduce((V,X)=>X.selected?[...V,fr(X.id,!1)]:V,[]),$=N.reduce((V,X)=>X.selected?[...V,fr(X.id,!1)]:V,[]);R(W),_($)},setNodeExtent:N=>{const{nodes:E,nodeLookup:R,parentLookup:_,nodeOrigin:I,elevateNodesOnSelect:W,nodeExtent:$,zIndexMode:V}=S();N[0][0]===$[0][0]&&N[0][1]===$[0][1]&&N[1][0]===$[1][0]&&N[1][1]===$[1][1]||(Ua(E,R,_,{nodeOrigin:I,nodeExtent:N,elevateNodesOnSelect:W,checkEquality:!1,zIndexMode:V}),w({nodeExtent:N}))},panBy:N=>{const{transform:E,width:R,height:_,panZoom:I,translateExtent:W}=S();return $w({delta:N,panZoom:I,transform:E,translateExtent:W,width:R,height:_})},setCenter:async(N,E,R)=>{const{width:_,height:I,maxZoom:W,panZoom:$}=S();if(!$)return!1;const V=typeof(R==null?void 0:R.zoom)<"u"?R.zoom:W;return await $.setViewport({x:_/2-N*V,y:I/2-E*V,zoom:V},{duration:R==null?void 0:R.duration,ease:R==null?void 0:R.ease,interpolate:R==null?void 0:R.interpolate}),!0},cancelConnection:()=>{w({connection:{...Rp}})},updateConnection:N=>{w({connection:N})},reset:()=>w({...Kh()})}},Object.is);function Og({initialNodes:t,initialEdges:r,defaultNodes:o,defaultEdges:l,initialWidth:u,initialHeight:c,initialMinZoom:f,initialMaxZoom:h,initialFitViewOptions:p,fitView:y,nodeOrigin:m,nodeExtent:v,zIndexMode:g,children:w}){const[S]=G.useState(()=>i_({nodes:t,edges:r,defaultNodes:o,defaultEdges:l,width:u,height:c,fitView:y,minZoom:f,maxZoom:h,fitViewOptions:p,nodeOrigin:m,nodeExtent:v,zIndexMode:g}));return P.jsx(y1,{value:S,children:P.jsx(U1,{children:P.jsx(iS,{children:w})})})}function o_({children:t,nodes:r,edges:o,defaultNodes:l,defaultEdges:u,width:c,height:f,fitView:h,fitViewOptions:p,minZoom:y,maxZoom:m,nodeOrigin:v,nodeExtent:g,zIndexMode:w}){return G.useContext(yl)?P.jsx(P.Fragment,{children:t}):P.jsx(Og,{initialNodes:r,initialEdges:o,defaultNodes:l,defaultEdges:u,initialWidth:c,initialHeight:f,fitView:h,initialFitViewOptions:p,initialMinZoom:y,initialMaxZoom:m,nodeOrigin:v,nodeExtent:g,zIndexMode:w,children:t})}const s_={width:"100%",height:"100%",overflow:"hidden",position:"relative",zIndex:0};function l_({nodes:t,edges:r,defaultNodes:o,defaultEdges:l,className:u,nodeTypes:c,edgeTypes:f,onNodeClick:h,onEdgeClick:p,onInit:y,onMove:m,onMoveStart:v,onMoveEnd:g,onConnect:w,onConnectStart:S,onConnectEnd:M,onClickConnectStart:N,onClickConnectEnd:E,onNodeMouseEnter:R,onNodeMouseMove:_,onNodeMouseLeave:I,onNodeContextMenu:W,onNodeDoubleClick:$,onNodeDragStart:V,onNodeDrag:X,onNodeDragStop:K,onNodesDelete:te,onEdgesDelete:Z,onDelete:ee,onSelectionChange:J,onSelectionDragStart:k,onSelectionDrag:B,onSelectionDragStop:H,onSelectionContextMenu:U,onSelectionStart:A,onSelectionEnd:j,onBeforeDelete:F,connectionMode:C,connectionLineType:z=Wn.Bezier,connectionLineStyle:ne,connectionLineComponent:ie,connectionLineContainerStyle:ce,deleteKeyCode:O="Backspace",selectionKeyCode:re="Shift",selectionOnDrag:Q=!1,selectionMode:le=lo.Full,panActivationKeyCode:pe="Space",multiSelectionKeyCode:we=ao()?"Meta":"Control",zoomActivationKeyCode:ve=ao()?"Meta":"Control",snapToGrid:me,snapGrid:ke,onlyRenderVisibleElements:Ce=!1,selectNodesOnDrag:Me,nodesDraggable:Re,autoPanOnNodeFocus:ot,nodesConnectable:ut,nodesFocusable:Je,nodeOrigin:et=cg,edgesFocusable:sn,edgesReconnectable:Gt,elementsSelectable:Kt=!0,defaultViewport:at=T1,minZoom:Ct=.5,maxZoom:yt=2,translateExtent:Mt=so,preventScrolling:wr=!0,nodeExtent:ln,defaultMarkerColor:Yn="#b1b1b7",zoomOnScroll:Sl=!0,zoomOnPinch:xo=!0,panOnScroll:wo=!1,panOnScrollSpeed:_l=.5,panOnScrollMode:si=pr.Free,zoomOnDoubleClick:li=!0,panOnDrag:ui=!0,onPaneClick:ai,onPaneMouseEnter:ci,onPaneMouseMove:wn,onPaneMouseLeave:Sn,onPaneScroll:So,onPaneContextMenu:_o,paneClickDistance:Eo=1,nodeClickDistance:ko=0,children:No,onReconnect:fi,onReconnectStart:Co,onReconnectEnd:Xn,onEdgeContextMenu:di,onEdgeDoubleClick:Qn,onEdgeMouseEnter:El,onEdgeMouseMove:Gn,onEdgeMouseLeave:Sr,reconnectRadius:_r=10,onNodesChange:hi,onEdgesChange:kl,noDragClassName:Nl="nodrag",noWheelClassName:Cl="nowheel",noPanClassName:qt="nopan",fitView:pi,fitViewOptions:gi,connectOnClick:Ml,attributionPosition:Mo,proOptions:Po,defaultEdgeOptions:Io,elevateNodesOnSelect:To=!0,elevateEdgesOnSelect:Pl=!1,disableKeyboardA11y:zo=!1,autoPanOnConnect:Oe,autoPanOnNodeDrag:Il,autoPanOnSelection:mi=!0,autoPanSpeed:Ro,connectionRadius:Er,isValidConnection:Tl,onError:Lo,style:kr,id:vt,nodeDragThreshold:zl,connectionDragThreshold:xt,viewport:Rl,onViewportChange:Ll,width:jl,height:Nr,colorMode:Cr="light",debug:Kn,onScroll:un,ariaLabelConfig:Al,zIndexMode:jo="basic",...yi},Ao){const qn=vt||"1",Zn=j1(Cr),$l=G.useCallback(Mr=>{Mr.currentTarget.scrollTo({top:0,left:0,behavior:"instant"}),un==null||un(Mr)},[un]);return P.jsx("div",{"data-testid":"rf__wrapper",...yi,onScroll:$l,style:{...kr,...s_},ref:Ao,className:be(["react-flow",u,Zn]),id:vt,role:"application",children:P.jsxs(o_,{nodes:t,edges:r,width:jl,height:Nr,fitView:pi,fitViewOptions:gi,minZoom:Ct,maxZoom:yt,nodeOrigin:et,nodeExtent:ln,zIndexMode:jo,children:[P.jsx(L1,{nodes:t,edges:r,defaultNodes:o,defaultEdges:l,onConnect:w,onConnectStart:S,onConnectEnd:M,onClickConnectStart:N,onClickConnectEnd:E,nodesDraggable:Re,autoPanOnNodeFocus:ot,nodesConnectable:ut,nodesFocusable:Je,edgesFocusable:sn,edgesReconnectable:Gt,elementsSelectable:Kt,elevateNodesOnSelect:To,elevateEdgesOnSelect:Pl,minZoom:Ct,maxZoom:yt,nodeExtent:ln,onNodesChange:hi,onEdgesChange:kl,snapToGrid:me,snapGrid:ke,connectionMode:C,translateExtent:Mt,connectOnClick:Ml,defaultEdgeOptions:Io,fitView:pi,fitViewOptions:gi,onNodesDelete:te,onEdgesDelete:Z,onDelete:ee,onNodeDragStart:V,onNodeDrag:X,onNodeDragStop:K,onSelectionDrag:B,onSelectionDragStart:k,onSelectionDragStop:H,onMove:m,onMoveStart:v,onMoveEnd:g,noPanClassName:qt,nodeOrigin:et,rfId:qn,autoPanOnConnect:Oe,autoPanOnNodeDrag:Il,autoPanSpeed:Ro,onError:Lo,connectionRadius:Er,isValidConnection:Tl,selectNodesOnDrag:Me,nodeDragThreshold:zl,connectionDragThreshold:xt,onBeforeDelete:F,debug:Kn,ariaLabelConfig:Al,zIndexMode:jo}),P.jsx(n_,{onInit:y,onNodeClick:h,onEdgeClick:p,onNodeMouseEnter:R,onNodeMouseMove:_,onNodeMouseLeave:I,onNodeContextMenu:W,onNodeDoubleClick:$,nodeTypes:c,edgeTypes:f,connectionLineType:z,connectionLineStyle:ne,connectionLineComponent:ie,connectionLineContainerStyle:ce,selectionKeyCode:re,selectionOnDrag:Q,selectionMode:le,deleteKeyCode:O,multiSelectionKeyCode:we,panActivationKeyCode:pe,zoomActivationKeyCode:ve,onlyRenderVisibleElements:Ce,defaultViewport:at,translateExtent:Mt,minZoom:Ct,maxZoom:yt,preventScrolling:wr,zoomOnScroll:Sl,zoomOnPinch:xo,zoomOnDoubleClick:li,panOnScroll:wo,panOnScrollSpeed:_l,panOnScrollMode:si,panOnDrag:ui,autoPanOnSelection:mi,onPaneClick:ai,onPaneMouseEnter:ci,onPaneMouseMove:wn,onPaneMouseLeave:Sn,onPaneScroll:So,onPaneContextMenu:_o,paneClickDistance:Eo,nodeClickDistance:ko,onSelectionContextMenu:U,onSelectionStart:A,onSelectionEnd:j,onReconnect:fi,onReconnectStart:Co,onReconnectEnd:Xn,onEdgeContextMenu:di,onEdgeDoubleClick:Qn,onEdgeMouseEnter:El,onEdgeMouseMove:Gn,onEdgeMouseLeave:Sr,reconnectRadius:_r,defaultMarkerColor:Yn,noDragClassName:Nl,noWheelClassName:Cl,noPanClassName:qt,rfId:qn,disableKeyboardA11y:zo,nodeExtent:ln,viewport:Rl,onViewportChange:Ll,nodesDraggable:Re}),P.jsx(I1,{onSelectionChange:J}),No,P.jsx(k1,{proOptions:Po,position:Mo}),P.jsx(E1,{rfId:qn,disableKeyboardA11y:zo})]})})}var u_=dg(l_);function a_({dimensions:t,lineWidth:r,variant:o,className:l}){return P.jsx("path",{strokeWidth:r,d:`M${t[0]/2} 0 V${t[1]} M0 ${t[1]/2} H${t[0]}`,className:be(["react-flow__background-pattern",o,l])})}function c_({radius:t,className:r}){return P.jsx("circle",{cx:t,cy:t,r:t,className:be(["react-flow__background-pattern","dots",r])})}var bn;(function(t){t.Lines="lines",t.Dots="dots",t.Cross="cross"})(bn||(bn={}));const f_={[bn.Dots]:1,[bn.Lines]:1,[bn.Cross]:6},d_=t=>({transform:t.transform,patternId:`pattern-${t.rfId}`});function Fg({id:t,variant:r=bn.Dots,gap:o=20,size:l,lineWidth:u=1,offset:c=0,color:f,bgColor:h,style:p,className:y,patternClassName:m}){const v=G.useRef(null),{transform:g,patternId:w}=Ie(d_,Ve),S=l||f_[r],M=r===bn.Dots,N=r===bn.Cross,E=Array.isArray(o)?o:[o,o],R=[E[0]*g[2]||1,E[1]*g[2]||1],_=S*g[2],I=Array.isArray(c)?c:[c,c],W=N?[_,_]:R,$=[I[0]*g[2]+W[0]/2,I[1]*g[2]+W[1]/2],V=`${w}${t||""}`;return P.jsxs("svg",{className:be(["react-flow__background",y]),style:{...p,...xl,"--xy-background-color-props":h,"--xy-background-pattern-color-props":f},ref:v,"data-testid":"rf__background",children:[P.jsx("pattern",{id:V,x:g[0]%R[0],y:g[1]%R[1],width:R[0],height:R[1],patternUnits:"userSpaceOnUse",patternTransform:`translate(-${$[0]},-${$[1]})`,children:M?P.jsx(c_,{radius:_/2,className:m}):P.jsx(a_,{dimensions:W,lineWidth:u,variant:r,className:m})}),P.jsx("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:`url(#${V})`})]})}Fg.displayName="Background";const h_=G.memo(Fg);function p_(){return P.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32",children:P.jsx("path",{d:"M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z"})})}function g_(){return P.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 5",children:P.jsx("path",{d:"M0 0h32v4.2H0z"})})}function m_(){return P.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 30",children:P.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 y_(){return P.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:P.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 v_(){return P.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:P.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 bs({children:t,className:r,...o}){return P.jsx("button",{type:"button",className:be(["react-flow__controls-button",r]),...o,children:t})}const x_=t=>({isInteractive:t.nodesDraggable||t.nodesConnectable||t.elementsSelectable,minZoomReached:t.transform[2]<=t.minZoom,maxZoomReached:t.transform[2]>=t.maxZoom,ariaLabelConfig:t.ariaLabelConfig});function Hg({style:t,showZoom:r=!0,showFitView:o=!0,showInteractive:l=!0,fitViewOptions:u,onZoomIn:c,onZoomOut:f,onFitView:h,onInteractiveChange:p,className:y,children:m,position:v="bottom-left",orientation:g="vertical","aria-label":w}){const S=$e(),{isInteractive:M,minZoomReached:N,maxZoomReached:E,ariaLabelConfig:R}=Ie(x_,Ve),{zoomIn:_,zoomOut:I,fitView:W}=ac(),$=()=>{_(),c==null||c()},V=()=>{I(),f==null||f()},X=()=>{W(u),h==null||h()},K=()=>{S.setState({nodesDraggable:!M,nodesConnectable:!M,elementsSelectable:!M}),p==null||p(!M)},te=g==="horizontal"?"horizontal":"vertical";return P.jsxs(vl,{className:be(["react-flow__controls",te,y]),position:v,style:t,"data-testid":"rf__controls","aria-label":w??R["controls.ariaLabel"],children:[r&&P.jsxs(P.Fragment,{children:[P.jsx(bs,{onClick:$,className:"react-flow__controls-zoomin",title:R["controls.zoomIn.ariaLabel"],"aria-label":R["controls.zoomIn.ariaLabel"],disabled:E,children:P.jsx(p_,{})}),P.jsx(bs,{onClick:V,className:"react-flow__controls-zoomout",title:R["controls.zoomOut.ariaLabel"],"aria-label":R["controls.zoomOut.ariaLabel"],disabled:N,children:P.jsx(g_,{})})]}),o&&P.jsx(bs,{className:"react-flow__controls-fitview",onClick:X,title:R["controls.fitView.ariaLabel"],"aria-label":R["controls.fitView.ariaLabel"],children:P.jsx(m_,{})}),l&&P.jsx(bs,{className:"react-flow__controls-interactive",onClick:K,title:R["controls.interactive.ariaLabel"],"aria-label":R["controls.interactive.ariaLabel"],children:M?P.jsx(v_,{}):P.jsx(y_,{})}),m]})}Hg.displayName="Controls";const w_=G.memo(Hg);function S_({id:t,x:r,y:o,width:l,height:u,style:c,color:f,strokeColor:h,strokeWidth:p,className:y,borderRadius:m,shapeRendering:v,selected:g,onClick:w}){const{background:S,backgroundColor:M}=c||{},N=f||S||M;return P.jsx("rect",{className:be(["react-flow__minimap-node",{selected:g},y]),x:r,y:o,rx:m,ry:m,width:l,height:u,style:{fill:N,stroke:h,strokeWidth:p},shapeRendering:v,onClick:w?E=>w(E,t):void 0})}const __=G.memo(S_),E_=t=>t.nodes.map(r=>r.id),Ta=t=>t instanceof Function?t:()=>t;function k_({nodeStrokeColor:t,nodeColor:r,nodeClassName:o="",nodeBorderRadius:l=5,nodeStrokeWidth:u,nodeComponent:c=__,onClick:f}){const h=Ie(E_,Ve),p=Ta(r),y=Ta(t),m=Ta(o),v=typeof window>"u"||window.chrome?"crispEdges":"geometricPrecision";return P.jsx(P.Fragment,{children:h.map(g=>P.jsx(C_,{id:g,nodeColorFunc:p,nodeStrokeColorFunc:y,nodeClassNameFunc:m,nodeBorderRadius:l,nodeStrokeWidth:u,NodeComponent:c,onClick:f,shapeRendering:v},g))})}function N_({id:t,nodeColorFunc:r,nodeStrokeColorFunc:o,nodeClassNameFunc:l,nodeBorderRadius:u,nodeStrokeWidth:c,shapeRendering:f,NodeComponent:h,onClick:p}){const{node:y,x:m,y:v,width:g,height:w}=Ie(S=>{const M=S.nodeLookup.get(t);if(!M)return{node:void 0,x:0,y:0,width:0,height:0};const N=M.internals.userNode,{x:E,y:R}=M.internals.positionAbsolute,{width:_,height:I}=Qt(N);return{node:N,x:E,y:R,width:_,height:I}},Ve);return!y||y.hidden||!Hp(y)?null:P.jsx(h,{x:m,y:v,width:g,height:w,style:y.style,selected:!!y.selected,className:l(y),color:r(y),borderRadius:u,strokeColor:o(y),strokeWidth:c,shapeRendering:f,onClick:p,id:y.id})}const C_=G.memo(N_);var M_=G.memo(k_);const P_=200,I_=150,T_=t=>!t.hidden,z_=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?Dp(mo(t.nodeLookup,{filter:T_}),r):r,rfId:t.rfId,panZoom:t.panZoom,translateExtent:t.translateExtent,flowWidth:t.width,flowHeight:t.height,ariaLabelConfig:t.ariaLabelConfig}},qh=(t,r)=>t.x===r.x&&t.y===r.y&&t.width===r.width&&t.height===r.height,R_=(t,r)=>qh(t.viewBB,r.viewBB)&&qh(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,L_="react-flow__minimap-desc";function Vg({style:t,className:r,nodeStrokeColor:o,nodeColor:l,nodeClassName:u="",nodeBorderRadius:c=5,nodeStrokeWidth:f,nodeComponent:h,bgColor:p,maskColor:y,maskStrokeColor:m,maskStrokeWidth:v,position:g="bottom-right",onClick:w,onNodeClick:S,pannable:M=!1,zoomable:N=!1,ariaLabel:E,inversePan:R,zoomStep:_=1,offsetScale:I=5}){const W=$e(),$=G.useRef(null),{boundingRect:V,viewBB:X,rfId:K,panZoom:te,translateExtent:Z,flowWidth:ee,flowHeight:J,ariaLabelConfig:k}=Ie(z_,R_),B=(t==null?void 0:t.width)??P_,H=(t==null?void 0:t.height)??I_,U=V.width/B,A=V.height/H,j=Math.max(U,A),F=j*B,C=j*H,z=I*j,ne=V.x-(F-V.width)/2-z,ie=V.y-(C-V.height)/2-z,ce=F+z*2,O=C+z*2,re=`${L_}-${K}`,Q=G.useRef(0),le=G.useRef();Q.current=j,G.useEffect(()=>{if($.current&&te)return le.current=bw({domNode:$.current,panZoom:te,getTransform:()=>W.getState().transform,getViewScale:()=>Q.current}),()=>{var me;(me=le.current)==null||me.destroy()}},[te]),G.useEffect(()=>{var me;(me=le.current)==null||me.update({translateExtent:Z,width:ee,height:J,inversePan:R,pannable:M,zoomStep:_,zoomable:N})},[M,N,R,_,Z,ee,J]);const pe=w?me=>{var Me;const[ke,Ce]=((Me=le.current)==null?void 0:Me.pointer(me))||[0,0];w(me,{x:ke,y:Ce})}:void 0,we=S?G.useCallback((me,ke)=>{const Ce=W.getState().nodeLookup.get(ke).internals.userNode;S(me,Ce)},[]):void 0,ve=E??k["minimap.ariaLabel"];return P.jsx(vl,{position:g,style:{...t,"--xy-minimap-background-color-props":typeof p=="string"?p:void 0,"--xy-minimap-mask-background-color-props":typeof y=="string"?y:void 0,"--xy-minimap-mask-stroke-color-props":typeof m=="string"?m:void 0,"--xy-minimap-mask-stroke-width-props":typeof v=="number"?v*j:void 0,"--xy-minimap-node-background-color-props":typeof l=="string"?l:void 0,"--xy-minimap-node-stroke-color-props":typeof o=="string"?o:void 0,"--xy-minimap-node-stroke-width-props":typeof f=="number"?f:void 0},className:be(["react-flow__minimap",r]),"data-testid":"rf__minimap",children:P.jsxs("svg",{width:B,height:H,viewBox:`${ne} ${ie} ${ce} ${O}`,className:"react-flow__minimap-svg",role:"img","aria-labelledby":re,ref:$,onClick:pe,children:[ve&&P.jsx("title",{id:re,children:ve}),P.jsx(M_,{onClick:we,nodeColor:l,nodeStrokeColor:o,nodeBorderRadius:c,nodeClassName:u,nodeStrokeWidth:f,nodeComponent:h}),P.jsx("path",{className:"react-flow__minimap-mask",d:`M${ne-z},${ie-z}h${ce+z*2}v${O+z*2}h${-ce-z*2}z + M${X.x},${X.y}h${X.width}v${X.height}h${-X.width}z`,fillRule:"evenodd",pointerEvents:"none"})]})})}Vg.displayName="MiniMap";const j_=G.memo(Vg),A_=t=>r=>t?`${Math.max(1/r.transform[2],1)}`:void 0,$_={[oi.Line]:"right",[oi.Handle]:"bottom-right"};function D_({nodeId:t,position:r,variant:o=oi.Handle,className:l,style:u=void 0,children:c,color:f,minWidth:h=10,minHeight:p=10,maxWidth:y=Number.MAX_VALUE,maxHeight:m=Number.MAX_VALUE,keepAspectRatio:v=!1,resizeDirection:g,autoScale:w=!0,shouldResize:S,onResizeStart:M,onResize:N,onResizeEnd:E}){const R=yg(),_=typeof t=="string"?t:R,I=$e(),W=G.useRef(null),$=o===oi.Handle,V=Ie(G.useCallback(A_($&&w),[$,w]),Ve),X=G.useRef(null),K=r??$_[o];G.useEffect(()=>{if(!(!W.current||!_))return X.current||(X.current=i1({domNode:W.current,nodeId:_,getStoreItems:()=>{const{nodeLookup:Z,transform:ee,snapGrid:J,snapToGrid:k,nodeOrigin:B,domNode:H}=I.getState();return{nodeLookup:Z,transform:ee,snapGrid:J,snapToGrid:k,nodeOrigin:B,paneDomNode:H}},onChange:(Z,ee)=>{const{triggerNodeChanges:J,nodeLookup:k,parentLookup:B,nodeOrigin:H}=I.getState(),U=[],A={x:Z.x,y:Z.y},j=k.get(_);if(j&&j.expandParent&&j.parentId){const F=j.origin??H,C=Z.width??j.measured.width??0,z=Z.height??j.measured.height??0,ne={id:j.id,parentId:j.parentId,rect:{width:C,height:z,...Vp({x:Z.x??j.position.x,y:Z.y??j.position.y},{width:C,height:z},j.parentId,k,F)}},ie=uc([ne],k,B,H);U.push(...ie),A.x=Z.x?Math.max(F[0]*C,Z.x):void 0,A.y=Z.y?Math.max(F[1]*z,Z.y):void 0}if(A.x!==void 0&&A.y!==void 0){const F={id:_,type:"position",position:{...A}};U.push(F)}if(Z.width!==void 0&&Z.height!==void 0){const C={id:_,type:"dimensions",resizing:!0,setAttributes:g?g==="horizontal"?"width":"height":!0,dimensions:{width:Z.width,height:Z.height}};U.push(C)}for(const F of ee){const C={...F,type:"position"};U.push(C)}J(U)},onEnd:({width:Z,height:ee})=>{const J={id:_,type:"dimensions",resizing:!1,dimensions:{width:Z,height:ee}};I.getState().triggerNodeChanges([J])}})),X.current.update({controlPosition:K,boundaries:{minWidth:h,minHeight:p,maxWidth:y,maxHeight:m},keepAspectRatio:v,resizeDirection:g,onResizeStart:M,onResize:N,onResizeEnd:E,shouldResize:S}),()=>{var Z;(Z=X.current)==null||Z.destroy()}},[K,h,p,y,m,v,M,N,E,S]);const te=K.split("-");return P.jsx("div",{className:be(["react-flow__resize-control","nodrag",...te,o,l]),ref:W,style:{...u,scale:V,...f&&{[$?"backgroundColor":"borderColor"]:f}},children:c})}G.memo(D_);const O_={"arch.context":0,"django.app":0,"django.route":1,"django.url_name":1,"django.view":2,"django.viewset_action":2,"django.permission":2,"django.serializer":3,"django.serializer_field":4,"django.service":4,"django.model":5,"django.field":6,"django.relation":6,"django.task":7,"django.receiver":7,"django.signal":7,"django.test":7,"django.migration_op":7,"django.admin":7,"openapi.path":8,"react.api_client":9,"react.query_key":10,"react.hook":10,"react.feature":10,"react.route":11,"react.page":11,"react.component":12,"react.form_schema":13,"react.test":13,"react.context":12};function F_(t){return O_[t]??8}function H_(t){const r=new Map;for(const l of t){const u=F_(l.type),c=r.get(u)??[];c.push(l),r.set(u,c)}const o=new Map;for(const[l,u]of r)u.sort((c,f)=>c.name.localeCompare(f.name)),u.forEach((c,f)=>{o.set(c.id,{x:l*240,y:f*92})});return o}const V_={cheap:"#4a5568",expensive:"#f4a261",critical:"#e85d04"};function B_({data:t}){return P.jsxs("div",{className:"lp-node",children:[P.jsx("div",{className:"t",children:t.type.split(".").pop()}),P.jsx("div",{className:"n",children:t.name})]})}const U_={load:B_};function za({nodes:t,edges:r}){const o=H_(t),l=t.map(c=>({id:c.id,type:"load",position:o.get(c.id)??{x:0,y:0},data:{name:c.name,type:c.type,file:c.file_path}})),u=r.filter(c=>t.some(f=>f.id===c.src)&&t.some(f=>f.id===c.dst)).map(c=>({id:c.id,source:c.src,target:c.dst,animated:c.weight==="critical",style:{stroke:V_[c.weight]||"#4a5568",strokeWidth:c.weight==="critical"?2.4:1.2,strokeDasharray:c.confidence<.8?"6 4":void 0},label:c.type.replaceAll("_"," "),labelStyle:{fill:"#8b9bb0",fontSize:9}}));return P.jsx(Og,{children:P.jsxs(u_,{nodes:l,edges:u,nodeTypes:U_,fitView:!0,minZoom:.2,"data-testid":"impact-graph",children:[P.jsx(h_,{}),P.jsx(j_,{pannable:!0,zoomable:!0}),P.jsx(w_,{})]})})}function W_(){var ce;const[t,r]=G.useState("review"),[o,l]=G.useState(localStorage.getItem("loadpath.repo")||""),[u,c]=G.useState("HEAD~1"),[f,h]=G.useState("HEAD"),[p,y]=G.useState(null),[m,v]=G.useState(null),[g,w]=G.useState([]),[S,M]=G.useState("review"),[N,E]=G.useState(""),[R,_]=G.useState(""),[I,W]=G.useState({}),[$,V]=G.useState([]),[X,K]=G.useState(""),[te,Z]=G.useState("github"),[ee,J]=G.useState(""),k=G.useRef(o);k.current=o,G.useEffect(()=>{Vt.settings().then(W).catch(()=>{}),Vt.repos().then(O=>w(O.repos)).catch(()=>{})},[]),G.useEffect(()=>{if(t!=="architecture"||!o)return;const O=o;let re=!1;return Vt.architecture(O).then(Q=>{!re&&k.current===O&&v(Q)}).catch(()=>{}),()=>{re=!0}},[t,o]);const B=O=>{l(O),localStorage.setItem("loadpath.repo",O)},H=async(O=o)=>{if(!O)return null;const re=await Vt.architecture(O);return k.current===O&&v(re),re},U=async()=>{E(""),_("Tracing load path…"),B(o);try{const O=await Vt.review(o,u,f,!0);y(O),M("review"),r("review"),await Vt.repos().then(re=>w(re.repos)).catch(()=>{}),await H(o)}catch(O){E(O instanceof Error?O.message:String(O))}finally{_("")}},A=async(O=!0)=>{E(""),_(O?"Indexing…":"Full reindex…"),B(o);try{await Vt.index(o,O);const re=await H(o);await Vt.repos().then(Q=>w(Q.repos)).catch(()=>{}),re!=null&&re.indexed&&(M("architecture"),r("architecture"))}catch(re){E(re instanceof Error?re.message:String(re))}finally{_("")}},j=async()=>{E(""),_("Fetching pull requests…");try{const O=await Vt.prs(te,X);V(O.pull_requests)}catch(O){E(O instanceof Error?O.message:String(O))}finally{_("")}},F=async O=>{O.preventDefault();const re=new FormData(O.currentTarget),Q={github_token:String(re.get("github_token")||""),bitbucket_token:String(re.get("bitbucket_token")||""),bitbucket_username:String(re.get("bitbucket_username")||""),ai_provider:String(re.get("ai_provider")||"none"),ai_api_key:String(re.get("ai_api_key")||""),ai_model:String(re.get("ai_model")||""),ai_base_url:String(re.get("ai_base_url")||""),workspaces:g.length?g.map(le=>({path:le.path,name:le.name})):o?[{path:o,name:o.split(/[\\/]/).pop()}]:[]};W(await Vt.saveSettings(Q))},C=async()=>{if(p){_("Residual analysis…");try{const O=await Vt.residual(p);J(O.note)}catch(O){E(O instanceof Error?O.message:String(O))}finally{_("")}}},z=G.useMemo(()=>S==="architecture"?(m==null?void 0:m.nodes)??[]:(p==null?void 0:p.nodes)??[],[S,m,p]),ne=G.useMemo(()=>S==="architecture"?(m==null?void 0:m.edges)??[]:(p==null?void 0:p.edges)??[],[S,m,p]),ie=p!=null&&p.index?`${p.index.counts.nodes} nodes / ${p.index.counts.edges} edges · ${p.index.incremental?"incremental":"full"}`:m!=null&&m.indexed?`${m.counts.nodes} nodes / ${m.counts.edges} edges indexed`:"Not indexed";return P.jsxs("div",{className:"app",children:[P.jsxs("nav",{className:"rail","data-testid":"rail",children:[P.jsx("div",{className:"brand",children:"Loadpath"}),P.jsx("button",{"data-testid":"tab-review",className:t==="review"?"active":"",onClick:()=>r("review"),children:"Review"}),P.jsx("button",{"data-testid":"tab-architecture",className:t==="architecture"?"active":"",onClick:()=>r("architecture"),children:"Architecture"}),P.jsx("button",{"data-testid":"tab-graph",className:t==="graph"?"active":"",onClick:()=>r("graph"),children:"Impact graph"}),P.jsx("button",{"data-testid":"tab-prs",className:t==="prs"?"active":"",onClick:()=>r("prs"),children:"Pull requests"}),P.jsx("button",{"data-testid":"tab-settings",className:t==="settings"?"active":"",onClick:()=>r("settings"),children:"Settings"}),P.jsx("div",{style:{flex:1}}),P.jsx("div",{className:"muted",children:R||ie})]}),P.jsxs("div",{className:"main",children:[P.jsxs("div",{className:"topbar","data-testid":"topbar",children:[g.length>0?P.jsxs("select",{"data-testid":"workspace-select",value:g.some(O=>O.path===o)?o:"",onChange:O=>{O.target.value&&B(O.target.value)},children:[P.jsx("option",{value:"",children:"Indexed repos…"}),g.map(O=>P.jsxs("option",{value:O.path,children:[O.name,O.indexed?` (${O.counts.nodes})`:""]},O.path))]}):null,P.jsx("input",{"data-testid":"repo-path",className:"path",placeholder:"Local monorepo path",value:o,onChange:O=>l(O.target.value)}),P.jsx("input",{"data-testid":"base-ref",value:u,onChange:O=>c(O.target.value),placeholder:"base"}),P.jsx("input",{"data-testid":"head-ref",value:f,onChange:O=>h(O.target.value),placeholder:"head"}),P.jsx("button",{"data-testid":"btn-index",onClick:()=>A(!0),children:"Index"}),P.jsx("button",{"data-testid":"btn-review",className:"btn primary",onClick:U,children:"Review"})]}),N?P.jsx("div",{className:"error",children:N}):null,t==="review"&&P.jsxs("div",{className:"content","data-testid":"review-layout",children:[P.jsx("aside",{className:"brief","data-testid":"brief",children:p?P.jsxs(P.Fragment,{children:[P.jsxs("div",{className:`level ${p.confidence.level}`,children:[p.confidence.level.toUpperCase()," — ",p.title]}),p.low_risk?P.jsx("span",{className:"chip",children:"loadpath:low-risk"}):null,p.change_kinds.map(O=>P.jsx("span",{className:"chip",children:O.replaceAll("_"," ")},O)),P.jsx("pre",{className:"headline",children:p.headline}),p.index?P.jsxs(P.Fragment,{children:[P.jsx("div",{className:"kicker",children:"Index"}),P.jsxs("div",{className:"muted",children:["Walked ",p.index.counts.nodes," nodes / ",p.index.counts.edges," edges",p.index.reindexed?" after an incremental refresh":" from the existing index","."]})]}):null,P.jsx("div",{className:"kicker",children:"Read this"}),p.read_order.map(O=>P.jsxs("div",{children:[P.jsx("span",{className:"file",children:O.path}),P.jsx("div",{className:"muted",children:O.why})]},O.path)),P.jsx("div",{className:"kicker",children:"Clusters"}),p.clusters.map(O=>P.jsxs("div",{className:"muted",children:[P.jsx("strong",{children:O.title})," — ",O.files.join(", ")]},O.id)),P.jsx("div",{className:"kicker",children:"Architecture"}),p.findings.filter(O=>!O.waived).length===0?P.jsx("div",{className:"muted",children:p.architecture_note}):p.findings.filter(O=>!O.waived).map(O=>P.jsxs("div",{className:"muted",children:[P.jsx("span",{className:`chip ${O.severity}`,children:O.severity}),O.message]},O.rule+O.message)),P.jsx("div",{className:"kicker",children:"Residual (AI only here)"}),p.residuals.map(O=>P.jsx("div",{className:"muted",children:O},O)),P.jsx("button",{className:"btn",onClick:C,style:{marginTop:12},children:"Ask configured model"}),ee?P.jsx("pre",{className:"headline",children:ee}):null,P.jsx("div",{className:"kicker",children:"Reviewers"}),P.jsx("div",{className:"muted",children:p.suggested_reviewers.join(", ")||"—"})]}):P.jsxs("p",{className:"muted",children:["Index a Django + React monorepo with ",P.jsx("code",{children:"loadpath.yml"}),", inspect architecture, then review a git range against that graph."]})}),P.jsx("div",{className:"graph-wrap","data-testid":"review-graph",children:p?P.jsx(za,{nodes:p.nodes,edges:p.edges}):null})]}),t==="architecture"&&P.jsxs("div",{className:"content","data-testid":"architecture-panel",children:[P.jsx("aside",{className:"brief","data-testid":"architecture-brief",children:m!=null&&m.indexed?P.jsxs(P.Fragment,{children:[P.jsxs("div",{className:"level high",children:["INDEXED — ",m.counts.nodes," nodes"]}),P.jsxs("span",{className:"chip",children:[m.counts.edges," edges"]}),m.has_config?P.jsx("span",{className:"chip",children:"loadpath.yml"}):null,P.jsxs("div",{className:"muted",style:{marginTop:8},children:[m.indexed_at?`Last index ${m.indexed_at}`:"Indexed",m.incremental?" · incremental":" · full"]}),P.jsx("div",{className:"kicker",children:"Bounded contexts"}),Object.values(m.contexts).map(O=>P.jsxs("div",{className:"muted",children:[P.jsx("strong",{children:O.name})," — ",(O.django_apps||[]).join(", ")||"no apps"," ·"," ",(O.owners||[]).join(", ")||"unowned"]},O.name)),P.jsx("div",{className:"kicker",children:"Rules"}),(m.rules||[]).map(O=>P.jsx("div",{className:"muted",children:O},O)),P.jsx("div",{className:"kicker",children:"Findings on the indexed graph"}),m.findings.filter(O=>!O.waived).length===0?P.jsx("div",{className:"muted",children:"No architecture rule hits on the full graph."}):m.findings.filter(O=>!O.waived).map(O=>P.jsxs("div",{className:"muted",children:[P.jsx("span",{className:`chip ${O.severity}`,children:O.severity}),O.message]},O.rule+O.message)),P.jsx("div",{className:"kicker",children:"Types"}),P.jsx("div",{className:"muted",children:Object.entries(m.type_counts||{}).sort((O,re)=>re[1]-O[1]).slice(0,12).map(([O,re])=>`${O.split(".").pop()} ${re}`).join(" · ")}),P.jsx("button",{className:"btn",style:{marginTop:12},onClick:()=>A(!1),"data-testid":"btn-full-reindex",children:"Full reindex"}),P.jsx("button",{className:"btn primary",style:{marginTop:8},onClick:U,children:"Review against this index"})]}):P.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."})}),P.jsx("div",{className:"graph-wrap","data-testid":"architecture-graph",children:m!=null&&m.indexed?P.jsx(za,{nodes:m.nodes,edges:m.edges}):null})]}),t==="graph"&&P.jsxs("div",{className:"graph-wrap","data-testid":"graph-full",style:{height:"100%",display:"flex",flexDirection:"column"},children:[P.jsxs("div",{className:"graph-modes",children:[P.jsx("button",{"data-testid":"graph-mode-review",className:S==="review"?"active":"",onClick:()=>M("review"),children:"This review"}),P.jsx("button",{"data-testid":"graph-mode-architecture",className:S==="architecture"?"active":"",onClick:()=>M("architecture"),children:"Indexed architecture"})]}),z.length?P.jsx("div",{style:{flex:1,minHeight:0},children:P.jsx(za,{nodes:z,edges:ne})}):P.jsx("p",{className:"muted",children:"Index the repo or run a review first."})]}),t==="prs"&&P.jsxs("div",{className:"pr-list","data-testid":"pr-list",children:[P.jsxs("div",{className:"topbar",style:{border:0,padding:0,marginBottom:12},children:[P.jsxs("select",{"data-testid":"pr-provider",value:te,onChange:O=>Z(O.target.value),children:[P.jsx("option",{value:"github",children:"GitHub"}),P.jsx("option",{value:"bitbucket",children:"Bitbucket"})]}),P.jsx("input",{"data-testid":"pr-repo",className:"path",placeholder:"owner/repo",value:X,onChange:O=>K(O.target.value)}),P.jsx("button",{"data-testid":"btn-list-prs",onClick:j,children:"List PRs"})]}),$.map(O=>P.jsxs("article",{className:"pr","data-testid":`pr-${O.number}`,children:[P.jsxs("h3",{children:["#",O.number," ",O.title]}),P.jsxs("div",{className:"muted",children:[O.author," · ",O.source_branch," → ",O.target_branch," · ",O.provider]}),P.jsxs("a",{href:O.url,target:"_blank",rel:"noreferrer",children:["Open on ",O.provider]}),P.jsx("div",{children:P.jsx("button",{className:"btn",onClick:()=>{c(O.target_branch),h(O.source_branch),r("review")},children:"Review this branch range"})})]},`${O.provider}-${O.number}`))]}),t==="settings"&&P.jsxs("form",{className:"settings","data-testid":"settings-form",onSubmit:F,children:[P.jsx("h1",{children:"Keys & providers"}),P.jsx("p",{className:"muted",children:"Tokens stay on this machine in ~/.loadpath/settings.json. GitHub and Bitbucket power the PR list. Indexed repos are remembered as workspaces. AI is used only for residual uncertainty the graph could not close."}),P.jsx("label",{children:"GitHub token"}),P.jsx("input",{name:"github_token",type:"password",placeholder:"ghp_…"}),P.jsx("label",{children:"Bitbucket token"}),P.jsx("input",{name:"bitbucket_token",type:"password"}),P.jsx("label",{children:"Bitbucket username (app passwords)"}),P.jsx("input",{name:"bitbucket_username",defaultValue:String(I.bitbucket_username||"")}),P.jsx("label",{children:"AI provider"}),P.jsxs("select",{name:"ai_provider",defaultValue:String(((ce=I.ai)==null?void 0:ce.provider)||"none"),children:[P.jsx("option",{value:"none",children:"none (graph only)"}),P.jsx("option",{value:"anthropic",children:"Anthropic"}),P.jsx("option",{value:"openai",children:"OpenAI"}),P.jsx("option",{value:"grok",children:"Grok / xAI"}),P.jsx("option",{value:"deepseek",children:"DeepSeek"}),P.jsx("option",{value:"cursor",children:"Cursor-compatible (OpenAI protocol)"}),P.jsx("option",{value:"ollama",children:"Ollama local"})]}),P.jsx("label",{children:"AI API key"}),P.jsx("input",{name:"ai_api_key",type:"password"}),P.jsx("label",{children:"Model"}),P.jsx("input",{name:"ai_model",placeholder:"optional override"}),P.jsx("label",{children:"Base URL"}),P.jsx("input",{name:"ai_base_url",placeholder:"optional, OpenAI-compatible"}),P.jsx("button",{className:"btn primary",type:"submit",children:"Save"})]})]})]})}P0.createRoot(document.getElementById("root")).render(P.jsx(G.StrictMode,{children:P.jsx(W_,{})})); diff --git a/src/loadpath/static/assets/index-CfK4f0dK.js b/src/loadpath/static/assets/index-CfK4f0dK.js deleted file mode 100644 index 702796c..0000000 --- a/src/loadpath/static/assets/index-CfK4f0dK.js +++ /dev/null @@ -1,62 +0,0 @@ -(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const u of document.querySelectorAll('link[rel="modulepreload"]'))l(u);new MutationObserver(u=>{for(const c of u)if(c.type==="childList")for(const f of c.addedNodes)f.tagName==="LINK"&&f.rel==="modulepreload"&&l(f)}).observe(document,{childList:!0,subtree:!0});function o(u){const c={};return u.integrity&&(c.integrity=u.integrity),u.referrerPolicy&&(c.referrerPolicy=u.referrerPolicy),u.crossOrigin==="use-credentials"?c.credentials="include":u.crossOrigin==="anonymous"?c.credentials="omit":c.credentials="same-origin",c}function l(u){if(u.ep)return;u.ep=!0;const c=o(u);fetch(u.href,c)}})();function Zh(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var ha={exports:{}},Gi={},pa={exports:{}},Ne={};/** - * @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 jd;function x0(){if(jd)return Ne;jd=1;var t=Symbol.for("react.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),l=Symbol.for("react.strict_mode"),u=Symbol.for("react.profiler"),c=Symbol.for("react.provider"),f=Symbol.for("react.context"),h=Symbol.for("react.forward_ref"),p=Symbol.for("react.suspense"),y=Symbol.for("react.memo"),m=Symbol.for("react.lazy"),v=Symbol.iterator;function g(C){return C===null||typeof C!="object"?null:(C=v&&C[v]||C["@@iterator"],typeof C=="function"?C:null)}var w={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},S=Object.assign,M={};function N(C,z,ne){this.props=C,this.context=z,this.refs=M,this.updater=ne||w}N.prototype.isReactComponent={},N.prototype.setState=function(C,z){if(typeof C!="object"&&typeof C!="function"&&C!=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,C,z,"setState")},N.prototype.forceUpdate=function(C){this.updater.enqueueForceUpdate(this,C,"forceUpdate")};function E(){}E.prototype=N.prototype;function L(C,z,ne){this.props=C,this.context=z,this.refs=M,this.updater=ne||w}var _=L.prototype=new E;_.constructor=L,S(_,N.prototype),_.isPureReactComponent=!0;var I=Array.isArray,U=Object.prototype.hasOwnProperty,D={current:null},V={key:!0,ref:!0,__self:!0,__source:!0};function X(C,z,ne){var re,$={},se=null,ce=null;if(z!=null)for(re in z.ref!==void 0&&(ce=z.ref),z.key!==void 0&&(se=""+z.key),z)U.call(z,re)&&!V.hasOwnProperty(re)&&($[re]=z[re]);var G=arguments.length-2;if(G===1)$.children=ne;else if(1>>1,z=A[C];if(0>>1;Cu($,F))seu(ce,$)?(A[C]=ce,A[se]=F,C=se):(A[C]=$,A[re]=F,C=re);else if(seu(ce,F))A[C]=ce,A[se]=F,C=se;else break e}}return j}function u(A,j){var F=A.sortIndex-j.sortIndex;return F!==0?F:A.id-j.id}if(typeof performance=="object"&&typeof performance.now=="function"){var c=performance;t.unstable_now=function(){return c.now()}}else{var f=Date,h=f.now();t.unstable_now=function(){return f.now()-h}}var p=[],y=[],m=1,v=null,g=3,w=!1,S=!1,M=!1,N=typeof setTimeout=="function"?setTimeout:null,E=typeof clearTimeout=="function"?clearTimeout:null,L=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function _(A){for(var j=o(y);j!==null;){if(j.callback===null)l(y);else if(j.startTime<=A)l(y),j.sortIndex=j.expirationTime,r(p,j);else break;j=o(y)}}function I(A){if(M=!1,_(A),!S)if(o(p)!==null)S=!0,H(U);else{var j=o(y);j!==null&&B(I,j.startTime-A)}}function U(A,j){S=!1,M&&(M=!1,E(X),X=-1),w=!0;var F=g;try{for(_(j),v=o(p);v!==null&&(!(v.expirationTime>j)||A&&!Z());){var C=v.callback;if(typeof C=="function"){v.callback=null,g=v.priorityLevel;var z=C(v.expirationTime<=j);j=t.unstable_now(),typeof z=="function"?v.callback=z:v===o(p)&&l(p),_(j)}else l(p);v=o(p)}if(v!==null)var ne=!0;else{var re=o(y);re!==null&&B(I,re.startTime-j),ne=!1}return ne}finally{v=null,g=F,w=!1}}var D=!1,V=null,X=-1,Q=5,te=-1;function Z(){return!(t.unstable_now()-teA||125C?(A.sortIndex=F,r(y,A),o(p)===null&&A===o(y)&&(M?(E(X),X=-1):M=!0,B(I,F-C))):(A.sortIndex=z,r(p,A),S||w||(S=!0,H(U))),A},t.unstable_shouldYield=Z,t.unstable_wrapCallback=function(A){var j=g;return function(){var F=g;g=j;try{return A.apply(this,arguments)}finally{g=F}}}})(ya)),ya}var Fd;function k0(){return Fd||(Fd=1,ma.exports=E0()),ma.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 Hd;function N0(){if(Hd)return gt;Hd=1;var t=fo(),r=k0();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"),p=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]*$/,m={},v={};function g(e){return p.call(v,e)?!0:p.call(m,e)?!1:y.test(e)?v[e]=!0:(m[e]=!0,!1)}function w(e,n,i,s){if(i!==null&&i.type===0)return!1;switch(typeof n){case"function":case"symbol":return!0;case"boolean":return s?!1:i!==null?!i.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function S(e,n,i,s){if(n===null||typeof n>"u"||w(e,n,i,s))return!0;if(s)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 M(e,n,i,s,a,d,x){this.acceptsBooleans=n===2||n===3||n===4,this.attributeName=s,this.attributeNamespace=a,this.mustUseProperty=i,this.propertyName=e,this.type=n,this.sanitizeURL=d,this.removeEmptyString=x}var N={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){N[e]=new M(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var n=e[0];N[n]=new M(n,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){N[e]=new M(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){N[e]=new M(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){N[e]=new M(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){N[e]=new M(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){N[e]=new M(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){N[e]=new M(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){N[e]=new M(e,5,!1,e.toLowerCase(),null,!1,!1)});var E=/[\-:]([a-z])/g;function L(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(E,L);N[n]=new M(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(E,L);N[n]=new M(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(E,L);N[n]=new M(n,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){N[e]=new M(e,1,!1,e.toLowerCase(),null,!1,!1)}),N.xlinkHref=new M("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){N[e]=new M(e,1,!1,e.toLowerCase(),null,!0,!0)});function _(e,n,i,s){var a=N.hasOwnProperty(n)?N[n]:null;(a!==null?a.type!==0:s||!(2T||a[x]!==d[T]){var R=` -`+a[x].replace(" at new "," at ");return e.displayName&&R.includes("")&&(R=R.replace("",e.displayName)),R}while(1<=x&&0<=T);break}}}finally{ne=!1,Error.prepareStackTrace=i}return(e=e?e.displayName||e.name:"")?z(e):""}function $(e){switch(e.tag){case 5:return z(e.type);case 16:return z("Lazy");case 13:return z("Suspense");case 19:return z("SuspenseList");case 0:case 2:case 15:return e=re(e.type,!1),e;case 11:return e=re(e.type.render,!1),e;case 1:return e=re(e.type,!0),e;default:return""}}function se(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 D:return"Portal";case Q:return"Profiler";case X:return"StrictMode";case J:return"Suspense";case k:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case Z:return(e.displayName||"Context")+".Consumer";case te:return(e._context.displayName||"Context")+".Provider";case ee: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:se(e.type)||"Memo";case H:n=e._payload,e=e._init;try{return se(e(n))}catch{}}return null}function ce(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 se(n);case 8:return n===X?"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 G(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function ue(e){var n=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(n==="checkbox"||n==="radio")}function pe(e){var n=ue(e)?"checked":"value",i=Object.getOwnPropertyDescriptor(e.constructor.prototype,n),s=""+e[n];if(!e.hasOwnProperty(n)&&typeof i<"u"&&typeof i.get=="function"&&typeof i.set=="function"){var a=i.get,d=i.set;return Object.defineProperty(e,n,{configurable:!0,get:function(){return a.call(this)},set:function(x){s=""+x,d.call(this,x)}}),Object.defineProperty(e,n,{enumerable:i.enumerable}),{getValue:function(){return s},setValue:function(x){s=""+x},stopTracking:function(){e._valueTracker=null,delete e[n]}}}}function we(e){e._valueTracker||(e._valueTracker=pe(e))}function ve(e){if(!e)return!1;var n=e._valueTracker;if(!n)return!0;var i=n.getValue(),s="";return e&&(s=ue(e)?e.checked?"true":"false":e.value),e=s,e!==i?(n.setValue(e),!0):!1}function me(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 ke(e,n){var i=n.checked;return F({},n,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:i??e._wrapperState.initialChecked})}function Ce(e,n){var i=n.defaultValue==null?"":n.defaultValue,s=n.checked!=null?n.checked:n.defaultChecked;i=G(n.value!=null?n.value:i),e._wrapperState={initialChecked:s,initialValue:i,controlled:n.type==="checkbox"||n.type==="radio"?n.checked!=null:n.value!=null}}function Me(e,n){n=n.checked,n!=null&&_(e,"checked",n,!1)}function Le(e,n){Me(e,n);var i=G(n.value),s=n.type;if(i!=null)s==="number"?(i===0&&e.value===""||e.value!=i)&&(e.value=""+i):e.value!==""+i&&(e.value=""+i);else if(s==="submit"||s==="reset"){e.removeAttribute("value");return}n.hasOwnProperty("value")?ut(e,n.type,i):n.hasOwnProperty("defaultValue")&&ut(e,n.type,G(n.defaultValue)),n.checked==null&&n.defaultChecked!=null&&(e.defaultChecked=!!n.defaultChecked)}function ot(e,n,i){if(n.hasOwnProperty("value")||n.hasOwnProperty("defaultValue")){var s=n.type;if(!(s!=="submit"&&s!=="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 ut(e,n,i){(n!=="number"||me(e.ownerDocument)!==e)&&(i==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+i&&(e.defaultValue=""+i))}var Je=Array.isArray;function et(e,n,i,s){if(e=e.options,n){n={};for(var a=0;a"+n.valueOf().toString()+"",n=Mt.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;n.firstChild;)e.appendChild(n.firstChild)}});function ln(e,n){if(n){var i=e.firstChild;if(i&&i===e.lastChild&&i.nodeType===3){i.nodeValue=n;return}}e.textContent=n}var Yn={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},Sl=["Webkit","ms","Moz","O"];Object.keys(Yn).forEach(function(e){Sl.forEach(function(n){n=n+e.charAt(0).toUpperCase()+e.substring(1),Yn[n]=Yn[e]})});function xo(e,n,i){return n==null||typeof n=="boolean"||n===""?"":i||typeof n!="number"||n===0||Yn.hasOwnProperty(e)&&Yn[e]?(""+n).trim():n+"px"}function wo(e,n){e=e.style;for(var i in n)if(n.hasOwnProperty(i)){var s=i.indexOf("--")===0,a=xo(i,n[i],s);i==="float"&&(i="cssFloat"),s?e.setProperty(i,a):e[i]=a}}var _l=F({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 si(e,n){if(n){if(_l[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 li(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 ui=null;function ai(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var ci=null,wn=null,Sn=null;function So(e){if(e=ji(e)){if(typeof ci!="function")throw Error(o(280));var n=e.stateNode;n&&(n=qo(n),ci(e.stateNode,e.type,n))}}function _o(e){wn?Sn?Sn.push(e):Sn=[e]:wn=e}function Eo(){if(wn){var e=wn,n=Sn;if(Sn=wn=null,So(e),n)for(e=0;e>>=0,e===0?32:31-(Ll(e)/Rl|0)|0}var Nr=64,Cr=4194304;function Kn(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 un(e,n){var i=e.pendingLanes;if(i===0)return 0;var s=0,a=e.suspendedLanes,d=e.pingedLanes,x=i&268435455;if(x!==0){var T=x&~a;T!==0?s=Kn(T):(d&=x,d!==0&&(s=Kn(d)))}else x=i&~a,x!==0?s=Kn(x):d!==0&&(s=Kn(d));if(s===0)return 0;if(n!==0&&n!==s&&(n&a)===0&&(a=s&-s,d=n&-n,a>=d||a===16&&(d&4194240)!==0))return n;if((s&4)!==0&&(s|=i&16),n=e.entangledLanes,n!==0)for(e=e.entanglements,n&=s;0i;i++)n.push(e);return n}function Zn(e,n,i){e.pendingLanes|=n,n!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,n=31-xt(n),e[n]=i}function $l(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 s=e.eventTimes;for(e=e.expirationTimes;0=Ni),Cc=" ",Mc=!1;function Pc(e,n){switch(e){case"keyup":return pm.indexOf(n.keyCode)!==-1;case"keydown":return n.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Ic(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Tr=!1;function mm(e,n){switch(e){case"compositionend":return Ic(n);case"keypress":return n.which!==32?null:(Mc=!0,Cc);case"textInput":return e=n.data,e===Cc&&Mc?null:e;default:return null}}function ym(e,n){if(Tr)return e==="compositionend"||!Xl&&Pc(e,n)?(e=wc(),Ho=Vl=Cn=null,Tr=!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=s}e:{for(;i;){if(i.nextSibling){i=i.nextSibling;break e}i=i.parentNode}i=void 0}i=$c(i)}}function Oc(e,n){return e&&n?e===n?!0:e&&e.nodeType===3?!1:n&&n.nodeType===3?Oc(e,n.parentNode):"contains"in e?e.contains(n):e.compareDocumentPosition?!!(e.compareDocumentPosition(n)&16):!1:!1}function Fc(){for(var e=window,n=me();n instanceof e.HTMLIFrameElement;){try{var i=typeof n.contentWindow.location.href=="string"}catch{i=!1}if(i)e=n.contentWindow;else break;n=me(e.document)}return n}function Kl(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 Cm(e){var n=Fc(),i=e.focusedElem,s=e.selectionRange;if(n!==i&&i&&i.ownerDocument&&Oc(i.ownerDocument.documentElement,i)){if(s!==null&&Kl(i)){if(n=s.start,e=s.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 a=i.textContent.length,d=Math.min(s.start,a);s=s.end===void 0?d:Math.min(s.end,a),!e.extend&&d>s&&(a=s,s=d,d=a),a=Dc(i,d);var x=Dc(i,s);a&&x&&(e.rangeCount!==1||e.anchorNode!==a.node||e.anchorOffset!==a.offset||e.focusNode!==x.node||e.focusOffset!==x.offset)&&(n=n.createRange(),n.setStart(a.node,a.offset),e.removeAllRanges(),d>s?(e.addRange(n),e.extend(x.node,x.offset)):(n.setEnd(x.node,x.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,zr=null,ql=null,Ii=null,Zl=!1;function Hc(e,n,i){var s=i.window===i?i.document:i.nodeType===9?i:i.ownerDocument;Zl||zr==null||zr!==me(s)||(s=zr,"selectionStart"in s&&Kl(s)?s={start:s.selectionStart,end:s.selectionEnd}:(s=(s.ownerDocument&&s.ownerDocument.defaultView||window).getSelection(),s={anchorNode:s.anchorNode,anchorOffset:s.anchorOffset,focusNode:s.focusNode,focusOffset:s.focusOffset}),Ii&&Pi(Ii,s)||(Ii=s,s=Qo(ql,"onSelect"),0$r||(e.current=cu[$r],cu[$r]=null,$r--)}function Re(e,n){$r++,cu[$r]=e.current,e.current=n}var Tn={},tt=In(Tn),ct=In(!1),er=Tn;function Dr(e,n){var i=e.type.contextTypes;if(!i)return Tn;var s=e.stateNode;if(s&&s.__reactInternalMemoizedUnmaskedChildContext===n)return s.__reactInternalMemoizedMaskedChildContext;var a={},d;for(d in i)a[d]=n[d];return s&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=n,e.__reactInternalMemoizedMaskedChildContext=a),a}function ft(e){return e=e.childContextTypes,e!=null}function Zo(){Ae(ct),Ae(tt)}function tf(e,n,i){if(tt.current!==Tn)throw Error(o(168));Re(tt,n),Re(ct,i)}function nf(e,n,i){var s=e.stateNode;if(n=n.childContextTypes,typeof s.getChildContext!="function")return i;s=s.getChildContext();for(var a in s)if(!(a in n))throw Error(o(108,ce(e)||"Unknown",a));return F({},i,s)}function Jo(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Tn,er=tt.current,Re(tt,e),Re(ct,ct.current),!0}function rf(e,n,i){var s=e.stateNode;if(!s)throw Error(o(169));i?(e=nf(e,n,er),s.__reactInternalMemoizedMergedChildContext=e,Ae(ct),Ae(tt),Re(tt,e)):Ae(ct),Re(ct,i)}var cn=null,es=!1,fu=!1;function of(e){cn===null?cn=[e]:cn.push(e)}function Om(e){es=!0,of(e)}function zn(){if(!fu&&cn!==null){fu=!0;var e=0,n=ze;try{var i=cn;for(ze=1;e>=x,a-=x,fn=1<<32-xt(n)+a|i<Ee?(Ke=_e,_e=null):Ke=_e.sibling;var Te=ie(b,_e,Y[Ee],ae);if(Te===null){_e===null&&(_e=Ke);break}e&&_e&&Te.alternate===null&&n(b,_e),O=d(Te,O,Ee),Se===null?ye=Te:Se.sibling=Te,Se=Te,_e=Ke}if(Ee===Y.length)return i(b,_e),De&&nr(b,Ee),ye;if(_e===null){for(;EeEe?(Ke=_e,_e=null):Ke=_e.sibling;var Hn=ie(b,_e,Te.value,ae);if(Hn===null){_e===null&&(_e=Ke);break}e&&_e&&Hn.alternate===null&&n(b,_e),O=d(Hn,O,Ee),Se===null?ye=Hn:Se.sibling=Hn,Se=Hn,_e=Ke}if(Te.done)return i(b,_e),De&&nr(b,Ee),ye;if(_e===null){for(;!Te.done;Ee++,Te=Y.next())Te=le(b,Te.value,ae),Te!==null&&(O=d(Te,O,Ee),Se===null?ye=Te:Se.sibling=Te,Se=Te);return De&&nr(b,Ee),ye}for(_e=s(b,_e);!Te.done;Ee++,Te=Y.next())Te=fe(_e,b,Ee,Te.value,ae),Te!==null&&(e&&Te.alternate!==null&&_e.delete(Te.key===null?Ee:Te.key),O=d(Te,O,Ee),Se===null?ye=Te:Se.sibling=Te,Se=Te);return e&&_e.forEach(function(v0){return n(b,v0)}),De&&nr(b,Ee),ye}function Ue(b,O,Y,ae){if(typeof Y=="object"&&Y!==null&&Y.type===V&&Y.key===null&&(Y=Y.props.children),typeof Y=="object"&&Y!==null){switch(Y.$$typeof){case U:e:{for(var ye=Y.key,Se=O;Se!==null;){if(Se.key===ye){if(ye=Y.type,ye===V){if(Se.tag===7){i(b,Se.sibling),O=a(Se,Y.props.children),O.return=b,b=O;break e}}else if(Se.elementType===ye||typeof ye=="object"&&ye!==null&&ye.$$typeof===H&&ff(ye)===Se.type){i(b,Se.sibling),O=a(Se,Y.props),O.ref=Ai(b,Se,Y),O.return=b,b=O;break e}i(b,Se);break}else n(b,Se);Se=Se.sibling}Y.type===V?(O=cr(Y.props.children,b.mode,ae,Y.key),O.return=b,b=O):(ae=Ps(Y.type,Y.key,Y.props,null,b.mode,ae),ae.ref=Ai(b,O,Y),ae.return=b,b=ae)}return x(b);case D:e:{for(Se=Y.key;O!==null;){if(O.key===Se)if(O.tag===4&&O.stateNode.containerInfo===Y.containerInfo&&O.stateNode.implementation===Y.implementation){i(b,O.sibling),O=a(O,Y.children||[]),O.return=b,b=O;break e}else{i(b,O);break}else n(b,O);O=O.sibling}O=ua(Y,b.mode,ae),O.return=b,b=O}return x(b);case H:return Se=Y._init,Ue(b,O,Se(Y._payload),ae)}if(Je(Y))return he(b,O,Y,ae);if(j(Y))return ge(b,O,Y,ae);is(b,Y)}return typeof Y=="string"&&Y!==""||typeof Y=="number"?(Y=""+Y,O!==null&&O.tag===6?(i(b,O.sibling),O=a(O,Y),O.return=b,b=O):(i(b,O),O=la(Y,b.mode,ae),O.return=b,b=O),x(b)):i(b,O)}return Ue}var Vr=df(!0),hf=df(!1),os=In(null),ss=null,Br=null,yu=null;function vu(){yu=Br=ss=null}function xu(e){var n=os.current;Ae(os),e._currentValue=n}function wu(e,n,i){for(;e!==null;){var s=e.alternate;if((e.childLanes&n)!==n?(e.childLanes|=n,s!==null&&(s.childLanes|=n)):s!==null&&(s.childLanes&n)!==n&&(s.childLanes|=n),e===i)break;e=e.return}}function Ur(e,n){ss=e,yu=Br=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&n)!==0&&(dt=!0),e.firstContext=null)}function Tt(e){var n=e._currentValue;if(yu!==e)if(e={context:e,memoizedValue:n,next:null},Br===null){if(ss===null)throw Error(o(308));Br=e,ss.dependencies={lanes:0,firstContext:e}}else Br=Br.next=e;return n}var rr=null;function Su(e){rr===null?rr=[e]:rr.push(e)}function pf(e,n,i,s){var a=n.interleaved;return a===null?(i.next=i,Su(n)):(i.next=a.next,a.next=i),n.interleaved=i,hn(e,s)}function hn(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 Ln=!1;function _u(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function gf(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 Rn(e,n,i){var s=e.updateQueue;if(s===null)return null;if(s=s.shared,(Pe&2)!==0){var a=s.pending;return a===null?n.next=n:(n.next=a.next,a.next=n),s.pending=n,hn(e,i)}return a=s.interleaved,a===null?(n.next=n,Su(s)):(n.next=a.next,a.next=n),s.interleaved=n,hn(e,i)}function ls(e,n,i){if(n=n.updateQueue,n!==null&&(n=n.shared,(i&4194240)!==0)){var s=n.lanes;s&=e.pendingLanes,i|=s,n.lanes=i,Mr(e,i)}}function mf(e,n){var i=e.updateQueue,s=e.alternate;if(s!==null&&(s=s.updateQueue,i===s)){var a=null,d=null;if(i=i.firstBaseUpdate,i!==null){do{var x={eventTime:i.eventTime,lane:i.lane,tag:i.tag,payload:i.payload,callback:i.callback,next:null};d===null?a=d=x:d=d.next=x,i=i.next}while(i!==null);d===null?a=d=n:d=d.next=n}else a=d=n;i={baseState:s.baseState,firstBaseUpdate:a,lastBaseUpdate:d,shared:s.shared,effects:s.effects},e.updateQueue=i;return}e=i.lastBaseUpdate,e===null?i.firstBaseUpdate=n:e.next=n,i.lastBaseUpdate=n}function us(e,n,i,s){var a=e.updateQueue;Ln=!1;var d=a.firstBaseUpdate,x=a.lastBaseUpdate,T=a.shared.pending;if(T!==null){a.shared.pending=null;var R=T,q=R.next;R.next=null,x===null?d=q:x.next=q,x=R;var oe=e.alternate;oe!==null&&(oe=oe.updateQueue,T=oe.lastBaseUpdate,T!==x&&(T===null?oe.firstBaseUpdate=q:T.next=q,oe.lastBaseUpdate=R))}if(d!==null){var le=a.baseState;x=0,oe=q=R=null,T=d;do{var ie=T.lane,fe=T.eventTime;if((s&ie)===ie){oe!==null&&(oe=oe.next={eventTime:fe,lane:0,tag:T.tag,payload:T.payload,callback:T.callback,next:null});e:{var he=e,ge=T;switch(ie=n,fe=i,ge.tag){case 1:if(he=ge.payload,typeof he=="function"){le=he.call(fe,le,ie);break e}le=he;break e;case 3:he.flags=he.flags&-65537|128;case 0:if(he=ge.payload,ie=typeof he=="function"?he.call(fe,le,ie):he,ie==null)break e;le=F({},le,ie);break e;case 2:Ln=!0}}T.callback!==null&&T.lane!==0&&(e.flags|=64,ie=a.effects,ie===null?a.effects=[T]:ie.push(T))}else fe={eventTime:fe,lane:ie,tag:T.tag,payload:T.payload,callback:T.callback,next:null},oe===null?(q=oe=fe,R=le):oe=oe.next=fe,x|=ie;if(T=T.next,T===null){if(T=a.shared.pending,T===null)break;ie=T,T=ie.next,ie.next=null,a.lastBaseUpdate=ie,a.shared.pending=null}}while(!0);if(oe===null&&(R=le),a.baseState=R,a.firstBaseUpdate=q,a.lastBaseUpdate=oe,n=a.shared.interleaved,n!==null){a=n;do x|=a.lane,a=a.next;while(a!==n)}else d===null&&(a.shared.lanes=0);sr|=x,e.lanes=x,e.memoizedState=le}}function yf(e,n,i){if(e=n.effects,n.effects=null,e!==null)for(n=0;ni?i:4,e(!0);var s=Mu.transition;Mu.transition={};try{e(!1),n()}finally{ze=i,Mu.transition=s}}function $f(){return zt().memoizedState}function Bm(e,n,i){var s=Dn(e);if(i={lane:s,action:i,hasEagerState:!1,eagerState:null,next:null},Df(e))Of(n,i);else if(i=pf(e,n,i,s),i!==null){var a=lt();Ft(i,e,s,a),Ff(i,n,s)}}function Um(e,n,i){var s=Dn(e),a={lane:s,action:i,hasEagerState:!1,eagerState:null,next:null};if(Df(e))Of(n,a);else{var d=e.alternate;if(e.lanes===0&&(d===null||d.lanes===0)&&(d=n.lastRenderedReducer,d!==null))try{var x=n.lastRenderedState,T=d(x,i);if(a.hasEagerState=!0,a.eagerState=T,jt(T,x)){var R=n.interleaved;R===null?(a.next=a,Su(n)):(a.next=R.next,R.next=a),n.interleaved=a;return}}catch{}finally{}i=pf(e,n,a,s),i!==null&&(a=lt(),Ft(i,e,s,a),Ff(i,n,s))}}function Df(e){var n=e.alternate;return e===He||n!==null&&n===He}function Of(e,n){Fi=fs=!0;var i=e.pending;i===null?n.next=n:(n.next=i.next,i.next=n),e.pending=n}function Ff(e,n,i){if((i&4194240)!==0){var s=n.lanes;s&=e.pendingLanes,i|=s,n.lanes=i,Mr(e,i)}}var ps={readContext:Tt,useCallback:nt,useContext:nt,useEffect:nt,useImperativeHandle:nt,useInsertionEffect:nt,useLayoutEffect:nt,useMemo:nt,useReducer:nt,useRef:nt,useState:nt,useDebugValue:nt,useDeferredValue:nt,useTransition:nt,useMutableSource:nt,useSyncExternalStore:nt,useId:nt,unstable_isNewReconciler:!1},Wm={readContext:Tt,useCallback:function(e,n){return en().memoizedState=[e,n===void 0?null:n],e},useContext:Tt,useEffect:Pf,useImperativeHandle:function(e,n,i){return i=i!=null?i.concat([e]):null,ds(4194308,4,zf.bind(null,n,e),i)},useLayoutEffect:function(e,n){return ds(4194308,4,e,n)},useInsertionEffect:function(e,n){return ds(4,2,e,n)},useMemo:function(e,n){var i=en();return n=n===void 0?null:n,e=e(),i.memoizedState=[e,n],e},useReducer:function(e,n,i){var s=en();return n=i!==void 0?i(n):n,s.memoizedState=s.baseState=n,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:n},s.queue=e,e=e.dispatch=Bm.bind(null,He,e),[s.memoizedState,e]},useRef:function(e){var n=en();return e={current:e},n.memoizedState=e},useState:Cf,useDebugValue:ju,useDeferredValue:function(e){return en().memoizedState=e},useTransition:function(){var e=Cf(!1),n=e[0];return e=Vm.bind(null,e[1]),en().memoizedState=e,[n,e]},useMutableSource:function(){},useSyncExternalStore:function(e,n,i){var s=He,a=en();if(De){if(i===void 0)throw Error(o(407));i=i()}else{if(i=n(),Ge===null)throw Error(o(349));(or&30)!==0||Sf(s,n,i)}a.memoizedState=i;var d={value:i,getSnapshot:n};return a.queue=d,Pf(Ef.bind(null,s,d,e),[e]),s.flags|=2048,Bi(9,_f.bind(null,s,d,i,n),void 0,null),i},useId:function(){var e=en(),n=Ge.identifierPrefix;if(De){var i=dn,s=fn;i=(s&~(1<<32-xt(s)-1)).toString(32)+i,n=":"+n+"R"+i,i=Hi++,0<\/script>",e=e.removeChild(e.firstChild)):typeof s.is=="string"?e=x.createElement(i,{is:s.is}):(e=x.createElement(i),i==="select"&&(x=e,s.multiple?x.multiple=!0:s.size&&(x.size=s.size))):e=x.createElementNS(e,i),e[Zt]=n,e[Ri]=s,od(e,n,!1,!1),n.stateNode=e;e:{switch(x=li(i,s),i){case"dialog":je("cancel",e),je("close",e),a=s;break;case"iframe":case"object":case"embed":je("load",e),a=s;break;case"video":case"audio":for(a=0;aQr&&(n.flags|=128,s=!0,Ui(d,!1),n.lanes=4194304)}else{if(!s)if(e=as(x),e!==null){if(n.flags|=128,s=!0,i=e.updateQueue,i!==null&&(n.updateQueue=i,n.flags|=4),Ui(d,!0),d.tail===null&&d.tailMode==="hidden"&&!x.alternate&&!De)return rt(n),null}else 2*Oe()-d.renderingStartTime>Qr&&i!==1073741824&&(n.flags|=128,s=!0,Ui(d,!1),n.lanes=4194304);d.isBackwards?(x.sibling=n.child,n.child=x):(i=d.last,i!==null?i.sibling=x:n.child=x,d.last=x)}return d.tail!==null?(n=d.tail,d.rendering=n,d.tail=n.sibling,d.renderingStartTime=Oe(),n.sibling=null,i=Fe.current,Re(Fe,s?i&1|2:i&1),n):(rt(n),null);case 22:case 23:return ia(),s=n.memoizedState!==null,e!==null&&e.memoizedState!==null!==s&&(n.flags|=8192),s&&(n.mode&1)!==0?(Et&1073741824)!==0&&(rt(n),n.subtreeFlags&6&&(n.flags|=8192)):rt(n),null;case 24:return null;case 25:return null}throw Error(o(156,n.tag))}function Zm(e,n){switch(hu(n),n.tag){case 1:return ft(n.type)&&Zo(),e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 3:return Wr(),Ae(ct),Ae(tt),Cu(),e=n.flags,(e&65536)!==0&&(e&128)===0?(n.flags=e&-65537|128,n):null;case 5:return ku(n),null;case 13:if(Ae(Fe),e=n.memoizedState,e!==null&&e.dehydrated!==null){if(n.alternate===null)throw Error(o(340));Hr()}return e=n.flags,e&65536?(n.flags=e&-65537|128,n):null;case 19:return Ae(Fe),null;case 4:return Wr(),null;case 10:return xu(n.type._context),null;case 22:case 23:return ia(),null;case 24:return null;default:return null}}var vs=!1,it=!1,Jm=typeof WeakSet=="function"?WeakSet:Set,de=null;function Yr(e,n){var i=e.ref;if(i!==null)if(typeof i=="function")try{i(null)}catch(s){Be(e,n,s)}else i.current=null}function Yu(e,n,i){try{i()}catch(s){Be(e,n,s)}}var ud=!1;function e0(e,n){if(iu=Oo,e=Fc(),Kl(e)){if("selectionStart"in e)var i={start:e.selectionStart,end:e.selectionEnd};else e:{i=(i=e.ownerDocument)&&i.defaultView||window;var s=i.getSelection&&i.getSelection();if(s&&s.rangeCount!==0){i=s.anchorNode;var a=s.anchorOffset,d=s.focusNode;s=s.focusOffset;try{i.nodeType,d.nodeType}catch{i=null;break e}var x=0,T=-1,R=-1,q=0,oe=0,le=e,ie=null;t:for(;;){for(var fe;le!==i||a!==0&&le.nodeType!==3||(T=x+a),le!==d||s!==0&&le.nodeType!==3||(R=x+s),le.nodeType===3&&(x+=le.nodeValue.length),(fe=le.firstChild)!==null;)ie=le,le=fe;for(;;){if(le===e)break t;if(ie===i&&++q===a&&(T=x),ie===d&&++oe===s&&(R=x),(fe=le.nextSibling)!==null)break;le=ie,ie=le.parentNode}le=fe}i=T===-1||R===-1?null:{start:T,end:R}}else i=null}i=i||{start:0,end:0}}else i=null;for(ou={focusedElem:e,selectionRange:i},Oo=!1,de=n;de!==null;)if(n=de,e=n.child,(n.subtreeFlags&1028)!==0&&e!==null)e.return=n,de=e;else for(;de!==null;){n=de;try{var he=n.alternate;if((n.flags&1024)!==0)switch(n.tag){case 0:case 11:case 15:break;case 1:if(he!==null){var ge=he.memoizedProps,Ue=he.memoizedState,b=n.stateNode,O=b.getSnapshotBeforeUpdate(n.elementType===n.type?ge:$t(n.type,ge),Ue);b.__reactInternalSnapshotBeforeUpdate=O}break;case 3:var Y=n.stateNode.containerInfo;Y.nodeType===1?Y.textContent="":Y.nodeType===9&&Y.documentElement&&Y.removeChild(Y.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(o(163))}}catch(ae){Be(n,n.return,ae)}if(e=n.sibling,e!==null){e.return=n.return,de=e;break}de=n.return}return he=ud,ud=!1,he}function Wi(e,n,i){var s=n.updateQueue;if(s=s!==null?s.lastEffect:null,s!==null){var a=s=s.next;do{if((a.tag&e)===e){var d=a.destroy;a.destroy=void 0,d!==void 0&&Yu(n,i,d)}a=a.next}while(a!==s)}}function xs(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 s=i.create;i.destroy=s()}i=i.next}while(i!==n)}}function Xu(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 ad(e){var n=e.alternate;n!==null&&(e.alternate=null,ad(n)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(n=e.stateNode,n!==null&&(delete n[Zt],delete n[Ri],delete n[au],delete n[$m],delete n[Dm])),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 cd(e){return e.tag===5||e.tag===3||e.tag===4}function fd(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||cd(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 Qu(e,n,i){var s=e.tag;if(s===5||s===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=Ko));else if(s!==4&&(e=e.child,e!==null))for(Qu(e,n,i),e=e.sibling;e!==null;)Qu(e,n,i),e=e.sibling}function Gu(e,n,i){var s=e.tag;if(s===5||s===6)e=e.stateNode,n?i.insertBefore(e,n):i.appendChild(e);else if(s!==4&&(e=e.child,e!==null))for(Gu(e,n,i),e=e.sibling;e!==null;)Gu(e,n,i),e=e.sibling}var qe=null,Dt=!1;function jn(e,n,i){for(i=i.child;i!==null;)dd(e,n,i),i=i.sibling}function dd(e,n,i){if(vt&&typeof vt.onCommitFiberUnmount=="function")try{vt.onCommitFiberUnmount(kr,i)}catch{}switch(i.tag){case 5:it||Yr(i,n);case 6:var s=qe,a=Dt;qe=null,jn(e,n,i),qe=s,Dt=a,qe!==null&&(Dt?(e=qe,i=i.stateNode,e.nodeType===8?e.parentNode.removeChild(i):e.removeChild(i)):qe.removeChild(i.stateNode));break;case 18:qe!==null&&(Dt?(e=qe,i=i.stateNode,e.nodeType===8?uu(e.parentNode,i):e.nodeType===1&&uu(e,i),_i(e)):uu(qe,i.stateNode));break;case 4:s=qe,a=Dt,qe=i.stateNode.containerInfo,Dt=!0,jn(e,n,i),qe=s,Dt=a;break;case 0:case 11:case 14:case 15:if(!it&&(s=i.updateQueue,s!==null&&(s=s.lastEffect,s!==null))){a=s=s.next;do{var d=a,x=d.destroy;d=d.tag,x!==void 0&&((d&2)!==0||(d&4)!==0)&&Yu(i,n,x),a=a.next}while(a!==s)}jn(e,n,i);break;case 1:if(!it&&(Yr(i,n),s=i.stateNode,typeof s.componentWillUnmount=="function"))try{s.props=i.memoizedProps,s.state=i.memoizedState,s.componentWillUnmount()}catch(T){Be(i,n,T)}jn(e,n,i);break;case 21:jn(e,n,i);break;case 22:i.mode&1?(it=(s=it)||i.memoizedState!==null,jn(e,n,i),it=s):jn(e,n,i);break;default:jn(e,n,i)}}function hd(e){var n=e.updateQueue;if(n!==null){e.updateQueue=null;var i=e.stateNode;i===null&&(i=e.stateNode=new Jm),n.forEach(function(s){var a=a0.bind(null,e,s);i.has(s)||(i.add(s),s.then(a,a))})}}function Ot(e,n){var i=n.deletions;if(i!==null)for(var s=0;sa&&(a=x),s&=~d}if(s=a,s=Oe()-s,s=(120>s?120:480>s?480:1080>s?1080:1920>s?1920:3e3>s?3e3:4320>s?4320:1960*n0(s/1960))-s,10e?16:e,$n===null)var s=!1;else{if(e=$n,$n=null,ks=0,(Pe&6)!==0)throw Error(o(331));var a=Pe;for(Pe|=4,de=e.current;de!==null;){var d=de,x=d.child;if((de.flags&16)!==0){var T=d.deletions;if(T!==null){for(var R=0;ROe()-Zu?ur(e,0):qu|=i),pt(e,n)}function Cd(e,n){n===0&&((e.mode&1)===0?n=1:(n=Cr,Cr<<=1,(Cr&130023424)===0&&(Cr=4194304)));var i=lt();e=hn(e,n),e!==null&&(Zn(e,n,i),pt(e,i))}function u0(e){var n=e.memoizedState,i=0;n!==null&&(i=n.retryLane),Cd(e,i)}function a0(e,n){var i=0;switch(e.tag){case 13:var s=e.stateNode,a=e.memoizedState;a!==null&&(i=a.retryLane);break;case 19:s=e.stateNode;break;default:throw Error(o(314))}s!==null&&s.delete(n),Cd(e,i)}var Md;Md=function(e,n,i){if(e!==null)if(e.memoizedProps!==n.pendingProps||ct.current)dt=!0;else{if((e.lanes&i)===0&&(n.flags&128)===0)return dt=!1,Km(e,n,i);dt=(e.flags&131072)!==0}else dt=!1,De&&(n.flags&1048576)!==0&&sf(n,ns,n.index);switch(n.lanes=0,n.tag){case 2:var s=n.type;ys(e,n),e=n.pendingProps;var a=Dr(n,tt.current);Ur(n,i),a=Iu(null,n,s,e,a,i);var d=Tu();return n.flags|=1,typeof a=="object"&&a!==null&&typeof a.render=="function"&&a.$$typeof===void 0?(n.tag=1,n.memoizedState=null,n.updateQueue=null,ft(s)?(d=!0,Jo(n)):d=!1,n.memoizedState=a.state!==null&&a.state!==void 0?a.state:null,_u(n),a.updater=gs,n.stateNode=a,a._reactInternals=n,$u(n,s,e,i),n=Hu(null,n,s,!0,d,i)):(n.tag=0,De&&d&&du(n),st(null,n,a,i),n=n.child),n;case 16:s=n.elementType;e:{switch(ys(e,n),e=n.pendingProps,a=s._init,s=a(s._payload),n.type=s,a=n.tag=f0(s),e=$t(s,e),a){case 0:n=Fu(null,n,s,e,i);break e;case 1:n=Jf(null,n,s,e,i);break e;case 11:n=Qf(null,n,s,e,i);break e;case 14:n=Gf(null,n,s,$t(s.type,e),i);break e}throw Error(o(306,s,""))}return n;case 0:return s=n.type,a=n.pendingProps,a=n.elementType===s?a:$t(s,a),Fu(e,n,s,a,i);case 1:return s=n.type,a=n.pendingProps,a=n.elementType===s?a:$t(s,a),Jf(e,n,s,a,i);case 3:e:{if(ed(n),e===null)throw Error(o(387));s=n.pendingProps,d=n.memoizedState,a=d.element,gf(e,n),us(n,s,null,i);var x=n.memoizedState;if(s=x.element,d.isDehydrated)if(d={element:s,isDehydrated:!1,cache:x.cache,pendingSuspenseBoundaries:x.pendingSuspenseBoundaries,transitions:x.transitions},n.updateQueue.baseState=d,n.memoizedState=d,n.flags&256){a=br(Error(o(423)),n),n=td(e,n,s,i,a);break e}else if(s!==a){a=br(Error(o(424)),n),n=td(e,n,s,i,a);break e}else for(_t=Pn(n.stateNode.containerInfo.firstChild),St=n,De=!0,At=null,i=hf(n,null,s,i),n.child=i;i;)i.flags=i.flags&-3|4096,i=i.sibling;else{if(Hr(),s===a){n=gn(e,n,i);break e}st(e,n,s,i)}n=n.child}return n;case 5:return vf(n),e===null&&gu(n),s=n.type,a=n.pendingProps,d=e!==null?e.memoizedProps:null,x=a.children,su(s,a)?x=null:d!==null&&su(s,d)&&(n.flags|=32),Zf(e,n),st(e,n,x,i),n.child;case 6:return e===null&&gu(n),null;case 13:return nd(e,n,i);case 4:return Eu(n,n.stateNode.containerInfo),s=n.pendingProps,e===null?n.child=Vr(n,null,s,i):st(e,n,s,i),n.child;case 11:return s=n.type,a=n.pendingProps,a=n.elementType===s?a:$t(s,a),Qf(e,n,s,a,i);case 7:return st(e,n,n.pendingProps,i),n.child;case 8:return st(e,n,n.pendingProps.children,i),n.child;case 12:return st(e,n,n.pendingProps.children,i),n.child;case 10:e:{if(s=n.type._context,a=n.pendingProps,d=n.memoizedProps,x=a.value,Re(os,s._currentValue),s._currentValue=x,d!==null)if(jt(d.value,x)){if(d.children===a.children&&!ct.current){n=gn(e,n,i);break e}}else for(d=n.child,d!==null&&(d.return=n);d!==null;){var T=d.dependencies;if(T!==null){x=d.child;for(var R=T.firstContext;R!==null;){if(R.context===s){if(d.tag===1){R=pn(-1,i&-i),R.tag=2;var q=d.updateQueue;if(q!==null){q=q.shared;var oe=q.pending;oe===null?R.next=R:(R.next=oe.next,oe.next=R),q.pending=R}}d.lanes|=i,R=d.alternate,R!==null&&(R.lanes|=i),wu(d.return,i,n),T.lanes|=i;break}R=R.next}}else if(d.tag===10)x=d.type===n.type?null:d.child;else if(d.tag===18){if(x=d.return,x===null)throw Error(o(341));x.lanes|=i,T=x.alternate,T!==null&&(T.lanes|=i),wu(x,i,n),x=d.sibling}else x=d.child;if(x!==null)x.return=d;else for(x=d;x!==null;){if(x===n){x=null;break}if(d=x.sibling,d!==null){d.return=x.return,x=d;break}x=x.return}d=x}st(e,n,a.children,i),n=n.child}return n;case 9:return a=n.type,s=n.pendingProps.children,Ur(n,i),a=Tt(a),s=s(a),n.flags|=1,st(e,n,s,i),n.child;case 14:return s=n.type,a=$t(s,n.pendingProps),a=$t(s.type,a),Gf(e,n,s,a,i);case 15:return Kf(e,n,n.type,n.pendingProps,i);case 17:return s=n.type,a=n.pendingProps,a=n.elementType===s?a:$t(s,a),ys(e,n),n.tag=1,ft(s)?(e=!0,Jo(n)):e=!1,Ur(n,i),Vf(n,s,a),$u(n,s,a,i),Hu(null,n,s,!0,e,i);case 19:return id(e,n,i);case 22:return qf(e,n,i)}throw Error(o(156,n.tag))};function Pd(e,n){return Io(e,n)}function c0(e,n,i,s){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=s,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Rt(e,n,i,s){return new c0(e,n,i,s)}function sa(e){return e=e.prototype,!(!e||!e.isReactComponent)}function f0(e){if(typeof e=="function")return sa(e)?1:0;if(e!=null){if(e=e.$$typeof,e===ee)return 11;if(e===W)return 14}return 2}function Fn(e,n){var i=e.alternate;return i===null?(i=Rt(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 Ps(e,n,i,s,a,d){var x=2;if(s=e,typeof e=="function")sa(e)&&(x=1);else if(typeof e=="string")x=5;else e:switch(e){case V:return cr(i.children,a,d,n);case X:x=8,a|=8;break;case Q:return e=Rt(12,i,n,a|2),e.elementType=Q,e.lanes=d,e;case J:return e=Rt(13,i,n,a),e.elementType=J,e.lanes=d,e;case k:return e=Rt(19,i,n,a),e.elementType=k,e.lanes=d,e;case B:return Is(i,a,d,n);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case te:x=10;break e;case Z:x=9;break e;case ee:x=11;break e;case W:x=14;break e;case H:x=16,s=null;break e}throw Error(o(130,e==null?e:typeof e,""))}return n=Rt(x,i,n,a),n.elementType=e,n.type=s,n.lanes=d,n}function cr(e,n,i,s){return e=Rt(7,e,s,n),e.lanes=i,e}function Is(e,n,i,s){return e=Rt(22,e,s,n),e.elementType=B,e.lanes=i,e.stateNode={isHidden:!1},e}function la(e,n,i){return e=Rt(6,e,null,n),e.lanes=i,e}function ua(e,n,i){return n=Rt(4,e.children!==null?e.children:[],e.key,n),n.lanes=i,n.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},n}function d0(e,n,i,s,a){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=qn(0),this.expirationTimes=qn(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=qn(0),this.identifierPrefix=s,this.onRecoverableError=a,this.mutableSourceEagerHydrationData=null}function aa(e,n,i,s,a,d,x,T,R){return e=new d0(e,n,i,T,R),n===1?(n=1,d===!0&&(n|=8)):n=0,d=Rt(3,null,null,n),e.current=d,d.stateNode=e,d.memoizedState={element:s,isDehydrated:i,cache:null,transitions:null,pendingSuspenseBoundaries:null},_u(d),e}function h0(e,n,i){var s=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(t)}catch(r){console.error(r)}}return t(),ga.exports=N0(),ga.exports}var Bd;function C0(){if(Bd)return $s;Bd=1;var t=Jh();return $s.createRoot=t.createRoot,$s.hydrateRoot=t.hydrateRoot,$s}var M0=C0();async function Ht(t,r){const o=await fetch(t,{...r,headers:{"Content-Type":"application/json",...(r==null?void 0:r.headers)||{}}});if(!o.ok){const l=await o.text();throw new Error(l||o.statusText)}return o.json()}const Vt={health:()=>Ht("/api/health"),settings:()=>Ht("/api/settings"),saveSettings:t=>Ht("/api/settings",{method:"PUT",body:JSON.stringify(t)}),repos:()=>Ht("/api/repos"),index:(t,r=!0)=>Ht("/api/index",{method:"POST",body:JSON.stringify({repo_path:t,incremental:r})}),indexStatus:t=>Ht(`/api/index?repo_path=${encodeURIComponent(t)}`),architecture:t=>Ht(`/api/architecture?repo_path=${encodeURIComponent(t)}`),review:(t,r,o,l=!0)=>Ht("/api/review",{method:"POST",body:JSON.stringify({repo_path:t,base:r,head:o||null,reindex:l,incremental:!0})}),graph:(t,r="full")=>Ht(`/api/graph?repo_path=${encodeURIComponent(t)}&scope=${r}`),prs:(t,r,o="open")=>Ht("/api/prs",{method:"POST",body:JSON.stringify({provider:t,repo:r,state:o})}),residual:t=>Ht("/api/ai/residual",{method:"POST",body:JSON.stringify({review:t})})};function be(t){if(typeof t=="string"||typeof t=="number")return""+t;let r="";if(Array.isArray(t))for(let o=0,l;o{}};function al(){for(var t=0,r=arguments.length,o={},l;t=0&&(l=o.slice(u+1),o=o.slice(0,u)),o&&!r.hasOwnProperty(o))throw new Error("unknown type: "+o);return{type:o,name:l}})}Ys.prototype=al.prototype={constructor:Ys,on:function(t,r){var o=this._,l=I0(t+"",o),u,c=-1,f=l.length;if(arguments.length<2){for(;++c0)for(var o=new Array(u),l=0,u,c;l=0&&(r=t.slice(0,o))!=="xmlns"&&(t=t.slice(o+1)),Wd.hasOwnProperty(r)?{space:Wd[r],local:t}:t}function z0(t){return function(){var r=this.ownerDocument,o=this.namespaceURI;return o===La&&r.documentElement.namespaceURI===La?r.createElement(t):r.createElementNS(o,t)}}function L0(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function ep(t){var r=cl(t);return(r.local?L0:z0)(r)}function R0(){}function Ya(t){return t==null?R0:function(){return this.querySelector(t)}}function j0(t){typeof t!="function"&&(t=Ya(t));for(var r=this._groups,o=r.length,l=new Array(o),u=0;u=_&&(_=L+1);!(U=N[_])&&++_=0;)(f=l[u])&&(c&&f.compareDocumentPosition(c)^4&&c.parentNode.insertBefore(f,c),c=f);return this}function oy(t){t||(t=sy);function r(v,g){return v&&g?t(v.__data__,g.__data__):!v-!g}for(var o=this._groups,l=o.length,u=new Array(l),c=0;cr?1:t>=r?0:NaN}function ly(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this}function uy(){return Array.from(this)}function ay(){for(var t=this._groups,r=0,o=t.length;r1?this.each((r==null?wy:typeof r=="function"?_y:Sy)(t,r,o??"")):ei(this.node(),t)}function ei(t,r){return t.style.getPropertyValue(r)||op(t).getComputedStyle(t,null).getPropertyValue(r)}function ky(t){return function(){delete this[t]}}function Ny(t,r){return function(){this[t]=r}}function Cy(t,r){return function(){var o=r.apply(this,arguments);o==null?delete this[t]:this[t]=o}}function My(t,r){return arguments.length>1?this.each((r==null?ky:typeof r=="function"?Cy:Ny)(t,r)):this.node()[t]}function sp(t){return t.trim().split(/^|\s+/)}function Xa(t){return t.classList||new lp(t)}function lp(t){this._node=t,this._names=sp(t.getAttribute("class")||"")}lp.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 up(t,r){for(var o=Xa(t),l=-1,u=r.length;++l=0&&(o=r.slice(l+1),r=r.slice(0,l)),{type:r,name:o}})}function tv(t){return function(){var r=this.__on;if(r){for(var o=0,l=-1,u=r.length,c;o()=>t;function Ra(t,{sourceEvent:r,subject:o,target:l,identifier:u,active:c,x:f,y:h,dx:p,dy:y,dispatch:m}){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:l,enumerable:!0,configurable:!0},identifier:{value:u,enumerable:!0,configurable:!0},active:{value:c,enumerable:!0,configurable:!0},x:{value:f,enumerable:!0,configurable:!0},y:{value:h,enumerable:!0,configurable:!0},dx:{value:p,enumerable:!0,configurable:!0},dy:{value:y,enumerable:!0,configurable:!0},_:{value:m}})}Ra.prototype.on=function(){var t=this._.on.apply(this._,arguments);return t===this._?this:t};function fv(t){return!t.ctrlKey&&!t.button}function dv(){return this.parentNode}function hv(t,r){return r??{x:t.x,y:t.y}}function pv(){return navigator.maxTouchPoints||"ontouchstart"in this}function pp(){var t=fv,r=dv,o=hv,l=pv,u={},c=al("start","drag","end"),f=0,h,p,y,m,v=0;function g(I){I.on("mousedown.drag",w).filter(l).on("touchstart.drag",N).on("touchmove.drag",E,cv).on("touchend.drag touchcancel.drag",L).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function w(I,U){if(!(m||!t.call(this,I,U))){var D=_(this,r.call(this,I,U),I,U,"mouse");D&&(kt(I.view).on("mousemove.drag",S,no).on("mouseup.drag",M,no),dp(I.view),va(I),y=!1,h=I.clientX,p=I.clientY,D("start",I))}}function S(I){if(Zr(I),!y){var U=I.clientX-h,D=I.clientY-p;y=U*U+D*D>v}u.mouse("drag",I)}function M(I){kt(I.view).on("mousemove.drag mouseup.drag",null),hp(I.view,y),Zr(I),u.mouse("end",I)}function N(I,U){if(t.call(this,I,U)){var D=I.changedTouches,V=r.call(this,I,U),X=D.length,Q,te;for(Q=0;Q>8&15|r>>4&240,r>>4&15|r&240,(r&15)<<4|r&15,1):o===8?Os(r>>24&255,r>>16&255,r>>8&255,(r&255)/255):o===4?Os(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=mv.exec(t))?new mt(r[1],r[2],r[3],1):(r=yv.exec(t))?new mt(r[1]*255/100,r[2]*255/100,r[3]*255/100,1):(r=vv.exec(t))?Os(r[1],r[2],r[3],r[4]):(r=xv.exec(t))?Os(r[1]*255/100,r[2]*255/100,r[3]*255/100,r[4]):(r=wv.exec(t))?qd(r[1],r[2]/100,r[3]/100,1):(r=Sv.exec(t))?qd(r[1],r[2]/100,r[3]/100,r[4]):bd.hasOwnProperty(t)?Qd(bd[t]):t==="transparent"?new mt(NaN,NaN,NaN,0):null}function Qd(t){return new mt(t>>16&255,t>>8&255,t&255,1)}function Os(t,r,o,l){return l<=0&&(t=r=o=NaN),new mt(t,r,o,l)}function kv(t){return t instanceof po||(t=gr(t)),t?(t=t.rgb(),new mt(t.r,t.g,t.b,t.opacity)):new mt}function ja(t,r,o,l){return arguments.length===1?kv(t):new mt(t,r,o,l??1)}function mt(t,r,o,l){this.r=+t,this.g=+r,this.b=+o,this.opacity=+l}Qa(mt,ja,gp(po,{brighter(t){return t=t==null?Zs:Math.pow(Zs,t),new mt(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=t==null?ro:Math.pow(ro,t),new mt(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new mt(hr(this.r),hr(this.g),hr(this.b),Js(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:Gd,formatHex:Gd,formatHex8:Nv,formatRgb:Kd,toString:Kd}));function Gd(){return`#${dr(this.r)}${dr(this.g)}${dr(this.b)}`}function Nv(){return`#${dr(this.r)}${dr(this.g)}${dr(this.b)}${dr((isNaN(this.opacity)?1:this.opacity)*255)}`}function Kd(){const t=Js(this.opacity);return`${t===1?"rgb(":"rgba("}${hr(this.r)}, ${hr(this.g)}, ${hr(this.b)}${t===1?")":`, ${t})`}`}function Js(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function hr(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function dr(t){return t=hr(t),(t<16?"0":"")+t.toString(16)}function qd(t,r,o,l){return l<=0?t=r=o=NaN:o<=0||o>=1?t=r=NaN:r<=0&&(t=NaN),new Ut(t,r,o,l)}function mp(t){if(t instanceof Ut)return new Ut(t.h,t.s,t.l,t.opacity);if(t instanceof po||(t=gr(t)),!t)return new Ut;if(t instanceof Ut)return t;t=t.rgb();var r=t.r/255,o=t.g/255,l=t.b/255,u=Math.min(r,o,l),c=Math.max(r,o,l),f=NaN,h=c-u,p=(c+u)/2;return h?(r===c?f=(o-l)/h+(o0&&p<1?0:f,new Ut(f,h,p,t.opacity)}function Cv(t,r,o,l){return arguments.length===1?mp(t):new Ut(t,r,o,l??1)}function Ut(t,r,o,l){this.h=+t,this.s=+r,this.l=+o,this.opacity=+l}Qa(Ut,Cv,gp(po,{brighter(t){return t=t==null?Zs:Math.pow(Zs,t),new Ut(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=t==null?ro:Math.pow(ro,t),new Ut(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,l=o+(o<.5?o:1-o)*r,u=2*o-l;return new mt(xa(t>=240?t-240:t+120,u,l),xa(t,u,l),xa(t<120?t+240:t-120,u,l),this.opacity)},clamp(){return new Ut(Zd(this.h),Fs(this.s),Fs(this.l),Js(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=Js(this.opacity);return`${t===1?"hsl(":"hsla("}${Zd(this.h)}, ${Fs(this.s)*100}%, ${Fs(this.l)*100}%${t===1?")":`, ${t})`}`}}));function Zd(t){return t=(t||0)%360,t<0?t+360:t}function Fs(t){return Math.max(0,Math.min(1,t||0))}function xa(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 Ga=t=>()=>t;function Mv(t,r){return function(o){return t+o*r}}function Pv(t,r,o){return t=Math.pow(t,o),r=Math.pow(r,o)-t,o=1/o,function(l){return Math.pow(t+l*r,o)}}function Iv(t){return(t=+t)==1?yp:function(r,o){return o-r?Pv(r,o,t):Ga(isNaN(r)?o:r)}}function yp(t,r){var o=r-t;return o?Mv(t,o):Ga(isNaN(t)?r:t)}const el=(function t(r){var o=Iv(r);function l(u,c){var f=o((u=ja(u)).r,(c=ja(c)).r),h=o(u.g,c.g),p=o(u.b,c.b),y=yp(u.opacity,c.opacity);return function(m){return u.r=f(m),u.g=h(m),u.b=p(m),u.opacity=y(m),u+""}}return l.gamma=t,l})(1);function Tv(t,r){r||(r=[]);var o=t?Math.min(r.length,t.length):0,l=r.slice(),u;return function(c){for(u=0;uo&&(c=r.slice(o,c),h[f]?h[f]+=c:h[++f]=c),(l=l[0])===(u=u[0])?h[f]?h[f]+=u:h[++f]=u:(h[++f]=null,p.push({i:f,x:nn(l,u)})),o=wa.lastIndex;return o180?m+=360:m-y>180&&(y+=360),g.push({i:v.push(u(v)+"rotate(",null,l)-2,x:nn(y,m)})):m&&v.push(u(v)+"rotate("+m+l)}function h(y,m,v,g){y!==m?g.push({i:v.push(u(v)+"skewX(",null,l)-2,x:nn(y,m)}):m&&v.push(u(v)+"skewX("+m+l)}function p(y,m,v,g,w,S){if(y!==v||m!==g){var M=w.push(u(w)+"scale(",null,",",null,")");S.push({i:M-4,x:nn(y,v)},{i:M-2,x:nn(m,g)})}else(v!==1||g!==1)&&w.push(u(w)+"scale("+v+","+g+")")}return function(y,m){var v=[],g=[];return y=t(y),m=t(m),c(y.translateX,y.translateY,m.translateX,m.translateY,v,g),f(y.rotate,m.rotate,v,g),h(y.skewX,m.skewX,v,g),p(y.scaleX,y.scaleY,m.scaleX,m.scaleY,v,g),y=m=null,function(w){for(var S=-1,M=g.length,N;++S=0&&t._call.call(void 0,r),t=t._next;--ti}function th(){mr=(nl=oo.now())+fl,ti=Zi=0;try{bv()}finally{ti=0,Xv(),mr=0}}function Yv(){var t=oo.now(),r=t-nl;r>Sp&&(fl-=r,nl=t)}function Xv(){for(var t,r=tl,o,l=1/0;r;)r._call?(l>r._time&&(l=r._time),t=r,r=r._next):(o=r._next,r._next=null,r=t?t._next=o:tl=o);Ji=t,Da(l)}function Da(t){if(!ti){Zi&&(Zi=clearTimeout(Zi));var r=t-mr;r>24?(t<1/0&&(Zi=setTimeout(th,t-oo.now()-fl)),Ki&&(Ki=clearInterval(Ki))):(Ki||(nl=oo.now(),Ki=setInterval(Yv,Sp)),ti=1,_p(th))}}function nh(t,r,o){var l=new rl;return r=r==null?0:+r,l.restart(u=>{l.stop(),t(u+r)},r,o),l}var Qv=al("start","end","cancel","interrupt"),Gv=[],kp=0,rh=1,Oa=2,Qs=3,ih=4,Fa=5,Gs=6;function dl(t,r,o,l,u,c){var f=t.__transition;if(!f)t.__transition={};else if(o in f)return;Kv(t,o,{name:r,index:l,group:u,on:Qv,tween:Gv,time:c.time,delay:c.delay,duration:c.duration,ease:c.ease,timer:null,state:kp})}function qa(t,r){var o=Xt(t,r);if(o.state>kp)throw new Error("too late; already scheduled");return o}function on(t,r){var o=Xt(t,r);if(o.state>Qs)throw new Error("too late; already running");return o}function Xt(t,r){var o=t.__transition;if(!o||!(o=o[r]))throw new Error("transition not found");return o}function Kv(t,r,o){var l=t.__transition,u;l[r]=o,o.timer=Ep(c,0,o.time);function c(y){o.state=rh,o.timer.restart(f,o.delay,o.time),o.delay<=y&&f(y-o.delay)}function f(y){var m,v,g,w;if(o.state!==rh)return p();for(m in l)if(w=l[m],w.name===o.name){if(w.state===Qs)return nh(f);w.state===ih?(w.state=Gs,w.timer.stop(),w.on.call("interrupt",t,t.__data__,w.index,w.group),delete l[m]):+mOa&&l.state=0&&(r=r.slice(0,o)),!r||r==="start"})}function Cx(t,r,o){var l,u,c=Nx(r)?qa:on;return function(){var f=c(this,t),h=f.on;h!==l&&(u=(l=h).copy()).on(r,o),f.on=u}}function Mx(t,r){var o=this._id;return arguments.length<2?Xt(this.node(),o).on.on(t):this.each(Cx(o,t,r))}function Px(t){return function(){var r=this.parentNode;for(var o in this.__transition)if(+o!==t)return;r&&r.removeChild(this)}}function Ix(){return this.on("end.remove",Px(this._id))}function Tx(t){var r=this._name,o=this._id;typeof t!="function"&&(t=Ya(t));for(var l=this._groups,u=l.length,c=new Array(u),f=0;f()=>t;function tw(t,{sourceEvent:r,target:o,transform:l,dispatch:u}){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:l,enumerable:!0,configurable:!0},_:{value:u}})}function vn(t,r,o){this.k=t,this.x=r,this.y=o}vn.prototype={constructor:vn,scale:function(t){return t===1?this:new vn(this.k*t,this.x,this.y)},translate:function(t,r){return t===0&r===0?this:new vn(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 hl=new vn(1,0,0);Pp.prototype=vn.prototype;function Pp(t){for(;!t.__zoom;)if(!(t=t.parentNode))return hl;return t.__zoom}function Sa(t){t.stopImmediatePropagation()}function qi(t){t.preventDefault(),t.stopImmediatePropagation()}function nw(t){return(!t.ctrlKey||t.type==="wheel")&&!t.button}function rw(){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 oh(){return this.__zoom||hl}function iw(t){return-t.deltaY*(t.deltaMode===1?.05:t.deltaMode?1:.002)*(t.ctrlKey?10:1)}function ow(){return navigator.maxTouchPoints||"ontouchstart"in this}function sw(t,r,o){var l=t.invertX(r[0][0])-o[0][0],u=t.invertX(r[1][0])-o[1][0],c=t.invertY(r[0][1])-o[0][1],f=t.invertY(r[1][1])-o[1][1];return t.translate(u>l?(l+u)/2:Math.min(0,l)||Math.max(0,u),f>c?(c+f)/2:Math.min(0,c)||Math.max(0,f))}function Ip(){var t=nw,r=rw,o=sw,l=iw,u=ow,c=[0,1/0],f=[[-1/0,-1/0],[1/0,1/0]],h=250,p=Xs,y=al("start","zoom","end"),m,v,g,w=500,S=150,M=0,N=10;function E(k){k.property("__zoom",oh).on("wheel.zoom",X,{passive:!1}).on("mousedown.zoom",Q).on("dblclick.zoom",te).filter(u).on("touchstart.zoom",Z).on("touchmove.zoom",ee).on("touchend.zoom touchcancel.zoom",J).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}E.transform=function(k,W,H,B){var A=k.selection?k.selection():k;A.property("__zoom",oh),k!==A?U(k,W,H,B):A.interrupt().each(function(){D(this,arguments).event(B).start().zoom(null,typeof W=="function"?W.apply(this,arguments):W).end()})},E.scaleBy=function(k,W,H,B){E.scaleTo(k,function(){var A=this.__zoom.k,j=typeof W=="function"?W.apply(this,arguments):W;return A*j},H,B)},E.scaleTo=function(k,W,H,B){E.transform(k,function(){var A=r.apply(this,arguments),j=this.__zoom,F=H==null?I(A):typeof H=="function"?H.apply(this,arguments):H,C=j.invert(F),z=typeof W=="function"?W.apply(this,arguments):W;return o(_(L(j,z),F,C),A,f)},H,B)},E.translateBy=function(k,W,H,B){E.transform(k,function(){return o(this.__zoom.translate(typeof W=="function"?W.apply(this,arguments):W,typeof H=="function"?H.apply(this,arguments):H),r.apply(this,arguments),f)},null,B)},E.translateTo=function(k,W,H,B,A){E.transform(k,function(){var j=r.apply(this,arguments),F=this.__zoom,C=B==null?I(j):typeof B=="function"?B.apply(this,arguments):B;return o(hl.translate(C[0],C[1]).scale(F.k).translate(typeof W=="function"?-W.apply(this,arguments):-W,typeof H=="function"?-H.apply(this,arguments):-H),j,f)},B,A)};function L(k,W){return W=Math.max(c[0],Math.min(c[1],W)),W===k.k?k:new vn(W,k.x,k.y)}function _(k,W,H){var B=W[0]-H[0]*k.k,A=W[1]-H[1]*k.k;return B===k.x&&A===k.y?k:new vn(k.k,B,A)}function I(k){return[(+k[0][0]+ +k[1][0])/2,(+k[0][1]+ +k[1][1])/2]}function U(k,W,H,B){k.on("start.zoom",function(){D(this,arguments).event(B).start()}).on("interrupt.zoom end.zoom",function(){D(this,arguments).event(B).end()}).tween("zoom",function(){var A=this,j=arguments,F=D(A,j).event(B),C=r.apply(A,j),z=H==null?I(C):typeof H=="function"?H.apply(A,j):H,ne=Math.max(C[1][0]-C[0][0],C[1][1]-C[0][1]),re=A.__zoom,$=typeof W=="function"?W.apply(A,j):W,se=p(re.invert(z).concat(ne/re.k),$.invert(z).concat(ne/$.k));return function(ce){if(ce===1)ce=$;else{var G=se(ce),ue=ne/G[2];ce=new vn(ue,z[0]-G[0]*ue,z[1]-G[1]*ue)}F.zoom(null,ce)}})}function D(k,W,H){return!H&&k.__zooming||new V(k,W)}function V(k,W){this.that=k,this.args=W,this.active=0,this.sourceEvent=null,this.extent=r.apply(k,W),this.taps=0}V.prototype={event:function(k){return k&&(this.sourceEvent=k),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(k,W){return this.mouse&&k!=="mouse"&&(this.mouse[1]=W.invert(this.mouse[0])),this.touch0&&k!=="touch"&&(this.touch0[1]=W.invert(this.touch0[0])),this.touch1&&k!=="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(k){var W=kt(this.that).datum();y.call(k,this.that,new tw(k,{sourceEvent:this.sourceEvent,target:E,transform:this.that.__zoom,dispatch:y}),W)}};function X(k,...W){if(!t.apply(this,arguments))return;var H=D(this,W).event(k),B=this.__zoom,A=Math.max(c[0],Math.min(c[1],B.k*Math.pow(2,l.apply(this,arguments)))),j=Bt(k);if(H.wheel)(H.mouse[0][0]!==j[0]||H.mouse[0][1]!==j[1])&&(H.mouse[1]=B.invert(H.mouse[0]=j)),clearTimeout(H.wheel);else{if(B.k===A)return;H.mouse=[j,B.invert(j)],Ks(this),H.start()}qi(k),H.wheel=setTimeout(F,S),H.zoom("mouse",o(_(L(B,A),H.mouse[0],H.mouse[1]),H.extent,f));function F(){H.wheel=null,H.end()}}function Q(k,...W){if(g||!t.apply(this,arguments))return;var H=k.currentTarget,B=D(this,W,!0).event(k),A=kt(k.view).on("mousemove.zoom",z,!0).on("mouseup.zoom",ne,!0),j=Bt(k,H),F=k.clientX,C=k.clientY;dp(k.view),Sa(k),B.mouse=[j,this.__zoom.invert(j)],Ks(this),B.start();function z(re){if(qi(re),!B.moved){var $=re.clientX-F,se=re.clientY-C;B.moved=$*$+se*se>M}B.event(re).zoom("mouse",o(_(B.that.__zoom,B.mouse[0]=Bt(re,H),B.mouse[1]),B.extent,f))}function ne(re){A.on("mousemove.zoom mouseup.zoom",null),hp(re.view,B.moved),qi(re),B.event(re).end()}}function te(k,...W){if(t.apply(this,arguments)){var H=this.__zoom,B=Bt(k.changedTouches?k.changedTouches[0]:k,this),A=H.invert(B),j=H.k*(k.shiftKey?.5:2),F=o(_(L(H,j),B,A),r.apply(this,W),f);qi(k),h>0?kt(this).transition().duration(h).call(U,F,B,k):kt(this).call(E.transform,F,B,k)}}function Z(k,...W){if(t.apply(this,arguments)){var H=k.touches,B=H.length,A=D(this,W,k.changedTouches.length===B).event(k),j,F,C,z;for(Sa(k),F=0;F`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:l})=>`Couldn't create edge for ${t} handle id: "${t==="source"?o:l}", 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.`},so=[[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]],Tp=["Enter"," ","Escape"],zp={"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 ni;(function(t){t.Strict="strict",t.Loose="loose"})(ni||(ni={}));var pr;(function(t){t.Free="free",t.Vertical="vertical",t.Horizontal="horizontal"})(pr||(pr={}));var lo;(function(t){t.Partial="partial",t.Full="full"})(lo||(lo={}));const Lp={inProgress:!1,isValid:null,from:null,fromHandle:null,fromPosition:null,fromNode:null,to:null,toHandle:null,toPosition:null,toNode:null,pointer:null};var Wn;(function(t){t.Bezier="default",t.Straight="straight",t.Step="step",t.SmoothStep="smoothstep",t.SimpleBezier="simplebezier"})(Wn||(Wn={}));var il;(function(t){t.Arrow="arrow",t.ArrowClosed="arrowclosed"})(il||(il={}));var xe;(function(t){t.Left="left",t.Top="top",t.Right="right",t.Bottom="bottom"})(xe||(xe={}));const sh={[xe.Left]:xe.Right,[xe.Right]:xe.Left,[xe.Top]:xe.Bottom,[xe.Bottom]:xe.Top};function Rp(t){return t===null?null:t?"valid":"invalid"}const jp=t=>!!t&&typeof t=="object"&&"id"in t&&"source"in t&&"target"in t,lw=t=>!!t&&typeof t=="object"&&"id"in t&&"position"in t&&!("source"in t)&&!("target"in t),Ja=t=>!!t&&typeof t=="object"&&"id"in t&&"internals"in t&&!("source"in t)&&!("target"in t),go=(t,r=[0,0])=>{const{width:o,height:l}=Qt(t),u=t.origin??r,c=o*u[0],f=l*u[1];return{x:t.position.x-c,y:t.position.y-f}},uw=(t,r={nodeOrigin:[0,0]})=>{if(t.length===0)return{x:0,y:0,width:0,height:0};let o=!1;const l=t.reduce((u,c)=>{const f=typeof c=="string";let h=!r.nodeLookup&&!f?c:void 0;return r.nodeLookup&&(h=f?r.nodeLookup.get(c):Ja(c)?c:r.nodeLookup.get(c.id)),h?(o=!0,pl(u,ol(h,r.nodeOrigin))):u},{x:1/0,y:1/0,x2:-1/0,y2:-1/0});return o?gl(l):{x:0,y:0,width:0,height:0}},mo=(t,r={})=>{let o={x:1/0,y:1/0,x2:-1/0,y2:-1/0},l=!1;return t.forEach(u=>{(r.filter===void 0||r.filter(u))&&(o=pl(o,ol(u)),l=!0)}),l?gl(o):{x:0,y:0,width:0,height:0}},ec=(t,r,[o,l,u]=[0,0,1],c=!1,f=!1)=>{const h=(r.x-o)/u,p=(r.y-l)/u,y=r.width/u,m=r.height/u,v=[];for(const g of t.values()){const{measured:w,selectable:S=!0,hidden:M=!1}=g;if(f&&!S||M)continue;const N=w.width??g.width??g.initialWidth??0,E=w.height??g.height??g.initialHeight??0,{x:L,y:_}=g.internals.positionAbsolute,I=Op(h,p,y,m,L,_,N,E),U=N*E,D=c&&I>0;(!g.internals.handleBounds||D||I>=U||g.dragging)&&v.push(g)}return v},aw=(t,r)=>{const o=new Set;return t.forEach(l=>{o.add(l.id)}),r.filter(l=>o.has(l.source)||o.has(l.target))};function cw(t,r){const o=new Map,l=r!=null&&r.nodes?new Set(r.nodes.map(u=>u.id)):null;return t.forEach(u=>{let c;if(r!=null&&r.includeHiddenNodes){const{width:f,height:h}=Qt(u);c=f>0&&h>0}else c=!!(u.measured.width&&u.measured.height&&!u.hidden);c&&(!l||l.has(u.id))&&o.set(u.id,u)}),o}async function fw({nodes:t,width:r,height:o,panZoom:l,minZoom:u,maxZoom:c},f){if(t.size===0)return!0;const h=cw(t,f),p=mo(h),y=nc(p,r,o,(f==null?void 0:f.minZoom)??u,(f==null?void 0:f.maxZoom)??c,(f==null?void 0:f.padding)??.1);return await l.setViewport(y,{duration:f==null?void 0:f.duration,ease:f==null?void 0:f.ease,interpolate:f==null?void 0:f.interpolate}),!0}function Ap({nodeId:t,nextPosition:r,nodeLookup:o,nodeOrigin:l=[0,0],nodeExtent:u,onError:c}){const f=o.get(t),h=f.parentId?o.get(f.parentId):void 0,{x:p,y}=h?h.internals.positionAbsolute:{x:0,y:0},m=f.origin??l;let v=f.extent||u;if(f.extent==="parent"&&!f.expandParent)if(!h)c==null||c("005",Yt.error005());else{const{width:w,height:S}=Qt(h);w&&S&&(v=[[p,y],[p+w,y+S]])}else h&&vr(f.extent)&&(v=[[f.extent[0][0]+p,f.extent[0][1]+y],[f.extent[1][0]+p,f.extent[1][1]+y]]);const g=vr(v)?yr(r,v,f.measured):r;return(f.measured.width===void 0||f.measured.height===void 0)&&(c==null||c("015",Yt.error015())),{position:{x:g.x-p+(f.measured.width??0)*m[0],y:g.y-y+(f.measured.height??0)*m[1]},positionAbsolute:g}}async function dw({nodesToRemove:t=[],edgesToRemove:r=[],nodes:o,edges:l,onBeforeDelete:u}){const c=new Set(t.map(g=>g.id)),f=[];for(const g of o){if(g.deletable===!1)continue;const w=c.has(g.id),S=!w&&g.parentId&&f.find(M=>M.id===g.parentId);(w||S)&&f.push(g)}const h=new Set(r.map(g=>g.id)),p=l.filter(g=>g.deletable!==!1),m=aw(f,p);for(const g of p)h.has(g.id)&&!m.find(S=>S.id===g.id)&&m.push(g);if(!u)return{edges:m,nodes:f};const v=await u({nodes:f,edges:m});return typeof v=="boolean"?v?{edges:m,nodes:f}:{edges:[],nodes:[]}:v}const ri=(t,r=0,o=1)=>Math.min(Math.max(t,r),o),yr=(t={x:0,y:0},r,o)=>({x:ri(t.x,r[0][0],r[1][0]-((o==null?void 0:o.width)??0)),y:ri(t.y,r[0][1],r[1][1]-((o==null?void 0:o.height)??0))});function $p(t,r,o){const{width:l,height:u}=Qt(o),{x:c,y:f}=o.internals.positionAbsolute;return yr(t,[[c,f],[c+l,f+u]],r)}const lh=(t,r,o)=>to?-ri(Math.abs(t-o),1,r)/r:0,tc=(t,r,o=15,l=40)=>{const u=lh(t.x,l,r.width-l)*o,c=lh(t.y,l,r.height-l)*o;return[u,c]},pl=(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)}),Ha=({x:t,y:r,width:o,height:l})=>({x:t,y:r,x2:t+o,y2:r+l}),gl=({x:t,y:r,x2:o,y2:l})=>({x:t,y:r,width:o-t,height:l-r}),uo=(t,r=[0,0])=>{var u,c;const{x:o,y:l}=Ja(t)?t.internals.positionAbsolute:go(t,r);return{x:o,y:l,width:((u=t.measured)==null?void 0:u.width)??t.width??t.initialWidth??0,height:((c=t.measured)==null?void 0:c.height)??t.height??t.initialHeight??0}},ol=(t,r=[0,0])=>{var u,c;const{x:o,y:l}=Ja(t)?t.internals.positionAbsolute:go(t,r);return{x:o,y:l,x2:o+(((u=t.measured)==null?void 0:u.width)??t.width??t.initialWidth??0),y2:l+(((c=t.measured)==null?void 0:c.height)??t.height??t.initialHeight??0)}},Dp=(t,r)=>gl(pl(Ha(t),Ha(r))),Op=(t,r,o,l,u,c,f,h)=>{const p=Math.max(0,Math.min(t+o,u+f)-Math.max(t,u)),y=Math.max(0,Math.min(r+l,c+h)-Math.max(r,c));return Math.ceil(p*y)},sl=(t,r)=>Op(t.x,t.y,t.width,t.height,r.x,r.y,r.width,r.height),uh=t=>Wt(t.width)&&Wt(t.height)&&Wt(t.x)&&Wt(t.y),Wt=t=>!isNaN(t)&&isFinite(t),Fp=(t,r)=>(o,l)=>{},yo=(t,r=[1,1])=>({x:r[0]*Math.round(t.x/r[0]),y:r[1]*Math.round(t.y/r[1])}),vo=({x:t,y:r},[o,l,u],c=!1,f=[1,1])=>{const h={x:(t-o)/u,y:(r-l)/u};return c?yo(h,f):h},ii=({x:t,y:r},[o,l,u])=>({x:t*u+o,y:r*u+l});function Kr(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 hw(t,r,o){if(typeof t=="string"||typeof t=="number"){const l=Kr(t,o),u=Kr(t,r);return{top:l,right:u,bottom:l,left:u,x:u*2,y:l*2}}if(typeof t=="object"){const l=Kr(t.top??t.y??0,o),u=Kr(t.bottom??t.y??0,o),c=Kr(t.left??t.x??0,r),f=Kr(t.right??t.x??0,r);return{top:l,right:f,bottom:u,left:c,x:c+f,y:l+u}}return{top:0,right:0,bottom:0,left:0,x:0,y:0}}function pw(t,r,o,l,u,c){const{x:f,y:h}=ii(t,[r,o,l]),{x:p,y}=ii({x:t.x+t.width,y:t.y+t.height},[r,o,l]),m=u-p,v=c-y;return{left:Math.floor(f),top:Math.floor(h),right:Math.floor(m),bottom:Math.floor(v)}}const nc=(t,r,o,l,u,c)=>{const f=hw(c,r,o),h=(r-f.x)/t.width,p=(o-f.y)/t.height,y=Math.min(h,p),m=ri(y,l,u),v=t.x+t.width/2,g=t.y+t.height/2,w=r/2-v*m,S=o/2-g*m,M=pw(t,w,S,m,r,o),N={left:Math.min(M.left-f.left,0),top:Math.min(M.top-f.top,0),right:Math.min(M.right-f.right,0),bottom:Math.min(M.bottom-f.bottom,0)};return{x:w-N.left+N.right,y:S-N.top+N.bottom,zoom:m}},ao=()=>{var t;return typeof navigator<"u"&&((t=navigator==null?void 0:navigator.userAgent)==null?void 0:t.indexOf("Mac"))>=0};function vr(t){return t!=null&&t!=="parent"}function Qt(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 Hp(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 Vp(t,r={width:0,height:0},o,l,u){const c={...t},f=l.get(o);if(f){const h=f.origin||u;c.x+=f.internals.positionAbsolute.x-(r.width??0)*h[0],c.y+=f.internals.positionAbsolute.y-(r.height??0)*h[1]}return c}function ah(t,r){if(t.size!==r.size)return!1;for(const o of t)if(!r.has(o))return!1;return!0}function gw(){let t,r;return{promise:new Promise((l,u)=>{t=l,r=u}),resolve:t,reject:r}}function mw(t){return{...zp,...t||{}}}function to(t,{snapGrid:r=[0,0],snapToGrid:o=!1,transform:l,containerBounds:u}){const{x:c,y:f}=bt(t),h=vo({x:c-((u==null?void 0:u.left)??0),y:f-((u==null?void 0:u.top)??0)},l),{x:p,y}=o?yo(h,r):h;return{xSnapped:p,ySnapped:y,...h}}const rc=t=>({width:t.offsetWidth,height:t.offsetHeight}),Bp=t=>{var r;return((r=t==null?void 0:t.getRootNode)==null?void 0:r.call(t))||(window==null?void 0:window.document)},yw=["INPUT","SELECT","TEXTAREA"];function Up(t){var l,u;const r=((u=(l=t.composedPath)==null?void 0:l.call(t))==null?void 0:u[0])||t.target;return(r==null?void 0:r.nodeType)!==1?!1:yw.includes(r.nodeName)||r.hasAttribute("contenteditable")||!!r.closest(".nokey")}const Wp=t=>"clientX"in t,bt=(t,r)=>{var c,f;const o=Wp(t),l=o?t.clientX:(c=t.touches)==null?void 0:c[0].clientX,u=o?t.clientY:(f=t.touches)==null?void 0:f[0].clientY;return{x:l-((r==null?void 0:r.left)??0),y:u-((r==null?void 0:r.top)??0)}},ch=(t,r,o,l,u)=>{const c=r.querySelectorAll(`.${t}`);return!c||!c.length?null:Array.from(c).map(f=>{const h=f.getBoundingClientRect();return{id:f.getAttribute("data-handleid"),type:t,nodeId:u,position:f.getAttribute("data-handlepos"),x:(h.left-o.left)/l,y:(h.top-o.top)/l,...rc(f)}})};function bp({sourceX:t,sourceY:r,targetX:o,targetY:l,sourceControlX:u,sourceControlY:c,targetControlX:f,targetControlY:h}){const p=t*.125+u*.375+f*.375+o*.125,y=r*.125+c*.375+h*.375+l*.125,m=Math.abs(p-t),v=Math.abs(y-r);return[p,y,m,v]}function Bs(t,r){return t>=0?.5*t:r*25*Math.sqrt(-t)}function fh({pos:t,x1:r,y1:o,x2:l,y2:u,c}){switch(t){case xe.Left:return[r-Bs(r-l,c),o];case xe.Right:return[r+Bs(l-r,c),o];case xe.Top:return[r,o-Bs(o-u,c)];case xe.Bottom:return[r,o+Bs(u-o,c)]}}function Yp({sourceX:t,sourceY:r,sourcePosition:o=xe.Bottom,targetX:l,targetY:u,targetPosition:c=xe.Top,curvature:f=.25}){const[h,p]=fh({pos:o,x1:t,y1:r,x2:l,y2:u,c:f}),[y,m]=fh({pos:c,x1:l,y1:u,x2:t,y2:r,c:f}),[v,g,w,S]=bp({sourceX:t,sourceY:r,targetX:l,targetY:u,sourceControlX:h,sourceControlY:p,targetControlX:y,targetControlY:m});return[`M${t},${r} C${h},${p} ${y},${m} ${l},${u}`,v,g,w,S]}function Xp({sourceX:t,sourceY:r,targetX:o,targetY:l}){const u=Math.abs(o-t)/2,c=o0}const ww=({source:t,sourceHandle:r,target:o,targetHandle:l})=>`xy-edge__${t}${r||""}-${o}${l||""}`,Sw=(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)),_w=(t,r,o={})=>{var c;if(!t.source||!t.target)return(c=o.onError)==null||c.call(o,"006",Yt.error006()),r;const l=o.getEdgeId||ww;let u;return jp(t)?u={...t}:u={...t,id:l(t)},Sw(u,r)?r:(u.sourceHandle===null&&delete u.sourceHandle,u.targetHandle===null&&delete u.targetHandle,r.concat(u))};function Qp({sourceX:t,sourceY:r,targetX:o,targetY:l}){const[u,c,f,h]=Xp({sourceX:t,sourceY:r,targetX:o,targetY:l});return[`M ${t},${r}L ${o},${l}`,u,c,f,h]}const dh={[xe.Left]:{x:-1,y:0},[xe.Right]:{x:1,y:0},[xe.Top]:{x:0,y:-1},[xe.Bottom]:{x:0,y:1}},Ew=({source:t,sourcePosition:r=xe.Bottom,target:o})=>r===xe.Left||r===xe.Right?t.xMath.sqrt(Math.pow(r.x-t.x,2)+Math.pow(r.y-t.y,2));function kw({source:t,sourcePosition:r=xe.Bottom,target:o,targetPosition:l=xe.Top,center:u,offset:c,stepPosition:f}){const h=dh[r],p=dh[l],y={x:t.x+h.x*c,y:t.y+h.y*c},m={x:o.x+p.x*c,y:o.y+p.y*c},v=Ew({source:y,sourcePosition:r,target:m}),g=v.x!==0?"x":"y",w=v[g];let S=[],M,N;const E={x:0,y:0},L={x:0,y:0},[,,_,I]=Xp({sourceX:t.x,sourceY:t.y,targetX:o.x,targetY:o.y});if(h[g]*p[g]===-1){g==="x"?(M=u.x??y.x+(m.x-y.x)*f,N=u.y??(y.y+m.y)/2):(M=u.x??(y.x+m.x)/2,N=u.y??y.y+(m.y-y.y)*f);const X=[{x:M,y:y.y},{x:M,y:m.y}],Q=[{x:y.x,y:N},{x:m.x,y:N}];h[g]===w?S=g==="x"?X:Q:S=g==="x"?Q:X}else{const X=[{x:y.x,y:m.y}],Q=[{x:m.x,y:y.y}];if(g==="x"?S=h.x===w?Q:X:S=h.y===w?X:Q,r===l){const k=Math.abs(t[g]-o[g]);if(k<=c){const W=Math.min(c-1,c-k);h[g]===w?E[g]=(y[g]>t[g]?-1:1)*W:L[g]=(m[g]>o[g]?-1:1)*W}}if(r!==l){const k=g==="x"?"y":"x",W=h[g]===p[k],H=y[k]>m[k],B=y[k]=J?(M=(te.x+Z.x)/2,N=S[0].y):(M=S[0].x,N=(te.y+Z.y)/2)}const U={x:y.x+E.x,y:y.y+E.y},D={x:m.x+L.x,y:m.y+L.y};return[[t,...U.x!==S[0].x||U.y!==S[0].y?[U]:[],...S,...D.x!==S[S.length-1].x||D.y!==S[S.length-1].y?[D]:[],o],M,N,_,I]}function Nw(t,r,o,l){const u=Math.min(hh(t,r)/2,hh(r,o)/2,l),{x:c,y:f}=r;if(t.x===c&&c===o.x||t.y===f&&f===o.y)return`L${c} ${f}`;if(t.y===f){const y=t.xo.id===r):t[0])||null}function Ba(t,r){return t?typeof t=="string"?t:`${r?`${r}__`:""}${Object.keys(t).sort().map(l=>`${l}=${t[l]}`).join("&")}`:""}function Mw(t,{id:r,defaultColor:o,defaultMarkerStart:l,defaultMarkerEnd:u}){const c=new Set;return t.reduce((f,h)=>([h.markerStart||l,h.markerEnd||u].forEach(p=>{if(p&&typeof p=="object"){const y=Ba(p,r);c.has(y)||(f.push({id:y,color:p.color||o,...p}),c.add(y))}}),f),[]).sort((f,h)=>f.id.localeCompare(h.id))}const Gp=1e3,Pw=10,ic={nodeOrigin:[0,0],nodeExtent:so,elevateNodesOnSelect:!0,zIndexMode:"basic",defaults:{}},Iw={...ic,checkEquality:!0};function oc(t,r){const o={...t};for(const l in r)r[l]!==void 0&&(o[l]=r[l]);return o}function Tw(t,r,o){const l=oc(ic,o);for(const u of t.values())if(u.parentId)lc(u,t,r,l);else{const c=go(u,l.nodeOrigin),f=vr(u.extent)?u.extent:l.nodeExtent,h=yr(c,f,Qt(u));u.internals.positionAbsolute=h}}function zw(t,r){if(!t.handles)return t.measured?r==null?void 0:r.internals.handleBounds:void 0;const o=[],l=[];for(const u of t.handles){const c={id:u.id,width:u.width??1,height:u.height??1,nodeId:t.id,x:u.x,y:u.y,position:u.position,type:u.type};u.type==="source"?o.push(c):u.type==="target"&&l.push(c)}return{source:o,target:l}}function sc(t){return t==="manual"}function Ua(t,r,o,l={}){var m,v;const u=oc(Iw,l),c={i:0},f=new Map(r),h=u!=null&&u.elevateNodesOnSelect&&!sc(u.zIndexMode)?Gp:0;let p=t.length>0,y=!1;r.clear(),o.clear();for(const g of t){let w=f.get(g.id);if(u.checkEquality&&g===(w==null?void 0:w.internals.userNode))r.set(g.id,w);else{const S=go(g,u.nodeOrigin),M=vr(g.extent)?g.extent:u.nodeExtent,N=yr(S,M,Qt(g));w={...u.defaults,...g,measured:{width:(m=g.measured)==null?void 0:m.width,height:(v=g.measured)==null?void 0:v.height},internals:{positionAbsolute:N,handleBounds:zw(g,w),z:Kp(g,h,u.zIndexMode),userNode:g}},r.set(g.id,w)}(w.measured===void 0||w.measured.width===void 0||w.measured.height===void 0)&&!w.hidden&&(p=!1),g.parentId&&lc(w,r,o,l,c),y||(y=g.selected??!1)}return{nodesInitialized:p,hasSelectedNodes:y}}function Lw(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 lc(t,r,o,l,u){const{elevateNodesOnSelect:c,nodeOrigin:f,nodeExtent:h,zIndexMode:p}=oc(ic,l),y=t.parentId,m=r.get(y);if(!m){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}Lw(t,o),u&&!m.parentId&&m.internals.rootParentIndex===void 0&&p==="auto"&&(m.internals.rootParentIndex=++u.i,m.internals.z=m.internals.z+u.i*Pw),u&&m.internals.rootParentIndex!==void 0&&(u.i=m.internals.rootParentIndex);const v=c&&!sc(p)?Gp:0,{x:g,y:w,z:S}=Rw(t,m,f,h,v,p),{positionAbsolute:M}=t.internals,N=g!==M.x||w!==M.y;(N||S!==t.internals.z)&&r.set(t.id,{...t,internals:{...t.internals,positionAbsolute:N?{x:g,y:w}:M,z:S}})}function Kp(t,r,o){const l=Wt(t.zIndex)?t.zIndex:0;return sc(o)?l:l+(t.selected?r:0)}function Rw(t,r,o,l,u,c){const{x:f,y:h}=r.internals.positionAbsolute,p=Qt(t),y=go(t,o),m=vr(t.extent)?yr(y,t.extent,p):y;let v=yr({x:f+m.x,y:h+m.y},l,p);t.extent==="parent"&&(v=$p(v,p,r));const g=Kp(t,u,c),w=r.internals.z??0;return{x:v.x,y:v.y,z:w>=g?w+1:g}}function uc(t,r,o,l=[0,0]){var f;const u=[],c=new Map;for(const h of t){const p=r.get(h.parentId);if(!p)continue;const y=((f=c.get(h.parentId))==null?void 0:f.expandedRect)??uo(p),m=Dp(y,h.rect);c.set(h.parentId,{expandedRect:m,parent:p})}return c.size>0&&c.forEach(({expandedRect:h,parent:p},y)=>{var _;const m=p.internals.positionAbsolute,v=Qt(p),g=p.origin??l,w=h.x0||S>0||E||L)&&(u.push({id:y,type:"position",position:{x:p.position.x-w+E,y:p.position.y-S+L}}),(_=o.get(y))==null||_.forEach(I=>{t.some(U=>U.id===I.id)||u.push({id:I.id,type:"position",position:{x:I.position.x+w,y:I.position.y+S}})})),(v.width0){const w=uc(g,r,o,u);y.push(...w)}return{changes:y,updatedInternals:p}}async function Aw({delta:t,panZoom:r,transform:o,translateExtent:l,width:u,height:c}){if(!r||!t.x&&!t.y)return!1;const f=await r.setViewportConstrained({x:o[0]+t.x,y:o[1]+t.y,zoom:o[2]},[[0,0],[u,c]],l);return!!f&&(f.x!==o[0]||f.y!==o[1]||f.k!==o[2])}function yh(t,r,o,l,u,c){let f=u;const h=l.get(f)||new Map;l.set(f,h.set(o,r)),f=`${u}-${t}`;const p=l.get(f)||new Map;if(l.set(f,p.set(o,r)),c){f=`${u}-${t}-${c}`;const y=l.get(f)||new Map;l.set(f,y.set(o,r))}}function qp(t,r,o){t.clear(),r.clear();for(const l of o){const{source:u,target:c,sourceHandle:f=null,targetHandle:h=null}=l,p={edgeId:l.id,source:u,target:c,sourceHandle:f,targetHandle:h},y=`${u}-${f}--${c}-${h}`,m=`${c}-${h}--${u}-${f}`;yh("source",p,m,t,u,f),yh("target",p,y,t,c,h),r.set(l.id,l)}}function Zp(t,r){if(!t.parentId)return!1;const o=r.get(t.parentId);return o?o.selected?!0:Zp(o,r):!1}function vh(t,r,o){var u;let l=t;do{if((u=l==null?void 0:l.matches)!=null&&u.call(l,r))return!0;if(l===o)return!1;l=l==null?void 0:l.parentElement}while(l);return!1}function $w(t,r,o,l){const u=new Map;for(const[c,f]of t)if((f.selected||f.id===l)&&(!f.parentId||!Zp(f,t))&&(f.draggable||r&&typeof f.draggable>"u")){const h=t.get(c);h&&u.set(c,{id:c,position:h.position||{x:0,y:0},distance:{x:o.x-h.internals.positionAbsolute.x,y:o.y-h.internals.positionAbsolute.y},extent:h.extent,parentId:h.parentId,origin:h.origin,expandParent:h.expandParent,internals:{positionAbsolute:h.internals.positionAbsolute||{x:0,y:0}},measured:{width:h.measured.width??0,height:h.measured.height??0}})}return u}function _a({nodeId:t,dragItems:r,nodeLookup:o,dragging:l=!0}){var f,h,p;const u=[];for(const[y,m]of r){const v=(f=o.get(y))==null?void 0:f.internals.userNode;v&&u.push({...v,position:m.position,dragging:l})}if(!t)return[u[0],u];const c=(h=o.get(t))==null?void 0:h.internals.userNode;return[c?{...c,position:((p=r.get(t))==null?void 0:p.position)||c.position,dragging:l}:u[0],u]}function Dw({dragItems:t,snapGrid:r,x:o,y:l}){const u=t.values().next().value;if(!u)return null;const c={x:o-u.distance.x,y:l-u.distance.y},f=yo(c,r);return{x:f.x-c.x,y:f.y-c.y}}function Ow({onNodeMouseDown:t,getStoreItems:r,onDragStart:o,onDrag:l,onDragStop:u}){let c={x:null,y:null},f=0,h=new Map,p=!1,y={x:0,y:0},m=null,v=!1,g=null,w=!1,S=!1,M=null;function N({noDragClassName:L,handleSelector:_,domNode:I,isSelectable:U,nodeId:D,nodeClickDistance:V=0}){g=kt(I);function X({x:ee,y:J}){const{nodeLookup:k,nodeExtent:W,snapGrid:H,snapToGrid:B,nodeOrigin:A,onNodeDrag:j,onSelectionDrag:F,onError:C,updateNodePositions:z}=r();c={x:ee,y:J};let ne=!1;const re=h.size>1,$=re&&W?Ha(mo(h)):null,se=re&&B?Dw({dragItems:h,snapGrid:H,x:ee,y:J}):null;for(const[ce,G]of h){if(!k.has(ce))continue;let ue={x:ee-G.distance.x,y:J-G.distance.y};B&&(ue=se?{x:Math.round(ue.x+se.x),y:Math.round(ue.y+se.y)}:yo(ue,H));let pe=null;if(re&&W&&!G.extent&&$){const{positionAbsolute:me}=G.internals,ke=me.x-$.x+W[0][0],Ce=me.x+G.measured.width-$.x2+W[1][0],Me=me.y-$.y+W[0][1],Le=me.y+G.measured.height-$.y2+W[1][1];pe=[[ke,Me],[Ce,Le]]}const{position:we,positionAbsolute:ve}=Ap({nodeId:ce,nextPosition:ue,nodeLookup:k,nodeExtent:pe||W,nodeOrigin:A,onError:C});ne=ne||G.position.x!==we.x||G.position.y!==we.y,G.position=we,G.internals.positionAbsolute=ve}if(S=S||ne,!!ne&&(z(h,!0),M&&(l||j||!D&&F))){const[ce,G]=_a({nodeId:D,dragItems:h,nodeLookup:k});l==null||l(M,h,ce,G),j==null||j(M,ce,G),D||F==null||F(M,G)}}async function Q(){if(!m)return;const{transform:ee,panBy:J,autoPanSpeed:k,autoPanOnNodeDrag:W}=r();if(!W){p=!1,cancelAnimationFrame(f);return}const[H,B]=tc(y,m,k);(H!==0||B!==0)&&(c.x=(c.x??0)-H/ee[2],c.y=(c.y??0)-B/ee[2],await J({x:H,y:B})&&X(c)),f=requestAnimationFrame(Q)}function te(ee){var re;const{nodeLookup:J,multiSelectionActive:k,nodesDraggable:W,transform:H,snapGrid:B,snapToGrid:A,selectNodesOnDrag:j,onNodeDragStart:F,onSelectionDragStart:C,unselectNodesAndEdges:z}=r();v=!0,(!j||!U)&&!k&&D&&((re=J.get(D))!=null&&re.selected||z()),U&&j&&D&&(t==null||t(D));const ne=to(ee.sourceEvent,{transform:H,snapGrid:B,snapToGrid:A,containerBounds:m});if(c=ne,h=$w(J,W,ne,D),h.size>0&&(o||F||!D&&C)){const[$,se]=_a({nodeId:D,dragItems:h,nodeLookup:J});o==null||o(ee.sourceEvent,h,$,se),F==null||F(ee.sourceEvent,$,se),D||C==null||C(ee.sourceEvent,se)}}const Z=pp().clickDistance(V).on("start",ee=>{const{domNode:J,nodeDragThreshold:k,transform:W,snapGrid:H,snapToGrid:B}=r();m=(J==null?void 0:J.getBoundingClientRect())||null,w=!1,S=!1,M=ee.sourceEvent,k===0&&te(ee),c=to(ee.sourceEvent,{transform:W,snapGrid:H,snapToGrid:B,containerBounds:m}),y=bt(ee.sourceEvent,m)}).on("drag",ee=>{const{autoPanOnNodeDrag:J,transform:k,snapGrid:W,snapToGrid:H,nodeDragThreshold:B,nodeLookup:A}=r(),j=to(ee.sourceEvent,{transform:k,snapGrid:W,snapToGrid:H,containerBounds:m});if(M=ee.sourceEvent,(ee.sourceEvent.type==="touchmove"&&ee.sourceEvent.touches.length>1||D&&!A.has(D))&&(w=!0),!w){if(!p&&J&&v&&(p=!0,Q()),!v){const F=bt(ee.sourceEvent,m),C=F.x-y.x,z=F.y-y.y;Math.sqrt(C*C+z*z)>B&&te(ee)}(c.x!==j.xSnapped||c.y!==j.ySnapped)&&h&&v&&(y=bt(ee.sourceEvent,m),X(j))}}).on("end",ee=>{if(!v||w){w&&h.size>0&&r().updateNodePositions(h,!1);return}if(p=!1,v=!1,cancelAnimationFrame(f),h.size>0){const{nodeLookup:J,updateNodePositions:k,onNodeDragStop:W,onSelectionDragStop:H}=r();if(S&&(k(h,!1),S=!1),u||W||!D&&H){const[B,A]=_a({nodeId:D,dragItems:h,nodeLookup:J,dragging:!1});u==null||u(ee.sourceEvent,h,B,A),W==null||W(ee.sourceEvent,B,A),D||H==null||H(ee.sourceEvent,A)}}}).filter(ee=>{const J=ee.target;return!ee.button&&(!L||!vh(J,`.${L}`,I))&&(!_||vh(J,_,I))});g.call(Z)}function E(){g==null||g.on(".drag",null)}return{update:N,destroy:E}}function Fw(t,r,o){const l=[],u={x:t.x-o,y:t.y-o,width:o*2,height:o*2};for(const c of r.values())sl(u,uo(c))>0&&l.push(c);return l}const Hw=250;function Vw(t,r,o,l){var h,p;let u=[],c=1/0;const f=Fw(t,o,r+Hw);for(const y of f){const m=[...((h=y.internals.handleBounds)==null?void 0:h.source)??[],...((p=y.internals.handleBounds)==null?void 0:p.target)??[]];for(const v of m){if(l.nodeId===v.nodeId&&l.type===v.type&&l.id===v.id)continue;const{x:g,y:w}=xr(y,v,v.position,!0),S=Math.sqrt(Math.pow(g-t.x,2)+Math.pow(w-t.y,2));S>r||(S1){const y=l.type==="source"?"target":"source";return u.find(m=>m.type===y)??u[0]}return u[0]}function Jp(t,r,o,l,u,c=!1){var y,m,v;const f=l.get(t);if(!f)return null;const h=u==="strict"?(y=f.internals.handleBounds)==null?void 0:y[r]:[...((m=f.internals.handleBounds)==null?void 0:m.source)??[],...((v=f.internals.handleBounds)==null?void 0:v.target)??[]],p=(o?h==null?void 0:h.find(g=>g.id===o):h==null?void 0:h[0])??null;return p&&c?{...p,...xr(f,p,p.position,!0)}:p}function eg(t,r){return t||(r!=null&&r.classList.contains("target")?"target":r!=null&&r.classList.contains("source")?"source":null)}function Bw(t,r){let o=null;return r?o=!0:t&&!r&&(o=!1),o}const tg=()=>!0;function Uw(t,{connectionMode:r,connectionRadius:o,handleId:l,nodeId:u,edgeUpdaterType:c,isTarget:f,domNode:h,nodeLookup:p,lib:y,autoPanOnConnect:m,flowId:v,panBy:g,cancelConnection:w,onConnectStart:S,onConnect:M,onConnectEnd:N,isValidConnection:E=tg,onReconnectEnd:L,updateConnection:_,getTransform:I,getFromHandle:U,autoPanSpeed:D,dragThreshold:V=1,handleDomNode:X}){const Q=Bp(t.target);let te=0,Z;const{x:ee,y:J}=bt(t),k=eg(c,X),W=h==null?void 0:h.getBoundingClientRect();let H=!1;if(!W||!k)return;const B=Jp(u,k,l,p,r);if(!B)return;let A=bt(t,W),j=!1,F=null,C=!1,z=null;function ne(){if(!m||!W)return;const[we,ve]=tc(A,W,D);g({x:we,y:ve}),te=requestAnimationFrame(ne)}const re={...B,nodeId:u,type:k,position:B.position},$=p.get(u);let ce={inProgress:!0,isValid:null,from:xr($,re,xe.Left,!0),fromHandle:re,fromPosition:re.position,fromNode:$,to:A,toHandle:null,toPosition:sh[re.position],toNode:null,pointer:A};function G(){H=!0,_(ce),S==null||S(t,{nodeId:u,handleId:l,handleType:k})}V===0&&G();function ue(we){if(!H){const{x:Le,y:ot}=bt(we),ut=Le-ee,Je=ot-J;if(!(ut*ut+Je*Je>V*V))return;G()}if(!U()||!re){pe(we);return}const ve=I();A=bt(we,W),Z=Vw(vo(A,ve,!1,[1,1]),o,p,re),j||(ne(),j=!0);const me=ng(we,{handle:Z,connectionMode:r,fromNodeId:u,fromHandleId:l,fromType:f?"target":"source",isValidConnection:E,doc:Q,lib:y,flowId:v,nodeLookup:p});z=me.handleDomNode,F=me.connection,C=Bw(!!Z,me.isValid);const ke=p.get(u),Ce=ke?xr(ke,re,xe.Left,!0):ce.from,Me={...ce,from:Ce,isValid:C,to:me.toHandle&&C?ii({x:me.toHandle.x,y:me.toHandle.y},ve):A,toHandle:me.toHandle,toPosition:C&&me.toHandle?me.toHandle.position:sh[re.position],toNode:me.toHandle?p.get(me.toHandle.nodeId):null,pointer:A};_(Me),ce=Me}function pe(we){if(!("touches"in we&&we.touches.length>0)){if(H){(Z||z)&&F&&C&&(M==null||M(F));const{inProgress:ve,...me}=ce,ke={...me,toPosition:ce.toHandle?ce.toPosition:null};N==null||N(we,ke),c&&(L==null||L(we,ke))}w(),cancelAnimationFrame(te),j=!1,C=!1,F=null,z=null,Q.removeEventListener("mousemove",ue),Q.removeEventListener("mouseup",pe),Q.removeEventListener("touchmove",ue),Q.removeEventListener("touchend",pe)}}Q.addEventListener("mousemove",ue),Q.addEventListener("mouseup",pe),Q.addEventListener("touchmove",ue),Q.addEventListener("touchend",pe)}function ng(t,{handle:r,connectionMode:o,fromNodeId:l,fromHandleId:u,fromType:c,doc:f,lib:h,flowId:p,isValidConnection:y=tg,nodeLookup:m}){const v=c==="target",g=r?f.querySelector(`.${h}-flow__handle[data-id="${p}-${r==null?void 0:r.nodeId}-${r==null?void 0:r.id}-${r==null?void 0:r.type}"]`):null,{x:w,y:S}=bt(t),M=f.elementFromPoint(w,S),N=M!=null&&M.classList.contains(`${h}-flow__handle`)?M:g,E={handleDomNode:N,isValid:!1,connection:null,toHandle:null};if(N){const L=eg(void 0,N),_=N.getAttribute("data-nodeid"),I=N.getAttribute("data-handleid"),U=N.classList.contains("connectable"),D=N.classList.contains("connectableend");if(!_||!L)return E;const V={source:v?_:l,sourceHandle:v?I:u,target:v?l:_,targetHandle:v?u:I};E.connection=V;const Q=U&&D&&(o===ni.Strict?v&&L==="source"||!v&&L==="target":_!==l||I!==u);E.isValid=Q&&y(V),E.toHandle=Jp(_,L,I,m,o,!0)}return E}const Wa={onPointerDown:Uw,isValid:ng};function Ww({domNode:t,panZoom:r,getTransform:o,getViewScale:l}){const u=kt(t);function c({translateExtent:h,width:p,height:y,zoomStep:m=1,pannable:v=!0,zoomable:g=!0,inversePan:w=!1}){const S=_=>{if(_.sourceEvent.type!=="wheel"||!r)return;const I=o(),U=_.sourceEvent.ctrlKey&&ao()?10:1,D=-_.sourceEvent.deltaY*(_.sourceEvent.deltaMode===1?.05:_.sourceEvent.deltaMode?1:.002)*m,V=I[2]*Math.pow(2,D*U);r.scaleTo(V)};let M=[0,0];const N=_=>{(_.sourceEvent.type==="mousedown"||_.sourceEvent.type==="touchstart")&&(M=[_.sourceEvent.clientX??_.sourceEvent.touches[0].clientX,_.sourceEvent.clientY??_.sourceEvent.touches[0].clientY])},E=_=>{const I=o();if(_.sourceEvent.type!=="mousemove"&&_.sourceEvent.type!=="touchmove"||!r)return;const U=[_.sourceEvent.clientX??_.sourceEvent.touches[0].clientX,_.sourceEvent.clientY??_.sourceEvent.touches[0].clientY],D=[U[0]-M[0],U[1]-M[1]];M=U;const V=l()*Math.max(I[2],Math.log(I[2]))*(w?-1:1),X={x:I[0]-D[0]*V,y:I[1]-D[1]*V},Q=[[0,0],[p,y]];r.setViewportConstrained({x:X.x,y:X.y,zoom:I[2]},Q,h)},L=Ip().on("start",N).on("zoom",v?E:null).on("zoom.wheel",g?S:null);u.call(L,{})}function f(){u.on("zoom",null)}return{update:c,destroy:f,pointer:Bt}}const ml=t=>({x:t.x,y:t.y,zoom:t.k}),Ea=({x:t,y:r,zoom:o})=>hl.translate(t,r).scale(o),Un=(t,r)=>t.target.closest(`.${r}`),rg=(t,r)=>r===2&&Array.isArray(t)&&t.includes(2),bw=t=>((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2,ka=(t,r=0,o=bw,l=()=>{})=>{const u=typeof r=="number"&&r>0;return u||l(),u?t.transition().duration(r).ease(o).on("end",l):t},ig=t=>{const r=t.ctrlKey&&ao()?10:1;return-t.deltaY*(t.deltaMode===1?.05:t.deltaMode?1:.002)*r};function Yw({zoomPanValues:t,noWheelClassName:r,d3Selection:o,d3Zoom:l,panOnScrollMode:u,panOnScrollSpeed:c,zoomOnPinch:f,onPanZoomStart:h,onPanZoom:p,onPanZoomEnd:y}){return m=>{if(Un(m,r))return m.ctrlKey&&m.preventDefault(),!1;m.preventDefault(),m.stopImmediatePropagation();const v=o.property("__zoom").k||1;if(m.ctrlKey&&f){const N=Bt(m),E=ig(m),L=v*Math.pow(2,E);l.scaleTo(o,L,N,m);return}const g=m.deltaMode===1?20:1;let w=u===pr.Vertical?0:m.deltaX*g,S=u===pr.Horizontal?0:m.deltaY*g;!ao()&&m.shiftKey&&u!==pr.Vertical&&(w=m.deltaY*g,S=0),l.translateBy(o,-(w/v)*c,-(S/v)*c,{internal:!0});const M=ml(o.property("__zoom"));clearTimeout(t.panScrollTimeout),t.isPanScrolling?p==null||p(m,M):(t.isPanScrolling=!0,h==null||h(m,M)),t.panScrollTimeout=setTimeout(()=>{y==null||y(m,M),t.isPanScrolling=!1},150)}}function Xw({noWheelClassName:t,preventScrolling:r,d3ZoomHandler:o}){return function(l,u){const c=l.type==="wheel",f=!r&&c&&!l.ctrlKey,h=Un(l,t);if(l.ctrlKey&&c&&h&&l.preventDefault(),f||h)return null;l.preventDefault(),o.call(this,l,u)}}function Qw({zoomPanValues:t,onDraggingChange:r,onPanZoomStart:o}){return l=>{var c,f,h;if((c=l.sourceEvent)!=null&&c.internal)return;const u=ml(l.transform);t.mouseButton=((f=l.sourceEvent)==null?void 0:f.button)||0,t.isZoomingOrPanning=!0,t.prevViewport=u,((h=l.sourceEvent)==null?void 0:h.type)==="mousedown"&&r(!0),o&&(o==null||o(l.sourceEvent,u))}}function Gw({zoomPanValues:t,panOnDrag:r,onPaneContextMenu:o,onTransformChange:l,onPanZoom:u}){return c=>{var f,h;t.usedRightMouseButton=!!(o&&rg(r,t.mouseButton??0)),(f=c.sourceEvent)!=null&&f.sync||l([c.transform.x,c.transform.y,c.transform.k]),u&&!((h=c.sourceEvent)!=null&&h.internal)&&(u==null||u(c.sourceEvent,ml(c.transform)))}}function Kw({zoomPanValues:t,panOnDrag:r,panOnScroll:o,onDraggingChange:l,onPanZoomEnd:u,onPaneContextMenu:c}){return f=>{var h;if(!((h=f.sourceEvent)!=null&&h.internal)&&(t.isZoomingOrPanning=!1,c&&rg(r,t.mouseButton??0)&&!t.usedRightMouseButton&&f.sourceEvent&&c(f.sourceEvent),t.usedRightMouseButton=!1,l(!1),u)){const p=ml(f.transform);t.prevViewport=p,clearTimeout(t.timerId),t.timerId=setTimeout(()=>{u==null||u(f.sourceEvent,p)},o?150:0)}}}function qw({panActivationKeyPressed:t,zoomActivationKeyPressed:r,zoomOnScroll:o,zoomOnPinch:l,panOnDrag:u,panOnScroll:c,zoomOnDoubleClick:f,userSelectionActive:h,noWheelClassName:p,noPanClassName:y,lib:m,connectionInProgress:v}){return g=>{var E;const w=r||o,S=l&&g.ctrlKey,M=g.type==="wheel";if(g.button===1&&g.type==="mousedown"&&(Un(g,`${m}-flow__node`)||Un(g,`${m}-flow__edge`)||Un(g,`${m}-flow__selection`)||Un(g,`${m}-flow__nodesselection`)))return!0;if(!u&&!w&&!c&&!f&&!l||h||v&&!M||Un(g,p)&&M||Un(g,y)&&(!M||c&&M&&!r)||!l&&g.ctrlKey&&M)return!1;if(!l&&g.type==="touchstart"&&((E=g.touches)==null?void 0:E.length)>1)return g.preventDefault(),!1;if(!w&&!c&&!S&&M||!u&&(g.type==="mousedown"||g.type==="touchstart")||Array.isArray(u)&&!u.includes(g.button)&&g.type==="mousedown")return!1;const N=Array.isArray(u)&&u.includes(g.button)||!g.button||g.button<=1;return(!g.ctrlKey||M||t)&&N}}function Zw({domNode:t,minZoom:r,maxZoom:o,translateExtent:l,viewport:u,onPanZoom:c,onPanZoomStart:f,onPanZoomEnd:h,onDraggingChange:p}){const y={isZoomingOrPanning:!1,usedRightMouseButton:!1,prevViewport:{},mouseButton:0,timerId:void 0,panScrollTimeout:void 0,isPanScrolling:!1},m=t.getBoundingClientRect();let v=[[0,0],[m.width,m.height]];const g=typeof ResizeObserver<"u"?new ResizeObserver(J=>{const k=J[0];k&&(v=[[0,0],[k.contentRect.width,k.contentRect.height]])}):null;g==null||g.observe(t);const w=Ip().extent(()=>v).scaleExtent([r,o]).translateExtent(l),S=kt(t).call(w);I({x:u.x,y:u.y,zoom:ri(u.zoom,r,o)},[[0,0],[m.width,m.height]],l);const M=S.on("wheel.zoom"),N=S.on("dblclick.zoom");w.wheelDelta(ig);async function E(J,k){return S?new Promise(W=>{w==null||w.interpolate((k==null?void 0:k.interpolate)==="linear"?eo:Xs).transform(ka(S,k==null?void 0:k.duration,k==null?void 0:k.ease,()=>W(!0)),J)}):!1}function L({noWheelClassName:J,noPanClassName:k,onPaneContextMenu:W,userSelectionActive:H,panOnScroll:B,panOnDrag:A,panOnScrollMode:j,panOnScrollSpeed:F,preventScrolling:C,zoomOnPinch:z,zoomOnScroll:ne,zoomOnDoubleClick:re,panActivationKeyPressed:$=!1,zoomActivationKeyPressed:se,lib:ce,onTransformChange:G,connectionInProgress:ue,paneClickDistance:pe,selectionOnDrag:we}){H&&!y.isZoomingOrPanning&&_();const ve=B&&!se&&!H;w.clickDistance(we?1/0:!Wt(pe)||pe<0?0:pe);const me=ve?Yw({zoomPanValues:y,noWheelClassName:J,d3Selection:S,d3Zoom:w,panOnScrollMode:j,panOnScrollSpeed:F,zoomOnPinch:z,onPanZoomStart:f,onPanZoom:c,onPanZoomEnd:h}):Xw({noWheelClassName:J,preventScrolling:C,d3ZoomHandler:M});S.on("wheel.zoom",me,{passive:!1});const ke=Qw({zoomPanValues:y,onDraggingChange:p,onPanZoomStart:f});w.on("start",ke);const Ce=Gw({zoomPanValues:y,panOnDrag:A,onPaneContextMenu:!!W,onPanZoom:c,onTransformChange:G});w.on("zoom",Ce);const Me=Kw({zoomPanValues:y,panOnDrag:A,panOnScroll:B,onPaneContextMenu:W,onPanZoomEnd:h,onDraggingChange:p});w.on("end",Me);const Le=qw({panActivationKeyPressed:$,zoomActivationKeyPressed:se,panOnDrag:A,zoomOnScroll:ne,panOnScroll:B,zoomOnDoubleClick:re,zoomOnPinch:z,userSelectionActive:H,noPanClassName:k,noWheelClassName:J,lib:ce,connectionInProgress:ue});w.filter(Le),re?S.on("dblclick.zoom",N):S.on("dblclick.zoom",null)}function _(){w.on("zoom",null)}async function I(J,k,W){const H=Ea(J),B=w==null?void 0:w.constrain()(H,k,W);return B&&await E(B),B}async function U(J,k){const W=Ea(J);return await E(W,k),W}function D(J){if(S){const k=Ea(J),W=S.property("__zoom");(W.k!==J.zoom||W.x!==J.x||W.y!==J.y)&&(w==null||w.transform(S,k,null,{sync:!0}))}}function V(){const J=S?Pp(S.node()):{x:0,y:0,k:1};return{x:J.x,y:J.y,zoom:J.k}}async function X(J,k){return S?new Promise(W=>{w==null||w.interpolate((k==null?void 0:k.interpolate)==="linear"?eo:Xs).scaleTo(ka(S,k==null?void 0:k.duration,k==null?void 0:k.ease,()=>W(!0)),J)}):!1}async function Q(J,k){return S?new Promise(W=>{w==null||w.interpolate((k==null?void 0:k.interpolate)==="linear"?eo:Xs).scaleBy(ka(S,k==null?void 0:k.duration,k==null?void 0:k.ease,()=>W(!0)),J)}):!1}function te(J){w==null||w.scaleExtent(J)}function Z(J){w==null||w.translateExtent(J)}function ee(J){const k=!Wt(J)||J<0?0:J;w==null||w.clickDistance(k)}return{update:L,destroy:_,setViewport:U,setViewportConstrained:I,getViewport:V,scaleTo:X,scaleBy:Q,setScaleExtent:te,setTranslateExtent:Z,syncViewport:D,setClickDistance:ee}}var oi;(function(t){t.Line="line",t.Handle="handle"})(oi||(oi={}));function Jw({width:t,prevWidth:r,height:o,prevHeight:l,affectsX:u,affectsY:c}){const f=t-r,h=o-l,p=[f>0?1:f<0?-1:0,h>0?1:h<0?-1:0];return f&&u&&(p[0]=p[0]*-1),h&&c&&(p[1]=p[1]*-1),p}function xh(t){const r=t.includes("right")||t.includes("left"),o=t.includes("bottom")||t.includes("top"),l=t.includes("left"),u=t.includes("top");return{isHorizontal:r,isVertical:o,affectsX:l,affectsY:u}}function Vn(t,r){return Math.max(0,r-t)}function Bn(t,r){return Math.max(0,t-r)}function Us(t,r,o){return Math.max(0,r-t,t-o)}function wh(t,r){return t?!r:r}function e1(t,r,o,l,u,c,f,h){let{affectsX:p,affectsY:y}=r;const{isHorizontal:m,isVertical:v}=r,g=m&&v,{xSnapped:w,ySnapped:S}=o,{minWidth:M,maxWidth:N,minHeight:E,maxHeight:L}=l,{x:_,y:I,width:U,height:D,aspectRatio:V}=t;let X=Math.floor(m?w-t.pointerX:0),Q=Math.floor(v?S-t.pointerY:0);const te=U+(p?-X:X),Z=D+(y?-Q:Q),ee=-c[0]*U,J=-c[1]*D;let k=Us(te,M,N),W=Us(Z,E,L);if(f){let A=0,j=0;p&&X<0?A=Vn(_+X+ee,f[0][0]):!p&&X>0&&(A=Bn(_+te+ee,f[1][0])),y&&Q<0?j=Vn(I+Q+J,f[0][1]):!y&&Q>0&&(j=Bn(I+Z+J,f[1][1])),k=Math.max(k,A),W=Math.max(W,j)}if(h){let A=0,j=0;p&&X>0?A=Bn(_+X,h[0][0]):!p&&X<0&&(A=Vn(_+te,h[1][0])),y&&Q>0?j=Bn(I+Q,h[0][1]):!y&&Q<0&&(j=Vn(I+Z,h[1][1])),k=Math.max(k,A),W=Math.max(W,j)}if(u){if(m){const A=Us(te/V,E,L)*V;if(k=Math.max(k,A),f){let j=0;!p&&!y||p&&!y&&g?j=Bn(I+J+te/V,f[1][1])*V:j=Vn(I+J+(p?X:-X)/V,f[0][1])*V,k=Math.max(k,j)}if(h){let j=0;!p&&!y||p&&!y&&g?j=Vn(I+te/V,h[1][1])*V:j=Bn(I+(p?X:-X)/V,h[0][1])*V,k=Math.max(k,j)}}if(v){const A=Us(Z*V,M,N)/V;if(W=Math.max(W,A),f){let j=0;!p&&!y||y&&!p&&g?j=Bn(_+Z*V+ee,f[1][0])/V:j=Vn(_+(y?Q:-Q)*V+ee,f[0][0])/V,W=Math.max(W,j)}if(h){let j=0;!p&&!y||y&&!p&&g?j=Vn(_+Z*V,h[1][0])/V:j=Bn(_+(y?Q:-Q)*V,h[0][0])/V,W=Math.max(W,j)}}}Q=Q+(Q<0?W:-W),X=X+(X<0?k:-k),u&&(g?te>Z*V?Q=(wh(p,y)?-X:X)/V:X=(wh(p,y)?-Q:Q)*V:m?(Q=X/V,y=p):(X=Q*V,p=y));const H=p?_+X:_,B=y?I+Q:I;return{width:U+(p?-X:X),height:D+(y?-Q:Q),x:c[0]*X*(p?-1:1)+H,y:c[1]*Q*(y?-1:1)+B}}const og={width:0,height:0,x:0,y:0},t1={...og,pointerX:0,pointerY:0,aspectRatio:1};function n1(t,r,o){const l=r.position.x+t.position.x,u=r.position.y+t.position.y,c=t.measured.width??0,f=t.measured.height??0,h=o[0]*c,p=o[1]*f;return[[l-h,u-p],[l+c-h,u+f-p]]}function r1({domNode:t,nodeId:r,getStoreItems:o,onChange:l,onEnd:u}){const c=kt(t);let f={controlDirection:xh("bottom-right"),boundaries:{minWidth:0,minHeight:0,maxWidth:Number.MAX_VALUE,maxHeight:Number.MAX_VALUE},resizeDirection:void 0,keepAspectRatio:!1};function h({controlPosition:y,boundaries:m,keepAspectRatio:v,resizeDirection:g,onResizeStart:w,onResize:S,onResizeEnd:M,shouldResize:N}){let E={...og},L={...t1};f={boundaries:m,resizeDirection:g,keepAspectRatio:v,controlDirection:xh(y)};let _,I=null,U=[],D,V,X,Q=!1;const te=pp().on("start",Z=>{const{nodeLookup:ee,transform:J,snapGrid:k,snapToGrid:W,nodeOrigin:H,paneDomNode:B}=o();if(_=ee.get(r),!_)return;I=(B==null?void 0:B.getBoundingClientRect())??null;const{xSnapped:A,ySnapped:j}=to(Z.sourceEvent,{transform:J,snapGrid:k,snapToGrid:W,containerBounds:I});E={width:_.measured.width??0,height:_.measured.height??0,x:_.position.x??0,y:_.position.y??0},L={...E,pointerX:A,pointerY:j,aspectRatio:E.width/E.height},D=void 0,V=vr(_.extent)?_.extent:void 0,_.parentId&&(_.extent==="parent"||_.expandParent)&&(D=ee.get(_.parentId)),D&&_.extent==="parent"&&(V=[[0,0],[D.measured.width,D.measured.height]]),U=[],X=void 0;for(const[F,C]of ee)if(C.parentId===r&&(U.push({id:F,position:{...C.position},extent:C.extent}),C.extent==="parent"||C.expandParent)){const z=n1(C,_,C.origin??H);X?X=[[Math.min(z[0][0],X[0][0]),Math.min(z[0][1],X[0][1])],[Math.max(z[1][0],X[1][0]),Math.max(z[1][1],X[1][1])]]:X=z}w==null||w(Z,{...E})}).on("drag",Z=>{const{transform:ee,snapGrid:J,snapToGrid:k,nodeOrigin:W}=o(),H=to(Z.sourceEvent,{transform:ee,snapGrid:J,snapToGrid:k,containerBounds:I}),B=[];if(!_)return;const{x:A,y:j,width:F,height:C}=E,z={},ne=_.origin??W,{width:re,height:$,x:se,y:ce}=e1(L,f.controlDirection,H,f.boundaries,f.keepAspectRatio,ne,V,X),G=re!==F,ue=$!==C,pe=se!==A&&G,we=ce!==j&&ue;if(!pe&&!we&&!G&&!ue)return;if((pe||we||ne[0]===1||ne[1]===1)&&(z.x=pe?se:E.x,z.y=we?ce:E.y,E.x=z.x,E.y=z.y,U.length>0)){const Ce=se-A,Me=ce-j;for(const Le of U)Le.position={x:Le.position.x-Ce+ne[0]*(re-F),y:Le.position.y-Me+ne[1]*($-C)},B.push(Le)}if((G||ue)&&(z.width=G&&(!f.resizeDirection||f.resizeDirection==="horizontal")?re:E.width,z.height=ue&&(!f.resizeDirection||f.resizeDirection==="vertical")?$:E.height,E.width=z.width,E.height=z.height),D&&_.expandParent){const Ce=ne[0]*(z.width??0);z.x&&z.x{Q&&(M==null||M(Z,{...E}),u==null||u({...E}),Q=!1)});c.call(te)}function p(){c.on(".drag",null)}return{update:h,destroy:p}}var Na={exports:{}},Ca={},Ma={exports:{}},Pa={};/** - * @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 Sh;function i1(){if(Sh)return Pa;Sh=1;var t=fo();function r(v,g){return v===g&&(v!==0||1/v===1/g)||v!==v&&g!==g}var o=typeof Object.is=="function"?Object.is:r,l=t.useState,u=t.useEffect,c=t.useLayoutEffect,f=t.useDebugValue;function h(v,g){var w=g(),S=l({inst:{value:w,getSnapshot:g}}),M=S[0].inst,N=S[1];return c(function(){M.value=w,M.getSnapshot=g,p(M)&&N({inst:M})},[v,w,g]),u(function(){return p(M)&&N({inst:M}),v(function(){p(M)&&N({inst:M})})},[v]),f(w),w}function p(v){var g=v.getSnapshot;v=v.value;try{var w=g();return!o(v,w)}catch{return!0}}function y(v,g){return g()}var m=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?y:h;return Pa.useSyncExternalStore=t.useSyncExternalStore!==void 0?t.useSyncExternalStore:m,Pa}var _h;function o1(){return _h||(_h=1,Ma.exports=i1()),Ma.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 Eh;function s1(){if(Eh)return Ca;Eh=1;var t=fo(),r=o1();function o(y,m){return y===m&&(y!==0||1/y===1/m)||y!==y&&m!==m}var l=typeof Object.is=="function"?Object.is:o,u=r.useSyncExternalStore,c=t.useRef,f=t.useEffect,h=t.useMemo,p=t.useDebugValue;return Ca.useSyncExternalStoreWithSelector=function(y,m,v,g,w){var S=c(null);if(S.current===null){var M={hasValue:!1,value:null};S.current=M}else M=S.current;S=h(function(){function E(D){if(!L){if(L=!0,_=D,D=g(D),w!==void 0&&M.hasValue){var V=M.value;if(w(V,D))return I=V}return I=D}if(V=I,l(_,D))return V;var X=g(D);return w!==void 0&&w(V,X)?(_=D,V):(_=D,I=X)}var L=!1,_,I,U=v===void 0?null:v;return[function(){return E(m())},U===null?void 0:function(){return E(U())}]},[m,v,g,w]);var N=u(y,S[0],S[1]);return f(function(){M.hasValue=!0,M.value=N},[N]),p(N),N},Ca}var kh;function l1(){return kh||(kh=1,Na.exports=s1()),Na.exports}var u1=l1();const a1=Zh(u1),c1={},Nh=t=>{let r;const o=new Set,l=(m,v)=>{const g=typeof m=="function"?m(r):m;if(!Object.is(g,r)){const w=r;r=v??(typeof g!="object"||g===null)?g:Object.assign({},r,g),o.forEach(S=>S(r,w))}},u=()=>r,p={setState:l,getState:u,getInitialState:()=>y,subscribe:m=>(o.add(m),()=>o.delete(m)),destroy:()=>{(c1?"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(l,u,p);return p},f1=t=>t?Nh(t):Nh,{useDebugValue:d1}=_0,{useSyncExternalStoreWithSelector:h1}=a1,p1=t=>t;function sg(t,r=p1,o){const l=h1(t.subscribe,t.getState,t.getServerState||t.getInitialState,r,o);return d1(l),l}const Ch=(t,r)=>{const o=f1(t),l=(u,c=r)=>sg(o,u,c);return Object.assign(l,o),l},g1=(t,r)=>t?Ch(t,r):Ch;function Ve(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[l,u]of t)if(!Object.is(u,r.get(l)))return!1;return!0}if(t instanceof Set&&r instanceof Set){if(t.size!==r.size)return!1;for(const l of t)if(!r.has(l))return!1;return!0}const o=Object.keys(t);if(o.length!==Object.keys(r).length)return!1;for(const l of o)if(!Object.prototype.hasOwnProperty.call(r,l)||!Object.is(t[l],r[l]))return!1;return!0}Jh();const yl=K.createContext(null),m1=yl.Provider,lg=Yt.error001("react");function Ie(t,r){const o=K.useContext(yl);if(o===null)throw new Error(lg);return sg(o,t,r)}function $e(){const t=K.useContext(yl);if(t===null)throw new Error(lg);return K.useMemo(()=>({getState:t.getState,setState:t.setState,subscribe:t.subscribe}),[t])}const Mh={display:"none"},y1={position:"absolute",width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0px, 0px, 0px, 0px)",clipPath:"inset(100%)"},ug="react-flow__node-desc",ag="react-flow__edge-desc",v1="react-flow__aria-live",x1=t=>t.ariaLiveMessage,w1=t=>t.ariaLabelConfig;function S1({rfId:t}){const r=Ie(x1);return P.jsx("div",{id:`${v1}-${t}`,"aria-live":"assertive","aria-atomic":"true",style:y1,children:r})}function _1({rfId:t,disableKeyboardA11y:r}){const o=Ie(w1);return P.jsxs(P.Fragment,{children:[P.jsx("div",{id:`${ug}-${t}`,style:Mh,children:r?o["node.a11yDescription.default"]:o["node.a11yDescription.keyboardDisabled"]}),P.jsx("div",{id:`${ag}-${t}`,style:Mh,children:o["edge.a11yDescription.default"]}),!r&&P.jsx(S1,{rfId:t})]})}const vl=K.forwardRef(({position:t="top-left",children:r,className:o,style:l,...u},c)=>{const f=`${t}`.split("-");return P.jsx("div",{className:be(["react-flow__panel",o,...f]),style:l,ref:c,...u,children:r})});vl.displayName="Panel";const Ph="https://reactflow.dev?utm_source=attribution";function E1({proOptions:t,position:r="bottom-right"}){return t!=null&&t.hideAttribution?null:P.jsx(vl,{position:r,className:"react-flow__attribution","data-message":`Please only hide this attribution when you are subscribed to React Flow Pro: ${Ph}`,children:P.jsx("a",{href:Ph,target:"_blank",rel:"noopener noreferrer","aria-label":"React Flow attribution",children:"React Flow"})})}const k1=t=>{const r=[],o=[];for(const[,l]of t.nodeLookup)l.selected&&r.push(l.internals.userNode);for(const[,l]of t.edgeLookup)l.selected&&o.push(l);return{selectedNodes:r,selectedEdges:o}},Ws=t=>t.id;function N1(t,r){return Ve(t.selectedNodes.map(Ws),r.selectedNodes.map(Ws))&&Ve(t.selectedEdges.map(Ws),r.selectedEdges.map(Ws))}function C1({onSelectionChange:t}){const r=$e(),{selectedNodes:o,selectedEdges:l}=Ie(k1,N1);return K.useEffect(()=>{const u={nodes:o,edges:l};t==null||t(u),r.getState().onSelectionChangeHandlers.forEach(c=>c(u))},[o,l,t]),null}const M1=t=>!!t.onSelectionChangeHandlers;function P1({onSelectionChange:t}){const r=Ie(M1);return t||r?P.jsx(C1,{onSelectionChange:t}):null}const cg=[0,0],I1={x:0,y:0,zoom:1},T1=["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"],Ih=[...T1,"rfId"],z1=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}),Th={translateExtent:so,nodeOrigin:cg,minZoom:.5,maxZoom:2,elementsSelectable:!0,noPanClassName:"nopan",rfId:"1"};function L1(t){const{setNodes:r,setEdges:o,setMinZoom:l,setMaxZoom:u,setTranslateExtent:c,setNodeExtent:f,reset:h,setDefaultNodesAndEdges:p}=Ie(z1,Ve),y=$e();K.useEffect(()=>(p(t.defaultNodes,t.defaultEdges),()=>{m.current=Th,h()}),[]);const m=K.useRef(Th);return K.useEffect(()=>{for(const v of Ih){const g=t[v],w=m.current[v];g!==w&&(typeof t[v]>"u"||(v==="nodes"?r(g):v==="edges"?o(g):v==="minZoom"?l(g):v==="maxZoom"?u(g):v==="translateExtent"?c(g):v==="nodeExtent"?f(g):v==="ariaLabelConfig"?y.setState({ariaLabelConfig:mw(g)}):v==="fitView"?y.setState({fitViewQueued:g}):v==="fitViewOptions"?y.setState({fitViewOptions:g}):y.setState({[v]:g})))}m.current=t},Ih.map(v=>t[v])),null}function zh(){return typeof window>"u"||!window.matchMedia?null:window.matchMedia("(prefers-color-scheme: dark)")}function R1(t){var l;const[r,o]=K.useState(t==="system"?null:t);return K.useEffect(()=>{if(t!=="system"){o(t);return}const u=zh(),c=()=>o(u!=null&&u.matches?"dark":"light");return c(),u==null||u.addEventListener("change",c),()=>{u==null||u.removeEventListener("change",c)}},[t]),r!==null?r:(l=zh())!=null&&l.matches?"dark":"light"}const Lh=typeof document<"u"?document:null;function co(t=null,r={target:Lh,actInsideInputWithModifier:!0}){const[o,l]=K.useState(!1),u=K.useRef(!1),c=K.useRef(new Set([])),[f,h]=K.useMemo(()=>{if(t!==null){const y=(Array.isArray(t)?t:[t]).filter(v=>typeof v=="string").map(v=>v.replace(/\+/g,` -`).replace(` - -`,` -+`).split(` -`)),m=y.reduce((v,g)=>v.concat(...g),[]);return[y,m]}return[[],[]]},[t]);return K.useEffect(()=>{const p=(r==null?void 0:r.target)??Lh,y=(r==null?void 0:r.actInsideInputWithModifier)??!0;if(t!==null){const m=w=>{var N,E;if(u.current=w.ctrlKey||w.metaKey||w.shiftKey||w.altKey,(!u.current||u.current&&!y)&&Up(w))return!1;const M=jh(w.code,h);if(c.current.add(w[M]),Rh(f,c.current,!1)){const L=((E=(N=w.composedPath)==null?void 0:N.call(w))==null?void 0:E[0])||w.target,_=(L==null?void 0:L.nodeName)==="BUTTON"||(L==null?void 0:L.nodeName)==="A";r.preventDefault!==!1&&(u.current||!_)&&w.preventDefault(),l(!0)}},v=w=>{const S=jh(w.code,h);Rh(f,c.current,!0)?(l(!1),c.current.clear()):c.current.delete(w[S]),w.key==="Meta"&&c.current.clear(),u.current=!1},g=()=>{c.current.clear(),l(!1)};return p==null||p.addEventListener("keydown",m),p==null||p.addEventListener("keyup",v),window.addEventListener("blur",g),window.addEventListener("contextmenu",g),()=>{p==null||p.removeEventListener("keydown",m),p==null||p.removeEventListener("keyup",v),window.removeEventListener("blur",g),window.removeEventListener("contextmenu",g)}}},[t,l]),o}function Rh(t,r,o){return t.filter(l=>o||l.length===r.size).some(l=>l.every(u=>r.has(u)))}function jh(t,r){return r.includes(t)?"code":"key"}const j1=()=>{const t=$e();return K.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:l}=t.getState();return l?l.scaleTo(r,o):!1},getZoom:()=>t.getState().transform[2],setViewport:async(r,o)=>{const{transform:[l,u,c],panZoom:f}=t.getState();return f?(await f.setViewport({x:r.x??l,y:r.y??u,zoom:r.zoom??c},o),!0):!1},getViewport:()=>{const[r,o,l]=t.getState().transform;return{x:r,y:o,zoom:l}},setCenter:async(r,o,l)=>t.getState().setCenter(r,o,l),fitBounds:async(r,o)=>{const{width:l,height:u,minZoom:c,maxZoom:f,panZoom:h}=t.getState(),p=nc(r,l,u,c,f,(o==null?void 0:o.padding)??.1);return h?(await h.setViewport(p,{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:l,snapGrid:u,snapToGrid:c,domNode:f}=t.getState();if(!f)return r;const{x:h,y:p}=f.getBoundingClientRect(),y={x:r.x-h,y:r.y-p},m=o.snapGrid??u,v=o.snapToGrid??c;return vo(y,l,v,m)},flowToScreenPosition:r=>{const{transform:o,domNode:l}=t.getState();if(!l)return r;const{x:u,y:c}=l.getBoundingClientRect(),f=ii(r,o);return{x:f.x+u,y:f.y+c}}}),[])};function fg(t,r){const o=[],l=new Map,u=[];for(const c of t)if(c.type==="add"){u.push(c);continue}else if(c.type==="remove"||c.type==="replace")l.set(c.id,[c]);else{const f=l.get(c.id);f?f.push(c):l.set(c.id,[c])}for(const c of r){const f=l.get(c.id);if(!f){o.push(c);continue}if(f[0].type==="remove")continue;if(f[0].type==="replace"){o.push({...f[0].item});continue}const h={...c};for(const p of f)A1(p,h);o.push(h)}return u.length&&u.forEach(c=>{c.index!==void 0?o.splice(c.index,0,{...c.item}):o.push({...c.item})}),o}function A1(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 $1(t,r){return fg(t,r)}function D1(t,r){return fg(t,r)}function fr(t,r){return{id:t,type:"select",selected:r}}function qr(t,r=new Set,o=!1){const l=[];for(const[u,c]of t){const f=r.has(u);!(c.selected===void 0&&!f)&&c.selected!==f&&(o&&(c.selected=f),l.push(fr(c.id,f)))}return l}function Ah({items:t=[],lookup:r}){var u;const o=[],l=new Map(t.map(c=>[c.id,c]));for(const[c,f]of t.entries()){const h=r.get(f.id),p=((u=h==null?void 0:h.internals)==null?void 0:u.userNode)??h;p!==void 0&&p!==f&&o.push({id:f.id,item:f,type:"replace"}),p===void 0&&o.push({item:f,type:"add",index:c})}for(const[c]of r)l.get(c)===void 0&&o.push({id:c,type:"remove"});return o}function $h(t){return{id:t.id,type:"remove"}}const O1=Fp();function F1(t,r,o={}){return _w(t,r,{...o,onError:o.onError??O1})}const Dh=t=>lw(t),H1=t=>jp(t);function dg(t){return K.forwardRef(t)}const hg=typeof window<"u"?K.useLayoutEffect:K.useEffect;function Oh(t){const[r,o]=K.useState(BigInt(0)),[l]=K.useState(()=>V1(()=>o(u=>u+BigInt(1))));return hg(()=>{const u=l.get();u.length&&(t(u),l.reset())},[r]),l}function V1(t){let r=[];return{get:()=>r,reset:()=>{r=[]},push:o=>{r.push(o),t()}}}const pg=K.createContext(null);function B1({children:t}){const r=$e(),o=K.useCallback(h=>{const{nodes:p=[],setNodes:y,hasDefaultNodes:m,onNodesChange:v,nodeLookup:g,fitViewQueued:w,onNodesChangeMiddlewareMap:S}=r.getState();let M=p;for(const E of h)M=typeof E=="function"?E(M):E;let N=Ah({items:M,lookup:g});for(const E of S.values())N=E(N);m&&y(M),N.length>0?v==null||v(N):w&&window.requestAnimationFrame(()=>{const{fitViewQueued:E,nodes:L,setNodes:_}=r.getState();E&&_(L)})},[]),l=Oh(o),u=K.useCallback(h=>{const{edges:p=[],setEdges:y,hasDefaultEdges:m,onEdgesChange:v,edgeLookup:g}=r.getState();let w=p;for(const S of h)w=typeof S=="function"?S(w):S;m?y(w):v&&v(Ah({items:w,lookup:g}))},[]),c=Oh(u),f=K.useMemo(()=>({nodeQueue:l,edgeQueue:c}),[]);return P.jsx(pg.Provider,{value:f,children:t})}function U1(){const t=K.useContext(pg);if(!t)throw new Error("useBatchContext must be used within a BatchProvider");return t}const W1=t=>!!t.panZoom;function ac(){const t=j1(),r=$e(),o=U1(),l=Ie(W1),u=K.useMemo(()=>{const c=v=>r.getState().nodeLookup.get(v),f=v=>{o.nodeQueue.push(v)},h=v=>{o.edgeQueue.push(v)},p=v=>{var E,L;const{nodeLookup:g,nodeOrigin:w}=r.getState(),S=Dh(v)?v:g.get(v.id),M=S.parentId?Vp(S.position,S.measured,S.parentId,g,w):S.position,N={...S,position:M,width:((E=S.measured)==null?void 0:E.width)??S.width,height:((L=S.measured)==null?void 0:L.height)??S.height};return uo(N)},y=(v,g,w={replace:!1})=>{f(S=>S.map(M=>{if(M.id===v){const N=typeof g=="function"?g(M):g;return w.replace&&Dh(N)?N:{...M,...N}}return M}))},m=(v,g,w={replace:!1})=>{h(S=>S.map(M=>{if(M.id===v){const N=typeof g=="function"?g(M):g;return w.replace&&H1(N)?N:{...M,...N}}return M}))};return{getNodes:()=>r.getState().nodes.map(v=>({...v})),getNode:v=>{var g;return(g=c(v))==null?void 0:g.internals.userNode},getInternalNode:c,getEdges:()=>{const{edges:v=[]}=r.getState();return v.map(g=>({...g}))},getEdge:v=>r.getState().edgeLookup.get(v),setNodes:f,setEdges:h,addNodes:v=>{const g=Array.isArray(v)?v:[v];o.nodeQueue.push(w=>[...w,...g])},addEdges:v=>{const g=Array.isArray(v)?v:[v];o.edgeQueue.push(w=>[...w,...g])},toObject:()=>{const{nodes:v=[],edges:g=[],transform:w}=r.getState(),[S,M,N]=w;return{nodes:v.map(E=>({...E})),edges:g.map(E=>({...E})),viewport:{x:S,y:M,zoom:N}}},deleteElements:async({nodes:v=[],edges:g=[]})=>{const{nodes:w,edges:S,onNodesDelete:M,onEdgesDelete:N,triggerNodeChanges:E,triggerEdgeChanges:L,onDelete:_,onBeforeDelete:I}=r.getState(),{nodes:U,edges:D}=await dw({nodesToRemove:v,edgesToRemove:g,nodes:w,edges:S,onBeforeDelete:I}),V=D.length>0,X=U.length>0;if(V){const Q=D.map($h);N==null||N(D),L(Q)}if(X){const Q=U.map($h);M==null||M(U),E(Q)}return(X||V)&&(_==null||_({nodes:U,edges:D})),{deletedNodes:U,deletedEdges:D}},getIntersectingNodes:(v,g=!0,w)=>{const S=uh(v),M=S?v:p(v),N=w!==void 0;return M?(w||r.getState().nodes).filter(E=>{const L=r.getState().nodeLookup.get(E.id);if(L&&!S&&(E.id===v.id||!L.internals.positionAbsolute))return!1;const _=uo(N?E:L),I=sl(_,M);return g&&I>0||I>=_.width*_.height||I>=M.width*M.height}):[]},isNodeIntersecting:(v,g,w=!0)=>{const M=uh(v)?v:p(v);if(!M)return!1;const N=sl(M,g);return w&&N>0||N>=g.width*g.height||N>=M.width*M.height},updateNode:y,updateNodeData:(v,g,w={replace:!1})=>{y(v,S=>{const M=typeof g=="function"?g(S):g;return w.replace?{...S,data:M}:{...S,data:{...S.data,...M}}},w)},updateEdge:m,updateEdgeData:(v,g,w={replace:!1})=>{m(v,S=>{const M=typeof g=="function"?g(S):g;return w.replace?{...S,data:M}:{...S,data:{...S.data,...M}}},w)},getNodesBounds:v=>{const{nodeLookup:g,nodeOrigin:w}=r.getState();return uw(v,{nodeLookup:g,nodeOrigin:w})},getHandleConnections:({type:v,id:g,nodeId:w})=>{var S;return Array.from(((S=r.getState().connectionLookup.get(`${w}-${v}${g?`-${g}`:""}`))==null?void 0:S.values())??[])},getNodeConnections:({type:v,handleId:g,nodeId:w})=>{var S;return Array.from(((S=r.getState().connectionLookup.get(`${w}${v?g?`-${v}-${g}`:`-${v}`:""}`))==null?void 0:S.values())??[])},fitView:async v=>{const g=r.getState().fitViewResolver??gw();return r.setState({fitViewQueued:!0,fitViewOptions:v,fitViewResolver:g}),o.nodeQueue.push(w=>[...w]),g.promise}}},[]);return K.useMemo(()=>({...u,...t,viewportInitialized:l}),[l])}const Fh=t=>t.selected,b1=typeof window<"u"?window:void 0;function Y1({deleteKeyCode:t,multiSelectionKeyCode:r}){const o=$e(),{deleteElements:l}=ac(),u=co(t,{actInsideInputWithModifier:!1}),c=co(r,{target:b1});K.useEffect(()=>{if(u){const{edges:f,nodes:h}=o.getState();l({nodes:h.filter(Fh),edges:f.filter(Fh)}),o.setState({nodesSelectionActive:!1})}},[u]),K.useEffect(()=>{o.setState({multiSelectionActive:c})},[c])}function X1(t){const r=$e();K.useEffect(()=>{const o=()=>{var u,c,f,h;if(!t.current||!(((c=(u=t.current).checkVisibility)==null?void 0:c.call(u))??!0))return!1;const l=rc(t.current);(l.height===0||l.width===0)&&((h=(f=r.getState()).onError)==null||h.call(f,"004",Yt.error004())),r.setState({width:l.width||500,height:l.height||500})};if(t.current){o(),window.addEventListener("resize",o);const l=new ResizeObserver(()=>o());return l.observe(t.current),()=>{window.removeEventListener("resize",o),l&&t.current&&l.unobserve(t.current)}}},[])}const xl={position:"absolute",width:"100%",height:"100%",top:0,left:0},Q1=t=>({userSelectionActive:t.userSelectionActive,lib:t.lib,connectionInProgress:t.connection.inProgress});function G1({onPaneContextMenu:t,zoomOnScroll:r=!0,zoomOnPinch:o=!0,panOnScroll:l=!1,panActivationKeyPressed:u,panOnScrollSpeed:c=.5,panOnScrollMode:f=pr.Free,zoomOnDoubleClick:h=!0,panOnDrag:p=!0,defaultViewport:y,translateExtent:m,minZoom:v,maxZoom:g,zoomActivationKeyCode:w,preventScrolling:S=!0,children:M,noWheelClassName:N,noPanClassName:E,onViewportChange:L,isControlledViewport:_,paneClickDistance:I,selectionOnDrag:U}){const D=$e(),V=K.useRef(null),{userSelectionActive:X,lib:Q,connectionInProgress:te}=Ie(Q1,Ve),Z=co(w),ee=K.useRef();X1(V);const J=K.useCallback(k=>{L==null||L({x:k[0],y:k[1],zoom:k[2]}),_||D.setState({transform:k})},[L,_]);return K.useEffect(()=>{if(V.current){ee.current=Zw({domNode:V.current,minZoom:v,maxZoom:g,translateExtent:m,viewport:y,onDraggingChange:B=>D.setState(A=>A.paneDragging===B?A:{paneDragging:B}),onPanZoomStart:(B,A)=>{const{onViewportChangeStart:j,onMoveStart:F}=D.getState();F==null||F(B,A),j==null||j(A)},onPanZoom:(B,A)=>{const{onViewportChange:j,onMove:F}=D.getState();F==null||F(B,A),j==null||j(A)},onPanZoomEnd:(B,A)=>{const{onViewportChangeEnd:j,onMoveEnd:F}=D.getState();F==null||F(B,A),j==null||j(A)}});const{x:k,y:W,zoom:H}=ee.current.getViewport();return D.setState({panZoom:ee.current,transform:[k,W,H],domNode:V.current.closest(".react-flow")}),()=>{var B;(B=ee.current)==null||B.destroy()}}},[]),K.useEffect(()=>{var k;(k=ee.current)==null||k.update({onPaneContextMenu:t,zoomOnScroll:r,zoomOnPinch:o,panOnScroll:l,panActivationKeyPressed:u,panOnScrollSpeed:c,panOnScrollMode:f,zoomOnDoubleClick:h,panOnDrag:p,zoomActivationKeyPressed:Z,preventScrolling:S,noPanClassName:E,userSelectionActive:X,noWheelClassName:N,lib:Q,onTransformChange:J,connectionInProgress:te,selectionOnDrag:U,paneClickDistance:I})},[t,r,o,l,u,c,f,h,p,Z,S,E,X,N,Q,J,te,U,I]),P.jsx("div",{className:"react-flow__renderer",ref:V,style:xl,children:M})}const K1=t=>({userSelectionActive:t.userSelectionActive,userSelectionRect:t.userSelectionRect});function q1(){const{userSelectionActive:t,userSelectionRect:r}=Ie(K1,Ve);return t&&r?P.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 Ia=(t,r)=>o=>{o.target===r.current&&(t==null||t(o))},Z1=t=>({userSelectionActive:t.userSelectionActive,elementsSelectable:t.elementsSelectable,dragging:t.paneDragging,panBy:t.panBy,autoPanSpeed:t.autoPanSpeed});function J1({isSelecting:t,selectionKeyPressed:r,selectionMode:o=lo.Full,panOnDrag:l,autoPanOnSelection:u,paneClickDistance:c,selectionOnDrag:f,onSelectionStart:h,onSelectionEnd:p,onPaneClick:y,onPaneContextMenu:m,onPaneScroll:v,onPaneMouseEnter:g,onPaneMouseMove:w,onPaneMouseLeave:S,children:M}){const N=K.useRef(0),E=$e(),{userSelectionActive:L,elementsSelectable:_,dragging:I,panBy:U,autoPanSpeed:D}=Ie(Z1,Ve),V=_&&(t||L),X=K.useRef(null),Q=K.useRef(),te=K.useRef(new Set),Z=K.useRef(new Set),ee=K.useRef(!1),J=K.useRef(!1),k=K.useRef({x:0,y:0}),W=K.useRef(!1),H=G=>{if(J.current||ee.current||E.getState().connection.inProgress){J.current=!1,ee.current=!1;return}y==null||y(G),E.getState().resetSelectedElements(),E.setState({nodesSelectionActive:!1})},B=G=>{if(Array.isArray(l)&&(l!=null&&l.includes(2))){G.preventDefault();return}m==null||m(G)},A=v?G=>v(G):void 0,j=G=>{J.current&&(G.stopPropagation(),J.current=!1)},F=G=>{var Le,ot;if(G.pointerType==="touch"&&l!==!1&&!r)return;const{domNode:ue,transform:pe}=E.getState();if(Q.current=ue==null?void 0:ue.getBoundingClientRect(),!Q.current)return;const we=G.target===X.current;if(!we&&!!G.target.closest(".nokey")||!t||!(f&&we||r)||G.button!==0||!G.isPrimary)return;(ot=(Le=G.target)==null?void 0:Le.setPointerCapture)==null||ot.call(Le,G.pointerId),J.current=!1;const{x:ke,y:Ce}=bt(G.nativeEvent,Q.current),Me=vo({x:ke,y:Ce},pe);E.setState({userSelectionRect:{width:0,height:0,startX:Me.x,startY:Me.y,x:ke,y:Ce}}),we||(G.stopPropagation(),G.preventDefault())};function C(G,ue){const{userSelectionRect:pe}=E.getState();if(!pe)return;const{transform:we,nodeLookup:ve,edgeLookup:me,connectionLookup:ke,triggerNodeChanges:Ce,triggerEdgeChanges:Me,defaultEdgeOptions:Le}=E.getState(),ot={x:pe.startX,y:pe.startY},{x:ut,y:Je}=ii(ot,we),et={startX:ot.x,startY:ot.y,x:Gat.id)),Z.current=new Set;const Kt=(Le==null?void 0:Le.selectable)??!0;for(const at of te.current){const Ct=ke.get(at);if(Ct)for(const{edgeId:yt}of Ct.values()){const Mt=me.get(yt);Mt&&(Mt.selectable??Kt)&&Z.current.add(yt)}}if(!ah(sn,te.current)){const at=qr(ve,te.current,!0);Ce(at)}if(!ah(Gt,Z.current)){const at=qr(me,Z.current);Me(at)}E.setState({userSelectionRect:et,userSelectionActive:!0,nodesSelectionActive:!1})}function z(){if(!u||!Q.current)return;const[G,ue]=tc(k.current,Q.current,D);U({x:G,y:ue}).then(pe=>{if(!J.current||!pe){N.current=requestAnimationFrame(z);return}const{x:we,y:ve}=k.current;C(we,ve),N.current=requestAnimationFrame(z)})}const ne=()=>{cancelAnimationFrame(N.current),N.current=0,W.current=!1};K.useEffect(()=>()=>ne(),[]);const re=G=>{const{userSelectionRect:ue,transform:pe,resetSelectedElements:we}=E.getState();if(!Q.current||!ue)return;const{x:ve,y:me}=bt(G.nativeEvent,Q.current);k.current={x:ve,y:me};const ke=ii({x:ue.startX,y:ue.startY},pe);if(!J.current){const Ce=r?0:c;if(Math.hypot(ve-ke.x,me-ke.y)<=Ce)return;we(),h==null||h(G)}J.current=!0,W.current||(z(),W.current=!0),C(ve,me)},$=G=>{var ue,pe;if(!V){G.target===X.current&&E.getState().connection.inProgress&&(ee.current=!0);return}G.button===0&&((pe=(ue=G.target)==null?void 0:ue.releasePointerCapture)==null||pe.call(ue,G.pointerId),!L&&G.target===X.current&&E.getState().userSelectionRect&&(H==null||H(G)),E.setState({userSelectionActive:!1,userSelectionRect:null}),J.current&&(p==null||p(G),E.setState({nodesSelectionActive:te.current.size>0})),ne())},se=G=>{var ue,pe;(pe=(ue=G.target)==null?void 0:ue.releasePointerCapture)==null||pe.call(ue,G.pointerId),ne()},ce=l===!0||Array.isArray(l)&&l.includes(0);return P.jsxs("div",{className:be(["react-flow__pane",{draggable:ce,dragging:I,selection:t}]),onClick:V?void 0:Ia(H,X),onContextMenu:Ia(B,X),onWheel:Ia(A,X),onPointerEnter:V?void 0:g,onPointerMove:V?re:w,onPointerUp:$,onPointerCancel:V?se:void 0,onPointerDownCapture:V?F:void 0,onClickCapture:V?j:void 0,onPointerLeave:S,ref:X,style:xl,children:[M,P.jsx(q1,{})]})}function ba({id:t,store:r,unselect:o=!1,nodeRef:l}){const{addSelectedNodes:u,unselectNodesAndEdges:c,multiSelectionActive:f,nodeLookup:h,onError:p}=r.getState(),y=h.get(t);if(!y){p==null||p("012",Yt.error012(t));return}r.setState({nodesSelectionActive:!1}),y.selected?(o||y.selected&&f)&&(c({nodes:[y],edges:[]}),requestAnimationFrame(()=>{var m;return(m=l==null?void 0:l.current)==null?void 0:m.blur()})):u([t])}function gg({nodeRef:t,disabled:r=!1,noDragClassName:o,handleSelector:l,nodeId:u,isSelectable:c,nodeClickDistance:f}){const h=$e(),[p,y]=K.useState(!1),m=K.useRef();return K.useEffect(()=>{if(!r)return m.current=Ow({getStoreItems:()=>h.getState(),onNodeMouseDown:v=>{ba({id:v,store:h,nodeRef:t})},onDragStart:()=>{y(!0)},onDragStop:()=>{y(!1)}}),()=>{var v;(v=m.current)==null||v.destroy(),m.current=void 0}},[r,h,t]),K.useEffect(()=>{r||!t.current||!m.current||m.current.update({noDragClassName:o,handleSelector:l,domNode:t.current,isSelectable:c,nodeId:u,nodeClickDistance:f})},[o,l,r,c,t,u,f]),p}const eS=t=>r=>r.selected&&(r.draggable||t&&typeof r.draggable>"u");function mg(){const t=$e();return K.useCallback(o=>{const{nodeExtent:l,snapToGrid:u,snapGrid:c,nodesDraggable:f,onError:h,updateNodePositions:p,nodeLookup:y,nodeOrigin:m}=t.getState(),v=new Map,g=eS(f),w=u?c[0]:5,S=u?c[1]:5,M=o.direction.x*w*o.factor,N=o.direction.y*S*o.factor;for(const[,E]of y){if(!g(E))continue;let L={x:E.internals.positionAbsolute.x+M,y:E.internals.positionAbsolute.y+N};u&&(L=yo(L,c));const{position:_,positionAbsolute:I}=Ap({nodeId:E.id,nextPosition:L,nodeLookup:y,nodeExtent:l,nodeOrigin:m,onError:h});E.position=_,E.internals.positionAbsolute=I,v.set(E.id,E)}p(v)},[])}const cc=K.createContext(null),tS=cc.Provider;cc.Consumer;const yg=()=>K.useContext(cc),nS=t=>({connectOnClick:t.connectOnClick,noPanClassName:t.noPanClassName,rfId:t.rfId}),vg=K.createContext(null);function rS({children:t}){const r=Ie(nS,Ve);return P.jsx(vg.Provider,{value:r,children:t})}function iS(){const t=K.useContext(vg);if(!t)throw new Error("useHandleConfig must be used within a HandleConfigProvider");return t}const oS={connectingFrom:!1,connectingTo:!1,clickConnecting:!1,isPossibleEndHandle:!0,connectionInProcess:!1,clickConnectionInProcess:!1,valid:!1},sS=(t,r,o)=>l=>{const{connectionClickStartHandle:u,connectionMode:c,connection:f}=l,{fromHandle:h,toHandle:p,isValid:y}=f;if(!h&&!u)return oS;const m=(p==null?void 0:p.nodeId)===t&&(p==null?void 0:p.id)===r&&(p==null?void 0:p.type)===o;return{connectingFrom:(h==null?void 0:h.nodeId)===t&&(h==null?void 0:h.id)===r&&(h==null?void 0:h.type)===o,connectingTo:m,clickConnecting:(u==null?void 0:u.nodeId)===t&&(u==null?void 0:u.id)===r&&(u==null?void 0:u.type)===o,isPossibleEndHandle:c===ni.Strict?(h==null?void 0:h.type)!==o:t!==(h==null?void 0:h.nodeId)||r!==(h==null?void 0:h.id),connectionInProcess:!!h,clickConnectionInProcess:!!u,valid:m&&y}};function lS({type:t="source",position:r=xe.Top,isValidConnection:o,isConnectable:l=!0,isConnectableStart:u=!0,isConnectableEnd:c=!0,id:f,onConnect:h,children:p,className:y,onMouseDown:m,onTouchStart:v,...g},w){var W,H;const S=f||null,M=t==="target",N=$e(),E=yg(),{connectOnClick:L,noPanClassName:_,rfId:I}=iS(),{connectingFrom:U,connectingTo:D,clickConnecting:V,isPossibleEndHandle:X,connectionInProcess:Q,clickConnectionInProcess:te,valid:Z}=Ie(sS(E,S,t),Ve);E||(H=(W=N.getState()).onError)==null||H.call(W,"010",Yt.error010());const ee=B=>{const{defaultEdgeOptions:A,onConnect:j,hasDefaultEdges:F}=N.getState(),C={...A,...B};if(F){const{edges:z,setEdges:ne,onError:re}=N.getState();ne(F1(C,z,{onError:re}))}j==null||j(C),h==null||h(C)},J=B=>{if(!E)return;const A=Wp(B.nativeEvent);if(u&&(A&&B.button===0||!A)){const j=N.getState();Wa.onPointerDown(B.nativeEvent,{handleDomNode:B.currentTarget,autoPanOnConnect:j.autoPanOnConnect,connectionMode:j.connectionMode,connectionRadius:j.connectionRadius,domNode:j.domNode,nodeLookup:j.nodeLookup,lib:j.lib,isTarget:M,handleId:S,nodeId:E,flowId:j.rfId,panBy:j.panBy,cancelConnection:j.cancelConnection,onConnectStart:j.onConnectStart,onConnectEnd:(...F)=>{var C,z;return(z=(C=N.getState()).onConnectEnd)==null?void 0:z.call(C,...F)},updateConnection:j.updateConnection,onConnect:ee,isValidConnection:o||((...F)=>{var C,z;return((z=(C=N.getState()).isValidConnection)==null?void 0:z.call(C,...F))??!0}),getTransform:()=>N.getState().transform,getFromHandle:()=>N.getState().connection.fromHandle,autoPanSpeed:j.autoPanSpeed,dragThreshold:j.connectionDragThreshold})}A?m==null||m(B):v==null||v(B)},k=B=>{const{onClickConnectStart:A,onClickConnectEnd:j,connectionClickStartHandle:F,connectionMode:C,isValidConnection:z,lib:ne,rfId:re,nodeLookup:$,connection:se}=N.getState();if(!E||!F&&!u)return;if(!F){A==null||A(B.nativeEvent,{nodeId:E,handleId:S,handleType:t}),N.setState({connectionClickStartHandle:{nodeId:E,type:t,id:S}});return}const ce=Bp(B.target),G=o||z,{connection:ue,isValid:pe}=Wa.isValid(B.nativeEvent,{handle:{nodeId:E,id:S,type:t},connectionMode:C,fromNodeId:F.nodeId,fromHandleId:F.id||null,fromType:F.type,isValidConnection:G,flowId:re,doc:ce,lib:ne,nodeLookup:$});pe&&ue&&ee(ue);const we=structuredClone(se);delete we.inProgress,we.toPosition=we.toHandle?we.toHandle.position:null,j==null||j(B,we),N.setState({connectionClickStartHandle:null})};return P.jsx("div",{"data-handleid":S,"data-nodeid":E,"data-handlepos":r,"data-id":`${I}-${E}-${S}-${t}`,className:be(["react-flow__handle",`react-flow__handle-${r}`,"nodrag",_,y,{source:!M,target:M,connectable:l,connectablestart:u,connectableend:c,clickconnecting:V,connectingfrom:U,connectingto:D,valid:Z,connectionindicator:l&&(!Q||X)&&(Q||te?c:u)}]),onMouseDown:J,onTouchStart:J,onClick:L?k:void 0,ref:w,...g,children:p})}const ll=K.memo(dg(lS));function uS({data:t,isConnectable:r,sourcePosition:o=xe.Bottom}){return P.jsxs(P.Fragment,{children:[t==null?void 0:t.label,P.jsx(ll,{type:"source",position:o,isConnectable:r})]})}function aS({data:t,isConnectable:r,targetPosition:o=xe.Top,sourcePosition:l=xe.Bottom}){return P.jsxs(P.Fragment,{children:[P.jsx(ll,{type:"target",position:o,isConnectable:r}),t==null?void 0:t.label,P.jsx(ll,{type:"source",position:l,isConnectable:r})]})}function cS(){return null}function fS({data:t,isConnectable:r,targetPosition:o=xe.Top}){return P.jsxs(P.Fragment,{children:[P.jsx(ll,{type:"target",position:o,isConnectable:r}),t==null?void 0:t.label]})}const ul={ArrowUp:{x:0,y:-1},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0},ArrowRight:{x:1,y:0}},Hh={input:uS,default:aS,output:fS,group:cS};function dS(t){var r,o,l,u;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??((l=t.style)==null?void 0:l.width),height:t.height??((u=t.style)==null?void 0:u.height)}}const hS=t=>{const{width:r,height:o,x:l,y:u}=mo(t.nodeLookup,{filter:c=>!!c.selected});return{width:Wt(r)?r:null,height:Wt(o)?o:null,userSelectionActive:t.userSelectionActive,transformString:`translate(${t.transform[0]}px,${t.transform[1]}px) scale(${t.transform[2]}) translate(${l}px,${u}px)`}};function pS({onSelectionContextMenu:t,noPanClassName:r,disableKeyboardA11y:o}){const l=$e(),{width:u,height:c,transformString:f,userSelectionActive:h}=Ie(hS,Ve),p=mg(),y=K.useRef(null);K.useEffect(()=>{var w;o||(w=y.current)==null||w.focus({preventScroll:!0})},[o]);const m=!h&&u!==null&&c!==null;if(gg({nodeRef:y,disabled:!m}),!m)return null;const v=t?w=>{const S=l.getState().nodes.filter(M=>M.selected);t(w,S)}:void 0,g=w=>{Object.prototype.hasOwnProperty.call(ul,w.key)&&(w.preventDefault(),p({direction:ul[w.key],factor:w.shiftKey?4:1}))};return P.jsx("div",{className:be(["react-flow__nodesselection","react-flow__container",r]),style:{transform:f},children:P.jsx("div",{ref:y,className:"react-flow__nodesselection-rect",onContextMenu:v,tabIndex:o?void 0:-1,onKeyDown:o?void 0:g,style:{width:u,height:c}})})}const Vh=typeof window<"u"?window:void 0,gS=t=>({nodesSelectionActive:t.nodesSelectionActive,userSelectionActive:t.userSelectionActive});function xg({children:t,onPaneClick:r,onPaneMouseEnter:o,onPaneMouseMove:l,onPaneMouseLeave:u,onPaneContextMenu:c,onPaneScroll:f,paneClickDistance:h,deleteKeyCode:p,selectionKeyCode:y,selectionOnDrag:m,selectionMode:v,onSelectionStart:g,onSelectionEnd:w,multiSelectionKeyCode:S,panActivationKeyCode:M,zoomActivationKeyCode:N,elementsSelectable:E,zoomOnScroll:L,zoomOnPinch:_,panOnScroll:I,panOnScrollSpeed:U,panOnScrollMode:D,zoomOnDoubleClick:V,panOnDrag:X,autoPanOnSelection:Q,defaultViewport:te,translateExtent:Z,minZoom:ee,maxZoom:J,preventScrolling:k,onSelectionContextMenu:W,noWheelClassName:H,noPanClassName:B,disableKeyboardA11y:A,onViewportChange:j,isControlledViewport:F}){const{nodesSelectionActive:C,userSelectionActive:z}=Ie(gS,Ve),ne=co(y,{target:Vh}),re=co(M,{target:Vh}),$=re||X,se=re||I,ce=m&&$!==!0,G=ne||z||ce;return Y1({deleteKeyCode:p,multiSelectionKeyCode:S}),P.jsx(G1,{onPaneContextMenu:c,elementsSelectable:E,zoomOnScroll:L,zoomOnPinch:_,panOnScroll:se,panActivationKeyPressed:re,panOnScrollSpeed:U,panOnScrollMode:D,zoomOnDoubleClick:V,panOnDrag:!ne&&$,defaultViewport:te,translateExtent:Z,minZoom:ee,maxZoom:J,zoomActivationKeyCode:N,preventScrolling:k,noWheelClassName:H,noPanClassName:B,onViewportChange:j,isControlledViewport:F,paneClickDistance:h,selectionOnDrag:ce,children:P.jsxs(J1,{onSelectionStart:g,onSelectionEnd:w,onPaneClick:r,onPaneMouseEnter:o,onPaneMouseMove:l,onPaneMouseLeave:u,onPaneContextMenu:c,onPaneScroll:f,panOnDrag:$,autoPanOnSelection:Q,isSelecting:!!G,selectionMode:v,selectionKeyPressed:ne,paneClickDistance:h,selectionOnDrag:ce,children:[t,C&&P.jsx(pS,{onSelectionContextMenu:W,noPanClassName:B,disableKeyboardA11y:A})]})})}xg.displayName="FlowRenderer";const mS=K.memo(xg),yS=t=>r=>t?ec(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 vS(t){return Ie(K.useCallback(yS(t),[t]),Ve)}const xS=t=>t.updateNodeInternals;function wS(){const t=Ie(xS),[r]=K.useState(()=>typeof ResizeObserver>"u"?null:new ResizeObserver(o=>{const l=new Map;o.forEach(u=>{const c=u.target.getAttribute("data-id");l.set(c,{id:c,nodeElement:u.target,force:!0})}),t(l)}));return K.useEffect(()=>()=>{r==null||r.disconnect()},[r]),r}function SS({node:t,nodeType:r,hasDimensions:o,resizeObserver:l}){const u=$e(),c=K.useRef(null),f=K.useRef(null),h=K.useRef(t.sourcePosition),p=K.useRef(t.targetPosition),y=K.useRef(r),m=o&&!!t.internals.handleBounds;return K.useEffect(()=>{c.current&&!t.hidden&&(!m||f.current!==c.current)&&(f.current&&(l==null||l.unobserve(f.current)),l==null||l.observe(c.current),f.current=c.current)},[m,t.hidden]),K.useEffect(()=>()=>{f.current&&(l==null||l.unobserve(f.current),f.current=null)},[]),K.useEffect(()=>{if(c.current){const v=y.current!==r,g=h.current!==t.sourcePosition,w=p.current!==t.targetPosition;(v||g||w)&&(y.current=r,h.current=t.sourcePosition,p.current=t.targetPosition,u.getState().updateNodeInternals(new Map([[t.id,{id:t.id,nodeElement:c.current,force:!0}]])))}},[t.id,r,t.sourcePosition,t.targetPosition]),c}function _S({id:t,onClick:r,onMouseEnter:o,onMouseMove:l,onMouseLeave:u,onContextMenu:c,onDoubleClick:f,nodesDraggable:h,elementsSelectable:p,nodesConnectable:y,nodesFocusable:m,resizeObserver:v,noDragClassName:g,noPanClassName:w,disableKeyboardA11y:S,rfId:M,nodeTypes:N,nodeClickDistance:E,onError:L}){const{node:_,internals:I,isParent:U}=Ie(G=>{const ue=G.nodeLookup.get(t),pe=G.parentLookup.has(t);return{node:ue,internals:ue.internals,isParent:pe}},Ve);let D=_.type||"default",V=(N==null?void 0:N[D])||Hh[D];V===void 0&&(L==null||L("003",Yt.error003(D)),D="default",V=(N==null?void 0:N.default)||Hh.default);const X=!!(_.draggable||h&&typeof _.draggable>"u"),Q=!!(_.selectable||p&&typeof _.selectable>"u"),te=!!(_.connectable||y&&typeof _.connectable>"u"),Z=!!(_.focusable||m&&typeof _.focusable>"u"),ee=$e(),J=Hp(_),k=SS({node:_,nodeType:D,hasDimensions:J,resizeObserver:v}),W=gg({nodeRef:k,disabled:_.hidden||!X,noDragClassName:g,handleSelector:_.dragHandle,nodeId:t,isSelectable:Q,nodeClickDistance:E}),H=mg();if(_.hidden)return null;const B=Qt(_),A=dS(_),j=Q||X||r||o||l||u,F=o?G=>o(G,{...I.userNode}):void 0,C=l?G=>l(G,{...I.userNode}):void 0,z=u?G=>u(G,{...I.userNode}):void 0,ne=c?G=>c(G,{...I.userNode}):void 0,re=f?G=>f(G,{...I.userNode}):void 0,$=G=>{const{selectNodesOnDrag:ue,nodeDragThreshold:pe}=ee.getState();Q&&(!ue||!X||pe>0)&&ba({id:t,store:ee,nodeRef:k}),r&&r(G,{...I.userNode})},se=G=>{if(!(Up(G.nativeEvent)||S)){if(Tp.includes(G.key)&&Q){const ue=G.key==="Escape";ba({id:t,store:ee,unselect:ue,nodeRef:k})}else if(X&&_.selected&&Object.prototype.hasOwnProperty.call(ul,G.key)){G.preventDefault();const{ariaLabelConfig:ue}=ee.getState();ee.setState({ariaLiveMessage:ue["node.a11yDescription.ariaLiveMessage"]({direction:G.key.replace("Arrow","").toLowerCase(),x:~~I.positionAbsolute.x,y:~~I.positionAbsolute.y})}),H({direction:ul[G.key],factor:G.shiftKey?4:1})}}},ce=()=>{var ke;if(S||!((ke=k.current)!=null&&ke.matches(":focus-visible")))return;const{transform:G,width:ue,height:pe,autoPanOnNodeFocus:we,setCenter:ve}=ee.getState();if(!we)return;ec(new Map([[t,_]]),{x:0,y:0,width:ue,height:pe},G,!0).length>0||ve(_.position.x+B.width/2,_.position.y+B.height/2,{zoom:G[2]})};return P.jsx("div",{className:be(["react-flow__node",`react-flow__node-${D}`,{[w]:X},_.className,{selected:_.selected,selectable:Q,parent:U,draggable:X,dragging:W}]),ref:k,style:{zIndex:I.z,transform:`translate(${I.positionAbsolute.x}px,${I.positionAbsolute.y}px)`,pointerEvents:j?"all":"none",visibility:J?"visible":"hidden",..._.style,...A},"data-id":t,"data-testid":`rf__node-${t}`,onMouseEnter:F,onMouseMove:C,onMouseLeave:z,onContextMenu:ne,onClick:$,onDoubleClick:re,onKeyDown:Z?se:void 0,tabIndex:Z?0:void 0,onFocus:Z?ce:void 0,role:_.ariaRole??(Z?"group":void 0),"aria-roledescription":"node","aria-describedby":S?void 0:`${ug}-${M}`,"aria-label":_.ariaLabel,..._.domAttributes,children:P.jsx(tS,{value:t,children:P.jsx(V,{id:t,data:_.data,type:D,positionAbsoluteX:I.positionAbsolute.x,positionAbsoluteY:I.positionAbsolute.y,selected:_.selected??!1,selectable:Q,draggable:X,deletable:_.deletable??!0,isConnectable:te,sourcePosition:_.sourcePosition,targetPosition:_.targetPosition,dragging:W,dragHandle:_.dragHandle,zIndex:I.z,parentId:_.parentId,...B})})})}var ES=K.memo(_S);const kS=t=>({nodesConnectable:t.nodesConnectable,nodesFocusable:t.nodesFocusable,elementsSelectable:t.elementsSelectable,onError:t.onError});function wg(t){const{nodesConnectable:r,nodesFocusable:o,elementsSelectable:l,onError:u}=Ie(kS,Ve),c=vS(t.onlyRenderVisibleElements),f=wS();return P.jsx("div",{className:"react-flow__nodes",style:xl,children:c.map(h=>P.jsx(ES,{id:h,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:f,nodesDraggable:t.nodesDraggable??!0,nodesConnectable:r,nodesFocusable:o,elementsSelectable:l,nodeClickDistance:t.nodeClickDistance,onError:u},h))})}wg.displayName="NodeRenderer";const NS=K.memo(wg);function CS(t){return Ie(K.useCallback(o=>{if(!t)return o.edges.map(u=>u.id);const l=[];if(o.width&&o.height)for(const u of o.edges){const c=o.nodeLookup.get(u.source),f=o.nodeLookup.get(u.target);c&&f&&xw({sourceNode:c,targetNode:f,width:o.width,height:o.height,transform:o.transform})&&l.push(u.id)}return l},[t]),Ve)}const MS=({color:t="none",strokeWidth:r=1})=>{const o={strokeWidth:r,...t&&{stroke:t}};return P.jsx("polyline",{className:"arrow",style:o,strokeLinecap:"round",fill:"none",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4"})},PS=({color:t="none",strokeWidth:r=1})=>{const o={strokeWidth:r,...t&&{stroke:t,fill:t}};return P.jsx("polyline",{className:"arrowclosed",style:o,strokeLinecap:"round",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4 -5,-4"})},Bh={[il.Arrow]:MS,[il.ArrowClosed]:PS};function IS(t){const r=$e();return K.useMemo(()=>{var u,c;return Object.prototype.hasOwnProperty.call(Bh,t)?Bh[t]:((c=(u=r.getState()).onError)==null||c.call(u,"009",Yt.error009(t)),null)},[t])}const TS=({id:t,type:r,color:o,width:l=12.5,height:u=12.5,markerUnits:c="strokeWidth",strokeWidth:f,orient:h="auto-start-reverse"})=>{const p=IS(r);return p?P.jsx("marker",{className:"react-flow__arrowhead",id:t,markerWidth:`${l}`,markerHeight:`${u}`,viewBox:"-10 -10 20 20",markerUnits:c,orient:h,refX:"0",refY:"0",children:P.jsx(p,{color:o,strokeWidth:f})}):null},Sg=({defaultColor:t,rfId:r})=>{const o=Ie(c=>c.edges),l=Ie(c=>c.defaultEdgeOptions),u=K.useMemo(()=>Mw(o,{id:r,defaultColor:t,defaultMarkerStart:l==null?void 0:l.markerStart,defaultMarkerEnd:l==null?void 0:l.markerEnd}),[o,l,r,t]);return u.length?P.jsx("svg",{className:"react-flow__marker","aria-hidden":"true",children:P.jsx("defs",{children:u.map(c=>P.jsx(TS,{id:c.id,type:c.type,color:c.color,width:c.width,height:c.height,markerUnits:c.markerUnits,strokeWidth:c.strokeWidth,orient:c.orient},c.id))})}):null};Sg.displayName="MarkerDefinitions";var zS=K.memo(Sg);function _g({x:t,y:r,label:o,labelStyle:l,labelShowBg:u=!0,labelBgStyle:c,labelBgPadding:f=[2,4],labelBgBorderRadius:h=2,children:p,className:y,...m}){const[v,g]=K.useState({x:1,y:0,width:0,height:0}),w=be(["react-flow__edge-textwrapper",y]),S=K.useRef(null);return K.useEffect(()=>{if(S.current){const M=S.current.getBBox();g({x:M.x,y:M.y,width:M.width,height:M.height})}},[o]),o?P.jsxs("g",{transform:`translate(${t-v.width/2} ${r-v.height/2})`,className:w,visibility:v.width?"visible":"hidden",...m,children:[u&&P.jsx("rect",{width:v.width+2*f[0],x:-f[0],y:-f[1],height:v.height+2*f[1],className:"react-flow__edge-textbg",style:c,rx:h,ry:h}),P.jsx("text",{className:"react-flow__edge-text",y:v.height/2,dy:"0.3em",ref:S,style:l,children:o}),p]}):null}_g.displayName="EdgeText";const LS=K.memo(_g);function wl({path:t,labelX:r,labelY:o,label:l,labelStyle:u,labelShowBg:c,labelBgStyle:f,labelBgPadding:h,labelBgBorderRadius:p,interactionWidth:y=20,...m}){return P.jsxs(P.Fragment,{children:[P.jsx("path",{...m,d:t,fill:"none",className:be(["react-flow__edge-path",m.className])}),y?P.jsx("path",{d:t,fill:"none",strokeOpacity:0,strokeWidth:y,className:"react-flow__edge-interaction"}):null,l&&Wt(r)&&Wt(o)?P.jsx(LS,{x:r,y:o,label:l,labelStyle:u,labelShowBg:c,labelBgStyle:f,labelBgPadding:h,labelBgBorderRadius:p}):null]})}function Uh({pos:t,x1:r,y1:o,x2:l,y2:u}){return t===xe.Left||t===xe.Right?[.5*(r+l),o]:[r,.5*(o+u)]}function Eg({sourceX:t,sourceY:r,sourcePosition:o=xe.Bottom,targetX:l,targetY:u,targetPosition:c=xe.Top}){const[f,h]=Uh({pos:o,x1:t,y1:r,x2:l,y2:u}),[p,y]=Uh({pos:c,x1:l,y1:u,x2:t,y2:r}),[m,v,g,w]=bp({sourceX:t,sourceY:r,targetX:l,targetY:u,sourceControlX:f,sourceControlY:h,targetControlX:p,targetControlY:y});return[`M${t},${r} C${f},${h} ${p},${y} ${l},${u}`,m,v,g,w]}function kg(t){return K.memo(({id:r,sourceX:o,sourceY:l,targetX:u,targetY:c,sourcePosition:f,targetPosition:h,label:p,labelStyle:y,labelShowBg:m,labelBgStyle:v,labelBgPadding:g,labelBgBorderRadius:w,style:S,markerEnd:M,markerStart:N,interactionWidth:E})=>{const[L,_,I]=Eg({sourceX:o,sourceY:l,sourcePosition:f,targetX:u,targetY:c,targetPosition:h}),U=t.isInternal?void 0:r;return P.jsx(wl,{id:U,path:L,labelX:_,labelY:I,label:p,labelStyle:y,labelShowBg:m,labelBgStyle:v,labelBgPadding:g,labelBgBorderRadius:w,style:S,markerEnd:M,markerStart:N,interactionWidth:E})})}const RS=kg({isInternal:!1}),Ng=kg({isInternal:!0});RS.displayName="SimpleBezierEdge";Ng.displayName="SimpleBezierEdgeInternal";function Cg(t){return K.memo(({id:r,sourceX:o,sourceY:l,targetX:u,targetY:c,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:y,labelBgPadding:m,labelBgBorderRadius:v,style:g,sourcePosition:w=xe.Bottom,targetPosition:S=xe.Top,markerEnd:M,markerStart:N,pathOptions:E,interactionWidth:L})=>{const[_,I,U]=Va({sourceX:o,sourceY:l,sourcePosition:w,targetX:u,targetY:c,targetPosition:S,borderRadius:E==null?void 0:E.borderRadius,offset:E==null?void 0:E.offset,stepPosition:E==null?void 0:E.stepPosition}),D=t.isInternal?void 0:r;return P.jsx(wl,{id:D,path:_,labelX:I,labelY:U,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:y,labelBgPadding:m,labelBgBorderRadius:v,style:g,markerEnd:M,markerStart:N,interactionWidth:L})})}const Mg=Cg({isInternal:!1}),Pg=Cg({isInternal:!0});Mg.displayName="SmoothStepEdge";Pg.displayName="SmoothStepEdgeInternal";function Ig(t){return K.memo(({id:r,...o})=>{var u;const l=t.isInternal?void 0:r;return P.jsx(Mg,{...o,id:l,pathOptions:K.useMemo(()=>{var c;return{borderRadius:0,offset:(c=o.pathOptions)==null?void 0:c.offset}},[(u=o.pathOptions)==null?void 0:u.offset])})})}const jS=Ig({isInternal:!1}),Tg=Ig({isInternal:!0});jS.displayName="StepEdge";Tg.displayName="StepEdgeInternal";function zg(t){return K.memo(({id:r,sourceX:o,sourceY:l,targetX:u,targetY:c,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:y,labelBgPadding:m,labelBgBorderRadius:v,style:g,markerEnd:w,markerStart:S,interactionWidth:M})=>{const[N,E,L]=Qp({sourceX:o,sourceY:l,targetX:u,targetY:c}),_=t.isInternal?void 0:r;return P.jsx(wl,{id:_,path:N,labelX:E,labelY:L,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:y,labelBgPadding:m,labelBgBorderRadius:v,style:g,markerEnd:w,markerStart:S,interactionWidth:M})})}const AS=zg({isInternal:!1}),Lg=zg({isInternal:!0});AS.displayName="StraightEdge";Lg.displayName="StraightEdgeInternal";function Rg(t){return K.memo(({id:r,sourceX:o,sourceY:l,targetX:u,targetY:c,sourcePosition:f=xe.Bottom,targetPosition:h=xe.Top,label:p,labelStyle:y,labelShowBg:m,labelBgStyle:v,labelBgPadding:g,labelBgBorderRadius:w,style:S,markerEnd:M,markerStart:N,pathOptions:E,interactionWidth:L})=>{const[_,I,U]=Yp({sourceX:o,sourceY:l,sourcePosition:f,targetX:u,targetY:c,targetPosition:h,curvature:E==null?void 0:E.curvature}),D=t.isInternal?void 0:r;return P.jsx(wl,{id:D,path:_,labelX:I,labelY:U,label:p,labelStyle:y,labelShowBg:m,labelBgStyle:v,labelBgPadding:g,labelBgBorderRadius:w,style:S,markerEnd:M,markerStart:N,interactionWidth:L})})}const $S=Rg({isInternal:!1}),jg=Rg({isInternal:!0});$S.displayName="BezierEdge";jg.displayName="BezierEdgeInternal";const Wh={default:jg,straight:Lg,step:Tg,smoothstep:Pg,simplebezier:Ng},bh={sourceX:null,sourceY:null,targetX:null,targetY:null,sourcePosition:null,targetPosition:null,zIndex:void 0},DS=(t,r,o)=>o===xe.Left?t-r:o===xe.Right?t+r:t,OS=(t,r,o)=>o===xe.Top?t-r:o===xe.Bottom?t+r:t,Yh="react-flow__edgeupdater";function Xh({position:t,centerX:r,centerY:o,radius:l=10,onMouseDown:u,onMouseEnter:c,onMouseOut:f,type:h}){return P.jsx("circle",{onMouseDown:u,onMouseEnter:c,onMouseOut:f,className:be([Yh,`${Yh}-${h}`]),cx:DS(r,l,t),cy:OS(o,l,t),r:l,stroke:"transparent",fill:"transparent"})}function FS({isReconnectable:t,reconnectRadius:r,edge:o,sourceX:l,sourceY:u,targetX:c,targetY:f,sourcePosition:h,targetPosition:p,onReconnect:y,onReconnectStart:m,onReconnectEnd:v,setReconnecting:g,setUpdateHover:w}){const S=$e(),M=(I,U)=>{if(I.button!==0)return;const{autoPanOnConnect:D,domNode:V,connectionMode:X,connectionRadius:Q,lib:te,onConnectStart:Z,cancelConnection:ee,nodeLookup:J,rfId:k,panBy:W,updateConnection:H}=S.getState(),B=U.type==="target",A=(C,z)=>{g(!1),v==null||v(C,o,U.type,z)},j=C=>y==null?void 0:y(o,C),F=(C,z)=>{g(!0),m==null||m(I,o,U.type),Z==null||Z(C,z)};Wa.onPointerDown(I.nativeEvent,{autoPanOnConnect:D,connectionMode:X,connectionRadius:Q,domNode:V,handleId:U.id,nodeId:U.nodeId,nodeLookup:J,isTarget:B,edgeUpdaterType:U.type,lib:te,flowId:k,cancelConnection:ee,panBy:W,isValidConnection:(...C)=>{var z,ne;return((ne=(z=S.getState()).isValidConnection)==null?void 0:ne.call(z,...C))??!0},onConnect:j,onConnectStart:F,onConnectEnd:(...C)=>{var z,ne;return(ne=(z=S.getState()).onConnectEnd)==null?void 0:ne.call(z,...C)},onReconnectEnd:A,updateConnection:H,getTransform:()=>S.getState().transform,getFromHandle:()=>S.getState().connection.fromHandle,dragThreshold:S.getState().connectionDragThreshold,handleDomNode:I.currentTarget})},N=I=>M(I,{nodeId:o.target,id:o.targetHandle??null,type:"target"}),E=I=>M(I,{nodeId:o.source,id:o.sourceHandle??null,type:"source"}),L=()=>w(!0),_=()=>w(!1);return P.jsxs(P.Fragment,{children:[(t===!0||t==="source")&&P.jsx(Xh,{position:h,centerX:l,centerY:u,radius:r,onMouseDown:N,onMouseEnter:L,onMouseOut:_,type:"source"}),(t===!0||t==="target")&&P.jsx(Xh,{position:p,centerX:c,centerY:f,radius:r,onMouseDown:E,onMouseEnter:L,onMouseOut:_,type:"target"})]})}function HS({id:t,edgesFocusable:r,edgesReconnectable:o,elementsSelectable:l,onClick:u,onDoubleClick:c,onContextMenu:f,onMouseEnter:h,onMouseMove:p,onMouseLeave:y,reconnectRadius:m,onReconnect:v,onReconnectStart:g,onReconnectEnd:w,rfId:S,edgeTypes:M,noPanClassName:N,onError:E,disableKeyboardA11y:L}){let _=Ie(ve=>ve.edgeLookup.get(t));const I=Ie(ve=>ve.defaultEdgeOptions);_=I?{...I,..._}:_;let U=_.type||"default",D=(M==null?void 0:M[U])||Wh[U];D===void 0&&(E==null||E("011",Yt.error011(U)),U="default",D=(M==null?void 0:M.default)||Wh.default);const V=!!(_.focusable||r&&typeof _.focusable>"u"),X=typeof v<"u"&&(_.reconnectable||o&&typeof _.reconnectable>"u"),Q=!!(_.selectable||l&&typeof _.selectable>"u"),te=K.useRef(null),[Z,ee]=K.useState(!1),[J,k]=K.useState(!1),W=$e(),{zIndex:H=_.zIndex,sourceX:B,sourceY:A,targetX:j,targetY:F,sourcePosition:C,targetPosition:z}=Ie(K.useCallback(ve=>{const me=ve.nodeLookup.get(_.source),ke=ve.nodeLookup.get(_.target);if(!me||!ke)return bh;const Ce=Cw({id:t,sourceNode:me,targetNode:ke,sourceHandle:_.sourceHandle||null,targetHandle:_.targetHandle||null,connectionMode:ve.connectionMode,onError:E}),Me=vw({selected:_.selected,zIndex:_.zIndex,sourceNode:me,targetNode:ke,elevateOnSelect:ve.elevateEdgesOnSelect,zIndexMode:ve.zIndexMode});return{...Ce||bh,zIndex:Me}},[_.source,_.target,_.sourceHandle,_.targetHandle,_.selected,_.zIndex,E]),Ve),ne=K.useMemo(()=>_.markerStart?`url('#${Ba(_.markerStart,S)}')`:void 0,[_.markerStart,S]),re=K.useMemo(()=>_.markerEnd?`url('#${Ba(_.markerEnd,S)}')`:void 0,[_.markerEnd,S]);if(_.hidden||B===null||A===null||j===null||F===null)return null;const $=ve=>{var Me;const{addSelectedEdges:me,unselectNodesAndEdges:ke,multiSelectionActive:Ce}=W.getState();Q&&(W.setState({nodesSelectionActive:!1}),_.selected&&Ce?(ke({nodes:[],edges:[_]}),(Me=te.current)==null||Me.blur()):me([t])),u&&u(ve,_)},se=c?ve=>{c(ve,{..._})}:void 0,ce=f?ve=>{f(ve,{..._})}:void 0,G=h?ve=>{h(ve,{..._})}:void 0,ue=p?ve=>{p(ve,{..._})}:void 0,pe=y?ve=>{y(ve,{..._})}:void 0,we=ve=>{var me;if(!L&&Tp.includes(ve.key)&&Q){const{unselectNodesAndEdges:ke,addSelectedEdges:Ce}=W.getState();ve.key==="Escape"?((me=te.current)==null||me.blur(),ke({edges:[_]})):Ce([t])}};return P.jsx("svg",{style:{zIndex:H},children:P.jsxs("g",{className:be(["react-flow__edge",`react-flow__edge-${U}`,_.className,N,{selected:_.selected,animated:_.animated,inactive:!Q&&!u,updating:Z,selectable:Q}]),onClick:$,onDoubleClick:se,onContextMenu:ce,onMouseEnter:G,onMouseMove:ue,onMouseLeave:pe,onKeyDown:V?we:void 0,tabIndex:V?0:void 0,role:_.ariaRole??(V?"group":"img"),"aria-roledescription":"edge","data-id":t,"data-testid":`rf__edge-${t}`,"aria-label":_.ariaLabel===null?void 0:_.ariaLabel||`Edge from ${_.source} to ${_.target}`,"aria-describedby":V?`${ag}-${S}`:void 0,ref:te,..._.domAttributes,children:[!J&&P.jsx(D,{id:t,source:_.source,target:_.target,type:_.type,selected:_.selected,animated:_.animated,selectable:Q,deletable:_.deletable??!0,label:_.label,labelStyle:_.labelStyle,labelShowBg:_.labelShowBg,labelBgStyle:_.labelBgStyle,labelBgPadding:_.labelBgPadding,labelBgBorderRadius:_.labelBgBorderRadius,sourceX:B,sourceY:A,targetX:j,targetY:F,sourcePosition:C,targetPosition:z,data:_.data,style:_.style,sourceHandleId:_.sourceHandle,targetHandleId:_.targetHandle,markerStart:ne,markerEnd:re,pathOptions:"pathOptions"in _?_.pathOptions:void 0,interactionWidth:_.interactionWidth}),X&&P.jsx(FS,{edge:_,isReconnectable:X,reconnectRadius:m,onReconnect:v,onReconnectStart:g,onReconnectEnd:w,sourceX:B,sourceY:A,targetX:j,targetY:F,sourcePosition:C,targetPosition:z,setUpdateHover:ee,setReconnecting:k})]})})}var VS=K.memo(HS);const BS=t=>({edgesFocusable:t.edgesFocusable,edgesReconnectable:t.edgesReconnectable,elementsSelectable:t.elementsSelectable,connectionMode:t.connectionMode,onError:t.onError});function Ag({defaultMarkerColor:t,onlyRenderVisibleElements:r,rfId:o,edgeTypes:l,noPanClassName:u,onReconnect:c,onEdgeContextMenu:f,onEdgeMouseEnter:h,onEdgeMouseMove:p,onEdgeMouseLeave:y,onEdgeClick:m,reconnectRadius:v,onEdgeDoubleClick:g,onReconnectStart:w,onReconnectEnd:S,disableKeyboardA11y:M}){const{edgesFocusable:N,edgesReconnectable:E,elementsSelectable:L,onError:_}=Ie(BS,Ve),I=CS(r);return P.jsxs("div",{className:"react-flow__edges",children:[P.jsx(zS,{defaultColor:t,rfId:o}),I.map(U=>P.jsx(VS,{id:U,edgesFocusable:N,edgesReconnectable:E,elementsSelectable:L,noPanClassName:u,onReconnect:c,onContextMenu:f,onMouseEnter:h,onMouseMove:p,onMouseLeave:y,onClick:m,reconnectRadius:v,onDoubleClick:g,onReconnectStart:w,onReconnectEnd:S,rfId:o,onError:_,edgeTypes:l,disableKeyboardA11y:M},U))]})}Ag.displayName="EdgeRenderer";const US=K.memo(Ag),Qh=t=>`translate(${t[0]}px,${t[1]}px) scale(${t[2]})`;function WS({children:t}){const r=$e(),o=K.useRef(null),[l]=K.useState(()=>r.getState().transform);return hg(()=>{let u=null;const c=()=>{const f=r.getState().transform;u&&f[0]===u[0]&&f[1]===u[1]&&f[2]===u[2]||(u=f,o.current&&(o.current.style.transform=Qh(f)))};return c(),r.subscribe(c)},[r]),P.jsx("div",{ref:o,className:"react-flow__viewport xyflow__viewport react-flow__container",style:{transform:Qh(l)},children:t})}function bS(t){const r=ac(),o=K.useRef(!1);K.useEffect(()=>{!o.current&&r.viewportInitialized&&t&&(setTimeout(()=>t(r),1),o.current=!0)},[t,r.viewportInitialized])}const YS=t=>{var r;return(r=t.panZoom)==null?void 0:r.syncViewport};function XS(t){const r=Ie(YS),o=$e();return K.useEffect(()=>{t&&(r==null||r(t),o.setState({transform:[t.x,t.y,t.zoom]}))},[t,r]),null}function QS(t){return t.connection.inProgress?{...t.connection,to:vo(t.connection.to,t.transform)}:{...t.connection}}function GS(t){return QS}function KS(t){const r=GS();return Ie(r,Ve)}const qS=t=>({nodesConnectable:t.nodesConnectable,isValid:t.connection.isValid,inProgress:t.connection.inProgress,width:t.width,height:t.height});function ZS({containerStyle:t,style:r,type:o,component:l}){const{nodesConnectable:u,width:c,height:f,isValid:h,inProgress:p}=Ie(qS,Ve);return!(c&&u&&p)?null:P.jsx("svg",{style:t,width:c,height:f,className:"react-flow__connectionline react-flow__container",children:P.jsx("g",{className:be(["react-flow__connection",Rp(h)]),children:P.jsx($g,{style:r,type:o,CustomComponent:l,isValid:h})})})}const $g=({style:t,type:r=Wn.Bezier,CustomComponent:o,isValid:l})=>{const{inProgress:u,from:c,fromNode:f,fromHandle:h,fromPosition:p,to:y,toNode:m,toHandle:v,toPosition:g,pointer:w}=KS();if(!u)return;if(o)return P.jsx(o,{connectionLineType:r,connectionLineStyle:t,fromNode:f,fromHandle:h,fromX:c.x,fromY:c.y,toX:y.x,toY:y.y,fromPosition:p,toPosition:g,connectionStatus:Rp(l),toNode:m,toHandle:v,pointer:w});let S="";const M={sourceX:c.x,sourceY:c.y,sourcePosition:p,targetX:y.x,targetY:y.y,targetPosition:g};switch(r){case Wn.Bezier:[S]=Yp(M);break;case Wn.SimpleBezier:[S]=Eg(M);break;case Wn.Step:[S]=Va({...M,borderRadius:0});break;case Wn.SmoothStep:[S]=Va(M);break;default:[S]=Qp(M)}return P.jsx("path",{d:S,fill:"none",className:"react-flow__connection-path",style:t})};$g.displayName="ConnectionLine";const JS={};function Gh(t=JS){K.useRef(t),$e(),K.useEffect(()=>{},[t])}function e_(){$e(),K.useRef(!1),K.useEffect(()=>{},[])}function Dg({nodeTypes:t,edgeTypes:r,onInit:o,onNodeClick:l,onEdgeClick:u,onNodeDoubleClick:c,onEdgeDoubleClick:f,onNodeMouseEnter:h,onNodeMouseMove:p,onNodeMouseLeave:y,onNodeContextMenu:m,onSelectionContextMenu:v,onSelectionStart:g,onSelectionEnd:w,connectionLineType:S,connectionLineStyle:M,connectionLineComponent:N,connectionLineContainerStyle:E,selectionKeyCode:L,selectionOnDrag:_,selectionMode:I,multiSelectionKeyCode:U,panActivationKeyCode:D,zoomActivationKeyCode:V,deleteKeyCode:X,onlyRenderVisibleElements:Q,elementsSelectable:te,defaultViewport:Z,translateExtent:ee,minZoom:J,maxZoom:k,preventScrolling:W,defaultMarkerColor:H,zoomOnScroll:B,zoomOnPinch:A,panOnScroll:j,panOnScrollSpeed:F,panOnScrollMode:C,zoomOnDoubleClick:z,panOnDrag:ne,autoPanOnSelection:re,onPaneClick:$,onPaneMouseEnter:se,onPaneMouseMove:ce,onPaneMouseLeave:G,onPaneScroll:ue,onPaneContextMenu:pe,paneClickDistance:we,nodeClickDistance:ve,onEdgeContextMenu:me,onEdgeMouseEnter:ke,onEdgeMouseMove:Ce,onEdgeMouseLeave:Me,reconnectRadius:Le,onReconnect:ot,onReconnectStart:ut,onReconnectEnd:Je,noDragClassName:et,noWheelClassName:sn,noPanClassName:Gt,disableKeyboardA11y:Kt,nodeExtent:at,rfId:Ct,viewport:yt,onViewportChange:Mt,nodesDraggable:wr}){return Gh(t),Gh(r),e_(),bS(o),XS(yt),P.jsx(mS,{onPaneClick:$,onPaneMouseEnter:se,onPaneMouseMove:ce,onPaneMouseLeave:G,onPaneContextMenu:pe,onPaneScroll:ue,paneClickDistance:we,deleteKeyCode:X,selectionKeyCode:L,selectionOnDrag:_,selectionMode:I,onSelectionStart:g,onSelectionEnd:w,multiSelectionKeyCode:U,panActivationKeyCode:D,zoomActivationKeyCode:V,elementsSelectable:te,zoomOnScroll:B,zoomOnPinch:A,zoomOnDoubleClick:z,panOnScroll:j,panOnScrollSpeed:F,panOnScrollMode:C,panOnDrag:ne,autoPanOnSelection:re,defaultViewport:Z,translateExtent:ee,minZoom:J,maxZoom:k,onSelectionContextMenu:v,preventScrolling:W,noDragClassName:et,noWheelClassName:sn,noPanClassName:Gt,disableKeyboardA11y:Kt,onViewportChange:Mt,isControlledViewport:!!yt,children:P.jsxs(WS,{children:[P.jsx(US,{edgeTypes:r,onEdgeClick:u,onEdgeDoubleClick:f,onReconnect:ot,onReconnectStart:ut,onReconnectEnd:Je,onlyRenderVisibleElements:Q,onEdgeContextMenu:me,onEdgeMouseEnter:ke,onEdgeMouseMove:Ce,onEdgeMouseLeave:Me,reconnectRadius:Le,defaultMarkerColor:H,noPanClassName:Gt,disableKeyboardA11y:Kt,rfId:Ct}),P.jsx(ZS,{style:M,type:S,component:N,containerStyle:E}),P.jsx("div",{className:"react-flow__edgelabel-renderer"}),P.jsx(NS,{nodeTypes:t,onNodeClick:l,onNodeDoubleClick:c,onNodeMouseEnter:h,onNodeMouseMove:p,onNodeMouseLeave:y,onNodeContextMenu:m,nodeClickDistance:ve,onlyRenderVisibleElements:Q,noPanClassName:Gt,noDragClassName:et,disableKeyboardA11y:Kt,nodeExtent:at,rfId:Ct,nodesDraggable:wr}),P.jsx("div",{className:"react-flow__viewport-portal"})]})})}Dg.displayName="GraphView";const t_=K.memo(Dg),n_=Fp(),Kh=({nodes:t,edges:r,defaultNodes:o,defaultEdges:l,width:u,height:c,fitView:f,fitViewOptions:h,minZoom:p=.5,maxZoom:y=2,nodeOrigin:m,nodeExtent:v,zIndexMode:g="basic"}={})=>{const w=new Map,S=new Map,M=new Map,N=new Map,E=l??r??[],L=o??t??[],_=m??[0,0],I=v??so;qp(M,N,E);const{nodesInitialized:U}=Ua(L,w,S,{nodeOrigin:_,nodeExtent:I,zIndexMode:g});let D=[0,0,1];if(f&&u&&c){const V=mo(w,{filter:Z=>!!((Z.width||Z.initialWidth)&&(Z.height||Z.initialHeight))}),{x:X,y:Q,zoom:te}=nc(V,u,c,p,y,(h==null?void 0:h.padding)??.1);D=[X,Q,te]}return{rfId:"1",width:u??0,height:c??0,transform:D,nodes:L,nodesInitialized:U,nodeLookup:w,parentLookup:S,edges:E,edgeLookup:N,connectionLookup:M,onNodesChange:null,onEdgesChange:null,hasDefaultNodes:o!==void 0,hasDefaultEdges:l!==void 0,panZoom:null,minZoom:p,maxZoom:y,translateExtent:so,nodeExtent:I,nodesSelectionActive:!1,userSelectionActive:!1,userSelectionRect:null,connectionMode:ni.Strict,domNode:null,paneDragging:!1,noPanClassName:"nopan",nodeOrigin:_,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:f??!1,fitViewOptions:h,fitViewResolver:null,connection:{...Lp},connectionClickStartHandle:null,connectOnClick:!0,ariaLiveMessage:"",autoPanOnConnect:!0,autoPanOnNodeDrag:!0,autoPanOnNodeFocus:!0,autoPanSpeed:15,connectionRadius:20,onError:n_,isValidConnection:void 0,onSelectionChangeHandlers:[],lib:"react",debug:!1,ariaLabelConfig:zp,zIndexMode:g,onNodesChangeMiddlewareMap:new Map,onEdgesChangeMiddlewareMap:new Map}},r_=({nodes:t,edges:r,defaultNodes:o,defaultEdges:l,width:u,height:c,fitView:f,fitViewOptions:h,minZoom:p,maxZoom:y,nodeOrigin:m,nodeExtent:v,zIndexMode:g})=>g1((w,S)=>{async function M(){const{nodeLookup:N,panZoom:E,fitViewOptions:L,fitViewResolver:_,width:I,height:U,minZoom:D,maxZoom:V}=S();E&&(await fw({nodes:N,width:I,height:U,panZoom:E,minZoom:D,maxZoom:V},L),_==null||_.resolve(!0),w({fitViewResolver:null}))}return{...Kh({nodes:t,edges:r,width:u,height:c,fitView:f,fitViewOptions:h,minZoom:p,maxZoom:y,nodeOrigin:m,nodeExtent:v,defaultNodes:o,defaultEdges:l,zIndexMode:g}),setNodes:N=>{const{nodeLookup:E,parentLookup:L,nodeOrigin:_,nodeExtent:I,elevateNodesOnSelect:U,fitViewQueued:D,zIndexMode:V,nodesSelectionActive:X}=S(),{nodesInitialized:Q,hasSelectedNodes:te}=Ua(N,E,L,{nodeOrigin:_,nodeExtent:I,elevateNodesOnSelect:U,checkEquality:!0,zIndexMode:V}),Z=X&&te;D&&Q?(M(),w({nodes:N,nodesInitialized:Q,fitViewQueued:!1,fitViewOptions:void 0,nodesSelectionActive:Z})):w({nodes:N,nodesInitialized:Q,nodesSelectionActive:Z})},setEdges:N=>{const{connectionLookup:E,edgeLookup:L}=S();qp(E,L,N),w({edges:N})},setDefaultNodesAndEdges:(N,E)=>{if(N){const{setNodes:L}=S();L(N),w({hasDefaultNodes:!0})}if(E){const{setEdges:L}=S();L(E),w({hasDefaultEdges:!0})}},updateNodeInternals:N=>{const{triggerNodeChanges:E,nodeLookup:L,parentLookup:_,domNode:I,nodeOrigin:U,nodeExtent:D,debug:V,fitViewQueued:X,zIndexMode:Q}=S(),{changes:te,updatedInternals:Z}=jw(N,L,_,I,U,D,Q);Z&&(Tw(L,_,{nodeOrigin:U,nodeExtent:D,zIndexMode:Q}),X?(M(),w({fitViewQueued:!1,fitViewOptions:void 0})):w({}),(te==null?void 0:te.length)>0&&(V&&console.log("React Flow: trigger node changes",te),E==null||E(te)))},updateNodePositions:(N,E=!1)=>{const L=[];let _=[];const{nodeLookup:I,triggerNodeChanges:U,connection:D,updateConnection:V,onNodesChangeMiddlewareMap:X}=S();for(const[Q,te]of N){const Z=I.get(Q),ee=!!(Z!=null&&Z.expandParent&&(Z!=null&&Z.parentId)&&(te!=null&&te.position)),J={id:Q,type:"position",position:ee?{x:Math.max(0,te.position.x),y:Math.max(0,te.position.y)}:te.position,dragging:E};if(Z&&D.inProgress&&D.fromNode.id===Z.id){const k=xr(Z,D.fromHandle,xe.Left,!0);V({...D,from:k})}ee&&Z.parentId&&L.push({id:Q,parentId:Z.parentId,rect:{...te.internals.positionAbsolute,width:te.measured.width??0,height:te.measured.height??0}}),_.push(J)}if(L.length>0){const{parentLookup:Q,nodeOrigin:te}=S(),Z=uc(L,I,Q,te);_.push(...Z)}for(const Q of X.values())_=Q(_);U(_)},triggerNodeChanges:N=>{const{onNodesChange:E,setNodes:L,nodes:_,hasDefaultNodes:I,debug:U}=S();if(N!=null&&N.length){if(I){const D=$1(N,_);L(D)}U&&console.log("React Flow: trigger node changes",N),E==null||E(N)}},triggerEdgeChanges:N=>{const{onEdgesChange:E,setEdges:L,edges:_,hasDefaultEdges:I,debug:U}=S();if(N!=null&&N.length){if(I){const D=D1(N,_);L(D)}U&&console.log("React Flow: trigger edge changes",N),E==null||E(N)}},addSelectedNodes:N=>{const{multiSelectionActive:E,edgeLookup:L,nodeLookup:_,triggerNodeChanges:I,triggerEdgeChanges:U}=S();if(E){const D=N.map(V=>fr(V,!0));I(D);return}I(qr(_,new Set([...N]),!0)),U(qr(L))},addSelectedEdges:N=>{const{multiSelectionActive:E,edgeLookup:L,nodeLookup:_,triggerNodeChanges:I,triggerEdgeChanges:U}=S();if(E){const D=N.map(V=>fr(V,!0));U(D);return}U(qr(L,new Set([...N]))),I(qr(_,new Set,!0))},unselectNodesAndEdges:({nodes:N,edges:E}={})=>{const{edges:L,nodes:_,nodeLookup:I,triggerNodeChanges:U,triggerEdgeChanges:D}=S(),V=N||_,X=E||L,Q=[];for(const Z of V){if(!Z.selected)continue;const ee=I.get(Z.id);ee&&(ee.selected=!1),Q.push(fr(Z.id,!1))}const te=[];for(const Z of X)Z.selected&&te.push(fr(Z.id,!1));U(Q),D(te)},setMinZoom:N=>{const{panZoom:E,maxZoom:L}=S();E==null||E.setScaleExtent([N,L]),w({minZoom:N})},setMaxZoom:N=>{const{panZoom:E,minZoom:L}=S();E==null||E.setScaleExtent([L,N]),w({maxZoom:N})},setTranslateExtent:N=>{var E;(E=S().panZoom)==null||E.setTranslateExtent(N),w({translateExtent:N})},resetSelectedElements:()=>{const{edges:N,nodes:E,triggerNodeChanges:L,triggerEdgeChanges:_,elementsSelectable:I}=S();if(!I)return;const U=E.reduce((V,X)=>X.selected?[...V,fr(X.id,!1)]:V,[]),D=N.reduce((V,X)=>X.selected?[...V,fr(X.id,!1)]:V,[]);L(U),_(D)},setNodeExtent:N=>{const{nodes:E,nodeLookup:L,parentLookup:_,nodeOrigin:I,elevateNodesOnSelect:U,nodeExtent:D,zIndexMode:V}=S();N[0][0]===D[0][0]&&N[0][1]===D[0][1]&&N[1][0]===D[1][0]&&N[1][1]===D[1][1]||(Ua(E,L,_,{nodeOrigin:I,nodeExtent:N,elevateNodesOnSelect:U,checkEquality:!1,zIndexMode:V}),w({nodeExtent:N}))},panBy:N=>{const{transform:E,width:L,height:_,panZoom:I,translateExtent:U}=S();return Aw({delta:N,panZoom:I,transform:E,translateExtent:U,width:L,height:_})},setCenter:async(N,E,L)=>{const{width:_,height:I,maxZoom:U,panZoom:D}=S();if(!D)return!1;const V=typeof(L==null?void 0:L.zoom)<"u"?L.zoom:U;return await D.setViewport({x:_/2-N*V,y:I/2-E*V,zoom:V},{duration:L==null?void 0:L.duration,ease:L==null?void 0:L.ease,interpolate:L==null?void 0:L.interpolate}),!0},cancelConnection:()=>{w({connection:{...Lp}})},updateConnection:N=>{w({connection:N})},reset:()=>w({...Kh()})}},Object.is);function i_({initialNodes:t,initialEdges:r,defaultNodes:o,defaultEdges:l,initialWidth:u,initialHeight:c,initialMinZoom:f,initialMaxZoom:h,initialFitViewOptions:p,fitView:y,nodeOrigin:m,nodeExtent:v,zIndexMode:g,children:w}){const[S]=K.useState(()=>r_({nodes:t,edges:r,defaultNodes:o,defaultEdges:l,width:u,height:c,fitView:y,minZoom:f,maxZoom:h,fitViewOptions:p,nodeOrigin:m,nodeExtent:v,zIndexMode:g}));return P.jsx(m1,{value:S,children:P.jsx(B1,{children:P.jsx(rS,{children:w})})})}function o_({children:t,nodes:r,edges:o,defaultNodes:l,defaultEdges:u,width:c,height:f,fitView:h,fitViewOptions:p,minZoom:y,maxZoom:m,nodeOrigin:v,nodeExtent:g,zIndexMode:w}){return K.useContext(yl)?P.jsx(P.Fragment,{children:t}):P.jsx(i_,{initialNodes:r,initialEdges:o,defaultNodes:l,defaultEdges:u,initialWidth:c,initialHeight:f,fitView:h,initialFitViewOptions:p,initialMinZoom:y,initialMaxZoom:m,nodeOrigin:v,nodeExtent:g,zIndexMode:w,children:t})}const s_={width:"100%",height:"100%",overflow:"hidden",position:"relative",zIndex:0};function l_({nodes:t,edges:r,defaultNodes:o,defaultEdges:l,className:u,nodeTypes:c,edgeTypes:f,onNodeClick:h,onEdgeClick:p,onInit:y,onMove:m,onMoveStart:v,onMoveEnd:g,onConnect:w,onConnectStart:S,onConnectEnd:M,onClickConnectStart:N,onClickConnectEnd:E,onNodeMouseEnter:L,onNodeMouseMove:_,onNodeMouseLeave:I,onNodeContextMenu:U,onNodeDoubleClick:D,onNodeDragStart:V,onNodeDrag:X,onNodeDragStop:Q,onNodesDelete:te,onEdgesDelete:Z,onDelete:ee,onSelectionChange:J,onSelectionDragStart:k,onSelectionDrag:W,onSelectionDragStop:H,onSelectionContextMenu:B,onSelectionStart:A,onSelectionEnd:j,onBeforeDelete:F,connectionMode:C,connectionLineType:z=Wn.Bezier,connectionLineStyle:ne,connectionLineComponent:re,connectionLineContainerStyle:$,deleteKeyCode:se="Backspace",selectionKeyCode:ce="Shift",selectionOnDrag:G=!1,selectionMode:ue=lo.Full,panActivationKeyCode:pe="Space",multiSelectionKeyCode:we=ao()?"Meta":"Control",zoomActivationKeyCode:ve=ao()?"Meta":"Control",snapToGrid:me,snapGrid:ke,onlyRenderVisibleElements:Ce=!1,selectNodesOnDrag:Me,nodesDraggable:Le,autoPanOnNodeFocus:ot,nodesConnectable:ut,nodesFocusable:Je,nodeOrigin:et=cg,edgesFocusable:sn,edgesReconnectable:Gt,elementsSelectable:Kt=!0,defaultViewport:at=I1,minZoom:Ct=.5,maxZoom:yt=2,translateExtent:Mt=so,preventScrolling:wr=!0,nodeExtent:ln,defaultMarkerColor:Yn="#b1b1b7",zoomOnScroll:Sl=!0,zoomOnPinch:xo=!0,panOnScroll:wo=!1,panOnScrollSpeed:_l=.5,panOnScrollMode:si=pr.Free,zoomOnDoubleClick:li=!0,panOnDrag:ui=!0,onPaneClick:ai,onPaneMouseEnter:ci,onPaneMouseMove:wn,onPaneMouseLeave:Sn,onPaneScroll:So,onPaneContextMenu:_o,paneClickDistance:Eo=1,nodeClickDistance:ko=0,children:No,onReconnect:fi,onReconnectStart:Co,onReconnectEnd:Xn,onEdgeContextMenu:di,onEdgeDoubleClick:Qn,onEdgeMouseEnter:El,onEdgeMouseMove:Gn,onEdgeMouseLeave:Sr,reconnectRadius:_r=10,onNodesChange:hi,onEdgesChange:kl,noDragClassName:Nl="nodrag",noWheelClassName:Cl="nowheel",noPanClassName:qt="nopan",fitView:pi,fitViewOptions:gi,connectOnClick:Ml,attributionPosition:Mo,proOptions:Po,defaultEdgeOptions:Io,elevateNodesOnSelect:To=!0,elevateEdgesOnSelect:Pl=!1,disableKeyboardA11y:zo=!1,autoPanOnConnect:Oe,autoPanOnNodeDrag:Il,autoPanOnSelection:mi=!0,autoPanSpeed:Lo,connectionRadius:Er,isValidConnection:Tl,onError:Ro,style:kr,id:vt,nodeDragThreshold:zl,connectionDragThreshold:xt,viewport:Ll,onViewportChange:Rl,width:jl,height:Nr,colorMode:Cr="light",debug:Kn,onScroll:un,ariaLabelConfig:Al,zIndexMode:jo="basic",...yi},Ao){const qn=vt||"1",Zn=R1(Cr),$l=K.useCallback(Mr=>{Mr.currentTarget.scrollTo({top:0,left:0,behavior:"instant"}),un==null||un(Mr)},[un]);return P.jsx("div",{"data-testid":"rf__wrapper",...yi,onScroll:$l,style:{...kr,...s_},ref:Ao,className:be(["react-flow",u,Zn]),id:vt,role:"application",children:P.jsxs(o_,{nodes:t,edges:r,width:jl,height:Nr,fitView:pi,fitViewOptions:gi,minZoom:Ct,maxZoom:yt,nodeOrigin:et,nodeExtent:ln,zIndexMode:jo,children:[P.jsx(L1,{nodes:t,edges:r,defaultNodes:o,defaultEdges:l,onConnect:w,onConnectStart:S,onConnectEnd:M,onClickConnectStart:N,onClickConnectEnd:E,nodesDraggable:Le,autoPanOnNodeFocus:ot,nodesConnectable:ut,nodesFocusable:Je,edgesFocusable:sn,edgesReconnectable:Gt,elementsSelectable:Kt,elevateNodesOnSelect:To,elevateEdgesOnSelect:Pl,minZoom:Ct,maxZoom:yt,nodeExtent:ln,onNodesChange:hi,onEdgesChange:kl,snapToGrid:me,snapGrid:ke,connectionMode:C,translateExtent:Mt,connectOnClick:Ml,defaultEdgeOptions:Io,fitView:pi,fitViewOptions:gi,onNodesDelete:te,onEdgesDelete:Z,onDelete:ee,onNodeDragStart:V,onNodeDrag:X,onNodeDragStop:Q,onSelectionDrag:W,onSelectionDragStart:k,onSelectionDragStop:H,onMove:m,onMoveStart:v,onMoveEnd:g,noPanClassName:qt,nodeOrigin:et,rfId:qn,autoPanOnConnect:Oe,autoPanOnNodeDrag:Il,autoPanSpeed:Lo,onError:Ro,connectionRadius:Er,isValidConnection:Tl,selectNodesOnDrag:Me,nodeDragThreshold:zl,connectionDragThreshold:xt,onBeforeDelete:F,debug:Kn,ariaLabelConfig:Al,zIndexMode:jo}),P.jsx(t_,{onInit:y,onNodeClick:h,onEdgeClick:p,onNodeMouseEnter:L,onNodeMouseMove:_,onNodeMouseLeave:I,onNodeContextMenu:U,onNodeDoubleClick:D,nodeTypes:c,edgeTypes:f,connectionLineType:z,connectionLineStyle:ne,connectionLineComponent:re,connectionLineContainerStyle:$,selectionKeyCode:ce,selectionOnDrag:G,selectionMode:ue,deleteKeyCode:se,multiSelectionKeyCode:we,panActivationKeyCode:pe,zoomActivationKeyCode:ve,onlyRenderVisibleElements:Ce,defaultViewport:at,translateExtent:Mt,minZoom:Ct,maxZoom:yt,preventScrolling:wr,zoomOnScroll:Sl,zoomOnPinch:xo,zoomOnDoubleClick:li,panOnScroll:wo,panOnScrollSpeed:_l,panOnScrollMode:si,panOnDrag:ui,autoPanOnSelection:mi,onPaneClick:ai,onPaneMouseEnter:ci,onPaneMouseMove:wn,onPaneMouseLeave:Sn,onPaneScroll:So,onPaneContextMenu:_o,paneClickDistance:Eo,nodeClickDistance:ko,onSelectionContextMenu:B,onSelectionStart:A,onSelectionEnd:j,onReconnect:fi,onReconnectStart:Co,onReconnectEnd:Xn,onEdgeContextMenu:di,onEdgeDoubleClick:Qn,onEdgeMouseEnter:El,onEdgeMouseMove:Gn,onEdgeMouseLeave:Sr,reconnectRadius:_r,defaultMarkerColor:Yn,noDragClassName:Nl,noWheelClassName:Cl,noPanClassName:qt,rfId:qn,disableKeyboardA11y:zo,nodeExtent:ln,viewport:Ll,onViewportChange:Rl,nodesDraggable:Le}),P.jsx(P1,{onSelectionChange:J}),No,P.jsx(E1,{proOptions:Po,position:Mo}),P.jsx(_1,{rfId:qn,disableKeyboardA11y:zo})]})})}var u_=dg(l_);function a_({dimensions:t,lineWidth:r,variant:o,className:l}){return P.jsx("path",{strokeWidth:r,d:`M${t[0]/2} 0 V${t[1]} M0 ${t[1]/2} H${t[0]}`,className:be(["react-flow__background-pattern",o,l])})}function c_({radius:t,className:r}){return P.jsx("circle",{cx:t,cy:t,r:t,className:be(["react-flow__background-pattern","dots",r])})}var bn;(function(t){t.Lines="lines",t.Dots="dots",t.Cross="cross"})(bn||(bn={}));const f_={[bn.Dots]:1,[bn.Lines]:1,[bn.Cross]:6},d_=t=>({transform:t.transform,patternId:`pattern-${t.rfId}`});function Og({id:t,variant:r=bn.Dots,gap:o=20,size:l,lineWidth:u=1,offset:c=0,color:f,bgColor:h,style:p,className:y,patternClassName:m}){const v=K.useRef(null),{transform:g,patternId:w}=Ie(d_,Ve),S=l||f_[r],M=r===bn.Dots,N=r===bn.Cross,E=Array.isArray(o)?o:[o,o],L=[E[0]*g[2]||1,E[1]*g[2]||1],_=S*g[2],I=Array.isArray(c)?c:[c,c],U=N?[_,_]:L,D=[I[0]*g[2]+U[0]/2,I[1]*g[2]+U[1]/2],V=`${w}${t||""}`;return P.jsxs("svg",{className:be(["react-flow__background",y]),style:{...p,...xl,"--xy-background-color-props":h,"--xy-background-pattern-color-props":f},ref:v,"data-testid":"rf__background",children:[P.jsx("pattern",{id:V,x:g[0]%L[0],y:g[1]%L[1],width:L[0],height:L[1],patternUnits:"userSpaceOnUse",patternTransform:`translate(-${D[0]},-${D[1]})`,children:M?P.jsx(c_,{radius:_/2,className:m}):P.jsx(a_,{dimensions:U,lineWidth:u,variant:r,className:m})}),P.jsx("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:`url(#${V})`})]})}Og.displayName="Background";const h_=K.memo(Og);function p_(){return P.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32",children:P.jsx("path",{d:"M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z"})})}function g_(){return P.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 5",children:P.jsx("path",{d:"M0 0h32v4.2H0z"})})}function m_(){return P.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 30",children:P.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 y_(){return P.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:P.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 v_(){return P.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:P.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 bs({children:t,className:r,...o}){return P.jsx("button",{type:"button",className:be(["react-flow__controls-button",r]),...o,children:t})}const x_=t=>({isInteractive:t.nodesDraggable||t.nodesConnectable||t.elementsSelectable,minZoomReached:t.transform[2]<=t.minZoom,maxZoomReached:t.transform[2]>=t.maxZoom,ariaLabelConfig:t.ariaLabelConfig});function Fg({style:t,showZoom:r=!0,showFitView:o=!0,showInteractive:l=!0,fitViewOptions:u,onZoomIn:c,onZoomOut:f,onFitView:h,onInteractiveChange:p,className:y,children:m,position:v="bottom-left",orientation:g="vertical","aria-label":w}){const S=$e(),{isInteractive:M,minZoomReached:N,maxZoomReached:E,ariaLabelConfig:L}=Ie(x_,Ve),{zoomIn:_,zoomOut:I,fitView:U}=ac(),D=()=>{_(),c==null||c()},V=()=>{I(),f==null||f()},X=()=>{U(u),h==null||h()},Q=()=>{S.setState({nodesDraggable:!M,nodesConnectable:!M,elementsSelectable:!M}),p==null||p(!M)},te=g==="horizontal"?"horizontal":"vertical";return P.jsxs(vl,{className:be(["react-flow__controls",te,y]),position:v,style:t,"data-testid":"rf__controls","aria-label":w??L["controls.ariaLabel"],children:[r&&P.jsxs(P.Fragment,{children:[P.jsx(bs,{onClick:D,className:"react-flow__controls-zoomin",title:L["controls.zoomIn.ariaLabel"],"aria-label":L["controls.zoomIn.ariaLabel"],disabled:E,children:P.jsx(p_,{})}),P.jsx(bs,{onClick:V,className:"react-flow__controls-zoomout",title:L["controls.zoomOut.ariaLabel"],"aria-label":L["controls.zoomOut.ariaLabel"],disabled:N,children:P.jsx(g_,{})})]}),o&&P.jsx(bs,{className:"react-flow__controls-fitview",onClick:X,title:L["controls.fitView.ariaLabel"],"aria-label":L["controls.fitView.ariaLabel"],children:P.jsx(m_,{})}),l&&P.jsx(bs,{className:"react-flow__controls-interactive",onClick:Q,title:L["controls.interactive.ariaLabel"],"aria-label":L["controls.interactive.ariaLabel"],children:M?P.jsx(v_,{}):P.jsx(y_,{})}),m]})}Fg.displayName="Controls";const w_=K.memo(Fg);function S_({id:t,x:r,y:o,width:l,height:u,style:c,color:f,strokeColor:h,strokeWidth:p,className:y,borderRadius:m,shapeRendering:v,selected:g,onClick:w}){const{background:S,backgroundColor:M}=c||{},N=f||S||M;return P.jsx("rect",{className:be(["react-flow__minimap-node",{selected:g},y]),x:r,y:o,rx:m,ry:m,width:l,height:u,style:{fill:N,stroke:h,strokeWidth:p},shapeRendering:v,onClick:w?E=>w(E,t):void 0})}const __=K.memo(S_),E_=t=>t.nodes.map(r=>r.id),Ta=t=>t instanceof Function?t:()=>t;function k_({nodeStrokeColor:t,nodeColor:r,nodeClassName:o="",nodeBorderRadius:l=5,nodeStrokeWidth:u,nodeComponent:c=__,onClick:f}){const h=Ie(E_,Ve),p=Ta(r),y=Ta(t),m=Ta(o),v=typeof window>"u"||window.chrome?"crispEdges":"geometricPrecision";return P.jsx(P.Fragment,{children:h.map(g=>P.jsx(C_,{id:g,nodeColorFunc:p,nodeStrokeColorFunc:y,nodeClassNameFunc:m,nodeBorderRadius:l,nodeStrokeWidth:u,NodeComponent:c,onClick:f,shapeRendering:v},g))})}function N_({id:t,nodeColorFunc:r,nodeStrokeColorFunc:o,nodeClassNameFunc:l,nodeBorderRadius:u,nodeStrokeWidth:c,shapeRendering:f,NodeComponent:h,onClick:p}){const{node:y,x:m,y:v,width:g,height:w}=Ie(S=>{const M=S.nodeLookup.get(t);if(!M)return{node:void 0,x:0,y:0,width:0,height:0};const N=M.internals.userNode,{x:E,y:L}=M.internals.positionAbsolute,{width:_,height:I}=Qt(N);return{node:N,x:E,y:L,width:_,height:I}},Ve);return!y||y.hidden||!Hp(y)?null:P.jsx(h,{x:m,y:v,width:g,height:w,style:y.style,selected:!!y.selected,className:l(y),color:r(y),borderRadius:u,strokeColor:o(y),strokeWidth:c,shapeRendering:f,onClick:p,id:y.id})}const C_=K.memo(N_);var M_=K.memo(k_);const P_=200,I_=150,T_=t=>!t.hidden,z_=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?Dp(mo(t.nodeLookup,{filter:T_}),r):r,rfId:t.rfId,panZoom:t.panZoom,translateExtent:t.translateExtent,flowWidth:t.width,flowHeight:t.height,ariaLabelConfig:t.ariaLabelConfig}},qh=(t,r)=>t.x===r.x&&t.y===r.y&&t.width===r.width&&t.height===r.height,L_=(t,r)=>qh(t.viewBB,r.viewBB)&&qh(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,R_="react-flow__minimap-desc";function Hg({style:t,className:r,nodeStrokeColor:o,nodeColor:l,nodeClassName:u="",nodeBorderRadius:c=5,nodeStrokeWidth:f,nodeComponent:h,bgColor:p,maskColor:y,maskStrokeColor:m,maskStrokeWidth:v,position:g="bottom-right",onClick:w,onNodeClick:S,pannable:M=!1,zoomable:N=!1,ariaLabel:E,inversePan:L,zoomStep:_=1,offsetScale:I=5}){const U=$e(),D=K.useRef(null),{boundingRect:V,viewBB:X,rfId:Q,panZoom:te,translateExtent:Z,flowWidth:ee,flowHeight:J,ariaLabelConfig:k}=Ie(z_,L_),W=(t==null?void 0:t.width)??P_,H=(t==null?void 0:t.height)??I_,B=V.width/W,A=V.height/H,j=Math.max(B,A),F=j*W,C=j*H,z=I*j,ne=V.x-(F-V.width)/2-z,re=V.y-(C-V.height)/2-z,$=F+z*2,se=C+z*2,ce=`${R_}-${Q}`,G=K.useRef(0),ue=K.useRef();G.current=j,K.useEffect(()=>{if(D.current&&te)return ue.current=Ww({domNode:D.current,panZoom:te,getTransform:()=>U.getState().transform,getViewScale:()=>G.current}),()=>{var me;(me=ue.current)==null||me.destroy()}},[te]),K.useEffect(()=>{var me;(me=ue.current)==null||me.update({translateExtent:Z,width:ee,height:J,inversePan:L,pannable:M,zoomStep:_,zoomable:N})},[M,N,L,_,Z,ee,J]);const pe=w?me=>{var Me;const[ke,Ce]=((Me=ue.current)==null?void 0:Me.pointer(me))||[0,0];w(me,{x:ke,y:Ce})}:void 0,we=S?K.useCallback((me,ke)=>{const Ce=U.getState().nodeLookup.get(ke).internals.userNode;S(me,Ce)},[]):void 0,ve=E??k["minimap.ariaLabel"];return P.jsx(vl,{position:g,style:{...t,"--xy-minimap-background-color-props":typeof p=="string"?p:void 0,"--xy-minimap-mask-background-color-props":typeof y=="string"?y:void 0,"--xy-minimap-mask-stroke-color-props":typeof m=="string"?m:void 0,"--xy-minimap-mask-stroke-width-props":typeof v=="number"?v*j:void 0,"--xy-minimap-node-background-color-props":typeof l=="string"?l:void 0,"--xy-minimap-node-stroke-color-props":typeof o=="string"?o:void 0,"--xy-minimap-node-stroke-width-props":typeof f=="number"?f:void 0},className:be(["react-flow__minimap",r]),"data-testid":"rf__minimap",children:P.jsxs("svg",{width:W,height:H,viewBox:`${ne} ${re} ${$} ${se}`,className:"react-flow__minimap-svg",role:"img","aria-labelledby":ce,ref:D,onClick:pe,children:[ve&&P.jsx("title",{id:ce,children:ve}),P.jsx(M_,{onClick:we,nodeColor:l,nodeStrokeColor:o,nodeBorderRadius:c,nodeClassName:u,nodeStrokeWidth:f,nodeComponent:h}),P.jsx("path",{className:"react-flow__minimap-mask",d:`M${ne-z},${re-z}h${$+z*2}v${se+z*2}h${-$-z*2}z - M${X.x},${X.y}h${X.width}v${X.height}h${-X.width}z`,fillRule:"evenodd",pointerEvents:"none"})]})})}Hg.displayName="MiniMap";const j_=K.memo(Hg),A_=t=>r=>t?`${Math.max(1/r.transform[2],1)}`:void 0,$_={[oi.Line]:"right",[oi.Handle]:"bottom-right"};function D_({nodeId:t,position:r,variant:o=oi.Handle,className:l,style:u=void 0,children:c,color:f,minWidth:h=10,minHeight:p=10,maxWidth:y=Number.MAX_VALUE,maxHeight:m=Number.MAX_VALUE,keepAspectRatio:v=!1,resizeDirection:g,autoScale:w=!0,shouldResize:S,onResizeStart:M,onResize:N,onResizeEnd:E}){const L=yg(),_=typeof t=="string"?t:L,I=$e(),U=K.useRef(null),D=o===oi.Handle,V=Ie(K.useCallback(A_(D&&w),[D,w]),Ve),X=K.useRef(null),Q=r??$_[o];K.useEffect(()=>{if(!(!U.current||!_))return X.current||(X.current=r1({domNode:U.current,nodeId:_,getStoreItems:()=>{const{nodeLookup:Z,transform:ee,snapGrid:J,snapToGrid:k,nodeOrigin:W,domNode:H}=I.getState();return{nodeLookup:Z,transform:ee,snapGrid:J,snapToGrid:k,nodeOrigin:W,paneDomNode:H}},onChange:(Z,ee)=>{const{triggerNodeChanges:J,nodeLookup:k,parentLookup:W,nodeOrigin:H}=I.getState(),B=[],A={x:Z.x,y:Z.y},j=k.get(_);if(j&&j.expandParent&&j.parentId){const F=j.origin??H,C=Z.width??j.measured.width??0,z=Z.height??j.measured.height??0,ne={id:j.id,parentId:j.parentId,rect:{width:C,height:z,...Vp({x:Z.x??j.position.x,y:Z.y??j.position.y},{width:C,height:z},j.parentId,k,F)}},re=uc([ne],k,W,H);B.push(...re),A.x=Z.x?Math.max(F[0]*C,Z.x):void 0,A.y=Z.y?Math.max(F[1]*z,Z.y):void 0}if(A.x!==void 0&&A.y!==void 0){const F={id:_,type:"position",position:{...A}};B.push(F)}if(Z.width!==void 0&&Z.height!==void 0){const C={id:_,type:"dimensions",resizing:!0,setAttributes:g?g==="horizontal"?"width":"height":!0,dimensions:{width:Z.width,height:Z.height}};B.push(C)}for(const F of ee){const C={...F,type:"position"};B.push(C)}J(B)},onEnd:({width:Z,height:ee})=>{const J={id:_,type:"dimensions",resizing:!1,dimensions:{width:Z,height:ee}};I.getState().triggerNodeChanges([J])}})),X.current.update({controlPosition:Q,boundaries:{minWidth:h,minHeight:p,maxWidth:y,maxHeight:m},keepAspectRatio:v,resizeDirection:g,onResizeStart:M,onResize:N,onResizeEnd:E,shouldResize:S}),()=>{var Z;(Z=X.current)==null||Z.destroy()}},[Q,h,p,y,m,v,M,N,E,S]);const te=Q.split("-");return P.jsx("div",{className:be(["react-flow__resize-control","nodrag",...te,o,l]),ref:U,style:{...u,scale:V,...f&&{[D?"backgroundColor":"borderColor"]:f}},children:c})}K.memo(D_);const O_={"arch.context":0,"django.app":0,"django.route":1,"django.url_name":1,"django.view":2,"django.viewset_action":2,"django.permission":2,"django.serializer":3,"django.serializer_field":4,"django.service":4,"django.model":5,"django.field":6,"django.relation":6,"django.task":7,"django.receiver":7,"django.signal":7,"django.test":7,"django.migration_op":7,"django.admin":7,"openapi.path":8,"react.api_client":9,"react.query_key":10,"react.hook":10,"react.feature":10,"react.route":11,"react.page":11,"react.component":12,"react.form_schema":13,"react.test":13,"react.context":12};function F_(t){return O_[t]??8}function H_(t){const r=new Map;for(const l of t){const u=F_(l.type),c=r.get(u)??[];c.push(l),r.set(u,c)}const o=new Map;for(const[l,u]of r)u.sort((c,f)=>c.name.localeCompare(f.name)),u.forEach((c,f)=>{o.set(c.id,{x:l*240,y:f*92})});return o}const V_={cheap:"#4a5568",expensive:"#f4a261",critical:"#e85d04"};function B_({data:t}){return P.jsxs("div",{className:"lp-node",children:[P.jsx("div",{className:"t",children:t.type.split(".").pop()}),P.jsx("div",{className:"n",children:t.name})]})}const U_={load:B_};function za({nodes:t,edges:r}){const o=H_(t),l=t.map(c=>({id:c.id,type:"load",position:o.get(c.id)??{x:0,y:0},data:{name:c.name,type:c.type,file:c.file_path}})),u=r.filter(c=>t.some(f=>f.id===c.src)&&t.some(f=>f.id===c.dst)).map(c=>({id:c.id,source:c.src,target:c.dst,animated:c.weight==="critical",style:{stroke:V_[c.weight]||"#4a5568",strokeWidth:c.weight==="critical"?2.4:1.2,strokeDasharray:c.confidence<.8?"6 4":void 0},label:c.type.replaceAll("_"," "),labelStyle:{fill:"#8b9bb0",fontSize:9}}));return P.jsxs(u_,{nodes:l,edges:u,nodeTypes:U_,fitView:!0,minZoom:.2,"data-testid":"impact-graph",children:[P.jsx(h_,{}),P.jsx(j_,{pannable:!0,zoomable:!0}),P.jsx(w_,{})]})}function W_(){var re;const[t,r]=K.useState("review"),[o,l]=K.useState(localStorage.getItem("loadpath.repo")||""),[u,c]=K.useState("HEAD~1"),[f,h]=K.useState("HEAD"),[p,y]=K.useState(null),[m,v]=K.useState(null),[g,w]=K.useState([]),[S,M]=K.useState("review"),[N,E]=K.useState(""),[L,_]=K.useState(""),[I,U]=K.useState({}),[D,V]=K.useState([]),[X,Q]=K.useState(""),[te,Z]=K.useState("github"),[ee,J]=K.useState("");K.useEffect(()=>{Vt.settings().then(U).catch(()=>{}),Vt.repos().then($=>w($.repos)).catch(()=>{})},[]),K.useEffect(()=>{t!=="architecture"||!o||Vt.architecture(o).then(v).catch(()=>{})},[t,o]);const k=$=>{l($),localStorage.setItem("loadpath.repo",$)},W=async($=o)=>{if(!$)return null;const se=await Vt.architecture($);return v(se),se},H=async()=>{E(""),_("Tracing load path…"),k(o);try{const $=await Vt.review(o,u,f,!0);y($),M("review"),r("review"),await Vt.repos().then(se=>w(se.repos)).catch(()=>{}),await W(o)}catch($){E($ instanceof Error?$.message:String($))}finally{_("")}},B=async($=!0)=>{E(""),_($?"Indexing…":"Full reindex…"),k(o);try{await Vt.index(o,$);const se=await W(o);await Vt.repos().then(ce=>w(ce.repos)).catch(()=>{}),se!=null&&se.indexed&&(M("architecture"),r("architecture"))}catch(se){E(se instanceof Error?se.message:String(se))}finally{_("")}},A=async()=>{E(""),_("Fetching pull requests…");try{const $=await Vt.prs(te,X);V($.pull_requests)}catch($){E($ instanceof Error?$.message:String($))}finally{_("")}},j=async $=>{$.preventDefault();const se=new FormData($.currentTarget),ce={github_token:String(se.get("github_token")||""),bitbucket_token:String(se.get("bitbucket_token")||""),bitbucket_username:String(se.get("bitbucket_username")||""),ai_provider:String(se.get("ai_provider")||"none"),ai_api_key:String(se.get("ai_api_key")||""),ai_model:String(se.get("ai_model")||""),ai_base_url:String(se.get("ai_base_url")||""),workspaces:g.length?g.map(G=>({path:G.path,name:G.name})):o?[{path:o,name:o.split(/[\\/]/).pop()}]:[]};U(await Vt.saveSettings(ce))},F=async()=>{if(p){_("Residual analysis…");try{const $=await Vt.residual(p);J($.note)}catch($){E($ instanceof Error?$.message:String($))}finally{_("")}}},C=K.useMemo(()=>S==="architecture"?(m==null?void 0:m.nodes)??[]:(p==null?void 0:p.nodes)??[],[S,m,p]),z=K.useMemo(()=>S==="architecture"?(m==null?void 0:m.edges)??[]:(p==null?void 0:p.edges)??[],[S,m,p]),ne=p!=null&&p.index?`${p.index.counts.nodes} nodes / ${p.index.counts.edges} edges · ${p.index.incremental?"incremental":"full"}`:m!=null&&m.indexed?`${m.counts.nodes} nodes / ${m.counts.edges} edges indexed`:"Not indexed";return P.jsxs("div",{className:"app",children:[P.jsxs("nav",{className:"rail","data-testid":"rail",children:[P.jsx("div",{className:"brand",children:"Loadpath"}),P.jsx("button",{"data-testid":"tab-review",className:t==="review"?"active":"",onClick:()=>r("review"),children:"Review"}),P.jsx("button",{"data-testid":"tab-architecture",className:t==="architecture"?"active":"",onClick:()=>r("architecture"),children:"Architecture"}),P.jsx("button",{"data-testid":"tab-graph",className:t==="graph"?"active":"",onClick:()=>r("graph"),children:"Impact graph"}),P.jsx("button",{"data-testid":"tab-prs",className:t==="prs"?"active":"",onClick:()=>r("prs"),children:"Pull requests"}),P.jsx("button",{"data-testid":"tab-settings",className:t==="settings"?"active":"",onClick:()=>r("settings"),children:"Settings"}),P.jsx("div",{style:{flex:1}}),P.jsx("div",{className:"muted",children:L||ne})]}),P.jsxs("div",{className:"main",children:[P.jsxs("div",{className:"topbar","data-testid":"topbar",children:[g.length>0?P.jsxs("select",{"data-testid":"workspace-select",value:g.some($=>$.path===o)?o:"",onChange:$=>{$.target.value&&k($.target.value)},children:[P.jsx("option",{value:"",children:"Indexed repos…"}),g.map($=>P.jsxs("option",{value:$.path,children:[$.name,$.indexed?` (${$.counts.nodes})`:""]},$.path))]}):null,P.jsx("input",{"data-testid":"repo-path",className:"path",placeholder:"Local monorepo path",value:o,onChange:$=>l($.target.value)}),P.jsx("input",{"data-testid":"base-ref",value:u,onChange:$=>c($.target.value),placeholder:"base"}),P.jsx("input",{"data-testid":"head-ref",value:f,onChange:$=>h($.target.value),placeholder:"head"}),P.jsx("button",{"data-testid":"btn-index",onClick:()=>B(!0),children:"Index"}),P.jsx("button",{"data-testid":"btn-review",className:"btn primary",onClick:H,children:"Review"})]}),N?P.jsx("div",{className:"error",children:N}):null,t==="review"&&P.jsxs("div",{className:"content","data-testid":"review-layout",children:[P.jsx("aside",{className:"brief","data-testid":"brief",children:p?P.jsxs(P.Fragment,{children:[P.jsxs("div",{className:`level ${p.confidence.level}`,children:[p.confidence.level.toUpperCase()," — ",p.title]}),p.low_risk?P.jsx("span",{className:"chip",children:"loadpath:low-risk"}):null,p.change_kinds.map($=>P.jsx("span",{className:"chip",children:$.replaceAll("_"," ")},$)),P.jsx("pre",{className:"headline",children:p.headline}),p.index?P.jsxs(P.Fragment,{children:[P.jsx("div",{className:"kicker",children:"Index"}),P.jsxs("div",{className:"muted",children:["Walked ",p.index.counts.nodes," nodes / ",p.index.counts.edges," edges",p.index.reindexed?" after an incremental refresh":" from the existing index","."]})]}):null,P.jsx("div",{className:"kicker",children:"Read this"}),p.read_order.map($=>P.jsxs("div",{children:[P.jsx("span",{className:"file",children:$.path}),P.jsx("div",{className:"muted",children:$.why})]},$.path)),P.jsx("div",{className:"kicker",children:"Clusters"}),p.clusters.map($=>P.jsxs("div",{className:"muted",children:[P.jsx("strong",{children:$.title})," — ",$.files.join(", ")]},$.id)),P.jsx("div",{className:"kicker",children:"Architecture"}),p.findings.filter($=>!$.waived).length===0?P.jsx("div",{className:"muted",children:p.architecture_note}):p.findings.filter($=>!$.waived).map($=>P.jsxs("div",{className:"muted",children:[P.jsx("span",{className:`chip ${$.severity}`,children:$.severity}),$.message]},$.rule+$.message)),P.jsx("div",{className:"kicker",children:"Residual (AI only here)"}),p.residuals.map($=>P.jsx("div",{className:"muted",children:$},$)),P.jsx("button",{className:"btn",onClick:F,style:{marginTop:12},children:"Ask configured model"}),ee?P.jsx("pre",{className:"headline",children:ee}):null,P.jsx("div",{className:"kicker",children:"Reviewers"}),P.jsx("div",{className:"muted",children:p.suggested_reviewers.join(", ")||"—"})]}):P.jsxs("p",{className:"muted",children:["Index a Django + React monorepo with ",P.jsx("code",{children:"loadpath.yml"}),", inspect architecture, then review a git range against that graph."]})}),P.jsx("div",{className:"graph-wrap","data-testid":"review-graph",children:p?P.jsx(za,{nodes:p.nodes,edges:p.edges}):null})]}),t==="architecture"&&P.jsxs("div",{className:"content","data-testid":"architecture-panel",children:[P.jsx("aside",{className:"brief","data-testid":"architecture-brief",children:m!=null&&m.indexed?P.jsxs(P.Fragment,{children:[P.jsxs("div",{className:"level high",children:["INDEXED — ",m.counts.nodes," nodes"]}),P.jsxs("span",{className:"chip",children:[m.counts.edges," edges"]}),m.has_config?P.jsx("span",{className:"chip",children:"loadpath.yml"}):null,P.jsxs("div",{className:"muted",style:{marginTop:8},children:[m.indexed_at?`Last index ${m.indexed_at}`:"Indexed",m.incremental?" · incremental":" · full"]}),P.jsx("div",{className:"kicker",children:"Bounded contexts"}),Object.values(m.contexts).map($=>P.jsxs("div",{className:"muted",children:[P.jsx("strong",{children:$.name})," — ",($.django_apps||[]).join(", ")||"no apps"," ·"," ",($.owners||[]).join(", ")||"unowned"]},$.name)),P.jsx("div",{className:"kicker",children:"Rules"}),(m.rules||[]).map($=>P.jsx("div",{className:"muted",children:$},$)),P.jsx("div",{className:"kicker",children:"Findings on the indexed graph"}),m.findings.filter($=>!$.waived).length===0?P.jsx("div",{className:"muted",children:"No architecture rule hits on the full graph."}):m.findings.filter($=>!$.waived).map($=>P.jsxs("div",{className:"muted",children:[P.jsx("span",{className:`chip ${$.severity}`,children:$.severity}),$.message]},$.rule+$.message)),P.jsx("div",{className:"kicker",children:"Types"}),P.jsx("div",{className:"muted",children:Object.entries(m.type_counts||{}).sort(($,se)=>se[1]-$[1]).slice(0,12).map(([$,se])=>`${$.split(".").pop()} ${se}`).join(" · ")}),P.jsx("button",{className:"btn",style:{marginTop:12},onClick:()=>B(!1),"data-testid":"btn-full-reindex",children:"Full reindex"}),P.jsx("button",{className:"btn primary",style:{marginTop:8},onClick:H,children:"Review against this index"})]}):P.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."})}),P.jsx("div",{className:"graph-wrap","data-testid":"architecture-graph",children:m!=null&&m.indexed?P.jsx(za,{nodes:m.nodes,edges:m.edges}):null})]}),t==="graph"&&P.jsxs("div",{className:"graph-wrap","data-testid":"graph-full",style:{height:"100%",display:"flex",flexDirection:"column"},children:[P.jsxs("div",{className:"graph-modes",children:[P.jsx("button",{"data-testid":"graph-mode-review",className:S==="review"?"active":"",onClick:()=>M("review"),children:"This review"}),P.jsx("button",{"data-testid":"graph-mode-architecture",className:S==="architecture"?"active":"",onClick:()=>M("architecture"),children:"Indexed architecture"})]}),C.length?P.jsx("div",{style:{flex:1,minHeight:0},children:P.jsx(za,{nodes:C,edges:z})}):P.jsx("p",{className:"muted",children:"Index the repo or run a review first."})]}),t==="prs"&&P.jsxs("div",{className:"pr-list","data-testid":"pr-list",children:[P.jsxs("div",{className:"topbar",style:{border:0,padding:0,marginBottom:12},children:[P.jsxs("select",{"data-testid":"pr-provider",value:te,onChange:$=>Z($.target.value),children:[P.jsx("option",{value:"github",children:"GitHub"}),P.jsx("option",{value:"bitbucket",children:"Bitbucket"})]}),P.jsx("input",{"data-testid":"pr-repo",className:"path",placeholder:"owner/repo",value:X,onChange:$=>Q($.target.value)}),P.jsx("button",{"data-testid":"btn-list-prs",onClick:A,children:"List PRs"})]}),D.map($=>P.jsxs("article",{className:"pr","data-testid":`pr-${$.number}`,children:[P.jsxs("h3",{children:["#",$.number," ",$.title]}),P.jsxs("div",{className:"muted",children:[$.author," · ",$.source_branch," → ",$.target_branch," · ",$.provider]}),P.jsxs("a",{href:$.url,target:"_blank",rel:"noreferrer",children:["Open on ",$.provider]}),P.jsx("div",{children:P.jsx("button",{className:"btn",onClick:()=>{c($.target_branch),h($.source_branch),r("review")},children:"Review this branch range"})})]},`${$.provider}-${$.number}`))]}),t==="settings"&&P.jsxs("form",{className:"settings","data-testid":"settings-form",onSubmit:j,children:[P.jsx("h1",{children:"Keys & providers"}),P.jsx("p",{className:"muted",children:"Tokens stay on this machine in ~/.loadpath/settings.json. GitHub and Bitbucket power the PR list. Indexed repos are remembered as workspaces. AI is used only for residual uncertainty the graph could not close."}),P.jsx("label",{children:"GitHub token"}),P.jsx("input",{name:"github_token",type:"password",placeholder:"ghp_…"}),P.jsx("label",{children:"Bitbucket token"}),P.jsx("input",{name:"bitbucket_token",type:"password"}),P.jsx("label",{children:"Bitbucket username (app passwords)"}),P.jsx("input",{name:"bitbucket_username",defaultValue:String(I.bitbucket_username||"")}),P.jsx("label",{children:"AI provider"}),P.jsxs("select",{name:"ai_provider",defaultValue:String(((re=I.ai)==null?void 0:re.provider)||"none"),children:[P.jsx("option",{value:"none",children:"none (graph only)"}),P.jsx("option",{value:"anthropic",children:"Anthropic"}),P.jsx("option",{value:"openai",children:"OpenAI"}),P.jsx("option",{value:"grok",children:"Grok / xAI"}),P.jsx("option",{value:"deepseek",children:"DeepSeek"}),P.jsx("option",{value:"cursor",children:"Cursor-compatible (OpenAI protocol)"}),P.jsx("option",{value:"ollama",children:"Ollama local"})]}),P.jsx("label",{children:"AI API key"}),P.jsx("input",{name:"ai_api_key",type:"password"}),P.jsx("label",{children:"Model"}),P.jsx("input",{name:"ai_model",placeholder:"optional override"}),P.jsx("label",{children:"Base URL"}),P.jsx("input",{name:"ai_base_url",placeholder:"optional, OpenAI-compatible"}),P.jsx("button",{className:"btn primary",type:"submit",children:"Save"})]})]})]})}M0.createRoot(document.getElementById("root")).render(P.jsx(K.StrictMode,{children:P.jsx(W_,{})})); diff --git a/src/loadpath/static/index.html b/src/loadpath/static/index.html index 7f0bb02..ce9e10a 100644 --- a/src/loadpath/static/index.html +++ b/src/loadpath/static/index.html @@ -7,7 +7,7 @@ - + diff --git a/tests/e2e/test_ui_screenshots.py b/tests/e2e/test_ui_screenshots.py index c901273..25994a1 100644 --- a/tests/e2e/test_ui_screenshots.py +++ b/tests/e2e/test_ui_screenshots.py @@ -13,9 +13,6 @@ from loadpath.server.app import create_app from tests.conftest import prepare_review_repo -SCREENSHOT_DIR = Path(__file__).resolve().parents[2] / "docs" / "screenshots" -PRETTY_REPO = Path("/tmp/acme-billing") - def _free_port() -> int: sock = socket.socket() @@ -32,9 +29,8 @@ def live_app(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Iterator[tuple[ monkeypatch.setenv("HOME", str(tmp_path / "home")) (tmp_path / "home").mkdir() repo = prepare_review_repo(tmp_path) - if PRETTY_REPO.exists(): - shutil.rmtree(PRETTY_REPO) - shutil.copytree(repo, PRETTY_REPO) + pretty = tmp_path / "acme-billing" + shutil.copytree(repo, pretty) port = _free_port() server = uvicorn.Server( uvicorn.Config(create_app(), host="127.0.0.1", port=port, log_level="warning") @@ -48,12 +44,10 @@ def live_app(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Iterator[tuple[ if not server.started: pytest.skip("uvicorn failed to start") try: - yield f"http://127.0.0.1:{port}", PRETTY_REPO + yield f"http://127.0.0.1:{port}", pretty finally: server.should_exit = True thread.join(timeout=5) - if PRETTY_REPO.exists(): - shutil.rmtree(PRETTY_REPO, ignore_errors=True) def _playwright_page(): @@ -92,7 +86,7 @@ def test_ui_review_graph_prs_settings(live_app, tmp_path: Path): page.get_by_test_id("base-ref").fill("HEAD~1") page.get_by_test_id("head-ref").fill("HEAD") - dest = Path(os.environ.get("LOADPATH_SCREENSHOT_DIR", str(SCREENSHOT_DIR))) + dest = Path(os.environ.get("LOADPATH_SCREENSHOT_DIR", str(tmp_path / "shots"))) dest.mkdir(parents=True, exist_ok=True) with page.expect_response( diff --git a/tests/unit/test_django_extractors.py b/tests/unit/test_django_extractors.py index 28a1f87..204dff8 100644 --- a/tests/unit/test_django_extractors.py +++ b/tests/unit/test_django_extractors.py @@ -214,6 +214,27 @@ def test_get_model_string_ref_is_residual(): assert any("get_model" in r for r in g.residuals) +def test_enqueue_resolves_foreign_app_task(): + src = """ +from rest_framework.viewsets import ModelViewSet +from accounts.tasks import notify_user + +class InvoiceViewSet(ModelViewSet): + def create(self, request): + notify_user.delay(1) +""" + g = extract_django_file("backend/billing/views.py", src, _cfg()) + edges = [e for e in g.edges if e.type.value == "enqueues"] + assert edges + assert any(e.dst == "django.task:accounts.notify_user" for e in edges) + + +def test_discover_settings_uses_django_root(): + from loadpath.extractors.django_boot import _discover_settings_module + + assert _discover_settings_module(FIXTURE, "backend") == "config.settings" + + def test_cross_app_model_import_on_view(): src = """ from rest_framework.views import APIView diff --git a/tests/unit/test_index_and_stitch.py b/tests/unit/test_index_and_stitch.py index dc448ea..73cc2ec 100644 --- a/tests/unit/test_index_and_stitch.py +++ b/tests/unit/test_index_and_stitch.py @@ -33,6 +33,39 @@ def test_index_is_incremental(tmp_path: Path): assert first["nodes"] == second["nodes"] +def test_incremental_index_drops_deleted_files(tmp_path: Path): + import shutil + + root = tmp_path / "repo" + shutil.copytree(FIXTURE, root) + db = tmp_path / "g.sqlite3" + store = index_repo(root, db_path=db, incremental=False) + assert any(n["name"] == "InvoicePage" for n in store.nodes()) + store.close() + (root / "frontend/src/features/billing/InvoicePage.tsx").unlink() + store = index_repo(root, db_path=db, incremental=True) + assert not any(n["name"] == "InvoicePage" for n in store.nodes()) + store.close() + + +def test_incremental_reindex_keeps_enqueue_edges(tmp_path: Path): + import shutil + + root = tmp_path / "repo" + shutil.copytree(FIXTURE, root) + db = tmp_path / "g.sqlite3" + store = index_repo(root, db_path=db, incremental=False) + before = [e for e in store.edges() if e["type"] == "enqueues"] + assert before + store.close() + tasks = root / "backend/billing/tasks.py" + tasks.write_text(tasks.read_text() + "\n# touch\n") + store = index_repo(root, db_path=db, incremental=True) + after = [e for e in store.edges() if e["type"] == "enqueues"] + assert len(after) >= len(before) + store.close() + + def test_contexts_assigned(tmp_path: Path): store = index_repo(FIXTURE, db_path=tmp_path / "g.sqlite3", incremental=False) invoice = next(n for n in store.nodes([NodeType.MODEL]) if n["name"] == "Invoice") diff --git a/tests/unit/test_providers_and_api.py b/tests/unit/test_providers_and_api.py index b5cbb1c..1236c80 100644 --- a/tests/unit/test_providers_and_api.py +++ b/tests/unit/test_providers_and_api.py @@ -73,3 +73,13 @@ def test_health_and_settings(tmp_path, monkeypatch): assert body["github_token_set"] is True assert "secret" not in body["github_token"] assert body["ai"]["provider"] == "anthropic" + kept = c.put("/api/settings", json={"github_token": "", "bitbucket_token": "", "ai_api_key": ""}) + assert kept.json()["github_token_set"] is True + + +def test_github_rejects_unsafe_repo_slug(): + import pytest + + gh = GitHubProvider("tok") + with pytest.raises(ValueError): + gh.list_pull_requests("../etc/passwd") diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 4e235d5..f3e781f 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -1,4 +1,4 @@ -import { useEffect, useMemo, useState } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; import { api } from "./api"; import { ImpactGraph } from "./ImpactGraph"; import type { ArchitectureReport, IndexedRepo, PullRequest, Review } from "./types"; @@ -22,6 +22,8 @@ export function App() { const [scmRepo, setScmRepo] = useState(""); const [provider, setProvider] = useState("github"); const [aiNote, setAiNote] = useState(""); + const repoRef = useRef(repo); + repoRef.current = repo; useEffect(() => { api.settings().then(setSettings).catch(() => undefined); @@ -30,7 +32,17 @@ export function App() { useEffect(() => { if (tab !== "architecture" || !repo) return; - api.architecture(repo).then(setArchitecture).catch(() => undefined); + const requested = repo; + let cancelled = false; + api + .architecture(requested) + .then((report) => { + if (!cancelled && repoRef.current === requested) setArchitecture(report); + }) + .catch(() => undefined); + return () => { + cancelled = true; + }; }, [tab, repo]); const persistRepo = (path: string) => { @@ -41,7 +53,7 @@ export function App() { const loadArchitecture = async (path = repo) => { if (!path) return null; const report = await api.architecture(path); - setArchitecture(report); + if (repoRef.current === path) setArchitecture(report); return report; }; diff --git a/ui/src/ImpactGraph.tsx b/ui/src/ImpactGraph.tsx index 78015c2..56bc856 100644 --- a/ui/src/ImpactGraph.tsx +++ b/ui/src/ImpactGraph.tsx @@ -1,4 +1,4 @@ -import { Background, Controls, MiniMap, ReactFlow, type Edge, type Node } from "@xyflow/react"; +import { Background, Controls, MiniMap, ReactFlow, ReactFlowProvider, type Edge, type Node } from "@xyflow/react"; import "@xyflow/react/dist/style.css"; import { layoutNodes, type GraphEdge, type GraphNode } from "./types"; @@ -44,10 +44,12 @@ export function ImpactGraph({ nodes, edges }: { nodes: GraphNode[]; edges: Graph })); return ( - - - - - + + + + + + + ); }

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 ec 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 Z1MII)_$PULb_?3Mq;vIR;rUyS{ts7u8kztA literal 0 HcmV?d00001 diff --git a/fixtures/demo_monorepo/backend/billing/actors.py b/fixtures/demo_monorepo/backend/billing/actors.py new file mode 100644 index 0000000..5f224a3 --- /dev/null +++ b/fixtures/demo_monorepo/backend/billing/actors.py @@ -0,0 +1,15 @@ +import dramatiq + +from billing.models import Invoice + + +@dramatiq.actor +def rebuild_ledger(invoice_id): + invoice = Invoice.objects.get(pk=invoice_id) + return str(invoice.total) + + +class NotifyCustomer(dramatiq.GenericActor): + def perform(self, invoice_id): + invoice = Invoice.objects.get(pk=invoice_id) + return invoice.status diff --git a/fixtures/demo_monorepo/backend/billing/api.py b/fixtures/demo_monorepo/backend/billing/api.py new file mode 100644 index 0000000..4f0afa6 --- /dev/null +++ b/fixtures/demo_monorepo/backend/billing/api.py @@ -0,0 +1,11 @@ +from ninja import Router + +from billing.models import Invoice + +router = Router() + + +@router.get("/invoices/{invoice_id}/ledger") +def invoice_ledger(request, invoice_id: int): + invoice = Invoice.objects.get(pk=invoice_id) + return {"total": str(invoice.total)} diff --git a/fixtures/demo_monorepo/backend/billing/management/__init__.py b/fixtures/demo_monorepo/backend/billing/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/fixtures/demo_monorepo/backend/billing/management/commands/__init__.py b/fixtures/demo_monorepo/backend/billing/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/fixtures/demo_monorepo/backend/billing/management/commands/resend_invoices.py b/fixtures/demo_monorepo/backend/billing/management/commands/resend_invoices.py new file mode 100644 index 0000000..739964e --- /dev/null +++ b/fixtures/demo_monorepo/backend/billing/management/commands/resend_invoices.py @@ -0,0 +1,12 @@ +from django.core.management.base import BaseCommand + +from billing.models import Invoice +from billing.tasks import send_invoice_email + + +class Command(BaseCommand): + help = "Re-send invoice emails" + + def handle(self, *args, **options): + for invoice in Invoice.objects.all(): + send_invoice_email.delay(invoice.id) diff --git a/fixtures/demo_monorepo/backend/billing/models.py b/fixtures/demo_monorepo/backend/billing/models.py index bae1123..a77e229 100644 --- a/fixtures/demo_monorepo/backend/billing/models.py +++ b/fixtures/demo_monorepo/backend/billing/models.py @@ -6,6 +6,7 @@ class Invoice(models.Model): total = models.DecimalField(max_digits=10, decimal_places=2) status = models.CharField(max_length=32, default="draft") created_at = models.DateTimeField(auto_now_add=True) + account = models.ForeignKey("accounts.UserProfile", null=True, on_delete=models.SET_NULL) class Meta: app_label = "billing" diff --git a/fixtures/demo_monorepo/backend/billing/tasks.py b/fixtures/demo_monorepo/backend/billing/tasks.py index ccbfbae..9452170 100644 --- a/fixtures/demo_monorepo/backend/billing/tasks.py +++ b/fixtures/demo_monorepo/backend/billing/tasks.py @@ -1,9 +1,32 @@ -from celery import shared_task +from celery import Task, chain, current_app, shared_task +from django.db import transaction from billing.models import Invoice -@shared_task +@shared_task(bind=False) def send_invoice_email(invoice_id): invoice = Invoice.objects.get(pk=invoice_id) return invoice.total + + +@shared_task +def apply_credit(invoice_id): + Invoice.objects.filter(pk=invoice_id).update(status="credited") + + +class RecalcTotals(Task): + name = "billing.recalc_totals" + + def run(self, invoice_id): + invoice = Invoice.objects.get(pk=invoice_id) + return invoice.total + + +def enqueue_email(invoice_id): + transaction.on_commit(lambda: send_invoice_email.apply_async(args=[invoice_id])) + + +def settle_invoice(invoice_id): + chain(apply_credit.s(invoice_id), send_invoice_email.si(invoice_id)).delay() + current_app.send_task("billing.tasks.send_invoice_email", args=[invoice_id]) diff --git a/fixtures/demo_monorepo/backend/billing/urls.py b/fixtures/demo_monorepo/backend/billing/urls.py index 42c0cb5..d25e864 100644 --- a/fixtures/demo_monorepo/backend/billing/urls.py +++ b/fixtures/demo_monorepo/backend/billing/urls.py @@ -1,13 +1,14 @@ from django.urls import include, path from rest_framework.routers import DefaultRouter -from billing.views import InvoiceViewSet +from billing.views import InvoiceViewSet, invoice_totals router = DefaultRouter() router.register("invoices", InvoiceViewSet, basename="invoice") urlpatterns = [ path("", include(router.urls)), + path("invoices/totals/", invoice_totals, name="invoice-totals"), path( "invoices//", InvoiceViewSet.as_view({"get": "retrieve", "put": "update"}), diff --git a/fixtures/demo_monorepo/backend/billing/views.py b/fixtures/demo_monorepo/backend/billing/views.py index f1c49b2..d5f8a2c 100644 --- a/fixtures/demo_monorepo/backend/billing/views.py +++ b/fixtures/demo_monorepo/backend/billing/views.py @@ -1,17 +1,36 @@ from rest_framework import viewsets +from rest_framework.decorators import api_view, permission_classes from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response +from billing.actors import rebuild_ledger from billing.models import Invoice from billing.serializers import InvoiceSerializer from billing.tasks import send_invoice_email +class InvoiceFilter: + """Stand-in for django-filter FilterSet (parsed as filterset_class).""" + + class InvoiceViewSet(viewsets.ModelViewSet): serializer_class = InvoiceSerializer permission_classes = [IsAuthenticated] + filterset_class = InvoiceFilter queryset = Invoice.objects.all() + def get_queryset(self): + return Invoice.objects.select_related() + def perform_create(self, serializer): invoice = serializer.save() send_invoice_email.delay(invoice.id) + rebuild_ledger.send(invoice.id) + rebuild_ledger.send_with_options(args=(invoice.id,)) return invoice + + +@api_view(["GET"]) +@permission_classes([IsAuthenticated]) +def invoice_totals(request): + return Response({"count": Invoice.objects.count()}) diff --git a/fixtures/demo_monorepo/backend/config/__init__.py b/fixtures/demo_monorepo/backend/config/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/fixtures/demo_monorepo/backend/config/settings.py b/fixtures/demo_monorepo/backend/config/settings.py new file mode 100644 index 0000000..0c0b095 --- /dev/null +++ b/fixtures/demo_monorepo/backend/config/settings.py @@ -0,0 +1,21 @@ +from pathlib import Path + +BASE_DIR = Path(__file__).resolve().parents[1] + +SECRET_KEY = "loadpath-demo-not-for-production" +DEBUG = True +INSTALLED_APPS = [ + "django.contrib.contenttypes", + "django.contrib.auth", + "billing", + "accounts", +] +DATABASES = {"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}} +USE_TZ = True +ROOT_URLCONF = "config.urls" +CELERY_BEAT_SCHEDULE = { + "credit-stale-invoices": { + "task": "billing.tasks.apply_credit", + "schedule": 3600, + } +} diff --git a/fixtures/demo_monorepo/loadpath.yml b/fixtures/demo_monorepo/loadpath.yml index 12ad543..30f8bec 100644 --- a/fixtures/demo_monorepo/loadpath.yml +++ b/fixtures/demo_monorepo/loadpath.yml @@ -29,3 +29,4 @@ django_root: backend react_root: frontend/src openapi_paths: - openapi.yaml +boot_django: false diff --git a/loadpath.yml.example b/loadpath.yml.example index 33c8e8b..1a2368f 100644 --- a/loadpath.yml.example +++ b/loadpath.yml.example @@ -27,3 +27,4 @@ rules: django_root: backend react_root: frontend/src openapi_paths: [] +boot_django: false diff --git a/pyproject.toml b/pyproject.toml index 383d15f..fe8fb9b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,6 +27,7 @@ dev = [ "pytest>=8.3.0", "pytest-asyncio>=0.24.0", "respx>=0.21.0", + "playwright>=1.49.0", ] [project.scripts] @@ -42,9 +43,11 @@ loadpath = ["report/*.html", "static/**/*"] testpaths = ["tests"] pythonpath = ["src"] addopts = "-q --tb=short" +markers = [ + "playwright: UI tests that need Chromium", +] filterwarnings = [ "ignore::DeprecationWarning", - "ignore:Using `httpx` with `starlette.testclient`:DeprecationWarning", ] [tool.ruff] diff --git a/src/loadpath/architecture/rules.py b/src/loadpath/architecture/rules.py index cd4291d..5fef789 100644 --- a/src/loadpath/architecture/rules.py +++ b/src/loadpath/architecture/rules.py @@ -13,7 +13,8 @@ "react_feature_may_only_call_own_or_shared_api": "A React feature may only call its own public API or shared clients.", "serializers_are_the_only_published_contract": "Serializers (and OpenAPI) are the only published contract; React must not drift.", "no_queryset_in_serializer": "Serializers must not run querysets.", - "celery_tasks_must_be_idempotent_on_model_pk": "Celery tasks must take a model pk/id, not a full object payload.", + "celery_tasks_must_be_idempotent_on_model_pk": "Celery and Dramatiq tasks must take a model pk/id, not a full object payload.", + "async_tasks_must_be_idempotent_on_model_pk": "Celery and Dramatiq tasks must take a model pk/id, not a full object payload.", } @@ -60,7 +61,7 @@ def evaluate(store: GraphStore, config: LoadpathConfig, changed_ids: set[str] | findings.extend(_contract_drift(store, config)) if "no_queryset_in_serializer" in enabled: findings.extend(_queryset_in_serializer(store)) - if "celery_tasks_must_be_idempotent_on_model_pk" in enabled: + if "celery_tasks_must_be_idempotent_on_model_pk" in enabled or "async_tasks_must_be_idempotent_on_model_pk" in enabled: findings.extend(_task_idempotency(store, changed_ids)) for f in findings: @@ -265,17 +266,19 @@ def _task_idempotency(store: GraphStore, changed_ids: set[str] | None) -> list[F pass if extra.get("looks_idempotent_on_pk") is True: continue + broker = extra.get("broker") or "task" + label = {"celery": "Celery", "dramatiq": "Dramatiq"}.get(broker, "Async") out.append( Finding( rule="celery_tasks_must_be_idempotent_on_model_pk", severity=RuleSeverity.WARNING, message=( - f"Celery task {task['name']} args {args} do not look like a model pk; " + f"{label} task {task['name']} args {args} do not look like a model pk; " "tasks must be idempotent on model pk" ), node_id=task["id"], file_path=task.get("file_path"), - extra={"args": args}, + extra={"args": args, "broker": broker}, ) ) return out diff --git a/src/loadpath/config.py b/src/loadpath/config.py index cff1896..a6e9c6e 100644 --- a/src/loadpath/config.py +++ b/src/loadpath/config.py @@ -52,6 +52,7 @@ class LoadpathConfig: ] ) extra: dict[str, Any] = field(default_factory=dict) + boot_django: bool = False def context_for_django_app(self, app: str) -> str | None: for name, ctx in self.contexts.items(): @@ -136,4 +137,5 @@ def load_config(repo_root: Path, config_path: Path | None = None) -> LoadpathCon ] ), extra=raw, + boot_django=bool(raw.get("boot_django", False)), ) diff --git a/src/loadpath/extractors/django.py b/src/loadpath/extractors/django.py index b225993..b903c65 100644 --- a/src/loadpath/extractors/django.py +++ b/src/loadpath/extractors/django.py @@ -32,7 +32,23 @@ SERIALIZER_BASES = {"Serializer", "ModelSerializer", "HyperlinkedModelSerializer", "ListSerializer"} MODEL_BASES = {"Model"} ADMIN_BASES = {"ModelAdmin", "StackedInline", "TabularInline"} -TASK_DECORATORS = {"shared_task", "task", "periodic_task"} +CELERY_DECORATORS = {"shared_task", "task", "periodic_task"} +DRAMATIQ_DECORATORS = {"actor"} +TASK_DECORATORS = CELERY_DECORATORS | DRAMATIQ_DECORATORS +CELERY_ENQUEUE = {"delay", "apply_async"} +CELERY_SIGNATURE = {"s", "si"} +CELERY_CANVAS = {"group", "chain", "chord", "signature"} +DRAMATIQ_ENQUEUE = {"send", "send_with_options"} +CELERY_TASK_BASES = {"Task"} +DRAMATIQ_TASK_BASES = {"GenericActor"} +NINJA_HTTP = {"get", "post", "put", "patch", "delete", "api_operation"} +REL_FIELD_TYPES = { + "ForeignKey", + "OneToOneField", + "ManyToManyField", + "GenericForeignKey", + "GenericRelation", +} SIGNAL_NAMES = { "pre_save", "post_save", @@ -198,6 +214,16 @@ def visit_ClassDef(self, node: ast.ClassDef) -> None: self._serializer(node) elif _has_base(node, DJANGO_VIEW_BASES) or node.name.endswith(("View", "ViewSet")): self._view(node) + elif any(b.split(".")[-1] in {"BaseCommand", "AppCommand", "LabelCommand"} for b in _bases(node)): + self.add_node( + NodeType.MANAGEMENT_COMMAND, + node.name if node.name != "Command" else Path(self.rel_path).stem, + f"{self.app}.{Path(self.rel_path).stem}", + node.lineno, + {"app": self.app}, + ) + elif self._task_class(node): + pass 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"): @@ -213,6 +239,8 @@ def visit_FunctionDef(self, node: ast.FunctionDef) -> None: self._maybe_command(node) self._maybe_test(node) self._maybe_service_fn(node) + self._maybe_fbv(node) + self._maybe_ninja(node) self.generic_visit(node) visit_AsyncFunctionDef = visit_FunctionDef # type: ignore[assignment] @@ -228,8 +256,27 @@ def visit_Call(self, node: ast.Call) -> None: pass elif short == "get_model": self._get_model(node) - elif short in {"delay", "apply_async"}: - self._enqueue(node, fname) + elif short in CELERY_ENQUEUE: + prefix = fname.rsplit(".", 1)[0] if "." in fname else "" + if prefix and prefix.split(".")[-1] not in CELERY_CANVAS: + self._enqueue(node, fname, broker="celery") + elif short in CELERY_SIGNATURE and self._looks_like_celery(fname): + self._enqueue(node, fname, broker="celery") + elif short in CELERY_CANVAS and self._looks_like_celery(fname): + self.graph.residuals.append(f"Celery canvas {fname}() at {self.rel_path}:{node.lineno}") + elif short == "send_task": + self._send_task(node) + elif short in DRAMATIQ_ENQUEUE and self._looks_like_dramatiq_send(fname): + self._enqueue(node, fname, broker="dramatiq") + elif short == "on_commit": + self.graph.residuals.append( + f"transaction.on_commit() at {self.rel_path}:{node.lineno} — async work may be hidden in a lambda" + ) + self._enqueue_from_on_commit(node) + elif short in {"raw", "execute"} or (short == "extra" and _kw(node, "where")): + self.graph.residuals.append(f"Raw SQL ({fname}) in {self.rel_path}:{node.lineno}") + elif short in {"select_related", "prefetch_related"}: + pass elif short == "connect" and any(s in fname for s in SIGNAL_NAMES | {"signal"}): self._signal_connect(node, fname) elif short == "reverse": @@ -243,6 +290,8 @@ def visit_Assign(self, node: ast.Assign) -> None: for elt in node.value.elts: if isinstance(elt, ast.Call): self.visit_Call(elt) + if isinstance(target, ast.Name) and target.id in {"CELERY_BEAT_SCHEDULE", "beat_schedule"}: + self._beat_schedule(node.value) self.generic_visit(node) def _model(self, node: ast.ClassDef) -> None: @@ -262,8 +311,14 @@ def _model(self, node: ast.ClassDef) -> None: if isinstance(stmt.value, ast.Call): call_name = _name(stmt.value.func) or "" extra["field_type"] = call_name.split(".")[-1] + extra["relation"] = extra["field_type"] in REL_FIELD_TYPES to_arg = stmt.value.args[0] if stmt.value.args else _kw(stmt.value, "to") rel_to = _const_str(to_arg) or _name(to_arg) + if isinstance(to_arg, ast.Constant) and isinstance(to_arg.value, str): + extra["string_ref"] = True + self.graph.residuals.append( + f'string model ref {to_arg.value} on {qname}.{fname} ({self.rel_path}:{stmt.lineno})' + ) od = _kw(stmt.value, "on_delete") on_delete = _name(od) extra["on_delete"] = on_delete.split(".")[-1] if on_delete else None @@ -273,14 +328,6 @@ def _model(self, node: ast.ClassDef) -> None: if rel_to: target = rel_to if "." in rel_to else f"{self.app}.{rel_to.split('.')[-1]}" rel_id = node_id(NodeType.MODEL, target) - rel_node = Node( - id=rel_id, - type=NodeType.MODEL, - name=target.split(".")[-1], - qualified_name=target, - extra={"placeholder": True}, - ) - self.graph.nodes.append(rel_node) self.add_edge( field_node.id, rel_id, @@ -369,6 +416,18 @@ def _view(self, node: ast.ClassDef) -> None: m = re.search(r"id='([A-Z][A-Za-z0-9_]+)'", dumped) if m: queryset_model = m.group(1) + elif key == "filterset_class": + extra["filterset"] = _name(stmt.value) + elif key == "authentication_classes": + extra["authentication"] = _list_names(stmt.value) + elif key == "pagination_class": + extra["pagination"] = _name(stmt.value) + if isinstance(stmt, ast.FunctionDef) and stmt.name == "get_queryset": + extra["get_queryset"] = True + dumped = ast.dump(stmt) + m = re.search(r"id='([A-Z][A-Za-z0-9_]+)'", dumped) + if m and not queryset_model: + queryset_model = m.group(1) if isinstance(stmt, ast.FunctionDef) and stmt.name == "get_serializer_class": dynamic_serializer = True extra["get_serializer_class"] = True @@ -454,20 +513,223 @@ def _app_config(self, node: ast.ClassDef) -> None: def _maybe_task(self, node: ast.FunctionDef) -> None: decs = _decorator_names(node) - if not any(d.split(".")[-1] in TASK_DECORATORS for d in decs): - if "tasks.py" not in self.rel_path: - return - if not node.name.endswith("task") and "task" not in node.name: - return + broker = None + if any("dramatiq" in d or d.split(".")[-1] in DRAMATIQ_DECORATORS for d in decs): + broker = "dramatiq" + elif any("celery" in d or d.split(".")[-1] in CELERY_DECORATORS for d in decs): + broker = "celery" + elif "tasks.py" in self.rel_path or "actors.py" in self.rel_path: + if node.name.endswith("task") or "task" in node.name or "actors.py" in self.rel_path: + broker = "dramatiq" if "actors.py" in self.rel_path else "celery" + if broker is None: + return qname = f"{self.app}.{node.name}" - args = [a.arg for a in node.args.args] - extra = {"app": self.app, "args": args} - extra["looks_idempotent_on_pk"] = any( - a in {"pk", "id", "invoice_id", "object_id", "model_id"} or a.endswith("_id") or a.endswith("_pk") - for a in args - ) + args = [a.arg for a in node.args.args if a.arg not in {"self", "cls"}] + extra = { + "app": self.app, + "args": args, + "broker": broker, + "decorators": decs, + } + extra["looks_idempotent_on_pk"] = _looks_idempotent(args) self.add_node(NodeType.TASK, node.name, qname, node.lineno, extra) + def _task_class(self, node: ast.ClassDef) -> bool: + bases = _bases(node) + shorts = {b.split(".")[-1] for b in bases} + blob = " ".join(self.imports.values()) + " " + " ".join(self.from_imports.values()) + broker = None + if shorts & DRAMATIQ_TASK_BASES or any("dramatiq" in b.lower() for b in bases): + broker = "dramatiq" + elif shorts & CELERY_TASK_BASES and ( + "celery" in blob.lower() or any("celery" in b.lower() for b in bases) + ): + broker = "celery" + if broker is None: + return False + run = next( + ( + stmt + for stmt in node.body + if isinstance(stmt, ast.FunctionDef) and stmt.name in {"run", "perform"} + ), + None, + ) + args = [a.arg for a in run.args.args if a.arg not in {"self", "cls"}] if run else [] + self.add_node( + NodeType.TASK, + node.name, + f"{self.app}.{node.name}", + node.lineno, + { + "app": self.app, + "args": args, + "broker": broker, + "task_class": True, + "looks_idempotent_on_pk": _looks_idempotent(args), + }, + ) + return True + + def _looks_like_celery(self, fname: str) -> bool: + blob = " ".join(self.imports.values()) + " " + " ".join(self.from_imports.values()) + " " + self.source[:800] + if "celery" in blob.lower() or "tasks.py" in self.rel_path: + return True + root = fname.split(".")[0] + target = self.from_imports.get(root, self.imports.get(root, "")) + return any(part in target for part in ("tasks", "celery", "actors")) + + def _looks_like_dramatiq_send(self, fname: str) -> bool: + blob = " ".join(self.imports.values()) + " " + " ".join(self.from_imports.values()) + " " + self.source[:400] + if "dramatiq" in blob: + return True + root = fname.split(".")[0] + target = self.from_imports.get(root, self.imports.get(root, "")) + return any(part in target for part in ("actors", "tasks", "dramatiq")) + + def _enqueue(self, node: ast.Call, fname: str, broker: str = "celery") -> None: + task_name = fname.rsplit(".", 1)[0] + short = task_name.split(".")[-1] + qname = f"{self.app}.{short}" + owner = self.class_stack[-1] if self.class_stack else Path(self.rel_path).stem + owner_type = NodeType.VIEW + if "management/commands" in self.rel_path: + owner_type = NodeType.MANAGEMENT_COMMAND + owner = Path(self.rel_path).stem + elif owner.endswith("Serializer"): + owner_type = NodeType.SERIALIZER + elif "Service" in owner or owner.endswith("UseCase"): + owner_type = NodeType.SERVICE + self.add_edge( + node_id(owner_type, f"{self.app}.{owner}"), + node_id(NodeType.TASK, qname), + EdgeType.ENQUEUES, + confidence=0.9, + extra={"call": fname, "line": node.lineno, "broker": broker}, + ) + self.add_node( + NodeType.TASK, + short, + qname, + node.lineno, + {"referenced": True, "app": self.app, "broker": broker}, + ) + + def _enqueue_from_on_commit(self, node: ast.Call) -> None: + for arg in list(node.args) + [kw.value for kw in node.keywords]: + for child in ast.walk(arg): + if isinstance(child, ast.Call): + fname = _name(child.func) or "" + short = fname.split(".")[-1] + if short in CELERY_ENQUEUE: + self._enqueue(child, fname, broker="celery") + elif short in DRAMATIQ_ENQUEUE: + self._enqueue(child, fname, broker="dramatiq") + + def _send_task(self, node: ast.Call) -> None: + name = _const_str(node.args[0]) if node.args else None + self.graph.residuals.append( + f'celery.send_task("{name or "?"}") at {self.rel_path}:{node.lineno}' + ) + if not name: + return + short = name.split(".")[-1] + app = name.split(".")[0] if "." in name else self.app + qname = f"{app}.{short}" + owner = self.class_stack[-1] if self.class_stack else Path(self.rel_path).stem + owner_type = NodeType.VIEW + if "management/commands" in self.rel_path: + owner_type = NodeType.MANAGEMENT_COMMAND + owner = Path(self.rel_path).stem + self.add_edge( + node_id(owner_type, f"{self.app}.{owner}"), + node_id(NodeType.TASK, qname), + EdgeType.ENQUEUES, + confidence=0.7, + extra={"call": "send_task", "line": node.lineno, "broker": "celery", "task": name}, + ) + self.add_node( + NodeType.TASK, + short, + qname, + node.lineno, + {"referenced": True, "app": app, "broker": "celery", "via": "send_task"}, + ) + + def _beat_schedule(self, value: ast.AST) -> None: + if not isinstance(value, ast.Dict): + return + for key, val in zip(value.keys, value.values): + entry_name = _const_str(key) or _name(key) or "beat" + task_name = None + if isinstance(val, ast.Dict): + for k, v in zip(val.keys, val.values): + label = _const_str(k) or _name(k) + if label == "task": + task_name = _const_str(v) or _name(v) + if not task_name: + continue + parts = task_name.split(".") + short = parts[-1] + app = parts[0] if len(parts) > 1 else self.app + qname = f"{app}.{short}" + self.add_node( + NodeType.TASK, + short, + qname, + getattr(value, "lineno", 1), + { + "referenced": True, + "app": app, + "broker": "celery", + "beat": True, + "schedule_name": entry_name, + }, + ) + self.graph.residuals.append( + f"Celery beat '{entry_name}' → {task_name} ({self.rel_path})" + ) + + def _maybe_fbv(self, node: ast.FunctionDef) -> None: + decs = _decorator_names(node) + if not any(d.split(".")[-1] in {"api_view", "csrf_exempt", "login_required", "permission_required", "require_GET", "require_POST"} for d in decs): + return + if node.name in {"get", "post", "put", "patch", "delete", "handle"}: + return + qname = f"{self.app}.{node.name}" + extra = {"app": self.app, "fbv": True, "decorators": decs} + view = self.add_node(NodeType.VIEW, node.name, qname, node.lineno, extra) + self._note_cross_app_model_imports(view.id) + + def _maybe_ninja(self, node: ast.FunctionDef) -> None: + for dec in node.decorator_list: + if not isinstance(dec, ast.Call): + continue + fname = _name(dec.func) or "" + short = fname.split(".")[-1] + if short not in NINJA_HTTP: + continue + if not any(tok in fname.lower() for tok in ("api", "router", "ninja")): + continue + route = _const_str(dec.args[0]) if dec.args else None + qname = f"{self.app}.{node.name}" + view = self.add_node( + NodeType.VIEW, + node.name, + qname, + node.lineno, + {"app": self.app, "ninja": True, "method": short.upper()}, + ) + if route: + rn = self.add_node( + NodeType.ROUTE, + route, + f"{self.app}:{route}", + node.lineno, + {"app": self.app, "route": route, "ninja": True, "method": short.upper()}, + ) + self.add_edge(rn.id, view.id, EdgeType.PUBLISHES_ROUTE) + def _maybe_receiver(self, node: ast.FunctionDef) -> None: for dec in node.decorator_list: dname = _name(dec.func if isinstance(dec, ast.Call) else dec) or "" @@ -600,25 +862,6 @@ def _get_model(self, node: ast.Call) -> None: ) self.add_node(NodeType.MODEL, label.split(".")[-1], label, node.lineno, {"string_ref": True}) - def _enqueue(self, node: ast.Call, fname: str) -> None: - task_name = fname.rsplit(".", 1)[0] - short = task_name.split(".")[-1] - qname = f"{self.app}.{short}" - owner = self.class_stack[-1] if self.class_stack else Path(self.rel_path).stem - owner_type = NodeType.VIEW - if owner.endswith("Serializer"): - owner_type = NodeType.SERIALIZER - elif "Service" in owner or owner.endswith("UseCase"): - owner_type = NodeType.SERVICE - self.add_edge( - node_id(owner_type, f"{self.app}.{owner}"), - node_id(NodeType.TASK, qname), - EdgeType.ENQUEUES, - confidence=0.9, - extra={"call": fname, "line": node.lineno}, - ) - self.add_node(NodeType.TASK, short, qname, node.lineno, {"referenced": True, "app": self.app}) - def _signal_connect(self, node: ast.Call, fname: str) -> None: self.graph.residuals.append(f"signal.connect() at {self.rel_path}:{node.lineno} ({fname})") @@ -634,6 +877,13 @@ def _slice(self, node: ast.AST) -> str: return "" +def _looks_idempotent(args: list[str]) -> bool: + return any( + a in {"pk", "id", "invoice_id", "object_id", "model_id"} or a.endswith("_id") or a.endswith("_pk") + for a in args + ) + + def extract_migrations(rel_path: str, source: str, config: LoadpathConfig) -> ExtractedGraph: graph = ExtractedGraph() app = _app_from_path(rel_path) or "unknown" diff --git a/src/loadpath/extractors/django_boot.py b/src/loadpath/extractors/django_boot.py new file mode 100644 index 0000000..150d9a9 --- /dev/null +++ b/src/loadpath/extractors/django_boot.py @@ -0,0 +1,121 @@ +"""Optional django.setup() overlay. AST is the default; boot enriches model _meta when settings import.""" + +from __future__ import annotations + +import os +import sys +from pathlib import Path + +from loadpath.config import LoadpathConfig +from loadpath.types import Edge, EdgeType, ExtractedGraph, Node, NodeType, node_id + + +def try_boot_models(repo_root: Path, config: LoadpathConfig) -> ExtractedGraph: + graph = ExtractedGraph() + settings_mod = _discover_settings_module(repo_root) + if not settings_mod: + return graph + try: + import django + from django.apps import apps + except ImportError: + graph.residuals.append("django.setup() skipped: Django is not installed (AST graph still used)") + return graph + + prev = os.environ.get("DJANGO_SETTINGS_MODULE") + added: list[str] = [] + try: + root = str(repo_root) + backend = str(repo_root / config.django_root) + for p in (root, backend): + if p not in sys.path: + sys.path.insert(0, p) + added.append(p) + os.environ["DJANGO_SETTINGS_MODULE"] = settings_mod + django.setup() + for model in apps.get_models(): + app = model._meta.app_label + qname = f"{app}.{model.__name__}" + context = config.context_for_django_app(app) + graph.nodes.append( + Node( + id=node_id(NodeType.MODEL, qname), + type=NodeType.MODEL, + name=model.__name__, + qualified_name=qname, + context=context, + extra={ + "app": app, + "db_table": model._meta.db_table, + "booted": True, + }, + ) + ) + for field in model._meta.get_fields(): + fname = getattr(field, "name", None) + if not fname: + continue + extra = { + "app": app, + "field_type": field.__class__.__name__, + "booted": True, + } + if getattr(field, "is_relation", False): + remote = getattr(field, "related_model", None) + on_delete = getattr(getattr(field, "remote_field", None), "on_delete", None) + extra["on_delete"] = getattr(on_delete, "__name__", None) if on_delete else None + extra["related_name"] = getattr(field, "related_name", None) + if remote is not None: + target = f"{remote._meta.app_label}.{remote.__name__}" + extra["to"] = target + graph.edges.append( + Edge( + src=node_id(NodeType.FIELD, f"{qname}.{fname}"), + dst=node_id(NodeType.MODEL, target), + type=EdgeType.RELATES_TO, + extra={"on_delete": extra["on_delete"], "booted": True}, + ) + ) + graph.nodes.append( + Node( + id=node_id(NodeType.FIELD, f"{qname}.{fname}"), + type=NodeType.FIELD, + name=fname, + qualified_name=f"{qname}.{fname}", + context=context, + extra=extra, + ) + ) + graph.edges.append( + Edge( + src=node_id(NodeType.MODEL, qname), + dst=node_id(NodeType.FIELD, f"{qname}.{fname}"), + type=EdgeType.HAS_FIELD, + ) + ) + graph.residuals.append(f"django.setup() overlay applied via {settings_mod}") + except Exception as exc: # noqa: BLE001 + graph.residuals.append(f"django.setup() skipped: {exc}") + finally: + if prev is None: + os.environ.pop("DJANGO_SETTINGS_MODULE", None) + else: + os.environ["DJANGO_SETTINGS_MODULE"] = prev + for p in added: + if p in sys.path: + sys.path.remove(p) + return graph + + +def _discover_settings_module(repo_root: Path) -> str | None: + env = os.environ.get("DJANGO_SETTINGS_MODULE") + if env: + return env + for settings in repo_root.rglob("settings.py"): + rel = settings.relative_to(repo_root).with_suffix("") + if any(part.startswith(".") for part in rel.parts): + continue + if "site-packages" in rel.parts: + continue + return ".".join(rel.parts) + return None diff --git a/src/loadpath/graph/store.py b/src/loadpath/graph/store.py index e4a7cc6..21a129e 100644 --- a/src/loadpath/graph/store.py +++ b/src/loadpath/graph/store.py @@ -121,6 +121,28 @@ def upsert_graph(self, graph: ExtractedGraph) -> None: self.conn.commit() def upsert_node(self, node: Node) -> None: + existing = self.get_node(node.id) + extra = dict(node.extra or {}) + file_path = node.file_path + start_line = node.start_line + context = node.context + if existing: + merged = dict(existing.get("extra") or {}) + merged.update(extra) + extra = merged + new_is_ref = bool(node.extra.get("referenced")) + old_is_ref = bool((existing.get("extra") or {}).get("referenced")) + # A definition (tasks.py / @actor) wins over a call-site placeholder. + if new_is_ref and not old_is_ref: + extra["referenced"] = False + for k, v in (existing.get("extra") or {}).items(): + if k not in node.extra or node.extra.get(k) is None: + extra[k] = v + file_path = existing.get("file_path") or file_path + start_line = existing.get("start_line") if existing.get("start_line") is not None else start_line + context = existing.get("context") or context + elif not new_is_ref and old_is_ref: + extra["referenced"] = False self.conn.execute( """ INSERT INTO nodes(id, type, name, qualified_name, file_path, start_line, end_line, context, extra) @@ -140,11 +162,11 @@ def upsert_node(self, node: Node) -> None: node.type.value, node.name, node.qualified_name, - node.file_path, - node.start_line, + file_path, + start_line, node.end_line, - node.context, - json.dumps(node.extra), + context, + json.dumps(extra), ), ) diff --git a/src/loadpath/index.py b/src/loadpath/index.py index 993a7f8..d75e09e 100644 --- a/src/loadpath/index.py +++ b/src/loadpath/index.py @@ -6,6 +6,7 @@ from loadpath.config import LoadpathConfig, load_config from loadpath.extractors.django import extract_django_file from loadpath.extractors.react import extract_react_file +from loadpath.extractors.django_boot import try_boot_models from loadpath.graph.store import GraphStore from loadpath.stitch.openapi import stitch from loadpath.types import GENERATED_PATH_MARKERS, ExtractedGraph, Node, NodeType, node_id @@ -88,6 +89,12 @@ def index_repo( store.upsert_graph(graph) residuals.extend(graph.residuals) + boot = ExtractedGraph() + if config.boot_django: + boot = try_boot_models(repo_root, config) + store.upsert_graph(boot) + residuals.extend(boot.residuals) + _ensure_context_nodes(store, config) stitch_residuals = stitch(store, config, repo_root) residuals.extend(stitch_residuals) diff --git a/src/loadpath/review/cluster.py b/src/loadpath/review/cluster.py index 99af277..32fc8d0 100644 --- a/src/loadpath/review/cluster.py +++ b/src/loadpath/review/cluster.py @@ -49,6 +49,9 @@ "tested_by", "has_permission", "belongs_to", + "destructive_migration", + "changes_permission", + "crosses_context", } BACKWARD_TYPES = { @@ -66,6 +69,7 @@ "receives", "uses_query_key", "belongs_to", + "destructive_migration", } @@ -91,6 +95,12 @@ def include(nid: str, expand: bool) -> None: if expand: frontier.add(nid) + seed_contexts = { + (by_id.get(s) or {}).get("context") + for s in seed_ids + if (by_id.get(s) or {}).get("context") + } + for _ in range(hops): nxt: set[str] = set() working = set(frontier) @@ -105,6 +115,22 @@ def include(nid: str, expand: bool) -> None: other = e["dst"] other_node = by_id.get(other) or {} expand = other_node.get("type") not in BRIDGE_TYPES + if ( + e["type"] == "relates_to" + and other_node.get("context") + and seed_contexts + and other_node.get("context") not in seed_contexts + ): + continue + if ( + e["type"] == "queries_model" + and other_node.get("context") + and seed_contexts + and other_node.get("context") not in seed_contexts + ): + include(other, False) + kept_edges[e["id"]] = e + continue include(other, expand) kept_edges[e["id"]] = e if expand and other not in working: diff --git a/src/loadpath/review/engine.py b/src/loadpath/review/engine.py index 7e902a9..dee982f 100644 --- a/src/loadpath/review/engine.py +++ b/src/loadpath/review/engine.py @@ -300,15 +300,16 @@ def _sink_summaries(nodes: list[dict], store: GraphStore) -> list[dict]: if n["type"] in interesting: extra = n.get("extra") or {} name = extra.get("mounted_at") or extra.get("full_path") or n["name"] - out.append( - { - "id": n["id"], - "type": n["type"], - "name": name, - "file_path": n.get("file_path"), - "context": n.get("context"), - } - ) + item = { + "id": n["id"], + "type": n["type"], + "name": name, + "file_path": n.get("file_path"), + "context": n.get("context"), + } + if extra.get("broker"): + item["broker"] = extra["broker"] + out.append(item) return out @@ -337,12 +338,22 @@ def _arch_note(findings: list, kinds: list[str], impact_nodes: list[dict] | None def _headline(confidence, title, sinks, tests_note, arch_note, residuals, reviewers) -> str: sink_bits = [] routes = [s["name"] for s in sinks if s["type"] == NodeType.ROUTE.value] - tasks = [s["name"] for s in sinks if s["type"] == NodeType.TASK.value] + celery_tasks = [s["name"] for s in sinks if s["type"] == NodeType.TASK.value and s.get("broker") == "celery"] + dramatiq_tasks = [s["name"] for s in sinks if s["type"] == NodeType.TASK.value and s.get("broker") == "dramatiq"] + other_tasks = [ + s["name"] + for s in sinks + if s["type"] == NodeType.TASK.value and s.get("broker") not in {"celery", "dramatiq"} + ] pages = [s["name"] for s in sinks if s["type"] in {NodeType.PAGE.value, NodeType.FORM_SCHEMA.value}] if routes: sink_bits.append(", ".join(routes[:4])) - if tasks: - sink_bits.append("Celery " + ", ".join(tasks[:3])) + if celery_tasks: + sink_bits.append("Celery " + ", ".join(celery_tasks[:3])) + if dramatiq_tasks: + sink_bits.append("Dramatiq " + ", ".join(dramatiq_tasks[:3])) + if other_tasks: + sink_bits.append("async " + ", ".join(other_tasks[:3])) if pages: sink_bits.append("React " + ", ".join(pages[:4])) residual = residuals[0] if residuals else "none" diff --git a/src/loadpath/static/assets/index-DigBKCrc.js b/src/loadpath/static/assets/index-BA8TjmLZ.js similarity index 68% rename from src/loadpath/static/assets/index-DigBKCrc.js rename to src/loadpath/static/assets/index-BA8TjmLZ.js index 5be5f50..bb69872 100644 --- a/src/loadpath/static/assets/index-DigBKCrc.js +++ b/src/loadpath/static/assets/index-BA8TjmLZ.js @@ -6,7 +6,7 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var Rd;function x0(){if(Rd)return Ne;Rd=1;var n=Symbol.for("react.element"),r=Symbol.for("react.portal"),i=Symbol.for("react.fragment"),l=Symbol.for("react.strict_mode"),u=Symbol.for("react.profiler"),c=Symbol.for("react.provider"),f=Symbol.for("react.context"),h=Symbol.for("react.forward_ref"),p=Symbol.for("react.suspense"),m=Symbol.for("react.memo"),v=Symbol.for("react.lazy"),y=Symbol.iterator;function g(C){return C===null||typeof C!="object"?null:(C=y&&C[y]||C["@@iterator"],typeof C=="function"?C:null)}var w={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},S=Object.assign,M={};function N(C,R,te){this.props=C,this.context=R,this.refs=M,this.updater=te||w}N.prototype.isReactComponent={},N.prototype.setState=function(C,R){if(typeof C!="object"&&typeof C!="function"&&C!=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,C,R,"setState")},N.prototype.forceUpdate=function(C){this.updater.enqueueForceUpdate(this,C,"forceUpdate")};function E(){}E.prototype=N.prototype;function L(C,R,te){this.props=C,this.context=R,this.refs=M,this.updater=te||w}var _=L.prototype=new E;_.constructor=L,S(_,N.prototype),_.isPureReactComponent=!0;var P=Array.isArray,U=Object.prototype.hasOwnProperty,D={current:null},V={key:!0,ref:!0,__self:!0,__source:!0};function X(C,R,te){var re,ue={},ce=null,ae=null;if(R!=null)for(re in R.ref!==void 0&&(ae=R.ref),R.key!==void 0&&(ce=""+R.key),R)U.call(R,re)&&!V.hasOwnProperty(re)&&(ue[re]=R[re]);var G=arguments.length-2;if(G===1)ue.children=te;else if(1>>1,R=j[C];if(0>>1;Cu(ue,F))ceu(ae,ue)?(j[C]=ae,j[ce]=F,C=ce):(j[C]=ue,j[re]=F,C=re);else if(ceu(ae,F))j[C]=ae,j[ce]=F,C=ce;else break e}}return $}function u(j,$){var F=j.sortIndex-$.sortIndex;return F!==0?F:j.id-$.id}if(typeof performance=="object"&&typeof performance.now=="function"){var c=performance;n.unstable_now=function(){return c.now()}}else{var f=Date,h=f.now();n.unstable_now=function(){return f.now()-h}}var p=[],m=[],v=1,y=null,g=3,w=!1,S=!1,M=!1,N=typeof setTimeout=="function"?setTimeout:null,E=typeof clearTimeout=="function"?clearTimeout:null,L=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function _(j){for(var $=i(m);$!==null;){if($.callback===null)l(m);else if($.startTime<=j)l(m),$.sortIndex=$.expirationTime,r(p,$);else break;$=i(m)}}function P(j){if(M=!1,_(j),!S)if(i(p)!==null)S=!0,z(U);else{var $=i(m);$!==null&&H(P,$.startTime-j)}}function U(j,$){S=!1,M&&(M=!1,E(X),X=-1),w=!0;var F=g;try{for(_($),y=i(p);y!==null&&(!(y.expirationTime>$)||j&&!q());){var C=y.callback;if(typeof C=="function"){y.callback=null,g=y.priorityLevel;var R=C(y.expirationTime<=$);$=n.unstable_now(),typeof R=="function"?y.callback=R:y===i(p)&&l(p),_($)}else l(p);y=i(p)}if(y!==null)var te=!0;else{var re=i(m);re!==null&&H(P,re.startTime-$),te=!1}return te}finally{y=null,g=F,w=!1}}var D=!1,V=null,X=-1,b=5,ee=-1;function q(){return!(n.unstable_now()-eej||125C?(j.sortIndex=F,r(m,j),i(p)===null&&j===i(m)&&(M?(E(X),X=-1):M=!0,H(P,F-C))):(j.sortIndex=R,r(p,j),S||w||(S=!0,z(U))),j},n.unstable_shouldYield=q,n.unstable_wrapCallback=function(j){var $=g;return function(){var F=g;g=$;try{return j.apply(this,arguments)}finally{g=F}}}})(ya)),ya}var Od;function k0(){return Od||(Od=1,ma.exports=E0()),ma.exports}/** + */var Dd;function E0(){return Dd||(Dd=1,(function(n){function r(j,$){var F=j.length;j.push($);e:for(;0>>1,R=j[C];if(0>>1;Cu(ue,F))ceu(ae,ue)?(j[C]=ae,j[ce]=F,C=ce):(j[C]=ue,j[re]=F,C=re);else if(ceu(ae,F))j[C]=ae,j[ce]=F,C=ce;else break e}}return $}function u(j,$){var F=j.sortIndex-$.sortIndex;return F!==0?F:j.id-$.id}if(typeof performance=="object"&&typeof performance.now=="function"){var c=performance;n.unstable_now=function(){return c.now()}}else{var f=Date,h=f.now();n.unstable_now=function(){return f.now()-h}}var p=[],m=[],v=1,y=null,g=3,x=!1,S=!1,M=!1,N=typeof setTimeout=="function"?setTimeout:null,E=typeof clearTimeout=="function"?clearTimeout:null,L=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function _(j){for(var $=i(m);$!==null;){if($.callback===null)l(m);else if($.startTime<=j)l(m),$.sortIndex=$.expirationTime,r(p,$);else break;$=i(m)}}function P(j){if(M=!1,_(j),!S)if(i(p)!==null)S=!0,I(U);else{var $=i(m);$!==null&&H(P,$.startTime-j)}}function U(j,$){S=!1,M&&(M=!1,E(Y),Y=-1),x=!0;var F=g;try{for(_($),y=i(p);y!==null&&(!(y.expirationTime>$)||j&&!q());){var C=y.callback;if(typeof C=="function"){y.callback=null,g=y.priorityLevel;var R=C(y.expirationTime<=$);$=n.unstable_now(),typeof R=="function"?y.callback=R:y===i(p)&&l(p),_($)}else l(p);y=i(p)}if(y!==null)var te=!0;else{var re=i(m);re!==null&&H(P,re.startTime-$),te=!1}return te}finally{y=null,g=F,x=!1}}var D=!1,V=null,Y=-1,X=5,ee=-1;function q(){return!(n.unstable_now()-eej||125C?(j.sortIndex=F,r(m,j),i(p)===null&&j===i(m)&&(M?(E(Y),Y=-1):M=!0,H(P,F-C))):(j.sortIndex=R,r(p,j),S||x||(S=!0,I(U))),j},n.unstable_shouldYield=q,n.unstable_wrapCallback=function(j){var $=g;return function(){var F=g;g=$;try{return j.apply(this,arguments)}finally{g=F}}}})(ya)),ya}var Od;function k0(){return Od||(Od=1,ma.exports=E0()),ma.exports}/** * @license React * react-dom.production.min.js * @@ -30,14 +30,14 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var Fd;function N0(){if(Fd)return gt;Fd=1;var n=di(),r=k0();function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,o=1;o"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),p=Object.prototype.hasOwnProperty,m=/^[: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={},y={};function g(e){return p.call(y,e)?!0:p.call(v,e)?!1:m.test(e)?y[e]=!0:(v[e]=!0,!1)}function w(e,t,o,s){if(o!==null&&o.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return s?!1:o!==null?!o.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function S(e,t,o,s){if(t===null||typeof t>"u"||w(e,t,o,s))return!0;if(s)return!1;if(o!==null)switch(o.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function M(e,t,o,s,a,d,x){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=s,this.attributeNamespace=a,this.mustUseProperty=o,this.propertyName=e,this.type=t,this.sanitizeURL=d,this.removeEmptyString=x}var N={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){N[e]=new M(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];N[t]=new M(t,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){N[e]=new M(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){N[e]=new M(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){N[e]=new M(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){N[e]=new M(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){N[e]=new M(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){N[e]=new M(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){N[e]=new M(e,5,!1,e.toLowerCase(),null,!1,!1)});var E=/[\-:]([a-z])/g;function L(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 t=e.replace(E,L);N[t]=new M(t,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(E,L);N[t]=new M(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(E,L);N[t]=new M(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){N[e]=new M(e,1,!1,e.toLowerCase(),null,!1,!1)}),N.xlinkHref=new M("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){N[e]=new M(e,1,!1,e.toLowerCase(),null,!0,!0)});function _(e,t,o,s){var a=N.hasOwnProperty(t)?N[t]:null;(a!==null?a.type!==0:s||!(2"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),p=Object.prototype.hasOwnProperty,m=/^[: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={},y={};function g(e){return p.call(y,e)?!0:p.call(v,e)?!1:m.test(e)?y[e]=!0:(v[e]=!0,!1)}function x(e,t,o,s){if(o!==null&&o.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return s?!1:o!==null?!o.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function S(e,t,o,s){if(t===null||typeof t>"u"||x(e,t,o,s))return!0;if(s)return!1;if(o!==null)switch(o.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function M(e,t,o,s,a,d,w){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=s,this.attributeNamespace=a,this.mustUseProperty=o,this.propertyName=e,this.type=t,this.sanitizeURL=d,this.removeEmptyString=w}var N={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){N[e]=new M(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];N[t]=new M(t,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){N[e]=new M(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){N[e]=new M(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){N[e]=new M(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){N[e]=new M(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){N[e]=new M(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){N[e]=new M(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){N[e]=new M(e,5,!1,e.toLowerCase(),null,!1,!1)});var E=/[\-:]([a-z])/g;function L(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 t=e.replace(E,L);N[t]=new M(t,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(E,L);N[t]=new M(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(E,L);N[t]=new M(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){N[e]=new M(e,1,!1,e.toLowerCase(),null,!1,!1)}),N.xlinkHref=new M("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){N[e]=new M(e,1,!1,e.toLowerCase(),null,!0,!0)});function _(e,t,o,s){var a=N.hasOwnProperty(t)?N[t]:null;(a!==null?a.type!==0:s||!(2I||a[x]!==d[I]){var A=` -`+a[x].replace(" at new "," at ");return e.displayName&&A.includes("")&&(A=A.replace("",e.displayName)),A}while(1<=x&&0<=I);break}}}finally{te=!1,Error.prepareStackTrace=o}return(e=e?e.displayName||e.name:"")?R(e):""}function ue(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=re(e.type,!1),e;case 11:return e=re(e.type.render,!1),e;case 1:return e=re(e.type,!0),e;default:return""}}function ce(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 D:return"Portal";case b:return"Profiler";case X:return"StrictMode";case Z:return"Suspense";case k:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case q:return(e.displayName||"Context")+".Consumer";case ee:return(e._context.displayName||"Context")+".Provider";case J:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case B:return t=e.displayName||null,t!==null?t:ce(e.type)||"Memo";case z:t=e._payload,e=e._init;try{return ce(e(t))}catch{}}return null}function ae(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return ce(t);case 8:return t===X?"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 t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function G(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function se(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function pe(e){var t=se(e)?"checked":"value",o=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),s=""+e[t];if(!e.hasOwnProperty(t)&&typeof o<"u"&&typeof o.get=="function"&&typeof o.set=="function"){var a=o.get,d=o.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return a.call(this)},set:function(x){s=""+x,d.call(this,x)}}),Object.defineProperty(e,t,{enumerable:o.enumerable}),{getValue:function(){return s},setValue:function(x){s=""+x},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function we(e){e._valueTracker||(e._valueTracker=pe(e))}function ve(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var o=t.getValue(),s="";return e&&(s=se(e)?e.checked?"true":"false":e.value),e=s,e!==o?(t.setValue(e),!0):!1}function me(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 ke(e,t){var o=t.checked;return F({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:o??e._wrapperState.initialChecked})}function Ce(e,t){var o=t.defaultValue==null?"":t.defaultValue,s=t.checked!=null?t.checked:t.defaultChecked;o=G(t.value!=null?t.value:o),e._wrapperState={initialChecked:s,initialValue:o,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function Me(e,t){t=t.checked,t!=null&&_(e,"checked",t,!1)}function Le(e,t){Me(e,t);var o=G(t.value),s=t.type;if(o!=null)s==="number"?(o===0&&e.value===""||e.value!=o)&&(e.value=""+o):e.value!==""+o&&(e.value=""+o);else if(s==="submit"||s==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?ut(e,t.type,o):t.hasOwnProperty("defaultValue")&&ut(e,t.type,G(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function it(e,t,o){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var s=t.type;if(!(s!=="submit"&&s!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,o||t===e.value||(e.value=t),e.defaultValue=t}o=e.name,o!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,o!==""&&(e.name=o)}function ut(e,t,o){(t!=="number"||me(e.ownerDocument)!==e)&&(o==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+o&&(e.defaultValue=""+o))}var Je=Array.isArray;function et(e,t,o,s){if(e=e.options,t){t={};for(var a=0;a"+t.valueOf().toString()+"",t=Mt.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function on(e,t){if(t){var o=e.firstChild;if(o&&o===e.lastChild&&o.nodeType===3){o.nodeValue=t;return}}e.textContent=t}var Yn={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},Sl=["Webkit","ms","Moz","O"];Object.keys(Yn).forEach(function(e){Sl.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),Yn[t]=Yn[e]})});function xi(e,t,o){return t==null||typeof t=="boolean"||t===""?"":o||typeof t!="number"||t===0||Yn.hasOwnProperty(e)&&Yn[e]?(""+t).trim():t+"px"}function wi(e,t){e=e.style;for(var o in t)if(t.hasOwnProperty(o)){var s=o.indexOf("--")===0,a=xi(o,t[o],s);o==="float"&&(o="cssFloat"),s?e.setProperty(o,a):e[o]=a}}var _l=F({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 so(e,t){if(t){if(_l[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(i(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(i(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(i(61))}if(t.style!=null&&typeof t.style!="object")throw Error(i(62))}}function lo(e,t){if(e.indexOf("-")===-1)return typeof t.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 uo=null;function ao(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var co=null,vn=null,xn=null;function Si(e){if(e=jo(e)){if(typeof co!="function")throw Error(i(280));var t=e.stateNode;t&&(t=qi(t),co(e.stateNode,e.type,t))}}function _i(e){vn?xn?xn.push(e):xn=[e]:vn=e}function Ei(){if(vn){var e=vn,t=xn;if(xn=vn=null,Si(e),t)for(e=0;e>>=0,e===0?32:31-(Ll(e)/Rl|0)|0}var kr=64,Nr=4194304;function Gn(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 sn(e,t){var o=e.pendingLanes;if(o===0)return 0;var s=0,a=e.suspendedLanes,d=e.pingedLanes,x=o&268435455;if(x!==0){var I=x&~a;I!==0?s=Gn(I):(d&=x,d!==0&&(s=Gn(d)))}else x=o&~a,x!==0?s=Gn(x):d!==0&&(s=Gn(d));if(s===0)return 0;if(t!==0&&t!==s&&(t&a)===0&&(a=s&-s,d=t&-t,a>=d||a===16&&(d&4194240)!==0))return t;if((s&4)!==0&&(s|=o&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=s;0o;o++)t.push(e);return t}function qn(e,t,o){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-xt(t),e[t]=o}function $l(e,t){var o=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var s=e.eventTimes;for(e=e.expirationTimes;0=Co),Nc=" ",Cc=!1;function Mc(e,t){switch(e){case"keyup":return pm.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Pc(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Ir=!1;function mm(e,t){switch(e){case"compositionend":return Pc(t);case"keypress":return t.which!==32?null:(Cc=!0,Nc);case"textInput":return e=t.data,e===Nc&&Cc?null:e;default:return null}}function ym(e,t){if(Ir)return e==="compositionend"||!bl&&Mc(e,t)?(e=xc(),Hi=Vl=kn=null,Ir=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:o,offset:t-e};e=s}e:{for(;o;){if(o.nextSibling){o=o.nextSibling;break e}o=o.parentNode}o=void 0}o=jc(o)}}function Dc(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Dc(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Oc(){for(var e=window,t=me();t instanceof e.HTMLIFrameElement;){try{var o=typeof t.contentWindow.location.href=="string"}catch{o=!1}if(o)e=t.contentWindow;else break;t=me(e.document)}return t}function Kl(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}function Cm(e){var t=Oc(),o=e.focusedElem,s=e.selectionRange;if(t!==o&&o&&o.ownerDocument&&Dc(o.ownerDocument.documentElement,o)){if(s!==null&&Kl(o)){if(t=s.start,e=s.end,e===void 0&&(e=t),"selectionStart"in o)o.selectionStart=t,o.selectionEnd=Math.min(e,o.value.length);else if(e=(t=o.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var a=o.textContent.length,d=Math.min(s.start,a);s=s.end===void 0?d:Math.min(s.end,a),!e.extend&&d>s&&(a=s,s=d,d=a),a=$c(o,d);var x=$c(o,s);a&&x&&(e.rangeCount!==1||e.anchorNode!==a.node||e.anchorOffset!==a.offset||e.focusNode!==x.node||e.focusOffset!==x.offset)&&(t=t.createRange(),t.setStart(a.node,a.offset),e.removeAllRanges(),d>s?(e.addRange(t),e.extend(x.node,x.offset)):(t.setEnd(x.node,x.offset),e.addRange(t)))}}for(t=[],e=o;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof o.focus=="function"&&o.focus(),o=0;o=document.documentMode,zr=null,ql=null,zo=null,Zl=!1;function Fc(e,t,o){var s=o.window===o?o.document:o.nodeType===9?o:o.ownerDocument;Zl||zr==null||zr!==me(s)||(s=zr,"selectionStart"in s&&Kl(s)?s={start:s.selectionStart,end:s.selectionEnd}:(s=(s.ownerDocument&&s.ownerDocument.defaultView||window).getSelection(),s={anchorNode:s.anchorNode,anchorOffset:s.anchorOffset,focusNode:s.focusNode,focusOffset:s.focusOffset}),zo&&Io(zo,s)||(zo=s,s=Qi(ql,"onSelect"),0jr||(e.current=cu[jr],cu[jr]=null,jr--)}function Re(e,t){jr++,cu[jr]=e.current,e.current=t}var Pn={},tt=Mn(Pn),ct=Mn(!1),Jn=Pn;function $r(e,t){var o=e.type.contextTypes;if(!o)return Pn;var s=e.stateNode;if(s&&s.__reactInternalMemoizedUnmaskedChildContext===t)return s.__reactInternalMemoizedMaskedChildContext;var a={},d;for(d in o)a[d]=t[d];return s&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=a),a}function ft(e){return e=e.childContextTypes,e!=null}function Zi(){je(ct),je(tt)}function ef(e,t,o){if(tt.current!==Pn)throw Error(i(168));Re(tt,t),Re(ct,o)}function tf(e,t,o){var s=e.stateNode;if(t=t.childContextTypes,typeof s.getChildContext!="function")return o;s=s.getChildContext();for(var a in s)if(!(a in t))throw Error(i(108,ae(e)||"Unknown",a));return F({},o,s)}function Ji(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Pn,Jn=tt.current,Re(tt,e),Re(ct,ct.current),!0}function nf(e,t,o){var s=e.stateNode;if(!s)throw Error(i(169));o?(e=tf(e,t,Jn),s.__reactInternalMemoizedMergedChildContext=e,je(ct),je(tt),Re(tt,e)):je(ct),Re(ct,o)}var un=null,es=!1,fu=!1;function rf(e){un===null?un=[e]:un.push(e)}function Om(e){es=!0,rf(e)}function In(){if(!fu&&un!==null){fu=!0;var e=0,t=Te;try{var o=un;for(Te=1;e>=x,a-=x,an=1<<32-xt(t)+a|o<Ee?(Ke=_e,_e=null):Ke=_e.sibling;var ze=ne(W,_e,Y[Ee],le);if(ze===null){_e===null&&(_e=Ke);break}e&&_e&&ze.alternate===null&&t(W,_e),O=d(ze,O,Ee),Se===null?ye=ze:Se.sibling=ze,Se=ze,_e=Ke}if(Ee===Y.length)return o(W,_e),De&&tr(W,Ee),ye;if(_e===null){for(;EeEe?(Ke=_e,_e=null):Ke=_e.sibling;var On=ne(W,_e,ze.value,le);if(On===null){_e===null&&(_e=Ke);break}e&&_e&&On.alternate===null&&t(W,_e),O=d(On,O,Ee),Se===null?ye=On:Se.sibling=On,Se=On,_e=Ke}if(ze.done)return o(W,_e),De&&tr(W,Ee),ye;if(_e===null){for(;!ze.done;Ee++,ze=Y.next())ze=ie(W,ze.value,le),ze!==null&&(O=d(ze,O,Ee),Se===null?ye=ze:Se.sibling=ze,Se=ze);return De&&tr(W,Ee),ye}for(_e=s(W,_e);!ze.done;Ee++,ze=Y.next())ze=fe(_e,W,Ee,ze.value,le),ze!==null&&(e&&ze.alternate!==null&&_e.delete(ze.key===null?Ee:ze.key),O=d(ze,O,Ee),Se===null?ye=ze:Se.sibling=ze,Se=ze);return e&&_e.forEach(function(v0){return t(W,v0)}),De&&tr(W,Ee),ye}function Ue(W,O,Y,le){if(typeof Y=="object"&&Y!==null&&Y.type===V&&Y.key===null&&(Y=Y.props.children),typeof Y=="object"&&Y!==null){switch(Y.$$typeof){case U:e:{for(var ye=Y.key,Se=O;Se!==null;){if(Se.key===ye){if(ye=Y.type,ye===V){if(Se.tag===7){o(W,Se.sibling),O=a(Se,Y.props.children),O.return=W,W=O;break e}}else if(Se.elementType===ye||typeof ye=="object"&&ye!==null&&ye.$$typeof===z&&cf(ye)===Se.type){o(W,Se.sibling),O=a(Se,Y.props),O.ref=$o(W,Se,Y),O.return=W,W=O;break e}o(W,Se);break}else t(W,Se);Se=Se.sibling}Y.type===V?(O=ar(Y.props.children,W.mode,le,Y.key),O.return=W,W=O):(le=Ps(Y.type,Y.key,Y.props,null,W.mode,le),le.ref=$o(W,O,Y),le.return=W,W=le)}return x(W);case D:e:{for(Se=Y.key;O!==null;){if(O.key===Se)if(O.tag===4&&O.stateNode.containerInfo===Y.containerInfo&&O.stateNode.implementation===Y.implementation){o(W,O.sibling),O=a(O,Y.children||[]),O.return=W,W=O;break e}else{o(W,O);break}else t(W,O);O=O.sibling}O=ua(Y,W.mode,le),O.return=W,W=O}return x(W);case z:return Se=Y._init,Ue(W,O,Se(Y._payload),le)}if(Je(Y))return he(W,O,Y,le);if($(Y))return ge(W,O,Y,le);os(W,Y)}return typeof Y=="string"&&Y!==""||typeof Y=="number"?(Y=""+Y,O!==null&&O.tag===6?(o(W,O.sibling),O=a(O,Y),O.return=W,W=O):(o(W,O),O=la(Y,W.mode,le),O.return=W,W=O),x(W)):o(W,O)}return Ue}var Hr=ff(!0),df=ff(!1),is=Mn(null),ss=null,Vr=null,yu=null;function vu(){yu=Vr=ss=null}function xu(e){var t=is.current;je(is),e._currentValue=t}function wu(e,t,o){for(;e!==null;){var s=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,s!==null&&(s.childLanes|=t)):s!==null&&(s.childLanes&t)!==t&&(s.childLanes|=t),e===o)break;e=e.return}}function Br(e,t){ss=e,yu=Vr=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&t)!==0&&(dt=!0),e.firstContext=null)}function zt(e){var t=e._currentValue;if(yu!==e)if(e={context:e,memoizedValue:t,next:null},Vr===null){if(ss===null)throw Error(i(308));Vr=e,ss.dependencies={lanes:0,firstContext:e}}else Vr=Vr.next=e;return t}var nr=null;function Su(e){nr===null?nr=[e]:nr.push(e)}function hf(e,t,o,s){var a=t.interleaved;return a===null?(o.next=o,Su(t)):(o.next=a.next,a.next=o),t.interleaved=o,fn(e,s)}function fn(e,t){e.lanes|=t;var o=e.alternate;for(o!==null&&(o.lanes|=t),o=e,e=e.return;e!==null;)e.childLanes|=t,o=e.alternate,o!==null&&(o.childLanes|=t),o=e,e=e.return;return o.tag===3?o.stateNode:null}var zn=!1;function _u(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function pf(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function dn(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function Tn(e,t,o){var s=e.updateQueue;if(s===null)return null;if(s=s.shared,(Pe&2)!==0){var a=s.pending;return a===null?t.next=t:(t.next=a.next,a.next=t),s.pending=t,fn(e,o)}return a=s.interleaved,a===null?(t.next=t,Su(s)):(t.next=a.next,a.next=t),s.interleaved=t,fn(e,o)}function ls(e,t,o){if(t=t.updateQueue,t!==null&&(t=t.shared,(o&4194240)!==0)){var s=t.lanes;s&=e.pendingLanes,o|=s,t.lanes=o,Cr(e,o)}}function gf(e,t){var o=e.updateQueue,s=e.alternate;if(s!==null&&(s=s.updateQueue,o===s)){var a=null,d=null;if(o=o.firstBaseUpdate,o!==null){do{var x={eventTime:o.eventTime,lane:o.lane,tag:o.tag,payload:o.payload,callback:o.callback,next:null};d===null?a=d=x:d=d.next=x,o=o.next}while(o!==null);d===null?a=d=t:d=d.next=t}else a=d=t;o={baseState:s.baseState,firstBaseUpdate:a,lastBaseUpdate:d,shared:s.shared,effects:s.effects},e.updateQueue=o;return}e=o.lastBaseUpdate,e===null?o.firstBaseUpdate=t:e.next=t,o.lastBaseUpdate=t}function us(e,t,o,s){var a=e.updateQueue;zn=!1;var d=a.firstBaseUpdate,x=a.lastBaseUpdate,I=a.shared.pending;if(I!==null){a.shared.pending=null;var A=I,Q=A.next;A.next=null,x===null?d=Q:x.next=Q,x=A;var oe=e.alternate;oe!==null&&(oe=oe.updateQueue,I=oe.lastBaseUpdate,I!==x&&(I===null?oe.firstBaseUpdate=Q:I.next=Q,oe.lastBaseUpdate=A))}if(d!==null){var ie=a.baseState;x=0,oe=Q=A=null,I=d;do{var ne=I.lane,fe=I.eventTime;if((s&ne)===ne){oe!==null&&(oe=oe.next={eventTime:fe,lane:0,tag:I.tag,payload:I.payload,callback:I.callback,next:null});e:{var he=e,ge=I;switch(ne=t,fe=o,ge.tag){case 1:if(he=ge.payload,typeof he=="function"){ie=he.call(fe,ie,ne);break e}ie=he;break e;case 3:he.flags=he.flags&-65537|128;case 0:if(he=ge.payload,ne=typeof he=="function"?he.call(fe,ie,ne):he,ne==null)break e;ie=F({},ie,ne);break e;case 2:zn=!0}}I.callback!==null&&I.lane!==0&&(e.flags|=64,ne=a.effects,ne===null?a.effects=[I]:ne.push(I))}else fe={eventTime:fe,lane:ne,tag:I.tag,payload:I.payload,callback:I.callback,next:null},oe===null?(Q=oe=fe,A=ie):oe=oe.next=fe,x|=ne;if(I=I.next,I===null){if(I=a.shared.pending,I===null)break;ne=I,I=ne.next,ne.next=null,a.lastBaseUpdate=ne,a.shared.pending=null}}while(!0);if(oe===null&&(A=ie),a.baseState=A,a.firstBaseUpdate=Q,a.lastBaseUpdate=oe,t=a.shared.interleaved,t!==null){a=t;do x|=a.lane,a=a.next;while(a!==t)}else d===null&&(a.shared.lanes=0);ir|=x,e.lanes=x,e.memoizedState=ie}}function mf(e,t,o){if(e=t.effects,t.effects=null,e!==null)for(t=0;to?o:4,e(!0);var s=Mu.transition;Mu.transition={};try{e(!1),t()}finally{Te=o,Mu.transition=s}}function jf(){return Tt().memoizedState}function Bm(e,t,o){var s=jn(e);if(o={lane:s,action:o,hasEagerState:!1,eagerState:null,next:null},$f(e))Df(t,o);else if(o=hf(e,t,o,s),o!==null){var a=lt();Ft(o,e,s,a),Of(o,t,s)}}function Um(e,t,o){var s=jn(e),a={lane:s,action:o,hasEagerState:!1,eagerState:null,next:null};if($f(e))Df(t,a);else{var d=e.alternate;if(e.lanes===0&&(d===null||d.lanes===0)&&(d=t.lastRenderedReducer,d!==null))try{var x=t.lastRenderedState,I=d(x,o);if(a.hasEagerState=!0,a.eagerState=I,At(I,x)){var A=t.interleaved;A===null?(a.next=a,Su(t)):(a.next=A.next,A.next=a),t.interleaved=a;return}}catch{}finally{}o=hf(e,t,a,s),o!==null&&(a=lt(),Ft(o,e,s,a),Of(o,t,s))}}function $f(e){var t=e.alternate;return e===He||t!==null&&t===He}function Df(e,t){Ho=fs=!0;var o=e.pending;o===null?t.next=t:(t.next=o.next,o.next=t),e.pending=t}function Of(e,t,o){if((o&4194240)!==0){var s=t.lanes;s&=e.pendingLanes,o|=s,t.lanes=o,Cr(e,o)}}var ps={readContext:zt,useCallback:nt,useContext:nt,useEffect:nt,useImperativeHandle:nt,useInsertionEffect:nt,useLayoutEffect:nt,useMemo:nt,useReducer:nt,useRef:nt,useState:nt,useDebugValue:nt,useDeferredValue:nt,useTransition:nt,useMutableSource:nt,useSyncExternalStore:nt,useId:nt,unstable_isNewReconciler:!1},Wm={readContext:zt,useCallback:function(e,t){return Zt().memoizedState=[e,t===void 0?null:t],e},useContext:zt,useEffect:Mf,useImperativeHandle:function(e,t,o){return o=o!=null?o.concat([e]):null,ds(4194308,4,zf.bind(null,t,e),o)},useLayoutEffect:function(e,t){return ds(4194308,4,e,t)},useInsertionEffect:function(e,t){return ds(4,2,e,t)},useMemo:function(e,t){var o=Zt();return t=t===void 0?null:t,e=e(),o.memoizedState=[e,t],e},useReducer:function(e,t,o){var s=Zt();return t=o!==void 0?o(t):t,s.memoizedState=s.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},s.queue=e,e=e.dispatch=Bm.bind(null,He,e),[s.memoizedState,e]},useRef:function(e){var t=Zt();return e={current:e},t.memoizedState=e},useState:Nf,useDebugValue:Au,useDeferredValue:function(e){return Zt().memoizedState=e},useTransition:function(){var e=Nf(!1),t=e[0];return e=Vm.bind(null,e[1]),Zt().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,o){var s=He,a=Zt();if(De){if(o===void 0)throw Error(i(407));o=o()}else{if(o=t(),Ge===null)throw Error(i(349));(or&30)!==0||wf(s,t,o)}a.memoizedState=o;var d={value:o,getSnapshot:t};return a.queue=d,Mf(_f.bind(null,s,d,e),[e]),s.flags|=2048,Uo(9,Sf.bind(null,s,d,o,t),void 0,null),o},useId:function(){var e=Zt(),t=Ge.identifierPrefix;if(De){var o=cn,s=an;o=(s&~(1<<32-xt(s)-1)).toString(32)+o,t=":"+t+"R"+o,o=Vo++,0z||a[w]!==d[z]){var A=` +`+a[w].replace(" at new "," at ");return e.displayName&&A.includes("")&&(A=A.replace("",e.displayName)),A}while(1<=w&&0<=z);break}}}finally{te=!1,Error.prepareStackTrace=o}return(e=e?e.displayName||e.name:"")?R(e):""}function ue(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=re(e.type,!1),e;case 11:return e=re(e.type.render,!1),e;case 1:return e=re(e.type,!0),e;default:return""}}function ce(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 D:return"Portal";case X:return"Profiler";case Y:return"StrictMode";case Z:return"Suspense";case k:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case q:return(e.displayName||"Context")+".Consumer";case ee:return(e._context.displayName||"Context")+".Provider";case J:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case B:return t=e.displayName||null,t!==null?t:ce(e.type)||"Memo";case I:t=e._payload,e=e._init;try{return ce(e(t))}catch{}}return null}function ae(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return ce(t);case 8:return t===Y?"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 t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function G(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function se(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function pe(e){var t=se(e)?"checked":"value",o=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),s=""+e[t];if(!e.hasOwnProperty(t)&&typeof o<"u"&&typeof o.get=="function"&&typeof o.set=="function"){var a=o.get,d=o.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return a.call(this)},set:function(w){s=""+w,d.call(this,w)}}),Object.defineProperty(e,t,{enumerable:o.enumerable}),{getValue:function(){return s},setValue:function(w){s=""+w},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function xe(e){e._valueTracker||(e._valueTracker=pe(e))}function ve(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var o=t.getValue(),s="";return e&&(s=se(e)?e.checked?"true":"false":e.value),e=s,e!==o?(t.setValue(e),!0):!1}function me(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 ke(e,t){var o=t.checked;return F({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:o??e._wrapperState.initialChecked})}function Ce(e,t){var o=t.defaultValue==null?"":t.defaultValue,s=t.checked!=null?t.checked:t.defaultChecked;o=G(t.value!=null?t.value:o),e._wrapperState={initialChecked:s,initialValue:o,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function Me(e,t){t=t.checked,t!=null&&_(e,"checked",t,!1)}function Le(e,t){Me(e,t);var o=G(t.value),s=t.type;if(o!=null)s==="number"?(o===0&&e.value===""||e.value!=o)&&(e.value=""+o):e.value!==""+o&&(e.value=""+o);else if(s==="submit"||s==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?ut(e,t.type,o):t.hasOwnProperty("defaultValue")&&ut(e,t.type,G(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function it(e,t,o){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var s=t.type;if(!(s!=="submit"&&s!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,o||t===e.value||(e.value=t),e.defaultValue=t}o=e.name,o!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,o!==""&&(e.name=o)}function ut(e,t,o){(t!=="number"||me(e.ownerDocument)!==e)&&(o==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+o&&(e.defaultValue=""+o))}var Je=Array.isArray;function et(e,t,o,s){if(e=e.options,t){t={};for(var a=0;a"+t.valueOf().toString()+"",t=Mt.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function on(e,t){if(t){var o=e.firstChild;if(o&&o===e.lastChild&&o.nodeType===3){o.nodeValue=t;return}}e.textContent=t}var bn={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},Sl=["Webkit","ms","Moz","O"];Object.keys(bn).forEach(function(e){Sl.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),bn[t]=bn[e]})});function wi(e,t,o){return t==null||typeof t=="boolean"||t===""?"":o||typeof t!="number"||t===0||bn.hasOwnProperty(e)&&bn[e]?(""+t).trim():t+"px"}function xi(e,t){e=e.style;for(var o in t)if(t.hasOwnProperty(o)){var s=o.indexOf("--")===0,a=wi(o,t[o],s);o==="float"&&(o="cssFloat"),s?e.setProperty(o,a):e[o]=a}}var _l=F({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 so(e,t){if(t){if(_l[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(i(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(i(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(i(61))}if(t.style!=null&&typeof t.style!="object")throw Error(i(62))}}function lo(e,t){if(e.indexOf("-")===-1)return typeof t.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 uo=null;function ao(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var co=null,vn=null,wn=null;function Si(e){if(e=jo(e)){if(typeof co!="function")throw Error(i(280));var t=e.stateNode;t&&(t=qi(t),co(e.stateNode,e.type,t))}}function _i(e){vn?wn?wn.push(e):wn=[e]:vn=e}function Ei(){if(vn){var e=vn,t=wn;if(wn=vn=null,Si(e),t)for(e=0;e>>=0,e===0?32:31-(Ll(e)/Rl|0)|0}var kr=64,Nr=4194304;function Gn(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 sn(e,t){var o=e.pendingLanes;if(o===0)return 0;var s=0,a=e.suspendedLanes,d=e.pingedLanes,w=o&268435455;if(w!==0){var z=w&~a;z!==0?s=Gn(z):(d&=w,d!==0&&(s=Gn(d)))}else w=o&~a,w!==0?s=Gn(w):d!==0&&(s=Gn(d));if(s===0)return 0;if(t!==0&&t!==s&&(t&a)===0&&(a=s&-s,d=t&-t,a>=d||a===16&&(d&4194240)!==0))return t;if((s&4)!==0&&(s|=o&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=s;0o;o++)t.push(e);return t}function qn(e,t,o){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-wt(t),e[t]=o}function $l(e,t){var o=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var s=e.eventTimes;for(e=e.expirationTimes;0=Co),Nc=" ",Cc=!1;function Mc(e,t){switch(e){case"keyup":return pm.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Pc(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Ir=!1;function mm(e,t){switch(e){case"compositionend":return Pc(t);case"keypress":return t.which!==32?null:(Cc=!0,Nc);case"textInput":return e=t.data,e===Nc&&Cc?null:e;default:return null}}function ym(e,t){if(Ir)return e==="compositionend"||!Xl&&Mc(e,t)?(e=wc(),Hi=Vl=kn=null,Ir=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:o,offset:t-e};e=s}e:{for(;o;){if(o.nextSibling){o=o.nextSibling;break e}o=o.parentNode}o=void 0}o=jc(o)}}function Dc(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Dc(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Oc(){for(var e=window,t=me();t instanceof e.HTMLIFrameElement;){try{var o=typeof t.contentWindow.location.href=="string"}catch{o=!1}if(o)e=t.contentWindow;else break;t=me(e.document)}return t}function Kl(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}function Cm(e){var t=Oc(),o=e.focusedElem,s=e.selectionRange;if(t!==o&&o&&o.ownerDocument&&Dc(o.ownerDocument.documentElement,o)){if(s!==null&&Kl(o)){if(t=s.start,e=s.end,e===void 0&&(e=t),"selectionStart"in o)o.selectionStart=t,o.selectionEnd=Math.min(e,o.value.length);else if(e=(t=o.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var a=o.textContent.length,d=Math.min(s.start,a);s=s.end===void 0?d:Math.min(s.end,a),!e.extend&&d>s&&(a=s,s=d,d=a),a=$c(o,d);var w=$c(o,s);a&&w&&(e.rangeCount!==1||e.anchorNode!==a.node||e.anchorOffset!==a.offset||e.focusNode!==w.node||e.focusOffset!==w.offset)&&(t=t.createRange(),t.setStart(a.node,a.offset),e.removeAllRanges(),d>s?(e.addRange(t),e.extend(w.node,w.offset)):(t.setEnd(w.node,w.offset),e.addRange(t)))}}for(t=[],e=o;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof o.focus=="function"&&o.focus(),o=0;o=document.documentMode,zr=null,ql=null,zo=null,Zl=!1;function Fc(e,t,o){var s=o.window===o?o.document:o.nodeType===9?o:o.ownerDocument;Zl||zr==null||zr!==me(s)||(s=zr,"selectionStart"in s&&Kl(s)?s={start:s.selectionStart,end:s.selectionEnd}:(s=(s.ownerDocument&&s.ownerDocument.defaultView||window).getSelection(),s={anchorNode:s.anchorNode,anchorOffset:s.anchorOffset,focusNode:s.focusNode,focusOffset:s.focusOffset}),zo&&Io(zo,s)||(zo=s,s=Qi(ql,"onSelect"),0jr||(e.current=cu[jr],cu[jr]=null,jr--)}function Re(e,t){jr++,cu[jr]=e.current,e.current=t}var Pn={},tt=Mn(Pn),ct=Mn(!1),Jn=Pn;function $r(e,t){var o=e.type.contextTypes;if(!o)return Pn;var s=e.stateNode;if(s&&s.__reactInternalMemoizedUnmaskedChildContext===t)return s.__reactInternalMemoizedMaskedChildContext;var a={},d;for(d in o)a[d]=t[d];return s&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=a),a}function ft(e){return e=e.childContextTypes,e!=null}function Zi(){je(ct),je(tt)}function ef(e,t,o){if(tt.current!==Pn)throw Error(i(168));Re(tt,t),Re(ct,o)}function tf(e,t,o){var s=e.stateNode;if(t=t.childContextTypes,typeof s.getChildContext!="function")return o;s=s.getChildContext();for(var a in s)if(!(a in t))throw Error(i(108,ae(e)||"Unknown",a));return F({},o,s)}function Ji(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Pn,Jn=tt.current,Re(tt,e),Re(ct,ct.current),!0}function nf(e,t,o){var s=e.stateNode;if(!s)throw Error(i(169));o?(e=tf(e,t,Jn),s.__reactInternalMemoizedMergedChildContext=e,je(ct),je(tt),Re(tt,e)):je(ct),Re(ct,o)}var un=null,es=!1,fu=!1;function rf(e){un===null?un=[e]:un.push(e)}function Om(e){es=!0,rf(e)}function In(){if(!fu&&un!==null){fu=!0;var e=0,t=Te;try{var o=un;for(Te=1;e>=w,a-=w,an=1<<32-wt(t)+a|o<Ee?(Ke=_e,_e=null):Ke=_e.sibling;var ze=ne(W,_e,b[Ee],le);if(ze===null){_e===null&&(_e=Ke);break}e&&_e&&ze.alternate===null&&t(W,_e),O=d(ze,O,Ee),Se===null?ye=ze:Se.sibling=ze,Se=ze,_e=Ke}if(Ee===b.length)return o(W,_e),De&&tr(W,Ee),ye;if(_e===null){for(;EeEe?(Ke=_e,_e=null):Ke=_e.sibling;var On=ne(W,_e,ze.value,le);if(On===null){_e===null&&(_e=Ke);break}e&&_e&&On.alternate===null&&t(W,_e),O=d(On,O,Ee),Se===null?ye=On:Se.sibling=On,Se=On,_e=Ke}if(ze.done)return o(W,_e),De&&tr(W,Ee),ye;if(_e===null){for(;!ze.done;Ee++,ze=b.next())ze=ie(W,ze.value,le),ze!==null&&(O=d(ze,O,Ee),Se===null?ye=ze:Se.sibling=ze,Se=ze);return De&&tr(W,Ee),ye}for(_e=s(W,_e);!ze.done;Ee++,ze=b.next())ze=fe(_e,W,Ee,ze.value,le),ze!==null&&(e&&ze.alternate!==null&&_e.delete(ze.key===null?Ee:ze.key),O=d(ze,O,Ee),Se===null?ye=ze:Se.sibling=ze,Se=ze);return e&&_e.forEach(function(v0){return t(W,v0)}),De&&tr(W,Ee),ye}function Ue(W,O,b,le){if(typeof b=="object"&&b!==null&&b.type===V&&b.key===null&&(b=b.props.children),typeof b=="object"&&b!==null){switch(b.$$typeof){case U:e:{for(var ye=b.key,Se=O;Se!==null;){if(Se.key===ye){if(ye=b.type,ye===V){if(Se.tag===7){o(W,Se.sibling),O=a(Se,b.props.children),O.return=W,W=O;break e}}else if(Se.elementType===ye||typeof ye=="object"&&ye!==null&&ye.$$typeof===I&&cf(ye)===Se.type){o(W,Se.sibling),O=a(Se,b.props),O.ref=$o(W,Se,b),O.return=W,W=O;break e}o(W,Se);break}else t(W,Se);Se=Se.sibling}b.type===V?(O=ar(b.props.children,W.mode,le,b.key),O.return=W,W=O):(le=Ps(b.type,b.key,b.props,null,W.mode,le),le.ref=$o(W,O,b),le.return=W,W=le)}return w(W);case D:e:{for(Se=b.key;O!==null;){if(O.key===Se)if(O.tag===4&&O.stateNode.containerInfo===b.containerInfo&&O.stateNode.implementation===b.implementation){o(W,O.sibling),O=a(O,b.children||[]),O.return=W,W=O;break e}else{o(W,O);break}else t(W,O);O=O.sibling}O=ua(b,W.mode,le),O.return=W,W=O}return w(W);case I:return Se=b._init,Ue(W,O,Se(b._payload),le)}if(Je(b))return he(W,O,b,le);if($(b))return ge(W,O,b,le);os(W,b)}return typeof b=="string"&&b!==""||typeof b=="number"?(b=""+b,O!==null&&O.tag===6?(o(W,O.sibling),O=a(O,b),O.return=W,W=O):(o(W,O),O=la(b,W.mode,le),O.return=W,W=O),w(W)):o(W,O)}return Ue}var Hr=ff(!0),df=ff(!1),is=Mn(null),ss=null,Vr=null,yu=null;function vu(){yu=Vr=ss=null}function wu(e){var t=is.current;je(is),e._currentValue=t}function xu(e,t,o){for(;e!==null;){var s=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,s!==null&&(s.childLanes|=t)):s!==null&&(s.childLanes&t)!==t&&(s.childLanes|=t),e===o)break;e=e.return}}function Br(e,t){ss=e,yu=Vr=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&t)!==0&&(dt=!0),e.firstContext=null)}function zt(e){var t=e._currentValue;if(yu!==e)if(e={context:e,memoizedValue:t,next:null},Vr===null){if(ss===null)throw Error(i(308));Vr=e,ss.dependencies={lanes:0,firstContext:e}}else Vr=Vr.next=e;return t}var nr=null;function Su(e){nr===null?nr=[e]:nr.push(e)}function hf(e,t,o,s){var a=t.interleaved;return a===null?(o.next=o,Su(t)):(o.next=a.next,a.next=o),t.interleaved=o,fn(e,s)}function fn(e,t){e.lanes|=t;var o=e.alternate;for(o!==null&&(o.lanes|=t),o=e,e=e.return;e!==null;)e.childLanes|=t,o=e.alternate,o!==null&&(o.childLanes|=t),o=e,e=e.return;return o.tag===3?o.stateNode:null}var zn=!1;function _u(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function pf(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function dn(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function Tn(e,t,o){var s=e.updateQueue;if(s===null)return null;if(s=s.shared,(Pe&2)!==0){var a=s.pending;return a===null?t.next=t:(t.next=a.next,a.next=t),s.pending=t,fn(e,o)}return a=s.interleaved,a===null?(t.next=t,Su(s)):(t.next=a.next,a.next=t),s.interleaved=t,fn(e,o)}function ls(e,t,o){if(t=t.updateQueue,t!==null&&(t=t.shared,(o&4194240)!==0)){var s=t.lanes;s&=e.pendingLanes,o|=s,t.lanes=o,Cr(e,o)}}function gf(e,t){var o=e.updateQueue,s=e.alternate;if(s!==null&&(s=s.updateQueue,o===s)){var a=null,d=null;if(o=o.firstBaseUpdate,o!==null){do{var w={eventTime:o.eventTime,lane:o.lane,tag:o.tag,payload:o.payload,callback:o.callback,next:null};d===null?a=d=w:d=d.next=w,o=o.next}while(o!==null);d===null?a=d=t:d=d.next=t}else a=d=t;o={baseState:s.baseState,firstBaseUpdate:a,lastBaseUpdate:d,shared:s.shared,effects:s.effects},e.updateQueue=o;return}e=o.lastBaseUpdate,e===null?o.firstBaseUpdate=t:e.next=t,o.lastBaseUpdate=t}function us(e,t,o,s){var a=e.updateQueue;zn=!1;var d=a.firstBaseUpdate,w=a.lastBaseUpdate,z=a.shared.pending;if(z!==null){a.shared.pending=null;var A=z,Q=A.next;A.next=null,w===null?d=Q:w.next=Q,w=A;var oe=e.alternate;oe!==null&&(oe=oe.updateQueue,z=oe.lastBaseUpdate,z!==w&&(z===null?oe.firstBaseUpdate=Q:z.next=Q,oe.lastBaseUpdate=A))}if(d!==null){var ie=a.baseState;w=0,oe=Q=A=null,z=d;do{var ne=z.lane,fe=z.eventTime;if((s&ne)===ne){oe!==null&&(oe=oe.next={eventTime:fe,lane:0,tag:z.tag,payload:z.payload,callback:z.callback,next:null});e:{var he=e,ge=z;switch(ne=t,fe=o,ge.tag){case 1:if(he=ge.payload,typeof he=="function"){ie=he.call(fe,ie,ne);break e}ie=he;break e;case 3:he.flags=he.flags&-65537|128;case 0:if(he=ge.payload,ne=typeof he=="function"?he.call(fe,ie,ne):he,ne==null)break e;ie=F({},ie,ne);break e;case 2:zn=!0}}z.callback!==null&&z.lane!==0&&(e.flags|=64,ne=a.effects,ne===null?a.effects=[z]:ne.push(z))}else fe={eventTime:fe,lane:ne,tag:z.tag,payload:z.payload,callback:z.callback,next:null},oe===null?(Q=oe=fe,A=ie):oe=oe.next=fe,w|=ne;if(z=z.next,z===null){if(z=a.shared.pending,z===null)break;ne=z,z=ne.next,ne.next=null,a.lastBaseUpdate=ne,a.shared.pending=null}}while(!0);if(oe===null&&(A=ie),a.baseState=A,a.firstBaseUpdate=Q,a.lastBaseUpdate=oe,t=a.shared.interleaved,t!==null){a=t;do w|=a.lane,a=a.next;while(a!==t)}else d===null&&(a.shared.lanes=0);ir|=w,e.lanes=w,e.memoizedState=ie}}function mf(e,t,o){if(e=t.effects,t.effects=null,e!==null)for(t=0;to?o:4,e(!0);var s=Mu.transition;Mu.transition={};try{e(!1),t()}finally{Te=o,Mu.transition=s}}function jf(){return Tt().memoizedState}function Bm(e,t,o){var s=jn(e);if(o={lane:s,action:o,hasEagerState:!1,eagerState:null,next:null},$f(e))Df(t,o);else if(o=hf(e,t,o,s),o!==null){var a=lt();Ft(o,e,s,a),Of(o,t,s)}}function Um(e,t,o){var s=jn(e),a={lane:s,action:o,hasEagerState:!1,eagerState:null,next:null};if($f(e))Df(t,a);else{var d=e.alternate;if(e.lanes===0&&(d===null||d.lanes===0)&&(d=t.lastRenderedReducer,d!==null))try{var w=t.lastRenderedState,z=d(w,o);if(a.hasEagerState=!0,a.eagerState=z,At(z,w)){var A=t.interleaved;A===null?(a.next=a,Su(t)):(a.next=A.next,A.next=a),t.interleaved=a;return}}catch{}finally{}o=hf(e,t,a,s),o!==null&&(a=lt(),Ft(o,e,s,a),Of(o,t,s))}}function $f(e){var t=e.alternate;return e===He||t!==null&&t===He}function Df(e,t){Ho=fs=!0;var o=e.pending;o===null?t.next=t:(t.next=o.next,o.next=t),e.pending=t}function Of(e,t,o){if((o&4194240)!==0){var s=t.lanes;s&=e.pendingLanes,o|=s,t.lanes=o,Cr(e,o)}}var ps={readContext:zt,useCallback:nt,useContext:nt,useEffect:nt,useImperativeHandle:nt,useInsertionEffect:nt,useLayoutEffect:nt,useMemo:nt,useReducer:nt,useRef:nt,useState:nt,useDebugValue:nt,useDeferredValue:nt,useTransition:nt,useMutableSource:nt,useSyncExternalStore:nt,useId:nt,unstable_isNewReconciler:!1},Wm={readContext:zt,useCallback:function(e,t){return Zt().memoizedState=[e,t===void 0?null:t],e},useContext:zt,useEffect:Mf,useImperativeHandle:function(e,t,o){return o=o!=null?o.concat([e]):null,ds(4194308,4,zf.bind(null,t,e),o)},useLayoutEffect:function(e,t){return ds(4194308,4,e,t)},useInsertionEffect:function(e,t){return ds(4,2,e,t)},useMemo:function(e,t){var o=Zt();return t=t===void 0?null:t,e=e(),o.memoizedState=[e,t],e},useReducer:function(e,t,o){var s=Zt();return t=o!==void 0?o(t):t,s.memoizedState=s.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},s.queue=e,e=e.dispatch=Bm.bind(null,He,e),[s.memoizedState,e]},useRef:function(e){var t=Zt();return e={current:e},t.memoizedState=e},useState:Nf,useDebugValue:Au,useDeferredValue:function(e){return Zt().memoizedState=e},useTransition:function(){var e=Nf(!1),t=e[0];return e=Vm.bind(null,e[1]),Zt().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,o){var s=He,a=Zt();if(De){if(o===void 0)throw Error(i(407));o=o()}else{if(o=t(),Ge===null)throw Error(i(349));(or&30)!==0||xf(s,t,o)}a.memoizedState=o;var d={value:o,getSnapshot:t};return a.queue=d,Mf(_f.bind(null,s,d,e),[e]),s.flags|=2048,Uo(9,Sf.bind(null,s,d,o,t),void 0,null),o},useId:function(){var e=Zt(),t=Ge.identifierPrefix;if(De){var o=cn,s=an;o=(s&~(1<<32-wt(s)-1)).toString(32)+o,t=":"+t+"R"+o,o=Vo++,0<\/script>",e=e.removeChild(e.firstChild)):typeof s.is=="string"?e=x.createElement(o,{is:s.is}):(e=x.createElement(o),o==="select"&&(x=e,s.multiple?x.multiple=!0:s.size&&(x.size=s.size))):e=x.createElementNS(e,o),e[Kt]=t,e[Ao]=s,od(e,t,!1,!1),t.stateNode=e;e:{switch(x=lo(o,s),o){case"dialog":Ae("cancel",e),Ae("close",e),a=s;break;case"iframe":case"object":case"embed":Ae("load",e),a=s;break;case"video":case"audio":for(a=0;abr&&(t.flags|=128,s=!0,Wo(d,!1),t.lanes=4194304)}else{if(!s)if(e=as(x),e!==null){if(t.flags|=128,s=!0,o=e.updateQueue,o!==null&&(t.updateQueue=o,t.flags|=4),Wo(d,!0),d.tail===null&&d.tailMode==="hidden"&&!x.alternate&&!De)return rt(t),null}else 2*Oe()-d.renderingStartTime>br&&o!==1073741824&&(t.flags|=128,s=!0,Wo(d,!1),t.lanes=4194304);d.isBackwards?(x.sibling=t.child,t.child=x):(o=d.last,o!==null?o.sibling=x:t.child=x,d.last=x)}return d.tail!==null?(t=d.tail,d.rendering=t,d.tail=t.sibling,d.renderingStartTime=Oe(),t.sibling=null,o=Fe.current,Re(Fe,s?o&1|2:o&1),t):(rt(t),null);case 22:case 23:return oa(),s=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==s&&(t.flags|=8192),s&&(t.mode&1)!==0?(Et&1073741824)!==0&&(rt(t),t.subtreeFlags&6&&(t.flags|=8192)):rt(t),null;case 24:return null;case 25:return null}throw Error(i(156,t.tag))}function Zm(e,t){switch(hu(t),t.tag){case 1:return ft(t.type)&&Zi(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Ur(),je(ct),je(tt),Cu(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 5:return ku(t),null;case 13:if(je(Fe),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));Fr()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return je(Fe),null;case 4:return Ur(),null;case 10:return xu(t.type._context),null;case 22:case 23:return oa(),null;case 24:return null;default:return null}}var vs=!1,ot=!1,Jm=typeof WeakSet=="function"?WeakSet:Set,de=null;function Yr(e,t){var o=e.ref;if(o!==null)if(typeof o=="function")try{o(null)}catch(s){Be(e,t,s)}else o.current=null}function Xu(e,t,o){try{o()}catch(s){Be(e,t,s)}}var ld=!1;function e0(e,t){if(ou=Oi,e=Oc(),Kl(e)){if("selectionStart"in e)var o={start:e.selectionStart,end:e.selectionEnd};else e:{o=(o=e.ownerDocument)&&o.defaultView||window;var s=o.getSelection&&o.getSelection();if(s&&s.rangeCount!==0){o=s.anchorNode;var a=s.anchorOffset,d=s.focusNode;s=s.focusOffset;try{o.nodeType,d.nodeType}catch{o=null;break e}var x=0,I=-1,A=-1,Q=0,oe=0,ie=e,ne=null;t:for(;;){for(var fe;ie!==o||a!==0&&ie.nodeType!==3||(I=x+a),ie!==d||s!==0&&ie.nodeType!==3||(A=x+s),ie.nodeType===3&&(x+=ie.nodeValue.length),(fe=ie.firstChild)!==null;)ne=ie,ie=fe;for(;;){if(ie===e)break t;if(ne===o&&++Q===a&&(I=x),ne===d&&++oe===s&&(A=x),(fe=ie.nextSibling)!==null)break;ie=ne,ne=ie.parentNode}ie=fe}o=I===-1||A===-1?null:{start:I,end:A}}else o=null}o=o||{start:0,end:0}}else o=null;for(iu={focusedElem:e,selectionRange:o},Oi=!1,de=t;de!==null;)if(t=de,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,de=e;else for(;de!==null;){t=de;try{var he=t.alternate;if((t.flags&1024)!==0)switch(t.tag){case 0:case 11:case 15:break;case 1:if(he!==null){var ge=he.memoizedProps,Ue=he.memoizedState,W=t.stateNode,O=W.getSnapshotBeforeUpdate(t.elementType===t.type?ge:$t(t.type,ge),Ue);W.__reactInternalSnapshotBeforeUpdate=O}break;case 3:var Y=t.stateNode.containerInfo;Y.nodeType===1?Y.textContent="":Y.nodeType===9&&Y.documentElement&&Y.removeChild(Y.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(i(163))}}catch(le){Be(t,t.return,le)}if(e=t.sibling,e!==null){e.return=t.return,de=e;break}de=t.return}return he=ld,ld=!1,he}function Yo(e,t,o){var s=t.updateQueue;if(s=s!==null?s.lastEffect:null,s!==null){var a=s=s.next;do{if((a.tag&e)===e){var d=a.destroy;a.destroy=void 0,d!==void 0&&Xu(t,o,d)}a=a.next}while(a!==s)}}function xs(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var o=t=t.next;do{if((o.tag&e)===e){var s=o.create;o.destroy=s()}o=o.next}while(o!==t)}}function bu(e){var t=e.ref;if(t!==null){var o=e.stateNode;switch(e.tag){case 5:e=o;break;default:e=o}typeof t=="function"?t(e):t.current=e}}function ud(e){var t=e.alternate;t!==null&&(e.alternate=null,ud(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[Kt],delete t[Ao],delete t[au],delete t[$m],delete t[Dm])),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 ad(e){return e.tag===5||e.tag===3||e.tag===4}function cd(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||ad(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 Qu(e,t,o){var s=e.tag;if(s===5||s===6)e=e.stateNode,t?o.nodeType===8?o.parentNode.insertBefore(e,t):o.insertBefore(e,t):(o.nodeType===8?(t=o.parentNode,t.insertBefore(e,o)):(t=o,t.appendChild(e)),o=o._reactRootContainer,o!=null||t.onclick!==null||(t.onclick=Ki));else if(s!==4&&(e=e.child,e!==null))for(Qu(e,t,o),e=e.sibling;e!==null;)Qu(e,t,o),e=e.sibling}function Gu(e,t,o){var s=e.tag;if(s===5||s===6)e=e.stateNode,t?o.insertBefore(e,t):o.appendChild(e);else if(s!==4&&(e=e.child,e!==null))for(Gu(e,t,o),e=e.sibling;e!==null;)Gu(e,t,o),e=e.sibling}var qe=null,Dt=!1;function Ln(e,t,o){for(o=o.child;o!==null;)fd(e,t,o),o=o.sibling}function fd(e,t,o){if(vt&&typeof vt.onCommitFiberUnmount=="function")try{vt.onCommitFiberUnmount(Er,o)}catch{}switch(o.tag){case 5:ot||Yr(o,t);case 6:var s=qe,a=Dt;qe=null,Ln(e,t,o),qe=s,Dt=a,qe!==null&&(Dt?(e=qe,o=o.stateNode,e.nodeType===8?e.parentNode.removeChild(o):e.removeChild(o)):qe.removeChild(o.stateNode));break;case 18:qe!==null&&(Dt?(e=qe,o=o.stateNode,e.nodeType===8?uu(e.parentNode,o):e.nodeType===1&&uu(e,o),Eo(e)):uu(qe,o.stateNode));break;case 4:s=qe,a=Dt,qe=o.stateNode.containerInfo,Dt=!0,Ln(e,t,o),qe=s,Dt=a;break;case 0:case 11:case 14:case 15:if(!ot&&(s=o.updateQueue,s!==null&&(s=s.lastEffect,s!==null))){a=s=s.next;do{var d=a,x=d.destroy;d=d.tag,x!==void 0&&((d&2)!==0||(d&4)!==0)&&Xu(o,t,x),a=a.next}while(a!==s)}Ln(e,t,o);break;case 1:if(!ot&&(Yr(o,t),s=o.stateNode,typeof s.componentWillUnmount=="function"))try{s.props=o.memoizedProps,s.state=o.memoizedState,s.componentWillUnmount()}catch(I){Be(o,t,I)}Ln(e,t,o);break;case 21:Ln(e,t,o);break;case 22:o.mode&1?(ot=(s=ot)||o.memoizedState!==null,Ln(e,t,o),ot=s):Ln(e,t,o);break;default:Ln(e,t,o)}}function dd(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var o=e.stateNode;o===null&&(o=e.stateNode=new Jm),t.forEach(function(s){var a=a0.bind(null,e,s);o.has(s)||(o.add(s),s.then(a,a))})}}function Ot(e,t){var o=t.deletions;if(o!==null)for(var s=0;sa&&(a=x),s&=~d}if(s=a,s=Oe()-s,s=(120>s?120:480>s?480:1080>s?1080:1920>s?1920:3e3>s?3e3:4320>s?4320:1960*n0(s/1960))-s,10e?16:e,An===null)var s=!1;else{if(e=An,An=null,ks=0,(Pe&6)!==0)throw Error(i(331));var a=Pe;for(Pe|=4,de=e.current;de!==null;){var d=de,x=d.child;if((de.flags&16)!==0){var I=d.deletions;if(I!==null){for(var A=0;AOe()-Zu?lr(e,0):qu|=o),pt(e,t)}function Nd(e,t){t===0&&((e.mode&1)===0?t=1:(t=Nr,Nr<<=1,(Nr&130023424)===0&&(Nr=4194304)));var o=lt();e=fn(e,t),e!==null&&(qn(e,t,o),pt(e,o))}function u0(e){var t=e.memoizedState,o=0;t!==null&&(o=t.retryLane),Nd(e,o)}function a0(e,t){var o=0;switch(e.tag){case 13:var s=e.stateNode,a=e.memoizedState;a!==null&&(o=a.retryLane);break;case 19:s=e.stateNode;break;default:throw Error(i(314))}s!==null&&s.delete(t),Nd(e,o)}var Cd;Cd=function(e,t,o){if(e!==null)if(e.memoizedProps!==t.pendingProps||ct.current)dt=!0;else{if((e.lanes&o)===0&&(t.flags&128)===0)return dt=!1,Km(e,t,o);dt=(e.flags&131072)!==0}else dt=!1,De&&(t.flags&1048576)!==0&&of(t,ns,t.index);switch(t.lanes=0,t.tag){case 2:var s=t.type;ys(e,t),e=t.pendingProps;var a=$r(t,tt.current);Br(t,o),a=Iu(null,t,s,e,a,o);var d=zu();return t.flags|=1,typeof a=="object"&&a!==null&&typeof a.render=="function"&&a.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,ft(s)?(d=!0,Ji(t)):d=!1,t.memoizedState=a.state!==null&&a.state!==void 0?a.state:null,_u(t),a.updater=gs,t.stateNode=a,a._reactInternals=t,$u(t,s,e,o),t=Hu(null,t,s,!0,d,o)):(t.tag=0,De&&d&&du(t),st(null,t,a,o),t=t.child),t;case 16:s=t.elementType;e:{switch(ys(e,t),e=t.pendingProps,a=s._init,s=a(s._payload),t.type=s,a=t.tag=f0(s),e=$t(s,e),a){case 0:t=Fu(null,t,s,e,o);break e;case 1:t=Zf(null,t,s,e,o);break e;case 11:t=bf(null,t,s,e,o);break e;case 14:t=Qf(null,t,s,$t(s.type,e),o);break e}throw Error(i(306,s,""))}return t;case 0:return s=t.type,a=t.pendingProps,a=t.elementType===s?a:$t(s,a),Fu(e,t,s,a,o);case 1:return s=t.type,a=t.pendingProps,a=t.elementType===s?a:$t(s,a),Zf(e,t,s,a,o);case 3:e:{if(Jf(t),e===null)throw Error(i(387));s=t.pendingProps,d=t.memoizedState,a=d.element,pf(e,t),us(t,s,null,o);var x=t.memoizedState;if(s=x.element,d.isDehydrated)if(d={element:s,isDehydrated:!1,cache:x.cache,pendingSuspenseBoundaries:x.pendingSuspenseBoundaries,transitions:x.transitions},t.updateQueue.baseState=d,t.memoizedState=d,t.flags&256){a=Wr(Error(i(423)),t),t=ed(e,t,s,o,a);break e}else if(s!==a){a=Wr(Error(i(424)),t),t=ed(e,t,s,o,a);break e}else for(_t=Cn(t.stateNode.containerInfo.firstChild),St=t,De=!0,jt=null,o=df(t,null,s,o),t.child=o;o;)o.flags=o.flags&-3|4096,o=o.sibling;else{if(Fr(),s===a){t=hn(e,t,o);break e}st(e,t,s,o)}t=t.child}return t;case 5:return yf(t),e===null&&gu(t),s=t.type,a=t.pendingProps,d=e!==null?e.memoizedProps:null,x=a.children,su(s,a)?x=null:d!==null&&su(s,d)&&(t.flags|=32),qf(e,t),st(e,t,x,o),t.child;case 6:return e===null&&gu(t),null;case 13:return td(e,t,o);case 4:return Eu(t,t.stateNode.containerInfo),s=t.pendingProps,e===null?t.child=Hr(t,null,s,o):st(e,t,s,o),t.child;case 11:return s=t.type,a=t.pendingProps,a=t.elementType===s?a:$t(s,a),bf(e,t,s,a,o);case 7:return st(e,t,t.pendingProps,o),t.child;case 8:return st(e,t,t.pendingProps.children,o),t.child;case 12:return st(e,t,t.pendingProps.children,o),t.child;case 10:e:{if(s=t.type._context,a=t.pendingProps,d=t.memoizedProps,x=a.value,Re(is,s._currentValue),s._currentValue=x,d!==null)if(At(d.value,x)){if(d.children===a.children&&!ct.current){t=hn(e,t,o);break e}}else for(d=t.child,d!==null&&(d.return=t);d!==null;){var I=d.dependencies;if(I!==null){x=d.child;for(var A=I.firstContext;A!==null;){if(A.context===s){if(d.tag===1){A=dn(-1,o&-o),A.tag=2;var Q=d.updateQueue;if(Q!==null){Q=Q.shared;var oe=Q.pending;oe===null?A.next=A:(A.next=oe.next,oe.next=A),Q.pending=A}}d.lanes|=o,A=d.alternate,A!==null&&(A.lanes|=o),wu(d.return,o,t),I.lanes|=o;break}A=A.next}}else if(d.tag===10)x=d.type===t.type?null:d.child;else if(d.tag===18){if(x=d.return,x===null)throw Error(i(341));x.lanes|=o,I=x.alternate,I!==null&&(I.lanes|=o),wu(x,o,t),x=d.sibling}else x=d.child;if(x!==null)x.return=d;else for(x=d;x!==null;){if(x===t){x=null;break}if(d=x.sibling,d!==null){d.return=x.return,x=d;break}x=x.return}d=x}st(e,t,a.children,o),t=t.child}return t;case 9:return a=t.type,s=t.pendingProps.children,Br(t,o),a=zt(a),s=s(a),t.flags|=1,st(e,t,s,o),t.child;case 14:return s=t.type,a=$t(s,t.pendingProps),a=$t(s.type,a),Qf(e,t,s,a,o);case 15:return Gf(e,t,t.type,t.pendingProps,o);case 17:return s=t.type,a=t.pendingProps,a=t.elementType===s?a:$t(s,a),ys(e,t),t.tag=1,ft(s)?(e=!0,Ji(t)):e=!1,Br(t,o),Hf(t,s,a),$u(t,s,a,o),Hu(null,t,s,!0,e,o);case 19:return rd(e,t,o);case 22:return Kf(e,t,o)}throw Error(i(156,t.tag))};function Md(e,t){return Ii(e,t)}function c0(e,t,o,s){this.tag=e,this.key=o,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=s,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Rt(e,t,o,s){return new c0(e,t,o,s)}function sa(e){return e=e.prototype,!(!e||!e.isReactComponent)}function f0(e){if(typeof e=="function")return sa(e)?1:0;if(e!=null){if(e=e.$$typeof,e===J)return 11;if(e===B)return 14}return 2}function Dn(e,t){var o=e.alternate;return o===null?(o=Rt(e.tag,t,e.key,e.mode),o.elementType=e.elementType,o.type=e.type,o.stateNode=e.stateNode,o.alternate=e,e.alternate=o):(o.pendingProps=t,o.type=e.type,o.flags=0,o.subtreeFlags=0,o.deletions=null),o.flags=e.flags&14680064,o.childLanes=e.childLanes,o.lanes=e.lanes,o.child=e.child,o.memoizedProps=e.memoizedProps,o.memoizedState=e.memoizedState,o.updateQueue=e.updateQueue,t=e.dependencies,o.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},o.sibling=e.sibling,o.index=e.index,o.ref=e.ref,o}function Ps(e,t,o,s,a,d){var x=2;if(s=e,typeof e=="function")sa(e)&&(x=1);else if(typeof e=="string")x=5;else e:switch(e){case V:return ar(o.children,a,d,t);case X:x=8,a|=8;break;case b:return e=Rt(12,o,t,a|2),e.elementType=b,e.lanes=d,e;case Z:return e=Rt(13,o,t,a),e.elementType=Z,e.lanes=d,e;case k:return e=Rt(19,o,t,a),e.elementType=k,e.lanes=d,e;case H:return Is(o,a,d,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case ee:x=10;break e;case q:x=9;break e;case J:x=11;break e;case B:x=14;break e;case z:x=16,s=null;break e}throw Error(i(130,e==null?e:typeof e,""))}return t=Rt(x,o,t,a),t.elementType=e,t.type=s,t.lanes=d,t}function ar(e,t,o,s){return e=Rt(7,e,s,t),e.lanes=o,e}function Is(e,t,o,s){return e=Rt(22,e,s,t),e.elementType=H,e.lanes=o,e.stateNode={isHidden:!1},e}function la(e,t,o){return e=Rt(6,e,null,t),e.lanes=o,e}function ua(e,t,o){return t=Rt(4,e.children!==null?e.children:[],e.key,t),t.lanes=o,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function d0(e,t,o,s,a){this.tag=t,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=Kn(0),this.expirationTimes=Kn(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Kn(0),this.identifierPrefix=s,this.onRecoverableError=a,this.mutableSourceEagerHydrationData=null}function aa(e,t,o,s,a,d,x,I,A){return e=new d0(e,t,o,I,A),t===1?(t=1,d===!0&&(t|=8)):t=0,d=Rt(3,null,null,t),e.current=d,d.stateNode=e,d.memoizedState={element:s,isDehydrated:o,cache:null,transitions:null,pendingSuspenseBoundaries:null},_u(d),e}function h0(e,t,o){var s=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(r){console.error(r)}}return n(),ga.exports=N0(),ga.exports}var Vd;function C0(){if(Vd)return $s;Vd=1;var n=Jh();return $s.createRoot=n.createRoot,$s.hydrateRoot=n.hydrateRoot,$s}var M0=C0();async function Fn(n,r){const i=await fetch(n,{...r,headers:{"Content-Type":"application/json",...(r==null?void 0:r.headers)||{}}});if(!i.ok){const l=await i.text();throw new Error(l||i.statusText)}return i.json()}const Gr={health:()=>Fn("/api/health"),settings:()=>Fn("/api/settings"),saveSettings:n=>Fn("/api/settings",{method:"PUT",body:JSON.stringify(n)}),index:n=>Fn("/api/index",{method:"POST",body:JSON.stringify({repo_path:n,incremental:!0})}),review:(n,r,i)=>Fn("/api/review",{method:"POST",body:JSON.stringify({repo_path:n,base:r,head:i||null,reindex:!0})}),graph:n=>Fn(`/api/graph?repo_path=${encodeURIComponent(n)}`),prs:(n,r,i="open")=>Fn("/api/prs",{method:"POST",body:JSON.stringify({provider:n,repo:r,state:i})}),residual:n=>Fn("/api/ai/residual",{method:"POST",body:JSON.stringify({review:n})})};function Ye(n){if(typeof n=="string"||typeof n=="number")return""+n;let r="";if(Array.isArray(n))for(let i=0,l;i{}};function al(){for(var n=0,r=arguments.length,i={},l;n=0&&(l=i.slice(u+1),i=i.slice(0,u)),i&&!r.hasOwnProperty(i))throw new Error("unknown type: "+i);return{type:i,name:l}})}Xs.prototype=al.prototype={constructor:Xs,on:function(n,r){var i=this._,l=I0(n+"",i),u,c=-1,f=l.length;if(arguments.length<2){for(;++c0)for(var i=new Array(u),l=0,u,c;l=0&&(r=n.slice(0,i))!=="xmlns"&&(n=n.slice(i+1)),Ud.hasOwnProperty(r)?{space:Ud[r],local:n}:n}function T0(n){return function(){var r=this.ownerDocument,i=this.namespaceURI;return i===Ta&&r.documentElement.namespaceURI===Ta?r.createElement(n):r.createElementNS(i,n)}}function L0(n){return function(){return this.ownerDocument.createElementNS(n.space,n.local)}}function ep(n){var r=cl(n);return(r.local?L0:T0)(r)}function R0(){}function Ya(n){return n==null?R0:function(){return this.querySelector(n)}}function A0(n){typeof n!="function"&&(n=Ya(n));for(var r=this._groups,i=r.length,l=new Array(i),u=0;u=_&&(_=L+1);!(U=N[_])&&++_=0;)(f=l[u])&&(c&&f.compareDocumentPosition(c)^4&&c.parentNode.insertBefore(f,c),c=f);return this}function iy(n){n||(n=sy);function r(y,g){return y&&g?n(y.__data__,g.__data__):!y-!g}for(var i=this._groups,l=i.length,u=new Array(l),c=0;cr?1:n>=r?0:NaN}function ly(){var n=arguments[0];return arguments[0]=this,n.apply(null,arguments),this}function uy(){return Array.from(this)}function ay(){for(var n=this._groups,r=0,i=n.length;r1?this.each((r==null?wy:typeof r=="function"?_y:Sy)(n,r,i??"")):eo(this.node(),n)}function eo(n,r){return n.style.getPropertyValue(r)||ip(n).getComputedStyle(n,null).getPropertyValue(r)}function ky(n){return function(){delete this[n]}}function Ny(n,r){return function(){this[n]=r}}function Cy(n,r){return function(){var i=r.apply(this,arguments);i==null?delete this[n]:this[n]=i}}function My(n,r){return arguments.length>1?this.each((r==null?ky:typeof r=="function"?Cy:Ny)(n,r)):this.node()[n]}function sp(n){return n.trim().split(/^|\s+/)}function Xa(n){return n.classList||new lp(n)}function lp(n){this._node=n,this._names=sp(n.getAttribute("class")||"")}lp.prototype={add:function(n){var r=this._names.indexOf(n);r<0&&(this._names.push(n),this._node.setAttribute("class",this._names.join(" ")))},remove:function(n){var r=this._names.indexOf(n);r>=0&&(this._names.splice(r,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(n){return this._names.indexOf(n)>=0}};function up(n,r){for(var i=Xa(n),l=-1,u=r.length;++l=0&&(i=r.slice(l+1),r=r.slice(0,l)),{type:r,name:i}})}function tv(n){return function(){var r=this.__on;if(r){for(var i=0,l=-1,u=r.length,c;i()=>n;function La(n,{sourceEvent:r,subject:i,target:l,identifier:u,active:c,x:f,y:h,dx:p,dy:m,dispatch:v}){Object.defineProperties(this,{type:{value:n,enumerable:!0,configurable:!0},sourceEvent:{value:r,enumerable:!0,configurable:!0},subject:{value:i,enumerable:!0,configurable:!0},target:{value:l,enumerable:!0,configurable:!0},identifier:{value:u,enumerable:!0,configurable:!0},active:{value:c,enumerable:!0,configurable:!0},x:{value:f,enumerable:!0,configurable:!0},y:{value:h,enumerable:!0,configurable:!0},dx:{value:p,enumerable:!0,configurable:!0},dy:{value:m,enumerable:!0,configurable:!0},_:{value:v}})}La.prototype.on=function(){var n=this._.on.apply(this._,arguments);return n===this._?this:n};function fv(n){return!n.ctrlKey&&!n.button}function dv(){return this.parentNode}function hv(n,r){return r??{x:n.x,y:n.y}}function pv(){return navigator.maxTouchPoints||"ontouchstart"in this}function pp(){var n=fv,r=dv,i=hv,l=pv,u={},c=al("start","drag","end"),f=0,h,p,m,v,y=0;function g(P){P.on("mousedown.drag",w).filter(l).on("touchstart.drag",N).on("touchmove.drag",E,cv).on("touchend.drag touchcancel.drag",L).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function w(P,U){if(!(v||!n.call(this,P,U))){var D=_(this,r.call(this,P,U),P,U,"mouse");D&&(kt(P.view).on("mousemove.drag",S,ri).on("mouseup.drag",M,ri),dp(P.view),va(P),m=!1,h=P.clientX,p=P.clientY,D("start",P))}}function S(P){if(Zr(P),!m){var U=P.clientX-h,D=P.clientY-p;m=U*U+D*D>y}u.mouse("drag",P)}function M(P){kt(P.view).on("mousemove.drag mouseup.drag",null),hp(P.view,m),Zr(P),u.mouse("end",P)}function N(P,U){if(n.call(this,P,U)){var D=P.changedTouches,V=r.call(this,P,U),X=D.length,b,ee;for(b=0;b>8&15|r>>4&240,r>>4&15|r&240,(r&15)<<4|r&15,1):i===8?Os(r>>24&255,r>>16&255,r>>8&255,(r&255)/255):i===4?Os(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=mv.exec(n))?new mt(r[1],r[2],r[3],1):(r=yv.exec(n))?new mt(r[1]*255/100,r[2]*255/100,r[3]*255/100,1):(r=vv.exec(n))?Os(r[1],r[2],r[3],r[4]):(r=xv.exec(n))?Os(r[1]*255/100,r[2]*255/100,r[3]*255/100,r[4]):(r=wv.exec(n))?Kd(r[1],r[2]/100,r[3]/100,1):(r=Sv.exec(n))?Kd(r[1],r[2]/100,r[3]/100,r[4]):Wd.hasOwnProperty(n)?bd(Wd[n]):n==="transparent"?new mt(NaN,NaN,NaN,0):null}function bd(n){return new mt(n>>16&255,n>>8&255,n&255,1)}function Os(n,r,i,l){return l<=0&&(n=r=i=NaN),new mt(n,r,i,l)}function kv(n){return n instanceof pi||(n=pr(n)),n?(n=n.rgb(),new mt(n.r,n.g,n.b,n.opacity)):new mt}function Ra(n,r,i,l){return arguments.length===1?kv(n):new mt(n,r,i,l??1)}function mt(n,r,i,l){this.r=+n,this.g=+r,this.b=+i,this.opacity=+l}ba(mt,Ra,gp(pi,{brighter(n){return n=n==null?Zs:Math.pow(Zs,n),new mt(this.r*n,this.g*n,this.b*n,this.opacity)},darker(n){return n=n==null?oi:Math.pow(oi,n),new mt(this.r*n,this.g*n,this.b*n,this.opacity)},rgb(){return this},clamp(){return new mt(dr(this.r),dr(this.g),dr(this.b),Js(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:Qd,formatHex:Qd,formatHex8:Nv,formatRgb:Gd,toString:Gd}));function Qd(){return`#${fr(this.r)}${fr(this.g)}${fr(this.b)}`}function Nv(){return`#${fr(this.r)}${fr(this.g)}${fr(this.b)}${fr((isNaN(this.opacity)?1:this.opacity)*255)}`}function Gd(){const n=Js(this.opacity);return`${n===1?"rgb(":"rgba("}${dr(this.r)}, ${dr(this.g)}, ${dr(this.b)}${n===1?")":`, ${n})`}`}function Js(n){return isNaN(n)?1:Math.max(0,Math.min(1,n))}function dr(n){return Math.max(0,Math.min(255,Math.round(n)||0))}function fr(n){return n=dr(n),(n<16?"0":"")+n.toString(16)}function Kd(n,r,i,l){return l<=0?n=r=i=NaN:i<=0||i>=1?n=r=NaN:r<=0&&(n=NaN),new Vt(n,r,i,l)}function mp(n){if(n instanceof Vt)return new Vt(n.h,n.s,n.l,n.opacity);if(n instanceof pi||(n=pr(n)),!n)return new Vt;if(n instanceof Vt)return n;n=n.rgb();var r=n.r/255,i=n.g/255,l=n.b/255,u=Math.min(r,i,l),c=Math.max(r,i,l),f=NaN,h=c-u,p=(c+u)/2;return h?(r===c?f=(i-l)/h+(i0&&p<1?0:f,new Vt(f,h,p,n.opacity)}function Cv(n,r,i,l){return arguments.length===1?mp(n):new Vt(n,r,i,l??1)}function Vt(n,r,i,l){this.h=+n,this.s=+r,this.l=+i,this.opacity=+l}ba(Vt,Cv,gp(pi,{brighter(n){return n=n==null?Zs:Math.pow(Zs,n),new Vt(this.h,this.s,this.l*n,this.opacity)},darker(n){return n=n==null?oi:Math.pow(oi,n),new Vt(this.h,this.s,this.l*n,this.opacity)},rgb(){var n=this.h%360+(this.h<0)*360,r=isNaN(n)||isNaN(this.s)?0:this.s,i=this.l,l=i+(i<.5?i:1-i)*r,u=2*i-l;return new mt(xa(n>=240?n-240:n+120,u,l),xa(n,u,l),xa(n<120?n+240:n-120,u,l),this.opacity)},clamp(){return new Vt(qd(this.h),Fs(this.s),Fs(this.l),Js(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 n=Js(this.opacity);return`${n===1?"hsl(":"hsla("}${qd(this.h)}, ${Fs(this.s)*100}%, ${Fs(this.l)*100}%${n===1?")":`, ${n})`}`}}));function qd(n){return n=(n||0)%360,n<0?n+360:n}function Fs(n){return Math.max(0,Math.min(1,n||0))}function xa(n,r,i){return(n<60?r+(i-r)*n/60:n<180?i:n<240?r+(i-r)*(240-n)/60:r)*255}const Qa=n=>()=>n;function Mv(n,r){return function(i){return n+i*r}}function Pv(n,r,i){return n=Math.pow(n,i),r=Math.pow(r,i)-n,i=1/i,function(l){return Math.pow(n+l*r,i)}}function Iv(n){return(n=+n)==1?yp:function(r,i){return i-r?Pv(r,i,n):Qa(isNaN(r)?i:r)}}function yp(n,r){var i=r-n;return i?Mv(n,i):Qa(isNaN(n)?r:n)}const el=(function n(r){var i=Iv(r);function l(u,c){var f=i((u=Ra(u)).r,(c=Ra(c)).r),h=i(u.g,c.g),p=i(u.b,c.b),m=yp(u.opacity,c.opacity);return function(v){return u.r=f(v),u.g=h(v),u.b=p(v),u.opacity=m(v),u+""}}return l.gamma=n,l})(1);function zv(n,r){r||(r=[]);var i=n?Math.min(r.length,n.length):0,l=r.slice(),u;return function(c){for(u=0;ui&&(c=r.slice(i,c),h[f]?h[f]+=c:h[++f]=c),(l=l[0])===(u=u[0])?h[f]?h[f]+=u:h[++f]=u:(h[++f]=null,p.push({i:f,x:en(l,u)})),i=wa.lastIndex;return i180?v+=360:v-m>180&&(m+=360),g.push({i:y.push(u(y)+"rotate(",null,l)-2,x:en(m,v)})):v&&y.push(u(y)+"rotate("+v+l)}function h(m,v,y,g){m!==v?g.push({i:y.push(u(y)+"skewX(",null,l)-2,x:en(m,v)}):v&&y.push(u(y)+"skewX("+v+l)}function p(m,v,y,g,w,S){if(m!==y||v!==g){var M=w.push(u(w)+"scale(",null,",",null,")");S.push({i:M-4,x:en(m,y)},{i:M-2,x:en(v,g)})}else(y!==1||g!==1)&&w.push(u(w)+"scale("+y+","+g+")")}return function(m,v){var y=[],g=[];return m=n(m),v=n(v),c(m.translateX,m.translateY,v.translateX,v.translateY,y,g),f(m.rotate,v.rotate,y,g),h(m.skewX,v.skewX,y,g),p(m.scaleX,m.scaleY,v.scaleX,v.scaleY,y,g),m=v=null,function(w){for(var S=-1,M=g.length,N;++S=0&&n._call.call(void 0,r),n=n._next;--to}function eh(){gr=(nl=si.now())+fl,to=Jo=0;try{Yv()}finally{to=0,bv(),gr=0}}function Xv(){var n=si.now(),r=n-nl;r>Sp&&(fl-=r,nl=n)}function bv(){for(var n,r=tl,i,l=1/0;r;)r._call?(l>r._time&&(l=r._time),n=r,r=r._next):(i=r._next,r._next=null,r=n?n._next=i:tl=i);ei=n,$a(l)}function $a(n){if(!to){Jo&&(Jo=clearTimeout(Jo));var r=n-gr;r>24?(n<1/0&&(Jo=setTimeout(eh,n-si.now()-fl)),qo&&(qo=clearInterval(qo))):(qo||(nl=si.now(),qo=setInterval(Xv,Sp)),to=1,_p(eh))}}function th(n,r,i){var l=new rl;return r=r==null?0:+r,l.restart(u=>{l.stop(),n(u+r)},r,i),l}var Qv=al("start","end","cancel","interrupt"),Gv=[],kp=0,nh=1,Da=2,Qs=3,rh=4,Oa=5,Gs=6;function dl(n,r,i,l,u,c){var f=n.__transition;if(!f)n.__transition={};else if(i in f)return;Kv(n,i,{name:r,index:l,group:u,on:Qv,tween:Gv,time:c.time,delay:c.delay,duration:c.duration,ease:c.ease,timer:null,state:kp})}function Ka(n,r){var i=Yt(n,r);if(i.state>kp)throw new Error("too late; already scheduled");return i}function nn(n,r){var i=Yt(n,r);if(i.state>Qs)throw new Error("too late; already running");return i}function Yt(n,r){var i=n.__transition;if(!i||!(i=i[r]))throw new Error("transition not found");return i}function Kv(n,r,i){var l=n.__transition,u;l[r]=i,i.timer=Ep(c,0,i.time);function c(m){i.state=nh,i.timer.restart(f,i.delay,i.time),i.delay<=m&&f(m-i.delay)}function f(m){var v,y,g,w;if(i.state!==nh)return p();for(v in l)if(w=l[v],w.name===i.name){if(w.state===Qs)return th(f);w.state===rh?(w.state=Gs,w.timer.stop(),w.on.call("interrupt",n,n.__data__,w.index,w.group),delete l[v]):+vDa&&l.state=0&&(r=r.slice(0,i)),!r||r==="start"})}function Cx(n,r,i){var l,u,c=Nx(r)?Ka:nn;return function(){var f=c(this,n),h=f.on;h!==l&&(u=(l=h).copy()).on(r,i),f.on=u}}function Mx(n,r){var i=this._id;return arguments.length<2?Yt(this.node(),i).on.on(n):this.each(Cx(i,n,r))}function Px(n){return function(){var r=this.parentNode;for(var i in this.__transition)if(+i!==n)return;r&&r.removeChild(this)}}function Ix(){return this.on("end.remove",Px(this._id))}function zx(n){var r=this._name,i=this._id;typeof n!="function"&&(n=Ya(n));for(var l=this._groups,u=l.length,c=new Array(u),f=0;f()=>n;function tw(n,{sourceEvent:r,target:i,transform:l,dispatch:u}){Object.defineProperties(this,{type:{value:n,enumerable:!0,configurable:!0},sourceEvent:{value:r,enumerable:!0,configurable:!0},target:{value:i,enumerable:!0,configurable:!0},transform:{value:l,enumerable:!0,configurable:!0},_:{value:u}})}function mn(n,r,i){this.k=n,this.x=r,this.y=i}mn.prototype={constructor:mn,scale:function(n){return n===1?this:new mn(this.k*n,this.x,this.y)},translate:function(n,r){return n===0&r===0?this:new mn(this.k,this.x+this.k*n,this.y+this.k*r)},apply:function(n){return[n[0]*this.k+this.x,n[1]*this.k+this.y]},applyX:function(n){return n*this.k+this.x},applyY:function(n){return n*this.k+this.y},invert:function(n){return[(n[0]-this.x)/this.k,(n[1]-this.y)/this.k]},invertX:function(n){return(n-this.x)/this.k},invertY:function(n){return(n-this.y)/this.k},rescaleX:function(n){return n.copy().domain(n.range().map(this.invertX,this).map(n.invert,n))},rescaleY:function(n){return n.copy().domain(n.range().map(this.invertY,this).map(n.invert,n))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var hl=new mn(1,0,0);Pp.prototype=mn.prototype;function Pp(n){for(;!n.__zoom;)if(!(n=n.parentNode))return hl;return n.__zoom}function Sa(n){n.stopImmediatePropagation()}function Zo(n){n.preventDefault(),n.stopImmediatePropagation()}function nw(n){return(!n.ctrlKey||n.type==="wheel")&&!n.button}function rw(){var n=this;return n instanceof SVGElement?(n=n.ownerSVGElement||n,n.hasAttribute("viewBox")?(n=n.viewBox.baseVal,[[n.x,n.y],[n.x+n.width,n.y+n.height]]):[[0,0],[n.width.baseVal.value,n.height.baseVal.value]]):[[0,0],[n.clientWidth,n.clientHeight]]}function oh(){return this.__zoom||hl}function ow(n){return-n.deltaY*(n.deltaMode===1?.05:n.deltaMode?1:.002)*(n.ctrlKey?10:1)}function iw(){return navigator.maxTouchPoints||"ontouchstart"in this}function sw(n,r,i){var l=n.invertX(r[0][0])-i[0][0],u=n.invertX(r[1][0])-i[1][0],c=n.invertY(r[0][1])-i[0][1],f=n.invertY(r[1][1])-i[1][1];return n.translate(u>l?(l+u)/2:Math.min(0,l)||Math.max(0,u),f>c?(c+f)/2:Math.min(0,c)||Math.max(0,f))}function Ip(){var n=nw,r=rw,i=sw,l=ow,u=iw,c=[0,1/0],f=[[-1/0,-1/0],[1/0,1/0]],h=250,p=bs,m=al("start","zoom","end"),v,y,g,w=500,S=150,M=0,N=10;function E(k){k.property("__zoom",oh).on("wheel.zoom",X,{passive:!1}).on("mousedown.zoom",b).on("dblclick.zoom",ee).filter(u).on("touchstart.zoom",q).on("touchmove.zoom",J).on("touchend.zoom touchcancel.zoom",Z).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}E.transform=function(k,B,z,H){var j=k.selection?k.selection():k;j.property("__zoom",oh),k!==j?U(k,B,z,H):j.interrupt().each(function(){D(this,arguments).event(H).start().zoom(null,typeof B=="function"?B.apply(this,arguments):B).end()})},E.scaleBy=function(k,B,z,H){E.scaleTo(k,function(){var j=this.__zoom.k,$=typeof B=="function"?B.apply(this,arguments):B;return j*$},z,H)},E.scaleTo=function(k,B,z,H){E.transform(k,function(){var j=r.apply(this,arguments),$=this.__zoom,F=z==null?P(j):typeof z=="function"?z.apply(this,arguments):z,C=$.invert(F),R=typeof B=="function"?B.apply(this,arguments):B;return i(_(L($,R),F,C),j,f)},z,H)},E.translateBy=function(k,B,z,H){E.transform(k,function(){return i(this.__zoom.translate(typeof B=="function"?B.apply(this,arguments):B,typeof z=="function"?z.apply(this,arguments):z),r.apply(this,arguments),f)},null,H)},E.translateTo=function(k,B,z,H,j){E.transform(k,function(){var $=r.apply(this,arguments),F=this.__zoom,C=H==null?P($):typeof H=="function"?H.apply(this,arguments):H;return i(hl.translate(C[0],C[1]).scale(F.k).translate(typeof B=="function"?-B.apply(this,arguments):-B,typeof z=="function"?-z.apply(this,arguments):-z),$,f)},H,j)};function L(k,B){return B=Math.max(c[0],Math.min(c[1],B)),B===k.k?k:new mn(B,k.x,k.y)}function _(k,B,z){var H=B[0]-z[0]*k.k,j=B[1]-z[1]*k.k;return H===k.x&&j===k.y?k:new mn(k.k,H,j)}function P(k){return[(+k[0][0]+ +k[1][0])/2,(+k[0][1]+ +k[1][1])/2]}function U(k,B,z,H){k.on("start.zoom",function(){D(this,arguments).event(H).start()}).on("interrupt.zoom end.zoom",function(){D(this,arguments).event(H).end()}).tween("zoom",function(){var j=this,$=arguments,F=D(j,$).event(H),C=r.apply(j,$),R=z==null?P(C):typeof z=="function"?z.apply(j,$):z,te=Math.max(C[1][0]-C[0][0],C[1][1]-C[0][1]),re=j.__zoom,ue=typeof B=="function"?B.apply(j,$):B,ce=p(re.invert(R).concat(te/re.k),ue.invert(R).concat(te/ue.k));return function(ae){if(ae===1)ae=ue;else{var G=ce(ae),se=te/G[2];ae=new mn(se,R[0]-G[0]*se,R[1]-G[1]*se)}F.zoom(null,ae)}})}function D(k,B,z){return!z&&k.__zooming||new V(k,B)}function V(k,B){this.that=k,this.args=B,this.active=0,this.sourceEvent=null,this.extent=r.apply(k,B),this.taps=0}V.prototype={event:function(k){return k&&(this.sourceEvent=k),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(k,B){return this.mouse&&k!=="mouse"&&(this.mouse[1]=B.invert(this.mouse[0])),this.touch0&&k!=="touch"&&(this.touch0[1]=B.invert(this.touch0[0])),this.touch1&&k!=="touch"&&(this.touch1[1]=B.invert(this.touch1[0])),this.that.__zoom=B,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(k){var B=kt(this.that).datum();m.call(k,this.that,new tw(k,{sourceEvent:this.sourceEvent,target:E,transform:this.that.__zoom,dispatch:m}),B)}};function X(k,...B){if(!n.apply(this,arguments))return;var z=D(this,B).event(k),H=this.__zoom,j=Math.max(c[0],Math.min(c[1],H.k*Math.pow(2,l.apply(this,arguments)))),$=Ht(k);if(z.wheel)(z.mouse[0][0]!==$[0]||z.mouse[0][1]!==$[1])&&(z.mouse[1]=H.invert(z.mouse[0]=$)),clearTimeout(z.wheel);else{if(H.k===j)return;z.mouse=[$,H.invert($)],Ks(this),z.start()}Zo(k),z.wheel=setTimeout(F,S),z.zoom("mouse",i(_(L(H,j),z.mouse[0],z.mouse[1]),z.extent,f));function F(){z.wheel=null,z.end()}}function b(k,...B){if(g||!n.apply(this,arguments))return;var z=k.currentTarget,H=D(this,B,!0).event(k),j=kt(k.view).on("mousemove.zoom",R,!0).on("mouseup.zoom",te,!0),$=Ht(k,z),F=k.clientX,C=k.clientY;dp(k.view),Sa(k),H.mouse=[$,this.__zoom.invert($)],Ks(this),H.start();function R(re){if(Zo(re),!H.moved){var ue=re.clientX-F,ce=re.clientY-C;H.moved=ue*ue+ce*ce>M}H.event(re).zoom("mouse",i(_(H.that.__zoom,H.mouse[0]=Ht(re,z),H.mouse[1]),H.extent,f))}function te(re){j.on("mousemove.zoom mouseup.zoom",null),hp(re.view,H.moved),Zo(re),H.event(re).end()}}function ee(k,...B){if(n.apply(this,arguments)){var z=this.__zoom,H=Ht(k.changedTouches?k.changedTouches[0]:k,this),j=z.invert(H),$=z.k*(k.shiftKey?.5:2),F=i(_(L(z,$),H,j),r.apply(this,B),f);Zo(k),h>0?kt(this).transition().duration(h).call(U,F,H,k):kt(this).call(E.transform,F,H,k)}}function q(k,...B){if(n.apply(this,arguments)){var z=k.touches,H=z.length,j=D(this,B,k.changedTouches.length===H).event(k),$,F,C,R;for(Sa(k),F=0;F`Seems like you have not used ${n==="svelte"?"SvelteFlowProvider":"ReactFlowProvider"} as an ancestor. Help: https://${n}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:n=>`Node type "${n}" 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:n=>`The old edge with id=${n} does not exist.`,error009:n=>`Marker type "${n}" doesn't exist.`,error008:(n,{id:r,sourceHandle:i,targetHandle:l})=>`Couldn't create edge for ${n} handle id: "${n==="source"?i:l}", edge id: ${r}.`,error010:()=>"Handle: No node id found. Make sure to only use a Handle inside a custom Node.",error011:n=>`Edge type "${n}" not found. Using fallback type "default".`,error012:n=>`Node with id "${n}" does not exist, it may have been removed. This can happen when a node is deleted before the "onNodeClick" handler is called.`,error013:(n="react")=>`It seems that you haven't loaded the styles. Please import '@xyflow/${n}/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:n=>`Edge with id "${n}" does not exist, it may have been removed. This can happen when an edge is deleted before the "onEdgeClick" handler is called.`},li=[[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]],zp=["Enter"," ","Escape"],Tp={"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:n,x:r,y:i})=>`Moved selected node ${n}. New position, x: ${r}, y: ${i}`,"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 no;(function(n){n.Strict="strict",n.Loose="loose"})(no||(no={}));var hr;(function(n){n.Free="free",n.Vertical="vertical",n.Horizontal="horizontal"})(hr||(hr={}));var ui;(function(n){n.Partial="partial",n.Full="full"})(ui||(ui={}));const Lp={inProgress:!1,isValid:null,from:null,fromHandle:null,fromPosition:null,fromNode:null,to:null,toHandle:null,toPosition:null,toNode:null,pointer:null};var Un;(function(n){n.Bezier="default",n.Straight="straight",n.Step="step",n.SmoothStep="smoothstep",n.SimpleBezier="simplebezier"})(Un||(Un={}));var ol;(function(n){n.Arrow="arrow",n.ArrowClosed="arrowclosed"})(ol||(ol={}));var xe;(function(n){n.Left="left",n.Top="top",n.Right="right",n.Bottom="bottom"})(xe||(xe={}));const ih={[xe.Left]:xe.Right,[xe.Right]:xe.Left,[xe.Top]:xe.Bottom,[xe.Bottom]:xe.Top};function Rp(n){return n===null?null:n?"valid":"invalid"}const Ap=n=>!!n&&typeof n=="object"&&"id"in n&&"source"in n&&"target"in n,lw=n=>!!n&&typeof n=="object"&&"id"in n&&"position"in n&&!("source"in n)&&!("target"in n),Za=n=>!!n&&typeof n=="object"&&"id"in n&&"internals"in n&&!("source"in n)&&!("target"in n),gi=(n,r=[0,0])=>{const{width:i,height:l}=Xt(n),u=n.origin??r,c=i*u[0],f=l*u[1];return{x:n.position.x-c,y:n.position.y-f}},uw=(n,r={nodeOrigin:[0,0]})=>{if(n.length===0)return{x:0,y:0,width:0,height:0};let i=!1;const l=n.reduce((u,c)=>{const f=typeof c=="string";let h=!r.nodeLookup&&!f?c:void 0;return r.nodeLookup&&(h=f?r.nodeLookup.get(c):Za(c)?c:r.nodeLookup.get(c.id)),h?(i=!0,pl(u,il(h,r.nodeOrigin))):u},{x:1/0,y:1/0,x2:-1/0,y2:-1/0});return i?gl(l):{x:0,y:0,width:0,height:0}},mi=(n,r={})=>{let i={x:1/0,y:1/0,x2:-1/0,y2:-1/0},l=!1;return n.forEach(u=>{(r.filter===void 0||r.filter(u))&&(i=pl(i,il(u)),l=!0)}),l?gl(i):{x:0,y:0,width:0,height:0}},Ja=(n,r,[i,l,u]=[0,0,1],c=!1,f=!1)=>{const h=(r.x-i)/u,p=(r.y-l)/u,m=r.width/u,v=r.height/u,y=[];for(const g of n.values()){const{measured:w,selectable:S=!0,hidden:M=!1}=g;if(f&&!S||M)continue;const N=w.width??g.width??g.initialWidth??0,E=w.height??g.height??g.initialHeight??0,{x:L,y:_}=g.internals.positionAbsolute,P=Op(h,p,m,v,L,_,N,E),U=N*E,D=c&&P>0;(!g.internals.handleBounds||D||P>=U||g.dragging)&&y.push(g)}return y},aw=(n,r)=>{const i=new Set;return n.forEach(l=>{i.add(l.id)}),r.filter(l=>i.has(l.source)||i.has(l.target))};function cw(n,r){const i=new Map,l=r!=null&&r.nodes?new Set(r.nodes.map(u=>u.id)):null;return n.forEach(u=>{let c;if(r!=null&&r.includeHiddenNodes){const{width:f,height:h}=Xt(u);c=f>0&&h>0}else c=!!(u.measured.width&&u.measured.height&&!u.hidden);c&&(!l||l.has(u.id))&&i.set(u.id,u)}),i}async function fw({nodes:n,width:r,height:i,panZoom:l,minZoom:u,maxZoom:c},f){if(n.size===0)return!0;const h=cw(n,f),p=mi(h),m=tc(p,r,i,(f==null?void 0:f.minZoom)??u,(f==null?void 0:f.maxZoom)??c,(f==null?void 0:f.padding)??.1);return await l.setViewport(m,{duration:f==null?void 0:f.duration,ease:f==null?void 0:f.ease,interpolate:f==null?void 0:f.interpolate}),!0}function jp({nodeId:n,nextPosition:r,nodeLookup:i,nodeOrigin:l=[0,0],nodeExtent:u,onError:c}){const f=i.get(n),h=f.parentId?i.get(f.parentId):void 0,{x:p,y:m}=h?h.internals.positionAbsolute:{x:0,y:0},v=f.origin??l;let y=f.extent||u;if(f.extent==="parent"&&!f.expandParent)if(!h)c==null||c("005",Wt.error005());else{const{width:w,height:S}=Xt(h);w&&S&&(y=[[p,m],[p+w,m+S]])}else h&&yr(f.extent)&&(y=[[f.extent[0][0]+p,f.extent[0][1]+m],[f.extent[1][0]+p,f.extent[1][1]+m]]);const g=yr(y)?mr(r,y,f.measured):r;return(f.measured.width===void 0||f.measured.height===void 0)&&(c==null||c("015",Wt.error015())),{position:{x:g.x-p+(f.measured.width??0)*v[0],y:g.y-m+(f.measured.height??0)*v[1]},positionAbsolute:g}}async function dw({nodesToRemove:n=[],edgesToRemove:r=[],nodes:i,edges:l,onBeforeDelete:u}){const c=new Set(n.map(g=>g.id)),f=[];for(const g of i){if(g.deletable===!1)continue;const w=c.has(g.id),S=!w&&g.parentId&&f.find(M=>M.id===g.parentId);(w||S)&&f.push(g)}const h=new Set(r.map(g=>g.id)),p=l.filter(g=>g.deletable!==!1),v=aw(f,p);for(const g of p)h.has(g.id)&&!v.find(S=>S.id===g.id)&&v.push(g);if(!u)return{edges:v,nodes:f};const y=await u({nodes:f,edges:v});return typeof y=="boolean"?y?{edges:v,nodes:f}:{edges:[],nodes:[]}:y}const ro=(n,r=0,i=1)=>Math.min(Math.max(n,r),i),mr=(n={x:0,y:0},r,i)=>({x:ro(n.x,r[0][0],r[1][0]-((i==null?void 0:i.width)??0)),y:ro(n.y,r[0][1],r[1][1]-((i==null?void 0:i.height)??0))});function $p(n,r,i){const{width:l,height:u}=Xt(i),{x:c,y:f}=i.internals.positionAbsolute;return mr(n,[[c,f],[c+l,f+u]],r)}const sh=(n,r,i)=>ni?-ro(Math.abs(n-i),1,r)/r:0,ec=(n,r,i=15,l=40)=>{const u=sh(n.x,l,r.width-l)*i,c=sh(n.y,l,r.height-l)*i;return[u,c]},pl=(n,r)=>({x:Math.min(n.x,r.x),y:Math.min(n.y,r.y),x2:Math.max(n.x2,r.x2),y2:Math.max(n.y2,r.y2)}),Fa=({x:n,y:r,width:i,height:l})=>({x:n,y:r,x2:n+i,y2:r+l}),gl=({x:n,y:r,x2:i,y2:l})=>({x:n,y:r,width:i-n,height:l-r}),ai=(n,r=[0,0])=>{var u,c;const{x:i,y:l}=Za(n)?n.internals.positionAbsolute:gi(n,r);return{x:i,y:l,width:((u=n.measured)==null?void 0:u.width)??n.width??n.initialWidth??0,height:((c=n.measured)==null?void 0:c.height)??n.height??n.initialHeight??0}},il=(n,r=[0,0])=>{var u,c;const{x:i,y:l}=Za(n)?n.internals.positionAbsolute:gi(n,r);return{x:i,y:l,x2:i+(((u=n.measured)==null?void 0:u.width)??n.width??n.initialWidth??0),y2:l+(((c=n.measured)==null?void 0:c.height)??n.height??n.initialHeight??0)}},Dp=(n,r)=>gl(pl(Fa(n),Fa(r))),Op=(n,r,i,l,u,c,f,h)=>{const p=Math.max(0,Math.min(n+i,u+f)-Math.max(n,u)),m=Math.max(0,Math.min(r+l,c+h)-Math.max(r,c));return Math.ceil(p*m)},sl=(n,r)=>Op(n.x,n.y,n.width,n.height,r.x,r.y,r.width,r.height),lh=n=>Bt(n.width)&&Bt(n.height)&&Bt(n.x)&&Bt(n.y),Bt=n=>!isNaN(n)&&isFinite(n),Fp=(n,r)=>(i,l)=>{},yi=(n,r=[1,1])=>({x:r[0]*Math.round(n.x/r[0]),y:r[1]*Math.round(n.y/r[1])}),vi=({x:n,y:r},[i,l,u],c=!1,f=[1,1])=>{const h={x:(n-i)/u,y:(r-l)/u};return c?yi(h,f):h},oo=({x:n,y:r},[i,l,u])=>({x:n*u+i,y:r*u+l});function Kr(n,r){if(typeof n=="number")return Math.floor((r-r/(1+n))*.5);if(typeof n=="string"&&n.endsWith("px")){const i=parseFloat(n);if(!Number.isNaN(i))return Math.floor(i)}if(typeof n=="string"&&n.endsWith("%")){const i=parseFloat(n);if(!Number.isNaN(i))return Math.floor(r*i*.01)}return console.error(`The padding value "${n}" is invalid. Please provide a number or a string with a valid unit (px or %).`),0}function hw(n,r,i){if(typeof n=="string"||typeof n=="number"){const l=Kr(n,i),u=Kr(n,r);return{top:l,right:u,bottom:l,left:u,x:u*2,y:l*2}}if(typeof n=="object"){const l=Kr(n.top??n.y??0,i),u=Kr(n.bottom??n.y??0,i),c=Kr(n.left??n.x??0,r),f=Kr(n.right??n.x??0,r);return{top:l,right:f,bottom:u,left:c,x:c+f,y:l+u}}return{top:0,right:0,bottom:0,left:0,x:0,y:0}}function pw(n,r,i,l,u,c){const{x:f,y:h}=oo(n,[r,i,l]),{x:p,y:m}=oo({x:n.x+n.width,y:n.y+n.height},[r,i,l]),v=u-p,y=c-m;return{left:Math.floor(f),top:Math.floor(h),right:Math.floor(v),bottom:Math.floor(y)}}const tc=(n,r,i,l,u,c)=>{const f=hw(c,r,i),h=(r-f.x)/n.width,p=(i-f.y)/n.height,m=Math.min(h,p),v=ro(m,l,u),y=n.x+n.width/2,g=n.y+n.height/2,w=r/2-y*v,S=i/2-g*v,M=pw(n,w,S,v,r,i),N={left:Math.min(M.left-f.left,0),top:Math.min(M.top-f.top,0),right:Math.min(M.right-f.right,0),bottom:Math.min(M.bottom-f.bottom,0)};return{x:w-N.left+N.right,y:S-N.top+N.bottom,zoom:v}},ci=()=>{var n;return typeof navigator<"u"&&((n=navigator==null?void 0:navigator.userAgent)==null?void 0:n.indexOf("Mac"))>=0};function yr(n){return n!=null&&n!=="parent"}function Xt(n){var r,i;return{width:((r=n.measured)==null?void 0:r.width)??n.width??n.initialWidth??0,height:((i=n.measured)==null?void 0:i.height)??n.height??n.initialHeight??0}}function Hp(n){var r,i;return(((r=n.measured)==null?void 0:r.width)??n.width??n.initialWidth)!==void 0&&(((i=n.measured)==null?void 0:i.height)??n.height??n.initialHeight)!==void 0}function Vp(n,r={width:0,height:0},i,l,u){const c={...n},f=l.get(i);if(f){const h=f.origin||u;c.x+=f.internals.positionAbsolute.x-(r.width??0)*h[0],c.y+=f.internals.positionAbsolute.y-(r.height??0)*h[1]}return c}function uh(n,r){if(n.size!==r.size)return!1;for(const i of n)if(!r.has(i))return!1;return!0}function gw(){let n,r;return{promise:new Promise((l,u)=>{n=l,r=u}),resolve:n,reject:r}}function mw(n){return{...Tp,...n||{}}}function ni(n,{snapGrid:r=[0,0],snapToGrid:i=!1,transform:l,containerBounds:u}){const{x:c,y:f}=Ut(n),h=vi({x:c-((u==null?void 0:u.left)??0),y:f-((u==null?void 0:u.top)??0)},l),{x:p,y:m}=i?yi(h,r):h;return{xSnapped:p,ySnapped:m,...h}}const nc=n=>({width:n.offsetWidth,height:n.offsetHeight}),Bp=n=>{var r;return((r=n==null?void 0:n.getRootNode)==null?void 0:r.call(n))||(window==null?void 0:window.document)},yw=["INPUT","SELECT","TEXTAREA"];function Up(n){var l,u;const r=((u=(l=n.composedPath)==null?void 0:l.call(n))==null?void 0:u[0])||n.target;return(r==null?void 0:r.nodeType)!==1?!1:yw.includes(r.nodeName)||r.hasAttribute("contenteditable")||!!r.closest(".nokey")}const Wp=n=>"clientX"in n,Ut=(n,r)=>{var c,f;const i=Wp(n),l=i?n.clientX:(c=n.touches)==null?void 0:c[0].clientX,u=i?n.clientY:(f=n.touches)==null?void 0:f[0].clientY;return{x:l-((r==null?void 0:r.left)??0),y:u-((r==null?void 0:r.top)??0)}},ah=(n,r,i,l,u)=>{const c=r.querySelectorAll(`.${n}`);return!c||!c.length?null:Array.from(c).map(f=>{const h=f.getBoundingClientRect();return{id:f.getAttribute("data-handleid"),type:n,nodeId:u,position:f.getAttribute("data-handlepos"),x:(h.left-i.left)/l,y:(h.top-i.top)/l,...nc(f)}})};function Yp({sourceX:n,sourceY:r,targetX:i,targetY:l,sourceControlX:u,sourceControlY:c,targetControlX:f,targetControlY:h}){const p=n*.125+u*.375+f*.375+i*.125,m=r*.125+c*.375+h*.375+l*.125,v=Math.abs(p-n),y=Math.abs(m-r);return[p,m,v,y]}function Bs(n,r){return n>=0?.5*n:r*25*Math.sqrt(-n)}function ch({pos:n,x1:r,y1:i,x2:l,y2:u,c}){switch(n){case xe.Left:return[r-Bs(r-l,c),i];case xe.Right:return[r+Bs(l-r,c),i];case xe.Top:return[r,i-Bs(i-u,c)];case xe.Bottom:return[r,i+Bs(u-i,c)]}}function Xp({sourceX:n,sourceY:r,sourcePosition:i=xe.Bottom,targetX:l,targetY:u,targetPosition:c=xe.Top,curvature:f=.25}){const[h,p]=ch({pos:i,x1:n,y1:r,x2:l,y2:u,c:f}),[m,v]=ch({pos:c,x1:l,y1:u,x2:n,y2:r,c:f}),[y,g,w,S]=Yp({sourceX:n,sourceY:r,targetX:l,targetY:u,sourceControlX:h,sourceControlY:p,targetControlX:m,targetControlY:v});return[`M${n},${r} C${h},${p} ${m},${v} ${l},${u}`,y,g,w,S]}function bp({sourceX:n,sourceY:r,targetX:i,targetY:l}){const u=Math.abs(i-n)/2,c=i0}const ww=({source:n,sourceHandle:r,target:i,targetHandle:l})=>`xy-edge__${n}${r||""}-${i}${l||""}`,Sw=(n,r)=>r.some(i=>i.source===n.source&&i.target===n.target&&(i.sourceHandle===n.sourceHandle||!i.sourceHandle&&!n.sourceHandle)&&(i.targetHandle===n.targetHandle||!i.targetHandle&&!n.targetHandle)),_w=(n,r,i={})=>{var c;if(!n.source||!n.target)return(c=i.onError)==null||c.call(i,"006",Wt.error006()),r;const l=i.getEdgeId||ww;let u;return Ap(n)?u={...n}:u={...n,id:l(n)},Sw(u,r)?r:(u.sourceHandle===null&&delete u.sourceHandle,u.targetHandle===null&&delete u.targetHandle,r.concat(u))};function Qp({sourceX:n,sourceY:r,targetX:i,targetY:l}){const[u,c,f,h]=bp({sourceX:n,sourceY:r,targetX:i,targetY:l});return[`M ${n},${r}L ${i},${l}`,u,c,f,h]}const fh={[xe.Left]:{x:-1,y:0},[xe.Right]:{x:1,y:0},[xe.Top]:{x:0,y:-1},[xe.Bottom]:{x:0,y:1}},Ew=({source:n,sourcePosition:r=xe.Bottom,target:i})=>r===xe.Left||r===xe.Right?n.xMath.sqrt(Math.pow(r.x-n.x,2)+Math.pow(r.y-n.y,2));function kw({source:n,sourcePosition:r=xe.Bottom,target:i,targetPosition:l=xe.Top,center:u,offset:c,stepPosition:f}){const h=fh[r],p=fh[l],m={x:n.x+h.x*c,y:n.y+h.y*c},v={x:i.x+p.x*c,y:i.y+p.y*c},y=Ew({source:m,sourcePosition:r,target:v}),g=y.x!==0?"x":"y",w=y[g];let S=[],M,N;const E={x:0,y:0},L={x:0,y:0},[,,_,P]=bp({sourceX:n.x,sourceY:n.y,targetX:i.x,targetY:i.y});if(h[g]*p[g]===-1){g==="x"?(M=u.x??m.x+(v.x-m.x)*f,N=u.y??(m.y+v.y)/2):(M=u.x??(m.x+v.x)/2,N=u.y??m.y+(v.y-m.y)*f);const X=[{x:M,y:m.y},{x:M,y:v.y}],b=[{x:m.x,y:N},{x:v.x,y:N}];h[g]===w?S=g==="x"?X:b:S=g==="x"?b:X}else{const X=[{x:m.x,y:v.y}],b=[{x:v.x,y:m.y}];if(g==="x"?S=h.x===w?b:X:S=h.y===w?X:b,r===l){const k=Math.abs(n[g]-i[g]);if(k<=c){const B=Math.min(c-1,c-k);h[g]===w?E[g]=(m[g]>n[g]?-1:1)*B:L[g]=(v[g]>i[g]?-1:1)*B}}if(r!==l){const k=g==="x"?"y":"x",B=h[g]===p[k],z=m[k]>v[k],H=m[k]=Z?(M=(ee.x+q.x)/2,N=S[0].y):(M=S[0].x,N=(ee.y+q.y)/2)}const U={x:m.x+E.x,y:m.y+E.y},D={x:v.x+L.x,y:v.y+L.y};return[[n,...U.x!==S[0].x||U.y!==S[0].y?[U]:[],...S,...D.x!==S[S.length-1].x||D.y!==S[S.length-1].y?[D]:[],i],M,N,_,P]}function Nw(n,r,i,l){const u=Math.min(dh(n,r)/2,dh(r,i)/2,l),{x:c,y:f}=r;if(n.x===c&&c===i.x||n.y===f&&f===i.y)return`L${c} ${f}`;if(n.y===f){const m=n.xi.id===r):n[0])||null}function Va(n,r){return n?typeof n=="string"?n:`${r?`${r}__`:""}${Object.keys(n).sort().map(l=>`${l}=${n[l]}`).join("&")}`:""}function Mw(n,{id:r,defaultColor:i,defaultMarkerStart:l,defaultMarkerEnd:u}){const c=new Set;return n.reduce((f,h)=>([h.markerStart||l,h.markerEnd||u].forEach(p=>{if(p&&typeof p=="object"){const m=Va(p,r);c.has(m)||(f.push({id:m,color:p.color||i,...p}),c.add(m))}}),f),[]).sort((f,h)=>f.id.localeCompare(h.id))}const Gp=1e3,Pw=10,rc={nodeOrigin:[0,0],nodeExtent:li,elevateNodesOnSelect:!0,zIndexMode:"basic",defaults:{}},Iw={...rc,checkEquality:!0};function oc(n,r){const i={...n};for(const l in r)r[l]!==void 0&&(i[l]=r[l]);return i}function zw(n,r,i){const l=oc(rc,i);for(const u of n.values())if(u.parentId)sc(u,n,r,l);else{const c=gi(u,l.nodeOrigin),f=yr(u.extent)?u.extent:l.nodeExtent,h=mr(c,f,Xt(u));u.internals.positionAbsolute=h}}function Tw(n,r){if(!n.handles)return n.measured?r==null?void 0:r.internals.handleBounds:void 0;const i=[],l=[];for(const u of n.handles){const c={id:u.id,width:u.width??1,height:u.height??1,nodeId:n.id,x:u.x,y:u.y,position:u.position,type:u.type};u.type==="source"?i.push(c):u.type==="target"&&l.push(c)}return{source:i,target:l}}function ic(n){return n==="manual"}function Ba(n,r,i,l={}){var v,y;const u=oc(Iw,l),c={i:0},f=new Map(r),h=u!=null&&u.elevateNodesOnSelect&&!ic(u.zIndexMode)?Gp:0;let p=n.length>0,m=!1;r.clear(),i.clear();for(const g of n){let w=f.get(g.id);if(u.checkEquality&&g===(w==null?void 0:w.internals.userNode))r.set(g.id,w);else{const S=gi(g,u.nodeOrigin),M=yr(g.extent)?g.extent:u.nodeExtent,N=mr(S,M,Xt(g));w={...u.defaults,...g,measured:{width:(v=g.measured)==null?void 0:v.width,height:(y=g.measured)==null?void 0:y.height},internals:{positionAbsolute:N,handleBounds:Tw(g,w),z:Kp(g,h,u.zIndexMode),userNode:g}},r.set(g.id,w)}(w.measured===void 0||w.measured.width===void 0||w.measured.height===void 0)&&!w.hidden&&(p=!1),g.parentId&&sc(w,r,i,l,c),m||(m=g.selected??!1)}return{nodesInitialized:p,hasSelectedNodes:m}}function Lw(n,r){if(!n.parentId)return;const i=r.get(n.parentId);i?i.set(n.id,n):r.set(n.parentId,new Map([[n.id,n]]))}function sc(n,r,i,l,u){const{elevateNodesOnSelect:c,nodeOrigin:f,nodeExtent:h,zIndexMode:p}=oc(rc,l),m=n.parentId,v=r.get(m);if(!v){console.warn(`Parent node ${m} not found. Please make sure that parent nodes are in front of their child nodes in the nodes array.`);return}Lw(n,i),u&&!v.parentId&&v.internals.rootParentIndex===void 0&&p==="auto"&&(v.internals.rootParentIndex=++u.i,v.internals.z=v.internals.z+u.i*Pw),u&&v.internals.rootParentIndex!==void 0&&(u.i=v.internals.rootParentIndex);const y=c&&!ic(p)?Gp:0,{x:g,y:w,z:S}=Rw(n,v,f,h,y,p),{positionAbsolute:M}=n.internals,N=g!==M.x||w!==M.y;(N||S!==n.internals.z)&&r.set(n.id,{...n,internals:{...n.internals,positionAbsolute:N?{x:g,y:w}:M,z:S}})}function Kp(n,r,i){const l=Bt(n.zIndex)?n.zIndex:0;return ic(i)?l:l+(n.selected?r:0)}function Rw(n,r,i,l,u,c){const{x:f,y:h}=r.internals.positionAbsolute,p=Xt(n),m=gi(n,i),v=yr(n.extent)?mr(m,n.extent,p):m;let y=mr({x:f+v.x,y:h+v.y},l,p);n.extent==="parent"&&(y=$p(y,p,r));const g=Kp(n,u,c),w=r.internals.z??0;return{x:y.x,y:y.y,z:w>=g?w+1:g}}function lc(n,r,i,l=[0,0]){var f;const u=[],c=new Map;for(const h of n){const p=r.get(h.parentId);if(!p)continue;const m=((f=c.get(h.parentId))==null?void 0:f.expandedRect)??ai(p),v=Dp(m,h.rect);c.set(h.parentId,{expandedRect:v,parent:p})}return c.size>0&&c.forEach(({expandedRect:h,parent:p},m)=>{var _;const v=p.internals.positionAbsolute,y=Xt(p),g=p.origin??l,w=h.x0||S>0||E||L)&&(u.push({id:m,type:"position",position:{x:p.position.x-w+E,y:p.position.y-S+L}}),(_=i.get(m))==null||_.forEach(P=>{n.some(U=>U.id===P.id)||u.push({id:P.id,type:"position",position:{x:P.position.x+w,y:P.position.y+S}})})),(y.width0){const w=lc(g,r,i,u);m.push(...w)}return{changes:m,updatedInternals:p}}async function jw({delta:n,panZoom:r,transform:i,translateExtent:l,width:u,height:c}){if(!r||!n.x&&!n.y)return!1;const f=await r.setViewportConstrained({x:i[0]+n.x,y:i[1]+n.y,zoom:i[2]},[[0,0],[u,c]],l);return!!f&&(f.x!==i[0]||f.y!==i[1]||f.k!==i[2])}function mh(n,r,i,l,u,c){let f=u;const h=l.get(f)||new Map;l.set(f,h.set(i,r)),f=`${u}-${n}`;const p=l.get(f)||new Map;if(l.set(f,p.set(i,r)),c){f=`${u}-${n}-${c}`;const m=l.get(f)||new Map;l.set(f,m.set(i,r))}}function qp(n,r,i){n.clear(),r.clear();for(const l of i){const{source:u,target:c,sourceHandle:f=null,targetHandle:h=null}=l,p={edgeId:l.id,source:u,target:c,sourceHandle:f,targetHandle:h},m=`${u}-${f}--${c}-${h}`,v=`${c}-${h}--${u}-${f}`;mh("source",p,v,n,u,f),mh("target",p,m,n,c,h),r.set(l.id,l)}}function Zp(n,r){if(!n.parentId)return!1;const i=r.get(n.parentId);return i?i.selected?!0:Zp(i,r):!1}function yh(n,r,i){var u;let l=n;do{if((u=l==null?void 0:l.matches)!=null&&u.call(l,r))return!0;if(l===i)return!1;l=l==null?void 0:l.parentElement}while(l);return!1}function $w(n,r,i,l){const u=new Map;for(const[c,f]of n)if((f.selected||f.id===l)&&(!f.parentId||!Zp(f,n))&&(f.draggable||r&&typeof f.draggable>"u")){const h=n.get(c);h&&u.set(c,{id:c,position:h.position||{x:0,y:0},distance:{x:i.x-h.internals.positionAbsolute.x,y:i.y-h.internals.positionAbsolute.y},extent:h.extent,parentId:h.parentId,origin:h.origin,expandParent:h.expandParent,internals:{positionAbsolute:h.internals.positionAbsolute||{x:0,y:0}},measured:{width:h.measured.width??0,height:h.measured.height??0}})}return u}function _a({nodeId:n,dragItems:r,nodeLookup:i,dragging:l=!0}){var f,h,p;const u=[];for(const[m,v]of r){const y=(f=i.get(m))==null?void 0:f.internals.userNode;y&&u.push({...y,position:v.position,dragging:l})}if(!n)return[u[0],u];const c=(h=i.get(n))==null?void 0:h.internals.userNode;return[c?{...c,position:((p=r.get(n))==null?void 0:p.position)||c.position,dragging:l}:u[0],u]}function Dw({dragItems:n,snapGrid:r,x:i,y:l}){const u=n.values().next().value;if(!u)return null;const c={x:i-u.distance.x,y:l-u.distance.y},f=yi(c,r);return{x:f.x-c.x,y:f.y-c.y}}function Ow({onNodeMouseDown:n,getStoreItems:r,onDragStart:i,onDrag:l,onDragStop:u}){let c={x:null,y:null},f=0,h=new Map,p=!1,m={x:0,y:0},v=null,y=!1,g=null,w=!1,S=!1,M=null;function N({noDragClassName:L,handleSelector:_,domNode:P,isSelectable:U,nodeId:D,nodeClickDistance:V=0}){g=kt(P);function X({x:J,y:Z}){const{nodeLookup:k,nodeExtent:B,snapGrid:z,snapToGrid:H,nodeOrigin:j,onNodeDrag:$,onSelectionDrag:F,onError:C,updateNodePositions:R}=r();c={x:J,y:Z};let te=!1;const re=h.size>1,ue=re&&B?Fa(mi(h)):null,ce=re&&H?Dw({dragItems:h,snapGrid:z,x:J,y:Z}):null;for(const[ae,G]of h){if(!k.has(ae))continue;let se={x:J-G.distance.x,y:Z-G.distance.y};H&&(se=ce?{x:Math.round(se.x+ce.x),y:Math.round(se.y+ce.y)}:yi(se,z));let pe=null;if(re&&B&&!G.extent&&ue){const{positionAbsolute:me}=G.internals,ke=me.x-ue.x+B[0][0],Ce=me.x+G.measured.width-ue.x2+B[1][0],Me=me.y-ue.y+B[0][1],Le=me.y+G.measured.height-ue.y2+B[1][1];pe=[[ke,Me],[Ce,Le]]}const{position:we,positionAbsolute:ve}=jp({nodeId:ae,nextPosition:se,nodeLookup:k,nodeExtent:pe||B,nodeOrigin:j,onError:C});te=te||G.position.x!==we.x||G.position.y!==we.y,G.position=we,G.internals.positionAbsolute=ve}if(S=S||te,!!te&&(R(h,!0),M&&(l||$||!D&&F))){const[ae,G]=_a({nodeId:D,dragItems:h,nodeLookup:k});l==null||l(M,h,ae,G),$==null||$(M,ae,G),D||F==null||F(M,G)}}async function b(){if(!v)return;const{transform:J,panBy:Z,autoPanSpeed:k,autoPanOnNodeDrag:B}=r();if(!B){p=!1,cancelAnimationFrame(f);return}const[z,H]=ec(m,v,k);(z!==0||H!==0)&&(c.x=(c.x??0)-z/J[2],c.y=(c.y??0)-H/J[2],await Z({x:z,y:H})&&X(c)),f=requestAnimationFrame(b)}function ee(J){var re;const{nodeLookup:Z,multiSelectionActive:k,nodesDraggable:B,transform:z,snapGrid:H,snapToGrid:j,selectNodesOnDrag:$,onNodeDragStart:F,onSelectionDragStart:C,unselectNodesAndEdges:R}=r();y=!0,(!$||!U)&&!k&&D&&((re=Z.get(D))!=null&&re.selected||R()),U&&$&&D&&(n==null||n(D));const te=ni(J.sourceEvent,{transform:z,snapGrid:H,snapToGrid:j,containerBounds:v});if(c=te,h=$w(Z,B,te,D),h.size>0&&(i||F||!D&&C)){const[ue,ce]=_a({nodeId:D,dragItems:h,nodeLookup:Z});i==null||i(J.sourceEvent,h,ue,ce),F==null||F(J.sourceEvent,ue,ce),D||C==null||C(J.sourceEvent,ce)}}const q=pp().clickDistance(V).on("start",J=>{const{domNode:Z,nodeDragThreshold:k,transform:B,snapGrid:z,snapToGrid:H}=r();v=(Z==null?void 0:Z.getBoundingClientRect())||null,w=!1,S=!1,M=J.sourceEvent,k===0&&ee(J),c=ni(J.sourceEvent,{transform:B,snapGrid:z,snapToGrid:H,containerBounds:v}),m=Ut(J.sourceEvent,v)}).on("drag",J=>{const{autoPanOnNodeDrag:Z,transform:k,snapGrid:B,snapToGrid:z,nodeDragThreshold:H,nodeLookup:j}=r(),$=ni(J.sourceEvent,{transform:k,snapGrid:B,snapToGrid:z,containerBounds:v});if(M=J.sourceEvent,(J.sourceEvent.type==="touchmove"&&J.sourceEvent.touches.length>1||D&&!j.has(D))&&(w=!0),!w){if(!p&&Z&&y&&(p=!0,b()),!y){const F=Ut(J.sourceEvent,v),C=F.x-m.x,R=F.y-m.y;Math.sqrt(C*C+R*R)>H&&ee(J)}(c.x!==$.xSnapped||c.y!==$.ySnapped)&&h&&y&&(m=Ut(J.sourceEvent,v),X($))}}).on("end",J=>{if(!y||w){w&&h.size>0&&r().updateNodePositions(h,!1);return}if(p=!1,y=!1,cancelAnimationFrame(f),h.size>0){const{nodeLookup:Z,updateNodePositions:k,onNodeDragStop:B,onSelectionDragStop:z}=r();if(S&&(k(h,!1),S=!1),u||B||!D&&z){const[H,j]=_a({nodeId:D,dragItems:h,nodeLookup:Z,dragging:!1});u==null||u(J.sourceEvent,h,H,j),B==null||B(J.sourceEvent,H,j),D||z==null||z(J.sourceEvent,j)}}}).filter(J=>{const Z=J.target;return!J.button&&(!L||!yh(Z,`.${L}`,P))&&(!_||yh(Z,_,P))});g.call(q)}function E(){g==null||g.on(".drag",null)}return{update:N,destroy:E}}function Fw(n,r,i){const l=[],u={x:n.x-i,y:n.y-i,width:i*2,height:i*2};for(const c of r.values())sl(u,ai(c))>0&&l.push(c);return l}const Hw=250;function Vw(n,r,i,l){var h,p;let u=[],c=1/0;const f=Fw(n,i,r+Hw);for(const m of f){const v=[...((h=m.internals.handleBounds)==null?void 0:h.source)??[],...((p=m.internals.handleBounds)==null?void 0:p.target)??[]];for(const y of v){if(l.nodeId===y.nodeId&&l.type===y.type&&l.id===y.id)continue;const{x:g,y:w}=vr(m,y,y.position,!0),S=Math.sqrt(Math.pow(g-n.x,2)+Math.pow(w-n.y,2));S>r||(S1){const m=l.type==="source"?"target":"source";return u.find(v=>v.type===m)??u[0]}return u[0]}function Jp(n,r,i,l,u,c=!1){var m,v,y;const f=l.get(n);if(!f)return null;const h=u==="strict"?(m=f.internals.handleBounds)==null?void 0:m[r]:[...((v=f.internals.handleBounds)==null?void 0:v.source)??[],...((y=f.internals.handleBounds)==null?void 0:y.target)??[]],p=(i?h==null?void 0:h.find(g=>g.id===i):h==null?void 0:h[0])??null;return p&&c?{...p,...vr(f,p,p.position,!0)}:p}function eg(n,r){return n||(r!=null&&r.classList.contains("target")?"target":r!=null&&r.classList.contains("source")?"source":null)}function Bw(n,r){let i=null;return r?i=!0:n&&!r&&(i=!1),i}const tg=()=>!0;function Uw(n,{connectionMode:r,connectionRadius:i,handleId:l,nodeId:u,edgeUpdaterType:c,isTarget:f,domNode:h,nodeLookup:p,lib:m,autoPanOnConnect:v,flowId:y,panBy:g,cancelConnection:w,onConnectStart:S,onConnect:M,onConnectEnd:N,isValidConnection:E=tg,onReconnectEnd:L,updateConnection:_,getTransform:P,getFromHandle:U,autoPanSpeed:D,dragThreshold:V=1,handleDomNode:X}){const b=Bp(n.target);let ee=0,q;const{x:J,y:Z}=Ut(n),k=eg(c,X),B=h==null?void 0:h.getBoundingClientRect();let z=!1;if(!B||!k)return;const H=Jp(u,k,l,p,r);if(!H)return;let j=Ut(n,B),$=!1,F=null,C=!1,R=null;function te(){if(!v||!B)return;const[we,ve]=ec(j,B,D);g({x:we,y:ve}),ee=requestAnimationFrame(te)}const re={...H,nodeId:u,type:k,position:H.position},ue=p.get(u);let ae={inProgress:!0,isValid:null,from:vr(ue,re,xe.Left,!0),fromHandle:re,fromPosition:re.position,fromNode:ue,to:j,toHandle:null,toPosition:ih[re.position],toNode:null,pointer:j};function G(){z=!0,_(ae),S==null||S(n,{nodeId:u,handleId:l,handleType:k})}V===0&&G();function se(we){if(!z){const{x:Le,y:it}=Ut(we),ut=Le-J,Je=it-Z;if(!(ut*ut+Je*Je>V*V))return;G()}if(!U()||!re){pe(we);return}const ve=P();j=Ut(we,B),q=Vw(vi(j,ve,!1,[1,1]),i,p,re),$||(te(),$=!0);const me=ng(we,{handle:q,connectionMode:r,fromNodeId:u,fromHandleId:l,fromType:f?"target":"source",isValidConnection:E,doc:b,lib:m,flowId:y,nodeLookup:p});R=me.handleDomNode,F=me.connection,C=Bw(!!q,me.isValid);const ke=p.get(u),Ce=ke?vr(ke,re,xe.Left,!0):ae.from,Me={...ae,from:Ce,isValid:C,to:me.toHandle&&C?oo({x:me.toHandle.x,y:me.toHandle.y},ve):j,toHandle:me.toHandle,toPosition:C&&me.toHandle?me.toHandle.position:ih[re.position],toNode:me.toHandle?p.get(me.toHandle.nodeId):null,pointer:j};_(Me),ae=Me}function pe(we){if(!("touches"in we&&we.touches.length>0)){if(z){(q||R)&&F&&C&&(M==null||M(F));const{inProgress:ve,...me}=ae,ke={...me,toPosition:ae.toHandle?ae.toPosition:null};N==null||N(we,ke),c&&(L==null||L(we,ke))}w(),cancelAnimationFrame(ee),$=!1,C=!1,F=null,R=null,b.removeEventListener("mousemove",se),b.removeEventListener("mouseup",pe),b.removeEventListener("touchmove",se),b.removeEventListener("touchend",pe)}}b.addEventListener("mousemove",se),b.addEventListener("mouseup",pe),b.addEventListener("touchmove",se),b.addEventListener("touchend",pe)}function ng(n,{handle:r,connectionMode:i,fromNodeId:l,fromHandleId:u,fromType:c,doc:f,lib:h,flowId:p,isValidConnection:m=tg,nodeLookup:v}){const y=c==="target",g=r?f.querySelector(`.${h}-flow__handle[data-id="${p}-${r==null?void 0:r.nodeId}-${r==null?void 0:r.id}-${r==null?void 0:r.type}"]`):null,{x:w,y:S}=Ut(n),M=f.elementFromPoint(w,S),N=M!=null&&M.classList.contains(`${h}-flow__handle`)?M:g,E={handleDomNode:N,isValid:!1,connection:null,toHandle:null};if(N){const L=eg(void 0,N),_=N.getAttribute("data-nodeid"),P=N.getAttribute("data-handleid"),U=N.classList.contains("connectable"),D=N.classList.contains("connectableend");if(!_||!L)return E;const V={source:y?_:l,sourceHandle:y?P:u,target:y?l:_,targetHandle:y?u:P};E.connection=V;const b=U&&D&&(i===no.Strict?y&&L==="source"||!y&&L==="target":_!==l||P!==u);E.isValid=b&&m(V),E.toHandle=Jp(_,L,P,v,i,!0)}return E}const Ua={onPointerDown:Uw,isValid:ng};function Ww({domNode:n,panZoom:r,getTransform:i,getViewScale:l}){const u=kt(n);function c({translateExtent:h,width:p,height:m,zoomStep:v=1,pannable:y=!0,zoomable:g=!0,inversePan:w=!1}){const S=_=>{if(_.sourceEvent.type!=="wheel"||!r)return;const P=i(),U=_.sourceEvent.ctrlKey&&ci()?10:1,D=-_.sourceEvent.deltaY*(_.sourceEvent.deltaMode===1?.05:_.sourceEvent.deltaMode?1:.002)*v,V=P[2]*Math.pow(2,D*U);r.scaleTo(V)};let M=[0,0];const N=_=>{(_.sourceEvent.type==="mousedown"||_.sourceEvent.type==="touchstart")&&(M=[_.sourceEvent.clientX??_.sourceEvent.touches[0].clientX,_.sourceEvent.clientY??_.sourceEvent.touches[0].clientY])},E=_=>{const P=i();if(_.sourceEvent.type!=="mousemove"&&_.sourceEvent.type!=="touchmove"||!r)return;const U=[_.sourceEvent.clientX??_.sourceEvent.touches[0].clientX,_.sourceEvent.clientY??_.sourceEvent.touches[0].clientY],D=[U[0]-M[0],U[1]-M[1]];M=U;const V=l()*Math.max(P[2],Math.log(P[2]))*(w?-1:1),X={x:P[0]-D[0]*V,y:P[1]-D[1]*V},b=[[0,0],[p,m]];r.setViewportConstrained({x:X.x,y:X.y,zoom:P[2]},b,h)},L=Ip().on("start",N).on("zoom",y?E:null).on("zoom.wheel",g?S:null);u.call(L,{})}function f(){u.on("zoom",null)}return{update:c,destroy:f,pointer:Ht}}const ml=n=>({x:n.x,y:n.y,zoom:n.k}),Ea=({x:n,y:r,zoom:i})=>hl.translate(n,r).scale(i),Bn=(n,r)=>n.target.closest(`.${r}`),rg=(n,r)=>r===2&&Array.isArray(n)&&n.includes(2),Yw=n=>((n*=2)<=1?n*n*n:(n-=2)*n*n+2)/2,ka=(n,r=0,i=Yw,l=()=>{})=>{const u=typeof r=="number"&&r>0;return u||l(),u?n.transition().duration(r).ease(i).on("end",l):n},og=n=>{const r=n.ctrlKey&&ci()?10:1;return-n.deltaY*(n.deltaMode===1?.05:n.deltaMode?1:.002)*r};function Xw({zoomPanValues:n,noWheelClassName:r,d3Selection:i,d3Zoom:l,panOnScrollMode:u,panOnScrollSpeed:c,zoomOnPinch:f,onPanZoomStart:h,onPanZoom:p,onPanZoomEnd:m}){return v=>{if(Bn(v,r))return v.ctrlKey&&v.preventDefault(),!1;v.preventDefault(),v.stopImmediatePropagation();const y=i.property("__zoom").k||1;if(v.ctrlKey&&f){const N=Ht(v),E=og(v),L=y*Math.pow(2,E);l.scaleTo(i,L,N,v);return}const g=v.deltaMode===1?20:1;let w=u===hr.Vertical?0:v.deltaX*g,S=u===hr.Horizontal?0:v.deltaY*g;!ci()&&v.shiftKey&&u!==hr.Vertical&&(w=v.deltaY*g,S=0),l.translateBy(i,-(w/y)*c,-(S/y)*c,{internal:!0});const M=ml(i.property("__zoom"));clearTimeout(n.panScrollTimeout),n.isPanScrolling?p==null||p(v,M):(n.isPanScrolling=!0,h==null||h(v,M)),n.panScrollTimeout=setTimeout(()=>{m==null||m(v,M),n.isPanScrolling=!1},150)}}function bw({noWheelClassName:n,preventScrolling:r,d3ZoomHandler:i}){return function(l,u){const c=l.type==="wheel",f=!r&&c&&!l.ctrlKey,h=Bn(l,n);if(l.ctrlKey&&c&&h&&l.preventDefault(),f||h)return null;l.preventDefault(),i.call(this,l,u)}}function Qw({zoomPanValues:n,onDraggingChange:r,onPanZoomStart:i}){return l=>{var c,f,h;if((c=l.sourceEvent)!=null&&c.internal)return;const u=ml(l.transform);n.mouseButton=((f=l.sourceEvent)==null?void 0:f.button)||0,n.isZoomingOrPanning=!0,n.prevViewport=u,((h=l.sourceEvent)==null?void 0:h.type)==="mousedown"&&r(!0),i&&(i==null||i(l.sourceEvent,u))}}function Gw({zoomPanValues:n,panOnDrag:r,onPaneContextMenu:i,onTransformChange:l,onPanZoom:u}){return c=>{var f,h;n.usedRightMouseButton=!!(i&&rg(r,n.mouseButton??0)),(f=c.sourceEvent)!=null&&f.sync||l([c.transform.x,c.transform.y,c.transform.k]),u&&!((h=c.sourceEvent)!=null&&h.internal)&&(u==null||u(c.sourceEvent,ml(c.transform)))}}function Kw({zoomPanValues:n,panOnDrag:r,panOnScroll:i,onDraggingChange:l,onPanZoomEnd:u,onPaneContextMenu:c}){return f=>{var h;if(!((h=f.sourceEvent)!=null&&h.internal)&&(n.isZoomingOrPanning=!1,c&&rg(r,n.mouseButton??0)&&!n.usedRightMouseButton&&f.sourceEvent&&c(f.sourceEvent),n.usedRightMouseButton=!1,l(!1),u)){const p=ml(f.transform);n.prevViewport=p,clearTimeout(n.timerId),n.timerId=setTimeout(()=>{u==null||u(f.sourceEvent,p)},i?150:0)}}}function qw({panActivationKeyPressed:n,zoomActivationKeyPressed:r,zoomOnScroll:i,zoomOnPinch:l,panOnDrag:u,panOnScroll:c,zoomOnDoubleClick:f,userSelectionActive:h,noWheelClassName:p,noPanClassName:m,lib:v,connectionInProgress:y}){return g=>{var E;const w=r||i,S=l&&g.ctrlKey,M=g.type==="wheel";if(g.button===1&&g.type==="mousedown"&&(Bn(g,`${v}-flow__node`)||Bn(g,`${v}-flow__edge`)||Bn(g,`${v}-flow__selection`)||Bn(g,`${v}-flow__nodesselection`)))return!0;if(!u&&!w&&!c&&!f&&!l||h||y&&!M||Bn(g,p)&&M||Bn(g,m)&&(!M||c&&M&&!r)||!l&&g.ctrlKey&&M)return!1;if(!l&&g.type==="touchstart"&&((E=g.touches)==null?void 0:E.length)>1)return g.preventDefault(),!1;if(!w&&!c&&!S&&M||!u&&(g.type==="mousedown"||g.type==="touchstart")||Array.isArray(u)&&!u.includes(g.button)&&g.type==="mousedown")return!1;const N=Array.isArray(u)&&u.includes(g.button)||!g.button||g.button<=1;return(!g.ctrlKey||M||n)&&N}}function Zw({domNode:n,minZoom:r,maxZoom:i,translateExtent:l,viewport:u,onPanZoom:c,onPanZoomStart:f,onPanZoomEnd:h,onDraggingChange:p}){const m={isZoomingOrPanning:!1,usedRightMouseButton:!1,prevViewport:{},mouseButton:0,timerId:void 0,panScrollTimeout:void 0,isPanScrolling:!1},v=n.getBoundingClientRect();let y=[[0,0],[v.width,v.height]];const g=typeof ResizeObserver<"u"?new ResizeObserver(Z=>{const k=Z[0];k&&(y=[[0,0],[k.contentRect.width,k.contentRect.height]])}):null;g==null||g.observe(n);const w=Ip().extent(()=>y).scaleExtent([r,i]).translateExtent(l),S=kt(n).call(w);P({x:u.x,y:u.y,zoom:ro(u.zoom,r,i)},[[0,0],[v.width,v.height]],l);const M=S.on("wheel.zoom"),N=S.on("dblclick.zoom");w.wheelDelta(og);async function E(Z,k){return S?new Promise(B=>{w==null||w.interpolate((k==null?void 0:k.interpolate)==="linear"?ti:bs).transform(ka(S,k==null?void 0:k.duration,k==null?void 0:k.ease,()=>B(!0)),Z)}):!1}function L({noWheelClassName:Z,noPanClassName:k,onPaneContextMenu:B,userSelectionActive:z,panOnScroll:H,panOnDrag:j,panOnScrollMode:$,panOnScrollSpeed:F,preventScrolling:C,zoomOnPinch:R,zoomOnScroll:te,zoomOnDoubleClick:re,panActivationKeyPressed:ue=!1,zoomActivationKeyPressed:ce,lib:ae,onTransformChange:G,connectionInProgress:se,paneClickDistance:pe,selectionOnDrag:we}){z&&!m.isZoomingOrPanning&&_();const ve=H&&!ce&&!z;w.clickDistance(we?1/0:!Bt(pe)||pe<0?0:pe);const me=ve?Xw({zoomPanValues:m,noWheelClassName:Z,d3Selection:S,d3Zoom:w,panOnScrollMode:$,panOnScrollSpeed:F,zoomOnPinch:R,onPanZoomStart:f,onPanZoom:c,onPanZoomEnd:h}):bw({noWheelClassName:Z,preventScrolling:C,d3ZoomHandler:M});S.on("wheel.zoom",me,{passive:!1});const ke=Qw({zoomPanValues:m,onDraggingChange:p,onPanZoomStart:f});w.on("start",ke);const Ce=Gw({zoomPanValues:m,panOnDrag:j,onPaneContextMenu:!!B,onPanZoom:c,onTransformChange:G});w.on("zoom",Ce);const Me=Kw({zoomPanValues:m,panOnDrag:j,panOnScroll:H,onPaneContextMenu:B,onPanZoomEnd:h,onDraggingChange:p});w.on("end",Me);const Le=qw({panActivationKeyPressed:ue,zoomActivationKeyPressed:ce,panOnDrag:j,zoomOnScroll:te,panOnScroll:H,zoomOnDoubleClick:re,zoomOnPinch:R,userSelectionActive:z,noPanClassName:k,noWheelClassName:Z,lib:ae,connectionInProgress:se});w.filter(Le),re?S.on("dblclick.zoom",N):S.on("dblclick.zoom",null)}function _(){w.on("zoom",null)}async function P(Z,k,B){const z=Ea(Z),H=w==null?void 0:w.constrain()(z,k,B);return H&&await E(H),H}async function U(Z,k){const B=Ea(Z);return await E(B,k),B}function D(Z){if(S){const k=Ea(Z),B=S.property("__zoom");(B.k!==Z.zoom||B.x!==Z.x||B.y!==Z.y)&&(w==null||w.transform(S,k,null,{sync:!0}))}}function V(){const Z=S?Pp(S.node()):{x:0,y:0,k:1};return{x:Z.x,y:Z.y,zoom:Z.k}}async function X(Z,k){return S?new Promise(B=>{w==null||w.interpolate((k==null?void 0:k.interpolate)==="linear"?ti:bs).scaleTo(ka(S,k==null?void 0:k.duration,k==null?void 0:k.ease,()=>B(!0)),Z)}):!1}async function b(Z,k){return S?new Promise(B=>{w==null||w.interpolate((k==null?void 0:k.interpolate)==="linear"?ti:bs).scaleBy(ka(S,k==null?void 0:k.duration,k==null?void 0:k.ease,()=>B(!0)),Z)}):!1}function ee(Z){w==null||w.scaleExtent(Z)}function q(Z){w==null||w.translateExtent(Z)}function J(Z){const k=!Bt(Z)||Z<0?0:Z;w==null||w.clickDistance(k)}return{update:L,destroy:_,setViewport:U,setViewportConstrained:P,getViewport:V,scaleTo:X,scaleBy:b,setScaleExtent:ee,setTranslateExtent:q,syncViewport:D,setClickDistance:J}}var io;(function(n){n.Line="line",n.Handle="handle"})(io||(io={}));function Jw({width:n,prevWidth:r,height:i,prevHeight:l,affectsX:u,affectsY:c}){const f=n-r,h=i-l,p=[f>0?1:f<0?-1:0,h>0?1:h<0?-1:0];return f&&u&&(p[0]=p[0]*-1),h&&c&&(p[1]=p[1]*-1),p}function vh(n){const r=n.includes("right")||n.includes("left"),i=n.includes("bottom")||n.includes("top"),l=n.includes("left"),u=n.includes("top");return{isHorizontal:r,isVertical:i,affectsX:l,affectsY:u}}function Hn(n,r){return Math.max(0,r-n)}function Vn(n,r){return Math.max(0,n-r)}function Us(n,r,i){return Math.max(0,r-n,n-i)}function xh(n,r){return n?!r:r}function e1(n,r,i,l,u,c,f,h){let{affectsX:p,affectsY:m}=r;const{isHorizontal:v,isVertical:y}=r,g=v&&y,{xSnapped:w,ySnapped:S}=i,{minWidth:M,maxWidth:N,minHeight:E,maxHeight:L}=l,{x:_,y:P,width:U,height:D,aspectRatio:V}=n;let X=Math.floor(v?w-n.pointerX:0),b=Math.floor(y?S-n.pointerY:0);const ee=U+(p?-X:X),q=D+(m?-b:b),J=-c[0]*U,Z=-c[1]*D;let k=Us(ee,M,N),B=Us(q,E,L);if(f){let j=0,$=0;p&&X<0?j=Hn(_+X+J,f[0][0]):!p&&X>0&&(j=Vn(_+ee+J,f[1][0])),m&&b<0?$=Hn(P+b+Z,f[0][1]):!m&&b>0&&($=Vn(P+q+Z,f[1][1])),k=Math.max(k,j),B=Math.max(B,$)}if(h){let j=0,$=0;p&&X>0?j=Vn(_+X,h[0][0]):!p&&X<0&&(j=Hn(_+ee,h[1][0])),m&&b>0?$=Vn(P+b,h[0][1]):!m&&b<0&&($=Hn(P+q,h[1][1])),k=Math.max(k,j),B=Math.max(B,$)}if(u){if(v){const j=Us(ee/V,E,L)*V;if(k=Math.max(k,j),f){let $=0;!p&&!m||p&&!m&&g?$=Vn(P+Z+ee/V,f[1][1])*V:$=Hn(P+Z+(p?X:-X)/V,f[0][1])*V,k=Math.max(k,$)}if(h){let $=0;!p&&!m||p&&!m&&g?$=Hn(P+ee/V,h[1][1])*V:$=Vn(P+(p?X:-X)/V,h[0][1])*V,k=Math.max(k,$)}}if(y){const j=Us(q*V,M,N)/V;if(B=Math.max(B,j),f){let $=0;!p&&!m||m&&!p&&g?$=Vn(_+q*V+J,f[1][0])/V:$=Hn(_+(m?b:-b)*V+J,f[0][0])/V,B=Math.max(B,$)}if(h){let $=0;!p&&!m||m&&!p&&g?$=Hn(_+q*V,h[1][0])/V:$=Vn(_+(m?b:-b)*V,h[0][0])/V,B=Math.max(B,$)}}}b=b+(b<0?B:-B),X=X+(X<0?k:-k),u&&(g?ee>q*V?b=(xh(p,m)?-X:X)/V:X=(xh(p,m)?-b:b)*V:v?(b=X/V,m=p):(X=b*V,p=m));const z=p?_+X:_,H=m?P+b:P;return{width:U+(p?-X:X),height:D+(m?-b:b),x:c[0]*X*(p?-1:1)+z,y:c[1]*b*(m?-1:1)+H}}const ig={width:0,height:0,x:0,y:0},t1={...ig,pointerX:0,pointerY:0,aspectRatio:1};function n1(n,r,i){const l=r.position.x+n.position.x,u=r.position.y+n.position.y,c=n.measured.width??0,f=n.measured.height??0,h=i[0]*c,p=i[1]*f;return[[l-h,u-p],[l+c-h,u+f-p]]}function r1({domNode:n,nodeId:r,getStoreItems:i,onChange:l,onEnd:u}){const c=kt(n);let f={controlDirection:vh("bottom-right"),boundaries:{minWidth:0,minHeight:0,maxWidth:Number.MAX_VALUE,maxHeight:Number.MAX_VALUE},resizeDirection:void 0,keepAspectRatio:!1};function h({controlPosition:m,boundaries:v,keepAspectRatio:y,resizeDirection:g,onResizeStart:w,onResize:S,onResizeEnd:M,shouldResize:N}){let E={...ig},L={...t1};f={boundaries:v,resizeDirection:g,keepAspectRatio:y,controlDirection:vh(m)};let _,P=null,U=[],D,V,X,b=!1;const ee=pp().on("start",q=>{const{nodeLookup:J,transform:Z,snapGrid:k,snapToGrid:B,nodeOrigin:z,paneDomNode:H}=i();if(_=J.get(r),!_)return;P=(H==null?void 0:H.getBoundingClientRect())??null;const{xSnapped:j,ySnapped:$}=ni(q.sourceEvent,{transform:Z,snapGrid:k,snapToGrid:B,containerBounds:P});E={width:_.measured.width??0,height:_.measured.height??0,x:_.position.x??0,y:_.position.y??0},L={...E,pointerX:j,pointerY:$,aspectRatio:E.width/E.height},D=void 0,V=yr(_.extent)?_.extent:void 0,_.parentId&&(_.extent==="parent"||_.expandParent)&&(D=J.get(_.parentId)),D&&_.extent==="parent"&&(V=[[0,0],[D.measured.width,D.measured.height]]),U=[],X=void 0;for(const[F,C]of J)if(C.parentId===r&&(U.push({id:F,position:{...C.position},extent:C.extent}),C.extent==="parent"||C.expandParent)){const R=n1(C,_,C.origin??z);X?X=[[Math.min(R[0][0],X[0][0]),Math.min(R[0][1],X[0][1])],[Math.max(R[1][0],X[1][0]),Math.max(R[1][1],X[1][1])]]:X=R}w==null||w(q,{...E})}).on("drag",q=>{const{transform:J,snapGrid:Z,snapToGrid:k,nodeOrigin:B}=i(),z=ni(q.sourceEvent,{transform:J,snapGrid:Z,snapToGrid:k,containerBounds:P}),H=[];if(!_)return;const{x:j,y:$,width:F,height:C}=E,R={},te=_.origin??B,{width:re,height:ue,x:ce,y:ae}=e1(L,f.controlDirection,z,f.boundaries,f.keepAspectRatio,te,V,X),G=re!==F,se=ue!==C,pe=ce!==j&&G,we=ae!==$&&se;if(!pe&&!we&&!G&&!se)return;if((pe||we||te[0]===1||te[1]===1)&&(R.x=pe?ce:E.x,R.y=we?ae:E.y,E.x=R.x,E.y=R.y,U.length>0)){const Ce=ce-j,Me=ae-$;for(const Le of U)Le.position={x:Le.position.x-Ce+te[0]*(re-F),y:Le.position.y-Me+te[1]*(ue-C)},H.push(Le)}if((G||se)&&(R.width=G&&(!f.resizeDirection||f.resizeDirection==="horizontal")?re:E.width,R.height=se&&(!f.resizeDirection||f.resizeDirection==="vertical")?ue:E.height,E.width=R.width,E.height=R.height),D&&_.expandParent){const Ce=te[0]*(R.width??0);R.x&&R.x{b&&(M==null||M(q,{...E}),u==null||u({...E}),b=!1)});c.call(ee)}function p(){c.on(".drag",null)}return{update:h,destroy:p}}var Na={exports:{}},Ca={},Ma={exports:{}},Pa={};/** +`+d.stack}return{value:e,source:t,stack:a,digest:null}}function Du(e,t,o){return{value:e,source:null,stack:o??null,digest:t??null}}function Ou(e,t){try{console.error(t.value)}catch(o){setTimeout(function(){throw o})}}var Xm=typeof WeakMap=="function"?WeakMap:Map;function Bf(e,t,o){o=dn(-1,o),o.tag=3,o.payload={element:null};var s=t.value;return o.callback=function(){_s||(_s=!0,Ju=s),Ou(e,t)},o}function Uf(e,t,o){o=dn(-1,o),o.tag=3;var s=e.type.getDerivedStateFromError;if(typeof s=="function"){var a=t.value;o.payload=function(){return s(a)},o.callback=function(){Ou(e,t)}}var d=e.stateNode;return d!==null&&typeof d.componentDidCatch=="function"&&(o.callback=function(){Ou(e,t),typeof s!="function"&&(Rn===null?Rn=new Set([this]):Rn.add(this));var w=t.stack;this.componentDidCatch(t.value,{componentStack:w!==null?w:""})}),o}function Wf(e,t,o){var s=e.pingCache;if(s===null){s=e.pingCache=new Xm;var a=new Set;s.set(t,a)}else a=s.get(t),a===void 0&&(a=new Set,s.set(t,a));a.has(o)||(a.add(o),e=l0.bind(null,e,t,o),t.then(e,e))}function bf(e){do{var t;if((t=e.tag===13)&&(t=e.memoizedState,t=t!==null?t.dehydrated!==null:!0),t)return e;e=e.return}while(e!==null);return null}function Yf(e,t,o,s,a){return(e.mode&1)===0?(e===t?e.flags|=65536:(e.flags|=128,o.flags|=131072,o.flags&=-52805,o.tag===1&&(o.alternate===null?o.tag=17:(t=dn(-1,1),t.tag=2,Tn(o,t,1))),o.lanes|=1),e):(e.flags|=65536,e.lanes=a,e)}var Qm=P.ReactCurrentOwner,dt=!1;function st(e,t,o,s){t.child=e===null?df(t,null,o,s):Hr(t,e.child,o,s)}function Xf(e,t,o,s,a){o=o.render;var d=t.ref;return Br(t,a),s=Iu(e,t,o,s,d,a),o=zu(),e!==null&&!dt?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~a,hn(e,t,a)):(De&&o&&du(t),t.flags|=1,st(e,t,s,a),t.child)}function Qf(e,t,o,s,a){if(e===null){var d=o.type;return typeof d=="function"&&!sa(d)&&d.defaultProps===void 0&&o.compare===null&&o.defaultProps===void 0?(t.tag=15,t.type=d,Gf(e,t,d,s,a)):(e=Ps(o.type,null,s,t,t.mode,a),e.ref=t.ref,e.return=t,t.child=e)}if(d=e.child,(e.lanes&a)===0){var w=d.memoizedProps;if(o=o.compare,o=o!==null?o:Io,o(w,s)&&e.ref===t.ref)return hn(e,t,a)}return t.flags|=1,e=Dn(d,s),e.ref=t.ref,e.return=t,t.child=e}function Gf(e,t,o,s,a){if(e!==null){var d=e.memoizedProps;if(Io(d,s)&&e.ref===t.ref)if(dt=!1,t.pendingProps=s=d,(e.lanes&a)!==0)(e.flags&131072)!==0&&(dt=!0);else return t.lanes=e.lanes,hn(e,t,a)}return Fu(e,t,o,s,a)}function Kf(e,t,o){var s=t.pendingProps,a=s.children,d=e!==null?e.memoizedState:null;if(s.mode==="hidden")if((t.mode&1)===0)t.memoizedState={baseLanes:0,cachePool:null,transitions:null},Re(Yr,Et),Et|=o;else{if((o&1073741824)===0)return e=d!==null?d.baseLanes|o:o,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,Re(Yr,Et),Et|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},s=d!==null?d.baseLanes:o,Re(Yr,Et),Et|=s}else d!==null?(s=d.baseLanes|o,t.memoizedState=null):s=o,Re(Yr,Et),Et|=s;return st(e,t,a,o),t.child}function qf(e,t){var o=t.ref;(e===null&&o!==null||e!==null&&e.ref!==o)&&(t.flags|=512,t.flags|=2097152)}function Fu(e,t,o,s,a){var d=ft(o)?Jn:tt.current;return d=$r(t,d),Br(t,a),o=Iu(e,t,o,s,d,a),s=zu(),e!==null&&!dt?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~a,hn(e,t,a)):(De&&s&&du(t),t.flags|=1,st(e,t,o,a),t.child)}function Zf(e,t,o,s,a){if(ft(o)){var d=!0;Ji(t)}else d=!1;if(Br(t,a),t.stateNode===null)ys(e,t),Hf(t,o,s),$u(t,o,s,a),s=!0;else if(e===null){var w=t.stateNode,z=t.memoizedProps;w.props=z;var A=w.context,Q=o.contextType;typeof Q=="object"&&Q!==null?Q=zt(Q):(Q=ft(o)?Jn:tt.current,Q=$r(t,Q));var oe=o.getDerivedStateFromProps,ie=typeof oe=="function"||typeof w.getSnapshotBeforeUpdate=="function";ie||typeof w.UNSAFE_componentWillReceiveProps!="function"&&typeof w.componentWillReceiveProps!="function"||(z!==s||A!==Q)&&Vf(t,w,s,Q),zn=!1;var ne=t.memoizedState;w.state=ne,us(t,s,w,a),A=t.memoizedState,z!==s||ne!==A||ct.current||zn?(typeof oe=="function"&&(ju(t,o,oe,s),A=t.memoizedState),(z=zn||Ff(t,o,z,s,ne,A,Q))?(ie||typeof w.UNSAFE_componentWillMount!="function"&&typeof w.componentWillMount!="function"||(typeof w.componentWillMount=="function"&&w.componentWillMount(),typeof w.UNSAFE_componentWillMount=="function"&&w.UNSAFE_componentWillMount()),typeof w.componentDidMount=="function"&&(t.flags|=4194308)):(typeof w.componentDidMount=="function"&&(t.flags|=4194308),t.memoizedProps=s,t.memoizedState=A),w.props=s,w.state=A,w.context=Q,s=z):(typeof w.componentDidMount=="function"&&(t.flags|=4194308),s=!1)}else{w=t.stateNode,pf(e,t),z=t.memoizedProps,Q=t.type===t.elementType?z:$t(t.type,z),w.props=Q,ie=t.pendingProps,ne=w.context,A=o.contextType,typeof A=="object"&&A!==null?A=zt(A):(A=ft(o)?Jn:tt.current,A=$r(t,A));var fe=o.getDerivedStateFromProps;(oe=typeof fe=="function"||typeof w.getSnapshotBeforeUpdate=="function")||typeof w.UNSAFE_componentWillReceiveProps!="function"&&typeof w.componentWillReceiveProps!="function"||(z!==ie||ne!==A)&&Vf(t,w,s,A),zn=!1,ne=t.memoizedState,w.state=ne,us(t,s,w,a);var he=t.memoizedState;z!==ie||ne!==he||ct.current||zn?(typeof fe=="function"&&(ju(t,o,fe,s),he=t.memoizedState),(Q=zn||Ff(t,o,Q,s,ne,he,A)||!1)?(oe||typeof w.UNSAFE_componentWillUpdate!="function"&&typeof w.componentWillUpdate!="function"||(typeof w.componentWillUpdate=="function"&&w.componentWillUpdate(s,he,A),typeof w.UNSAFE_componentWillUpdate=="function"&&w.UNSAFE_componentWillUpdate(s,he,A)),typeof w.componentDidUpdate=="function"&&(t.flags|=4),typeof w.getSnapshotBeforeUpdate=="function"&&(t.flags|=1024)):(typeof w.componentDidUpdate!="function"||z===e.memoizedProps&&ne===e.memoizedState||(t.flags|=4),typeof w.getSnapshotBeforeUpdate!="function"||z===e.memoizedProps&&ne===e.memoizedState||(t.flags|=1024),t.memoizedProps=s,t.memoizedState=he),w.props=s,w.state=he,w.context=A,s=Q):(typeof w.componentDidUpdate!="function"||z===e.memoizedProps&&ne===e.memoizedState||(t.flags|=4),typeof w.getSnapshotBeforeUpdate!="function"||z===e.memoizedProps&&ne===e.memoizedState||(t.flags|=1024),s=!1)}return Hu(e,t,o,s,d,a)}function Hu(e,t,o,s,a,d){qf(e,t);var w=(t.flags&128)!==0;if(!s&&!w)return a&&nf(t,o,!1),hn(e,t,d);s=t.stateNode,Qm.current=t;var z=w&&typeof o.getDerivedStateFromError!="function"?null:s.render();return t.flags|=1,e!==null&&w?(t.child=Hr(t,e.child,null,d),t.child=Hr(t,null,z,d)):st(e,t,z,d),t.memoizedState=s.state,a&&nf(t,o,!0),t.child}function Jf(e){var t=e.stateNode;t.pendingContext?ef(e,t.pendingContext,t.pendingContext!==t.context):t.context&&ef(e,t.context,!1),Eu(e,t.containerInfo)}function ed(e,t,o,s,a){return Fr(),mu(a),t.flags|=256,st(e,t,o,s),t.child}var Vu={dehydrated:null,treeContext:null,retryLane:0};function Bu(e){return{baseLanes:e,cachePool:null,transitions:null}}function td(e,t,o){var s=t.pendingProps,a=Fe.current,d=!1,w=(t.flags&128)!==0,z;if((z=w)||(z=e!==null&&e.memoizedState===null?!1:(a&2)!==0),z?(d=!0,t.flags&=-129):(e===null||e.memoizedState!==null)&&(a|=1),Re(Fe,a&1),e===null)return gu(t),e=t.memoizedState,e!==null&&(e=e.dehydrated,e!==null)?((t.mode&1)===0?t.lanes=1:e.data==="$!"?t.lanes=8:t.lanes=1073741824,null):(w=s.children,e=s.fallback,d?(s=t.mode,d=t.child,w={mode:"hidden",children:w},(s&1)===0&&d!==null?(d.childLanes=0,d.pendingProps=w):d=Is(w,s,0,null),e=ar(e,s,o,null),d.return=t,e.return=t,d.sibling=e,t.child=d,t.child.memoizedState=Bu(o),t.memoizedState=Vu,e):Uu(t,w));if(a=e.memoizedState,a!==null&&(z=a.dehydrated,z!==null))return Gm(e,t,w,s,z,a,o);if(d){d=s.fallback,w=t.mode,a=e.child,z=a.sibling;var A={mode:"hidden",children:s.children};return(w&1)===0&&t.child!==a?(s=t.child,s.childLanes=0,s.pendingProps=A,t.deletions=null):(s=Dn(a,A),s.subtreeFlags=a.subtreeFlags&14680064),z!==null?d=Dn(z,d):(d=ar(d,w,o,null),d.flags|=2),d.return=t,s.return=t,s.sibling=d,t.child=s,s=d,d=t.child,w=e.child.memoizedState,w=w===null?Bu(o):{baseLanes:w.baseLanes|o,cachePool:null,transitions:w.transitions},d.memoizedState=w,d.childLanes=e.childLanes&~o,t.memoizedState=Vu,s}return d=e.child,e=d.sibling,s=Dn(d,{mode:"visible",children:s.children}),(t.mode&1)===0&&(s.lanes=o),s.return=t,s.sibling=null,e!==null&&(o=t.deletions,o===null?(t.deletions=[e],t.flags|=16):o.push(e)),t.child=s,t.memoizedState=null,s}function Uu(e,t){return t=Is({mode:"visible",children:t},e.mode,0,null),t.return=e,e.child=t}function ms(e,t,o,s){return s!==null&&mu(s),Hr(t,e.child,null,o),e=Uu(t,t.pendingProps.children),e.flags|=2,t.memoizedState=null,e}function Gm(e,t,o,s,a,d,w){if(o)return t.flags&256?(t.flags&=-257,s=Du(Error(i(422))),ms(e,t,w,s)):t.memoizedState!==null?(t.child=e.child,t.flags|=128,null):(d=s.fallback,a=t.mode,s=Is({mode:"visible",children:s.children},a,0,null),d=ar(d,a,w,null),d.flags|=2,s.return=t,d.return=t,s.sibling=d,t.child=s,(t.mode&1)!==0&&Hr(t,e.child,null,w),t.child.memoizedState=Bu(w),t.memoizedState=Vu,d);if((t.mode&1)===0)return ms(e,t,w,null);if(a.data==="$!"){if(s=a.nextSibling&&a.nextSibling.dataset,s)var z=s.dgst;return s=z,d=Error(i(419)),s=Du(d,s,void 0),ms(e,t,w,s)}if(z=(w&e.childLanes)!==0,dt||z){if(s=Ge,s!==null){switch(w&-w){case 4:a=2;break;case 16:a=8;break;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:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:a=32;break;case 536870912:a=268435456;break;default:a=0}a=(a&(s.suspendedLanes|w))!==0?0:a,a!==0&&a!==d.retryLane&&(d.retryLane=a,fn(e,a),Ft(s,e,a,-1))}return ia(),s=Du(Error(i(421))),ms(e,t,w,s)}return a.data==="$?"?(t.flags|=128,t.child=e.child,t=u0.bind(null,e),a._reactRetry=t,null):(e=d.treeContext,_t=Cn(a.nextSibling),St=t,De=!0,jt=null,e!==null&&(Pt[It++]=an,Pt[It++]=cn,Pt[It++]=er,an=e.id,cn=e.overflow,er=t),t=Uu(t,s.children),t.flags|=4096,t)}function nd(e,t,o){e.lanes|=t;var s=e.alternate;s!==null&&(s.lanes|=t),xu(e.return,t,o)}function Wu(e,t,o,s,a){var d=e.memoizedState;d===null?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:s,tail:o,tailMode:a}:(d.isBackwards=t,d.rendering=null,d.renderingStartTime=0,d.last=s,d.tail=o,d.tailMode=a)}function rd(e,t,o){var s=t.pendingProps,a=s.revealOrder,d=s.tail;if(st(e,t,s.children,o),s=Fe.current,(s&2)!==0)s=s&1|2,t.flags|=128;else{if(e!==null&&(e.flags&128)!==0)e:for(e=t.child;e!==null;){if(e.tag===13)e.memoizedState!==null&&nd(e,o,t);else if(e.tag===19)nd(e,o,t);else if(e.child!==null){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;e.sibling===null;){if(e.return===null||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}s&=1}if(Re(Fe,s),(t.mode&1)===0)t.memoizedState=null;else switch(a){case"forwards":for(o=t.child,a=null;o!==null;)e=o.alternate,e!==null&&as(e)===null&&(a=o),o=o.sibling;o=a,o===null?(a=t.child,t.child=null):(a=o.sibling,o.sibling=null),Wu(t,!1,a,o,d);break;case"backwards":for(o=null,a=t.child,t.child=null;a!==null;){if(e=a.alternate,e!==null&&as(e)===null){t.child=a;break}e=a.sibling,a.sibling=o,o=a,a=e}Wu(t,!0,o,null,d);break;case"together":Wu(t,!1,null,null,void 0);break;default:t.memoizedState=null}return t.child}function ys(e,t){(t.mode&1)===0&&e!==null&&(e.alternate=null,t.alternate=null,t.flags|=2)}function hn(e,t,o){if(e!==null&&(t.dependencies=e.dependencies),ir|=t.lanes,(o&t.childLanes)===0)return null;if(e!==null&&t.child!==e.child)throw Error(i(153));if(t.child!==null){for(e=t.child,o=Dn(e,e.pendingProps),t.child=o,o.return=t;e.sibling!==null;)e=e.sibling,o=o.sibling=Dn(e,e.pendingProps),o.return=t;o.sibling=null}return t.child}function Km(e,t,o){switch(t.tag){case 3:Jf(t),Fr();break;case 5:yf(t);break;case 1:ft(t.type)&&Ji(t);break;case 4:Eu(t,t.stateNode.containerInfo);break;case 10:var s=t.type._context,a=t.memoizedProps.value;Re(is,s._currentValue),s._currentValue=a;break;case 13:if(s=t.memoizedState,s!==null)return s.dehydrated!==null?(Re(Fe,Fe.current&1),t.flags|=128,null):(o&t.child.childLanes)!==0?td(e,t,o):(Re(Fe,Fe.current&1),e=hn(e,t,o),e!==null?e.sibling:null);Re(Fe,Fe.current&1);break;case 19:if(s=(o&t.childLanes)!==0,(e.flags&128)!==0){if(s)return rd(e,t,o);t.flags|=128}if(a=t.memoizedState,a!==null&&(a.rendering=null,a.tail=null,a.lastEffect=null),Re(Fe,Fe.current),s)break;return null;case 22:case 23:return t.lanes=0,Kf(e,t,o)}return hn(e,t,o)}var od,bu,id,sd;od=function(e,t){for(var o=t.child;o!==null;){if(o.tag===5||o.tag===6)e.appendChild(o.stateNode);else if(o.tag!==4&&o.child!==null){o.child.return=o,o=o.child;continue}if(o===t)break;for(;o.sibling===null;){if(o.return===null||o.return===t)return;o=o.return}o.sibling.return=o.return,o=o.sibling}},bu=function(){},id=function(e,t,o,s){var a=e.memoizedProps;if(a!==s){e=t.stateNode,rr(qt.current);var d=null;switch(o){case"input":a=ke(e,a),s=ke(e,s),d=[];break;case"select":a=F({},a,{value:void 0}),s=F({},s,{value:void 0}),d=[];break;case"textarea":a=rn(e,a),s=rn(e,s),d=[];break;default:typeof a.onClick!="function"&&typeof s.onClick=="function"&&(e.onclick=Ki)}so(o,s);var w;o=null;for(Q in a)if(!s.hasOwnProperty(Q)&&a.hasOwnProperty(Q)&&a[Q]!=null)if(Q==="style"){var z=a[Q];for(w in z)z.hasOwnProperty(w)&&(o||(o={}),o[w]="")}else Q!=="dangerouslySetInnerHTML"&&Q!=="children"&&Q!=="suppressContentEditableWarning"&&Q!=="suppressHydrationWarning"&&Q!=="autoFocus"&&(u.hasOwnProperty(Q)?d||(d=[]):(d=d||[]).push(Q,null));for(Q in s){var A=s[Q];if(z=a!=null?a[Q]:void 0,s.hasOwnProperty(Q)&&A!==z&&(A!=null||z!=null))if(Q==="style")if(z){for(w in z)!z.hasOwnProperty(w)||A&&A.hasOwnProperty(w)||(o||(o={}),o[w]="");for(w in A)A.hasOwnProperty(w)&&z[w]!==A[w]&&(o||(o={}),o[w]=A[w])}else o||(d||(d=[]),d.push(Q,o)),o=A;else Q==="dangerouslySetInnerHTML"?(A=A?A.__html:void 0,z=z?z.__html:void 0,A!=null&&z!==A&&(d=d||[]).push(Q,A)):Q==="children"?typeof A!="string"&&typeof A!="number"||(d=d||[]).push(Q,""+A):Q!=="suppressContentEditableWarning"&&Q!=="suppressHydrationWarning"&&(u.hasOwnProperty(Q)?(A!=null&&Q==="onScroll"&&Ae("scroll",e),d||z===A||(d=[])):(d=d||[]).push(Q,A))}o&&(d=d||[]).push("style",o);var Q=d;(t.updateQueue=Q)&&(t.flags|=4)}},sd=function(e,t,o,s){o!==s&&(t.flags|=4)};function Wo(e,t){if(!De)switch(e.tailMode){case"hidden":t=e.tail;for(var o=null;t!==null;)t.alternate!==null&&(o=t),t=t.sibling;o===null?e.tail=null:o.sibling=null;break;case"collapsed":o=e.tail;for(var s=null;o!==null;)o.alternate!==null&&(s=o),o=o.sibling;s===null?t||e.tail===null?e.tail=null:e.tail.sibling=null:s.sibling=null}}function rt(e){var t=e.alternate!==null&&e.alternate.child===e.child,o=0,s=0;if(t)for(var a=e.child;a!==null;)o|=a.lanes|a.childLanes,s|=a.subtreeFlags&14680064,s|=a.flags&14680064,a.return=e,a=a.sibling;else for(a=e.child;a!==null;)o|=a.lanes|a.childLanes,s|=a.subtreeFlags,s|=a.flags,a.return=e,a=a.sibling;return e.subtreeFlags|=s,e.childLanes=o,t}function qm(e,t,o){var s=t.pendingProps;switch(hu(t),t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return rt(t),null;case 1:return ft(t.type)&&Zi(),rt(t),null;case 3:return s=t.stateNode,Ur(),je(ct),je(tt),Cu(),s.pendingContext&&(s.context=s.pendingContext,s.pendingContext=null),(e===null||e.child===null)&&(rs(t)?t.flags|=4:e===null||e.memoizedState.isDehydrated&&(t.flags&256)===0||(t.flags|=1024,jt!==null&&(na(jt),jt=null))),bu(e,t),rt(t),null;case 5:ku(t);var a=rr(Fo.current);if(o=t.type,e!==null&&t.stateNode!=null)id(e,t,o,s,a),e.ref!==t.ref&&(t.flags|=512,t.flags|=2097152);else{if(!s){if(t.stateNode===null)throw Error(i(166));return rt(t),null}if(e=rr(qt.current),rs(t)){s=t.stateNode,o=t.type;var d=t.memoizedProps;switch(s[Kt]=t,s[Ao]=d,e=(t.mode&1)!==0,o){case"dialog":Ae("cancel",s),Ae("close",s);break;case"iframe":case"object":case"embed":Ae("load",s);break;case"video":case"audio":for(a=0;a<\/script>",e=e.removeChild(e.firstChild)):typeof s.is=="string"?e=w.createElement(o,{is:s.is}):(e=w.createElement(o),o==="select"&&(w=e,s.multiple?w.multiple=!0:s.size&&(w.size=s.size))):e=w.createElementNS(e,o),e[Kt]=t,e[Ao]=s,od(e,t,!1,!1),t.stateNode=e;e:{switch(w=lo(o,s),o){case"dialog":Ae("cancel",e),Ae("close",e),a=s;break;case"iframe":case"object":case"embed":Ae("load",e),a=s;break;case"video":case"audio":for(a=0;aXr&&(t.flags|=128,s=!0,Wo(d,!1),t.lanes=4194304)}else{if(!s)if(e=as(w),e!==null){if(t.flags|=128,s=!0,o=e.updateQueue,o!==null&&(t.updateQueue=o,t.flags|=4),Wo(d,!0),d.tail===null&&d.tailMode==="hidden"&&!w.alternate&&!De)return rt(t),null}else 2*Oe()-d.renderingStartTime>Xr&&o!==1073741824&&(t.flags|=128,s=!0,Wo(d,!1),t.lanes=4194304);d.isBackwards?(w.sibling=t.child,t.child=w):(o=d.last,o!==null?o.sibling=w:t.child=w,d.last=w)}return d.tail!==null?(t=d.tail,d.rendering=t,d.tail=t.sibling,d.renderingStartTime=Oe(),t.sibling=null,o=Fe.current,Re(Fe,s?o&1|2:o&1),t):(rt(t),null);case 22:case 23:return oa(),s=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==s&&(t.flags|=8192),s&&(t.mode&1)!==0?(Et&1073741824)!==0&&(rt(t),t.subtreeFlags&6&&(t.flags|=8192)):rt(t),null;case 24:return null;case 25:return null}throw Error(i(156,t.tag))}function Zm(e,t){switch(hu(t),t.tag){case 1:return ft(t.type)&&Zi(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Ur(),je(ct),je(tt),Cu(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 5:return ku(t),null;case 13:if(je(Fe),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));Fr()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return je(Fe),null;case 4:return Ur(),null;case 10:return wu(t.type._context),null;case 22:case 23:return oa(),null;case 24:return null;default:return null}}var vs=!1,ot=!1,Jm=typeof WeakSet=="function"?WeakSet:Set,de=null;function br(e,t){var o=e.ref;if(o!==null)if(typeof o=="function")try{o(null)}catch(s){Be(e,t,s)}else o.current=null}function Yu(e,t,o){try{o()}catch(s){Be(e,t,s)}}var ld=!1;function e0(e,t){if(ou=Oi,e=Oc(),Kl(e)){if("selectionStart"in e)var o={start:e.selectionStart,end:e.selectionEnd};else e:{o=(o=e.ownerDocument)&&o.defaultView||window;var s=o.getSelection&&o.getSelection();if(s&&s.rangeCount!==0){o=s.anchorNode;var a=s.anchorOffset,d=s.focusNode;s=s.focusOffset;try{o.nodeType,d.nodeType}catch{o=null;break e}var w=0,z=-1,A=-1,Q=0,oe=0,ie=e,ne=null;t:for(;;){for(var fe;ie!==o||a!==0&&ie.nodeType!==3||(z=w+a),ie!==d||s!==0&&ie.nodeType!==3||(A=w+s),ie.nodeType===3&&(w+=ie.nodeValue.length),(fe=ie.firstChild)!==null;)ne=ie,ie=fe;for(;;){if(ie===e)break t;if(ne===o&&++Q===a&&(z=w),ne===d&&++oe===s&&(A=w),(fe=ie.nextSibling)!==null)break;ie=ne,ne=ie.parentNode}ie=fe}o=z===-1||A===-1?null:{start:z,end:A}}else o=null}o=o||{start:0,end:0}}else o=null;for(iu={focusedElem:e,selectionRange:o},Oi=!1,de=t;de!==null;)if(t=de,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,de=e;else for(;de!==null;){t=de;try{var he=t.alternate;if((t.flags&1024)!==0)switch(t.tag){case 0:case 11:case 15:break;case 1:if(he!==null){var ge=he.memoizedProps,Ue=he.memoizedState,W=t.stateNode,O=W.getSnapshotBeforeUpdate(t.elementType===t.type?ge:$t(t.type,ge),Ue);W.__reactInternalSnapshotBeforeUpdate=O}break;case 3:var b=t.stateNode.containerInfo;b.nodeType===1?b.textContent="":b.nodeType===9&&b.documentElement&&b.removeChild(b.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(i(163))}}catch(le){Be(t,t.return,le)}if(e=t.sibling,e!==null){e.return=t.return,de=e;break}de=t.return}return he=ld,ld=!1,he}function bo(e,t,o){var s=t.updateQueue;if(s=s!==null?s.lastEffect:null,s!==null){var a=s=s.next;do{if((a.tag&e)===e){var d=a.destroy;a.destroy=void 0,d!==void 0&&Yu(t,o,d)}a=a.next}while(a!==s)}}function ws(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var o=t=t.next;do{if((o.tag&e)===e){var s=o.create;o.destroy=s()}o=o.next}while(o!==t)}}function Xu(e){var t=e.ref;if(t!==null){var o=e.stateNode;switch(e.tag){case 5:e=o;break;default:e=o}typeof t=="function"?t(e):t.current=e}}function ud(e){var t=e.alternate;t!==null&&(e.alternate=null,ud(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[Kt],delete t[Ao],delete t[au],delete t[$m],delete t[Dm])),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 ad(e){return e.tag===5||e.tag===3||e.tag===4}function cd(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||ad(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 Qu(e,t,o){var s=e.tag;if(s===5||s===6)e=e.stateNode,t?o.nodeType===8?o.parentNode.insertBefore(e,t):o.insertBefore(e,t):(o.nodeType===8?(t=o.parentNode,t.insertBefore(e,o)):(t=o,t.appendChild(e)),o=o._reactRootContainer,o!=null||t.onclick!==null||(t.onclick=Ki));else if(s!==4&&(e=e.child,e!==null))for(Qu(e,t,o),e=e.sibling;e!==null;)Qu(e,t,o),e=e.sibling}function Gu(e,t,o){var s=e.tag;if(s===5||s===6)e=e.stateNode,t?o.insertBefore(e,t):o.appendChild(e);else if(s!==4&&(e=e.child,e!==null))for(Gu(e,t,o),e=e.sibling;e!==null;)Gu(e,t,o),e=e.sibling}var qe=null,Dt=!1;function Ln(e,t,o){for(o=o.child;o!==null;)fd(e,t,o),o=o.sibling}function fd(e,t,o){if(vt&&typeof vt.onCommitFiberUnmount=="function")try{vt.onCommitFiberUnmount(Er,o)}catch{}switch(o.tag){case 5:ot||br(o,t);case 6:var s=qe,a=Dt;qe=null,Ln(e,t,o),qe=s,Dt=a,qe!==null&&(Dt?(e=qe,o=o.stateNode,e.nodeType===8?e.parentNode.removeChild(o):e.removeChild(o)):qe.removeChild(o.stateNode));break;case 18:qe!==null&&(Dt?(e=qe,o=o.stateNode,e.nodeType===8?uu(e.parentNode,o):e.nodeType===1&&uu(e,o),Eo(e)):uu(qe,o.stateNode));break;case 4:s=qe,a=Dt,qe=o.stateNode.containerInfo,Dt=!0,Ln(e,t,o),qe=s,Dt=a;break;case 0:case 11:case 14:case 15:if(!ot&&(s=o.updateQueue,s!==null&&(s=s.lastEffect,s!==null))){a=s=s.next;do{var d=a,w=d.destroy;d=d.tag,w!==void 0&&((d&2)!==0||(d&4)!==0)&&Yu(o,t,w),a=a.next}while(a!==s)}Ln(e,t,o);break;case 1:if(!ot&&(br(o,t),s=o.stateNode,typeof s.componentWillUnmount=="function"))try{s.props=o.memoizedProps,s.state=o.memoizedState,s.componentWillUnmount()}catch(z){Be(o,t,z)}Ln(e,t,o);break;case 21:Ln(e,t,o);break;case 22:o.mode&1?(ot=(s=ot)||o.memoizedState!==null,Ln(e,t,o),ot=s):Ln(e,t,o);break;default:Ln(e,t,o)}}function dd(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var o=e.stateNode;o===null&&(o=e.stateNode=new Jm),t.forEach(function(s){var a=a0.bind(null,e,s);o.has(s)||(o.add(s),s.then(a,a))})}}function Ot(e,t){var o=t.deletions;if(o!==null)for(var s=0;sa&&(a=w),s&=~d}if(s=a,s=Oe()-s,s=(120>s?120:480>s?480:1080>s?1080:1920>s?1920:3e3>s?3e3:4320>s?4320:1960*n0(s/1960))-s,10e?16:e,An===null)var s=!1;else{if(e=An,An=null,ks=0,(Pe&6)!==0)throw Error(i(331));var a=Pe;for(Pe|=4,de=e.current;de!==null;){var d=de,w=d.child;if((de.flags&16)!==0){var z=d.deletions;if(z!==null){for(var A=0;AOe()-Zu?lr(e,0):qu|=o),pt(e,t)}function Nd(e,t){t===0&&((e.mode&1)===0?t=1:(t=Nr,Nr<<=1,(Nr&130023424)===0&&(Nr=4194304)));var o=lt();e=fn(e,t),e!==null&&(qn(e,t,o),pt(e,o))}function u0(e){var t=e.memoizedState,o=0;t!==null&&(o=t.retryLane),Nd(e,o)}function a0(e,t){var o=0;switch(e.tag){case 13:var s=e.stateNode,a=e.memoizedState;a!==null&&(o=a.retryLane);break;case 19:s=e.stateNode;break;default:throw Error(i(314))}s!==null&&s.delete(t),Nd(e,o)}var Cd;Cd=function(e,t,o){if(e!==null)if(e.memoizedProps!==t.pendingProps||ct.current)dt=!0;else{if((e.lanes&o)===0&&(t.flags&128)===0)return dt=!1,Km(e,t,o);dt=(e.flags&131072)!==0}else dt=!1,De&&(t.flags&1048576)!==0&&of(t,ns,t.index);switch(t.lanes=0,t.tag){case 2:var s=t.type;ys(e,t),e=t.pendingProps;var a=$r(t,tt.current);Br(t,o),a=Iu(null,t,s,e,a,o);var d=zu();return t.flags|=1,typeof a=="object"&&a!==null&&typeof a.render=="function"&&a.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,ft(s)?(d=!0,Ji(t)):d=!1,t.memoizedState=a.state!==null&&a.state!==void 0?a.state:null,_u(t),a.updater=gs,t.stateNode=a,a._reactInternals=t,$u(t,s,e,o),t=Hu(null,t,s,!0,d,o)):(t.tag=0,De&&d&&du(t),st(null,t,a,o),t=t.child),t;case 16:s=t.elementType;e:{switch(ys(e,t),e=t.pendingProps,a=s._init,s=a(s._payload),t.type=s,a=t.tag=f0(s),e=$t(s,e),a){case 0:t=Fu(null,t,s,e,o);break e;case 1:t=Zf(null,t,s,e,o);break e;case 11:t=Xf(null,t,s,e,o);break e;case 14:t=Qf(null,t,s,$t(s.type,e),o);break e}throw Error(i(306,s,""))}return t;case 0:return s=t.type,a=t.pendingProps,a=t.elementType===s?a:$t(s,a),Fu(e,t,s,a,o);case 1:return s=t.type,a=t.pendingProps,a=t.elementType===s?a:$t(s,a),Zf(e,t,s,a,o);case 3:e:{if(Jf(t),e===null)throw Error(i(387));s=t.pendingProps,d=t.memoizedState,a=d.element,pf(e,t),us(t,s,null,o);var w=t.memoizedState;if(s=w.element,d.isDehydrated)if(d={element:s,isDehydrated:!1,cache:w.cache,pendingSuspenseBoundaries:w.pendingSuspenseBoundaries,transitions:w.transitions},t.updateQueue.baseState=d,t.memoizedState=d,t.flags&256){a=Wr(Error(i(423)),t),t=ed(e,t,s,o,a);break e}else if(s!==a){a=Wr(Error(i(424)),t),t=ed(e,t,s,o,a);break e}else for(_t=Cn(t.stateNode.containerInfo.firstChild),St=t,De=!0,jt=null,o=df(t,null,s,o),t.child=o;o;)o.flags=o.flags&-3|4096,o=o.sibling;else{if(Fr(),s===a){t=hn(e,t,o);break e}st(e,t,s,o)}t=t.child}return t;case 5:return yf(t),e===null&&gu(t),s=t.type,a=t.pendingProps,d=e!==null?e.memoizedProps:null,w=a.children,su(s,a)?w=null:d!==null&&su(s,d)&&(t.flags|=32),qf(e,t),st(e,t,w,o),t.child;case 6:return e===null&&gu(t),null;case 13:return td(e,t,o);case 4:return Eu(t,t.stateNode.containerInfo),s=t.pendingProps,e===null?t.child=Hr(t,null,s,o):st(e,t,s,o),t.child;case 11:return s=t.type,a=t.pendingProps,a=t.elementType===s?a:$t(s,a),Xf(e,t,s,a,o);case 7:return st(e,t,t.pendingProps,o),t.child;case 8:return st(e,t,t.pendingProps.children,o),t.child;case 12:return st(e,t,t.pendingProps.children,o),t.child;case 10:e:{if(s=t.type._context,a=t.pendingProps,d=t.memoizedProps,w=a.value,Re(is,s._currentValue),s._currentValue=w,d!==null)if(At(d.value,w)){if(d.children===a.children&&!ct.current){t=hn(e,t,o);break e}}else for(d=t.child,d!==null&&(d.return=t);d!==null;){var z=d.dependencies;if(z!==null){w=d.child;for(var A=z.firstContext;A!==null;){if(A.context===s){if(d.tag===1){A=dn(-1,o&-o),A.tag=2;var Q=d.updateQueue;if(Q!==null){Q=Q.shared;var oe=Q.pending;oe===null?A.next=A:(A.next=oe.next,oe.next=A),Q.pending=A}}d.lanes|=o,A=d.alternate,A!==null&&(A.lanes|=o),xu(d.return,o,t),z.lanes|=o;break}A=A.next}}else if(d.tag===10)w=d.type===t.type?null:d.child;else if(d.tag===18){if(w=d.return,w===null)throw Error(i(341));w.lanes|=o,z=w.alternate,z!==null&&(z.lanes|=o),xu(w,o,t),w=d.sibling}else w=d.child;if(w!==null)w.return=d;else for(w=d;w!==null;){if(w===t){w=null;break}if(d=w.sibling,d!==null){d.return=w.return,w=d;break}w=w.return}d=w}st(e,t,a.children,o),t=t.child}return t;case 9:return a=t.type,s=t.pendingProps.children,Br(t,o),a=zt(a),s=s(a),t.flags|=1,st(e,t,s,o),t.child;case 14:return s=t.type,a=$t(s,t.pendingProps),a=$t(s.type,a),Qf(e,t,s,a,o);case 15:return Gf(e,t,t.type,t.pendingProps,o);case 17:return s=t.type,a=t.pendingProps,a=t.elementType===s?a:$t(s,a),ys(e,t),t.tag=1,ft(s)?(e=!0,Ji(t)):e=!1,Br(t,o),Hf(t,s,a),$u(t,s,a,o),Hu(null,t,s,!0,e,o);case 19:return rd(e,t,o);case 22:return Kf(e,t,o)}throw Error(i(156,t.tag))};function Md(e,t){return Ii(e,t)}function c0(e,t,o,s){this.tag=e,this.key=o,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=s,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Rt(e,t,o,s){return new c0(e,t,o,s)}function sa(e){return e=e.prototype,!(!e||!e.isReactComponent)}function f0(e){if(typeof e=="function")return sa(e)?1:0;if(e!=null){if(e=e.$$typeof,e===J)return 11;if(e===B)return 14}return 2}function Dn(e,t){var o=e.alternate;return o===null?(o=Rt(e.tag,t,e.key,e.mode),o.elementType=e.elementType,o.type=e.type,o.stateNode=e.stateNode,o.alternate=e,e.alternate=o):(o.pendingProps=t,o.type=e.type,o.flags=0,o.subtreeFlags=0,o.deletions=null),o.flags=e.flags&14680064,o.childLanes=e.childLanes,o.lanes=e.lanes,o.child=e.child,o.memoizedProps=e.memoizedProps,o.memoizedState=e.memoizedState,o.updateQueue=e.updateQueue,t=e.dependencies,o.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},o.sibling=e.sibling,o.index=e.index,o.ref=e.ref,o}function Ps(e,t,o,s,a,d){var w=2;if(s=e,typeof e=="function")sa(e)&&(w=1);else if(typeof e=="string")w=5;else e:switch(e){case V:return ar(o.children,a,d,t);case Y:w=8,a|=8;break;case X:return e=Rt(12,o,t,a|2),e.elementType=X,e.lanes=d,e;case Z:return e=Rt(13,o,t,a),e.elementType=Z,e.lanes=d,e;case k:return e=Rt(19,o,t,a),e.elementType=k,e.lanes=d,e;case H:return Is(o,a,d,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case ee:w=10;break e;case q:w=9;break e;case J:w=11;break e;case B:w=14;break e;case I:w=16,s=null;break e}throw Error(i(130,e==null?e:typeof e,""))}return t=Rt(w,o,t,a),t.elementType=e,t.type=s,t.lanes=d,t}function ar(e,t,o,s){return e=Rt(7,e,s,t),e.lanes=o,e}function Is(e,t,o,s){return e=Rt(22,e,s,t),e.elementType=H,e.lanes=o,e.stateNode={isHidden:!1},e}function la(e,t,o){return e=Rt(6,e,null,t),e.lanes=o,e}function ua(e,t,o){return t=Rt(4,e.children!==null?e.children:[],e.key,t),t.lanes=o,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function d0(e,t,o,s,a){this.tag=t,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=Kn(0),this.expirationTimes=Kn(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Kn(0),this.identifierPrefix=s,this.onRecoverableError=a,this.mutableSourceEagerHydrationData=null}function aa(e,t,o,s,a,d,w,z,A){return e=new d0(e,t,o,z,A),t===1?(t=1,d===!0&&(t|=8)):t=0,d=Rt(3,null,null,t),e.current=d,d.stateNode=e,d.memoizedState={element:s,isDehydrated:o,cache:null,transitions:null,pendingSuspenseBoundaries:null},_u(d),e}function h0(e,t,o){var s=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(r){console.error(r)}}return n(),ga.exports=N0(),ga.exports}var Vd;function C0(){if(Vd)return $s;Vd=1;var n=Jh();return $s.createRoot=n.createRoot,$s.hydrateRoot=n.hydrateRoot,$s}var M0=C0();async function Fn(n,r){const i=await fetch(n,{...r,headers:{"Content-Type":"application/json",...(r==null?void 0:r.headers)||{}}});if(!i.ok){const l=await i.text();throw new Error(l||i.statusText)}return i.json()}const Gr={health:()=>Fn("/api/health"),settings:()=>Fn("/api/settings"),saveSettings:n=>Fn("/api/settings",{method:"PUT",body:JSON.stringify(n)}),index:n=>Fn("/api/index",{method:"POST",body:JSON.stringify({repo_path:n,incremental:!0})}),review:(n,r,i)=>Fn("/api/review",{method:"POST",body:JSON.stringify({repo_path:n,base:r,head:i||null,reindex:!0})}),graph:n=>Fn(`/api/graph?repo_path=${encodeURIComponent(n)}`),prs:(n,r,i="open")=>Fn("/api/prs",{method:"POST",body:JSON.stringify({provider:n,repo:r,state:i})}),residual:n=>Fn("/api/ai/residual",{method:"POST",body:JSON.stringify({review:n})})};function be(n){if(typeof n=="string"||typeof n=="number")return""+n;let r="";if(Array.isArray(n))for(let i=0,l;i{}};function al(){for(var n=0,r=arguments.length,i={},l;n=0&&(l=i.slice(u+1),i=i.slice(0,u)),i&&!r.hasOwnProperty(i))throw new Error("unknown type: "+i);return{type:i,name:l}})}Ys.prototype=al.prototype={constructor:Ys,on:function(n,r){var i=this._,l=I0(n+"",i),u,c=-1,f=l.length;if(arguments.length<2){for(;++c0)for(var i=new Array(u),l=0,u,c;l=0&&(r=n.slice(0,i))!=="xmlns"&&(n=n.slice(i+1)),Ud.hasOwnProperty(r)?{space:Ud[r],local:n}:n}function T0(n){return function(){var r=this.ownerDocument,i=this.namespaceURI;return i===Ta&&r.documentElement.namespaceURI===Ta?r.createElement(n):r.createElementNS(i,n)}}function L0(n){return function(){return this.ownerDocument.createElementNS(n.space,n.local)}}function ep(n){var r=cl(n);return(r.local?L0:T0)(r)}function R0(){}function ba(n){return n==null?R0:function(){return this.querySelector(n)}}function A0(n){typeof n!="function"&&(n=ba(n));for(var r=this._groups,i=r.length,l=new Array(i),u=0;u=_&&(_=L+1);!(U=N[_])&&++_=0;)(f=l[u])&&(c&&f.compareDocumentPosition(c)^4&&c.parentNode.insertBefore(f,c),c=f);return this}function iy(n){n||(n=sy);function r(y,g){return y&&g?n(y.__data__,g.__data__):!y-!g}for(var i=this._groups,l=i.length,u=new Array(l),c=0;cr?1:n>=r?0:NaN}function ly(){var n=arguments[0];return arguments[0]=this,n.apply(null,arguments),this}function uy(){return Array.from(this)}function ay(){for(var n=this._groups,r=0,i=n.length;r1?this.each((r==null?xy:typeof r=="function"?_y:Sy)(n,r,i??"")):eo(this.node(),n)}function eo(n,r){return n.style.getPropertyValue(r)||ip(n).getComputedStyle(n,null).getPropertyValue(r)}function ky(n){return function(){delete this[n]}}function Ny(n,r){return function(){this[n]=r}}function Cy(n,r){return function(){var i=r.apply(this,arguments);i==null?delete this[n]:this[n]=i}}function My(n,r){return arguments.length>1?this.each((r==null?ky:typeof r=="function"?Cy:Ny)(n,r)):this.node()[n]}function sp(n){return n.trim().split(/^|\s+/)}function Ya(n){return n.classList||new lp(n)}function lp(n){this._node=n,this._names=sp(n.getAttribute("class")||"")}lp.prototype={add:function(n){var r=this._names.indexOf(n);r<0&&(this._names.push(n),this._node.setAttribute("class",this._names.join(" ")))},remove:function(n){var r=this._names.indexOf(n);r>=0&&(this._names.splice(r,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(n){return this._names.indexOf(n)>=0}};function up(n,r){for(var i=Ya(n),l=-1,u=r.length;++l=0&&(i=r.slice(l+1),r=r.slice(0,l)),{type:r,name:i}})}function tv(n){return function(){var r=this.__on;if(r){for(var i=0,l=-1,u=r.length,c;i()=>n;function La(n,{sourceEvent:r,subject:i,target:l,identifier:u,active:c,x:f,y:h,dx:p,dy:m,dispatch:v}){Object.defineProperties(this,{type:{value:n,enumerable:!0,configurable:!0},sourceEvent:{value:r,enumerable:!0,configurable:!0},subject:{value:i,enumerable:!0,configurable:!0},target:{value:l,enumerable:!0,configurable:!0},identifier:{value:u,enumerable:!0,configurable:!0},active:{value:c,enumerable:!0,configurable:!0},x:{value:f,enumerable:!0,configurable:!0},y:{value:h,enumerable:!0,configurable:!0},dx:{value:p,enumerable:!0,configurable:!0},dy:{value:m,enumerable:!0,configurable:!0},_:{value:v}})}La.prototype.on=function(){var n=this._.on.apply(this._,arguments);return n===this._?this:n};function fv(n){return!n.ctrlKey&&!n.button}function dv(){return this.parentNode}function hv(n,r){return r??{x:n.x,y:n.y}}function pv(){return navigator.maxTouchPoints||"ontouchstart"in this}function pp(){var n=fv,r=dv,i=hv,l=pv,u={},c=al("start","drag","end"),f=0,h,p,m,v,y=0;function g(P){P.on("mousedown.drag",x).filter(l).on("touchstart.drag",N).on("touchmove.drag",E,cv).on("touchend.drag touchcancel.drag",L).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function x(P,U){if(!(v||!n.call(this,P,U))){var D=_(this,r.call(this,P,U),P,U,"mouse");D&&(kt(P.view).on("mousemove.drag",S,ri).on("mouseup.drag",M,ri),dp(P.view),va(P),m=!1,h=P.clientX,p=P.clientY,D("start",P))}}function S(P){if(Zr(P),!m){var U=P.clientX-h,D=P.clientY-p;m=U*U+D*D>y}u.mouse("drag",P)}function M(P){kt(P.view).on("mousemove.drag mouseup.drag",null),hp(P.view,m),Zr(P),u.mouse("end",P)}function N(P,U){if(n.call(this,P,U)){var D=P.changedTouches,V=r.call(this,P,U),Y=D.length,X,ee;for(X=0;X>8&15|r>>4&240,r>>4&15|r&240,(r&15)<<4|r&15,1):i===8?Os(r>>24&255,r>>16&255,r>>8&255,(r&255)/255):i===4?Os(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=mv.exec(n))?new mt(r[1],r[2],r[3],1):(r=yv.exec(n))?new mt(r[1]*255/100,r[2]*255/100,r[3]*255/100,1):(r=vv.exec(n))?Os(r[1],r[2],r[3],r[4]):(r=wv.exec(n))?Os(r[1]*255/100,r[2]*255/100,r[3]*255/100,r[4]):(r=xv.exec(n))?Kd(r[1],r[2]/100,r[3]/100,1):(r=Sv.exec(n))?Kd(r[1],r[2]/100,r[3]/100,r[4]):Wd.hasOwnProperty(n)?Xd(Wd[n]):n==="transparent"?new mt(NaN,NaN,NaN,0):null}function Xd(n){return new mt(n>>16&255,n>>8&255,n&255,1)}function Os(n,r,i,l){return l<=0&&(n=r=i=NaN),new mt(n,r,i,l)}function kv(n){return n instanceof pi||(n=pr(n)),n?(n=n.rgb(),new mt(n.r,n.g,n.b,n.opacity)):new mt}function Ra(n,r,i,l){return arguments.length===1?kv(n):new mt(n,r,i,l??1)}function mt(n,r,i,l){this.r=+n,this.g=+r,this.b=+i,this.opacity=+l}Xa(mt,Ra,gp(pi,{brighter(n){return n=n==null?Zs:Math.pow(Zs,n),new mt(this.r*n,this.g*n,this.b*n,this.opacity)},darker(n){return n=n==null?oi:Math.pow(oi,n),new mt(this.r*n,this.g*n,this.b*n,this.opacity)},rgb(){return this},clamp(){return new mt(dr(this.r),dr(this.g),dr(this.b),Js(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:Qd,formatHex:Qd,formatHex8:Nv,formatRgb:Gd,toString:Gd}));function Qd(){return`#${fr(this.r)}${fr(this.g)}${fr(this.b)}`}function Nv(){return`#${fr(this.r)}${fr(this.g)}${fr(this.b)}${fr((isNaN(this.opacity)?1:this.opacity)*255)}`}function Gd(){const n=Js(this.opacity);return`${n===1?"rgb(":"rgba("}${dr(this.r)}, ${dr(this.g)}, ${dr(this.b)}${n===1?")":`, ${n})`}`}function Js(n){return isNaN(n)?1:Math.max(0,Math.min(1,n))}function dr(n){return Math.max(0,Math.min(255,Math.round(n)||0))}function fr(n){return n=dr(n),(n<16?"0":"")+n.toString(16)}function Kd(n,r,i,l){return l<=0?n=r=i=NaN:i<=0||i>=1?n=r=NaN:r<=0&&(n=NaN),new Vt(n,r,i,l)}function mp(n){if(n instanceof Vt)return new Vt(n.h,n.s,n.l,n.opacity);if(n instanceof pi||(n=pr(n)),!n)return new Vt;if(n instanceof Vt)return n;n=n.rgb();var r=n.r/255,i=n.g/255,l=n.b/255,u=Math.min(r,i,l),c=Math.max(r,i,l),f=NaN,h=c-u,p=(c+u)/2;return h?(r===c?f=(i-l)/h+(i0&&p<1?0:f,new Vt(f,h,p,n.opacity)}function Cv(n,r,i,l){return arguments.length===1?mp(n):new Vt(n,r,i,l??1)}function Vt(n,r,i,l){this.h=+n,this.s=+r,this.l=+i,this.opacity=+l}Xa(Vt,Cv,gp(pi,{brighter(n){return n=n==null?Zs:Math.pow(Zs,n),new Vt(this.h,this.s,this.l*n,this.opacity)},darker(n){return n=n==null?oi:Math.pow(oi,n),new Vt(this.h,this.s,this.l*n,this.opacity)},rgb(){var n=this.h%360+(this.h<0)*360,r=isNaN(n)||isNaN(this.s)?0:this.s,i=this.l,l=i+(i<.5?i:1-i)*r,u=2*i-l;return new mt(wa(n>=240?n-240:n+120,u,l),wa(n,u,l),wa(n<120?n+240:n-120,u,l),this.opacity)},clamp(){return new Vt(qd(this.h),Fs(this.s),Fs(this.l),Js(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 n=Js(this.opacity);return`${n===1?"hsl(":"hsla("}${qd(this.h)}, ${Fs(this.s)*100}%, ${Fs(this.l)*100}%${n===1?")":`, ${n})`}`}}));function qd(n){return n=(n||0)%360,n<0?n+360:n}function Fs(n){return Math.max(0,Math.min(1,n||0))}function wa(n,r,i){return(n<60?r+(i-r)*n/60:n<180?i:n<240?r+(i-r)*(240-n)/60:r)*255}const Qa=n=>()=>n;function Mv(n,r){return function(i){return n+i*r}}function Pv(n,r,i){return n=Math.pow(n,i),r=Math.pow(r,i)-n,i=1/i,function(l){return Math.pow(n+l*r,i)}}function Iv(n){return(n=+n)==1?yp:function(r,i){return i-r?Pv(r,i,n):Qa(isNaN(r)?i:r)}}function yp(n,r){var i=r-n;return i?Mv(n,i):Qa(isNaN(n)?r:n)}const el=(function n(r){var i=Iv(r);function l(u,c){var f=i((u=Ra(u)).r,(c=Ra(c)).r),h=i(u.g,c.g),p=i(u.b,c.b),m=yp(u.opacity,c.opacity);return function(v){return u.r=f(v),u.g=h(v),u.b=p(v),u.opacity=m(v),u+""}}return l.gamma=n,l})(1);function zv(n,r){r||(r=[]);var i=n?Math.min(r.length,n.length):0,l=r.slice(),u;return function(c){for(u=0;ui&&(c=r.slice(i,c),h[f]?h[f]+=c:h[++f]=c),(l=l[0])===(u=u[0])?h[f]?h[f]+=u:h[++f]=u:(h[++f]=null,p.push({i:f,x:en(l,u)})),i=xa.lastIndex;return i180?v+=360:v-m>180&&(m+=360),g.push({i:y.push(u(y)+"rotate(",null,l)-2,x:en(m,v)})):v&&y.push(u(y)+"rotate("+v+l)}function h(m,v,y,g){m!==v?g.push({i:y.push(u(y)+"skewX(",null,l)-2,x:en(m,v)}):v&&y.push(u(y)+"skewX("+v+l)}function p(m,v,y,g,x,S){if(m!==y||v!==g){var M=x.push(u(x)+"scale(",null,",",null,")");S.push({i:M-4,x:en(m,y)},{i:M-2,x:en(v,g)})}else(y!==1||g!==1)&&x.push(u(x)+"scale("+y+","+g+")")}return function(m,v){var y=[],g=[];return m=n(m),v=n(v),c(m.translateX,m.translateY,v.translateX,v.translateY,y,g),f(m.rotate,v.rotate,y,g),h(m.skewX,v.skewX,y,g),p(m.scaleX,m.scaleY,v.scaleX,v.scaleY,y,g),m=v=null,function(x){for(var S=-1,M=g.length,N;++S=0&&n._call.call(void 0,r),n=n._next;--to}function eh(){gr=(nl=si.now())+fl,to=Jo=0;try{bv()}finally{to=0,Xv(),gr=0}}function Yv(){var n=si.now(),r=n-nl;r>Sp&&(fl-=r,nl=n)}function Xv(){for(var n,r=tl,i,l=1/0;r;)r._call?(l>r._time&&(l=r._time),n=r,r=r._next):(i=r._next,r._next=null,r=n?n._next=i:tl=i);ei=n,$a(l)}function $a(n){if(!to){Jo&&(Jo=clearTimeout(Jo));var r=n-gr;r>24?(n<1/0&&(Jo=setTimeout(eh,n-si.now()-fl)),qo&&(qo=clearInterval(qo))):(qo||(nl=si.now(),qo=setInterval(Yv,Sp)),to=1,_p(eh))}}function th(n,r,i){var l=new rl;return r=r==null?0:+r,l.restart(u=>{l.stop(),n(u+r)},r,i),l}var Qv=al("start","end","cancel","interrupt"),Gv=[],kp=0,nh=1,Da=2,Qs=3,rh=4,Oa=5,Gs=6;function dl(n,r,i,l,u,c){var f=n.__transition;if(!f)n.__transition={};else if(i in f)return;Kv(n,i,{name:r,index:l,group:u,on:Qv,tween:Gv,time:c.time,delay:c.delay,duration:c.duration,ease:c.ease,timer:null,state:kp})}function Ka(n,r){var i=bt(n,r);if(i.state>kp)throw new Error("too late; already scheduled");return i}function nn(n,r){var i=bt(n,r);if(i.state>Qs)throw new Error("too late; already running");return i}function bt(n,r){var i=n.__transition;if(!i||!(i=i[r]))throw new Error("transition not found");return i}function Kv(n,r,i){var l=n.__transition,u;l[r]=i,i.timer=Ep(c,0,i.time);function c(m){i.state=nh,i.timer.restart(f,i.delay,i.time),i.delay<=m&&f(m-i.delay)}function f(m){var v,y,g,x;if(i.state!==nh)return p();for(v in l)if(x=l[v],x.name===i.name){if(x.state===Qs)return th(f);x.state===rh?(x.state=Gs,x.timer.stop(),x.on.call("interrupt",n,n.__data__,x.index,x.group),delete l[v]):+vDa&&l.state=0&&(r=r.slice(0,i)),!r||r==="start"})}function Cw(n,r,i){var l,u,c=Nw(r)?Ka:nn;return function(){var f=c(this,n),h=f.on;h!==l&&(u=(l=h).copy()).on(r,i),f.on=u}}function Mw(n,r){var i=this._id;return arguments.length<2?bt(this.node(),i).on.on(n):this.each(Cw(i,n,r))}function Pw(n){return function(){var r=this.parentNode;for(var i in this.__transition)if(+i!==n)return;r&&r.removeChild(this)}}function Iw(){return this.on("end.remove",Pw(this._id))}function zw(n){var r=this._name,i=this._id;typeof n!="function"&&(n=ba(n));for(var l=this._groups,u=l.length,c=new Array(u),f=0;f()=>n;function tx(n,{sourceEvent:r,target:i,transform:l,dispatch:u}){Object.defineProperties(this,{type:{value:n,enumerable:!0,configurable:!0},sourceEvent:{value:r,enumerable:!0,configurable:!0},target:{value:i,enumerable:!0,configurable:!0},transform:{value:l,enumerable:!0,configurable:!0},_:{value:u}})}function mn(n,r,i){this.k=n,this.x=r,this.y=i}mn.prototype={constructor:mn,scale:function(n){return n===1?this:new mn(this.k*n,this.x,this.y)},translate:function(n,r){return n===0&r===0?this:new mn(this.k,this.x+this.k*n,this.y+this.k*r)},apply:function(n){return[n[0]*this.k+this.x,n[1]*this.k+this.y]},applyX:function(n){return n*this.k+this.x},applyY:function(n){return n*this.k+this.y},invert:function(n){return[(n[0]-this.x)/this.k,(n[1]-this.y)/this.k]},invertX:function(n){return(n-this.x)/this.k},invertY:function(n){return(n-this.y)/this.k},rescaleX:function(n){return n.copy().domain(n.range().map(this.invertX,this).map(n.invert,n))},rescaleY:function(n){return n.copy().domain(n.range().map(this.invertY,this).map(n.invert,n))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};var hl=new mn(1,0,0);Pp.prototype=mn.prototype;function Pp(n){for(;!n.__zoom;)if(!(n=n.parentNode))return hl;return n.__zoom}function Sa(n){n.stopImmediatePropagation()}function Zo(n){n.preventDefault(),n.stopImmediatePropagation()}function nx(n){return(!n.ctrlKey||n.type==="wheel")&&!n.button}function rx(){var n=this;return n instanceof SVGElement?(n=n.ownerSVGElement||n,n.hasAttribute("viewBox")?(n=n.viewBox.baseVal,[[n.x,n.y],[n.x+n.width,n.y+n.height]]):[[0,0],[n.width.baseVal.value,n.height.baseVal.value]]):[[0,0],[n.clientWidth,n.clientHeight]]}function oh(){return this.__zoom||hl}function ox(n){return-n.deltaY*(n.deltaMode===1?.05:n.deltaMode?1:.002)*(n.ctrlKey?10:1)}function ix(){return navigator.maxTouchPoints||"ontouchstart"in this}function sx(n,r,i){var l=n.invertX(r[0][0])-i[0][0],u=n.invertX(r[1][0])-i[1][0],c=n.invertY(r[0][1])-i[0][1],f=n.invertY(r[1][1])-i[1][1];return n.translate(u>l?(l+u)/2:Math.min(0,l)||Math.max(0,u),f>c?(c+f)/2:Math.min(0,c)||Math.max(0,f))}function Ip(){var n=nx,r=rx,i=sx,l=ox,u=ix,c=[0,1/0],f=[[-1/0,-1/0],[1/0,1/0]],h=250,p=Xs,m=al("start","zoom","end"),v,y,g,x=500,S=150,M=0,N=10;function E(k){k.property("__zoom",oh).on("wheel.zoom",Y,{passive:!1}).on("mousedown.zoom",X).on("dblclick.zoom",ee).filter(u).on("touchstart.zoom",q).on("touchmove.zoom",J).on("touchend.zoom touchcancel.zoom",Z).style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}E.transform=function(k,B,I,H){var j=k.selection?k.selection():k;j.property("__zoom",oh),k!==j?U(k,B,I,H):j.interrupt().each(function(){D(this,arguments).event(H).start().zoom(null,typeof B=="function"?B.apply(this,arguments):B).end()})},E.scaleBy=function(k,B,I,H){E.scaleTo(k,function(){var j=this.__zoom.k,$=typeof B=="function"?B.apply(this,arguments):B;return j*$},I,H)},E.scaleTo=function(k,B,I,H){E.transform(k,function(){var j=r.apply(this,arguments),$=this.__zoom,F=I==null?P(j):typeof I=="function"?I.apply(this,arguments):I,C=$.invert(F),R=typeof B=="function"?B.apply(this,arguments):B;return i(_(L($,R),F,C),j,f)},I,H)},E.translateBy=function(k,B,I,H){E.transform(k,function(){return i(this.__zoom.translate(typeof B=="function"?B.apply(this,arguments):B,typeof I=="function"?I.apply(this,arguments):I),r.apply(this,arguments),f)},null,H)},E.translateTo=function(k,B,I,H,j){E.transform(k,function(){var $=r.apply(this,arguments),F=this.__zoom,C=H==null?P($):typeof H=="function"?H.apply(this,arguments):H;return i(hl.translate(C[0],C[1]).scale(F.k).translate(typeof B=="function"?-B.apply(this,arguments):-B,typeof I=="function"?-I.apply(this,arguments):-I),$,f)},H,j)};function L(k,B){return B=Math.max(c[0],Math.min(c[1],B)),B===k.k?k:new mn(B,k.x,k.y)}function _(k,B,I){var H=B[0]-I[0]*k.k,j=B[1]-I[1]*k.k;return H===k.x&&j===k.y?k:new mn(k.k,H,j)}function P(k){return[(+k[0][0]+ +k[1][0])/2,(+k[0][1]+ +k[1][1])/2]}function U(k,B,I,H){k.on("start.zoom",function(){D(this,arguments).event(H).start()}).on("interrupt.zoom end.zoom",function(){D(this,arguments).event(H).end()}).tween("zoom",function(){var j=this,$=arguments,F=D(j,$).event(H),C=r.apply(j,$),R=I==null?P(C):typeof I=="function"?I.apply(j,$):I,te=Math.max(C[1][0]-C[0][0],C[1][1]-C[0][1]),re=j.__zoom,ue=typeof B=="function"?B.apply(j,$):B,ce=p(re.invert(R).concat(te/re.k),ue.invert(R).concat(te/ue.k));return function(ae){if(ae===1)ae=ue;else{var G=ce(ae),se=te/G[2];ae=new mn(se,R[0]-G[0]*se,R[1]-G[1]*se)}F.zoom(null,ae)}})}function D(k,B,I){return!I&&k.__zooming||new V(k,B)}function V(k,B){this.that=k,this.args=B,this.active=0,this.sourceEvent=null,this.extent=r.apply(k,B),this.taps=0}V.prototype={event:function(k){return k&&(this.sourceEvent=k),this},start:function(){return++this.active===1&&(this.that.__zooming=this,this.emit("start")),this},zoom:function(k,B){return this.mouse&&k!=="mouse"&&(this.mouse[1]=B.invert(this.mouse[0])),this.touch0&&k!=="touch"&&(this.touch0[1]=B.invert(this.touch0[0])),this.touch1&&k!=="touch"&&(this.touch1[1]=B.invert(this.touch1[0])),this.that.__zoom=B,this.emit("zoom"),this},end:function(){return--this.active===0&&(delete this.that.__zooming,this.emit("end")),this},emit:function(k){var B=kt(this.that).datum();m.call(k,this.that,new tx(k,{sourceEvent:this.sourceEvent,target:E,transform:this.that.__zoom,dispatch:m}),B)}};function Y(k,...B){if(!n.apply(this,arguments))return;var I=D(this,B).event(k),H=this.__zoom,j=Math.max(c[0],Math.min(c[1],H.k*Math.pow(2,l.apply(this,arguments)))),$=Ht(k);if(I.wheel)(I.mouse[0][0]!==$[0]||I.mouse[0][1]!==$[1])&&(I.mouse[1]=H.invert(I.mouse[0]=$)),clearTimeout(I.wheel);else{if(H.k===j)return;I.mouse=[$,H.invert($)],Ks(this),I.start()}Zo(k),I.wheel=setTimeout(F,S),I.zoom("mouse",i(_(L(H,j),I.mouse[0],I.mouse[1]),I.extent,f));function F(){I.wheel=null,I.end()}}function X(k,...B){if(g||!n.apply(this,arguments))return;var I=k.currentTarget,H=D(this,B,!0).event(k),j=kt(k.view).on("mousemove.zoom",R,!0).on("mouseup.zoom",te,!0),$=Ht(k,I),F=k.clientX,C=k.clientY;dp(k.view),Sa(k),H.mouse=[$,this.__zoom.invert($)],Ks(this),H.start();function R(re){if(Zo(re),!H.moved){var ue=re.clientX-F,ce=re.clientY-C;H.moved=ue*ue+ce*ce>M}H.event(re).zoom("mouse",i(_(H.that.__zoom,H.mouse[0]=Ht(re,I),H.mouse[1]),H.extent,f))}function te(re){j.on("mousemove.zoom mouseup.zoom",null),hp(re.view,H.moved),Zo(re),H.event(re).end()}}function ee(k,...B){if(n.apply(this,arguments)){var I=this.__zoom,H=Ht(k.changedTouches?k.changedTouches[0]:k,this),j=I.invert(H),$=I.k*(k.shiftKey?.5:2),F=i(_(L(I,$),H,j),r.apply(this,B),f);Zo(k),h>0?kt(this).transition().duration(h).call(U,F,H,k):kt(this).call(E.transform,F,H,k)}}function q(k,...B){if(n.apply(this,arguments)){var I=k.touches,H=I.length,j=D(this,B,k.changedTouches.length===H).event(k),$,F,C,R;for(Sa(k),F=0;F`Seems like you have not used ${n==="svelte"?"SvelteFlowProvider":"ReactFlowProvider"} as an ancestor. Help: https://${n}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:n=>`Node type "${n}" 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:n=>`The old edge with id=${n} does not exist.`,error009:n=>`Marker type "${n}" doesn't exist.`,error008:(n,{id:r,sourceHandle:i,targetHandle:l})=>`Couldn't create edge for ${n} handle id: "${n==="source"?i:l}", edge id: ${r}.`,error010:()=>"Handle: No node id found. Make sure to only use a Handle inside a custom Node.",error011:n=>`Edge type "${n}" not found. Using fallback type "default".`,error012:n=>`Node with id "${n}" does not exist, it may have been removed. This can happen when a node is deleted before the "onNodeClick" handler is called.`,error013:(n="react")=>`It seems that you haven't loaded the styles. Please import '@xyflow/${n}/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:n=>`Edge with id "${n}" does not exist, it may have been removed. This can happen when an edge is deleted before the "onEdgeClick" handler is called.`},li=[[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]],zp=["Enter"," ","Escape"],Tp={"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:n,x:r,y:i})=>`Moved selected node ${n}. New position, x: ${r}, y: ${i}`,"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 no;(function(n){n.Strict="strict",n.Loose="loose"})(no||(no={}));var hr;(function(n){n.Free="free",n.Vertical="vertical",n.Horizontal="horizontal"})(hr||(hr={}));var ui;(function(n){n.Partial="partial",n.Full="full"})(ui||(ui={}));const Lp={inProgress:!1,isValid:null,from:null,fromHandle:null,fromPosition:null,fromNode:null,to:null,toHandle:null,toPosition:null,toNode:null,pointer:null};var Un;(function(n){n.Bezier="default",n.Straight="straight",n.Step="step",n.SmoothStep="smoothstep",n.SimpleBezier="simplebezier"})(Un||(Un={}));var ol;(function(n){n.Arrow="arrow",n.ArrowClosed="arrowclosed"})(ol||(ol={}));var we;(function(n){n.Left="left",n.Top="top",n.Right="right",n.Bottom="bottom"})(we||(we={}));const ih={[we.Left]:we.Right,[we.Right]:we.Left,[we.Top]:we.Bottom,[we.Bottom]:we.Top};function Rp(n){return n===null?null:n?"valid":"invalid"}const Ap=n=>!!n&&typeof n=="object"&&"id"in n&&"source"in n&&"target"in n,lx=n=>!!n&&typeof n=="object"&&"id"in n&&"position"in n&&!("source"in n)&&!("target"in n),Za=n=>!!n&&typeof n=="object"&&"id"in n&&"internals"in n&&!("source"in n)&&!("target"in n),gi=(n,r=[0,0])=>{const{width:i,height:l}=Yt(n),u=n.origin??r,c=i*u[0],f=l*u[1];return{x:n.position.x-c,y:n.position.y-f}},ux=(n,r={nodeOrigin:[0,0]})=>{if(n.length===0)return{x:0,y:0,width:0,height:0};let i=!1;const l=n.reduce((u,c)=>{const f=typeof c=="string";let h=!r.nodeLookup&&!f?c:void 0;return r.nodeLookup&&(h=f?r.nodeLookup.get(c):Za(c)?c:r.nodeLookup.get(c.id)),h?(i=!0,pl(u,il(h,r.nodeOrigin))):u},{x:1/0,y:1/0,x2:-1/0,y2:-1/0});return i?gl(l):{x:0,y:0,width:0,height:0}},mi=(n,r={})=>{let i={x:1/0,y:1/0,x2:-1/0,y2:-1/0},l=!1;return n.forEach(u=>{(r.filter===void 0||r.filter(u))&&(i=pl(i,il(u)),l=!0)}),l?gl(i):{x:0,y:0,width:0,height:0}},Ja=(n,r,[i,l,u]=[0,0,1],c=!1,f=!1)=>{const h=(r.x-i)/u,p=(r.y-l)/u,m=r.width/u,v=r.height/u,y=[];for(const g of n.values()){const{measured:x,selectable:S=!0,hidden:M=!1}=g;if(f&&!S||M)continue;const N=x.width??g.width??g.initialWidth??0,E=x.height??g.height??g.initialHeight??0,{x:L,y:_}=g.internals.positionAbsolute,P=Op(h,p,m,v,L,_,N,E),U=N*E,D=c&&P>0;(!g.internals.handleBounds||D||P>=U||g.dragging)&&y.push(g)}return y},ax=(n,r)=>{const i=new Set;return n.forEach(l=>{i.add(l.id)}),r.filter(l=>i.has(l.source)||i.has(l.target))};function cx(n,r){const i=new Map,l=r!=null&&r.nodes?new Set(r.nodes.map(u=>u.id)):null;return n.forEach(u=>{let c;if(r!=null&&r.includeHiddenNodes){const{width:f,height:h}=Yt(u);c=f>0&&h>0}else c=!!(u.measured.width&&u.measured.height&&!u.hidden);c&&(!l||l.has(u.id))&&i.set(u.id,u)}),i}async function fx({nodes:n,width:r,height:i,panZoom:l,minZoom:u,maxZoom:c},f){if(n.size===0)return!0;const h=cx(n,f),p=mi(h),m=tc(p,r,i,(f==null?void 0:f.minZoom)??u,(f==null?void 0:f.maxZoom)??c,(f==null?void 0:f.padding)??.1);return await l.setViewport(m,{duration:f==null?void 0:f.duration,ease:f==null?void 0:f.ease,interpolate:f==null?void 0:f.interpolate}),!0}function jp({nodeId:n,nextPosition:r,nodeLookup:i,nodeOrigin:l=[0,0],nodeExtent:u,onError:c}){const f=i.get(n),h=f.parentId?i.get(f.parentId):void 0,{x:p,y:m}=h?h.internals.positionAbsolute:{x:0,y:0},v=f.origin??l;let y=f.extent||u;if(f.extent==="parent"&&!f.expandParent)if(!h)c==null||c("005",Wt.error005());else{const{width:x,height:S}=Yt(h);x&&S&&(y=[[p,m],[p+x,m+S]])}else h&&yr(f.extent)&&(y=[[f.extent[0][0]+p,f.extent[0][1]+m],[f.extent[1][0]+p,f.extent[1][1]+m]]);const g=yr(y)?mr(r,y,f.measured):r;return(f.measured.width===void 0||f.measured.height===void 0)&&(c==null||c("015",Wt.error015())),{position:{x:g.x-p+(f.measured.width??0)*v[0],y:g.y-m+(f.measured.height??0)*v[1]},positionAbsolute:g}}async function dx({nodesToRemove:n=[],edgesToRemove:r=[],nodes:i,edges:l,onBeforeDelete:u}){const c=new Set(n.map(g=>g.id)),f=[];for(const g of i){if(g.deletable===!1)continue;const x=c.has(g.id),S=!x&&g.parentId&&f.find(M=>M.id===g.parentId);(x||S)&&f.push(g)}const h=new Set(r.map(g=>g.id)),p=l.filter(g=>g.deletable!==!1),v=ax(f,p);for(const g of p)h.has(g.id)&&!v.find(S=>S.id===g.id)&&v.push(g);if(!u)return{edges:v,nodes:f};const y=await u({nodes:f,edges:v});return typeof y=="boolean"?y?{edges:v,nodes:f}:{edges:[],nodes:[]}:y}const ro=(n,r=0,i=1)=>Math.min(Math.max(n,r),i),mr=(n={x:0,y:0},r,i)=>({x:ro(n.x,r[0][0],r[1][0]-((i==null?void 0:i.width)??0)),y:ro(n.y,r[0][1],r[1][1]-((i==null?void 0:i.height)??0))});function $p(n,r,i){const{width:l,height:u}=Yt(i),{x:c,y:f}=i.internals.positionAbsolute;return mr(n,[[c,f],[c+l,f+u]],r)}const sh=(n,r,i)=>ni?-ro(Math.abs(n-i),1,r)/r:0,ec=(n,r,i=15,l=40)=>{const u=sh(n.x,l,r.width-l)*i,c=sh(n.y,l,r.height-l)*i;return[u,c]},pl=(n,r)=>({x:Math.min(n.x,r.x),y:Math.min(n.y,r.y),x2:Math.max(n.x2,r.x2),y2:Math.max(n.y2,r.y2)}),Fa=({x:n,y:r,width:i,height:l})=>({x:n,y:r,x2:n+i,y2:r+l}),gl=({x:n,y:r,x2:i,y2:l})=>({x:n,y:r,width:i-n,height:l-r}),ai=(n,r=[0,0])=>{var u,c;const{x:i,y:l}=Za(n)?n.internals.positionAbsolute:gi(n,r);return{x:i,y:l,width:((u=n.measured)==null?void 0:u.width)??n.width??n.initialWidth??0,height:((c=n.measured)==null?void 0:c.height)??n.height??n.initialHeight??0}},il=(n,r=[0,0])=>{var u,c;const{x:i,y:l}=Za(n)?n.internals.positionAbsolute:gi(n,r);return{x:i,y:l,x2:i+(((u=n.measured)==null?void 0:u.width)??n.width??n.initialWidth??0),y2:l+(((c=n.measured)==null?void 0:c.height)??n.height??n.initialHeight??0)}},Dp=(n,r)=>gl(pl(Fa(n),Fa(r))),Op=(n,r,i,l,u,c,f,h)=>{const p=Math.max(0,Math.min(n+i,u+f)-Math.max(n,u)),m=Math.max(0,Math.min(r+l,c+h)-Math.max(r,c));return Math.ceil(p*m)},sl=(n,r)=>Op(n.x,n.y,n.width,n.height,r.x,r.y,r.width,r.height),lh=n=>Bt(n.width)&&Bt(n.height)&&Bt(n.x)&&Bt(n.y),Bt=n=>!isNaN(n)&&isFinite(n),Fp=(n,r)=>(i,l)=>{},yi=(n,r=[1,1])=>({x:r[0]*Math.round(n.x/r[0]),y:r[1]*Math.round(n.y/r[1])}),vi=({x:n,y:r},[i,l,u],c=!1,f=[1,1])=>{const h={x:(n-i)/u,y:(r-l)/u};return c?yi(h,f):h},oo=({x:n,y:r},[i,l,u])=>({x:n*u+i,y:r*u+l});function Kr(n,r){if(typeof n=="number")return Math.floor((r-r/(1+n))*.5);if(typeof n=="string"&&n.endsWith("px")){const i=parseFloat(n);if(!Number.isNaN(i))return Math.floor(i)}if(typeof n=="string"&&n.endsWith("%")){const i=parseFloat(n);if(!Number.isNaN(i))return Math.floor(r*i*.01)}return console.error(`The padding value "${n}" is invalid. Please provide a number or a string with a valid unit (px or %).`),0}function hx(n,r,i){if(typeof n=="string"||typeof n=="number"){const l=Kr(n,i),u=Kr(n,r);return{top:l,right:u,bottom:l,left:u,x:u*2,y:l*2}}if(typeof n=="object"){const l=Kr(n.top??n.y??0,i),u=Kr(n.bottom??n.y??0,i),c=Kr(n.left??n.x??0,r),f=Kr(n.right??n.x??0,r);return{top:l,right:f,bottom:u,left:c,x:c+f,y:l+u}}return{top:0,right:0,bottom:0,left:0,x:0,y:0}}function px(n,r,i,l,u,c){const{x:f,y:h}=oo(n,[r,i,l]),{x:p,y:m}=oo({x:n.x+n.width,y:n.y+n.height},[r,i,l]),v=u-p,y=c-m;return{left:Math.floor(f),top:Math.floor(h),right:Math.floor(v),bottom:Math.floor(y)}}const tc=(n,r,i,l,u,c)=>{const f=hx(c,r,i),h=(r-f.x)/n.width,p=(i-f.y)/n.height,m=Math.min(h,p),v=ro(m,l,u),y=n.x+n.width/2,g=n.y+n.height/2,x=r/2-y*v,S=i/2-g*v,M=px(n,x,S,v,r,i),N={left:Math.min(M.left-f.left,0),top:Math.min(M.top-f.top,0),right:Math.min(M.right-f.right,0),bottom:Math.min(M.bottom-f.bottom,0)};return{x:x-N.left+N.right,y:S-N.top+N.bottom,zoom:v}},ci=()=>{var n;return typeof navigator<"u"&&((n=navigator==null?void 0:navigator.userAgent)==null?void 0:n.indexOf("Mac"))>=0};function yr(n){return n!=null&&n!=="parent"}function Yt(n){var r,i;return{width:((r=n.measured)==null?void 0:r.width)??n.width??n.initialWidth??0,height:((i=n.measured)==null?void 0:i.height)??n.height??n.initialHeight??0}}function Hp(n){var r,i;return(((r=n.measured)==null?void 0:r.width)??n.width??n.initialWidth)!==void 0&&(((i=n.measured)==null?void 0:i.height)??n.height??n.initialHeight)!==void 0}function Vp(n,r={width:0,height:0},i,l,u){const c={...n},f=l.get(i);if(f){const h=f.origin||u;c.x+=f.internals.positionAbsolute.x-(r.width??0)*h[0],c.y+=f.internals.positionAbsolute.y-(r.height??0)*h[1]}return c}function uh(n,r){if(n.size!==r.size)return!1;for(const i of n)if(!r.has(i))return!1;return!0}function gx(){let n,r;return{promise:new Promise((l,u)=>{n=l,r=u}),resolve:n,reject:r}}function mx(n){return{...Tp,...n||{}}}function ni(n,{snapGrid:r=[0,0],snapToGrid:i=!1,transform:l,containerBounds:u}){const{x:c,y:f}=Ut(n),h=vi({x:c-((u==null?void 0:u.left)??0),y:f-((u==null?void 0:u.top)??0)},l),{x:p,y:m}=i?yi(h,r):h;return{xSnapped:p,ySnapped:m,...h}}const nc=n=>({width:n.offsetWidth,height:n.offsetHeight}),Bp=n=>{var r;return((r=n==null?void 0:n.getRootNode)==null?void 0:r.call(n))||(window==null?void 0:window.document)},yx=["INPUT","SELECT","TEXTAREA"];function Up(n){var l,u;const r=((u=(l=n.composedPath)==null?void 0:l.call(n))==null?void 0:u[0])||n.target;return(r==null?void 0:r.nodeType)!==1?!1:yx.includes(r.nodeName)||r.hasAttribute("contenteditable")||!!r.closest(".nokey")}const Wp=n=>"clientX"in n,Ut=(n,r)=>{var c,f;const i=Wp(n),l=i?n.clientX:(c=n.touches)==null?void 0:c[0].clientX,u=i?n.clientY:(f=n.touches)==null?void 0:f[0].clientY;return{x:l-((r==null?void 0:r.left)??0),y:u-((r==null?void 0:r.top)??0)}},ah=(n,r,i,l,u)=>{const c=r.querySelectorAll(`.${n}`);return!c||!c.length?null:Array.from(c).map(f=>{const h=f.getBoundingClientRect();return{id:f.getAttribute("data-handleid"),type:n,nodeId:u,position:f.getAttribute("data-handlepos"),x:(h.left-i.left)/l,y:(h.top-i.top)/l,...nc(f)}})};function bp({sourceX:n,sourceY:r,targetX:i,targetY:l,sourceControlX:u,sourceControlY:c,targetControlX:f,targetControlY:h}){const p=n*.125+u*.375+f*.375+i*.125,m=r*.125+c*.375+h*.375+l*.125,v=Math.abs(p-n),y=Math.abs(m-r);return[p,m,v,y]}function Bs(n,r){return n>=0?.5*n:r*25*Math.sqrt(-n)}function ch({pos:n,x1:r,y1:i,x2:l,y2:u,c}){switch(n){case we.Left:return[r-Bs(r-l,c),i];case we.Right:return[r+Bs(l-r,c),i];case we.Top:return[r,i-Bs(i-u,c)];case we.Bottom:return[r,i+Bs(u-i,c)]}}function Yp({sourceX:n,sourceY:r,sourcePosition:i=we.Bottom,targetX:l,targetY:u,targetPosition:c=we.Top,curvature:f=.25}){const[h,p]=ch({pos:i,x1:n,y1:r,x2:l,y2:u,c:f}),[m,v]=ch({pos:c,x1:l,y1:u,x2:n,y2:r,c:f}),[y,g,x,S]=bp({sourceX:n,sourceY:r,targetX:l,targetY:u,sourceControlX:h,sourceControlY:p,targetControlX:m,targetControlY:v});return[`M${n},${r} C${h},${p} ${m},${v} ${l},${u}`,y,g,x,S]}function Xp({sourceX:n,sourceY:r,targetX:i,targetY:l}){const u=Math.abs(i-n)/2,c=i0}const xx=({source:n,sourceHandle:r,target:i,targetHandle:l})=>`xy-edge__${n}${r||""}-${i}${l||""}`,Sx=(n,r)=>r.some(i=>i.source===n.source&&i.target===n.target&&(i.sourceHandle===n.sourceHandle||!i.sourceHandle&&!n.sourceHandle)&&(i.targetHandle===n.targetHandle||!i.targetHandle&&!n.targetHandle)),_x=(n,r,i={})=>{var c;if(!n.source||!n.target)return(c=i.onError)==null||c.call(i,"006",Wt.error006()),r;const l=i.getEdgeId||xx;let u;return Ap(n)?u={...n}:u={...n,id:l(n)},Sx(u,r)?r:(u.sourceHandle===null&&delete u.sourceHandle,u.targetHandle===null&&delete u.targetHandle,r.concat(u))};function Qp({sourceX:n,sourceY:r,targetX:i,targetY:l}){const[u,c,f,h]=Xp({sourceX:n,sourceY:r,targetX:i,targetY:l});return[`M ${n},${r}L ${i},${l}`,u,c,f,h]}const fh={[we.Left]:{x:-1,y:0},[we.Right]:{x:1,y:0},[we.Top]:{x:0,y:-1},[we.Bottom]:{x:0,y:1}},Ex=({source:n,sourcePosition:r=we.Bottom,target:i})=>r===we.Left||r===we.Right?n.xMath.sqrt(Math.pow(r.x-n.x,2)+Math.pow(r.y-n.y,2));function kx({source:n,sourcePosition:r=we.Bottom,target:i,targetPosition:l=we.Top,center:u,offset:c,stepPosition:f}){const h=fh[r],p=fh[l],m={x:n.x+h.x*c,y:n.y+h.y*c},v={x:i.x+p.x*c,y:i.y+p.y*c},y=Ex({source:m,sourcePosition:r,target:v}),g=y.x!==0?"x":"y",x=y[g];let S=[],M,N;const E={x:0,y:0},L={x:0,y:0},[,,_,P]=Xp({sourceX:n.x,sourceY:n.y,targetX:i.x,targetY:i.y});if(h[g]*p[g]===-1){g==="x"?(M=u.x??m.x+(v.x-m.x)*f,N=u.y??(m.y+v.y)/2):(M=u.x??(m.x+v.x)/2,N=u.y??m.y+(v.y-m.y)*f);const Y=[{x:M,y:m.y},{x:M,y:v.y}],X=[{x:m.x,y:N},{x:v.x,y:N}];h[g]===x?S=g==="x"?Y:X:S=g==="x"?X:Y}else{const Y=[{x:m.x,y:v.y}],X=[{x:v.x,y:m.y}];if(g==="x"?S=h.x===x?X:Y:S=h.y===x?Y:X,r===l){const k=Math.abs(n[g]-i[g]);if(k<=c){const B=Math.min(c-1,c-k);h[g]===x?E[g]=(m[g]>n[g]?-1:1)*B:L[g]=(v[g]>i[g]?-1:1)*B}}if(r!==l){const k=g==="x"?"y":"x",B=h[g]===p[k],I=m[k]>v[k],H=m[k]=Z?(M=(ee.x+q.x)/2,N=S[0].y):(M=S[0].x,N=(ee.y+q.y)/2)}const U={x:m.x+E.x,y:m.y+E.y},D={x:v.x+L.x,y:v.y+L.y};return[[n,...U.x!==S[0].x||U.y!==S[0].y?[U]:[],...S,...D.x!==S[S.length-1].x||D.y!==S[S.length-1].y?[D]:[],i],M,N,_,P]}function Nx(n,r,i,l){const u=Math.min(dh(n,r)/2,dh(r,i)/2,l),{x:c,y:f}=r;if(n.x===c&&c===i.x||n.y===f&&f===i.y)return`L${c} ${f}`;if(n.y===f){const m=n.xi.id===r):n[0])||null}function Va(n,r){return n?typeof n=="string"?n:`${r?`${r}__`:""}${Object.keys(n).sort().map(l=>`${l}=${n[l]}`).join("&")}`:""}function Mx(n,{id:r,defaultColor:i,defaultMarkerStart:l,defaultMarkerEnd:u}){const c=new Set;return n.reduce((f,h)=>([h.markerStart||l,h.markerEnd||u].forEach(p=>{if(p&&typeof p=="object"){const m=Va(p,r);c.has(m)||(f.push({id:m,color:p.color||i,...p}),c.add(m))}}),f),[]).sort((f,h)=>f.id.localeCompare(h.id))}const Gp=1e3,Px=10,rc={nodeOrigin:[0,0],nodeExtent:li,elevateNodesOnSelect:!0,zIndexMode:"basic",defaults:{}},Ix={...rc,checkEquality:!0};function oc(n,r){const i={...n};for(const l in r)r[l]!==void 0&&(i[l]=r[l]);return i}function zx(n,r,i){const l=oc(rc,i);for(const u of n.values())if(u.parentId)sc(u,n,r,l);else{const c=gi(u,l.nodeOrigin),f=yr(u.extent)?u.extent:l.nodeExtent,h=mr(c,f,Yt(u));u.internals.positionAbsolute=h}}function Tx(n,r){if(!n.handles)return n.measured?r==null?void 0:r.internals.handleBounds:void 0;const i=[],l=[];for(const u of n.handles){const c={id:u.id,width:u.width??1,height:u.height??1,nodeId:n.id,x:u.x,y:u.y,position:u.position,type:u.type};u.type==="source"?i.push(c):u.type==="target"&&l.push(c)}return{source:i,target:l}}function ic(n){return n==="manual"}function Ba(n,r,i,l={}){var v,y;const u=oc(Ix,l),c={i:0},f=new Map(r),h=u!=null&&u.elevateNodesOnSelect&&!ic(u.zIndexMode)?Gp:0;let p=n.length>0,m=!1;r.clear(),i.clear();for(const g of n){let x=f.get(g.id);if(u.checkEquality&&g===(x==null?void 0:x.internals.userNode))r.set(g.id,x);else{const S=gi(g,u.nodeOrigin),M=yr(g.extent)?g.extent:u.nodeExtent,N=mr(S,M,Yt(g));x={...u.defaults,...g,measured:{width:(v=g.measured)==null?void 0:v.width,height:(y=g.measured)==null?void 0:y.height},internals:{positionAbsolute:N,handleBounds:Tx(g,x),z:Kp(g,h,u.zIndexMode),userNode:g}},r.set(g.id,x)}(x.measured===void 0||x.measured.width===void 0||x.measured.height===void 0)&&!x.hidden&&(p=!1),g.parentId&&sc(x,r,i,l,c),m||(m=g.selected??!1)}return{nodesInitialized:p,hasSelectedNodes:m}}function Lx(n,r){if(!n.parentId)return;const i=r.get(n.parentId);i?i.set(n.id,n):r.set(n.parentId,new Map([[n.id,n]]))}function sc(n,r,i,l,u){const{elevateNodesOnSelect:c,nodeOrigin:f,nodeExtent:h,zIndexMode:p}=oc(rc,l),m=n.parentId,v=r.get(m);if(!v){console.warn(`Parent node ${m} not found. Please make sure that parent nodes are in front of their child nodes in the nodes array.`);return}Lx(n,i),u&&!v.parentId&&v.internals.rootParentIndex===void 0&&p==="auto"&&(v.internals.rootParentIndex=++u.i,v.internals.z=v.internals.z+u.i*Px),u&&v.internals.rootParentIndex!==void 0&&(u.i=v.internals.rootParentIndex);const y=c&&!ic(p)?Gp:0,{x:g,y:x,z:S}=Rx(n,v,f,h,y,p),{positionAbsolute:M}=n.internals,N=g!==M.x||x!==M.y;(N||S!==n.internals.z)&&r.set(n.id,{...n,internals:{...n.internals,positionAbsolute:N?{x:g,y:x}:M,z:S}})}function Kp(n,r,i){const l=Bt(n.zIndex)?n.zIndex:0;return ic(i)?l:l+(n.selected?r:0)}function Rx(n,r,i,l,u,c){const{x:f,y:h}=r.internals.positionAbsolute,p=Yt(n),m=gi(n,i),v=yr(n.extent)?mr(m,n.extent,p):m;let y=mr({x:f+v.x,y:h+v.y},l,p);n.extent==="parent"&&(y=$p(y,p,r));const g=Kp(n,u,c),x=r.internals.z??0;return{x:y.x,y:y.y,z:x>=g?x+1:g}}function lc(n,r,i,l=[0,0]){var f;const u=[],c=new Map;for(const h of n){const p=r.get(h.parentId);if(!p)continue;const m=((f=c.get(h.parentId))==null?void 0:f.expandedRect)??ai(p),v=Dp(m,h.rect);c.set(h.parentId,{expandedRect:v,parent:p})}return c.size>0&&c.forEach(({expandedRect:h,parent:p},m)=>{var _;const v=p.internals.positionAbsolute,y=Yt(p),g=p.origin??l,x=h.x0||S>0||E||L)&&(u.push({id:m,type:"position",position:{x:p.position.x-x+E,y:p.position.y-S+L}}),(_=i.get(m))==null||_.forEach(P=>{n.some(U=>U.id===P.id)||u.push({id:P.id,type:"position",position:{x:P.position.x+x,y:P.position.y+S}})})),(y.width0){const x=lc(g,r,i,u);m.push(...x)}return{changes:m,updatedInternals:p}}async function jx({delta:n,panZoom:r,transform:i,translateExtent:l,width:u,height:c}){if(!r||!n.x&&!n.y)return!1;const f=await r.setViewportConstrained({x:i[0]+n.x,y:i[1]+n.y,zoom:i[2]},[[0,0],[u,c]],l);return!!f&&(f.x!==i[0]||f.y!==i[1]||f.k!==i[2])}function mh(n,r,i,l,u,c){let f=u;const h=l.get(f)||new Map;l.set(f,h.set(i,r)),f=`${u}-${n}`;const p=l.get(f)||new Map;if(l.set(f,p.set(i,r)),c){f=`${u}-${n}-${c}`;const m=l.get(f)||new Map;l.set(f,m.set(i,r))}}function qp(n,r,i){n.clear(),r.clear();for(const l of i){const{source:u,target:c,sourceHandle:f=null,targetHandle:h=null}=l,p={edgeId:l.id,source:u,target:c,sourceHandle:f,targetHandle:h},m=`${u}-${f}--${c}-${h}`,v=`${c}-${h}--${u}-${f}`;mh("source",p,v,n,u,f),mh("target",p,m,n,c,h),r.set(l.id,l)}}function Zp(n,r){if(!n.parentId)return!1;const i=r.get(n.parentId);return i?i.selected?!0:Zp(i,r):!1}function yh(n,r,i){var u;let l=n;do{if((u=l==null?void 0:l.matches)!=null&&u.call(l,r))return!0;if(l===i)return!1;l=l==null?void 0:l.parentElement}while(l);return!1}function $x(n,r,i,l){const u=new Map;for(const[c,f]of n)if((f.selected||f.id===l)&&(!f.parentId||!Zp(f,n))&&(f.draggable||r&&typeof f.draggable>"u")){const h=n.get(c);h&&u.set(c,{id:c,position:h.position||{x:0,y:0},distance:{x:i.x-h.internals.positionAbsolute.x,y:i.y-h.internals.positionAbsolute.y},extent:h.extent,parentId:h.parentId,origin:h.origin,expandParent:h.expandParent,internals:{positionAbsolute:h.internals.positionAbsolute||{x:0,y:0}},measured:{width:h.measured.width??0,height:h.measured.height??0}})}return u}function _a({nodeId:n,dragItems:r,nodeLookup:i,dragging:l=!0}){var f,h,p;const u=[];for(const[m,v]of r){const y=(f=i.get(m))==null?void 0:f.internals.userNode;y&&u.push({...y,position:v.position,dragging:l})}if(!n)return[u[0],u];const c=(h=i.get(n))==null?void 0:h.internals.userNode;return[c?{...c,position:((p=r.get(n))==null?void 0:p.position)||c.position,dragging:l}:u[0],u]}function Dx({dragItems:n,snapGrid:r,x:i,y:l}){const u=n.values().next().value;if(!u)return null;const c={x:i-u.distance.x,y:l-u.distance.y},f=yi(c,r);return{x:f.x-c.x,y:f.y-c.y}}function Ox({onNodeMouseDown:n,getStoreItems:r,onDragStart:i,onDrag:l,onDragStop:u}){let c={x:null,y:null},f=0,h=new Map,p=!1,m={x:0,y:0},v=null,y=!1,g=null,x=!1,S=!1,M=null;function N({noDragClassName:L,handleSelector:_,domNode:P,isSelectable:U,nodeId:D,nodeClickDistance:V=0}){g=kt(P);function Y({x:J,y:Z}){const{nodeLookup:k,nodeExtent:B,snapGrid:I,snapToGrid:H,nodeOrigin:j,onNodeDrag:$,onSelectionDrag:F,onError:C,updateNodePositions:R}=r();c={x:J,y:Z};let te=!1;const re=h.size>1,ue=re&&B?Fa(mi(h)):null,ce=re&&H?Dx({dragItems:h,snapGrid:I,x:J,y:Z}):null;for(const[ae,G]of h){if(!k.has(ae))continue;let se={x:J-G.distance.x,y:Z-G.distance.y};H&&(se=ce?{x:Math.round(se.x+ce.x),y:Math.round(se.y+ce.y)}:yi(se,I));let pe=null;if(re&&B&&!G.extent&&ue){const{positionAbsolute:me}=G.internals,ke=me.x-ue.x+B[0][0],Ce=me.x+G.measured.width-ue.x2+B[1][0],Me=me.y-ue.y+B[0][1],Le=me.y+G.measured.height-ue.y2+B[1][1];pe=[[ke,Me],[Ce,Le]]}const{position:xe,positionAbsolute:ve}=jp({nodeId:ae,nextPosition:se,nodeLookup:k,nodeExtent:pe||B,nodeOrigin:j,onError:C});te=te||G.position.x!==xe.x||G.position.y!==xe.y,G.position=xe,G.internals.positionAbsolute=ve}if(S=S||te,!!te&&(R(h,!0),M&&(l||$||!D&&F))){const[ae,G]=_a({nodeId:D,dragItems:h,nodeLookup:k});l==null||l(M,h,ae,G),$==null||$(M,ae,G),D||F==null||F(M,G)}}async function X(){if(!v)return;const{transform:J,panBy:Z,autoPanSpeed:k,autoPanOnNodeDrag:B}=r();if(!B){p=!1,cancelAnimationFrame(f);return}const[I,H]=ec(m,v,k);(I!==0||H!==0)&&(c.x=(c.x??0)-I/J[2],c.y=(c.y??0)-H/J[2],await Z({x:I,y:H})&&Y(c)),f=requestAnimationFrame(X)}function ee(J){var re;const{nodeLookup:Z,multiSelectionActive:k,nodesDraggable:B,transform:I,snapGrid:H,snapToGrid:j,selectNodesOnDrag:$,onNodeDragStart:F,onSelectionDragStart:C,unselectNodesAndEdges:R}=r();y=!0,(!$||!U)&&!k&&D&&((re=Z.get(D))!=null&&re.selected||R()),U&&$&&D&&(n==null||n(D));const te=ni(J.sourceEvent,{transform:I,snapGrid:H,snapToGrid:j,containerBounds:v});if(c=te,h=$x(Z,B,te,D),h.size>0&&(i||F||!D&&C)){const[ue,ce]=_a({nodeId:D,dragItems:h,nodeLookup:Z});i==null||i(J.sourceEvent,h,ue,ce),F==null||F(J.sourceEvent,ue,ce),D||C==null||C(J.sourceEvent,ce)}}const q=pp().clickDistance(V).on("start",J=>{const{domNode:Z,nodeDragThreshold:k,transform:B,snapGrid:I,snapToGrid:H}=r();v=(Z==null?void 0:Z.getBoundingClientRect())||null,x=!1,S=!1,M=J.sourceEvent,k===0&&ee(J),c=ni(J.sourceEvent,{transform:B,snapGrid:I,snapToGrid:H,containerBounds:v}),m=Ut(J.sourceEvent,v)}).on("drag",J=>{const{autoPanOnNodeDrag:Z,transform:k,snapGrid:B,snapToGrid:I,nodeDragThreshold:H,nodeLookup:j}=r(),$=ni(J.sourceEvent,{transform:k,snapGrid:B,snapToGrid:I,containerBounds:v});if(M=J.sourceEvent,(J.sourceEvent.type==="touchmove"&&J.sourceEvent.touches.length>1||D&&!j.has(D))&&(x=!0),!x){if(!p&&Z&&y&&(p=!0,X()),!y){const F=Ut(J.sourceEvent,v),C=F.x-m.x,R=F.y-m.y;Math.sqrt(C*C+R*R)>H&&ee(J)}(c.x!==$.xSnapped||c.y!==$.ySnapped)&&h&&y&&(m=Ut(J.sourceEvent,v),Y($))}}).on("end",J=>{if(!y||x){x&&h.size>0&&r().updateNodePositions(h,!1);return}if(p=!1,y=!1,cancelAnimationFrame(f),h.size>0){const{nodeLookup:Z,updateNodePositions:k,onNodeDragStop:B,onSelectionDragStop:I}=r();if(S&&(k(h,!1),S=!1),u||B||!D&&I){const[H,j]=_a({nodeId:D,dragItems:h,nodeLookup:Z,dragging:!1});u==null||u(J.sourceEvent,h,H,j),B==null||B(J.sourceEvent,H,j),D||I==null||I(J.sourceEvent,j)}}}).filter(J=>{const Z=J.target;return!J.button&&(!L||!yh(Z,`.${L}`,P))&&(!_||yh(Z,_,P))});g.call(q)}function E(){g==null||g.on(".drag",null)}return{update:N,destroy:E}}function Fx(n,r,i){const l=[],u={x:n.x-i,y:n.y-i,width:i*2,height:i*2};for(const c of r.values())sl(u,ai(c))>0&&l.push(c);return l}const Hx=250;function Vx(n,r,i,l){var h,p;let u=[],c=1/0;const f=Fx(n,i,r+Hx);for(const m of f){const v=[...((h=m.internals.handleBounds)==null?void 0:h.source)??[],...((p=m.internals.handleBounds)==null?void 0:p.target)??[]];for(const y of v){if(l.nodeId===y.nodeId&&l.type===y.type&&l.id===y.id)continue;const{x:g,y:x}=vr(m,y,y.position,!0),S=Math.sqrt(Math.pow(g-n.x,2)+Math.pow(x-n.y,2));S>r||(S1){const m=l.type==="source"?"target":"source";return u.find(v=>v.type===m)??u[0]}return u[0]}function Jp(n,r,i,l,u,c=!1){var m,v,y;const f=l.get(n);if(!f)return null;const h=u==="strict"?(m=f.internals.handleBounds)==null?void 0:m[r]:[...((v=f.internals.handleBounds)==null?void 0:v.source)??[],...((y=f.internals.handleBounds)==null?void 0:y.target)??[]],p=(i?h==null?void 0:h.find(g=>g.id===i):h==null?void 0:h[0])??null;return p&&c?{...p,...vr(f,p,p.position,!0)}:p}function eg(n,r){return n||(r!=null&&r.classList.contains("target")?"target":r!=null&&r.classList.contains("source")?"source":null)}function Bx(n,r){let i=null;return r?i=!0:n&&!r&&(i=!1),i}const tg=()=>!0;function Ux(n,{connectionMode:r,connectionRadius:i,handleId:l,nodeId:u,edgeUpdaterType:c,isTarget:f,domNode:h,nodeLookup:p,lib:m,autoPanOnConnect:v,flowId:y,panBy:g,cancelConnection:x,onConnectStart:S,onConnect:M,onConnectEnd:N,isValidConnection:E=tg,onReconnectEnd:L,updateConnection:_,getTransform:P,getFromHandle:U,autoPanSpeed:D,dragThreshold:V=1,handleDomNode:Y}){const X=Bp(n.target);let ee=0,q;const{x:J,y:Z}=Ut(n),k=eg(c,Y),B=h==null?void 0:h.getBoundingClientRect();let I=!1;if(!B||!k)return;const H=Jp(u,k,l,p,r);if(!H)return;let j=Ut(n,B),$=!1,F=null,C=!1,R=null;function te(){if(!v||!B)return;const[xe,ve]=ec(j,B,D);g({x:xe,y:ve}),ee=requestAnimationFrame(te)}const re={...H,nodeId:u,type:k,position:H.position},ue=p.get(u);let ae={inProgress:!0,isValid:null,from:vr(ue,re,we.Left,!0),fromHandle:re,fromPosition:re.position,fromNode:ue,to:j,toHandle:null,toPosition:ih[re.position],toNode:null,pointer:j};function G(){I=!0,_(ae),S==null||S(n,{nodeId:u,handleId:l,handleType:k})}V===0&&G();function se(xe){if(!I){const{x:Le,y:it}=Ut(xe),ut=Le-J,Je=it-Z;if(!(ut*ut+Je*Je>V*V))return;G()}if(!U()||!re){pe(xe);return}const ve=P();j=Ut(xe,B),q=Vx(vi(j,ve,!1,[1,1]),i,p,re),$||(te(),$=!0);const me=ng(xe,{handle:q,connectionMode:r,fromNodeId:u,fromHandleId:l,fromType:f?"target":"source",isValidConnection:E,doc:X,lib:m,flowId:y,nodeLookup:p});R=me.handleDomNode,F=me.connection,C=Bx(!!q,me.isValid);const ke=p.get(u),Ce=ke?vr(ke,re,we.Left,!0):ae.from,Me={...ae,from:Ce,isValid:C,to:me.toHandle&&C?oo({x:me.toHandle.x,y:me.toHandle.y},ve):j,toHandle:me.toHandle,toPosition:C&&me.toHandle?me.toHandle.position:ih[re.position],toNode:me.toHandle?p.get(me.toHandle.nodeId):null,pointer:j};_(Me),ae=Me}function pe(xe){if(!("touches"in xe&&xe.touches.length>0)){if(I){(q||R)&&F&&C&&(M==null||M(F));const{inProgress:ve,...me}=ae,ke={...me,toPosition:ae.toHandle?ae.toPosition:null};N==null||N(xe,ke),c&&(L==null||L(xe,ke))}x(),cancelAnimationFrame(ee),$=!1,C=!1,F=null,R=null,X.removeEventListener("mousemove",se),X.removeEventListener("mouseup",pe),X.removeEventListener("touchmove",se),X.removeEventListener("touchend",pe)}}X.addEventListener("mousemove",se),X.addEventListener("mouseup",pe),X.addEventListener("touchmove",se),X.addEventListener("touchend",pe)}function ng(n,{handle:r,connectionMode:i,fromNodeId:l,fromHandleId:u,fromType:c,doc:f,lib:h,flowId:p,isValidConnection:m=tg,nodeLookup:v}){const y=c==="target",g=r?f.querySelector(`.${h}-flow__handle[data-id="${p}-${r==null?void 0:r.nodeId}-${r==null?void 0:r.id}-${r==null?void 0:r.type}"]`):null,{x,y:S}=Ut(n),M=f.elementFromPoint(x,S),N=M!=null&&M.classList.contains(`${h}-flow__handle`)?M:g,E={handleDomNode:N,isValid:!1,connection:null,toHandle:null};if(N){const L=eg(void 0,N),_=N.getAttribute("data-nodeid"),P=N.getAttribute("data-handleid"),U=N.classList.contains("connectable"),D=N.classList.contains("connectableend");if(!_||!L)return E;const V={source:y?_:l,sourceHandle:y?P:u,target:y?l:_,targetHandle:y?u:P};E.connection=V;const X=U&&D&&(i===no.Strict?y&&L==="source"||!y&&L==="target":_!==l||P!==u);E.isValid=X&&m(V),E.toHandle=Jp(_,L,P,v,i,!0)}return E}const Ua={onPointerDown:Ux,isValid:ng};function Wx({domNode:n,panZoom:r,getTransform:i,getViewScale:l}){const u=kt(n);function c({translateExtent:h,width:p,height:m,zoomStep:v=1,pannable:y=!0,zoomable:g=!0,inversePan:x=!1}){const S=_=>{if(_.sourceEvent.type!=="wheel"||!r)return;const P=i(),U=_.sourceEvent.ctrlKey&&ci()?10:1,D=-_.sourceEvent.deltaY*(_.sourceEvent.deltaMode===1?.05:_.sourceEvent.deltaMode?1:.002)*v,V=P[2]*Math.pow(2,D*U);r.scaleTo(V)};let M=[0,0];const N=_=>{(_.sourceEvent.type==="mousedown"||_.sourceEvent.type==="touchstart")&&(M=[_.sourceEvent.clientX??_.sourceEvent.touches[0].clientX,_.sourceEvent.clientY??_.sourceEvent.touches[0].clientY])},E=_=>{const P=i();if(_.sourceEvent.type!=="mousemove"&&_.sourceEvent.type!=="touchmove"||!r)return;const U=[_.sourceEvent.clientX??_.sourceEvent.touches[0].clientX,_.sourceEvent.clientY??_.sourceEvent.touches[0].clientY],D=[U[0]-M[0],U[1]-M[1]];M=U;const V=l()*Math.max(P[2],Math.log(P[2]))*(x?-1:1),Y={x:P[0]-D[0]*V,y:P[1]-D[1]*V},X=[[0,0],[p,m]];r.setViewportConstrained({x:Y.x,y:Y.y,zoom:P[2]},X,h)},L=Ip().on("start",N).on("zoom",y?E:null).on("zoom.wheel",g?S:null);u.call(L,{})}function f(){u.on("zoom",null)}return{update:c,destroy:f,pointer:Ht}}const ml=n=>({x:n.x,y:n.y,zoom:n.k}),Ea=({x:n,y:r,zoom:i})=>hl.translate(n,r).scale(i),Bn=(n,r)=>n.target.closest(`.${r}`),rg=(n,r)=>r===2&&Array.isArray(n)&&n.includes(2),bx=n=>((n*=2)<=1?n*n*n:(n-=2)*n*n+2)/2,ka=(n,r=0,i=bx,l=()=>{})=>{const u=typeof r=="number"&&r>0;return u||l(),u?n.transition().duration(r).ease(i).on("end",l):n},og=n=>{const r=n.ctrlKey&&ci()?10:1;return-n.deltaY*(n.deltaMode===1?.05:n.deltaMode?1:.002)*r};function Yx({zoomPanValues:n,noWheelClassName:r,d3Selection:i,d3Zoom:l,panOnScrollMode:u,panOnScrollSpeed:c,zoomOnPinch:f,onPanZoomStart:h,onPanZoom:p,onPanZoomEnd:m}){return v=>{if(Bn(v,r))return v.ctrlKey&&v.preventDefault(),!1;v.preventDefault(),v.stopImmediatePropagation();const y=i.property("__zoom").k||1;if(v.ctrlKey&&f){const N=Ht(v),E=og(v),L=y*Math.pow(2,E);l.scaleTo(i,L,N,v);return}const g=v.deltaMode===1?20:1;let x=u===hr.Vertical?0:v.deltaX*g,S=u===hr.Horizontal?0:v.deltaY*g;!ci()&&v.shiftKey&&u!==hr.Vertical&&(x=v.deltaY*g,S=0),l.translateBy(i,-(x/y)*c,-(S/y)*c,{internal:!0});const M=ml(i.property("__zoom"));clearTimeout(n.panScrollTimeout),n.isPanScrolling?p==null||p(v,M):(n.isPanScrolling=!0,h==null||h(v,M)),n.panScrollTimeout=setTimeout(()=>{m==null||m(v,M),n.isPanScrolling=!1},150)}}function Xx({noWheelClassName:n,preventScrolling:r,d3ZoomHandler:i}){return function(l,u){const c=l.type==="wheel",f=!r&&c&&!l.ctrlKey,h=Bn(l,n);if(l.ctrlKey&&c&&h&&l.preventDefault(),f||h)return null;l.preventDefault(),i.call(this,l,u)}}function Qx({zoomPanValues:n,onDraggingChange:r,onPanZoomStart:i}){return l=>{var c,f,h;if((c=l.sourceEvent)!=null&&c.internal)return;const u=ml(l.transform);n.mouseButton=((f=l.sourceEvent)==null?void 0:f.button)||0,n.isZoomingOrPanning=!0,n.prevViewport=u,((h=l.sourceEvent)==null?void 0:h.type)==="mousedown"&&r(!0),i&&(i==null||i(l.sourceEvent,u))}}function Gx({zoomPanValues:n,panOnDrag:r,onPaneContextMenu:i,onTransformChange:l,onPanZoom:u}){return c=>{var f,h;n.usedRightMouseButton=!!(i&&rg(r,n.mouseButton??0)),(f=c.sourceEvent)!=null&&f.sync||l([c.transform.x,c.transform.y,c.transform.k]),u&&!((h=c.sourceEvent)!=null&&h.internal)&&(u==null||u(c.sourceEvent,ml(c.transform)))}}function Kx({zoomPanValues:n,panOnDrag:r,panOnScroll:i,onDraggingChange:l,onPanZoomEnd:u,onPaneContextMenu:c}){return f=>{var h;if(!((h=f.sourceEvent)!=null&&h.internal)&&(n.isZoomingOrPanning=!1,c&&rg(r,n.mouseButton??0)&&!n.usedRightMouseButton&&f.sourceEvent&&c(f.sourceEvent),n.usedRightMouseButton=!1,l(!1),u)){const p=ml(f.transform);n.prevViewport=p,clearTimeout(n.timerId),n.timerId=setTimeout(()=>{u==null||u(f.sourceEvent,p)},i?150:0)}}}function qx({panActivationKeyPressed:n,zoomActivationKeyPressed:r,zoomOnScroll:i,zoomOnPinch:l,panOnDrag:u,panOnScroll:c,zoomOnDoubleClick:f,userSelectionActive:h,noWheelClassName:p,noPanClassName:m,lib:v,connectionInProgress:y}){return g=>{var E;const x=r||i,S=l&&g.ctrlKey,M=g.type==="wheel";if(g.button===1&&g.type==="mousedown"&&(Bn(g,`${v}-flow__node`)||Bn(g,`${v}-flow__edge`)||Bn(g,`${v}-flow__selection`)||Bn(g,`${v}-flow__nodesselection`)))return!0;if(!u&&!x&&!c&&!f&&!l||h||y&&!M||Bn(g,p)&&M||Bn(g,m)&&(!M||c&&M&&!r)||!l&&g.ctrlKey&&M)return!1;if(!l&&g.type==="touchstart"&&((E=g.touches)==null?void 0:E.length)>1)return g.preventDefault(),!1;if(!x&&!c&&!S&&M||!u&&(g.type==="mousedown"||g.type==="touchstart")||Array.isArray(u)&&!u.includes(g.button)&&g.type==="mousedown")return!1;const N=Array.isArray(u)&&u.includes(g.button)||!g.button||g.button<=1;return(!g.ctrlKey||M||n)&&N}}function Zx({domNode:n,minZoom:r,maxZoom:i,translateExtent:l,viewport:u,onPanZoom:c,onPanZoomStart:f,onPanZoomEnd:h,onDraggingChange:p}){const m={isZoomingOrPanning:!1,usedRightMouseButton:!1,prevViewport:{},mouseButton:0,timerId:void 0,panScrollTimeout:void 0,isPanScrolling:!1},v=n.getBoundingClientRect();let y=[[0,0],[v.width,v.height]];const g=typeof ResizeObserver<"u"?new ResizeObserver(Z=>{const k=Z[0];k&&(y=[[0,0],[k.contentRect.width,k.contentRect.height]])}):null;g==null||g.observe(n);const x=Ip().extent(()=>y).scaleExtent([r,i]).translateExtent(l),S=kt(n).call(x);P({x:u.x,y:u.y,zoom:ro(u.zoom,r,i)},[[0,0],[v.width,v.height]],l);const M=S.on("wheel.zoom"),N=S.on("dblclick.zoom");x.wheelDelta(og);async function E(Z,k){return S?new Promise(B=>{x==null||x.interpolate((k==null?void 0:k.interpolate)==="linear"?ti:Xs).transform(ka(S,k==null?void 0:k.duration,k==null?void 0:k.ease,()=>B(!0)),Z)}):!1}function L({noWheelClassName:Z,noPanClassName:k,onPaneContextMenu:B,userSelectionActive:I,panOnScroll:H,panOnDrag:j,panOnScrollMode:$,panOnScrollSpeed:F,preventScrolling:C,zoomOnPinch:R,zoomOnScroll:te,zoomOnDoubleClick:re,panActivationKeyPressed:ue=!1,zoomActivationKeyPressed:ce,lib:ae,onTransformChange:G,connectionInProgress:se,paneClickDistance:pe,selectionOnDrag:xe}){I&&!m.isZoomingOrPanning&&_();const ve=H&&!ce&&!I;x.clickDistance(xe?1/0:!Bt(pe)||pe<0?0:pe);const me=ve?Yx({zoomPanValues:m,noWheelClassName:Z,d3Selection:S,d3Zoom:x,panOnScrollMode:$,panOnScrollSpeed:F,zoomOnPinch:R,onPanZoomStart:f,onPanZoom:c,onPanZoomEnd:h}):Xx({noWheelClassName:Z,preventScrolling:C,d3ZoomHandler:M});S.on("wheel.zoom",me,{passive:!1});const ke=Qx({zoomPanValues:m,onDraggingChange:p,onPanZoomStart:f});x.on("start",ke);const Ce=Gx({zoomPanValues:m,panOnDrag:j,onPaneContextMenu:!!B,onPanZoom:c,onTransformChange:G});x.on("zoom",Ce);const Me=Kx({zoomPanValues:m,panOnDrag:j,panOnScroll:H,onPaneContextMenu:B,onPanZoomEnd:h,onDraggingChange:p});x.on("end",Me);const Le=qx({panActivationKeyPressed:ue,zoomActivationKeyPressed:ce,panOnDrag:j,zoomOnScroll:te,panOnScroll:H,zoomOnDoubleClick:re,zoomOnPinch:R,userSelectionActive:I,noPanClassName:k,noWheelClassName:Z,lib:ae,connectionInProgress:se});x.filter(Le),re?S.on("dblclick.zoom",N):S.on("dblclick.zoom",null)}function _(){x.on("zoom",null)}async function P(Z,k,B){const I=Ea(Z),H=x==null?void 0:x.constrain()(I,k,B);return H&&await E(H),H}async function U(Z,k){const B=Ea(Z);return await E(B,k),B}function D(Z){if(S){const k=Ea(Z),B=S.property("__zoom");(B.k!==Z.zoom||B.x!==Z.x||B.y!==Z.y)&&(x==null||x.transform(S,k,null,{sync:!0}))}}function V(){const Z=S?Pp(S.node()):{x:0,y:0,k:1};return{x:Z.x,y:Z.y,zoom:Z.k}}async function Y(Z,k){return S?new Promise(B=>{x==null||x.interpolate((k==null?void 0:k.interpolate)==="linear"?ti:Xs).scaleTo(ka(S,k==null?void 0:k.duration,k==null?void 0:k.ease,()=>B(!0)),Z)}):!1}async function X(Z,k){return S?new Promise(B=>{x==null||x.interpolate((k==null?void 0:k.interpolate)==="linear"?ti:Xs).scaleBy(ka(S,k==null?void 0:k.duration,k==null?void 0:k.ease,()=>B(!0)),Z)}):!1}function ee(Z){x==null||x.scaleExtent(Z)}function q(Z){x==null||x.translateExtent(Z)}function J(Z){const k=!Bt(Z)||Z<0?0:Z;x==null||x.clickDistance(k)}return{update:L,destroy:_,setViewport:U,setViewportConstrained:P,getViewport:V,scaleTo:Y,scaleBy:X,setScaleExtent:ee,setTranslateExtent:q,syncViewport:D,setClickDistance:J}}var io;(function(n){n.Line="line",n.Handle="handle"})(io||(io={}));function Jx({width:n,prevWidth:r,height:i,prevHeight:l,affectsX:u,affectsY:c}){const f=n-r,h=i-l,p=[f>0?1:f<0?-1:0,h>0?1:h<0?-1:0];return f&&u&&(p[0]=p[0]*-1),h&&c&&(p[1]=p[1]*-1),p}function vh(n){const r=n.includes("right")||n.includes("left"),i=n.includes("bottom")||n.includes("top"),l=n.includes("left"),u=n.includes("top");return{isHorizontal:r,isVertical:i,affectsX:l,affectsY:u}}function Hn(n,r){return Math.max(0,r-n)}function Vn(n,r){return Math.max(0,n-r)}function Us(n,r,i){return Math.max(0,r-n,n-i)}function wh(n,r){return n?!r:r}function e1(n,r,i,l,u,c,f,h){let{affectsX:p,affectsY:m}=r;const{isHorizontal:v,isVertical:y}=r,g=v&&y,{xSnapped:x,ySnapped:S}=i,{minWidth:M,maxWidth:N,minHeight:E,maxHeight:L}=l,{x:_,y:P,width:U,height:D,aspectRatio:V}=n;let Y=Math.floor(v?x-n.pointerX:0),X=Math.floor(y?S-n.pointerY:0);const ee=U+(p?-Y:Y),q=D+(m?-X:X),J=-c[0]*U,Z=-c[1]*D;let k=Us(ee,M,N),B=Us(q,E,L);if(f){let j=0,$=0;p&&Y<0?j=Hn(_+Y+J,f[0][0]):!p&&Y>0&&(j=Vn(_+ee+J,f[1][0])),m&&X<0?$=Hn(P+X+Z,f[0][1]):!m&&X>0&&($=Vn(P+q+Z,f[1][1])),k=Math.max(k,j),B=Math.max(B,$)}if(h){let j=0,$=0;p&&Y>0?j=Vn(_+Y,h[0][0]):!p&&Y<0&&(j=Hn(_+ee,h[1][0])),m&&X>0?$=Vn(P+X,h[0][1]):!m&&X<0&&($=Hn(P+q,h[1][1])),k=Math.max(k,j),B=Math.max(B,$)}if(u){if(v){const j=Us(ee/V,E,L)*V;if(k=Math.max(k,j),f){let $=0;!p&&!m||p&&!m&&g?$=Vn(P+Z+ee/V,f[1][1])*V:$=Hn(P+Z+(p?Y:-Y)/V,f[0][1])*V,k=Math.max(k,$)}if(h){let $=0;!p&&!m||p&&!m&&g?$=Hn(P+ee/V,h[1][1])*V:$=Vn(P+(p?Y:-Y)/V,h[0][1])*V,k=Math.max(k,$)}}if(y){const j=Us(q*V,M,N)/V;if(B=Math.max(B,j),f){let $=0;!p&&!m||m&&!p&&g?$=Vn(_+q*V+J,f[1][0])/V:$=Hn(_+(m?X:-X)*V+J,f[0][0])/V,B=Math.max(B,$)}if(h){let $=0;!p&&!m||m&&!p&&g?$=Hn(_+q*V,h[1][0])/V:$=Vn(_+(m?X:-X)*V,h[0][0])/V,B=Math.max(B,$)}}}X=X+(X<0?B:-B),Y=Y+(Y<0?k:-k),u&&(g?ee>q*V?X=(wh(p,m)?-Y:Y)/V:Y=(wh(p,m)?-X:X)*V:v?(X=Y/V,m=p):(Y=X*V,p=m));const I=p?_+Y:_,H=m?P+X:P;return{width:U+(p?-Y:Y),height:D+(m?-X:X),x:c[0]*Y*(p?-1:1)+I,y:c[1]*X*(m?-1:1)+H}}const ig={width:0,height:0,x:0,y:0},t1={...ig,pointerX:0,pointerY:0,aspectRatio:1};function n1(n,r,i){const l=r.position.x+n.position.x,u=r.position.y+n.position.y,c=n.measured.width??0,f=n.measured.height??0,h=i[0]*c,p=i[1]*f;return[[l-h,u-p],[l+c-h,u+f-p]]}function r1({domNode:n,nodeId:r,getStoreItems:i,onChange:l,onEnd:u}){const c=kt(n);let f={controlDirection:vh("bottom-right"),boundaries:{minWidth:0,minHeight:0,maxWidth:Number.MAX_VALUE,maxHeight:Number.MAX_VALUE},resizeDirection:void 0,keepAspectRatio:!1};function h({controlPosition:m,boundaries:v,keepAspectRatio:y,resizeDirection:g,onResizeStart:x,onResize:S,onResizeEnd:M,shouldResize:N}){let E={...ig},L={...t1};f={boundaries:v,resizeDirection:g,keepAspectRatio:y,controlDirection:vh(m)};let _,P=null,U=[],D,V,Y,X=!1;const ee=pp().on("start",q=>{const{nodeLookup:J,transform:Z,snapGrid:k,snapToGrid:B,nodeOrigin:I,paneDomNode:H}=i();if(_=J.get(r),!_)return;P=(H==null?void 0:H.getBoundingClientRect())??null;const{xSnapped:j,ySnapped:$}=ni(q.sourceEvent,{transform:Z,snapGrid:k,snapToGrid:B,containerBounds:P});E={width:_.measured.width??0,height:_.measured.height??0,x:_.position.x??0,y:_.position.y??0},L={...E,pointerX:j,pointerY:$,aspectRatio:E.width/E.height},D=void 0,V=yr(_.extent)?_.extent:void 0,_.parentId&&(_.extent==="parent"||_.expandParent)&&(D=J.get(_.parentId)),D&&_.extent==="parent"&&(V=[[0,0],[D.measured.width,D.measured.height]]),U=[],Y=void 0;for(const[F,C]of J)if(C.parentId===r&&(U.push({id:F,position:{...C.position},extent:C.extent}),C.extent==="parent"||C.expandParent)){const R=n1(C,_,C.origin??I);Y?Y=[[Math.min(R[0][0],Y[0][0]),Math.min(R[0][1],Y[0][1])],[Math.max(R[1][0],Y[1][0]),Math.max(R[1][1],Y[1][1])]]:Y=R}x==null||x(q,{...E})}).on("drag",q=>{const{transform:J,snapGrid:Z,snapToGrid:k,nodeOrigin:B}=i(),I=ni(q.sourceEvent,{transform:J,snapGrid:Z,snapToGrid:k,containerBounds:P}),H=[];if(!_)return;const{x:j,y:$,width:F,height:C}=E,R={},te=_.origin??B,{width:re,height:ue,x:ce,y:ae}=e1(L,f.controlDirection,I,f.boundaries,f.keepAspectRatio,te,V,Y),G=re!==F,se=ue!==C,pe=ce!==j&&G,xe=ae!==$&&se;if(!pe&&!xe&&!G&&!se)return;if((pe||xe||te[0]===1||te[1]===1)&&(R.x=pe?ce:E.x,R.y=xe?ae:E.y,E.x=R.x,E.y=R.y,U.length>0)){const Ce=ce-j,Me=ae-$;for(const Le of U)Le.position={x:Le.position.x-Ce+te[0]*(re-F),y:Le.position.y-Me+te[1]*(ue-C)},H.push(Le)}if((G||se)&&(R.width=G&&(!f.resizeDirection||f.resizeDirection==="horizontal")?re:E.width,R.height=se&&(!f.resizeDirection||f.resizeDirection==="vertical")?ue:E.height,E.width=R.width,E.height=R.height),D&&_.expandParent){const Ce=te[0]*(R.width??0);R.x&&R.x{X&&(M==null||M(q,{...E}),u==null||u({...E}),X=!1)});c.call(ee)}function p(){c.on(".drag",null)}return{update:h,destroy:p}}var Na={exports:{}},Ca={},Ma={exports:{}},Pa={};/** * @license React * use-sync-external-store-shim.production.js * @@ -45,7 +45,7 @@ Error generating stack: `+d.message+` * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var wh;function o1(){if(wh)return Pa;wh=1;var n=di();function r(y,g){return y===g&&(y!==0||1/y===1/g)||y!==y&&g!==g}var i=typeof Object.is=="function"?Object.is:r,l=n.useState,u=n.useEffect,c=n.useLayoutEffect,f=n.useDebugValue;function h(y,g){var w=g(),S=l({inst:{value:w,getSnapshot:g}}),M=S[0].inst,N=S[1];return c(function(){M.value=w,M.getSnapshot=g,p(M)&&N({inst:M})},[y,w,g]),u(function(){return p(M)&&N({inst:M}),y(function(){p(M)&&N({inst:M})})},[y]),f(w),w}function p(y){var g=y.getSnapshot;y=y.value;try{var w=g();return!i(y,w)}catch{return!0}}function m(y,g){return g()}var v=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?m:h;return Pa.useSyncExternalStore=n.useSyncExternalStore!==void 0?n.useSyncExternalStore:v,Pa}var Sh;function i1(){return Sh||(Sh=1,Ma.exports=o1()),Ma.exports}/** + */var xh;function o1(){if(xh)return Pa;xh=1;var n=di();function r(y,g){return y===g&&(y!==0||1/y===1/g)||y!==y&&g!==g}var i=typeof Object.is=="function"?Object.is:r,l=n.useState,u=n.useEffect,c=n.useLayoutEffect,f=n.useDebugValue;function h(y,g){var x=g(),S=l({inst:{value:x,getSnapshot:g}}),M=S[0].inst,N=S[1];return c(function(){M.value=x,M.getSnapshot=g,p(M)&&N({inst:M})},[y,x,g]),u(function(){return p(M)&&N({inst:M}),y(function(){p(M)&&N({inst:M})})},[y]),f(x),x}function p(y){var g=y.getSnapshot;y=y.value;try{var x=g();return!i(y,x)}catch{return!0}}function m(y,g){return g()}var v=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?m:h;return Pa.useSyncExternalStore=n.useSyncExternalStore!==void 0?n.useSyncExternalStore:v,Pa}var Sh;function i1(){return Sh||(Sh=1,Ma.exports=o1()),Ma.exports}/** * @license React * use-sync-external-store-shim/with-selector.production.js * @@ -53,10 +53,10 @@ Error generating stack: `+d.message+` * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var _h;function s1(){if(_h)return Ca;_h=1;var n=di(),r=i1();function i(m,v){return m===v&&(m!==0||1/m===1/v)||m!==m&&v!==v}var l=typeof Object.is=="function"?Object.is:i,u=r.useSyncExternalStore,c=n.useRef,f=n.useEffect,h=n.useMemo,p=n.useDebugValue;return Ca.useSyncExternalStoreWithSelector=function(m,v,y,g,w){var S=c(null);if(S.current===null){var M={hasValue:!1,value:null};S.current=M}else M=S.current;S=h(function(){function E(D){if(!L){if(L=!0,_=D,D=g(D),w!==void 0&&M.hasValue){var V=M.value;if(w(V,D))return P=V}return P=D}if(V=P,l(_,D))return V;var X=g(D);return w!==void 0&&w(V,X)?(_=D,V):(_=D,P=X)}var L=!1,_,P,U=y===void 0?null:y;return[function(){return E(v())},U===null?void 0:function(){return E(U())}]},[v,y,g,w]);var N=u(m,S[0],S[1]);return f(function(){M.hasValue=!0,M.value=N},[N]),p(N),N},Ca}var Eh;function l1(){return Eh||(Eh=1,Na.exports=s1()),Na.exports}var u1=l1();const a1=Zh(u1),c1={},kh=n=>{let r;const i=new Set,l=(v,y)=>{const g=typeof v=="function"?v(r):v;if(!Object.is(g,r)){const w=r;r=y??(typeof g!="object"||g===null)?g:Object.assign({},r,g),i.forEach(S=>S(r,w))}},u=()=>r,p={setState:l,getState:u,getInitialState:()=>m,subscribe:v=>(i.add(v),()=>i.delete(v)),destroy:()=>{(c1?"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."),i.clear()}},m=r=n(l,u,p);return p},f1=n=>n?kh(n):kh,{useDebugValue:d1}=_0,{useSyncExternalStoreWithSelector:h1}=a1,p1=n=>n;function sg(n,r=p1,i){const l=h1(n.subscribe,n.getState,n.getServerState||n.getInitialState,r,i);return d1(l),l}const Nh=(n,r)=>{const i=f1(n),l=(u,c=r)=>sg(i,u,c);return Object.assign(l,i),l},g1=(n,r)=>n?Nh(n,r):Nh;function Ve(n,r){if(Object.is(n,r))return!0;if(typeof n!="object"||n===null||typeof r!="object"||r===null)return!1;if(n instanceof Map&&r instanceof Map){if(n.size!==r.size)return!1;for(const[l,u]of n)if(!Object.is(u,r.get(l)))return!1;return!0}if(n instanceof Set&&r instanceof Set){if(n.size!==r.size)return!1;for(const l of n)if(!r.has(l))return!1;return!0}const i=Object.keys(n);if(i.length!==Object.keys(r).length)return!1;for(const l of i)if(!Object.prototype.hasOwnProperty.call(r,l)||!Object.is(n[l],r[l]))return!1;return!0}Jh();const yl=K.createContext(null),m1=yl.Provider,lg=Wt.error001("react");function Ie(n,r){const i=K.useContext(yl);if(i===null)throw new Error(lg);return sg(i,n,r)}function $e(){const n=K.useContext(yl);if(n===null)throw new Error(lg);return K.useMemo(()=>({getState:n.getState,setState:n.setState,subscribe:n.subscribe}),[n])}const Ch={display:"none"},y1={position:"absolute",width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0px, 0px, 0px, 0px)",clipPath:"inset(100%)"},ug="react-flow__node-desc",ag="react-flow__edge-desc",v1="react-flow__aria-live",x1=n=>n.ariaLiveMessage,w1=n=>n.ariaLabelConfig;function S1({rfId:n}){const r=Ie(x1);return T.jsx("div",{id:`${v1}-${n}`,"aria-live":"assertive","aria-atomic":"true",style:y1,children:r})}function _1({rfId:n,disableKeyboardA11y:r}){const i=Ie(w1);return T.jsxs(T.Fragment,{children:[T.jsx("div",{id:`${ug}-${n}`,style:Ch,children:r?i["node.a11yDescription.default"]:i["node.a11yDescription.keyboardDisabled"]}),T.jsx("div",{id:`${ag}-${n}`,style:Ch,children:i["edge.a11yDescription.default"]}),!r&&T.jsx(S1,{rfId:n})]})}const vl=K.forwardRef(({position:n="top-left",children:r,className:i,style:l,...u},c)=>{const f=`${n}`.split("-");return T.jsx("div",{className:Ye(["react-flow__panel",i,...f]),style:l,ref:c,...u,children:r})});vl.displayName="Panel";const Mh="https://reactflow.dev?utm_source=attribution";function E1({proOptions:n,position:r="bottom-right"}){return n!=null&&n.hideAttribution?null:T.jsx(vl,{position:r,className:"react-flow__attribution","data-message":`Please only hide this attribution when you are subscribed to React Flow Pro: ${Mh}`,children:T.jsx("a",{href:Mh,target:"_blank",rel:"noopener noreferrer","aria-label":"React Flow attribution",children:"React Flow"})})}const k1=n=>{const r=[],i=[];for(const[,l]of n.nodeLookup)l.selected&&r.push(l.internals.userNode);for(const[,l]of n.edgeLookup)l.selected&&i.push(l);return{selectedNodes:r,selectedEdges:i}},Ws=n=>n.id;function N1(n,r){return Ve(n.selectedNodes.map(Ws),r.selectedNodes.map(Ws))&&Ve(n.selectedEdges.map(Ws),r.selectedEdges.map(Ws))}function C1({onSelectionChange:n}){const r=$e(),{selectedNodes:i,selectedEdges:l}=Ie(k1,N1);return K.useEffect(()=>{const u={nodes:i,edges:l};n==null||n(u),r.getState().onSelectionChangeHandlers.forEach(c=>c(u))},[i,l,n]),null}const M1=n=>!!n.onSelectionChangeHandlers;function P1({onSelectionChange:n}){const r=Ie(M1);return n||r?T.jsx(C1,{onSelectionChange:n}):null}const cg=[0,0],I1={x:0,y:0,zoom:1},z1=["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"],Ph=[...z1,"rfId"],T1=n=>({setNodes:n.setNodes,setEdges:n.setEdges,setMinZoom:n.setMinZoom,setMaxZoom:n.setMaxZoom,setTranslateExtent:n.setTranslateExtent,setNodeExtent:n.setNodeExtent,reset:n.reset,setDefaultNodesAndEdges:n.setDefaultNodesAndEdges}),Ih={translateExtent:li,nodeOrigin:cg,minZoom:.5,maxZoom:2,elementsSelectable:!0,noPanClassName:"nopan",rfId:"1"};function L1(n){const{setNodes:r,setEdges:i,setMinZoom:l,setMaxZoom:u,setTranslateExtent:c,setNodeExtent:f,reset:h,setDefaultNodesAndEdges:p}=Ie(T1,Ve),m=$e();K.useEffect(()=>(p(n.defaultNodes,n.defaultEdges),()=>{v.current=Ih,h()}),[]);const v=K.useRef(Ih);return K.useEffect(()=>{for(const y of Ph){const g=n[y],w=v.current[y];g!==w&&(typeof n[y]>"u"||(y==="nodes"?r(g):y==="edges"?i(g):y==="minZoom"?l(g):y==="maxZoom"?u(g):y==="translateExtent"?c(g):y==="nodeExtent"?f(g):y==="ariaLabelConfig"?m.setState({ariaLabelConfig:mw(g)}):y==="fitView"?m.setState({fitViewQueued:g}):y==="fitViewOptions"?m.setState({fitViewOptions:g}):m.setState({[y]:g})))}v.current=n},Ph.map(y=>n[y])),null}function zh(){return typeof window>"u"||!window.matchMedia?null:window.matchMedia("(prefers-color-scheme: dark)")}function R1(n){var l;const[r,i]=K.useState(n==="system"?null:n);return K.useEffect(()=>{if(n!=="system"){i(n);return}const u=zh(),c=()=>i(u!=null&&u.matches?"dark":"light");return c(),u==null||u.addEventListener("change",c),()=>{u==null||u.removeEventListener("change",c)}},[n]),r!==null?r:(l=zh())!=null&&l.matches?"dark":"light"}const Th=typeof document<"u"?document:null;function fi(n=null,r={target:Th,actInsideInputWithModifier:!0}){const[i,l]=K.useState(!1),u=K.useRef(!1),c=K.useRef(new Set([])),[f,h]=K.useMemo(()=>{if(n!==null){const m=(Array.isArray(n)?n:[n]).filter(y=>typeof y=="string").map(y=>y.replace(/\+/g,` + */var _h;function s1(){if(_h)return Ca;_h=1;var n=di(),r=i1();function i(m,v){return m===v&&(m!==0||1/m===1/v)||m!==m&&v!==v}var l=typeof Object.is=="function"?Object.is:i,u=r.useSyncExternalStore,c=n.useRef,f=n.useEffect,h=n.useMemo,p=n.useDebugValue;return Ca.useSyncExternalStoreWithSelector=function(m,v,y,g,x){var S=c(null);if(S.current===null){var M={hasValue:!1,value:null};S.current=M}else M=S.current;S=h(function(){function E(D){if(!L){if(L=!0,_=D,D=g(D),x!==void 0&&M.hasValue){var V=M.value;if(x(V,D))return P=V}return P=D}if(V=P,l(_,D))return V;var Y=g(D);return x!==void 0&&x(V,Y)?(_=D,V):(_=D,P=Y)}var L=!1,_,P,U=y===void 0?null:y;return[function(){return E(v())},U===null?void 0:function(){return E(U())}]},[v,y,g,x]);var N=u(m,S[0],S[1]);return f(function(){M.hasValue=!0,M.value=N},[N]),p(N),N},Ca}var Eh;function l1(){return Eh||(Eh=1,Na.exports=s1()),Na.exports}var u1=l1();const a1=Zh(u1),c1={},kh=n=>{let r;const i=new Set,l=(v,y)=>{const g=typeof v=="function"?v(r):v;if(!Object.is(g,r)){const x=r;r=y??(typeof g!="object"||g===null)?g:Object.assign({},r,g),i.forEach(S=>S(r,x))}},u=()=>r,p={setState:l,getState:u,getInitialState:()=>m,subscribe:v=>(i.add(v),()=>i.delete(v)),destroy:()=>{(c1?"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."),i.clear()}},m=r=n(l,u,p);return p},f1=n=>n?kh(n):kh,{useDebugValue:d1}=_0,{useSyncExternalStoreWithSelector:h1}=a1,p1=n=>n;function sg(n,r=p1,i){const l=h1(n.subscribe,n.getState,n.getServerState||n.getInitialState,r,i);return d1(l),l}const Nh=(n,r)=>{const i=f1(n),l=(u,c=r)=>sg(i,u,c);return Object.assign(l,i),l},g1=(n,r)=>n?Nh(n,r):Nh;function Ve(n,r){if(Object.is(n,r))return!0;if(typeof n!="object"||n===null||typeof r!="object"||r===null)return!1;if(n instanceof Map&&r instanceof Map){if(n.size!==r.size)return!1;for(const[l,u]of n)if(!Object.is(u,r.get(l)))return!1;return!0}if(n instanceof Set&&r instanceof Set){if(n.size!==r.size)return!1;for(const l of n)if(!r.has(l))return!1;return!0}const i=Object.keys(n);if(i.length!==Object.keys(r).length)return!1;for(const l of i)if(!Object.prototype.hasOwnProperty.call(r,l)||!Object.is(n[l],r[l]))return!1;return!0}Jh();const yl=K.createContext(null),m1=yl.Provider,lg=Wt.error001("react");function Ie(n,r){const i=K.useContext(yl);if(i===null)throw new Error(lg);return sg(i,n,r)}function $e(){const n=K.useContext(yl);if(n===null)throw new Error(lg);return K.useMemo(()=>({getState:n.getState,setState:n.setState,subscribe:n.subscribe}),[n])}const Ch={display:"none"},y1={position:"absolute",width:1,height:1,margin:-1,border:0,padding:0,overflow:"hidden",clip:"rect(0px, 0px, 0px, 0px)",clipPath:"inset(100%)"},ug="react-flow__node-desc",ag="react-flow__edge-desc",v1="react-flow__aria-live",w1=n=>n.ariaLiveMessage,x1=n=>n.ariaLabelConfig;function S1({rfId:n}){const r=Ie(w1);return T.jsx("div",{id:`${v1}-${n}`,"aria-live":"assertive","aria-atomic":"true",style:y1,children:r})}function _1({rfId:n,disableKeyboardA11y:r}){const i=Ie(x1);return T.jsxs(T.Fragment,{children:[T.jsx("div",{id:`${ug}-${n}`,style:Ch,children:r?i["node.a11yDescription.default"]:i["node.a11yDescription.keyboardDisabled"]}),T.jsx("div",{id:`${ag}-${n}`,style:Ch,children:i["edge.a11yDescription.default"]}),!r&&T.jsx(S1,{rfId:n})]})}const vl=K.forwardRef(({position:n="top-left",children:r,className:i,style:l,...u},c)=>{const f=`${n}`.split("-");return T.jsx("div",{className:be(["react-flow__panel",i,...f]),style:l,ref:c,...u,children:r})});vl.displayName="Panel";const Mh="https://reactflow.dev?utm_source=attribution";function E1({proOptions:n,position:r="bottom-right"}){return n!=null&&n.hideAttribution?null:T.jsx(vl,{position:r,className:"react-flow__attribution","data-message":`Please only hide this attribution when you are subscribed to React Flow Pro: ${Mh}`,children:T.jsx("a",{href:Mh,target:"_blank",rel:"noopener noreferrer","aria-label":"React Flow attribution",children:"React Flow"})})}const k1=n=>{const r=[],i=[];for(const[,l]of n.nodeLookup)l.selected&&r.push(l.internals.userNode);for(const[,l]of n.edgeLookup)l.selected&&i.push(l);return{selectedNodes:r,selectedEdges:i}},Ws=n=>n.id;function N1(n,r){return Ve(n.selectedNodes.map(Ws),r.selectedNodes.map(Ws))&&Ve(n.selectedEdges.map(Ws),r.selectedEdges.map(Ws))}function C1({onSelectionChange:n}){const r=$e(),{selectedNodes:i,selectedEdges:l}=Ie(k1,N1);return K.useEffect(()=>{const u={nodes:i,edges:l};n==null||n(u),r.getState().onSelectionChangeHandlers.forEach(c=>c(u))},[i,l,n]),null}const M1=n=>!!n.onSelectionChangeHandlers;function P1({onSelectionChange:n}){const r=Ie(M1);return n||r?T.jsx(C1,{onSelectionChange:n}):null}const cg=[0,0],I1={x:0,y:0,zoom:1},z1=["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"],Ph=[...z1,"rfId"],T1=n=>({setNodes:n.setNodes,setEdges:n.setEdges,setMinZoom:n.setMinZoom,setMaxZoom:n.setMaxZoom,setTranslateExtent:n.setTranslateExtent,setNodeExtent:n.setNodeExtent,reset:n.reset,setDefaultNodesAndEdges:n.setDefaultNodesAndEdges}),Ih={translateExtent:li,nodeOrigin:cg,minZoom:.5,maxZoom:2,elementsSelectable:!0,noPanClassName:"nopan",rfId:"1"};function L1(n){const{setNodes:r,setEdges:i,setMinZoom:l,setMaxZoom:u,setTranslateExtent:c,setNodeExtent:f,reset:h,setDefaultNodesAndEdges:p}=Ie(T1,Ve),m=$e();K.useEffect(()=>(p(n.defaultNodes,n.defaultEdges),()=>{v.current=Ih,h()}),[]);const v=K.useRef(Ih);return K.useEffect(()=>{for(const y of Ph){const g=n[y],x=v.current[y];g!==x&&(typeof n[y]>"u"||(y==="nodes"?r(g):y==="edges"?i(g):y==="minZoom"?l(g):y==="maxZoom"?u(g):y==="translateExtent"?c(g):y==="nodeExtent"?f(g):y==="ariaLabelConfig"?m.setState({ariaLabelConfig:mx(g)}):y==="fitView"?m.setState({fitViewQueued:g}):y==="fitViewOptions"?m.setState({fitViewOptions:g}):m.setState({[y]:g})))}v.current=n},Ph.map(y=>n[y])),null}function zh(){return typeof window>"u"||!window.matchMedia?null:window.matchMedia("(prefers-color-scheme: dark)")}function R1(n){var l;const[r,i]=K.useState(n==="system"?null:n);return K.useEffect(()=>{if(n!=="system"){i(n);return}const u=zh(),c=()=>i(u!=null&&u.matches?"dark":"light");return c(),u==null||u.addEventListener("change",c),()=>{u==null||u.removeEventListener("change",c)}},[n]),r!==null?r:(l=zh())!=null&&l.matches?"dark":"light"}const Th=typeof document<"u"?document:null;function fi(n=null,r={target:Th,actInsideInputWithModifier:!0}){const[i,l]=K.useState(!1),u=K.useRef(!1),c=K.useRef(new Set([])),[f,h]=K.useMemo(()=>{if(n!==null){const m=(Array.isArray(n)?n:[n]).filter(y=>typeof y=="string").map(y=>y.replace(/\+/g,` `).replace(` `,` +`).split(` -`)),v=m.reduce((y,g)=>y.concat(...g),[]);return[m,v]}return[[],[]]},[n]);return K.useEffect(()=>{const p=(r==null?void 0:r.target)??Th,m=(r==null?void 0:r.actInsideInputWithModifier)??!0;if(n!==null){const v=w=>{var N,E;if(u.current=w.ctrlKey||w.metaKey||w.shiftKey||w.altKey,(!u.current||u.current&&!m)&&Up(w))return!1;const M=Rh(w.code,h);if(c.current.add(w[M]),Lh(f,c.current,!1)){const L=((E=(N=w.composedPath)==null?void 0:N.call(w))==null?void 0:E[0])||w.target,_=(L==null?void 0:L.nodeName)==="BUTTON"||(L==null?void 0:L.nodeName)==="A";r.preventDefault!==!1&&(u.current||!_)&&w.preventDefault(),l(!0)}},y=w=>{const S=Rh(w.code,h);Lh(f,c.current,!0)?(l(!1),c.current.clear()):c.current.delete(w[S]),w.key==="Meta"&&c.current.clear(),u.current=!1},g=()=>{c.current.clear(),l(!1)};return p==null||p.addEventListener("keydown",v),p==null||p.addEventListener("keyup",y),window.addEventListener("blur",g),window.addEventListener("contextmenu",g),()=>{p==null||p.removeEventListener("keydown",v),p==null||p.removeEventListener("keyup",y),window.removeEventListener("blur",g),window.removeEventListener("contextmenu",g)}}},[n,l]),i}function Lh(n,r,i){return n.filter(l=>i||l.length===r.size).some(l=>l.every(u=>r.has(u)))}function Rh(n,r){return r.includes(n)?"code":"key"}const A1=()=>{const n=$e();return K.useMemo(()=>({zoomIn:async r=>{const{panZoom:i}=n.getState();return i?i.scaleBy(1.2,r):!1},zoomOut:async r=>{const{panZoom:i}=n.getState();return i?i.scaleBy(1/1.2,r):!1},zoomTo:async(r,i)=>{const{panZoom:l}=n.getState();return l?l.scaleTo(r,i):!1},getZoom:()=>n.getState().transform[2],setViewport:async(r,i)=>{const{transform:[l,u,c],panZoom:f}=n.getState();return f?(await f.setViewport({x:r.x??l,y:r.y??u,zoom:r.zoom??c},i),!0):!1},getViewport:()=>{const[r,i,l]=n.getState().transform;return{x:r,y:i,zoom:l}},setCenter:async(r,i,l)=>n.getState().setCenter(r,i,l),fitBounds:async(r,i)=>{const{width:l,height:u,minZoom:c,maxZoom:f,panZoom:h}=n.getState(),p=tc(r,l,u,c,f,(i==null?void 0:i.padding)??.1);return h?(await h.setViewport(p,{duration:i==null?void 0:i.duration,ease:i==null?void 0:i.ease,interpolate:i==null?void 0:i.interpolate}),!0):!1},screenToFlowPosition:(r,i={})=>{const{transform:l,snapGrid:u,snapToGrid:c,domNode:f}=n.getState();if(!f)return r;const{x:h,y:p}=f.getBoundingClientRect(),m={x:r.x-h,y:r.y-p},v=i.snapGrid??u,y=i.snapToGrid??c;return vi(m,l,y,v)},flowToScreenPosition:r=>{const{transform:i,domNode:l}=n.getState();if(!l)return r;const{x:u,y:c}=l.getBoundingClientRect(),f=oo(r,i);return{x:f.x+u,y:f.y+c}}}),[])};function fg(n,r){const i=[],l=new Map,u=[];for(const c of n)if(c.type==="add"){u.push(c);continue}else if(c.type==="remove"||c.type==="replace")l.set(c.id,[c]);else{const f=l.get(c.id);f?f.push(c):l.set(c.id,[c])}for(const c of r){const f=l.get(c.id);if(!f){i.push(c);continue}if(f[0].type==="remove")continue;if(f[0].type==="replace"){i.push({...f[0].item});continue}const h={...c};for(const p of f)j1(p,h);i.push(h)}return u.length&&u.forEach(c=>{c.index!==void 0?i.splice(c.index,0,{...c.item}):i.push({...c.item})}),i}function j1(n,r){switch(n.type){case"select":{r.selected=n.selected;break}case"position":{typeof n.position<"u"&&(r.position=n.position),typeof n.dragging<"u"&&(r.dragging=n.dragging);break}case"dimensions":{typeof n.dimensions<"u"&&(r.measured={...n.dimensions},n.setAttributes&&((n.setAttributes===!0||n.setAttributes==="width")&&(r.width=n.dimensions.width),(n.setAttributes===!0||n.setAttributes==="height")&&(r.height=n.dimensions.height))),typeof n.resizing=="boolean"&&(r.resizing=n.resizing);break}}}function $1(n,r){return fg(n,r)}function D1(n,r){return fg(n,r)}function cr(n,r){return{id:n,type:"select",selected:r}}function qr(n,r=new Set,i=!1){const l=[];for(const[u,c]of n){const f=r.has(u);!(c.selected===void 0&&!f)&&c.selected!==f&&(i&&(c.selected=f),l.push(cr(c.id,f)))}return l}function Ah({items:n=[],lookup:r}){var u;const i=[],l=new Map(n.map(c=>[c.id,c]));for(const[c,f]of n.entries()){const h=r.get(f.id),p=((u=h==null?void 0:h.internals)==null?void 0:u.userNode)??h;p!==void 0&&p!==f&&i.push({id:f.id,item:f,type:"replace"}),p===void 0&&i.push({item:f,type:"add",index:c})}for(const[c]of r)l.get(c)===void 0&&i.push({id:c,type:"remove"});return i}function jh(n){return{id:n.id,type:"remove"}}const O1=Fp();function F1(n,r,i={}){return _w(n,r,{...i,onError:i.onError??O1})}const $h=n=>lw(n),H1=n=>Ap(n);function dg(n){return K.forwardRef(n)}const hg=typeof window<"u"?K.useLayoutEffect:K.useEffect;function Dh(n){const[r,i]=K.useState(BigInt(0)),[l]=K.useState(()=>V1(()=>i(u=>u+BigInt(1))));return hg(()=>{const u=l.get();u.length&&(n(u),l.reset())},[r]),l}function V1(n){let r=[];return{get:()=>r,reset:()=>{r=[]},push:i=>{r.push(i),n()}}}const pg=K.createContext(null);function B1({children:n}){const r=$e(),i=K.useCallback(h=>{const{nodes:p=[],setNodes:m,hasDefaultNodes:v,onNodesChange:y,nodeLookup:g,fitViewQueued:w,onNodesChangeMiddlewareMap:S}=r.getState();let M=p;for(const E of h)M=typeof E=="function"?E(M):E;let N=Ah({items:M,lookup:g});for(const E of S.values())N=E(N);v&&m(M),N.length>0?y==null||y(N):w&&window.requestAnimationFrame(()=>{const{fitViewQueued:E,nodes:L,setNodes:_}=r.getState();E&&_(L)})},[]),l=Dh(i),u=K.useCallback(h=>{const{edges:p=[],setEdges:m,hasDefaultEdges:v,onEdgesChange:y,edgeLookup:g}=r.getState();let w=p;for(const S of h)w=typeof S=="function"?S(w):S;v?m(w):y&&y(Ah({items:w,lookup:g}))},[]),c=Dh(u),f=K.useMemo(()=>({nodeQueue:l,edgeQueue:c}),[]);return T.jsx(pg.Provider,{value:f,children:n})}function U1(){const n=K.useContext(pg);if(!n)throw new Error("useBatchContext must be used within a BatchProvider");return n}const W1=n=>!!n.panZoom;function uc(){const n=A1(),r=$e(),i=U1(),l=Ie(W1),u=K.useMemo(()=>{const c=y=>r.getState().nodeLookup.get(y),f=y=>{i.nodeQueue.push(y)},h=y=>{i.edgeQueue.push(y)},p=y=>{var E,L;const{nodeLookup:g,nodeOrigin:w}=r.getState(),S=$h(y)?y:g.get(y.id),M=S.parentId?Vp(S.position,S.measured,S.parentId,g,w):S.position,N={...S,position:M,width:((E=S.measured)==null?void 0:E.width)??S.width,height:((L=S.measured)==null?void 0:L.height)??S.height};return ai(N)},m=(y,g,w={replace:!1})=>{f(S=>S.map(M=>{if(M.id===y){const N=typeof g=="function"?g(M):g;return w.replace&&$h(N)?N:{...M,...N}}return M}))},v=(y,g,w={replace:!1})=>{h(S=>S.map(M=>{if(M.id===y){const N=typeof g=="function"?g(M):g;return w.replace&&H1(N)?N:{...M,...N}}return M}))};return{getNodes:()=>r.getState().nodes.map(y=>({...y})),getNode:y=>{var g;return(g=c(y))==null?void 0:g.internals.userNode},getInternalNode:c,getEdges:()=>{const{edges:y=[]}=r.getState();return y.map(g=>({...g}))},getEdge:y=>r.getState().edgeLookup.get(y),setNodes:f,setEdges:h,addNodes:y=>{const g=Array.isArray(y)?y:[y];i.nodeQueue.push(w=>[...w,...g])},addEdges:y=>{const g=Array.isArray(y)?y:[y];i.edgeQueue.push(w=>[...w,...g])},toObject:()=>{const{nodes:y=[],edges:g=[],transform:w}=r.getState(),[S,M,N]=w;return{nodes:y.map(E=>({...E})),edges:g.map(E=>({...E})),viewport:{x:S,y:M,zoom:N}}},deleteElements:async({nodes:y=[],edges:g=[]})=>{const{nodes:w,edges:S,onNodesDelete:M,onEdgesDelete:N,triggerNodeChanges:E,triggerEdgeChanges:L,onDelete:_,onBeforeDelete:P}=r.getState(),{nodes:U,edges:D}=await dw({nodesToRemove:y,edgesToRemove:g,nodes:w,edges:S,onBeforeDelete:P}),V=D.length>0,X=U.length>0;if(V){const b=D.map(jh);N==null||N(D),L(b)}if(X){const b=U.map(jh);M==null||M(U),E(b)}return(X||V)&&(_==null||_({nodes:U,edges:D})),{deletedNodes:U,deletedEdges:D}},getIntersectingNodes:(y,g=!0,w)=>{const S=lh(y),M=S?y:p(y),N=w!==void 0;return M?(w||r.getState().nodes).filter(E=>{const L=r.getState().nodeLookup.get(E.id);if(L&&!S&&(E.id===y.id||!L.internals.positionAbsolute))return!1;const _=ai(N?E:L),P=sl(_,M);return g&&P>0||P>=_.width*_.height||P>=M.width*M.height}):[]},isNodeIntersecting:(y,g,w=!0)=>{const M=lh(y)?y:p(y);if(!M)return!1;const N=sl(M,g);return w&&N>0||N>=g.width*g.height||N>=M.width*M.height},updateNode:m,updateNodeData:(y,g,w={replace:!1})=>{m(y,S=>{const M=typeof g=="function"?g(S):g;return w.replace?{...S,data:M}:{...S,data:{...S.data,...M}}},w)},updateEdge:v,updateEdgeData:(y,g,w={replace:!1})=>{v(y,S=>{const M=typeof g=="function"?g(S):g;return w.replace?{...S,data:M}:{...S,data:{...S.data,...M}}},w)},getNodesBounds:y=>{const{nodeLookup:g,nodeOrigin:w}=r.getState();return uw(y,{nodeLookup:g,nodeOrigin:w})},getHandleConnections:({type:y,id:g,nodeId:w})=>{var S;return Array.from(((S=r.getState().connectionLookup.get(`${w}-${y}${g?`-${g}`:""}`))==null?void 0:S.values())??[])},getNodeConnections:({type:y,handleId:g,nodeId:w})=>{var S;return Array.from(((S=r.getState().connectionLookup.get(`${w}${y?g?`-${y}-${g}`:`-${y}`:""}`))==null?void 0:S.values())??[])},fitView:async y=>{const g=r.getState().fitViewResolver??gw();return r.setState({fitViewQueued:!0,fitViewOptions:y,fitViewResolver:g}),i.nodeQueue.push(w=>[...w]),g.promise}}},[]);return K.useMemo(()=>({...u,...n,viewportInitialized:l}),[l])}const Oh=n=>n.selected,Y1=typeof window<"u"?window:void 0;function X1({deleteKeyCode:n,multiSelectionKeyCode:r}){const i=$e(),{deleteElements:l}=uc(),u=fi(n,{actInsideInputWithModifier:!1}),c=fi(r,{target:Y1});K.useEffect(()=>{if(u){const{edges:f,nodes:h}=i.getState();l({nodes:h.filter(Oh),edges:f.filter(Oh)}),i.setState({nodesSelectionActive:!1})}},[u]),K.useEffect(()=>{i.setState({multiSelectionActive:c})},[c])}function b1(n){const r=$e();K.useEffect(()=>{const i=()=>{var u,c,f,h;if(!n.current||!(((c=(u=n.current).checkVisibility)==null?void 0:c.call(u))??!0))return!1;const l=nc(n.current);(l.height===0||l.width===0)&&((h=(f=r.getState()).onError)==null||h.call(f,"004",Wt.error004())),r.setState({width:l.width||500,height:l.height||500})};if(n.current){i(),window.addEventListener("resize",i);const l=new ResizeObserver(()=>i());return l.observe(n.current),()=>{window.removeEventListener("resize",i),l&&n.current&&l.unobserve(n.current)}}},[])}const xl={position:"absolute",width:"100%",height:"100%",top:0,left:0},Q1=n=>({userSelectionActive:n.userSelectionActive,lib:n.lib,connectionInProgress:n.connection.inProgress});function G1({onPaneContextMenu:n,zoomOnScroll:r=!0,zoomOnPinch:i=!0,panOnScroll:l=!1,panActivationKeyPressed:u,panOnScrollSpeed:c=.5,panOnScrollMode:f=hr.Free,zoomOnDoubleClick:h=!0,panOnDrag:p=!0,defaultViewport:m,translateExtent:v,minZoom:y,maxZoom:g,zoomActivationKeyCode:w,preventScrolling:S=!0,children:M,noWheelClassName:N,noPanClassName:E,onViewportChange:L,isControlledViewport:_,paneClickDistance:P,selectionOnDrag:U}){const D=$e(),V=K.useRef(null),{userSelectionActive:X,lib:b,connectionInProgress:ee}=Ie(Q1,Ve),q=fi(w),J=K.useRef();b1(V);const Z=K.useCallback(k=>{L==null||L({x:k[0],y:k[1],zoom:k[2]}),_||D.setState({transform:k})},[L,_]);return K.useEffect(()=>{if(V.current){J.current=Zw({domNode:V.current,minZoom:y,maxZoom:g,translateExtent:v,viewport:m,onDraggingChange:H=>D.setState(j=>j.paneDragging===H?j:{paneDragging:H}),onPanZoomStart:(H,j)=>{const{onViewportChangeStart:$,onMoveStart:F}=D.getState();F==null||F(H,j),$==null||$(j)},onPanZoom:(H,j)=>{const{onViewportChange:$,onMove:F}=D.getState();F==null||F(H,j),$==null||$(j)},onPanZoomEnd:(H,j)=>{const{onViewportChangeEnd:$,onMoveEnd:F}=D.getState();F==null||F(H,j),$==null||$(j)}});const{x:k,y:B,zoom:z}=J.current.getViewport();return D.setState({panZoom:J.current,transform:[k,B,z],domNode:V.current.closest(".react-flow")}),()=>{var H;(H=J.current)==null||H.destroy()}}},[]),K.useEffect(()=>{var k;(k=J.current)==null||k.update({onPaneContextMenu:n,zoomOnScroll:r,zoomOnPinch:i,panOnScroll:l,panActivationKeyPressed:u,panOnScrollSpeed:c,panOnScrollMode:f,zoomOnDoubleClick:h,panOnDrag:p,zoomActivationKeyPressed:q,preventScrolling:S,noPanClassName:E,userSelectionActive:X,noWheelClassName:N,lib:b,onTransformChange:Z,connectionInProgress:ee,selectionOnDrag:U,paneClickDistance:P})},[n,r,i,l,u,c,f,h,p,q,S,E,X,N,b,Z,ee,U,P]),T.jsx("div",{className:"react-flow__renderer",ref:V,style:xl,children:M})}const K1=n=>({userSelectionActive:n.userSelectionActive,userSelectionRect:n.userSelectionRect});function q1(){const{userSelectionActive:n,userSelectionRect:r}=Ie(K1,Ve);return n&&r?T.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 Ia=(n,r)=>i=>{i.target===r.current&&(n==null||n(i))},Z1=n=>({userSelectionActive:n.userSelectionActive,elementsSelectable:n.elementsSelectable,dragging:n.paneDragging,panBy:n.panBy,autoPanSpeed:n.autoPanSpeed});function J1({isSelecting:n,selectionKeyPressed:r,selectionMode:i=ui.Full,panOnDrag:l,autoPanOnSelection:u,paneClickDistance:c,selectionOnDrag:f,onSelectionStart:h,onSelectionEnd:p,onPaneClick:m,onPaneContextMenu:v,onPaneScroll:y,onPaneMouseEnter:g,onPaneMouseMove:w,onPaneMouseLeave:S,children:M}){const N=K.useRef(0),E=$e(),{userSelectionActive:L,elementsSelectable:_,dragging:P,panBy:U,autoPanSpeed:D}=Ie(Z1,Ve),V=_&&(n||L),X=K.useRef(null),b=K.useRef(),ee=K.useRef(new Set),q=K.useRef(new Set),J=K.useRef(!1),Z=K.useRef(!1),k=K.useRef({x:0,y:0}),B=K.useRef(!1),z=G=>{if(Z.current||J.current||E.getState().connection.inProgress){Z.current=!1,J.current=!1;return}m==null||m(G),E.getState().resetSelectedElements(),E.setState({nodesSelectionActive:!1})},H=G=>{if(Array.isArray(l)&&(l!=null&&l.includes(2))){G.preventDefault();return}v==null||v(G)},j=y?G=>y(G):void 0,$=G=>{Z.current&&(G.stopPropagation(),Z.current=!1)},F=G=>{var Le,it;if(G.pointerType==="touch"&&l!==!1&&!r)return;const{domNode:se,transform:pe}=E.getState();if(b.current=se==null?void 0:se.getBoundingClientRect(),!b.current)return;const we=G.target===X.current;if(!we&&!!G.target.closest(".nokey")||!n||!(f&&we||r)||G.button!==0||!G.isPrimary)return;(it=(Le=G.target)==null?void 0:Le.setPointerCapture)==null||it.call(Le,G.pointerId),Z.current=!1;const{x:ke,y:Ce}=Ut(G.nativeEvent,b.current),Me=vi({x:ke,y:Ce},pe);E.setState({userSelectionRect:{width:0,height:0,startX:Me.x,startY:Me.y,x:ke,y:Ce}}),we||(G.stopPropagation(),G.preventDefault())};function C(G,se){const{userSelectionRect:pe}=E.getState();if(!pe)return;const{transform:we,nodeLookup:ve,edgeLookup:me,connectionLookup:ke,triggerNodeChanges:Ce,triggerEdgeChanges:Me,defaultEdgeOptions:Le}=E.getState(),it={x:pe.startX,y:pe.startY},{x:ut,y:Je}=oo(it,we),et={startX:it.x,startY:it.y,x:Gat.id)),q.current=new Set;const Qt=(Le==null?void 0:Le.selectable)??!0;for(const at of ee.current){const Ct=ke.get(at);if(Ct)for(const{edgeId:yt}of Ct.values()){const Mt=me.get(yt);Mt&&(Mt.selectable??Qt)&&q.current.add(yt)}}if(!uh(rn,ee.current)){const at=qr(ve,ee.current,!0);Ce(at)}if(!uh(bt,q.current)){const at=qr(me,q.current);Me(at)}E.setState({userSelectionRect:et,userSelectionActive:!0,nodesSelectionActive:!1})}function R(){if(!u||!b.current)return;const[G,se]=ec(k.current,b.current,D);U({x:G,y:se}).then(pe=>{if(!Z.current||!pe){N.current=requestAnimationFrame(R);return}const{x:we,y:ve}=k.current;C(we,ve),N.current=requestAnimationFrame(R)})}const te=()=>{cancelAnimationFrame(N.current),N.current=0,B.current=!1};K.useEffect(()=>()=>te(),[]);const re=G=>{const{userSelectionRect:se,transform:pe,resetSelectedElements:we}=E.getState();if(!b.current||!se)return;const{x:ve,y:me}=Ut(G.nativeEvent,b.current);k.current={x:ve,y:me};const ke=oo({x:se.startX,y:se.startY},pe);if(!Z.current){const Ce=r?0:c;if(Math.hypot(ve-ke.x,me-ke.y)<=Ce)return;we(),h==null||h(G)}Z.current=!0,B.current||(R(),B.current=!0),C(ve,me)},ue=G=>{var se,pe;if(!V){G.target===X.current&&E.getState().connection.inProgress&&(J.current=!0);return}G.button===0&&((pe=(se=G.target)==null?void 0:se.releasePointerCapture)==null||pe.call(se,G.pointerId),!L&&G.target===X.current&&E.getState().userSelectionRect&&(z==null||z(G)),E.setState({userSelectionActive:!1,userSelectionRect:null}),Z.current&&(p==null||p(G),E.setState({nodesSelectionActive:ee.current.size>0})),te())},ce=G=>{var se,pe;(pe=(se=G.target)==null?void 0:se.releasePointerCapture)==null||pe.call(se,G.pointerId),te()},ae=l===!0||Array.isArray(l)&&l.includes(0);return T.jsxs("div",{className:Ye(["react-flow__pane",{draggable:ae,dragging:P,selection:n}]),onClick:V?void 0:Ia(z,X),onContextMenu:Ia(H,X),onWheel:Ia(j,X),onPointerEnter:V?void 0:g,onPointerMove:V?re:w,onPointerUp:ue,onPointerCancel:V?ce:void 0,onPointerDownCapture:V?F:void 0,onClickCapture:V?$:void 0,onPointerLeave:S,ref:X,style:xl,children:[M,T.jsx(q1,{})]})}function Wa({id:n,store:r,unselect:i=!1,nodeRef:l}){const{addSelectedNodes:u,unselectNodesAndEdges:c,multiSelectionActive:f,nodeLookup:h,onError:p}=r.getState(),m=h.get(n);if(!m){p==null||p("012",Wt.error012(n));return}r.setState({nodesSelectionActive:!1}),m.selected?(i||m.selected&&f)&&(c({nodes:[m],edges:[]}),requestAnimationFrame(()=>{var v;return(v=l==null?void 0:l.current)==null?void 0:v.blur()})):u([n])}function gg({nodeRef:n,disabled:r=!1,noDragClassName:i,handleSelector:l,nodeId:u,isSelectable:c,nodeClickDistance:f}){const h=$e(),[p,m]=K.useState(!1),v=K.useRef();return K.useEffect(()=>{if(!r)return v.current=Ow({getStoreItems:()=>h.getState(),onNodeMouseDown:y=>{Wa({id:y,store:h,nodeRef:n})},onDragStart:()=>{m(!0)},onDragStop:()=>{m(!1)}}),()=>{var y;(y=v.current)==null||y.destroy(),v.current=void 0}},[r,h,n]),K.useEffect(()=>{r||!n.current||!v.current||v.current.update({noDragClassName:i,handleSelector:l,domNode:n.current,isSelectable:c,nodeId:u,nodeClickDistance:f})},[i,l,r,c,n,u,f]),p}const eS=n=>r=>r.selected&&(r.draggable||n&&typeof r.draggable>"u");function mg(){const n=$e();return K.useCallback(i=>{const{nodeExtent:l,snapToGrid:u,snapGrid:c,nodesDraggable:f,onError:h,updateNodePositions:p,nodeLookup:m,nodeOrigin:v}=n.getState(),y=new Map,g=eS(f),w=u?c[0]:5,S=u?c[1]:5,M=i.direction.x*w*i.factor,N=i.direction.y*S*i.factor;for(const[,E]of m){if(!g(E))continue;let L={x:E.internals.positionAbsolute.x+M,y:E.internals.positionAbsolute.y+N};u&&(L=yi(L,c));const{position:_,positionAbsolute:P}=jp({nodeId:E.id,nextPosition:L,nodeLookup:m,nodeExtent:l,nodeOrigin:v,onError:h});E.position=_,E.internals.positionAbsolute=P,y.set(E.id,E)}p(y)},[])}const ac=K.createContext(null),tS=ac.Provider;ac.Consumer;const yg=()=>K.useContext(ac),nS=n=>({connectOnClick:n.connectOnClick,noPanClassName:n.noPanClassName,rfId:n.rfId}),vg=K.createContext(null);function rS({children:n}){const r=Ie(nS,Ve);return T.jsx(vg.Provider,{value:r,children:n})}function oS(){const n=K.useContext(vg);if(!n)throw new Error("useHandleConfig must be used within a HandleConfigProvider");return n}const iS={connectingFrom:!1,connectingTo:!1,clickConnecting:!1,isPossibleEndHandle:!0,connectionInProcess:!1,clickConnectionInProcess:!1,valid:!1},sS=(n,r,i)=>l=>{const{connectionClickStartHandle:u,connectionMode:c,connection:f}=l,{fromHandle:h,toHandle:p,isValid:m}=f;if(!h&&!u)return iS;const v=(p==null?void 0:p.nodeId)===n&&(p==null?void 0:p.id)===r&&(p==null?void 0:p.type)===i;return{connectingFrom:(h==null?void 0:h.nodeId)===n&&(h==null?void 0:h.id)===r&&(h==null?void 0:h.type)===i,connectingTo:v,clickConnecting:(u==null?void 0:u.nodeId)===n&&(u==null?void 0:u.id)===r&&(u==null?void 0:u.type)===i,isPossibleEndHandle:c===no.Strict?(h==null?void 0:h.type)!==i:n!==(h==null?void 0:h.nodeId)||r!==(h==null?void 0:h.id),connectionInProcess:!!h,clickConnectionInProcess:!!u,valid:v&&m}};function lS({type:n="source",position:r=xe.Top,isValidConnection:i,isConnectable:l=!0,isConnectableStart:u=!0,isConnectableEnd:c=!0,id:f,onConnect:h,children:p,className:m,onMouseDown:v,onTouchStart:y,...g},w){var B,z;const S=f||null,M=n==="target",N=$e(),E=yg(),{connectOnClick:L,noPanClassName:_,rfId:P}=oS(),{connectingFrom:U,connectingTo:D,clickConnecting:V,isPossibleEndHandle:X,connectionInProcess:b,clickConnectionInProcess:ee,valid:q}=Ie(sS(E,S,n),Ve);E||(z=(B=N.getState()).onError)==null||z.call(B,"010",Wt.error010());const J=H=>{const{defaultEdgeOptions:j,onConnect:$,hasDefaultEdges:F}=N.getState(),C={...j,...H};if(F){const{edges:R,setEdges:te,onError:re}=N.getState();te(F1(C,R,{onError:re}))}$==null||$(C),h==null||h(C)},Z=H=>{if(!E)return;const j=Wp(H.nativeEvent);if(u&&(j&&H.button===0||!j)){const $=N.getState();Ua.onPointerDown(H.nativeEvent,{handleDomNode:H.currentTarget,autoPanOnConnect:$.autoPanOnConnect,connectionMode:$.connectionMode,connectionRadius:$.connectionRadius,domNode:$.domNode,nodeLookup:$.nodeLookup,lib:$.lib,isTarget:M,handleId:S,nodeId:E,flowId:$.rfId,panBy:$.panBy,cancelConnection:$.cancelConnection,onConnectStart:$.onConnectStart,onConnectEnd:(...F)=>{var C,R;return(R=(C=N.getState()).onConnectEnd)==null?void 0:R.call(C,...F)},updateConnection:$.updateConnection,onConnect:J,isValidConnection:i||((...F)=>{var C,R;return((R=(C=N.getState()).isValidConnection)==null?void 0:R.call(C,...F))??!0}),getTransform:()=>N.getState().transform,getFromHandle:()=>N.getState().connection.fromHandle,autoPanSpeed:$.autoPanSpeed,dragThreshold:$.connectionDragThreshold})}j?v==null||v(H):y==null||y(H)},k=H=>{const{onClickConnectStart:j,onClickConnectEnd:$,connectionClickStartHandle:F,connectionMode:C,isValidConnection:R,lib:te,rfId:re,nodeLookup:ue,connection:ce}=N.getState();if(!E||!F&&!u)return;if(!F){j==null||j(H.nativeEvent,{nodeId:E,handleId:S,handleType:n}),N.setState({connectionClickStartHandle:{nodeId:E,type:n,id:S}});return}const ae=Bp(H.target),G=i||R,{connection:se,isValid:pe}=Ua.isValid(H.nativeEvent,{handle:{nodeId:E,id:S,type:n},connectionMode:C,fromNodeId:F.nodeId,fromHandleId:F.id||null,fromType:F.type,isValidConnection:G,flowId:re,doc:ae,lib:te,nodeLookup:ue});pe&&se&&J(se);const we=structuredClone(ce);delete we.inProgress,we.toPosition=we.toHandle?we.toHandle.position:null,$==null||$(H,we),N.setState({connectionClickStartHandle:null})};return T.jsx("div",{"data-handleid":S,"data-nodeid":E,"data-handlepos":r,"data-id":`${P}-${E}-${S}-${n}`,className:Ye(["react-flow__handle",`react-flow__handle-${r}`,"nodrag",_,m,{source:!M,target:M,connectable:l,connectablestart:u,connectableend:c,clickconnecting:V,connectingfrom:U,connectingto:D,valid:q,connectionindicator:l&&(!b||X)&&(b||ee?c:u)}]),onMouseDown:Z,onTouchStart:Z,onClick:L?k:void 0,ref:w,...g,children:p})}const ll=K.memo(dg(lS));function uS({data:n,isConnectable:r,sourcePosition:i=xe.Bottom}){return T.jsxs(T.Fragment,{children:[n==null?void 0:n.label,T.jsx(ll,{type:"source",position:i,isConnectable:r})]})}function aS({data:n,isConnectable:r,targetPosition:i=xe.Top,sourcePosition:l=xe.Bottom}){return T.jsxs(T.Fragment,{children:[T.jsx(ll,{type:"target",position:i,isConnectable:r}),n==null?void 0:n.label,T.jsx(ll,{type:"source",position:l,isConnectable:r})]})}function cS(){return null}function fS({data:n,isConnectable:r,targetPosition:i=xe.Top}){return T.jsxs(T.Fragment,{children:[T.jsx(ll,{type:"target",position:i,isConnectable:r}),n==null?void 0:n.label]})}const ul={ArrowUp:{x:0,y:-1},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0},ArrowRight:{x:1,y:0}},Fh={input:uS,default:aS,output:fS,group:cS};function dS(n){var r,i,l,u;return n.internals.handleBounds===void 0?{width:n.width??n.initialWidth??((r=n.style)==null?void 0:r.width),height:n.height??n.initialHeight??((i=n.style)==null?void 0:i.height)}:{width:n.width??((l=n.style)==null?void 0:l.width),height:n.height??((u=n.style)==null?void 0:u.height)}}const hS=n=>{const{width:r,height:i,x:l,y:u}=mi(n.nodeLookup,{filter:c=>!!c.selected});return{width:Bt(r)?r:null,height:Bt(i)?i:null,userSelectionActive:n.userSelectionActive,transformString:`translate(${n.transform[0]}px,${n.transform[1]}px) scale(${n.transform[2]}) translate(${l}px,${u}px)`}};function pS({onSelectionContextMenu:n,noPanClassName:r,disableKeyboardA11y:i}){const l=$e(),{width:u,height:c,transformString:f,userSelectionActive:h}=Ie(hS,Ve),p=mg(),m=K.useRef(null);K.useEffect(()=>{var w;i||(w=m.current)==null||w.focus({preventScroll:!0})},[i]);const v=!h&&u!==null&&c!==null;if(gg({nodeRef:m,disabled:!v}),!v)return null;const y=n?w=>{const S=l.getState().nodes.filter(M=>M.selected);n(w,S)}:void 0,g=w=>{Object.prototype.hasOwnProperty.call(ul,w.key)&&(w.preventDefault(),p({direction:ul[w.key],factor:w.shiftKey?4:1}))};return T.jsx("div",{className:Ye(["react-flow__nodesselection","react-flow__container",r]),style:{transform:f},children:T.jsx("div",{ref:m,className:"react-flow__nodesselection-rect",onContextMenu:y,tabIndex:i?void 0:-1,onKeyDown:i?void 0:g,style:{width:u,height:c}})})}const Hh=typeof window<"u"?window:void 0,gS=n=>({nodesSelectionActive:n.nodesSelectionActive,userSelectionActive:n.userSelectionActive});function xg({children:n,onPaneClick:r,onPaneMouseEnter:i,onPaneMouseMove:l,onPaneMouseLeave:u,onPaneContextMenu:c,onPaneScroll:f,paneClickDistance:h,deleteKeyCode:p,selectionKeyCode:m,selectionOnDrag:v,selectionMode:y,onSelectionStart:g,onSelectionEnd:w,multiSelectionKeyCode:S,panActivationKeyCode:M,zoomActivationKeyCode:N,elementsSelectable:E,zoomOnScroll:L,zoomOnPinch:_,panOnScroll:P,panOnScrollSpeed:U,panOnScrollMode:D,zoomOnDoubleClick:V,panOnDrag:X,autoPanOnSelection:b,defaultViewport:ee,translateExtent:q,minZoom:J,maxZoom:Z,preventScrolling:k,onSelectionContextMenu:B,noWheelClassName:z,noPanClassName:H,disableKeyboardA11y:j,onViewportChange:$,isControlledViewport:F}){const{nodesSelectionActive:C,userSelectionActive:R}=Ie(gS,Ve),te=fi(m,{target:Hh}),re=fi(M,{target:Hh}),ue=re||X,ce=re||P,ae=v&&ue!==!0,G=te||R||ae;return X1({deleteKeyCode:p,multiSelectionKeyCode:S}),T.jsx(G1,{onPaneContextMenu:c,elementsSelectable:E,zoomOnScroll:L,zoomOnPinch:_,panOnScroll:ce,panActivationKeyPressed:re,panOnScrollSpeed:U,panOnScrollMode:D,zoomOnDoubleClick:V,panOnDrag:!te&&ue,defaultViewport:ee,translateExtent:q,minZoom:J,maxZoom:Z,zoomActivationKeyCode:N,preventScrolling:k,noWheelClassName:z,noPanClassName:H,onViewportChange:$,isControlledViewport:F,paneClickDistance:h,selectionOnDrag:ae,children:T.jsxs(J1,{onSelectionStart:g,onSelectionEnd:w,onPaneClick:r,onPaneMouseEnter:i,onPaneMouseMove:l,onPaneMouseLeave:u,onPaneContextMenu:c,onPaneScroll:f,panOnDrag:ue,autoPanOnSelection:b,isSelecting:!!G,selectionMode:y,selectionKeyPressed:te,paneClickDistance:h,selectionOnDrag:ae,children:[n,C&&T.jsx(pS,{onSelectionContextMenu:B,noPanClassName:H,disableKeyboardA11y:j})]})})}xg.displayName="FlowRenderer";const mS=K.memo(xg),yS=n=>r=>n?Ja(r.nodeLookup,{x:0,y:0,width:r.width,height:r.height},r.transform,!0).map(i=>i.id):Array.from(r.nodeLookup.keys());function vS(n){return Ie(K.useCallback(yS(n),[n]),Ve)}const xS=n=>n.updateNodeInternals;function wS(){const n=Ie(xS),[r]=K.useState(()=>typeof ResizeObserver>"u"?null:new ResizeObserver(i=>{const l=new Map;i.forEach(u=>{const c=u.target.getAttribute("data-id");l.set(c,{id:c,nodeElement:u.target,force:!0})}),n(l)}));return K.useEffect(()=>()=>{r==null||r.disconnect()},[r]),r}function SS({node:n,nodeType:r,hasDimensions:i,resizeObserver:l}){const u=$e(),c=K.useRef(null),f=K.useRef(null),h=K.useRef(n.sourcePosition),p=K.useRef(n.targetPosition),m=K.useRef(r),v=i&&!!n.internals.handleBounds;return K.useEffect(()=>{c.current&&!n.hidden&&(!v||f.current!==c.current)&&(f.current&&(l==null||l.unobserve(f.current)),l==null||l.observe(c.current),f.current=c.current)},[v,n.hidden]),K.useEffect(()=>()=>{f.current&&(l==null||l.unobserve(f.current),f.current=null)},[]),K.useEffect(()=>{if(c.current){const y=m.current!==r,g=h.current!==n.sourcePosition,w=p.current!==n.targetPosition;(y||g||w)&&(m.current=r,h.current=n.sourcePosition,p.current=n.targetPosition,u.getState().updateNodeInternals(new Map([[n.id,{id:n.id,nodeElement:c.current,force:!0}]])))}},[n.id,r,n.sourcePosition,n.targetPosition]),c}function _S({id:n,onClick:r,onMouseEnter:i,onMouseMove:l,onMouseLeave:u,onContextMenu:c,onDoubleClick:f,nodesDraggable:h,elementsSelectable:p,nodesConnectable:m,nodesFocusable:v,resizeObserver:y,noDragClassName:g,noPanClassName:w,disableKeyboardA11y:S,rfId:M,nodeTypes:N,nodeClickDistance:E,onError:L}){const{node:_,internals:P,isParent:U}=Ie(G=>{const se=G.nodeLookup.get(n),pe=G.parentLookup.has(n);return{node:se,internals:se.internals,isParent:pe}},Ve);let D=_.type||"default",V=(N==null?void 0:N[D])||Fh[D];V===void 0&&(L==null||L("003",Wt.error003(D)),D="default",V=(N==null?void 0:N.default)||Fh.default);const X=!!(_.draggable||h&&typeof _.draggable>"u"),b=!!(_.selectable||p&&typeof _.selectable>"u"),ee=!!(_.connectable||m&&typeof _.connectable>"u"),q=!!(_.focusable||v&&typeof _.focusable>"u"),J=$e(),Z=Hp(_),k=SS({node:_,nodeType:D,hasDimensions:Z,resizeObserver:y}),B=gg({nodeRef:k,disabled:_.hidden||!X,noDragClassName:g,handleSelector:_.dragHandle,nodeId:n,isSelectable:b,nodeClickDistance:E}),z=mg();if(_.hidden)return null;const H=Xt(_),j=dS(_),$=b||X||r||i||l||u,F=i?G=>i(G,{...P.userNode}):void 0,C=l?G=>l(G,{...P.userNode}):void 0,R=u?G=>u(G,{...P.userNode}):void 0,te=c?G=>c(G,{...P.userNode}):void 0,re=f?G=>f(G,{...P.userNode}):void 0,ue=G=>{const{selectNodesOnDrag:se,nodeDragThreshold:pe}=J.getState();b&&(!se||!X||pe>0)&&Wa({id:n,store:J,nodeRef:k}),r&&r(G,{...P.userNode})},ce=G=>{if(!(Up(G.nativeEvent)||S)){if(zp.includes(G.key)&&b){const se=G.key==="Escape";Wa({id:n,store:J,unselect:se,nodeRef:k})}else if(X&&_.selected&&Object.prototype.hasOwnProperty.call(ul,G.key)){G.preventDefault();const{ariaLabelConfig:se}=J.getState();J.setState({ariaLiveMessage:se["node.a11yDescription.ariaLiveMessage"]({direction:G.key.replace("Arrow","").toLowerCase(),x:~~P.positionAbsolute.x,y:~~P.positionAbsolute.y})}),z({direction:ul[G.key],factor:G.shiftKey?4:1})}}},ae=()=>{var ke;if(S||!((ke=k.current)!=null&&ke.matches(":focus-visible")))return;const{transform:G,width:se,height:pe,autoPanOnNodeFocus:we,setCenter:ve}=J.getState();if(!we)return;Ja(new Map([[n,_]]),{x:0,y:0,width:se,height:pe},G,!0).length>0||ve(_.position.x+H.width/2,_.position.y+H.height/2,{zoom:G[2]})};return T.jsx("div",{className:Ye(["react-flow__node",`react-flow__node-${D}`,{[w]:X},_.className,{selected:_.selected,selectable:b,parent:U,draggable:X,dragging:B}]),ref:k,style:{zIndex:P.z,transform:`translate(${P.positionAbsolute.x}px,${P.positionAbsolute.y}px)`,pointerEvents:$?"all":"none",visibility:Z?"visible":"hidden",..._.style,...j},"data-id":n,"data-testid":`rf__node-${n}`,onMouseEnter:F,onMouseMove:C,onMouseLeave:R,onContextMenu:te,onClick:ue,onDoubleClick:re,onKeyDown:q?ce:void 0,tabIndex:q?0:void 0,onFocus:q?ae:void 0,role:_.ariaRole??(q?"group":void 0),"aria-roledescription":"node","aria-describedby":S?void 0:`${ug}-${M}`,"aria-label":_.ariaLabel,..._.domAttributes,children:T.jsx(tS,{value:n,children:T.jsx(V,{id:n,data:_.data,type:D,positionAbsoluteX:P.positionAbsolute.x,positionAbsoluteY:P.positionAbsolute.y,selected:_.selected??!1,selectable:b,draggable:X,deletable:_.deletable??!0,isConnectable:ee,sourcePosition:_.sourcePosition,targetPosition:_.targetPosition,dragging:B,dragHandle:_.dragHandle,zIndex:P.z,parentId:_.parentId,...H})})})}var ES=K.memo(_S);const kS=n=>({nodesConnectable:n.nodesConnectable,nodesFocusable:n.nodesFocusable,elementsSelectable:n.elementsSelectable,onError:n.onError});function wg(n){const{nodesConnectable:r,nodesFocusable:i,elementsSelectable:l,onError:u}=Ie(kS,Ve),c=vS(n.onlyRenderVisibleElements),f=wS();return T.jsx("div",{className:"react-flow__nodes",style:xl,children:c.map(h=>T.jsx(ES,{id:h,nodeTypes:n.nodeTypes,nodeExtent:n.nodeExtent,onClick:n.onNodeClick,onMouseEnter:n.onNodeMouseEnter,onMouseMove:n.onNodeMouseMove,onMouseLeave:n.onNodeMouseLeave,onContextMenu:n.onNodeContextMenu,onDoubleClick:n.onNodeDoubleClick,noDragClassName:n.noDragClassName,noPanClassName:n.noPanClassName,rfId:n.rfId,disableKeyboardA11y:n.disableKeyboardA11y,resizeObserver:f,nodesDraggable:n.nodesDraggable??!0,nodesConnectable:r,nodesFocusable:i,elementsSelectable:l,nodeClickDistance:n.nodeClickDistance,onError:u},h))})}wg.displayName="NodeRenderer";const NS=K.memo(wg);function CS(n){return Ie(K.useCallback(i=>{if(!n)return i.edges.map(u=>u.id);const l=[];if(i.width&&i.height)for(const u of i.edges){const c=i.nodeLookup.get(u.source),f=i.nodeLookup.get(u.target);c&&f&&xw({sourceNode:c,targetNode:f,width:i.width,height:i.height,transform:i.transform})&&l.push(u.id)}return l},[n]),Ve)}const MS=({color:n="none",strokeWidth:r=1})=>{const i={strokeWidth:r,...n&&{stroke:n}};return T.jsx("polyline",{className:"arrow",style:i,strokeLinecap:"round",fill:"none",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4"})},PS=({color:n="none",strokeWidth:r=1})=>{const i={strokeWidth:r,...n&&{stroke:n,fill:n}};return T.jsx("polyline",{className:"arrowclosed",style:i,strokeLinecap:"round",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4 -5,-4"})},Vh={[ol.Arrow]:MS,[ol.ArrowClosed]:PS};function IS(n){const r=$e();return K.useMemo(()=>{var u,c;return Object.prototype.hasOwnProperty.call(Vh,n)?Vh[n]:((c=(u=r.getState()).onError)==null||c.call(u,"009",Wt.error009(n)),null)},[n])}const zS=({id:n,type:r,color:i,width:l=12.5,height:u=12.5,markerUnits:c="strokeWidth",strokeWidth:f,orient:h="auto-start-reverse"})=>{const p=IS(r);return p?T.jsx("marker",{className:"react-flow__arrowhead",id:n,markerWidth:`${l}`,markerHeight:`${u}`,viewBox:"-10 -10 20 20",markerUnits:c,orient:h,refX:"0",refY:"0",children:T.jsx(p,{color:i,strokeWidth:f})}):null},Sg=({defaultColor:n,rfId:r})=>{const i=Ie(c=>c.edges),l=Ie(c=>c.defaultEdgeOptions),u=K.useMemo(()=>Mw(i,{id:r,defaultColor:n,defaultMarkerStart:l==null?void 0:l.markerStart,defaultMarkerEnd:l==null?void 0:l.markerEnd}),[i,l,r,n]);return u.length?T.jsx("svg",{className:"react-flow__marker","aria-hidden":"true",children:T.jsx("defs",{children:u.map(c=>T.jsx(zS,{id:c.id,type:c.type,color:c.color,width:c.width,height:c.height,markerUnits:c.markerUnits,strokeWidth:c.strokeWidth,orient:c.orient},c.id))})}):null};Sg.displayName="MarkerDefinitions";var TS=K.memo(Sg);function _g({x:n,y:r,label:i,labelStyle:l,labelShowBg:u=!0,labelBgStyle:c,labelBgPadding:f=[2,4],labelBgBorderRadius:h=2,children:p,className:m,...v}){const[y,g]=K.useState({x:1,y:0,width:0,height:0}),w=Ye(["react-flow__edge-textwrapper",m]),S=K.useRef(null);return K.useEffect(()=>{if(S.current){const M=S.current.getBBox();g({x:M.x,y:M.y,width:M.width,height:M.height})}},[i]),i?T.jsxs("g",{transform:`translate(${n-y.width/2} ${r-y.height/2})`,className:w,visibility:y.width?"visible":"hidden",...v,children:[u&&T.jsx("rect",{width:y.width+2*f[0],x:-f[0],y:-f[1],height:y.height+2*f[1],className:"react-flow__edge-textbg",style:c,rx:h,ry:h}),T.jsx("text",{className:"react-flow__edge-text",y:y.height/2,dy:"0.3em",ref:S,style:l,children:i}),p]}):null}_g.displayName="EdgeText";const LS=K.memo(_g);function wl({path:n,labelX:r,labelY:i,label:l,labelStyle:u,labelShowBg:c,labelBgStyle:f,labelBgPadding:h,labelBgBorderRadius:p,interactionWidth:m=20,...v}){return T.jsxs(T.Fragment,{children:[T.jsx("path",{...v,d:n,fill:"none",className:Ye(["react-flow__edge-path",v.className])}),m?T.jsx("path",{d:n,fill:"none",strokeOpacity:0,strokeWidth:m,className:"react-flow__edge-interaction"}):null,l&&Bt(r)&&Bt(i)?T.jsx(LS,{x:r,y:i,label:l,labelStyle:u,labelShowBg:c,labelBgStyle:f,labelBgPadding:h,labelBgBorderRadius:p}):null]})}function Bh({pos:n,x1:r,y1:i,x2:l,y2:u}){return n===xe.Left||n===xe.Right?[.5*(r+l),i]:[r,.5*(i+u)]}function Eg({sourceX:n,sourceY:r,sourcePosition:i=xe.Bottom,targetX:l,targetY:u,targetPosition:c=xe.Top}){const[f,h]=Bh({pos:i,x1:n,y1:r,x2:l,y2:u}),[p,m]=Bh({pos:c,x1:l,y1:u,x2:n,y2:r}),[v,y,g,w]=Yp({sourceX:n,sourceY:r,targetX:l,targetY:u,sourceControlX:f,sourceControlY:h,targetControlX:p,targetControlY:m});return[`M${n},${r} C${f},${h} ${p},${m} ${l},${u}`,v,y,g,w]}function kg(n){return K.memo(({id:r,sourceX:i,sourceY:l,targetX:u,targetY:c,sourcePosition:f,targetPosition:h,label:p,labelStyle:m,labelShowBg:v,labelBgStyle:y,labelBgPadding:g,labelBgBorderRadius:w,style:S,markerEnd:M,markerStart:N,interactionWidth:E})=>{const[L,_,P]=Eg({sourceX:i,sourceY:l,sourcePosition:f,targetX:u,targetY:c,targetPosition:h}),U=n.isInternal?void 0:r;return T.jsx(wl,{id:U,path:L,labelX:_,labelY:P,label:p,labelStyle:m,labelShowBg:v,labelBgStyle:y,labelBgPadding:g,labelBgBorderRadius:w,style:S,markerEnd:M,markerStart:N,interactionWidth:E})})}const RS=kg({isInternal:!1}),Ng=kg({isInternal:!0});RS.displayName="SimpleBezierEdge";Ng.displayName="SimpleBezierEdgeInternal";function Cg(n){return K.memo(({id:r,sourceX:i,sourceY:l,targetX:u,targetY:c,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:m,labelBgPadding:v,labelBgBorderRadius:y,style:g,sourcePosition:w=xe.Bottom,targetPosition:S=xe.Top,markerEnd:M,markerStart:N,pathOptions:E,interactionWidth:L})=>{const[_,P,U]=Ha({sourceX:i,sourceY:l,sourcePosition:w,targetX:u,targetY:c,targetPosition:S,borderRadius:E==null?void 0:E.borderRadius,offset:E==null?void 0:E.offset,stepPosition:E==null?void 0:E.stepPosition}),D=n.isInternal?void 0:r;return T.jsx(wl,{id:D,path:_,labelX:P,labelY:U,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:m,labelBgPadding:v,labelBgBorderRadius:y,style:g,markerEnd:M,markerStart:N,interactionWidth:L})})}const Mg=Cg({isInternal:!1}),Pg=Cg({isInternal:!0});Mg.displayName="SmoothStepEdge";Pg.displayName="SmoothStepEdgeInternal";function Ig(n){return K.memo(({id:r,...i})=>{var u;const l=n.isInternal?void 0:r;return T.jsx(Mg,{...i,id:l,pathOptions:K.useMemo(()=>{var c;return{borderRadius:0,offset:(c=i.pathOptions)==null?void 0:c.offset}},[(u=i.pathOptions)==null?void 0:u.offset])})})}const AS=Ig({isInternal:!1}),zg=Ig({isInternal:!0});AS.displayName="StepEdge";zg.displayName="StepEdgeInternal";function Tg(n){return K.memo(({id:r,sourceX:i,sourceY:l,targetX:u,targetY:c,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:m,labelBgPadding:v,labelBgBorderRadius:y,style:g,markerEnd:w,markerStart:S,interactionWidth:M})=>{const[N,E,L]=Qp({sourceX:i,sourceY:l,targetX:u,targetY:c}),_=n.isInternal?void 0:r;return T.jsx(wl,{id:_,path:N,labelX:E,labelY:L,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:m,labelBgPadding:v,labelBgBorderRadius:y,style:g,markerEnd:w,markerStart:S,interactionWidth:M})})}const jS=Tg({isInternal:!1}),Lg=Tg({isInternal:!0});jS.displayName="StraightEdge";Lg.displayName="StraightEdgeInternal";function Rg(n){return K.memo(({id:r,sourceX:i,sourceY:l,targetX:u,targetY:c,sourcePosition:f=xe.Bottom,targetPosition:h=xe.Top,label:p,labelStyle:m,labelShowBg:v,labelBgStyle:y,labelBgPadding:g,labelBgBorderRadius:w,style:S,markerEnd:M,markerStart:N,pathOptions:E,interactionWidth:L})=>{const[_,P,U]=Xp({sourceX:i,sourceY:l,sourcePosition:f,targetX:u,targetY:c,targetPosition:h,curvature:E==null?void 0:E.curvature}),D=n.isInternal?void 0:r;return T.jsx(wl,{id:D,path:_,labelX:P,labelY:U,label:p,labelStyle:m,labelShowBg:v,labelBgStyle:y,labelBgPadding:g,labelBgBorderRadius:w,style:S,markerEnd:M,markerStart:N,interactionWidth:L})})}const $S=Rg({isInternal:!1}),Ag=Rg({isInternal:!0});$S.displayName="BezierEdge";Ag.displayName="BezierEdgeInternal";const Uh={default:Ag,straight:Lg,step:zg,smoothstep:Pg,simplebezier:Ng},Wh={sourceX:null,sourceY:null,targetX:null,targetY:null,sourcePosition:null,targetPosition:null,zIndex:void 0},DS=(n,r,i)=>i===xe.Left?n-r:i===xe.Right?n+r:n,OS=(n,r,i)=>i===xe.Top?n-r:i===xe.Bottom?n+r:n,Yh="react-flow__edgeupdater";function Xh({position:n,centerX:r,centerY:i,radius:l=10,onMouseDown:u,onMouseEnter:c,onMouseOut:f,type:h}){return T.jsx("circle",{onMouseDown:u,onMouseEnter:c,onMouseOut:f,className:Ye([Yh,`${Yh}-${h}`]),cx:DS(r,l,n),cy:OS(i,l,n),r:l,stroke:"transparent",fill:"transparent"})}function FS({isReconnectable:n,reconnectRadius:r,edge:i,sourceX:l,sourceY:u,targetX:c,targetY:f,sourcePosition:h,targetPosition:p,onReconnect:m,onReconnectStart:v,onReconnectEnd:y,setReconnecting:g,setUpdateHover:w}){const S=$e(),M=(P,U)=>{if(P.button!==0)return;const{autoPanOnConnect:D,domNode:V,connectionMode:X,connectionRadius:b,lib:ee,onConnectStart:q,cancelConnection:J,nodeLookup:Z,rfId:k,panBy:B,updateConnection:z}=S.getState(),H=U.type==="target",j=(C,R)=>{g(!1),y==null||y(C,i,U.type,R)},$=C=>m==null?void 0:m(i,C),F=(C,R)=>{g(!0),v==null||v(P,i,U.type),q==null||q(C,R)};Ua.onPointerDown(P.nativeEvent,{autoPanOnConnect:D,connectionMode:X,connectionRadius:b,domNode:V,handleId:U.id,nodeId:U.nodeId,nodeLookup:Z,isTarget:H,edgeUpdaterType:U.type,lib:ee,flowId:k,cancelConnection:J,panBy:B,isValidConnection:(...C)=>{var R,te;return((te=(R=S.getState()).isValidConnection)==null?void 0:te.call(R,...C))??!0},onConnect:$,onConnectStart:F,onConnectEnd:(...C)=>{var R,te;return(te=(R=S.getState()).onConnectEnd)==null?void 0:te.call(R,...C)},onReconnectEnd:j,updateConnection:z,getTransform:()=>S.getState().transform,getFromHandle:()=>S.getState().connection.fromHandle,dragThreshold:S.getState().connectionDragThreshold,handleDomNode:P.currentTarget})},N=P=>M(P,{nodeId:i.target,id:i.targetHandle??null,type:"target"}),E=P=>M(P,{nodeId:i.source,id:i.sourceHandle??null,type:"source"}),L=()=>w(!0),_=()=>w(!1);return T.jsxs(T.Fragment,{children:[(n===!0||n==="source")&&T.jsx(Xh,{position:h,centerX:l,centerY:u,radius:r,onMouseDown:N,onMouseEnter:L,onMouseOut:_,type:"source"}),(n===!0||n==="target")&&T.jsx(Xh,{position:p,centerX:c,centerY:f,radius:r,onMouseDown:E,onMouseEnter:L,onMouseOut:_,type:"target"})]})}function HS({id:n,edgesFocusable:r,edgesReconnectable:i,elementsSelectable:l,onClick:u,onDoubleClick:c,onContextMenu:f,onMouseEnter:h,onMouseMove:p,onMouseLeave:m,reconnectRadius:v,onReconnect:y,onReconnectStart:g,onReconnectEnd:w,rfId:S,edgeTypes:M,noPanClassName:N,onError:E,disableKeyboardA11y:L}){let _=Ie(ve=>ve.edgeLookup.get(n));const P=Ie(ve=>ve.defaultEdgeOptions);_=P?{...P,..._}:_;let U=_.type||"default",D=(M==null?void 0:M[U])||Uh[U];D===void 0&&(E==null||E("011",Wt.error011(U)),U="default",D=(M==null?void 0:M.default)||Uh.default);const V=!!(_.focusable||r&&typeof _.focusable>"u"),X=typeof y<"u"&&(_.reconnectable||i&&typeof _.reconnectable>"u"),b=!!(_.selectable||l&&typeof _.selectable>"u"),ee=K.useRef(null),[q,J]=K.useState(!1),[Z,k]=K.useState(!1),B=$e(),{zIndex:z=_.zIndex,sourceX:H,sourceY:j,targetX:$,targetY:F,sourcePosition:C,targetPosition:R}=Ie(K.useCallback(ve=>{const me=ve.nodeLookup.get(_.source),ke=ve.nodeLookup.get(_.target);if(!me||!ke)return Wh;const Ce=Cw({id:n,sourceNode:me,targetNode:ke,sourceHandle:_.sourceHandle||null,targetHandle:_.targetHandle||null,connectionMode:ve.connectionMode,onError:E}),Me=vw({selected:_.selected,zIndex:_.zIndex,sourceNode:me,targetNode:ke,elevateOnSelect:ve.elevateEdgesOnSelect,zIndexMode:ve.zIndexMode});return{...Ce||Wh,zIndex:Me}},[_.source,_.target,_.sourceHandle,_.targetHandle,_.selected,_.zIndex,E]),Ve),te=K.useMemo(()=>_.markerStart?`url('#${Va(_.markerStart,S)}')`:void 0,[_.markerStart,S]),re=K.useMemo(()=>_.markerEnd?`url('#${Va(_.markerEnd,S)}')`:void 0,[_.markerEnd,S]);if(_.hidden||H===null||j===null||$===null||F===null)return null;const ue=ve=>{var Me;const{addSelectedEdges:me,unselectNodesAndEdges:ke,multiSelectionActive:Ce}=B.getState();b&&(B.setState({nodesSelectionActive:!1}),_.selected&&Ce?(ke({nodes:[],edges:[_]}),(Me=ee.current)==null||Me.blur()):me([n])),u&&u(ve,_)},ce=c?ve=>{c(ve,{..._})}:void 0,ae=f?ve=>{f(ve,{..._})}:void 0,G=h?ve=>{h(ve,{..._})}:void 0,se=p?ve=>{p(ve,{..._})}:void 0,pe=m?ve=>{m(ve,{..._})}:void 0,we=ve=>{var me;if(!L&&zp.includes(ve.key)&&b){const{unselectNodesAndEdges:ke,addSelectedEdges:Ce}=B.getState();ve.key==="Escape"?((me=ee.current)==null||me.blur(),ke({edges:[_]})):Ce([n])}};return T.jsx("svg",{style:{zIndex:z},children:T.jsxs("g",{className:Ye(["react-flow__edge",`react-flow__edge-${U}`,_.className,N,{selected:_.selected,animated:_.animated,inactive:!b&&!u,updating:q,selectable:b}]),onClick:ue,onDoubleClick:ce,onContextMenu:ae,onMouseEnter:G,onMouseMove:se,onMouseLeave:pe,onKeyDown:V?we:void 0,tabIndex:V?0:void 0,role:_.ariaRole??(V?"group":"img"),"aria-roledescription":"edge","data-id":n,"data-testid":`rf__edge-${n}`,"aria-label":_.ariaLabel===null?void 0:_.ariaLabel||`Edge from ${_.source} to ${_.target}`,"aria-describedby":V?`${ag}-${S}`:void 0,ref:ee,..._.domAttributes,children:[!Z&&T.jsx(D,{id:n,source:_.source,target:_.target,type:_.type,selected:_.selected,animated:_.animated,selectable:b,deletable:_.deletable??!0,label:_.label,labelStyle:_.labelStyle,labelShowBg:_.labelShowBg,labelBgStyle:_.labelBgStyle,labelBgPadding:_.labelBgPadding,labelBgBorderRadius:_.labelBgBorderRadius,sourceX:H,sourceY:j,targetX:$,targetY:F,sourcePosition:C,targetPosition:R,data:_.data,style:_.style,sourceHandleId:_.sourceHandle,targetHandleId:_.targetHandle,markerStart:te,markerEnd:re,pathOptions:"pathOptions"in _?_.pathOptions:void 0,interactionWidth:_.interactionWidth}),X&&T.jsx(FS,{edge:_,isReconnectable:X,reconnectRadius:v,onReconnect:y,onReconnectStart:g,onReconnectEnd:w,sourceX:H,sourceY:j,targetX:$,targetY:F,sourcePosition:C,targetPosition:R,setUpdateHover:J,setReconnecting:k})]})})}var VS=K.memo(HS);const BS=n=>({edgesFocusable:n.edgesFocusable,edgesReconnectable:n.edgesReconnectable,elementsSelectable:n.elementsSelectable,connectionMode:n.connectionMode,onError:n.onError});function jg({defaultMarkerColor:n,onlyRenderVisibleElements:r,rfId:i,edgeTypes:l,noPanClassName:u,onReconnect:c,onEdgeContextMenu:f,onEdgeMouseEnter:h,onEdgeMouseMove:p,onEdgeMouseLeave:m,onEdgeClick:v,reconnectRadius:y,onEdgeDoubleClick:g,onReconnectStart:w,onReconnectEnd:S,disableKeyboardA11y:M}){const{edgesFocusable:N,edgesReconnectable:E,elementsSelectable:L,onError:_}=Ie(BS,Ve),P=CS(r);return T.jsxs("div",{className:"react-flow__edges",children:[T.jsx(TS,{defaultColor:n,rfId:i}),P.map(U=>T.jsx(VS,{id:U,edgesFocusable:N,edgesReconnectable:E,elementsSelectable:L,noPanClassName:u,onReconnect:c,onContextMenu:f,onMouseEnter:h,onMouseMove:p,onMouseLeave:m,onClick:v,reconnectRadius:y,onDoubleClick:g,onReconnectStart:w,onReconnectEnd:S,rfId:i,onError:_,edgeTypes:l,disableKeyboardA11y:M},U))]})}jg.displayName="EdgeRenderer";const US=K.memo(jg),bh=n=>`translate(${n[0]}px,${n[1]}px) scale(${n[2]})`;function WS({children:n}){const r=$e(),i=K.useRef(null),[l]=K.useState(()=>r.getState().transform);return hg(()=>{let u=null;const c=()=>{const f=r.getState().transform;u&&f[0]===u[0]&&f[1]===u[1]&&f[2]===u[2]||(u=f,i.current&&(i.current.style.transform=bh(f)))};return c(),r.subscribe(c)},[r]),T.jsx("div",{ref:i,className:"react-flow__viewport xyflow__viewport react-flow__container",style:{transform:bh(l)},children:n})}function YS(n){const r=uc(),i=K.useRef(!1);K.useEffect(()=>{!i.current&&r.viewportInitialized&&n&&(setTimeout(()=>n(r),1),i.current=!0)},[n,r.viewportInitialized])}const XS=n=>{var r;return(r=n.panZoom)==null?void 0:r.syncViewport};function bS(n){const r=Ie(XS),i=$e();return K.useEffect(()=>{n&&(r==null||r(n),i.setState({transform:[n.x,n.y,n.zoom]}))},[n,r]),null}function QS(n){return n.connection.inProgress?{...n.connection,to:vi(n.connection.to,n.transform)}:{...n.connection}}function GS(n){return QS}function KS(n){const r=GS();return Ie(r,Ve)}const qS=n=>({nodesConnectable:n.nodesConnectable,isValid:n.connection.isValid,inProgress:n.connection.inProgress,width:n.width,height:n.height});function ZS({containerStyle:n,style:r,type:i,component:l}){const{nodesConnectable:u,width:c,height:f,isValid:h,inProgress:p}=Ie(qS,Ve);return!(c&&u&&p)?null:T.jsx("svg",{style:n,width:c,height:f,className:"react-flow__connectionline react-flow__container",children:T.jsx("g",{className:Ye(["react-flow__connection",Rp(h)]),children:T.jsx($g,{style:r,type:i,CustomComponent:l,isValid:h})})})}const $g=({style:n,type:r=Un.Bezier,CustomComponent:i,isValid:l})=>{const{inProgress:u,from:c,fromNode:f,fromHandle:h,fromPosition:p,to:m,toNode:v,toHandle:y,toPosition:g,pointer:w}=KS();if(!u)return;if(i)return T.jsx(i,{connectionLineType:r,connectionLineStyle:n,fromNode:f,fromHandle:h,fromX:c.x,fromY:c.y,toX:m.x,toY:m.y,fromPosition:p,toPosition:g,connectionStatus:Rp(l),toNode:v,toHandle:y,pointer:w});let S="";const M={sourceX:c.x,sourceY:c.y,sourcePosition:p,targetX:m.x,targetY:m.y,targetPosition:g};switch(r){case Un.Bezier:[S]=Xp(M);break;case Un.SimpleBezier:[S]=Eg(M);break;case Un.Step:[S]=Ha({...M,borderRadius:0});break;case Un.SmoothStep:[S]=Ha(M);break;default:[S]=Qp(M)}return T.jsx("path",{d:S,fill:"none",className:"react-flow__connection-path",style:n})};$g.displayName="ConnectionLine";const JS={};function Qh(n=JS){K.useRef(n),$e(),K.useEffect(()=>{},[n])}function e_(){$e(),K.useRef(!1),K.useEffect(()=>{},[])}function Dg({nodeTypes:n,edgeTypes:r,onInit:i,onNodeClick:l,onEdgeClick:u,onNodeDoubleClick:c,onEdgeDoubleClick:f,onNodeMouseEnter:h,onNodeMouseMove:p,onNodeMouseLeave:m,onNodeContextMenu:v,onSelectionContextMenu:y,onSelectionStart:g,onSelectionEnd:w,connectionLineType:S,connectionLineStyle:M,connectionLineComponent:N,connectionLineContainerStyle:E,selectionKeyCode:L,selectionOnDrag:_,selectionMode:P,multiSelectionKeyCode:U,panActivationKeyCode:D,zoomActivationKeyCode:V,deleteKeyCode:X,onlyRenderVisibleElements:b,elementsSelectable:ee,defaultViewport:q,translateExtent:J,minZoom:Z,maxZoom:k,preventScrolling:B,defaultMarkerColor:z,zoomOnScroll:H,zoomOnPinch:j,panOnScroll:$,panOnScrollSpeed:F,panOnScrollMode:C,zoomOnDoubleClick:R,panOnDrag:te,autoPanOnSelection:re,onPaneClick:ue,onPaneMouseEnter:ce,onPaneMouseMove:ae,onPaneMouseLeave:G,onPaneScroll:se,onPaneContextMenu:pe,paneClickDistance:we,nodeClickDistance:ve,onEdgeContextMenu:me,onEdgeMouseEnter:ke,onEdgeMouseMove:Ce,onEdgeMouseLeave:Me,reconnectRadius:Le,onReconnect:it,onReconnectStart:ut,onReconnectEnd:Je,noDragClassName:et,noWheelClassName:rn,noPanClassName:bt,disableKeyboardA11y:Qt,nodeExtent:at,rfId:Ct,viewport:yt,onViewportChange:Mt,nodesDraggable:xr}){return Qh(n),Qh(r),e_(),YS(i),bS(yt),T.jsx(mS,{onPaneClick:ue,onPaneMouseEnter:ce,onPaneMouseMove:ae,onPaneMouseLeave:G,onPaneContextMenu:pe,onPaneScroll:se,paneClickDistance:we,deleteKeyCode:X,selectionKeyCode:L,selectionOnDrag:_,selectionMode:P,onSelectionStart:g,onSelectionEnd:w,multiSelectionKeyCode:U,panActivationKeyCode:D,zoomActivationKeyCode:V,elementsSelectable:ee,zoomOnScroll:H,zoomOnPinch:j,zoomOnDoubleClick:R,panOnScroll:$,panOnScrollSpeed:F,panOnScrollMode:C,panOnDrag:te,autoPanOnSelection:re,defaultViewport:q,translateExtent:J,minZoom:Z,maxZoom:k,onSelectionContextMenu:y,preventScrolling:B,noDragClassName:et,noWheelClassName:rn,noPanClassName:bt,disableKeyboardA11y:Qt,onViewportChange:Mt,isControlledViewport:!!yt,children:T.jsxs(WS,{children:[T.jsx(US,{edgeTypes:r,onEdgeClick:u,onEdgeDoubleClick:f,onReconnect:it,onReconnectStart:ut,onReconnectEnd:Je,onlyRenderVisibleElements:b,onEdgeContextMenu:me,onEdgeMouseEnter:ke,onEdgeMouseMove:Ce,onEdgeMouseLeave:Me,reconnectRadius:Le,defaultMarkerColor:z,noPanClassName:bt,disableKeyboardA11y:Qt,rfId:Ct}),T.jsx(ZS,{style:M,type:S,component:N,containerStyle:E}),T.jsx("div",{className:"react-flow__edgelabel-renderer"}),T.jsx(NS,{nodeTypes:n,onNodeClick:l,onNodeDoubleClick:c,onNodeMouseEnter:h,onNodeMouseMove:p,onNodeMouseLeave:m,onNodeContextMenu:v,nodeClickDistance:ve,onlyRenderVisibleElements:b,noPanClassName:bt,noDragClassName:et,disableKeyboardA11y:Qt,nodeExtent:at,rfId:Ct,nodesDraggable:xr}),T.jsx("div",{className:"react-flow__viewport-portal"})]})})}Dg.displayName="GraphView";const t_=K.memo(Dg),n_=Fp(),Gh=({nodes:n,edges:r,defaultNodes:i,defaultEdges:l,width:u,height:c,fitView:f,fitViewOptions:h,minZoom:p=.5,maxZoom:m=2,nodeOrigin:v,nodeExtent:y,zIndexMode:g="basic"}={})=>{const w=new Map,S=new Map,M=new Map,N=new Map,E=l??r??[],L=i??n??[],_=v??[0,0],P=y??li;qp(M,N,E);const{nodesInitialized:U}=Ba(L,w,S,{nodeOrigin:_,nodeExtent:P,zIndexMode:g});let D=[0,0,1];if(f&&u&&c){const V=mi(w,{filter:q=>!!((q.width||q.initialWidth)&&(q.height||q.initialHeight))}),{x:X,y:b,zoom:ee}=tc(V,u,c,p,m,(h==null?void 0:h.padding)??.1);D=[X,b,ee]}return{rfId:"1",width:u??0,height:c??0,transform:D,nodes:L,nodesInitialized:U,nodeLookup:w,parentLookup:S,edges:E,edgeLookup:N,connectionLookup:M,onNodesChange:null,onEdgesChange:null,hasDefaultNodes:i!==void 0,hasDefaultEdges:l!==void 0,panZoom:null,minZoom:p,maxZoom:m,translateExtent:li,nodeExtent:P,nodesSelectionActive:!1,userSelectionActive:!1,userSelectionRect:null,connectionMode:no.Strict,domNode:null,paneDragging:!1,noPanClassName:"nopan",nodeOrigin:_,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:f??!1,fitViewOptions:h,fitViewResolver:null,connection:{...Lp},connectionClickStartHandle:null,connectOnClick:!0,ariaLiveMessage:"",autoPanOnConnect:!0,autoPanOnNodeDrag:!0,autoPanOnNodeFocus:!0,autoPanSpeed:15,connectionRadius:20,onError:n_,isValidConnection:void 0,onSelectionChangeHandlers:[],lib:"react",debug:!1,ariaLabelConfig:Tp,zIndexMode:g,onNodesChangeMiddlewareMap:new Map,onEdgesChangeMiddlewareMap:new Map}},r_=({nodes:n,edges:r,defaultNodes:i,defaultEdges:l,width:u,height:c,fitView:f,fitViewOptions:h,minZoom:p,maxZoom:m,nodeOrigin:v,nodeExtent:y,zIndexMode:g})=>g1((w,S)=>{async function M(){const{nodeLookup:N,panZoom:E,fitViewOptions:L,fitViewResolver:_,width:P,height:U,minZoom:D,maxZoom:V}=S();E&&(await fw({nodes:N,width:P,height:U,panZoom:E,minZoom:D,maxZoom:V},L),_==null||_.resolve(!0),w({fitViewResolver:null}))}return{...Gh({nodes:n,edges:r,width:u,height:c,fitView:f,fitViewOptions:h,minZoom:p,maxZoom:m,nodeOrigin:v,nodeExtent:y,defaultNodes:i,defaultEdges:l,zIndexMode:g}),setNodes:N=>{const{nodeLookup:E,parentLookup:L,nodeOrigin:_,nodeExtent:P,elevateNodesOnSelect:U,fitViewQueued:D,zIndexMode:V,nodesSelectionActive:X}=S(),{nodesInitialized:b,hasSelectedNodes:ee}=Ba(N,E,L,{nodeOrigin:_,nodeExtent:P,elevateNodesOnSelect:U,checkEquality:!0,zIndexMode:V}),q=X&ⅇD&&b?(M(),w({nodes:N,nodesInitialized:b,fitViewQueued:!1,fitViewOptions:void 0,nodesSelectionActive:q})):w({nodes:N,nodesInitialized:b,nodesSelectionActive:q})},setEdges:N=>{const{connectionLookup:E,edgeLookup:L}=S();qp(E,L,N),w({edges:N})},setDefaultNodesAndEdges:(N,E)=>{if(N){const{setNodes:L}=S();L(N),w({hasDefaultNodes:!0})}if(E){const{setEdges:L}=S();L(E),w({hasDefaultEdges:!0})}},updateNodeInternals:N=>{const{triggerNodeChanges:E,nodeLookup:L,parentLookup:_,domNode:P,nodeOrigin:U,nodeExtent:D,debug:V,fitViewQueued:X,zIndexMode:b}=S(),{changes:ee,updatedInternals:q}=Aw(N,L,_,P,U,D,b);q&&(zw(L,_,{nodeOrigin:U,nodeExtent:D,zIndexMode:b}),X?(M(),w({fitViewQueued:!1,fitViewOptions:void 0})):w({}),(ee==null?void 0:ee.length)>0&&(V&&console.log("React Flow: trigger node changes",ee),E==null||E(ee)))},updateNodePositions:(N,E=!1)=>{const L=[];let _=[];const{nodeLookup:P,triggerNodeChanges:U,connection:D,updateConnection:V,onNodesChangeMiddlewareMap:X}=S();for(const[b,ee]of N){const q=P.get(b),J=!!(q!=null&&q.expandParent&&(q!=null&&q.parentId)&&(ee!=null&&ee.position)),Z={id:b,type:"position",position:J?{x:Math.max(0,ee.position.x),y:Math.max(0,ee.position.y)}:ee.position,dragging:E};if(q&&D.inProgress&&D.fromNode.id===q.id){const k=vr(q,D.fromHandle,xe.Left,!0);V({...D,from:k})}J&&q.parentId&&L.push({id:b,parentId:q.parentId,rect:{...ee.internals.positionAbsolute,width:ee.measured.width??0,height:ee.measured.height??0}}),_.push(Z)}if(L.length>0){const{parentLookup:b,nodeOrigin:ee}=S(),q=lc(L,P,b,ee);_.push(...q)}for(const b of X.values())_=b(_);U(_)},triggerNodeChanges:N=>{const{onNodesChange:E,setNodes:L,nodes:_,hasDefaultNodes:P,debug:U}=S();if(N!=null&&N.length){if(P){const D=$1(N,_);L(D)}U&&console.log("React Flow: trigger node changes",N),E==null||E(N)}},triggerEdgeChanges:N=>{const{onEdgesChange:E,setEdges:L,edges:_,hasDefaultEdges:P,debug:U}=S();if(N!=null&&N.length){if(P){const D=D1(N,_);L(D)}U&&console.log("React Flow: trigger edge changes",N),E==null||E(N)}},addSelectedNodes:N=>{const{multiSelectionActive:E,edgeLookup:L,nodeLookup:_,triggerNodeChanges:P,triggerEdgeChanges:U}=S();if(E){const D=N.map(V=>cr(V,!0));P(D);return}P(qr(_,new Set([...N]),!0)),U(qr(L))},addSelectedEdges:N=>{const{multiSelectionActive:E,edgeLookup:L,nodeLookup:_,triggerNodeChanges:P,triggerEdgeChanges:U}=S();if(E){const D=N.map(V=>cr(V,!0));U(D);return}U(qr(L,new Set([...N]))),P(qr(_,new Set,!0))},unselectNodesAndEdges:({nodes:N,edges:E}={})=>{const{edges:L,nodes:_,nodeLookup:P,triggerNodeChanges:U,triggerEdgeChanges:D}=S(),V=N||_,X=E||L,b=[];for(const q of V){if(!q.selected)continue;const J=P.get(q.id);J&&(J.selected=!1),b.push(cr(q.id,!1))}const ee=[];for(const q of X)q.selected&&ee.push(cr(q.id,!1));U(b),D(ee)},setMinZoom:N=>{const{panZoom:E,maxZoom:L}=S();E==null||E.setScaleExtent([N,L]),w({minZoom:N})},setMaxZoom:N=>{const{panZoom:E,minZoom:L}=S();E==null||E.setScaleExtent([L,N]),w({maxZoom:N})},setTranslateExtent:N=>{var E;(E=S().panZoom)==null||E.setTranslateExtent(N),w({translateExtent:N})},resetSelectedElements:()=>{const{edges:N,nodes:E,triggerNodeChanges:L,triggerEdgeChanges:_,elementsSelectable:P}=S();if(!P)return;const U=E.reduce((V,X)=>X.selected?[...V,cr(X.id,!1)]:V,[]),D=N.reduce((V,X)=>X.selected?[...V,cr(X.id,!1)]:V,[]);L(U),_(D)},setNodeExtent:N=>{const{nodes:E,nodeLookup:L,parentLookup:_,nodeOrigin:P,elevateNodesOnSelect:U,nodeExtent:D,zIndexMode:V}=S();N[0][0]===D[0][0]&&N[0][1]===D[0][1]&&N[1][0]===D[1][0]&&N[1][1]===D[1][1]||(Ba(E,L,_,{nodeOrigin:P,nodeExtent:N,elevateNodesOnSelect:U,checkEquality:!1,zIndexMode:V}),w({nodeExtent:N}))},panBy:N=>{const{transform:E,width:L,height:_,panZoom:P,translateExtent:U}=S();return jw({delta:N,panZoom:P,transform:E,translateExtent:U,width:L,height:_})},setCenter:async(N,E,L)=>{const{width:_,height:P,maxZoom:U,panZoom:D}=S();if(!D)return!1;const V=typeof(L==null?void 0:L.zoom)<"u"?L.zoom:U;return await D.setViewport({x:_/2-N*V,y:P/2-E*V,zoom:V},{duration:L==null?void 0:L.duration,ease:L==null?void 0:L.ease,interpolate:L==null?void 0:L.interpolate}),!0},cancelConnection:()=>{w({connection:{...Lp}})},updateConnection:N=>{w({connection:N})},reset:()=>w({...Gh()})}},Object.is);function o_({initialNodes:n,initialEdges:r,defaultNodes:i,defaultEdges:l,initialWidth:u,initialHeight:c,initialMinZoom:f,initialMaxZoom:h,initialFitViewOptions:p,fitView:m,nodeOrigin:v,nodeExtent:y,zIndexMode:g,children:w}){const[S]=K.useState(()=>r_({nodes:n,edges:r,defaultNodes:i,defaultEdges:l,width:u,height:c,fitView:m,minZoom:f,maxZoom:h,fitViewOptions:p,nodeOrigin:v,nodeExtent:y,zIndexMode:g}));return T.jsx(m1,{value:S,children:T.jsx(B1,{children:T.jsx(rS,{children:w})})})}function i_({children:n,nodes:r,edges:i,defaultNodes:l,defaultEdges:u,width:c,height:f,fitView:h,fitViewOptions:p,minZoom:m,maxZoom:v,nodeOrigin:y,nodeExtent:g,zIndexMode:w}){return K.useContext(yl)?T.jsx(T.Fragment,{children:n}):T.jsx(o_,{initialNodes:r,initialEdges:i,defaultNodes:l,defaultEdges:u,initialWidth:c,initialHeight:f,fitView:h,initialFitViewOptions:p,initialMinZoom:m,initialMaxZoom:v,nodeOrigin:y,nodeExtent:g,zIndexMode:w,children:n})}const s_={width:"100%",height:"100%",overflow:"hidden",position:"relative",zIndex:0};function l_({nodes:n,edges:r,defaultNodes:i,defaultEdges:l,className:u,nodeTypes:c,edgeTypes:f,onNodeClick:h,onEdgeClick:p,onInit:m,onMove:v,onMoveStart:y,onMoveEnd:g,onConnect:w,onConnectStart:S,onConnectEnd:M,onClickConnectStart:N,onClickConnectEnd:E,onNodeMouseEnter:L,onNodeMouseMove:_,onNodeMouseLeave:P,onNodeContextMenu:U,onNodeDoubleClick:D,onNodeDragStart:V,onNodeDrag:X,onNodeDragStop:b,onNodesDelete:ee,onEdgesDelete:q,onDelete:J,onSelectionChange:Z,onSelectionDragStart:k,onSelectionDrag:B,onSelectionDragStop:z,onSelectionContextMenu:H,onSelectionStart:j,onSelectionEnd:$,onBeforeDelete:F,connectionMode:C,connectionLineType:R=Un.Bezier,connectionLineStyle:te,connectionLineComponent:re,connectionLineContainerStyle:ue,deleteKeyCode:ce="Backspace",selectionKeyCode:ae="Shift",selectionOnDrag:G=!1,selectionMode:se=ui.Full,panActivationKeyCode:pe="Space",multiSelectionKeyCode:we=ci()?"Meta":"Control",zoomActivationKeyCode:ve=ci()?"Meta":"Control",snapToGrid:me,snapGrid:ke,onlyRenderVisibleElements:Ce=!1,selectNodesOnDrag:Me,nodesDraggable:Le,autoPanOnNodeFocus:it,nodesConnectable:ut,nodesFocusable:Je,nodeOrigin:et=cg,edgesFocusable:rn,edgesReconnectable:bt,elementsSelectable:Qt=!0,defaultViewport:at=I1,minZoom:Ct=.5,maxZoom:yt=2,translateExtent:Mt=li,preventScrolling:xr=!0,nodeExtent:on,defaultMarkerColor:Yn="#b1b1b7",zoomOnScroll:Sl=!0,zoomOnPinch:xi=!0,panOnScroll:wi=!1,panOnScrollSpeed:_l=.5,panOnScrollMode:so=hr.Free,zoomOnDoubleClick:lo=!0,panOnDrag:uo=!0,onPaneClick:ao,onPaneMouseEnter:co,onPaneMouseMove:vn,onPaneMouseLeave:xn,onPaneScroll:Si,onPaneContextMenu:_i,paneClickDistance:Ei=1,nodeClickDistance:ki=0,children:Ni,onReconnect:fo,onReconnectStart:Ci,onReconnectEnd:Xn,onEdgeContextMenu:ho,onEdgeDoubleClick:bn,onEdgeMouseEnter:El,onEdgeMouseMove:Qn,onEdgeMouseLeave:wr,reconnectRadius:Sr=10,onNodesChange:po,onEdgesChange:kl,noDragClassName:Nl="nodrag",noWheelClassName:Cl="nowheel",noPanClassName:Gt="nopan",fitView:go,fitViewOptions:mo,connectOnClick:Ml,attributionPosition:Mi,proOptions:Pi,defaultEdgeOptions:Ii,elevateNodesOnSelect:zi=!0,elevateEdgesOnSelect:Pl=!1,disableKeyboardA11y:Ti=!1,autoPanOnConnect:Oe,autoPanOnNodeDrag:Il,autoPanOnSelection:yo=!0,autoPanSpeed:Li,connectionRadius:_r,isValidConnection:zl,onError:Ri,style:Er,id:vt,nodeDragThreshold:Tl,connectionDragThreshold:xt,viewport:Ll,onViewportChange:Rl,width:Al,height:kr,colorMode:Nr="light",debug:Gn,onScroll:sn,ariaLabelConfig:jl,zIndexMode:Ai="basic",...vo},ji){const Kn=vt||"1",qn=R1(Nr),$l=K.useCallback(Cr=>{Cr.currentTarget.scrollTo({top:0,left:0,behavior:"instant"}),sn==null||sn(Cr)},[sn]);return T.jsx("div",{"data-testid":"rf__wrapper",...vo,onScroll:$l,style:{...Er,...s_},ref:ji,className:Ye(["react-flow",u,qn]),id:vt,role:"application",children:T.jsxs(i_,{nodes:n,edges:r,width:Al,height:kr,fitView:go,fitViewOptions:mo,minZoom:Ct,maxZoom:yt,nodeOrigin:et,nodeExtent:on,zIndexMode:Ai,children:[T.jsx(L1,{nodes:n,edges:r,defaultNodes:i,defaultEdges:l,onConnect:w,onConnectStart:S,onConnectEnd:M,onClickConnectStart:N,onClickConnectEnd:E,nodesDraggable:Le,autoPanOnNodeFocus:it,nodesConnectable:ut,nodesFocusable:Je,edgesFocusable:rn,edgesReconnectable:bt,elementsSelectable:Qt,elevateNodesOnSelect:zi,elevateEdgesOnSelect:Pl,minZoom:Ct,maxZoom:yt,nodeExtent:on,onNodesChange:po,onEdgesChange:kl,snapToGrid:me,snapGrid:ke,connectionMode:C,translateExtent:Mt,connectOnClick:Ml,defaultEdgeOptions:Ii,fitView:go,fitViewOptions:mo,onNodesDelete:ee,onEdgesDelete:q,onDelete:J,onNodeDragStart:V,onNodeDrag:X,onNodeDragStop:b,onSelectionDrag:B,onSelectionDragStart:k,onSelectionDragStop:z,onMove:v,onMoveStart:y,onMoveEnd:g,noPanClassName:Gt,nodeOrigin:et,rfId:Kn,autoPanOnConnect:Oe,autoPanOnNodeDrag:Il,autoPanSpeed:Li,onError:Ri,connectionRadius:_r,isValidConnection:zl,selectNodesOnDrag:Me,nodeDragThreshold:Tl,connectionDragThreshold:xt,onBeforeDelete:F,debug:Gn,ariaLabelConfig:jl,zIndexMode:Ai}),T.jsx(t_,{onInit:m,onNodeClick:h,onEdgeClick:p,onNodeMouseEnter:L,onNodeMouseMove:_,onNodeMouseLeave:P,onNodeContextMenu:U,onNodeDoubleClick:D,nodeTypes:c,edgeTypes:f,connectionLineType:R,connectionLineStyle:te,connectionLineComponent:re,connectionLineContainerStyle:ue,selectionKeyCode:ae,selectionOnDrag:G,selectionMode:se,deleteKeyCode:ce,multiSelectionKeyCode:we,panActivationKeyCode:pe,zoomActivationKeyCode:ve,onlyRenderVisibleElements:Ce,defaultViewport:at,translateExtent:Mt,minZoom:Ct,maxZoom:yt,preventScrolling:xr,zoomOnScroll:Sl,zoomOnPinch:xi,zoomOnDoubleClick:lo,panOnScroll:wi,panOnScrollSpeed:_l,panOnScrollMode:so,panOnDrag:uo,autoPanOnSelection:yo,onPaneClick:ao,onPaneMouseEnter:co,onPaneMouseMove:vn,onPaneMouseLeave:xn,onPaneScroll:Si,onPaneContextMenu:_i,paneClickDistance:Ei,nodeClickDistance:ki,onSelectionContextMenu:H,onSelectionStart:j,onSelectionEnd:$,onReconnect:fo,onReconnectStart:Ci,onReconnectEnd:Xn,onEdgeContextMenu:ho,onEdgeDoubleClick:bn,onEdgeMouseEnter:El,onEdgeMouseMove:Qn,onEdgeMouseLeave:wr,reconnectRadius:Sr,defaultMarkerColor:Yn,noDragClassName:Nl,noWheelClassName:Cl,noPanClassName:Gt,rfId:Kn,disableKeyboardA11y:Ti,nodeExtent:on,viewport:Ll,onViewportChange:Rl,nodesDraggable:Le}),T.jsx(P1,{onSelectionChange:Z}),Ni,T.jsx(E1,{proOptions:Pi,position:Mi}),T.jsx(_1,{rfId:Kn,disableKeyboardA11y:Ti})]})})}var u_=dg(l_);function a_({dimensions:n,lineWidth:r,variant:i,className:l}){return T.jsx("path",{strokeWidth:r,d:`M${n[0]/2} 0 V${n[1]} M0 ${n[1]/2} H${n[0]}`,className:Ye(["react-flow__background-pattern",i,l])})}function c_({radius:n,className:r}){return T.jsx("circle",{cx:n,cy:n,r:n,className:Ye(["react-flow__background-pattern","dots",r])})}var Wn;(function(n){n.Lines="lines",n.Dots="dots",n.Cross="cross"})(Wn||(Wn={}));const f_={[Wn.Dots]:1,[Wn.Lines]:1,[Wn.Cross]:6},d_=n=>({transform:n.transform,patternId:`pattern-${n.rfId}`});function Og({id:n,variant:r=Wn.Dots,gap:i=20,size:l,lineWidth:u=1,offset:c=0,color:f,bgColor:h,style:p,className:m,patternClassName:v}){const y=K.useRef(null),{transform:g,patternId:w}=Ie(d_,Ve),S=l||f_[r],M=r===Wn.Dots,N=r===Wn.Cross,E=Array.isArray(i)?i:[i,i],L=[E[0]*g[2]||1,E[1]*g[2]||1],_=S*g[2],P=Array.isArray(c)?c:[c,c],U=N?[_,_]:L,D=[P[0]*g[2]+U[0]/2,P[1]*g[2]+U[1]/2],V=`${w}${n||""}`;return T.jsxs("svg",{className:Ye(["react-flow__background",m]),style:{...p,...xl,"--xy-background-color-props":h,"--xy-background-pattern-color-props":f},ref:y,"data-testid":"rf__background",children:[T.jsx("pattern",{id:V,x:g[0]%L[0],y:g[1]%L[1],width:L[0],height:L[1],patternUnits:"userSpaceOnUse",patternTransform:`translate(-${D[0]},-${D[1]})`,children:M?T.jsx(c_,{radius:_/2,className:v}):T.jsx(a_,{dimensions:U,lineWidth:u,variant:r,className:v})}),T.jsx("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:`url(#${V})`})]})}Og.displayName="Background";const h_=K.memo(Og);function p_(){return T.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32",children:T.jsx("path",{d:"M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z"})})}function g_(){return T.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 5",children:T.jsx("path",{d:"M0 0h32v4.2H0z"})})}function m_(){return T.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 30",children:T.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 y_(){return T.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:T.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 v_(){return T.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:T.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 Ys({children:n,className:r,...i}){return T.jsx("button",{type:"button",className:Ye(["react-flow__controls-button",r]),...i,children:n})}const x_=n=>({isInteractive:n.nodesDraggable||n.nodesConnectable||n.elementsSelectable,minZoomReached:n.transform[2]<=n.minZoom,maxZoomReached:n.transform[2]>=n.maxZoom,ariaLabelConfig:n.ariaLabelConfig});function Fg({style:n,showZoom:r=!0,showFitView:i=!0,showInteractive:l=!0,fitViewOptions:u,onZoomIn:c,onZoomOut:f,onFitView:h,onInteractiveChange:p,className:m,children:v,position:y="bottom-left",orientation:g="vertical","aria-label":w}){const S=$e(),{isInteractive:M,minZoomReached:N,maxZoomReached:E,ariaLabelConfig:L}=Ie(x_,Ve),{zoomIn:_,zoomOut:P,fitView:U}=uc(),D=()=>{_(),c==null||c()},V=()=>{P(),f==null||f()},X=()=>{U(u),h==null||h()},b=()=>{S.setState({nodesDraggable:!M,nodesConnectable:!M,elementsSelectable:!M}),p==null||p(!M)},ee=g==="horizontal"?"horizontal":"vertical";return T.jsxs(vl,{className:Ye(["react-flow__controls",ee,m]),position:y,style:n,"data-testid":"rf__controls","aria-label":w??L["controls.ariaLabel"],children:[r&&T.jsxs(T.Fragment,{children:[T.jsx(Ys,{onClick:D,className:"react-flow__controls-zoomin",title:L["controls.zoomIn.ariaLabel"],"aria-label":L["controls.zoomIn.ariaLabel"],disabled:E,children:T.jsx(p_,{})}),T.jsx(Ys,{onClick:V,className:"react-flow__controls-zoomout",title:L["controls.zoomOut.ariaLabel"],"aria-label":L["controls.zoomOut.ariaLabel"],disabled:N,children:T.jsx(g_,{})})]}),i&&T.jsx(Ys,{className:"react-flow__controls-fitview",onClick:X,title:L["controls.fitView.ariaLabel"],"aria-label":L["controls.fitView.ariaLabel"],children:T.jsx(m_,{})}),l&&T.jsx(Ys,{className:"react-flow__controls-interactive",onClick:b,title:L["controls.interactive.ariaLabel"],"aria-label":L["controls.interactive.ariaLabel"],children:M?T.jsx(v_,{}):T.jsx(y_,{})}),v]})}Fg.displayName="Controls";const w_=K.memo(Fg);function S_({id:n,x:r,y:i,width:l,height:u,style:c,color:f,strokeColor:h,strokeWidth:p,className:m,borderRadius:v,shapeRendering:y,selected:g,onClick:w}){const{background:S,backgroundColor:M}=c||{},N=f||S||M;return T.jsx("rect",{className:Ye(["react-flow__minimap-node",{selected:g},m]),x:r,y:i,rx:v,ry:v,width:l,height:u,style:{fill:N,stroke:h,strokeWidth:p},shapeRendering:y,onClick:w?E=>w(E,n):void 0})}const __=K.memo(S_),E_=n=>n.nodes.map(r=>r.id),za=n=>n instanceof Function?n:()=>n;function k_({nodeStrokeColor:n,nodeColor:r,nodeClassName:i="",nodeBorderRadius:l=5,nodeStrokeWidth:u,nodeComponent:c=__,onClick:f}){const h=Ie(E_,Ve),p=za(r),m=za(n),v=za(i),y=typeof window>"u"||window.chrome?"crispEdges":"geometricPrecision";return T.jsx(T.Fragment,{children:h.map(g=>T.jsx(C_,{id:g,nodeColorFunc:p,nodeStrokeColorFunc:m,nodeClassNameFunc:v,nodeBorderRadius:l,nodeStrokeWidth:u,NodeComponent:c,onClick:f,shapeRendering:y},g))})}function N_({id:n,nodeColorFunc:r,nodeStrokeColorFunc:i,nodeClassNameFunc:l,nodeBorderRadius:u,nodeStrokeWidth:c,shapeRendering:f,NodeComponent:h,onClick:p}){const{node:m,x:v,y,width:g,height:w}=Ie(S=>{const M=S.nodeLookup.get(n);if(!M)return{node:void 0,x:0,y:0,width:0,height:0};const N=M.internals.userNode,{x:E,y:L}=M.internals.positionAbsolute,{width:_,height:P}=Xt(N);return{node:N,x:E,y:L,width:_,height:P}},Ve);return!m||m.hidden||!Hp(m)?null:T.jsx(h,{x:v,y,width:g,height:w,style:m.style,selected:!!m.selected,className:l(m),color:r(m),borderRadius:u,strokeColor:i(m),strokeWidth:c,shapeRendering:f,onClick:p,id:m.id})}const C_=K.memo(N_);var M_=K.memo(k_);const P_=200,I_=150,z_=n=>!n.hidden,T_=n=>{const r={x:-n.transform[0]/n.transform[2],y:-n.transform[1]/n.transform[2],width:n.width/n.transform[2],height:n.height/n.transform[2]};return{viewBB:r,boundingRect:n.nodeLookup.size>0?Dp(mi(n.nodeLookup,{filter:z_}),r):r,rfId:n.rfId,panZoom:n.panZoom,translateExtent:n.translateExtent,flowWidth:n.width,flowHeight:n.height,ariaLabelConfig:n.ariaLabelConfig}},Kh=(n,r)=>n.x===r.x&&n.y===r.y&&n.width===r.width&&n.height===r.height,L_=(n,r)=>Kh(n.viewBB,r.viewBB)&&Kh(n.boundingRect,r.boundingRect)&&n.rfId===r.rfId&&n.panZoom===r.panZoom&&n.translateExtent===r.translateExtent&&n.flowWidth===r.flowWidth&&n.flowHeight===r.flowHeight&&n.ariaLabelConfig===r.ariaLabelConfig,R_="react-flow__minimap-desc";function Hg({style:n,className:r,nodeStrokeColor:i,nodeColor:l,nodeClassName:u="",nodeBorderRadius:c=5,nodeStrokeWidth:f,nodeComponent:h,bgColor:p,maskColor:m,maskStrokeColor:v,maskStrokeWidth:y,position:g="bottom-right",onClick:w,onNodeClick:S,pannable:M=!1,zoomable:N=!1,ariaLabel:E,inversePan:L,zoomStep:_=1,offsetScale:P=5}){const U=$e(),D=K.useRef(null),{boundingRect:V,viewBB:X,rfId:b,panZoom:ee,translateExtent:q,flowWidth:J,flowHeight:Z,ariaLabelConfig:k}=Ie(T_,L_),B=(n==null?void 0:n.width)??P_,z=(n==null?void 0:n.height)??I_,H=V.width/B,j=V.height/z,$=Math.max(H,j),F=$*B,C=$*z,R=P*$,te=V.x-(F-V.width)/2-R,re=V.y-(C-V.height)/2-R,ue=F+R*2,ce=C+R*2,ae=`${R_}-${b}`,G=K.useRef(0),se=K.useRef();G.current=$,K.useEffect(()=>{if(D.current&&ee)return se.current=Ww({domNode:D.current,panZoom:ee,getTransform:()=>U.getState().transform,getViewScale:()=>G.current}),()=>{var me;(me=se.current)==null||me.destroy()}},[ee]),K.useEffect(()=>{var me;(me=se.current)==null||me.update({translateExtent:q,width:J,height:Z,inversePan:L,pannable:M,zoomStep:_,zoomable:N})},[M,N,L,_,q,J,Z]);const pe=w?me=>{var Me;const[ke,Ce]=((Me=se.current)==null?void 0:Me.pointer(me))||[0,0];w(me,{x:ke,y:Ce})}:void 0,we=S?K.useCallback((me,ke)=>{const Ce=U.getState().nodeLookup.get(ke).internals.userNode;S(me,Ce)},[]):void 0,ve=E??k["minimap.ariaLabel"];return T.jsx(vl,{position:g,style:{...n,"--xy-minimap-background-color-props":typeof p=="string"?p:void 0,"--xy-minimap-mask-background-color-props":typeof m=="string"?m:void 0,"--xy-minimap-mask-stroke-color-props":typeof v=="string"?v:void 0,"--xy-minimap-mask-stroke-width-props":typeof y=="number"?y*$:void 0,"--xy-minimap-node-background-color-props":typeof l=="string"?l:void 0,"--xy-minimap-node-stroke-color-props":typeof i=="string"?i:void 0,"--xy-minimap-node-stroke-width-props":typeof f=="number"?f:void 0},className:Ye(["react-flow__minimap",r]),"data-testid":"rf__minimap",children:T.jsxs("svg",{width:B,height:z,viewBox:`${te} ${re} ${ue} ${ce}`,className:"react-flow__minimap-svg",role:"img","aria-labelledby":ae,ref:D,onClick:pe,children:[ve&&T.jsx("title",{id:ae,children:ve}),T.jsx(M_,{onClick:we,nodeColor:l,nodeStrokeColor:i,nodeBorderRadius:c,nodeClassName:u,nodeStrokeWidth:f,nodeComponent:h}),T.jsx("path",{className:"react-flow__minimap-mask",d:`M${te-R},${re-R}h${ue+R*2}v${ce+R*2}h${-ue-R*2}z - M${X.x},${X.y}h${X.width}v${X.height}h${-X.width}z`,fillRule:"evenodd",pointerEvents:"none"})]})})}Hg.displayName="MiniMap";const A_=K.memo(Hg),j_=n=>r=>n?`${Math.max(1/r.transform[2],1)}`:void 0,$_={[io.Line]:"right",[io.Handle]:"bottom-right"};function D_({nodeId:n,position:r,variant:i=io.Handle,className:l,style:u=void 0,children:c,color:f,minWidth:h=10,minHeight:p=10,maxWidth:m=Number.MAX_VALUE,maxHeight:v=Number.MAX_VALUE,keepAspectRatio:y=!1,resizeDirection:g,autoScale:w=!0,shouldResize:S,onResizeStart:M,onResize:N,onResizeEnd:E}){const L=yg(),_=typeof n=="string"?n:L,P=$e(),U=K.useRef(null),D=i===io.Handle,V=Ie(K.useCallback(j_(D&&w),[D,w]),Ve),X=K.useRef(null),b=r??$_[i];K.useEffect(()=>{if(!(!U.current||!_))return X.current||(X.current=r1({domNode:U.current,nodeId:_,getStoreItems:()=>{const{nodeLookup:q,transform:J,snapGrid:Z,snapToGrid:k,nodeOrigin:B,domNode:z}=P.getState();return{nodeLookup:q,transform:J,snapGrid:Z,snapToGrid:k,nodeOrigin:B,paneDomNode:z}},onChange:(q,J)=>{const{triggerNodeChanges:Z,nodeLookup:k,parentLookup:B,nodeOrigin:z}=P.getState(),H=[],j={x:q.x,y:q.y},$=k.get(_);if($&&$.expandParent&&$.parentId){const F=$.origin??z,C=q.width??$.measured.width??0,R=q.height??$.measured.height??0,te={id:$.id,parentId:$.parentId,rect:{width:C,height:R,...Vp({x:q.x??$.position.x,y:q.y??$.position.y},{width:C,height:R},$.parentId,k,F)}},re=lc([te],k,B,z);H.push(...re),j.x=q.x?Math.max(F[0]*C,q.x):void 0,j.y=q.y?Math.max(F[1]*R,q.y):void 0}if(j.x!==void 0&&j.y!==void 0){const F={id:_,type:"position",position:{...j}};H.push(F)}if(q.width!==void 0&&q.height!==void 0){const C={id:_,type:"dimensions",resizing:!0,setAttributes:g?g==="horizontal"?"width":"height":!0,dimensions:{width:q.width,height:q.height}};H.push(C)}for(const F of J){const C={...F,type:"position"};H.push(C)}Z(H)},onEnd:({width:q,height:J})=>{const Z={id:_,type:"dimensions",resizing:!1,dimensions:{width:q,height:J}};P.getState().triggerNodeChanges([Z])}})),X.current.update({controlPosition:b,boundaries:{minWidth:h,minHeight:p,maxWidth:m,maxHeight:v},keepAspectRatio:y,resizeDirection:g,onResizeStart:M,onResize:N,onResizeEnd:E,shouldResize:S}),()=>{var q;(q=X.current)==null||q.destroy()}},[b,h,p,m,v,y,M,N,E,S]);const ee=b.split("-");return T.jsx("div",{className:Ye(["react-flow__resize-control","nodrag",...ee,i,l]),ref:U,style:{...u,scale:V,...f&&{[D?"backgroundColor":"borderColor"]:f}},children:c})}K.memo(D_);const O_={"arch.context":0,"django.app":0,"django.route":1,"django.url_name":1,"django.view":2,"django.viewset_action":2,"django.permission":2,"django.serializer":3,"django.serializer_field":4,"django.service":4,"django.model":5,"django.field":6,"django.relation":6,"django.task":7,"django.receiver":7,"django.signal":7,"django.test":7,"django.migration_op":7,"django.admin":7,"openapi.path":8,"react.api_client":9,"react.query_key":10,"react.hook":10,"react.feature":10,"react.route":11,"react.page":11,"react.component":12,"react.form_schema":13,"react.test":13,"react.context":12};function F_(n){return O_[n]??8}function H_(n){const r=new Map;for(const l of n){const u=F_(l.type),c=r.get(u)??[];c.push(l),r.set(u,c)}const i=new Map;for(const[l,u]of r)u.sort((c,f)=>c.name.localeCompare(f.name)),u.forEach((c,f)=>{i.set(c.id,{x:l*240,y:f*92})});return i}const V_={cheap:"#4a5568",expensive:"#f4a261",critical:"#e85d04"};function B_({data:n}){return T.jsxs("div",{className:"lp-node",children:[T.jsx("div",{className:"t",children:n.type.split(".").pop()}),T.jsx("div",{className:"n",children:n.name})]})}const U_={load:B_};function qh({nodes:n,edges:r}){const i=H_(n),l=n.map(c=>({id:c.id,type:"load",position:i.get(c.id)??{x:0,y:0},data:{name:c.name,type:c.type,file:c.file_path}})),u=r.filter(c=>n.some(f=>f.id===c.src)&&n.some(f=>f.id===c.dst)).map(c=>({id:c.id,source:c.src,target:c.dst,animated:c.weight==="critical",style:{stroke:V_[c.weight]||"#4a5568",strokeWidth:c.weight==="critical"?2.4:1.2,strokeDasharray:c.confidence<.8?"6 4":void 0},label:c.type.replaceAll("_"," "),labelStyle:{fill:"#8b9bb0",fontSize:9}}));return T.jsxs(u_,{nodes:l,edges:u,nodeTypes:U_,fitView:!0,minZoom:.2,children:[T.jsx(h_,{}),T.jsx(A_,{pannable:!0,zoomable:!0}),T.jsx(w_,{})]})}function W_(){var B;const[n,r]=K.useState("review"),[i,l]=K.useState(localStorage.getItem("loadpath.repo")||""),[u,c]=K.useState("HEAD~1"),[f,h]=K.useState("HEAD"),[p,m]=K.useState(null),[v,y]=K.useState(""),[g,w]=K.useState(""),[S,M]=K.useState({}),[N,E]=K.useState([]),[L,_]=K.useState(""),[P,U]=K.useState("github"),[D,V]=K.useState("");K.useEffect(()=>{Gr.settings().then(M).catch(()=>{})},[]);const X=async()=>{y(""),w("Tracing load path…"),localStorage.setItem("loadpath.repo",i);try{const z=await Gr.review(i,u,f);m(z),r("review")}catch(z){y(z instanceof Error?z.message:String(z))}finally{w("")}},b=async()=>{y(""),w("Indexing…");try{await Gr.index(i)}catch(z){y(z instanceof Error?z.message:String(z))}finally{w("")}},ee=async()=>{y(""),w("Fetching pull requests…");try{const z=await Gr.prs(P,L);E(z.pull_requests)}catch(z){y(z instanceof Error?z.message:String(z))}finally{w("")}},q=async z=>{z.preventDefault();const H=new FormData(z.currentTarget),j={github_token:String(H.get("github_token")||""),bitbucket_token:String(H.get("bitbucket_token")||""),bitbucket_username:String(H.get("bitbucket_username")||""),ai_provider:String(H.get("ai_provider")||"none"),ai_api_key:String(H.get("ai_api_key")||""),ai_model:String(H.get("ai_model")||""),ai_base_url:String(H.get("ai_base_url")||""),workspaces:i?[{path:i,name:i.split(/[\\/]/).pop()}]:[]};M(await Gr.saveSettings(j))},J=async()=>{if(p){w("Residual analysis…");try{const z=await Gr.residual(p);V(z.note)}catch(z){y(z instanceof Error?z.message:String(z))}finally{w("")}}},Z=K.useMemo(()=>(p==null?void 0:p.nodes)??[],[p]),k=K.useMemo(()=>(p==null?void 0:p.edges)??[],[p]);return T.jsxs("div",{className:"app",children:[T.jsxs("nav",{className:"rail",children:[T.jsx("div",{className:"brand",children:"Loadpath"}),T.jsx("button",{className:n==="review"?"active":"",onClick:()=>r("review"),children:"Review"}),T.jsx("button",{className:n==="graph"?"active":"",onClick:()=>r("graph"),children:"Impact graph"}),T.jsx("button",{className:n==="prs"?"active":"",onClick:()=>r("prs"),children:"Pull requests"}),T.jsx("button",{className:n==="settings"?"active":"",onClick:()=>r("settings"),children:"Settings"}),T.jsx("div",{style:{flex:1}}),T.jsx("div",{className:"muted",children:g||"Django + React load paths"})]}),T.jsxs("div",{className:"main",children:[T.jsxs("div",{className:"topbar",children:[T.jsx("input",{className:"path",placeholder:"Local monorepo path",value:i,onChange:z=>l(z.target.value)}),T.jsx("input",{value:u,onChange:z=>c(z.target.value),placeholder:"base"}),T.jsx("input",{value:f,onChange:z=>h(z.target.value),placeholder:"head"}),T.jsx("button",{onClick:b,children:"Index"}),T.jsx("button",{className:"btn primary",onClick:X,children:"Review"})]}),v?T.jsx("div",{className:"error",children:v}):null,n==="review"&&T.jsxs("div",{className:"content",children:[T.jsx("aside",{className:"brief",children:p?T.jsxs(T.Fragment,{children:[T.jsxs("div",{className:`level ${p.confidence.level}`,children:[p.confidence.level.toUpperCase()," — ",p.title]}),p.low_risk?T.jsx("span",{className:"chip",children:"loadpath:low-risk"}):null,p.change_kinds.map(z=>T.jsx("span",{className:"chip",children:z.replaceAll("_"," ")},z)),T.jsx("pre",{className:"headline",children:p.headline}),T.jsx("div",{className:"kicker",children:"Read this"}),p.read_order.map(z=>T.jsxs("div",{children:[T.jsx("span",{className:"file",children:z.path}),T.jsx("div",{className:"muted",children:z.why})]},z.path)),T.jsx("div",{className:"kicker",children:"Clusters"}),p.clusters.map(z=>T.jsxs("div",{className:"muted",children:[T.jsx("strong",{children:z.title})," — ",z.files.join(", ")]},z.id)),T.jsx("div",{className:"kicker",children:"Architecture"}),p.findings.filter(z=>!z.waived).length===0?T.jsx("div",{className:"muted",children:p.architecture_note}):p.findings.filter(z=>!z.waived).map(z=>T.jsxs("div",{className:"muted",children:[T.jsx("span",{className:`chip ${z.severity}`,children:z.severity}),z.message]},z.rule+z.message)),T.jsx("div",{className:"kicker",children:"Residual (AI only here)"}),p.residuals.map(z=>T.jsx("div",{className:"muted",children:z},z)),T.jsx("button",{className:"btn",onClick:J,style:{marginTop:12},children:"Ask configured model"}),D?T.jsx("pre",{className:"headline",children:D}):null,T.jsx("div",{className:"kicker",children:"Reviewers"}),T.jsx("div",{className:"muted",children:p.suggested_reviewers.join(", ")||"—"})]}):T.jsxs("p",{className:"muted",children:["Point at a Django + React monorepo with ",T.jsx("code",{children:"loadpath.yml"}),", then review a git range. The graph — not hunk comments — is the artifact."]})}),T.jsx("div",{className:"graph-wrap",children:p?T.jsx(qh,{nodes:Z,edges:k}):null})]}),n==="graph"&&T.jsx("div",{className:"graph-wrap",style:{height:"100%"},children:p?T.jsx(qh,{nodes:Z,edges:k}):T.jsx("p",{className:"muted",children:"Run a review first."})}),n==="prs"&&T.jsxs("div",{className:"pr-list",children:[T.jsxs("div",{className:"topbar",style:{border:0,padding:0,marginBottom:12},children:[T.jsxs("select",{value:P,onChange:z=>U(z.target.value),children:[T.jsx("option",{value:"github",children:"GitHub"}),T.jsx("option",{value:"bitbucket",children:"Bitbucket"})]}),T.jsx("input",{className:"path",placeholder:"owner/repo",value:L,onChange:z=>_(z.target.value)}),T.jsx("button",{onClick:ee,children:"List PRs"})]}),N.map(z=>T.jsxs("article",{className:"pr",children:[T.jsxs("h3",{children:["#",z.number," ",z.title]}),T.jsxs("div",{className:"muted",children:[z.author," · ",z.source_branch," → ",z.target_branch," · ",z.provider]}),T.jsxs("a",{href:z.url,target:"_blank",rel:"noreferrer",children:["Open on ",z.provider]}),T.jsx("div",{children:T.jsx("button",{className:"btn",onClick:()=>{c(z.target_branch),h(z.source_branch),r("review")},children:"Review this branch range"})})]},`${z.provider}-${z.number}`))]}),n==="settings"&&T.jsxs("form",{className:"settings",onSubmit:q,children:[T.jsx("h1",{children:"Keys & providers"}),T.jsx("p",{className:"muted",children:"Tokens stay on this machine in ~/.loadpath/settings.json. GitHub and Bitbucket power the PR list. AI is used only for residual uncertainty the graph could not close."}),T.jsx("label",{children:"GitHub token"}),T.jsx("input",{name:"github_token",type:"password",placeholder:"ghp_…"}),T.jsx("label",{children:"Bitbucket token"}),T.jsx("input",{name:"bitbucket_token",type:"password"}),T.jsx("label",{children:"Bitbucket username (app passwords)"}),T.jsx("input",{name:"bitbucket_username",defaultValue:String(S.bitbucket_username||"")}),T.jsx("label",{children:"AI provider"}),T.jsxs("select",{name:"ai_provider",defaultValue:String(((B=S.ai)==null?void 0:B.provider)||"none"),children:[T.jsx("option",{value:"none",children:"none (graph only)"}),T.jsx("option",{value:"anthropic",children:"Anthropic"}),T.jsx("option",{value:"openai",children:"OpenAI"}),T.jsx("option",{value:"grok",children:"Grok / xAI"}),T.jsx("option",{value:"deepseek",children:"DeepSeek"}),T.jsx("option",{value:"cursor",children:"Cursor-compatible (OpenAI protocol)"}),T.jsx("option",{value:"ollama",children:"Ollama local"})]}),T.jsx("label",{children:"AI API key"}),T.jsx("input",{name:"ai_api_key",type:"password"}),T.jsx("label",{children:"Model"}),T.jsx("input",{name:"ai_model",placeholder:"optional override"}),T.jsx("label",{children:"Base URL"}),T.jsx("input",{name:"ai_base_url",placeholder:"optional, OpenAI-compatible"}),T.jsx("button",{className:"btn primary",type:"submit",children:"Save"})]})]})]})}M0.createRoot(document.getElementById("root")).render(T.jsx(K.StrictMode,{children:T.jsx(W_,{})})); +`)),v=m.reduce((y,g)=>y.concat(...g),[]);return[m,v]}return[[],[]]},[n]);return K.useEffect(()=>{const p=(r==null?void 0:r.target)??Th,m=(r==null?void 0:r.actInsideInputWithModifier)??!0;if(n!==null){const v=x=>{var N,E;if(u.current=x.ctrlKey||x.metaKey||x.shiftKey||x.altKey,(!u.current||u.current&&!m)&&Up(x))return!1;const M=Rh(x.code,h);if(c.current.add(x[M]),Lh(f,c.current,!1)){const L=((E=(N=x.composedPath)==null?void 0:N.call(x))==null?void 0:E[0])||x.target,_=(L==null?void 0:L.nodeName)==="BUTTON"||(L==null?void 0:L.nodeName)==="A";r.preventDefault!==!1&&(u.current||!_)&&x.preventDefault(),l(!0)}},y=x=>{const S=Rh(x.code,h);Lh(f,c.current,!0)?(l(!1),c.current.clear()):c.current.delete(x[S]),x.key==="Meta"&&c.current.clear(),u.current=!1},g=()=>{c.current.clear(),l(!1)};return p==null||p.addEventListener("keydown",v),p==null||p.addEventListener("keyup",y),window.addEventListener("blur",g),window.addEventListener("contextmenu",g),()=>{p==null||p.removeEventListener("keydown",v),p==null||p.removeEventListener("keyup",y),window.removeEventListener("blur",g),window.removeEventListener("contextmenu",g)}}},[n,l]),i}function Lh(n,r,i){return n.filter(l=>i||l.length===r.size).some(l=>l.every(u=>r.has(u)))}function Rh(n,r){return r.includes(n)?"code":"key"}const A1=()=>{const n=$e();return K.useMemo(()=>({zoomIn:async r=>{const{panZoom:i}=n.getState();return i?i.scaleBy(1.2,r):!1},zoomOut:async r=>{const{panZoom:i}=n.getState();return i?i.scaleBy(1/1.2,r):!1},zoomTo:async(r,i)=>{const{panZoom:l}=n.getState();return l?l.scaleTo(r,i):!1},getZoom:()=>n.getState().transform[2],setViewport:async(r,i)=>{const{transform:[l,u,c],panZoom:f}=n.getState();return f?(await f.setViewport({x:r.x??l,y:r.y??u,zoom:r.zoom??c},i),!0):!1},getViewport:()=>{const[r,i,l]=n.getState().transform;return{x:r,y:i,zoom:l}},setCenter:async(r,i,l)=>n.getState().setCenter(r,i,l),fitBounds:async(r,i)=>{const{width:l,height:u,minZoom:c,maxZoom:f,panZoom:h}=n.getState(),p=tc(r,l,u,c,f,(i==null?void 0:i.padding)??.1);return h?(await h.setViewport(p,{duration:i==null?void 0:i.duration,ease:i==null?void 0:i.ease,interpolate:i==null?void 0:i.interpolate}),!0):!1},screenToFlowPosition:(r,i={})=>{const{transform:l,snapGrid:u,snapToGrid:c,domNode:f}=n.getState();if(!f)return r;const{x:h,y:p}=f.getBoundingClientRect(),m={x:r.x-h,y:r.y-p},v=i.snapGrid??u,y=i.snapToGrid??c;return vi(m,l,y,v)},flowToScreenPosition:r=>{const{transform:i,domNode:l}=n.getState();if(!l)return r;const{x:u,y:c}=l.getBoundingClientRect(),f=oo(r,i);return{x:f.x+u,y:f.y+c}}}),[])};function fg(n,r){const i=[],l=new Map,u=[];for(const c of n)if(c.type==="add"){u.push(c);continue}else if(c.type==="remove"||c.type==="replace")l.set(c.id,[c]);else{const f=l.get(c.id);f?f.push(c):l.set(c.id,[c])}for(const c of r){const f=l.get(c.id);if(!f){i.push(c);continue}if(f[0].type==="remove")continue;if(f[0].type==="replace"){i.push({...f[0].item});continue}const h={...c};for(const p of f)j1(p,h);i.push(h)}return u.length&&u.forEach(c=>{c.index!==void 0?i.splice(c.index,0,{...c.item}):i.push({...c.item})}),i}function j1(n,r){switch(n.type){case"select":{r.selected=n.selected;break}case"position":{typeof n.position<"u"&&(r.position=n.position),typeof n.dragging<"u"&&(r.dragging=n.dragging);break}case"dimensions":{typeof n.dimensions<"u"&&(r.measured={...n.dimensions},n.setAttributes&&((n.setAttributes===!0||n.setAttributes==="width")&&(r.width=n.dimensions.width),(n.setAttributes===!0||n.setAttributes==="height")&&(r.height=n.dimensions.height))),typeof n.resizing=="boolean"&&(r.resizing=n.resizing);break}}}function $1(n,r){return fg(n,r)}function D1(n,r){return fg(n,r)}function cr(n,r){return{id:n,type:"select",selected:r}}function qr(n,r=new Set,i=!1){const l=[];for(const[u,c]of n){const f=r.has(u);!(c.selected===void 0&&!f)&&c.selected!==f&&(i&&(c.selected=f),l.push(cr(c.id,f)))}return l}function Ah({items:n=[],lookup:r}){var u;const i=[],l=new Map(n.map(c=>[c.id,c]));for(const[c,f]of n.entries()){const h=r.get(f.id),p=((u=h==null?void 0:h.internals)==null?void 0:u.userNode)??h;p!==void 0&&p!==f&&i.push({id:f.id,item:f,type:"replace"}),p===void 0&&i.push({item:f,type:"add",index:c})}for(const[c]of r)l.get(c)===void 0&&i.push({id:c,type:"remove"});return i}function jh(n){return{id:n.id,type:"remove"}}const O1=Fp();function F1(n,r,i={}){return _x(n,r,{...i,onError:i.onError??O1})}const $h=n=>lx(n),H1=n=>Ap(n);function dg(n){return K.forwardRef(n)}const hg=typeof window<"u"?K.useLayoutEffect:K.useEffect;function Dh(n){const[r,i]=K.useState(BigInt(0)),[l]=K.useState(()=>V1(()=>i(u=>u+BigInt(1))));return hg(()=>{const u=l.get();u.length&&(n(u),l.reset())},[r]),l}function V1(n){let r=[];return{get:()=>r,reset:()=>{r=[]},push:i=>{r.push(i),n()}}}const pg=K.createContext(null);function B1({children:n}){const r=$e(),i=K.useCallback(h=>{const{nodes:p=[],setNodes:m,hasDefaultNodes:v,onNodesChange:y,nodeLookup:g,fitViewQueued:x,onNodesChangeMiddlewareMap:S}=r.getState();let M=p;for(const E of h)M=typeof E=="function"?E(M):E;let N=Ah({items:M,lookup:g});for(const E of S.values())N=E(N);v&&m(M),N.length>0?y==null||y(N):x&&window.requestAnimationFrame(()=>{const{fitViewQueued:E,nodes:L,setNodes:_}=r.getState();E&&_(L)})},[]),l=Dh(i),u=K.useCallback(h=>{const{edges:p=[],setEdges:m,hasDefaultEdges:v,onEdgesChange:y,edgeLookup:g}=r.getState();let x=p;for(const S of h)x=typeof S=="function"?S(x):S;v?m(x):y&&y(Ah({items:x,lookup:g}))},[]),c=Dh(u),f=K.useMemo(()=>({nodeQueue:l,edgeQueue:c}),[]);return T.jsx(pg.Provider,{value:f,children:n})}function U1(){const n=K.useContext(pg);if(!n)throw new Error("useBatchContext must be used within a BatchProvider");return n}const W1=n=>!!n.panZoom;function uc(){const n=A1(),r=$e(),i=U1(),l=Ie(W1),u=K.useMemo(()=>{const c=y=>r.getState().nodeLookup.get(y),f=y=>{i.nodeQueue.push(y)},h=y=>{i.edgeQueue.push(y)},p=y=>{var E,L;const{nodeLookup:g,nodeOrigin:x}=r.getState(),S=$h(y)?y:g.get(y.id),M=S.parentId?Vp(S.position,S.measured,S.parentId,g,x):S.position,N={...S,position:M,width:((E=S.measured)==null?void 0:E.width)??S.width,height:((L=S.measured)==null?void 0:L.height)??S.height};return ai(N)},m=(y,g,x={replace:!1})=>{f(S=>S.map(M=>{if(M.id===y){const N=typeof g=="function"?g(M):g;return x.replace&&$h(N)?N:{...M,...N}}return M}))},v=(y,g,x={replace:!1})=>{h(S=>S.map(M=>{if(M.id===y){const N=typeof g=="function"?g(M):g;return x.replace&&H1(N)?N:{...M,...N}}return M}))};return{getNodes:()=>r.getState().nodes.map(y=>({...y})),getNode:y=>{var g;return(g=c(y))==null?void 0:g.internals.userNode},getInternalNode:c,getEdges:()=>{const{edges:y=[]}=r.getState();return y.map(g=>({...g}))},getEdge:y=>r.getState().edgeLookup.get(y),setNodes:f,setEdges:h,addNodes:y=>{const g=Array.isArray(y)?y:[y];i.nodeQueue.push(x=>[...x,...g])},addEdges:y=>{const g=Array.isArray(y)?y:[y];i.edgeQueue.push(x=>[...x,...g])},toObject:()=>{const{nodes:y=[],edges:g=[],transform:x}=r.getState(),[S,M,N]=x;return{nodes:y.map(E=>({...E})),edges:g.map(E=>({...E})),viewport:{x:S,y:M,zoom:N}}},deleteElements:async({nodes:y=[],edges:g=[]})=>{const{nodes:x,edges:S,onNodesDelete:M,onEdgesDelete:N,triggerNodeChanges:E,triggerEdgeChanges:L,onDelete:_,onBeforeDelete:P}=r.getState(),{nodes:U,edges:D}=await dx({nodesToRemove:y,edgesToRemove:g,nodes:x,edges:S,onBeforeDelete:P}),V=D.length>0,Y=U.length>0;if(V){const X=D.map(jh);N==null||N(D),L(X)}if(Y){const X=U.map(jh);M==null||M(U),E(X)}return(Y||V)&&(_==null||_({nodes:U,edges:D})),{deletedNodes:U,deletedEdges:D}},getIntersectingNodes:(y,g=!0,x)=>{const S=lh(y),M=S?y:p(y),N=x!==void 0;return M?(x||r.getState().nodes).filter(E=>{const L=r.getState().nodeLookup.get(E.id);if(L&&!S&&(E.id===y.id||!L.internals.positionAbsolute))return!1;const _=ai(N?E:L),P=sl(_,M);return g&&P>0||P>=_.width*_.height||P>=M.width*M.height}):[]},isNodeIntersecting:(y,g,x=!0)=>{const M=lh(y)?y:p(y);if(!M)return!1;const N=sl(M,g);return x&&N>0||N>=g.width*g.height||N>=M.width*M.height},updateNode:m,updateNodeData:(y,g,x={replace:!1})=>{m(y,S=>{const M=typeof g=="function"?g(S):g;return x.replace?{...S,data:M}:{...S,data:{...S.data,...M}}},x)},updateEdge:v,updateEdgeData:(y,g,x={replace:!1})=>{v(y,S=>{const M=typeof g=="function"?g(S):g;return x.replace?{...S,data:M}:{...S,data:{...S.data,...M}}},x)},getNodesBounds:y=>{const{nodeLookup:g,nodeOrigin:x}=r.getState();return ux(y,{nodeLookup:g,nodeOrigin:x})},getHandleConnections:({type:y,id:g,nodeId:x})=>{var S;return Array.from(((S=r.getState().connectionLookup.get(`${x}-${y}${g?`-${g}`:""}`))==null?void 0:S.values())??[])},getNodeConnections:({type:y,handleId:g,nodeId:x})=>{var S;return Array.from(((S=r.getState().connectionLookup.get(`${x}${y?g?`-${y}-${g}`:`-${y}`:""}`))==null?void 0:S.values())??[])},fitView:async y=>{const g=r.getState().fitViewResolver??gx();return r.setState({fitViewQueued:!0,fitViewOptions:y,fitViewResolver:g}),i.nodeQueue.push(x=>[...x]),g.promise}}},[]);return K.useMemo(()=>({...u,...n,viewportInitialized:l}),[l])}const Oh=n=>n.selected,b1=typeof window<"u"?window:void 0;function Y1({deleteKeyCode:n,multiSelectionKeyCode:r}){const i=$e(),{deleteElements:l}=uc(),u=fi(n,{actInsideInputWithModifier:!1}),c=fi(r,{target:b1});K.useEffect(()=>{if(u){const{edges:f,nodes:h}=i.getState();l({nodes:h.filter(Oh),edges:f.filter(Oh)}),i.setState({nodesSelectionActive:!1})}},[u]),K.useEffect(()=>{i.setState({multiSelectionActive:c})},[c])}function X1(n){const r=$e();K.useEffect(()=>{const i=()=>{var u,c,f,h;if(!n.current||!(((c=(u=n.current).checkVisibility)==null?void 0:c.call(u))??!0))return!1;const l=nc(n.current);(l.height===0||l.width===0)&&((h=(f=r.getState()).onError)==null||h.call(f,"004",Wt.error004())),r.setState({width:l.width||500,height:l.height||500})};if(n.current){i(),window.addEventListener("resize",i);const l=new ResizeObserver(()=>i());return l.observe(n.current),()=>{window.removeEventListener("resize",i),l&&n.current&&l.unobserve(n.current)}}},[])}const wl={position:"absolute",width:"100%",height:"100%",top:0,left:0},Q1=n=>({userSelectionActive:n.userSelectionActive,lib:n.lib,connectionInProgress:n.connection.inProgress});function G1({onPaneContextMenu:n,zoomOnScroll:r=!0,zoomOnPinch:i=!0,panOnScroll:l=!1,panActivationKeyPressed:u,panOnScrollSpeed:c=.5,panOnScrollMode:f=hr.Free,zoomOnDoubleClick:h=!0,panOnDrag:p=!0,defaultViewport:m,translateExtent:v,minZoom:y,maxZoom:g,zoomActivationKeyCode:x,preventScrolling:S=!0,children:M,noWheelClassName:N,noPanClassName:E,onViewportChange:L,isControlledViewport:_,paneClickDistance:P,selectionOnDrag:U}){const D=$e(),V=K.useRef(null),{userSelectionActive:Y,lib:X,connectionInProgress:ee}=Ie(Q1,Ve),q=fi(x),J=K.useRef();X1(V);const Z=K.useCallback(k=>{L==null||L({x:k[0],y:k[1],zoom:k[2]}),_||D.setState({transform:k})},[L,_]);return K.useEffect(()=>{if(V.current){J.current=Zx({domNode:V.current,minZoom:y,maxZoom:g,translateExtent:v,viewport:m,onDraggingChange:H=>D.setState(j=>j.paneDragging===H?j:{paneDragging:H}),onPanZoomStart:(H,j)=>{const{onViewportChangeStart:$,onMoveStart:F}=D.getState();F==null||F(H,j),$==null||$(j)},onPanZoom:(H,j)=>{const{onViewportChange:$,onMove:F}=D.getState();F==null||F(H,j),$==null||$(j)},onPanZoomEnd:(H,j)=>{const{onViewportChangeEnd:$,onMoveEnd:F}=D.getState();F==null||F(H,j),$==null||$(j)}});const{x:k,y:B,zoom:I}=J.current.getViewport();return D.setState({panZoom:J.current,transform:[k,B,I],domNode:V.current.closest(".react-flow")}),()=>{var H;(H=J.current)==null||H.destroy()}}},[]),K.useEffect(()=>{var k;(k=J.current)==null||k.update({onPaneContextMenu:n,zoomOnScroll:r,zoomOnPinch:i,panOnScroll:l,panActivationKeyPressed:u,panOnScrollSpeed:c,panOnScrollMode:f,zoomOnDoubleClick:h,panOnDrag:p,zoomActivationKeyPressed:q,preventScrolling:S,noPanClassName:E,userSelectionActive:Y,noWheelClassName:N,lib:X,onTransformChange:Z,connectionInProgress:ee,selectionOnDrag:U,paneClickDistance:P})},[n,r,i,l,u,c,f,h,p,q,S,E,Y,N,X,Z,ee,U,P]),T.jsx("div",{className:"react-flow__renderer",ref:V,style:wl,children:M})}const K1=n=>({userSelectionActive:n.userSelectionActive,userSelectionRect:n.userSelectionRect});function q1(){const{userSelectionActive:n,userSelectionRect:r}=Ie(K1,Ve);return n&&r?T.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 Ia=(n,r)=>i=>{i.target===r.current&&(n==null||n(i))},Z1=n=>({userSelectionActive:n.userSelectionActive,elementsSelectable:n.elementsSelectable,dragging:n.paneDragging,panBy:n.panBy,autoPanSpeed:n.autoPanSpeed});function J1({isSelecting:n,selectionKeyPressed:r,selectionMode:i=ui.Full,panOnDrag:l,autoPanOnSelection:u,paneClickDistance:c,selectionOnDrag:f,onSelectionStart:h,onSelectionEnd:p,onPaneClick:m,onPaneContextMenu:v,onPaneScroll:y,onPaneMouseEnter:g,onPaneMouseMove:x,onPaneMouseLeave:S,children:M}){const N=K.useRef(0),E=$e(),{userSelectionActive:L,elementsSelectable:_,dragging:P,panBy:U,autoPanSpeed:D}=Ie(Z1,Ve),V=_&&(n||L),Y=K.useRef(null),X=K.useRef(),ee=K.useRef(new Set),q=K.useRef(new Set),J=K.useRef(!1),Z=K.useRef(!1),k=K.useRef({x:0,y:0}),B=K.useRef(!1),I=G=>{if(Z.current||J.current||E.getState().connection.inProgress){Z.current=!1,J.current=!1;return}m==null||m(G),E.getState().resetSelectedElements(),E.setState({nodesSelectionActive:!1})},H=G=>{if(Array.isArray(l)&&(l!=null&&l.includes(2))){G.preventDefault();return}v==null||v(G)},j=y?G=>y(G):void 0,$=G=>{Z.current&&(G.stopPropagation(),Z.current=!1)},F=G=>{var Le,it;if(G.pointerType==="touch"&&l!==!1&&!r)return;const{domNode:se,transform:pe}=E.getState();if(X.current=se==null?void 0:se.getBoundingClientRect(),!X.current)return;const xe=G.target===Y.current;if(!xe&&!!G.target.closest(".nokey")||!n||!(f&&xe||r)||G.button!==0||!G.isPrimary)return;(it=(Le=G.target)==null?void 0:Le.setPointerCapture)==null||it.call(Le,G.pointerId),Z.current=!1;const{x:ke,y:Ce}=Ut(G.nativeEvent,X.current),Me=vi({x:ke,y:Ce},pe);E.setState({userSelectionRect:{width:0,height:0,startX:Me.x,startY:Me.y,x:ke,y:Ce}}),xe||(G.stopPropagation(),G.preventDefault())};function C(G,se){const{userSelectionRect:pe}=E.getState();if(!pe)return;const{transform:xe,nodeLookup:ve,edgeLookup:me,connectionLookup:ke,triggerNodeChanges:Ce,triggerEdgeChanges:Me,defaultEdgeOptions:Le}=E.getState(),it={x:pe.startX,y:pe.startY},{x:ut,y:Je}=oo(it,xe),et={startX:it.x,startY:it.y,x:Gat.id)),q.current=new Set;const Qt=(Le==null?void 0:Le.selectable)??!0;for(const at of ee.current){const Ct=ke.get(at);if(Ct)for(const{edgeId:yt}of Ct.values()){const Mt=me.get(yt);Mt&&(Mt.selectable??Qt)&&q.current.add(yt)}}if(!uh(rn,ee.current)){const at=qr(ve,ee.current,!0);Ce(at)}if(!uh(Xt,q.current)){const at=qr(me,q.current);Me(at)}E.setState({userSelectionRect:et,userSelectionActive:!0,nodesSelectionActive:!1})}function R(){if(!u||!X.current)return;const[G,se]=ec(k.current,X.current,D);U({x:G,y:se}).then(pe=>{if(!Z.current||!pe){N.current=requestAnimationFrame(R);return}const{x:xe,y:ve}=k.current;C(xe,ve),N.current=requestAnimationFrame(R)})}const te=()=>{cancelAnimationFrame(N.current),N.current=0,B.current=!1};K.useEffect(()=>()=>te(),[]);const re=G=>{const{userSelectionRect:se,transform:pe,resetSelectedElements:xe}=E.getState();if(!X.current||!se)return;const{x:ve,y:me}=Ut(G.nativeEvent,X.current);k.current={x:ve,y:me};const ke=oo({x:se.startX,y:se.startY},pe);if(!Z.current){const Ce=r?0:c;if(Math.hypot(ve-ke.x,me-ke.y)<=Ce)return;xe(),h==null||h(G)}Z.current=!0,B.current||(R(),B.current=!0),C(ve,me)},ue=G=>{var se,pe;if(!V){G.target===Y.current&&E.getState().connection.inProgress&&(J.current=!0);return}G.button===0&&((pe=(se=G.target)==null?void 0:se.releasePointerCapture)==null||pe.call(se,G.pointerId),!L&&G.target===Y.current&&E.getState().userSelectionRect&&(I==null||I(G)),E.setState({userSelectionActive:!1,userSelectionRect:null}),Z.current&&(p==null||p(G),E.setState({nodesSelectionActive:ee.current.size>0})),te())},ce=G=>{var se,pe;(pe=(se=G.target)==null?void 0:se.releasePointerCapture)==null||pe.call(se,G.pointerId),te()},ae=l===!0||Array.isArray(l)&&l.includes(0);return T.jsxs("div",{className:be(["react-flow__pane",{draggable:ae,dragging:P,selection:n}]),onClick:V?void 0:Ia(I,Y),onContextMenu:Ia(H,Y),onWheel:Ia(j,Y),onPointerEnter:V?void 0:g,onPointerMove:V?re:x,onPointerUp:ue,onPointerCancel:V?ce:void 0,onPointerDownCapture:V?F:void 0,onClickCapture:V?$:void 0,onPointerLeave:S,ref:Y,style:wl,children:[M,T.jsx(q1,{})]})}function Wa({id:n,store:r,unselect:i=!1,nodeRef:l}){const{addSelectedNodes:u,unselectNodesAndEdges:c,multiSelectionActive:f,nodeLookup:h,onError:p}=r.getState(),m=h.get(n);if(!m){p==null||p("012",Wt.error012(n));return}r.setState({nodesSelectionActive:!1}),m.selected?(i||m.selected&&f)&&(c({nodes:[m],edges:[]}),requestAnimationFrame(()=>{var v;return(v=l==null?void 0:l.current)==null?void 0:v.blur()})):u([n])}function gg({nodeRef:n,disabled:r=!1,noDragClassName:i,handleSelector:l,nodeId:u,isSelectable:c,nodeClickDistance:f}){const h=$e(),[p,m]=K.useState(!1),v=K.useRef();return K.useEffect(()=>{if(!r)return v.current=Ox({getStoreItems:()=>h.getState(),onNodeMouseDown:y=>{Wa({id:y,store:h,nodeRef:n})},onDragStart:()=>{m(!0)},onDragStop:()=>{m(!1)}}),()=>{var y;(y=v.current)==null||y.destroy(),v.current=void 0}},[r,h,n]),K.useEffect(()=>{r||!n.current||!v.current||v.current.update({noDragClassName:i,handleSelector:l,domNode:n.current,isSelectable:c,nodeId:u,nodeClickDistance:f})},[i,l,r,c,n,u,f]),p}const eS=n=>r=>r.selected&&(r.draggable||n&&typeof r.draggable>"u");function mg(){const n=$e();return K.useCallback(i=>{const{nodeExtent:l,snapToGrid:u,snapGrid:c,nodesDraggable:f,onError:h,updateNodePositions:p,nodeLookup:m,nodeOrigin:v}=n.getState(),y=new Map,g=eS(f),x=u?c[0]:5,S=u?c[1]:5,M=i.direction.x*x*i.factor,N=i.direction.y*S*i.factor;for(const[,E]of m){if(!g(E))continue;let L={x:E.internals.positionAbsolute.x+M,y:E.internals.positionAbsolute.y+N};u&&(L=yi(L,c));const{position:_,positionAbsolute:P}=jp({nodeId:E.id,nextPosition:L,nodeLookup:m,nodeExtent:l,nodeOrigin:v,onError:h});E.position=_,E.internals.positionAbsolute=P,y.set(E.id,E)}p(y)},[])}const ac=K.createContext(null),tS=ac.Provider;ac.Consumer;const yg=()=>K.useContext(ac),nS=n=>({connectOnClick:n.connectOnClick,noPanClassName:n.noPanClassName,rfId:n.rfId}),vg=K.createContext(null);function rS({children:n}){const r=Ie(nS,Ve);return T.jsx(vg.Provider,{value:r,children:n})}function oS(){const n=K.useContext(vg);if(!n)throw new Error("useHandleConfig must be used within a HandleConfigProvider");return n}const iS={connectingFrom:!1,connectingTo:!1,clickConnecting:!1,isPossibleEndHandle:!0,connectionInProcess:!1,clickConnectionInProcess:!1,valid:!1},sS=(n,r,i)=>l=>{const{connectionClickStartHandle:u,connectionMode:c,connection:f}=l,{fromHandle:h,toHandle:p,isValid:m}=f;if(!h&&!u)return iS;const v=(p==null?void 0:p.nodeId)===n&&(p==null?void 0:p.id)===r&&(p==null?void 0:p.type)===i;return{connectingFrom:(h==null?void 0:h.nodeId)===n&&(h==null?void 0:h.id)===r&&(h==null?void 0:h.type)===i,connectingTo:v,clickConnecting:(u==null?void 0:u.nodeId)===n&&(u==null?void 0:u.id)===r&&(u==null?void 0:u.type)===i,isPossibleEndHandle:c===no.Strict?(h==null?void 0:h.type)!==i:n!==(h==null?void 0:h.nodeId)||r!==(h==null?void 0:h.id),connectionInProcess:!!h,clickConnectionInProcess:!!u,valid:v&&m}};function lS({type:n="source",position:r=we.Top,isValidConnection:i,isConnectable:l=!0,isConnectableStart:u=!0,isConnectableEnd:c=!0,id:f,onConnect:h,children:p,className:m,onMouseDown:v,onTouchStart:y,...g},x){var B,I;const S=f||null,M=n==="target",N=$e(),E=yg(),{connectOnClick:L,noPanClassName:_,rfId:P}=oS(),{connectingFrom:U,connectingTo:D,clickConnecting:V,isPossibleEndHandle:Y,connectionInProcess:X,clickConnectionInProcess:ee,valid:q}=Ie(sS(E,S,n),Ve);E||(I=(B=N.getState()).onError)==null||I.call(B,"010",Wt.error010());const J=H=>{const{defaultEdgeOptions:j,onConnect:$,hasDefaultEdges:F}=N.getState(),C={...j,...H};if(F){const{edges:R,setEdges:te,onError:re}=N.getState();te(F1(C,R,{onError:re}))}$==null||$(C),h==null||h(C)},Z=H=>{if(!E)return;const j=Wp(H.nativeEvent);if(u&&(j&&H.button===0||!j)){const $=N.getState();Ua.onPointerDown(H.nativeEvent,{handleDomNode:H.currentTarget,autoPanOnConnect:$.autoPanOnConnect,connectionMode:$.connectionMode,connectionRadius:$.connectionRadius,domNode:$.domNode,nodeLookup:$.nodeLookup,lib:$.lib,isTarget:M,handleId:S,nodeId:E,flowId:$.rfId,panBy:$.panBy,cancelConnection:$.cancelConnection,onConnectStart:$.onConnectStart,onConnectEnd:(...F)=>{var C,R;return(R=(C=N.getState()).onConnectEnd)==null?void 0:R.call(C,...F)},updateConnection:$.updateConnection,onConnect:J,isValidConnection:i||((...F)=>{var C,R;return((R=(C=N.getState()).isValidConnection)==null?void 0:R.call(C,...F))??!0}),getTransform:()=>N.getState().transform,getFromHandle:()=>N.getState().connection.fromHandle,autoPanSpeed:$.autoPanSpeed,dragThreshold:$.connectionDragThreshold})}j?v==null||v(H):y==null||y(H)},k=H=>{const{onClickConnectStart:j,onClickConnectEnd:$,connectionClickStartHandle:F,connectionMode:C,isValidConnection:R,lib:te,rfId:re,nodeLookup:ue,connection:ce}=N.getState();if(!E||!F&&!u)return;if(!F){j==null||j(H.nativeEvent,{nodeId:E,handleId:S,handleType:n}),N.setState({connectionClickStartHandle:{nodeId:E,type:n,id:S}});return}const ae=Bp(H.target),G=i||R,{connection:se,isValid:pe}=Ua.isValid(H.nativeEvent,{handle:{nodeId:E,id:S,type:n},connectionMode:C,fromNodeId:F.nodeId,fromHandleId:F.id||null,fromType:F.type,isValidConnection:G,flowId:re,doc:ae,lib:te,nodeLookup:ue});pe&&se&&J(se);const xe=structuredClone(ce);delete xe.inProgress,xe.toPosition=xe.toHandle?xe.toHandle.position:null,$==null||$(H,xe),N.setState({connectionClickStartHandle:null})};return T.jsx("div",{"data-handleid":S,"data-nodeid":E,"data-handlepos":r,"data-id":`${P}-${E}-${S}-${n}`,className:be(["react-flow__handle",`react-flow__handle-${r}`,"nodrag",_,m,{source:!M,target:M,connectable:l,connectablestart:u,connectableend:c,clickconnecting:V,connectingfrom:U,connectingto:D,valid:q,connectionindicator:l&&(!X||Y)&&(X||ee?c:u)}]),onMouseDown:Z,onTouchStart:Z,onClick:L?k:void 0,ref:x,...g,children:p})}const ll=K.memo(dg(lS));function uS({data:n,isConnectable:r,sourcePosition:i=we.Bottom}){return T.jsxs(T.Fragment,{children:[n==null?void 0:n.label,T.jsx(ll,{type:"source",position:i,isConnectable:r})]})}function aS({data:n,isConnectable:r,targetPosition:i=we.Top,sourcePosition:l=we.Bottom}){return T.jsxs(T.Fragment,{children:[T.jsx(ll,{type:"target",position:i,isConnectable:r}),n==null?void 0:n.label,T.jsx(ll,{type:"source",position:l,isConnectable:r})]})}function cS(){return null}function fS({data:n,isConnectable:r,targetPosition:i=we.Top}){return T.jsxs(T.Fragment,{children:[T.jsx(ll,{type:"target",position:i,isConnectable:r}),n==null?void 0:n.label]})}const ul={ArrowUp:{x:0,y:-1},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0},ArrowRight:{x:1,y:0}},Fh={input:uS,default:aS,output:fS,group:cS};function dS(n){var r,i,l,u;return n.internals.handleBounds===void 0?{width:n.width??n.initialWidth??((r=n.style)==null?void 0:r.width),height:n.height??n.initialHeight??((i=n.style)==null?void 0:i.height)}:{width:n.width??((l=n.style)==null?void 0:l.width),height:n.height??((u=n.style)==null?void 0:u.height)}}const hS=n=>{const{width:r,height:i,x:l,y:u}=mi(n.nodeLookup,{filter:c=>!!c.selected});return{width:Bt(r)?r:null,height:Bt(i)?i:null,userSelectionActive:n.userSelectionActive,transformString:`translate(${n.transform[0]}px,${n.transform[1]}px) scale(${n.transform[2]}) translate(${l}px,${u}px)`}};function pS({onSelectionContextMenu:n,noPanClassName:r,disableKeyboardA11y:i}){const l=$e(),{width:u,height:c,transformString:f,userSelectionActive:h}=Ie(hS,Ve),p=mg(),m=K.useRef(null);K.useEffect(()=>{var x;i||(x=m.current)==null||x.focus({preventScroll:!0})},[i]);const v=!h&&u!==null&&c!==null;if(gg({nodeRef:m,disabled:!v}),!v)return null;const y=n?x=>{const S=l.getState().nodes.filter(M=>M.selected);n(x,S)}:void 0,g=x=>{Object.prototype.hasOwnProperty.call(ul,x.key)&&(x.preventDefault(),p({direction:ul[x.key],factor:x.shiftKey?4:1}))};return T.jsx("div",{className:be(["react-flow__nodesselection","react-flow__container",r]),style:{transform:f},children:T.jsx("div",{ref:m,className:"react-flow__nodesselection-rect",onContextMenu:y,tabIndex:i?void 0:-1,onKeyDown:i?void 0:g,style:{width:u,height:c}})})}const Hh=typeof window<"u"?window:void 0,gS=n=>({nodesSelectionActive:n.nodesSelectionActive,userSelectionActive:n.userSelectionActive});function wg({children:n,onPaneClick:r,onPaneMouseEnter:i,onPaneMouseMove:l,onPaneMouseLeave:u,onPaneContextMenu:c,onPaneScroll:f,paneClickDistance:h,deleteKeyCode:p,selectionKeyCode:m,selectionOnDrag:v,selectionMode:y,onSelectionStart:g,onSelectionEnd:x,multiSelectionKeyCode:S,panActivationKeyCode:M,zoomActivationKeyCode:N,elementsSelectable:E,zoomOnScroll:L,zoomOnPinch:_,panOnScroll:P,panOnScrollSpeed:U,panOnScrollMode:D,zoomOnDoubleClick:V,panOnDrag:Y,autoPanOnSelection:X,defaultViewport:ee,translateExtent:q,minZoom:J,maxZoom:Z,preventScrolling:k,onSelectionContextMenu:B,noWheelClassName:I,noPanClassName:H,disableKeyboardA11y:j,onViewportChange:$,isControlledViewport:F}){const{nodesSelectionActive:C,userSelectionActive:R}=Ie(gS,Ve),te=fi(m,{target:Hh}),re=fi(M,{target:Hh}),ue=re||Y,ce=re||P,ae=v&&ue!==!0,G=te||R||ae;return Y1({deleteKeyCode:p,multiSelectionKeyCode:S}),T.jsx(G1,{onPaneContextMenu:c,elementsSelectable:E,zoomOnScroll:L,zoomOnPinch:_,panOnScroll:ce,panActivationKeyPressed:re,panOnScrollSpeed:U,panOnScrollMode:D,zoomOnDoubleClick:V,panOnDrag:!te&&ue,defaultViewport:ee,translateExtent:q,minZoom:J,maxZoom:Z,zoomActivationKeyCode:N,preventScrolling:k,noWheelClassName:I,noPanClassName:H,onViewportChange:$,isControlledViewport:F,paneClickDistance:h,selectionOnDrag:ae,children:T.jsxs(J1,{onSelectionStart:g,onSelectionEnd:x,onPaneClick:r,onPaneMouseEnter:i,onPaneMouseMove:l,onPaneMouseLeave:u,onPaneContextMenu:c,onPaneScroll:f,panOnDrag:ue,autoPanOnSelection:X,isSelecting:!!G,selectionMode:y,selectionKeyPressed:te,paneClickDistance:h,selectionOnDrag:ae,children:[n,C&&T.jsx(pS,{onSelectionContextMenu:B,noPanClassName:H,disableKeyboardA11y:j})]})})}wg.displayName="FlowRenderer";const mS=K.memo(wg),yS=n=>r=>n?Ja(r.nodeLookup,{x:0,y:0,width:r.width,height:r.height},r.transform,!0).map(i=>i.id):Array.from(r.nodeLookup.keys());function vS(n){return Ie(K.useCallback(yS(n),[n]),Ve)}const wS=n=>n.updateNodeInternals;function xS(){const n=Ie(wS),[r]=K.useState(()=>typeof ResizeObserver>"u"?null:new ResizeObserver(i=>{const l=new Map;i.forEach(u=>{const c=u.target.getAttribute("data-id");l.set(c,{id:c,nodeElement:u.target,force:!0})}),n(l)}));return K.useEffect(()=>()=>{r==null||r.disconnect()},[r]),r}function SS({node:n,nodeType:r,hasDimensions:i,resizeObserver:l}){const u=$e(),c=K.useRef(null),f=K.useRef(null),h=K.useRef(n.sourcePosition),p=K.useRef(n.targetPosition),m=K.useRef(r),v=i&&!!n.internals.handleBounds;return K.useEffect(()=>{c.current&&!n.hidden&&(!v||f.current!==c.current)&&(f.current&&(l==null||l.unobserve(f.current)),l==null||l.observe(c.current),f.current=c.current)},[v,n.hidden]),K.useEffect(()=>()=>{f.current&&(l==null||l.unobserve(f.current),f.current=null)},[]),K.useEffect(()=>{if(c.current){const y=m.current!==r,g=h.current!==n.sourcePosition,x=p.current!==n.targetPosition;(y||g||x)&&(m.current=r,h.current=n.sourcePosition,p.current=n.targetPosition,u.getState().updateNodeInternals(new Map([[n.id,{id:n.id,nodeElement:c.current,force:!0}]])))}},[n.id,r,n.sourcePosition,n.targetPosition]),c}function _S({id:n,onClick:r,onMouseEnter:i,onMouseMove:l,onMouseLeave:u,onContextMenu:c,onDoubleClick:f,nodesDraggable:h,elementsSelectable:p,nodesConnectable:m,nodesFocusable:v,resizeObserver:y,noDragClassName:g,noPanClassName:x,disableKeyboardA11y:S,rfId:M,nodeTypes:N,nodeClickDistance:E,onError:L}){const{node:_,internals:P,isParent:U}=Ie(G=>{const se=G.nodeLookup.get(n),pe=G.parentLookup.has(n);return{node:se,internals:se.internals,isParent:pe}},Ve);let D=_.type||"default",V=(N==null?void 0:N[D])||Fh[D];V===void 0&&(L==null||L("003",Wt.error003(D)),D="default",V=(N==null?void 0:N.default)||Fh.default);const Y=!!(_.draggable||h&&typeof _.draggable>"u"),X=!!(_.selectable||p&&typeof _.selectable>"u"),ee=!!(_.connectable||m&&typeof _.connectable>"u"),q=!!(_.focusable||v&&typeof _.focusable>"u"),J=$e(),Z=Hp(_),k=SS({node:_,nodeType:D,hasDimensions:Z,resizeObserver:y}),B=gg({nodeRef:k,disabled:_.hidden||!Y,noDragClassName:g,handleSelector:_.dragHandle,nodeId:n,isSelectable:X,nodeClickDistance:E}),I=mg();if(_.hidden)return null;const H=Yt(_),j=dS(_),$=X||Y||r||i||l||u,F=i?G=>i(G,{...P.userNode}):void 0,C=l?G=>l(G,{...P.userNode}):void 0,R=u?G=>u(G,{...P.userNode}):void 0,te=c?G=>c(G,{...P.userNode}):void 0,re=f?G=>f(G,{...P.userNode}):void 0,ue=G=>{const{selectNodesOnDrag:se,nodeDragThreshold:pe}=J.getState();X&&(!se||!Y||pe>0)&&Wa({id:n,store:J,nodeRef:k}),r&&r(G,{...P.userNode})},ce=G=>{if(!(Up(G.nativeEvent)||S)){if(zp.includes(G.key)&&X){const se=G.key==="Escape";Wa({id:n,store:J,unselect:se,nodeRef:k})}else if(Y&&_.selected&&Object.prototype.hasOwnProperty.call(ul,G.key)){G.preventDefault();const{ariaLabelConfig:se}=J.getState();J.setState({ariaLiveMessage:se["node.a11yDescription.ariaLiveMessage"]({direction:G.key.replace("Arrow","").toLowerCase(),x:~~P.positionAbsolute.x,y:~~P.positionAbsolute.y})}),I({direction:ul[G.key],factor:G.shiftKey?4:1})}}},ae=()=>{var ke;if(S||!((ke=k.current)!=null&&ke.matches(":focus-visible")))return;const{transform:G,width:se,height:pe,autoPanOnNodeFocus:xe,setCenter:ve}=J.getState();if(!xe)return;Ja(new Map([[n,_]]),{x:0,y:0,width:se,height:pe},G,!0).length>0||ve(_.position.x+H.width/2,_.position.y+H.height/2,{zoom:G[2]})};return T.jsx("div",{className:be(["react-flow__node",`react-flow__node-${D}`,{[x]:Y},_.className,{selected:_.selected,selectable:X,parent:U,draggable:Y,dragging:B}]),ref:k,style:{zIndex:P.z,transform:`translate(${P.positionAbsolute.x}px,${P.positionAbsolute.y}px)`,pointerEvents:$?"all":"none",visibility:Z?"visible":"hidden",..._.style,...j},"data-id":n,"data-testid":`rf__node-${n}`,onMouseEnter:F,onMouseMove:C,onMouseLeave:R,onContextMenu:te,onClick:ue,onDoubleClick:re,onKeyDown:q?ce:void 0,tabIndex:q?0:void 0,onFocus:q?ae:void 0,role:_.ariaRole??(q?"group":void 0),"aria-roledescription":"node","aria-describedby":S?void 0:`${ug}-${M}`,"aria-label":_.ariaLabel,..._.domAttributes,children:T.jsx(tS,{value:n,children:T.jsx(V,{id:n,data:_.data,type:D,positionAbsoluteX:P.positionAbsolute.x,positionAbsoluteY:P.positionAbsolute.y,selected:_.selected??!1,selectable:X,draggable:Y,deletable:_.deletable??!0,isConnectable:ee,sourcePosition:_.sourcePosition,targetPosition:_.targetPosition,dragging:B,dragHandle:_.dragHandle,zIndex:P.z,parentId:_.parentId,...H})})})}var ES=K.memo(_S);const kS=n=>({nodesConnectable:n.nodesConnectable,nodesFocusable:n.nodesFocusable,elementsSelectable:n.elementsSelectable,onError:n.onError});function xg(n){const{nodesConnectable:r,nodesFocusable:i,elementsSelectable:l,onError:u}=Ie(kS,Ve),c=vS(n.onlyRenderVisibleElements),f=xS();return T.jsx("div",{className:"react-flow__nodes",style:wl,children:c.map(h=>T.jsx(ES,{id:h,nodeTypes:n.nodeTypes,nodeExtent:n.nodeExtent,onClick:n.onNodeClick,onMouseEnter:n.onNodeMouseEnter,onMouseMove:n.onNodeMouseMove,onMouseLeave:n.onNodeMouseLeave,onContextMenu:n.onNodeContextMenu,onDoubleClick:n.onNodeDoubleClick,noDragClassName:n.noDragClassName,noPanClassName:n.noPanClassName,rfId:n.rfId,disableKeyboardA11y:n.disableKeyboardA11y,resizeObserver:f,nodesDraggable:n.nodesDraggable??!0,nodesConnectable:r,nodesFocusable:i,elementsSelectable:l,nodeClickDistance:n.nodeClickDistance,onError:u},h))})}xg.displayName="NodeRenderer";const NS=K.memo(xg);function CS(n){return Ie(K.useCallback(i=>{if(!n)return i.edges.map(u=>u.id);const l=[];if(i.width&&i.height)for(const u of i.edges){const c=i.nodeLookup.get(u.source),f=i.nodeLookup.get(u.target);c&&f&&wx({sourceNode:c,targetNode:f,width:i.width,height:i.height,transform:i.transform})&&l.push(u.id)}return l},[n]),Ve)}const MS=({color:n="none",strokeWidth:r=1})=>{const i={strokeWidth:r,...n&&{stroke:n}};return T.jsx("polyline",{className:"arrow",style:i,strokeLinecap:"round",fill:"none",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4"})},PS=({color:n="none",strokeWidth:r=1})=>{const i={strokeWidth:r,...n&&{stroke:n,fill:n}};return T.jsx("polyline",{className:"arrowclosed",style:i,strokeLinecap:"round",strokeLinejoin:"round",points:"-5,-4 0,0 -5,4 -5,-4"})},Vh={[ol.Arrow]:MS,[ol.ArrowClosed]:PS};function IS(n){const r=$e();return K.useMemo(()=>{var u,c;return Object.prototype.hasOwnProperty.call(Vh,n)?Vh[n]:((c=(u=r.getState()).onError)==null||c.call(u,"009",Wt.error009(n)),null)},[n])}const zS=({id:n,type:r,color:i,width:l=12.5,height:u=12.5,markerUnits:c="strokeWidth",strokeWidth:f,orient:h="auto-start-reverse"})=>{const p=IS(r);return p?T.jsx("marker",{className:"react-flow__arrowhead",id:n,markerWidth:`${l}`,markerHeight:`${u}`,viewBox:"-10 -10 20 20",markerUnits:c,orient:h,refX:"0",refY:"0",children:T.jsx(p,{color:i,strokeWidth:f})}):null},Sg=({defaultColor:n,rfId:r})=>{const i=Ie(c=>c.edges),l=Ie(c=>c.defaultEdgeOptions),u=K.useMemo(()=>Mx(i,{id:r,defaultColor:n,defaultMarkerStart:l==null?void 0:l.markerStart,defaultMarkerEnd:l==null?void 0:l.markerEnd}),[i,l,r,n]);return u.length?T.jsx("svg",{className:"react-flow__marker","aria-hidden":"true",children:T.jsx("defs",{children:u.map(c=>T.jsx(zS,{id:c.id,type:c.type,color:c.color,width:c.width,height:c.height,markerUnits:c.markerUnits,strokeWidth:c.strokeWidth,orient:c.orient},c.id))})}):null};Sg.displayName="MarkerDefinitions";var TS=K.memo(Sg);function _g({x:n,y:r,label:i,labelStyle:l,labelShowBg:u=!0,labelBgStyle:c,labelBgPadding:f=[2,4],labelBgBorderRadius:h=2,children:p,className:m,...v}){const[y,g]=K.useState({x:1,y:0,width:0,height:0}),x=be(["react-flow__edge-textwrapper",m]),S=K.useRef(null);return K.useEffect(()=>{if(S.current){const M=S.current.getBBox();g({x:M.x,y:M.y,width:M.width,height:M.height})}},[i]),i?T.jsxs("g",{transform:`translate(${n-y.width/2} ${r-y.height/2})`,className:x,visibility:y.width?"visible":"hidden",...v,children:[u&&T.jsx("rect",{width:y.width+2*f[0],x:-f[0],y:-f[1],height:y.height+2*f[1],className:"react-flow__edge-textbg",style:c,rx:h,ry:h}),T.jsx("text",{className:"react-flow__edge-text",y:y.height/2,dy:"0.3em",ref:S,style:l,children:i}),p]}):null}_g.displayName="EdgeText";const LS=K.memo(_g);function xl({path:n,labelX:r,labelY:i,label:l,labelStyle:u,labelShowBg:c,labelBgStyle:f,labelBgPadding:h,labelBgBorderRadius:p,interactionWidth:m=20,...v}){return T.jsxs(T.Fragment,{children:[T.jsx("path",{...v,d:n,fill:"none",className:be(["react-flow__edge-path",v.className])}),m?T.jsx("path",{d:n,fill:"none",strokeOpacity:0,strokeWidth:m,className:"react-flow__edge-interaction"}):null,l&&Bt(r)&&Bt(i)?T.jsx(LS,{x:r,y:i,label:l,labelStyle:u,labelShowBg:c,labelBgStyle:f,labelBgPadding:h,labelBgBorderRadius:p}):null]})}function Bh({pos:n,x1:r,y1:i,x2:l,y2:u}){return n===we.Left||n===we.Right?[.5*(r+l),i]:[r,.5*(i+u)]}function Eg({sourceX:n,sourceY:r,sourcePosition:i=we.Bottom,targetX:l,targetY:u,targetPosition:c=we.Top}){const[f,h]=Bh({pos:i,x1:n,y1:r,x2:l,y2:u}),[p,m]=Bh({pos:c,x1:l,y1:u,x2:n,y2:r}),[v,y,g,x]=bp({sourceX:n,sourceY:r,targetX:l,targetY:u,sourceControlX:f,sourceControlY:h,targetControlX:p,targetControlY:m});return[`M${n},${r} C${f},${h} ${p},${m} ${l},${u}`,v,y,g,x]}function kg(n){return K.memo(({id:r,sourceX:i,sourceY:l,targetX:u,targetY:c,sourcePosition:f,targetPosition:h,label:p,labelStyle:m,labelShowBg:v,labelBgStyle:y,labelBgPadding:g,labelBgBorderRadius:x,style:S,markerEnd:M,markerStart:N,interactionWidth:E})=>{const[L,_,P]=Eg({sourceX:i,sourceY:l,sourcePosition:f,targetX:u,targetY:c,targetPosition:h}),U=n.isInternal?void 0:r;return T.jsx(xl,{id:U,path:L,labelX:_,labelY:P,label:p,labelStyle:m,labelShowBg:v,labelBgStyle:y,labelBgPadding:g,labelBgBorderRadius:x,style:S,markerEnd:M,markerStart:N,interactionWidth:E})})}const RS=kg({isInternal:!1}),Ng=kg({isInternal:!0});RS.displayName="SimpleBezierEdge";Ng.displayName="SimpleBezierEdgeInternal";function Cg(n){return K.memo(({id:r,sourceX:i,sourceY:l,targetX:u,targetY:c,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:m,labelBgPadding:v,labelBgBorderRadius:y,style:g,sourcePosition:x=we.Bottom,targetPosition:S=we.Top,markerEnd:M,markerStart:N,pathOptions:E,interactionWidth:L})=>{const[_,P,U]=Ha({sourceX:i,sourceY:l,sourcePosition:x,targetX:u,targetY:c,targetPosition:S,borderRadius:E==null?void 0:E.borderRadius,offset:E==null?void 0:E.offset,stepPosition:E==null?void 0:E.stepPosition}),D=n.isInternal?void 0:r;return T.jsx(xl,{id:D,path:_,labelX:P,labelY:U,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:m,labelBgPadding:v,labelBgBorderRadius:y,style:g,markerEnd:M,markerStart:N,interactionWidth:L})})}const Mg=Cg({isInternal:!1}),Pg=Cg({isInternal:!0});Mg.displayName="SmoothStepEdge";Pg.displayName="SmoothStepEdgeInternal";function Ig(n){return K.memo(({id:r,...i})=>{var u;const l=n.isInternal?void 0:r;return T.jsx(Mg,{...i,id:l,pathOptions:K.useMemo(()=>{var c;return{borderRadius:0,offset:(c=i.pathOptions)==null?void 0:c.offset}},[(u=i.pathOptions)==null?void 0:u.offset])})})}const AS=Ig({isInternal:!1}),zg=Ig({isInternal:!0});AS.displayName="StepEdge";zg.displayName="StepEdgeInternal";function Tg(n){return K.memo(({id:r,sourceX:i,sourceY:l,targetX:u,targetY:c,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:m,labelBgPadding:v,labelBgBorderRadius:y,style:g,markerEnd:x,markerStart:S,interactionWidth:M})=>{const[N,E,L]=Qp({sourceX:i,sourceY:l,targetX:u,targetY:c}),_=n.isInternal?void 0:r;return T.jsx(xl,{id:_,path:N,labelX:E,labelY:L,label:f,labelStyle:h,labelShowBg:p,labelBgStyle:m,labelBgPadding:v,labelBgBorderRadius:y,style:g,markerEnd:x,markerStart:S,interactionWidth:M})})}const jS=Tg({isInternal:!1}),Lg=Tg({isInternal:!0});jS.displayName="StraightEdge";Lg.displayName="StraightEdgeInternal";function Rg(n){return K.memo(({id:r,sourceX:i,sourceY:l,targetX:u,targetY:c,sourcePosition:f=we.Bottom,targetPosition:h=we.Top,label:p,labelStyle:m,labelShowBg:v,labelBgStyle:y,labelBgPadding:g,labelBgBorderRadius:x,style:S,markerEnd:M,markerStart:N,pathOptions:E,interactionWidth:L})=>{const[_,P,U]=Yp({sourceX:i,sourceY:l,sourcePosition:f,targetX:u,targetY:c,targetPosition:h,curvature:E==null?void 0:E.curvature}),D=n.isInternal?void 0:r;return T.jsx(xl,{id:D,path:_,labelX:P,labelY:U,label:p,labelStyle:m,labelShowBg:v,labelBgStyle:y,labelBgPadding:g,labelBgBorderRadius:x,style:S,markerEnd:M,markerStart:N,interactionWidth:L})})}const $S=Rg({isInternal:!1}),Ag=Rg({isInternal:!0});$S.displayName="BezierEdge";Ag.displayName="BezierEdgeInternal";const Uh={default:Ag,straight:Lg,step:zg,smoothstep:Pg,simplebezier:Ng},Wh={sourceX:null,sourceY:null,targetX:null,targetY:null,sourcePosition:null,targetPosition:null,zIndex:void 0},DS=(n,r,i)=>i===we.Left?n-r:i===we.Right?n+r:n,OS=(n,r,i)=>i===we.Top?n-r:i===we.Bottom?n+r:n,bh="react-flow__edgeupdater";function Yh({position:n,centerX:r,centerY:i,radius:l=10,onMouseDown:u,onMouseEnter:c,onMouseOut:f,type:h}){return T.jsx("circle",{onMouseDown:u,onMouseEnter:c,onMouseOut:f,className:be([bh,`${bh}-${h}`]),cx:DS(r,l,n),cy:OS(i,l,n),r:l,stroke:"transparent",fill:"transparent"})}function FS({isReconnectable:n,reconnectRadius:r,edge:i,sourceX:l,sourceY:u,targetX:c,targetY:f,sourcePosition:h,targetPosition:p,onReconnect:m,onReconnectStart:v,onReconnectEnd:y,setReconnecting:g,setUpdateHover:x}){const S=$e(),M=(P,U)=>{if(P.button!==0)return;const{autoPanOnConnect:D,domNode:V,connectionMode:Y,connectionRadius:X,lib:ee,onConnectStart:q,cancelConnection:J,nodeLookup:Z,rfId:k,panBy:B,updateConnection:I}=S.getState(),H=U.type==="target",j=(C,R)=>{g(!1),y==null||y(C,i,U.type,R)},$=C=>m==null?void 0:m(i,C),F=(C,R)=>{g(!0),v==null||v(P,i,U.type),q==null||q(C,R)};Ua.onPointerDown(P.nativeEvent,{autoPanOnConnect:D,connectionMode:Y,connectionRadius:X,domNode:V,handleId:U.id,nodeId:U.nodeId,nodeLookup:Z,isTarget:H,edgeUpdaterType:U.type,lib:ee,flowId:k,cancelConnection:J,panBy:B,isValidConnection:(...C)=>{var R,te;return((te=(R=S.getState()).isValidConnection)==null?void 0:te.call(R,...C))??!0},onConnect:$,onConnectStart:F,onConnectEnd:(...C)=>{var R,te;return(te=(R=S.getState()).onConnectEnd)==null?void 0:te.call(R,...C)},onReconnectEnd:j,updateConnection:I,getTransform:()=>S.getState().transform,getFromHandle:()=>S.getState().connection.fromHandle,dragThreshold:S.getState().connectionDragThreshold,handleDomNode:P.currentTarget})},N=P=>M(P,{nodeId:i.target,id:i.targetHandle??null,type:"target"}),E=P=>M(P,{nodeId:i.source,id:i.sourceHandle??null,type:"source"}),L=()=>x(!0),_=()=>x(!1);return T.jsxs(T.Fragment,{children:[(n===!0||n==="source")&&T.jsx(Yh,{position:h,centerX:l,centerY:u,radius:r,onMouseDown:N,onMouseEnter:L,onMouseOut:_,type:"source"}),(n===!0||n==="target")&&T.jsx(Yh,{position:p,centerX:c,centerY:f,radius:r,onMouseDown:E,onMouseEnter:L,onMouseOut:_,type:"target"})]})}function HS({id:n,edgesFocusable:r,edgesReconnectable:i,elementsSelectable:l,onClick:u,onDoubleClick:c,onContextMenu:f,onMouseEnter:h,onMouseMove:p,onMouseLeave:m,reconnectRadius:v,onReconnect:y,onReconnectStart:g,onReconnectEnd:x,rfId:S,edgeTypes:M,noPanClassName:N,onError:E,disableKeyboardA11y:L}){let _=Ie(ve=>ve.edgeLookup.get(n));const P=Ie(ve=>ve.defaultEdgeOptions);_=P?{...P,..._}:_;let U=_.type||"default",D=(M==null?void 0:M[U])||Uh[U];D===void 0&&(E==null||E("011",Wt.error011(U)),U="default",D=(M==null?void 0:M.default)||Uh.default);const V=!!(_.focusable||r&&typeof _.focusable>"u"),Y=typeof y<"u"&&(_.reconnectable||i&&typeof _.reconnectable>"u"),X=!!(_.selectable||l&&typeof _.selectable>"u"),ee=K.useRef(null),[q,J]=K.useState(!1),[Z,k]=K.useState(!1),B=$e(),{zIndex:I=_.zIndex,sourceX:H,sourceY:j,targetX:$,targetY:F,sourcePosition:C,targetPosition:R}=Ie(K.useCallback(ve=>{const me=ve.nodeLookup.get(_.source),ke=ve.nodeLookup.get(_.target);if(!me||!ke)return Wh;const Ce=Cx({id:n,sourceNode:me,targetNode:ke,sourceHandle:_.sourceHandle||null,targetHandle:_.targetHandle||null,connectionMode:ve.connectionMode,onError:E}),Me=vx({selected:_.selected,zIndex:_.zIndex,sourceNode:me,targetNode:ke,elevateOnSelect:ve.elevateEdgesOnSelect,zIndexMode:ve.zIndexMode});return{...Ce||Wh,zIndex:Me}},[_.source,_.target,_.sourceHandle,_.targetHandle,_.selected,_.zIndex,E]),Ve),te=K.useMemo(()=>_.markerStart?`url('#${Va(_.markerStart,S)}')`:void 0,[_.markerStart,S]),re=K.useMemo(()=>_.markerEnd?`url('#${Va(_.markerEnd,S)}')`:void 0,[_.markerEnd,S]);if(_.hidden||H===null||j===null||$===null||F===null)return null;const ue=ve=>{var Me;const{addSelectedEdges:me,unselectNodesAndEdges:ke,multiSelectionActive:Ce}=B.getState();X&&(B.setState({nodesSelectionActive:!1}),_.selected&&Ce?(ke({nodes:[],edges:[_]}),(Me=ee.current)==null||Me.blur()):me([n])),u&&u(ve,_)},ce=c?ve=>{c(ve,{..._})}:void 0,ae=f?ve=>{f(ve,{..._})}:void 0,G=h?ve=>{h(ve,{..._})}:void 0,se=p?ve=>{p(ve,{..._})}:void 0,pe=m?ve=>{m(ve,{..._})}:void 0,xe=ve=>{var me;if(!L&&zp.includes(ve.key)&&X){const{unselectNodesAndEdges:ke,addSelectedEdges:Ce}=B.getState();ve.key==="Escape"?((me=ee.current)==null||me.blur(),ke({edges:[_]})):Ce([n])}};return T.jsx("svg",{style:{zIndex:I},children:T.jsxs("g",{className:be(["react-flow__edge",`react-flow__edge-${U}`,_.className,N,{selected:_.selected,animated:_.animated,inactive:!X&&!u,updating:q,selectable:X}]),onClick:ue,onDoubleClick:ce,onContextMenu:ae,onMouseEnter:G,onMouseMove:se,onMouseLeave:pe,onKeyDown:V?xe:void 0,tabIndex:V?0:void 0,role:_.ariaRole??(V?"group":"img"),"aria-roledescription":"edge","data-id":n,"data-testid":`rf__edge-${n}`,"aria-label":_.ariaLabel===null?void 0:_.ariaLabel||`Edge from ${_.source} to ${_.target}`,"aria-describedby":V?`${ag}-${S}`:void 0,ref:ee,..._.domAttributes,children:[!Z&&T.jsx(D,{id:n,source:_.source,target:_.target,type:_.type,selected:_.selected,animated:_.animated,selectable:X,deletable:_.deletable??!0,label:_.label,labelStyle:_.labelStyle,labelShowBg:_.labelShowBg,labelBgStyle:_.labelBgStyle,labelBgPadding:_.labelBgPadding,labelBgBorderRadius:_.labelBgBorderRadius,sourceX:H,sourceY:j,targetX:$,targetY:F,sourcePosition:C,targetPosition:R,data:_.data,style:_.style,sourceHandleId:_.sourceHandle,targetHandleId:_.targetHandle,markerStart:te,markerEnd:re,pathOptions:"pathOptions"in _?_.pathOptions:void 0,interactionWidth:_.interactionWidth}),Y&&T.jsx(FS,{edge:_,isReconnectable:Y,reconnectRadius:v,onReconnect:y,onReconnectStart:g,onReconnectEnd:x,sourceX:H,sourceY:j,targetX:$,targetY:F,sourcePosition:C,targetPosition:R,setUpdateHover:J,setReconnecting:k})]})})}var VS=K.memo(HS);const BS=n=>({edgesFocusable:n.edgesFocusable,edgesReconnectable:n.edgesReconnectable,elementsSelectable:n.elementsSelectable,connectionMode:n.connectionMode,onError:n.onError});function jg({defaultMarkerColor:n,onlyRenderVisibleElements:r,rfId:i,edgeTypes:l,noPanClassName:u,onReconnect:c,onEdgeContextMenu:f,onEdgeMouseEnter:h,onEdgeMouseMove:p,onEdgeMouseLeave:m,onEdgeClick:v,reconnectRadius:y,onEdgeDoubleClick:g,onReconnectStart:x,onReconnectEnd:S,disableKeyboardA11y:M}){const{edgesFocusable:N,edgesReconnectable:E,elementsSelectable:L,onError:_}=Ie(BS,Ve),P=CS(r);return T.jsxs("div",{className:"react-flow__edges",children:[T.jsx(TS,{defaultColor:n,rfId:i}),P.map(U=>T.jsx(VS,{id:U,edgesFocusable:N,edgesReconnectable:E,elementsSelectable:L,noPanClassName:u,onReconnect:c,onContextMenu:f,onMouseEnter:h,onMouseMove:p,onMouseLeave:m,onClick:v,reconnectRadius:y,onDoubleClick:g,onReconnectStart:x,onReconnectEnd:S,rfId:i,onError:_,edgeTypes:l,disableKeyboardA11y:M},U))]})}jg.displayName="EdgeRenderer";const US=K.memo(jg),Xh=n=>`translate(${n[0]}px,${n[1]}px) scale(${n[2]})`;function WS({children:n}){const r=$e(),i=K.useRef(null),[l]=K.useState(()=>r.getState().transform);return hg(()=>{let u=null;const c=()=>{const f=r.getState().transform;u&&f[0]===u[0]&&f[1]===u[1]&&f[2]===u[2]||(u=f,i.current&&(i.current.style.transform=Xh(f)))};return c(),r.subscribe(c)},[r]),T.jsx("div",{ref:i,className:"react-flow__viewport xyflow__viewport react-flow__container",style:{transform:Xh(l)},children:n})}function bS(n){const r=uc(),i=K.useRef(!1);K.useEffect(()=>{!i.current&&r.viewportInitialized&&n&&(setTimeout(()=>n(r),1),i.current=!0)},[n,r.viewportInitialized])}const YS=n=>{var r;return(r=n.panZoom)==null?void 0:r.syncViewport};function XS(n){const r=Ie(YS),i=$e();return K.useEffect(()=>{n&&(r==null||r(n),i.setState({transform:[n.x,n.y,n.zoom]}))},[n,r]),null}function QS(n){return n.connection.inProgress?{...n.connection,to:vi(n.connection.to,n.transform)}:{...n.connection}}function GS(n){return QS}function KS(n){const r=GS();return Ie(r,Ve)}const qS=n=>({nodesConnectable:n.nodesConnectable,isValid:n.connection.isValid,inProgress:n.connection.inProgress,width:n.width,height:n.height});function ZS({containerStyle:n,style:r,type:i,component:l}){const{nodesConnectable:u,width:c,height:f,isValid:h,inProgress:p}=Ie(qS,Ve);return!(c&&u&&p)?null:T.jsx("svg",{style:n,width:c,height:f,className:"react-flow__connectionline react-flow__container",children:T.jsx("g",{className:be(["react-flow__connection",Rp(h)]),children:T.jsx($g,{style:r,type:i,CustomComponent:l,isValid:h})})})}const $g=({style:n,type:r=Un.Bezier,CustomComponent:i,isValid:l})=>{const{inProgress:u,from:c,fromNode:f,fromHandle:h,fromPosition:p,to:m,toNode:v,toHandle:y,toPosition:g,pointer:x}=KS();if(!u)return;if(i)return T.jsx(i,{connectionLineType:r,connectionLineStyle:n,fromNode:f,fromHandle:h,fromX:c.x,fromY:c.y,toX:m.x,toY:m.y,fromPosition:p,toPosition:g,connectionStatus:Rp(l),toNode:v,toHandle:y,pointer:x});let S="";const M={sourceX:c.x,sourceY:c.y,sourcePosition:p,targetX:m.x,targetY:m.y,targetPosition:g};switch(r){case Un.Bezier:[S]=Yp(M);break;case Un.SimpleBezier:[S]=Eg(M);break;case Un.Step:[S]=Ha({...M,borderRadius:0});break;case Un.SmoothStep:[S]=Ha(M);break;default:[S]=Qp(M)}return T.jsx("path",{d:S,fill:"none",className:"react-flow__connection-path",style:n})};$g.displayName="ConnectionLine";const JS={};function Qh(n=JS){K.useRef(n),$e(),K.useEffect(()=>{},[n])}function e_(){$e(),K.useRef(!1),K.useEffect(()=>{},[])}function Dg({nodeTypes:n,edgeTypes:r,onInit:i,onNodeClick:l,onEdgeClick:u,onNodeDoubleClick:c,onEdgeDoubleClick:f,onNodeMouseEnter:h,onNodeMouseMove:p,onNodeMouseLeave:m,onNodeContextMenu:v,onSelectionContextMenu:y,onSelectionStart:g,onSelectionEnd:x,connectionLineType:S,connectionLineStyle:M,connectionLineComponent:N,connectionLineContainerStyle:E,selectionKeyCode:L,selectionOnDrag:_,selectionMode:P,multiSelectionKeyCode:U,panActivationKeyCode:D,zoomActivationKeyCode:V,deleteKeyCode:Y,onlyRenderVisibleElements:X,elementsSelectable:ee,defaultViewport:q,translateExtent:J,minZoom:Z,maxZoom:k,preventScrolling:B,defaultMarkerColor:I,zoomOnScroll:H,zoomOnPinch:j,panOnScroll:$,panOnScrollSpeed:F,panOnScrollMode:C,zoomOnDoubleClick:R,panOnDrag:te,autoPanOnSelection:re,onPaneClick:ue,onPaneMouseEnter:ce,onPaneMouseMove:ae,onPaneMouseLeave:G,onPaneScroll:se,onPaneContextMenu:pe,paneClickDistance:xe,nodeClickDistance:ve,onEdgeContextMenu:me,onEdgeMouseEnter:ke,onEdgeMouseMove:Ce,onEdgeMouseLeave:Me,reconnectRadius:Le,onReconnect:it,onReconnectStart:ut,onReconnectEnd:Je,noDragClassName:et,noWheelClassName:rn,noPanClassName:Xt,disableKeyboardA11y:Qt,nodeExtent:at,rfId:Ct,viewport:yt,onViewportChange:Mt,nodesDraggable:wr}){return Qh(n),Qh(r),e_(),bS(i),XS(yt),T.jsx(mS,{onPaneClick:ue,onPaneMouseEnter:ce,onPaneMouseMove:ae,onPaneMouseLeave:G,onPaneContextMenu:pe,onPaneScroll:se,paneClickDistance:xe,deleteKeyCode:Y,selectionKeyCode:L,selectionOnDrag:_,selectionMode:P,onSelectionStart:g,onSelectionEnd:x,multiSelectionKeyCode:U,panActivationKeyCode:D,zoomActivationKeyCode:V,elementsSelectable:ee,zoomOnScroll:H,zoomOnPinch:j,zoomOnDoubleClick:R,panOnScroll:$,panOnScrollSpeed:F,panOnScrollMode:C,panOnDrag:te,autoPanOnSelection:re,defaultViewport:q,translateExtent:J,minZoom:Z,maxZoom:k,onSelectionContextMenu:y,preventScrolling:B,noDragClassName:et,noWheelClassName:rn,noPanClassName:Xt,disableKeyboardA11y:Qt,onViewportChange:Mt,isControlledViewport:!!yt,children:T.jsxs(WS,{children:[T.jsx(US,{edgeTypes:r,onEdgeClick:u,onEdgeDoubleClick:f,onReconnect:it,onReconnectStart:ut,onReconnectEnd:Je,onlyRenderVisibleElements:X,onEdgeContextMenu:me,onEdgeMouseEnter:ke,onEdgeMouseMove:Ce,onEdgeMouseLeave:Me,reconnectRadius:Le,defaultMarkerColor:I,noPanClassName:Xt,disableKeyboardA11y:Qt,rfId:Ct}),T.jsx(ZS,{style:M,type:S,component:N,containerStyle:E}),T.jsx("div",{className:"react-flow__edgelabel-renderer"}),T.jsx(NS,{nodeTypes:n,onNodeClick:l,onNodeDoubleClick:c,onNodeMouseEnter:h,onNodeMouseMove:p,onNodeMouseLeave:m,onNodeContextMenu:v,nodeClickDistance:ve,onlyRenderVisibleElements:X,noPanClassName:Xt,noDragClassName:et,disableKeyboardA11y:Qt,nodeExtent:at,rfId:Ct,nodesDraggable:wr}),T.jsx("div",{className:"react-flow__viewport-portal"})]})})}Dg.displayName="GraphView";const t_=K.memo(Dg),n_=Fp(),Gh=({nodes:n,edges:r,defaultNodes:i,defaultEdges:l,width:u,height:c,fitView:f,fitViewOptions:h,minZoom:p=.5,maxZoom:m=2,nodeOrigin:v,nodeExtent:y,zIndexMode:g="basic"}={})=>{const x=new Map,S=new Map,M=new Map,N=new Map,E=l??r??[],L=i??n??[],_=v??[0,0],P=y??li;qp(M,N,E);const{nodesInitialized:U}=Ba(L,x,S,{nodeOrigin:_,nodeExtent:P,zIndexMode:g});let D=[0,0,1];if(f&&u&&c){const V=mi(x,{filter:q=>!!((q.width||q.initialWidth)&&(q.height||q.initialHeight))}),{x:Y,y:X,zoom:ee}=tc(V,u,c,p,m,(h==null?void 0:h.padding)??.1);D=[Y,X,ee]}return{rfId:"1",width:u??0,height:c??0,transform:D,nodes:L,nodesInitialized:U,nodeLookup:x,parentLookup:S,edges:E,edgeLookup:N,connectionLookup:M,onNodesChange:null,onEdgesChange:null,hasDefaultNodes:i!==void 0,hasDefaultEdges:l!==void 0,panZoom:null,minZoom:p,maxZoom:m,translateExtent:li,nodeExtent:P,nodesSelectionActive:!1,userSelectionActive:!1,userSelectionRect:null,connectionMode:no.Strict,domNode:null,paneDragging:!1,noPanClassName:"nopan",nodeOrigin:_,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:f??!1,fitViewOptions:h,fitViewResolver:null,connection:{...Lp},connectionClickStartHandle:null,connectOnClick:!0,ariaLiveMessage:"",autoPanOnConnect:!0,autoPanOnNodeDrag:!0,autoPanOnNodeFocus:!0,autoPanSpeed:15,connectionRadius:20,onError:n_,isValidConnection:void 0,onSelectionChangeHandlers:[],lib:"react",debug:!1,ariaLabelConfig:Tp,zIndexMode:g,onNodesChangeMiddlewareMap:new Map,onEdgesChangeMiddlewareMap:new Map}},r_=({nodes:n,edges:r,defaultNodes:i,defaultEdges:l,width:u,height:c,fitView:f,fitViewOptions:h,minZoom:p,maxZoom:m,nodeOrigin:v,nodeExtent:y,zIndexMode:g})=>g1((x,S)=>{async function M(){const{nodeLookup:N,panZoom:E,fitViewOptions:L,fitViewResolver:_,width:P,height:U,minZoom:D,maxZoom:V}=S();E&&(await fx({nodes:N,width:P,height:U,panZoom:E,minZoom:D,maxZoom:V},L),_==null||_.resolve(!0),x({fitViewResolver:null}))}return{...Gh({nodes:n,edges:r,width:u,height:c,fitView:f,fitViewOptions:h,minZoom:p,maxZoom:m,nodeOrigin:v,nodeExtent:y,defaultNodes:i,defaultEdges:l,zIndexMode:g}),setNodes:N=>{const{nodeLookup:E,parentLookup:L,nodeOrigin:_,nodeExtent:P,elevateNodesOnSelect:U,fitViewQueued:D,zIndexMode:V,nodesSelectionActive:Y}=S(),{nodesInitialized:X,hasSelectedNodes:ee}=Ba(N,E,L,{nodeOrigin:_,nodeExtent:P,elevateNodesOnSelect:U,checkEquality:!0,zIndexMode:V}),q=Y&ⅇD&&X?(M(),x({nodes:N,nodesInitialized:X,fitViewQueued:!1,fitViewOptions:void 0,nodesSelectionActive:q})):x({nodes:N,nodesInitialized:X,nodesSelectionActive:q})},setEdges:N=>{const{connectionLookup:E,edgeLookup:L}=S();qp(E,L,N),x({edges:N})},setDefaultNodesAndEdges:(N,E)=>{if(N){const{setNodes:L}=S();L(N),x({hasDefaultNodes:!0})}if(E){const{setEdges:L}=S();L(E),x({hasDefaultEdges:!0})}},updateNodeInternals:N=>{const{triggerNodeChanges:E,nodeLookup:L,parentLookup:_,domNode:P,nodeOrigin:U,nodeExtent:D,debug:V,fitViewQueued:Y,zIndexMode:X}=S(),{changes:ee,updatedInternals:q}=Ax(N,L,_,P,U,D,X);q&&(zx(L,_,{nodeOrigin:U,nodeExtent:D,zIndexMode:X}),Y?(M(),x({fitViewQueued:!1,fitViewOptions:void 0})):x({}),(ee==null?void 0:ee.length)>0&&(V&&console.log("React Flow: trigger node changes",ee),E==null||E(ee)))},updateNodePositions:(N,E=!1)=>{const L=[];let _=[];const{nodeLookup:P,triggerNodeChanges:U,connection:D,updateConnection:V,onNodesChangeMiddlewareMap:Y}=S();for(const[X,ee]of N){const q=P.get(X),J=!!(q!=null&&q.expandParent&&(q!=null&&q.parentId)&&(ee!=null&&ee.position)),Z={id:X,type:"position",position:J?{x:Math.max(0,ee.position.x),y:Math.max(0,ee.position.y)}:ee.position,dragging:E};if(q&&D.inProgress&&D.fromNode.id===q.id){const k=vr(q,D.fromHandle,we.Left,!0);V({...D,from:k})}J&&q.parentId&&L.push({id:X,parentId:q.parentId,rect:{...ee.internals.positionAbsolute,width:ee.measured.width??0,height:ee.measured.height??0}}),_.push(Z)}if(L.length>0){const{parentLookup:X,nodeOrigin:ee}=S(),q=lc(L,P,X,ee);_.push(...q)}for(const X of Y.values())_=X(_);U(_)},triggerNodeChanges:N=>{const{onNodesChange:E,setNodes:L,nodes:_,hasDefaultNodes:P,debug:U}=S();if(N!=null&&N.length){if(P){const D=$1(N,_);L(D)}U&&console.log("React Flow: trigger node changes",N),E==null||E(N)}},triggerEdgeChanges:N=>{const{onEdgesChange:E,setEdges:L,edges:_,hasDefaultEdges:P,debug:U}=S();if(N!=null&&N.length){if(P){const D=D1(N,_);L(D)}U&&console.log("React Flow: trigger edge changes",N),E==null||E(N)}},addSelectedNodes:N=>{const{multiSelectionActive:E,edgeLookup:L,nodeLookup:_,triggerNodeChanges:P,triggerEdgeChanges:U}=S();if(E){const D=N.map(V=>cr(V,!0));P(D);return}P(qr(_,new Set([...N]),!0)),U(qr(L))},addSelectedEdges:N=>{const{multiSelectionActive:E,edgeLookup:L,nodeLookup:_,triggerNodeChanges:P,triggerEdgeChanges:U}=S();if(E){const D=N.map(V=>cr(V,!0));U(D);return}U(qr(L,new Set([...N]))),P(qr(_,new Set,!0))},unselectNodesAndEdges:({nodes:N,edges:E}={})=>{const{edges:L,nodes:_,nodeLookup:P,triggerNodeChanges:U,triggerEdgeChanges:D}=S(),V=N||_,Y=E||L,X=[];for(const q of V){if(!q.selected)continue;const J=P.get(q.id);J&&(J.selected=!1),X.push(cr(q.id,!1))}const ee=[];for(const q of Y)q.selected&&ee.push(cr(q.id,!1));U(X),D(ee)},setMinZoom:N=>{const{panZoom:E,maxZoom:L}=S();E==null||E.setScaleExtent([N,L]),x({minZoom:N})},setMaxZoom:N=>{const{panZoom:E,minZoom:L}=S();E==null||E.setScaleExtent([L,N]),x({maxZoom:N})},setTranslateExtent:N=>{var E;(E=S().panZoom)==null||E.setTranslateExtent(N),x({translateExtent:N})},resetSelectedElements:()=>{const{edges:N,nodes:E,triggerNodeChanges:L,triggerEdgeChanges:_,elementsSelectable:P}=S();if(!P)return;const U=E.reduce((V,Y)=>Y.selected?[...V,cr(Y.id,!1)]:V,[]),D=N.reduce((V,Y)=>Y.selected?[...V,cr(Y.id,!1)]:V,[]);L(U),_(D)},setNodeExtent:N=>{const{nodes:E,nodeLookup:L,parentLookup:_,nodeOrigin:P,elevateNodesOnSelect:U,nodeExtent:D,zIndexMode:V}=S();N[0][0]===D[0][0]&&N[0][1]===D[0][1]&&N[1][0]===D[1][0]&&N[1][1]===D[1][1]||(Ba(E,L,_,{nodeOrigin:P,nodeExtent:N,elevateNodesOnSelect:U,checkEquality:!1,zIndexMode:V}),x({nodeExtent:N}))},panBy:N=>{const{transform:E,width:L,height:_,panZoom:P,translateExtent:U}=S();return jx({delta:N,panZoom:P,transform:E,translateExtent:U,width:L,height:_})},setCenter:async(N,E,L)=>{const{width:_,height:P,maxZoom:U,panZoom:D}=S();if(!D)return!1;const V=typeof(L==null?void 0:L.zoom)<"u"?L.zoom:U;return await D.setViewport({x:_/2-N*V,y:P/2-E*V,zoom:V},{duration:L==null?void 0:L.duration,ease:L==null?void 0:L.ease,interpolate:L==null?void 0:L.interpolate}),!0},cancelConnection:()=>{x({connection:{...Lp}})},updateConnection:N=>{x({connection:N})},reset:()=>x({...Gh()})}},Object.is);function o_({initialNodes:n,initialEdges:r,defaultNodes:i,defaultEdges:l,initialWidth:u,initialHeight:c,initialMinZoom:f,initialMaxZoom:h,initialFitViewOptions:p,fitView:m,nodeOrigin:v,nodeExtent:y,zIndexMode:g,children:x}){const[S]=K.useState(()=>r_({nodes:n,edges:r,defaultNodes:i,defaultEdges:l,width:u,height:c,fitView:m,minZoom:f,maxZoom:h,fitViewOptions:p,nodeOrigin:v,nodeExtent:y,zIndexMode:g}));return T.jsx(m1,{value:S,children:T.jsx(B1,{children:T.jsx(rS,{children:x})})})}function i_({children:n,nodes:r,edges:i,defaultNodes:l,defaultEdges:u,width:c,height:f,fitView:h,fitViewOptions:p,minZoom:m,maxZoom:v,nodeOrigin:y,nodeExtent:g,zIndexMode:x}){return K.useContext(yl)?T.jsx(T.Fragment,{children:n}):T.jsx(o_,{initialNodes:r,initialEdges:i,defaultNodes:l,defaultEdges:u,initialWidth:c,initialHeight:f,fitView:h,initialFitViewOptions:p,initialMinZoom:m,initialMaxZoom:v,nodeOrigin:y,nodeExtent:g,zIndexMode:x,children:n})}const s_={width:"100%",height:"100%",overflow:"hidden",position:"relative",zIndex:0};function l_({nodes:n,edges:r,defaultNodes:i,defaultEdges:l,className:u,nodeTypes:c,edgeTypes:f,onNodeClick:h,onEdgeClick:p,onInit:m,onMove:v,onMoveStart:y,onMoveEnd:g,onConnect:x,onConnectStart:S,onConnectEnd:M,onClickConnectStart:N,onClickConnectEnd:E,onNodeMouseEnter:L,onNodeMouseMove:_,onNodeMouseLeave:P,onNodeContextMenu:U,onNodeDoubleClick:D,onNodeDragStart:V,onNodeDrag:Y,onNodeDragStop:X,onNodesDelete:ee,onEdgesDelete:q,onDelete:J,onSelectionChange:Z,onSelectionDragStart:k,onSelectionDrag:B,onSelectionDragStop:I,onSelectionContextMenu:H,onSelectionStart:j,onSelectionEnd:$,onBeforeDelete:F,connectionMode:C,connectionLineType:R=Un.Bezier,connectionLineStyle:te,connectionLineComponent:re,connectionLineContainerStyle:ue,deleteKeyCode:ce="Backspace",selectionKeyCode:ae="Shift",selectionOnDrag:G=!1,selectionMode:se=ui.Full,panActivationKeyCode:pe="Space",multiSelectionKeyCode:xe=ci()?"Meta":"Control",zoomActivationKeyCode:ve=ci()?"Meta":"Control",snapToGrid:me,snapGrid:ke,onlyRenderVisibleElements:Ce=!1,selectNodesOnDrag:Me,nodesDraggable:Le,autoPanOnNodeFocus:it,nodesConnectable:ut,nodesFocusable:Je,nodeOrigin:et=cg,edgesFocusable:rn,edgesReconnectable:Xt,elementsSelectable:Qt=!0,defaultViewport:at=I1,minZoom:Ct=.5,maxZoom:yt=2,translateExtent:Mt=li,preventScrolling:wr=!0,nodeExtent:on,defaultMarkerColor:bn="#b1b1b7",zoomOnScroll:Sl=!0,zoomOnPinch:wi=!0,panOnScroll:xi=!1,panOnScrollSpeed:_l=.5,panOnScrollMode:so=hr.Free,zoomOnDoubleClick:lo=!0,panOnDrag:uo=!0,onPaneClick:ao,onPaneMouseEnter:co,onPaneMouseMove:vn,onPaneMouseLeave:wn,onPaneScroll:Si,onPaneContextMenu:_i,paneClickDistance:Ei=1,nodeClickDistance:ki=0,children:Ni,onReconnect:fo,onReconnectStart:Ci,onReconnectEnd:Yn,onEdgeContextMenu:ho,onEdgeDoubleClick:Xn,onEdgeMouseEnter:El,onEdgeMouseMove:Qn,onEdgeMouseLeave:xr,reconnectRadius:Sr=10,onNodesChange:po,onEdgesChange:kl,noDragClassName:Nl="nodrag",noWheelClassName:Cl="nowheel",noPanClassName:Gt="nopan",fitView:go,fitViewOptions:mo,connectOnClick:Ml,attributionPosition:Mi,proOptions:Pi,defaultEdgeOptions:Ii,elevateNodesOnSelect:zi=!0,elevateEdgesOnSelect:Pl=!1,disableKeyboardA11y:Ti=!1,autoPanOnConnect:Oe,autoPanOnNodeDrag:Il,autoPanOnSelection:yo=!0,autoPanSpeed:Li,connectionRadius:_r,isValidConnection:zl,onError:Ri,style:Er,id:vt,nodeDragThreshold:Tl,connectionDragThreshold:wt,viewport:Ll,onViewportChange:Rl,width:Al,height:kr,colorMode:Nr="light",debug:Gn,onScroll:sn,ariaLabelConfig:jl,zIndexMode:Ai="basic",...vo},ji){const Kn=vt||"1",qn=R1(Nr),$l=K.useCallback(Cr=>{Cr.currentTarget.scrollTo({top:0,left:0,behavior:"instant"}),sn==null||sn(Cr)},[sn]);return T.jsx("div",{"data-testid":"rf__wrapper",...vo,onScroll:$l,style:{...Er,...s_},ref:ji,className:be(["react-flow",u,qn]),id:vt,role:"application",children:T.jsxs(i_,{nodes:n,edges:r,width:Al,height:kr,fitView:go,fitViewOptions:mo,minZoom:Ct,maxZoom:yt,nodeOrigin:et,nodeExtent:on,zIndexMode:Ai,children:[T.jsx(L1,{nodes:n,edges:r,defaultNodes:i,defaultEdges:l,onConnect:x,onConnectStart:S,onConnectEnd:M,onClickConnectStart:N,onClickConnectEnd:E,nodesDraggable:Le,autoPanOnNodeFocus:it,nodesConnectable:ut,nodesFocusable:Je,edgesFocusable:rn,edgesReconnectable:Xt,elementsSelectable:Qt,elevateNodesOnSelect:zi,elevateEdgesOnSelect:Pl,minZoom:Ct,maxZoom:yt,nodeExtent:on,onNodesChange:po,onEdgesChange:kl,snapToGrid:me,snapGrid:ke,connectionMode:C,translateExtent:Mt,connectOnClick:Ml,defaultEdgeOptions:Ii,fitView:go,fitViewOptions:mo,onNodesDelete:ee,onEdgesDelete:q,onDelete:J,onNodeDragStart:V,onNodeDrag:Y,onNodeDragStop:X,onSelectionDrag:B,onSelectionDragStart:k,onSelectionDragStop:I,onMove:v,onMoveStart:y,onMoveEnd:g,noPanClassName:Gt,nodeOrigin:et,rfId:Kn,autoPanOnConnect:Oe,autoPanOnNodeDrag:Il,autoPanSpeed:Li,onError:Ri,connectionRadius:_r,isValidConnection:zl,selectNodesOnDrag:Me,nodeDragThreshold:Tl,connectionDragThreshold:wt,onBeforeDelete:F,debug:Gn,ariaLabelConfig:jl,zIndexMode:Ai}),T.jsx(t_,{onInit:m,onNodeClick:h,onEdgeClick:p,onNodeMouseEnter:L,onNodeMouseMove:_,onNodeMouseLeave:P,onNodeContextMenu:U,onNodeDoubleClick:D,nodeTypes:c,edgeTypes:f,connectionLineType:R,connectionLineStyle:te,connectionLineComponent:re,connectionLineContainerStyle:ue,selectionKeyCode:ae,selectionOnDrag:G,selectionMode:se,deleteKeyCode:ce,multiSelectionKeyCode:xe,panActivationKeyCode:pe,zoomActivationKeyCode:ve,onlyRenderVisibleElements:Ce,defaultViewport:at,translateExtent:Mt,minZoom:Ct,maxZoom:yt,preventScrolling:wr,zoomOnScroll:Sl,zoomOnPinch:wi,zoomOnDoubleClick:lo,panOnScroll:xi,panOnScrollSpeed:_l,panOnScrollMode:so,panOnDrag:uo,autoPanOnSelection:yo,onPaneClick:ao,onPaneMouseEnter:co,onPaneMouseMove:vn,onPaneMouseLeave:wn,onPaneScroll:Si,onPaneContextMenu:_i,paneClickDistance:Ei,nodeClickDistance:ki,onSelectionContextMenu:H,onSelectionStart:j,onSelectionEnd:$,onReconnect:fo,onReconnectStart:Ci,onReconnectEnd:Yn,onEdgeContextMenu:ho,onEdgeDoubleClick:Xn,onEdgeMouseEnter:El,onEdgeMouseMove:Qn,onEdgeMouseLeave:xr,reconnectRadius:Sr,defaultMarkerColor:bn,noDragClassName:Nl,noWheelClassName:Cl,noPanClassName:Gt,rfId:Kn,disableKeyboardA11y:Ti,nodeExtent:on,viewport:Ll,onViewportChange:Rl,nodesDraggable:Le}),T.jsx(P1,{onSelectionChange:Z}),Ni,T.jsx(E1,{proOptions:Pi,position:Mi}),T.jsx(_1,{rfId:Kn,disableKeyboardA11y:Ti})]})})}var u_=dg(l_);function a_({dimensions:n,lineWidth:r,variant:i,className:l}){return T.jsx("path",{strokeWidth:r,d:`M${n[0]/2} 0 V${n[1]} M0 ${n[1]/2} H${n[0]}`,className:be(["react-flow__background-pattern",i,l])})}function c_({radius:n,className:r}){return T.jsx("circle",{cx:n,cy:n,r:n,className:be(["react-flow__background-pattern","dots",r])})}var Wn;(function(n){n.Lines="lines",n.Dots="dots",n.Cross="cross"})(Wn||(Wn={}));const f_={[Wn.Dots]:1,[Wn.Lines]:1,[Wn.Cross]:6},d_=n=>({transform:n.transform,patternId:`pattern-${n.rfId}`});function Og({id:n,variant:r=Wn.Dots,gap:i=20,size:l,lineWidth:u=1,offset:c=0,color:f,bgColor:h,style:p,className:m,patternClassName:v}){const y=K.useRef(null),{transform:g,patternId:x}=Ie(d_,Ve),S=l||f_[r],M=r===Wn.Dots,N=r===Wn.Cross,E=Array.isArray(i)?i:[i,i],L=[E[0]*g[2]||1,E[1]*g[2]||1],_=S*g[2],P=Array.isArray(c)?c:[c,c],U=N?[_,_]:L,D=[P[0]*g[2]+U[0]/2,P[1]*g[2]+U[1]/2],V=`${x}${n||""}`;return T.jsxs("svg",{className:be(["react-flow__background",m]),style:{...p,...wl,"--xy-background-color-props":h,"--xy-background-pattern-color-props":f},ref:y,"data-testid":"rf__background",children:[T.jsx("pattern",{id:V,x:g[0]%L[0],y:g[1]%L[1],width:L[0],height:L[1],patternUnits:"userSpaceOnUse",patternTransform:`translate(-${D[0]},-${D[1]})`,children:M?T.jsx(c_,{radius:_/2,className:v}):T.jsx(a_,{dimensions:U,lineWidth:u,variant:r,className:v})}),T.jsx("rect",{x:"0",y:"0",width:"100%",height:"100%",fill:`url(#${V})`})]})}Og.displayName="Background";const h_=K.memo(Og);function p_(){return T.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 32",children:T.jsx("path",{d:"M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z"})})}function g_(){return T.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 5",children:T.jsx("path",{d:"M0 0h32v4.2H0z"})})}function m_(){return T.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 32 30",children:T.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 y_(){return T.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:T.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 v_(){return T.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 25 32",children:T.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 bs({children:n,className:r,...i}){return T.jsx("button",{type:"button",className:be(["react-flow__controls-button",r]),...i,children:n})}const w_=n=>({isInteractive:n.nodesDraggable||n.nodesConnectable||n.elementsSelectable,minZoomReached:n.transform[2]<=n.minZoom,maxZoomReached:n.transform[2]>=n.maxZoom,ariaLabelConfig:n.ariaLabelConfig});function Fg({style:n,showZoom:r=!0,showFitView:i=!0,showInteractive:l=!0,fitViewOptions:u,onZoomIn:c,onZoomOut:f,onFitView:h,onInteractiveChange:p,className:m,children:v,position:y="bottom-left",orientation:g="vertical","aria-label":x}){const S=$e(),{isInteractive:M,minZoomReached:N,maxZoomReached:E,ariaLabelConfig:L}=Ie(w_,Ve),{zoomIn:_,zoomOut:P,fitView:U}=uc(),D=()=>{_(),c==null||c()},V=()=>{P(),f==null||f()},Y=()=>{U(u),h==null||h()},X=()=>{S.setState({nodesDraggable:!M,nodesConnectable:!M,elementsSelectable:!M}),p==null||p(!M)},ee=g==="horizontal"?"horizontal":"vertical";return T.jsxs(vl,{className:be(["react-flow__controls",ee,m]),position:y,style:n,"data-testid":"rf__controls","aria-label":x??L["controls.ariaLabel"],children:[r&&T.jsxs(T.Fragment,{children:[T.jsx(bs,{onClick:D,className:"react-flow__controls-zoomin",title:L["controls.zoomIn.ariaLabel"],"aria-label":L["controls.zoomIn.ariaLabel"],disabled:E,children:T.jsx(p_,{})}),T.jsx(bs,{onClick:V,className:"react-flow__controls-zoomout",title:L["controls.zoomOut.ariaLabel"],"aria-label":L["controls.zoomOut.ariaLabel"],disabled:N,children:T.jsx(g_,{})})]}),i&&T.jsx(bs,{className:"react-flow__controls-fitview",onClick:Y,title:L["controls.fitView.ariaLabel"],"aria-label":L["controls.fitView.ariaLabel"],children:T.jsx(m_,{})}),l&&T.jsx(bs,{className:"react-flow__controls-interactive",onClick:X,title:L["controls.interactive.ariaLabel"],"aria-label":L["controls.interactive.ariaLabel"],children:M?T.jsx(v_,{}):T.jsx(y_,{})}),v]})}Fg.displayName="Controls";const x_=K.memo(Fg);function S_({id:n,x:r,y:i,width:l,height:u,style:c,color:f,strokeColor:h,strokeWidth:p,className:m,borderRadius:v,shapeRendering:y,selected:g,onClick:x}){const{background:S,backgroundColor:M}=c||{},N=f||S||M;return T.jsx("rect",{className:be(["react-flow__minimap-node",{selected:g},m]),x:r,y:i,rx:v,ry:v,width:l,height:u,style:{fill:N,stroke:h,strokeWidth:p},shapeRendering:y,onClick:x?E=>x(E,n):void 0})}const __=K.memo(S_),E_=n=>n.nodes.map(r=>r.id),za=n=>n instanceof Function?n:()=>n;function k_({nodeStrokeColor:n,nodeColor:r,nodeClassName:i="",nodeBorderRadius:l=5,nodeStrokeWidth:u,nodeComponent:c=__,onClick:f}){const h=Ie(E_,Ve),p=za(r),m=za(n),v=za(i),y=typeof window>"u"||window.chrome?"crispEdges":"geometricPrecision";return T.jsx(T.Fragment,{children:h.map(g=>T.jsx(C_,{id:g,nodeColorFunc:p,nodeStrokeColorFunc:m,nodeClassNameFunc:v,nodeBorderRadius:l,nodeStrokeWidth:u,NodeComponent:c,onClick:f,shapeRendering:y},g))})}function N_({id:n,nodeColorFunc:r,nodeStrokeColorFunc:i,nodeClassNameFunc:l,nodeBorderRadius:u,nodeStrokeWidth:c,shapeRendering:f,NodeComponent:h,onClick:p}){const{node:m,x:v,y,width:g,height:x}=Ie(S=>{const M=S.nodeLookup.get(n);if(!M)return{node:void 0,x:0,y:0,width:0,height:0};const N=M.internals.userNode,{x:E,y:L}=M.internals.positionAbsolute,{width:_,height:P}=Yt(N);return{node:N,x:E,y:L,width:_,height:P}},Ve);return!m||m.hidden||!Hp(m)?null:T.jsx(h,{x:v,y,width:g,height:x,style:m.style,selected:!!m.selected,className:l(m),color:r(m),borderRadius:u,strokeColor:i(m),strokeWidth:c,shapeRendering:f,onClick:p,id:m.id})}const C_=K.memo(N_);var M_=K.memo(k_);const P_=200,I_=150,z_=n=>!n.hidden,T_=n=>{const r={x:-n.transform[0]/n.transform[2],y:-n.transform[1]/n.transform[2],width:n.width/n.transform[2],height:n.height/n.transform[2]};return{viewBB:r,boundingRect:n.nodeLookup.size>0?Dp(mi(n.nodeLookup,{filter:z_}),r):r,rfId:n.rfId,panZoom:n.panZoom,translateExtent:n.translateExtent,flowWidth:n.width,flowHeight:n.height,ariaLabelConfig:n.ariaLabelConfig}},Kh=(n,r)=>n.x===r.x&&n.y===r.y&&n.width===r.width&&n.height===r.height,L_=(n,r)=>Kh(n.viewBB,r.viewBB)&&Kh(n.boundingRect,r.boundingRect)&&n.rfId===r.rfId&&n.panZoom===r.panZoom&&n.translateExtent===r.translateExtent&&n.flowWidth===r.flowWidth&&n.flowHeight===r.flowHeight&&n.ariaLabelConfig===r.ariaLabelConfig,R_="react-flow__minimap-desc";function Hg({style:n,className:r,nodeStrokeColor:i,nodeColor:l,nodeClassName:u="",nodeBorderRadius:c=5,nodeStrokeWidth:f,nodeComponent:h,bgColor:p,maskColor:m,maskStrokeColor:v,maskStrokeWidth:y,position:g="bottom-right",onClick:x,onNodeClick:S,pannable:M=!1,zoomable:N=!1,ariaLabel:E,inversePan:L,zoomStep:_=1,offsetScale:P=5}){const U=$e(),D=K.useRef(null),{boundingRect:V,viewBB:Y,rfId:X,panZoom:ee,translateExtent:q,flowWidth:J,flowHeight:Z,ariaLabelConfig:k}=Ie(T_,L_),B=(n==null?void 0:n.width)??P_,I=(n==null?void 0:n.height)??I_,H=V.width/B,j=V.height/I,$=Math.max(H,j),F=$*B,C=$*I,R=P*$,te=V.x-(F-V.width)/2-R,re=V.y-(C-V.height)/2-R,ue=F+R*2,ce=C+R*2,ae=`${R_}-${X}`,G=K.useRef(0),se=K.useRef();G.current=$,K.useEffect(()=>{if(D.current&&ee)return se.current=Wx({domNode:D.current,panZoom:ee,getTransform:()=>U.getState().transform,getViewScale:()=>G.current}),()=>{var me;(me=se.current)==null||me.destroy()}},[ee]),K.useEffect(()=>{var me;(me=se.current)==null||me.update({translateExtent:q,width:J,height:Z,inversePan:L,pannable:M,zoomStep:_,zoomable:N})},[M,N,L,_,q,J,Z]);const pe=x?me=>{var Me;const[ke,Ce]=((Me=se.current)==null?void 0:Me.pointer(me))||[0,0];x(me,{x:ke,y:Ce})}:void 0,xe=S?K.useCallback((me,ke)=>{const Ce=U.getState().nodeLookup.get(ke).internals.userNode;S(me,Ce)},[]):void 0,ve=E??k["minimap.ariaLabel"];return T.jsx(vl,{position:g,style:{...n,"--xy-minimap-background-color-props":typeof p=="string"?p:void 0,"--xy-minimap-mask-background-color-props":typeof m=="string"?m:void 0,"--xy-minimap-mask-stroke-color-props":typeof v=="string"?v:void 0,"--xy-minimap-mask-stroke-width-props":typeof y=="number"?y*$:void 0,"--xy-minimap-node-background-color-props":typeof l=="string"?l:void 0,"--xy-minimap-node-stroke-color-props":typeof i=="string"?i:void 0,"--xy-minimap-node-stroke-width-props":typeof f=="number"?f:void 0},className:be(["react-flow__minimap",r]),"data-testid":"rf__minimap",children:T.jsxs("svg",{width:B,height:I,viewBox:`${te} ${re} ${ue} ${ce}`,className:"react-flow__minimap-svg",role:"img","aria-labelledby":ae,ref:D,onClick:pe,children:[ve&&T.jsx("title",{id:ae,children:ve}),T.jsx(M_,{onClick:xe,nodeColor:l,nodeStrokeColor:i,nodeBorderRadius:c,nodeClassName:u,nodeStrokeWidth:f,nodeComponent:h}),T.jsx("path",{className:"react-flow__minimap-mask",d:`M${te-R},${re-R}h${ue+R*2}v${ce+R*2}h${-ue-R*2}z + M${Y.x},${Y.y}h${Y.width}v${Y.height}h${-Y.width}z`,fillRule:"evenodd",pointerEvents:"none"})]})})}Hg.displayName="MiniMap";const A_=K.memo(Hg),j_=n=>r=>n?`${Math.max(1/r.transform[2],1)}`:void 0,$_={[io.Line]:"right",[io.Handle]:"bottom-right"};function D_({nodeId:n,position:r,variant:i=io.Handle,className:l,style:u=void 0,children:c,color:f,minWidth:h=10,minHeight:p=10,maxWidth:m=Number.MAX_VALUE,maxHeight:v=Number.MAX_VALUE,keepAspectRatio:y=!1,resizeDirection:g,autoScale:x=!0,shouldResize:S,onResizeStart:M,onResize:N,onResizeEnd:E}){const L=yg(),_=typeof n=="string"?n:L,P=$e(),U=K.useRef(null),D=i===io.Handle,V=Ie(K.useCallback(j_(D&&x),[D,x]),Ve),Y=K.useRef(null),X=r??$_[i];K.useEffect(()=>{if(!(!U.current||!_))return Y.current||(Y.current=r1({domNode:U.current,nodeId:_,getStoreItems:()=>{const{nodeLookup:q,transform:J,snapGrid:Z,snapToGrid:k,nodeOrigin:B,domNode:I}=P.getState();return{nodeLookup:q,transform:J,snapGrid:Z,snapToGrid:k,nodeOrigin:B,paneDomNode:I}},onChange:(q,J)=>{const{triggerNodeChanges:Z,nodeLookup:k,parentLookup:B,nodeOrigin:I}=P.getState(),H=[],j={x:q.x,y:q.y},$=k.get(_);if($&&$.expandParent&&$.parentId){const F=$.origin??I,C=q.width??$.measured.width??0,R=q.height??$.measured.height??0,te={id:$.id,parentId:$.parentId,rect:{width:C,height:R,...Vp({x:q.x??$.position.x,y:q.y??$.position.y},{width:C,height:R},$.parentId,k,F)}},re=lc([te],k,B,I);H.push(...re),j.x=q.x?Math.max(F[0]*C,q.x):void 0,j.y=q.y?Math.max(F[1]*R,q.y):void 0}if(j.x!==void 0&&j.y!==void 0){const F={id:_,type:"position",position:{...j}};H.push(F)}if(q.width!==void 0&&q.height!==void 0){const C={id:_,type:"dimensions",resizing:!0,setAttributes:g?g==="horizontal"?"width":"height":!0,dimensions:{width:q.width,height:q.height}};H.push(C)}for(const F of J){const C={...F,type:"position"};H.push(C)}Z(H)},onEnd:({width:q,height:J})=>{const Z={id:_,type:"dimensions",resizing:!1,dimensions:{width:q,height:J}};P.getState().triggerNodeChanges([Z])}})),Y.current.update({controlPosition:X,boundaries:{minWidth:h,minHeight:p,maxWidth:m,maxHeight:v},keepAspectRatio:y,resizeDirection:g,onResizeStart:M,onResize:N,onResizeEnd:E,shouldResize:S}),()=>{var q;(q=Y.current)==null||q.destroy()}},[X,h,p,m,v,y,M,N,E,S]);const ee=X.split("-");return T.jsx("div",{className:be(["react-flow__resize-control","nodrag",...ee,i,l]),ref:U,style:{...u,scale:V,...f&&{[D?"backgroundColor":"borderColor"]:f}},children:c})}K.memo(D_);const O_={"arch.context":0,"django.app":0,"django.route":1,"django.url_name":1,"django.view":2,"django.viewset_action":2,"django.permission":2,"django.serializer":3,"django.serializer_field":4,"django.service":4,"django.model":5,"django.field":6,"django.relation":6,"django.task":7,"django.receiver":7,"django.signal":7,"django.test":7,"django.migration_op":7,"django.admin":7,"openapi.path":8,"react.api_client":9,"react.query_key":10,"react.hook":10,"react.feature":10,"react.route":11,"react.page":11,"react.component":12,"react.form_schema":13,"react.test":13,"react.context":12};function F_(n){return O_[n]??8}function H_(n){const r=new Map;for(const l of n){const u=F_(l.type),c=r.get(u)??[];c.push(l),r.set(u,c)}const i=new Map;for(const[l,u]of r)u.sort((c,f)=>c.name.localeCompare(f.name)),u.forEach((c,f)=>{i.set(c.id,{x:l*240,y:f*92})});return i}const V_={cheap:"#4a5568",expensive:"#f4a261",critical:"#e85d04"};function B_({data:n}){return T.jsxs("div",{className:"lp-node",children:[T.jsx("div",{className:"t",children:n.type.split(".").pop()}),T.jsx("div",{className:"n",children:n.name})]})}const U_={load:B_};function qh({nodes:n,edges:r}){const i=H_(n),l=n.map(c=>({id:c.id,type:"load",position:i.get(c.id)??{x:0,y:0},data:{name:c.name,type:c.type,file:c.file_path}})),u=r.filter(c=>n.some(f=>f.id===c.src)&&n.some(f=>f.id===c.dst)).map(c=>({id:c.id,source:c.src,target:c.dst,animated:c.weight==="critical",style:{stroke:V_[c.weight]||"#4a5568",strokeWidth:c.weight==="critical"?2.4:1.2,strokeDasharray:c.confidence<.8?"6 4":void 0},label:c.type.replaceAll("_"," "),labelStyle:{fill:"#8b9bb0",fontSize:9}}));return T.jsxs(u_,{nodes:l,edges:u,nodeTypes:U_,fitView:!0,minZoom:.2,"data-testid":"impact-graph",children:[T.jsx(h_,{}),T.jsx(A_,{pannable:!0,zoomable:!0}),T.jsx(x_,{})]})}function W_(){var B;const[n,r]=K.useState("review"),[i,l]=K.useState(localStorage.getItem("loadpath.repo")||""),[u,c]=K.useState("HEAD~1"),[f,h]=K.useState("HEAD"),[p,m]=K.useState(null),[v,y]=K.useState(""),[g,x]=K.useState(""),[S,M]=K.useState({}),[N,E]=K.useState([]),[L,_]=K.useState(""),[P,U]=K.useState("github"),[D,V]=K.useState("");K.useEffect(()=>{Gr.settings().then(M).catch(()=>{})},[]);const Y=async()=>{y(""),x("Tracing load path…"),localStorage.setItem("loadpath.repo",i);try{const I=await Gr.review(i,u,f);m(I),r("review")}catch(I){y(I instanceof Error?I.message:String(I))}finally{x("")}},X=async()=>{y(""),x("Indexing…");try{await Gr.index(i)}catch(I){y(I instanceof Error?I.message:String(I))}finally{x("")}},ee=async()=>{y(""),x("Fetching pull requests…");try{const I=await Gr.prs(P,L);E(I.pull_requests)}catch(I){y(I instanceof Error?I.message:String(I))}finally{x("")}},q=async I=>{I.preventDefault();const H=new FormData(I.currentTarget),j={github_token:String(H.get("github_token")||""),bitbucket_token:String(H.get("bitbucket_token")||""),bitbucket_username:String(H.get("bitbucket_username")||""),ai_provider:String(H.get("ai_provider")||"none"),ai_api_key:String(H.get("ai_api_key")||""),ai_model:String(H.get("ai_model")||""),ai_base_url:String(H.get("ai_base_url")||""),workspaces:i?[{path:i,name:i.split(/[\\/]/).pop()}]:[]};M(await Gr.saveSettings(j))},J=async()=>{if(p){x("Residual analysis…");try{const I=await Gr.residual(p);V(I.note)}catch(I){y(I instanceof Error?I.message:String(I))}finally{x("")}}},Z=K.useMemo(()=>(p==null?void 0:p.nodes)??[],[p]),k=K.useMemo(()=>(p==null?void 0:p.edges)??[],[p]);return T.jsxs("div",{className:"app",children:[T.jsxs("nav",{className:"rail","data-testid":"rail",children:[T.jsx("div",{className:"brand",children:"Loadpath"}),T.jsx("button",{"data-testid":"tab-review",className:n==="review"?"active":"",onClick:()=>r("review"),children:"Review"}),T.jsx("button",{"data-testid":"tab-graph",className:n==="graph"?"active":"",onClick:()=>r("graph"),children:"Impact graph"}),T.jsx("button",{"data-testid":"tab-prs",className:n==="prs"?"active":"",onClick:()=>r("prs"),children:"Pull requests"}),T.jsx("button",{"data-testid":"tab-settings",className:n==="settings"?"active":"",onClick:()=>r("settings"),children:"Settings"}),T.jsx("div",{style:{flex:1}}),T.jsx("div",{className:"muted",children:g||"Django + React load paths"})]}),T.jsxs("div",{className:"main",children:[T.jsxs("div",{className:"topbar","data-testid":"topbar",children:[T.jsx("input",{"data-testid":"repo-path",className:"path",placeholder:"Local monorepo path",value:i,onChange:I=>l(I.target.value)}),T.jsx("input",{"data-testid":"base-ref",value:u,onChange:I=>c(I.target.value),placeholder:"base"}),T.jsx("input",{"data-testid":"head-ref",value:f,onChange:I=>h(I.target.value),placeholder:"head"}),T.jsx("button",{"data-testid":"btn-index",onClick:X,children:"Index"}),T.jsx("button",{"data-testid":"btn-review",className:"btn primary",onClick:Y,children:"Review"})]}),v?T.jsx("div",{className:"error",children:v}):null,n==="review"&&T.jsxs("div",{className:"content","data-testid":"review-layout",children:[T.jsx("aside",{className:"brief","data-testid":"brief",children:p?T.jsxs(T.Fragment,{children:[T.jsxs("div",{className:`level ${p.confidence.level}`,children:[p.confidence.level.toUpperCase()," — ",p.title]}),p.low_risk?T.jsx("span",{className:"chip",children:"loadpath:low-risk"}):null,p.change_kinds.map(I=>T.jsx("span",{className:"chip",children:I.replaceAll("_"," ")},I)),T.jsx("pre",{className:"headline",children:p.headline}),T.jsx("div",{className:"kicker",children:"Read this"}),p.read_order.map(I=>T.jsxs("div",{children:[T.jsx("span",{className:"file",children:I.path}),T.jsx("div",{className:"muted",children:I.why})]},I.path)),T.jsx("div",{className:"kicker",children:"Clusters"}),p.clusters.map(I=>T.jsxs("div",{className:"muted",children:[T.jsx("strong",{children:I.title})," — ",I.files.join(", ")]},I.id)),T.jsx("div",{className:"kicker",children:"Architecture"}),p.findings.filter(I=>!I.waived).length===0?T.jsx("div",{className:"muted",children:p.architecture_note}):p.findings.filter(I=>!I.waived).map(I=>T.jsxs("div",{className:"muted",children:[T.jsx("span",{className:`chip ${I.severity}`,children:I.severity}),I.message]},I.rule+I.message)),T.jsx("div",{className:"kicker",children:"Residual (AI only here)"}),p.residuals.map(I=>T.jsx("div",{className:"muted",children:I},I)),T.jsx("button",{className:"btn",onClick:J,style:{marginTop:12},children:"Ask configured model"}),D?T.jsx("pre",{className:"headline",children:D}):null,T.jsx("div",{className:"kicker",children:"Reviewers"}),T.jsx("div",{className:"muted",children:p.suggested_reviewers.join(", ")||"—"})]}):T.jsxs("p",{className:"muted",children:["Point at a Django + React monorepo with ",T.jsx("code",{children:"loadpath.yml"}),", then review a git range. The graph — not hunk comments — is the artifact."]})}),T.jsx("div",{className:"graph-wrap","data-testid":"review-graph",children:p?T.jsx(qh,{nodes:Z,edges:k}):null})]}),n==="graph"&&T.jsx("div",{className:"graph-wrap","data-testid":"graph-full",style:{height:"100%"},children:p?T.jsx(qh,{nodes:Z,edges:k}):T.jsx("p",{className:"muted",children:"Run a review first."})}),n==="prs"&&T.jsxs("div",{className:"pr-list","data-testid":"pr-list",children:[T.jsxs("div",{className:"topbar",style:{border:0,padding:0,marginBottom:12},children:[T.jsxs("select",{"data-testid":"pr-provider",value:P,onChange:I=>U(I.target.value),children:[T.jsx("option",{value:"github",children:"GitHub"}),T.jsx("option",{value:"bitbucket",children:"Bitbucket"})]}),T.jsx("input",{"data-testid":"pr-repo",className:"path",placeholder:"owner/repo",value:L,onChange:I=>_(I.target.value)}),T.jsx("button",{"data-testid":"btn-list-prs",onClick:ee,children:"List PRs"})]}),N.map(I=>T.jsxs("article",{className:"pr","data-testid":`pr-${I.number}`,children:[T.jsxs("h3",{children:["#",I.number," ",I.title]}),T.jsxs("div",{className:"muted",children:[I.author," · ",I.source_branch," → ",I.target_branch," · ",I.provider]}),T.jsxs("a",{href:I.url,target:"_blank",rel:"noreferrer",children:["Open on ",I.provider]}),T.jsx("div",{children:T.jsx("button",{className:"btn",onClick:()=>{c(I.target_branch),h(I.source_branch),r("review")},children:"Review this branch range"})})]},`${I.provider}-${I.number}`))]}),n==="settings"&&T.jsxs("form",{className:"settings","data-testid":"settings-form",onSubmit:q,children:[T.jsx("h1",{children:"Keys & providers"}),T.jsx("p",{className:"muted",children:"Tokens stay on this machine in ~/.loadpath/settings.json. GitHub and Bitbucket power the PR list. AI is used only for residual uncertainty the graph could not close."}),T.jsx("label",{children:"GitHub token"}),T.jsx("input",{name:"github_token",type:"password",placeholder:"ghp_…"}),T.jsx("label",{children:"Bitbucket token"}),T.jsx("input",{name:"bitbucket_token",type:"password"}),T.jsx("label",{children:"Bitbucket username (app passwords)"}),T.jsx("input",{name:"bitbucket_username",defaultValue:String(S.bitbucket_username||"")}),T.jsx("label",{children:"AI provider"}),T.jsxs("select",{name:"ai_provider",defaultValue:String(((B=S.ai)==null?void 0:B.provider)||"none"),children:[T.jsx("option",{value:"none",children:"none (graph only)"}),T.jsx("option",{value:"anthropic",children:"Anthropic"}),T.jsx("option",{value:"openai",children:"OpenAI"}),T.jsx("option",{value:"grok",children:"Grok / xAI"}),T.jsx("option",{value:"deepseek",children:"DeepSeek"}),T.jsx("option",{value:"cursor",children:"Cursor-compatible (OpenAI protocol)"}),T.jsx("option",{value:"ollama",children:"Ollama local"})]}),T.jsx("label",{children:"AI API key"}),T.jsx("input",{name:"ai_api_key",type:"password"}),T.jsx("label",{children:"Model"}),T.jsx("input",{name:"ai_model",placeholder:"optional override"}),T.jsx("label",{children:"Base URL"}),T.jsx("input",{name:"ai_base_url",placeholder:"optional, OpenAI-compatible"}),T.jsx("button",{className:"btn primary",type:"submit",children:"Save"})]})]})]})}M0.createRoot(document.getElementById("root")).render(T.jsx(K.StrictMode,{children:T.jsx(W_,{})})); diff --git a/src/loadpath/static/index.html b/src/loadpath/static/index.html index e0095b2..8fa63c8 100644 --- a/src/loadpath/static/index.html +++ b/src/loadpath/static/index.html @@ -7,7 +7,7 @@ - + diff --git a/tests/conftest.py b/tests/conftest.py index e0e149a..a81c1be 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -24,3 +24,22 @@ def git_init_with_main(repo: Path) -> None: def git_commit_all(repo: Path, message: str) -> None: subprocess.check_call(["git", "add", "-A"], cwd=repo) subprocess.check_call(["git", "commit", "-m", message], cwd=repo, stdout=subprocess.DEVNULL) + + +def change_serializer_total(repo: Path) -> None: + path = repo / "backend/billing/serializers.py" + text = path.read_text() + path.write_text( + text.replace( + 'fields = ["id", "customer_id", "total", "status"]', + 'fields = ["id", "customer_id", "total", "status"]\n extra_kwargs = {"total": {"required": True}}', + ) + ) + + +def prepare_review_repo(dest: Path) -> Path: + repo = copy_fixture(dest) + git_init_with_main(repo) + change_serializer_total(repo) + git_commit_all(repo, "tighten Invoice.total contract") + return repo diff --git a/tests/e2e/test_api_flow.py b/tests/e2e/test_api_flow.py new file mode 100644 index 0000000..2b29b7b --- /dev/null +++ b/tests/e2e/test_api_flow.py @@ -0,0 +1,113 @@ +from __future__ import annotations + +import json + +import httpx +import respx +from fastapi.testclient import TestClient + +from loadpath.server.app import create_app +from tests.conftest import prepare_review_repo + + +def test_api_health_index_review_graph_settings(tmp_path, monkeypatch): + monkeypatch.setenv("HOME", str(tmp_path / "home")) + (tmp_path / "home").mkdir() + repo = prepare_review_repo(tmp_path) + client = TestClient(create_app()) + + health = client.get("/api/health") + assert health.status_code == 200 + assert health.json()["status"] == "ok" + + indexed = client.post("/api/index", json={"repo_path": str(repo), "incremental": False}) + assert indexed.status_code == 200, indexed.text + assert indexed.json()["counts"]["nodes"] > 20 + + review = client.post( + "/api/review", + json={"repo_path": str(repo), "base": "HEAD~1", "head": "HEAD", "reindex": False}, + ) + assert review.status_code == 200, review.text + body = review.json() + assert body["confidence"]["level"] in {"high", "medium", "low"} + names = {n["name"] for n in body["nodes"]} + assert "InvoicePage" in names + assert "send_invoice_email" in names + assert "rebuild_ledger" in names + assert "markdown" in body + assert "Celery" in body["headline"] or "celery" in body["headline"].lower() + assert "Dramatiq" in body["headline"] or "dramatiq" in body["headline"].lower() + + graph = client.get("/api/graph", params={"repo_path": str(repo)}) + assert graph.status_code == 200 + assert graph.json()["counts"]["edges"] > 0 + + cfg = client.get("/api/config", params={"repo_path": str(repo)}) + assert "billing" in cfg.json()["contexts"] + + saved = client.put( + "/api/settings", + json={"github_token": "ghp_e2e_token_value", "ai_provider": "grok"}, + ) + assert saved.json()["github_token_set"] is True + assert "e2e_token" not in json.dumps(saved.json()) + assert saved.json()["ai"]["provider"] == "grok" + + home = client.get("/") + assert home.status_code == 200 + assert b"Loadpath" in home.content + + +@respx.mock +def test_api_lists_github_and_bitbucket_prs(tmp_path, monkeypatch): + monkeypatch.setenv("HOME", str(tmp_path / "home")) + (tmp_path / "home").mkdir() + client = TestClient(create_app()) + client.put("/api/settings", json={"github_token": "ghp_test", "bitbucket_token": "bb_test"}) + + respx.get("https://api.github.com/repos/acme/demo/pulls").mock( + return_value=httpx.Response( + 200, + json=[ + { + "id": 1, + "number": 42, + "title": "Invoice total field", + "html_url": "https://github.com/acme/demo/pull/42", + "user": {"login": "ada"}, + "head": {"ref": "feat/total"}, + "base": {"ref": "main"}, + "state": "open", + "updated_at": "2026-08-14T00:00:00Z", + "draft": False, + } + ], + ) + ) + gh = client.post("/api/prs", json={"provider": "github", "repo": "acme/demo"}) + assert gh.status_code == 200, gh.text + assert gh.json()["pull_requests"][0]["number"] == 42 + + respx.get("https://api.bitbucket.org/2.0/repositories/acme/demo/pullrequests").mock( + return_value=httpx.Response( + 200, + json={ + "values": [ + { + "id": 7, + "title": "ledger", + "links": {"html": {"href": "https://bitbucket.org/acme/demo/pull-requests/7"}}, + "author": {"display_name": "bob"}, + "source": {"branch": {"name": "feat"}}, + "destination": {"branch": {"name": "main"}}, + "state": "OPEN", + "updated_on": "2026-08-14T00:00:00Z", + } + ] + }, + ) + ) + bb = client.post("/api/prs", json={"provider": "bitbucket", "repo": "acme/demo"}) + assert bb.status_code == 200, bb.text + assert bb.json()["pull_requests"][0]["provider"] == "bitbucket" diff --git a/tests/e2e/test_brokers_and_django.py b/tests/e2e/test_brokers_and_django.py new file mode 100644 index 0000000..529d602 --- /dev/null +++ b/tests/e2e/test_brokers_and_django.py @@ -0,0 +1,137 @@ +from __future__ import annotations + +from loadpath.config import load_config +from loadpath.extractors.django_boot import try_boot_models +from loadpath.index import index_repo +from loadpath.review.engine import run_review +from loadpath.types import NodeType +from tests.conftest import FIXTURE_ROOT, copy_fixture, git_commit_all, git_init_with_main, prepare_review_repo + + +def test_serializer_change_includes_celery_and_dramatiq_sinks(tmp_path): + repo = prepare_review_repo(tmp_path) + review = run_review(repo, base="HEAD~1", head="HEAD") + names = {n["name"] for n in review["nodes"]} + types = {n["type"] for n in review["nodes"]} + assert "send_invoice_email" in names + assert "rebuild_ledger" in names + assert "django.task" in types + brokers = { + (n.get("extra") or {}).get("broker") + for n in review["nodes"] + if n["type"] == "django.task" + } + assert "celery" in brokers + assert "dramatiq" in brokers + assert any(e["type"] == "enqueues" for e in review["edges"]) + + +def test_dramatiq_actor_change_is_its_own_load_path(tmp_path): + repo = copy_fixture(tmp_path) + git_init_with_main(repo) + actors = repo / "backend/billing/actors.py" + actors.write_text(actors.read_text().replace("return str(invoice.total)", "return f'{invoice.total:.2f}'")) + git_commit_all(repo, "touch dramatiq actor") + review = run_review(repo, base="HEAD~1", head="HEAD") + assert any(n["name"] == "rebuild_ledger" for n in review["nodes"]) + assert any((n.get("extra") or {}).get("broker") == "dramatiq" for n in review["nodes"]) + + +def test_non_idempotent_dramatiq_task_warns(tmp_path): + repo = copy_fixture(tmp_path) + git_init_with_main(repo) + (repo / "backend/billing/actors.py").write_text( + "import dramatiq\n\n@dramatiq.actor\ndef blast(invoice):\n return invoice\n" + ) + git_commit_all(repo, "unsafe dramatiq payload") + review = run_review(repo, base="HEAD~1", head="HEAD") + rules = [f["rule"] for f in review["findings"] if not f.get("waived")] + assert "celery_tasks_must_be_idempotent_on_model_pk" in rules + assert any("Dramatiq" in f["message"] for f in review["findings"]) + + +def test_destructive_migration_is_classified(tmp_path): + repo = copy_fixture(tmp_path) + git_init_with_main(repo) + mig = repo / "backend/billing/migrations/0002_remove_total.py" + mig.write_text( + "from django.db import migrations\n\n" + "class Migration(migrations.Migration):\n" + " operations = [migrations.RemoveField(model_name='Invoice', name='total')]\n" + ) + git_commit_all(repo, "remove total field") + review = run_review(repo, base="HEAD~1", head="HEAD") + assert "schema_migration" in review["change_kinds"] + assert any(n["type"] == "django.migration_op" for n in review["nodes"]) + assert any(e["type"] == "destructive_migration" for e in review["edges"]) + + +def test_cross_context_view_is_blocker_on_pr(tmp_path): + repo = copy_fixture(tmp_path) + git_init_with_main(repo) + views = repo / "backend/billing/views.py" + views.write_text("from accounts.models import UserProfile\n" + views.read_text()) + git_commit_all(repo, "leak identity model") + review = run_review(repo, base="HEAD~1", head="HEAD") + assert "cross_context" in review["change_kinds"] + assert review["confidence"]["level"] == "low" + assert any(f["rule"] == "views_cannot_import_other_context_models" for f in review["findings"]) + + +def test_django_boot_overlay_reports_skip_or_models(tmp_path): + cfg = load_config(FIXTURE_ROOT) + cfg.boot_django = True + graph = try_boot_models(FIXTURE_ROOT, cfg) + assert graph.residuals + assert any("django.setup()" in r for r in graph.residuals) + # Either Django isn't installed, settings failed, or models were booted. + if any(n.type is NodeType.MODEL and (n.extra or {}).get("booted") for n in graph.nodes): + assert any(n.name == "Invoice" for n in graph.nodes) + + +def test_index_counts_grow_with_new_django_files(tmp_path): + store = index_repo(FIXTURE_ROOT, db_path=tmp_path / "g.sqlite3", incremental=False) + types = {n["type"] for n in store.nodes()} + assert "django.task" in types + assert "django.management_command" in types + tasks = [n for n in store.nodes() if n["type"] == "django.task"] + brokers = {(n.get("extra") or {}).get("broker") for n in tasks} + assert {"celery", "dramatiq"} <= brokers + names = {n["name"] for n in tasks} + assert "RecalcTotals" in names + assert "NotifyCustomer" in names + assert any((n.get("extra") or {}).get("beat") for n in tasks) + store.close() + + +def test_celery_canvas_and_send_task_are_residuals_on_task_pr(tmp_path): + repo = copy_fixture(tmp_path) + git_init_with_main(repo) + tasks = repo / "backend/billing/tasks.py" + tasks.write_text(tasks.read_text() + "\n# touch canvas\n") + git_commit_all(repo, "touch celery canvas") + review = run_review(repo, base="HEAD~1", head="HEAD") + blob = " ".join(review["residuals"]) + assert "send_task" in blob or "canvas" in blob.lower() + assert any(n["name"] == "send_invoice_email" for n in review["nodes"]) + + +def test_management_command_change_traces_to_celery(tmp_path): + repo = copy_fixture(tmp_path) + git_init_with_main(repo) + cmd = repo / "backend/billing/management/commands/resend_invoices.py" + cmd.write_text(cmd.read_text().replace("invoice.id", "invoice.pk")) + git_commit_all(repo, "command uses pk") + review = run_review(repo, base="HEAD~1", head="HEAD") + names = {n["name"] for n in review["nodes"]} + assert "resend_invoices" in names + assert "send_invoice_email" in names + assert any(e["type"] == "enqueues" for e in review["edges"]) + + +def test_ninja_and_fbv_are_indexed(tmp_path): + store = index_repo(FIXTURE_ROOT, db_path=tmp_path / "g.sqlite3", incremental=False) + names = {n["name"] for n in store.nodes()} + assert "invoice_totals" in names + assert any("ledger" in n["name"] for n in store.nodes() if n["type"] == "django.route") + store.close() diff --git a/tests/e2e/test_cli_review.py b/tests/e2e/test_cli_review.py index 61334ea..935b427 100644 --- a/tests/e2e/test_cli_review.py +++ b/tests/e2e/test_cli_review.py @@ -3,20 +3,53 @@ from typer.testing import CliRunner from loadpath.cli import app -from tests.conftest import copy_fixture, git_commit_all, git_init_with_main +from tests.conftest import prepare_review_repo runner = CliRunner() -def test_cli_index_and_review(tmp_path): - repo = copy_fixture(tmp_path) - git_init_with_main(repo) - ser = repo / "backend/billing/serializers.py" - ser.write_text(ser.read_text() + "\n# touch\n") - git_commit_all(repo, "touch serializer") +def test_cli_index_review_json_and_html(tmp_path): + repo = prepare_review_repo(tmp_path) result = runner.invoke(app, ["index", str(repo)]) assert result.exit_code == 0, result.output assert "nodes" in result.output - result = runner.invoke(app, ["review", str(repo), "--base", "HEAD~1", "--head", "HEAD"]) - assert result.exit_code == 0, result.output + + md = runner.invoke(app, ["review", str(repo), "--base", "HEAD~1", "--head", "HEAD"]) + assert md.exit_code == 0, md.output + assert "Loadpath" in md.output + assert "MEDIUM" in md.output or "LOW" in md.output or "HIGH" in md.output + + json_out = tmp_path / "review.json" + js = runner.invoke( + app, + ["review", str(repo), "--base", "HEAD~1", "--head", "HEAD", "--format", "json", "--out", str(json_out)], + ) + assert js.exit_code == 0, js.output + payload = json_out.read_text() + assert "InvoiceSerializer" in payload + assert "rebuild_ledger" in payload + assert "send_invoice_email" in payload + assert "Dramatiq" in payload or "dramatiq" in payload + assert "Celery" in payload or "celery" in payload + + html_out = tmp_path / "review.html" + html = runner.invoke( + app, + ["review", str(repo), "--base", "HEAD~1", "--head", "HEAD", "--format", "html", "--out", str(html_out)], + ) + assert html.exit_code == 0, html.output + text = html_out.read_text() + assert "vis-network" in text + assert "Loadpath" in text + + +def test_cli_help(): + result = runner.invoke(app, ["--help"]) + assert result.exit_code == 0 assert "Loadpath" in result.output + + +def test_cli_serve_help(): + result = runner.invoke(app, ["serve", "--help"]) + assert result.exit_code == 0 + assert "port" in result.output.lower() diff --git a/tests/e2e/test_ui_screenshots.py b/tests/e2e/test_ui_screenshots.py new file mode 100644 index 0000000..a25a277 --- /dev/null +++ b/tests/e2e/test_ui_screenshots.py @@ -0,0 +1,134 @@ +from __future__ import annotations + +import os +import shutil +import socket +import threading +from collections.abc import Iterator +from pathlib import Path + +import pytest +import uvicorn + +from loadpath.server.app import create_app +from tests.conftest import prepare_review_repo + +SCREENSHOT_DIR = Path(__file__).resolve().parents[2] / "docs" / "screenshots" +PRETTY_REPO = Path("/tmp/acme-billing") + + +def _free_port() -> int: + sock = socket.socket() + sock.bind(("127.0.0.1", 0)) + port = sock.getsockname()[1] + sock.close() + return port + + +@pytest.fixture +def live_app(tmp_path: Path) -> Iterator[tuple[str, Path]]: + repo = prepare_review_repo(tmp_path) + if PRETTY_REPO.exists(): + shutil.rmtree(PRETTY_REPO) + shutil.copytree(repo, PRETTY_REPO) + port = _free_port() + server = uvicorn.Server( + uvicorn.Config(create_app(), host="127.0.0.1", port=port, log_level="warning") + ) + thread = threading.Thread(target=server.run, daemon=True) + thread.start() + for _ in range(50): + if server.started: + break + thread.join(0.05) + if not server.started: + pytest.skip("uvicorn failed to start") + try: + yield f"http://127.0.0.1:{port}", PRETTY_REPO + finally: + server.should_exit = True + thread.join(timeout=5) + if PRETTY_REPO.exists(): + shutil.rmtree(PRETTY_REPO, ignore_errors=True) + + +def _playwright_page(): + pytest.importorskip("playwright") + from playwright.sync_api import sync_playwright + + try: + pw = sync_playwright().start() + browser = pw.chromium.launch(headless=True) + except Exception as exc: # noqa: BLE001 + pytest.skip(f"Chromium not available: {exc}") + page = browser.new_page(viewport={"width": 1440, "height": 900}) + return pw, browser, page + + +@pytest.mark.playwright +def test_ui_review_graph_prs_settings(live_app, tmp_path: Path): + base_url, repo = live_app + pw, browser, page = _playwright_page() + try: + page.route( + "**/api/prs", + lambda route: route.fulfill( + status=200, + content_type="application/json", + body='{"pull_requests":[{"provider":"github","id":"1","number":42,"title":"Invoice.total field change","url":"https://github.com/acme/demo/pull/42","author":"ada","source_branch":"feat/total","target_branch":"main","repo":"acme/demo","state":"open","updated_at":"2026-08-14T00:00:00Z","draft":false}]}', + ), + ) + page.goto(base_url, wait_until="networkidle") + try: + page.wait_for_function("document.fonts ? document.fonts.status === 'loaded' : true", timeout=5_000) + except Exception: + pass + assert page.get_by_test_id("rail").is_visible() + page.get_by_test_id("repo-path").fill(str(repo)) + page.get_by_test_id("base-ref").fill("HEAD~1") + page.get_by_test_id("head-ref").fill("HEAD") + with page.expect_response( + lambda r: "/api/review" in r.url and r.request.method == "POST", + timeout=60_000, + ) as pending: + page.get_by_test_id("btn-review").click() + response = pending.value + if not response.ok: + pytest.fail(f"review API {response.status}: {response.text()}") + error = page.locator(".error") + if error.count() and error.inner_text().strip(): + pytest.fail(error.inner_text()) + page.locator(".level").wait_for(timeout=15_000) + brief = page.get_by_test_id("brief").inner_text() + assert "MEDIUM" in brief or "LOW" in brief or "HIGH" in brief + page.locator(".react-flow__node").first.wait_for(timeout=15_000) + page.wait_for_timeout(800) + + dest = Path(os.environ.get("LOADPATH_SCREENSHOT_DIR", str(SCREENSHOT_DIR))) + dest.mkdir(parents=True, exist_ok=True) + page.screenshot(path=str(dest / "review.png"), full_page=False) + + page.get_by_test_id("tab-graph").click() + page.get_by_test_id("graph-full").wait_for() + page.locator(".react-flow__node").first.wait_for(timeout=15_000) + page.wait_for_timeout(600) + page.screenshot(path=str(dest / "graph.png"), full_page=False) + + page.get_by_test_id("tab-prs").click() + page.get_by_test_id("pr-repo").fill("acme/demo") + page.get_by_test_id("btn-list-prs").click() + page.get_by_text("#42").wait_for(timeout=10_000) + page.wait_for_timeout(300) + page.screenshot(path=str(dest / "pull-requests.png"), full_page=False) + + page.get_by_test_id("tab-settings").click() + page.get_by_test_id("settings-form").wait_for() + page.locator('select[name="ai_provider"]').select_option("grok") + page.wait_for_timeout(200) + page.screenshot(path=str(dest / "settings.png"), full_page=False) + + for name in ("review.png", "graph.png", "pull-requests.png", "settings.png"): + assert (dest / name).stat().st_size > 1000 + finally: + browser.close() + pw.stop() diff --git a/tests/unit/test_django_extractors.py b/tests/unit/test_django_extractors.py index 03943bd..28a1f87 100644 --- a/tests/unit/test_django_extractors.py +++ b/tests/unit/test_django_extractors.py @@ -61,9 +61,116 @@ def test_extracts_signal_receiver(): def test_extracts_celery_task_pk_idempotency(): source = (FIXTURE / "backend/billing/tasks.py").read_text() g = extract_django_file("backend/billing/tasks.py", source, _cfg()) - tasks = [n for n in g.nodes if n.type is NodeType.TASK] - assert tasks[0].name == "send_invoice_email" - assert tasks[0].extra["looks_idempotent_on_pk"] is True + defined = [ + n + for n in g.nodes + if n.type is NodeType.TASK and n.name == "send_invoice_email" and n.extra.get("looks_idempotent_on_pk") is not None + ] + assert defined + assert defined[0].extra["looks_idempotent_on_pk"] is True + assert defined[0].extra.get("broker") == "celery" + + +def test_extracts_celery_task_class_canvas_and_send_task(): + source = (FIXTURE / "backend/billing/tasks.py").read_text() + g = extract_django_file("backend/billing/tasks.py", source, _cfg()) + recalc = next(n for n in g.nodes if n.name == "RecalcTotals") + assert recalc.type is NodeType.TASK + assert recalc.extra.get("broker") == "celery" + assert recalc.extra.get("task_class") is True + assert any("send_task" in r for r in g.residuals) + assert any("canvas" in r.lower() for r in g.residuals) + assert any( + e.type.value == "enqueues" and "apply_credit" in e.dst for e in g.edges + ) + + +def test_extracts_dramatiq_actor(): + source = (FIXTURE / "backend/billing/actors.py").read_text() + g = extract_django_file("backend/billing/actors.py", source, _cfg()) + actors = [n for n in g.nodes if n.type is NodeType.TASK] + names = {n.name for n in actors} + assert "rebuild_ledger" in names + assert "NotifyCustomer" in names + ledger = next(n for n in actors if n.name == "rebuild_ledger") + assert ledger.extra.get("broker") == "dramatiq" + assert ledger.extra["looks_idempotent_on_pk"] is True + notify = next(n for n in actors if n.name == "NotifyCustomer") + assert notify.extra.get("task_class") is True + + +def test_extracts_celery_beat_schedule(): + source = (FIXTURE / "backend/config/settings.py").read_text() + g = extract_django_file("backend/config/settings.py", source, _cfg()) + assert any(n.extra.get("beat") and n.name == "apply_credit" for n in g.nodes) + assert any("Celery beat" in r for r in g.residuals) + + +def test_management_command_enqueues_celery(): + rel = "backend/billing/management/commands/resend_invoices.py" + source = (FIXTURE / rel).read_text() + g = extract_django_file(rel, source, _cfg()) + assert any(n.type is NodeType.MANAGEMENT_COMMAND for n in g.nodes) + assert any( + e.type.value == "enqueues" and "resend_invoices" in e.src for e in g.edges + ) + + +def test_view_enqueues_celery_and_dramatiq(): + source = (FIXTURE / "backend/billing/views.py").read_text() + g = extract_django_file("backend/billing/views.py", source, _cfg()) + brokers = {e.extra.get("broker") for e in g.edges if e.type.value == "enqueues"} + assert "celery" in brokers + assert "dramatiq" in brokers + assert any(n.type is NodeType.VIEW and n.extra.get("fbv") for n in g.nodes) + view = next(n for n in g.nodes if n.name == "InvoiceViewSet") + assert view.extra.get("get_queryset") is True + assert view.extra.get("filterset") == "InvoiceFilter" + + +def test_extracts_ninja_route(): + source = (FIXTURE / "backend/billing/api.py").read_text() + g = extract_django_file("backend/billing/api.py", source, _cfg()) + assert any(n.type is NodeType.ROUTE and "ledger" in n.name for n in g.nodes) + assert any(n.type is NodeType.VIEW and n.extra.get("ninja") for n in g.nodes) + + +def test_task_definition_file_survives_call_site_placeholder(tmp_path): + from loadpath.index import index_repo + + store = index_repo(FIXTURE, db_path=tmp_path / "g.sqlite3", incremental=False) + ledger = next(n for n in store.nodes() if n["name"] == "rebuild_ledger") + assert "actors.py" in (ledger.get("file_path") or "") + assert not (ledger.get("extra") or {}).get("referenced") + email = next( + n + for n in store.nodes() + if n["name"] == "send_invoice_email" and (n.get("extra") or {}).get("looks_idempotent_on_pk") + ) + assert "tasks.py" in (email.get("file_path") or "") + store.close() + + +def test_extracts_management_command(): + rel = "backend/billing/management/commands/resend_invoices.py" + source = (FIXTURE / rel).read_text() + g = extract_django_file(rel, source, _cfg()) + assert any(n.type is NodeType.MANAGEMENT_COMMAND for n in g.nodes) + + +def test_on_commit_and_apply_async(): + source = (FIXTURE / "backend/billing/tasks.py").read_text() + g = extract_django_file("backend/billing/tasks.py", source, _cfg()) + assert any("on_commit" in r for r in g.residuals) + assert any(e.type.value == "enqueues" and "apply_async" in (e.extra.get("call") or "") for e in g.edges) + + +def test_foreignkey_string_ref(): + source = (FIXTURE / "backend/billing/models.py").read_text() + g = extract_django_file("backend/billing/models.py", source, _cfg()) + assert any("string model ref" in r for r in g.residuals) + account = next(n for n in g.nodes if n.name == "account") + assert account.extra.get("on_delete") == "SET_NULL" def test_extracts_service_and_admin_and_tests(): diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 5eb161e..76720ea 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -97,43 +97,44 @@ export function App() { return (

-z1qL(RCeRc~| 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 literal 0 HcmV?d00001 diff --git a/docs/screenshots/pull-requests.png b/docs/screenshots/pull-requests.png new file mode 100644 index 0000000000000000000000000000000000000000..a49a9389c664ffce5ed2970d007ce109c7d7d46e GIT binary patch literal 39198 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 literal 0 HcmV?d00001 diff --git a/docs/screenshots/review.png b/docs/screenshots/review.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9b4fda3fdc6e72e476df1c298c824bd87dee9a GIT binary patch literal 314719 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