+ {treemapRoot.children && treemapRoot.children.length > 0
+ ? 'This folder is empty. Use the breadcrumb above to go back.'
+ : 'No file data. Run index + enrich first.'}
+
- );
-}
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/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;
}
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 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,
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);
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/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
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 00000000..42c558b6
Binary files /dev/null and b/src/main/resources/static/assets/BricolageGrotesque-Variable-C5Lc8Qmc.woff2 differ
diff --git a/src/main/resources/static/assets/GeistMono-Variable-BNLlm6Cd.woff2 b/src/main/resources/static/assets/GeistMono-Variable-BNLlm6Cd.woff2
new file mode 100644
index 00000000..dbdb8c2d
Binary files /dev/null and b/src/main/resources/static/assets/GeistMono-Variable-BNLlm6Cd.woff2 differ
diff --git a/src/main/resources/static/assets/PlusJakartaSans-Variable-eXO_dkmS.woff2 b/src/main/resources/static/assets/PlusJakartaSans-Variable-eXO_dkmS.woff2
new file mode 100644
index 00000000..a180dc40
Binary files /dev/null and b/src/main/resources/static/assets/PlusJakartaSans-Variable-eXO_dkmS.woff2 differ
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};
diff --git a/src/main/resources/static/assets/tesselator-D_j4OGEy.js b/src/main/resources/static/assets/tesselator-D_j4OGEy.js
new file mode 100644
index 00000000..4ae28e49
--- /dev/null
+++ b/src/main/resources/static/assets/tesselator-D_j4OGEy.js
@@ -0,0 +1,1916 @@
+var el=Object.defineProperty;var tl=(e,t,r)=>t 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?`