From 0c13d26aecc2aa1d26d034cdd1f37c3fdb32cd24 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Wed, 29 Apr 2026 13:30:58 +0000 Subject: [PATCH 1/7] perf(detectors): quick-reject pre-screen on auth detectors (-31% detector CPU) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Profiling on a 30K-file polyglot fixture (kept at ~/projects/polyglot-bench: spring-petclinic-microservices, airflow, istio, eShop, angular/components, nuxt, actix/examples, ktor-samples, nlohmann/json, play-samples, PSScriptAnalyzer, terraform-aws-eks; 14 distinct languages) showed the three cross-cutting auth detectors burning 55% of all detector CPU because they ran the lines × patterns double loop on every supported-language file — even files with zero auth keywords. Fix: per-detector PRE_SCREEN Pattern with all distinctive literal substrings of the underlying patterns. One regex pass over file content; if no keyword present, the file cannot match — short-circuit before the line loop. Measured impact (JFR ExecutionSample, JDK 25, polyglot fixture): CertificateAuthDetector: 244 → 147 samples (-39.8%, -0.97s CPU) SessionHeaderAuthDetector: 206 → 43 samples (-79.1%, -1.63s CPU) LdapAuthDetector: 47 → 25 samples (-46.8%, -0.22s CPU) Auth subtotal: 497 → 215 samples (-56.7%, -2.82s) All detectors total: 902 → 624 samples (-30.8%, -2.78s) Detection semantics unchanged — pre-screen rejects only files where no underlying pattern can match (keyword absent). Tests covering keyword-bearing fixtures pass through pre-screen and run the existing logic byte-for-byte. Tests: 3689 / 0 failures / 0 errors / 32 skipped. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../detector/auth/CertificateAuthDetector.java | 17 +++++++++++++++++ .../iq/detector/auth/LdapAuthDetector.java | 9 +++++++++ .../auth/SessionHeaderAuthDetector.java | 14 ++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/src/main/java/io/github/randomcodespace/iq/detector/auth/CertificateAuthDetector.java b/src/main/java/io/github/randomcodespace/iq/detector/auth/CertificateAuthDetector.java index 5dd1616f..9195d94d 100644 --- a/src/main/java/io/github/randomcodespace/iq/detector/auth/CertificateAuthDetector.java +++ b/src/main/java/io/github/randomcodespace/iq/detector/auth/CertificateAuthDetector.java @@ -78,6 +78,20 @@ private record PatternDef(Pattern regex, String authType) {} private static final Pattern CERT_PATH_RE = Pattern.compile("['\"]([^'\"]*\\.(?:pem|crt|key|cert|pfx|p12))['\"]"); private static final Pattern TENANT_ID_RE = Pattern.compile("AZURE_TENANT_ID\\s*[=:]\\s*['\"]?([a-f0-9-]+)['\"]?"); + // Quick-reject pre-screen: a single regex pass over file content. If no + // distinctive literal substring from any pattern in ALL_PATTERNS is + // present, the file cannot match — short-circuit before the lines × patterns + // double loop. Profiling on polyglot-bench (29.7K files, 14 languages) showed + // this detector accounting for ~27% of detector CPU because it scanned every + // YAML/JSON in supported-languages even when no auth keyword was present. + private static final Pattern PRE_SCREEN = Pattern.compile( + "ssl_verify_client|requestCert|clientAuth|X509|" + + "AddCertificateForwarding|CertificateAuthenticationDefaults|" + + "\\.x509\\(|javax\\.net\\.ssl|SSLContext|tls\\.createServer|" + + "trustStore|AzureAd|AZURE_TENANT_ID|AZURE_CLIENT_ID|" + + "ClientCertificateCredential|AddMicrosoftIdentityWebApi|" + + "msal|MSAL|@azure/msal|\\.pem|\\.crt|\\.cert"); + @Override public String getName() { return "certificate_auth"; @@ -95,6 +109,9 @@ public DetectorResult detect(DetectorContext ctx) { if (text == null || text.isEmpty()) { return DetectorResult.empty(); } + if (!PRE_SCREEN.matcher(text).find()) { + return DetectorResult.empty(); + } String filePath = ctx.filePath(); String[] lines = text.split("\n", -1); diff --git a/src/main/java/io/github/randomcodespace/iq/detector/auth/LdapAuthDetector.java b/src/main/java/io/github/randomcodespace/iq/detector/auth/LdapAuthDetector.java index d46f38ae..2044cd67 100644 --- a/src/main/java/io/github/randomcodespace/iq/detector/auth/LdapAuthDetector.java +++ b/src/main/java/io/github/randomcodespace/iq/detector/auth/LdapAuthDetector.java @@ -59,6 +59,12 @@ public class LdapAuthDetector extends AbstractRegexDetector { "csharp", CSHARP_PATTERNS ); + // Quick-reject pre-screen — see CertificateAuthDetector for rationale. + // Most code files don't mention LDAP at all; one regex pass over content + // skips the lines × patterns double loop in those cases. + private static final Pattern PRE_SCREEN = Pattern.compile( + "(?i:ldap)|DirectoryServices|DirectoryEntry"); + @Override public String getName() { return "ldap_auth"; @@ -80,6 +86,9 @@ public DetectorResult detect(DetectorContext ctx) { if (text == null || text.isEmpty()) { return DetectorResult.empty(); } + if (!PRE_SCREEN.matcher(text).find()) { + return DetectorResult.empty(); + } List nodes = new ArrayList<>(); String[] lines = text.split("\n", -1); diff --git a/src/main/java/io/github/randomcodespace/iq/detector/auth/SessionHeaderAuthDetector.java b/src/main/java/io/github/randomcodespace/iq/detector/auth/SessionHeaderAuthDetector.java index 6ffe5718..1bbdbde2 100644 --- a/src/main/java/io/github/randomcodespace/iq/detector/auth/SessionHeaderAuthDetector.java +++ b/src/main/java/io/github/randomcodespace/iq/detector/auth/SessionHeaderAuthDetector.java @@ -78,6 +78,17 @@ private record PatternDef(Pattern regex, String authType, NodeKind nodeKind) {} PROP_CSRF, PROP_CSRF ); + // Quick-reject pre-screen — see CertificateAuthDetector for rationale. + // Single regex pass over file content; if no distinctive substring of any + // pattern in ALL_PATTERNS is present, the file cannot match — short-circuit + // before the lines × patterns double loop. Profiling on polyglot-bench + // showed this detector at ~23% of detector CPU; most TS/Python files have + // no auth keyword at all. + private static final Pattern PRE_SCREEN = Pattern.compile( + "express-session|cookie-session|@SessionAttributes|SessionMiddleware|" + + "HttpSession|SESSION_ENGINE|" + + "(?i:X-API|Authorization|api[_-]?key|csurf|csrf|getHeader)"); + @Override public String getName() { return "session_header_auth"; @@ -98,6 +109,9 @@ public DetectorResult detect(DetectorContext ctx) { if (text == null || text.isEmpty()) { return DetectorResult.empty(); } + if (!PRE_SCREEN.matcher(text).find()) { + return DetectorResult.empty(); + } List nodes = new ArrayList<>(); String[] lines = text.split("\n", -1); From 3a82e2891732b0f29d1b2720da76debceec50404 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Sun, 3 May 2026 15:45:43 +0000 Subject: [PATCH 2/7] feat(ui): migrate frontend from AntD to @ossrandom/design-system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Full UI rewrite onto @ossrandom/design-system v0.3.0 (npm). Replaces Ant Design + ECharts + @ant-design/icons with the design-system primitives + charts subpath + an inline-SVG icon set. Surface changes: - AppShell-based header with a single IconButton theme toggle and a monospace MCP-URL pill (copy-to-clipboard). - Stats grid replaced with a CSS auto-fit grid (mobile-responsive). - File-tree treemap renders via @ossrandom/design-system/charts (d3-hierarchy, canvas engine, maxDepth=1) with an explicit drill-down / drill-up affordance via a breadcrumb row; treemap layout is deterministic (children sorted alphabetically, fixed height, single remount via key when focusPath changes). - File viewer drawer kept; MCP Tools sidebar removed (the design-system Menu's nested-inline expansion didn't match the prior UX). - Three orphan pages deleted (Explorer.tsx, McpConsole.tsx, CodebaseMap.tsx) — none were routed in App.tsx. - index.css trimmed to body reset + layout-only classes using design-system CSS tokens; `.rcs-treemap-engine-badge` hidden via a single rule. - vite.config.ts: manualChunks reorganised (vendor-ds / vendor-ds-charts replace vendor-antd / vendor-echarts). Bundled fonts and the deck.gl tesselator chunk live alongside the hashed JS in src/main/resources/static/assets/ — air-gapped requirement per build.md. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/main/frontend/package-lock.json | 1081 +--------- src/main/frontend/package.json | 6 +- .../frontend/src/components/AppLayout.tsx | 113 +- src/main/frontend/src/components/Icons.tsx | 27 + src/main/frontend/src/index.css | 138 +- src/main/frontend/src/main.tsx | 86 +- src/main/frontend/src/pages/CodebaseMap.tsx | 294 --- src/main/frontend/src/pages/Dashboard.tsx | 516 ++--- src/main/frontend/src/pages/Explorer.tsx | 354 --- src/main/frontend/src/pages/McpConsole.tsx | 415 ---- src/main/frontend/vite.config.ts | 4 +- ...BricolageGrotesque-Variable-C5Lc8Qmc.woff2 | Bin 0 -> 131548 bytes .../assets/GeistMono-Variable-BNLlm6Cd.woff2 | Bin 0 -> 71004 bytes .../PlusJakartaSans-Variable-eXO_dkmS.woff2 | Bin 0 -> 27348 bytes .../static/assets/tesselator-D_j4OGEy.js | 1916 +++++++++++++++++ 15 files changed, 2441 insertions(+), 2509 deletions(-) create mode 100644 src/main/frontend/src/components/Icons.tsx delete mode 100644 src/main/frontend/src/pages/CodebaseMap.tsx delete mode 100644 src/main/frontend/src/pages/Explorer.tsx delete mode 100644 src/main/frontend/src/pages/McpConsole.tsx create mode 100644 src/main/resources/static/assets/BricolageGrotesque-Variable-C5Lc8Qmc.woff2 create mode 100644 src/main/resources/static/assets/GeistMono-Variable-BNLlm6Cd.woff2 create mode 100644 src/main/resources/static/assets/PlusJakartaSans-Variable-eXO_dkmS.woff2 create mode 100644 src/main/resources/static/assets/tesselator-D_j4OGEy.js diff --git a/src/main/frontend/package-lock.json b/src/main/frontend/package-lock.json index 790dac60..69762b10 100644 --- a/src/main/frontend/package-lock.json +++ b/src/main/frontend/package-lock.json @@ -8,10 +8,8 @@ "name": "codeiq-ui", "version": "0.2.0", "dependencies": { - "@ant-design/icons": "^6.2.1", - "antd": "^6.3.7", - "echarts": "^6.0.0", - "echarts-for-react": "^3.0.2", + "@ossrandom/design-system": "^0.3.0", + "d3-hierarchy": "^3.1.2", "react": "^19.2.5", "react-dom": "^19.2.5", "react-router-dom": "^7.1.5" @@ -27,97 +25,67 @@ "vite": "^6.4.2" } }, - "node_modules/@ant-design/colors": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-8.0.1.tgz", - "integrity": "sha512-foPVl0+SWIslGUtD/xBr1p9U4AKzPhNYEseXYRRo5QSzGACYZrQbe11AYJbYfAWnWSpGBx6JjBmSeugUsD9vqQ==", + "../../../../design-system": { + "name": "@ossrandom/design-system", + "version": "0.3.0", "license": "MIT", - "dependencies": { - "@ant-design/fast-color": "^3.0.0" - } - }, - "node_modules/@ant-design/cssinjs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@ant-design/cssinjs/-/cssinjs-2.1.2.tgz", - "integrity": "sha512-2Hy8BnCEH31xPeSLbhhB2ctCPXE2ZnASdi+KbSeS79BNbUhL9hAEe20SkUk+BR8aKTmqb6+FKFruk7w8z0VoRQ==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.11.1", - "@emotion/hash": "^0.8.0", - "@emotion/unitless": "^0.7.5", - "@rc-component/util": "^1.4.0", - "clsx": "^2.1.1", - "csstype": "^3.1.3", - "stylis": "^4.3.4" - }, - "peerDependencies": { - "react": ">=16.0.0", - "react-dom": ">=16.0.0" - } - }, - "node_modules/@ant-design/cssinjs-utils": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@ant-design/cssinjs-utils/-/cssinjs-utils-2.1.2.tgz", - "integrity": "sha512-5fTHQ158jJJ5dC/ECeyIdZUzKxE/mpEMRZxthyG1sw/AKRHKgJBg00Yi6ACVXgycdje7KahRNvNET/uBccwCnA==", - "license": "MIT", - "dependencies": { - "@ant-design/cssinjs": "^2.1.2", - "@babel/runtime": "^7.23.2", - "@rc-component/util": "^1.4.0" + "devDependencies": { + "@babel/standalone": "^7.29.0", + "@playwright/test": "^1.59.1", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.2", + "@testing-library/user-event": "^14.6.1", + "@types/node": "^22.0.0", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", + "@vitest/coverage-v8": "^4.1.5", + "esbuild": "^0.28.0", + "eslint": "^9.0.0", + "jsdom": "^29.0.2", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "typescript": "^5.6.0", + "vite": "^8.0.10", + "vitest": "^4.1.5" + }, + "engines": { + "node": ">=18.18" }, "peerDependencies": { + "@deck.gl/core": "^9.0.0", + "@deck.gl/layers": "^9.0.0", + "cytoscape": "^3.30.0", + "cytoscape-cose-bilkent": "^4.1.0", + "d3-force": "^3.0.0", + "d3-hierarchy": "^3.0.0", "react": ">=18", - "react-dom": ">=18" - } - }, - "node_modules/@ant-design/fast-color": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@ant-design/fast-color/-/fast-color-3.0.1.tgz", - "integrity": "sha512-esKJegpW4nckh0o6kV3Tkb7NPIZYbPnnFxmQDUmL08ukXZAvV85TZBr70eGuke/CIArLaP6aw8lt9KILjnWuOw==", - "license": "MIT", - "engines": { - "node": ">=8.x" - } - }, - "node_modules/@ant-design/icons": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-6.2.1.tgz", - "integrity": "sha512-mYt5ynqj0CsuGoffbYTPKGBy9q8iQtKk6hNLkdH1Wr3a8Z5I9MUWgFsexGxIlDnaskfWIr8M21MA/8If6E0/+Q==", - "license": "MIT", - "dependencies": { - "@ant-design/colors": "^8.0.1", - "@ant-design/icons-svg": "^4.4.2", - "@rc-component/util": "^1.10.1", - "clsx": "^2.1.1" - }, - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "react": ">=16.0.0", - "react-dom": ">=16.0.0" - } - }, - "node_modules/@ant-design/icons-svg": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz", - "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==", - "license": "MIT" - }, - "node_modules/@ant-design/react-slick": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-2.0.0.tgz", - "integrity": "sha512-HMS9sRoEmZey8LsE/Yo6+klhlzU12PisjrVcydW3So7RdklyEd2qehyU6a7Yp+OYN72mgsYs3NFCyP2lCPFVqg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.28.4", - "clsx": "^2.1.1", - "json2mq": "^0.2.0", - "throttle-debounce": "^5.0.0" + "react-dom": ">=18", + "uplot": "^1.6.0" }, - "peerDependencies": { - "react": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + "peerDependenciesMeta": { + "@deck.gl/core": { + "optional": true + }, + "@deck.gl/layers": { + "optional": true + }, + "cytoscape": { + "optional": true + }, + "cytoscape-cose-bilkent": { + "optional": true + }, + "d3-force": { + "optional": true + }, + "d3-hierarchy": { + "optional": true + }, + "uplot": { + "optional": true + } } }, "node_modules/@axe-core/playwright": { @@ -367,15 +335,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/runtime": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", - "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/template": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", @@ -424,18 +383,6 @@ "node": ">=6.9.0" } }, - "node_modules/@emotion/hash": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", - "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==", - "license": "MIT" - }, - "node_modules/@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==", - "license": "MIT" - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", @@ -928,6 +875,10 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@ossrandom/design-system": { + "resolved": "../../../../design-system", + "link": true + }, "node_modules/@playwright/test": { "version": "1.59.1", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.59.1.tgz", @@ -944,719 +895,6 @@ "node": ">=18" } }, - "node_modules/@rc-component/async-validator": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@rc-component/async-validator/-/async-validator-5.1.0.tgz", - "integrity": "sha512-n4HcR5siNUXRX23nDizbZBQPO0ZM/5oTtmKZ6/eqL0L2bo747cklFdZGRN2f+c9qWGICwDzrhW0H7tE9PptdcA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.24.4" - }, - "engines": { - "node": ">=14.x" - } - }, - "node_modules/@rc-component/cascader": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/@rc-component/cascader/-/cascader-1.14.0.tgz", - "integrity": "sha512-Ip9356xwZUR2nbW5PRVGif4B/bDve4pLa/N+PGbvBaTnjbvmN4PFMBGQSmlDlzKP1ovxaYMvwF/dI9lXNLT4iQ==", - "license": "MIT", - "dependencies": { - "@rc-component/select": "~1.6.0", - "@rc-component/tree": "~1.2.0", - "@rc-component/util": "^1.4.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=18.0.0" - } - }, - "node_modules/@rc-component/checkbox": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@rc-component/checkbox/-/checkbox-2.0.0.tgz", - "integrity": "sha512-3CXGPpAR9gsPKeO2N78HAPOzU30UdemD6HGJoWVJOpa6WleaGB5kzZj3v6bdTZab31YuWgY/RxV3VKPctn0DwQ==", - "license": "MIT", - "dependencies": { - "@rc-component/util": "^1.3.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/collapse": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@rc-component/collapse/-/collapse-1.2.0.tgz", - "integrity": "sha512-ZRYSKSS39qsFx93p26bde7JUZJshsUBEQRlRXPuJYlAiNX0vyYlF5TsAm8JZN3LcF8XvKikdzPbgAtXSbkLUkw==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.10.1", - "@rc-component/motion": "^1.1.4", - "@rc-component/util": "^1.3.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=18.0.0" - } - }, - "node_modules/@rc-component/color-picker": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-3.1.1.tgz", - "integrity": "sha512-OHaCHLHszCegdXmIq2ZRIZBN/EtpT6Wm8SG/gpzLATHbVKc/avvuKi+zlOuk05FTWvgaMmpxAko44uRJ3M+2pg==", - "license": "MIT", - "dependencies": { - "@ant-design/fast-color": "^3.0.1", - "@rc-component/util": "^1.3.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/context": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@rc-component/context/-/context-2.0.1.tgz", - "integrity": "sha512-HyZbYm47s/YqtP6pKXNMjPEMaukyg7P0qVfgMLzr7YiFNMHbK2fKTAGzms9ykfGHSfyf75nBbgWw+hHkp+VImw==", - "license": "MIT", - "dependencies": { - "@rc-component/util": "^1.3.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/dialog": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/@rc-component/dialog/-/dialog-1.8.4.tgz", - "integrity": "sha512-Ay6PM7phkTkquplG8fWfUGFZ2GTLx9diTl4f0d8Eqxd7W1u1KjE9AQooFQHOHnhZf0Ya3z51+5EKCWHmt/dNEw==", - "license": "MIT", - "dependencies": { - "@rc-component/motion": "^1.1.3", - "@rc-component/portal": "^2.1.0", - "@rc-component/util": "^1.9.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=18.0.0" - } - }, - "node_modules/@rc-component/drawer": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@rc-component/drawer/-/drawer-1.4.2.tgz", - "integrity": "sha512-1ib+fZEp6FBu+YvcIktm+nCQ+Q+qIpwpoaJH6opGr4ofh2QMq+qdr5DLC4oCf5qf3pcWX9lUWPYX652k4ini8Q==", - "license": "MIT", - "dependencies": { - "@rc-component/motion": "^1.1.4", - "@rc-component/portal": "^2.1.3", - "@rc-component/util": "^1.9.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=18.0.0" - } - }, - "node_modules/@rc-component/dropdown": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rc-component/dropdown/-/dropdown-1.0.2.tgz", - "integrity": "sha512-6PY2ecUSYhDPhkNHHb4wfeAya04WhpmUSKzdR60G+kMNVUCX2vjT/AgTS0Lz0I/K6xrPMJ3enQbwVpeN3sHCgg==", - "license": "MIT", - "dependencies": { - "@rc-component/trigger": "^3.0.0", - "@rc-component/util": "^1.2.1", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=16.11.0", - "react-dom": ">=16.11.0" - } - }, - "node_modules/@rc-component/form": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@rc-component/form/-/form-1.8.1.tgz", - "integrity": "sha512-8O7TB55Fi2mWIGvSnwZjk8jFqVNYyKDAswglwGShcbndxqzKz4cHwNtNaLjZlAeRge9wcB0LL8IWsC/Bl18raQ==", - "license": "MIT", - "dependencies": { - "@rc-component/async-validator": "^5.1.0", - "@rc-component/util": "^1.6.2", - "clsx": "^2.1.1" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/image": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@rc-component/image/-/image-1.9.0.tgz", - "integrity": "sha512-khF7w7xkBH5B1bsBcI1FSUZdkyd1aqpl2eYyILCqCzzQH3XdfehGUaZTnptyaJJfs09/R5hv9jXWyazOMFIClQ==", - "license": "MIT", - "dependencies": { - "@rc-component/motion": "^1.0.0", - "@rc-component/portal": "^2.1.2", - "@rc-component/util": "^1.10.1", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/input": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@rc-component/input/-/input-1.1.2.tgz", - "integrity": "sha512-Q61IMR47piUBudgixJ30CciKIy9b1H95qe7GgEKOmSJVJXvFRWJllJfQry9tif+MX2cWFXWJf/RXz4kaCeq/Fg==", - "license": "MIT", - "dependencies": { - "@rc-component/util": "^1.4.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=16.0.0", - "react-dom": ">=16.0.0" - } - }, - "node_modules/@rc-component/input-number": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@rc-component/input-number/-/input-number-1.6.2.tgz", - "integrity": "sha512-Gjcq7meZlCOiWN1t1xCC+7/s85humHVokTBI7PJgTfoyw5OWF74y3e6P8PHX104g9+b54jsodFIzyaj6p8LI9w==", - "license": "MIT", - "dependencies": { - "@rc-component/mini-decimal": "^1.0.1", - "@rc-component/util": "^1.4.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/mentions": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@rc-component/mentions/-/mentions-1.6.0.tgz", - "integrity": "sha512-KIkQNP6habNuTsLhUv0UGEOwG67tlmE7KNIJoQZZNggEZl5lQJTytFDb69sl5CK3TDdISCTjKP3nGEBKgT61CQ==", - "license": "MIT", - "dependencies": { - "@rc-component/input": "~1.1.0", - "@rc-component/menu": "~1.2.0", - "@rc-component/textarea": "~1.1.0", - "@rc-component/trigger": "^3.0.0", - "@rc-component/util": "^1.3.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/menu": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@rc-component/menu/-/menu-1.2.0.tgz", - "integrity": "sha512-VWwDuhvYHSnTGj4n6bV3ISrLACcPAzdPOq3d0BzkeiM5cve8BEYfvkEhNoM0PLzv51jpcejeyrLXeMVIJ+QJlg==", - "license": "MIT", - "dependencies": { - "@rc-component/motion": "^1.1.4", - "@rc-component/overflow": "^1.0.0", - "@rc-component/trigger": "^3.0.0", - "@rc-component/util": "^1.3.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/mini-decimal": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@rc-component/mini-decimal/-/mini-decimal-1.1.3.tgz", - "integrity": "sha512-bk/FJ09fLf+NLODMAFll6CfYrHPBioTedhW6lxDBuuWucJEqFUd4l/D/5JgIi3dina6sYahB8iuPAZTNz2pMxw==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.18.0" - }, - "engines": { - "node": ">=8.x" - } - }, - "node_modules/@rc-component/motion": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@rc-component/motion/-/motion-1.3.2.tgz", - "integrity": "sha512-itfd+GztzJYAb04Z4RkEub1TbJAfZc2Iuy8p44U44xD1F5+fNYFKI3897ijlbIyfvXkTmMm+KGcjkQQGMHywEQ==", - "license": "MIT", - "dependencies": { - "@rc-component/util": "^1.2.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/mutate-observer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@rc-component/mutate-observer/-/mutate-observer-2.0.1.tgz", - "integrity": "sha512-AyarjoLU5YlxuValRi+w8JRH2Z84TBbFO2RoGWz9d8bSu0FqT8DtugH3xC3BV7mUwlmROFauyWuXFuq4IFbH+w==", - "license": "MIT", - "dependencies": { - "@rc-component/util": "^1.2.0" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/notification": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@rc-component/notification/-/notification-1.2.0.tgz", - "integrity": "sha512-OX3J+zVU7rvoJCikjrfW7qOUp7zlDeFBK2eA3SFbGSkDqo63Sl4Ss8A04kFP+fxHSxMDIS9jYVEZtU1FNCFuBA==", - "license": "MIT", - "dependencies": { - "@rc-component/motion": "^1.1.4", - "@rc-component/util": "^1.2.1", - "clsx": "^2.1.1" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/overflow": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rc-component/overflow/-/overflow-1.0.1.tgz", - "integrity": "sha512-syfmgAABaHCnCDzPwHZ/2tuvIcpOO3jefYZMmfkN+pmo8HKTzsfhS57vxo4ksPdN0By+uWVJhJWNFozNBxi2eA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.11.1", - "@rc-component/resize-observer": "^1.0.1", - "@rc-component/util": "^1.4.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/pagination": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@rc-component/pagination/-/pagination-1.2.0.tgz", - "integrity": "sha512-YcpUFE8dMLfSo6OARJlK6DbHHvrxz7pMGPGmC/caZSJJz6HRKHC1RPP001PRHCvG9Z/veD039uOQmazVuLJzlw==", - "license": "MIT", - "dependencies": { - "@rc-component/util": "^1.3.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/picker": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@rc-component/picker/-/picker-1.9.1.tgz", - "integrity": "sha512-9FBYYsvH3HMLICaPDA/1Th5FLaDkFa7qAtangIdlhKb3ZALaR745e9PsOhheJb6asS4QXc12ffiAcjdkZ4C5/g==", - "license": "MIT", - "dependencies": { - "@rc-component/overflow": "^1.0.0", - "@rc-component/resize-observer": "^1.0.0", - "@rc-component/trigger": "^3.6.15", - "@rc-component/util": "^1.3.0", - "clsx": "^2.1.1" - }, - "engines": { - "node": ">=12.x" - }, - "peerDependencies": { - "date-fns": ">= 2.x", - "dayjs": ">= 1.x", - "luxon": ">= 3.x", - "moment": ">= 2.x", - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - }, - "peerDependenciesMeta": { - "date-fns": { - "optional": true - }, - "dayjs": { - "optional": true - }, - "luxon": { - "optional": true - }, - "moment": { - "optional": true - } - } - }, - "node_modules/@rc-component/portal": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@rc-component/portal/-/portal-2.2.0.tgz", - "integrity": "sha512-oc6FlA+uXCMiwArHsJyHcIkX4q6uKyndrPol2eWX8YPkAnztHOPsFIRtmWG4BMlGE5h7YIRE3NiaJ5VS8Lb1QQ==", - "license": "MIT", - "dependencies": { - "@rc-component/util": "^1.2.1", - "clsx": "^2.1.1" - }, - "engines": { - "node": ">=12.x" - }, - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=18.0.0" - } - }, - "node_modules/@rc-component/progress": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rc-component/progress/-/progress-1.0.2.tgz", - "integrity": "sha512-WZUnH9eGxH1+xodZKqdrHke59uyGZSWgj5HBM5Kwk5BrTMuAORO7VJ2IP5Qbm9aH3n9x3IcesqHHR0NWPBC7fQ==", - "license": "MIT", - "dependencies": { - "@rc-component/util": "^1.2.1", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/qrcode": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@rc-component/qrcode/-/qrcode-1.1.1.tgz", - "integrity": "sha512-LfLGNymzKdUPjXUbRP+xOhIWY4jQ+YMj5MmWAcgcAq1Ij8XP7tRmAXqyuv96XvLUBE/5cA8hLFl9eO1JQMujrA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.24.7" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/rate": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rc-component/rate/-/rate-1.0.1.tgz", - "integrity": "sha512-bkXxeBqDpl5IOC7yL7GcSYjQx9G8H+6kLYQnNZWeBYq2OYIv1MONd6mqKTjnnJYpV0cQIU2z3atdW0j1kttpTw==", - "license": "MIT", - "dependencies": { - "@rc-component/util": "^1.3.0", - "clsx": "^2.1.1" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/resize-observer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@rc-component/resize-observer/-/resize-observer-1.1.2.tgz", - "integrity": "sha512-t/Bb0W8uvL4PYKAB3YcChC+DlHh0Wt5kM7q/J+0qpVEUMLe7Hk5zuvc9km0hMnTFPSx5Z7Wu/fzCLN6erVLE8Q==", - "license": "MIT", - "dependencies": { - "@rc-component/util": "^1.2.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/segmented": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@rc-component/segmented/-/segmented-1.3.0.tgz", - "integrity": "sha512-5J/bJ01mbDnoA6P/FW8SxUvKn+OgUSTZJPzCNnTBntG50tzoP7DydGhqxp7ggZXZls7me3mc2EQDXakU3iTVFg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.11.1", - "@rc-component/motion": "^1.1.4", - "@rc-component/util": "^1.3.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=16.0.0", - "react-dom": ">=16.0.0" - } - }, - "node_modules/@rc-component/select": { - "version": "1.6.15", - "resolved": "https://registry.npmjs.org/@rc-component/select/-/select-1.6.15.tgz", - "integrity": "sha512-SyVCWnqxCQZZcQvQJ/CxSjx2bGma6ds/HtnpkIfZVnt6RoEgbqUmHgD6vrzNarNXwbLXerwVzWwq8F3d1sst7g==", - "license": "MIT", - "dependencies": { - "@rc-component/overflow": "^1.0.0", - "@rc-component/trigger": "^3.0.0", - "@rc-component/util": "^1.3.0", - "@rc-component/virtual-list": "^1.0.1", - "clsx": "^2.1.1" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/@rc-component/slider": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@rc-component/slider/-/slider-1.0.1.tgz", - "integrity": "sha512-uDhEPU1z3WDfCJhaL9jfd2ha/Eqpdfxsn0Zb0Xcq1NGQAman0TWaR37OWp2vVXEOdV2y0njSILTMpTfPV1454g==", - "license": "MIT", - "dependencies": { - "@rc-component/util": "^1.3.0", - "clsx": "^2.1.1" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/steps": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@rc-component/steps/-/steps-1.2.2.tgz", - "integrity": "sha512-/yVIZ00gDYYPHSY0JP+M+s3ZvuXLu2f9rEjQqiUDs7EcYsUYrpJ/1bLj9aI9R7MBR3fu/NGh6RM9u2qGfqp+Nw==", - "license": "MIT", - "dependencies": { - "@rc-component/util": "^1.2.1", - "clsx": "^2.1.1" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/switch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@rc-component/switch/-/switch-1.0.3.tgz", - "integrity": "sha512-Jgi+EbOBquje/XNdofr7xbJQZPYJP+BlPfR0h+WN4zFkdtB2EWqEfvkXJWeipflwjWip0/17rNbxEAqs8hVHfw==", - "license": "MIT", - "dependencies": { - "@rc-component/util": "^1.3.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/table": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@rc-component/table/-/table-1.9.1.tgz", - "integrity": "sha512-FVI5ZS/GdB3BcgexfCYKi3iHhZS3Fr59EtsxORszYGrfpH1eWr33eDNSYkVfLI6tfJ7vftJDd9D5apfFWqkdJg==", - "license": "MIT", - "dependencies": { - "@rc-component/context": "^2.0.1", - "@rc-component/resize-observer": "^1.0.0", - "@rc-component/util": "^1.1.0", - "@rc-component/virtual-list": "^1.0.1", - "clsx": "^2.1.1" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=18.0.0" - } - }, - "node_modules/@rc-component/tabs": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@rc-component/tabs/-/tabs-1.7.0.tgz", - "integrity": "sha512-J48cs2iBi7Ho3nptBxxIqizEliUC+ExE23faspUQKGQ550vaBlv3aGF8Epv/UB1vFWeoJDTW/dNzgIU0Qj5i/w==", - "license": "MIT", - "dependencies": { - "@rc-component/dropdown": "~1.0.0", - "@rc-component/menu": "~1.2.0", - "@rc-component/motion": "^1.1.3", - "@rc-component/resize-observer": "^1.0.0", - "@rc-component/util": "^1.3.0", - "clsx": "^2.1.1" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/textarea": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@rc-component/textarea/-/textarea-1.1.2.tgz", - "integrity": "sha512-9rMUEODWZDMovfScIEHXWlVZuPljZ2pd1LKNjslJVitn4SldEzq5vO1CL3yy3Dnib6zZal2r2DPtjy84VVpF6A==", - "license": "MIT", - "dependencies": { - "@rc-component/input": "~1.1.0", - "@rc-component/resize-observer": "^1.0.0", - "@rc-component/util": "^1.3.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/tooltip": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@rc-component/tooltip/-/tooltip-1.4.0.tgz", - "integrity": "sha512-8Rx5DCctIlLI4raR0I0xHjVTf1aF48+gKCNeAAo5bmF5VoR5YED+A/XEqzXv9KKqrJDRcd3Wndpxh2hyzrTtSg==", - "license": "MIT", - "dependencies": { - "@rc-component/trigger": "^3.7.1", - "@rc-component/util": "^1.3.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=18.0.0" - } - }, - "node_modules/@rc-component/tour": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@rc-component/tour/-/tour-2.3.0.tgz", - "integrity": "sha512-K04K9r32kUC+auBSQfr+Fss4SpSIS9JGe56oq/ALAX0p+i2ylYOI1MgR83yBY7v96eO6ZFXcM/igCQmubps0Ow==", - "license": "MIT", - "dependencies": { - "@rc-component/portal": "^2.2.0", - "@rc-component/trigger": "^3.0.0", - "@rc-component/util": "^1.7.0", - "clsx": "^2.1.1" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/tree": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@rc-component/tree/-/tree-1.2.4.tgz", - "integrity": "sha512-5Gli43+m4R7NhpYYz3Z61I6LOw9yI6CNChxgVtvrO6xB1qML7iE6QMLVMB3+FTjo2yF6uFdAHtqWPECz/zbX5w==", - "license": "MIT", - "dependencies": { - "@rc-component/motion": "^1.0.0", - "@rc-component/util": "^1.8.1", - "@rc-component/virtual-list": "^1.0.1", - "clsx": "^2.1.1" - }, - "engines": { - "node": ">=10.x" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/@rc-component/tree-select": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@rc-component/tree-select/-/tree-select-1.8.0.tgz", - "integrity": "sha512-iYsPq3nuLYvGqdvFAW+l+I9ASRIOVbMXyA8FGZg2lGym/GwkaWeJGzI4eJ7c9IOEhRj0oyfIN4S92Fl3J05mjQ==", - "license": "MIT", - "dependencies": { - "@rc-component/select": "~1.6.0", - "@rc-component/tree": "~1.2.0", - "@rc-component/util": "^1.4.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/@rc-component/trigger": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-3.9.0.tgz", - "integrity": "sha512-X8btpwfrT27AgrZVOz4swclhEHTZcqaHeQMXXBgveagOiakTa36uObXbdwerXffgV8G9dH1fAAE0DHtVQs8EHg==", - "license": "MIT", - "dependencies": { - "@rc-component/motion": "^1.1.4", - "@rc-component/portal": "^2.2.0", - "@rc-component/resize-observer": "^1.1.1", - "@rc-component/util": "^1.2.1", - "clsx": "^2.1.1" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=18.0.0" - } - }, - "node_modules/@rc-component/upload": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rc-component/upload/-/upload-1.1.0.tgz", - "integrity": "sha512-LIBV90mAnUE6VK5N4QvForoxZc4XqEYZimcp7fk+lkE4XwHHyJWxpIXQQwMU8hJM+YwBbsoZkGksL1sISWHQxw==", - "license": "MIT", - "dependencies": { - "@rc-component/util": "^1.3.0", - "clsx": "^2.1.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/util": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@rc-component/util/-/util-1.10.1.tgz", - "integrity": "sha512-q++9S6rUa5Idb/xIBNz6jtvumw5+O5YV5V0g4iK9mn9jWs4oGJheE3ZN1kAnE723AXyaD8v95yeOASmdk8Jnng==", - "license": "MIT", - "dependencies": { - "is-mobile": "^5.0.0", - "react-is": "^18.2.0" - }, - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=18.0.0" - } - }, - "node_modules/@rc-component/virtual-list": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@rc-component/virtual-list/-/virtual-list-1.0.2.tgz", - "integrity": "sha512-uvTol/mH74FYsn5loDGJxo+7kjkO4i+y4j87Re1pxJBs0FaeuMuLRzQRGaXwnMcV1CxpZLi2Z56Rerj2M00fjQ==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.20.0", - "@rc-component/resize-observer": "^1.0.1", - "@rc-component/util": "^1.4.0", - "clsx": "^2.1.1" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.27", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", @@ -2117,70 +1355,6 @@ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, - "node_modules/antd": { - "version": "6.3.7", - "resolved": "https://registry.npmjs.org/antd/-/antd-6.3.7.tgz", - "integrity": "sha512-WTHi4bHVNKpYXLHESzU0Tts7rRNQeL84Bph9dfI3Qw7mHbTulExDcYKNHny5CTXcrBBOpraXbU9miBAwUR5vaw==", - "license": "MIT", - "dependencies": { - "@ant-design/colors": "^8.0.1", - "@ant-design/cssinjs": "^2.1.2", - "@ant-design/cssinjs-utils": "^2.1.2", - "@ant-design/fast-color": "^3.0.1", - "@ant-design/icons": "^6.1.1", - "@ant-design/react-slick": "~2.0.0", - "@babel/runtime": "^7.28.4", - "@rc-component/cascader": "~1.14.0", - "@rc-component/checkbox": "~2.0.0", - "@rc-component/collapse": "~1.2.0", - "@rc-component/color-picker": "~3.1.1", - "@rc-component/dialog": "~1.8.4", - "@rc-component/drawer": "~1.4.2", - "@rc-component/dropdown": "~1.0.2", - "@rc-component/form": "~1.8.1", - "@rc-component/image": "~1.9.0", - "@rc-component/input": "~1.1.2", - "@rc-component/input-number": "~1.6.2", - "@rc-component/mentions": "~1.6.0", - "@rc-component/menu": "~1.2.0", - "@rc-component/motion": "^1.3.2", - "@rc-component/mutate-observer": "^2.0.1", - "@rc-component/notification": "~1.2.0", - "@rc-component/pagination": "~1.2.0", - "@rc-component/picker": "~1.9.1", - "@rc-component/progress": "~1.0.2", - "@rc-component/qrcode": "~1.1.1", - "@rc-component/rate": "~1.0.1", - "@rc-component/resize-observer": "^1.1.2", - "@rc-component/segmented": "~1.3.0", - "@rc-component/select": "~1.6.15", - "@rc-component/slider": "~1.0.1", - "@rc-component/steps": "~1.2.2", - "@rc-component/switch": "~1.0.3", - "@rc-component/table": "~1.9.1", - "@rc-component/tabs": "~1.7.0", - "@rc-component/textarea": "~1.1.2", - "@rc-component/tooltip": "~1.4.0", - "@rc-component/tour": "~2.3.0", - "@rc-component/tree": "~1.2.4", - "@rc-component/tree-select": "~1.8.0", - "@rc-component/trigger": "^3.9.0", - "@rc-component/upload": "~1.1.0", - "@rc-component/util": "^1.10.1", - "clsx": "^2.1.1", - "dayjs": "^1.11.11", - "scroll-into-view-if-needed": "^3.1.0", - "throttle-debounce": "^5.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/ant-design" - }, - "peerDependencies": { - "react": ">=18.0.0", - "react-dom": ">=18.0.0" - } - }, "node_modules/axe-core": { "version": "4.11.2", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.2.tgz", @@ -2259,21 +1433,6 @@ ], "license": "CC-BY-4.0" }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/compute-scroll-into-view": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.1.tgz", - "integrity": "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==", - "license": "MIT" - }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -2298,13 +1457,17 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, "license": "MIT" }, - "node_modules/dayjs": { - "version": "1.11.20", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", - "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", - "license": "MIT" + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", + "engines": { + "node": ">=12" + } }, "node_modules/debug": { "version": "4.4.3", @@ -2324,30 +1487,6 @@ } } }, - "node_modules/echarts": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/echarts/-/echarts-6.0.0.tgz", - "integrity": "sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "2.3.0", - "zrender": "6.0.0" - } - }, - "node_modules/echarts-for-react": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/echarts-for-react/-/echarts-for-react-3.0.6.tgz", - "integrity": "sha512-4zqLgTGWS3JvkQDXjzkR1k1CHRdpd6by0988TWMJgnvDytegWLbeP/VNZmMa+0VJx2eD7Y632bi2JquXDgiGJg==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "size-sensor": "^1.0.1" - }, - "peerDependencies": { - "echarts": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", - "react": "^15.0.0 || >=16.0.0" - } - }, "node_modules/electron-to-chromium": { "version": "1.5.331", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.331.tgz", @@ -2407,12 +1546,6 @@ "node": ">=6" } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT" - }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -2456,12 +1589,6 @@ "node": ">=6.9.0" } }, - "node_modules/is-mobile": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-mobile/-/is-mobile-5.0.0.tgz", - "integrity": "sha512-Tz/yndySvLAEXh+Uk8liFCxOwVH6YutuR74utvOcu7I9Di+DwM0mtdPVZNaVvvBUM2OXxne/NhOs1zAO7riusQ==", - "license": "MIT" - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -2482,15 +1609,6 @@ "node": ">=6" } }, - "node_modules/json2mq": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", - "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==", - "license": "MIT", - "dependencies": { - "string-convert": "^0.2.0" - } - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -2649,12 +1767,6 @@ "react": "^19.2.5" } }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT" - }, "node_modules/react-refresh": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", @@ -2754,15 +1866,6 @@ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, - "node_modules/scroll-into-view-if-needed": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz", - "integrity": "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==", - "license": "MIT", - "dependencies": { - "compute-scroll-into-view": "^3.0.2" - } - }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -2779,12 +1882,6 @@ "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", "license": "MIT" }, - "node_modules/size-sensor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/size-sensor/-/size-sensor-1.0.3.tgz", - "integrity": "sha512-+k9mJ2/rQMiRmQUcjn+qznch260leIXY8r4FyYKKyRBO/s5UoeMAHGkCJyE1R/4wrIhTJONfyloY55SkE7ve3A==", - "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", @@ -2795,27 +1892,6 @@ "node": ">=0.10.0" } }, - "node_modules/string-convert": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", - "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==", - "license": "MIT" - }, - "node_modules/stylis": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.4.0.tgz", - "integrity": "sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==", - "license": "MIT" - }, - "node_modules/throttle-debounce": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz", - "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==", - "license": "MIT", - "engines": { - "node": ">=12.22" - } - }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", @@ -2833,12 +1909,6 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tslib": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", - "license": "0BSD" - }, "node_modules/typescript": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", @@ -2987,15 +2057,6 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true, "license": "ISC" - }, - "node_modules/zrender": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/zrender/-/zrender-6.0.0.tgz", - "integrity": "sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg==", - "license": "BSD-3-Clause", - "dependencies": { - "tslib": "2.3.0" - } } } } diff --git a/src/main/frontend/package.json b/src/main/frontend/package.json index ad2b29f4..f16a702e 100644 --- a/src/main/frontend/package.json +++ b/src/main/frontend/package.json @@ -12,10 +12,8 @@ "test:e2e:report": "playwright show-report" }, "dependencies": { - "@ant-design/icons": "^6.2.1", - "antd": "^6.3.7", - "echarts": "^6.0.0", - "echarts-for-react": "^3.0.2", + "@ossrandom/design-system": "^0.3.0", + "d3-hierarchy": "^3.1.2", "react": "^19.2.5", "react-dom": "^19.2.5", "react-router-dom": "^7.1.5" diff --git a/src/main/frontend/src/components/AppLayout.tsx b/src/main/frontend/src/components/AppLayout.tsx index 8baf8894..eda3718e 100644 --- a/src/main/frontend/src/components/AppLayout.tsx +++ b/src/main/frontend/src/components/AppLayout.tsx @@ -1,45 +1,88 @@ import { Outlet } from 'react-router-dom'; -import { Layout, Switch, Typography, Space } from 'antd'; -import { SunOutlined, MoonOutlined } from '@ant-design/icons'; +import { useState } from 'react'; +import { AppShell, IconButton } from '@ossrandom/design-system'; import { useTheme } from '@/context/ThemeContext'; -const { Header, Content } = Layout; +function SunIcon() { + return ( + + ); +} -export default function AppLayout() { +function MoonIcon() { + return ( + + ); +} + +function CopyIcon({ ok }: { ok: boolean }) { + if (ok) { + return ( + + ); + } + return ( + + ); +} + +function McpUrlPill() { + const [copied, setCopied] = useState(false); + const url = (typeof window !== 'undefined' ? window.location.origin : '') + '/mcp'; + const onCopy = async () => { + try { + await navigator.clipboard.writeText(url); + setCopied(true); + setTimeout(() => setCopied(false), 1200); + } catch { + /* clipboard blocked — silent */ + } + }; + return ( +
+ MCP · {url} + +
+ ); +} + +function Header() { const { isDark, toggle } = useTheme(); + return ( +
+
Code IQ
+
+ + : } + aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'} + variant="ghost" + size="sm" + onClick={toggle} + /> +
+
+ ); +} +export default function AppLayout() { return ( - -
- - Code IQ - - - } - unCheckedChildren={} - /> - -
- + }> +
- - +
+
); } diff --git a/src/main/frontend/src/components/Icons.tsx b/src/main/frontend/src/components/Icons.tsx new file mode 100644 index 00000000..cbfdeab3 --- /dev/null +++ b/src/main/frontend/src/components/Icons.tsx @@ -0,0 +1,27 @@ +import type { CSSProperties } from 'react'; + +const base: CSSProperties = { display: 'inline-block', verticalAlign: '-2px' }; + +function Svg({ d, size = 14 }: { d: string; size?: number }) { + return ( + + ); +} + +export const Icon = { + Nodes: () => , + Branches: () => , + File: () => , + Code: () => , + Api: () => , + Safety: () => , + Appstore: () => , + Build: () => , + Play: () => , + Clock: () => , + Search: () => , + History: () => , +}; diff --git a/src/main/frontend/src/index.css b/src/main/frontend/src/index.css index b895e769..39d1a1b3 100644 --- a/src/main/frontend/src/index.css +++ b/src/main/frontend/src/index.css @@ -2,13 +2,133 @@ body { margin: 0; padding: 0; } -/* Ant Design handles all theming */ - -/* MCP tool list: allow multiline descriptions */ -.mcp-tool-menu .ant-menu-item { - height: auto !important; - line-height: normal !important; - padding-top: 4px !important; - padding-bottom: 4px !important; - white-space: normal !important; + +/* Layout-only — visuals come from design-system tokens. */ +.codeiq-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + padding: 0 16px; + height: 56px; +} + +.codeiq-brand { + color: var(--accent); + font-size: var(--fs-h4); + font-weight: var(--fw-semibold); + letter-spacing: -0.01em; + white-space: nowrap; +} + +.codeiq-content { + padding: 16px; +} + +.codeiq-header-actions { + display: flex; + align-items: center; + gap: 8px; + min-width: 0; +} + +.codeiq-mcp-url { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 4px 8px; + border: 1px solid var(--border-1); + border-radius: 6px; + background: var(--bg-2); + color: var(--fg-2); + font-family: var(--font-mono); + font-size: 12px; + max-width: 360px; + overflow: hidden; +} + +.codeiq-mcp-url > span { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.codeiq-mcp-url > button { + flex: none; + background: transparent; + border: 0; + padding: 2px; + color: var(--fg-3); + cursor: pointer; + border-radius: 4px; +} + +.codeiq-mcp-url > button:hover { + color: var(--fg-1); + background: var(--bg-3); +} + +/* Stats grid — auto-fit so cards flow on mobile. */ +.codeiq-stats-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: 8px; +} + +/* Hide the design-system Treemap's engine badge (renders "canvas"/"webgl" + in a corner — debug affordance, not desired in app chrome). */ +.rcs-treemap-engine-badge { + display: none !important; +} + +.codeiq-breadcrumb { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 4px; + padding: 6px 10px; + border: 1px solid var(--border-1); + border-radius: 6px; + background: var(--bg-1); + font-size: 12px; + color: var(--fg-2); + font-family: var(--font-mono); +} + +.codeiq-breadcrumb button { + background: transparent; + border: 0; + padding: 2px 6px; + border-radius: 4px; + color: inherit; + font-family: inherit; + font-size: inherit; + cursor: pointer; +} + +.codeiq-breadcrumb button:hover:not(:disabled) { + background: var(--bg-3); + color: var(--fg-1); +} + +.codeiq-breadcrumb button:disabled { + cursor: default; + opacity: 0.7; +} + +.codeiq-breadcrumb-sep { + opacity: 0.4; + user-select: none; +} + +@media (max-width: 600px) { + .codeiq-header { + padding: 0 12px; + } + .codeiq-content { + padding: 12px; + } + .codeiq-mcp-url { + display: none; + } } diff --git a/src/main/frontend/src/main.tsx b/src/main/frontend/src/main.tsx index 8b1356b0..4ab5648f 100644 --- a/src/main/frontend/src/main.tsx +++ b/src/main/frontend/src/main.tsx @@ -1,91 +1,19 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import { BrowserRouter } from 'react-router-dom'; -import { ConfigProvider, theme, App as AntApp } from 'antd'; +import { ToastRegion } from '@ossrandom/design-system'; import AppRoot from './App'; -import { ThemeProvider, useTheme } from './context/ThemeContext'; +import { ThemeProvider } from './context/ThemeContext'; +import '@ossrandom/design-system/styles.css'; import './index.css'; -function ThemedApp() { - const { isDark } = useTheme(); - return ( - - - - - - - - ); -} - ReactDOM.createRoot(document.getElementById('root')!).render( - + + + + ); diff --git a/src/main/frontend/src/pages/CodebaseMap.tsx b/src/main/frontend/src/pages/CodebaseMap.tsx deleted file mode 100644 index 43a3706f..00000000 --- a/src/main/frontend/src/pages/CodebaseMap.tsx +++ /dev/null @@ -1,294 +0,0 @@ -import { useState, useMemo, useCallback } from 'react'; -import { Typography, Spin, Alert, Drawer } from 'antd'; -import ReactECharts from 'echarts-for-react'; -import { useApi } from '@/hooks/useApi'; -import { api } from '@/lib/api'; -import { useTheme } from '@/context/ThemeContext'; -import type { FileTreeResponse, FileTreeNode } from '@/types/api'; - -const LANG_COLORS: Record = { - java: '#b07219', python: '#3572A5', typescript: '#3178c6', javascript: '#f1e05a', - go: '#00ADD8', csharp: '#178600', rust: '#dea584', kotlin: '#A97BFF', - yaml: '#cb171e', json: '#555', ruby: '#701516', scala: '#c22d40', - cpp: '#f34b7d', shell: '#89e051', markdown: '#083fa1', html: '#e34c26', - css: '#563d7c', sql: '#e38c00', proto: '#60a0b0', dockerfile: '#384d54', - other: '#888', -}; - -const EXT_TO_LANG: Record = { - java: 'java', py: 'python', ts: 'typescript', tsx: 'typescript', - js: 'javascript', jsx: 'javascript', go: 'go', cs: 'csharp', - rs: 'rust', kt: 'kotlin', yml: 'yaml', yaml: 'yaml', - json: 'json', rb: 'ruby', scala: 'scala', cpp: 'cpp', - h: 'cpp', sh: 'shell', md: 'markdown', html: 'html', - css: 'css', sql: 'sql', proto: 'proto', -}; - -interface EChartsTreeNode { - name: string; - value?: number; - children?: EChartsTreeNode[]; - itemStyle?: { color: string }; -} - -function inferLang(name: string): string { - const ext = name.split('.').pop()?.toLowerCase() ?? ''; - return EXT_TO_LANG[ext] ?? 'other'; -} - -function dominantLang(nodes: FileTreeNode[]): string { - const counts: Record = {}; - function walk(items: FileTreeNode[]) { - for (const item of items) { - if (item.type === 'file') { - const lang = inferLang(item.name); - counts[lang] = (counts[lang] ?? 0) + (item.nodeCount || 1); - } - if (item.children) walk(item.children); - } - } - walk(nodes); - return Object.entries(counts).sort((a, b) => b[1] - a[1])[0]?.[0] ?? 'other'; -} - -function collapseTree(nodes: FileTreeNode[]): FileTreeNode[] { - return nodes.map(n => { - if (n.type !== 'directory' || !n.children || n.children.length === 0) return n; - - let current = n; - let collapsedName = n.name; - while ( - current.type === 'directory' && - current.children && - current.children.length === 1 && - current.children[0].type === 'directory' && - current.children[0].children && - current.children[0].children.length > 0 - ) { - current = current.children[0]; - collapsedName += '/' + current.name; - } - - const collapsedChildren = collapseTree(current.children ?? []); - return { ...current, name: collapsedName, children: collapsedChildren, nodeCount: n.nodeCount }; - }); -} - -function toEChartsNodes(nodes: FileTreeNode[]): EChartsTreeNode[] { - const result: EChartsTreeNode[] = []; - for (const n of nodes) { - if (n.nodeCount <= 0 && (!n.children || n.children.length === 0)) continue; - - if (n.type === 'directory' && n.children && n.children.length > 0) { - const children = toEChartsNodes(n.children); - if (children.length === 0) continue; - const lang = dominantLang(n.children); - result.push({ - name: n.name, - children, - itemStyle: { color: LANG_COLORS[lang] ?? '#666' }, - }); - } else { - const lang = inferLang(n.name); - result.push({ - name: n.name, - value: Math.max(n.nodeCount, 1), - itemStyle: { color: LANG_COLORS[lang] ?? '#666' }, - }); - } - } - return result; -} - -function fileTreeToECharts(nodes: FileTreeNode[]): EChartsTreeNode[] { - return toEChartsNodes(collapseTree(nodes)); -} - -export default function CodebaseMap() { - const { isDark } = useTheme(); - const [fileDrawer, setFileDrawer] = useState<{ path: string; content: string } | null>(null); - const [fileLoading, setFileLoading] = useState(false); - - const { data: treeData, loading, error } = useApi( - () => api.getFileTree(), [] - ); - - const tree = treeData?.tree ?? []; - const totalFiles = treeData?.total_files ?? 0; - const treemapData = useMemo(() => fileTreeToECharts(tree), [tree]); - - // On click: if leaf node (no children), open file in drawer - const onClickNode = useCallback(async (params: { - data?: { children?: unknown[] }; - treePathInfo?: Array<{ name: string }>; - }) => { - if (params.data?.children && (params.data.children as unknown[]).length > 0) return; - const pathParts = params.treePathInfo?.map(p => p.name).filter(Boolean) ?? []; - if (pathParts.length === 0) return; - const filePath = pathParts.join('/'); - setFileLoading(true); - try { - const content = await api.readFile(filePath); - setFileDrawer({ path: filePath, content }); - } catch { - setFileDrawer({ path: filePath, content: '// Could not load file' }); - } finally { - setFileLoading(false); - } - }, []); - - const onEvents = useMemo(() => ({ - click: onClickNode, - }), [onClickNode]); - - const chartOption = useMemo(() => ({ - tooltip: { - formatter: (info: { name: string; value: number; treePathInfo?: Array<{ name: string }> }) => { - const path = info.treePathInfo?.map(p => p.name).filter(Boolean).join('/') ?? info.name; - return `${path}
Nodes: ${(info.value ?? 0).toLocaleString()}`; - }, - }, - series: [{ - type: 'treemap', - data: treemapData, - top: 0, - left: 0, - right: 0, - bottom: 0, - width: '100%', - height: '100%', - leafDepth: 2, - drillDownIcon: '▶ ', - roam: false, - nodeClick: 'zoomToNode', - breadcrumb: { - show: true, - bottom: 8, - left: 'center', - height: 28, - itemStyle: { - color: isDark ? '#1f1f1f' : '#fff', - borderColor: isDark ? '#444' : '#bbb', - borderWidth: 1, - shadowBlur: 3, - shadowColor: isDark ? 'rgba(0,0,0,0.5)' : 'rgba(0,0,0,0.15)', - }, - textStyle: { - color: isDark ? '#e0e0e0' : '#333', - fontSize: 14, - fontWeight: 'bold' as const, - }, - }, - levels: [ - { - itemStyle: { - borderColor: isDark ? '#303030' : '#bbb', - borderWidth: 3, - gapWidth: 3, - }, - upperLabel: { - show: true, - height: 30, - color: isDark ? '#e0e0e0' : '#333', - fontSize: 14, - fontWeight: 'bold' as const, - }, - }, - { - itemStyle: { - borderColor: isDark ? '#404040' : '#ccc', - borderWidth: 2, - gapWidth: 2, - }, - upperLabel: { - show: true, - height: 24, - fontSize: 12, - color: isDark ? '#ccc' : '#555', - }, - }, - { - itemStyle: { - borderColor: isDark ? '#4a4a4a' : '#ddd', - borderWidth: 1, - gapWidth: 1, - }, - label: { show: true, fontSize: 11 }, - }, - ], - label: { - show: true, - formatter: '{b}', - fontSize: 12, - color: isDark ? '#ddd' : '#333', - }, - }], - }), [treemapData, isDark]); - - if (loading) { - return
; - } - - if (error) { - return ; - } - - return ( -
- {treemapData.length > 0 ? ( - <> -
- {totalFiles.toLocaleString()} files -
- - - ) : ( -
- No file data available. Run index + enrich first. -
- )} - - setFileDrawer(null)} - styles={{ body: { padding: 0 } }} - > - {fileLoading ? ( -
- ) : ( -
-            {fileDrawer?.content}
-          
- )} -
-
- ); -} diff --git a/src/main/frontend/src/pages/Dashboard.tsx b/src/main/frontend/src/pages/Dashboard.tsx index 13d67f66..6ce8829c 100644 --- a/src/main/frontend/src/pages/Dashboard.tsx +++ b/src/main/frontend/src/pages/Dashboard.tsx @@ -1,23 +1,15 @@ -import { useState, useMemo, useCallback } from 'react'; +import { useState, useMemo, useCallback, useEffect, Fragment } from 'react'; import { - Card, Col, Row, Statistic, Spin, Alert, Typography, Modal, Table, Drawer, Menu, - Form, Input, InputNumber, Select, Button, Space, Tag, -} from 'antd'; -import { - NodeIndexOutlined, BranchesOutlined, FileOutlined, CodeOutlined, - ApiOutlined, SafetyOutlined, AppstoreOutlined, BuildOutlined, - PlayCircleOutlined, ClockCircleOutlined, SearchOutlined, - BarChartOutlined, ThunderboltOutlined, SafetyCertificateOutlined, - HistoryOutlined, -} from '@ant-design/icons'; -import ReactECharts from 'echarts-for-react'; + Card, Spin, Alert, Modal, Drawer, Stat, Table, ScrollDiv, Space, +} from '@ossrandom/design-system'; +import { Treemap } from '@ossrandom/design-system/charts'; +import type { TreemapNode } from '@ossrandom/design-system/charts'; import { useApi } from '@/hooks/useApi'; import { api } from '@/lib/api'; -import { useTheme } from '@/context/ThemeContext'; -import { TOOLS, CATEGORIES, toolsByCategory, type McpTool } from '@/lib/mcp-tools'; import type { StatsResponse, FileTreeResponse, FileTreeNode } from '@/types/api'; +import { Icon } from '@/components/Icons'; -// ── Stats ── +// ── Stats helpers ── function flattenToRecord(val: unknown): Record { if (!val || typeof val !== 'object') return {}; @@ -35,39 +27,62 @@ function sumValues(rec: Record): number { return Object.values(rec).reduce((a, b) => a + b, 0); } +function isComputedStats(s: StatsResponse): s is StatsResponse & { + graph: { nodes: number; edges: number; files: number }; + languages: Record; frameworks: Record; + connections?: unknown; auth?: unknown; architecture?: unknown; +} { return 'graph' in s; } + +interface BreakdownRow { key: string; name: string; count: number } + function StatCard({ title, value, icon, detail, detailTitle }: { title: string; value: number | string; icon: React.ReactNode; detail?: Record; detailTitle?: string; }) { const [open, setOpen] = useState(false); const hasDetail = detail && Object.keys(detail).length > 0 && sumValues(detail) > 0; - const tableData = hasDetail + const tableData: BreakdownRow[] = hasDetail ? Object.entries(detail!).sort((a, b) => b[1] - a[1]).map(([name, count]) => ({ key: name, name, count })) : []; + + const cardEl = ( + + {icon}{title}} + value={value} + /> + + ); + return ( <> - hasDetail && setOpen(true)} - style={{ cursor: hasDetail ? 'pointer' : 'default', height: '100%' }} size="small"> - - - setOpen(false)} footer={null} width={600}> - 15 ? { pageSize: 15 } : false} size="small" - columns={[ - { title: 'Name', dataIndex: 'name', key: 'name' }, - { title: 'Count', dataIndex: 'count', key: 'count', align: 'right' as const, render: (v: number) => v.toLocaleString() }, - ]} /> + {hasDetail ? ( +
setOpen(true)} + onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setOpen(true); } }} + style={{ cursor: 'pointer', height: '100%' }}> + {cardEl} +
+ ) : cardEl} + setOpen(false)} title={detailTitle ?? title} size="md"> + + + rowKey="key" + density="compact" + data={tableData} + columns={[ + { key: 'name', title: 'Name', dataKey: 'name' }, + { key: 'count', title: 'Count', dataKey: 'count', align: 'right', + render: (v) => (typeof v === 'number' ? v.toLocaleString() : String(v)) }, + ]} + /> + ); } -function isComputedStats(s: StatsResponse): s is StatsResponse & { - graph: { nodes: number; edges: number; files: number }; - languages: Record; frameworks: Record; - connections?: unknown; auth?: unknown; architecture?: unknown; -} { return 'graph' in s; } - -// ── Treemap ── +// ── Treemap data ── const LANG_COLORS: Record = { java: '#b07219', python: '#3572A5', typescript: '#3178c6', javascript: '#f1e05a', @@ -86,8 +101,6 @@ const EXT_TO_LANG: Record = { css: 'css', sql: 'sql', proto: 'proto', }; -interface EChartsTreeNode { name: string; value?: number; children?: EChartsTreeNode[]; itemStyle?: { color: string } } - function inferLang(name: string): string { return EXT_TO_LANG[name.split('.').pop()?.toLowerCase() ?? ''] ?? 'other'; } @@ -115,47 +128,56 @@ function collapseTree(nodes: FileTreeNode[]): FileTreeNode[] { }); } -function toEChartsNodes(nodes: FileTreeNode[]): EChartsTreeNode[] { - const result: EChartsTreeNode[] = []; - for (const n of nodes) { +function buildTreemapTree( + nodes: FileTreeNode[], + parentPath: string, + pathMap: WeakMap, +): TreemapNode[] { + // Sort children by name so the treemap layout is stable across page + // loads regardless of API result ordering. d3-hierarchy's squarified + // layout is deterministic in input order; so deterministic input ⇒ + // deterministic visual. + const sorted = [...nodes].sort((a, b) => a.name.localeCompare(b.name)); + const out: TreemapNode[] = []; + for (const n of sorted) { + const fullPath = parentPath ? `${parentPath}/${n.name}` : n.name; if (n.nodeCount <= 0 && (!n.children || n.children.length === 0)) continue; if (n.type === 'directory' && n.children && n.children.length > 0) { - const children = toEChartsNodes(n.children); + const children = buildTreemapTree(n.children, fullPath, pathMap); if (children.length === 0) continue; - result.push({ name: n.name, children, itemStyle: { color: LANG_COLORS[dominantLang(n.children)] ?? '#666' } }); + const node: TreemapNode = { + name: n.name, + children, + color: LANG_COLORS[dominantLang(n.children)] ?? '#666', + }; + pathMap.set(node, fullPath); + out.push(node); } else { - result.push({ name: n.name, value: Math.max(n.nodeCount, 1), itemStyle: { color: LANG_COLORS[inferLang(n.name)] ?? '#666' } }); + const node: TreemapNode = { + name: n.name, + value: Math.max(n.nodeCount, 1), + color: LANG_COLORS[inferLang(n.name)] ?? '#666', + }; + pathMap.set(node, fullPath); + out.push(node); } } - return result; + return out; } -// ── MCP ── - -const CATEGORY_ICONS: Record = { - stats: , query: , topology: , - flow: , analysis: , security: , - code: , -}; - -function resolveUrl(tool: McpTool, params: Record): string { - return typeof tool.url === 'function' ? tool.url(params) : tool.url; -} - -function countResults(json: unknown): number | null { - if (Array.isArray(json)) return json.length; - if (json && typeof json === 'object') { - const obj = json as Record; - for (const k of ['nodes', 'services', 'kinds']) if (Array.isArray(obj[k])) return (obj[k] as unknown[]).length; - } - return null; +function useViewportHeight(offset: number): number { + const [h, setH] = useState(() => (typeof window === 'undefined' ? 600 : window.innerHeight - offset)); + useEffect(() => { + const onResize = () => setH(window.innerHeight - offset); + window.addEventListener('resize', onResize); + return () => window.removeEventListener('resize', onResize); + }, [offset]); + return Math.max(360, h); } // ── Main ── export default function Dashboard() { - const { isDark } = useTheme(); - // Stats const { data: stats, loading: statsLoading, error: statsError } = useApi(() => api.getStats(), []); const { data: kinds } = useApi(() => api.getKinds(), []); @@ -182,272 +204,152 @@ export default function Dashboard() { if (g?.edges_by_kind && typeof g.edges_by_kind === 'object') Object.assign(edgeKindBreakdown, flattenToRecord(g.edges_by_kind)); } + // Treemap height — header(56) + content padding(32) + stats row(~110) + + // breadcrumb(38) + gaps(24) + const treemapHeight = useViewportHeight(56 + 32 + 110 + 38 + 24); + // Treemap const { data: treeData, loading: treeLoading } = useApi(() => api.getFileTree(), []); - const treemapData = useMemo(() => toEChartsNodes(collapseTree(treeData?.tree ?? [])), [treeData]); + const { treemapRoot, pathMap } = useMemo(() => { + const map = new WeakMap(); + const children = buildTreemapTree(collapseTree(treeData?.tree ?? []), '', map); + const root: TreemapNode = { name: 'root', children }; + return { treemapRoot: root, pathMap: map }; + }, [treeData]); + + // Drill state — names of the directories we've drilled into, in order. + // Empty = full tree. Single-click on a directory pushes; clicking a + // breadcrumb segment slices back to that depth. + const [focusPath, setFocusPath] = useState([]); + + // Reset focus when the underlying tree changes (e.g., re-fetch after enrich). + useEffect(() => { setFocusPath([]); }, [treemapRoot]); + + // Walk treemapRoot along focusPath. Falls back to root if any segment is + // missing (defensive — shouldn't happen since focusPath only ever holds + // names we just clicked). + const focusedRoot = useMemo(() => { + let cur: TreemapNode = treemapRoot; + for (const name of focusPath) { + const child = cur.children?.find(c => c.name === name); + if (!child) return treemapRoot; + cur = child; + } + return cur; + }, [treemapRoot, focusPath]); - // File viewer — dblclick only (single click = treemap navigate) + // File viewer const [fileDrawer, setFileDrawer] = useState<{ path: string; content: string } | null>(null); const [fileLoading, setFileLoading] = useState(false); - const onDblClickNode = useCallback(async (params: { data?: { children?: unknown[] }; treePathInfo?: Array<{ name: string }> }) => { - if (params.data?.children && (params.data.children as unknown[]).length > 0) return; - const pathParts = params.treePathInfo?.map(p => p.name).filter(Boolean) ?? []; - if (pathParts.length === 0) return; - const filePath = pathParts.join('/'); + const onTreemapNodeClick = useCallback(async (node: TreemapNode) => { + // Directory — drill down one level. + if (node.children && node.children.length > 0) { + setFocusPath(prev => [...prev, node.name]); + return; + } + // Leaf — open file in drawer. + const filePath = pathMap.get(node); + if (!filePath) return; setFileLoading(true); + setFileDrawer({ path: filePath, content: '' }); try { setFileDrawer({ path: filePath, content: await api.readFile(filePath) }); } catch { setFileDrawer({ path: filePath, content: '// Could not load file' }); } finally { setFileLoading(false); } - }, []); - const treemapEvents = useMemo(() => ({ dblclick: onDblClickNode }), [onDblClickNode]); - - const chartOption = useMemo(() => ({ - tooltip: { - formatter: (info: { name: string; value: number; treePathInfo?: Array<{ name: string }> }) => { - const path = info.treePathInfo?.map(p => p.name).filter(Boolean).join('/') ?? info.name; - return `${path}
Nodes: ${(info.value ?? 0).toLocaleString()}
Double-click to view source`; - }, - }, - series: [{ - type: 'treemap', data: treemapData, top: 0, left: 0, right: 0, bottom: 0, width: '100%', height: '100%', - leafDepth: 2, drillDownIcon: '▶ ', roam: false, nodeClick: 'zoomToNode', - breadcrumb: { - show: true, bottom: 8, left: 'center', height: 28, - itemStyle: { - color: isDark ? '#000' : '#1a1a1a', - borderColor: isDark ? '#555' : '#333', - borderWidth: 1, - shadowBlur: 6, - shadowColor: 'rgba(0,0,0,0.4)', - borderRadius: 4, - }, - textStyle: { color: '#fff', fontSize: 13, fontWeight: 'bold' as const }, - emphasis: { - itemStyle: { color: isDark ? '#1a1a1a' : '#333' }, - textStyle: { color: '#fff' }, - }, - }, - levels: [ - { itemStyle: { borderColor: isDark ? '#303030' : '#bbb', borderWidth: 3, gapWidth: 3 }, - upperLabel: { show: true, height: 28, color: isDark ? '#e0e0e0' : '#333', fontSize: 13, fontWeight: 'bold' as const } }, - { itemStyle: { borderColor: isDark ? '#404040' : '#ccc', borderWidth: 2, gapWidth: 2 }, - upperLabel: { show: true, height: 22, fontSize: 11, color: isDark ? '#ccc' : '#555' } }, - { itemStyle: { borderColor: isDark ? '#4a4a4a' : '#ddd', borderWidth: 1, gapWidth: 1 }, label: { show: true, fontSize: 10 } }, - ], - label: { show: true, formatter: '{b}', fontSize: 11, color: isDark ? '#ddd' : '#333' }, - }], - }), [treemapData, isDark]); - - // MCP Console - const [selectedTool, setSelectedTool] = useState(TOOLS[0] ?? null); - const [toolModalOpen, setToolModalOpen] = useState(false); - const [mcpResponse, setMcpResponse] = useState(''); - const [mcpStatus, setMcpStatus] = useState(null); - const [mcpDuration, setMcpDuration] = useState(null); - const [executing, setExecuting] = useState(false); - const [mcpResultCount, setMcpResultCount] = useState(null); - const [responseModalOpen, setResponseModalOpen] = useState(false); - const [history, setHistory] = useState>([]); - const [paletteQuery, setPaletteQuery] = useState(''); - const [form] = Form.useForm(); - const grouped = toolsByCategory(); - - - const selectTool = useCallback((tool: McpTool) => { - setSelectedTool(tool); - const defaults: Record = {}; - tool.params.forEach(p => { if (p.default !== undefined) defaults[p.name] = p.default; }); - form.setFieldsValue(defaults); - }, [form]); + }, [pathMap]); - const execute = useCallback(async () => { - if (!selectedTool) return; - const values = form.getFieldsValue(); - const params: Record = {}; - for (const [k, v] of Object.entries(values)) { if (v !== undefined && v !== null && v !== '') params[k] = String(v); } - if (selectedTool.params.filter(p => p.required && !params[p.name]?.trim()).length) { form.validateFields(); return; } - setExecuting(true); - const start = performance.now(); - try { - const res = await fetch(resolveUrl(selectedTool, params), { - method: selectedTool.method ?? 'GET', - ...(selectedTool.method === 'POST' ? { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(params) } : {}), - }); - const elapsed = Math.round(performance.now() - start); - setMcpStatus(res.status); setMcpDuration(elapsed); - const ct = res.headers.get('content-type') ?? ''; - let text: string; - if (ct.includes('json')) { const json = await res.json(); text = JSON.stringify(json, null, 2); setMcpResultCount(countResults(json)); } - else { text = await res.text(); setMcpResultCount(null); } - setMcpResponse(text); setResponseModalOpen(true); - setHistory(prev => [{ toolName: selectedTool.name, status: res.status, duration: elapsed, response: text }, ...prev.slice(0, 19)]); - } catch (err) { - const elapsed = Math.round(performance.now() - start); - setMcpStatus(0); setMcpDuration(elapsed); - const text = JSON.stringify({ error: err instanceof Error ? err.message : String(err) }, null, 2); - setMcpResponse(text); setMcpResultCount(null); setResponseModalOpen(true); - setHistory(prev => [{ toolName: selectedTool.name, status: 0, duration: elapsed, response: text }, ...prev.slice(0, 19)]); - } finally { setExecuting(false); } - }, [selectedTool, form]); - - const q = paletteQuery.toLowerCase().trim(); - const filteredMenuItems = CATEGORIES.map(cat => { - const tools = (grouped[cat.id] ?? []).filter(t => !q || t.name.includes(q) || t.description.toLowerCase().includes(q)); - return { - key: cat.id, icon: CATEGORY_ICONS[cat.id] ?? , label: cat.label, - children: tools.map(tool => ({ - key: tool.name, - label: ( -
-
{tool.name}
-
{tool.description}
-
- ), - })), - }; - }).filter(cat => cat.children.length > 0); - - if (statsLoading || treeLoading) return
; - if (statsError) return ; + if (statsLoading || treeLoading) { + return
; + } + if (statsError) { + return {statsError}; + } return ( -
- {/* Stats row */} - +
+
{[ - { t: 'Nodes', v: nodeCount.toLocaleString(), i: , d: nodeKindBreakdown, dt: 'Nodes by Kind' }, - { t: 'Edges', v: edgeCount.toLocaleString(), i: , d: edgeKindBreakdown, dt: 'Edges by Kind' }, - { t: 'Files', v: fileCount.toLocaleString(), i: }, - { t: 'Languages', v: Object.keys(languages).length, i: , d: languages, dt: 'Languages' }, - { t: 'Frameworks', v: Object.keys(frameworks).length, i: , d: frameworks, dt: 'Frameworks' }, - { t: 'Connections', v: sumValues(connections), i: , d: connections, dt: 'Connections' }, - { t: 'Security', v: sumValues(auth), i: , d: auth, dt: 'Auth Patterns' }, - { t: 'Code Structure', v: sumValues(architecture), i: , d: architecture, dt: 'Code Structure' }, + { t: 'Nodes', v: nodeCount.toLocaleString(), i: , d: nodeKindBreakdown, dt: 'Nodes by Kind' }, + { t: 'Edges', v: edgeCount.toLocaleString(), i: , d: edgeKindBreakdown, dt: 'Edges by Kind' }, + { t: 'Files', v: fileCount.toLocaleString(), i: }, + { t: 'Languages', v: Object.keys(languages).length, i: , d: languages, dt: 'Languages' }, + { t: 'Frameworks', v: Object.keys(frameworks).length, i: , d: frameworks, dt: 'Frameworks' }, + { t: 'Connections', v: sumValues(connections), i: , d: connections, dt: 'Connections' }, + { t: 'Security', v: sumValues(auth), i: , d: auth, dt: 'Auth Patterns' }, + { t: 'Code Structure', v: sumValues(architecture), i: , d: architecture, dt: 'Code Structure' }, ].map(s => ( -
- - + ))} - - - {/* Main area: Treemap (left) + MCP Console (right) */} -
- {/* Treemap */} -
- {treemapData.length > 0 ? ( - - ) : ( -
- No file data. Run index + enrich first. -
- )} -
- - {/* MCP Tools — 20% */} -
-
- MCP Tools - } - allowClear value={paletteQuery} onChange={e => setPaletteQuery(e.target.value)} style={{ marginTop: 6 }} /> -
-
- c.id) : ['stats']} - items={filteredMenuItems} - onClick={({ key }: { key: string }) => { - const t = TOOLS.find(t => t.name === key); - if (t) { selectTool(t); setToolModalOpen(true); } - }} - style={{ borderRight: 'none', fontSize: 11 }} /> -
-
- {/* MCP Tool Form Modal */} - - {selectedTool.name} - {selectedTool.method ?? 'GET'} - - ) : 'Tool'} - open={toolModalOpen} - onCancel={() => setToolModalOpen(false)} - footer={null} - width={500} - > - {selectedTool && ( - <> - {selectedTool.description} - {selectedTool.params.length > 0 ? ( -
{ execute(); setToolModalOpen(false); }} size="small"> - {selectedTool.params.map(param => ( - {param.name}{param.required && required}} - rules={param.required ? [{ required: true, message: `${param.name} is required` }] : []} - tooltip={param.description}> - {param.options ? ( - - ) : ( - { execute(); setToolModalOpen(false); }} /> - )} - - ))} - - - ) : ( - - )} +
+ + {focusPath.map((seg, i) => ( + + / + + + ))} +
- {history.length > 0 && ( -
- Recent - {history.slice(0, 5).map((entry, i) => ( -
{ setMcpResponse(entry.response); setMcpStatus(entry.status); setMcpDuration(entry.duration); setResponseModalOpen(true); }} - style={{ padding: '3px 0', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 6, fontSize: 11 }}> - = 200 && entry.status < 300 ? 'green' : 'red'} style={{ fontSize: 10 }}>{entry.status} - {entry.toolName} - {entry.duration}ms -
- ))} -
- )} - +
+ {focusedRoot.children && focusedRoot.children.length > 0 ? ( + v.toLocaleString()} + /> + ) : ( + +
+ {treemapRoot.children && treemapRoot.children.length > 0 + ? 'This folder is empty. Use the breadcrumb above to go back.' + : 'No file data. Run index + enrich first.'} +
+
)} - - - {/* MCP Response Modal */} - - Response - {mcpStatus !== null && = 200 && mcpStatus < 300 ? 'green' : mcpStatus >= 400 ? 'red' : 'orange'}>{mcpStatus}} - {mcpDuration !== null && {mcpDuration}ms} - {mcpResultCount !== null && {mcpResultCount} results} - - } open={responseModalOpen} onCancel={() => setResponseModalOpen(false)} footer={null} width={700}> -
{mcpResponse}
-
+
- {/* File viewer Drawer (double-click on leaf file) */} - setFileDrawer(null)} styles={{ body: { padding: 0 } }}> - {fileLoading ?
: ( -
{fileDrawer?.content}
+ setFileDrawer(null)} + placement="right" + width="60vw" + title={fileDrawer?.path} + > + {fileLoading ? ( +
+ ) : ( +
+            {fileDrawer?.content}
+          
)}
- ); } diff --git a/src/main/frontend/src/pages/Explorer.tsx b/src/main/frontend/src/pages/Explorer.tsx deleted file mode 100644 index a6f5d33d..00000000 --- a/src/main/frontend/src/pages/Explorer.tsx +++ /dev/null @@ -1,354 +0,0 @@ -import { useState, useCallback, useEffect } from 'react'; -import { useParams, useNavigate } from 'react-router-dom'; -import { Tabs, Table, Tag, Input, Drawer, Descriptions, Spin, Alert, Typography, Space, List } from 'antd'; -import type { ColumnsType } from 'antd/es/table'; -import { useApi } from '@/hooks/useApi'; -import { api } from '@/lib/api'; -import type { KindsResponse, NodeResponse, NodesListResponse, SearchResult } from '@/types/api'; - -const KIND_COLORS: Record = { - endpoint: 'green', entity: 'blue', class: 'purple', method: 'cyan', - module: 'orange', guard: 'red', config_key: 'gold', infra_resource: 'volcano', - component: 'geekblue', service: 'magenta', interface: 'lime', function: 'cyan', - enum: 'gold', field: 'default', route: 'green', middleware: 'orange', - producer: 'volcano', consumer: 'blue', topic: 'purple', schema: 'geekblue', -}; - -export default function Explorer() { - const { kind: urlKind } = useParams<{ kind?: string }>(); - const navigate = useNavigate(); - const [activeKind, setActiveKind] = useState(urlKind ?? ''); - const [page, setPage] = useState(1); - const [pageSize, setPageSize] = useState(50); - const [searchQuery, setSearchQuery] = useState(''); - const [searchResults, setSearchResults] = useState(null); - const [searchLoading, setSearchLoading] = useState(false); - const [drawerOpen, setDrawerOpen] = useState(false); - const [selectedNode, setSelectedNode] = useState(null); - const [detailLoading, setDetailLoading] = useState(false); - const [neighbors, setNeighbors] = useState<{ incoming: Array<{ edge: { kind: string }; node: NodeResponse }>; outgoing: Array<{ edge: { kind: string }; node: NodeResponse }> } | null>(null); - - const { data: kinds, loading: kindsLoading } = useApi(() => api.getKinds(), []); - - const { data: nodesData, loading: nodesLoading } = useApi( - () => activeKind - ? api.getNodesByKind(activeKind, pageSize, (page - 1) * pageSize) - : api.getNodes(undefined, undefined, pageSize, (page - 1) * pageSize), - [activeKind, page, pageSize] - ); - - // Sync URL with active kind - useEffect(() => { - if (urlKind && urlKind !== activeKind) { - setActiveKind(urlKind); - setPage(1); - } - }, [urlKind]); - - const handleKindChange = useCallback((kind: string) => { - setActiveKind(kind); - setPage(1); - setSearchResults(null); - setSearchQuery(''); - navigate(kind ? `/explorer/${kind}` : '/explorer', { replace: true }); - }, [navigate]); - - const handleSearch = useCallback(async (value: string) => { - if (!value.trim()) { - setSearchResults(null); - return; - } - setSearchLoading(true); - try { - const results = await api.search(value, 50); - setSearchResults(results); - } catch { - setSearchResults([]); - } finally { - setSearchLoading(false); - } - }, []); - - const openDetail = useCallback(async (nodeId: string) => { - setDrawerOpen(true); - setDetailLoading(true); - setNeighbors(null); - try { - const [detail, nbrs] = await Promise.all([ - api.getNodeDetail(nodeId), - api.getNodeNeighbors(nodeId).catch(() => null), - ]); - setSelectedNode(detail); - if (nbrs && typeof nbrs === 'object') { - setNeighbors(nbrs as typeof neighbors); - } - } catch { - setSelectedNode(null); - } finally { - setDetailLoading(false); - } - }, []); - - const columns: ColumnsType = [ - { - title: 'Label', - dataIndex: 'label', - key: 'label', - ellipsis: true, - render: (text: string, record: NodeResponse) => ( - openDetail(record.id)}>{text} - ), - }, - { - title: 'Kind', - dataIndex: 'kind', - key: 'kind', - width: 130, - render: (kind: string) => {kind}, - }, - { - title: 'Module', - dataIndex: 'module', - key: 'module', - width: 180, - ellipsis: true, - }, - { - title: 'File Path', - dataIndex: 'file_path', - key: 'file_path', - ellipsis: true, - width: 300, - }, - { - title: 'Layer', - dataIndex: 'layer', - key: 'layer', - width: 100, - render: (layer: string) => layer ? {layer} : null, - }, - ]; - - const searchColumns: ColumnsType = [ - { - title: 'Label', - key: 'label', - ellipsis: true, - render: (_: unknown, record: SearchResult) => ( - openDetail(record.id)}>{record.label ?? record.name ?? record.id} - ), - }, - { - title: 'Kind', - dataIndex: 'kind', - key: 'kind', - width: 130, - render: (kind: string) => {kind}, - }, - { - title: 'File', - key: 'file', - ellipsis: true, - width: 300, - render: (_: unknown, record: SearchResult) => record.file_path ?? record.filePath ?? '', - }, - { - title: 'Score', - dataIndex: 'score', - key: 'score', - width: 80, - render: (score: number) => score !== undefined ? score.toFixed(2) : '', - }, - ]; - - if (kindsLoading) { - return
; - } - - const kindTabs = [ - { key: '', label: `All (${kinds?.total ?? 0})` }, - ...(kinds?.kinds ?? []) - .sort((a, b) => b.count - a.count) - .map(k => ({ - key: k.kind, - label: `${k.kind} (${k.count})`, - })), - ]; - - return ( -
- Explorer - - setSearchQuery(e.target.value)} - onSearch={handleSearch} - loading={searchLoading} - /> - - {searchResults ? ( -
-
- - {searchResults.length} search result{searchResults.length !== 1 ? 's' : ''} - - { setSearchResults(null); setSearchQuery(''); }} style={{ marginLeft: 12 }}> - Clear search - -
-
- - ) : ( - <> - -
{ setPage(p); setPageSize(ps); }, - }} - onRow={(record) => ({ - style: { cursor: 'pointer' }, - onClick: () => openDetail(record.id), - })} - /> - - )} - - { setDrawerOpen(false); setSelectedNode(null); setNeighbors(null); }} - > - {detailLoading ? ( -
- ) : selectedNode ? ( -
- - - - {selectedNode.id} - - - - {selectedNode.kind} - - {selectedNode.fqn && ( - {selectedNode.fqn} - )} - {selectedNode.module && ( - {selectedNode.module} - )} - {selectedNode.file_path && ( - {selectedNode.file_path} - )} - {selectedNode.line_start != null && ( - - {selectedNode.line_start}{selectedNode.line_end ? ` - ${selectedNode.line_end}` : ''} - - )} - {selectedNode.layer && ( - {selectedNode.layer} - )} - {selectedNode.annotations && selectedNode.annotations.length > 0 && ( - - - {selectedNode.annotations.map((a, i) => {a})} - - - )} - - - {/* Properties */} - {selectedNode.properties && Object.keys(selectedNode.properties).length > 0 && ( - <> - Properties - - {Object.entries(selectedNode.properties).map(([key, val]) => ( - - - {typeof val === 'object' ? JSON.stringify(val) : String(val)} - - - ))} - - - )} - - {/* Neighbors */} - {neighbors && ( - <> - {neighbors.incoming && neighbors.incoming.length > 0 && ( - <> - Incoming ({neighbors.incoming.length}) - ( - - - {item.node.kind} - openDetail(item.node.id)}>{item.node.label} - {item.edge.kind} - - - )} - /> - - )} - {neighbors.outgoing && neighbors.outgoing.length > 0 && ( - <> - Outgoing ({neighbors.outgoing.length}) - ( - - - {item.edge.kind} - openDetail(item.node.id)}>{item.node.label} - {item.node.kind} - - - )} - /> - - )} - - )} -
- ) : ( - - )} -
- - ); -} diff --git a/src/main/frontend/src/pages/McpConsole.tsx b/src/main/frontend/src/pages/McpConsole.tsx deleted file mode 100644 index e55f6001..00000000 --- a/src/main/frontend/src/pages/McpConsole.tsx +++ /dev/null @@ -1,415 +0,0 @@ -import { useState, useCallback, useEffect } from 'react'; -import { - Layout, Menu, Card, Form, Input, InputNumber, Select, Button, Typography, - Space, Tag, Tooltip, Modal, Empty, -} from 'antd'; -import { - PlayCircleOutlined, - ClockCircleOutlined, - SearchOutlined, - BarChartOutlined, - BranchesOutlined, - ApiOutlined, - ThunderboltOutlined, - SafetyCertificateOutlined, - CodeOutlined, - AppstoreOutlined, - HistoryOutlined, -} from '@ant-design/icons'; -import { TOOLS, CATEGORIES, toolsByCategory, type McpTool } from '@/lib/mcp-tools'; - -const { Sider, Content } = Layout; - -const CATEGORY_ICONS: Record = { - stats: , - query: , - topology: , - flow: , - analysis: , - security: , - code: , -}; - -interface HistoryEntry { - toolName: string; - status: number; - duration: number; - response: string; - timestamp: number; -} - -function resolveUrl(tool: McpTool, params: Record): string { - return typeof tool.url === 'function' ? tool.url(params) : tool.url; -} - -function countResults(json: unknown): number | null { - if (Array.isArray(json)) return json.length; - if (json && typeof json === 'object') { - const obj = json as Record; - if (Array.isArray(obj.nodes)) return (obj.nodes as unknown[]).length; - if (Array.isArray(obj.services)) return (obj.services as unknown[]).length; - if (Array.isArray(obj.kinds)) return (obj.kinds as unknown[]).length; - } - return null; -} - -export default function McpConsole() { - const [selectedTool, setSelectedTool] = useState(TOOLS[0] ?? null); - const [response, setResponse] = useState(''); - const [status, setStatus] = useState(null); - const [duration, setDuration] = useState(null); - const [executing, setExecuting] = useState(false); - const [resultCount, setResultCount] = useState(null); - const [history, setHistory] = useState([]); - const [paletteOpen, setPaletteOpen] = useState(false); - const [paletteQuery, setPaletteQuery] = useState(''); - const [form] = Form.useForm(); - const grouped = toolsByCategory(); - - // Cmd+K shortcut - useEffect(() => { - const handler = (e: KeyboardEvent) => { - if ((e.metaKey || e.ctrlKey) && e.key === 'k') { - e.preventDefault(); - setPaletteOpen(v => !v); - } - }; - window.addEventListener('keydown', handler); - return () => window.removeEventListener('keydown', handler); - }, []); - - const selectTool = useCallback((tool: McpTool) => { - setSelectedTool(tool); - const defaults: Record = {}; - tool.params.forEach(p => { if (p.default !== undefined) defaults[p.name] = p.default; }); - form.setFieldsValue(defaults); - }, [form]); - - const execute = useCallback(async () => { - if (!selectedTool) return; - const values = form.getFieldsValue(); - const params: Record = {}; - for (const [k, v] of Object.entries(values)) { - if (v !== undefined && v !== null && v !== '') params[k] = String(v); - } - - // Validate required - const missing = selectedTool.params - .filter(p => p.required && !params[p.name]?.trim()) - .map(p => p.name); - if (missing.length) { - form.validateFields(); - return; - } - - setExecuting(true); - const start = performance.now(); - try { - const url = resolveUrl(selectedTool, params); - const method = selectedTool.method ?? 'GET'; - const opts: RequestInit = { method }; - if (method === 'POST') { - opts.headers = { 'Content-Type': 'application/json' }; - opts.body = JSON.stringify(params); - } - const res = await fetch(url, opts); - const elapsed = Math.round(performance.now() - start); - setStatus(res.status); - setDuration(elapsed); - - const ct = res.headers.get('content-type') ?? ''; - let text: string; - if (ct.includes('json')) { - const json = await res.json(); - text = JSON.stringify(json, null, 2); - setResultCount(countResults(json)); - } else { - text = await res.text(); - setResultCount(null); - } - setResponse(text); - setHistory(prev => [ - { toolName: selectedTool.name, status: res.status, duration: elapsed, response: text, timestamp: Date.now() }, - ...prev.slice(0, 19), - ]); - } catch (err) { - const elapsed = Math.round(performance.now() - start); - setStatus(0); - setDuration(elapsed); - const text = JSON.stringify({ error: err instanceof Error ? err.message : String(err) }, null, 2); - setResponse(text); - setResultCount(null); - setHistory(prev => [ - { toolName: selectedTool.name, status: 0, duration: elapsed, response: text, timestamp: Date.now() }, - ...prev.slice(0, 19), - ]); - } finally { - setExecuting(false); - } - }, [selectedTool, form]); - - // Build menu items - const menuItems = CATEGORIES.map(cat => ({ - key: cat.id, - icon: CATEGORY_ICONS[cat.id] ?? , - label: cat.label, - children: (grouped[cat.id] ?? []).map(tool => ({ - key: tool.name, - label: ( - - {tool.name} - - ), - })), - })); - - const paletteResults = paletteQuery.trim() - ? TOOLS.filter(t => - t.name.includes(paletteQuery.toLowerCase()) || - t.description.toLowerCase().includes(paletteQuery.toLowerCase()) - ) - : TOOLS; - - return ( -
-
-
- MCP Console - - {TOOLS.length} tools across {CATEGORIES.length} categories - -
- -
- - - - - { - const tool = TOOLS.find(t => t.name === key); - if (tool) selectTool(tool); - }} - style={{ borderRight: 'none' }} - /> - - - - -
- {/* Tool form */} - - {selectedTool.name} - - {selectedTool.method ?? 'GET'} - - - ) : 'Select a tool'} - extra={selectedTool && ( - - )} - > - {selectedTool ? ( - <> - - {selectedTool.description} - - {selectedTool.params.length > 0 ? ( -
- {selectedTool.params.map(param => ( - - {param.name} - {param.required && required} - {param.type} - - } - name={param.name} - rules={param.required ? [{ required: true, message: `${param.name} is required` }] : []} - tooltip={param.description} - > - {param.options ? ( - - ) : ( - - )} - - ))} - - ) : ( - No parameters required. Click Run to execute. - )} - - {resolveUrl(selectedTool, form.getFieldsValue() ?? {})} - - - ) : ( - - )} -
- - {/* Response */} - - Response - {status !== null && ( - = 200 && status < 300 ? 'green' : status >= 400 ? 'red' : 'orange'}> - {status} - - )} - {duration !== null && ( - - {duration}ms - - )} - {resultCount !== null && ( - - {resultCount} results - - )} - - } - style={{ flex: 1 }} - styles={{ body: { overflow: 'auto', maxHeight: 400 } }} - > - {response ? ( -
-                  {response}
-                
- ) : ( - - )} -
- - {/* History */} - {history.length > 0 && ( - History ({history.length})} - styles={{ body: { padding: 0 } }} - size="small" - > - {history.map((entry, i) => ( -
setResponse(entry.response)} - style={{ - padding: '8px 16px', - cursor: 'pointer', - display: 'flex', - alignItems: 'center', - gap: 8, - borderBottom: '1px solid rgba(128,128,128,0.1)', - }} - > - = 200 && entry.status < 300 ? 'green' : 'red'}> - {entry.status} - - {entry.toolName} - - {entry.duration}ms - -
- ))} -
- )} -
-
- - - {/* Command Palette */} - { setPaletteOpen(false); setPaletteQuery(''); }} - footer={null} - width={500} - > - setPaletteQuery(e.target.value)} - prefix={} - style={{ marginBottom: 16 }} - onKeyDown={e => { - if (e.key === 'Enter' && paletteResults.length > 0) { - selectTool(paletteResults[0]); - setPaletteOpen(false); - setPaletteQuery(''); - } - }} - /> -
- {paletteResults.length === 0 ? ( - - ) : ( - paletteResults.map(tool => { - const cat = CATEGORIES.find(c => c.id === tool.category); - return ( -
{ - selectTool(tool); - setPaletteOpen(false); - setPaletteQuery(''); - }} - style={{ - padding: '8px 12px', - cursor: 'pointer', - borderBottom: '1px solid rgba(128,128,128,0.1)', - display: 'flex', - alignItems: 'center', - gap: 8, - }} - > -
- {tool.name} -
- - {tool.description} - -
- {cat && {cat.label}} -
- ); - }) - )} -
-
-
- ); -} diff --git a/src/main/frontend/vite.config.ts b/src/main/frontend/vite.config.ts index 1ea464d6..b0686b1d 100644 --- a/src/main/frontend/vite.config.ts +++ b/src/main/frontend/vite.config.ts @@ -18,8 +18,8 @@ export default defineConfig({ output: { manualChunks: { 'vendor-react': ['react', 'react-dom', 'react-router-dom'], - 'vendor-antd': ['antd', '@ant-design/icons'], - 'vendor-echarts': ['echarts', 'echarts-for-react'], + 'vendor-ds': ['@ossrandom/design-system'], + 'vendor-ds-charts': ['@ossrandom/design-system/charts', 'd3-hierarchy'], }, }, }, diff --git a/src/main/resources/static/assets/BricolageGrotesque-Variable-C5Lc8Qmc.woff2 b/src/main/resources/static/assets/BricolageGrotesque-Variable-C5Lc8Qmc.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..42c558b61ba40e340cfccf50786dcda816f3d30b GIT binary patch literal 131548 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�}8`x;BvtDX&FP5@dzdI^3Yr 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ð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 Z9j0ttYr0kbmz00000000000000000000 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[@+FJuP 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⪙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 in e?el(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var f=(e,t,r)=>tl(e,typeof t!="symbol"?t+"":t,r);function zs(e,t){if(!e)throw new Error(t||"loader assertion failed.")}const Do=!!(typeof process!="object"||String(process)!=="[object process]"||process.browser),js=typeof process<"u"&&process.version&&/v([0-9]*)/.exec(process.version);js&&parseFloat(js[1]);const Bt=globalThis,Ue=globalThis.process||{},rl=globalThis.navigator||{};function Fo(e){var i,s;if(typeof window<"u"&&((i=window.process)==null?void 0:i.type)==="renderer"||typeof process<"u"&&((s=process.versions)!=null&&s.electron))return!0;const r=typeof navigator<"u"&&navigator.userAgent;return!!(r&&r.indexOf("Electron")>=0)}function it(){return!(typeof process=="object"&&String(process)==="[object process]"&&!(process!=null&&process.browser))||Fo()}function il(e){return it()?Fo()?"Electron":(rl.userAgent||"").indexOf("Edge")>-1?"Edge":globalThis.chrome?"Chrome":globalThis.safari?"Safari":globalThis.mozInnerScreenX?"Firefox":"Unknown":"Node"}const Uo="4.1.1";function ps(e,t){if(!e)throw new Error("Assertion failed")}function Lo(e){if(!e)return 0;let t;switch(typeof e){case"number":t=e;break;case"object":t=e.logLevel||e.priority||0;break;default:return 0}return ps(Number.isFinite(t)&&t>=0),t}function sl(e){const{logLevel:t,message:r}=e;e.logLevel=Lo(t);const i=e.args?Array.from(e.args):[];for(;i.length&&i.shift()!==r;);switch(typeof t){case"string":case"function":r!==void 0&&i.unshift(r),e.message=t;break;case"object":Object.assign(e,t);break}typeof e.message=="function"&&(e.message=e.message());const s=typeof e.message;return ps(s==="string"||s==="object"),Object.assign(e,{args:i},e.opts)}const We=()=>{};class nl{constructor({level:t=0}={}){this.userData={},this._onceCache=new Set,this._level=t}set level(t){this.setLevel(t)}get level(){return this.getLevel()}setLevel(t){return this._level=t,this}getLevel(){return this._level}warn(t,...r){return this._log("warn",0,t,r,{once:!0})}error(t,...r){return this._log("error",0,t,r)}log(t,r,...i){return this._log("log",t,r,i)}info(t,r,...i){return this._log("info",t,r,i)}once(t,r,...i){return this._log("once",t,r,i,{once:!0})}_log(t,r,i,s,n={}){const o=sl({logLevel:r,message:i,args:this._buildArgs(r,i,s),opts:n});return this._createLogFunction(t,o,n)}_buildArgs(t,r,i){return[t,r,...i]}_createLogFunction(t,r,i){if(!this._shouldLog(r.logLevel))return We;const s=this._getOnceTag(i.tag??r.tag??r.message);if((i.once||r.once)&&s!==void 0){if(this._onceCache.has(s))return We;this._onceCache.add(s)}return this._emit(t,r)}_shouldLog(t){return this.getLevel()>=Lo(t)}_getOnceTag(t){if(t!==void 0)try{return typeof t=="string"?t:String(t)}catch{return}}}function ol(e){try{const t=window[e],r="__storage_test__";return t.setItem(r,r),t.removeItem(r),t}catch{return null}}class al{constructor(t,r,i="sessionStorage"){this.storage=ol(i),this.id=t,this.config=r,this._loadConfiguration()}getConfiguration(){return this.config}setConfiguration(t){if(Object.assign(this.config,t),this.storage){const r=JSON.stringify(this.config);this.storage.setItem(this.id,r)}}_loadConfiguration(){let t={};if(this.storage){const r=this.storage.getItem(this.id);t=r?JSON.parse(r):{}}return Object.assign(this.config,t),this}}function cl(e){let t;return e<10?t=`${e.toFixed(2)}ms`:e<100?t=`${e.toFixed(1)}ms`:e<1e3?t=`${e.toFixed(0)}ms`:t=`${(e/1e3).toFixed(2)}s`,t}function ll(e,t=8){const r=Math.max(t-e.length,0);return`${" ".repeat(r)}${e}`}var rr;(function(e){e[e.BLACK=30]="BLACK",e[e.RED=31]="RED",e[e.GREEN=32]="GREEN",e[e.YELLOW=33]="YELLOW",e[e.BLUE=34]="BLUE",e[e.MAGENTA=35]="MAGENTA",e[e.CYAN=36]="CYAN",e[e.WHITE=37]="WHITE",e[e.BRIGHT_BLACK=90]="BRIGHT_BLACK",e[e.BRIGHT_RED=91]="BRIGHT_RED",e[e.BRIGHT_GREEN=92]="BRIGHT_GREEN",e[e.BRIGHT_YELLOW=93]="BRIGHT_YELLOW",e[e.BRIGHT_BLUE=94]="BRIGHT_BLUE",e[e.BRIGHT_MAGENTA=95]="BRIGHT_MAGENTA",e[e.BRIGHT_CYAN=96]="BRIGHT_CYAN",e[e.BRIGHT_WHITE=97]="BRIGHT_WHITE"})(rr||(rr={}));const fl=10;function Hs(e){return typeof e!="string"?e:(e=e.toUpperCase(),rr[e]||rr.WHITE)}function ul(e,t,r){return!it&&typeof e=="string"&&(t&&(e=`\x1B[${Hs(t)}m${e}\x1B[39m`),r&&(e=`\x1B[${Hs(r)+fl}m${e}\x1B[49m`)),e}function hl(e,t=["constructor"]){const r=Object.getPrototypeOf(e),i=Object.getOwnPropertyNames(r),s=e;for(const n of i){const o=s[n];typeof o=="function"&&(t.find(a=>n===a)||(s[n]=o.bind(e)))}}function ct(){var t,r,i;let e;if(it()&&Bt.performance)e=(r=(t=Bt==null?void 0:Bt.performance)==null?void 0:t.now)==null?void 0:r.call(t);else if("hrtime"in Ue){const s=(i=Ue==null?void 0:Ue.hrtime)==null?void 0:i.call(Ue);e=s[0]*1e3+s[1]/1e6}else e=Date.now();return e}const Le={debug:it()&&console.debug||console.log,log:console.log,info:console.info,warn:console.warn,error:console.error},Qr={enabled:!0,level:0};class xt extends nl{constructor({id:t}={id:""}){super({level:0}),this.VERSION=Uo,this._startTs=ct(),this._deltaTs=ct(),this.userData={},this.LOG_THROTTLE_TIMEOUT=0,this.id=t,this.userData={},this._storage=new al(`__probe-${this.id}__`,{[this.id]:Qr}),this.timeStamp(`${this.id} started`),hl(this),Object.seal(this)}isEnabled(){return this._getConfiguration().enabled}getLevel(){return this._getConfiguration().level}getTotal(){return Number((ct()-this._startTs).toPrecision(10))}getDelta(){return Number((ct()-this._deltaTs).toPrecision(10))}set priority(t){this.level=t}get priority(){return this.level}getPriority(){return this.level}enable(t=!0){return this._updateConfiguration({enabled:t}),this}setLevel(t){return this._updateConfiguration({level:t}),this}get(t){return this._getConfiguration()[t]}set(t,r){this._updateConfiguration({[t]:r})}settings(){console.table?console.table(this._storage.config):console.log(this._storage.config)}assert(t,r){if(!t)throw new Error(r||"Assertion failed")}warn(t,...r){return this._log("warn",0,t,r,{method:Le.warn,once:!0})}error(t,...r){return this._log("error",0,t,r,{method:Le.error})}deprecated(t,r){return this.warn(`\`${t}\` is deprecated and will be removed in a later version. Use \`${r}\` instead`)}removed(t,r){return this.error(`\`${t}\` has been removed. Use \`${r}\` instead`)}probe(t,r,...i){return this._log("log",t,r,i,{method:Le.log,time:!0,once:!0})}log(t,r,...i){return this._log("log",t,r,i,{method:Le.debug})}info(t,r,...i){return this._log("info",t,r,i,{method:console.info})}once(t,r,...i){return this._log("once",t,r,i,{method:Le.debug||Le.info,once:!0})}table(t,r,i){return r?this._log("table",t,r,i&&[i]||[],{method:console.table||We,tag:gl(r)}):We}time(t,r){return this._log("time",t,r,[],{method:console.time?console.time:console.info})}timeEnd(t,r){return this._log("time",t,r,[],{method:console.timeEnd?console.timeEnd:console.info})}timeStamp(t,r){return this._log("time",t,r,[],{method:console.timeStamp||We})}group(t,r,i={collapsed:!1}){const s=(i.collapsed?console.groupCollapsed:console.group)||console.info;return this._log("group",t,r,[],{method:s})}groupCollapsed(t,r,i={}){return this.group(t,r,Object.assign({},i,{collapsed:!0}))}groupEnd(t){return this._log("groupEnd",t,"",[],{method:console.groupEnd||We})}withGroup(t,r,i){this.group(t,r)();try{i()}finally{this.groupEnd(t)()}}trace(){console.trace&&console.trace()}_shouldLog(t){return this.isEnabled()&&super._shouldLog(t)}_emit(t,r){const i=r.method;ps(i),r.total=this.getTotal(),r.delta=this.getDelta(),this._deltaTs=ct();const s=dl(this.id,r.message,r);return i.bind(console,s,...r.args)}_getConfiguration(){return this._storage.config[this.id]||this._updateConfiguration(Qr),this._storage.config[this.id]}_updateConfiguration(t){const r=this._storage.config[this.id]||{...Qr};this._storage.setConfiguration({[this.id]:{...r,...t}})}}xt.VERSION=Uo;function dl(e,t,r){if(typeof t=="string"){const i=r.time?ll(cl(r.total)):"";t=r.time?`${e}: ${i} ${t}`:`${e}: ${t}`,t=ul(t,r.color,r.background)}return t}function gl(e){for(const t in e)for(const r in e[t])return r||"untitled";return"empty"}const qr="4.4.1",pl=qr[0]>="0"&&qr[0]<="9"?`v${qr}`:"";function _l(){const e=new xt({id:"loaders.gl"});return globalThis.loaders||(globalThis.loaders={}),globalThis.loaders.log=e,globalThis.loaders.version=pl,globalThis.probe||(globalThis.probe={}),globalThis.probe.loaders=e,e}const ml=_l(),bl=e=>typeof e=="boolean",ae=e=>typeof e=="function",Be=e=>e!==null&&typeof e=="object",Vs=e=>Be(e)&&e.constructor==={}.constructor,ko=e=>typeof SharedArrayBuffer<"u"&&e instanceof SharedArrayBuffer,_s=e=>Be(e)&&typeof e.byteLength=="number"&&typeof e.slice=="function",Tl=e=>!!e&&ae(e[Symbol.iterator]),Al=e=>!!e&&ae(e[Symbol.asyncIterator]),De=e=>typeof Response<"u"&&e instanceof Response||Be(e)&&ae(e.arrayBuffer)&&ae(e.text)&&ae(e.json),Fe=e=>typeof Blob<"u"&&e instanceof Blob,yl=e=>typeof ReadableStream<"u"&&e instanceof ReadableStream||Be(e)&&ae(e.tee)&&ae(e.cancel)&&ae(e.getReader),Rl=e=>Be(e)&&ae(e.read)&&ae(e.pipe)&&bl(e.readable),Wo=e=>yl(e)||Rl(e);function El(e,t){return $o(e||{},t)}function $o(e,t,r=0){if(r>3)return t;const i={...e};for(const[s,n]of Object.entries(t))n&&typeof n=="object"&&!Array.isArray(n)?i[s]=$o(i[s]||{},t[s],r+1):i[s]=t[s];return i}const Sl="latest";function Cl(){var e;return(e=globalThis._loadersgl_)!=null&&e.version||(globalThis._loadersgl_=globalThis._loadersgl_||{},globalThis._loadersgl_.version="4.4.1"),globalThis._loadersgl_.version}const vl=Cl();function Te(e,t){if(!e)throw new Error(t||"loaders.gl assertion failed.")}const Ce=typeof process!="object"||String(process)!=="[object process]"||process.browser,Pl=typeof window<"u"&&typeof window.orientation<"u",Xs=typeof process<"u"&&process.version&&/v([0-9]*)/.exec(process.version);Xs&&parseFloat(Xs[1]);class wl{constructor(t,r){f(this,"name");f(this,"workerThread");f(this,"isRunning",!0);f(this,"result");f(this,"_resolve",()=>{});f(this,"_reject",()=>{});this.name=t,this.workerThread=r,this.result=new Promise((i,s)=>{this._resolve=i,this._reject=s})}postMessage(t,r){this.workerThread.postMessage({source:"loaders.gl",type:t,payload:r})}done(t){Te(this.isRunning),this.isRunning=!1,this._resolve(t)}error(t){Te(this.isRunning),this.isRunning=!1,this._reject(t)}}class Zr{terminate(){}}const Jr=new Map;function Ol(e){Te(e.source&&!e.url||!e.source&&e.url);let t=Jr.get(e.source||e.url);return t||(e.url&&(t=xl(e.url),Jr.set(e.url,t)),e.source&&(t=zo(e.source),Jr.set(e.source,t))),Te(t),t}function xl(e){if(!e.startsWith("http"))return e;const t=Ml(e);return zo(t)}function zo(e){const t=new Blob([e],{type:"application/javascript"});return URL.createObjectURL(t)}function Ml(e){return`try { + importScripts('${e}'); +} catch (error) { + console.error(error); + throw error; +}`}function jo(e,t=!0,r){const i=r||new Set;if(e){if(Ys(e))i.add(e);else if(Ys(e.buffer))i.add(e.buffer);else if(!ArrayBuffer.isView(e)){if(t&&typeof e=="object")for(const s in e)jo(e[s],t,i)}}return r===void 0?Array.from(i):[]}function Ys(e){return e?e instanceof ArrayBuffer||typeof MessagePort<"u"&&e instanceof MessagePort||typeof ImageBitmap<"u"&&e instanceof ImageBitmap||typeof OffscreenCanvas<"u"&&e instanceof OffscreenCanvas:!1}const Gr=()=>{};class Ni{constructor(t){f(this,"name");f(this,"source");f(this,"url");f(this,"terminated",!1);f(this,"worker");f(this,"onMessage");f(this,"onError");f(this,"_loadableURL","");const{name:r,source:i,url:s}=t;Te(i||s),this.name=r,this.source=i,this.url=s,this.onMessage=Gr,this.onError=n=>console.log(n),this.worker=Ce?this._createBrowserWorker():this._createNodeWorker()}static isSupported(){return typeof Worker<"u"&&Ce||typeof Zr<"u"&&!Ce}destroy(){this.onMessage=Gr,this.onError=Gr,this.worker.terminate(),this.terminated=!0}get isRunning(){return!!this.onMessage}postMessage(t,r){r=r||jo(t),this.worker.postMessage(t,r)}_getErrorFromErrorEvent(t){let r="Failed to load ";return r+=`worker ${this.name} from ${this.url}. `,t.message&&(r+=`${t.message} in `),t.lineno&&(r+=`:${t.lineno}:${t.colno}`),new Error(r)}_createBrowserWorker(){this._loadableURL=Ol({source:this.source,url:this.url});const t=new Worker(this._loadableURL,{name:this.name});return t.onmessage=r=>{r.data?this.onMessage(r.data):this.onError(new Error("No data received"))},t.onerror=r=>{this.onError(this._getErrorFromErrorEvent(r)),this.terminated=!0},t.onmessageerror=r=>console.error(r),t}_createNodeWorker(){let t;if(this.url){const i=this.url.includes(":/")||this.url.startsWith("/")?this.url:`./${this.url}`,s=this.url.endsWith(".ts")||this.url.endsWith(".mjs")?"module":"commonjs";t=new Zr(i,{eval:!1,type:s})}else if(this.source)t=new Zr(this.source,{eval:!0});else throw new Error("no worker");return t.on("message",r=>{this.onMessage(r)}),t.on("error",r=>{this.onError(r)}),t.on("exit",r=>{}),t}}class Il{constructor(t){f(this,"name","unnamed");f(this,"source");f(this,"url");f(this,"maxConcurrency",1);f(this,"maxMobileConcurrency",1);f(this,"onDebug",()=>{});f(this,"reuseWorkers",!0);f(this,"props",{});f(this,"jobQueue",[]);f(this,"idleQueue",[]);f(this,"count",0);f(this,"isDestroyed",!1);this.source=t.source,this.url=t.url,this.setProps(t)}static isSupported(){return Ni.isSupported()}destroy(){this.idleQueue.forEach(t=>t.destroy()),this.isDestroyed=!0}setProps(t){this.props={...this.props,...t},t.name!==void 0&&(this.name=t.name),t.maxConcurrency!==void 0&&(this.maxConcurrency=t.maxConcurrency),t.maxMobileConcurrency!==void 0&&(this.maxMobileConcurrency=t.maxMobileConcurrency),t.reuseWorkers!==void 0&&(this.reuseWorkers=t.reuseWorkers),t.onDebug!==void 0&&(this.onDebug=t.onDebug)}async startJob(t,r=(s,n,o)=>s.done(o),i=(s,n)=>s.error(n)){const s=new Promise(n=>(this.jobQueue.push({name:t,onMessage:r,onError:i,onStart:n}),this));return this._startQueuedJob(),await s}async _startQueuedJob(){if(!this.jobQueue.length)return;const t=this._getAvailableWorker();if(!t)return;const r=this.jobQueue.shift();if(r){this.onDebug({message:"Starting job",name:r.name,workerThread:t,backlog:this.jobQueue.length});const i=new wl(r.name,t);t.onMessage=s=>r.onMessage(i,s.type,s.payload),t.onError=s=>r.onError(i,s),r.onStart(i);try{await i.result}catch(s){console.error(`Worker exception: ${s}`)}finally{this.returnWorkerToQueue(t)}}}returnWorkerToQueue(t){!Ce||this.isDestroyed||!this.reuseWorkers||this.count>this._getMaxConcurrency()?(t.destroy(),this.count--):this.idleQueue.push(t),this.isDestroyed||this._startQueuedJob()}_getAvailableWorker(){if(this.idleQueue.length>0)return this.idleQueue.shift()||null;if(this.count{}},ge=class ge{constructor(t){f(this,"props");f(this,"workerPools",new Map);this.props={...Nl},this.setProps(t),this.workerPools=new Map}static isSupported(){return Ni.isSupported()}static getWorkerFarm(t={}){return ge._workerFarm=ge._workerFarm||new ge({}),ge._workerFarm.setProps(t),ge._workerFarm}destroy(){for(const t of this.workerPools.values())t.destroy();this.workerPools=new Map}setProps(t){this.props={...this.props,...t};for(const r of this.workerPools.values())r.setProps(this._getWorkerPoolProps())}getWorkerPool(t){const{name:r,source:i,url:s}=t;let n=this.workerPools.get(r);return n||(n=new Il({name:r,source:i,url:s}),n.setProps(this._getWorkerPoolProps()),this.workerPools.set(r,n)),n}_getWorkerPoolProps(){return{maxConcurrency:this.props.maxConcurrency,maxMobileConcurrency:this.props.maxMobileConcurrency,reuseWorkers:this.props.reuseWorkers,onDebug:this.props.onDebug}}};f(ge,"_workerFarm");let ir=ge;function Bl(e,t={}){var o;const r=t[e.id]||{},i=Ce?`${e.id}-worker.js`:`${e.id}-worker-node.js`;let s=r.workerUrl;if(!s&&e.id==="compression"&&(s=t.workerUrl),(t._workerType||((o=t==null?void 0:t.core)==null?void 0:o._workerType))==="test"&&(Ce?s=`modules/${e.module}/dist/${i}`:s=`modules/${e.module}/src/workers/${e.id}-worker-node.ts`),!s){let a=e.version;a==="latest"&&(a=Sl);const c=a?`@${a}`:"";s=`https://unpkg.com/@loaders.gl/${e.module}${c}/dist/${i}`}return Te(s),s}function Dl(e,t=vl){Te(e,"no worker provided");const r=e.version;return!(!t||!r)}function Fl(e,t){var s,n;if(!ir.isSupported())return!1;const r=(t==null?void 0:t._nodeWorkers)??((s=t==null?void 0:t.core)==null?void 0:s._nodeWorkers);if(!Ce&&!r)return!1;const i=(t==null?void 0:t.worker)??((n=t==null?void 0:t.core)==null?void 0:n.worker);return!!(e.worker&&i)}async function Ul(e,t,r,i,s){const n=e.id,o=Bl(e,r),c=ir.getWorkerFarm(r==null?void 0:r.core).getWorkerPool({name:n,url:o});r=JSON.parse(JSON.stringify(r)),i=JSON.parse(JSON.stringify(i||{}));const l=await c.startJob("process-on-worker",Ll.bind(null,s));return l.postMessage("process",{input:t,options:r,context:i}),await(await l.result).result}async function Ll(e,t,r,i){switch(r){case"done":t.done(i);break;case"error":t.error(new Error(i.error));break;case"process":const{id:s,input:n,options:o}=i;try{const a=await e(n,o);t.postMessage("done",{id:s,result:a})}catch(a){const c=a instanceof Error?a.message:"unknown error";t.postMessage("error",{id:s,error:c})}break;default:console.warn(`parse-with-worker unknown message ${r}`)}}function kl(e,t,r){if(r=r||e.byteLength,e.byteLengthn instanceof ArrayBuffer?new Uint8Array(n):n),r=t.reduce((n,o)=>n+o.byteLength,0),i=new Uint8Array(r);let s=0;for(const n of t)i.set(n,s),s+=n.byteLength;return i.buffer}async function zl(e){const t=[];for await(const r of e)t.push(jl(r));return Wl(...t)}function jl(e){if(e instanceof ArrayBuffer)return e;if(ArrayBuffer.isView(e)){const{buffer:t,byteOffset:r,byteLength:i}=e;return Ks(t,r,i)}return Ks(e)}function Ks(e,t=0,r=e.byteLength-t){const i=new Uint8Array(e,t,r),s=new Uint8Array(i.length);return s.set(i),s.buffer}function Qs(){let e;if(typeof window<"u"&&window.performance)e=window.performance.now();else if(typeof process<"u"&&process.hrtime){const t=process.hrtime();e=t[0]*1e3+t[1]/1e6}else e=Date.now();return e}class qs{constructor(t,r){this.sampleSize=1,this.time=0,this.count=0,this.samples=0,this.lastTiming=0,this.lastSampleTime=0,this.lastSampleCount=0,this._count=0,this._time=0,this._samples=0,this._startTime=0,this._timerPending=!1,this.name=t,this.type=r,this.reset()}reset(){return this.time=0,this.count=0,this.samples=0,this.lastTiming=0,this.lastSampleTime=0,this.lastSampleCount=0,this._count=0,this._time=0,this._samples=0,this._startTime=0,this._timerPending=!1,this}setSampleSize(t){return this.sampleSize=t,this}incrementCount(){return this.addCount(1),this}decrementCount(){return this.subtractCount(1),this}addCount(t){return this._count+=t,this._samples++,this._checkSampling(),this}subtractCount(t){return this._count-=t,this._samples++,this._checkSampling(),this}addTime(t){return this._time+=t,this.lastTiming=t,this._samples++,this._checkSampling(),this}timeStart(){return this._startTime=Qs(),this._timerPending=!0,this}timeEnd(){return this._timerPending?(this.addTime(Qs()-this._startTime),this._timerPending=!1,this._checkSampling(),this):this}getSampleAverageCount(){return this.sampleSize>0?this.lastSampleCount/this.sampleSize:0}getSampleAverageTime(){return this.sampleSize>0?this.lastSampleTime/this.sampleSize:0}getSampleHz(){return this.lastSampleTime>0?this.sampleSize/(this.lastSampleTime/1e3):0}getAverageCount(){return this.samples>0?this.count/this.samples:0}getAverageTime(){return this.samples>0?this.time/this.samples:0}getHz(){return this.time>0?this.samples/(this.time/1e3):0}_checkSampling(){this._samples===this.sampleSize&&(this.lastSampleTime=this._time,this.lastSampleCount=this._count,this.count+=this._count,this.time+=this._time,this.samples+=this._samples,this._time=0,this._count=0,this._samples=0)}}class Hl{constructor(t){this.stats={},this.id=t.id,this.stats={},this._initializeStats(t.stats),Object.seal(this)}get(t,r="count"){return this._getOrCreate({name:t,type:r})}get size(){return Object.keys(this.stats).length}reset(){for(const t of Object.values(this.stats))t.reset();return this}forEach(t){for(const r of Object.values(this.stats))t(r)}getTable(){const t={};return this.forEach(r=>{t[r.name]={time:r.time||0,count:r.count||0,average:r.getAverageTime()||0,hz:r.getHz()||0}}),t}_initializeStats(t=[]){t.forEach(r=>this._getOrCreate(r))}_getOrCreate(t){const{name:r,type:i}=t;let s=this.stats[r];return s||(t instanceof qs?s=t:s=new qs(r,i),this.stats[r]=s),s}}let Vl="";const Zs={};function Xl(e){for(const t in Zs)if(e.startsWith(t)){const r=Zs[t];e=e.replace(t,r)}return!e.startsWith("http://")&&!e.startsWith("https://")&&(e=`${Vl}${e}`),e}function Ho(e){return e&&typeof e=="object"&&e.isBuffer}function ms(e){if(Ho(e))return e;if(e instanceof ArrayBuffer)return e;if(ko(e))return Bi(e);if(ArrayBuffer.isView(e)){const t=e.buffer;return e.byteOffset===0&&e.byteLength===e.buffer.byteLength?t:t.slice(e.byteOffset,e.byteOffset+e.byteLength)}if(typeof e=="string"){const t=e;return new TextEncoder().encode(t).buffer}if(e&&typeof e=="object"&&e._toArrayBuffer)return e._toArrayBuffer();throw new Error("toArrayBuffer")}function Vo(e){if(e instanceof ArrayBuffer)return e;if(ko(e))return Bi(e);const{buffer:t,byteOffset:r,byteLength:i}=e;return t instanceof ArrayBuffer&&r===0&&i===t.byteLength?t:Bi(t,r,i)}function Bi(e,t=0,r=e.byteLength-t){const i=new Uint8Array(e,t,r),s=new Uint8Array(i.length);return s.set(i),s.buffer}function Yl(e){return ArrayBuffer.isView(e)?e:new Uint8Array(e)}function Xo(e){const t=e?e.lastIndexOf("/"):-1;return t>=0?e.substr(t+1):e}function Yo(e){const t=e?e.lastIndexOf("/"):-1;return t>=0?e.substr(0,t):""}class Kl extends Error{constructor(r,i){super(r);f(this,"reason");f(this,"url");f(this,"response");this.reason=i.reason,this.url=i.url,this.response=i.response}}const Ql=/^data:([-\w.]+\/[-\w.+]+)(;|,)/,ql=/^([-\w.]+\/[-\w.+]+)/;function Js(e,t){return e.toLowerCase()===t.toLowerCase()}function Zl(e){const t=ql.exec(e);return t?t[1]:e}function Gs(e){const t=Ql.exec(e);return t?t[1]:""}const Ko=/\?.*/;function Jl(e){const t=e.match(Ko);return t&&t[0]}function Wr(e){return e.replace(Ko,"")}function Gl(e){if(e.length<50)return e;const t=e.slice(e.length-15);return`${e.substr(0,32)}...${t}`}function $r(e){return De(e)?e.url:Fe(e)?("name"in e?e.name:"")||"":typeof e=="string"?e:""}function zr(e){if(De(e)){const t=e.headers.get("content-type")||"",r=Wr(e.url);return Zl(t)||Gs(r)}return Fe(e)?e.type||"":typeof e=="string"?Gs(e):""}function ef(e){return De(e)?e.headers["content-length"]||-1:Fe(e)?e.size:typeof e=="string"?e.length:e instanceof ArrayBuffer||ArrayBuffer.isView(e)?e.byteLength:-1}async function Qo(e){if(De(e))return e;const t={},r=ef(e);r>=0&&(t["content-length"]=String(r));const i=$r(e),s=zr(e);s&&(t["content-type"]=s);const n=await sf(e);n&&(t["x-first-bytes"]=n),typeof e=="string"&&(e=new TextEncoder().encode(e));const o=new Response(e,{headers:t});return Object.defineProperty(o,"url",{value:i}),o}async function tf(e){if(!e.ok)throw await rf(e)}async function rf(e){const t=Gl(e.url);let r=`Failed to fetch resource (${e.status}) ${e.statusText}: ${t}`;r=r.length>100?`${r.slice(0,100)}...`:r;const i={reason:e.statusText,url:e.url,response:e};try{const s=e.headers.get("Content-Type");i.reason=!e.bodyUsed&&(s!=null&&s.includes("application/json"))?await e.json():await e.text()}catch{}return new Kl(r,i)}async function sf(e){if(typeof e=="string")return`data:,${e.slice(0,5)}`;if(e instanceof Blob){const r=e.slice(0,5);return await new Promise(i=>{const s=new FileReader;s.onload=n=>{var o;return i((o=n==null?void 0:n.target)==null?void 0:o.result)},s.readAsDataURL(r)})}if(e instanceof ArrayBuffer){const r=e.slice(0,5);return`data:base64,${nf(r)}`}return null}function nf(e){let t="";const r=new Uint8Array(e);for(let i=0;i{}}info(){return()=>{}}warn(){return()=>{}}error(){return()=>{}}}class ff{constructor(){f(this,"console");this.console=console}log(...t){return this.console.log.bind(this.console,...t)}info(...t){return this.console.info.bind(this.console,...t)}warn(...t){return this.console.warn.bind(this.console,...t)}error(...t){return this.console.error.bind(this.console,...t)}}const Di={core:{baseUrl:void 0,fetch:null,mimeType:void 0,fallbackMimeType:void 0,ignoreRegisteredLoaders:void 0,nothrow:!1,log:new ff,useLocalLibraries:!1,CDN:"https://unpkg.com/@loaders.gl",worker:!0,maxConcurrency:3,maxMobileConcurrency:1,reuseWorkers:Do,_nodeWorkers:!1,_workerType:"",limit:0,_limitMB:0,batchSize:"auto",batchDebounceMs:0,metadata:!1,transforms:[]}},uf={baseUri:"core.baseUrl",fetch:"core.fetch",mimeType:"core.mimeType",fallbackMimeType:"core.fallbackMimeType",ignoreRegisteredLoaders:"core.ignoreRegisteredLoaders",nothrow:"core.nothrow",log:"core.log",useLocalLibraries:"core.useLocalLibraries",CDN:"core.CDN",worker:"core.worker",maxConcurrency:"core.maxConcurrency",maxMobileConcurrency:"core.maxMobileConcurrency",reuseWorkers:"core.reuseWorkers",_nodeWorkers:"core.nodeWorkers",_workerType:"core._workerType",_worker:"core._workerType",limit:"core.limit",_limitMB:"core._limitMB",batchSize:"core.batchSize",batchDebounceMs:"core.batchDebounceMs",metadata:"core.metadata",transforms:"core.transforms",throws:"nothrow",dataType:"(no longer used)",uri:"core.baseUrl",method:"core.fetch.method",headers:"core.fetch.headers",body:"core.fetch.body",mode:"core.fetch.mode",credentials:"core.fetch.credentials",cache:"core.fetch.cache",redirect:"core.fetch.redirect",referrer:"core.fetch.referrer",referrerPolicy:"core.fetch.referrerPolicy",integrity:"core.fetch.integrity",keepalive:"core.fetch.keepalive",signal:"core.fetch.signal"},bs=["baseUrl","fetch","mimeType","fallbackMimeType","ignoreRegisteredLoaders","nothrow","log","useLocalLibraries","CDN","worker","maxConcurrency","maxMobileConcurrency","reuseWorkers","_nodeWorkers","_workerType","limit","_limitMB","batchSize","batchDebounceMs","metadata","transforms"];function qo(){globalThis.loaders=globalThis.loaders||{};const{loaders:e}=globalThis;return e._state||(e._state={}),e._state}function Zo(){const e=qo();return e.globalOptions=e.globalOptions||{...Di,core:{...Di.core}},xe(e.globalOptions)}function hf(e,t,r,i){return r=r||[],r=Array.isArray(r)?r:[r],df(e,r),xe(pf(t,e,i))}function xe(e){const t=mf(e);Jo(t);for(const r of bs)t.core&&t.core[r]!==void 0&&delete t[r];return t.core&&t.core._workerType!==void 0&&delete t._worker,t}function df(e,t){tn(e,null,Di,uf,t);for(const r of t){const i=e&&e[r.id]||{},s=r.options&&r.options[r.id]||{},n=r.deprecatedOptions&&r.deprecatedOptions[r.id]||{};tn(i,r.id,s,n,t)}}function tn(e,t,r,i,s){const n=t||"Top level",o=t?`${t}.`:"";for(const a in e){const c=!t&&Be(e[a]),l=a==="baseUri"&&!t,u=a==="workerUrl"&&t;if(!(a in r)&&!l&&!u){if(a in i)Dt.level>0&&Dt.warn(`${n} loader option '${o}${a}' no longer supported, use '${i[a]}'`)();else if(!c&&Dt.level>0){const h=gf(a,s);Dt.warn(`${n} loader option '${o}${a}' not recognized. ${h}`)()}}}}function gf(e,t){const r=e.toLowerCase();let i="";for(const s of t)for(const n in s.options){if(e===n)return`Did you mean '${s.id}.${n}'?`;const o=n.toLowerCase();(r.startsWith(o)||o.startsWith(r))&&(i=i||`Did you mean '${s.id}.${n}'?`)}return i}function pf(e,t,r){var o;const i=e.options||{},s={...i};i.core&&(s.core={...i.core}),Jo(s),((o=s.core)==null?void 0:o.log)===null&&(s.core={...s.core,log:new lf}),rn(s,xe(Zo()));const n=xe(t);return rn(s,n),_f(s,r),bf(s),s}function rn(e,t){for(const r in t)if(r in t){const i=t[r];Vs(i)&&Vs(e[r])?e[r]={...e[r],...t[r]}:e[r]=t[r]}}function _f(e,t){var i;if(!t)return;((i=e.core)==null?void 0:i.baseUrl)!==void 0||(e.core||(e.core={}),e.core.baseUrl=Yo(Wr(t)))}function mf(e){const t={...e};return e.core&&(t.core={...e.core}),t}function Jo(e){e.baseUri!==void 0&&(e.core||(e.core={}),e.core.baseUrl===void 0&&(e.core.baseUrl=e.baseUri));for(const r of bs)if(e[r]!==void 0){const s=e.core=e.core||{};s[r]===void 0&&(s[r]=e[r])}const t=e._worker;t!==void 0&&(e.core||(e.core={}),e.core._workerType===void 0&&(e.core._workerType=t))}function bf(e){const t=e.core;if(t)for(const r of bs)t[r]!==void 0&&(e[r]=t[r])}function Ts(e){return e?(Array.isArray(e)&&(e=e[0]),Array.isArray(e==null?void 0:e.extensions)):!1}function As(e){zs(e,"null loader"),zs(Ts(e),"invalid loader");let t;return Array.isArray(e)&&(t=e[1],e=e[0],e={...e,options:{...e.options,...t}}),(e!=null&&e.parseTextSync||e!=null&&e.parseText)&&(e.text=!0),e.text||(e.binary=!0),e}const Go=()=>{const e=qo();return e.loaderRegistry=e.loaderRegistry||[],e.loaderRegistry};function RA(e){const t=Go();e=Array.isArray(e)?e:[e];for(const r of e){const i=As(r);t.find(s=>i===s)||t.unshift(i)}}function Tf(){return Go()}const Af=/\.([^.]+)$/;async function yf(e,t=[],r,i){if(!ea(e))return null;const s=xe(r||{});if(s.core||(s.core={}),e instanceof Response&&sn(e)){const o=await e.clone().text(),a=Ft(o,t,{...s,core:{...s.core,nothrow:!0}},i);if(a)return a}let n=Ft(e,t,{...s,core:{...s.core,nothrow:!0}},i);if(n)return n;if(Fe(e)&&(e=await e.slice(0,10).arrayBuffer(),n=Ft(e,t,s,i)),!n&&e instanceof Response&&sn(e)){const o=await e.clone().text();n=Ft(o,t,s,i)}if(!n&&!s.core.nothrow)throw new Error(ta(e));return n}function sn(e){const t=zr(e);return!!(t&&(t.startsWith("text/")||t==="application/json"||t.endsWith("+json")))}function Ft(e,t=[],r,i){if(!ea(e))return null;const s=xe(r||{});if(s.core||(s.core={}),t&&!Array.isArray(t))return As(t);let n=[];t&&(n=n.concat(t)),s.core.ignoreRegisteredLoaders||n.push(...Tf()),Ef(n);const o=Rf(e,n,s,i);if(!o&&!s.core.nothrow)throw new Error(ta(e));return o}function Rf(e,t,r,i){var l,u,h,d,g;const s=$r(e),n=zr(e),o=Wr(s)||(i==null?void 0:i.url);let a=null,c="";return(l=r==null?void 0:r.core)!=null&&l.mimeType&&(a=ei(t,(u=r==null?void 0:r.core)==null?void 0:u.mimeType),c=`match forced by supplied MIME type ${(h=r==null?void 0:r.core)==null?void 0:h.mimeType}`),a=a||Sf(t,o),c=c||(a?`matched url ${o}`:""),a=a||ei(t,n),c=c||(a?`matched MIME type ${n}`:""),a=a||vf(t,e),c=c||(a?`matched initial data ${ra(e)}`:""),(d=r==null?void 0:r.core)!=null&&d.fallbackMimeType&&(a=a||ei(t,(g=r==null?void 0:r.core)==null?void 0:g.fallbackMimeType),c=c||(a?`matched fallback MIME type ${n}`:"")),c&&ml.log(1,`selectLoader selected ${a==null?void 0:a.name}: ${c}.`),a}function ea(e){return!(e instanceof Response&&e.status===204)}function ta(e){const t=$r(e),r=zr(e);let i="No valid loader found (";i+=t?`${Xo(t)}, `:"no url provided, ",i+=`MIME type: ${r?`"${r}"`:"not provided"}, `;const s=e?ra(e):"";return i+=s?` first bytes: "${s}"`:"first bytes: not available",i+=")",i}function Ef(e){for(const t of e)As(t)}function Sf(e,t){const r=t&&Af.exec(t),i=r&&r[1];return i?Cf(e,i):null}function Cf(e,t){t=t.toLowerCase();for(const r of e)for(const i of r.extensions)if(i.toLowerCase()===t)return r;return null}function ei(e,t){var r;for(const i of e)if((r=i.mimeTypes)!=null&&r.some(s=>Js(t,s))||Js(t,`application/x.${i.id}`))return i;return null}function vf(e,t){if(!t)return null;for(const r of e)if(typeof t=="string"){if(Pf(t,r))return r}else if(ArrayBuffer.isView(t)){if(nn(t.buffer,t.byteOffset,r))return r}else if(t instanceof ArrayBuffer&&nn(t,0,r))return r;return null}function Pf(e,t){return t.testText?t.testText(e):(Array.isArray(t.tests)?t.tests:[t.tests]).some(i=>e.startsWith(i))}function nn(e,t,r){return(Array.isArray(r.tests)?r.tests:[r.tests]).some(s=>wf(e,t,r,s))}function wf(e,t,r,i){if(_s(i))return kl(i,e,i.byteLength);switch(typeof i){case"function":return i(Vo(e));case"string":const s=Fi(e,t,i.length);return i===s;default:return!1}}function ra(e,t=5){return typeof e=="string"?e.slice(0,t):ArrayBuffer.isView(e)?Fi(e.buffer,e.byteOffset,t):e instanceof ArrayBuffer?Fi(e,0,t):""}function Fi(e,t,r){if(e.byteLengthen(o,s):t!=null&&t.fetch?t==null?void 0:t.fetch:en}function Wf(e,t,r){if(r)return r;const i={fetch:sa(t,e),...e};if(i.url){const s=Wr(i.url);i.baseUrl=s,i.queryString=Jl(i.url),i.filename=Xo(s),i.baseUrl=Yo(s)}return Array.isArray(i.loaders)||(i.loaders=null),i}function $f(e,t){if(e&&!Array.isArray(e))return e;let r;if(e&&(r=Array.isArray(e)?e:[e]),t&&t.loaders){const i=Array.isArray(t.loaders)?t.loaders:[t.loaders];r=r?[...r,...i]:i}return r&&r.length?r:void 0}async function sr(e,t,r,i){t&&!Array.isArray(t)&&!Ts(t)&&(i=void 0,r=t,t=void 0),e=await e,r=r||{};const s=$r(e),o=$f(t,i),a=await yf(e,o,r);if(!a)return null;const c=hf(r,a,o,s);return i=Wf({url:s,_parse:sr,loaders:o},c,i||null),await zf(a,e,c,i)}async function zf(e,t,r,i){if(Dl(e),r=El(e.options,r),De(t)){const{ok:n,redirected:o,status:a,statusText:c,type:l,url:u}=t,h=Object.fromEntries(t.headers.entries());i.response={headers:h,ok:n,redirected:o,status:a,statusText:c,type:l,url:u}}t=await kf(t,e,r);const s=e;if(s.parseTextSync&&typeof t=="string")return s.parseTextSync(t,r,i);if(Fl(e,r))return await Ul(e,t,r,i,sr);if(s.parseText&&typeof t=="string")return await s.parseText(t,r,i);if(s.parse)return await s.parse(t,r,i);throw Te(!s.parseSync),new Error(`${e.id} loader - no parser found and worker is disabled`)}function jf(e){return ArrayBuffer.isView(e)&&!(e instanceof DataView)}function Hf(e){return Array.isArray(e)?e.length===0||typeof e[0]=="number":!1}function Vf(e){return jf(e)||Hf(e)}async function an(e,t,r,i){var c;let s,n;!Array.isArray(t)&&!Ts(t)?(s=[],n=t):(s=t,n=r);const o=sa(n);let a=e;return typeof e=="string"&&(a=await o(e)),Fe(e)&&(a=await o(e)),typeof e=="string"&&((c=xe(n||{}).core)!=null&&c.baseUrl||(n={...n,core:{...n==null?void 0:n.core,baseUrl:e}})),Array.isArray(s)?await sr(a,s,n):await sr(a,s,n)}const G=new xt({id:"deck"});let Ui={};function EA(e){Ui=e}function X(e,t,r,i){G.level>0&&Ui[e]&&Ui[e].call(null,t,r,i)}function Mt(e,t){var r;if(!e){const i=new Error(t||"shadertools: assertion failed.");throw(r=Error.captureStackTrace)==null||r.call(Error,i,Mt),i}}const ti={number:{type:"number",validate(e,t){return Number.isFinite(e)&&typeof t=="object"&&(t.max===void 0||e<=t.max)&&(t.min===void 0||e>=t.min)}},array:{type:"array",validate(e,t){return Array.isArray(e)||ArrayBuffer.isView(e)}}};function Xf(e){const t={};for(const[r,i]of Object.entries(e))t[r]=Yf(i);return t}function Yf(e){let t=cn(e);if(t!=="object")return{value:e,...ti[t],type:t};if(typeof e=="object")return e?e.type!==void 0?{...e,...ti[e.type],type:e.type}:e.value===void 0?{type:"object",value:e}:(t=cn(e.value),{...e,...ti[t],type:t}):{type:"object",value:null};throw new Error("props")}function cn(e){return Array.isArray(e)||ArrayBuffer.isView(e)?"array":typeof e}const Kf=`#ifdef MODULE_LOGDEPTH + logdepth_adjustPosition(gl_Position); +#endif +`,Qf=`#ifdef MODULE_MATERIAL + fragColor = material_filterColor(fragColor); +#endif + +#ifdef MODULE_LIGHTING + fragColor = lighting_filterColor(fragColor); +#endif + +#ifdef MODULE_FOG + fragColor = fog_filterColor(fragColor); +#endif + +#ifdef MODULE_PICKING + fragColor = picking_filterHighlightColor(fragColor); + fragColor = picking_filterPickingColor(fragColor); +#endif + +#ifdef MODULE_LOGDEPTH + logdepth_setFragDepth(); +#endif +`,qf={vertex:Kf,fragment:Qf},ln=/void\s+main\s*\([^)]*\)\s*\{\n?/,fn=/}\n?[^{}]*$/,ri=[],Jt="__LUMA_INJECT_DECLARATIONS__";function Zf(e){const t={vertex:{},fragment:{}};for(const r in e){let i=e[r];const s=Jf(r);typeof i=="string"&&(i={order:0,injection:i}),t[s][r]=i}return t}function Jf(e){const t=e.slice(0,2);switch(t){case"vs":return"vertex";case"fs":return"fragment";default:throw new Error(t)}}function nr(e,t,r,i=!1){const s=t==="vertex";for(const n in r){const o=r[n];o.sort((c,l)=>c.order-l.order),ri.length=o.length;for(let c=0,l=o.length;cc+a));break;case"vs:#main-end":s&&(e=e.replace(fn,c=>a+c));break;case"fs:#decl":s||(e=e.replace(Jt,a));break;case"fs:#main-start":s||(e=e.replace(ln,c=>c+a));break;case"fs:#main-end":s||(e=e.replace(fn,c=>a+c));break;default:e=e.replace(n,c=>c+a)}}return e=e.replace(Jt,""),i&&(e=e.replace(/\}\s*$/,n=>n+qf[t])),e}function or(e){e.map(t=>Gf(t))}function Gf(e){if(e.instance)return;or(e.dependencies||[]);const{propTypes:t={},deprecations:r=[],inject:i={}}=e,s={normalizedInjections:Zf(i),parsedDeprecations:eu(r)};t&&(s.propValidators=Xf(t)),e.instance=s;let n={};t&&(n=Object.entries(t).reduce((o,[a,c])=>{const l=c==null?void 0:c.value;return l&&(o[a]=l),o},{})),e.defaultUniforms={...e.defaultUniforms,...n}}function na(e,t,r){var i;(i=e.deprecations)==null||i.forEach(s=>{var n;(n=s.regex)!=null&&n.test(t)&&(s.deprecated?r.deprecated(s.old,s.new)():r.removed(s.old,s.new)())})}function eu(e){return e.forEach(t=>{switch(t.type){case"function":t.regex=new RegExp(`\\b${t.old}\\(`);break;default:t.regex=new RegExp(`${t.type} ${t.old};`)}}),e}function ys(e){or(e);const t={},r={};oa({modules:e,level:0,moduleMap:t,moduleDepth:r});const i=Object.keys(r).sort((s,n)=>r[n]-r[s]).map(s=>t[s]);return or(i),i}function oa(e){const{modules:t,level:r,moduleMap:i,moduleDepth:s}=e;if(r>=5)throw new Error("Possible loop in shader dependency graph");for(const n of t)i[n.name]=n,(s[n.name]===void 0||s[n.name]]+>)?\s+([A-Za-z0-9_]+)(?:\s*\[[^\]]+\])?\s*;/,ru=/((?:layout\s*\([^)]*\)\s*)*)uniform\s+([A-Za-z_][A-Za-z0-9_]*)\s*\{([\s\S]*?)\}\s*([A-Za-z_][A-Za-z0-9_]*)?\s*;/g;function aa(e){return`${e.name}Uniforms`}function iu(e,t){const r=t==="wgsl"?e.source:t==="vertex"?e.vs:e.fs;if(!r)return null;const i=aa(e);return au(r,t==="wgsl"?"wgsl":"glsl",i)}function su(e,t){const r=Object.keys(e.uniformTypes||{});if(!r.length)return null;const i=iu(e,t);return i?{moduleName:e.name,uniformBlockName:aa(e),stage:t,expectedUniformNames:r,actualUniformNames:i,matches:fu(r,i)}:null}function nu(e,t,r={}){var n,o;const i=su(e,t);if(!i||i.matches)return i;const s=uu(i);return(o=(n=r.log)==null?void 0:n.error)==null||o.call(n,s,i)(),r.throwOnError!==!1&&Mt(!1,s),i}function ca(e){var i;const t=[],r=hu(e);for(const s of r.matchAll(ru)){const n=((i=s[1])==null?void 0:i.trim())||null;t.push({blockName:s[2],body:s[3],instanceName:s[4]||null,layoutQualifier:n,hasLayoutQualifier:!!n,isStd140:!!(n&&/\blayout\s*\([^)]*\bstd140\b[^)]*\)/.exec(n))})}return t}function ou(e,t,r,i){var o;const s=ca(e).filter(a=>!a.isStd140),n=new Set;for(const a of s){if(n.has(a.blockName))continue;n.add(a.blockName);const c="",l=a.hasLayoutQualifier?`declares ${du(a.layoutQualifier)} instead of layout(std140)`:"does not declare layout(std140)",u=`${c}${t} shader uniform block ${a.blockName} ${l}. luma.gl host-side shader block packing assumes explicit layout(std140) for GLSL uniform blocks. Add \`layout(std140)\` to the block declaration.`;(o=r==null?void 0:r.warn)==null||o.call(r,u,a)()}return s}function au(e,t,r){const i=t==="wgsl"?cu(e,r):lu(e,r);if(!i)return null;const s=[];for(const n of i.split(` +`)){const o=n.replace(/\/\/.*$/,"").trim();if(!o||o.startsWith("#"))continue;const a=t==="wgsl"?o.match(/^([A-Za-z0-9_]+)\s*:/):o.match(tu);a&&s.push(a[1])}return s}function cu(e,t){const r=new RegExp(`\\bstruct\\s+${t}\\b`,"m").exec(e);if(!r)return null;const i=e.indexOf("{",r.index);if(i<0)return null;let s=0;for(let n=i;ni.blockName===t);return(r==null?void 0:r.body)||null}function fu(e,t){if(e.length!==t.length)return!1;for(let r=0;r!r.includes(a)),s=r.filter(a=>!t.includes(a)),n=[`Expected ${t.length} fields, found ${r.length}.`],o=gu(t,r);return o&&n.push(o),i.length&&n.push(`Missing from shader block (${i.length}): ${un(i)}.`),s.length&&n.push(`Unexpected in shader block (${s.length}): ${un(s)}.`),t.length<=12&&r.length<=12&&(i.length||s.length)&&(n.push(`Expected: ${t.join(", ")}.`),n.push(`Actual: ${r.join(", ")}.`)),`${e.moduleName}: ${e.stage} shader uniform block ${e.uniformBlockName} does not match module.uniformTypes. ${n.join(" ")}`}function hu(e){return e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"")}function du(e){return e.replace(/\s+/g," ").trim()}function gu(e,t){const r=Math.min(e.length,t.length);for(let i=0;it.length?`Shader block ends after field ${t.length}; expected next field ${e[t.length]}.`:t.length>e.length?`Shader block has extra field ${t.length}: ${t[e.length]}.`:null}function un(e,t=8){if(e.length<=t)return e.join(", ");const r=e.length-t;return`${e.slice(0,t).join(", ")}, ... (${r} more)`}function pu(e){switch(e==null?void 0:e.gpu.toLowerCase()){case"apple":return`#define APPLE_GPU +// Apple optimizes away the calculation necessary for emulated fp64 +#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1 +#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1 +// Intel GPU doesn't have full 32 bits precision in same cases, causes overflow +#define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1 +`;case"nvidia":return`#define NVIDIA_GPU +// Nvidia optimizes away the calculation necessary for emulated fp64 +#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1 +`;case"intel":return`#define INTEL_GPU +// Intel optimizes away the calculation necessary for emulated fp64 +#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1 +// Intel's built-in 'tan' function doesn't have acceptable precision +#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1 +// Intel GPU doesn't have full 32 bits precision in same cases, causes overflow +#define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1 +`;case"amd":return`#define AMD_GPU +`;default:return`#define DEFAULT_GPU +// Prevent driver from optimizing away the calculation necessary for emulated fp64 +#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1 +// Headless Chrome's software shader 'tan' function doesn't have acceptable precision +#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1 +// If the GPU doesn't have full 32 bits precision, will causes overflow +#define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1 +`}}function _u(e,t){var i;if(Number(((i=e.match(/^#version[ \t]+(\d+)/m))==null?void 0:i[1])||100)!==300)throw new Error("luma.gl v9 only supports GLSL 3.00 shader sources");switch(t){case"vertex":return e=hn(e,mu),e;case"fragment":return e=hn(e,bu),e;default:throw new Error(t)}}const la=[[/^(#version[ \t]+(100|300[ \t]+es))?[ \t]*\n/,`#version 300 es +`],[/\btexture(2D|2DProj|Cube)Lod(EXT)?\(/g,"textureLod("],[/\btexture(2D|2DProj|Cube)(EXT)?\(/g,"texture("]],mu=[...la,[Li("attribute"),"in $1"],[Li("varying"),"out $1"]],bu=[...la,[Li("varying"),"in $1"]];function hn(e,t){for(const[r,i]of t)e=e.replace(r,i);return e}function Li(e){return new RegExp(`\\b${e}[ \\t]+(\\w+[ \\t]+\\w+(\\[\\w+\\])?;)`,"g")}function fa(e,t){let r="";for(const i in e){const s=e[i];if(r+=`void ${s.signature} { +`,s.header&&(r+=` ${s.header}`),t[i]){const n=t[i];n.sort((o,a)=>o.order-a.order);for(const o of n)r+=` ${o.injection} +`}s.footer&&(r+=` ${s.footer}`),r+=`} +`}return r}function ua(e){const t={vertex:{},fragment:{}};for(const r of e){let i,s;typeof r!="string"?(i=r,s=i.hook):(i={},s=r),s=s.trim();const[n,o]=s.split(":"),a=s.replace(/\(.+/,""),c=Object.assign(i,{signature:o});switch(n){case"vs":t.vertex[a]=c;break;case"fs":t.fragment[a]=c;break;default:throw new Error(n)}}return t}function Tu(e,t){return{name:Au(e,t),language:"glsl",version:yu(e)}}function Au(e,t="unnamed"){const i=/#define[^\S\r\n]*SHADER_NAME[^\S\r\n]*([A-Za-z0-9_-]+)\s*/.exec(e);return i?i[1]:t}function yu(e){let t=100;const r=e.match(/[^\s]+/g);if(r&&r.length>=2&&r[0]==="#version"){const i=parseInt(r[1],10);Number.isFinite(i)&&(t=i)}if(t!==100&&t!==300)throw new Error(`Invalid GLSL version ${t}`);return t}const Q="(?:var<\\s*(uniform|storage(?:\\s*,\\s*[A-Za-z_][A-Za-z0-9_]*)?)\\s*>|var)\\s+([A-Za-z_][A-Za-z0-9_]*)",q="\\s*",St=[new RegExp(`@binding\\(\\s*(auto|\\d+)\\s*\\)${q}@group\\(\\s*(\\d+)\\s*\\)${q}${Q}`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)${q}@binding\\(\\s*(auto|\\d+)\\s*\\)${q}${Q}`,"g")],ki=[new RegExp(`@binding\\(\\s*(auto|\\d+)\\s*\\)${q}@group\\(\\s*(\\d+)\\s*\\)${q}${Q}`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)${q}@binding\\(\\s*(auto|\\d+)\\s*\\)${q}${Q}`,"g")],Ru=[new RegExp(`@binding\\(\\s*(\\d+)\\s*\\)${q}@group\\(\\s*(\\d+)\\s*\\)${q}${Q}`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)${q}@binding\\(\\s*(\\d+)\\s*\\)${q}${Q}`,"g")],Eu=[new RegExp(`@binding\\(\\s*(auto)\\s*\\)\\s*@group\\(\\s*(\\d+)\\s*\\)\\s*${Q}`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)\\s*@binding\\(\\s*(auto)\\s*\\)\\s*${Q}`,"g"),new RegExp(`@binding\\(\\s*(auto)\\s*\\)\\s*@group\\(\\s*(\\d+)\\s*\\)(?:[\\s\\n\\r]*@[A-Za-z_][^\\n\\r]*)*[\\s\\n\\r]*${Q}`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)\\s*@binding\\(\\s*(auto)\\s*\\)(?:[\\s\\n\\r]*@[A-Za-z_][^\\n\\r]*)*[\\s\\n\\r]*${Q}`,"g")];function Rs(e){const t=e.split("");let r=0,i=0,s=!1,n=!1,o=!1;for(;r0){if(a==="/"&&c==="*"){t[r]=" ",t[r+1]=" ",i++,r+=2;continue}if(a==="*"&&c==="/"){t[r]=" ",t[r+1]=" ",i--,r+=2;continue}a!==` +`&&a!=="\r"&&(t[r]=" "),r++;continue}if(a==='"'){n=!0,r++;continue}if(a==="/"&&c==="/"){t[r]=" ",t[r+1]=" ",s=!0,r+=2;continue}if(a==="/"&&c==="*"){t[r]=" ",t[r+1]=" ",i=1,r+=2;continue}r++}return t.join("")}function st(e,t){var s;const r=Rs(e),i=[];for(const n of t){n.lastIndex=0;let o;for(o=n.exec(r);o;){const a=n===t[0],c=o.index,l=o[0].length;i.push({match:e.slice(c,c+l),index:c,length:l,bindingToken:o[a?1:2],groupToken:o[a?2:1],accessDeclaration:(s=o[3])==null?void 0:s.trim(),name:o[4]}),o=n.exec(r)}}return i.sort((n,o)=>n.index-o.index)}function ha(e,t,r){const i=st(e,t);if(!i.length)return e;let s="",n=0;for(const o of i)s+=e.slice(n,o.index),s+=r(o),n=o.index+o.length;return s+=e.slice(n),s}function da(e){return/@binding\(\s*auto\s*\)/.test(Rs(e))}function Su(e,t){return st(e,t===St||t===ki?Eu:t).find(i=>i.bindingToken==="auto")}const dn=[new RegExp(`@binding\\(\\s*(\\d+)\\s*\\)\\s*@group\\(\\s*(\\d+)\\s*\\)\\s*${Q}\\s*:\\s*([^;]+);`,"g"),new RegExp(`@group\\(\\s*(\\d+)\\s*\\)\\s*@binding\\(\\s*(\\d+)\\s*\\)\\s*${Q}\\s*:\\s*([^;]+);`,"g")];function ga(e,t=[]){var n;const r=Rs(e),i=new Map;for(const o of t)i.set(gn(o.name,o.group,o.location),o.moduleName);const s=[];for(const o of dn){o.lastIndex=0;let a;for(a=o.exec(r);a;){const c=o===dn[0],l=Number(a[c?1:2]),u=Number(a[c?2:1]),h=(n=a[3])==null?void 0:n.trim(),d=a[4],g=a[5].trim(),p=i.get(gn(d,u,l));s.push(Cu({name:d,group:u,binding:l,owner:p?"module":"application",moduleName:p,accessDeclaration:h,resourceType:g})),a=o.exec(r)}}return s.sort((o,a)=>o.group!==a.group?o.group-a.group:o.binding!==a.binding?o.binding-a.binding:o.name.localeCompare(a.name))}function Cu(e){const t={name:e.name,group:e.group,binding:e.binding,owner:e.owner,kind:"unknown",moduleName:e.moduleName,resourceType:e.resourceType};if(e.accessDeclaration){const r=e.accessDeclaration.split(",").map(i=>i.trim());if(r[0]==="uniform")return{...t,kind:"uniform",access:"uniform"};if(r[0]==="storage"){const i=r[1]||"read_write";return{...t,kind:i==="read"?"read-only-storage":"storage",access:i}}}return e.resourceType==="sampler"||e.resourceType==="sampler_comparison"?{...t,kind:"sampler",samplerKind:e.resourceType==="sampler_comparison"?"comparison":"filtering"}:e.resourceType.startsWith("texture_storage_")?{...t,kind:"storage-texture",access:Pu(e.resourceType),viewDimension:pn(e.resourceType)}:e.resourceType.startsWith("texture_")?{...t,kind:"texture",viewDimension:pn(e.resourceType),sampleType:vu(e.resourceType),multisampled:e.resourceType.startsWith("texture_multisampled_")}:t}function gn(e,t,r){return`${t}:${r}:${e}`}function pn(e){if(e.includes("cube_array"))return"cube-array";if(e.includes("2d_array"))return"2d-array";if(e.includes("cube"))return"cube";if(e.includes("3d"))return"3d";if(e.includes("2d"))return"2d";if(e.includes("1d"))return"1d"}function vu(e){if(e.startsWith("texture_depth_"))return"depth";if(e.includes(""))return"sint";if(e.includes(""))return"uint";if(e.includes(""))return"float"}function Pu(e){const t=/,\s*([A-Za-z_][A-Za-z0-9_]*)\s*>$/.exec(e);return t==null?void 0:t[1]}const Es=` + +${Jt} +`,Ct=100,wu=`precision highp float; +`;function Ou(e){const t=ys(e.modules||[]),{source:r,bindingAssignments:i}=Mu(e.platformInfo,{...e,source:e.source,stage:"vertex",modules:t});return{source:r,getUniforms:pa(t),bindingAssignments:i,bindingTable:ga(r,i)}}function xu(e){const{vs:t,fs:r}=e,i=ys(e.modules||[]);return{vs:_n(e.platformInfo,{...e,source:t,stage:"vertex",modules:i}),fs:_n(e.platformInfo,{...e,source:r,stage:"fragment",modules:i}),getUniforms:pa(i)}}function Mu(e,t){var T;const{source:r,stage:i,modules:s,hookFunctions:n=[],inject:o={},log:a}=t;Mt(typeof r=="string","shader source must be a string");const c=r;let l="";const u=ua(n),h={},d={},g={};for(const y in o){const E=typeof o[y]=="string"?{injection:o[y],order:0}:o[y],S=/^(v|f)s:(#)?([\w-]+)$/.exec(y);if(S){const C=S[2],v=S[3];C?v==="decl"?d[y]=[E]:g[y]=[E]:h[y]=[E]}else g[y]=[E]}const p=s,_=Bu(c),m=Nu(_.source),b=Lu(p,t._bindingRegistry,m),R=[];for(const y of p){a&&na(y,c,a);const E=Du(_a(y,"wgsl",a),y,{usedBindingsByGroup:m,bindingRegistry:t._bindingRegistry,reservedBindingKeysByGroup:b});R.push(...E.bindingAssignments);const S=E.source;l+=S;const C=((T=y.injections)==null?void 0:T[i])||{};for(const v in C){const w=/^(v|f)s:#([\w-]+)$/.exec(v);if(w){const B=w[2]==="decl"?d:g;B[v]=B[v]||[],B[v].push(C[v])}else h[v]=h[v]||[],h[v].push(C[v])}}return l+=Es,l=nr(l,i,d),l+=fa(u[i],h),l+=ju(R),l+=_.source,l=nr(l,i,g),zu(l),{source:l,bindingAssignments:R}}function _n(e,t){var S;const{source:r,stage:i,language:s="glsl",modules:n,defines:o={},hookFunctions:a=[],inject:c={},prologue:l=!0,log:u}=t;Mt(typeof r=="string","shader source must be a string");const h=s==="glsl"?Tu(r).version:-1,d=e.shaderLanguageVersion,g=h===100?"#version 100":"#version 300 es",_=r.split(` +`).slice(1).join(` +`),m={};n.forEach(C=>{Object.assign(m,C.defines)}),Object.assign(m,o);let b="";switch(s){case"wgsl":break;case"glsl":b=l?`${g} + +// ----- PROLOGUE ------------------------- +${`#define SHADER_TYPE_${i.toUpperCase()}`} + +${pu(e)} +${i==="fragment"?wu:""} + +// ----- APPLICATION DEFINES ------------------------- + +${Iu(m)} + +`:`${g} +`;break}const R=ua(a),T={},y={},E={};for(const C in c){const v=typeof c[C]=="string"?{injection:c[C],order:0}:c[C],w=/^(v|f)s:(#)?([\w-]+)$/.exec(C);if(w){const x=w[2],B=w[3];x?B==="decl"?y[C]=[v]:E[C]=[v]:T[C]=[v]}else E[C]=[v]}for(const C of n){u&&na(C,_,u);const v=_a(C,i,u);b+=v;const w=((S=C.instance)==null?void 0:S.normalizedInjections[i])||{};for(const x in w){const B=/^(v|f)s:#([\w-]+)$/.exec(x);if(B){const H=B[2]==="decl"?y:E;H[x]=H[x]||[],H[x].push(w[x])}else T[x]=T[x]||[],T[x].push(w[x])}}return b+="// ----- MAIN SHADER SOURCE -------------------------",b+=Es,b=nr(b,i,y),b+=fa(R[i],T),b+=_,b=nr(b,i,E),s==="glsl"&&h!==d&&(b=_u(b,i)),s==="glsl"&&ou(b,i,u),b.trim()}function pa(e){return function(r){var s;const i={};for(const n of e){const o=(s=n.getUniforms)==null?void 0:s.call(n,r,i);Object.assign(i,o)}return i}}function Iu(e={}){let t="";for(const r in e){const i=e[r];(i||Number.isFinite(i))&&(t+=`#define ${r.toUpperCase()} ${e[r]} +`)}return t}function _a(e,t,r){let i;switch(t){case"vertex":i=e.vs||"";break;case"fragment":i=e.fs||"";break;case"wgsl":i=e.source||"";break;default:Mt(!1)}if(!e.name)throw new Error("Shader module must have a name");nu(e,t,{log:r});const s=e.name.toUpperCase().replace(/[^0-9a-z]/gi,"_");let n=`// ----- MODULE ${e.name} --------------- + +`;return t!=="wgsl"&&(n+=`#define MODULE_${s} +`),n+=`${i} +`,n}function Nu(e){const t=new Map;for(const r of st(e,Ru)){const i=Number(r.bindingToken),s=Number(r.groupToken);Ss(s,i,r.name),qe(t,s,i,`application binding "${r.name}"`)}return t}function Bu(e){const t=st(e,ki),r=new Map;for(const n of t){if(n.bindingToken==="auto")continue;const o=Number(n.bindingToken),a=Number(n.groupToken);Ss(a,o,n.name),qe(r,a,o,`application binding "${n.name}"`)}const i={sawSupportedBindingDeclaration:t.length>0},s=ha(e,ki,n=>Uu(n,r,i));if(da(e)&&!i.sawSupportedBindingDeclaration)throw new Error('Unsupported @binding(auto) declaration form in application WGSL. Use adjacent "@group(N)" and "@binding(auto)" decorators followed by a bindable "var" declaration.');return{source:s}}function Du(e,t,r){const i=[],n={sawSupportedBindingDeclaration:st(e,St).length>0,nextHintedBindingLocation:typeof t.firstBindingSlot=="number"?t.firstBindingSlot:null},o=ha(e,St,a=>Fu(a,{module:t,context:r,bindingAssignments:i,relocationState:n}));if(da(e)&&!n.sawSupportedBindingDeclaration)throw new Error(`Unsupported @binding(auto) declaration form in module "${t.name}". Use adjacent "@group(N)" and "@binding(auto)" decorators followed by a bindable "var" declaration.`);return{source:o,bindingAssignments:i}}function Fu(e,t){var d,g;const{module:r,context:i,bindingAssignments:s,relocationState:n}=t,{match:o,bindingToken:a,groupToken:c,name:l}=e,u=Number(c);if(a==="auto"){const p=ma(u,r.name,l),_=(d=i.bindingRegistry)==null?void 0:d.get(p),m=_!==void 0?_:n.nextHintedBindingLocation===null?bn(u,i.usedBindingsByGroup):bn(u,i.usedBindingsByGroup,n.nextHintedBindingLocation);return mn(r.name,u,m,l),_!==void 0&&ku(i.reservedBindingKeysByGroup,u,m,p)?(s.push({moduleName:r.name,name:l,group:u,location:m}),o.replace(/@binding\(\s*auto\s*\)/,`@binding(${m})`)):(qe(i.usedBindingsByGroup,u,m,`module "${r.name}" binding "${l}"`),(g=i.bindingRegistry)==null||g.set(p,m),s.push({moduleName:r.name,name:l,group:u,location:m}),n.nextHintedBindingLocation!==null&&_===void 0&&(n.nextHintedBindingLocation=m+1),o.replace(/@binding\(\s*auto\s*\)/,`@binding(${m})`))}const h=Number(a);return mn(r.name,u,h,l),qe(i.usedBindingsByGroup,u,h,`module "${r.name}" binding "${l}"`),s.push({moduleName:r.name,name:l,group:u,location:h}),o}function Uu(e,t,r){const{match:i,bindingToken:s,groupToken:n,name:o}=e,a=Number(n);if(s==="auto"){const c=$u(a,t);return Ss(a,c,o),qe(t,a,c,`application binding "${o}"`),i.replace(/@binding\(\s*auto\s*\)/,`@binding(${c})`)}return r.sawSupportedBindingDeclaration=!0,i}function Lu(e,t,r){const i=new Map;if(!t)return i;for(const s of e)for(const n of Wu(s)){const o=ma(n.group,s.name,n.name),a=t.get(o);if(a!==void 0){const c=i.get(n.group)||new Map,l=c.get(a);if(l&&l!==o)throw new Error(`Duplicate WGSL binding reservation for modules "${l}" and "${o}": group ${n.group}, binding ${a}.`);qe(r,n.group,a,`registered module binding "${o}"`),c.set(a,o),i.set(n.group,c)}}return i}function ku(e,t,r,i){const s=e.get(t);if(!s)return!1;const n=s.get(r);if(!n)return!1;if(n!==i)throw new Error(`Registered module binding "${i}" collided with "${n}": group ${t}, binding ${r}.`);return!0}function Wu(e){const t=[],r=e.source||"";for(const i of st(r,St))t.push({name:i.name,group:Number(i.groupToken)});return t}function Ss(e,t,r){if(e===0&&t>=Ct)throw new Error(`Application binding "${r}" in group 0 uses reserved binding ${t}. Application-owned explicit group-0 bindings must stay below ${Ct}.`)}function mn(e,t,r,i){if(t===0&&r0?Math.max(...i)+1:0);for(;i.has(s);)s++;return s}function $u(e,t){const r=t.get(e)||new Set;let i=0;for(;r.has(i);)i++;return i}function zu(e){const t=Su(e,St);if(!t)return;const r=Hu(e,t.index);throw r?new Error(`Unresolved @binding(auto) for module "${r}" binding "${t.name}" remained in assembled WGSL source.`):Vu(e,t.index)?new Error(`Unresolved @binding(auto) for application binding "${t.name}" remained in assembled WGSL source.`):new Error(`Unresolved @binding(auto) remained in assembled WGSL source near "${Xu(t.match)}".`)}function ju(e){if(e.length===0)return"";let t=`// ----- MODULE WGSL BINDING ASSIGNMENTS --------------- +`;for(const r of e)t+=`// ${r.moduleName}.${r.name} -> @group(${r.group}) @binding(${r.location}) +`;return t+=` +`,t}function ma(e,t,r){return`${e}:${t}:${r}`}function Hu(e,t){const r=/^\/\/ ----- MODULE ([^\n]+) ---------------$/gm;let i,s;for(s=r.exec(e);s&&s.index<=t;)i=s[1],s=r.exec(e);return i}function Vu(e,t){const r=e.indexOf(Es);return r>=0?t>r:!0}function Xu(e){return e.replace(/\s+/g," ").trim()}const Cs="([a-zA-Z_][a-zA-Z0-9_]*)",Yu=new RegExp(`^\\s*\\#\\s*ifdef\\s*${Cs}\\s*$`),Ku=new RegExp(`^\\s*\\#\\s*ifndef\\s*${Cs}\\s*(?:\\/\\/.*)?$`),Qu=/^\s*\#\s*else\s*(?:\/\/.*)?$/,qu=/^\s*\#\s*endif\s*$/,Zu=new RegExp(`^\\s*\\#\\s*ifdef\\s*${Cs}\\s*(?:\\/\\/.*)?$`),Ju=/^\s*\#\s*endif\s*(?:\/\/.*)?$/;function Gu(e,t){var o,a;const r=e.split(` +`),i=[],s=[];let n=!0;for(const c of r){const l=c.match(Zu)||c.match(Yu),u=c.match(Ku),h=c.match(Qu),d=c.match(Ju)||c.match(qu);if(l||u){const g=(o=l||u)==null?void 0:o[1],p=!!((a=t==null?void 0:t.defines)!=null&&a[g]),_=l?p:!p,m=n&&_;s.push({parentActive:n,branchTaken:_,active:m}),n=m}else if(h){const g=s[s.length-1];if(!g)throw new Error("Encountered #else without matching #ifdef or #ifndef");g.active=g.parentActive&&!g.branchTaken,g.branchTaken=!0,n=g.active}else d?(s.pop(),n=s.length?s[s.length-1].active:!0):n&&i.push(c)}if(s.length>0)throw new Error("Unterminated conditional block in shader source");return i.join(` +`)}const Re=class Re{constructor(){f(this,"_hookFunctions",[]);f(this,"_defaultModules",[]);f(this,"_wgslBindingRegistry",new Map)}static getDefaultShaderAssembler(){return Re.defaultShaderAssembler=Re.defaultShaderAssembler||new Re,Re.defaultShaderAssembler}addDefaultModule(t){this._defaultModules.find(r=>r.name===(typeof t=="string"?t:t.name))||this._defaultModules.push(t)}removeDefaultModule(t){const r=typeof t=="string"?t:t.name;this._defaultModules=this._defaultModules.filter(i=>i.name!==r)}addShaderHook(t,r){r&&(t=Object.assign(r,{hook:t})),this._hookFunctions.push(t)}assembleWGSLShader(t){const r=this._getModuleList(t.modules),i=this._hookFunctions,{source:s,getUniforms:n,bindingAssignments:o}=Ou({...t,source:t.source,_bindingRegistry:this._wgslBindingRegistry,modules:r,hookFunctions:i}),a={...r.reduce((l,u)=>(Object.assign(l,u.defines),l),{}),...t.defines},c=t.platformInfo.shaderLanguage==="wgsl"?Gu(s,{defines:a}):s;return{source:c,getUniforms:n,modules:r,bindingAssignments:o,bindingTable:ga(c,o)}}assembleGLSLShaderPair(t){const r=this._getModuleList(t.modules),i=this._hookFunctions;return{...xu({...t,vs:t.vs,fs:t.fs,modules:r,hookFunctions:i}),modules:r}}_getModuleList(t=[]){const r=new Array(this._defaultModules.length+t.length),i={};let s=0;for(let n=0,o=this._defaultModules.length;nr*oh,t)}function CA(e,t){return vs(e,r=>r*nh,t)}function ar(e,t,r){return vs(e,i=>Math.max(t,Math.min(r,i)))}function ba(e,t,r){return Ze(e)?e.map((i,s)=>ba(i,t[s],r)):r*t+(1-r)*e}function cr(e,t,r){const i=Z.EPSILON;try{if(e===t)return!0;if(Ze(e)&&Ze(t)){if(e.length!==t.length)return!1;for(let s=0;s0?", ":"")+ch(this[i],t);return`${t.printTypes?this.constructor.name:""}[${r}]`}equals(t){if(!t||this.length!==t.length)return!1;for(let r=0;r=0&&t=0&&tMath.PI*2)throw Error("expected radians")}function ed(e,t,r,i,s,n){const o=2*n/(r-t),a=2*n/(s-i),c=(r+t)/(r-t),l=(s+i)/(s-i),u=-1,h=-1,d=-2*n;return e[0]=o,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=a,e[6]=0,e[7]=0,e[8]=c,e[9]=l,e[10]=u,e[11]=h,e[12]=0,e[13]=0,e[14]=d,e[15]=0,e}function Ca(e,t=[],r=0){const i=Math.fround(e),s=e-i;return t[r]=i,t[r+1]=s,t}function td(e){return e-Math.fround(e)}function rd(e){const t=new Float32Array(32);for(let r=0;r<4;++r)for(let i=0;i<4;++i){const s=r*4+i;Ca(e[i*4+r],t,s*2)}return t}function va(e,t=!0){return e??t}function Pa(e=[0,0,0],t=!0){return t?e.map(r=>r/255):[...e]}function id(e,t=!0){const r=Pa(e.slice(0,3),t),i=Number.isFinite(e[3]),s=i?e[3]:1;return[r[0],r[1],r[2],t&&i?s/255:s]}const sd=`#ifdef LUMA_FP32_TAN_PRECISION_WORKAROUND + +// All these functions are for substituting tan() function from Intel GPU only +const float TWO_PI = 6.2831854820251465; +const float PI_2 = 1.5707963705062866; +const float PI_16 = 0.1963495463132858; + +const float SIN_TABLE_0 = 0.19509032368659973; +const float SIN_TABLE_1 = 0.3826834261417389; +const float SIN_TABLE_2 = 0.5555702447891235; +const float SIN_TABLE_3 = 0.7071067690849304; + +const float COS_TABLE_0 = 0.9807852506637573; +const float COS_TABLE_1 = 0.9238795042037964; +const float COS_TABLE_2 = 0.8314695954322815; +const float COS_TABLE_3 = 0.7071067690849304; + +const float INVERSE_FACTORIAL_3 = 1.666666716337204e-01; // 1/3! +const float INVERSE_FACTORIAL_5 = 8.333333767950535e-03; // 1/5! +const float INVERSE_FACTORIAL_7 = 1.9841270113829523e-04; // 1/7! +const float INVERSE_FACTORIAL_9 = 2.75573188446287533e-06; // 1/9! + +float sin_taylor_fp32(float a) { + float r, s, t, x; + + if (a == 0.0) { + return 0.0; + } + + x = -a * a; + s = a; + r = a; + + r = r * x; + t = r * INVERSE_FACTORIAL_3; + s = s + t; + + r = r * x; + t = r * INVERSE_FACTORIAL_5; + s = s + t; + + r = r * x; + t = r * INVERSE_FACTORIAL_7; + s = s + t; + + r = r * x; + t = r * INVERSE_FACTORIAL_9; + s = s + t; + + return s; +} + +void sincos_taylor_fp32(float a, out float sin_t, out float cos_t) { + if (a == 0.0) { + sin_t = 0.0; + cos_t = 1.0; + } + sin_t = sin_taylor_fp32(a); + cos_t = sqrt(1.0 - sin_t * sin_t); +} + +float tan_taylor_fp32(float a) { + float sin_a; + float cos_a; + + if (a == 0.0) { + return 0.0; + } + + // 2pi range reduction + float z = floor(a / TWO_PI); + float r = a - TWO_PI * z; + + float t; + float q = floor(r / PI_2 + 0.5); + int j = int(q); + + if (j < -2 || j > 2) { + return 1.0 / 0.0; + } + + t = r - PI_2 * q; + + q = floor(t / PI_16 + 0.5); + int k = int(q); + int abs_k = int(abs(float(k))); + + if (abs_k > 4) { + return 1.0 / 0.0; + } else { + t = t - PI_16 * q; + } + + float u = 0.0; + float v = 0.0; + + float sin_t, cos_t; + float s, c; + sincos_taylor_fp32(t, sin_t, cos_t); + + if (k == 0) { + s = sin_t; + c = cos_t; + } else { + if (abs(float(abs_k) - 1.0) < 0.5) { + u = COS_TABLE_0; + v = SIN_TABLE_0; + } else if (abs(float(abs_k) - 2.0) < 0.5) { + u = COS_TABLE_1; + v = SIN_TABLE_1; + } else if (abs(float(abs_k) - 3.0) < 0.5) { + u = COS_TABLE_2; + v = SIN_TABLE_2; + } else if (abs(float(abs_k) - 4.0) < 0.5) { + u = COS_TABLE_3; + v = SIN_TABLE_3; + } + if (k > 0) { + s = u * sin_t + v * cos_t; + c = u * cos_t - v * sin_t; + } else { + s = u * sin_t - v * cos_t; + c = u * cos_t + v * sin_t; + } + } + + if (j == 0) { + sin_a = s; + cos_a = c; + } else if (j == 1) { + sin_a = c; + cos_a = -s; + } else if (j == -1) { + sin_a = -c; + cos_a = s; + } else { + sin_a = -s; + cos_a = -c; + } + return sin_a / cos_a; +} +#endif + +float tan_fp32(float a) { +#ifdef LUMA_FP32_TAN_PRECISION_WORKAROUND + return tan_taylor_fp32(a); +#else + return tan(a); +#endif +} +`,nd={name:"fp32",vs:sd},Rn=` +layout(std140) uniform fp64arithmeticUniforms { + uniform float ONE; + uniform float SPLIT; +} fp64; + +/* +About LUMA_FP64_CODE_ELIMINATION_WORKAROUND + +The purpose of this workaround is to prevent shader compilers from +optimizing away necessary arithmetic operations by swapping their sequences +or transform the equation to some 'equivalent' form. + +These helpers implement Dekker/Veltkamp-style error tracking. If the compiler +folds constants or reassociates the arithmetic, the high/low split can stop +tracking the rounding error correctly. That failure mode tends to look fine in +simple coordinate setup, but then breaks down inside iterative arithmetic such +as fp64 Mandelbrot loops. + +The method is to multiply an artifical variable, ONE, which will be known to +the compiler to be 1 only at runtime. The whole expression is then represented +as a polynomial with respective to ONE. In the coefficients of all terms, only one a +and one b should appear + +err = (a + b) * ONE^6 - a * ONE^5 - (a + b) * ONE^4 + a * ONE^3 - b - (a + b) * ONE^2 + a * ONE +*/ + +float prevent_fp64_optimization(float value) { +#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) + return value + fp64.ONE * 0.0; +#else + return value; +#endif +} + +// Divide float number to high and low floats to extend fraction bits +vec2 split(float a) { + // Keep SPLIT as a runtime uniform so the compiler cannot fold the Dekker + // split into a constant expression and reassociate the recovery steps. + float split = prevent_fp64_optimization(fp64.SPLIT); + float t = prevent_fp64_optimization(a * split); + float temp = t - a; + float a_hi = t - temp; + float a_lo = a - a_hi; + return vec2(a_hi, a_lo); +} + +// Divide float number again when high float uses too many fraction bits +vec2 split2(vec2 a) { + vec2 b = split(a.x); + b.y += a.y; + return b; +} + +// Special sum operation when a > b +vec2 quickTwoSum(float a, float b) { +#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) + float sum = (a + b) * fp64.ONE; + float err = b - (sum - a) * fp64.ONE; +#else + float sum = a + b; + float err = b - (sum - a); +#endif + return vec2(sum, err); +} + +// General sum operation +vec2 twoSum(float a, float b) { + float s = (a + b); +#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) + float v = (s * fp64.ONE - a) * fp64.ONE; + float err = (a - (s - v) * fp64.ONE) * fp64.ONE * fp64.ONE * fp64.ONE + (b - v); +#else + float v = s - a; + float err = (a - (s - v)) + (b - v); +#endif + return vec2(s, err); +} + +vec2 twoSub(float a, float b) { + float s = (a - b); +#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) + float v = (s * fp64.ONE - a) * fp64.ONE; + float err = (a - (s - v) * fp64.ONE) * fp64.ONE * fp64.ONE * fp64.ONE - (b + v); +#else + float v = s - a; + float err = (a - (s - v)) - (b + v); +#endif + return vec2(s, err); +} + +vec2 twoSqr(float a) { + float prod = a * a; + vec2 a_fp64 = split(a); +#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) + float err = ((a_fp64.x * a_fp64.x - prod) * fp64.ONE + 2.0 * a_fp64.x * + a_fp64.y * fp64.ONE * fp64.ONE) + a_fp64.y * a_fp64.y * fp64.ONE * fp64.ONE * fp64.ONE; +#else + float err = ((a_fp64.x * a_fp64.x - prod) + 2.0 * a_fp64.x * a_fp64.y) + a_fp64.y * a_fp64.y; +#endif + return vec2(prod, err); +} + +vec2 twoProd(float a, float b) { + float prod = a * b; + vec2 a_fp64 = split(a); + vec2 b_fp64 = split(b); + // twoProd is especially sensitive because mul_fp64 and div_fp64 both depend + // on the split terms and cross terms staying in the original evaluation + // order. If the compiler folds or reassociates them, the low part tends to + // collapse to zero or NaN on some drivers. + float highProduct = prevent_fp64_optimization(a_fp64.x * b_fp64.x); + float crossProduct1 = prevent_fp64_optimization(a_fp64.x * b_fp64.y); + float crossProduct2 = prevent_fp64_optimization(a_fp64.y * b_fp64.x); + float lowProduct = prevent_fp64_optimization(a_fp64.y * b_fp64.y); +#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) + float err1 = (highProduct - prod) * fp64.ONE; + float err2 = crossProduct1 * fp64.ONE * fp64.ONE; + float err3 = crossProduct2 * fp64.ONE * fp64.ONE * fp64.ONE; + float err4 = lowProduct * fp64.ONE * fp64.ONE * fp64.ONE * fp64.ONE; +#else + float err1 = highProduct - prod; + float err2 = crossProduct1; + float err3 = crossProduct2; + float err4 = lowProduct; +#endif + float err = ((err1 + err2) + err3) + err4; + return vec2(prod, err); +} + +vec2 sum_fp64(vec2 a, vec2 b) { + vec2 s, t; + s = twoSum(a.x, b.x); + t = twoSum(a.y, b.y); + s.y += t.x; + s = quickTwoSum(s.x, s.y); + s.y += t.y; + s = quickTwoSum(s.x, s.y); + return s; +} + +vec2 sub_fp64(vec2 a, vec2 b) { + vec2 s, t; + s = twoSub(a.x, b.x); + t = twoSub(a.y, b.y); + s.y += t.x; + s = quickTwoSum(s.x, s.y); + s.y += t.y; + s = quickTwoSum(s.x, s.y); + return s; +} + +vec2 mul_fp64(vec2 a, vec2 b) { + vec2 prod = twoProd(a.x, b.x); + // y component is for the error + prod.y += a.x * b.y; +#if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND) + prod = split2(prod); +#endif + prod = quickTwoSum(prod.x, prod.y); + prod.y += a.y * b.x; +#if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND) + prod = split2(prod); +#endif + prod = quickTwoSum(prod.x, prod.y); + return prod; +} + +vec2 div_fp64(vec2 a, vec2 b) { + float xn = 1.0 / b.x; +#if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND) + vec2 yn = mul_fp64(a, vec2(xn, 0)); +#else + vec2 yn = a * xn; +#endif + float diff = (sub_fp64(a, mul_fp64(b, yn))).x; + vec2 prod = twoProd(xn, diff); + return sum_fp64(yn, prod); +} + +vec2 sqrt_fp64(vec2 a) { + if (a.x == 0.0 && a.y == 0.0) return vec2(0.0, 0.0); + if (a.x < 0.0) return vec2(0.0 / 0.0, 0.0 / 0.0); + + float x = 1.0 / sqrt(a.x); + float yn = a.x * x; +#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) + vec2 yn_sqr = twoSqr(yn) * fp64.ONE; +#else + vec2 yn_sqr = twoSqr(yn); +#endif + float diff = sub_fp64(a, yn_sqr).x; + vec2 prod = twoProd(x * 0.5, diff); +#if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND) + return sum_fp64(split(yn), prod); +#else + return sum_fp64(vec2(yn, 0.0), prod); +#endif +} +`,od=`struct Fp64ArithmeticUniforms { + ONE: f32, + SPLIT: f32, +}; + +@group(0) @binding(auto) var fp64arithmetic : Fp64ArithmeticUniforms; + +fn fp64_nan(seed: f32) -> f32 { + let nanBits = 0x7fc00000u | select(0u, 1u, seed < 0.0); + return bitcast(nanBits); +} + +fn fp64_runtime_zero() -> f32 { + return fp64arithmetic.ONE * 0.0; +} + +fn prevent_fp64_optimization(value: f32) -> f32 { +#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND + return value + fp64_runtime_zero(); +#else + return value; +#endif +} + +fn split(a: f32) -> vec2f { + let splitValue = prevent_fp64_optimization(fp64arithmetic.SPLIT + fp64_runtime_zero()); + let t = prevent_fp64_optimization(a * splitValue); + let temp = prevent_fp64_optimization(t - a); + let aHi = prevent_fp64_optimization(t - temp); + let aLo = prevent_fp64_optimization(a - aHi); + return vec2f(aHi, aLo); +} + +fn split2(a: vec2f) -> vec2f { + var b = split(a.x); + b.y = b.y + a.y; + return b; +} + +fn quickTwoSum(a: f32, b: f32) -> vec2f { +#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND + let sum = prevent_fp64_optimization((a + b) * fp64arithmetic.ONE); + let err = prevent_fp64_optimization(b - (sum - a) * fp64arithmetic.ONE); +#else + let sum = prevent_fp64_optimization(a + b); + let err = prevent_fp64_optimization(b - (sum - a)); +#endif + return vec2f(sum, err); +} + +fn twoSum(a: f32, b: f32) -> vec2f { + let s = prevent_fp64_optimization(a + b); +#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND + let v = prevent_fp64_optimization((s * fp64arithmetic.ONE - a) * fp64arithmetic.ONE); + let err = + prevent_fp64_optimization((a - (s - v) * fp64arithmetic.ONE) * + fp64arithmetic.ONE * + fp64arithmetic.ONE * + fp64arithmetic.ONE) + + prevent_fp64_optimization(b - v); +#else + let v = prevent_fp64_optimization(s - a); + let err = prevent_fp64_optimization(a - (s - v)) + prevent_fp64_optimization(b - v); +#endif + return vec2f(s, err); +} + +fn twoSub(a: f32, b: f32) -> vec2f { + let s = prevent_fp64_optimization(a - b); +#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND + let v = prevent_fp64_optimization((s * fp64arithmetic.ONE - a) * fp64arithmetic.ONE); + let err = + prevent_fp64_optimization((a - (s - v) * fp64arithmetic.ONE) * + fp64arithmetic.ONE * + fp64arithmetic.ONE * + fp64arithmetic.ONE) - + prevent_fp64_optimization(b + v); +#else + let v = prevent_fp64_optimization(s - a); + let err = prevent_fp64_optimization(a - (s - v)) - prevent_fp64_optimization(b + v); +#endif + return vec2f(s, err); +} + +fn twoSqr(a: f32) -> vec2f { + let prod = prevent_fp64_optimization(a * a); + let aFp64 = split(a); + let highProduct = prevent_fp64_optimization(aFp64.x * aFp64.x); + let crossProduct = prevent_fp64_optimization(2.0 * aFp64.x * aFp64.y); + let lowProduct = prevent_fp64_optimization(aFp64.y * aFp64.y); +#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND + let err = + (prevent_fp64_optimization(highProduct - prod) * fp64arithmetic.ONE + + crossProduct * fp64arithmetic.ONE * fp64arithmetic.ONE) + + lowProduct * fp64arithmetic.ONE * fp64arithmetic.ONE * fp64arithmetic.ONE; +#else + let err = ((prevent_fp64_optimization(highProduct - prod) + crossProduct) + lowProduct); +#endif + return vec2f(prod, err); +} + +fn twoProd(a: f32, b: f32) -> vec2f { + let prod = prevent_fp64_optimization(a * b); + let aFp64 = split(a); + let bFp64 = split(b); + let highProduct = prevent_fp64_optimization(aFp64.x * bFp64.x); + let crossProduct1 = prevent_fp64_optimization(aFp64.x * bFp64.y); + let crossProduct2 = prevent_fp64_optimization(aFp64.y * bFp64.x); + let lowProduct = prevent_fp64_optimization(aFp64.y * bFp64.y); +#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND + let err1 = (highProduct - prod) * fp64arithmetic.ONE; + let err2 = crossProduct1 * fp64arithmetic.ONE * fp64arithmetic.ONE; + let err3 = crossProduct2 * fp64arithmetic.ONE * fp64arithmetic.ONE * fp64arithmetic.ONE; + let err4 = + lowProduct * + fp64arithmetic.ONE * + fp64arithmetic.ONE * + fp64arithmetic.ONE * + fp64arithmetic.ONE; +#else + let err1 = highProduct - prod; + let err2 = crossProduct1; + let err3 = crossProduct2; + let err4 = lowProduct; +#endif + let err12InputA = prevent_fp64_optimization(err1); + let err12InputB = prevent_fp64_optimization(err2); + let err12 = prevent_fp64_optimization(err12InputA + err12InputB); + let err123InputA = prevent_fp64_optimization(err12); + let err123InputB = prevent_fp64_optimization(err3); + let err123 = prevent_fp64_optimization(err123InputA + err123InputB); + let err1234InputA = prevent_fp64_optimization(err123); + let err1234InputB = prevent_fp64_optimization(err4); + let err = prevent_fp64_optimization(err1234InputA + err1234InputB); + return vec2f(prod, err); +} + +fn sum_fp64(a: vec2f, b: vec2f) -> vec2f { + var s = twoSum(a.x, b.x); + let t = twoSum(a.y, b.y); + s.y = prevent_fp64_optimization(s.y + t.x); + s = quickTwoSum(s.x, s.y); + s.y = prevent_fp64_optimization(s.y + t.y); + s = quickTwoSum(s.x, s.y); + return s; +} + +fn sub_fp64(a: vec2f, b: vec2f) -> vec2f { + var s = twoSub(a.x, b.x); + let t = twoSub(a.y, b.y); + s.y = prevent_fp64_optimization(s.y + t.x); + s = quickTwoSum(s.x, s.y); + s.y = prevent_fp64_optimization(s.y + t.y); + s = quickTwoSum(s.x, s.y); + return s; +} + +fn mul_fp64(a: vec2f, b: vec2f) -> vec2f { + var prod = twoProd(a.x, b.x); + let crossProduct1 = prevent_fp64_optimization(a.x * b.y); + prod.y = prevent_fp64_optimization(prod.y + crossProduct1); +#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND + prod = split2(prod); +#endif + prod = quickTwoSum(prod.x, prod.y); + let crossProduct2 = prevent_fp64_optimization(a.y * b.x); + prod.y = prevent_fp64_optimization(prod.y + crossProduct2); +#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND + prod = split2(prod); +#endif + prod = quickTwoSum(prod.x, prod.y); + return prod; +} + +fn div_fp64(a: vec2f, b: vec2f) -> vec2f { + let xn = prevent_fp64_optimization(1.0 / b.x); + let yn = mul_fp64(a, vec2f(xn, fp64_runtime_zero())); + let diff = prevent_fp64_optimization(sub_fp64(a, mul_fp64(b, yn)).x); + let prod = twoProd(xn, diff); + return sum_fp64(yn, prod); +} + +fn sqrt_fp64(a: vec2f) -> vec2f { + if (a.x == 0.0 && a.y == 0.0) { + return vec2f(0.0, 0.0); + } + if (a.x < 0.0) { + let nanValue = fp64_nan(a.x); + return vec2f(nanValue, nanValue); + } + + let x = prevent_fp64_optimization(1.0 / sqrt(a.x)); + let yn = prevent_fp64_optimization(a.x * x); +#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND + let ynSqr = twoSqr(yn) * fp64arithmetic.ONE; +#else + let ynSqr = twoSqr(yn); +#endif + let diff = prevent_fp64_optimization(sub_fp64(a, ynSqr).x); + let prod = twoProd(prevent_fp64_optimization(x * 0.5), diff); +#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND + return sum_fp64(split(yn), prod); +#else + return sum_fp64(vec2f(yn, 0.0), prod); +#endif +} +`,ad={ONE:1,SPLIT:4097},cd={name:"fp64arithmetic",source:od,fs:Rn,vs:Rn,defaultUniforms:ad,uniformTypes:{ONE:"f32",SPLIT:"f32"},fp64ify:Ca,fp64LowPart:td,fp64ifyMatrix4:rd},En=`layout(std140) uniform floatColorsUniforms { + float useByteColors; +} floatColors; + +vec3 floatColors_normalize(vec3 inputColor) { + return floatColors.useByteColors > 0.5 ? inputColor / 255.0 : inputColor; +} + +vec4 floatColors_normalize(vec4 inputColor) { + return floatColors.useByteColors > 0.5 ? inputColor / 255.0 : inputColor; +} + +vec4 floatColors_premultiplyAlpha(vec4 inputColor) { + return vec4(inputColor.rgb * inputColor.a, inputColor.a); +} + +vec4 floatColors_unpremultiplyAlpha(vec4 inputColor) { + return inputColor.a > 0.0 ? vec4(inputColor.rgb / inputColor.a, inputColor.a) : vec4(0.0); +} + +vec4 floatColors_premultiply_alpha(vec4 inputColor) { + return floatColors_premultiplyAlpha(inputColor); +} + +vec4 floatColors_unpremultiply_alpha(vec4 inputColor) { + return floatColors_unpremultiplyAlpha(inputColor); +} +`,ld=`struct floatColorsUniforms { + useByteColors: f32 +}; + +@group(0) @binding(auto) var floatColors : floatColorsUniforms; + +fn floatColors_normalize(inputColor: vec3) -> vec3 { + return select(inputColor, inputColor / 255.0, floatColors.useByteColors > 0.5); +} + +fn floatColors_normalize4(inputColor: vec4) -> vec4 { + return select(inputColor, inputColor / 255.0, floatColors.useByteColors > 0.5); +} + +fn floatColors_premultiplyAlpha(inputColor: vec4) -> vec4 { + return vec4(inputColor.rgb * inputColor.a, inputColor.a); +} + +fn floatColors_unpremultiplyAlpha(inputColor: vec4) -> vec4 { + return select( + vec4(0.0), + vec4(inputColor.rgb / inputColor.a, inputColor.a), + inputColor.a > 0.0 + ); +} + +fn floatColors_premultiply_alpha(inputColor: vec4) -> vec4 { + return floatColors_premultiplyAlpha(inputColor); +} + +fn floatColors_unpremultiply_alpha(inputColor: vec4) -> vec4 { + return floatColors_unpremultiplyAlpha(inputColor); +} +`,wa={name:"floatColors",props:{},uniforms:{},vs:En,fs:En,source:ld,uniformTypes:{useByteColors:"f32"},defaultUniforms:{useByteColors:!0}},fd=[0,1,1,1],ud=`layout(std140) uniform pickingUniforms { + float isActive; + float isAttribute; + float isHighlightActive; + float useByteColors; + vec3 highlightedObjectColor; + vec4 highlightColor; +} picking; + +out vec4 picking_vRGBcolor_Avalid; + +// Normalize unsigned byte color to 0-1 range +vec3 picking_normalizeColor(vec3 color) { + return picking.useByteColors > 0.5 ? color / 255.0 : color; +} + +// Normalize unsigned byte color to 0-1 range +vec4 picking_normalizeColor(vec4 color) { + return picking.useByteColors > 0.5 ? color / 255.0 : color; +} + +bool picking_isColorZero(vec3 color) { + return dot(color, vec3(1.0)) < 0.00001; +} + +bool picking_isColorValid(vec3 color) { + return dot(color, vec3(1.0)) > 0.00001; +} + +// Check if this vertex is highlighted +bool isVertexHighlighted(vec3 vertexColor) { + vec3 highlightedObjectColor = picking_normalizeColor(picking.highlightedObjectColor); + return + bool(picking.isHighlightActive) && picking_isColorZero(abs(vertexColor - highlightedObjectColor)); +} + +// Set the current picking color +void picking_setPickingColor(vec3 pickingColor) { + pickingColor = picking_normalizeColor(pickingColor); + + if (bool(picking.isActive)) { + // Use alpha as the validity flag. If pickingColor is [0, 0, 0] fragment is non-pickable + picking_vRGBcolor_Avalid.a = float(picking_isColorValid(pickingColor)); + + if (!bool(picking.isAttribute)) { + // Stores the picking color so that the fragment shader can render it during picking + picking_vRGBcolor_Avalid.rgb = pickingColor; + } + } else { + // Do the comparison with selected item color in vertex shader as it should mean fewer compares + picking_vRGBcolor_Avalid.a = float(isVertexHighlighted(pickingColor)); + } +} + +void picking_setPickingAttribute(float value) { + if (bool(picking.isAttribute)) { + picking_vRGBcolor_Avalid.r = value; + } +} + +void picking_setPickingAttribute(vec2 value) { + if (bool(picking.isAttribute)) { + picking_vRGBcolor_Avalid.rg = value; + } +} + +void picking_setPickingAttribute(vec3 value) { + if (bool(picking.isAttribute)) { + picking_vRGBcolor_Avalid.rgb = value; + } +} +`,hd=`layout(std140) uniform pickingUniforms { + float isActive; + float isAttribute; + float isHighlightActive; + float useByteColors; + vec3 highlightedObjectColor; + vec4 highlightColor; +} picking; + +in vec4 picking_vRGBcolor_Avalid; + +/* + * Returns highlight color if this item is selected. + */ +vec4 picking_filterHighlightColor(vec4 color) { + // If we are still picking, we don't highlight + if (picking.isActive > 0.5) { + return color; + } + + bool selected = bool(picking_vRGBcolor_Avalid.a); + + if (selected) { + // Blend in highlight color based on its alpha value + float highLightAlpha = picking.highlightColor.a; + float blendedAlpha = highLightAlpha + color.a * (1.0 - highLightAlpha); + float highLightRatio = highLightAlpha / blendedAlpha; + + vec3 blendedRGB = mix(color.rgb, picking.highlightColor.rgb, highLightRatio); + return vec4(blendedRGB, blendedAlpha); + } else { + return color; + } +} + +/* + * Returns picking color if picking enabled else unmodified argument. + */ +vec4 picking_filterPickingColor(vec4 color) { + if (bool(picking.isActive)) { + if (picking_vRGBcolor_Avalid.a == 0.0) { + discard; + } + return picking_vRGBcolor_Avalid; + } + return color; +} + +/* + * Returns picking color if picking is enabled if not + * highlight color if this item is selected, otherwise unmodified argument. + */ +vec4 picking_filterColor(vec4 color) { + vec4 highlightColor = picking_filterHighlightColor(color); + return picking_filterPickingColor(highlightColor); +} +`,Sn={props:{},uniforms:{},name:"picking",uniformTypes:{isActive:"f32",isAttribute:"f32",isHighlightActive:"f32",useByteColors:"f32",highlightedObjectColor:"vec3",highlightColor:"vec4"},defaultUniforms:{isActive:!1,isAttribute:!1,isHighlightActive:!1,useByteColors:!0,highlightedObjectColor:[0,0,0],highlightColor:fd},vs:ud,fs:hd,getUniforms:dd};function dd(e={},t){const r={},i=va(e.useByteColors,!0);if(e.highlightedObjectColor!==void 0)if(e.highlightedObjectColor===null)r.isHighlightActive=!1;else{r.isHighlightActive=!0;const s=e.highlightedObjectColor.slice(0,3);r.highlightedObjectColor=s}return e.highlightColor&&(r.highlightColor=id(e.highlightColor,i)),e.isActive!==void 0&&(r.isActive=!!e.isActive,r.isAttribute=!!e.isAttribute),e.useByteColors!==void 0&&(r.useByteColors=!!e.useByteColors),r}const gd="GPU Time and Memory",pd=["Adapter","GPU","GPU Type","GPU Backend","Frame Rate","CPU Time","GPU Time","GPU Memory","Buffer Memory","Texture Memory","Referenced Buffer Memory","Referenced Texture Memory","Swap Chain Texture"],Cn=new WeakMap,vn=new WeakMap;class _d{constructor(){f(this,"stats",new Map)}getStats(t){return this.get(t)}get(t){this.stats.has(t)||this.stats.set(t,new Hl({id:t}));const r=this.stats.get(t);return t===gd&&bd(r,pd),r}}const md=new _d;function bd(e,t){const r=e.stats;let i=!1;for(const c of t)r[c]||(e.get(c),i=!0);const s=Object.keys(r).length,n=Cn.get(e);if(!i&&(n==null?void 0:n.orderedStatNames)===t&&n.statCount===s)return;const o={};let a=vn.get(t);a||(a=new Set(t),vn.set(t,a));for(const c of t)r[c]&&(o[c]=r[c]);for(const[c,l]of Object.entries(r))a.has(c)||(o[c]=l);for(const c of Object.keys(r))delete r[c];Object.assign(r,o),Cn.set(e,{orderedStatNames:t,statCount:s})}const A=new xt({id:"luma.gl"}),ai={};function Nt(e="id"){ai[e]=ai[e]||1;const t=ai[e]++;return`${e}-${t}`}const Td="cpu-hotspot-profiler",Pn="GPU Resource Counts",wn="Resource Counts",On="GPU Time and Memory",Ad=["Resources","Buffers","Textures","Samplers","TextureViews","Framebuffers","QuerySets","Shaders","RenderPipelines","ComputePipelines","PipelineLayouts","VertexArrays","RenderPasss","ComputePasss","CommandEncoders","CommandBuffers"],yd=["Resources","Buffers","Textures","Samplers","TextureViews","Framebuffers","QuerySets","Shaders","RenderPipelines","SharedRenderPipelines","ComputePipelines","PipelineLayouts","VertexArrays","RenderPasss","ComputePasss","CommandEncoders","CommandBuffers"],Rd=Ad.flatMap(e=>[`${e} Created`,`${e} Active`]),Ed=yd.flatMap(e=>[`${e} Created`,`${e} Active`]),xn=new WeakMap,Mn=new WeakMap;class O{constructor(t,r,i){f(this,"id");f(this,"props");f(this,"userData",{});f(this,"_device");f(this,"destroyed",!1);f(this,"allocatedBytes",0);f(this,"allocatedBytesName",null);f(this,"_attachedResources",new Set);if(!t)throw new Error("no device");this._device=t,this.props=Sd(r,i);const s=this.props.id!=="undefined"?this.props.id:Nt(this[Symbol.toStringTag]);this.props.id=s,this.id=s,this.userData=this.props.userData||{},this.addStats()}toString(){return`${this[Symbol.toStringTag]||this.constructor.name}:"${this.id}"`}destroy(){this.destroyed||this.destroyResource()}delete(){return this.destroy(),this}getProps(){return this.props}attachResource(t){this._attachedResources.add(t)}detachResource(t){this._attachedResources.delete(t)}destroyAttachedResource(t){this._attachedResources.delete(t)&&t.destroy()}destroyAttachedResources(){for(const t of this._attachedResources)t.destroy();this._attachedResources=new Set}destroyResource(){this.destroyed||(this.destroyAttachedResources(),this.removeStats(),this.destroyed=!0)}removeStats(){const t=gt(this._device),r=t?ue():0,i=[this._device.statsManager.getStats(Pn),this._device.statsManager.getStats(wn)],s=Nn(this._device);for(const o of i)In(o,s);const n=this.getStatsName();for(const o of i)o.get("Resources Active").decrementCount(),o.get(`${n}s Active`).decrementCount();t&&(t.statsBookkeepingCalls=(t.statsBookkeepingCalls||0)+1,t.statsBookkeepingTimeMs=(t.statsBookkeepingTimeMs||0)+(ue()-r))}trackAllocatedMemory(t,r=this.getStatsName()){const i=gt(this._device),s=i?ue():0,n=this._device.statsManager.getStats(On);this.allocatedBytes>0&&this.allocatedBytesName&&(n.get("GPU Memory").subtractCount(this.allocatedBytes),n.get(`${this.allocatedBytesName} Memory`).subtractCount(this.allocatedBytes)),n.get("GPU Memory").addCount(t),n.get(`${r} Memory`).addCount(t),i&&(i.statsBookkeepingCalls=(i.statsBookkeepingCalls||0)+1,i.statsBookkeepingTimeMs=(i.statsBookkeepingTimeMs||0)+(ue()-s)),this.allocatedBytes=t,this.allocatedBytesName=r}trackReferencedMemory(t,r=this.getStatsName()){this.trackAllocatedMemory(t,`Referenced ${r}`)}trackDeallocatedMemory(t=this.getStatsName()){if(this.allocatedBytes===0){this.allocatedBytesName=null;return}const r=gt(this._device),i=r?ue():0,s=this._device.statsManager.getStats(On);s.get("GPU Memory").subtractCount(this.allocatedBytes),s.get(`${this.allocatedBytesName||t} Memory`).subtractCount(this.allocatedBytes),r&&(r.statsBookkeepingCalls=(r.statsBookkeepingCalls||0)+1,r.statsBookkeepingTimeMs=(r.statsBookkeepingTimeMs||0)+(ue()-i)),this.allocatedBytes=0,this.allocatedBytesName=null}trackDeallocatedReferencedMemory(t=this.getStatsName()){this.trackDeallocatedMemory(`Referenced ${t}`)}addStats(){const t=this.getStatsName(),r=gt(this._device),i=r?ue():0,s=[this._device.statsManager.getStats(Pn),this._device.statsManager.getStats(wn)],n=Nn(this._device);for(const o of s)In(o,n);for(const o of s)o.get("Resources Created").incrementCount(),o.get("Resources Active").incrementCount(),o.get(`${t}s Created`).incrementCount(),o.get(`${t}s Active`).incrementCount();r&&(r.statsBookkeepingCalls=(r.statsBookkeepingCalls||0)+1,r.statsBookkeepingTimeMs=(r.statsBookkeepingTimeMs||0)+(ue()-i)),Cd(this._device,t)}getStatsName(){return vd(this)}}f(O,"defaultProps",{id:"undefined",handle:void 0,userData:void 0});function Sd(e,t){const r={...t};for(const i in e)e[i]!==void 0&&(r[i]=e[i]);return r}function In(e,t){const r=e.stats;let i=!1;for(const c of t)r[c]||(e.get(c),i=!0);const s=Object.keys(r).length,n=xn.get(e);if(!i&&(n==null?void 0:n.orderedStatNames)===t&&n.statCount===s)return;const o={};let a=Mn.get(t);a||(a=new Set(t),Mn.set(t,a));for(const c of t)r[c]&&(o[c]=r[c]);for(const[c,l]of Object.entries(r))a.has(c)||(o[c]=l);for(const c of Object.keys(r))delete r[c];Object.assign(r,o),xn.set(e,{orderedStatNames:t,statCount:s})}function Nn(e){return e.type==="webgl"?Ed:Rd}function gt(e){const t=e.userData[Td];return t!=null&&t.enabled?t:null}function ue(){var e,t;return((t=(e=globalThis.performance)==null?void 0:e.now)==null?void 0:t.call(e))??Date.now()}function Cd(e,t){const r=gt(e);if(!(!r||!r.activeDefaultFramebufferAcquireDepth))switch(r.transientCanvasResourceCreates=(r.transientCanvasResourceCreates||0)+1,t){case"Texture":r.transientCanvasTextureCreates=(r.transientCanvasTextureCreates||0)+1;break;case"TextureView":r.transientCanvasTextureViewCreates=(r.transientCanvasTextureViewCreates||0)+1;break;case"Sampler":r.transientCanvasSamplerCreates=(r.transientCanvasSamplerCreates||0)+1;break;case"Framebuffer":r.transientCanvasFramebufferCreates=(r.transientCanvasFramebufferCreates||0)+1;break}}function vd(e){let t=Object.getPrototypeOf(e);for(;t;){const r=Object.getPrototypeOf(t);if(!r||r===O.prototype)return Pd(t)||e[Symbol.toStringTag]||e.constructor.name;t=r}return e[Symbol.toStringTag]||e.constructor.name}function Pd(e){const t=Object.getOwnPropertyDescriptor(e,Symbol.toStringTag);return typeof(t==null?void 0:t.get)=="function"?t.get.call(e):typeof(t==null?void 0:t.value)=="string"?t.value:null}const z=class z extends O{constructor(r,i){const s={...i};(i.usage||0)&z.INDEX&&!i.indexType&&(i.data instanceof Uint32Array?s.indexType="uint32":i.data instanceof Uint16Array?s.indexType="uint16":i.data instanceof Uint8Array&&(s.indexType="uint8")),delete s.data;super(r,s,z.defaultProps);f(this,"usage");f(this,"indexType");f(this,"updateTimestamp");f(this,"debugData",new ArrayBuffer(0));this.usage=s.usage||0,this.indexType=s.indexType,this.updateTimestamp=r.incrementTimestamp()}get[Symbol.toStringTag](){return"Buffer"}clone(r){return this.device.createBuffer({...this.props,...r})}_setDebugData(r,i,s){let n=null,o;ArrayBuffer.isView(r)?(n=r,o=r.buffer):o=r;const a=Math.min(r?r.byteLength:s,z.DEBUG_DATA_MAX_LENGTH);if(o===null)this.debugData=new ArrayBuffer(a);else{const c=Math.min((n==null?void 0:n.byteOffset)||0,o.byteLength),l=Math.max(0,o.byteLength-c),u=Math.min(a,l);this.debugData=new Uint8Array(o,c,u).slice().buffer}}};f(z,"INDEX",16),f(z,"VERTEX",32),f(z,"UNIFORM",64),f(z,"STORAGE",128),f(z,"INDIRECT",256),f(z,"QUERY_RESOLVE",512),f(z,"MAP_READ",1),f(z,"MAP_WRITE",2),f(z,"COPY_SRC",4),f(z,"COPY_DST",8),f(z,"DEBUG_DATA_MAX_LENGTH",32),f(z,"defaultProps",{...O.defaultProps,usage:0,byteLength:0,byteOffset:0,data:null,indexType:"uint16",onMapped:void 0});let N=z;class wd{getDataTypeInfo(t){const[r,i,s]=ci[t],n=t.includes("norm"),o=!n&&!t.startsWith("float"),a=t.startsWith("s");return{signedType:r,primitiveType:i,byteLength:s,normalized:n,integer:o,signed:a}}getNormalizedDataType(t){const r=t;switch(r){case"uint8":return"unorm8";case"sint8":return"snorm8";case"uint16":return"unorm16";case"sint16":return"snorm16";default:return r}}alignTo(t,r){switch(r){case 1:return t;case 2:return t+t%2;default:return t+(4-t%4)%4}}getDataType(t){const r=ArrayBuffer.isView(t)?t.constructor:t;if(r===Uint8ClampedArray)return"uint8";const i=Object.values(ci).find(s=>r===s[4]);if(!i)throw new Error(r.name);return i[0]}getTypedArrayConstructor(t){const[,,,,r]=ci[t];return r}}const le=new wd,ci={uint8:["uint8","u32",1,!1,Uint8Array],sint8:["sint8","i32",1,!1,Int8Array],unorm8:["uint8","f32",1,!0,Uint8Array],snorm8:["sint8","f32",1,!0,Int8Array],uint16:["uint16","u32",2,!1,Uint16Array],sint16:["sint16","i32",2,!1,Int16Array],unorm16:["uint16","u32",2,!0,Uint16Array],snorm16:["sint16","i32",2,!0,Int16Array],float16:["float16","f16",2,!1,Uint16Array],float32:["float32","f32",4,!1,Float32Array],uint32:["uint32","u32",4,!1,Uint32Array],sint32:["sint32","i32",4,!1,Int32Array]};class Od{getVertexFormatInfo(t){let r;t.endsWith("-webgl")&&(t.replace("-webgl",""),r=!0);const[i,s]=t.split("x"),n=i,o=s?parseInt(s):1,a=le.getDataTypeInfo(n),c={type:n,components:o,byteLength:a.byteLength*o,integer:a.integer,signed:a.signed,normalized:a.normalized};return r&&(c.webglOnly=!0),c}makeVertexFormat(t,r,i){const s=i?le.getNormalizedDataType(t):t;switch(s){case"unorm8":return r===1?"unorm8":r===3?"unorm8x3-webgl":`${s}x${r}`;case"snorm8":return r===1?"snorm8":r===3?"snorm8x3-webgl":`${s}x${r}`;case"uint8":case"sint8":if(r===1||r===3)throw new Error(`size: ${r}`);return`${s}x${r}`;case"uint16":return r===1?"uint16":r===3?"uint16x3-webgl":`${s}x${r}`;case"sint16":return r===1?"sint16":r===3?"sint16x3-webgl":`${s}x${r}`;case"unorm16":return r===1?"unorm16":r===3?"unorm16x3-webgl":`${s}x${r}`;case"snorm16":return r===1?"snorm16":r===3?"snorm16x3-webgl":`${s}x${r}`;case"float16":if(r===1||r===3)throw new Error(`size: ${r}`);return`${s}x${r}`;default:return r===1?s:`${s}x${r}`}}getVertexFormatFromAttribute(t,r,i){if(!r||r>4)throw new Error(`size ${r}`);const s=r,n=le.getDataType(t);return this.makeVertexFormat(n,s,i)}getCompatibleVertexFormat(t){let r;switch(t.primitiveType){case"f32":r="float32";break;case"i32":r="sint32";break;case"u32":r="uint32";break;case"f16":return t.components<=2?"float16x2":"float16x4"}return t.components===1?r:`${r}x${t.components}`}}const vt=new Od,j="texture-compression-bc",M="texture-compression-astc",ne="texture-compression-etc2",xd="texture-compression-etc1-webgl",Wt="texture-compression-pvrtc-webgl",li="texture-compression-atc-webgl",$t="float32-renderable-webgl",fi="float16-renderable-webgl",Md="rgb9e5ufloat-renderable-webgl",ui="snorm8-renderable-webgl",he="norm16-webgl",hi="norm16-renderable-webgl",di="snorm16-renderable-webgl",zt="float32-filterable",Bn="float16-filterable-webgl";function Oa(e){const t=xa[e];if(!t)throw new Error(`Unsupported texture format ${e}`);return t}function Id(){return xa}const Nd={r8unorm:{},rg8unorm:{},"rgb8unorm-webgl":{},rgba8unorm:{},"rgba8unorm-srgb":{},r8snorm:{render:ui},rg8snorm:{render:ui},"rgb8snorm-webgl":{},rgba8snorm:{render:ui},r8uint:{},rg8uint:{},rgba8uint:{},r8sint:{},rg8sint:{},rgba8sint:{},bgra8unorm:{},"bgra8unorm-srgb":{},r16unorm:{f:he,render:hi},rg16unorm:{f:he,render:hi},"rgb16unorm-webgl":{f:he,render:!1},rgba16unorm:{f:he,render:hi},r16snorm:{f:he,render:di},rg16snorm:{f:he,render:di},"rgb16snorm-webgl":{f:he,render:!1},rgba16snorm:{f:he,render:di},r16uint:{},rg16uint:{},rgba16uint:{},r16sint:{},rg16sint:{},rgba16sint:{},r16float:{render:fi,filter:"float16-filterable-webgl"},rg16float:{render:fi,filter:Bn},rgba16float:{render:fi,filter:Bn},r32uint:{},rg32uint:{},rgba32uint:{},r32sint:{},rg32sint:{},rgba32sint:{},r32float:{render:$t,filter:zt},rg32float:{render:!1,filter:zt},"rgb32float-webgl":{render:$t,filter:zt},rgba32float:{render:$t,filter:zt},"rgba4unorm-webgl":{channels:"rgba",bitsPerChannel:[4,4,4,4],packed:!0},"rgb565unorm-webgl":{channels:"rgb",bitsPerChannel:[5,6,5,0],packed:!0},"rgb5a1unorm-webgl":{channels:"rgba",bitsPerChannel:[5,5,5,1],packed:!0},rgb9e5ufloat:{channels:"rgb",packed:!0,render:Md},rg11b10ufloat:{channels:"rgb",bitsPerChannel:[11,11,10,0],packed:!0,p:1,render:$t},rgb10a2unorm:{channels:"rgba",bitsPerChannel:[10,10,10,2],packed:!0,p:1},rgb10a2uint:{channels:"rgba",bitsPerChannel:[10,10,10,2],packed:!0,p:1},stencil8:{attachment:"stencil",bitsPerChannel:[8,0,0,0],dataType:"uint8"},depth16unorm:{attachment:"depth",bitsPerChannel:[16,0,0,0],dataType:"uint16"},depth24plus:{attachment:"depth",bitsPerChannel:[24,0,0,0],dataType:"uint32"},depth32float:{attachment:"depth",bitsPerChannel:[32,0,0,0],dataType:"float32"},"depth24plus-stencil8":{attachment:"depth-stencil",bitsPerChannel:[24,8,0,0],packed:!0},"depth32float-stencil8":{attachment:"depth-stencil",bitsPerChannel:[32,8,0,0],packed:!0}},Bd={"bc1-rgb-unorm-webgl":{f:j},"bc1-rgb-unorm-srgb-webgl":{f:j},"bc1-rgba-unorm":{f:j},"bc1-rgba-unorm-srgb":{f:j},"bc2-rgba-unorm":{f:j},"bc2-rgba-unorm-srgb":{f:j},"bc3-rgba-unorm":{f:j},"bc3-rgba-unorm-srgb":{f:j},"bc4-r-unorm":{f:j},"bc4-r-snorm":{f:j},"bc5-rg-unorm":{f:j},"bc5-rg-snorm":{f:j},"bc6h-rgb-ufloat":{f:j},"bc6h-rgb-float":{f:j},"bc7-rgba-unorm":{f:j},"bc7-rgba-unorm-srgb":{f:j},"etc2-rgb8unorm":{f:ne},"etc2-rgb8unorm-srgb":{f:ne},"etc2-rgb8a1unorm":{f:ne},"etc2-rgb8a1unorm-srgb":{f:ne},"etc2-rgba8unorm":{f:ne},"etc2-rgba8unorm-srgb":{f:ne},"eac-r11unorm":{f:ne},"eac-r11snorm":{f:ne},"eac-rg11unorm":{f:ne},"eac-rg11snorm":{f:ne},"astc-4x4-unorm":{f:M},"astc-4x4-unorm-srgb":{f:M},"astc-5x4-unorm":{f:M},"astc-5x4-unorm-srgb":{f:M},"astc-5x5-unorm":{f:M},"astc-5x5-unorm-srgb":{f:M},"astc-6x5-unorm":{f:M},"astc-6x5-unorm-srgb":{f:M},"astc-6x6-unorm":{f:M},"astc-6x6-unorm-srgb":{f:M},"astc-8x5-unorm":{f:M},"astc-8x5-unorm-srgb":{f:M},"astc-8x6-unorm":{f:M},"astc-8x6-unorm-srgb":{f:M},"astc-8x8-unorm":{f:M},"astc-8x8-unorm-srgb":{f:M},"astc-10x5-unorm":{f:M},"astc-10x5-unorm-srgb":{f:M},"astc-10x6-unorm":{f:M},"astc-10x6-unorm-srgb":{f:M},"astc-10x8-unorm":{f:M},"astc-10x8-unorm-srgb":{f:M},"astc-10x10-unorm":{f:M},"astc-10x10-unorm-srgb":{f:M},"astc-12x10-unorm":{f:M},"astc-12x10-unorm-srgb":{f:M},"astc-12x12-unorm":{f:M},"astc-12x12-unorm-srgb":{f:M},"pvrtc-rgb4unorm-webgl":{f:Wt},"pvrtc-rgba4unorm-webgl":{f:Wt},"pvrtc-rgb2unorm-webgl":{f:Wt},"pvrtc-rgba2unorm-webgl":{f:Wt},"etc1-rbg-unorm-webgl":{f:xd},"atc-rgb-unorm-webgl":{f:li},"atc-rgba-unorm-webgl":{f:li},"atc-rgbai-unorm-webgl":{f:li}},xa={...Nd,...Bd},Dd=/^(r|rg|rgb|rgba|bgra)([0-9]*)([a-z]*)(-srgb)?(-webgl)?$/,Fd=["rgb","rgba","bgra"],Ud=["depth","stencil"],Ld=["bc1","bc2","bc3","bc4","bc5","bc6","bc7","etc1","etc2","eac","atc","astc","pvrtc"];class kd{isColor(t){return Fd.some(r=>t.startsWith(r))}isDepthStencil(t){return Ud.some(r=>t.startsWith(r))}isCompressed(t){return Ld.some(r=>t.startsWith(r))}getInfo(t){return Ma(t)}getCapabilities(t){return $d(t)}computeMemoryLayout(t){return Wd(t)}}const re=new kd;function Wd({format:e,width:t,height:r,depth:i,byteAlignment:s}){const n=re.getInfo(e),{bytesPerPixel:o,bytesPerBlock:a=o,blockWidth:c=1,blockHeight:l=1,compressed:u=!1}=n,h=u?Math.ceil(t/c):t,d=u?Math.ceil(r/l):r,g=h*a,p=Math.ceil(g/s)*s,_=d,m=p*_*i;return{bytesPerPixel:o,bytesPerRow:p,rowsPerImage:_,depthOrArrayLayers:i,bytesPerImage:p*_,byteLength:m}}function $d(e){const t=Oa(e),r={format:e,create:t.f??!0,render:t.render??!0,filter:t.filter??!0,blend:t.blend??!0,store:t.store??!0},i=Ma(e),s=e.startsWith("depth")||e.startsWith("stencil"),n=i==null?void 0:i.signed,o=i==null?void 0:i.integer,a=i==null?void 0:i.webgl,c=!!(i!=null&&i.compressed);return r.render&&(r.render=!s&&!c),r.filter&&(r.filter=!s&&!n&&!o&&!a),r}function Ma(e){let t=zd(e);if(re.isCompressed(e)){t.channels="rgb",t.components=3,t.bytesPerPixel=1,t.srgb=!1,t.compressed=!0,t.bytesPerBlock=Hd(e);const i=jd(e);i&&(t.blockWidth=i.blockWidth,t.blockHeight=i.blockHeight)}const r=t.packed?null:Dd.exec(e);if(r){const[,i,s,n,o,a]=r,c=`${n}${s}`,l=le.getDataTypeInfo(c),u=l.byteLength*8,h=(i==null?void 0:i.length)??1,d=[u,h>=2?u:0,h>=3?u:0,h>=4?u:0];t={format:e,attachment:t.attachment,dataType:l.signedType,components:h,channels:i,integer:l.integer,signed:l.signed,normalized:l.normalized,bitsPerChannel:d,bytesPerPixel:l.byteLength*h,packed:t.packed,srgb:t.srgb},a==="-webgl"&&(t.webgl=!0),o==="-srgb"&&(t.srgb=!0)}return e.endsWith("-webgl")&&(t.webgl=!0),e.endsWith("-srgb")&&(t.srgb=!0),t}function zd(e){var n;const t=Oa(e),r=t.bytesPerPixel||1,i=t.bitsPerChannel||[8,8,8,8];return delete t.bitsPerChannel,delete t.bytesPerPixel,delete t.f,delete t.render,delete t.filter,delete t.blend,delete t.store,{...t,format:e,attachment:t.attachment||"color",channels:t.channels||"r",components:t.components||((n=t.channels)==null?void 0:n.length)||1,bytesPerPixel:r,bitsPerChannel:i,dataType:t.dataType||"uint8",srgb:t.srgb??!1,packed:t.packed??!1,webgl:t.webgl??!1,integer:t.integer??!1,signed:t.signed??!1,normalized:t.normalized??!1,compressed:t.compressed??!1}}function jd(e){const r=/.*-(\d+)x(\d+)-.*/.exec(e);if(r){const[,i,s]=r;return{blockWidth:Number(i),blockHeight:Number(s)}}return e.startsWith("bc")||e.startsWith("etc1")||e.startsWith("etc2")||e.startsWith("eac")||e.startsWith("atc")?{blockWidth:4,blockHeight:4}:e.startsWith("pvrtc-rgb4")||e.startsWith("pvrtc-rgba4")?{blockWidth:4,blockHeight:4}:e.startsWith("pvrtc-rgb2")||e.startsWith("pvrtc-rgba2")?{blockWidth:8,blockHeight:4}:null}function Hd(e){return e.startsWith("bc1")||e.startsWith("bc4")||e.startsWith("etc1")||e.startsWith("etc2-rgb8")||e.startsWith("etc2-rgb8a1")||e.startsWith("eac-r11")||e==="atc-rgb-unorm-webgl"?8:e.startsWith("bc2")||e.startsWith("bc3")||e.startsWith("bc5")||e.startsWith("bc6h")||e.startsWith("bc7")||e.startsWith("etc2-rgba8")||e.startsWith("eac-rg11")||e.startsWith("astc")||e==="atc-rgba-unorm-webgl"||e==="atc-rgbai-unorm-webgl"?16:e.startsWith("pvrtc")?8:16}function ws(e){return typeof ImageData<"u"&&e instanceof ImageData||typeof ImageBitmap<"u"&&e instanceof ImageBitmap||typeof HTMLImageElement<"u"&&e instanceof HTMLImageElement||typeof HTMLVideoElement<"u"&&e instanceof HTMLVideoElement||typeof VideoFrame<"u"&&e instanceof VideoFrame||typeof HTMLCanvasElement<"u"&&e instanceof HTMLCanvasElement||typeof OffscreenCanvas<"u"&&e instanceof OffscreenCanvas}function Ia(e){if(typeof ImageData<"u"&&e instanceof ImageData||typeof ImageBitmap<"u"&&e instanceof ImageBitmap||typeof HTMLCanvasElement<"u"&&e instanceof HTMLCanvasElement||typeof OffscreenCanvas<"u"&&e instanceof OffscreenCanvas)return{width:e.width,height:e.height};if(typeof HTMLImageElement<"u"&&e instanceof HTMLImageElement)return{width:e.naturalWidth,height:e.naturalHeight};if(typeof HTMLVideoElement<"u"&&e instanceof HTMLVideoElement)return{width:e.videoWidth,height:e.videoHeight};if(typeof VideoFrame<"u"&&e instanceof VideoFrame)return{width:e.displayWidth,height:e.displayHeight};throw new Error("Unknown image type")}class Vd{}function Xd(e,t){const r=ji(e),i=t.map(ji).filter(s=>s!==void 0);return[r,...i].filter(s=>s!==void 0)}function ji(e){var t;if(e!==void 0){if(e===null||typeof e=="string"||typeof e=="number"||typeof e=="boolean")return e;if(e instanceof Error)return e.message;if(Array.isArray(e))return e.map(ji);if(typeof e=="object"){if(Yd(e)){const r=String(e);if(r!=="[object Object]")return r}return Kd(e)?Qd(e):((t=e.constructor)==null?void 0:t.name)||"Object"}return String(e)}}function Yd(e){return"toString"in e&&typeof e.toString=="function"&&e.toString!==Object.prototype.toString}function Kd(e){return"message"in e&&"type"in e}function Qd(e){const t=typeof e.type=="string"?e.type:"message",r=typeof e.message=="string"?e.message:"",i=typeof e.lineNum=="number"?e.lineNum:null,s=typeof e.linePos=="number"?e.linePos:null,n=i!==null&&s!==null?` @ ${i}:${s}`:i!==null?` @ ${i}`:"";return`${t}${n}: ${r}`.trim()}class qd{constructor(t=[],r){f(this,"features");f(this,"disabledFeatures");this.features=new Set(t),this.disabledFeatures=r||{}}*[Symbol.iterator](){yield*this.features}has(t){var r;return!((r=this.disabledFeatures)!=null&&r[t])&&this.features.has(t)}}const Sr=class Sr{constructor(t){f(this,"id");f(this,"props");f(this,"userData",{});f(this,"statsManager",md);f(this,"_factories",{});f(this,"timestamp",0);f(this,"_reused",!1);f(this,"_moduleData",{});f(this,"_textureCaps",{});f(this,"_debugGPUTimeQuery",null);this.props={...Sr.defaultProps,...t},this.id=this.props.id||Nt(this[Symbol.toStringTag].toLowerCase())}get[Symbol.toStringTag](){return"Device"}toString(){return`Device(${this.id})`}getVertexFormatInfo(t){return vt.getVertexFormatInfo(t)}isVertexFormatSupported(t){return!0}getTextureFormatInfo(t){return re.getInfo(t)}getTextureFormatCapabilities(t){let r=this._textureCaps[t];if(!r){const i=this._getDeviceTextureFormatCapabilities(t);r=this._getDeviceSpecificTextureFormatCapabilities(i),this._textureCaps[t]=r}return r}getMipLevelCount(t,r,i=1){const s=Math.max(t,r,i);return 1+Math.floor(Math.log2(s))}isExternalImage(t){return ws(t)}getExternalImageSize(t){return Ia(t)}isTextureFormatSupported(t){return this.getTextureFormatCapabilities(t).create}isTextureFormatFilterable(t){return this.getTextureFormatCapabilities(t).filter}isTextureFormatRenderable(t){return this.getTextureFormatCapabilities(t).render}isTextureFormatCompressed(t){return re.isCompressed(t)}getSupportedCompressedTextureFormats(){const t=[];for(const r of Object.keys(Id()))this.isTextureFormatCompressed(r)&&this.isTextureFormatSupported(r)&&t.push(r);return t}pushDebugGroup(t){this.commandEncoder.pushDebugGroup(t)}popDebugGroup(){var t;(t=this.commandEncoder)==null||t.popDebugGroup()}insertDebugMarker(t){var r;(r=this.commandEncoder)==null||r.insertDebugMarker(t)}loseDevice(){return!1}incrementTimestamp(){return this.timestamp++}reportError(t,r,...i){if(!this.props.onError(t,r)){const n=Xd(r,i);return A.error(this.type==="webgl"?"%cWebGL":"%cWebGPU","color: white; background: red; padding: 2px 6px; border-radius: 3px;",t.message,...n)}return()=>{}}debug(){if(this.props.debug)debugger;else A.once(0,`'Type luma.log.set({debug: true}) in console to enable debug breakpoints', +or create a device with the 'debug: true' prop.`)()}getDefaultCanvasContext(){if(!this.canvasContext)throw new Error("Device has no default CanvasContext. See props.createCanvasContext");return this.canvasContext}createFence(){throw new Error("createFence() not implemented")}beginRenderPass(t){return this.commandEncoder.beginRenderPass(t)}beginComputePass(t){return this.commandEncoder.beginComputePass(t)}generateMipmapsWebGPU(t){throw new Error("not implemented")}_createSharedRenderPipelineWebGL(t){throw new Error("_createSharedRenderPipelineWebGL() not implemented")}_createBindGroupLayoutWebGPU(t,r){throw new Error("_createBindGroupLayoutWebGPU() not implemented")}_createBindGroupWebGPU(t,r,i,s,n){throw new Error("_createBindGroupWebGPU() not implemented")}_supportsDebugGPUTime(){return this.features.has("timestamp-query")&&!!(this.props.debug||this.props.debugGPUTime)}_enableDebugGPUTime(t=256){if(!this._supportsDebugGPUTime())return null;if(this._debugGPUTimeQuery)return this._debugGPUTimeQuery;try{this._debugGPUTimeQuery=this.createQuerySet({type:"timestamp",count:t}),this.commandEncoder=this.createCommandEncoder({id:this.commandEncoder.props.id,timeProfilingQuerySet:this._debugGPUTimeQuery})}catch{this._debugGPUTimeQuery=null}return this._debugGPUTimeQuery}_disableDebugGPUTime(){this._debugGPUTimeQuery&&(this.commandEncoder.getTimeProfilingQuerySet()===this._debugGPUTimeQuery&&(this.commandEncoder=this.createCommandEncoder({id:this.commandEncoder.props.id})),this._debugGPUTimeQuery.destroy(),this._debugGPUTimeQuery=null)}_isDebugGPUTimeEnabled(){return this._debugGPUTimeQuery!==null}getCanvasContext(){return this.getDefaultCanvasContext()}readPixelsToArrayWebGL(t,r){throw new Error("not implemented")}readPixelsToBufferWebGL(t,r){throw new Error("not implemented")}setParametersWebGL(t){throw new Error("not implemented")}getParametersWebGL(t){throw new Error("not implemented")}withParametersWebGL(t,r){throw new Error("not implemented")}clearWebGL(t){throw new Error("not implemented")}resetWebGL(){throw new Error("not implemented")}getModuleData(t){var r;return(r=this._moduleData)[t]||(r[t]={}),this._moduleData[t]}static _getCanvasContextProps(t){return t.createCanvasContext===!0?{}:t.createCanvasContext}_getDeviceTextureFormatCapabilities(t){const r=re.getCapabilities(t),i=n=>(typeof n=="string"?this.features.has(n):n)??!0,s=i(r.create);return{format:t,create:s,render:s&&i(r.render),filter:s&&i(r.filter),blend:s&&i(r.blend),store:s&&i(r.store)}}_normalizeBufferProps(t){(t instanceof ArrayBuffer||ArrayBuffer.isView(t))&&(t={data:t});const r={...t};if((t.usage||0)&N.INDEX&&(t.indexType||(t.data instanceof Uint32Array?r.indexType="uint32":t.data instanceof Uint16Array?r.indexType="uint16":t.data instanceof Uint8Array&&(r.data=new Uint16Array(t.data),r.indexType="uint16")),!r.indexType))throw new Error("indices buffer content must be of type uint16 or uint32");return r}};f(Sr,"defaultProps",{id:null,powerPreference:"high-performance",failIfMajorPerformanceCaveat:!1,createCanvasContext:void 0,webgl:{},onError:(t,r)=>{},onResize:(t,r)=>{const[i,s]=t.getDevicePixelSize();A.log(1,`${t} resized => ${i}x${s}px`)()},onPositionChange:(t,r)=>{const[i,s]=t.getPosition();A.log(1,`${t} repositioned => ${i},${s}`)()},onVisibilityChange:t=>A.log(1,`${t} Visibility changed ${t.isVisible}`)(),onDevicePixelRatioChange:(t,r)=>A.log(1,`${t} DPR changed ${r.oldRatio} => ${t.devicePixelRatio}`)(),debug:Jd(),debugGPUTime:!1,debugShaders:A.get("debug-shaders")||void 0,debugFramebuffers:!!A.get("debug-framebuffers"),debugFactories:!!A.get("debug-factories"),debugWebGL:!!A.get("debug-webgl"),debugSpectorJS:void 0,debugSpectorJSUrl:void 0,_reuseDevices:!1,_requestMaxLimits:!0,_cacheShaders:!0,_destroyShaders:!1,_cachePipelines:!0,_sharePipelines:!0,_destroyPipelines:!1,_initializeFeatures:!0,_disabledFeatures:{"compilation-status-async-webgl":!0},_handle:void 0});let fr=Sr;function Zd(e,t){return e!=null?!!e:t!==void 0?t!=="production":!1}function Jd(){return Zd(A.get("debug"),Gd())}function Gd(){const e=globalThis.process;if(e!=null&&e.env)return e.env.NODE_ENV}class eg{constructor(t){f(this,"props");f(this,"_resizeObserver");f(this,"_intersectionObserver");f(this,"_observeDevicePixelRatioTimeout",null);f(this,"_observeDevicePixelRatioMediaQuery",null);f(this,"_handleDevicePixelRatioChange",()=>this._refreshDevicePixelRatio());f(this,"_trackPositionInterval",null);f(this,"_started",!1);this.props=t}get started(){return this._started}start(){if(!(this._started||!this.props.canvas)){this._started=!0,this._intersectionObserver||(this._intersectionObserver=new IntersectionObserver(t=>this.props.onIntersection(t))),this._resizeObserver||(this._resizeObserver=new ResizeObserver(t=>this.props.onResize(t))),this._intersectionObserver.observe(this.props.canvas);try{this._resizeObserver.observe(this.props.canvas,{box:"device-pixel-content-box"})}catch{this._resizeObserver.observe(this.props.canvas,{box:"content-box"})}this._observeDevicePixelRatioTimeout=setTimeout(()=>this._refreshDevicePixelRatio(),0),this.props.trackPosition&&this._trackPosition()}}stop(){var t,r;this._started&&(this._started=!1,this._observeDevicePixelRatioTimeout&&(clearTimeout(this._observeDevicePixelRatioTimeout),this._observeDevicePixelRatioTimeout=null),this._observeDevicePixelRatioMediaQuery&&(this._observeDevicePixelRatioMediaQuery.removeEventListener("change",this._handleDevicePixelRatioChange),this._observeDevicePixelRatioMediaQuery=null),this._trackPositionInterval&&(clearInterval(this._trackPositionInterval),this._trackPositionInterval=null),(t=this._resizeObserver)==null||t.disconnect(),(r=this._intersectionObserver)==null||r.disconnect())}_refreshDevicePixelRatio(){var t;this._started&&(this.props.onDevicePixelRatioChange(),(t=this._observeDevicePixelRatioMediaQuery)==null||t.removeEventListener("change",this._handleDevicePixelRatioChange),this._observeDevicePixelRatioMediaQuery=matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`),this._observeDevicePixelRatioMediaQuery.addEventListener("change",this._handleDevicePixelRatioChange,{once:!0}))}_trackPosition(t=100){this._trackPositionInterval||(this._trackPositionInterval=setInterval(()=>{this._started?this.props.onPositionChange():this._trackPositionInterval&&(clearInterval(this._trackPositionInterval),this._trackPositionInterval=null)},t))}}function tg(){let e,t;return{promise:new Promise((i,s)=>{e=i,t=s}),resolve:e,reject:t}}function Na(e,t){var r;if(!e){const i=new Error(t??"luma.gl assertion failed.");throw(r=Error.captureStackTrace)==null||r.call(Error,i,Na),i}}function Os(e,t){return Na(e,t),e}const Ye=class Ye{constructor(t){f(this,"id");f(this,"props");f(this,"canvas");f(this,"htmlCanvas");f(this,"offscreenCanvas");f(this,"type");f(this,"initialized");f(this,"isInitialized",!1);f(this,"isVisible",!0);f(this,"cssWidth");f(this,"cssHeight");f(this,"devicePixelRatio");f(this,"devicePixelWidth");f(this,"devicePixelHeight");f(this,"drawingBufferWidth");f(this,"drawingBufferHeight");f(this,"_initializedResolvers",tg());f(this,"_canvasObserver");f(this,"_position",[0,0]);f(this,"destroyed",!1);f(this,"_needsDrawingBufferResize",!0);var r,i;this.props={...Ye.defaultProps,...t},t=this.props,this.initialized=this._initializedResolvers.promise,it()?t.canvas?typeof t.canvas=="string"?this.canvas=ig(t.canvas):this.canvas=t.canvas:this.canvas=sg(t):this.canvas={width:t.width||1,height:t.height||1},Ye.isHTMLCanvas(this.canvas)?(this.id=t.id||this.canvas.id,this.type="html-canvas",this.htmlCanvas=this.canvas):Ye.isOffscreenCanvas(this.canvas)?(this.id=t.id||"offscreen-canvas",this.type="offscreen-canvas",this.offscreenCanvas=this.canvas):(this.id=t.id||"node-canvas-context",this.type="node"),this.cssWidth=((r=this.htmlCanvas)==null?void 0:r.clientWidth)||this.canvas.width,this.cssHeight=((i=this.htmlCanvas)==null?void 0:i.clientHeight)||this.canvas.height,this.devicePixelWidth=this.canvas.width,this.devicePixelHeight=this.canvas.height,this.drawingBufferWidth=this.canvas.width,this.drawingBufferHeight=this.canvas.height,this.devicePixelRatio=globalThis.devicePixelRatio||1,this._position=[0,0],this._canvasObserver=new eg({canvas:this.htmlCanvas,trackPosition:this.props.trackPosition,onResize:s=>this._handleResize(s),onIntersection:s=>this._handleIntersection(s),onDevicePixelRatioChange:()=>this._observeDevicePixelRatio(),onPositionChange:()=>this.updatePosition()})}static isHTMLCanvas(t){return typeof HTMLCanvasElement<"u"&&t instanceof HTMLCanvasElement}static isOffscreenCanvas(t){return typeof OffscreenCanvas<"u"&&t instanceof OffscreenCanvas}toString(){return`${this[Symbol.toStringTag]}(${this.id})`}destroy(){this.destroyed||(this.destroyed=!0,this._stopObservers(),this.device=null)}setProps(t){return"useDevicePixels"in t&&(this.props.useDevicePixels=t.useDevicePixels||!1,this._updateDrawingBufferSize()),this}getCurrentFramebuffer(t){return this._resizeDrawingBufferIfNeeded(),this._getCurrentFramebuffer(t)}getCSSSize(){return[this.cssWidth,this.cssHeight]}getPosition(){return this._position}getDevicePixelSize(){return[this.devicePixelWidth,this.devicePixelHeight]}getDrawingBufferSize(){return[this.drawingBufferWidth,this.drawingBufferHeight]}getMaxDrawingBufferSize(){const t=this.device.limits.maxTextureDimension2D;return[t,t]}setDrawingBufferSize(t,r){t=Math.floor(t),r=Math.floor(r),!(this.drawingBufferWidth===t&&this.drawingBufferHeight===r)&&(this.drawingBufferWidth=t,this.drawingBufferHeight=r,this._needsDrawingBufferResize=!0)}getDevicePixelRatio(){return typeof window<"u"&&window.devicePixelRatio||1}cssToDevicePixels(t,r=!0){const i=this.cssToDeviceRatio(),[s,n]=this.getDrawingBufferSize();return ng(t,i,s,n,r)}getPixelSize(){return this.getDevicePixelSize()}getAspect(){const[t,r]=this.getDrawingBufferSize();return t>0&&r>0?t/r:1}cssToDeviceRatio(){try{const[t]=this.getDrawingBufferSize(),[r]=this.getCSSSize();return r?t/r:1}catch{return 1}}resize(t){this.setDrawingBufferSize(t.width,t.height)}_setAutoCreatedCanvasId(t){var r;((r=this.htmlCanvas)==null?void 0:r.id)==="lumagl-auto-created-canvas"&&(this.htmlCanvas.id=t)}_startObservers(){this.destroyed||this._canvasObserver.start()}_stopObservers(){this._canvasObserver.stop()}_handleIntersection(t){if(this.destroyed)return;const r=t.find(s=>s.target===this.canvas);if(!r)return;const i=r.isIntersecting;this.isVisible!==i&&(this.isVisible=i,this.device.props.onVisibilityChange(this))}_handleResize(t){var l,u,h,d,g;if(this.destroyed)return;const r=t.find(p=>p.target===this.canvas);if(!r)return;const i=Os((l=r.contentBoxSize)==null?void 0:l[0]);this.cssWidth=i.inlineSize,this.cssHeight=i.blockSize;const s=this.getDevicePixelSize(),n=((h=(u=r.devicePixelContentBoxSize)==null?void 0:u[0])==null?void 0:h.inlineSize)||i.inlineSize*devicePixelRatio,o=((g=(d=r.devicePixelContentBoxSize)==null?void 0:d[0])==null?void 0:g.blockSize)||i.blockSize*devicePixelRatio,[a,c]=this.getMaxDrawingBufferSize();this.devicePixelWidth=Math.max(1,Math.min(n,a)),this.devicePixelHeight=Math.max(1,Math.min(o,c)),this._updateDrawingBufferSize(),this.device.props.onResize(this,{oldPixelSize:s})}_updateDrawingBufferSize(){if(this.props.autoResize)if(typeof this.props.useDevicePixels=="number"){const t=this.props.useDevicePixels;this.setDrawingBufferSize(this.cssWidth*t,this.cssHeight*t)}else this.props.useDevicePixels?this.setDrawingBufferSize(this.devicePixelWidth,this.devicePixelHeight):this.setDrawingBufferSize(this.cssWidth,this.cssHeight);this._initializedResolvers.resolve(),this.isInitialized=!0,this.updatePosition()}_resizeDrawingBufferIfNeeded(){this._needsDrawingBufferResize&&(this._needsDrawingBufferResize=!1,(this.drawingBufferWidth!==this.canvas.width||this.drawingBufferHeight!==this.canvas.height)&&(this.canvas.width=this.drawingBufferWidth,this.canvas.height=this.drawingBufferHeight,this._configureDevice()))}_observeDevicePixelRatio(){var r,i;if(this.destroyed||!this._canvasObserver.started)return;const t=this.devicePixelRatio;this.devicePixelRatio=window.devicePixelRatio,this.updatePosition(),(i=(r=this.device.props).onDevicePixelRatioChange)==null||i.call(r,this,{oldRatio:t})}updatePosition(){var r,i,s;if(this.destroyed)return;const t=(r=this.htmlCanvas)==null?void 0:r.getBoundingClientRect();if(t){const n=[t.left,t.top];if(this._position??(this._position=n),n[0]!==this._position[0]||n[1]!==this._position[1]){const a=this._position;this._position=n,(s=(i=this.device.props).onPositionChange)==null||s.call(i,this,{oldPosition:a})}}}};f(Ye,"defaultProps",{id:void 0,canvas:null,width:800,height:600,useDevicePixels:!0,autoResize:!0,container:null,visible:!0,alphaMode:"opaque",colorSpace:"srgb",trackPosition:!1});let et=Ye;function rg(e){if(typeof e=="string"){const t=document.getElementById(e);if(!t)throw new Error(`${e} is not an HTML element`);return t}return e||document.body}function ig(e){const t=document.getElementById(e);if(!et.isHTMLCanvas(t))throw new Error("Object is not a canvas element");return t}function sg(e){const{width:t,height:r}=e,i=document.createElement("canvas");i.id=Nt("lumagl-auto-created-canvas"),i.width=t||1,i.height=r||1,i.style.width=Number.isFinite(t)?`${t}px`:"100%",i.style.height=Number.isFinite(r)?`${r}px`:"100%",e!=null&&e.visible||(i.style.visibility="hidden");const s=rg((e==null?void 0:e.container)||null);return s.insertBefore(i,s.firstChild),i}function ng(e,t,r,i,s){const n=e,o=Dn(n[0],t,r);let a=Fn(n[1],t,i,s),c=Dn(n[0]+1,t,r);const l=c===r-1?c:c-1;c=Fn(n[1]+1,t,i,s);let u;return s?(c=c===0?c:c+1,u=a,a=c):u=c===i-1?c:c-1,{x:o,y:a,width:Math.max(l-o+1,1),height:Math.max(u-a+1,1)}}function Dn(e,t,r){return Math.min(Math.round(e*t),r-1)}function Fn(e,t,r,i){return i?Math.max(0,r-1-Math.round(e*t)):Math.min(Math.round(e*t),r-1)}class Ba extends et{}f(Ba,"defaultProps",et.defaultProps);class og extends et{}const Rt=class Rt extends O{get[Symbol.toStringTag](){return"Sampler"}constructor(t,r){r=Rt.normalizeProps(t,r),super(t,r,Rt.defaultProps)}static normalizeProps(t,r){return r}};f(Rt,"defaultProps",{...O.defaultProps,type:"color-sampler",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",addressModeW:"clamp-to-edge",magFilter:"nearest",minFilter:"nearest",mipmapFilter:"none",lodMinClamp:0,lodMaxClamp:32,compare:"less-equal",maxAnisotropy:1});let tt=Rt;const ag={"1d":"1d","2d":"2d","2d-array":"2d",cube:"2d","cube-array":"2d","3d":"3d"},F=class F extends O{constructor(r,i,s){i=F.normalizeProps(r,i);super(r,i,F.defaultProps);f(this,"dimension");f(this,"baseDimension");f(this,"format");f(this,"width");f(this,"height");f(this,"depth");f(this,"mipLevels");f(this,"samples");f(this,"byteAlignment");f(this,"ready",Promise.resolve(this));f(this,"isReady",!0);f(this,"updateTimestamp");if(this.dimension=this.props.dimension,this.baseDimension=ag[this.dimension],this.format=this.props.format,this.width=this.props.width,this.height=this.props.height,this.depth=this.props.depth,this.mipLevels=this.props.mipLevels,this.samples=this.props.samples||1,this.dimension==="cube"&&(this.depth=6),this.props.width===void 0||this.props.height===void 0)if(r.isExternalImage(i.data)){const n=r.getExternalImageSize(i.data);this.width=(n==null?void 0:n.width)||1,this.height=(n==null?void 0:n.height)||1}else this.width=1,this.height=1,(this.props.width===void 0||this.props.height===void 0)&&A.warn(`${this} created with undefined width or height. This is deprecated. Use DynamicTexture instead.`)();this.byteAlignment=(s==null?void 0:s.byteAlignment)||1,this.updateTimestamp=r.incrementTimestamp()}get[Symbol.toStringTag](){return"Texture"}toString(){return`Texture(${this.id},${this.format},${this.width}x${this.height})`}clone(r){return this.device.createTexture({...this.props,...r})}setSampler(r){this.sampler=r instanceof tt?r:this.device.createSampler(r)}copyImageData(r){const{data:i,depth:s,...n}=r;this.writeData(i,{...n,depthOrArrayLayers:n.depthOrArrayLayers??s})}computeMemoryLayout(r={}){const i=this._normalizeTextureReadOptions(r),{width:s=this.width,height:n=this.height,depthOrArrayLayers:o=this.depth}=i,{format:a,byteAlignment:c}=this;return re.computeMemoryLayout({format:a,width:s,height:n,depth:o,byteAlignment:c})}readBuffer(r,i){throw new Error("readBuffer not implemented")}readDataAsync(r){throw new Error("readBuffer not implemented")}writeBuffer(r,i){throw new Error("readBuffer not implemented")}writeData(r,i){throw new Error("readBuffer not implemented")}readDataSyncWebGL(r){throw new Error("readDataSyncWebGL not available")}generateMipmapsWebGL(){throw new Error("generateMipmapsWebGL not available")}static normalizeProps(r,i){const s={...i},{width:n,height:o}=s;return typeof n=="number"&&(s.width=Math.max(1,Math.ceil(n))),typeof o=="number"&&(s.height=Math.max(1,Math.ceil(o))),s}_initializeData(r){this.device.isExternalImage(r)?this.copyExternalImage({image:r,width:this.width,height:this.height,depth:this.depth,mipLevel:0,x:0,y:0,z:0,aspect:"all",colorSpace:"srgb",premultipliedAlpha:!1,flipY:!1}):r&&this.copyImageData({data:r,mipLevel:0,x:0,y:0,z:0,aspect:"all"})}_normalizeCopyImageDataOptions(r){const{data:i,depth:s,...n}=r,o=this._normalizeTextureWriteOptions({...n,depthOrArrayLayers:n.depthOrArrayLayers??s});return{data:i,depth:o.depthOrArrayLayers,...o}}_normalizeCopyExternalImageOptions(r){const i=F._omitUndefined(r),s=i.mipLevel??0,n=this._getMipLevelSize(s),o=this.device.getExternalImageSize(r.image),a={...F.defaultCopyExternalImageOptions,...n,...o,...i};return a.width=Math.min(a.width,n.width-a.x),a.height=Math.min(a.height,n.height-a.y),a.depth=Math.min(a.depth,n.depthOrArrayLayers-a.z),a}_normalizeTextureReadOptions(r){const i=F._omitUndefined(r),s=i.mipLevel??0,n=this._getMipLevelSize(s),o={...F.defaultTextureReadOptions,...n,...i};return o.width=Math.min(o.width,n.width-o.x),o.height=Math.min(o.height,n.height-o.y),o.depthOrArrayLayers=Math.min(o.depthOrArrayLayers,n.depthOrArrayLayers-o.z),o}_getSupportedColorReadOptions(r){const i=this._normalizeTextureReadOptions(r),s=re.getInfo(this.format);switch(this._validateColorReadAspect(i),this._validateColorReadFormat(s),this.dimension){case"2d":case"cube":case"cube-array":case"2d-array":case"3d":return i;default:throw new Error(`${this} color readback does not support ${this.dimension} textures`)}}_validateColorReadAspect(r){if(r.aspect!=="all")throw new Error(`${this} color readback only supports aspect 'all'`)}_validateColorReadFormat(r){if(r.compressed)throw new Error(`${this} color readback does not support compressed formats (${this.format})`);switch(r.attachment){case"color":return;case"depth":throw new Error(`${this} color readback does not support depth formats (${this.format})`);case"stencil":throw new Error(`${this} color readback does not support stencil formats (${this.format})`);case"depth-stencil":throw new Error(`${this} color readback does not support depth-stencil formats (${this.format})`);default:throw new Error(`${this} color readback does not support format ${this.format}`)}}_normalizeTextureWriteOptions(r){const i=F._omitUndefined(r),s=i.mipLevel??0,n=this._getMipLevelSize(s),o={...F.defaultTextureWriteOptions,...n,...i};o.width=Math.min(o.width,n.width-o.x),o.height=Math.min(o.height,n.height-o.y),o.depthOrArrayLayers=Math.min(o.depthOrArrayLayers,n.depthOrArrayLayers-o.z);const a=re.computeMemoryLayout({format:this.format,width:o.width,height:o.height,depth:o.depthOrArrayLayers,byteAlignment:this.byteAlignment}),c=a.bytesPerPixel*o.width;if(o.bytesPerRow=i.bytesPerRow??a.bytesPerRow,o.rowsPerImage=i.rowsPerImage??o.height,o.bytesPerRow>r),s=this.baseDimension==="1d"?1:Math.max(1,this.height>>r),n=this.dimension==="3d"?Math.max(1,this.depth>>r):this.depth;return{width:i,height:s,depthOrArrayLayers:n}}getAllocatedByteLength(){let r=0;for(let i=0;ii!==void 0))}};f(F,"SAMPLE",4),f(F,"STORAGE",8),f(F,"RENDER",16),f(F,"COPY_SRC",1),f(F,"COPY_DST",2),f(F,"TEXTURE",4),f(F,"RENDER_ATTACHMENT",16),f(F,"defaultProps",{...O.defaultProps,data:null,dimension:"2d",format:"rgba8unorm",usage:F.SAMPLE|F.RENDER|F.COPY_DST,width:void 0,height:void 0,depth:1,mipLevels:1,samples:void 0,sampler:{},view:void 0}),f(F,"defaultCopyDataOptions",{data:void 0,byteOffset:0,bytesPerRow:void 0,rowsPerImage:void 0,width:void 0,height:void 0,depthOrArrayLayers:void 0,depth:1,mipLevel:0,x:0,y:0,z:0,aspect:"all"}),f(F,"defaultCopyExternalImageOptions",{image:void 0,sourceX:0,sourceY:0,width:void 0,height:void 0,depth:1,mipLevel:0,x:0,y:0,z:0,aspect:"all",colorSpace:"srgb",premultipliedAlpha:!1,flipY:!1}),f(F,"defaultTextureReadOptions",{x:0,y:0,z:0,width:void 0,height:void 0,depthOrArrayLayers:1,mipLevel:0,aspect:"all"}),f(F,"defaultTextureWriteOptions",{byteOffset:0,bytesPerRow:void 0,rowsPerImage:void 0,x:0,y:0,z:0,width:void 0,height:void 0,depthOrArrayLayers:1,mipLevel:0,aspect:"all"});let U=F;const Cr=class Cr extends O{get[Symbol.toStringTag](){return"TextureView"}constructor(t,r){super(t,r,Cr.defaultProps)}};f(Cr,"defaultProps",{...O.defaultProps,format:void 0,dimension:void 0,aspect:"all",baseMipLevel:0,mipLevelCount:void 0,baseArrayLayer:0,arrayLayerCount:void 0});let ur=Cr;function cg(e,t,r){let i="";const s=t.split(/\r?\n/),n=e.slice().sort((o,a)=>o.lineNum-a.lineNum);switch((r==null?void 0:r.showSourceCode)||"no"){case"all":let o=0;for(let a=1;a<=s.length;a++){const c=s[a-1],l=n[o];for(c&&l&&(i+=Da(c,a,r));n.length>o&&l.lineNum===a;){const u=n[o++];u&&(i+=gi(u,s,u.lineNum,{...r,inlineSource:!1}))}}for(;n.length>o;){const a=n[o++];a&&(i+=gi(a,[],0,{...r,inlineSource:!1}))}return i;case"issues":case"no":for(const a of e)i+=gi(a,s,a.lineNum,{inlineSource:(r==null?void 0:r.showSourceCode)!=="no"});return i}}function gi(e,t,r,i){if(i!=null&&i.inlineSource){const n=lg(t,r),o=e.linePos>0?`${" ".repeat(e.linePos+5)}^^^ +`:"";return` +${n}${o}${e.type.toUpperCase()}: ${e.message} + +`}const s=e.type==="error"?"red":"orange";return i!=null&&i.html?`
${e.type.toUpperCase()}: ${e.message}
`:`${e.type.toUpperCase()}: ${e.message}`}function lg(e,t,r){let i="";for(let s=t-2;s<=t;s++){const n=e[s-1];n!==void 0&&(i+=Da(n,t,r))}return i}function Da(e,t,r){const i=r!=null&&r.html?ug(e):e;return`${fg(String(t),4)}: ${i}${r!=null&&r.html?"
":` +`}`}function fg(e,t){let r="";for(let i=e.length;i",">").replaceAll('"',""").replaceAll("'","'")}const vr=class vr extends O{constructor(r,i){i={...i,debugShaders:i.debugShaders||r.props.debugShaders||"errors"};super(r,{id:hg(i),...i},vr.defaultProps);f(this,"stage");f(this,"source");f(this,"compilationStatus","pending");this.stage=this.props.stage,this.source=this.props.source}get[Symbol.toStringTag](){return"Shader"}getCompilationInfoSync(){return null}getTranslatedSource(){return null}async debugShader(){const r=this.props.debugShaders;switch(r){case"never":return;case"errors":if(this.compilationStatus==="success")return;break}const i=await this.getCompilationInfo();r==="warnings"&&(i==null?void 0:i.length)===0||this._displayShaderLog(i,this.id)}_displayShaderLog(r,i){if(typeof document>"u"||!(document!=null&&document.createElement))return;const s=i,n=`${this.stage} shader "${s}"`,o=cg(r,this.source,{showSourceCode:"all",html:!0}),a=this.getTranslatedSource(),c=document.createElement("div");c.innerHTML=`

Compilation error in ${n}

+
+
+ +
+
${o}
`,a&&(c.innerHTML+=`

Translated Source



${a}
`),c.style.top="0",c.style.left="0",c.style.background="white",c.style.position="fixed",c.style.zIndex="9999",c.style.maxWidth="100vw",c.style.maxHeight="100vh",c.style.overflowY="auto",document.body.appendChild(c);const l=c.querySelector(".luma-compiler-log-error");l==null||l.scrollIntoView(),c.querySelector("button#close").onclick=()=>{c.remove()},c.querySelector("button#copy").onclick=()=>{navigator.clipboard.writeText(this.source)}}};f(vr,"defaultProps",{...O.defaultProps,language:"auto",stage:void 0,source:"",sourceMap:null,entryPoint:"main",debugShaders:void 0});let hr=vr;function hg(e){return dg(e.source)||e.id||Nt(`unnamed ${e.stage}-shader`)}function dg(e,t="unnamed"){const i=/#define[\s*]SHADER_NAME[\s*]([A-Za-z0-9_-]+)[\s*]/.exec(e);return(i==null?void 0:i[1])??t}const Pr=class Pr extends O{constructor(r,i={}){super(r,i,Pr.defaultProps);f(this,"width");f(this,"height");this.width=this.props.width,this.height=this.props.height}get[Symbol.toStringTag](){return"Framebuffer"}clone(r){const i=this.colorAttachments.map(n=>n.texture.clone(r)),s=this.depthStencilAttachment&&this.depthStencilAttachment.texture.clone(r);return this.device.createFramebuffer({...this.props,...r,colorAttachments:i,depthStencilAttachment:s})}resize(r){let i=!r;if(r){const[s,n]=Array.isArray(r)?r:[r.width,r.height];i=i||n!==this.height||s!==this.width,this.width=s,this.height=n}i&&(A.log(2,`Resizing framebuffer ${this.id} to ${this.width}x${this.height}`)(),this.resizeAttachments(this.width,this.height))}autoCreateAttachmentTextures(){if(this.props.colorAttachments.length===0&&!this.props.depthStencilAttachment)throw new Error("Framebuffer has noattachments");this.colorAttachments=this.props.colorAttachments.map((i,s)=>{if(typeof i=="string"){const n=this.createColorTexture(i,s);return this.attachResource(n),n.view}return i instanceof U?i.view:i});const r=this.props.depthStencilAttachment;if(r)if(typeof r=="string"){const i=this.createDepthStencilTexture(r);this.attachResource(i),this.depthStencilAttachment=i.view}else r instanceof U?this.depthStencilAttachment=r.view:this.depthStencilAttachment=r}createColorTexture(r,i){return this.device.createTexture({id:`${this.id}-color-attachment-${i}`,usage:U.RENDER_ATTACHMENT,format:r,width:this.width,height:this.height,sampler:{magFilter:"linear",minFilter:"linear"}})}createDepthStencilTexture(r){return this.device.createTexture({id:`${this.id}-depth-stencil-attachment`,usage:U.RENDER_ATTACHMENT,format:r,width:this.width,height:this.height})}resizeAttachments(r,i){if(this.colorAttachments.forEach((s,n)=>{const o=s.texture.clone({width:r,height:i});this.destroyAttachedResource(s),this.colorAttachments[n]=o.view,this.attachResource(o.view)}),this.depthStencilAttachment){const s=this.depthStencilAttachment.texture.clone({width:r,height:i});this.destroyAttachedResource(this.depthStencilAttachment),this.depthStencilAttachment=s.view,this.attachResource(s)}this.updateAttachments()}};f(Pr,"defaultProps",{...O.defaultProps,width:1,height:1,colorAttachments:[],depthStencilAttachment:null});let dr=Pr;const wr=class wr extends O{constructor(r,i){super(r,i,wr.defaultProps);f(this,"shaderLayout");f(this,"bufferLayout");f(this,"linkStatus","pending");f(this,"hash","");f(this,"sharedRenderPipeline",null);this.shaderLayout=this.props.shaderLayout,this.bufferLayout=this.props.bufferLayout||[],this.sharedRenderPipeline=this.props._sharedRenderPipeline||null}get[Symbol.toStringTag](){return"RenderPipeline"}get isPending(){var r;return this.linkStatus==="pending"||this.vs.compilationStatus==="pending"||((r=this.fs)==null?void 0:r.compilationStatus)==="pending"}get isErrored(){var r;return this.linkStatus==="error"||this.vs.compilationStatus==="error"||((r=this.fs)==null?void 0:r.compilationStatus)==="error"}};f(wr,"defaultProps",{...O.defaultProps,vs:null,vertexEntryPoint:"vertexMain",vsConstants:{},fs:null,fragmentEntryPoint:"fragmentMain",fsConstants:{},shaderLayout:null,bufferLayout:[],topology:"triangle-list",colorAttachmentFormats:void 0,depthStencilAttachmentFormat:void 0,parameters:{},varyings:void 0,bufferMode:void 0,disableWarnings:!1,_sharedRenderPipeline:void 0,bindings:void 0,bindGroups:void 0});let _e=wr;class gg extends O{get[Symbol.toStringTag](){return"SharedRenderPipeline"}constructor(t,r){super(t,r,{...O.defaultProps,handle:void 0,vs:void 0,fs:void 0,varyings:void 0,bufferMode:void 0})}}const Or=class Or extends O{constructor(r,i){super(r,i,Or.defaultProps);f(this,"hash","");f(this,"shaderLayout");this.shaderLayout=i.shaderLayout}get[Symbol.toStringTag](){return"ComputePipeline"}};f(Or,"defaultProps",{...O.defaultProps,shader:void 0,entryPoint:void 0,constants:{},shaderLayout:void 0});let gr=Or;const xr=class xr{constructor(t){f(this,"device");f(this,"_hashCounter",0);f(this,"_hashes",{});f(this,"_renderPipelineCache",{});f(this,"_computePipelineCache",{});f(this,"_sharedRenderPipelineCache",{});this.device=t}static getDefaultPipelineFactory(t){const r=t.getModuleData("@luma.gl/core");return r.defaultPipelineFactory||(r.defaultPipelineFactory=new xr(t)),r.defaultPipelineFactory}get[Symbol.toStringTag](){return"PipelineFactory"}toString(){return`PipelineFactory(${this.device.id})`}createRenderPipeline(t){var o;if(!this.device.props._cachePipelines)return this.device.createRenderPipeline(t);const r={..._e.defaultProps,...t},i=this._renderPipelineCache,s=this._hashRenderPipeline(r);let n=(o=i[s])==null?void 0:o.resource;if(n)i[s].useCount++,this.device.props.debugFactories&&A.log(3,`${this}: ${i[s].resource} reused, count=${i[s].useCount}, (id=${t.id})`)();else{const a=this.device.type==="webgl"&&this.device.props._sharePipelines?this.createSharedRenderPipeline(r):void 0;n=this.device.createRenderPipeline({...r,id:r.id?`${r.id}-cached`:Nt("unnamed-cached"),_sharedRenderPipeline:a}),n.hash=s,i[s]={resource:n,useCount:1},this.device.props.debugFactories&&A.log(3,`${this}: ${n} created, count=${i[s].useCount}`)()}return n}createComputePipeline(t){var o;if(!this.device.props._cachePipelines)return this.device.createComputePipeline(t);const r={...gr.defaultProps,...t},i=this._computePipelineCache,s=this._hashComputePipeline(r);let n=(o=i[s])==null?void 0:o.resource;return n?(i[s].useCount++,this.device.props.debugFactories&&A.log(3,`${this}: ${i[s].resource} reused, count=${i[s].useCount}, (id=${t.id})`)()):(n=this.device.createComputePipeline({...r,id:r.id?`${r.id}-cached`:void 0}),n.hash=s,i[s]={resource:n,useCount:1},this.device.props.debugFactories&&A.log(3,`${this}: ${n} created, count=${i[s].useCount}`)()),n}release(t){if(!this.device.props._cachePipelines){t.destroy();return}const r=this._getCache(t),i=t.hash;r[i].useCount--,r[i].useCount===0?(this._destroyPipeline(t),this.device.props.debugFactories&&A.log(3,`${this}: ${t} released and destroyed`)()):r[i].useCount<0?(A.error(`${this}: ${t} released, useCount < 0, resetting`)(),r[i].useCount=0):this.device.props.debugFactories&&A.log(3,`${this}: ${t} released, count=${r[i].useCount}`)()}createSharedRenderPipeline(t){const r=this._hashSharedRenderPipeline(t);let i=this._sharedRenderPipelineCache[r];return i||(i={resource:this.device._createSharedRenderPipelineWebGL(t),useCount:0},this._sharedRenderPipelineCache[r]=i),i.useCount++,i.resource}releaseSharedRenderPipeline(t){if(!t.sharedRenderPipeline)return;const r=this._hashSharedRenderPipeline(t.sharedRenderPipeline.props),i=this._sharedRenderPipelineCache[r];i&&(i.useCount--,i.useCount===0&&(i.resource.destroy(),delete this._sharedRenderPipelineCache[r]))}_destroyPipeline(t){const r=this._getCache(t);return this.device.props._destroyPipelines?(delete r[t.hash],t.destroy(),t instanceof _e&&this.releaseSharedRenderPipeline(t),!0):!1}_getCache(t){let r;if(t instanceof gr&&(r=this._computePipelineCache),t instanceof _e&&(r=this._renderPipelineCache),!r)throw new Error(`${this}`);if(!r[t.hash])throw new Error(`${this}: ${t} matched incorrect entry`);return r}_hashComputePipeline(t){const{type:r}=this.device,i=this._getHash(t.shader.source),s=this._getHash(JSON.stringify(t.shaderLayout));return`${r}/C/${i}SL${s}`}_hashRenderPipeline(t){const r=t.vs?this._getHash(t.vs.source):0,i=t.fs?this._getHash(t.fs.source):0,s=this._getWebGLVaryingHash(t),n=this._getHash(JSON.stringify(t.shaderLayout)),o=this._getHash(JSON.stringify(t.bufferLayout)),{type:a}=this.device;switch(a){case"webgl":const c=this._getHash(JSON.stringify(t.parameters));return`${a}/R/${r}/${i}V${s}T${t.topology}P${c}SL${n}BL${o}`;case"webgpu":default:const l=this._getHash(JSON.stringify({vertexEntryPoint:t.vertexEntryPoint,fragmentEntryPoint:t.fragmentEntryPoint})),u=this._getHash(JSON.stringify(t.parameters)),h=this._getWebGPUAttachmentHash(t);return`${a}/R/${r}/${i}V${s}T${t.topology}EP${l}P${u}SL${n}BL${o}A${h}`}}_hashSharedRenderPipeline(t){const r=t.vs?this._getHash(t.vs.source):0,i=t.fs?this._getHash(t.fs.source):0,s=this._getWebGLVaryingHash(t);return`webgl/S/${r}/${i}V${s}`}_getHash(t){return this._hashes[t]===void 0&&(this._hashes[t]=this._hashCounter++),this._hashes[t]}_getWebGLVaryingHash(t){const{varyings:r=[],bufferMode:i=null}=t;return this._getHash(JSON.stringify({varyings:r,bufferMode:i}))}_getWebGPUAttachmentHash(t){var s;const r=t.colorAttachmentFormats??[this.device.preferredColorFormat],i=(s=t.parameters)!=null&&s.depthWriteEnabled?t.depthStencilAttachmentFormat||this.device.preferredDepthFormat:null;return this._getHash(JSON.stringify({colorAttachmentFormats:r,depthStencilAttachmentFormat:i}))}};f(xr,"defaultProps",{..._e.defaultProps});let Hi=xr;const Mr=class Mr{constructor(t){f(this,"device");f(this,"_cache",{});this.device=t}static getDefaultShaderFactory(t){const r=t.getModuleData("@luma.gl/core");return r.defaultShaderFactory||(r.defaultShaderFactory=new Mr(t)),r.defaultShaderFactory}get[Symbol.toStringTag](){return"ShaderFactory"}toString(){return`${this[Symbol.toStringTag]}(${this.device.id})`}createShader(t){if(!this.device.props._cacheShaders)return this.device.createShader(t);const r=this._hashShader(t);let i=this._cache[r];if(i)i.useCount++,this.device.props.debugFactories&&A.log(3,`${this}: Reusing shader ${i.resource.id} count=${i.useCount}`)();else{const s=this.device.createShader({...t,id:t.id?`${t.id}-cached`:void 0});this._cache[r]=i={resource:s,useCount:1},this.device.props.debugFactories&&A.log(3,`${this}: Created new shader ${s.id}`)()}return i.resource}release(t){if(!this.device.props._cacheShaders){t.destroy();return}const r=this._hashShader(t),i=this._cache[r];if(i)if(i.useCount--,i.useCount===0)this.device.props._destroyShaders&&(delete this._cache[r],i.resource.destroy(),this.device.props.debugFactories&&A.log(3,`${this}: Releasing shader ${t.id}, destroyed`)());else{if(i.useCount<0)throw new Error(`ShaderFactory: Shader ${t.id} released too many times`);this.device.props.debugFactories&&A.log(3,`${this}: Releasing shader ${t.id} count=${i.useCount}`)()}}_hashShader(t){return`${t.stage}:${t.source}`}};f(Mr,"defaultProps",{...hr.defaultProps});let Vi=Mr;function pg(e,t,r){const i=e.bindings.find(s=>s.name===t||`${s.name.toLocaleLowerCase()}uniforms`===t.toLocaleLowerCase());return i||A.warn(`Binding ${t} not set: Not found in shader layout.`)(),i||null}function Fa(e,t){if(!t)return{};if(_g(t))return Object.fromEntries(Object.entries(t).map(([s,n])=>[Number(s),{...n}]));const r={};for(const[i,s]of Object.entries(t)){const n=pg(e,i),o=(n==null?void 0:n.group)??0;r[o]||(r[o]={}),r[o][i]=s}return r}function Un(e){const t={};for(const r of Object.values(e))Object.assign(t,r);return t}function _g(e){const t=Object.keys(e);return t.length>0&&t.every(r=>/^\d+$/.test(r))}const te=class te extends O{get[Symbol.toStringTag](){return"RenderPass"}constructor(t,r){r=te.normalizeProps(t,r),super(t,r,te.defaultProps)}static normalizeProps(t,r){return r}};f(te,"defaultClearColor",[0,0,0,1]),f(te,"defaultClearDepth",1),f(te,"defaultClearStencil",0),f(te,"defaultProps",{...O.defaultProps,framebuffer:null,parameters:void 0,clearColor:te.defaultClearColor,clearColors:void 0,clearDepth:te.defaultClearDepth,clearStencil:te.defaultClearStencil,depthReadOnly:!1,stencilReadOnly:!1,discard:!1,occlusionQuerySet:void 0,timestampQuerySet:void 0,beginTimestampIndex:void 0,endTimestampIndex:void 0});let Xi=te;const Ir=class Ir extends O{constructor(r,i){super(r,i,Ir.defaultProps);f(this,"_timeProfilingQuerySet",null);f(this,"_timeProfilingSlotCount",0);f(this,"_gpuTimeMs");this._timeProfilingQuerySet=i.timeProfilingQuerySet??null,this._timeProfilingSlotCount=0,this._gpuTimeMs=void 0}get[Symbol.toStringTag](){return"CommandEncoder"}async resolveTimeProfilingQuerySet(){if(this._gpuTimeMs=void 0,!this._timeProfilingQuerySet)return;const r=Math.floor(this._timeProfilingSlotCount/2);if(r<=0)return;const i=r*2,s=await this._timeProfilingQuerySet.readResults({firstQuery:0,queryCount:i});let n=0n;for(let o=0;o=this._timeProfilingQuerySet.props.count?i:(this._timeProfilingSlotCount+=2,{...i,timestampQuerySet:this._timeProfilingQuerySet,beginTimestampIndex:s,endTimestampIndex:s+1})}_supportsTimestampQueries(){return this.device.features.has("timestamp-query")}};f(Ir,"defaultProps",{...O.defaultProps,measureExecutionTime:void 0,timeProfilingQuerySet:void 0});let Yi=Ir;const Nr=class Nr extends O{get[Symbol.toStringTag](){return"CommandBuffer"}constructor(t,r){super(t,r,Nr.defaultProps)}};f(Nr,"defaultProps",{...O.defaultProps});let Ki=Nr;function xs(e){const t=Ms(e),r=Eg[t];if(!r)throw new Error(`Unsupported variable shader type: ${e}`);return r}function mg(e){const t=Ua(e),r=Rg[t];if(!r)throw new Error(`Unsupported attribute shader type: ${e}`);const[i,s]=r,n=i==="i32"||i==="u32",o=i!=="u32",a=yg[i]*s;return{primitiveType:i,components:s,byteLength:a,integer:n,signed:o}}class bg{getVariableShaderTypeInfo(t){return xs(t)}getAttributeShaderTypeInfo(t){return mg(t)}makeShaderAttributeType(t,r){return Tg(t,r)}resolveAttributeShaderTypeAlias(t){return Ua(t)}resolveVariableShaderTypeAlias(t){return Ms(t)}}function Tg(e,t){return t===1?e:`vec${t}<${e}>`}function Ua(e){return Sg[e]||e}function Ms(e){return Cg[e]||e}const Ag=new bg,yg={f32:4,f16:2,i32:4,u32:4},Rg={f32:["f32",1],"vec2":["f32",2],"vec3":["f32",3],"vec4":["f32",4],f16:["f16",1],"vec2":["f16",2],"vec3":["f16",3],"vec4":["f16",4],i32:["i32",1],"vec2":["i32",2],"vec3":["i32",3],"vec4":["i32",4],u32:["u32",1],"vec2":["u32",2],"vec3":["u32",3],"vec4":["u32",4]},Eg={f32:{type:"f32",components:1},f16:{type:"f16",components:1},i32:{type:"i32",components:1},u32:{type:"u32",components:1},"vec2":{type:"f32",components:2},"vec3":{type:"f32",components:3},"vec4":{type:"f32",components:4},"vec2":{type:"f16",components:2},"vec3":{type:"f16",components:3},"vec4":{type:"f16",components:4},"vec2":{type:"i32",components:2},"vec3":{type:"i32",components:3},"vec4":{type:"i32",components:4},"vec2":{type:"u32",components:2},"vec3":{type:"u32",components:3},"vec4":{type:"u32",components:4},"mat2x2":{type:"f32",components:4},"mat2x3":{type:"f32",components:6},"mat2x4":{type:"f32",components:8},"mat3x2":{type:"f32",components:6},"mat3x3":{type:"f32",components:9},"mat3x4":{type:"f32",components:12},"mat4x2":{type:"f32",components:8},"mat4x3":{type:"f32",components:12},"mat4x4":{type:"f32",components:16},"mat2x2":{type:"f16",components:4},"mat2x3":{type:"f16",components:6},"mat2x4":{type:"f16",components:8},"mat3x2":{type:"f16",components:6},"mat3x3":{type:"f16",components:9},"mat3x4":{type:"f16",components:12},"mat4x2":{type:"f16",components:8},"mat4x3":{type:"f16",components:12},"mat4x4":{type:"f16",components:16},"mat2x2":{type:"i32",components:4},"mat2x3":{type:"i32",components:6},"mat2x4":{type:"i32",components:8},"mat3x2":{type:"i32",components:6},"mat3x3":{type:"i32",components:9},"mat3x4":{type:"i32",components:12},"mat4x2":{type:"i32",components:8},"mat4x3":{type:"i32",components:12},"mat4x4":{type:"i32",components:16},"mat2x2":{type:"u32",components:4},"mat2x3":{type:"u32",components:6},"mat2x4":{type:"u32",components:8},"mat3x2":{type:"u32",components:6},"mat3x3":{type:"u32",components:9},"mat3x4":{type:"u32",components:12},"mat4x2":{type:"u32",components:8},"mat4x3":{type:"u32",components:12},"mat4x4":{type:"u32",components:16}},Sg={vec2i:"vec2",vec3i:"vec3",vec4i:"vec4",vec2u:"vec2",vec3u:"vec3",vec4u:"vec4",vec2f:"vec2",vec3f:"vec3",vec4f:"vec4",vec2h:"vec2",vec3h:"vec3",vec4h:"vec4"},Cg={vec2i:"vec2",vec3i:"vec3",vec4i:"vec4",vec2u:"vec2",vec3u:"vec3",vec4u:"vec4",vec2f:"vec2",vec3f:"vec3",vec4f:"vec4",vec2h:"vec2",vec3h:"vec3",vec4h:"vec4",mat2x2f:"mat2x2",mat2x3f:"mat2x3",mat2x4f:"mat2x4",mat3x2f:"mat3x2",mat3x3f:"mat3x3",mat3x4f:"mat3x4",mat4x2f:"mat4x2",mat4x3f:"mat4x3",mat4x4f:"mat4x4",mat2x2i:"mat2x2",mat2x3i:"mat2x3",mat2x4i:"mat2x4",mat3x2i:"mat3x2",mat3x3i:"mat3x3",mat3x4i:"mat3x4",mat4x2i:"mat4x2",mat4x3i:"mat4x3",mat4x4i:"mat4x4",mat2x2u:"mat2x2",mat2x3u:"mat2x3",mat2x4u:"mat2x4",mat3x2u:"mat3x2",mat3x3u:"mat3x3",mat3x4u:"mat3x4",mat4x2u:"mat4x2",mat4x3u:"mat4x3",mat4x4u:"mat4x4",mat2x2h:"mat2x2",mat2x3h:"mat2x3",mat2x4h:"mat2x4",mat3x2h:"mat3x2",mat3x3h:"mat3x3",mat3x4h:"mat3x4",mat4x2h:"mat4x2",mat4x3h:"mat4x3",mat4x4h:"mat4x4"};function La(e,t){const r={};for(const i of e.attributes){const s=Pg(e,t,i.name);s&&(r[i.name]=s)}return r}function vg(e,t,r=16){const i=La(e,t),s=new Array(r).fill(null);for(const n of Object.values(i))s[n.location]=n;return s}function Pg(e,t,r){const i=wg(e,r),s=Og(t,r);if(!i)return null;const n=Ag.getAttributeShaderTypeInfo(i.type),o=vt.getCompatibleVertexFormat(n),a=(s==null?void 0:s.vertexFormat)||o,c=vt.getVertexFormatInfo(a);return{attributeName:(s==null?void 0:s.attributeName)||i.name,bufferName:(s==null?void 0:s.bufferName)||i.name,location:i.location,shaderType:i.type,primitiveType:n.primitiveType,shaderComponents:n.components,vertexFormat:a,bufferDataType:c.type,bufferComponents:c.components,normalized:c.normalized,integer:n.integer,stepMode:(s==null?void 0:s.stepMode)||i.stepMode||"vertex",byteOffset:(s==null?void 0:s.byteOffset)||0,byteStride:(s==null?void 0:s.byteStride)||0}}function wg(e,t){const r=e.attributes.find(i=>i.name===t);return r||A.warn(`shader layout attribute "${t}" not present in shader`),r||null}function Og(e,t){xg(e);let r=Mg(e,t);return r||(r=Ig(e,t),r)?r:(A.warn(`layout for attribute "${t}" not present in buffer layout`),null)}function xg(e){for(const t of e)(t.attributes&&t.format||!t.attributes&&!t.format)&&A.warn(`BufferLayout ${name} must have either 'attributes' or 'format' field`)}function Mg(e,t){for(const r of e)if(r.format&&r.name===t)return{attributeName:r.name,bufferName:t,stepMode:r.stepMode,vertexFormat:r.format,byteOffset:0,byteStride:r.byteStride||0};return null}function Ig(e,t){var r;for(const i of e){let s=i.byteStride;if(typeof i.byteStride!="number")for(const o of i.attributes||[]){const a=vt.getVertexFormatInfo(o.format);s+=a.byteLength}const n=(r=i.attributes)==null?void 0:r.find(o=>o.attribute===t);if(n)return{attributeName:n.attribute,bufferName:i.name,stepMode:i.stepMode,vertexFormat:n.format,byteOffset:n.byteOffset,byteStride:s}}return null}const Br=class Br extends O{constructor(r,i){super(r,i,Br.defaultProps);f(this,"maxVertexAttributes");f(this,"attributeInfos");f(this,"indexBuffer",null);f(this,"attributes");this.maxVertexAttributes=r.limits.maxVertexAttributes,this.attributes=new Array(this.maxVertexAttributes).fill(null),this.attributeInfos=vg(i.shaderLayout,i.bufferLayout,this.maxVertexAttributes)}get[Symbol.toStringTag](){return"VertexArray"}setConstantWebGL(r,i){this.device.reportError(new Error("constant attributes not supported"),this)()}};f(Br,"defaultProps",{...O.defaultProps,shaderLayout:void 0,bufferLayout:[]});let Qi=Br;const Dr=class Dr extends O{get[Symbol.toStringTag](){return"TransformFeedback"}constructor(t,r){super(t,r,Dr.defaultProps)}};f(Dr,"defaultProps",{...O.defaultProps,layout:void 0,buffers:{}});let qi=Dr;const Fr=class Fr extends O{get[Symbol.toStringTag](){return"QuerySet"}constructor(t,r){super(t,r,Fr.defaultProps)}};f(Fr,"defaultProps",{...O.defaultProps,type:void 0,count:void 0});let Zi=Fr;const Ur=class Ur extends O{get[Symbol.toStringTag](){return"Fence"}constructor(t,r={}){super(t,r,Ur.defaultProps)}};f(Ur,"defaultProps",{...O.defaultProps});let Ji=Ur;function ce(e,t){switch(t){case 1:return e;case 2:return e+e%2;default:return e+(4-e%4)%4}}function ka(e){const[,,,,t]=Ng[e];return t}const Ng={uint8:["uint8","u32",1,!1,Uint8Array],sint8:["sint8","i32",1,!1,Int8Array],unorm8:["uint8","f32",1,!0,Uint8Array],snorm8:["sint8","f32",1,!0,Int8Array],uint16:["uint16","u32",2,!1,Uint16Array],sint16:["sint16","i32",2,!1,Int16Array],unorm16:["uint16","u32",2,!0,Uint16Array],snorm16:["sint16","i32",2,!0,Int16Array],float16:["float16","f16",2,!1,Uint16Array],float32:["float32","f32",4,!1,Float32Array],uint32:["uint32","u32",4,!1,Uint32Array],sint32:["sint32","i32",4,!1,Int32Array]};function Bg(e,t={}){const r={...e},i=t.layout??"std140",s={};let n=0;for(const[o,a]of Object.entries(r))n=Gi(s,o,a,n,i);return n=ce(n,Ae(r,i)),{layout:i,byteLength:n*4,uniformTypes:r,fields:s}}function jr(e,t){const r=Ms(e),i=xs(r),s=/^mat(\d)x(\d)<.+>$/.exec(r);if(s){const o=Number(s[1]),a=Number(s[2]),c=Ln(a,r,i.type),l=Fg(c.size,c.alignment,t);return{alignment:c.alignment,size:o*l,components:o*a,columns:o,rows:a,columnStride:l,shaderType:r,type:i.type}}const n=/^vec(\d)<.+>$/.exec(r);return n?Ln(Number(n[1]),r,i.type):{alignment:1,size:1,components:1,columns:1,rows:1,columnStride:1,shaderType:r,type:i.type}}function Wa(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function Gi(e,t,r,i,s){if(typeof r=="string"){const n=jr(r,s),o=ce(i,n.alignment);return e[t]={offset:o,...n},o+n.size}if(Array.isArray(r)){if(Array.isArray(r[0]))throw new Error(`Nested arrays are not supported for ${t}`);const n=r[0],o=r[1],a=za(n,s),c=ce(i,Ae(r,s));for(let l=0;l=o.length)break;c===1?t[`${r}[${l}]`]=Number(o[u]):t[`${r}[${l}]`]=zg(n,u,u+c)}}_writeLeafValue(t,r,i){const s=this.layout.fields[r];if(!s){A.warn(`Uniform ${r} not found in layout`)();return}const{type:n,components:o,columns:a,rows:c,offset:l,columnStride:u}=s,h=t[n];if(o===1){h[l]=Number(i);return}const d=i;if(a===1){for(let p=0;pn)return!1;for(let o=0;on.type==="uniform"&&n.name===(t==null?void 0:t.name));if(!i)throw new Error(t==null?void 0:t.name);const s=i;for(const n of s.uniforms||[])this.bindingLayout[n.name]=n}}setUniforms(t){for(const[r,i]of Object.entries(t))this._setUniform(r,i),this.needsRedraw||this.setNeedsRedraw(`${this.name}.${r}=${i}`)}setNeedsRedraw(t){this.needsRedraw=this.needsRedraw||t}getAllUniforms(){return this.modifiedUniforms={},this.needsRedraw=!1,this.uniforms||{}}_setUniform(t,r){Hg(this.uniforms[t],r)||(this.uniforms[t]=Vg(r),this.modifiedUniforms[t]=!0,this.modified=!0)}}const Yg=1024;class Kg{constructor(t,r){f(this,"device");f(this,"uniformBlocks",new Map);f(this,"shaderBlockLayouts",new Map);f(this,"shaderBlockWriters",new Map);f(this,"uniformBuffers",new Map);this.device=t;for(const[i,s]of Object.entries(r)){const n=i,o=Bg(s.uniformTypes??{},{layout:s.layout??Qg(t)}),a=new Wg(o);this.shaderBlockLayouts.set(n,o),this.shaderBlockWriters.set(n,a);const c=new Xg({name:i});c.setUniforms(a.getFlatUniformValues(s.defaultUniforms||{})),this.uniformBlocks.set(n,c)}}destroy(){for(const t of this.uniformBuffers.values())t.destroy()}setUniforms(t){var r;for(const[i,s]of Object.entries(t)){const n=i,o=this.shaderBlockWriters.get(n),a=o==null?void 0:o.getFlatUniformValues(s||{});(r=this.uniformBlocks.get(n))==null||r.setUniforms(a||{})}this.updateUniformBuffers()}getUniformBufferByteLength(t){var i;const r=((i=this.shaderBlockLayouts.get(t))==null?void 0:i.byteLength)||0;return Math.max(r,Yg)}getUniformBufferData(t){var s;const r=((s=this.uniformBlocks.get(t))==null?void 0:s.getAllUniforms())||{},i=this.shaderBlockWriters.get(t);return(i==null?void 0:i.getData(r))||new Uint8Array(0)}createUniformBuffer(t,r){r&&this.setUniforms(r);const i=this.getUniformBufferByteLength(t),s=this.device.createBuffer({usage:N.UNIFORM|N.COPY_DST,byteLength:i}),n=this.getUniformBufferData(t);return s.write(n),s}getManagedUniformBuffer(t){if(!this.uniformBuffers.get(t)){const r=this.getUniformBufferByteLength(t),i=this.device.createBuffer({usage:N.UNIFORM|N.COPY_DST,byteLength:r});this.uniformBuffers.set(t,i)}return this.uniformBuffers.get(t)}updateUniformBuffers(){let t=!1;for(const r of this.uniformBlocks.keys()){const i=this.updateUniformBuffer(r);t||(t=i)}return t&&A.log(3,`UniformStore.updateUniformBuffers(): ${t}`)(),t}updateUniformBuffer(t){var n;const r=this.uniformBlocks.get(t);let i=this.uniformBuffers.get(t),s=!1;if(i&&(r!=null&&r.needsRedraw)){s||(s=r.needsRedraw);const o=this.getUniformBufferData(t);i=this.uniformBuffers.get(t),i==null||i.write(o);const a=(n=this.uniformBlocks.get(t))==null?void 0:n.getAllUniforms();A.log(4,`Writing to uniform buffer ${String(t)}`,o,a)()}return s}}function Qg(e){return e.type==="webgpu"?"wgsl-uniform":"std140"}const kn=`precision highp int; + +// #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX)) +struct AmbientLight { + vec3 color; +}; + +struct PointLight { + vec3 color; + vec3 position; + vec3 attenuation; // 2nd order x:Constant-y:Linear-z:Exponential +}; + +struct SpotLight { + vec3 color; + vec3 position; + vec3 direction; + vec3 attenuation; + vec2 coneCos; +}; + +struct DirectionalLight { + vec3 color; + vec3 direction; +}; + +struct UniformLight { + vec3 color; + vec3 position; + vec3 direction; + vec3 attenuation; + vec2 coneCos; +}; + +layout(std140) uniform lightingUniforms { + int enabled; + int directionalLightCount; + int pointLightCount; + int spotLightCount; + vec3 ambientColor; + UniformLight lights[5]; +} lighting; + +PointLight lighting_getPointLight(int index) { + UniformLight light = lighting.lights[index]; + return PointLight(light.color, light.position, light.attenuation); +} + +SpotLight lighting_getSpotLight(int index) { + UniformLight light = lighting.lights[lighting.pointLightCount + index]; + return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos); +} + +DirectionalLight lighting_getDirectionalLight(int index) { + UniformLight light = + lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index]; + return DirectionalLight(light.color, light.direction); +} + +float getPointLightAttenuation(PointLight pointLight, float distance) { + return pointLight.attenuation.x + + pointLight.attenuation.y * distance + + pointLight.attenuation.z * distance * distance; +} + +float getSpotLightAttenuation(SpotLight spotLight, vec3 positionWorldspace) { + vec3 light_direction = normalize(positionWorldspace - spotLight.position); + float coneFactor = smoothstep( + spotLight.coneCos.y, + spotLight.coneCos.x, + dot(normalize(spotLight.direction), light_direction) + ); + float distanceAttenuation = getPointLightAttenuation( + PointLight(spotLight.color, spotLight.position, spotLight.attenuation), + distance(spotLight.position, positionWorldspace) + ); + return distanceAttenuation / max(coneFactor, 0.0001); +} + +// #endif +`,qg=`// #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX)) +const MAX_LIGHTS: i32 = 5; + +struct AmbientLight { + color: vec3, +}; + +struct PointLight { + color: vec3, + position: vec3, + attenuation: vec3, // 2nd order x:Constant-y:Linear-z:Exponential +}; + +struct SpotLight { + color: vec3, + position: vec3, + direction: vec3, + attenuation: vec3, + coneCos: vec2, +}; + +struct DirectionalLight { + color: vec3, + direction: vec3, +}; + +struct UniformLight { + color: vec3, + position: vec3, + direction: vec3, + attenuation: vec3, + coneCos: vec2, +}; + +struct lightingUniforms { + enabled: i32, + directionalLightCount: i32, + pointLightCount: i32, + spotLightCount: i32, + ambientColor: vec3, + lights: array, +}; + +@group(2) @binding(auto) var lighting : lightingUniforms; + +fn lighting_getPointLight(index: i32) -> PointLight { + let light = lighting.lights[index]; + return PointLight(light.color, light.position, light.attenuation); +} + +fn lighting_getSpotLight(index: i32) -> SpotLight { + let light = lighting.lights[lighting.pointLightCount + index]; + return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos); +} + +fn lighting_getDirectionalLight(index: i32) -> DirectionalLight { + let light = lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index]; + return DirectionalLight(light.color, light.direction); +} + +fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 { + return pointLight.attenuation.x + + pointLight.attenuation.y * distance + + pointLight.attenuation.z * distance * distance; +} + +fn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3) -> f32 { + let lightDirection = normalize(positionWorldspace - spotLight.position); + let coneFactor = smoothstep( + spotLight.coneCos.y, + spotLight.coneCos.x, + dot(normalize(spotLight.direction), lightDirection) + ); + let distanceAttenuation = getPointLightAttenuation( + PointLight(spotLight.color, spotLight.position, spotLight.attenuation), + distance(spotLight.position, positionWorldspace) + ); + return distanceAttenuation / max(coneFactor, 0.0001); +} +`,ye=5,Zg={color:"vec3",position:"vec3",direction:"vec3",attenuation:"vec3",coneCos:"vec2"},Va={props:{},uniforms:{},name:"lighting",defines:{},uniformTypes:{enabled:"i32",directionalLightCount:"i32",pointLightCount:"i32",spotLightCount:"i32",ambientColor:"vec3",lights:[Zg,ye]},defaultUniforms:er(),bindingLayout:[{name:"lighting",group:2}],firstBindingSlot:0,source:qg,vs:kn,fs:kn,getUniforms:Jg};function Jg(e,t={}){if(e=e&&{...e},!e)return er();e.lights&&(e={...e,...ep(e.lights),lights:void 0});const{useByteColors:r,ambientLight:i,pointLights:s,spotLights:n,directionalLights:o}=e||{};if(!(i||s&&s.length>0||n&&n.length>0||o&&o.length>0))return{...er(),enabled:0};const c={...er(),...Gg({useByteColors:r,ambientLight:i,pointLights:s,spotLights:n,directionalLights:o})};return e.enabled!==void 0&&(c.enabled=e.enabled?1:0),c}function Gg({useByteColors:e,ambientLight:t,pointLights:r=[],spotLights:i=[],directionalLights:s=[]}){const n=Xa();let o=0,a=0,c=0,l=0;for(const u of r){if(o>=ye)break;n[o]={...n[o],color:Ht(u,e),position:u.position,attenuation:u.attenuation||[1,0,0]},o++,a++}for(const u of i){if(o>=ye)break;n[o]={...n[o],color:Ht(u,e),position:u.position,direction:u.direction,attenuation:u.attenuation||[1,0,0],coneCos:rp(u)},o++,c++}for(const u of s){if(o>=ye)break;n[o]={...n[o],color:Ht(u,e),direction:u.direction},o++,l++}return r.length+i.length+s.length>ye&&A.warn(`MAX_LIGHTS exceeded, truncating to ${ye}`)(),{ambientColor:Ht(t,e),directionalLightCount:l,pointLightCount:a,spotLightCount:c,lights:n}}function ep(e){var r,i,s;const t={pointLights:[],spotLights:[],directionalLights:[]};for(const n of e||[])switch(n.type){case"ambient":t.ambientLight=n;break;case"directional":(r=t.directionalLights)==null||r.push(n);break;case"point":(i=t.pointLights)==null||i.push(n);break;case"spot":(s=t.spotLights)==null||s.push(n);break}return t}function Ht(e={},t){const{color:r=[0,0,0],intensity:i=1}=e;return Pa(r,va(t,!0)).map(n=>n*i)}function er(){return{enabled:1,directionalLightCount:0,pointLightCount:0,spotLightCount:0,ambientColor:[.1,.1,.1],lights:Xa()}}function Xa(){return Array.from({length:ye},()=>tp())}function tp(){return{color:[1,1,1],position:[1,1,2],direction:[1,1,1],attenuation:[1,0,0],coneCos:[1,0]}}function rp(e){const t=e.innerConeAngle??0,r=e.outerConeAngle??Math.PI/4;return[Math.cos(t),Math.cos(r)]}const Ya=`layout(std140) uniform phongMaterialUniforms { + uniform bool unlit; + uniform float ambient; + uniform float diffuse; + uniform float shininess; + uniform vec3 specularColor; +} material; +`,Ka=`layout(std140) uniform phongMaterialUniforms { + uniform bool unlit; + uniform float ambient; + uniform float diffuse; + uniform float shininess; + uniform vec3 specularColor; +} material; + +vec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 view_direction, vec3 normal_worldspace, vec3 color) { + vec3 halfway_direction = normalize(light_direction + view_direction); + float lambertian = dot(light_direction, normal_worldspace); + float specular = 0.0; + if (lambertian > 0.0) { + float specular_angle = max(dot(normal_worldspace, halfway_direction), 0.0); + specular = pow(specular_angle, material.shininess); + } + lambertian = max(lambertian, 0.0); + return (lambertian * material.diffuse * surfaceColor + specular * floatColors_normalize(material.specularColor)) * color; +} + +vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) { + vec3 lightColor = surfaceColor; + + if (material.unlit) { + return surfaceColor; + } + + if (lighting.enabled == 0) { + return lightColor; + } + + vec3 view_direction = normalize(cameraPosition - position_worldspace); + lightColor = material.ambient * surfaceColor * lighting.ambientColor; + + for (int i = 0; i < lighting.pointLightCount; i++) { + PointLight pointLight = lighting_getPointLight(i); + vec3 light_position_worldspace = pointLight.position; + vec3 light_direction = normalize(light_position_worldspace - position_worldspace); + float light_attenuation = getPointLightAttenuation(pointLight, distance(light_position_worldspace, position_worldspace)); + lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color / light_attenuation); + } + + for (int i = 0; i < lighting.spotLightCount; i++) { + SpotLight spotLight = lighting_getSpotLight(i); + vec3 light_position_worldspace = spotLight.position; + vec3 light_direction = normalize(light_position_worldspace - position_worldspace); + float light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace); + lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, spotLight.color / light_attenuation); + } + + for (int i = 0; i < lighting.directionalLightCount; i++) { + DirectionalLight directionalLight = lighting_getDirectionalLight(i); + lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color); + } + + return lightColor; +} +`,Qa=`struct phongMaterialUniforms { + unlit: u32, + ambient: f32, + diffuse: f32, + shininess: f32, + specularColor: vec3, +}; + +@group(3) @binding(auto) var phongMaterial : phongMaterialUniforms; + +fn lighting_getLightColor(surfaceColor: vec3, light_direction: vec3, view_direction: vec3, normal_worldspace: vec3, color: vec3) -> vec3 { + let halfway_direction: vec3 = normalize(light_direction + view_direction); + var lambertian: f32 = dot(light_direction, normal_worldspace); + var specular: f32 = 0.0; + if (lambertian > 0.0) { + let specular_angle = max(dot(normal_worldspace, halfway_direction), 0.0); + specular = pow(specular_angle, phongMaterial.shininess); + } + lambertian = max(lambertian, 0.0); + return ( + lambertian * phongMaterial.diffuse * surfaceColor + + specular * floatColors_normalize(phongMaterial.specularColor) + ) * color; +} + +fn lighting_getLightColor2(surfaceColor: vec3, cameraPosition: vec3, position_worldspace: vec3, normal_worldspace: vec3) -> vec3 { + var lightColor: vec3 = surfaceColor; + + if (phongMaterial.unlit != 0u) { + return surfaceColor; + } + + if (lighting.enabled == 0) { + return lightColor; + } + + let view_direction: vec3 = normalize(cameraPosition - position_worldspace); + lightColor = phongMaterial.ambient * surfaceColor * lighting.ambientColor; + + for (var i: i32 = 0; i < lighting.pointLightCount; i++) { + let pointLight: PointLight = lighting_getPointLight(i); + let light_position_worldspace: vec3 = pointLight.position; + let light_direction: vec3 = normalize(light_position_worldspace - position_worldspace); + let light_attenuation = getPointLightAttenuation( + pointLight, + distance(light_position_worldspace, position_worldspace) + ); + lightColor += lighting_getLightColor( + surfaceColor, + light_direction, + view_direction, + normal_worldspace, + pointLight.color / light_attenuation + ); + } + + for (var i: i32 = 0; i < lighting.spotLightCount; i++) { + let spotLight: SpotLight = lighting_getSpotLight(i); + let light_position_worldspace: vec3 = spotLight.position; + let light_direction: vec3 = normalize(light_position_worldspace - position_worldspace); + let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace); + lightColor += lighting_getLightColor( + surfaceColor, + light_direction, + view_direction, + normal_worldspace, + spotLight.color / light_attenuation + ); + } + + for (var i: i32 = 0; i < lighting.directionalLightCount; i++) { + let directionalLight: DirectionalLight = lighting_getDirectionalLight(i); + lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color); + } + + return lightColor; +} + +fn lighting_getSpecularLightColor(cameraPosition: vec3, position_worldspace: vec3, normal_worldspace: vec3) -> vec3{ + var lightColor = vec3(0, 0, 0); + let surfaceColor = vec3(0, 0, 0); + + if (lighting.enabled != 0) { + let view_direction = normalize(cameraPosition - position_worldspace); + + for (var i: i32 = 0; i < lighting.pointLightCount; i++) { + let pointLight: PointLight = lighting_getPointLight(i); + let light_position_worldspace: vec3 = pointLight.position; + let light_direction: vec3 = normalize(light_position_worldspace - position_worldspace); + let light_attenuation = getPointLightAttenuation( + pointLight, + distance(light_position_worldspace, position_worldspace) + ); + lightColor += lighting_getLightColor( + surfaceColor, + light_direction, + view_direction, + normal_worldspace, + pointLight.color / light_attenuation + ); + } + + for (var i: i32 = 0; i < lighting.spotLightCount; i++) { + let spotLight: SpotLight = lighting_getSpotLight(i); + let light_position_worldspace: vec3 = spotLight.position; + let light_direction: vec3 = normalize(light_position_worldspace - position_worldspace); + let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace); + lightColor += lighting_getLightColor( + surfaceColor, + light_direction, + view_direction, + normal_worldspace, + spotLight.color / light_attenuation + ); + } + + for (var i: i32 = 0; i < lighting.directionalLightCount; i++) { + let directionalLight: DirectionalLight = lighting_getDirectionalLight(i); + lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color); + } + } + return lightColor; +} +`,ip=[38.25,38.25,38.25],sp={props:{},name:"gouraudMaterial",bindingLayout:[{name:"gouraudMaterial",group:3}],vs:Ka.replace("phongMaterial","gouraudMaterial"),fs:Ya.replace("phongMaterial","gouraudMaterial"),source:Qa.replaceAll("phongMaterial","gouraudMaterial"),defines:{LIGHTING_VERTEX:!0},dependencies:[Va,wa],uniformTypes:{unlit:"i32",ambient:"f32",diffuse:"f32",shininess:"f32",specularColor:"vec3"},defaultUniforms:{unlit:!1,ambient:.35,diffuse:.6,shininess:32,specularColor:ip},getUniforms(e){return{...sp.defaultUniforms,...e}}},np=[38.25,38.25,38.25],op={name:"phongMaterial",firstBindingSlot:0,bindingLayout:[{name:"phongMaterial",group:3}],dependencies:[Va,wa],source:Qa,vs:Ya,fs:Ka,defines:{LIGHTING_FRAGMENT:!0},uniformTypes:{unlit:"i32",ambient:"f32",diffuse:"f32",shininess:"f32",specularColor:"vec3"},defaultUniforms:{unlit:!1,ambient:.35,diffuse:.6,shininess:32,specularColor:np},getUniforms(e){return{...op.defaultUniforms,...e}}},ap=` + +@must_use +fn deckgl_premultiplied_alpha(fragColor: vec4) -> vec4 { + return vec4(fragColor.rgb * fragColor.a, fragColor.a); +}; +`,MA={name:"color",dependencies:[],source:ap,getUniforms:e=>({})},cp=`const SMOOTH_EDGE_RADIUS: f32 = 0.5; + +struct VertexGeometry { + position: vec4, + worldPosition: vec3, + worldPositionAlt: vec3, + normal: vec3, + uv: vec2, + pickingColor: vec3, +}; + +var geometry_: VertexGeometry = VertexGeometry( + vec4(0.0, 0.0, 1.0, 0.0), + vec3(0.0, 0.0, 0.0), + vec3(0.0, 0.0, 0.0), + vec3(0.0, 0.0, 0.0), + vec2(0.0, 0.0), + vec3(0.0, 0.0, 0.0) +); + +struct FragmentGeometry { + uv: vec2, +}; + +var fragmentGeometry: FragmentGeometry; + +fn smoothedge(edge: f32, x: f32) -> f32 { + return smoothstep(edge - SMOOTH_EDGE_RADIUS, edge + SMOOTH_EDGE_RADIUS, x); +} +`,qa="#define SMOOTH_EDGE_RADIUS 0.5",lp=`${qa} + +struct VertexGeometry { + vec4 position; + vec3 worldPosition; + vec3 worldPositionAlt; + vec3 normal; + vec2 uv; + vec3 pickingColor; +} geometry = VertexGeometry( + vec4(0.0, 0.0, 1.0, 0.0), + vec3(0.0), + vec3(0.0), + vec3(0.0), + vec2(0.0), + vec3(0.0) +); +`,fp=`${qa} + +struct FragmentGeometry { + vec2 uv; +} geometry; + +float smoothedge(float edge, float x) { + return smoothstep(edge - SMOOTH_EDGE_RADIUS, edge + SMOOTH_EDGE_RADIUS, x); +} +`,up={name:"geometry",source:cp,vs:lp,fs:fp},hp=25;var W;(function(e){e[e.Start=1]="Start",e[e.Move=2]="Move",e[e.End=4]="End",e[e.Cancel=8]="Cancel"})(W||(W={}));var $;(function(e){e[e.None=0]="None",e[e.Left=1]="Left",e[e.Right=2]="Right",e[e.Up=4]="Up",e[e.Down=8]="Down",e[e.Horizontal=3]="Horizontal",e[e.Vertical=12]="Vertical",e[e.All=15]="All"})($||($={}));var P;(function(e){e[e.Possible=1]="Possible",e[e.Began=2]="Began",e[e.Changed=4]="Changed",e[e.Ended=8]="Ended",e[e.Recognized=8]="Recognized",e[e.Cancelled=16]="Cancelled",e[e.Failed=32]="Failed"})(P||(P={}));const IA="compute",NA="auto",dp="manipulation",gp="none",pp="pan-x",_p="pan-y";function Za(e){return e.trim().split(/\s+/g)}function pi(e,t,r){if(e)for(const i of Za(t))e.addEventListener(i,r,!1)}function _i(e,t,r){if(e)for(const i of Za(t))e.removeEventListener(i,r,!1)}function Wn(e){return(e.ownerDocument||e).defaultView}function mp(e,t){let r=e;for(;r;){if(r===t)return!0;r=r.parentNode}return!1}function Ja(e){const t=e.length;if(t===1)return{x:Math.round(e[0].clientX),y:Math.round(e[0].clientY)};let r=0,i=0,s=0;for(;s=Math.abs(t)?e<0?$.Left:$.Right:t<0?$.Up:$.Down}function Tp(e,t){const r=t.center;let i=e.offsetDelta,s=e.prevDelta;const n=e.prevInput;return(t.eventType===W.Start||(n==null?void 0:n.eventType)===W.End)&&(s=e.prevDelta={x:(n==null?void 0:n.deltaX)||0,y:(n==null?void 0:n.deltaY)||0},i=e.offsetDelta={x:r.x,y:r.y}),{deltaX:s.x+(r.x-i.x),deltaY:s.y+(r.y-i.y)}}function tc(e,t,r){return{x:t/e||0,y:r/e||0}}function Ap(e,t){return zn(t[0],t[1])/zn(e[0],e[1])}function yp(e,t){return jn(t[1],t[0])-jn(e[1],e[0])}function Rp(e,t){const r=e.lastInterval||t,i=t.timeStamp-r.timeStamp;let s,n,o,a;if(t.eventType!==W.Cancel&&(i>hp||r.velocity===void 0)){const c=t.deltaX-r.deltaX,l=t.deltaY-r.deltaY,u=tc(i,c,l);n=u.x,o=u.y,s=Math.abs(u.x)>Math.abs(u.y)?u.x:u.y,a=ec(c,l),e.lastInterval=t}else s=r.velocity,n=r.velocityX,o=r.velocityY,a=r.direction;t.velocity=s,t.velocityX=n,t.velocityY=o,t.direction=a}function Ep(e,t){const{session:r}=e,{pointers:i}=t,{length:s}=i;r.firstInput||(r.firstInput=$n(t)),s>1&&!r.firstMultiple?r.firstMultiple=$n(t):s===1&&(r.firstMultiple=!1);const{firstInput:n,firstMultiple:o}=r,a=o?o.center:n.center,c=t.center=Ja(i);t.timeStamp=Date.now(),t.deltaTime=t.timeStamp-n.timeStamp,t.angle=bp(a,c),t.distance=Ga(a,c);const{deltaX:l,deltaY:u}=Tp(r,t);t.deltaX=l,t.deltaY=u,t.offsetDirection=ec(t.deltaX,t.deltaY);const h=tc(t.deltaTime,t.deltaX,t.deltaY);t.overallVelocityX=h.x,t.overallVelocityY=h.y,t.overallVelocity=Math.abs(h.x)>Math.abs(h.y)?h.x:h.y,t.scale=o?Ap(o.pointers,i):1,t.rotation=o?yp(o.pointers,i):0,t.maxPointers=r.prevInput?t.pointers.length>r.prevInput.maxPointers?t.pointers.length:r.prevInput.maxPointers:t.pointers.length;let d=e.element;return mp(t.srcEvent.target,d)&&(d=t.srcEvent.target),t.target=d,Rp(r,t),t}function Sp(e,t,r){const i=r.pointers.length,s=r.changedPointers.length,n=t&W.Start&&i-s===0,o=t&(W.End|W.Cancel)&&i-s===0;r.isFirst=!!n,r.isFinal=!!o,n&&(e.session={}),r.eventType=t;const a=Ep(e,r);e.emit("hammer.input",a),e.recognize(a),e.session.prevInput=a}let Cp=class{constructor(t){this.evEl="",this.evWin="",this.evTarget="",this.domHandler=r=>{this.manager.options.enable&&this.handler(r)},this.manager=t,this.element=t.element,this.target=t.options.inputTarget||t.element}callback(t,r){Sp(this.manager,t,r)}init(){pi(this.element,this.evEl,this.domHandler),pi(this.target,this.evTarget,this.domHandler),pi(Wn(this.element),this.evWin,this.domHandler)}destroy(){_i(this.element,this.evEl,this.domHandler),_i(this.target,this.evTarget,this.domHandler),_i(Wn(this.element),this.evWin,this.domHandler)}};const vp={pointerdown:W.Start,pointermove:W.Move,pointerup:W.End,pointercancel:W.Cancel,pointerout:W.Cancel},Pp="pointerdown",wp="pointermove pointerup pointercancel";class DA extends Cp{constructor(t){super(t),this.evEl=Pp,this.evWin=wp,this.store=this.manager.session.pointerEvents=[],this.init()}handler(t){const{store:r}=this;let i=!1;const s=vp[t.type],n=t.pointerType,o=n==="touch";let a=r.findIndex(c=>c.pointerId===t.pointerId);s&W.Start&&(t.buttons||o)?a<0&&(r.push(t),a=r.length-1):s&(W.End|W.Cancel)&&(i=!0),!(a<0)&&(r[a]=t,this.callback(s,{pointers:r,changedPointers:[t],eventType:s,pointerType:n,srcEvent:t}),i&&r.splice(a,1))}}let Op=1;function xp(){return Op++}function Hn(e){return e&P.Cancelled?"cancel":e&P.Ended?"end":e&P.Changed?"move":e&P.Began?"start":""}class rc{constructor(t){this.options=t,this.id=xp(),this.state=P.Possible,this.simultaneous={},this.requireFail=[]}set(t){return Object.assign(this.options,t),this.manager.touchAction.update(),this}recognizeWith(t){if(Array.isArray(t)){for(const s of t)this.recognizeWith(s);return this}let r;if(typeof t=="string"){if(r=this.manager.get(t),!r)throw new Error(`Cannot find recognizer ${t}`)}else r=t;const{simultaneous:i}=this;return i[r.id]||(i[r.id]=r,r.recognizeWith(this)),this}dropRecognizeWith(t){if(Array.isArray(t)){for(const i of t)this.dropRecognizeWith(i);return this}let r;return typeof t=="string"?r=this.manager.get(t):r=t,r&&delete this.simultaneous[r.id],this}requireFailure(t){if(Array.isArray(t)){for(const s of t)this.requireFailure(s);return this}let r;if(typeof t=="string"){if(r=this.manager.get(t),!r)throw new Error(`Cannot find recognizer ${t}`)}else r=t;const{requireFail:i}=this;return i.indexOf(r)===-1&&(i.push(r),r.requireFailure(this)),this}dropRequireFailure(t){if(Array.isArray(t)){for(const i of t)this.dropRequireFailure(i);return this}let r;if(typeof t=="string"?r=this.manager.get(t):r=t,r){const i=this.requireFail.indexOf(r);i>-1&&this.requireFail.splice(i,1)}return this}hasRequireFailures(){return!!this.requireFail.find(t=>t.options.enable)}canRecognizeWith(t){return!!this.simultaneous[t.id]}emit(t){if(!t)return;const{state:r}=this;r=P.Ended&&this.manager.emit(this.options.event+Hn(r),t)}tryEmit(t){this.canEmit()?this.emit(t):this.state=P.Failed}canEmit(){let t=0;for(;t{this.state=P.Recognized,this.tryEmit(this._input)},r.interval),P.Began):P.Recognized}return P.Failed}failTimeout(){return this._timer=setTimeout(()=>{this.state=P.Failed},this.options.interval),P.Failed}reset(){clearTimeout(this._timer)}emit(t){this.state===P.Recognized&&(t.tapCount=this.count,this.manager.emit(this.options.event,t))}}const Mp=["","start","move","end","cancel","up","down","left","right"];class Xn extends ic{constructor(t={}){super({enable:!0,pointers:1,event:"pan",threshold:10,direction:$.All,...t}),this.pX=null,this.pY=null}getTouchAction(){const{options:{direction:t}}=this,r=[];return t&$.Horizontal&&r.push(_p),t&$.Vertical&&r.push(pp),r}getEventNames(){return Mp.map(t=>this.options.event+t)}directionTest(t){const{options:r}=this;let i=!0,{distance:s}=t,{direction:n}=t;const o=t.deltaX,a=t.deltaY;return n&r.direction||(r.direction&$.Horizontal?(n=o===0?$.None:o<0?$.Left:$.Right,i=o!==this.pX,s=Math.abs(t.deltaX)):(n=a===0?$.None:a<0?$.Up:$.Down,i=a!==this.pY,s=Math.abs(t.deltaY))),t.direction=n,i&&s>r.threshold&&!!(n&r.direction)}attrTest(t){return super.attrTest(t)&&(!!(this.state&P.Began)||!(this.state&P.Began)&&this.directionTest(t))}emit(t){this.pX=t.deltaX,this.pY=t.deltaY;const r=$[t.direction].toLowerCase();r&&(t.additionalEvent=this.options.event+r),super.emit(t)}}const Ip=["","start","move","end","cancel","in","out"];class Np extends ic{constructor(t={}){super({enable:!0,event:"pinch",threshold:0,pointers:2,...t})}getTouchAction(){return[gp]}getEventNames(){return Ip.map(t=>this.options.event+t)}attrTest(t){return super.attrTest(t)&&(Math.abs(t.scale-1)>this.options.threshold||!!(this.state&P.Began))}emit(t){if(t.scale!==1){const r=t.scale<1?"in":"out";t.additionalEvent=this.options.event+r}super.emit(t)}}class Bp{constructor(t,r,i){this.element=t,this.callback=r,this.options=i}}const Dp=typeof navigator<"u"&&navigator.userAgent?navigator.userAgent.toLowerCase():"",Fp=Dp.indexOf("firefox")!==-1,Yn=4.000244140625,Up=40,Lp=.25;class FA extends Bp{constructor(t,r,i){super(t,r,{enable:!0,...i}),this.handleEvent=s=>{if(!this.options.enable)return;let n=s.deltaY;globalThis.WheelEvent&&(Fp&&s.deltaMode===globalThis.WheelEvent.DOM_DELTA_PIXEL&&(n/=globalThis.devicePixelRatio),s.deltaMode===globalThis.WheelEvent.DOM_DELTA_LINE&&(n*=Up)),n!==0&&n%Yn===0&&(n=Math.floor(n/Yn)),s.shiftKey&&n&&(n=n*Lp),this.callback({type:"wheel",center:{x:s.clientX,y:s.clientY},delta:-n,srcEvent:s,pointerType:"mouse",target:s.target})},t.addEventListener("wheel",this.handleEvent,{passive:!1})}destroy(){this.element.removeEventListener("wheel",this.handleEvent)}enableEventType(t,r){t==="wheel"&&(this.options.enable=r)}}const Kn={DEFAULT:"default",LNGLAT:"lnglat",METER_OFFSETS:"meter-offsets",LNGLAT_OFFSETS:"lnglat-offsets",CARTESIAN:"cartesian"};Object.defineProperty(Kn,"IDENTITY",{get:()=>(G.deprecated("COORDINATE_SYSTEM.IDENTITY","COORDINATE_SYSTEM.CARTESIAN")(),Kn.CARTESIAN)});const ie={WEB_MERCATOR:1,GLOBE:2,WEB_MERCATOR_AUTO_OFFSET:4,IDENTITY:0},_r={common:0,meters:1,pixels:2},UA={click:"onClick",dblclick:"onClick",panstart:"onDragStart",panmove:"onDrag",panend:"onDragEnd"},LA={multipan:[Xn,{threshold:10,direction:$.Vertical,pointers:2}],pinch:[Np,{},null,["multipan"]],pan:[Xn,{threshold:1},["pinch"],["multipan"]],dblclick:[Vn,{event:"dblclick",taps:2}],click:[Vn,{event:"click"},null,["dblclick"]]},kA={DRAW:"draw",MASK:"mask",TERRAIN:"terrain"};function kp(e,t){if(e===t)return!0;if(Array.isArray(e)){const r=e.length;if(!t||t.length!==r)return!1;for(let i=0;i{for(const s in i)if(!kp(i[s],t[s])){r=e(i),t=i;break}return r}}const Qn=[0,0,0,0],Wp=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0],sc=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],$p=[0,0,0],nc=[0,0,0],zp={default:-1,cartesian:0,lnglat:1,"meter-offsets":2,"lnglat-offsets":3};function Ns(e){const t=zp[e];if(t===void 0)throw new Error(`Invalid coordinateSystem: ${e}`);return t}const jp=Is(Xp);function oc(e,t,r=nc){r.length<3&&(r=[r[0],r[1],0]);let i=r,s,n=!0;switch(t==="lnglat-offsets"||t==="meter-offsets"?s=r:s=e.isGeospatial?[Math.fround(e.longitude),Math.fround(e.latitude),0]:null,e.projectionMode){case ie.WEB_MERCATOR:(t==="lnglat"||t==="cartesian")&&(s=[0,0,0],n=!1);break;case ie.WEB_MERCATOR_AUTO_OFFSET:t==="lnglat"?i=s:t==="cartesian"&&(i=[Math.fround(e.center[0]),Math.fround(e.center[1]),0],s=e.unprojectPosition(i),i[0]-=r[0],i[1]-=r[1],i[2]-=r[2]);break;case ie.IDENTITY:i=e.position.map(Math.fround),i[2]=i[2]||0;break;case ie.GLOBE:n=!1,s=null;break;default:n=!1}return{geospatialOrigin:s,shaderCoordinateOrigin:i,offsetMode:n}}function Hp(e,t,r){const{viewMatrixUncentered:i,projectionMatrix:s}=e;let{viewMatrix:n,viewProjectionMatrix:o}=e,a=Qn,c=Qn,l=e.cameraPosition;const{geospatialOrigin:u,shaderCoordinateOrigin:h,offsetMode:d}=oc(e,t,r);return d&&(c=e.projectPosition(u||h),l=[l[0]-c[0],l[1]-c[1],l[2]-c[2]],c[3]=1,a=It([],c,o),n=i||n,o=ve([],s,n),o=ve([],o,Wp)),{viewMatrix:n,viewProjectionMatrix:o,projectionCenter:a,originCommon:c,cameraPosCommon:l,shaderCoordinateOrigin:h,geospatialOrigin:u}}function Vp({viewport:e,devicePixelRatio:t=1,modelMatrix:r=null,coordinateSystem:i="default",coordinateOrigin:s=nc,autoWrapLongitude:n=!1}){i==="default"&&(i=e.isGeospatial?"lnglat":"cartesian");const o=jp({viewport:e,devicePixelRatio:t,coordinateSystem:i,coordinateOrigin:s});return o.wrapLongitude=n,o.modelMatrix=r||sc,o}function Xp({viewport:e,devicePixelRatio:t,coordinateSystem:r,coordinateOrigin:i}){const{projectionCenter:s,viewProjectionMatrix:n,originCommon:o,cameraPosCommon:a,shaderCoordinateOrigin:c,geospatialOrigin:l}=Hp(e,r,i),u=e.getDistanceScales(),h=[e.width*t,e.height*t],d=It([],[0,0,-e.focalDistance,1],e.projectionMatrix)[3]||1,g={coordinateSystem:Ns(r),projectionMode:e.projectionMode,coordinateOrigin:c,commonOrigin:o.slice(0,3),center:s,pseudoMeters:!!e._pseudoMeters,viewportSize:h,devicePixelRatio:t,focalDistance:d,commonUnitsPerMeter:u.unitsPerMeter,commonUnitsPerWorldUnit:u.unitsPerMeter,commonUnitsPerWorldUnit2:$p,scale:e.scale,wrapLongitude:!1,viewProjectionMatrix:n,modelMatrix:sc,cameraPosition:a};if(l){const p=e.getDistanceScales(l);switch(r){case"meter-offsets":g.commonUnitsPerWorldUnit=p.unitsPerMeter,g.commonUnitsPerWorldUnit2=p.unitsPerMeter2;break;case"lnglat":case"lnglat-offsets":e._pseudoMeters||(g.commonUnitsPerMeter=p.unitsPerMeter),g.commonUnitsPerWorldUnit=p.unitsPerDegree,g.commonUnitsPerWorldUnit2=p.unitsPerDegree2;break;case"cartesian":g.commonUnitsPerWorldUnit=[1,1,p.unitsPerMeter[2]],g.commonUnitsPerWorldUnit2=[0,0,p.unitsPerMeter2[2]];break}}return g}const Yp=["default","lnglat","meter-offsets","lnglat-offsets","cartesian"],Kp=Yp.map(e=>`const COORDINATE_SYSTEM_${e.toUpperCase().replaceAll("-","_")}: i32 = ${Ns(e)};`).join(""),Qp=Object.keys(ie).map(e=>`const PROJECTION_MODE_${e}: i32 = ${ie[e]};`).join(""),qp=Object.keys(_r).map(e=>`const UNIT_${e.toUpperCase()}: i32 = ${_r[e]};`).join(""),Zp=`${Kp} +${Qp} +${qp} + +const TILE_SIZE: f32 = 512.0; +const PI: f32 = 3.1415926536; +const WORLD_SCALE: f32 = TILE_SIZE / (PI * 2.0); +const ZERO_64_LOW: vec3 = vec3(0.0, 0.0, 0.0); +const EARTH_RADIUS: f32 = 6370972.0; // meters +const GLOBE_RADIUS: f32 = 256.0; + +// ----------------------------------------------------------------------------- +// Uniform block (converted from GLSL uniform block) +// ----------------------------------------------------------------------------- +struct ProjectUniforms { + wrapLongitude: i32, + coordinateSystem: i32, + commonUnitsPerMeter: vec3, + projectionMode: i32, + scale: f32, + commonUnitsPerWorldUnit: vec3, + commonUnitsPerWorldUnit2: vec3, + center: vec4, + modelMatrix: mat4x4, + viewProjectionMatrix: mat4x4, + viewportSize: vec2, + devicePixelRatio: f32, + focalDistance: f32, + cameraPosition: vec3, + coordinateOrigin: vec3, + commonOrigin: vec3, + pseudoMeters: i32, +}; + +@group(0) @binding(auto) +var project: ProjectUniforms; + +// ----------------------------------------------------------------------------- +// Geometry data shared across the project helpers. +// The active layer shader is responsible for populating this private module +// state before calling the project functions below. +// ----------------------------------------------------------------------------- + +// Structure to carry additional geometry data used by deck.gl filters. +struct Geometry { + worldPosition: vec3, + worldPositionAlt: vec3, + position: vec4, + normal: vec3, + uv: vec2, + pickingColor: vec3, +}; + +var geometry: Geometry; +`,Jp=`${Zp} + +// ----------------------------------------------------------------------------- +// Functions +// ----------------------------------------------------------------------------- + +// Returns an adjustment factor for commonUnitsPerMeter +fn _project_size_at_latitude(lat: f32) -> f32 { + let y = clamp(lat, -89.9, 89.9); + return 1.0 / cos(radians(y)); +} + +// Overloaded version: scales a value in meters at a given latitude. +fn _project_size_at_latitude_m(meters: f32, lat: f32) -> f32 { + return meters * project.commonUnitsPerMeter.z * _project_size_at_latitude(lat); +} + +// Computes a non-linear scale factor based on geometry. +// (Note: This function relies on "geometry" being provided.) +fn project_size() -> f32 { + if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR && + project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT && + project.pseudoMeters == 0) { + if (geometry.position.w == 0.0) { + return _project_size_at_latitude(geometry.worldPosition.y); + } + let y: f32 = geometry.position.y / TILE_SIZE * 2.0 - 1.0; + let y2 = y * y; + let y4 = y2 * y2; + let y6 = y4 * y2; + return 1.0 + 4.9348 * y2 + 4.0587 * y4 + 1.5642 * y6; + } + return 1.0; +} + +// Overloads to scale offsets (meters to world units) +fn project_size_float(meters: f32) -> f32 { + return meters * project.commonUnitsPerMeter.z * project_size(); +} + +fn project_size_vec2(meters: vec2) -> vec2 { + return meters * project.commonUnitsPerMeter.xy * project_size(); +} + +fn project_size_vec3(meters: vec3) -> vec3 { + return meters * project.commonUnitsPerMeter * project_size(); +} + +fn project_size_vec4(meters: vec4) -> vec4 { + return vec4(meters.xyz * project.commonUnitsPerMeter, meters.w); +} + +// Returns a rotation matrix aligning the z‑axis with the given up vector. +fn project_get_orientation_matrix(up: vec3) -> mat3x3 { + let uz = normalize(up); + let ux = select( + vec3(1.0, 0.0, 0.0), + normalize(vec3(uz.y, -uz.x, 0.0)), + abs(uz.z) == 1.0 + ); + let uy = cross(uz, ux); + return mat3x3(ux, uy, uz); +} + +// Since WGSL does not support "out" parameters, we return a struct. +struct RotationResult { + needsRotation: bool, + transform: mat3x3, +}; + +fn project_needs_rotation(commonPosition: vec3) -> RotationResult { + if (project.projectionMode == PROJECTION_MODE_GLOBE) { + return RotationResult(true, project_get_orientation_matrix(commonPosition)); + } else { + return RotationResult(false, mat3x3()); // identity alternative if needed + }; +} + +// Projects a normal vector from the current coordinate system to world space. +fn project_normal(vector: vec3) -> vec3 { + let normal_modelspace = project.modelMatrix * vec4(vector, 0.0); + var n = normalize(normal_modelspace.xyz * project.commonUnitsPerMeter); + let rotResult = project_needs_rotation(geometry.position.xyz); + if (rotResult.needsRotation) { + n = rotResult.transform * n; + } + return n; +} + +// Applies a scale offset based on y-offset (dy) +fn project_offset_(offset: vec4) -> vec4 { + let dy: f32 = offset.y; + let commonUnitsPerWorldUnit = project.commonUnitsPerWorldUnit + project.commonUnitsPerWorldUnit2 * dy; + return vec4(offset.xyz * commonUnitsPerWorldUnit, offset.w); +} + +// Projects lng/lat coordinates to a unit tile [0,1] +fn project_mercator_(lnglat: vec2) -> vec2 { + var x = lnglat.x; + if (project.wrapLongitude != 0) { + x = ((x + 180.0) % 360.0) - 180.0; + } + let y = clamp(lnglat.y, -89.9, 89.9); + return vec2( + radians(x) + PI, + PI + log(tan(PI * 0.25 + radians(y) * 0.5)) + ) * WORLD_SCALE; +} + +// Projects lng/lat/z coordinates for a globe projection. +fn project_globe_(lnglatz: vec3) -> vec3 { + let lambda = radians(lnglatz.x); + let phi = radians(lnglatz.y); + let cosPhi = cos(phi); + let D = (lnglatz.z / EARTH_RADIUS + 1.0) * GLOBE_RADIUS; + return vec3( + sin(lambda) * cosPhi, + -cos(lambda) * cosPhi, + sin(phi) + ) * D; +} + +// Projects positions (with an optional 64-bit low part) from the input +// coordinate system to the common space. +fn project_position_vec4_f64(position: vec4, position64Low: vec3) -> vec4 { + var position_world = project.modelMatrix * position; + + // Work around for a Mac+NVIDIA bug: + if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR) { + if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) { + return vec4( + project_mercator_(position_world.xy), + _project_size_at_latitude_m(position_world.z, position_world.y), + position_world.w + ); + } + if (project.coordinateSystem == COORDINATE_SYSTEM_CARTESIAN) { + position_world = vec4f(position_world.xyz + project.coordinateOrigin, position_world.w); + } + } + if (project.projectionMode == PROJECTION_MODE_GLOBE) { + if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) { + return vec4( + project_globe_(position_world.xyz), + position_world.w + ); + } + } + if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET) { + if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) { + if (abs(position_world.y - project.coordinateOrigin.y) > 0.25) { + return vec4( + project_mercator_(position_world.xy) - project.commonOrigin.xy, + project_size_float(position_world.z), + position_world.w + ); + } + } + } + if (project.projectionMode == PROJECTION_MODE_IDENTITY || + (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET && + (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT || + project.coordinateSystem == COORDINATE_SYSTEM_CARTESIAN))) { + position_world = vec4f(position_world.xyz - project.coordinateOrigin, position_world.w); + } + + return project_offset_(position_world) + + project_offset_(project.modelMatrix * vec4(position64Low, 0.0)); +} + +// Overloaded versions for different input types. +fn project_position_vec4_f32(position: vec4) -> vec4 { + return project_position_vec4_f64(position, ZERO_64_LOW); +} + +fn project_position_vec3_f64(position: vec3, position64Low: vec3) -> vec3 { + let projected_position = project_position_vec4_f64(vec4(position, 1.0), position64Low); + return projected_position.xyz; +} + +fn project_position_vec3_f32(position: vec3) -> vec3 { + let projected_position = project_position_vec4_f64(vec4(position, 1.0), ZERO_64_LOW); + return projected_position.xyz; +} + +fn project_position_vec2_f32(position: vec2) -> vec2 { + let projected_position = project_position_vec4_f64(vec4(position, 0.0, 1.0), ZERO_64_LOW); + return projected_position.xy; +} + +// Transforms a common space position to clip space. +fn project_common_position_to_clipspace_with_projection(position: vec4, viewProjectionMatrix: mat4x4, center: vec4) -> vec4 { + return viewProjectionMatrix * position + center; +} + +// Uses the project viewProjectionMatrix and center. +fn project_common_position_to_clipspace(position: vec4) -> vec4 { + return project_common_position_to_clipspace_with_projection(position, project.viewProjectionMatrix, project.center); +} + +// Returns a clip space offset corresponding to a given number of screen pixels. +fn project_pixel_size_to_clipspace(pixels: vec2) -> vec2 { + let offset = pixels / project.viewportSize * project.devicePixelRatio * 2.0; + return offset * project.focalDistance; +} + +fn project_meter_size_to_pixel(meters: f32) -> f32 { + return project_size_float(meters) * project.scale; +} + +fn project_unit_size_to_pixel(size: f32, unit: i32) -> f32 { + if (unit == UNIT_METERS) { + return project_meter_size_to_pixel(size); + } else if (unit == UNIT_COMMON) { + return size * project.scale; + } + // UNIT_PIXELS: no scaling applied. + return size; +} + +fn project_pixel_size_float(pixels: f32) -> f32 { + return pixels / project.scale; +} + +fn project_pixel_size_vec2(pixels: vec2) -> vec2 { + return pixels / project.scale; +} +`,Gp=["default","lnglat","meter-offsets","lnglat-offsets","cartesian"],e_=Gp.map(e=>`const int COORDINATE_SYSTEM_${e.toUpperCase().replaceAll("-","_")} = ${Ns(e)};`).join(""),t_=Object.keys(ie).map(e=>`const int PROJECTION_MODE_${e} = ${ie[e]};`).join(""),r_=Object.keys(_r).map(e=>`const int UNIT_${e.toUpperCase()} = ${_r[e]};`).join(""),i_=`${e_} +${t_} +${r_} +layout(std140) uniform projectUniforms { +bool wrapLongitude; +int coordinateSystem; +vec3 commonUnitsPerMeter; +int projectionMode; +float scale; +vec3 commonUnitsPerWorldUnit; +vec3 commonUnitsPerWorldUnit2; +vec4 center; +mat4 modelMatrix; +mat4 viewProjectionMatrix; +vec2 viewportSize; +float devicePixelRatio; +float focalDistance; +vec3 cameraPosition; +vec3 coordinateOrigin; +vec3 commonOrigin; +bool pseudoMeters; +} project; +const float TILE_SIZE = 512.0; +const float PI = 3.1415926536; +const float WORLD_SCALE = TILE_SIZE / (PI * 2.0); +const vec3 ZERO_64_LOW = vec3(0.0); +const float EARTH_RADIUS = 6370972.0; +const float GLOBE_RADIUS = 256.0; +float project_size_at_latitude(float lat) { +float y = clamp(lat, -89.9, 89.9); +return 1.0 / cos(radians(y)); +} +float project_size() { +if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR && +project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT && +project.pseudoMeters == false) { +if (geometry.position.w == 0.0) { +return project_size_at_latitude(geometry.worldPosition.y); +} +float y = geometry.position.y / TILE_SIZE * 2.0 - 1.0; +float y2 = y * y; +float y4 = y2 * y2; +float y6 = y4 * y2; +return 1.0 + 4.9348 * y2 + 4.0587 * y4 + 1.5642 * y6; +} +return 1.0; +} +float project_size_at_latitude(float meters, float lat) { +return meters * project.commonUnitsPerMeter.z * project_size_at_latitude(lat); +} +float project_size(float meters) { +return meters * project.commonUnitsPerMeter.z * project_size(); +} +vec2 project_size(vec2 meters) { +return meters * project.commonUnitsPerMeter.xy * project_size(); +} +vec3 project_size(vec3 meters) { +return meters * project.commonUnitsPerMeter * project_size(); +} +vec4 project_size(vec4 meters) { +return vec4(meters.xyz * project.commonUnitsPerMeter, meters.w); +} +mat3 project_get_orientation_matrix(vec3 up) { +vec3 uz = normalize(up); +vec3 ux = abs(uz.z) == 1.0 ? vec3(1.0, 0.0, 0.0) : normalize(vec3(uz.y, -uz.x, 0)); +vec3 uy = cross(uz, ux); +return mat3(ux, uy, uz); +} +bool project_needs_rotation(vec3 commonPosition, out mat3 transform) { +if (project.projectionMode == PROJECTION_MODE_GLOBE) { +transform = project_get_orientation_matrix(commonPosition); +return true; +} +return false; +} +vec3 project_normal(vec3 vector) { +vec4 normal_modelspace = project.modelMatrix * vec4(vector, 0.0); +vec3 n = normalize(normal_modelspace.xyz * project.commonUnitsPerMeter); +mat3 rotation; +if (project_needs_rotation(geometry.position.xyz, rotation)) { +n = rotation * n; +} +return n; +} +vec4 project_offset_(vec4 offset) { +float dy = offset.y; +vec3 commonUnitsPerWorldUnit = project.commonUnitsPerWorldUnit + project.commonUnitsPerWorldUnit2 * dy; +return vec4(offset.xyz * commonUnitsPerWorldUnit, offset.w); +} +vec2 project_mercator_(vec2 lnglat) { +float x = lnglat.x; +if (project.wrapLongitude) { +x = mod(x + 180., 360.0) - 180.; +} +float y = clamp(lnglat.y, -89.9, 89.9); +return vec2( +radians(x) + PI, +PI + log(tan_fp32(PI * 0.25 + radians(y) * 0.5)) +) * WORLD_SCALE; +} +vec3 project_globe_(vec3 lnglatz) { +float lambda = radians(lnglatz.x); +float phi = radians(lnglatz.y); +float cosPhi = cos(phi); +float D = (lnglatz.z / EARTH_RADIUS + 1.0) * GLOBE_RADIUS; +return vec3( +sin(lambda) * cosPhi, +-cos(lambda) * cosPhi, +sin(phi) +) * D; +} +vec4 project_position(vec4 position, vec3 position64Low) { +vec4 position_world = project.modelMatrix * position; +if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR) { +if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) { +return vec4( +project_mercator_(position_world.xy), +project_size_at_latitude(position_world.z, position_world.y), +position_world.w +); +} +if (project.coordinateSystem == COORDINATE_SYSTEM_CARTESIAN) { +position_world.xyz += project.coordinateOrigin; +} +} +if (project.projectionMode == PROJECTION_MODE_GLOBE) { +if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) { +return vec4( +project_globe_(position_world.xyz), +position_world.w +); +} +} +if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET) { +if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) { +if (abs(position_world.y - project.coordinateOrigin.y) > 0.25) { +return vec4( +project_mercator_(position_world.xy) - project.commonOrigin.xy, +project_size(position_world.z), +position_world.w +); +} +} +} +if (project.projectionMode == PROJECTION_MODE_IDENTITY || +(project.projectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET && +(project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT || +project.coordinateSystem == COORDINATE_SYSTEM_CARTESIAN))) { +position_world.xyz -= project.coordinateOrigin; +} +return project_offset_(position_world) + project_offset_(project.modelMatrix * vec4(position64Low, 0.0)); +} +vec4 project_position(vec4 position) { +return project_position(position, ZERO_64_LOW); +} +vec3 project_position(vec3 position, vec3 position64Low) { +vec4 projected_position = project_position(vec4(position, 1.0), position64Low); +return projected_position.xyz; +} +vec3 project_position(vec3 position) { +vec4 projected_position = project_position(vec4(position, 1.0), ZERO_64_LOW); +return projected_position.xyz; +} +vec2 project_position(vec2 position) { +vec4 projected_position = project_position(vec4(position, 0.0, 1.0), ZERO_64_LOW); +return projected_position.xy; +} +vec4 project_common_position_to_clipspace(vec4 position, mat4 viewProjectionMatrix, vec4 center) { +return viewProjectionMatrix * position + center; +} +vec4 project_common_position_to_clipspace(vec4 position) { +return project_common_position_to_clipspace(position, project.viewProjectionMatrix, project.center); +} +vec2 project_pixel_size_to_clipspace(vec2 pixels) { +vec2 offset = pixels / project.viewportSize * project.devicePixelRatio * 2.0; +return offset * project.focalDistance; +} +float project_size_to_pixel(float meters) { +return project_size(meters) * project.scale; +} +vec2 project_size_to_pixel(vec2 meters) { +return project_size(meters) * project.scale; +} +float project_size_to_pixel(float size, int unit) { +if (unit == UNIT_METERS) return project_size_to_pixel(size); +if (unit == UNIT_COMMON) return size * project.scale; +return size; +} +float project_pixel_size(float pixels) { +return pixels / project.scale; +} +vec2 project_pixel_size(vec2 pixels) { +return pixels / project.scale; +} +`,s_={};function n_(e=s_){return"viewport"in e?Vp(e):{}}const o_={name:"project",dependencies:[nd,up],source:Jp,vs:i_,getUniforms:n_,uniformTypes:{wrapLongitude:"f32",coordinateSystem:"i32",commonUnitsPerMeter:"vec3",projectionMode:"i32",scale:"f32",commonUnitsPerWorldUnit:"vec3",commonUnitsPerWorldUnit2:"vec3",center:"vec4",modelMatrix:"mat4x4",viewProjectionMatrix:"mat4x4",viewportSize:"vec2",devicePixelRatio:"f32",focalDistance:"f32",cameraPosition:"vec3",coordinateOrigin:"vec3",commonOrigin:"vec3",pseudoMeters:"f32"}},a_=`// Define a structure to hold both the clip-space position and the common position. +struct ProjectResult { + clipPosition: vec4, + commonPosition: vec4, +}; + +// This function mimics the GLSL version with the 'out' parameter by returning both values. +fn project_position_to_clipspace_and_commonspace( + position: vec3, + position64Low: vec3, + offset: vec3 +) -> ProjectResult { + // Compute the projected position. + let projectedPosition: vec3 = project_position_vec3_f64(position, position64Low); + + // Start with the provided offset. + var finalOffset: vec3 = offset; + + // Get whether a rotation is needed and the rotation matrix. + let rotationResult = project_needs_rotation(projectedPosition); + + // If rotation is needed, update the offset. + if (rotationResult.needsRotation) { + finalOffset = rotationResult.transform * offset; + } + + // Compute the common position. + let commonPosition: vec4 = vec4(projectedPosition + finalOffset, 1.0); + + // Convert to clip-space. + let clipPosition: vec4 = project_common_position_to_clipspace(commonPosition); + + return ProjectResult(clipPosition, commonPosition); +} + +// A convenience overload that returns only the clip-space position. +fn project_position_to_clipspace( + position: vec3, + position64Low: vec3, + offset: vec3 +) -> vec4 { + return project_position_to_clipspace_and_commonspace(position, position64Low, offset).clipPosition; +} +`,c_=`vec4 project_position_to_clipspace( + vec3 position, vec3 position64Low, vec3 offset, out vec4 commonPosition +) { + vec3 projectedPosition = project_position(position, position64Low); + mat3 rotation; + if (project_needs_rotation(projectedPosition, rotation)) { + // offset is specified as ENU + // when in globe projection, rotate offset so that the ground alighs with the surface of the globe + offset = rotation * offset; + } + commonPosition = vec4(projectedPosition + offset, 1.0); + return project_common_position_to_clipspace(commonPosition); +} + +vec4 project_position_to_clipspace( + vec3 position, vec3 position64Low, vec3 offset +) { + vec4 commonPosition; + return project_position_to_clipspace(position, position64Low, offset, commonPosition); +} +`,WA={name:"project32",dependencies:[o_],source:a_,vs:c_};function l_(){return[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}function Ke(e,t){const r=It([],t,e);return Kh(r,r,1/r[3]),r}function $A(e,t,r){return r*t+(1-r)*e}function es(e,t,r){return er?r:e}function f_(e){return Math.log(e)*Math.LOG2E}const ac=Math.log2||f_;function fe(e,t){if(!e)throw new Error(t||"@math.gl/web-mercator: assertion failed.")}const se=Math.PI,cc=se/4,J=se/180,ts=180/se,rt=512,mr=4003e4,Vt=85.051129,u_=1.5;function zA(e){return Math.pow(2,e)}function h_(e){return ac(e)}function br(e){const[t,r]=e;fe(Number.isFinite(t)),fe(Number.isFinite(r)&&r>=-90&&r<=90,"invalid latitude");const i=t*J,s=r*J,n=rt*(i+se)/(2*se),o=rt*(se+Math.log(Math.tan(cc+s*.5)))/(2*se);return[n,o]}function Hr(e){const[t,r]=e,i=t/rt*(2*se)-se,s=2*(Math.atan(Math.exp(r/rt*(2*se)-se))-cc);return[i*ts,s*ts]}function d_(e){const{latitude:t}=e;fe(Number.isFinite(t));const r=Math.cos(t*J);return h_(mr*r)-9}function mi(e){const t=Math.cos(e*J);return rt/mr/t}function rs(e){const{latitude:t,longitude:r,highPrecision:i=!1}=e;fe(Number.isFinite(t)&&Number.isFinite(r));const s=rt,n=Math.cos(t*J),o=s/360,a=o/n,c=s/mr/n,l={unitsPerMeter:[c,c,c],metersPerUnit:[1/c,1/c,1/c],unitsPerDegree:[o,a,c],degreesPerUnit:[1/o,1/a,1/c]};if(i){const u=J*Math.tan(t*J)/n,h=o*u/2,d=s/mr*u,g=d/a*c;l.unitsPerDegree2=[0,h,d],l.unitsPerMeter2=[g,0,g]}return l}function lc(e,t){const[r,i,s]=e,[n,o,a]=t,{unitsPerMeter:c,unitsPerMeter2:l}=rs({longitude:r,latitude:i,highPrecision:!0}),u=br(e);u[0]+=n*(c[0]+l[0]*o),u[1]+=o*(c[1]+l[1]*o);const h=Hr(u),d=(s||0)+(a||0);return Number.isFinite(s)||Number.isFinite(a)?[h[0],h[1],d]:h}function g_(e){const{height:t,pitch:r,bearing:i,altitude:s,scale:n,center:o}=e,a=l_();lr(a,a,[0,0,-s]),Ea(a,a,-r*J),Sa(a,a,i*J);const c=n/t;return Ps(a,a,[c,c,c]),o&&lr(a,a,Sh([],o)),a}function p_(e){const{width:t,height:r,altitude:i,pitch:s=0,offset:n,center:o,scale:a,nearZMultiplier:c=1,farZMultiplier:l=1}=e;let{fovy:u=Tr(u_)}=e;i!==void 0&&(u=Tr(i));const h=u*J,d=s*J,g=fc(u);let p=g;o&&(p+=o[2]*a/Math.cos(d)/r);const _=h*(.5+(n?n[1]:0)/r),m=Math.sin(_)*p/Math.sin(es(Math.PI/2-d-_,.01,Math.PI-.01)),b=Math.sin(d)*m+p,R=p*10,T=Math.min(b*l,R);return{fov:h,aspect:t/r,focalDistance:g,near:c,far:T}}function Tr(e){return 2*Math.atan(.5/e)*ts}function fc(e){return .5/Math.tan(.5*e*J)}function uc(e,t){const[r,i,s=0]=e;return fe(Number.isFinite(r)&&Number.isFinite(i)&&Number.isFinite(s)),Ke(t,[r,i,s,1])}function hc(e,t,r=0){const[i,s,n]=e;if(fe(Number.isFinite(i)&&Number.isFinite(s),"invalid pixel coordinate"),Number.isFinite(n))return Ke(t,[i,s,n,1]);const o=Ke(t,[i,s,0,1]),a=Ke(t,[i,s,1,1]),c=o[2],l=a[2],u=c===l?0:((r||0)-c)/(l-c);return Aa([],o,a,u)}function __(e){const{width:t,height:r,bounds:i,minExtent:s=0,maxZoom:n=24,offset:o=[0,0]}=e,[[a,c],[l,u]]=i,h=m_(e.padding),d=br([a,es(u,-Vt,Vt)]),g=br([l,es(c,-Vt,Vt)]),p=[Math.max(Math.abs(g[0]-d[0]),s),Math.max(Math.abs(g[1]-d[1]),s)],_=[t-h.left-h.right-Math.abs(o[0])*2,r-h.top-h.bottom-Math.abs(o[1])*2];fe(_[0]>0&&_[1]>0);const m=_[0]/p[0],b=_[1]/p[1],R=(h.right-h.left)/2/m,T=(h.top-h.bottom)/2/b,y=[(g[0]+d[0])/2+R,(g[1]+d[1])/2+T],E=Hr(y),S=Math.min(n,ac(Math.abs(Math.min(m,b))));return fe(Number.isFinite(S)),{longitude:E[0],latitude:E[1],zoom:S}}function m_(e=0){return typeof e=="number"?{top:e,bottom:e,left:e,right:e}:(fe(Number.isFinite(e.top)&&Number.isFinite(e.bottom)&&Number.isFinite(e.left)&&Number.isFinite(e.right)),e)}const qn=Math.PI/180;function b_(e,t=0){const{width:r,height:i,unproject:s}=e,n={targetZ:t},o=s([0,i],n),a=s([r,i],n);let c,l;const u=e.fovy?.5*e.fovy*qn:Math.atan(.5/e.altitude),h=(90-e.pitch)*qn;return u>h-.01?(c=Zn(e,0,t),l=Zn(e,r,t)):(c=s([0,0],n),l=s([r,0],n)),[o,a,l,c]}function Zn(e,t,r){const{pixelUnprojectionMatrix:i}=e,s=Ke(i,[t,0,1,1]),n=Ke(i,[t,e.height,1,1]),a=(r*e.distanceScales.unitsPerMeter[2]-s[2])/(n[2]-s[2]),c=Aa([],s,n,a),l=Hr(c);return l.push(r),l}const T_=`struct pickingUniforms { + isActive: f32, + isAttribute: f32, + isHighlightActive: f32, + useByteColors: f32, + highlightedObjectColor: vec3, + highlightColor: vec4, +}; + +@group(0) @binding(auto) var picking: pickingUniforms; + +fn picking_normalizeColor(color: vec3) -> vec3 { + return select(color, color / 255.0, picking.useByteColors > 0.5); +} + +fn picking_normalizeColor4(color: vec4) -> vec4 { + return select(color, color / 255.0, picking.useByteColors > 0.5); +} + +fn picking_isColorZero(color: vec3) -> bool { + return dot(color, vec3(1.0)) < 0.00001; +} + +fn picking_isColorValid(color: vec3) -> bool { + return dot(color, vec3(1.0)) > 0.00001; +} +`,jA={...Sn,source:T_,defaultUniforms:{...Sn.defaultUniforms,useByteColors:!0},inject:{"vs:DECKGL_FILTER_GL_POSITION":` + // for picking depth values + picking_setPickingAttribute(position.z / position.w); + `,"vs:DECKGL_FILTER_COLOR":` + picking_setPickingColor(geometry.pickingColor); + `,"fs:DECKGL_FILTER_COLOR":{order:99,injection:` + // use highlight color if this fragment belongs to the selected object. + color = picking_filterHighlightColor(color); + + // use picking color if rendering to picking FBO. + color = picking_filterPickingColor(color); + `}}};class A_{constructor(t={}){this._pool=[],this.opts={overAlloc:2,poolSize:100},this.setOptions(t)}setOptions(t){Object.assign(this.opts,t)}allocate(t,r,{size:i=1,type:s,padding:n=0,copy:o=!1,initialize:a=!1,maxCount:c}){const l=s||t&&t.constructor||Float32Array,u=r*i+n;if(ArrayBuffer.isView(t)){if(u<=t.length)return t;if(u*t.BYTES_PER_ELEMENT<=t.buffer.byteLength)return new l(t.buffer,0,u)}let h=1/0;c&&(h=c*i+n);const d=this._allocate(l,u,a,h);return t&&o?d.set(t):a||d.fill(0,0,4),this._release(t),d}release(t){this._release(t)}_allocate(t,r,i,s){let n=Math.max(Math.ceil(r*this.opts.overAlloc),1);n>s&&(n=s);const o=this._pool,a=t.BYTES_PER_ELEMENT*n,c=o.findIndex(l=>l.byteLength>=a);if(c>=0){const l=new t(o.splice(c,1)[0],0,n);return i&&l.fill(0),l}return new t(n)}_release(t){if(!ArrayBuffer.isView(t))return;const r=this._pool,{buffer:i}=t,{byteLength:s}=i,n=r.findIndex(o=>o.byteLength>=s);n<0?r.push(i):(n>0||r.lengththis.opts.poolSize&&r.shift()}}const Pt=new A_;function pt(){return[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]}function HA(e,t){const r=e%t;return r<0?t+r:r}function y_(e){return[e[12],e[13],e[14]]}function VA(e){const t=e[10],r=e[14];return{near:r/(t-1),far:r/(t+1)}}function R_(e){return{left:ke(e[3]+e[0],e[7]+e[4],e[11]+e[8],e[15]+e[12]),right:ke(e[3]-e[0],e[7]-e[4],e[11]-e[8],e[15]-e[12]),bottom:ke(e[3]+e[1],e[7]+e[5],e[11]+e[9],e[15]+e[13]),top:ke(e[3]-e[1],e[7]-e[5],e[11]-e[9],e[15]-e[13]),near:ke(e[3]+e[2],e[7]+e[6],e[11]+e[10],e[15]+e[14]),far:ke(e[3]-e[2],e[7]-e[6],e[11]-e[10],e[15]-e[14])}}const Jn=new Ge;function ke(e,t,r,i){Jn.set(e,t,r);const s=Jn.len();return{distance:i/s,normal:new Ge(-e/s,-t/s,-r/s)}}function E_(e){return e-Math.fround(e)}let lt;function bi(e,t){const{size:r=1,startIndex:i=0}=t,s=t.endIndex!==void 0?t.endIndex:e.length,n=(s-i)/r;lt=Pt.allocate(lt,n,{type:Float32Array,size:r*2});let o=i,a=0;for(;or.name===t)||null}getAttributeNamesForBuffer(t){var r;return t.attributes?(r=t.attributes)==null?void 0:r.map(i=>i.attribute):[t.name]}mergeBufferLayouts(t,r){const i=[...t];for(const s of r){const n=i.findIndex(o=>o.name===s.name);n<0?i.push(s):i[n]=s}return i}getBufferIndex(t){const r=this.bufferLayouts.findIndex(i=>i.name===t);return r===-1&&A.warn(`BufferLayout: Missing buffer for "${t}".`)(),r}}function io(e,t){let r=1/0;for(const i of e){const s=t[i];s!==void 0&&(r=Math.min(r,s))}return r}function $_(e,t){const r=Object.fromEntries(e.attributes.map(s=>[s.name,s.location])),i=t.slice();return i.sort((s,n)=>{const o=s.attributes?s.attributes.map(u=>u.attribute):[s.name],a=n.attributes?n.attributes.map(u=>u.attribute):[n.name],c=io(o,r),l=io(a,r);return c-l}),i}function so(e,t){if(!e||!t.some(i=>{var s;return(s=i.bindingLayout)==null?void 0:s.length}))return e;const r={...e,bindings:e.bindings.map(i=>({...i}))};"attributes"in(e||{})&&(r.attributes=(e==null?void 0:e.attributes)||[]);for(const i of t)for(const s of i.bindingLayout||[])for(const n of j_(s.name)){const o=r.bindings.find(a=>a.name===n);(o==null?void 0:o.group)===0&&(o.group=s.group)}return r}function z_(e){return!!(e.uniformTypes&&!H_(e.uniformTypes))}function j_(e){const t=new Set([e,`${e}Uniforms`]);return e.endsWith("Uniforms")||t.add(`${e}Sampler`),[...t]}function H_(e){for(const t in e)return!1;return!0}function V_(e){return Vf(e)||typeof e=="number"||typeof e=="boolean"}function X_(e,t={}){const r={bindings:{},uniforms:{}};return Object.keys(e).forEach(i=>{const s=e[i];Object.prototype.hasOwnProperty.call(t,i)||V_(s)?r.uniforms[i]=s:r.bindings[i]=s}),r}class Y_{constructor(t,r){f(this,"options",{disableWarnings:!1});f(this,"modules");f(this,"moduleUniforms");f(this,"moduleBindings");Object.assign(this.options,r);const i=ys(Object.values(t).filter(K_));for(const s of i)t[s.name]=s;A.log(1,"Creating ShaderInputs with modules",Object.keys(t))(),this.modules=t,this.moduleUniforms={},this.moduleBindings={};for(const[s,n]of Object.entries(t))n&&(this._addModule(n),n.name&&s!==n.name&&!this.options.disableWarnings&&A.warn(`Module name: ${s} vs ${n.name}`)())}destroy(){}setProps(t){var r;for(const i of Object.keys(t)){const s=i,n=t[s]||{},o=this.modules[s];if(!o)this.options.disableWarnings||A.warn(`Module ${i} not found`)();else{const a=this.moduleUniforms[s],c=this.moduleBindings[s],l=((r=o.getUniforms)==null?void 0:r.call(o,n,a))||n,{uniforms:u,bindings:h}=X_(l,o.uniformTypes);this.moduleUniforms[s]=no(a,u,o.uniformTypes),this.moduleBindings[s]={...c,...h}}}}getModules(){return Object.values(this.modules)}getUniformValues(){return this.moduleUniforms}getBindingValues(){const t={};for(const r of Object.values(this.moduleBindings))Object.assign(t,r);return t}getDebugTable(){var r;const t={};for(const[i,s]of Object.entries(this.moduleUniforms))for(const[n,o]of Object.entries(s))t[`${i}.${n}`]={type:(r=this.modules[i].uniformTypes)==null?void 0:r[n],value:String(o)};return t}_addModule(t){const r=t.name;this.moduleUniforms[r]=no({},t.defaultUniforms||{},t.uniformTypes),this.moduleBindings[r]={}}}function no(e={},t={},r={}){const i={...e};for(const[s,n]of Object.entries(t))n!==void 0&&(i[s]=ss(e[s],n,r[s]));return i}function ss(e,t,r){if(!r||typeof r=="string")return bt(t);if(Array.isArray(r)){if(ns(t)||!Array.isArray(t))return bt(t);const o=Array.isArray(e)&&!ns(e)?[...e]:[],a=o.slice();for(let c=0;cr===void 0?void 0:bt(r)):os(e)?Object.fromEntries(Object.entries(e).map(([t,r])=>[t,r===void 0?void 0:bt(r)])):e}function ns(e){return ArrayBuffer.isView(e)||Array.isArray(e)&&(e.length===0||typeof e[0]=="number")}function os(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&!ArrayBuffer.isView(e)}function K_(e){return!!(e!=null&&e.dependencies)}const dc={"+X":0,"-X":1,"+Y":2,"-Y":3,"+Z":4,"-Z":5};function ft(e){return e?Array.isArray(e)?e[0]??null:e:null}function Q_(e){const{dimension:t,data:r}=e;if(!r)return null;switch(t){case"1d":{const i=ft(r);if(!i)return null;const{width:s}=ut(i);return{width:s,height:1}}case"2d":{const i=ft(r);return i?ut(i):null}case"3d":case"2d-array":{if(!Array.isArray(r)||r.length===0)return null;const i=ft(r[0]);return i?ut(i):null}case"cube":{const i=Object.keys(r)[0]??null;if(!i)return null;const s=r[i],n=ft(s);return n?ut(n):null}case"cube-array":{if(!Array.isArray(r)||r.length===0)return null;const i=r[0],s=Object.keys(i)[0]??null;if(!s)return null;const n=ft(i[s]);return n?ut(n):null}default:return null}}function ut(e){if(ws(e))return Ia(e);if(typeof e=="object"&&"width"in e&&"height"in e)return{width:e.width,height:e.height};throw new Error("Unsupported mip-level data")}function q_(e){return typeof e=="object"&&e!==null&&"data"in e&&"width"in e&&"height"in e}function Z_(e){return ArrayBuffer.isView(e)}function gc(e){const{textureFormat:t,format:r}=e;if(t&&r&&t!==r)throw new Error(`Conflicting texture formats "${t}" and "${r}" provided for the same mip level`);return t??r}function pc(e){const t=dc[e];if(t===void 0)throw new Error(`Invalid cube face: ${e}`);return t}function J_(e,t){return 6*e+pc(t)}function _c(e){throw new Error("setTexture1DData not supported in WebGL.")}function G_(e){return Array.isArray(e)?e:[e]}function nt(e,t,r,i){const s=G_(t),n=e,o=[];for(let a=0;a>a),height:Math.max(1,r.height>>a),...i?{format:i}:{}},textureFormat:i,z:n,mipLevel:a});else throw new Error("Unsupported 2D mip-level payload")}return o}function mc(e){const t=[];for(let r=0;r{for(const[s,n]of Object.entries(r)){const o=J_(i,s);t.push(...nt(o,n))}}),t}const Lr=class Lr{constructor(t,r){f(this,"device");f(this,"id");f(this,"props");f(this,"_texture",null);f(this,"_sampler",null);f(this,"_view",null);f(this,"ready");f(this,"isReady",!1);f(this,"destroyed",!1);f(this,"resolveReady",()=>{});f(this,"rejectReady",()=>{});this.device=t;const i=Xr("dynamic-texture"),s=r;this.props={...Lr.defaultProps,id:i,...r,data:null},this.id=this.props.id,this.ready=new Promise((n,o)=>{this.resolveReady=n,this.rejectReady=o}),this.initAsync(s)}get texture(){if(!this._texture)throw new Error("Texture not initialized yet");return this._texture}get sampler(){if(!this._sampler)throw new Error("Sampler not initialized yet");return this._sampler}get view(){if(!this._view)throw new Error("View not initialized yet");return this._view}get[Symbol.toStringTag](){return"DynamicTexture"}toString(){var i,s;const t=((i=this._texture)==null?void 0:i.width)??this.props.width??"?",r=((s=this._texture)==null?void 0:s.height)??this.props.height??"?";return`DynamicTexture:"${this.id}":${t}x${r}px:(${this.isReady?"ready":"loading..."})`}async initAsync(t){try{const r=await this._loadAllData(t);this._checkNotDestroyed();const i=r.data?em({...r,width:t.width,height:t.height,format:t.format}):[],s="format"in t&&t.format!==void 0,n="usage"in t&&t.usage!==void 0,a=(()=>{if(this.props.width&&this.props.height)return{width:this.props.width,height:this.props.height};const _=Q_(r);return _||{width:this.props.width||1,height:this.props.height||1}})();if(!a||a.width<=0||a.height<=0)throw new Error(`${this} size could not be determined or was zero`);const c=tm(this.device,i,a,{format:s?t.format:void 0}),l=c.format??this.props.format,u={...this.props,...a,format:l,mipLevels:1,data:void 0};this.device.isTextureFormatCompressed(l)&&!n&&(u.usage=U.SAMPLE|U.COPY_DST);const h=this.props.mipmaps&&!c.hasExplicitMipChain&&!this.device.isTextureFormatCompressed(l);if(this.device.type==="webgpu"&&h){const _=this.props.dimension==="3d"?U.SAMPLE|U.STORAGE|U.COPY_DST|U.COPY_SRC:U.SAMPLE|U.RENDER|U.COPY_DST|U.COPY_SRC;u.usage|=_}const d=this.device.getMipLevelCount(u.width,u.height),g=c.hasExplicitMipChain?c.mipLevels:this.props.mipLevels==="auto"?d:Math.max(1,Math.min(d,this.props.mipLevels??1)),p={...u,mipLevels:g};this._texture=this.device.createTexture(p),this._sampler=this.texture.sampler,this._view=this.texture.view,c.subresources.length&&this._setTextureSubresources(c.subresources),this.props.mipmaps&&!c.hasExplicitMipChain&&!h&&A.warn(`${this} skipping auto-generated mipmaps for compressed texture format`)(),h&&this.generateMipmaps(),this.isReady=!0,this.resolveReady(this.texture),A.info(0,`${this} created`)()}catch(r){const i=r instanceof Error?r:new Error(String(r));this.rejectReady(i)}}destroy(){this._texture&&(this._texture.destroy(),this._texture=null,this._sampler=null,this._view=null),this.destroyed=!0}generateMipmaps(){this.device.type==="webgl"?this.texture.generateMipmapsWebGL():this.device.type==="webgpu"?this.device.generateMipmapsWebGPU(this.texture):A.warn(`${this} mipmaps not supported on ${this.device.type}`)}setSampler(t={}){this._checkReady();const r=t instanceof tt?t:this.device.createSampler(t);this.texture.setSampler(r),this._sampler=r}async readBuffer(t={}){this.isReady||await this.ready;const r=t.width??this.texture.width,i=t.height??this.texture.height,s=t.depthOrArrayLayers??this.texture.depth,n=this.texture.computeMemoryLayout({width:r,height:i,depthOrArrayLayers:s}),o=this.device.createBuffer({byteLength:n.byteLength,usage:N.COPY_DST|N.MAP_READ});this.texture.readBuffer({...t,width:r,height:i,depthOrArrayLayers:s},o);const a=this.device.createFence();return await a.signaled,a.destroy(),o}async readAsync(t={}){this.isReady||await this.ready;const r=t.width??this.texture.width,i=t.height??this.texture.height,s=t.depthOrArrayLayers??this.texture.depth,n=this.texture.computeMemoryLayout({width:r,height:i,depthOrArrayLayers:s}),o=await this.readBuffer(t),a=await o.readAsync(0,n.byteLength);return o.destroy(),a.buffer}resize(t){if(this._checkReady(),t.width===this.texture.width&&t.height===this.texture.height)return!1;const r=this.texture;return this._texture=r.clone(t),this._sampler=this.texture.sampler,this._view=this.texture.view,r.destroy(),A.info(`${this} resized`),!0}getCubeFaceIndex(t){const r=dc[t];if(r===void 0)throw new Error(`Invalid cube face: ${t}`);return r}getCubeArrayFaceIndex(t,r){return 6*t+this.getCubeFaceIndex(r)}setTexture1DData(t){if(this._checkReady(),this.texture.props.dimension!=="1d")throw new Error(`${this} is not 1d`);const r=_c();this._setTextureSubresources(r)}setTexture2DData(t,r=0){if(this._checkReady(),this.texture.props.dimension!=="2d")throw new Error(`${this} is not 2d`);const i=nt(r,t);this._setTextureSubresources(i)}setTexture3DData(t){if(this.texture.props.dimension!=="3d")throw new Error(`${this} is not 3d`);const r=mc(t);this._setTextureSubresources(r)}setTextureArrayData(t){if(this.texture.props.dimension!=="2d-array")throw new Error(`${this} is not 2d-array`);const r=bc(t);this._setTextureSubresources(r)}setTextureCubeData(t){if(this.texture.props.dimension!=="cube")throw new Error(`${this} is not cube`);const r=Tc(t);this._setTextureSubresources(r)}setTextureCubeArrayData(t){if(this.texture.props.dimension!=="cube-array")throw new Error(`${this} is not cube-array`);const r=Ac(t);this._setTextureSubresources(r)}_setTextureSubresources(t){for(const r of t){const{z:i,mipLevel:s}=r;switch(r.type){case"external-image":const{image:n,flipY:o}=r;this.texture.copyExternalImage({image:n,z:i,mipLevel:s,flipY:o});break;case"texture-data":const{data:a,textureFormat:c}=r;if(c&&c!==this.texture.format)throw new Error(`${this} mip level ${s} uses format "${c}" but texture format is "${this.texture.format}"`);this.texture.writeData(a.data,{x:0,y:0,z:i,width:a.width,height:a.height,depthOrArrayLayers:1,mipLevel:s});break;default:throw new Error("Unsupported 2D mip-level payload")}}}async _loadAllData(t){const r=await as(t.data);return{dimension:t.dimension??"2d",data:r??null}}_checkNotDestroyed(){this.destroyed&&A.warn(`${this} already destroyed`)}_checkReady(){this.isReady||A.warn(`${this} Cannot perform this operation before ready`)}};f(Lr,"defaultProps",{...U.defaultProps,dimension:"2d",data:null,mipmaps:!1});let $e=Lr;function em(e){if(!e.data)return[];const t=e.width&&e.height?{width:e.width,height:e.height}:void 0,r="format"in e?e.format:void 0;switch(e.dimension){case"1d":return _c();case"2d":return nt(0,e.data,t,r);case"3d":return mc(e.data);case"2d-array":return bc(e.data);case"cube":return Tc(e.data);case"cube-array":return Ac(e.data);default:throw new Error(`Unhandled dimension ${e.dimension}`)}}function tm(e,t,r,i){if(t.length===0)return{subresources:t,mipLevels:1,format:i.format,hasExplicitMipChain:!1};const s=new Map;for(const u of t){const h=s.get(u.z)??[];h.push(u),s.set(u.z,h)}const n=t.some(u=>u.mipLevel>0);let o=i.format,a=Number.POSITIVE_INFINITY;const c=[];for(const[u,h]of s){const d=[...h].sort((R,T)=>R.mipLevel-T.mipLevel),g=d[0];if(!g||g.mipLevel!==0)throw new Error(`DynamicTexture: slice ${u} is missing mip level 0`);const p=ao(e,g);if(p.width!==r.width||p.height!==r.height)throw new Error(`DynamicTexture: slice ${u} base level dimensions ${p.width}x${p.height} do not match expected ${r.width}x${r.height}`);const _=oo(g);if(_){if(o&&o!==_)throw new Error(`DynamicTexture: slice ${u} base level format "${_}" does not match texture format "${o}"`);o=_}const m=o&&e.isTextureFormatCompressed(o)?rm(e,p.width,p.height,o):e.getMipLevelCount(p.width,p.height);let b=0;for(let R=0;R=m)break;const y=ao(e,T),E=Math.max(1,p.width>>R),S=Math.max(1,p.height>>R);if(y.width!==E||y.height!==S)break;const C=oo(T);if(C&&(o||(o=C),C!==o))break;b++,c.push(T)}a=Math.min(a,b)}const l=Number.isFinite(a)?Math.max(1,a):1;return{subresources:c.filter(u=>u.mipLevel>a),l=Math.max(1,r>>a);if(c[d.name,d]))||[]),s=r.shaderInputs||new Y_(i,{disableWarnings:this.props.disableWarnings});this.setShaderInputs(s);const n=sm(t),o=(((l=this.props.modules)==null?void 0:l.length)>0?this.props.modules:(u=this.shaderInputs)==null?void 0:u.getModules())||[];if(this.props.shaderLayout=so(this.props.shaderLayout,o)||null,this.device.type==="webgpu"&&this.props.source){const{source:d,getUniforms:g,bindingTable:p}=this.props.shaderAssembler.assembleWGSLShader({platformInfo:n,...this.props,modules:o});this.source=d,this._getModuleUniforms=g,this._bindingTable=p;const _=(h=t.getShaderLayout)==null?void 0:h.call(t,this.source);this.props.shaderLayout=so(this.props.shaderLayout||_||null,o)||null}else{const{vs:d,fs:g,getUniforms:p}=this.props.shaderAssembler.assembleGLSLShaderPair({platformInfo:n,...this.props,modules:o});this.vs=d,this.fs=g,this._getModuleUniforms=p,this._bindingTable=[]}this.vertexCount=this.props.vertexCount,this.instanceCount=this.props.instanceCount,this.topology=this.props.topology,this.bufferLayout=this.props.bufferLayout,this.parameters=this.props.parameters,r.geometry&&this.setGeometry(r.geometry),this.pipelineFactory=r.pipelineFactory||Hi.getDefaultPipelineFactory(this.device),this.shaderFactory=r.shaderFactory||Vi.getDefaultShaderFactory(this.device),this.pipeline=this._updatePipeline(),this.vertexArray=t.createVertexArray({shaderLayout:this.pipeline.shaderLayout,bufferLayout:this.pipeline.bufferLayout}),this._gpuGeometry&&this._setGeometryAttributes(this._gpuGeometry),"isInstanced"in r&&(this.isInstanced=r.isInstanced),r.instanceCount&&this.setInstanceCount(r.instanceCount),r.vertexCount&&this.setVertexCount(r.vertexCount),r.indexBuffer&&this.setIndexBuffer(r.indexBuffer),r.attributes&&this.setAttributes(r.attributes),r.constantAttributes&&this.setConstantAttributes(r.constantAttributes),r.bindings&&this.setBindings(r.bindings),r.transformFeedback&&(this.transformFeedback=r.transformFeedback)}get[Symbol.toStringTag](){return"Model"}toString(){return`Model(${this.id})`}destroy(){var t;this._destroyed||(this.pipelineFactory.release(this.pipeline),this.shaderFactory.release(this.pipeline.vs),this.pipeline.fs&&this.pipeline.fs!==this.pipeline.vs&&this.shaderFactory.release(this.pipeline.fs),this._uniformStore.destroy(),(t=this._gpuGeometry)==null||t.destroy(),this._destroyed=!0)}needsRedraw(){this._getBindingsUpdateTimestamp()>this._lastDrawTimestamp&&this.setNeedsRedraw("contents of bound textures or buffers updated");const t=this._needsRedraw;return this._needsRedraw=!1,t}setNeedsRedraw(t){this._needsRedraw||(this._needsRedraw=t)}getBindingDebugTable(){return this._bindingTable}predraw(){this.updateShaderInputs(),this.pipeline=this._updatePipeline()}draw(t){const r=this._areBindingsLoading();if(r)return A.info(de,`>>> DRAWING ABORTED ${this.id}: ${r} not loaded`)(),!1;try{t.pushDebugGroup(`${this}.predraw(${t})`),this.predraw()}finally{t.popDebugGroup()}let i,s=this.pipeline.isErrored;try{if(t.pushDebugGroup(`${this}.draw(${t})`),this._logDrawCallStart(),this.pipeline=this._updatePipeline(),s=this.pipeline.isErrored,s)A.info(de,`>>> DRAWING ABORTED ${this.id}: ${co}`)(),i=!1;else{const n=this._getBindings(),o=this._getBindGroups(),{indexBuffer:a}=this.vertexArray,c=a?a.byteLength/(a.indexType==="uint32"?4:2):void 0;i=this.pipeline.draw({renderPass:t,vertexArray:this.vertexArray,isInstanced:this.isInstanced,vertexCount:this.vertexCount,instanceCount:this.instanceCount,indexCount:c,transformFeedback:this.transformFeedback||void 0,bindings:n,bindGroups:o,_bindGroupCacheKeys:this._getBindGroupCacheKeys(),uniforms:this.props.uniforms,parameters:this.parameters,topology:this.topology})}}finally{t.popDebugGroup(),this._logDrawCallEnd()}return this._logFramebuffer(t),i?(this._lastDrawTimestamp=this.device.timestamp,this._needsRedraw=!1):s?this._needsRedraw=co:this._needsRedraw="waiting for resource initialization",i}setGeometry(t){var i;(i=this._gpuGeometry)==null||i.destroy();const r=t&&M_(this.device,t);if(r){this.setTopology(r.topology||"triangle-list");const s=new Ri(this.bufferLayout);this.bufferLayout=s.mergeBufferLayouts(r.bufferLayout,this.bufferLayout),this.vertexArray&&this._setGeometryAttributes(r)}this._gpuGeometry=r}setTopology(t){t!==this.topology&&(this.topology=t,this._setPipelineNeedsUpdate("topology"))}setBufferLayout(t){const r=new Ri(this.bufferLayout);this.bufferLayout=this._gpuGeometry?r.mergeBufferLayouts(t,this._gpuGeometry.bufferLayout):t,this._setPipelineNeedsUpdate("bufferLayout"),this.pipeline=this._updatePipeline(),this.vertexArray=this.device.createVertexArray({shaderLayout:this.pipeline.shaderLayout,bufferLayout:this.pipeline.bufferLayout}),this._gpuGeometry&&this._setGeometryAttributes(this._gpuGeometry)}setParameters(t){is(t,this.parameters,2)||(this.parameters=t,this._setPipelineNeedsUpdate("parameters"))}setInstanceCount(t){this.instanceCount=t,this.isInstanced===void 0&&t>0&&(this.isInstanced=!0),this.setNeedsRedraw("instanceCount")}setVertexCount(t){this.vertexCount=t,this.setNeedsRedraw("vertexCount")}setShaderInputs(t){var r;this.shaderInputs=t,this._uniformStore=new Kg(this.device,this.shaderInputs.modules);for(const[i,s]of Object.entries(this.shaderInputs.modules))if(z_(s)&&!((r=this.material)!=null&&r.ownsModule(i))){const n=this._uniformStore.getManagedUniformBuffer(i);this.bindings[`${i}Uniforms`]=n}this.setNeedsRedraw("shaderInputs")}setMaterial(t){this.material=t,this.setNeedsRedraw("material")}updateShaderInputs(){this._uniformStore.setUniforms(this.shaderInputs.getUniformValues()),this.setBindings(this._getNonMaterialBindings(this.shaderInputs.getBindingValues())),this.setNeedsRedraw("shaderInputs")}setBindings(t){Object.assign(this.bindings,t),this.setNeedsRedraw("bindings")}setTransformFeedback(t){this.transformFeedback=t,this.setNeedsRedraw("transformFeedback")}setIndexBuffer(t){this.vertexArray.setIndexBuffer(t),this.setNeedsRedraw("indexBuffer")}setAttributes(t,r){const i=(r==null?void 0:r.disableWarnings)??this.props.disableWarnings;t.indices&&A.warn(`Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`)(),this.bufferLayout=$_(this.pipeline.shaderLayout,this.bufferLayout);const s=new Ri(this.bufferLayout);for(const[n,o]of Object.entries(t)){const a=s.getBufferLayout(n);if(!a){i||A.warn(`Model(${this.id}): Missing layout for buffer "${n}".`)();continue}const c=s.getAttributeNamesForBuffer(a);let l=!1;for(const u of c){const h=this._attributeInfos[u];if(h){const d=this.device.type==="webgpu"?s.getBufferIndex(h.bufferName):h.location;this.vertexArray.setBuffer(d,o),l=!0}}!l&&!i&&A.warn(`Model(${this.id}): Ignoring buffer "${o.id}" for unknown attribute "${n}"`)()}this.setNeedsRedraw("attributes")}setConstantAttributes(t,r){for(const[i,s]of Object.entries(t)){const n=this._attributeInfos[i];n?this.vertexArray.setConstantWebGL(n.location,s):((r==null?void 0:r.disableWarnings)??this.props.disableWarnings)||A.warn(`Model "${this.id}: Ignoring constant supplied for unknown attribute "${i}"`)()}this.setNeedsRedraw("constants")}_areBindingsLoading(){var t;for(const r of Object.values(this.bindings))if(r instanceof $e&&!r.isReady)return r.id;for(const r of Object.values(((t=this.material)==null?void 0:t.bindings)||{}))if(r instanceof $e&&!r.isReady)return r.id;return!1}_getBindings(){const t={};for(const[r,i]of Object.entries(this.bindings))i instanceof $e?i.isReady&&(t[r]=i.texture):t[r]=i;return t}_getBindGroups(){var i;const t=((i=this.pipeline)==null?void 0:i.shaderLayout)||this.props.shaderLayout||{bindings:[]},r=t.bindings.length?Fa(t,this._getBindings()):{0:this._getBindings()};if(!this.material)return r;for(const[s,n]of Object.entries(this.material.getBindingsByGroup())){const o=Number(s);r[o]={...r[o]||{},...n}}return r}_getBindGroupCacheKeys(){var r;const t=(r=this.material)==null?void 0:r.getBindGroupCacheKey(3);return t?{3:t}:{}}_getBindingsUpdateTimestamp(){var r;let t=0;for(const i of Object.values(this.bindings))i instanceof ur?t=Math.max(t,i.texture.updateTimestamp):i instanceof N||i instanceof U?t=Math.max(t,i.updateTimestamp):i instanceof $e?t=i.texture?Math.max(t,i.texture.updateTimestamp):1/0:i instanceof tt||(t=Math.max(t,i.buffer.updateTimestamp));return Math.max(t,((r=this.material)==null?void 0:r.getBindingsUpdateTimestamp())||0)}_setGeometryAttributes(t){const r={...t.attributes};for(const[i]of Object.entries(r))!this.pipeline.shaderLayout.attributes.find(s=>s.name===i)&&i!=="positions"&&delete r[i];this.vertexCount=t.vertexCount,this.setIndexBuffer(t.indices||null),this.setAttributes(t.attributes,{disableWarnings:!0}),this.setAttributes(r,{disableWarnings:this.props.disableWarnings}),this.setNeedsRedraw("geometry attributes")}_setPipelineNeedsUpdate(t){this._pipelineNeedsUpdate||(this._pipelineNeedsUpdate=t),this.setNeedsRedraw(t)}_updatePipeline(){if(this._pipelineNeedsUpdate){let t=null,r=null;this.pipeline&&(A.log(1,`Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)(),t=this.pipeline.vs,r=this.pipeline.fs),this._pipelineNeedsUpdate=!1;const i=this.shaderFactory.createShader({id:`${this.id}-vertex`,stage:"vertex",source:this.source||this.vs,debugShaders:this.props.debugShaders});let s=null;this.source?s=i:this.fs&&(s=this.shaderFactory.createShader({id:`${this.id}-fragment`,stage:"fragment",source:this.source||this.fs,debugShaders:this.props.debugShaders})),this.pipeline=this.pipelineFactory.createRenderPipeline({...this.props,bindings:void 0,bufferLayout:this.bufferLayout,topology:this.topology,parameters:this.parameters,bindGroups:this._getBindGroups(),vs:i,fs:s}),this._attributeInfos=La(this.pipeline.shaderLayout,this.bufferLayout),t&&this.shaderFactory.release(t),r&&r!==t&&this.shaderFactory.release(r)}return this.pipeline}_logDrawCallStart(){const t=A.level>3?0:im;A.level<2||Date.now()-this._lastLogTime>> DRAWING MODEL ${this.id}`,{collapsed:A.level<=2})())}_logDrawCallEnd(){if(this._logOpen){const t=B_(this.pipeline.shaderLayout,this.id);A.table(de,t)();const r=this.shaderInputs.getDebugTable();A.table(de,r)();const i=this._getAttributeDebugTable();A.table(de,this._attributeInfos)(),A.table(de,i)(),A.groupEnd(de)(),this._logOpen=!1}}_logFramebuffer(t){const r=this.device.props.debugFramebuffers;if(this._drawCount++,!r)return;const i=t.props.framebuffer;D_(t,i,{id:(i==null?void 0:i.id)||`${this.id}-framebuffer`,minimap:!0})}_getAttributeDebugTable(){const t={};for(const[r,i]of Object.entries(this._attributeInfos)){const s=this.vertexArray.attributes[i.location];t[i.location]={name:r,type:i.shaderType,values:s?this._getBufferOrConstantValues(s,i.bufferDataType):"null"}}if(this.vertexArray.indexBuffer){const{indexBuffer:r}=this.vertexArray,i=r.indexType==="uint32"?new Uint32Array(r.debugData):new Uint16Array(r.debugData);t.indices={name:"indices",type:r.indexType,values:i.toString()}}return t}_getBufferOrConstantValues(t,r){const i=le.getTypedArrayConstructor(r);return(t instanceof N?new i(t.debugData):t).toString()}_getNonMaterialBindings(t){if(!this.material)return t;const r={};for(const[i,s]of Object.entries(t))this.material.ownsBinding(i)||(r[i]=s);return r}};f(kr,"defaultProps",{..._e.defaultProps,source:void 0,vs:null,fs:null,id:"unnamed",handle:void 0,userData:{},defines:{},modules:[],geometry:null,indexBuffer:null,attributes:{},constantAttributes:{},bindings:{},uniforms:{},varyings:[],isInstanced:void 0,instanceCount:0,vertexCount:0,shaderInputs:void 0,material:void 0,pipelineFactory:void 0,shaderFactory:void 0,transformFeedback:void 0,shaderAssembler:Wi.getDefaultShaderAssembler(),debugShaders:void 0,disableWarnings:void 0});let Ar=kr;function sm(e){return{type:e.type,shaderLanguage:e.info.shadingLanguage,shaderLanguageVersion:e.info.shadingLanguageVersion,gpu:e.info.gpu,features:e.features}}const Et=class Et{constructor(t,r=Et.defaultProps){f(this,"device");f(this,"model");f(this,"transformFeedback");if(!Et.isSupported(t))throw new Error("BufferTransform not yet implemented on WebGPU");this.device=t,this.model=new Ar(this.device,{id:r.id||"buffer-transform-model",fs:r.fs||rh(),topology:r.topology||"point-list",varyings:r.outputs||r.varyings,...r}),this.transformFeedback=this.device.createTransformFeedback({layout:this.model.pipeline.shaderLayout,buffers:r.feedbackBuffers}),this.model.setTransformFeedback(this.transformFeedback),Object.seal(this)}static isSupported(t){var r;return((r=t==null?void 0:t.info)==null?void 0:r.type)==="webgl"}destroy(){this.model&&this.model.destroy()}delete(){this.destroy()}run(t){t!=null&&t.inputBuffers&&this.model.setAttributes(t.inputBuffers),t!=null&&t.outputBuffers&&this.transformFeedback.setBuffers(t.outputBuffers);const r=this.device.beginRenderPass(t);this.model.draw(r),r.end()}getBuffer(t){return this.transformFeedback.getBuffer(t)}readAsync(t){const r=this.getBuffer(t);if(!r)throw new Error("BufferTransform#getBuffer");if(r instanceof N)return r.readAsync();const{buffer:i,byteOffset:s=0,byteLength:n=i.byteLength}=r;return i.readAsync(s,n)}};f(Et,"defaultProps",{...Ar.defaultProps,outputs:void 0,feedbackBuffers:void 0});let Ot=Et;class XA{constructor(t){f(this,"id");f(this,"topology");f(this,"vertexCount");f(this,"indices");f(this,"attributes");f(this,"userData",{});const{attributes:r={},indices:i=null,vertexCount:s=null}=t;this.id=t.id||Xr("geometry"),this.topology=t.topology,i&&(this.indices=ArrayBuffer.isView(i)?{value:i,size:1}:i),this.attributes={};for(const[n,o]of Object.entries(r)){const a=ArrayBuffer.isView(o)?{value:o}:o;if(!ArrayBuffer.isView(a.value))throw new Error(`${this._print(n)}: must be typed array or object with value as typed array`);if((n==="POSITION"||n==="positions")&&!a.size&&(a.size=3),n==="indices"){if(this.indices)throw new Error("Multiple indices detected");this.indices=a}else this.attributes[n]=a}this.indices&&this.indices.isIndexed!==void 0&&(this.indices=Object.assign({},this.indices),delete this.indices.isIndexed),this.vertexCount=s||this._calculateVertexCount(this.attributes,this.indices)}getVertexCount(){return this.vertexCount}getAttributes(){return this.indices?{indices:this.indices,...this.attributes}:this.attributes}_print(t){return`Geometry ${this.id} attribute ${t}`}_setAttributes(t,r){return this}_calculateVertexCount(t,r){if(r)return r.value.length;let i=1/0;for(const s of Object.values(t)){const{value:n,size:o,constant:a}=s;!a&&n&&o!==void 0&&o>=1&&(i=Math.min(i,n.length/o))}return i}}const nm={NO_STATE:"Awaiting state",MATCHED:"Matched. State transferred from previous layer",INITIALIZED:"Initialized",AWAITING_GC:"Discarded. Awaiting garbage collection",AWAITING_FINALIZATION:"No longer matched. Awaiting garbage collection",FINALIZED:"Finalized! Awaiting garbage collection"},yr=Symbol.for("component"),be=Symbol.for("propTypes"),Ei=Symbol.for("deprecatedProps"),Qe=Symbol.for("asyncPropDefaults"),Ie=Symbol.for("asyncPropOriginal"),me=Symbol.for("asyncPropResolved");function om(e,t=()=>!0){return Array.isArray(e)?yc(e,t,[]):t(e)?[e]:[]}function yc(e,t,r){let i=-1;for(;++i{i.onload=s,i.onerror=o=>n(new Error(`Unable to load script '${e}': ${o}`)),r.appendChild(i)})}function Rr(e){const t=e.luma||{_polyfilled:!1,extensions:{},softwareRenderer:!1};return t._polyfilled??(t._polyfilled=!1),t.extensions||(t.extensions={}),e.luma=t,t}const cm=1;let I=null,lo=!1;const Ec={debugSpectorJS:A.get("debug-spectorjs"),debugSpectorJSUrl:"https://cdn.jsdelivr.net/npm/spectorjs@0.9.30/dist/spector.bundle.js",gl:void 0};async function YA(e){if(!globalThis.SPECTOR)try{await Rc(e.debugSpectorJSUrl||Ec.debugSpectorJSUrl)}catch(t){A.warn(String(t))}}function lm(e){var t;if(e={...Ec,...e},!e.debugSpectorJS)return null;if(!I&&globalThis.SPECTOR&&!((t=globalThis.luma)!=null&&t.spector)){A.probe(cm,"SPECTOR found and initialized. Start with `luma.spector.displayUI()`")();const{Spector:r}=globalThis.SPECTOR;I=new r,globalThis.luma&&(globalThis.luma.spector=I)}if(!I)return null;if(lo||(lo=!0,I.spyCanvases(),I==null||I.onCaptureStarted.add(r=>A.info("Spector capture started:",r)()),I==null||I.onCapture.add(r=>{A.info("Spector capture complete:",r)(),I==null||I.getResultUI(),I==null||I.resultView.display(),I==null||I.resultView.addCapture(r)})),e.gl){const r=e.gl,i=Rr(r),s=i.device;I==null||I.startCapture(e.gl,500),i.device=s,new Promise(n=>setTimeout(n,2e3)).then(n=>{A.info("Spector capture stopped after 2 seconds")(),I==null||I.stopCapture()})}return I}const fm="https://unpkg.com/webgl-debug@2.0.1/index.js";function Sc(e){return e.luma=e.luma||{},e.luma}async function KA(){it()&&!globalThis.WebGLDebugUtils&&(globalThis.global=globalThis.global||globalThis,globalThis.global.module={},await Rc(fm))}function um(e,t={}){return t.debugWebGL||t.traceWebGL?dm(e,t):hm(e)}function hm(e){const t=Sc(e);return t.realContext?t.realContext:e}function dm(e,t){if(!globalThis.WebGLDebugUtils)return A.warn("webgl-debug not loaded")(),e;const r=Sc(e);if(r.debugContext)return r.debugContext;globalThis.WebGLDebugUtils.init({...je,...e});const i=globalThis.WebGLDebugUtils.makeDebugContext(e,gm.bind(null,t),pm.bind(null,t));for(const o in je)!(o in i)&&typeof je[o]=="number"&&(i[o]=je[o]);class s{}Object.setPrototypeOf(i,Object.getPrototypeOf(e)),Object.setPrototypeOf(s,i);const n=Object.create(s);return r.realContext=e,r.debugContext=n,n.luma=r,n.debug=!0,n}function fo(e,t){t=Array.from(t).map(i=>i===void 0?"undefined":i);let r=globalThis.WebGLDebugUtils.glFunctionArgsToString(e,t);return r=`${r.slice(0,100)}${r.length>100?"...":""}`,`gl.${e}(${r})`}function gm(e,t,r,i){i=Array.from(i).map(a=>a===void 0?"undefined":a);const s=globalThis.WebGLDebugUtils.glEnumToString(t),n=globalThis.WebGLDebugUtils.glFunctionArgsToString(r,i),o=`${s} in gl.${r}(${n})`;A.error("%cWebGL","color: white; background: red; padding: 2px 6px; border-radius: 3px;",o)();debugger;throw new Error(o)}function pm(e,t,r){let i="";e.traceWebGL&&A.level>=1&&(i=fo(t,r),A.info(1,"%cWebGL","color: white; background: blue; padding: 2px 6px; border-radius: 3px;",i)());for(const s of r)if(s===void 0){i=i||fo(t,r);debugger}}const Fs={3042:!1,32773:new Float32Array([0,0,0,0]),32777:32774,34877:32774,32969:1,32968:0,32971:1,32970:0,3106:new Float32Array([0,0,0,0]),3107:[!0,!0,!0,!0],2884:!1,2885:1029,2929:!1,2931:1,2932:513,2928:new Float32Array([0,1]),2930:!0,3024:!0,35725:null,36006:null,36007:null,34229:null,34964:null,2886:2305,33170:4352,2849:1,32823:!1,32824:0,10752:0,32926:!1,32928:!1,32938:1,32939:!1,3089:!1,3088:new Int32Array([0,0,1024,1024]),2960:!1,2961:0,2968:4294967295,36005:4294967295,2962:519,2967:0,2963:4294967295,34816:519,36003:0,36004:4294967295,2964:7680,2965:7680,2966:7680,34817:7680,34818:7680,34819:7680,2978:[0,0,1024,1024],36389:null,36662:null,36663:null,35053:null,35055:null,35723:4352,36010:null,35977:!1,3333:4,3317:4,37440:!1,37441:!1,37443:37444,3330:0,3332:0,3331:0,3314:0,32878:0,3316:0,3315:0,32877:0},k=(e,t,r)=>t?e.enable(r):e.disable(r),uo=(e,t,r)=>e.hint(r,t),V=(e,t,r)=>e.pixelStorei(r,t),ho=(e,t,r)=>{const i=r===36006?36009:36008;return e.bindFramebuffer(i,t)},ht=(e,t,r)=>{const s={34964:34962,36662:36662,36663:36663,35053:35051,35055:35052}[r];e.bindBuffer(s,t)};function Si(e){return Array.isArray(e)||ArrayBuffer.isView(e)&&!(e instanceof DataView)}const _m={3042:k,32773:(e,t)=>e.blendColor(...t),32777:"blendEquation",34877:"blendEquation",32969:"blendFunc",32968:"blendFunc",32971:"blendFunc",32970:"blendFunc",3106:(e,t)=>e.clearColor(...t),3107:(e,t)=>e.colorMask(...t),2884:k,2885:(e,t)=>e.cullFace(t),2929:k,2931:(e,t)=>e.clearDepth(t),2932:(e,t)=>e.depthFunc(t),2928:(e,t)=>e.depthRange(...t),2930:(e,t)=>e.depthMask(t),3024:k,35723:uo,35725:(e,t)=>e.useProgram(t),36007:(e,t)=>e.bindRenderbuffer(36161,t),36389:(e,t)=>{var r;return(r=e.bindTransformFeedback)==null?void 0:r.call(e,36386,t)},34229:(e,t)=>e.bindVertexArray(t),36006:ho,36010:ho,34964:ht,36662:ht,36663:ht,35053:ht,35055:ht,2886:(e,t)=>e.frontFace(t),33170:uo,2849:(e,t)=>e.lineWidth(t),32823:k,32824:"polygonOffset",10752:"polygonOffset",35977:k,32926:k,32928:k,32938:"sampleCoverage",32939:"sampleCoverage",3089:k,3088:(e,t)=>e.scissor(...t),2960:k,2961:(e,t)=>e.clearStencil(t),2968:(e,t)=>e.stencilMaskSeparate(1028,t),36005:(e,t)=>e.stencilMaskSeparate(1029,t),2962:"stencilFuncFront",2967:"stencilFuncFront",2963:"stencilFuncFront",34816:"stencilFuncBack",36003:"stencilFuncBack",36004:"stencilFuncBack",2964:"stencilOpFront",2965:"stencilOpFront",2966:"stencilOpFront",34817:"stencilOpBack",34818:"stencilOpBack",34819:"stencilOpBack",2978:(e,t)=>e.viewport(...t),34383:k,10754:k,12288:k,12289:k,12290:k,12291:k,12292:k,12293:k,12294:k,12295:k,3333:V,3317:V,37440:V,37441:V,37443:V,3330:V,3332:V,3331:V,3314:V,32878:V,3316:V,3315:V,32877:V,framebuffer:(e,t)=>{const r=t&&"handle"in t?t.handle:t;return e.bindFramebuffer(36160,r)},blend:(e,t)=>t?e.enable(3042):e.disable(3042),blendColor:(e,t)=>e.blendColor(...t),blendEquation:(e,t)=>{const r=typeof t=="number"?[t,t]:t;e.blendEquationSeparate(...r)},blendFunc:(e,t)=>{const r=(t==null?void 0:t.length)===2?[...t,...t]:t;e.blendFuncSeparate(...r)},clearColor:(e,t)=>e.clearColor(...t),clearDepth:(e,t)=>e.clearDepth(t),clearStencil:(e,t)=>e.clearStencil(t),colorMask:(e,t)=>e.colorMask(...t),cull:(e,t)=>t?e.enable(2884):e.disable(2884),cullFace:(e,t)=>e.cullFace(t),depthTest:(e,t)=>t?e.enable(2929):e.disable(2929),depthFunc:(e,t)=>e.depthFunc(t),depthMask:(e,t)=>e.depthMask(t),depthRange:(e,t)=>e.depthRange(...t),dither:(e,t)=>t?e.enable(3024):e.disable(3024),derivativeHint:(e,t)=>{e.hint(35723,t)},frontFace:(e,t)=>e.frontFace(t),mipmapHint:(e,t)=>e.hint(33170,t),lineWidth:(e,t)=>e.lineWidth(t),polygonOffsetFill:(e,t)=>t?e.enable(32823):e.disable(32823),polygonOffset:(e,t)=>e.polygonOffset(...t),sampleCoverage:(e,t)=>e.sampleCoverage(t[0],t[1]||!1),scissorTest:(e,t)=>t?e.enable(3089):e.disable(3089),scissor:(e,t)=>e.scissor(...t),stencilTest:(e,t)=>t?e.enable(2960):e.disable(2960),stencilMask:(e,t)=>{t=Si(t)?t:[t,t];const[r,i]=t;e.stencilMaskSeparate(1028,r),e.stencilMaskSeparate(1029,i)},stencilFunc:(e,t)=>{t=Si(t)&&t.length===3?[...t,...t]:t;const[r,i,s,n,o,a]=t;e.stencilFuncSeparate(1028,r,i,s),e.stencilFuncSeparate(1029,n,o,a)},stencilOp:(e,t)=>{t=Si(t)&&t.length===3?[...t,...t]:t;const[r,i,s,n,o,a]=t;e.stencilOpSeparate(1028,r,i,s),e.stencilOpSeparate(1029,n,o,a)},viewport:(e,t)=>e.viewport(...t)};function L(e,t,r){return t[e]!==void 0?t[e]:r[e]}const mm={blendEquation:(e,t,r)=>e.blendEquationSeparate(L(32777,t,r),L(34877,t,r)),blendFunc:(e,t,r)=>e.blendFuncSeparate(L(32969,t,r),L(32968,t,r),L(32971,t,r),L(32970,t,r)),polygonOffset:(e,t,r)=>e.polygonOffset(L(32824,t,r),L(10752,t,r)),sampleCoverage:(e,t,r)=>e.sampleCoverage(L(32938,t,r),L(32939,t,r)),stencilFuncFront:(e,t,r)=>e.stencilFuncSeparate(1028,L(2962,t,r),L(2967,t,r),L(2963,t,r)),stencilFuncBack:(e,t,r)=>e.stencilFuncSeparate(1029,L(34816,t,r),L(36003,t,r),L(36004,t,r)),stencilOpFront:(e,t,r)=>e.stencilOpSeparate(1028,L(2964,t,r),L(2965,t,r),L(2966,t,r)),stencilOpBack:(e,t,r)=>e.stencilOpSeparate(1029,L(34817,t,r),L(34818,t,r),L(34819,t,r))},go={enable:(e,t)=>e({[t]:!0}),disable:(e,t)=>e({[t]:!1}),pixelStorei:(e,t,r)=>e({[t]:r}),hint:(e,t,r)=>e({[t]:r}),useProgram:(e,t)=>e({35725:t}),bindRenderbuffer:(e,t,r)=>e({36007:r}),bindTransformFeedback:(e,t,r)=>e({36389:r}),bindVertexArray:(e,t)=>e({34229:t}),bindFramebuffer:(e,t,r)=>{switch(t){case 36160:return e({36006:r,36010:r});case 36009:return e({36006:r});case 36008:return e({36010:r});default:return null}},bindBuffer:(e,t,r)=>{const i={34962:[34964],36662:[36662],36663:[36663],35051:[35053],35052:[35055]}[t];return i?e({[i]:r}):{valueChanged:!0}},blendColor:(e,t,r,i,s)=>e({32773:new Float32Array([t,r,i,s])}),blendEquation:(e,t)=>e({32777:t,34877:t}),blendEquationSeparate:(e,t,r)=>e({32777:t,34877:r}),blendFunc:(e,t,r)=>e({32969:t,32968:r,32971:t,32970:r}),blendFuncSeparate:(e,t,r,i,s)=>e({32969:t,32968:r,32971:i,32970:s}),clearColor:(e,t,r,i,s)=>e({3106:new Float32Array([t,r,i,s])}),clearDepth:(e,t)=>e({2931:t}),clearStencil:(e,t)=>e({2961:t}),colorMask:(e,t,r,i,s)=>e({3107:[t,r,i,s]}),cullFace:(e,t)=>e({2885:t}),depthFunc:(e,t)=>e({2932:t}),depthRange:(e,t,r)=>e({2928:new Float32Array([t,r])}),depthMask:(e,t)=>e({2930:t}),frontFace:(e,t)=>e({2886:t}),lineWidth:(e,t)=>e({2849:t}),polygonOffset:(e,t,r)=>e({32824:t,10752:r}),sampleCoverage:(e,t,r)=>e({32938:t,32939:r}),scissor:(e,t,r,i,s)=>e({3088:new Int32Array([t,r,i,s])}),stencilMask:(e,t)=>e({2968:t,36005:t}),stencilMaskSeparate:(e,t,r)=>e({[t===1028?2968:36005]:r}),stencilFunc:(e,t,r,i)=>e({2962:t,2967:r,2963:i,34816:t,36003:r,36004:i}),stencilFuncSeparate:(e,t,r,i,s)=>e({[t===1028?2962:34816]:r,[t===1028?2967:36003]:i,[t===1028?2963:36004]:s}),stencilOp:(e,t,r,i)=>e({2964:t,2965:r,2966:i,34817:t,34818:r,34819:i}),stencilOpSeparate:(e,t,r,i,s)=>e({[t===1028?2964:34817]:r,[t===1028?2965:34818]:i,[t===1028?2966:34819]:s}),viewport:(e,t,r,i,s)=>e({2978:[t,r,i,s]})},oe=(e,t)=>e.isEnabled(t),po={3042:oe,2884:oe,2929:oe,3024:oe,32823:oe,32926:oe,32928:oe,3089:oe,2960:oe,35977:oe},bm=new Set([34016,36388,36387,35983,35368,34965,35739,35738,3074,34853,34854,34855,34856,34857,34858,34859,34860,34861,34862,34863,34864,34865,34866,34867,34868,35097,32873,35869,32874,34068]);function ot(e,t){var s;if(Am(t))return;const r={};for(const n in t){const o=Number(n),a=_m[n];a&&(typeof a=="string"?r[a]=!0:a(e,t[n],o))}const i=(s=e.lumaState)==null?void 0:s.cache;if(i)for(const n in r){const o=mm[n];o(e,t,i)}}function Cc(e,t=Fs){if(typeof t=="number"){const s=t,n=po[s];return n?n(e,s):e.getParameter(s)}const r=Array.isArray(t)?t:Object.keys(t),i={};for(const s of r){const n=po[s];i[s]=n?n(e,Number(s)):e.getParameter(Number(s))}return i}function Tm(e){ot(e,Fs)}function Am(e){for(const t in e)return!1;return!0}function ym(e,t){if(e===t)return!0;if(_o(e)&&_o(t)&&e.length===t.length){for(let r=0;r{}),this._updateCache=this._updateCache.bind(this),Object.seal(this)}static get(t){return t.lumaState}push(t={}){this.stateStack.push({})}pop(){const t=this.stateStack[this.stateStack.length-1];ot(this.gl,t),this.stateStack.pop()}trackState(t,r){if(this.cache=r!=null&&r.copyState?Cc(t):Object.assign({},Fs),this.initialized)throw new Error("WebGLStateTracker");this.initialized=!0,this.gl.lumaState=this,Em(t);for(const i in go){const s=go[i];Rm(t,i,s)}mo(t,"getParameter"),mo(t,"isEnabled")}_updateCache(t){let r=!1,i;const s=this.stateStack.length>0?this.stateStack[this.stateStack.length-1]:null;for(const n in t){const o=t[n],a=this.cache[n];ym(o,a)||(r=!0,i=a,s&&!(n in s)&&(s[n]=a),this.cache[n]=o)}return{valueChanged:r,oldValue:i}}}function mo(e,t){const r=e[t].bind(e);e[t]=function(s){if(s===void 0||bm.has(s))return r(s);const n=Pe.get(e);return s in n.cache||(n.cache[s]=r(s)),n.enable?n.cache[s]:r(s)},Object.defineProperty(e[t],"name",{value:`${t}-from-cache`,configurable:!1})}function Rm(e,t,r){if(!e[t])return;const i=e[t].bind(e);e[t]=function(...n){const o=Pe.get(e),{valueChanged:a,oldValue:c}=r(o._updateCache,...n);return a&&i(...n),c},Object.defineProperty(e[t],"name",{value:`${t}-to-cache`,configurable:!1})}function Em(e){const t=e.useProgram.bind(e);e.useProgram=function(i){const s=Pe.get(e);s.program!==i&&(t(i),s.program=i)}}function Sm(e,t,r){let i="";const s=c=>{const l=c.statusMessage;l&&(i||(i=l))};e.addEventListener("webglcontextcreationerror",s,!1);const n=r.failIfMajorPerformanceCaveat!==!0,o={preserveDrawingBuffer:!0,...r,failIfMajorPerformanceCaveat:!0};let a=null;try{a||(a=e.getContext("webgl2",o)),!a&&o.failIfMajorPerformanceCaveat&&(i||(i="Only software GPU is available. Set `failIfMajorPerformanceCaveat: false` to allow."));let c=!1;if(!a&&n&&(o.failIfMajorPerformanceCaveat=!1,a=e.getContext("webgl2",o),c=!0),a||(a=e.getContext("webgl",{}),a&&(a=null,i||(i="Your browser only supports WebGL1"))),!a)throw i||(i="Your browser does not support WebGL"),new Error(`Failed to create WebGL context: ${i}`);const l=Rr(a);l.softwareRenderer=c;const{onContextLost:u,onContextRestored:h}=t;return e.addEventListener("webglcontextlost",d=>u(d),!1),e.addEventListener("webglcontextrestored",d=>h(d),!1),a}finally{e.removeEventListener("webglcontextcreationerror",s,!1)}}function Ne(e,t,r){return r[t]===void 0&&(r[t]=e.getExtension(t)||null),r[t]}function Cm(e,t){const r=e.getParameter(7936),i=e.getParameter(7937);Ne(e,"WEBGL_debug_renderer_info",t);const s=t.WEBGL_debug_renderer_info,n=e.getParameter(s?s.UNMASKED_VENDOR_WEBGL:7936),o=e.getParameter(s?s.UNMASKED_RENDERER_WEBGL:7937),a=n||r,c=o||i,l=e.getParameter(7938),u=vc(a,c),h=vm(a,c),d=Pm(a,c);return{type:"webgl",gpu:u,gpuType:d,gpuBackend:h,vendor:a,renderer:c,version:l,shadingLanguage:"glsl",shadingLanguageVersion:300}}function vc(e,t){return/NVIDIA/i.exec(e)||/NVIDIA/i.exec(t)?"nvidia":/INTEL/i.exec(e)||/INTEL/i.exec(t)?"intel":/Apple/i.exec(e)||/Apple/i.exec(t)?"apple":/AMD/i.exec(e)||/AMD/i.exec(t)||/ATI/i.exec(e)||/ATI/i.exec(t)?"amd":/SwiftShader/i.exec(e)||/SwiftShader/i.exec(t)?"software":"unknown"}function vm(e,t){return/Metal/i.exec(e)||/Metal/i.exec(t)?"metal":/ANGLE/i.exec(e)||/ANGLE/i.exec(t)?"opengl":"unknown"}function Pm(e,t){if(/SwiftShader/i.exec(e)||/SwiftShader/i.exec(t))return"cpu";switch(vc(e,t)){case"apple":return wm(e,t)?"integrated":"unknown";case"intel":return"integrated";case"software":return"cpu";case"unknown":return"unknown";default:return"discrete"}}function wm(e,t){return/Apple (M\d|A\d|GPU)/i.test(`${e} ${t}`)}function Pc(e){switch(e){case"uint8":return 5121;case"sint8":return 5120;case"unorm8":return 5121;case"snorm8":return 5120;case"uint16":return 5123;case"sint16":return 5122;case"unorm16":return 5123;case"snorm16":return 5122;case"uint32":return 5125;case"sint32":return 5124;case"float16":return 5131;case"float32":return 5126}throw new Error(String(e))}const _t="WEBGL_compressed_texture_s3tc",mt="WEBGL_compressed_texture_s3tc_srgb",He="EXT_texture_compression_rgtc",Ve="EXT_texture_compression_bptc",Om="WEBGL_compressed_texture_etc",xm="WEBGL_compressed_texture_astc",Mm="WEBGL_compressed_texture_etc1",Im="WEBGL_compressed_texture_pvrtc",Nm="WEBGL_compressed_texture_atc",Bm="EXT_texture_norm16",bo="EXT_render_snorm",wc="EXT_color_buffer_float",Ci="snorm8-renderable-webgl",vi="norm16-renderable-webgl",Pi="snorm16-renderable-webgl",wi="float16-renderable-webgl",Yt="float32-renderable-webgl",Dm="rgb9e5ufloat-renderable-webgl",Us={"float32-renderable-webgl":{extensions:[wc]},"float16-renderable-webgl":{extensions:["EXT_color_buffer_half_float"]},"rgb9e5ufloat-renderable-webgl":{extensions:["WEBGL_render_shared_exponent"]},"snorm8-renderable-webgl":{extensions:[bo]},"norm16-webgl":{extensions:[Bm]},"norm16-renderable-webgl":{features:["norm16-webgl"]},"snorm16-renderable-webgl":{features:["norm16-webgl"],extensions:[bo]},"float32-filterable":{extensions:["OES_texture_float_linear"]},"float16-filterable-webgl":{extensions:["OES_texture_half_float_linear"]},"texture-filterable-anisotropic-webgl":{extensions:["EXT_texture_filter_anisotropic"]},"texture-blend-float-webgl":{extensions:["EXT_float_blend"]},"texture-compression-bc":{extensions:[_t,mt,He,Ve]},"texture-compression-bc5-webgl":{extensions:[He]},"texture-compression-bc7-webgl":{extensions:[Ve]},"texture-compression-etc2":{extensions:[Om]},"texture-compression-astc":{extensions:[xm]},"texture-compression-etc1-webgl":{extensions:[Mm]},"texture-compression-pvrtc-webgl":{extensions:[Im]},"texture-compression-atc-webgl":{extensions:[Nm]}};function Fm(e){return e in Us}function Oc(e,t,r){return xc(e,t,r,new Set)}function xc(e,t,r,i){const s=Us[t];if(!s||i.has(t))return!1;i.add(t);const n=(s.features||[]).every(o=>xc(e,o,r,i));return i.delete(t),n?(s.extensions||[]).every(o=>!!Ne(e,o,r)):!1}const Yr={r8unorm:{gl:33321,rb:!0},r8snorm:{gl:36756,r:Ci},r8uint:{gl:33330,rb:!0},r8sint:{gl:33329,rb:!0},rg8unorm:{gl:33323,rb:!0},rg8snorm:{gl:36757,r:Ci},rg8uint:{gl:33336,rb:!0},rg8sint:{gl:33335,rb:!0},r16uint:{gl:33332,rb:!0},r16sint:{gl:33331,rb:!0},r16float:{gl:33325,rb:!0,r:wi},r16unorm:{gl:33322,rb:!0,r:vi},r16snorm:{gl:36760,r:Pi},"rgba4unorm-webgl":{gl:32854,rb:!0},"rgb565unorm-webgl":{gl:36194,rb:!0},"rgb5a1unorm-webgl":{gl:32855,rb:!0},"rgb8unorm-webgl":{gl:32849},"rgb8snorm-webgl":{gl:36758},rgba8unorm:{gl:32856},"rgba8unorm-srgb":{gl:35907},rgba8snorm:{gl:36759,r:Ci},rgba8uint:{gl:36220},rgba8sint:{gl:36238},bgra8unorm:{},"bgra8unorm-srgb":{},rg16uint:{gl:33338},rg16sint:{gl:33337},rg16float:{gl:33327,rb:!0,r:wi},rg16unorm:{gl:33324,r:vi},rg16snorm:{gl:36761,r:Pi},r32uint:{gl:33334,rb:!0},r32sint:{gl:33333,rb:!0},r32float:{gl:33326,r:Yt},rgb9e5ufloat:{gl:35901,r:Dm},rg11b10ufloat:{gl:35898,rb:!0},rgb10a2unorm:{gl:32857,rb:!0},rgb10a2uint:{gl:36975,rb:!0},"rgb16unorm-webgl":{gl:32852,r:!1},"rgb16snorm-webgl":{gl:36762,r:!1},rg32uint:{gl:33340,rb:!0},rg32sint:{gl:33339,rb:!0},rg32float:{gl:33328,rb:!0,r:Yt},rgba16uint:{gl:36214,rb:!0},rgba16sint:{gl:36232,rb:!0},rgba16float:{gl:34842,r:wi},rgba16unorm:{gl:32859,rb:!0,r:vi},rgba16snorm:{gl:36763,r:Pi},"rgb32float-webgl":{gl:34837,x:wc,r:Yt,dataFormat:6407,types:[5126]},rgba32uint:{gl:36208,rb:!0},rgba32sint:{gl:36226,rb:!0},rgba32float:{gl:34836,rb:!0,r:Yt},stencil8:{gl:36168,rb:!0},depth16unorm:{gl:33189,dataFormat:6402,types:[5123],rb:!0},depth24plus:{gl:33190,dataFormat:6402,types:[5125]},depth32float:{gl:36012,dataFormat:6402,types:[5126],rb:!0},"depth24plus-stencil8":{gl:35056,rb:!0,depthTexture:!0,dataFormat:34041,types:[34042]},"depth32float-stencil8":{gl:36013,dataFormat:34041,types:[36269],rb:!0},"bc1-rgb-unorm-webgl":{gl:33776,x:_t},"bc1-rgb-unorm-srgb-webgl":{gl:35916,x:mt},"bc1-rgba-unorm":{gl:33777,x:_t},"bc1-rgba-unorm-srgb":{gl:35916,x:mt},"bc2-rgba-unorm":{gl:33778,x:_t},"bc2-rgba-unorm-srgb":{gl:35918,x:mt},"bc3-rgba-unorm":{gl:33779,x:_t},"bc3-rgba-unorm-srgb":{gl:35919,x:mt},"bc4-r-unorm":{gl:36283,x:He},"bc4-r-snorm":{gl:36284,x:He},"bc5-rg-unorm":{gl:36285,x:He},"bc5-rg-snorm":{gl:36286,x:He},"bc6h-rgb-ufloat":{gl:36495,x:Ve},"bc6h-rgb-float":{gl:36494,x:Ve},"bc7-rgba-unorm":{gl:36492,x:Ve},"bc7-rgba-unorm-srgb":{gl:36493,x:Ve},"etc2-rgb8unorm":{gl:37492},"etc2-rgb8unorm-srgb":{gl:37494},"etc2-rgb8a1unorm":{gl:37496},"etc2-rgb8a1unorm-srgb":{gl:37497},"etc2-rgba8unorm":{gl:37493},"etc2-rgba8unorm-srgb":{gl:37495},"eac-r11unorm":{gl:37488},"eac-r11snorm":{gl:37489},"eac-rg11unorm":{gl:37490},"eac-rg11snorm":{gl:37491},"astc-4x4-unorm":{gl:37808},"astc-4x4-unorm-srgb":{gl:37840},"astc-5x4-unorm":{gl:37809},"astc-5x4-unorm-srgb":{gl:37841},"astc-5x5-unorm":{gl:37810},"astc-5x5-unorm-srgb":{gl:37842},"astc-6x5-unorm":{gl:37811},"astc-6x5-unorm-srgb":{gl:37843},"astc-6x6-unorm":{gl:37812},"astc-6x6-unorm-srgb":{gl:37844},"astc-8x5-unorm":{gl:37813},"astc-8x5-unorm-srgb":{gl:37845},"astc-8x6-unorm":{gl:37814},"astc-8x6-unorm-srgb":{gl:37846},"astc-8x8-unorm":{gl:37815},"astc-8x8-unorm-srgb":{gl:37847},"astc-10x5-unorm":{gl:37816},"astc-10x5-unorm-srgb":{gl:37848},"astc-10x6-unorm":{gl:37817},"astc-10x6-unorm-srgb":{gl:37849},"astc-10x8-unorm":{gl:37818},"astc-10x8-unorm-srgb":{gl:37850},"astc-10x10-unorm":{gl:37819},"astc-10x10-unorm-srgb":{gl:37851},"astc-12x10-unorm":{gl:37820},"astc-12x10-unorm-srgb":{gl:37852},"astc-12x12-unorm":{gl:37821},"astc-12x12-unorm-srgb":{gl:37853},"pvrtc-rgb4unorm-webgl":{gl:35840},"pvrtc-rgba4unorm-webgl":{gl:35842},"pvrtc-rgb2unorm-webgl":{gl:35841},"pvrtc-rgba2unorm-webgl":{gl:35843},"etc1-rbg-unorm-webgl":{gl:36196},"atc-rgb-unorm-webgl":{gl:35986},"atc-rgba-unorm-webgl":{gl:35986},"atc-rgbai-unorm-webgl":{gl:34798}};function Um(e,t,r){let i=t.create;const s=Yr[t.format];(s==null?void 0:s.gl)===void 0&&(i=!1),s!=null&&s.x&&(i=i&&!!Ne(e,s.x,r)),t.format==="stencil8"&&(i=!1);const n=(s==null?void 0:s.r)===!1?!1:(s==null?void 0:s.r)===void 0||Oc(e,s.r,r),o=i&&t.render&&n&&Lm(e,t.format,r);return{format:t.format,create:i&&t.create,render:o,filter:i&&t.filter,blend:i&&t.blend,store:i&&t.store}}function Lm(e,t,r){const i=Yr[t],s=i==null?void 0:i.gl;if(s===void 0||i!=null&&i.x&&!Ne(e,i.x,r))return!1;const n=e.getParameter(32873),o=e.getParameter(36006),a=e.createTexture(),c=e.createFramebuffer();if(!a||!c)return!1;const l=0;let u=Number(e.getError());for(;u!==l;)u=e.getError();let h=!1;try{if(e.bindTexture(3553,a),e.texStorage2D(3553,1,s,1,1),Number(e.getError())!==l)return!1;e.bindFramebuffer(36160,c),e.framebufferTexture2D(36160,36064,3553,a,0),h=Number(e.checkFramebufferStatus(36160))===36053&&Number(e.getError())===l}finally{e.bindFramebuffer(36160,o),e.deleteFramebuffer(c),e.bindTexture(3553,n),e.deleteTexture(a)}return h}function Mc(e){var s;const t=Yr[e],r=$m(e),i=re.getInfo(e);return i.compressed&&(t.dataFormat=r),{internalFormat:r,format:(t==null?void 0:t.dataFormat)||Wm(i.channels,i.integer,i.normalized,r),type:i.dataType?Pc(i.dataType):((s=t==null?void 0:t.types)==null?void 0:s[0])||5121,compressed:i.compressed||!1}}function km(e){switch(re.getInfo(e).attachment){case"depth":return 36096;case"stencil":return 36128;case"depth-stencil":return 33306;default:throw new Error(`Not a depth stencil format: ${e}`)}}function Wm(e,t,r,i){if(i===6408||i===6407)return i;switch(e){case"r":return t&&!r?36244:6403;case"rg":return t&&!r?33320:33319;case"rgb":return t&&!r?36248:6407;case"rgba":return t&&!r?36249:6408;case"bgra":throw new Error("bgra pixels not supported by WebGL");default:return 6408}}function $m(e){const t=Yr[e],r=t==null?void 0:t.gl;if(r===void 0)throw new Error(`Unsupported texture format ${e}`);return r}const To={"depth-clip-control":"EXT_depth_clamp","timestamp-query":"EXT_disjoint_timer_query_webgl2","compilation-status-async-webgl":"KHR_parallel_shader_compile","polygon-mode-webgl":"WEBGL_polygon_mode","provoking-vertex-webgl":"WEBGL_provoking_vertex","shader-clip-cull-distance-webgl":"WEBGL_clip_cull_distance","shader-noperspective-interpolation-webgl":"NV_shader_noperspective_interpolation","shader-conservative-depth-webgl":"EXT_conservative_depth"};class zm extends qd{constructor(r,i,s){super([],s);f(this,"gl");f(this,"extensions");f(this,"testedFeatures",new Set);this.gl=r,this.extensions=i,Ne(r,"EXT_color_buffer_float",i)}*[Symbol.iterator](){const r=this.getFeatures();for(const i of r)this.has(i)&&(yield i);return[]}has(r){var i;return(i=this.disabledFeatures)!=null&&i[r]?!1:(this.testedFeatures.has(r)||(this.testedFeatures.add(r),Fm(r)&&Oc(this.gl,r,this.extensions)&&this.features.add(r),this.getWebGLFeature(r)&&this.features.add(r)),this.features.has(r))}initializeFeatures(){const r=this.getFeatures().filter(i=>i!=="polygon-mode-webgl");for(const i of r)this.has(i)}getFeatures(){return[...Object.keys(To),...Object.keys(Us)]}getWebGLFeature(r){const i=To[r];return typeof i=="string"?!!Ne(this.gl,i,this.extensions):!!i}}class jm extends Vd{constructor(r){super();f(this,"gl");f(this,"limits",{});this.gl=r}get maxTextureDimension1D(){return 0}get maxTextureDimension2D(){return this.getParameter(3379)}get maxTextureDimension3D(){return this.getParameter(32883)}get maxTextureArrayLayers(){return this.getParameter(35071)}get maxBindGroups(){return 0}get maxDynamicUniformBuffersPerPipelineLayout(){return 0}get maxDynamicStorageBuffersPerPipelineLayout(){return 0}get maxSampledTexturesPerShaderStage(){return this.getParameter(35660)}get maxSamplersPerShaderStage(){return this.getParameter(35661)}get maxStorageBuffersPerShaderStage(){return 0}get maxStorageTexturesPerShaderStage(){return 0}get maxUniformBuffersPerShaderStage(){return this.getParameter(35375)}get maxUniformBufferBindingSize(){return this.getParameter(35376)}get maxStorageBufferBindingSize(){return 0}get minUniformBufferOffsetAlignment(){return this.getParameter(35380)}get minStorageBufferOffsetAlignment(){return 0}get maxVertexBuffers(){return 16}get maxVertexAttributes(){return this.getParameter(34921)}get maxVertexBufferArrayStride(){return 2048}get maxInterStageShaderVariables(){return this.getParameter(35659)}get maxComputeWorkgroupStorageSize(){return 0}get maxComputeInvocationsPerWorkgroup(){return 0}get maxComputeWorkgroupSizeX(){return 0}get maxComputeWorkgroupSizeY(){return 0}get maxComputeWorkgroupSizeZ(){return 0}get maxComputeWorkgroupsPerDimension(){return 0}getParameter(r){return this.limits[r]===void 0&&(this.limits[r]=this.gl.getParameter(r)),this.limits[r]||0}}class Tt extends dr{constructor(r,i){super(r,i);f(this,"device");f(this,"gl");f(this,"handle");f(this,"colorAttachments",[]);f(this,"depthStencilAttachment",null);const s=i.handle===null;this.device=r,this.gl=r.gl,this.handle=this.props.handle||s?this.props.handle:this.gl.createFramebuffer(),s||(r._setWebGLDebugMetadata(this.handle,this,{spector:this.props}),i.handle||(this.autoCreateAttachmentTextures(),this.updateAttachments()))}destroy(){super.destroy(),!this.destroyed&&this.handle!==null&&!this.props.handle&&this.gl.deleteFramebuffer(this.handle)}updateAttachments(){const r=this.gl.bindFramebuffer(36160,this.handle);for(let i=0;i{this.compilationStatus="error"})}destroy(){this.handle&&(this.removeStats(),this.device.gl.deleteShader(this.handle),this.destroyed=!0,this.handle.destroyed=!0)}get asyncCompilationStatus(){return this._waitForCompilationComplete().then(()=>(this._getCompilationStatus(),this.compilationStatus))}async getCompilationInfo(){return await this._waitForCompilationComplete(),this.getCompilationInfoSync()}getCompilationInfoSync(){const r=this.device.gl.getShaderInfoLog(this.handle);return r?Zm(r):[]}getTranslatedSource(){const i=this.device.getExtension("WEBGL_debug_shaders").WEBGL_debug_shaders;return(i==null?void 0:i.getTranslatedShaderSource(this.handle))||null}_compile(r){r=r.startsWith("#version ")?r:`#version 300 es +${r}`;const{gl:i}=this.device;if(i.shaderSource(this.handle,r),i.compileShader(this.handle),!this.device.props.debug){this.compilationStatus="pending";return}if(!this.device.features.has("compilation-status-async-webgl")){if(this._getCompilationStatus(),this.debugShader(),this.compilationStatus==="error")throw new Error(`GLSL compilation errors in ${this.props.stage} shader ${this.props.id}`);return}return A.once(1,"Shader compilation is asynchronous")(),this._waitForCompilationComplete().then(()=>{A.info(2,`Shader ${this.id} - async compilation complete: ${this.compilationStatus}`)(),this._getCompilationStatus(),this.debugShader()})}async _waitForCompilationComplete(){const r=async n=>await new Promise(o=>setTimeout(o,n));if(!this.device.features.has("compilation-status-async-webgl")){await r(10);return}const{gl:s}=this.device;for(;;){if(s.getShaderParameter(this.handle,37297))return;await r(10)}}_getCompilationStatus(){this.compilationStatus=this.device.gl.getShaderParameter(this.handle,35713)?"success":"error"}}function Gm(e,t,r,i){if(ib(t))return i(e);const s=e;s.pushState();try{return eb(e,t),ot(s.gl,r),i(e)}finally{s.popState()}}function eb(e,t){const r=e,{gl:i}=r;if(t.cullMode)switch(t.cullMode){case"none":i.disable(2884);break;case"front":i.enable(2884),i.cullFace(1028);break;case"back":i.enable(2884),i.cullFace(1029);break}if(t.frontFace&&i.frontFace(we("frontFace",t.frontFace,{ccw:2305,cw:2304})),t.unclippedDepth&&e.features.has("depth-clip-control")&&i.enable(34383),t.depthBias!==void 0&&(i.enable(32823),i.polygonOffset(t.depthBias,t.depthBiasSlopeScale||0)),t.provokingVertex&&e.features.has("provoking-vertex-webgl")){const n=r.getExtension("WEBGL_provoking_vertex").WEBGL_provoking_vertex,o=we("provokingVertex",t.provokingVertex,{first:36429,last:36430});n==null||n.provokingVertexWEBGL(o)}if((t.polygonMode||t.polygonOffsetLine)&&e.features.has("polygon-mode-webgl")){if(t.polygonMode){const n=r.getExtension("WEBGL_polygon_mode").WEBGL_polygon_mode,o=we("polygonMode",t.polygonMode,{fill:6914,line:6913});n==null||n.polygonModeWEBGL(1028,o),n==null||n.polygonModeWEBGL(1029,o)}t.polygonOffsetLine&&i.enable(10754)}if(e.features.has("shader-clip-cull-distance-webgl")&&(t.clipDistance0&&i.enable(12288),t.clipDistance1&&i.enable(12289),t.clipDistance2&&i.enable(12290),t.clipDistance3&&i.enable(12291),t.clipDistance4&&i.enable(12292),t.clipDistance5&&i.enable(12293),t.clipDistance6&&i.enable(12294),t.clipDistance7&&i.enable(12295)),t.depthWriteEnabled!==void 0&&i.depthMask(rb("depthWriteEnabled",t.depthWriteEnabled)),t.depthCompare&&(t.depthCompare!=="always"?i.enable(2929):i.disable(2929),i.depthFunc(cs("depthCompare",t.depthCompare))),t.clearDepth!==void 0&&i.clearDepth(t.clearDepth),t.stencilWriteMask){const s=t.stencilWriteMask;i.stencilMaskSeparate(1028,s),i.stencilMaskSeparate(1029,s)}if(t.stencilReadMask&&A.warn("stencilReadMask not supported under WebGL"),t.stencilCompare){const s=t.stencilReadMask||4294967295,n=cs("depthCompare",t.stencilCompare);t.stencilCompare!=="always"?i.enable(2960):i.disable(2960),i.stencilFuncSeparate(1028,n,0,s),i.stencilFuncSeparate(1029,n,0,s)}if(t.stencilPassOperation&&t.stencilFailOperation&&t.stencilDepthFailOperation){const s=xi("stencilPassOperation",t.stencilPassOperation),n=xi("stencilFailOperation",t.stencilFailOperation),o=xi("stencilDepthFailOperation",t.stencilDepthFailOperation);i.stencilOpSeparate(1028,n,o,s),i.stencilOpSeparate(1029,n,o,s)}switch(t.blend){case!0:i.enable(3042);break;case!1:i.disable(3042);break}if(t.blendColorOperation||t.blendAlphaOperation){const s=Ao("blendColorOperation",t.blendColorOperation||"add"),n=Ao("blendAlphaOperation",t.blendAlphaOperation||"add");i.blendEquationSeparate(s,n);const o=Qt("blendColorSrcFactor",t.blendColorSrcFactor||"one"),a=Qt("blendColorDstFactor",t.blendColorDstFactor||"zero"),c=Qt("blendAlphaSrcFactor",t.blendAlphaSrcFactor||"one"),l=Qt("blendAlphaDstFactor",t.blendAlphaDstFactor||"zero");i.blendFuncSeparate(o,a,c,l)}}function cs(e,t){return we(e,t,{never:512,less:513,equal:514,"less-equal":515,greater:516,"not-equal":517,"greater-equal":518,always:519})}function xi(e,t){return we(e,t,{keep:7680,zero:0,replace:7681,invert:5386,"increment-clamp":7682,"decrement-clamp":7683,"increment-wrap":34055,"decrement-wrap":34056})}function Ao(e,t){return we(e,t,{add:32774,subtract:32778,"reverse-subtract":32779,min:32775,max:32776})}function Qt(e,t,r="color"){return we(e,t,{one:1,zero:0,src:768,"one-minus-src":769,dst:774,"one-minus-dst":775,"src-alpha":770,"one-minus-src-alpha":771,"dst-alpha":772,"one-minus-dst-alpha":773,"src-alpha-saturated":776,constant:r==="color"?32769:32771,"one-minus-constant":r==="color"?32770:32772,src1:768,"one-minus-src1":769,"src1-alpha":770,"one-minus-src1-alpha":771})}function tb(e,t){return`Illegal parameter ${t} for ${e}`}function we(e,t,r){if(!(t in r))throw new Error(tb(e,t));return r[t]}function rb(e,t){return t}function ib(e){let t=!0;for(const r in e){t=!1;break}return t}function Ic(e){const t={};return e.addressModeU&&(t[10242]=Mi(e.addressModeU)),e.addressModeV&&(t[10243]=Mi(e.addressModeV)),e.addressModeW&&(t[32882]=Mi(e.addressModeW)),e.magFilter&&(t[10240]=ls(e.magFilter)),(e.minFilter||e.mipmapFilter)&&(t[10241]=sb(e.minFilter||"linear",e.mipmapFilter)),e.lodMinClamp!==void 0&&(t[33082]=e.lodMinClamp),e.lodMaxClamp!==void 0&&(t[33083]=e.lodMaxClamp),e.type==="comparison-sampler"&&(t[34892]=34894),e.compare&&(t[34893]=cs("compare",e.compare)),e.maxAnisotropy&&(t[34046]=e.maxAnisotropy),t}function Mi(e){switch(e){case"clamp-to-edge":return 33071;case"repeat":return 10497;case"mirror-repeat":return 33648}}function ls(e){switch(e){case"nearest":return 9728;case"linear":return 9729}}function sb(e,t="none"){if(!t)return ls(e);switch(t){case"none":return ls(e);case"nearest":switch(e){case"nearest":return 9984;case"linear":return 9985}break;case"linear":switch(e){case"nearest":return 9986;case"linear":return 9987}}}class nb extends tt{constructor(r,i){super(r,i);f(this,"device");f(this,"handle");f(this,"parameters");this.device=r,this.parameters=Ic(i),this.handle=i.handle||this.device.gl.createSampler(),this._setSamplerParameters(this.parameters)}destroy(){this.handle&&(this.device.gl.deleteSampler(this.handle),this.handle=void 0)}toString(){return`Sampler(${this.id},${JSON.stringify(this.props)})`}_setSamplerParameters(r){for(const[i,s]of Object.entries(r)){const n=Number(i);switch(n){case 33082:case 33083:this.device.gl.samplerParameterf(this.handle,n,s);break;default:this.device.gl.samplerParameteri(this.handle,n,s);break}}}}function Ee(e,t,r){if(ob(t))return r(e);const{nocatch:i=!0}=t,s=Pe.get(e);s.push(),ot(e,t);let n;if(i)n=r(e),s.pop();else try{n=r(e)}finally{s.pop()}return n}function ob(e){for(const t in e)return!1;return!0}class Xe extends ur{constructor(r,i){super(r,{...U.defaultProps,...i});f(this,"device");f(this,"gl");f(this,"handle");f(this,"texture");this.device=r,this.gl=this.device.gl,this.handle=null,this.texture=i.texture}}function Nc(e){return ab[e]}const ab={5124:"sint32",5125:"uint32",5122:"sint16",5123:"uint16",5120:"sint8",5121:"uint8",5126:"float32",5131:"float16",33635:"uint16",32819:"uint16",32820:"uint16",33640:"uint32",35899:"uint32",35902:"uint32",34042:"uint32",36269:"uint32"};class yt extends U{constructor(r,i){super(r,i,{byteAlignment:1});f(this,"device");f(this,"gl");f(this,"handle");f(this,"sampler");f(this,"view");f(this,"glTarget");f(this,"glFormat");f(this,"glType");f(this,"glInternalFormat");f(this,"compressed");f(this,"_textureUnit",0);f(this,"_framebuffer",null);f(this,"_framebufferAttachmentKey",null);this.device=r,this.gl=this.device.gl;const s=Mc(this.props.format);this.glTarget=fb(this.props.dimension),this.glInternalFormat=s.internalFormat,this.glFormat=s.format,this.glType=s.type,this.compressed=s.compressed,this.handle=this.props.handle||this.gl.createTexture(),this.device._setWebGLDebugMetadata(this.handle,this,{spector:this.props}),this.gl.bindTexture(this.glTarget,this.handle);const{dimension:n,width:o,height:a,depth:c,mipLevels:l,glTarget:u,glInternalFormat:h}=this;if(!this.compressed)switch(n){case"2d":case"cube":this.gl.texStorage2D(u,l,h,o,a);break;case"2d-array":case"3d":this.gl.texStorage3D(u,l,h,o,a,c);break;default:throw new Error(n)}this.gl.bindTexture(this.glTarget,null),this._initializeData(i.data),this.props.handle?this.trackReferencedMemory(this.getAllocatedByteLength(),"Texture"):this.trackAllocatedMemory(this.getAllocatedByteLength(),"Texture"),this.setSampler(this.props.sampler),this.view=new Xe(this.device,{...this.props,texture:this}),Object.seal(this)}destroy(){var r;this.handle&&((r=this._framebuffer)==null||r.destroy(),this._framebuffer=null,this._framebufferAttachmentKey=null,this.removeStats(),this.props.handle?this.trackDeallocatedReferencedMemory("Texture"):(this.gl.deleteTexture(this.handle),this.trackDeallocatedMemory("Texture")),this.destroyed=!0)}createView(r){return new Xe(this.device,{...r,texture:this})}setSampler(r={}){super.setSampler(r);const i=Ic(this.sampler.props);this._setSamplerParameters(i)}copyExternalImage(r){const i=this._normalizeCopyExternalImageOptions(r);if(i.sourceX||i.sourceY)throw new Error("WebGL does not support sourceX/sourceY)");const{glFormat:s,glType:n}=this,{image:o,depth:a,mipLevel:c,x:l,y:u,z:h,width:d,height:g}=i,p=qt(this.glTarget,this.dimension,h),_=i.flipY?{37440:!0}:{};return this.gl.bindTexture(this.glTarget,this.handle),Ee(this.gl,_,()=>{switch(this.dimension){case"2d":case"cube":this.gl.texSubImage2D(p,c,l,u,d,g,s,n,o);break;case"2d-array":case"3d":this.gl.texSubImage3D(p,c,l,u,h,d,g,a,s,n,o);break;default:}}),this.gl.bindTexture(this.glTarget,null),{width:i.width,height:i.height}}copyImageData(r){super.copyImageData(r)}readBuffer(r={},i){if(!i)throw new Error(`${this} readBuffer requires a destination buffer`);const s=this._getSupportedColorReadOptions(r),n=r.byteOffset??0,o=this.computeMemoryLayout(s);if(i.byteLength{this.gl.readPixels(s.x,s.y,s.width,s.height,this.glFormat,this.glType,n+c)})}finally{this.gl.bindBuffer(35051,null)}return i}async readDataAsync(r={}){throw new Error(`${this} readDataAsync is deprecated; use readBuffer() with an explicit destination buffer or DynamicTexture.readAsync()`)}writeBuffer(r,i={}){const s=this._normalizeTextureWriteOptions(i),{width:n,height:o,depthOrArrayLayers:a,mipLevel:c,byteOffset:l,x:u,y:h,z:d}=s,{glFormat:g,glType:p,compressed:_}=this,m=qt(this.glTarget,this.dimension,d);if(_)throw new Error("writeBuffer for compressed textures is not implemented in WebGL");const{bytesPerPixel:b}=this.device.getTextureFormatInfo(this.format),R=b?s.bytesPerRow/b:void 0,T={3317:this.byteAlignment,...R!==void 0?{3314:R}:{},32878:s.rowsPerImage};this.gl.bindTexture(this.glTarget,this.handle),this.gl.bindBuffer(35052,r.handle),Ee(this.gl,T,()=>{switch(this.dimension){case"2d":case"cube":this.gl.texSubImage2D(m,c,u,h,n,o,g,p,l);break;case"2d-array":case"3d":this.gl.texSubImage3D(m,c,u,h,d,n,o,a,g,p,l);break;default:}}),this.gl.bindBuffer(35052,null),this.gl.bindTexture(this.glTarget,null)}writeData(r,i={}){const s=this._normalizeTextureWriteOptions(i),n=ArrayBuffer.isView(r)?r:new Uint8Array(r),{width:o,height:a,depthOrArrayLayers:c,mipLevel:l,x:u,y:h,z:d,byteOffset:g}=s,{glFormat:p,glType:_,compressed:m}=this,b=qt(this.glTarget,this.dimension,d);let R;if(!m){const{bytesPerPixel:v}=this.device.getTextureFormatInfo(this.format);v&&(R=s.bytesPerRow/v)}const T=this.compressed?{}:{3317:this.byteAlignment,...R!==void 0?{3314:R}:{},32878:s.rowsPerImage},y=lb(n,g),E=m?cb(n,g):n,S=this._getMipLevelSize(l),C=u===0&&h===0&&d===0&&o===S.width&&a===S.height&&c===S.depthOrArrayLayers;this.gl.bindTexture(this.glTarget,this.handle),this.gl.bindBuffer(35052,null),Ee(this.gl,T,()=>{switch(this.dimension){case"2d":case"cube":m?C?this.gl.compressedTexImage2D(b,l,p,o,a,0,E):this.gl.compressedTexSubImage2D(b,l,u,h,o,a,p,E):this.gl.texSubImage2D(b,l,u,h,o,a,p,_,n,y);break;case"2d-array":case"3d":m?C?this.gl.compressedTexImage3D(b,l,p,o,a,c,0,E):this.gl.compressedTexSubImage3D(b,l,u,h,d,o,a,c,p,E):this.gl.texSubImage3D(b,l,u,h,d,o,a,c,p,_,n,y);break;default:}}),this.gl.bindTexture(this.glTarget,null)}_getRowByteAlignment(r,i){return 1}_getFramebuffer(){return this._framebuffer||(this._framebuffer=this.device.createFramebuffer({id:`framebuffer-for-${this.id}`,width:this.width,height:this.height,colorAttachments:[this]})),this._framebuffer}readDataSyncWebGL(r={}){const i=this._getSupportedColorReadOptions(r),s=this.computeMemoryLayout(i),n=Nc(this.glType),o=ka(n),a=new o(s.byteLength/o.BYTES_PER_ELEMENT);return this._readColorTextureLayers(i,s,c=>{const l=new o(a.buffer,a.byteOffset+c,s.bytesPerImage/o.BYTES_PER_ELEMENT);this.gl.readPixels(i.x,i.y,i.width,i.height,this.glFormat,this.glType,l)}),a.buffer}_readColorTextureLayers(r,i,s){const n=this._getFramebuffer(),o=i.bytesPerRow/i.bytesPerPixel,a={3333:this.byteAlignment,...o!==r.width?{3330:o}:{}},c=this.gl.getParameter(3074),l=this.gl.bindFramebuffer(36160,n.handle);try{this.gl.readBuffer(36064),Ee(this.gl,a,()=>{for(let u=0;u`"${l.name}"`).join(", ");i!=null&&i.disableWarnings||A.warn(`No binding "${n}" in render pipeline "${this.id}", expected one of ${c}`,o)()}}}draw(r){var R;this._syncLinkStatus();const i=r.bindGroups?Un(r.bindGroups):r.bindings||this.bindings,{renderPass:s,parameters:n=this.props.parameters,topology:o=this.props.topology,vertexArray:a,vertexCount:c,instanceCount:l,isInstanced:u=!1,firstVertex:h=0,transformFeedback:d,uniforms:g=this.uniforms}=r,p=hb(o),_=!!a.indexBuffer,m=(R=a.indexBuffer)==null?void 0:R.glIndexType;if(this.linkStatus!=="success")return A.info(2,`RenderPipeline:${this.id}.draw() aborted - waiting for shader linking`)(),!1;if(!this._areTexturesRenderable(i))return A.info(2,`RenderPipeline:${this.id}.draw() aborted - textures not yet loaded`)(),!1;this.device.gl.useProgram(this.handle),a.bindBeforeRender(s),d&&d.begin(this.props.topology),this._applyBindings(i,{disableWarnings:this.props.disableWarnings}),this._applyUniforms(g);const b=s;return Gm(this.device,n,b.glParameters,()=>{_&&u?this.device.gl.drawElementsInstanced(p,c||0,m,h,l||0):_?this.device.gl.drawElements(p,c||0,m,h):u?this.device.gl.drawArraysInstanced(p,h,c||0,l||0):this.device.gl.drawArrays(p,h,c||0),d&&d.end()}),a.unbindAfterRender(s),!0}_areTexturesRenderable(r){let i=!0;for(const s of this.shaderLayout.bindings)yo(r,s.name)||(A.warn(`Binding ${s.name} not found in ${this.id}`)(),i=!1);return i}_applyBindings(r,i){if(this._syncLinkStatus(),this.linkStatus!=="success")return;const{gl:s}=this.device;s.useProgram(this.handle);let n=0,o=0;for(const a of this.shaderLayout.bindings){const c=yo(r,a.name);if(!c)throw new Error(`No value for binding ${a.name} in ${this.id}`);switch(a.type){case"uniform":const{name:l}=a,u=s.getUniformBlockIndex(this.handle,l);if(u===4294967295)throw new Error(`Invalid uniform block name ${l}`);if(s.uniformBlockBinding(this.handle,u,o),c instanceof At)s.bindBufferBase(35345,o,c.handle);else{const d=c;s.bindBufferRange(35345,o,d.buffer.handle,d.offset||0,d.size||d.buffer.byteLength-(d.offset||0))}o+=1;break;case"texture":if(!(c instanceof Xe||c instanceof yt||c instanceof Tt))throw new Error("texture");let h;if(c instanceof Xe)h=c.texture;else if(c instanceof yt)h=c;else if(c instanceof Tt&&c.colorAttachments[0]instanceof Xe)A.warn("Passing framebuffer in texture binding may be deprecated. Use fbo.colorAttachments[0] instead")(),h=c.colorAttachments[0].texture;else throw new Error("No texture");s.activeTexture(33984+n),s.bindTexture(h.glTarget,h.handle),n+=1;break;case"sampler":break;case"storage":case"read-only-storage":throw new Error(`binding type '${a.type}' not supported in WebGL`)}}}_applyUniforms(r){for(const i of this.shaderLayout.uniforms||[]){const{name:s,location:n,type:o,textureUnit:a}=i,c=r[s]??a;c!==void 0&&ub(this.device.gl,n,o,c)}}_syncLinkStatus(){this.linkStatus=this.sharedRenderPipeline.linkStatus}}function pb(e,t){const r={...e,attributes:e.attributes.map(i=>({...i})),bindings:e.bindings.map(i=>({...i}))};for(const i of(t==null?void 0:t.attributes)||[]){const s=r.attributes.find(n=>n.name===i.name);s?(s.type=i.type||s.type,s.stepMode=i.stepMode||s.stepMode):A.warn(`shader layout attribute ${i.name} not present in shader`)}for(const i of(t==null?void 0:t.bindings)||[]){const s=Bc(r,i.name);if(!s){A.warn(`shader layout binding ${i.name} not present in shader`);continue}Object.assign(s,i)}return r}function Bc(e,t){return e.bindings.find(r=>r.name===t||r.name===`${t}Uniforms`||`${r.name}Uniforms`===t)}function yo(e,t){return e[t]||e[`${t}Uniforms`]||e[t.replace(/Uniforms$/,"")]}function _b(e){return Tb[e]}function Ls(e){return bb[e]}function Dc(e){return!!Fc[e]}function mb(e){return Fc[e]}const bb={5126:"f32",35664:"vec2",35665:"vec3",35666:"vec4",5124:"i32",35667:"vec2",35668:"vec3",35669:"vec4",5125:"u32",36294:"vec2",36295:"vec3",36296:"vec4",35670:"f32",35671:"vec2",35672:"vec3",35673:"vec4",35674:"mat2x2",35685:"mat2x3",35686:"mat2x4",35687:"mat3x2",35675:"mat3x3",35688:"mat3x4",35689:"mat4x2",35690:"mat4x3",35676:"mat4x4"},Fc={35678:{viewDimension:"2d",sampleType:"float"},35680:{viewDimension:"cube",sampleType:"float"},35679:{viewDimension:"3d",sampleType:"float"},35682:{viewDimension:"3d",sampleType:"depth"},36289:{viewDimension:"2d-array",sampleType:"float"},36292:{viewDimension:"2d-array",sampleType:"depth"},36293:{viewDimension:"cube",sampleType:"float"},36298:{viewDimension:"2d",sampleType:"sint"},36299:{viewDimension:"3d",sampleType:"sint"},36300:{viewDimension:"cube",sampleType:"sint"},36303:{viewDimension:"2d-array",sampleType:"uint"},36306:{viewDimension:"2d",sampleType:"uint"},36307:{viewDimension:"3d",sampleType:"uint"},36308:{viewDimension:"cube",sampleType:"uint"},36311:{viewDimension:"2d-array",sampleType:"uint"}},Tb={uint8:5121,sint8:5120,unorm8:5121,snorm8:5120,uint16:5123,sint16:5122,unorm16:5123,snorm16:5122,uint32:5125,sint32:5124,float16:5131,float32:5126};function Ab(e,t){const r={attributes:[],bindings:[]};r.attributes=yb(e,t);const i=Sb(e,t);for(const a of i){const c=a.uniforms.map(l=>({name:l.name,format:l.format,byteOffset:l.byteOffset,byteStride:l.byteStride,arrayLength:l.arrayLength}));r.bindings.push({type:"uniform",name:a.name,group:0,location:a.location,visibility:(a.vertex?1:0)&(a.fragment?2:0),minBindingSize:a.byteLength,uniforms:c})}const s=Eb(e,t);let n=0;for(const a of s)if(Dc(a.type)){const{viewDimension:c,sampleType:l}=mb(a.type);r.bindings.push({type:"texture",name:a.name,group:0,location:n,viewDimension:c,sampleType:l}),a.textureUnit=n,n+=1}s.length&&(r.uniforms=s);const o=Rb(e,t);return o!=null&&o.length&&(r.varyings=o),r}function yb(e,t){const r=[],i=e.getProgramParameter(t,35721);for(let s=0;s=0){const l=Ls(a),u=/instance/i.test(o)?"instance":"vertex";r.push({name:o,location:c,stepMode:u,type:l})}}return r.sort((s,n)=>s.location-n.location),r}function Rb(e,t){const r=[],i=e.getProgramParameter(t,35971);for(let s=0;ss.location-n.location),r}function Eb(e,t){const r=[],i=e.getProgramParameter(t,35718);for(let s=0;s1)for(let g=0;ge.getActiveUniformBlockParameter(t,n,o),i=[],s=e.getProgramParameter(t,35382);for(let n=0;np.name.split(".")[0]).filter(p=>!!p)),g=o.name.replace(/Uniforms$/,"");if(d.size===1&&!d.has(o.name)&&!d.has(g)){const[p]=d;A.warn(`Uniform block "${o.name}" uses GLSL instance "${p}". luma.gl binds uniform buffers by block name ("${o.name}") and alias ("${g}"). Prefer matching the instance name to one of those to avoid confusing silent mismatches.`)()}i.push(o)}return i.sort((n,o)=>n.location-o.location),i}function Cb(e){if(e[e.length-1]!=="]")return{name:e,length:1,isArray:!1};const r=/([^[]*)(\[[0-9]+\])?/.exec(e);return{name:Os(r==null?void 0:r[1],`Failed to parse GLSL uniform name ${e}`),length:r!=null&&r[2]?1:0,isArray:!!(r!=null&&r[2])}}const Ro=4;class vb extends gg{constructor(r,i){super(r,i);f(this,"device");f(this,"handle");f(this,"vs");f(this,"fs");f(this,"introspectedLayout",{attributes:[],bindings:[],uniforms:[]});f(this,"linkStatus","pending");this.device=r,this.handle=i.handle||this.device.gl.createProgram(),this.vs=i.vs,this.fs=i.fs,i.varyings&&i.varyings.length>0&&this.device.gl.transformFeedbackVaryings(this.handle,i.varyings,i.bufferMode||35981),this._linkShaders(),A.time(3,`RenderPipeline ${this.id} - shaderLayout introspection`)(),this.introspectedLayout=Ab(this.device.gl,this.handle),A.timeEnd(3,`RenderPipeline ${this.id} - shaderLayout introspection`)()}destroy(){this.destroyed||(this.device.gl.useProgram(null),this.device.gl.deleteProgram(this.handle),this.handle.destroyed=!0,this.destroyResource())}async _linkShaders(){const{gl:r}=this.device;if(r.attachShader(this.handle,this.vs.handle),r.attachShader(this.handle,this.fs.handle),A.time(Ro,`linkProgram for ${this.id}`)(),r.linkProgram(this.handle),A.timeEnd(Ro,`linkProgram for ${this.id}`)(),!this.device.features.has("compilation-status-async-webgl")){const s=this._getLinkStatus();this._reportLinkStatus(s);return}A.once(1,"RenderPipeline linking is asynchronous")(),await this._waitForLinkComplete(),A.info(2,`RenderPipeline ${this.id} - async linking complete: ${this.linkStatus}`)();const i=this._getLinkStatus();this._reportLinkStatus(i)}async _reportLinkStatus(r){var i;switch(r){case"success":return;default:const s=r==="link-error"?"Link error":"Validation error";switch(this.vs.compilationStatus){case"error":throw this.vs.debugShader(),new Error(`${this} ${s} during compilation of ${this.vs}`);case"pending":await this.vs.asyncCompilationStatus,this.vs.debugShader();break}switch((i=this.fs)==null?void 0:i.compilationStatus){case"error":throw this.fs.debugShader(),new Error(`${this} ${s} during compilation of ${this.fs}`);case"pending":await this.fs.asyncCompilationStatus,this.fs.debugShader();break}const n=this.device.gl.getProgramInfoLog(this.handle);this.device.reportError(new Error(`${s} during ${r}: ${n}`),this)(),this.device.debug()}}_getLinkStatus(){const{gl:r}=this.device;return r.getProgramParameter(this.handle,35714)?(this._initializeSamplerUniforms(),r.validateProgram(this.handle),r.getProgramParameter(this.handle,35715)?(this.linkStatus="success","success"):(this.linkStatus="error","validation-error")):(this.linkStatus="error","link-error")}_initializeSamplerUniforms(){const{gl:r}=this.device;r.useProgram(this.handle);let i=0;const s=r.getProgramParameter(this.handle,35718);for(let n=0;n1){const a=Int32Array.from({length:i.size},(c,l)=>n+l);return o.uniform1iv(r,a),n+i.size}return o.uniform1i(r,n),n+1}async _waitForLinkComplete(){const r=async n=>await new Promise(o=>setTimeout(o,n));if(!this.device.features.has("compilation-status-async-webgl")){await r(10);return}const{gl:s}=this.device;for(;;){if(s.getProgramParameter(this.handle,37297))return;await r(10)}}}class Pb extends Ki{constructor(r,i={}){super(r,i);f(this,"device");f(this,"handle",null);f(this,"commands",[]);this.device=r}_executeCommands(r=this.commands){for(const i of r)switch(i.name){case"copy-buffer-to-buffer":wb(this.device,i.options);break;case"copy-buffer-to-texture":Ob(this.device,i.options);break;case"copy-texture-to-buffer":xb(this.device,i.options);break;case"copy-texture-to-texture":Mb(this.device,i.options);break;default:throw new Error(i.name)}}}function wb(e,t){const r=t.sourceBuffer,i=t.destinationBuffer;e.gl.bindBuffer(36662,r.handle),e.gl.bindBuffer(36663,i.handle),e.gl.copyBufferSubData(36662,36663,t.sourceOffset??0,t.destinationOffset??0,t.size),e.gl.bindBuffer(36662,null),e.gl.bindBuffer(36663,null)}function Ob(e,t){throw new Error("copyBufferToTexture is not supported in WebGL")}function xb(e,t){const{sourceTexture:r,mipLevel:i=0,aspect:s="all",width:n=t.sourceTexture.width,height:o=t.sourceTexture.height,depthOrArrayLayers:a,origin:c=[0,0,0],destinationBuffer:l,byteOffset:u=0,bytesPerRow:h,rowsPerImage:d}=t;if(r instanceof U){r.readBuffer({x:c[0]??0,y:c[1]??0,z:c[2]??0,width:n,height:o,depthOrArrayLayers:a,mipLevel:i,aspect:s,byteOffset:u},l);return}if(s!=="all")throw new Error("aspect not supported in WebGL");if(i!==0||a!==void 0||h||d)throw new Error("not implemented");const{framebuffer:g,destroyFramebuffer:p}=Uc(r);let _;try{const m=l,b=n||g.width,R=o||g.height,T=Os(g.colorAttachments[0]),y=Mc(T.texture.props.format),E=y.format,S=y.type;e.gl.bindBuffer(35051,m.handle),_=e.gl.bindFramebuffer(36160,g.handle),e.gl.readPixels(c[0],c[1],b,R,E,S,u)}finally{e.gl.bindBuffer(35051,null),_!==void 0&&e.gl.bindFramebuffer(36160,_),p&&g.destroy()}}function Mb(e,t){const{sourceTexture:r,destinationMipLevel:i=0,origin:s=[0,0],destinationOrigin:n=[0,0,0],destinationTexture:o}=t;let{width:a=t.destinationTexture.width,height:c=t.destinationTexture.height}=t;const{framebuffer:l,destroyFramebuffer:u}=Uc(r),[h=0,d=0]=s,[g,p,_]=n,m=e.gl.bindFramebuffer(36160,l.handle);let b,R;if(o instanceof yt)b=o,a=Number.isFinite(a)?a:b.width,c=Number.isFinite(c)?c:b.height,b._bind(0),R=b.glTarget;else throw new Error("invalid destination");switch(R){case 3553:case 34067:e.gl.copyTexSubImage2D(R,i,g,p,h,d,a,c);break;case 35866:case 32879:e.gl.copyTexSubImage3D(R,i,g,p,_,h,d,a,c);break}b&&b._unbind(),e.gl.bindFramebuffer(36160,m),u&&l.destroy()}function Uc(e){if(e instanceof U){const{width:t,height:r,id:i}=e;return{framebuffer:e.device.createFramebuffer({id:`framebuffer-for-${i}`,width:t,height:r,colorAttachments:[e]}),destroyFramebuffer:!0}}return{framebuffer:e,destroyFramebuffer:!1}}const Ib=[1,2,4,8];class Nb extends Xi{constructor(r,i){var a;super(r,i);f(this,"device");f(this,"handle",null);f(this,"glParameters",{});this.device=r;const s=this.props.framebuffer,n=!s||s.handle===null;n&&r.getDefaultCanvasContext()._resizeDrawingBufferIfNeeded();let o;if(!((a=i==null?void 0:i.parameters)!=null&&a.viewport))if(!n&&s){const{width:c,height:l}=s;o=[0,0,c,l]}else{const[c,l]=r.getDefaultCanvasContext().getDrawingBufferSize();o=[0,0,c,l]}if(this.device.pushState(),this.setParameters({viewport:o,...this.props.parameters}),!n&&(s!=null&&s.colorAttachments.length)){const c=s.colorAttachments.map((l,u)=>36064+u);this.device.gl.drawBuffers(c)}else n&&this.device.gl.drawBuffers([1029]);this.clear(),this.props.timestampQuerySet&&this.props.beginTimestampIndex!==void 0&&this.props.timestampQuerySet.writeTimestamp(this.props.beginTimestampIndex)}end(){this.destroyed||(this.props.timestampQuerySet&&this.props.endTimestampIndex!==void 0&&this.props.timestampQuerySet.writeTimestamp(this.props.endTimestampIndex),this.device.popState(),this.destroy())}pushDebugGroup(r){}popDebugGroup(){}insertDebugMarker(r){}setParameters(r={}){const i={...this.glParameters};i.framebuffer=this.props.framebuffer||null,this.props.depthReadOnly&&(i.depthMask=!this.props.depthReadOnly),i.stencilMask=this.props.stencilReadOnly?0:1,i[35977]=this.props.discard,r.viewport&&(r.viewport.length>=6?(i.viewport=r.viewport.slice(0,4),i.depthRange=[r.viewport[4],r.viewport[5]]):i.viewport=r.viewport),r.scissorRect&&(i.scissorTest=!0,i.scissor=r.scissorRect),r.blendConstant&&(i.blendColor=r.blendConstant),r.stencilReference!==void 0&&(i[2967]=r.stencilReference,i[36003]=r.stencilReference),"colorMask"in r&&(i.colorMask=Ib.map(s=>!!(s&r.colorMask))),this.glParameters=i,ot(this.device.gl,i)}beginOcclusionQuery(r){const i=this.props.occlusionQuerySet;i==null||i.beginOcclusionQuery()}endOcclusionQuery(){const r=this.props.occlusionQuerySet;r==null||r.endOcclusionQuery()}clear(){const r={...this.glParameters};let i=0;this.props.clearColors&&this.props.clearColors.forEach((s,n)=>{s&&this.clearColorBuffer(n,s)}),this.props.clearColor!==!1&&this.props.clearColors===void 0&&(i|=16384,r.clearColor=this.props.clearColor),this.props.clearDepth!==!1&&(i|=256,r.clearDepth=this.props.clearDepth),this.props.clearStencil!==!1&&(i|=1024,r.clearStencil=this.props.clearStencil),i!==0&&Ee(this.device.gl,r,()=>{this.device.gl.clear(i)})}clearColorBuffer(r=0,i=[0,0,0,0]){Ee(this.device.gl,{framebuffer:this.props.framebuffer},()=>{switch(i.constructor){case Int8Array:case Int16Array:case Int32Array:this.device.gl.clearBufferiv(6144,r,i);break;case Uint8Array:case Uint8ClampedArray:case Uint16Array:case Uint32Array:this.device.gl.clearBufferuiv(6144,r,i);break;case Float32Array:this.device.gl.clearBufferfv(6144,r,i);break;default:throw new Error("clearColorBuffer: color must be typed array")}})}}class Eo extends Yi{constructor(r,i){super(r,i);f(this,"device");f(this,"handle",null);f(this,"commandBuffer");this.device=r,this.commandBuffer=new Pb(r,{id:`${this.props.id}-command-buffer`})}destroy(){this.destroyResource()}finish(r){return r!=null&&r.id&&this.commandBuffer.id!==r.id&&(this.commandBuffer.id=r.id,this.commandBuffer.props.id=r.id),this.destroy(),this.commandBuffer}beginRenderPass(r={}){return new Nb(this.device,this._applyTimeProfilingToPassProps(r))}beginComputePass(r={}){throw new Error("ComputePass not supported in WebGL")}copyBufferToBuffer(r){this.commandBuffer.commands.push({name:"copy-buffer-to-buffer",options:r})}copyBufferToTexture(r){this.commandBuffer.commands.push({name:"copy-buffer-to-texture",options:r})}copyTextureToBuffer(r){this.commandBuffer.commands.push({name:"copy-texture-to-buffer",options:r})}copyTextureToTexture(r){this.commandBuffer.commands.push({name:"copy-texture-to-texture",options:r})}pushDebugGroup(r){}popDebugGroup(){}insertDebugMarker(r){}resolveQuerySet(r,i,s){throw new Error("resolveQuerySet is not supported in WebGL")}writeTimestamp(r,i){r.writeTimestamp(i)}}function Bb(e){const{target:t,source:r,start:i=0,count:s=1}=e,n=r.length,o=s*n;let a=0;for(let c=i;a{for(const[i,s]of Object.entries(r))this.setBuffer(i,s)})}setBuffer(r,i){const s=this._getVaryingIndex(r),{buffer:n,byteLength:o,byteOffset:a}=this._getBufferRange(i);if(s<0){this.unusedBuffers[r]=n,A.warn(`${this.id} unusedBuffers varying buffer ${r}`)();return}this.buffers[s]={buffer:n,byteLength:o,byteOffset:a},this.bindOnUse||this._bindBuffer(s,n,a,o)}getBuffer(r){if(So(r))return this.buffers[r]||null;const i=this._getVaryingIndex(r);return this.buffers[i]??null}bind(r=this.handle){if(typeof r!="function")return this.gl.bindTransformFeedback(36386,r),this;let i;return this._bound?i=r():(this.gl.bindTransformFeedback(36386,this.handle),this._bound=!0,i=r(),this._bound=!1,this.gl.bindTransformFeedback(36386,null)),i}unbind(){this.bind(null)}_getBufferRange(r){if(r instanceof At)return{buffer:r,byteOffset:0,byteLength:r.byteLength};const{buffer:i,byteOffset:s=0,byteLength:n=r.buffer.byteLength}=r;return{buffer:i,byteOffset:s,byteLength:n}}_getVaryingIndex(r){if(So(r))return Number(r);for(const i of this.layout.varyings||[])if(r===i.name)return i.location;return-1}_bindBuffers(){for(const[r,i]of Object.entries(this.buffers)){const{buffer:s,byteLength:n,byteOffset:o}=this._getBufferRange(i);this._bindBuffer(Number(r),s,o,n)}}_unbindBuffers(){for(const r in this.buffers)this.gl.bindBufferBase(35982,Number(r),null)}_bindBuffer(r,i,s=0,n){const o=i&&i.handle;!o||n===void 0?this.gl.bindBufferBase(35982,r,o):this.gl.bindBufferRange(35982,r,o,s,n)}}function So(e){return typeof e=="number"?Number.isInteger(e):/^\d+$/.test(e)}class Lb extends Zi{constructor(r,i){super(r,i);f(this,"device");f(this,"handle");f(this,"_timestampPairs",[]);f(this,"_pendingReads",new Set);f(this,"_occlusionQuery",null);f(this,"_occlusionActive",!1);if(this.device=r,i.type==="timestamp"){if(i.count<2)throw new Error("Timestamp QuerySet requires at least two query slots");this._timestampPairs=new Array(Math.ceil(i.count/2)).fill(null).map(()=>({activeQuery:null,completedQueries:[]})),this.handle=null}else{if(i.count>1)throw new Error("WebGL occlusion QuerySet can only have one value");const s=this.device.gl.createQuery();if(!s)throw new Error("WebGL query not supported");this.handle=s}Object.seal(this)}get[Symbol.toStringTag](){return"QuerySet"}destroy(){if(!this.destroyed){this.handle&&this.device.gl.deleteQuery(this.handle);for(const r of this._timestampPairs){r.activeQuery&&(this._cancelPendingQuery(r.activeQuery),this.device.gl.deleteQuery(r.activeQuery.handle));for(const i of r.completedQueries)this._cancelPendingQuery(i),this.device.gl.deleteQuery(i.handle)}this._occlusionQuery&&(this._cancelPendingQuery(this._occlusionQuery),this.device.gl.deleteQuery(this._occlusionQuery.handle));for(const r of Array.from(this._pendingReads))this._cancelPendingQuery(r);this.destroyResource()}}isResultAvailable(r){return this.props.type==="timestamp"?r===void 0?this._timestampPairs.some((i,s)=>this._isTimestampPairAvailable(s)):this._isTimestampPairAvailable(this._getTimestampPairIndex(r)):this._occlusionQuery?this._pollQueryAvailability(this._occlusionQuery):!1}async readResults(r){const i=(r==null?void 0:r.firstQuery)||0,s=(r==null?void 0:r.queryCount)||this.props.count-i;if(this._validateRange(i,s),this.props.type==="timestamp"){const n=new Array(s).fill(0n),o=Math.floor(i/2),a=Math.floor((i+s-1)/2);for(let c=o;c<=a;c++){const l=await this._consumeTimestampPairResult(c),u=c*2,h=u+1;u>=i&&u=i&&h=this.props.count||i<=r)throw new Error("Timestamp duration range is out of bounds");if(r%2!==0||i!==r+1)throw new Error("WebGL timestamp durations require adjacent even/odd query indices");const s=await this._consumeTimestampPairResult(this._getTimestampPairIndex(r));return Number(s)/1e6}beginOcclusionQuery(){if(this.props.type!=="occlusion")throw new Error("Occlusion queries require an occlusion QuerySet");if(!this.handle)throw new Error("WebGL occlusion query is not available");if(this._occlusionActive)throw new Error("Occlusion query is already active");this.device.gl.beginQuery(35887,this.handle),this._occlusionQuery={handle:this.handle,promise:null,result:null,disjoint:!1,cancelled:!1,pollRequestId:null,resolve:null,reject:null},this._occlusionActive=!0}endOcclusionQuery(){if(!this._occlusionActive)throw new Error("Occlusion query is not active");this.device.gl.endQuery(35887),this._occlusionActive=!1}writeTimestamp(r){if(this.props.type!=="timestamp")throw new Error("Timestamp writes require a timestamp QuerySet");const i=this._getTimestampPairIndex(r),s=this._timestampPairs[i];if(r%2===0){if(s.activeQuery)throw new Error("Timestamp query pair is already active");const n=this.device.gl.createQuery();if(!n)throw new Error("WebGL query not supported");const o={handle:n,promise:null,result:null,disjoint:!1,cancelled:!1,pollRequestId:null,resolve:null,reject:null};this.device.gl.beginQuery(35007,n),s.activeQuery=o;return}if(!s.activeQuery)throw new Error("Timestamp query pair was ended before it was started");this.device.gl.endQuery(35007),s.completedQueries.push(s.activeQuery),s.activeQuery=null}_validateRange(r,i){if(r<0||i<0||r+i>this.props.count)throw new Error("Query read range is out of bounds")}_getTimestampPairIndex(r){if(r<0||r>=this.props.count)throw new Error("Query index is out of bounds");return Math.floor(r/2)}_isTimestampPairAvailable(r){const i=this._timestampPairs[r];return!i||i.completedQueries.length===0?!1:this._pollQueryAvailability(i.completedQueries[0])}_pollQueryAvailability(r){if(r.cancelled||this.destroyed)return r.result=0n,!0;if(r.result!==null||r.disjoint)return!0;if(!this.device.gl.getQueryParameter(r.handle,34919))return!1;const s=!!this.device.gl.getParameter(36795);return r.disjoint=s,r.result=s?0n:BigInt(this.device.gl.getQueryParameter(r.handle,34918)),!0}async _consumeTimestampPairResult(r){const i=this._timestampPairs[r];if(!i||i.completedQueries.length===0)throw new Error("Timestamp query pair has no completed result");const s=i.completedQueries.shift();try{return await this._consumeQueryResult(s)}finally{this.device.gl.deleteQuery(s.handle)}}_consumeQueryResult(r){return r.promise||(this._pendingReads.add(r),r.promise=new Promise((i,s)=>{r.resolve=i,r.reject=s;const n=()=>{if(r.pollRequestId=null,r.cancelled||this.destroyed){this._pendingReads.delete(r),r.promise=null,r.resolve=null,r.reject=null,i(0n);return}if(!this._pollQueryAvailability(r)){r.pollRequestId=this._requestAnimationFrame(n);return}this._pendingReads.delete(r),r.promise=null,r.resolve=null,r.reject=null,r.disjoint?s(new Error("GPU timestamp query was invalidated by a disjoint event")):i(r.result||0n)};n()})),r.promise}_cancelPendingQuery(r){if(this._pendingReads.delete(r),r.cancelled=!0,r.pollRequestId!==null&&(this._cancelAnimationFrame(r.pollRequestId),r.pollRequestId=null),r.resolve){const i=r.resolve;r.promise=null,r.resolve=null,r.reject=null,i(0n)}}_requestAnimationFrame(r){return requestAnimationFrame(r)}_cancelAnimationFrame(r){cancelAnimationFrame(r)}}class kb extends Ji{constructor(r,i={}){super(r,{});f(this,"device");f(this,"gl");f(this,"handle");f(this,"signaled");f(this,"_signaled",!1);this.device=r,this.gl=r.gl;const s=this.props.handle||this.gl.fenceSync(this.gl.SYNC_GPU_COMMANDS_COMPLETE,0);if(!s)throw new Error("Failed to create WebGL fence");this.handle=s,this.signaled=new Promise(n=>{const o=()=>{const a=this.gl.clientWaitSync(this.handle,0,0);a===this.gl.ALREADY_SIGNALED||a===this.gl.CONDITION_SATISFIED?(this._signaled=!0,n()):setTimeout(o,1)};o()})}isSignaled(){if(this._signaled)return!0;const r=this.gl.getSyncParameter(this.handle,this.gl.SYNC_STATUS);return this._signaled=r===this.gl.SIGNALED,this._signaled}destroy(){this.destroyed||this.gl.deleteSync(this.handle)}}function Lc(e){switch(e){case 6406:case 33326:case 6403:case 36244:return 1;case 33339:case 33340:case 33328:case 33320:case 33319:return 2;case 6407:case 36248:case 34837:return 3;case 6408:case 36249:case 34836:return 4;default:return 0}}function Wb(e){switch(e){case 5121:return 1;case 33635:case 32819:case 32820:return 2;case 5126:return 4;default:return 0}}function $b(e,t){var R;const{sourceX:r=0,sourceY:i=0,sourceAttachment:s=0}=t||{};let{target:n=null,sourceWidth:o,sourceHeight:a,sourceDepth:c,sourceFormat:l,sourceType:u}=t||{};const{framebuffer:h,deleteFramebuffer:d}=kc(e),{gl:g,handle:p}=h;o||(o=h.width),a||(a=h.height);const _=(R=h.colorAttachments[s])==null?void 0:R.texture;if(!_)throw new Error(`Invalid framebuffer attachment ${s}`);c=(_==null?void 0:_.depth)||1,l||(l=(_==null?void 0:_.glFormat)||6408),u||(u=(_==null?void 0:_.glType)||5121),n=Hb(n,u,l,o,a);const m=le.getDataType(n);u=u||_b(m);const b=g.bindFramebuffer(36160,p);return g.readBuffer(36064+s),g.readPixels(r,i,o,a,l,u,n),g.readBuffer(36064),g.bindFramebuffer(36160,b||null),d&&h.destroy(),n}function zb(e,t){const{target:r,sourceX:i=0,sourceY:s=0,sourceFormat:n=6408,targetByteOffset:o=0}=t||{};let{sourceWidth:a,sourceHeight:c,sourceType:l}=t||{};const{framebuffer:u,deleteFramebuffer:h}=kc(e);a=a||u.width,c=c||u.height;const d=u;l=l||5121;let g=r;if(!g){const _=Lc(n),m=Wb(l),b=o+a*c*_*m;g=d.device.createBuffer({byteLength:b})}const p=e.device.createCommandEncoder();return p.copyTextureToBuffer({sourceTexture:e,width:a,height:c,origin:[i,s],destinationBuffer:g,byteOffset:o}),p.destroy(),h&&u.destroy(),g}function kc(e){return e instanceof dr?{framebuffer:e,deleteFramebuffer:!1}:{framebuffer:jb(e),deleteFramebuffer:!0}}function jb(e,t){const{device:r,width:i,height:s,id:n}=e;return r.createFramebuffer({...t,id:`framebuffer-for-${n}`,width:i,height:s,colorAttachments:[e]})}function Hb(e,t,r,i,s,n){if(e)return e;t||(t=5121);const o=Nc(t),a=le.getTypedArrayConstructor(o),c=Lc(r);return new a(i*s*c)}class Oe extends fr{constructor(r){var h;super({...r,id:r.id||Km("webgl-device")});f(this,"type","webgl");f(this,"handle");f(this,"features");f(this,"limits");f(this,"info");f(this,"canvasContext");f(this,"preferredColorFormat","rgba8unorm");f(this,"preferredDepthFormat","depth24plus");f(this,"commandEncoder");f(this,"lost");f(this,"_resolveContextLost");f(this,"gl");f(this,"_constants");f(this,"extensions");f(this,"_polyfilled",!1);f(this,"spectorJS");const i=fr._getCanvasContextProps(r);if(!i)throw new Error("WebGLDevice requires props.createCanvasContext to be set");const s=((h=i.canvas)==null?void 0:h.gl)??null;let n=Oe.getDeviceFromContext(s);if(n)throw new Error(`WebGL context already attached to device ${n.id}`);this.canvasContext=new Xm(this,i),this.lost=new Promise(d=>{this._resolveContextLost=d});const o={...r.webgl};i.alphaMode==="premultiplied"&&(o.premultipliedAlpha=!0),r.powerPreference!==void 0&&(o.powerPreference=r.powerPreference),r.failIfMajorPerformanceCaveat!==void 0&&(o.failIfMajorPerformanceCaveat=r.failIfMajorPerformanceCaveat);const c=this.props._handle||Sm(this.canvasContext.canvas,{onContextLost:d=>{var g;return(g=this._resolveContextLost)==null?void 0:g.call(this,{reason:"destroyed",message:"Entered sleep mode, or too many apps or browser tabs are using the GPU."})},onContextRestored:d=>console.log("WebGL context restored")},o);if(!c)throw new Error("WebGL context creation failed");if(n=Oe.getDeviceFromContext(c),n){if(r._reuseDevices)return A.log(1,`Not creating a new Device, instead returning a reference to Device ${n.id} already attached to WebGL context`,n)(),this.canvasContext.destroy(),n._reused=!0,n;throw new Error(`WebGL context already attached to device ${n.id}`)}this.handle=c,this.gl=c,this.spectorJS=lm({...this.props,gl:this.handle});const l=Rr(this.handle);l.device=this,l.extensions||(l.extensions={}),this.extensions=l.extensions,this.info=Cm(this.gl,this.extensions),this.limits=new jm(this.gl),this.features=new zm(this.gl,this.extensions,this.props._disabledFeatures),this.props._initializeFeatures&&this.features.initializeFeatures(),new Pe(this.gl,{log:(...d)=>A.log(1,...d)()}).trackState(this.gl,{copyState:!1}),(r.debug||r.debugWebGL)&&(this.gl=um(this.gl,{debugWebGL:!0,traceWebGL:r.debugWebGL}),A.warn("WebGL debug mode activated. Performance reduced.")()),r.debugWebGL&&(A.level=Math.max(A.level,1)),this.commandEncoder=new Eo(this,{id:`${this}-command-encoder`}),this.canvasContext._startObservers()}static getDeviceFromContext(r){var i;return r?((i=r.luma)==null?void 0:i.device)??null:null}get[Symbol.toStringTag](){return"WebGLDevice"}toString(){return`${this[Symbol.toStringTag]}(${this.id})`}isVertexFormatSupported(r){switch(r){case"unorm8x4-bgra":return!1;default:return!0}}destroy(){var r;if((r=this.commandEncoder)==null||r.destroy(),!this.props._reuseDevices&&!this._reused){const i=Rr(this.handle);i.device=null}}get isLost(){return this.gl.isContextLost()}createCanvasContext(r){throw new Error("WebGL only supports a single canvas")}createPresentationContext(r){return new Ym(this,r||{})}createBuffer(r){const i=this._normalizeBufferProps(r);return new At(this,i)}createTexture(r){return new yt(this,r)}createExternalTexture(r){throw new Error("createExternalTexture() not implemented")}createSampler(r){return new nb(this,r)}createShader(r){return new Jm(this,r)}createFramebuffer(r){return new Tt(this,r)}createVertexArray(r){return new ks(this,r)}createTransformFeedback(r){return new Ub(this,r)}createQuerySet(r){return new Lb(this,r)}createFence(){return new kb(this)}createRenderPipeline(r){return new gb(this,r)}_createSharedRenderPipelineWebGL(r){return new vb(this,r)}createComputePipeline(r){throw new Error("ComputePipeline not supported in WebGL")}createCommandEncoder(r={}){return new Eo(this,r)}submit(r){let i=null;r||({submittedCommandEncoder:i,commandBuffer:r}=this._finalizeDefaultCommandEncoderForSubmit());try{r._executeCommands(),i&&i.resolveTimeProfilingQuerySet().then(()=>{this.commandEncoder._gpuTimeMs=i._gpuTimeMs}).catch(()=>{})}finally{r.destroy()}}_finalizeDefaultCommandEncoderForSubmit(){const r=this.commandEncoder,i=r.finish();return this.commandEncoder.destroy(),this.commandEncoder=this.createCommandEncoder({id:r.props.id,timeProfilingQuerySet:r.getTimeProfilingQuerySet()}),{submittedCommandEncoder:r,commandBuffer:i}}readPixelsToArrayWebGL(r,i){return $b(r,i)}readPixelsToBufferWebGL(r,i){return zb(r,i)}setParametersWebGL(r){ot(this.gl,r)}getParametersWebGL(r){return Cc(this.gl,r)}withParametersWebGL(r,i){return Ee(this.gl,r,i)}resetWebGL(){A.warn("WebGLDevice.resetWebGL is deprecated, use only for debugging")(),Tm(this.gl)}_getDeviceSpecificTextureFormatCapabilities(r){return Um(this.gl,r,this.extensions)}loseDevice(){var n;let r=!1;const s=this.getExtension("WEBGL_lose_context").WEBGL_lose_context;return s&&(r=!0,s.loseContext()),(n=this._resolveContextLost)==null||n.call(this,{reason:"destroyed",message:"Application triggered context loss"}),r}pushState(){Pe.get(this.gl).push()}popState(){Pe.get(this.gl).pop()}getGLKey(r,i){const s=Number(r);for(const n in this.gl)if(this.gl[n]===s)return`GL.${n}`;return i!=null&&i.emptyIfUnknown?"":String(r)}getGLKeys(r){const i={emptyIfUnknown:!0};return Object.entries(r).reduce((s,[n,o])=>(s[`${n}:${this.getGLKey(n,i)}`]=`${o}:${this.getGLKey(o,i)}`,s),{})}setConstantAttributeWebGL(r,i){const s=this.limits.maxVertexAttributes;this._constants=this._constants||new Array(s).fill(null);const n=this._constants[r];switch(n&&Kb(n,i)&&A.info(1,`setConstantAttributeWebGL(${r}) could have been skipped, value unchanged`)(),this._constants[r]=i,i.constructor){case Float32Array:Vb(this,r,i);break;case Int32Array:Xb(this,r,i);break;case Uint32Array:Yb(this,r,i);break;default:throw new Error("constant")}}getExtension(r){return Ne(this.gl,r,this.extensions),this.extensions}_setWebGLDebugMetadata(r,i,s){r.luma=i;const n={props:s.spector,id:s.spector.id};r.__SPECTOR_Metadata=n}}function Vb(e,t,r){switch(r.length){case 1:e.gl.vertexAttrib1fv(t,r);break;case 2:e.gl.vertexAttrib2fv(t,r);break;case 3:e.gl.vertexAttrib3fv(t,r);break;case 4:e.gl.vertexAttrib4fv(t,r);break}}function Xb(e,t,r){e.gl.vertexAttribI4iv(t,r)}function Yb(e,t,r){e.gl.vertexAttribI4uiv(t,r)}function Kb(e,t){if(!e||!t||e.length!==t.length||e.constructor!==t.constructor)return!1;for(let r=0;r4)return null;const i=r==="webgpu"&&t.type==="uint8"?"unorm8":t.type;return{attribute:e,format:t.size>1?`${i}x${t.size}`:t.type,byteOffset:t.offset||0}}function Se(e){return e.stride||e.size*e.bytesPerElement}function Zb(e,t){return e.type===t.type&&e.size===t.size&&Se(e)===Se(t)&&(e.offset||0)===(t.offset||0)}function fs(e,t){t.offset&&G.removed("shaderAttribute.offset","vertexOffset, elementOffset")();const r=Se(e),i=t.vertexOffset!==void 0?t.vertexOffset:e.vertexOffset||0,s=t.elementOffset||0,n=i*r+s*e.bytesPerElement+(e.offset||0);return{...t,offset:n,stride:r}}function Jb(e,t){const r=fs(e,t);return{high:r,low:{...r,offset:r.offset+e.size*4}}}class Gb{constructor(t,r,i){this._buffer=null,this.device=t,this.id=r.id||"",this.size=r.size||1;const s=r.logicalType||r.type,n=s==="float64";let{defaultValue:o}=r;o=Number.isFinite(o)?[o]:o||new Array(this.size).fill(0);let a;n?a="float32":!s&&r.isIndexed?a="uint32":a=s||"float32";let c=Qb(s||a);this.doublePrecision=n,n&&r.fp64===!1&&(c=Float32Array),this.value=null,this.settings={...r,defaultType:c,defaultValue:o,logicalType:s,type:a,normalized:a.includes("norm"),size:this.size,bytesPerElement:c.BYTES_PER_ELEMENT},this.state={...i,externalBuffer:null,bufferAccessor:this.settings,allocatedValue:null,numInstances:0,bounds:null,constant:!1}}get isConstant(){return this.state.constant}get buffer(){return this._buffer}get byteOffset(){const t=this.getAccessor();return t.vertexOffset?t.vertexOffset*Se(t):0}get numInstances(){return this.state.numInstances}set numInstances(t){this.state.numInstances=t}delete(){this._buffer&&(this._buffer.delete(),this._buffer=null),Pt.release(this.state.allocatedValue)}getBuffer(){return this.state.constant?null:this.state.externalBuffer||this._buffer}getValue(t=this.id,r=null){const i={};if(this.state.constant){const s=this.value;if(r){const n=fs(this.getAccessor(),r),o=n.offset/s.BYTES_PER_ELEMENT,a=n.size||this.size;i[t]=s.subarray(o,o+a)}else i[t]=s}else i[t]=this.getBuffer();return this.doublePrecision&&(this.value instanceof Float64Array?i[`${t}64Low`]=i[t]:i[`${t}64Low`]=new Float32Array(this.size)),i}_getBufferLayout(t=this.id,r=null){const i=this.getAccessor(),s=[],n={name:this.id,byteStride:Se(i)};if(this.doublePrecision){const o=Jb(i,r||{});s.push(Zt(t,{...i,...o.high},this.device.type),Zt(`${t}64Low`,{...i,...o.low},this.device.type))}else if(r){const o=fs(i,r);s.push(Zt(t,{...i,...o},this.device.type))}else s.push(Zt(t,i,this.device.type));return n.attributes=s.filter(Boolean),n}setAccessor(t){this.state.bufferAccessor=t}getAccessor(){return this.state.bufferAccessor}getBounds(){if(this.state.bounds)return this.state.bounds;let t=null;if(this.state.constant&&this.value){const r=Array.from(this.value);t=[r,r]}else{const{value:r,numInstances:i,size:s}=this,n=i*s;if(r&&n&&r.length>=n){const o=new Array(s).fill(1/0),a=new Array(s).fill(-1/0);for(let c=0;ca[l]&&(a[l]=u)}t=[o,a]}}return this.state.bounds=t,t}setData(t){const{state:r}=this;let i;ArrayBuffer.isView(t)?i={value:t}:t instanceof N?i={buffer:t}:i=t;const s={...this.settings,...i};if(ArrayBuffer.isView(i.value)){if(!i.type)if(this.doublePrecision&&i.value instanceof Float64Array)s.type="float32";else{const o=qb(i.value);s.type=s.normalized?o.replace("int","norm"):o}s.bytesPerElement=i.value.BYTES_PER_ELEMENT,s.stride=Se(s)}if(r.bounds=null,i.constant){let n=i.value;if(n=this._normalizeValue(n,[],0),this.settings.normalized&&(n=this.normalizeConstant(n)),!(!r.constant||!this._areValuesEqual(n,this.value)))return!1;r.externalBuffer=null,r.constant=!0,this.value=ArrayBuffer.isView(n)?n:new Float32Array(n)}else if(i.buffer){const n=i.buffer;r.externalBuffer=n,r.constant=!1,this.value=i.value||null}else if(i.value){this._checkExternalBuffer(i);let n=i.value;r.externalBuffer=null,r.constant=!1,this.value=n;let{buffer:o}=this;const a=Se(s),c=(s.vertexOffset||0)*a;if(this.doublePrecision&&n instanceof Float64Array&&(n=bi(n,s)),this.settings.isIndexed){const u=this.settings.defaultType;n.constructor!==u&&(n=new u(n))}const l=n.byteLength+c+a*2;(!o||o.byteLength(r+128)/255*2-1);case"snorm16":return new Float32Array(t).map(r=>(r+32768)/65535*2-1);case"unorm8":return new Float32Array(t).map(r=>r/255);case"unorm16":return new Float32Array(t).map(r=>r/65535);default:return t}}_normalizeValue(t,r,i){const{defaultValue:s,size:n}=this.settings;if(Number.isFinite(t))return r[i]=t,r;if(!t){let o=n;for(;--o>=0;)r[i+o]=s[o];return r}switch(n){case 4:r[i+3]=Number.isFinite(t[3])?t[3]:s[3];case 3:r[i+2]=Number.isFinite(t[2])?t[2]:s[2];case 2:r[i+1]=Number.isFinite(t[1])?t[1]:s[1];case 1:r[i+0]=Number.isFinite(t[0])?t[0]:s[0];break;default:let o=n;for(;--o>=0;)r[i+o]=Number.isFinite(t[o])?t[o]:s[o]}return r}_areValuesEqual(t,r){if(!t||!r)return!1;const{size:i}=this;for(let s=0;s0&&(vo.length=e.length,i=vo):i=Co,(t>0||Number.isFinite(r))&&(i=(Array.isArray(i)?i:Array.from(i)).slice(t,r),s.index=t-1),{iterable:i,objectInfo:s}}function $c(e){return e&&e[Symbol.asyncIterator]}function zc(e,t){const{size:r,stride:i,offset:s,startIndices:n,nested:o}=t,a=e.BYTES_PER_ELEMENT,c=i?i/a:r,l=s?s/a:0,u=Math.floor((e.length-l)/c);return(h,{index:d,target:g})=>{if(!n){const b=d*c+l;for(let R=0;R=t[1]))return e;const r=[],i=e.length;let s=0;for(let n=0;nt[1]?r.push(o):t=[Math.min(o[0],t[0]),Math.max(o[1],t[1])]}return r.splice(s,0,t),r}const rT={interpolation:{duration:0,easing:e=>e},spring:{stiffness:.05,damping:.5}};function jc(e,t){if(!e)return null;Number.isFinite(e)&&(e={type:"interpolation",duration:e});const r=e.type||"interpolation";return{...rT[r],...t,...e,type:r}}class Hc extends Gb{constructor(t,r){super(t,r,{startIndices:null,lastExternalBuffer:null,binaryValue:null,binaryAccessor:null,needsUpdate:!0,needsRedraw:!1,layoutChanged:!1,updateRanges:tr}),this.constant=!1,this.settings.update=r.update||(r.accessor?this._autoUpdater:void 0),Object.seal(this.settings),Object.seal(this.state),this._validateAttributeUpdaters()}get startIndices(){return this.state.startIndices}set startIndices(t){this.state.startIndices=t}needsUpdate(){return this.state.needsUpdate}needsRedraw({clearChangedFlags:t=!1}={}){const r=this.state.needsRedraw;return this.state.needsRedraw=r&&!t,r}layoutChanged(){return this.state.layoutChanged}setAccessor(t){var r;(r=this.state).layoutChanged||(r.layoutChanged=!Zb(t,this.getAccessor())),super.setAccessor(t)}getUpdateTriggers(){const{accessor:t}=this.settings;return[this.id].concat(typeof t!="function"&&t||[])}supportsTransition(){return!!this.settings.transition}getTransitionSetting(t){if(!t||!this.supportsTransition())return null;const{accessor:r}=this.settings,i=this.settings.transition,s=Array.isArray(r)?t[r.find(n=>t[n])]:t[r];return jc(s,i)}setNeedsUpdate(t=this.id,r){if(this.state.needsUpdate=this.state.needsUpdate||t,this.setNeedsRedraw(t),r){const{startRow:i=0,endRow:s=1/0}=r;this.state.updateRanges=tT(this.state.updateRanges,[i,s])}else this.state.updateRanges=tr}clearNeedsUpdate(){this.state.needsUpdate=!1,this.state.updateRanges=eT}setNeedsRedraw(t=this.id){this.state.needsRedraw=this.state.needsRedraw||t}allocate(t){const{state:r,settings:i}=this;return i.noAlloc?!1:i.update?(super.allocate(t,r.updateRanges!==tr),!0):!1}updateBuffer({numInstances:t,data:r,props:i,context:s}){if(!this.needsUpdate())return!1;const{state:{updateRanges:n},settings:{update:o,noAlloc:a}}=this;let c=!0;if(o){for(const[l,u]of n)o.call(s,this,{data:r,startRow:l,endRow:u,props:i,numInstances:t});if(this.value)if(this.constant||!this.buffer||this.buffer.byteLengthu?l.set(T,_):(t._normalizeValue(T,b.target,0),am({target:l,source:b.target,start:_,count:y}));_+=y*u}else t._normalizeValue(T,l,_),_+=u}}_validateAttributeUpdaters(){const{settings:t}=this;if(!(t.noAlloc||typeof t.update=="function"))throw new Error(`Attribute ${this.id} missing update or accessor`)}_checkAttributeArray(){const{value:t}=this,r=Math.min(4,this.size);if(t&&t.length>=r){let i=!0;switch(r){case 4:i=i&&Number.isFinite(t[3]);case 3:i=i&&Number.isFinite(t[2]);case 2:i=i&&Number.isFinite(t[1]);case 1:i=i&&Number.isFinite(t[0]);break;default:i=!1}if(!i)throw new Error(`Illegal attribute generated for ${this.id}`)}}}function Ii(e){const{source:t,target:r,start:i=0,size:s,getData:n}=e,o=e.end||r.length,a=t.length,c=o-i;if(a>c){r.set(t.subarray(0,c),i);return}if(r.set(t,i),!n)return;let l=a;for(;li(u+a,h)),l=Math.min(s.length,n.length);for(let u=1;ua}){const a=r.doublePrecision&&r.value instanceof Float64Array?2:1,c=r.size*a,l=r.byteOffset,u=r.settings.bytesPerElement<4?l/r.settings.bytesPerElement*4:l,h=r.startIndices,d=n&&h,g=r.isConstant;if(!d&&t&&i>=s)return t;const p=r.value instanceof Float64Array?Float32Array:r.value.constructor,_=g?r.value:new p(r.getBuffer().readSyncWebGL(l,s*p.BYTES_PER_ELEMENT).buffer);if(r.settings.normalized&&!g){const T=o;o=(y,E)=>r.normalizeConstant(T(y,E))}const m=g?(T,y)=>o(_,y):(T,y)=>o(_.subarray(T+l,T+l+c),y),b=t?new Float32Array(t.readSyncWebGL(u,i*4).buffer):new Float32Array(0),R=new Float32Array(s);return iT({source:b,target:R,sourceStartIndices:n,targetStartIndices:h,size:c,getData:m}),(!t||t.byteLength0||s.end()}delete(){super.delete(),this.transform.destroy(),this.texture.destroy(),this.framebuffer.destroy()}}const hT=`layout(std140) uniform springUniforms { + float damping; + float stiffness; +} spring; +`,dT={name:"spring",vs:hT,uniformTypes:{damping:"f32",stiffness:"f32"}},gT=`#version 300 es +#define SHADER_NAME spring-transition-vertex-shader + +#define EPSILON 0.00001 + +in ATTRIBUTE_TYPE aPrev; +in ATTRIBUTE_TYPE aCur; +in ATTRIBUTE_TYPE aTo; +out ATTRIBUTE_TYPE vNext; +out float vIsTransitioningFlag; + +ATTRIBUTE_TYPE getNextValue(ATTRIBUTE_TYPE cur, ATTRIBUTE_TYPE prev, ATTRIBUTE_TYPE dest) { + ATTRIBUTE_TYPE velocity = cur - prev; + ATTRIBUTE_TYPE delta = dest - cur; + ATTRIBUTE_TYPE force = delta * spring.stiffness; + ATTRIBUTE_TYPE resistance = velocity * spring.damping; + return force - resistance + velocity + cur; +} + +void main(void) { + bool isTransitioning = length(aCur - aPrev) > EPSILON || length(aTo - aCur) > EPSILON; + vIsTransitioningFlag = isTransitioning ? 1.0 : 0.0; + + vNext = getNextValue(aCur, aPrev, aTo); + gl_Position = vec4(0, 0, 0, 1); + gl_PointSize = 100.0; +} +`,pT=`#version 300 es +#define SHADER_NAME spring-transition-is-transitioning-fragment-shader + +in float vIsTransitioningFlag; + +out vec4 fragColor; + +void main(void) { + if (vIsTransitioningFlag == 0.0) { + discard; + } + fragColor = vec4(1.0); +}`;function _T(e,t){const r=Vc(t.size),i=Xc(t.size);return new Ot(e,{vs:gT,fs:pT,bufferLayout:[{name:"aPrev",format:i},{name:"aCur",format:i},{name:"aTo",format:t.getBufferLayout().attributes[0].format}],varyings:["vNext"],modules:[dT],defines:{ATTRIBUTE_TYPE:r},parameters:{depthCompare:"always",blendColorOperation:"max",blendColorSrcFactor:"one",blendColorDstFactor:"one",blendAlphaOperation:"max",blendAlphaSrcFactor:"one",blendAlphaDstFactor:"one"}})}function mT(e){return e.createTexture({data:new Uint8Array(4),format:"rgba8unorm",width:1,height:1})}function bT(e,t){return e.createFramebuffer({id:"spring-transition-is-transitioning-framebuffer",width:1,height:1,colorAttachments:[t]})}const TT={interpolation:oT,spring:uT};class AT{constructor(t,{id:r,timeline:i}){if(!t)throw new Error("AttributeTransitionManager is constructed without device");this.id=r,this.device=t,this.timeline=i,this.transitions={},this.needsRedraw=!1,this.numInstances=1}finalize(){for(const t in this.transitions)this._removeTransition(t)}update({attributes:t,transitions:r,numInstances:i}){this.numInstances=i||1;for(const s in t){const n=t[s],o=n.getTransitionSetting(r);o&&this._updateAttribute(s,n,o)}for(const s in this.transitions){const n=t[s];(!n||!n.getTransitionSetting(r))&&this._removeTransition(s)}}hasAttribute(t){const r=this.transitions[t];return r&&r.inProgress}getAttributes(){const t={};for(const r in this.transitions){const i=this.transitions[r];i.inProgress&&(t[r]=i.attributeInTransition)}return t}run(){if(this.numInstances===0)return!1;for(const r in this.transitions)this.transitions[r].update()&&(this.needsRedraw=!0);const t=this.needsRedraw;return this.needsRedraw=!1,t}_removeTransition(t){this.transitions[t].delete(),delete this.transitions[t]}_updateAttribute(t,r,i){const s=this.transitions[t];let n=!s||s.type!==i.type;if(n){s&&this._removeTransition(t);const o=TT[i.type];o?this.transitions[t]=new o({attribute:r,timeline:this.timeline,device:this.device}):(G.error(`unsupported transition type '${i.type}'`)(),n=!1)}(n||r.needsRedraw())&&(this.needsRedraw=!0,this.transitions[t].start(i,this.numInstances))}}const wo="attributeManager.invalidate",yT="attributeManager.updateStart",RT="attributeManager.updateEnd",ET="attribute.updateStart",ST="attribute.allocate",CT="attribute.updateEnd";class vT{constructor(t,{id:r="attribute-manager",stats:i,timeline:s}={}){this.mergeBoundsMemoized=Is(S_),this.id=r,this.device=t,this.attributes={},this.updateTriggers={},this.needsRedraw=!0,this.userData={},this.stats=i,this.attributeTransitionManager=new AT(t,{id:`${r}-transitions`,timeline:s}),Object.seal(this)}finalize(){for(const t in this.attributes)this.attributes[t].delete();this.attributeTransitionManager.finalize()}getNeedsRedraw(t={clearRedrawFlags:!1}){const r=this.needsRedraw;return this.needsRedraw=this.needsRedraw&&!t.clearRedrawFlags,r&&this.id}setNeedsRedraw(){this.needsRedraw=!0}add(t){this._add(t)}addInstanced(t){this._add(t,{stepMode:"instance"})}remove(t){for(const r of t)this.attributes[r]!==void 0&&(this.attributes[r].delete(),delete this.attributes[r])}invalidate(t,r){const i=this._invalidateTrigger(t,r);X(wo,this,t,i)}invalidateAll(t){for(const r in this.attributes)this.attributes[r].setNeedsUpdate(r,t);X(wo,this,"all")}update({data:t,numInstances:r,startIndices:i=null,transitions:s,props:n={},buffers:o={},context:a={}}){let c=!1;X(yT,this),this.stats&&this.stats.get("Update Attributes").timeStart();for(const l in this.attributes){const u=this.attributes[l],h=u.settings.accessor;u.startIndices=i,u.numInstances=r,n[l]&&G.removed(`props.${l}`,`data.attributes.${l}`)(),u.setExternalBuffer(o[l])||u.setBinaryValue(typeof h=="string"?o[h]:void 0,t.startIndices)||typeof h=="string"&&!o[h]&&u.setConstantValue(a,n[h])||u.needsUpdate()&&(c=!0,this._updateAttribute({attribute:u,numInstances:r,data:t,props:n,context:a})),this.needsRedraw=this.needsRedraw||u.needsRedraw()}c&&X(RT,this,r),this.stats&&(this.stats.get("Update Attributes").timeEnd(),c&&this.stats.get("Attributes updated").incrementCount()),this.attributeTransitionManager.update({attributes:this.attributes,numInstances:r,transitions:s})}updateTransition(){const{attributeTransitionManager:t}=this,r=t.run();return this.needsRedraw=this.needsRedraw||r,r}getAttributes(){return{...this.attributes,...this.attributeTransitionManager.getAttributes()}}getBounds(t){const r=t.map(i=>{var s;return(s=this.attributes[i])==null?void 0:s.getBounds()});return this.mergeBoundsMemoized(r)}getChangedAttributes(t={clearChangedFlags:!1}){const{attributes:r,attributeTransitionManager:i}=this,s={...i.getAttributes()};for(const n in r){const o=r[n];o.needsRedraw(t)&&!i.hasAttribute(n)&&(s[n]=o)}return s}getBufferLayouts(t){return Object.values(this.getAttributes()).map(r=>r.getBufferLayout(t))}_add(t,r){for(const i in t){const s=t[i],n={...s,id:i,size:s.isIndexed&&1||s.size||1,...r};this.attributes[i]=new Hc(this.device,n)}this._mapUpdateTriggersToAttributes()}_mapUpdateTriggersToAttributes(){const t={};for(const r in this.attributes)this.attributes[r].getUpdateTriggers().forEach(s=>{t[s]||(t[s]=[]),t[s].push(r)});this.updateTriggers=t}_invalidateTrigger(t,r){const{attributes:i,updateTriggers:s}=this,n=s[t];return n&&n.forEach(o=>{const a=i[o];a&&a.setNeedsUpdate(a.id,r)}),n}_updateAttribute(t){const{attribute:r,numInstances:i}=t;if(X(ET,r),r.constant){r.setConstantValue(t.context,r.value);return}r.allocate(i)&&X(ST,r,i),r.updateBuffer(t)&&(this.needsRedraw=!0,X(CT,r,i))}}class PT extends Ds{get value(){return this._value}_onUpdate(){const{time:t,settings:{fromValue:r,toValue:i,duration:s,easing:n}}=this,o=n(t/s);this._value=ba(r,i,o)}}const Oo=1e-5;function xo(e,t,r,i,s){const n=t-e,a=(r-t)*s,c=-n*i;return a+c+n+t}function wT(e,t,r,i,s){if(Array.isArray(r)){const n=[];for(let o=0;o0}add(t,r,i,s){const{transitions:n}=this;if(n.has(t)){const c=n.get(t),{value:l=c.settings.fromValue}=c;r=l,this.remove(t)}if(s=jc(s),!s)return;const o=xT[s.type];if(!o){G.error(`unsupported transition type '${s.type}'`)();return}const a=new o(this.timeline);a.start({...s,fromValue:r,toValue:i}),n.set(t,a)}remove(t){const{transitions:r}=this;r.has(t)&&(r.get(t).cancel(),r.delete(t))}update(){const t={};for(const[r,i]of this.transitions)i.update(),t[r]=i.value,i.inProgress||this.remove(r);return t}clear(){for(const t of this.transitions.keys())this.remove(t)}}function IT(e){const t=e[be];for(const r in t){const i=t[r],{validate:s}=i;if(s&&!s(e[r],i))throw new Error(`Invalid prop ${r}: ${e[r]}`)}}function NT(e,t){const r=Jc({newProps:e,oldProps:t,propTypes:e[be],ignoreProps:{data:null,updateTriggers:null,extensions:null,transitions:null}}),i=DT(e,t);let s=!1;return i||(s=FT(e,t)),{dataChanged:i,propsChanged:r,updateTriggersChanged:s,extensionsChanged:UT(e,t),transitionsChanged:BT(e,t)}}function BT(e,t){if(!e.transitions)return!1;const r={},i=e[be];let s=!1;for(const n in e.transitions){const o=i[n],a=o&&o.type;(a==="number"||a==="color"||a==="array")&&us(e[n],t[n],o)&&(r[n]=!0,s=!0)}return s?r:!1}function Jc({newProps:e,oldProps:t,ignoreProps:r={},propTypes:i={},triggerName:s="props"}){if(t===e)return!1;if(typeof e!="object"||e===null)return`${s} changed shallowly`;if(typeof t!="object"||t===null)return`${s} changed shallowly`;for(const n of Object.keys(e))if(!(n in r)){if(!(n in t))return`${s}.${n} added`;const o=us(e[n],t[n],i[n]);if(o)return`${s}.${n} ${o}`}for(const n of Object.keys(t))if(!(n in r)){if(!(n in e))return`${s}.${n} dropped`;if(!Object.hasOwnProperty.call(e,n)){const o=us(e[n],t[n],i[n]);if(o)return`${s}.${n} ${o}`}}return!1}function us(e,t,r){let i=r&&r.equal;return i&&!i(e,t,r)||!i&&(i=e&&t&&e.equals,i&&!i.call(e,t))?"changed deeply":!i&&t!==e?"changed shallowly":null}function DT(e,t){if(t===null)return"oldProps is null, initial diff";let r=!1;const{dataComparator:i,_dataDiff:s}=e;return i?i(e.data,t.data)||(r="Data comparator detected a change"):e.data!==t.data&&(r="A new data container was supplied"),r&&s&&(r=s(e.data,t.data)||r),r}function FT(e,t){if(t===null)return{all:!0};if("all"in e.updateTriggers&&Io(e,t,"all"))return{all:!0};const r={};let i=!1;for(const s in e.updateTriggers)s!=="all"&&Io(e,t,s)&&(r[s]=!0,i=!0);return i?r:!1}function UT(e,t){if(t===null)return!0;const r=t.extensions,{extensions:i}=e;if(i===r)return!1;if(!r||!i||i.length!==r.length)return!0;for(let s=0;si.name==="project64"))){const i=r.modules.findIndex(s=>s.name==="project32");i>=0&&r.modules.splice(i,1)}if("inject"in t)if(!e.inject)r.inject=t.inject;else{const i={...e.inject};for(const s in t.inject)i[s]=(i[s]||"")+t.inject[s];r.inject=i}return r}const jT={minFilter:"linear",mipmapFilter:"linear",magFilter:"linear",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"},hs={};function HT(e,t,r,i){if(r instanceof U)return r;r.constructor&&r.constructor.name!=="Object"&&(r={data:r});let s=null;r.compressed&&(s={minFilter:"linear",mipmapFilter:r.data.length>1?"nearest":"linear"});const{width:n,height:o}=r.data,a=t.createTexture({...r,sampler:{...jT,...s,...i},mipLevels:t.getMipLevelCount(n,o)});return t.type==="webgl"?a.generateMipmapsWebGL():t.type==="webgpu"&&t.generateMipmapsWebGPU(a),hs[a.id]=e,a}function VT(e,t){!t||!(t instanceof U)||hs[t.id]===e&&(t.delete(),delete hs[t.id])}const XT={boolean:{validate(e,t){return!0},equal(e,t,r){return!!e==!!t}},number:{validate(e,t){return Number.isFinite(e)&&(!("max"in t)||e<=t.max)&&(!("min"in t)||e>=t.min)}},color:{validate(e,t){return t.optional&&!e||ds(e)&&(e.length===3||e.length===4)},equal(e,t,r){return ze(e,t,1)}},accessor:{validate(e,t){const r=Er(e);return r==="function"||r===Er(t.value)},equal(e,t,r){return typeof t=="function"?!0:ze(e,t,1)}},array:{validate(e,t){return t.optional&&!e||ds(e)},equal(e,t,r){const{compare:i}=r,s=Number.isInteger(i)?i:i?1:0;return i?ze(e,t,s):e===t}},object:{equal(e,t,r){if(r.ignore)return!0;const{compare:i}=r,s=Number.isInteger(i)?i:i?1:0;return i?ze(e,t,s):e===t}},function:{validate(e,t){return t.optional&&!e||typeof e=="function"},equal(e,t,r){return!r.compare&&r.ignore!==!1||e===t}},data:{transform:(e,t,r)=>{if(!e)return e;const{dataTransform:i}=r.props;return i?i(e):typeof e.shape=="string"&&e.shape.endsWith("-table")&&Array.isArray(e.data)?e.data:e}},image:{transform:(e,t,r)=>{const i=r.context;return!i||!i.device?null:HT(r.id,i.device,e,{...t.parameters,...r.props.textureParameters})},release:(e,t,r)=>{VT(r.id,e)}}};function YT(e){const t={},r={},i={};for(const[s,n]of Object.entries(e)){const o=n==null?void 0:n.deprecatedFor;if(o)i[s]=Array.isArray(o)?o:[o];else{const a=KT(s,n);t[s]=a,r[s]=a.value}}return{propTypes:t,defaultProps:r,deprecatedProps:i}}function KT(e,t){switch(Er(t)){case"object":return dt(e,t);case"array":return dt(e,{type:"array",value:t,compare:!1});case"boolean":return dt(e,{type:"boolean",value:t});case"number":return dt(e,{type:"number",value:t});case"function":return dt(e,{type:"function",value:t,compare:!0});default:return{name:e,type:"unknown",value:t}}}function dt(e,t){return"type"in t?{name:e,...XT[t.type],...t}:"value"in t?{name:e,type:Er(t.value),...t}:{name:e,type:"object",value:t}}function ds(e){return Array.isArray(e)||ArrayBuffer.isView(e)}function Er(e){return ds(e)?"array":e===null?"null":typeof e}function QT(e,t){let r;for(let n=t.length-1;n>=0;n--){const o=t[n];"extensions"in o&&(r=o.extensions)}const i=gs(e.constructor,r),s=Object.create(i);s[yr]=e,s[Ie]={},s[me]={};for(let n=0;n{},this.oldProps=null,this.oldAsyncProps=null}finalize(){for(const t in this.asyncProps){const r=this.asyncProps[t];r&&r.type&&r.type.release&&r.type.release(r.resolvedValue,r.type,this.component)}this.asyncProps={},this.component=null,this.resetOldProps()}getOldProps(){return this.oldAsyncProps||this.oldProps||sA}resetOldProps(){this.oldAsyncProps=null,this.oldProps=this.component?this.component.props:null}hasAsyncProp(t){return t in this.asyncProps}getAsyncProp(t){const r=this.asyncProps[t];return r&&r.resolvedValue}isAsyncPropLoading(t){if(t){const r=this.asyncProps[t];return!!(r&&r.pendingLoadCount>0&&r.pendingLoadCount!==r.resolvedLoadCount)}for(const r in this.asyncProps)if(this.isAsyncPropLoading(r))return!0;return!1}reloadAsyncProp(t,r){this._watchPromise(t,Promise.resolve(r))}setAsyncProps(t){this.component=t[yr]||this.component;const r=t[me]||{},i=t[Ie]||t,s=t[Qe]||{};for(const n in r){const o=r[n];this._createAsyncPropData(n,s[n]),this._updateAsyncProp(n,o),r[n]=this.getAsyncProp(n)}for(const n in i){const o=i[n];this._createAsyncPropData(n,s[n]),this._updateAsyncProp(n,o)}}_fetch(t,r){return null}_onResolve(t,r){}_onError(t,r){}_updateAsyncProp(t,r){if(this._didAsyncInputValueChange(t,r)){if(typeof r=="string"&&(r=this._fetch(t,r)),r instanceof Promise){this._watchPromise(t,r);return}if($c(r)){this._resolveAsyncIterable(t,r);return}this._setPropValue(t,r)}}_freezeAsyncOldProps(){if(!this.oldAsyncProps&&this.oldProps){this.oldAsyncProps=Object.create(this.oldProps);for(const t in this.asyncProps)Object.defineProperty(this.oldAsyncProps,t,{enumerable:!0,value:this.oldProps[t]})}}_didAsyncInputValueChange(t,r){const i=this.asyncProps[t];return r===i.resolvedValue||r===i.lastValue?!1:(i.lastValue=r,!0)}_setPropValue(t,r){this._freezeAsyncOldProps();const i=this.asyncProps[t];i&&(r=this._postProcessValue(i,r),i.resolvedValue=r,i.pendingLoadCount++,i.resolvedLoadCount=i.pendingLoadCount)}_setAsyncPropValue(t,r,i){const s=this.asyncProps[t];s&&i>=s.resolvedLoadCount&&r!==void 0&&(this._freezeAsyncOldProps(),s.resolvedValue=r,s.resolvedLoadCount=i,this.onAsyncPropUpdated(t,r))}_watchPromise(t,r){const i=this.asyncProps[t];if(i){i.pendingLoadCount++;const s=i.pendingLoadCount;r.then(n=>{this.component&&(n=this._postProcessValue(i,n),this._setAsyncPropValue(t,n,s),this._onResolve(t,n))}).catch(n=>{this._onError(t,n)})}}async _resolveAsyncIterable(t,r){if(t!=="data"){this._setPropValue(t,r);return}const i=this.asyncProps[t];if(!i)return;i.pendingLoadCount++;const s=i.pendingLoadCount;let n=[],o=0;for await(const a of r){if(!this.component)return;const{dataTransform:c}=this.component.props;c?n=c(a,n):n=n.concat(a),Object.defineProperty(n,"__diff",{enumerable:!1,value:[{startRow:o,endRow:n.length}]}),o=n.length,this._setAsyncPropValue(t,n,s)}this._onResolve(t,n)}_postProcessValue(t,r){const i=t.type;return i&&this.component&&(i.release&&i.release(t.resolvedValue,i,this.component),i.transform)?i.transform(r,i,this.component):r}_createAsyncPropData(t,r){if(!this.asyncProps[t]){const s=this.component&&this.component.props[be];this.asyncProps[t]={type:s&&s[t],lastValue:null,resolvedValue:r,pendingLoadCount:0,resolvedLoadCount:0}}}}class oA extends nA{constructor({attributeManager:t,layer:r}){super(r),this.attributeManager=t,this.needsRedraw=!0,this.needsUpdate=!0,this.subLayers=null,this.usesPickingColorCache=!1}get layer(){return this.component}_fetch(t,r){const i=this.layer,s=i==null?void 0:i.props.fetch;return s?s(r,{propName:t,layer:i}):super._fetch(t,r)}_onResolve(t,r){const i=this.layer;if(i){const s=i.props.onDataLoad;t==="data"&&s&&s(r,{propName:t,layer:i})}}_onError(t,r){const i=this.layer;i&&i.raiseError(r,`loading ${t} of ${this.layer}`)}}const aA="layer.changeFlag",cA="layer.initialize",lA="layer.update",fA="layer.finalize",uA="layer.matched",Bo=2**24-1,hA=Object.freeze([]),dA=Is(({oldViewport:e,viewport:t})=>e.equals(t));let ee=new Uint8ClampedArray(0);const gA={data:{type:"data",value:hA,async:!0},dataComparator:{type:"function",value:null,optional:!0},_dataDiff:{type:"function",value:e=>e&&e.__diff,optional:!0},dataTransform:{type:"function",value:null,optional:!0},onDataLoad:{type:"function",value:null,optional:!0},onError:{type:"function",value:null,optional:!0},fetch:{type:"function",value:(e,{propName:t,layer:r,loaders:i,loadOptions:s,signal:n})=>{var c;const{resourceManager:o}=r.context;s=s||r.getLoadOptions(),i=i||r.props.loaders,n&&(s={...s,core:{...s==null?void 0:s.core,fetch:{...(c=s==null?void 0:s.core)==null?void 0:c.fetch,signal:n}}});let a=o.contains(e);return!a&&!s&&(o.add({resourceId:e,data:an(e,i),persistent:!1}),a=!0),a?o.subscribe({resourceId:e,onChange:l=>{var u;return(u=r.internalState)==null?void 0:u.reloadAsyncProp(t,l)},consumerId:r.id,requestId:t}):an(e,i,s)}},updateTriggers:{},visible:!0,pickable:!1,opacity:{type:"number",min:0,max:1,value:1},operation:"draw",onHover:{type:"function",value:null,optional:!0},onClick:{type:"function",value:null,optional:!0},onDragStart:{type:"function",value:null,optional:!0},onDrag:{type:"function",value:null,optional:!0},onDragEnd:{type:"function",value:null,optional:!0},coordinateSystem:"default",coordinateOrigin:{type:"array",value:[0,0,0],compare:!0},modelMatrix:{type:"array",value:null,compare:!0,optional:!0},wrapLongitude:!1,positionFormat:"XYZ",colorFormat:"RGBA",parameters:{type:"object",value:{},optional:!0,compare:2},loadOptions:{type:"object",value:null,optional:!0,ignore:!0},transitions:null,extensions:[],loaders:{type:"array",value:[],optional:!0,ignore:!0},getPolygonOffset:{type:"function",value:({layerIndex:e})=>[0,-e*100]},highlightedObjectIndex:null,autoHighlight:!1,highlightColor:{type:"accessor",value:[0,0,128,128]}};class $s extends Kr{constructor(){super(...arguments),this.internalState=null,this.lifecycle=nm.NO_STATE,this.parent=null}static get componentName(){return Object.prototype.hasOwnProperty.call(this,"layerName")?this.layerName:""}get root(){let t=this;for(;t.parent;)t=t.parent;return t}toString(){return`${this.constructor.layerName||this.constructor.name}({id: '${this.props.id}'})`}project(t){pe(this.internalState);const r=this.internalState.viewport||this.context.viewport,i=Bs(t,{viewport:r,modelMatrix:this.props.modelMatrix,coordinateOrigin:this.props.coordinateOrigin,coordinateSystem:this.props.coordinateSystem}),[s,n,o]=uc(i,r.pixelProjectionMatrix);return t.length===2?[s,n]:[s,n,o]}unproject(t){return pe(this.internalState),(this.internalState.viewport||this.context.viewport).unproject(t)}projectPosition(t,r){pe(this.internalState);const i=this.internalState.viewport||this.context.viewport;return x_(t,{viewport:i,modelMatrix:this.props.modelMatrix,coordinateOrigin:this.props.coordinateOrigin,coordinateSystem:this.props.coordinateSystem,...r})}get isComposite(){return!1}get isDrawable(){return!0}setState(t){this.setChangeFlags({stateChanged:!0}),Object.assign(this.state,t),this.setNeedsRedraw()}setNeedsRedraw(){this.internalState&&(this.internalState.needsRedraw=!0)}setNeedsUpdate(){this.internalState&&(this.context.layerManager.setNeedsUpdate(String(this)),this.internalState.needsUpdate=!0)}get isLoaded(){return this.internalState?!this.internalState.isAsyncPropLoading():!1}get wrapLongitude(){return this.props.wrapLongitude}isPickable(){return this.props.pickable&&this.props.visible}getModels(){const t=this.state;return t&&(t.models||t.model&&[t.model])||[]}setShaderModuleProps(...t){for(const r of this.getModels())r.shaderInputs.setProps(...t)}getAttributeManager(){return this.internalState&&this.internalState.attributeManager}getCurrentLayer(){return this.internalState&&this.internalState.layer}getLoadOptions(){return this.props.loadOptions}use64bitPositions(){const{coordinateSystem:t}=this.props;return t==="default"||t==="lnglat"||t==="cartesian"}onHover(t,r){return this.props.onHover&&this.props.onHover(t,r)||!1}onClick(t,r){return this.props.onClick&&this.props.onClick(t,r)||!1}nullPickingColor(){return[0,0,0]}encodePickingColor(t,r=[]){return r[0]=t+1&255,r[1]=t+1>>8&255,r[2]=t+1>>8>>8&255,r}decodePickingColor(t){pe(t instanceof Uint8Array);const[r,i,s]=t;return r+i*256+s*65536-1}getNumInstances(){return Number.isFinite(this.props.numInstances)?this.props.numInstances:this.state&&this.state.numInstances!==void 0?this.state.numInstances:WT(this.props.data)}getStartIndices(){return this.props.startIndices?this.props.startIndices:this.state&&this.state.startIndices?this.state.startIndices:null}getBounds(){var t;return(t=this.getAttributeManager())==null?void 0:t.getBounds(["positions","instancePositions"])}getShaders(t){t=No(t,{disableWarnings:!0,modules:this.context.defaultShaderModules});for(const r of this.props.extensions)t=No(t,r.getShaders.call(this,r));return t}shouldUpdateState(t){return t.changeFlags.propsOrDataChanged}updateState(t){const r=this.getAttributeManager(),{dataChanged:i}=t.changeFlags;if(i&&r)if(Array.isArray(i))for(const s of i)r.invalidateAll(s);else r.invalidateAll();if(r){const{props:s}=t,n=this.internalState.hasPickingBuffer,o=Number.isInteger(s.highlightedObjectIndex)||!!s.pickable||s.extensions.some(a=>a.getNeedsPickingBuffer.call(this,a));if(n!==o){this.internalState.hasPickingBuffer=o;const{pickingColors:a,instancePickingColors:c}=r.attributes,l=a||c;l&&(o&&l.constant&&(l.constant=!1,r.invalidate(l.id)),!l.value&&!o&&(l.constant=!0,l.value=[0,0,0]))}}}finalizeState(t){for(const i of this.getModels())i.destroy();const r=this.getAttributeManager();r&&r.finalize(),this.context&&this.context.resourceManager.unsubscribe({consumerId:this.id}),this.internalState&&(this.internalState.uniformTransitions.clear(),this.internalState.finalize())}draw(t){for(const r of this.getModels())r.draw(t.renderPass)}getPickingInfo({info:t,mode:r,sourceLayer:i}){const{index:s}=t;return s>=0&&Array.isArray(this.props.data)&&(t.object=this.props.data[s]),t}raiseError(t,r){var i,s,n,o;r&&(t=new Error(`${r}: ${t.message}`,{cause:t})),(s=(i=this.props).onError)!=null&&s.call(i,t)||(o=(n=this.context)==null?void 0:n.onError)==null||o.call(n,t,this)}getNeedsRedraw(t={clearRedrawFlags:!1}){return this._getNeedsRedraw(t)}needsUpdate(){return this.internalState?this.internalState.needsUpdate||this.hasUniformTransition()||this.shouldUpdateState(this._getUpdateParams()):!1}hasUniformTransition(){var t;return((t=this.internalState)==null?void 0:t.uniformTransitions.active)||!1}activateViewport(t){if(!this.internalState)return;const r=this.internalState.viewport;this.internalState.viewport=t,(!r||!dA({oldViewport:r,viewport:t}))&&(this.setChangeFlags({viewportChanged:!0}),this.isComposite?this.needsUpdate()&&this.setNeedsUpdate():this._update())}invalidateAttribute(t="all"){const r=this.getAttributeManager();r&&(t==="all"?r.invalidateAll():r.invalidate(t))}updateAttributes(t){let r=!1;for(const i in t)t[i].layoutChanged()&&(r=!0);for(const i of this.getModels())this._setModelAttributes(i,t,r)}_updateAttributes(){const t=this.getAttributeManager();if(!t)return;const r=this.props,i=this.getNumInstances(),s=this.getStartIndices();t.update({data:r.data,numInstances:i,startIndices:s,props:r,transitions:r.transitions,buffers:r.data.attributes,context:this});const n=t.getChangedAttributes({clearChangedFlags:!0});this.updateAttributes(n)}_updateAttributeTransition(){const t=this.getAttributeManager();t&&t.updateTransition()}_updateUniformTransition(){const{uniformTransitions:t}=this.internalState;if(t.active){const r=t.update(),i=Object.create(this.props);for(const s in r)Object.defineProperty(i,s,{value:r[s]});return i}return this.props}calculateInstancePickingColors(t,{numInstances:r}){if(t.constant)return;const i=Math.floor(ee.length/4);if(this.internalState.usesPickingColorCache=!0,iBo&&G.warn("Layer has too many data objects. Picking might not be able to distinguish all objects.")(),ee=Pt.allocate(ee,r,{size:4,copy:!0,maxCount:Math.max(r,Bo)});const s=Math.floor(ee.length/4),n=[0,0,0];for(let o=i;o(G.deprecated("layer.state.attributeManager","layer.getAttributeManager()")(),t)}),this.internalState.uniformTransitions=new MT(this.context.timeline),this.internalState.onAsyncPropUpdated=this._onAsyncPropUpdated.bind(this),this.internalState.setAsyncProps(this.props),this.initializeState(this.context);for(const r of this.props.extensions)r.initializeState.call(this,this.context,r);this.setChangeFlags({dataChanged:"init",propsChanged:"init",viewportChanged:!0,extensionsChanged:!0}),this._update()}_transferState(t){X(uA,this,this===t);const{state:r,internalState:i}=t;this!==t&&(this.internalState=i,this.state=r,this.internalState.setAsyncProps(this.props),this._diffProps(this.props,this.internalState.getOldProps()))}_update(){const t=this.needsUpdate();if(X(lA,this,t),!t)return;this.context.stats.get("Layer updates").incrementCount();const r=this.props,i=this.context,s=this.internalState,n=i.viewport,o=this._updateUniformTransition();s.propsInTransition=o,i.viewport=s.viewport||n,this.props=o;try{const a=this._getUpdateParams(),c=this.getModels();if(i.device)this.updateState(a);else try{this.updateState(a)}catch{}for(const u of this.props.extensions)u.updateState.call(this,a,u);this.setNeedsRedraw(),this._updateAttributes();const l=this.getModels()[0]!==c[0];this._postUpdate(a,l)}finally{i.viewport=n,this.props=r,this._clearChangeFlags(),s.needsUpdate=!1,s.resetOldProps()}}_finalize(){X(fA,this),this.finalizeState(this.context);for(const t of this.props.extensions)t.finalizeState.call(this,this.context,t)}_drawLayer({renderPass:t,shaderModuleProps:r=null,uniforms:i={},parameters:s={}}){this._updateAttributeTransition();const n=this.props,o=this.context;this.props=this.internalState.propsInTransition||n;try{r&&this.setShaderModuleProps(r);const{getPolygonOffset:a}=this.props,c=a&&a(i)||[0,0];o.device instanceof Oe&&o.device.setParametersWebGL({polygonOffset:c});const l=o.device instanceof Oe?null:pA(s);if(_A(this.getModels(),t,s,l),o.device instanceof Oe)o.device.withParametersWebGL(s,()=>{const u={renderPass:t,shaderModuleProps:r,uniforms:i,parameters:s,context:o};for(const h of this.props.extensions)h.draw.call(this,u,h);this.draw(u)});else{l!=null&&l.renderPassParameters&&t.setParameters(l.renderPassParameters);const u={renderPass:t,shaderModuleProps:r,uniforms:i,parameters:s,context:o};for(const h of this.props.extensions)h.draw.call(this,u,h);this.draw(u)}}finally{this.props=n}}getChangeFlags(){var t;return(t=this.internalState)==null?void 0:t.changeFlags}setChangeFlags(t){if(!this.internalState)return;const{changeFlags:r}=this.internalState;for(const s in t)if(t[s]){let n=!1;switch(s){case"dataChanged":const o=t[s],a=r[s];o&&Array.isArray(a)&&(r.dataChanged=Array.isArray(o)?a.concat(o):o,n=!0);default:r[s]||(r[s]=t[s],n=!0)}n&&X(aA,this,s,t)}const i=!!(r.dataChanged||r.updateTriggersChanged||r.propsChanged||r.extensionsChanged);r.propsOrDataChanged=i,r.somethingChanged=i||r.viewportChanged||r.stateChanged}_clearChangeFlags(){this.internalState.changeFlags={dataChanged:!1,propsChanged:!1,updateTriggersChanged:!1,viewportChanged:!1,stateChanged:!1,extensionsChanged:!1,propsOrDataChanged:!1,somethingChanged:!1}}_diffProps(t,r){var s;const i=NT(t,r);if(i.updateTriggersChanged)for(const n in i.updateTriggersChanged)i.updateTriggersChanged[n]&&this.invalidateAttribute(n);if(i.transitionsChanged)for(const n in i.transitionsChanged)this.internalState.uniformTransitions.add(n,r[n],t[n],(s=t.transitions)==null?void 0:s[n]);return this.setChangeFlags(i)}validateProps(){IT(this.props)}updateAutoHighlight(t){this.props.autoHighlight&&!Number.isInteger(this.props.highlightedObjectIndex)&&this._updateAutoHighlight(t)}_updateAutoHighlight(t){const r={highlightedObjectColor:t.picked?t.color:null},{highlightColor:i}=this.props;t.picked&&typeof i=="function"&&(r.highlightColor=i(t)),this.setShaderModuleProps({picking:r}),this.setNeedsRedraw()}_getAttributeManager(){const t=this.context;return new vT(t.device,{id:this.props.id,stats:t.stats,timeline:t.timeline})}_postUpdate(t,r){const{props:i,oldProps:s}=t,n=this.state.model;n!=null&&n.isInstanced&&n.setInstanceCount(this.getNumInstances());const{autoHighlight:o,highlightedObjectIndex:a,highlightColor:c}=i;if(r||s.autoHighlight!==o||s.highlightedObjectIndex!==a||s.highlightColor!==c){const l={};Array.isArray(c)&&(l.highlightColor=c),(r||s.autoHighlight!==o||a!==s.highlightedObjectIndex)&&(l.highlightedObjectColor=Number.isFinite(a)&&a>=0?this.encodePickingColor(a):null),this.setShaderModuleProps({picking:l})}}_getUpdateParams(){return{props:this.props,oldProps:this.internalState.getOldProps(),context:this.context,changeFlags:this.internalState.changeFlags}}_getNeedsRedraw(t){if(!this.internalState)return!1;let r=!1;r=r||this.internalState.needsRedraw&&this.id;const i=this.getAttributeManager(),s=i?i.getNeedsRedraw(t):!1;if(r=r||s,r)for(const n of this.props.extensions)n.onNeedsRedraw.call(this,n);return this.internalState.needsRedraw=this.internalState.needsRedraw&&!t.clearRedrawFlags,r}_onAsyncPropUpdated(){this._diffProps(this.props,this.internalState.getOldProps()),this.setNeedsUpdate()}}$s.defaultProps=gA;$s.layerName="Layer";function pA(e){const{blendConstant:t,...r}=e;return t?{pipelineParameters:r,renderPassParameters:{blendConstant:t}}:{pipelineParameters:r}}function _A(e,t,r,i){for(const s of e)s.device.type==="webgpu"?(mA(s,t),s.setParameters({...s.parameters,...i==null?void 0:i.pipelineParameters})):s.setParameters(r)}function mA(e,t){var o,a;const r=t.props.framebuffer||(t.framebuffer??null);if(!r)return;const i=r.colorAttachments.map(c=>{var l;return((l=c==null?void 0:c.texture)==null?void 0:l.format)??null}),s=(a=(o=r.depthStencilAttachment)==null?void 0:o.texture)==null?void 0:a.format,n=e;(!bA(n.props.colorAttachmentFormats,i)||n.props.depthStencilAttachmentFormat!==s)&&(n.props.colorAttachmentFormats=i,n.props.depthStencilAttachmentFormat=s,n._setPipelineNeedsUpdate("attachment formats"))}function bA(e,t){if(e===t)return!0;if(!e||!t||e.length!==t.length)return!1;for(let r=0;rt.isLoaded)}getSubLayers(){return this.internalState&&this.internalState.subLayers||[]}initializeState(t){}setState(t){super.setState(t),this.setNeedsUpdate()}getPickingInfo({info:t}){const{object:r}=t;return r&&r.__source&&r.__source.parent&&r.__source.parent.id===this.id&&(t.object=r.__source.object,t.index=r.__source.index),t}filterSubLayer(t){return!0}shouldRenderSubLayer(t,r){return r&&r.length}getSubLayerClass(t,r){const{_subLayerProps:i}=this.props;return i&&i[t]&&i[t].type||r}getSubLayerRow(t,r,i){return t.__source={parent:this,object:r,index:i},t}getSubLayerAccessor(t){if(typeof t=="function"){const r={index:-1,data:this.props.data,target:[]};return(i,s)=>i&&i.__source?(r.index=i.__source.index,t(i.__source.object,r)):t(i,s)}return t}getSubLayerProps(t={}){var C;const{opacity:r,pickable:i,visible:s,parameters:n,getPolygonOffset:o,highlightedObjectIndex:a,autoHighlight:c,highlightColor:l,coordinateSystem:u,coordinateOrigin:h,wrapLongitude:d,positionFormat:g,modelMatrix:p,extensions:_,fetch:m,operation:b,_subLayerProps:R}=this.props,T={id:"",updateTriggers:{},opacity:r,pickable:i,visible:s,parameters:n,getPolygonOffset:o,highlightedObjectIndex:a,autoHighlight:c,highlightColor:l,coordinateSystem:u,coordinateOrigin:h,wrapLongitude:d,positionFormat:g,modelMatrix:p,extensions:_,fetch:m,operation:b},y=R&&t.id&&R[t.id],E=y&&y.updateTriggers,S=t.id||"sublayer";if(y){const v=this.props[be],w=t.type?t.type._propTypes:{};for(const x in y){const B=w[x]||v[x];B&&B.type==="accessor"&&(y[x]=this.getSubLayerAccessor(y[x]))}}Object.assign(T,t,y),T.id=`${this.props.id}-${S}`,T.updateTriggers={all:(C=this.props.updateTriggers)==null?void 0:C.all,...t.updateTriggers,...E};for(const v of _){const w=v.getSubLayerProps.call(this,v);w&&Object.assign(T,w,{updateTriggers:Object.assign(T.updateTriggers,w.updateTriggers)})}return T}_updateAutoHighlight(t){for(const r of this.getSubLayers())r.updateAutoHighlight(t)}_getAttributeManager(){return null}_postUpdate(t,r){let i=this.internalState.subLayers;const s=!i||this.needsUpdate();if(s){const n=this.renderLayers();i=om(n,Boolean),this.internalState.subLayers=i}X(TA,this,s,i);for(const n of i)n.parent=this}}AA.layerName="CompositeLayer";class qA{constructor(t){this.indexStarts=[0],this.vertexStarts=[0],this.vertexCount=0,this.instanceCount=0;const{attributes:r={}}=t;this.typedArrayManager=Pt,this.attributes={},this._attributeDefs=r,this.opts=t,this.updateGeometry(t)}updateGeometry(t){Object.assign(this.opts,t);const{data:r,buffers:i={},getGeometry:s,geometryBuffer:n,positionFormat:o,dataChanged:a,normalize:c=!0}=this.opts;if(this.data=r,this.getGeometry=s,this.positionSize=n&&n.size||(o==="XY"?2:3),this.buffers=i,this.normalize=c,n&&(pe(r.startIndices),this.getGeometry=this.getGeometryFromBuffer(n),c||(i.vertexPositions=n)),this.geometryBuffer=i.vertexPositions,Array.isArray(a))for(const l of a)this._rebuildGeometry(l);else this._rebuildGeometry()}updatePartialGeometry({startRow:t,endRow:r}){this._rebuildGeometry({startRow:t,endRow:r})}getGeometryFromBuffer(t){const r=t.value||t;return ArrayBuffer.isView(r)?zc(r,{size:this.positionSize,offset:t.offset,stride:t.stride,startIndices:this.data.startIndices}):null}_allocate(t,r){const{attributes:i,buffers:s,_attributeDefs:n,typedArrayManager:o}=this;for(const a in n)if(a in s)o.release(i[a]),i[a]=null;else{const c=n[a];c.copy=r,i[a]=o.allocate(i[a],t,c)}}_forEachGeometry(t,r,i){const{data:s,getGeometry:n}=this,{iterable:o,objectInfo:a}=Wc(s,r,i);for(const c of o){a.index++;const l=n?n(c,a):null;t(l,a.index)}}_rebuildGeometry(t){if(!this.data)return;let{indexStarts:r,vertexStarts:i,instanceCount:s}=this;const{data:n,geometryBuffer:o}=this,{startRow:a=0,endRow:c=1/0}=t||{},l={};if(t||(r=[0],i=[0]),this.normalize||!o)this._forEachGeometry((h,d)=>{const g=h&&this.normalizeGeometry(h);l[d]=g,i[d+1]=i[d]+(g?this.getGeometrySize(g):0)},a,c),s=i[i.length-1];else if(i=n.startIndices,s=i[n.length]||0,ArrayBuffer.isView(o))s=s||o.length/this.positionSize;else if(o instanceof N){const h=this.positionSize*4;s=s||o.byteLength/h}else if(o.buffer){const h=o.stride||this.positionSize*4;s=s||o.buffer.byteLength/h}else if(o.value){const h=o.value,d=o.stride/h.BYTES_PER_ELEMENT||this.positionSize;s=s||h.length/d}this._allocate(s,!!t),this.indexStarts=r,this.vertexStarts=i,this.instanceCount=s;const u={};this._forEachGeometry((h,d)=>{const g=l[d]||h;u.vertexStart=i[d],u.indexStart=r[d];const p=d Date: Sun, 3 May 2026 15:45:53 +0000 Subject: [PATCH 3/7] fix(auth): allow_unauthenticated bypass actually grants /api access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When `mcp.auth.mode=none` AND `allow_unauthenticated=true`, the filter used to call chain.doFilter(...) without setting an Authentication on the SecurityContext. The SecurityFilterChain has .requestMatchers("/api/**", "/mcp/**", "/actuator/**").authenticated() .anonymous().disable() so requests reaching the controllers without a Principal were rejected with 403 — the "unauthenticated" escape hatch was inert. Bypass branch now installs a fake PreAuthenticatedAuthenticationToken with role ROLE_MCP_CLIENT (mirroring the bearer-success path) and clears the context in finally, so the chain's authenticated() rule passes. Behavioural impact only when allow_unauthenticated=true; bearer mode unaffected. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../iq/config/security/BearerAuthFilter.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/github/randomcodespace/iq/config/security/BearerAuthFilter.java b/src/main/java/io/github/randomcodespace/iq/config/security/BearerAuthFilter.java index 508feee4..8e17106b 100644 --- a/src/main/java/io/github/randomcodespace/iq/config/security/BearerAuthFilter.java +++ b/src/main/java/io/github/randomcodespace/iq/config/security/BearerAuthFilter.java @@ -75,10 +75,21 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { if (!tokenResolver.isAuthRequired()) { - // mode=none with allow_unauthenticated=true. Pass through; the - // SecurityFilterChain's authorizeHttpRequests rules still apply, - // but anonymous principals will satisfy permitAll endpoints only. - chain.doFilter(request, response); + // mode=none with allow_unauthenticated=true. Set a fake + // authenticated principal so /api/**, /mcp/**, /actuator/** + // (all `.authenticated()` in SecurityConfig) actually pass. + // Without this, the bypass branch is inert because the chain + // still requires a Principal and `.anonymous()` is disabled. + var auth = new PreAuthenticatedAuthenticationToken( + "anonymous-mcp-client", "N/A", + List.of(new SimpleGrantedAuthority("ROLE_MCP_CLIENT"))); + auth.setAuthenticated(true); + SecurityContextHolder.getContext().setAuthentication(auth); + try { + chain.doFilter(request, response); + } finally { + SecurityContextHolder.clearContext(); + } return; } From aaf7160f6fd802d2611834779113eb378c1357a9 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Sun, 3 May 2026 15:46:07 +0000 Subject: [PATCH 4/7] feat(auth)!: default mcp.auth.mode=none with allow_unauthenticated=true MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Built-in defaults now produce a server that starts unauthenticated out of the box. The fail-fast safety valve still works: explicitly setting mcp.auth.allow_unauthenticated=false in codeiq.yml (or env) makes mode=none refuse to start under the serving profile. ConfigDefaults previously emitted new McpAuthConfig("none", "CODEIQ_MCP_TOKEN", null, null) which evaluated to allowUnauthenticated=false at runtime; combined with TokenResolver's serving-profile gate, this hard-failed every fresh install on `codeiq serve`. Operators wanting auth in production opt in explicitly via mode=bearer (and CODEIQ_MCP_TOKEN env var). McpAuthConfig javadoc updated to document the new default semantics: allow_unauthenticated is now an opt-in *harden* flag (set false to reject mode=none) rather than an opt-in *escape hatch*. BREAKING (defaults): a fresh install no longer prompts for or enforces a token. Upgraded deployments that already set mode=bearer in codeiq.yml are unaffected. To preserve the prior fail-fast behaviour, set mcp.auth.allow_unauthenticated: false explicitly. Tests: TokenResolverTest, ConfigDefaultsTest, ServingChainIntegrationTest, UnifiedConfigAdapterTest — 27/27 pass. Full suite: 3706 / 0 / 32. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../iq/config/unified/ConfigDefaults.java | 7 ++++++- .../iq/config/unified/McpAuthConfig.java | 19 ++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/main/java/io/github/randomcodespace/iq/config/unified/ConfigDefaults.java b/src/main/java/io/github/randomcodespace/iq/config/unified/ConfigDefaults.java index 4ebdf158..beea1207 100644 --- a/src/main/java/io/github/randomcodespace/iq/config/unified/ConfigDefaults.java +++ b/src/main/java/io/github/randomcodespace/iq/config/unified/ConfigDefaults.java @@ -40,7 +40,12 @@ public static CodeIqUnifiedConfig builtIn() { true, "http", "/mcp", - new McpAuthConfig("none", "CODEIQ_MCP_TOKEN", null, null), + // Default: no auth out of the box. Operators opt into + // bearer for production by setting mcp.auth.mode=bearer + // (and providing a token via CODEIQ_MCP_TOKEN env var or + // mcp.auth.token). Setting mode=none + allow_unauthenticated=false + // explicitly remains a fail-fast safety valve — see TokenResolver. + new McpAuthConfig("none", "CODEIQ_MCP_TOKEN", null, Boolean.TRUE), new McpLimitsConfig(15_000, 500, 2_000_000L, 300, 10), new McpToolsConfig(List.of("*"), List.of()) ), diff --git a/src/main/java/io/github/randomcodespace/iq/config/unified/McpAuthConfig.java b/src/main/java/io/github/randomcodespace/iq/config/unified/McpAuthConfig.java index efeb7b41..de82aaa9 100644 --- a/src/main/java/io/github/randomcodespace/iq/config/unified/McpAuthConfig.java +++ b/src/main/java/io/github/randomcodespace/iq/config/unified/McpAuthConfig.java @@ -5,19 +5,24 @@ * *

{@code mode} selects the authentication scheme. Supported values: *

    - *
  • {@code none} — no auth. Permitted only outside the {@code serving} profile, - * OR with {@code allowUnauthenticated=true} (logs a startup warning). Production - * deploys (serving profile) with {@code mode=none} fail-fast at startup.
  • - *
  • {@code bearer} — opaque bearer token. Source priority: {@code CODEIQ_MCP_TOKEN} - * env var > {@code token} field below > startup failure.
  • + *
  • {@code none} — no auth. Default. Built-in defaults set + * {@code allowUnauthenticated=true} so the server starts unauthenticated + * out of the box. Operators who want hard-fail can override + * {@code mcp.auth.allow_unauthenticated: false} explicitly; the resolver + * will then refuse to start under the {@code serving} profile.
  • + *
  • {@code bearer} — opaque bearer token. Recommended for production. + * Source priority: {@code CODEIQ_MCP_TOKEN} env var > {@code token} field + * below > startup failure.
  • *
  • {@code mtls} — reserved; not yet wired (tracked under follow-up).
  • *
* *

{@code tokenEnv} is the env-var name to read the token from (defaults to * {@code CODEIQ_MCP_TOKEN} when null). {@code token} is a fallback in-config token — * not recommended for production (use the env var + a Kubernetes Secret); allowed for - * local development. {@code allowUnauthenticated} is the explicit escape hatch for - * {@code mode=none} in serving — must be set deliberately. + * local development. {@code allowUnauthenticated} is the explicit acknowledgement + * flag for {@code mode=none} in serving — defaulted to {@code true} via + * {@code ConfigDefaults} so a fresh install just works; override to {@code false} + * to make {@code mode=none} a fail-fast misconfiguration in serving. */ public record McpAuthConfig( String mode, From 33914224912dfba441252ff80df0beb602167255 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Sun, 3 May 2026 15:46:24 +0000 Subject: [PATCH 5/7] feat(messaging): Apache ActiveMQ Classic + Artemis detector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds io.github.randomcodespace.iq.detector.jvm.java.ActiveMqDetector covering both ActiveMQ Classic (org.apache.activemq.*) and ActiveMQ Artemis (org.apache.activemq.artemis.*). Both products ship a class literally named ActiveMQConnectionFactory, so the broker flavour is disambiguated by import / FQN before emission. Coverage: - Connection factories: ActiveMQConnectionFactory, ActiveMQQueueConnectionFactory, ActiveMQTopicConnectionFactory, ActiveMQJMSConnectionFactory, ActiveMQXAConnectionFactory, PooledConnectionFactory. - Transport URLs: tcp/ssl/nio/udp/vm/amqp/stomp/mqtt/ws/wss with the optional +nio / +ssl modifiers, plus failover:(...) / failover:tcp:... (the failover transport uses `:(` rather than `://`, handled as a separate alternation in BROKER_URL_RE). - Direct destination instantiation: new ActiveMQQueue("..."), new ActiveMQTopic("..."). - session.createQueue("...") / session.createTopic("...") only attributed to ActiveMQ when the file already mentions an AMQ import or class ref — avoids double-counting against JmsDetector. - Spring Boot config keys: spring.activemq.broker-url and spring.artemis.broker-url in application.properties / application.yml (no class context — emits the broker MESSAGE_QUEUE node only). Emits NodeKind {MESSAGE_QUEUE, QUEUE, TOPIC} with broker properties ("activemq" or "activemq_artemis"), plus EdgeKind {CONNECTS_TO, SENDS_TO, RECEIVES_FROM} — same shape as IbmMqDetector and TibcoEmsDetector so the topology view composes cleanly. Tests: 17 cases covering metadata, early-exit, Classic + Artemis, named queue/topic producer/consumer, transport URL variants (failover, pooled), Spring Boot config keys, negative double-counting against JmsDetector, and a determinism fixture. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../detector/jvm/java/ActiveMqDetector.java | 287 ++++++++++++++++ .../jvm/java/ActiveMqDetectorTest.java | 323 ++++++++++++++++++ 2 files changed, 610 insertions(+) create mode 100644 src/main/java/io/github/randomcodespace/iq/detector/jvm/java/ActiveMqDetector.java create mode 100644 src/test/java/io/github/randomcodespace/iq/detector/jvm/java/ActiveMqDetectorTest.java diff --git a/src/main/java/io/github/randomcodespace/iq/detector/jvm/java/ActiveMqDetector.java b/src/main/java/io/github/randomcodespace/iq/detector/jvm/java/ActiveMqDetector.java new file mode 100644 index 00000000..d27a4f79 --- /dev/null +++ b/src/main/java/io/github/randomcodespace/iq/detector/jvm/java/ActiveMqDetector.java @@ -0,0 +1,287 @@ +package io.github.randomcodespace.iq.detector.jvm.java; + +import io.github.randomcodespace.iq.detector.DetectorContext; +import io.github.randomcodespace.iq.detector.DetectorInfo; +import io.github.randomcodespace.iq.detector.DetectorResult; +import io.github.randomcodespace.iq.model.CodeEdge; +import io.github.randomcodespace.iq.model.CodeNode; +import io.github.randomcodespace.iq.model.EdgeKind; +import io.github.randomcodespace.iq.model.NodeKind; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Detects Apache ActiveMQ usage — both ActiveMQ Classic ({@code + * org.apache.activemq}) and ActiveMQ Artemis ({@code + * org.apache.activemq.artemis}). Both products ship a class literally + * named {@code ActiveMQConnectionFactory}, so the broker flavour is + * disambiguated by the surrounding import / FQN. + */ +@DetectorInfo( + name = "active_mq", + category = "messaging", + description = "Detects Apache ActiveMQ (Classic and Artemis) queue and topic connections", + languages = {"java"}, + nodeKinds = {NodeKind.MESSAGE_QUEUE, NodeKind.QUEUE, NodeKind.TOPIC}, + edgeKinds = {EdgeKind.CONNECTS_TO, EdgeKind.RECEIVES_FROM, EdgeKind.SENDS_TO}, + properties = {"broker", "queue", "topic", "broker_url", "factory_type"} +) +@Component +public class ActiveMqDetector extends AbstractJavaMessagingDetector { + private static final String PROP_BROKER = "broker"; + private static final String PROP_BROKER_URL = "broker_url"; + private static final String PROP_FACTORY_TYPE = "factory_type"; + private static final String PROP_QUEUE = "queue"; + private static final String PROP_TOPIC = "topic"; + + private static final String BROKER_AMQ_CLASSIC = "activemq"; + private static final String BROKER_AMQ_ARTEMIS = "activemq_artemis"; + + // Distinguishes Classic vs Artemis by import path or FQN. If neither + // shows up but the bare class name does, default to Classic (it's the + // older, more common product). + private static final Pattern ARTEMIS_IMPORT_RE = Pattern.compile( + "import\\s+org\\.apache\\.activemq\\.artemis\\.|org\\.apache\\.activemq\\.artemis\\."); + private static final Pattern CLASSIC_IMPORT_RE = Pattern.compile( + "import\\s+org\\.apache\\.activemq\\.(?!artemis\\.)"); + + // Connection-factory class references (both products share names). + private static final Pattern FACTORY_RE = Pattern.compile( + "\\b(ActiveMQConnectionFactory|ActiveMQQueueConnectionFactory|" + + "ActiveMQTopicConnectionFactory|ActiveMQJMSConnectionFactory|" + + "ActiveMQXAConnectionFactory|PooledConnectionFactory)\\b"); + + // Broker URLs. Two grammars to support: + // 1. scheme://host:port — tcp/ssl/nio/udp/vm/amqp/stomp/mqtt/ws/wss + // with optional ActiveMQ +nio / +ssl modifiers. + // 2. failover:(...) — ActiveMQ's failover transport, which uses + // the form `failover:(tcp://a,tcp://b)?opts` or + // `failover:tcp://a,tcp://b`. The scheme is followed by ":" and + // then either "(" or another scheme — NOT "://". + private static final Pattern BROKER_URL_RE = Pattern.compile( + "\"((?:(?:tcp|ssl|nio|udp|vm|amqp|stomp|mqtt|ws|wss)" + + "(?:\\+nio|\\+ssl)?://[^\"]+|failover:[^\"]+))\""); + + // Spring Boot config keys — application.properties / application.yml. + private static final Pattern SPRING_BROKER_URL_RE = Pattern.compile( + "(?m)^\\s*spring\\.(activemq|artemis)\\.broker[._-]url\\s*[=:]\\s*(\\S+)"); + + // Destination instantiation and per-API patterns. + private static final Pattern AMQ_QUEUE_RE = Pattern.compile( + "new\\s+ActiveMQQueue\\s*\\(\\s*\"([^\"]+)\""); + private static final Pattern AMQ_TOPIC_RE = Pattern.compile( + "new\\s+ActiveMQTopic\\s*\\(\\s*\"([^\"]+)\""); + private static final Pattern CREATE_QUEUE_RE = Pattern.compile( + "createQueue\\s*\\(\\s*\"([^\"]+)\""); + private static final Pattern CREATE_TOPIC_RE = Pattern.compile( + "createTopic\\s*\\(\\s*\"([^\"]+)\""); + + // Producer/consumer affordances. + private static final Pattern SEND_RE = Pattern.compile("\\bsend\\s*\\("); + private static final Pattern PUBLISH_RE = Pattern.compile("\\bpublish\\s*\\("); + private static final Pattern RECEIVE_RE = Pattern.compile("\\breceive\\s*\\("); + private static final Pattern ON_MESSAGE_RE = Pattern.compile("\\bonMessage\\s*\\("); + private static final Pattern PRODUCER_RE = Pattern.compile("\\bMessageProducer\\b"); + private static final Pattern CONSUMER_RE = Pattern.compile("\\bMessageConsumer\\b"); + + @Override + public String getName() { + return "active_mq"; + } + + @Override + public Set getSupportedLanguages() { + return Set.of("java"); + } + + @Override + public DetectorResult detect(DetectorContext ctx) { + String text = ctx.content(); + if (text == null || text.isEmpty()) return DetectorResult.empty(); + + // Quick-reject: must mention either an import/FQN of activemq or one + // of the distinctive class names. Avoids the lines×patterns loop on + // ~all non-messaging Java files. + boolean hasArtemis = ARTEMIS_IMPORT_RE.matcher(text).find(); + boolean hasClassic = !hasArtemis && CLASSIC_IMPORT_RE.matcher(text).find(); + boolean hasClassRef = text.contains("ActiveMQConnectionFactory") + || text.contains("ActiveMQQueue") + || text.contains("ActiveMQTopic") + || text.contains("ActiveMQJMSConnectionFactory"); + boolean hasSpringConfig = text.contains("spring.activemq.") + || text.contains("spring.artemis."); + if (!hasArtemis && !hasClassic && !hasClassRef && !hasSpringConfig) { + return DetectorResult.empty(); + } + + // Disambiguate broker flavour. Default to Classic when the bare class + // name appears with no import context (older codebases sometimes + // shadow imports via wildcards). + String broker = hasArtemis ? BROKER_AMQ_ARTEMIS : BROKER_AMQ_CLASSIC; + + List nodes = new ArrayList<>(); + List edges = new ArrayList<>(); + Set seenQueues = new LinkedHashSet<>(); + Set seenTopics = new LinkedHashSet<>(); + + // Spring Boot config — application.properties / application.yml. + // These files don't have a class context, so we emit a broker node + // alone; the application-level CONNECTS_TO edge is added by the + // class-context branch below if any. + Matcher springM = SPRING_BROKER_URL_RE.matcher(text); + while (springM.find()) { + String flavor = springM.group(1).toLowerCase(); + String detectedBroker = "artemis".equals(flavor) ? BROKER_AMQ_ARTEMIS : BROKER_AMQ_CLASSIC; + String url = springM.group(2).replaceAll("[\"']", ""); + String nodeId = "amq:server:" + detectedBroker + ":" + url; + CodeNode node = new CodeNode(); + node.setId(nodeId); + node.setKind(NodeKind.MESSAGE_QUEUE); + node.setLabel(detectedBroker + ":" + url); + node.getProperties().put(PROP_BROKER, detectedBroker); + node.getProperties().put(PROP_BROKER_URL, url); + nodes.add(node); + } + + // For class-context edges we need a class name. .properties / .yaml + // won't have one — that's fine, we already emitted the broker node + // above, just skip the rest. + String className = extractClassName(text); + if (className == null) { + return DetectorResult.of(nodes, edges); + } + + String classNodeId = ctx.filePath() + ":" + className; + String[] lines = text.split("\n", -1); + + boolean isProducer = SEND_RE.matcher(text).find() + || PUBLISH_RE.matcher(text).find() + || PRODUCER_RE.matcher(text).find(); + boolean isConsumer = RECEIVE_RE.matcher(text).find() + || ON_MESSAGE_RE.matcher(text).find() + || CONSUMER_RE.matcher(text).find(); + + // Connection factory + nearby broker URL. + for (int i = 0; i < lines.length; i++) { + Matcher m = FACTORY_RE.matcher(lines[i]); + if (!m.find()) continue; + String factoryType = m.group(1); + String url = null; + for (int j = Math.max(0, i - 1); j < Math.min(lines.length, i + 4); j++) { + Matcher urlM = BROKER_URL_RE.matcher(lines[j]); + if (urlM.find()) { + url = urlM.group(1); + break; + } + } + + String nodeId = "amq:server:" + broker + ":" + factoryType + + (url != null ? ":" + url : ""); + CodeNode node = new CodeNode(); + node.setId(nodeId); + node.setKind(NodeKind.MESSAGE_QUEUE); + node.setLabel(broker + ":" + factoryType); + node.getProperties().put(PROP_BROKER, broker); + node.getProperties().put(PROP_FACTORY_TYPE, factoryType); + if (url != null) node.getProperties().put(PROP_BROKER_URL, url); + nodes.add(node); + + CodeEdge edge = new CodeEdge(); + edge.setId(classNodeId + "->connects_to->" + nodeId); + edge.setKind(EdgeKind.CONNECTS_TO); + edge.setSourceId(classNodeId); + edge.setTarget(node); + edge.setProperties(Map.of(PROP_FACTORY_TYPE, factoryType)); + edges.add(edge); + } + + // Direct destination instantiation: new ActiveMQQueue("...") / + // new ActiveMQTopic("..."). + for (String line : lines) { + Matcher mq = AMQ_QUEUE_RE.matcher(line); + if (mq.find()) { + String name = mq.group(1); + String qid = ensureQueueNode(name, broker, seenQueues, nodes); + if (isProducer) addMessagingEdge(classNodeId, qid, EdgeKind.SENDS_TO, + className + " sends to " + name, Map.of(PROP_QUEUE, name), edges); + if (isConsumer) addMessagingEdge(classNodeId, qid, EdgeKind.RECEIVES_FROM, + className + " receives from " + name, Map.of(PROP_QUEUE, name), edges); + } + Matcher mt = AMQ_TOPIC_RE.matcher(line); + if (mt.find()) { + String name = mt.group(1); + String tid = ensureTopicNode(name, broker, seenTopics, nodes); + if (isProducer) addMessagingEdge(classNodeId, tid, EdgeKind.SENDS_TO, + className + " sends to " + name, Map.of(PROP_TOPIC, name), edges); + if (isConsumer) addMessagingEdge(classNodeId, tid, EdgeKind.RECEIVES_FROM, + className + " receives from " + name, Map.of(PROP_TOPIC, name), edges); + } + } + + // session.createQueue("...") / session.createTopic("...") — only + // attribute these to ActiveMQ when the file already mentions an AMQ + // factory or import to avoid double-counting against JmsDetector. + boolean isAmqContext = hasArtemis || hasClassic || hasClassRef; + if (isAmqContext) { + for (String line : lines) { + Matcher cq = CREATE_QUEUE_RE.matcher(line); + if (cq.find()) { + String name = cq.group(1); + String qid = ensureQueueNode(name, broker, seenQueues, nodes); + if (isProducer) addMessagingEdge(classNodeId, qid, EdgeKind.SENDS_TO, + className + " sends to " + name, Map.of(PROP_QUEUE, name), edges); + if (isConsumer) addMessagingEdge(classNodeId, qid, EdgeKind.RECEIVES_FROM, + className + " receives from " + name, Map.of(PROP_QUEUE, name), edges); + } + Matcher ct = CREATE_TOPIC_RE.matcher(line); + if (ct.find()) { + String name = ct.group(1); + String tid = ensureTopicNode(name, broker, seenTopics, nodes); + if (isProducer) addMessagingEdge(classNodeId, tid, EdgeKind.SENDS_TO, + className + " sends to " + name, Map.of(PROP_TOPIC, name), edges); + if (isConsumer) addMessagingEdge(classNodeId, tid, EdgeKind.RECEIVES_FROM, + className + " receives from " + name, Map.of(PROP_TOPIC, name), edges); + } + } + } + + return DetectorResult.of(nodes, edges); + } + + private String ensureQueueNode(String name, String broker, Set seen, List nodes) { + String id = "amq:queue:" + broker + ":" + name; + if (!seen.contains(name)) { + seen.add(name); + CodeNode node = new CodeNode(); + node.setId(id); + node.setKind(NodeKind.QUEUE); + node.setLabel(broker + ":queue:" + name); + node.getProperties().put(PROP_BROKER, broker); + node.getProperties().put(PROP_QUEUE, name); + nodes.add(node); + } + return id; + } + + private String ensureTopicNode(String name, String broker, Set seen, List nodes) { + String id = "amq:topic:" + broker + ":" + name; + if (!seen.contains(name)) { + seen.add(name); + CodeNode node = new CodeNode(); + node.setId(id); + node.setKind(NodeKind.TOPIC); + node.setLabel(broker + ":topic:" + name); + node.getProperties().put(PROP_BROKER, broker); + node.getProperties().put(PROP_TOPIC, name); + nodes.add(node); + } + return id; + } +} diff --git a/src/test/java/io/github/randomcodespace/iq/detector/jvm/java/ActiveMqDetectorTest.java b/src/test/java/io/github/randomcodespace/iq/detector/jvm/java/ActiveMqDetectorTest.java new file mode 100644 index 00000000..acec812b --- /dev/null +++ b/src/test/java/io/github/randomcodespace/iq/detector/jvm/java/ActiveMqDetectorTest.java @@ -0,0 +1,323 @@ +package io.github.randomcodespace.iq.detector.jvm.java; + +import io.github.randomcodespace.iq.detector.DetectorContext; +import io.github.randomcodespace.iq.detector.DetectorResult; +import io.github.randomcodespace.iq.detector.DetectorTestUtils; +import io.github.randomcodespace.iq.model.EdgeKind; +import io.github.randomcodespace.iq.model.NodeKind; +import org.junit.jupiter.api.Test; + +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +/** + * Unit tests for {@link ActiveMqDetector}. Covers ActiveMQ Classic and + * Artemis flavour disambiguation, named queue/topic instantiation, common + * transport URLs, the JMS-style {@code session.createQueue/createTopic} + * API, Spring Boot {@code spring.activemq.*} / {@code spring.artemis.*} + * config-key forms, and determinism on a mixed fixture. + */ +class ActiveMqDetectorTest { + + private final ActiveMqDetector detector = new ActiveMqDetector(); + + // --------------------------------------------------------------- + // Metadata + // --------------------------------------------------------------- + + @Test + void getName_returnsActiveMq() { + assertEquals("active_mq", detector.getName()); + } + + @Test + void getSupportedLanguages_isJavaOnly() { + Set langs = detector.getSupportedLanguages(); + assertEquals(Set.of("java"), langs); + } + + // --------------------------------------------------------------- + // Early exit + // --------------------------------------------------------------- + + @Test + void emptyContent_returnsEmpty() { + DetectorContext ctx = DetectorTestUtils.contextFor("Foo.java", "java", ""); + DetectorResult r = detector.detect(ctx); + assertTrue(r.nodes().isEmpty()); + assertTrue(r.edges().isEmpty()); + } + + @Test + void nullContent_returnsEmpty() { + DetectorContext ctx = new DetectorContext("Foo.java", "java", null); + DetectorResult r = detector.detect(ctx); + assertTrue(r.nodes().isEmpty()); + assertTrue(r.edges().isEmpty()); + } + + @Test + void fileWithoutActiveMqKeywords_returnsEmpty() { + String code = """ + package app; + public class Plain { + public int add(int a, int b) { return a + b; } + } + """; + DetectorContext ctx = DetectorTestUtils.contextFor("Plain.java", "java", code); + DetectorResult r = detector.detect(ctx); + assertTrue(r.nodes().isEmpty()); + assertTrue(r.edges().isEmpty()); + } + + // --------------------------------------------------------------- + // ActiveMQ Classic: connection factory + queue + topic + // --------------------------------------------------------------- + + @Test + void detectsClassicConnectionFactoryWithBrokerUrl() { + String code = """ + package app; + import org.apache.activemq.ActiveMQConnectionFactory; + public class OrdersClient { + private final ActiveMQConnectionFactory cf = + new ActiveMQConnectionFactory("tcp://localhost:61616"); + } + """; + DetectorContext ctx = DetectorTestUtils.contextFor("OrdersClient.java", "java", code); + DetectorResult r = detector.detect(ctx); + + // MESSAGE_QUEUE node for the broker, broker=activemq, broker_url present + assertThat(r.nodes()).anyMatch(n -> + n.getKind() == NodeKind.MESSAGE_QUEUE + && "activemq".equals(n.getProperties().get("broker")) + && "tcp://localhost:61616".equals(n.getProperties().get("broker_url"))); + // CONNECTS_TO from class to broker + assertThat(r.edges()).anyMatch(e -> e.getKind() == EdgeKind.CONNECTS_TO); + } + + @Test + void detectsClassicNamedQueueProducer() { + String code = """ + package app; + import org.apache.activemq.ActiveMQConnectionFactory; + import org.apache.activemq.command.ActiveMQQueue; + public class OrdersProducer { + private final ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory(); + private final ActiveMQQueue q = new ActiveMQQueue("orders"); + public void publish() { producer.send(msg); } + private javax.jms.MessageProducer producer; + } + """; + DetectorContext ctx = DetectorTestUtils.contextFor("OrdersProducer.java", "java", code); + DetectorResult r = detector.detect(ctx); + + assertThat(r.nodes()).anyMatch(n -> + n.getKind() == NodeKind.QUEUE + && "amq:queue:activemq:orders".equals(n.getId())); + assertThat(r.edges()).anyMatch(e -> + e.getKind() == EdgeKind.SENDS_TO + && "amq:queue:activemq:orders".equals(e.getTarget().getId())); + } + + @Test + void detectsClassicNamedTopicConsumer() { + String code = """ + package app; + import org.apache.activemq.ActiveMQConnectionFactory; + import org.apache.activemq.command.ActiveMQTopic; + public class TickerListener { + private final ActiveMQTopic t = new ActiveMQTopic("ticker"); + public void onMessage(javax.jms.Message m) { /* ... */ } + } + """; + DetectorContext ctx = DetectorTestUtils.contextFor("TickerListener.java", "java", code); + DetectorResult r = detector.detect(ctx); + + assertThat(r.nodes()).anyMatch(n -> + n.getKind() == NodeKind.TOPIC + && "amq:topic:activemq:ticker".equals(n.getId())); + assertThat(r.edges()).anyMatch(e -> e.getKind() == EdgeKind.RECEIVES_FROM); + } + + @Test + void detectsSessionCreateQueueWhenAmqContext() { + String code = """ + package app; + import org.apache.activemq.ActiveMQConnectionFactory; + public class JmsApi { + public void send(javax.jms.Session s) { + javax.jms.Queue q = s.createQueue("workers"); + producer.send(msg); + } + private javax.jms.MessageProducer producer; + } + """; + DetectorContext ctx = DetectorTestUtils.contextFor("JmsApi.java", "java", code); + DetectorResult r = detector.detect(ctx); + assertThat(r.nodes()).anyMatch(n -> + n.getKind() == NodeKind.QUEUE + && "amq:queue:activemq:workers".equals(n.getId())); + } + + // --------------------------------------------------------------- + // ActiveMQ Artemis: distinguished by package path + // --------------------------------------------------------------- + + @Test + void detectsArtemisFlavourViaImport() { + String code = """ + package app; + import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; + public class ArtemisClient { + private final ActiveMQConnectionFactory cf = + new ActiveMQConnectionFactory("tcp://artemis:61616"); + } + """; + DetectorContext ctx = DetectorTestUtils.contextFor("ArtemisClient.java", "java", code); + DetectorResult r = detector.detect(ctx); + + assertThat(r.nodes()).anyMatch(n -> + n.getKind() == NodeKind.MESSAGE_QUEUE + && "activemq_artemis".equals(n.getProperties().get("broker"))); + } + + @Test + void detectsArtemisJmsConnectionFactoryClass() { + String code = """ + package app; + import org.apache.activemq.artemis.api.jms.ActiveMQJMSConnectionFactory; + public class ArtemisJms { + private final ActiveMQJMSConnectionFactory cf = + new ActiveMQJMSConnectionFactory("tcp://artemis:61616"); + } + """; + DetectorContext ctx = DetectorTestUtils.contextFor("ArtemisJms.java", "java", code); + DetectorResult r = detector.detect(ctx); + + assertThat(r.nodes()).anyMatch(n -> + n.getKind() == NodeKind.MESSAGE_QUEUE + && "activemq_artemis".equals(n.getProperties().get("broker")) + && "ActiveMQJMSConnectionFactory".equals(n.getProperties().get("factory_type"))); + } + + // --------------------------------------------------------------- + // Transport URL variants + // --------------------------------------------------------------- + + @Test + void capturesFailoverTransportUrl() { + String code = """ + package app; + import org.apache.activemq.ActiveMQConnectionFactory; + public class HaClient { + private final ActiveMQConnectionFactory cf = + new ActiveMQConnectionFactory("failover:(tcp://a:61616,tcp://b:61616)"); + } + """; + DetectorContext ctx = DetectorTestUtils.contextFor("HaClient.java", "java", code); + DetectorResult r = detector.detect(ctx); + + assertThat(r.nodes()).anyMatch(n -> { + Object url = n.getProperties().get("broker_url"); + return url != null && url.toString().startsWith("failover:"); + }); + } + + @Test + void capturesPooledConnectionFactory() { + String code = """ + package app; + import org.apache.activemq.pool.PooledConnectionFactory; + public class PoolClient { + private final PooledConnectionFactory pcf = new PooledConnectionFactory(); + } + """; + DetectorContext ctx = DetectorTestUtils.contextFor("PoolClient.java", "java", code); + DetectorResult r = detector.detect(ctx); + + assertThat(r.nodes()).anyMatch(n -> + "PooledConnectionFactory".equals(n.getProperties().get("factory_type"))); + } + + // --------------------------------------------------------------- + // Spring Boot config keys (no class context — config files / property files) + // --------------------------------------------------------------- + + @Test + void detectsSpringActivemqBrokerUrl_emitsBrokerNodeOnly() { + // application.properties content — no class declaration; detector + // emits a broker node but no class-context CONNECTS_TO edge. + String props = "spring.activemq.broker-url=tcp://broker:61616\n"; + DetectorContext ctx = DetectorTestUtils.contextFor("application.properties", "java", props); + DetectorResult r = detector.detect(ctx); + + assertThat(r.nodes()).anyMatch(n -> + n.getKind() == NodeKind.MESSAGE_QUEUE + && "activemq".equals(n.getProperties().get("broker")) + && "tcp://broker:61616".equals(n.getProperties().get("broker_url"))); + assertTrue(r.edges().isEmpty(), + "No class context in a .properties file → no edges expected"); + } + + @Test + void detectsSpringArtemisBrokerUrl() { + String props = "spring.artemis.broker-url=tcp://artemis-broker:61616\n"; + DetectorContext ctx = DetectorTestUtils.contextFor("application.properties", "java", props); + DetectorResult r = detector.detect(ctx); + + assertThat(r.nodes()).anyMatch(n -> + n.getKind() == NodeKind.MESSAGE_QUEUE + && "activemq_artemis".equals(n.getProperties().get("broker"))); + } + + // --------------------------------------------------------------- + // Negative: JMS without ActiveMQ context should NOT be claimed + // --------------------------------------------------------------- + + @Test + void plainJmsCreateQueue_withoutActiveMqContext_isIgnored() { + // JmsDetector handles bare JMS; ActiveMqDetector should only claim + // createQueue/createTopic when an ActiveMQ import or class ref is + // present in the same file. This avoids double-counting. + String code = """ + package app; + public class PlainJms { + public void send(javax.jms.Session s) { + javax.jms.Queue q = s.createQueue("anywhere"); + } + } + """; + DetectorContext ctx = DetectorTestUtils.contextFor("PlainJms.java", "java", code); + DetectorResult r = detector.detect(ctx); + assertTrue(r.nodes().isEmpty(), + "createQueue without an AMQ import/class ref must not be attributed to ActiveMQ"); + } + + // --------------------------------------------------------------- + // Determinism + // --------------------------------------------------------------- + + @Test + void deterministic_sameInputSameOutput() { + String code = """ + package app; + import org.apache.activemq.ActiveMQConnectionFactory; + import org.apache.activemq.command.ActiveMQQueue; + import org.apache.activemq.command.ActiveMQTopic; + public class Mixed { + ActiveMQConnectionFactory cf = + new ActiveMQConnectionFactory("tcp://localhost:61616"); + ActiveMQQueue q = new ActiveMQQueue("orders"); + ActiveMQTopic t = new ActiveMQTopic("events"); + public void publish() { producer.send(msg); } + public void onMessage(javax.jms.Message m) { /* ... */ } + private javax.jms.MessageProducer producer; + } + """; + DetectorContext ctx = DetectorTestUtils.contextFor("Mixed.java", "java", code); + DetectorTestUtils.assertDeterministic(detector, ctx); + } +} From c46e6562be0ad7603a9841303bbd70a941184f75 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Sun, 3 May 2026 15:46:39 +0000 Subject: [PATCH 6/7] fix(health): make `codeiq serve` start cleanly under Spring Boot 4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two coupled changes that together let `serve` boot from defaults without -D / env / config overrides. 1. GraphHealthIndicator: @ConditionalOnBean(GraphStore.class) → @Profile("serving"). Spring documents @ConditionalOnBean as fragile on user @Component classes (its evaluation depends on bean-definition ordering during scan). The serving profile already guarantees GraphStore is present; @Profile activates earlier and deterministic- ally so the readiness-group reference resolves on a clean install. 2. application.yml: management.endpoint.health.validate-group-membership set to false. Spring Boot 4 enabled strict group-membership validation by default — startup fails when a `health.group.*.include` references a profile-conditional bean that hasn't yet been added to the registry when the management endpoint config loads. The serving profile's readiness include of `graphHealthIndicator` consistently tripped this. Disabled per the error message's own remediation hint; missing health contributors are silently skipped at probe time, which is the desired runtime behaviour. Verified: `java -jar code-iq-cli.jar serve -p 37779` with no flags / env / codeiq.yml — port binds, /api/stats returns data without auth, /actuator/health/readiness returns {"status":"UP"}. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../iq/health/GraphHealthIndicator.java | 12 ++++++++++-- src/main/resources/application.yml | 12 ++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/github/randomcodespace/iq/health/GraphHealthIndicator.java b/src/main/java/io/github/randomcodespace/iq/health/GraphHealthIndicator.java index 73f222f5..d26b8c19 100644 --- a/src/main/java/io/github/randomcodespace/iq/health/GraphHealthIndicator.java +++ b/src/main/java/io/github/randomcodespace/iq/health/GraphHealthIndicator.java @@ -3,9 +3,9 @@ import io.github.randomcodespace.iq.graph.GraphStore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.health.contributor.Health; import org.springframework.boot.health.contributor.HealthIndicator; +import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; import java.time.Duration; @@ -37,8 +37,16 @@ * name + a static reason — operators correlate via the WARN log line that * carries the full exception. */ +// Profile-gated rather than @ConditionalOnBean(GraphStore.class) — the +// latter is documented as fragile on user @Component classes (its +// evaluation depends on bean-definition ordering during scan, and the +// readiness group config in application.yml references this bean by +// name). @Profile("serving") activates earlier, in lockstep with +// GraphStore (also a serving-profile bean), so Spring's +// "Included health contributor 'graphHealthIndicator' in group +// 'readiness' does not exist" startup validation passes deterministically. @Component -@ConditionalOnBean(GraphStore.class) +@Profile("serving") public class GraphHealthIndicator implements HealthIndicator { private static final Logger log = LoggerFactory.getLogger(GraphHealthIndicator.class); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 65c22a1e..a2ef2586 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -31,6 +31,18 @@ management: web: exposure: include: health,info,metrics + endpoint: + health: + # Spring Boot 4 enabled strict group-membership validation by default, + # which fails startup if a `health.group.*.include` references a + # health-contributor bean that hasn't registered yet (or is profile- + # gated and not active in the current profile). The serving profile + # references `graphHealthIndicator` from a profile-gated bean, and the + # validation runs before all profile-conditional beans are visible — + # so the readiness include trips it. Disable the strict validation; + # missing health contributors are silently skipped at probe time, + # which is the desired behaviour. + validate-group-membership: false # Runtime codeiq.* values (cache dir, limits, pipeline tuning, MCP auth, etc.) # are sourced from codeiq.yml / env / CLI via CodeIqUnifiedConfig (see From 306ab282e3e6d83456c137c958391a5d709a23b4 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Sun, 3 May 2026 15:53:18 +0000 Subject: [PATCH 7/7] fix(build): regenerate package-lock.json against npm registry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous lockfile pointed @ossrandom/design-system at a local filesystem path (`file:../../../../design-system`, link:true) — a holdover from the local-checkout development of the design-system. On CI that path doesn't exist, so `npm install` left the dep unresolved and `vite build` failed with TS2307 "Cannot find module '@ossrandom/design-system'". Regenerated lockfile resolves to the published 0.3.0 tarball: https://registry.npmjs.org/@ossrandom/design-system/-/design-system-0.3.0.tgz Verified locally: `rm -rf node_modules && npm install` clean, `npm run build` produces the same bundle modulo content-hash filenames. The two new design-system-*.js chunks reflect the registry-resolved artifact. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/main/frontend/package-lock.json | 435 +++++++++--------- .../static/assets/design-system-BIHI7g3E.js | 1 + .../static/assets/design-system-Df6KNeSA.js | 1 + 3 files changed, 227 insertions(+), 210 deletions(-) create mode 100644 src/main/resources/static/assets/design-system-BIHI7g3E.js create mode 100644 src/main/resources/static/assets/design-system-Df6KNeSA.js diff --git a/src/main/frontend/package-lock.json b/src/main/frontend/package-lock.json index 69762b10..287e6a3a 100644 --- a/src/main/frontend/package-lock.json +++ b/src/main/frontend/package-lock.json @@ -25,77 +25,14 @@ "vite": "^6.4.2" } }, - "../../../../design-system": { - "name": "@ossrandom/design-system", - "version": "0.3.0", - "license": "MIT", - "devDependencies": { - "@babel/standalone": "^7.29.0", - "@playwright/test": "^1.59.1", - "@testing-library/jest-dom": "^6.9.1", - "@testing-library/react": "^16.3.2", - "@testing-library/user-event": "^14.6.1", - "@types/node": "^22.0.0", - "@types/react": "^19.0.0", - "@types/react-dom": "^19.0.0", - "@typescript-eslint/eslint-plugin": "^8.0.0", - "@typescript-eslint/parser": "^8.0.0", - "@vitest/coverage-v8": "^4.1.5", - "esbuild": "^0.28.0", - "eslint": "^9.0.0", - "jsdom": "^29.0.2", - "react": "^19.0.0", - "react-dom": "^19.0.0", - "typescript": "^5.6.0", - "vite": "^8.0.10", - "vitest": "^4.1.5" - }, - "engines": { - "node": ">=18.18" - }, - "peerDependencies": { - "@deck.gl/core": "^9.0.0", - "@deck.gl/layers": "^9.0.0", - "cytoscape": "^3.30.0", - "cytoscape-cose-bilkent": "^4.1.0", - "d3-force": "^3.0.0", - "d3-hierarchy": "^3.0.0", - "react": ">=18", - "react-dom": ">=18", - "uplot": "^1.6.0" - }, - "peerDependenciesMeta": { - "@deck.gl/core": { - "optional": true - }, - "@deck.gl/layers": { - "optional": true - }, - "cytoscape": { - "optional": true - }, - "cytoscape-cose-bilkent": { - "optional": true - }, - "d3-force": { - "optional": true - }, - "d3-hierarchy": { - "optional": true - }, - "uplot": { - "optional": true - } - } - }, "node_modules/@axe-core/playwright": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.11.1.tgz", - "integrity": "sha512-mKEfoUIB1MkVTht0BGZFXtSAEKXMJoDkyV5YZ9jbBmZCcWDz71tegNsdTkIN8zc/yMi5Gm2kx7Z5YQ9PfWNAWw==", + "version": "4.11.3", + "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.11.3.tgz", + "integrity": "sha512-h/kfksv4F0cVIDlKpT4700OehdRgpvuVskuQ2nb7/JmtWUXpe9ftHAPtwyXGvVSsa6SJ64A9ER7Zrzc/sIvC4w==", "dev": true, "license": "MPL-2.0", "dependencies": { - "axe-core": "~4.11.1" + "axe-core": "~4.11.4" }, "peerDependencies": { "playwright-core": ">= 1.0.0" @@ -117,9 +54,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", - "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", + "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", "dev": true, "license": "MIT", "engines": { @@ -288,9 +225,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", - "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", + "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", "dev": true, "license": "MIT", "dependencies": { @@ -876,8 +813,47 @@ } }, "node_modules/@ossrandom/design-system": { - "resolved": "../../../../design-system", - "link": true + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@ossrandom/design-system/-/design-system-0.3.0.tgz", + "integrity": "sha512-flW4PBob1WCjyero4HA8/gYHbQe+ufy2XpQ5EpjO988LdNaM/oArj4gONQSdXdGGlQ4zoXzuRTgPjDDBB61o2A==", + "license": "MIT", + "engines": { + "node": ">=18.18" + }, + "peerDependencies": { + "@deck.gl/core": "^9.0.0", + "@deck.gl/layers": "^9.0.0", + "cytoscape": "^3.30.0", + "cytoscape-cose-bilkent": "^4.1.0", + "d3-force": "^3.0.0", + "d3-hierarchy": "^3.0.0", + "react": ">=18", + "react-dom": ">=18", + "uplot": "^1.6.0" + }, + "peerDependenciesMeta": { + "@deck.gl/core": { + "optional": true + }, + "@deck.gl/layers": { + "optional": true + }, + "cytoscape": { + "optional": true + }, + "cytoscape-cose-bilkent": { + "optional": true + }, + "d3-force": { + "optional": true + }, + "d3-hierarchy": { + "optional": true + }, + "uplot": { + "optional": true + } + } }, "node_modules/@playwright/test": { "version": "1.59.1", @@ -903,9 +879,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz", - "integrity": "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.2.tgz", + "integrity": "sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==", "cpu": [ "arm" ], @@ -917,9 +893,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1.tgz", - "integrity": "sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.2.tgz", + "integrity": "sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==", "cpu": [ "arm64" ], @@ -931,9 +907,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1.tgz", - "integrity": "sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.2.tgz", + "integrity": "sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==", "cpu": [ "arm64" ], @@ -945,9 +921,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1.tgz", - "integrity": "sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.2.tgz", + "integrity": "sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==", "cpu": [ "x64" ], @@ -959,9 +935,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1.tgz", - "integrity": "sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.2.tgz", + "integrity": "sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==", "cpu": [ "arm64" ], @@ -973,9 +949,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1.tgz", - "integrity": "sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.2.tgz", + "integrity": "sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==", "cpu": [ "x64" ], @@ -987,13 +963,16 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1.tgz", - "integrity": "sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.2.tgz", + "integrity": "sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==", "cpu": [ "arm" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1001,13 +980,16 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1.tgz", - "integrity": "sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.2.tgz", + "integrity": "sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==", "cpu": [ "arm" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1015,13 +997,16 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1.tgz", - "integrity": "sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.2.tgz", + "integrity": "sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1029,13 +1014,16 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1.tgz", - "integrity": "sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz", + "integrity": "sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1043,13 +1031,16 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz", - "integrity": "sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz", + "integrity": "sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==", "cpu": [ "loong64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1057,13 +1048,16 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz", - "integrity": "sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz", + "integrity": "sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==", "cpu": [ "loong64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1071,13 +1065,16 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz", - "integrity": "sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz", + "integrity": "sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==", "cpu": [ "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1085,13 +1082,16 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz", - "integrity": "sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz", + "integrity": "sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==", "cpu": [ "ppc64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1099,13 +1099,16 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1.tgz", - "integrity": "sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz", + "integrity": "sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==", "cpu": [ "riscv64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1113,13 +1116,16 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1.tgz", - "integrity": "sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz", + "integrity": "sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==", "cpu": [ "riscv64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1127,13 +1133,16 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1.tgz", - "integrity": "sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz", + "integrity": "sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==", "cpu": [ "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1141,13 +1150,16 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1.tgz", - "integrity": "sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz", + "integrity": "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1155,13 +1167,16 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1.tgz", - "integrity": "sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz", + "integrity": "sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1169,9 +1184,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz", - "integrity": "sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz", + "integrity": "sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==", "cpu": [ "x64" ], @@ -1183,9 +1198,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1.tgz", - "integrity": "sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz", + "integrity": "sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==", "cpu": [ "arm64" ], @@ -1197,9 +1212,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1.tgz", - "integrity": "sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz", + "integrity": "sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==", "cpu": [ "arm64" ], @@ -1211,9 +1226,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1.tgz", - "integrity": "sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz", + "integrity": "sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==", "cpu": [ "ia32" ], @@ -1225,9 +1240,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz", - "integrity": "sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz", + "integrity": "sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==", "cpu": [ "x64" ], @@ -1239,9 +1254,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1.tgz", - "integrity": "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz", + "integrity": "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==", "cpu": [ "x64" ], @@ -1356,9 +1371,9 @@ } }, "node_modules/axe-core": { - "version": "4.11.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.2.tgz", - "integrity": "sha512-byD6KPdvo72y/wj2T/4zGEvvlis+PsZsn/yPS3pEO+sFpcrqRpX/TJCxvVaEsNeMrfQbCr7w163YqoD9IYwHXw==", + "version": "4.11.4", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.4.tgz", + "integrity": "sha512-KunSNx+TVpkAw/6ULfhnx+HWRecjqZGTOyquAoWHYLRSdK1tB5Ihce1ZW+UY3fj33bYAFWPu7W/GRSmmrCGuxA==", "dev": true, "license": "MPL-2.0", "engines": { @@ -1366,9 +1381,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.10.15", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.15.tgz", - "integrity": "sha512-1nfKCq9wuAZFTkA2ey/3OXXx7GzFjLdkTiFVNwlJ9WqdI706CZRIhEqjuwanjMIja+84jDLa9rcyZDPDiVkASQ==", + "version": "2.10.27", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.27.tgz", + "integrity": "sha512-zEs/ufmZoUd7WftKpKyXaT6RFxpQ5Qm9xytKRHvJfxFV9DFJkZph9RvJ1LcOUi0Z1ZVijMte65JbILeV+8QQEA==", "dev": true, "license": "Apache-2.0", "bin": { @@ -1413,9 +1428,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001785", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001785.tgz", - "integrity": "sha512-blhOL/WNR+Km1RI/LCVAvA73xplXA7ZbjzI4YkMK9pa6T/P3F2GxjNpEkyw5repTw9IvkyrjyHpwjnhZ5FOvYQ==", + "version": "1.0.30001791", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001791.tgz", + "integrity": "sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==", "dev": true, "funding": [ { @@ -1488,9 +1503,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.331", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.331.tgz", - "integrity": "sha512-IbxXrsTlD3hRodkLnbxAPP4OuJYdWCeM3IOdT+CpcMoIwIoDfCmRpEtSPfwBXxVkg9xmBeY7Lz2Eo2TDn/HC3Q==", + "version": "1.5.349", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.349.tgz", + "integrity": "sha512-QsWVGyRuY07Aqb234QytTfwd5d9AJlfNIQ5wIOl1L+PZDzI9d9+Fn0FRale/QYlFxt/bUnB0/nLd1jFPGxGK1A==", "dev": true, "license": "ISC" }, @@ -1640,9 +1655,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", "dev": true, "funding": [ { @@ -1659,9 +1674,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.37", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz", - "integrity": "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==", + "version": "2.0.38", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz", + "integrity": "sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==", "dev": true, "license": "MIT" }, @@ -1718,9 +1733,9 @@ } }, "node_modules/postcss": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", - "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.13.tgz", + "integrity": "sha512-qif0+jGGZoLWdHey3UFHHWP0H7Gbmsk8T5VEqyYFbWqPr1XqvLGBbk/sl8V5exGmcYJklJOhOQq1pV9IcsiFag==", "dev": true, "funding": [ { @@ -1778,9 +1793,9 @@ } }, "node_modules/react-router": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.14.0.tgz", - "integrity": "sha512-m/xR9N4LQLmAS0ZhkY2nkPA1N7gQ5TUVa5n8TgANuDTARbn1gt+zLPXEm7W0XDTbrQ2AJSJKhoa6yx1D8BcpxQ==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.14.2.tgz", + "integrity": "sha512-yCqNne6I8IB6rVCH7XUvlBK7/QKyqypBFGv+8dj4QBFJiiRX+FG7/nkdAvGElyvVZ/HQP5N19wzteuTARXi5Gw==", "license": "MIT", "dependencies": { "cookie": "^1.0.1", @@ -1800,12 +1815,12 @@ } }, "node_modules/react-router-dom": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.14.0.tgz", - "integrity": "sha512-2G3ajSVSZMEtmTjIklRWlNvo8wICEpLihfD/0YMDxbWK2UyP5EGfnoIn9AIQGnF3G/FX0MRbHXdFcD+rL1ZreQ==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.14.2.tgz", + "integrity": "sha512-YZcM5ES8jJSM+KrJ9BdvHHqlnGTg5tH3sC5ChFRj4inosKctdyzBDhOyyHdGk597q2OT6NTrCA1OvB/YDwfekQ==", "license": "MIT", "dependencies": { - "react-router": "7.14.0" + "react-router": "7.14.2" }, "engines": { "node": ">=20.0.0" @@ -1816,9 +1831,9 @@ } }, "node_modules/rollup": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz", - "integrity": "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.2.tgz", + "integrity": "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1832,31 +1847,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.60.1", - "@rollup/rollup-android-arm64": "4.60.1", - "@rollup/rollup-darwin-arm64": "4.60.1", - "@rollup/rollup-darwin-x64": "4.60.1", - "@rollup/rollup-freebsd-arm64": "4.60.1", - "@rollup/rollup-freebsd-x64": "4.60.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", - "@rollup/rollup-linux-arm-musleabihf": "4.60.1", - "@rollup/rollup-linux-arm64-gnu": "4.60.1", - "@rollup/rollup-linux-arm64-musl": "4.60.1", - "@rollup/rollup-linux-loong64-gnu": "4.60.1", - "@rollup/rollup-linux-loong64-musl": "4.60.1", - "@rollup/rollup-linux-ppc64-gnu": "4.60.1", - "@rollup/rollup-linux-ppc64-musl": "4.60.1", - "@rollup/rollup-linux-riscv64-gnu": "4.60.1", - "@rollup/rollup-linux-riscv64-musl": "4.60.1", - "@rollup/rollup-linux-s390x-gnu": "4.60.1", - "@rollup/rollup-linux-x64-gnu": "4.60.1", - "@rollup/rollup-linux-x64-musl": "4.60.1", - "@rollup/rollup-openbsd-x64": "4.60.1", - "@rollup/rollup-openharmony-arm64": "4.60.1", - "@rollup/rollup-win32-arm64-msvc": "4.60.1", - "@rollup/rollup-win32-ia32-msvc": "4.60.1", - "@rollup/rollup-win32-x64-gnu": "4.60.1", - "@rollup/rollup-win32-x64-msvc": "4.60.1", + "@rollup/rollup-android-arm-eabi": "4.60.2", + "@rollup/rollup-android-arm64": "4.60.2", + "@rollup/rollup-darwin-arm64": "4.60.2", + "@rollup/rollup-darwin-x64": "4.60.2", + "@rollup/rollup-freebsd-arm64": "4.60.2", + "@rollup/rollup-freebsd-x64": "4.60.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.2", + "@rollup/rollup-linux-arm-musleabihf": "4.60.2", + "@rollup/rollup-linux-arm64-gnu": "4.60.2", + "@rollup/rollup-linux-arm64-musl": "4.60.2", + "@rollup/rollup-linux-loong64-gnu": "4.60.2", + "@rollup/rollup-linux-loong64-musl": "4.60.2", + "@rollup/rollup-linux-ppc64-gnu": "4.60.2", + "@rollup/rollup-linux-ppc64-musl": "4.60.2", + "@rollup/rollup-linux-riscv64-gnu": "4.60.2", + "@rollup/rollup-linux-riscv64-musl": "4.60.2", + "@rollup/rollup-linux-s390x-gnu": "4.60.2", + "@rollup/rollup-linux-x64-gnu": "4.60.2", + "@rollup/rollup-linux-x64-musl": "4.60.2", + "@rollup/rollup-openbsd-x64": "4.60.2", + "@rollup/rollup-openharmony-arm64": "4.60.2", + "@rollup/rollup-win32-arm64-msvc": "4.60.2", + "@rollup/rollup-win32-ia32-msvc": "4.60.2", + "@rollup/rollup-win32-x64-gnu": "4.60.2", + "@rollup/rollup-win32-x64-msvc": "4.60.2", "fsevents": "~2.3.2" } }, @@ -1893,14 +1908,14 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" diff --git a/src/main/resources/static/assets/design-system-BIHI7g3E.js b/src/main/resources/static/assets/design-system-BIHI7g3E.js new file mode 100644 index 00000000..b480ffe6 --- /dev/null +++ b/src/main/resources/static/assets/design-system-BIHI7g3E.js @@ -0,0 +1 @@ +const e={};export{e as default}; diff --git a/src/main/resources/static/assets/design-system-Df6KNeSA.js b/src/main/resources/static/assets/design-system-Df6KNeSA.js new file mode 100644 index 00000000..b480ffe6 --- /dev/null +++ b/src/main/resources/static/assets/design-system-Df6KNeSA.js @@ -0,0 +1 @@ +const e={};export{e as default};