@react-three/fiber 10.0.0-canary.e881a4a → 10.0.0-canary.ea31ccd

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,22 +1,21 @@
1
1
  import * as webgpu from 'three/webgpu';
2
- import { CubeRenderTarget, RenderTarget, CubeReflectionMapping, EquirectangularReflectionMapping, CubeTextureLoader, Scene, HalfFloatType, Color, Frustum, Matrix4, Group, BoxGeometry, MeshBasicNodeMaterial, Mesh, Node, NodeUpdateType, Layers, ShaderMaterial, Uniform, SRGBColorSpace, RGBAFormat, UnsignedByteType, Vector3, Vector2, TextureLoader, Texture as Texture$1, CanvasTarget, Raycaster, OrthographicCamera, PerspectiveCamera, PCFShadowMap, VSMShadowMap, BasicShadowMap, ACESFilmicToneMapping, WebGPURenderer } from 'three/webgpu';
2
+ import { CubeRenderTarget, RenderTarget, Frustum, Matrix4, Group, BoxGeometry, MeshBasicNodeMaterial, Mesh, Node, NodeUpdateType, Layers, ShaderMaterial, Uniform, SRGBColorSpace, RGBAFormat, UnsignedByteType, Vector3, Vector2, TextureLoader, Texture as Texture$1, CubeReflectionMapping, EquirectangularReflectionMapping, CubeTextureLoader, CanvasTarget, Raycaster, OrthographicCamera, PerspectiveCamera, Scene, PCFShadowMap, VSMShadowMap, BasicShadowMap, ACESFilmicToneMapping, WebGPURenderer, HalfFloatType, Color } from 'three/webgpu';
3
3
  import { WebGLCubeRenderTarget, WebGLRenderTarget, WebGLRenderer } from 'three';
4
- import { Inspector } from 'three/addons/inspector/Inspector.js';
5
4
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
6
5
  import * as React from 'react';
7
- import React__default, { useLayoutEffect, useRef, useMemo, useEffect, useContext, useImperativeHandle, useCallback, useState } from 'react';
6
+ import React__default, { useRef, useMemo, useLayoutEffect, useEffect, useContext, useImperativeHandle, useCallback, useState } from 'react';
8
7
  import useMeasure from 'react-use-measure';
9
8
  import { useFiber, useContextBridge, traverseFiber, FiberProvider } from 'its-fine';
10
- import { useThree as useThree$1, useLoader as useLoader$1, useFrame as useFrame$1, createPortal as createPortal$1, applyProps as applyProps$1, extend as extend$1 } from '@react-three/fiber';
9
+ import { createWithEqualityFn } from 'zustand/traditional';
10
+ import { getScheduler } from '@pmndrs/scheduler';
11
+ export { Scheduler, getScheduler } from '@pmndrs/scheduler';
12
+ import Tb, { unstable_getCurrentPriorityLevel, unstable_IdlePriority, unstable_LowPriority, unstable_NormalPriority, unstable_UserBlockingPriority, unstable_ImmediatePriority, unstable_scheduleCallback } from 'scheduler';
11
13
  import { GroundedSkybox } from 'three/examples/jsm/objects/GroundedSkybox.js';
12
14
  import { HDRLoader } from 'three/examples/jsm/loaders/HDRLoader.js';
15
+ import { HDRCubeTextureLoader } from 'three/examples/jsm/loaders/HDRCubeTextureLoader.js';
13
16
  import { EXRLoader } from 'three/examples/jsm/loaders/EXRLoader.js';
14
17
  import { UltraHDRLoader } from 'three/examples/jsm/loaders/UltraHDRLoader.js';
15
18
  import { GainMapLoader } from '@monogrid/gainmap-js';
16
- import Tb, { unstable_scheduleCallback, unstable_IdlePriority } from 'scheduler';
17
- import { createWithEqualityFn } from 'zustand/traditional';
18
- import { getScheduler } from '@pmndrs/scheduler';
19
- export { Scheduler, getScheduler } from '@pmndrs/scheduler';
20
19
  import { suspend, preload, clear } from 'suspend-react';
21
20
 
22
21
  function _mergeNamespaces(n, m) {
@@ -33,18 +32,22 @@ function _mergeNamespaces(n, m) {
33
32
 
34
33
  const R3F_BUILD_LEGACY = true;
35
34
  const R3F_BUILD_WEBGPU = true;
35
+ async function loadInspector() {
36
+ const { Inspector } = await import('three/addons/inspector/Inspector.js');
37
+ return Inspector;
38
+ }
36
39
 
37
40
  const THREE = /*#__PURE__*/_mergeNamespaces({
38
41
  __proto__: null,
39
42
  CubeRenderTarget: CubeRenderTarget,
40
43
  CubeRenderTargetCompat: CubeRenderTarget,
41
- Inspector: Inspector,
42
44
  R3F_BUILD_LEGACY: R3F_BUILD_LEGACY,
43
45
  R3F_BUILD_WEBGPU: R3F_BUILD_WEBGPU,
44
46
  RenderTargetCompat: RenderTarget,
45
47
  WebGLCubeRenderTarget: WebGLCubeRenderTarget,
46
48
  WebGLRenderTarget: WebGLRenderTarget,
47
- WebGLRenderer: WebGLRenderer
49
+ WebGLRenderer: WebGLRenderer,
50
+ loadInspector: loadInspector
48
51
  }, [webgpu]);
49
52
 
50
53
  const primaryRegistry = /* @__PURE__ */ new Map();
@@ -105,823 +108,553 @@ function getPrimaryIds() {
105
108
  return Array.from(primaryRegistry.keys());
106
109
  }
107
110
 
108
- const presetsObj = {
109
- apartment: "lebombo_1k.hdr",
110
- city: "potsdamer_platz_1k.hdr",
111
- dawn: "kiara_1_dawn_1k.hdr",
112
- forest: "forest_slope_1k.hdr",
113
- lobby: "st_fagans_interior_1k.hdr",
114
- night: "dikhololo_night_1k.hdr",
115
- park: "rooitou_park_1k.hdr",
116
- studio: "studio_small_03_1k.hdr",
117
- sunset: "venice_sunset_1k.hdr",
118
- warehouse: "empty_warehouse_01_1k.hdr"
119
- };
111
+ var __defProp = Object.defineProperty;
112
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
113
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
114
+ const useIsomorphicLayoutEffect = /* @__PURE__ */ (() => typeof window !== "undefined" && (window.document?.createElement || window.navigator?.product === "ReactNative"))() ? React.useLayoutEffect : React.useEffect;
115
+ function useMutableCallback(fn) {
116
+ const ref = React.useRef(fn);
117
+ useIsomorphicLayoutEffect(() => void (ref.current = fn), [fn]);
118
+ return ref;
119
+ }
120
+ function useBridge() {
121
+ const fiber = useFiber();
122
+ const ContextBridge = useContextBridge();
123
+ return React.useMemo(
124
+ () => ({ children }) => {
125
+ const strict = !!traverseFiber(fiber, true, (node) => node.type === React.StrictMode);
126
+ const Root = strict ? React.StrictMode : React.Fragment;
127
+ return /* @__PURE__ */ jsx(Root, { children: /* @__PURE__ */ jsx(ContextBridge, { children }) });
128
+ },
129
+ [fiber, ContextBridge]
130
+ );
131
+ }
132
+ function Block({ set }) {
133
+ useIsomorphicLayoutEffect(() => {
134
+ set(new Promise(() => null));
135
+ return () => set(false);
136
+ }, [set]);
137
+ return null;
138
+ }
139
+ const ErrorBoundary = /* @__PURE__ */ (() => {
140
+ var _a;
141
+ return _a = class extends React.Component {
142
+ constructor() {
143
+ super(...arguments);
144
+ __publicField(this, "state", { error: false });
145
+ }
146
+ componentDidCatch(err) {
147
+ this.props.set(err);
148
+ }
149
+ render() {
150
+ return this.state.error ? null : this.props.children;
151
+ }
152
+ }, __publicField(_a, "getDerivedStateFromError", () => ({ error: true })), _a;
153
+ })();
120
154
 
121
- const CUBEMAP_ROOT = "https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/";
122
- const isArray = (arr) => Array.isArray(arr);
123
- const defaultFiles = ["/px.png", "/nx.png", "/py.png", "/ny.png", "/pz.png", "/nz.png"];
124
- function useEnvironment({
125
- files = defaultFiles,
126
- path = "",
127
- preset = void 0,
128
- colorSpace = void 0,
129
- extensions
130
- } = {}) {
131
- if (preset) {
132
- validatePreset(preset);
133
- files = presetsObj[preset];
134
- path = CUBEMAP_ROOT;
135
- }
136
- const multiFile = isArray(files);
137
- const { extension, isCubemap } = getExtension(files);
138
- const loader = getLoader$1(extension);
139
- if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
140
- const renderer = useThree$1((state) => state.renderer);
141
- useLayoutEffect(() => {
142
- if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
143
- function clearGainmapTexture() {
144
- useLoader$1.clear(loader, multiFile ? [files] : files);
155
+ const is = {
156
+ obj: (a) => a === Object(a) && !is.arr(a) && typeof a !== "function",
157
+ fun: (a) => typeof a === "function",
158
+ str: (a) => typeof a === "string",
159
+ num: (a) => typeof a === "number",
160
+ boo: (a) => typeof a === "boolean",
161
+ und: (a) => a === void 0,
162
+ nul: (a) => a === null,
163
+ arr: (a) => Array.isArray(a),
164
+ equ(a, b, { arrays = "shallow", objects = "reference", strict = true } = {}) {
165
+ if (typeof a !== typeof b || !!a !== !!b) return false;
166
+ if (is.str(a) || is.num(a) || is.boo(a)) return a === b;
167
+ const isObj = is.obj(a);
168
+ if (isObj && objects === "reference") return a === b;
169
+ const isArr = is.arr(a);
170
+ if (isArr && arrays === "reference") return a === b;
171
+ if ((isArr || isObj) && a === b) return true;
172
+ let i;
173
+ for (i in a) if (!(i in b)) return false;
174
+ if (isObj && arrays === "shallow" && objects === "shallow") {
175
+ for (i in strict ? b : a) if (!is.equ(a[i], b[i], { strict, objects: "reference" })) return false;
176
+ } else {
177
+ for (i in strict ? b : a) if (a[i] !== b[i]) return false;
145
178
  }
146
- renderer.domElement.addEventListener("webglcontextlost", clearGainmapTexture, { once: true });
147
- }, [extension, files, loader, multiFile, renderer.domElement]);
148
- const loaderResult = useLoader$1(
149
- loader,
150
- multiFile ? [files] : files,
151
- (loader2) => {
152
- if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
153
- loader2.setRenderer?.(renderer);
154
- }
155
- loader2.setPath?.(path);
156
- if (extensions) extensions(loader2);
179
+ if (is.und(i)) {
180
+ if (isArr && a.length === 0 && b.length === 0) return true;
181
+ if (isObj && Object.keys(a).length === 0 && Object.keys(b).length === 0) return true;
182
+ if (a !== b) return false;
157
183
  }
158
- );
159
- let texture = multiFile ? (
160
- // @ts-ignore
161
- loaderResult[0]
162
- ) : loaderResult;
163
- if (extension === "jpg" || extension === "jpeg" || extension === "webp") {
164
- texture = texture.renderTarget?.texture;
184
+ return true;
165
185
  }
166
- texture.mapping = isCubemap ? CubeReflectionMapping : EquirectangularReflectionMapping;
167
- texture.colorSpace = colorSpace ?? (isCubemap ? "srgb" : "srgb-linear");
168
- return texture;
169
- }
170
- const preloadDefaultOptions = {
171
- files: defaultFiles,
172
- path: "",
173
- preset: void 0,
174
- extensions: void 0
175
186
  };
176
- useEnvironment.preload = (preloadOptions) => {
177
- const options = { ...preloadDefaultOptions, ...preloadOptions };
178
- let { files, path = "" } = options;
179
- const { preset, extensions } = options;
180
- if (preset) {
181
- validatePreset(preset);
182
- files = presetsObj[preset];
183
- path = CUBEMAP_ROOT;
187
+ const isOrthographicCamera = (def) => def && def.isOrthographicCamera;
188
+ const isRef$1 = (obj) => obj !== null && typeof obj === "object" && obj.hasOwnProperty("current");
189
+ const isColorRepresentation = (value) => value != null && (typeof value === "string" || typeof value === "number" || value.isColor);
190
+ const isObject3D = (object) => object?.isObject3D;
191
+ const isTexture = (value) => !!value?.isTexture;
192
+ const isVectorLike = (object) => object !== null && typeof object === "object" && "set" in object && typeof object.set === "function";
193
+ const isCopyable = (object) => isVectorLike(object) && "copy" in object && typeof object.copy === "function";
194
+ const hasConstructor = (object) => !!object?.constructor;
195
+
196
+ function calculateDpr(dpr) {
197
+ const target = typeof window !== "undefined" ? window.devicePixelRatio ?? 2 : 1;
198
+ return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], target), dpr[1]) : dpr;
199
+ }
200
+ function getUuidPrefix(uuid) {
201
+ return uuid.split("-")[0];
202
+ }
203
+ function updateCamera(camera, size) {
204
+ if (camera.manual) return;
205
+ if (isOrthographicCamera(camera)) {
206
+ camera.left = size.width / -2;
207
+ camera.right = size.width / 2;
208
+ camera.top = size.height / 2;
209
+ camera.bottom = size.height / -2;
210
+ } else {
211
+ camera.aspect = size.width / size.height;
184
212
  }
185
- const { extension } = getExtension(files);
186
- if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
187
- throw new Error("useEnvironment: Preloading gainmaps is not supported");
213
+ camera.updateProjectionMatrix();
214
+ }
215
+ const frustumMatrix = new Matrix4();
216
+ function updateFrustum(camera, frustum) {
217
+ const target = frustum ?? new Frustum();
218
+ frustumMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
219
+ target.setFromProjectionMatrix(frustumMatrix);
220
+ return target;
221
+ }
222
+
223
+ const REACT_INTERNAL_PROPS = ["children", "key", "ref"];
224
+ function findInitialRoot(instance) {
225
+ let root = instance.root;
226
+ while (root.getState().previousRoot) root = root.getState().previousRoot;
227
+ return root;
228
+ }
229
+ function getRootState(obj) {
230
+ let state = obj.__r3f?.root.getState();
231
+ if (!state) {
232
+ obj.traverseAncestors((ancestor) => {
233
+ const parentState = ancestor.__r3f?.root.getState();
234
+ if (parentState) {
235
+ state = parentState;
236
+ return false;
237
+ }
238
+ });
188
239
  }
189
- const loader = getLoader$1(extension);
190
- if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
191
- useLoader$1.preload(loader, isArray(files) ? [files] : files, (loader2) => {
192
- loader2.setPath?.(path);
193
- if (extensions) extensions(loader2);
194
- });
195
- };
196
- const clearDefaultOptins = {
197
- files: defaultFiles,
198
- preset: void 0
199
- };
200
- useEnvironment.clear = (clearOptions) => {
201
- const options = { ...clearDefaultOptins, ...clearOptions };
202
- let { files } = options;
203
- const { preset } = options;
204
- if (preset) {
205
- validatePreset(preset);
206
- files = presetsObj[preset];
240
+ return state;
241
+ }
242
+ function buildGraph(object) {
243
+ const data = { nodes: {}, materials: {}, meshes: {} };
244
+ if (object) {
245
+ object.traverse((obj) => {
246
+ if (obj.name) data.nodes[obj.name] = obj;
247
+ if (obj.material) {
248
+ const material = Array.isArray(obj.material) ? obj.material[0] : obj.material;
249
+ const nameAlreadyUsed = data.materials[material.name];
250
+ let materialName = material.name;
251
+ if (nameAlreadyUsed) {
252
+ materialName = materialName + `-${getUuidPrefix(material.uuid)}`;
253
+ material.userData.materialCacheName = materialName;
254
+ }
255
+ data.materials[materialName] = material;
256
+ }
257
+ if (obj.isMesh && !data.meshes[obj.name]) data.meshes[obj.name] = obj;
258
+ });
207
259
  }
208
- const { extension } = getExtension(files);
209
- const loader = getLoader$1(extension);
210
- if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
211
- useLoader$1.clear(loader, isArray(files) ? [files] : files);
212
- };
213
- function validatePreset(preset) {
214
- if (!(preset in presetsObj)) throw new Error("Preset must be one of: " + Object.keys(presetsObj).join(", "));
260
+ return data;
215
261
  }
216
- function getExtension(files) {
217
- const isCubemap = isArray(files) && files.length === 6;
218
- const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
219
- const firstEntry = isArray(files) ? files[0] : files;
220
- const extension = isCubemap ? "cube" : isGainmap ? "webp" : firstEntry.startsWith("data:application/exr") ? "exr" : firstEntry.startsWith("data:application/hdr") ? "hdr" : firstEntry.startsWith("data:image/jpeg") ? "jpg" : firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
221
- return { extension, isCubemap, isGainmap };
262
+ function dispose(obj) {
263
+ if (obj.type !== "Scene") obj.dispose?.();
264
+ for (const p in obj) {
265
+ const prop = obj[p];
266
+ if (prop?.type !== "Scene") prop?.dispose?.();
267
+ }
222
268
  }
223
- function getLoader$1(extension) {
224
- const loader = extension === "cube" ? CubeTextureLoader : extension === "hdr" ? HDRLoader : extension === "exr" ? EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader : extension === "webp" ? GainMapLoader : null;
225
- return loader;
269
+ function getInstanceProps(pendingProps) {
270
+ const props = {};
271
+ for (const key in pendingProps) {
272
+ if (!REACT_INTERNAL_PROPS.includes(key)) props[key] = pendingProps[key];
273
+ }
274
+ return props;
275
+ }
276
+ function prepare(target, root, type, props) {
277
+ const object = target;
278
+ let instance = object?.__r3f;
279
+ if (!instance) {
280
+ instance = {
281
+ root,
282
+ type,
283
+ parent: null,
284
+ children: [],
285
+ props: getInstanceProps(props),
286
+ object,
287
+ eventCount: 0,
288
+ handlers: {},
289
+ isHidden: false
290
+ };
291
+ if (object) object.__r3f = instance;
292
+ }
293
+ return instance;
294
+ }
295
+ function invalidateInstance(instance) {
296
+ if (!instance.parent) return;
297
+ const state = instance.root?.getState?.();
298
+ if (state && state.internal.frames === 0) state.invalidate();
226
299
  }
227
300
 
228
- const isRef$1 = (obj) => obj.current && obj.current.isScene;
229
- const resolveScene = (scene) => isRef$1(scene) ? scene.current : scene;
230
- function setEnvProps(background, scene, defaultScene, texture, sceneProps = {}) {
231
- sceneProps = {
232
- backgroundBlurriness: 0,
233
- backgroundIntensity: 1,
234
- backgroundRotation: [0, 0, 0],
235
- environmentIntensity: 1,
236
- environmentRotation: [0, 0, 0],
237
- ...sceneProps
238
- };
239
- const target = resolveScene(scene || defaultScene);
240
- const oldbg = target.background;
241
- const oldenv = target.environment;
242
- const oldSceneProps = {
243
- // @ts-ignore
244
- backgroundBlurriness: target.backgroundBlurriness,
245
- // @ts-ignore
246
- backgroundIntensity: target.backgroundIntensity,
247
- // @ts-ignore
248
- backgroundRotation: target.backgroundRotation?.clone?.() ?? [0, 0, 0],
249
- // @ts-ignore
250
- environmentIntensity: target.environmentIntensity,
251
- // @ts-ignore
252
- environmentRotation: target.environmentRotation?.clone?.() ?? [0, 0, 0]
301
+ const tempFrustum = new Frustum();
302
+ let hasWarnedWebGL = false;
303
+ let tslModule = null;
304
+ async function loadTSL() {
305
+ if (tslModule) return tslModule;
306
+ try {
307
+ const tsl = await import('three/tsl');
308
+ tslModule = { uniform: tsl.uniform, nodeObject: tsl.nodeObject };
309
+ return tslModule;
310
+ } catch {
311
+ return null;
312
+ }
313
+ }
314
+ function createOcclusionObserverNode(store, uniform) {
315
+ const node = new Node("float");
316
+ node.updateType = NodeUpdateType.OBJECT;
317
+ node.update = function(frame) {
318
+ const { internal } = store.getState();
319
+ const registry = internal.visibilityRegistry;
320
+ const cache = internal.occlusionCache;
321
+ for (const entry of registry.values()) {
322
+ const { object, handlers } = entry;
323
+ if (handlers.onOccluded || handlers.onVisible) {
324
+ const isOccluded = frame.renderer.isOccluded(object);
325
+ cache.set(object, isOccluded);
326
+ }
327
+ }
253
328
  };
254
- if (background !== "only") target.environment = texture;
255
- if (background) target.background = texture;
256
- applyProps$1(target, sceneProps);
257
- return () => {
258
- if (background !== "only") target.environment = oldenv;
259
- if (background) target.background = oldbg;
260
- applyProps$1(target, oldSceneProps);
329
+ node.setup = function() {
330
+ return uniform(0);
261
331
  };
332
+ return node;
262
333
  }
263
- function EnvironmentMap({ scene, background = false, map, ...config }) {
264
- const defaultScene = useThree$1((state) => state.scene);
265
- React.useLayoutEffect(() => {
266
- if (map) return setEnvProps(background, scene, defaultScene, map, config);
267
- });
268
- return null;
334
+ let occlusionSetupPromise = null;
335
+ function enableOcclusion(store) {
336
+ const state = store.getState();
337
+ const { internal, renderer } = state;
338
+ if (internal.occlusionEnabled || occlusionSetupPromise) return;
339
+ const hasOcclusionSupport = typeof renderer?.isOccluded === "function";
340
+ if (!hasOcclusionSupport) {
341
+ if (!hasWarnedWebGL) {
342
+ console.warn(
343
+ "[R3F] Warning: onOccluded/onVisible occlusion queries require WebGPU renderer. Occlusion events will not fire on WebGL."
344
+ );
345
+ hasWarnedWebGL = true;
346
+ }
347
+ return;
348
+ }
349
+ occlusionSetupPromise = setupOcclusion(store);
269
350
  }
270
- function EnvironmentCube({
271
- background = false,
272
- scene,
273
- blur,
274
- backgroundBlurriness,
275
- backgroundIntensity,
276
- backgroundRotation,
277
- environmentIntensity,
278
- environmentRotation,
279
- ...rest
280
- }) {
281
- const texture = useEnvironment(rest);
282
- const defaultScene = useThree$1((state) => state.scene);
283
- React.useLayoutEffect(() => {
284
- return setEnvProps(background, scene, defaultScene, texture, {
285
- backgroundBlurriness: blur ?? backgroundBlurriness,
286
- backgroundIntensity,
287
- backgroundRotation,
288
- environmentIntensity,
289
- environmentRotation
290
- });
351
+ async function setupOcclusion(store) {
352
+ const state = store.getState();
353
+ const { internal, rootScene, set } = state;
354
+ const tsl = await loadTSL();
355
+ if (!tsl) {
356
+ console.warn("[R3F] Warning: TSL module not available. Occlusion queries disabled.");
357
+ occlusionSetupPromise = null;
358
+ return;
359
+ }
360
+ const { uniform, nodeObject } = tsl;
361
+ let helperGroup = internal.helperGroup;
362
+ if (!helperGroup) {
363
+ helperGroup = new Group();
364
+ helperGroup.name = "__r3fInternal";
365
+ helperGroup.__r3fInternal = true;
366
+ rootScene.add(helperGroup);
367
+ }
368
+ const geometry = new BoxGeometry(1, 1, 1);
369
+ const material = new MeshBasicNodeMaterial({
370
+ transparent: true,
371
+ opacity: 0
291
372
  });
292
- React.useEffect(() => {
293
- return () => {
294
- texture.dispose();
295
- };
296
- }, [texture]);
297
- return null;
298
- }
299
- function EnvironmentPortal({
300
- children,
301
- near = 0.1,
302
- far = 1e3,
303
- resolution = 256,
304
- frames = 1,
305
- map,
306
- background = false,
307
- blur,
308
- backgroundBlurriness,
309
- backgroundIntensity,
310
- backgroundRotation,
311
- environmentIntensity,
312
- environmentRotation,
313
- scene,
314
- files,
315
- path,
316
- preset = void 0,
317
- extensions
318
- }) {
319
- const renderer = useThree$1((state) => state.renderer);
320
- const isLegacy = useThree$1((state) => state.isLegacy);
321
- const defaultScene = useThree$1((state) => state.scene);
322
- const camera = React.useRef(null);
323
- const [virtualScene] = React.useState(() => new Scene());
324
- const fbo = React.useMemo(() => {
325
- const fbo2 = isLegacy ? new WebGLCubeRenderTarget(resolution) : new CubeRenderTarget(resolution);
326
- fbo2.texture.type = HalfFloatType;
327
- return fbo2;
328
- }, [resolution, isLegacy]);
329
- React.useEffect(() => {
330
- return () => {
331
- fbo.dispose();
332
- };
333
- }, [fbo]);
334
- React.useLayoutEffect(() => {
335
- if (frames === 1) {
336
- const autoClear = renderer.autoClear;
337
- renderer.autoClear = true;
338
- camera.current.update(renderer, virtualScene);
339
- renderer.autoClear = autoClear;
340
- }
341
- return setEnvProps(background, scene, defaultScene, fbo.texture, {
342
- backgroundBlurriness: blur ?? backgroundBlurriness,
343
- backgroundIntensity,
344
- backgroundRotation,
345
- environmentIntensity,
346
- environmentRotation
347
- });
348
- }, [
349
- children,
350
- virtualScene,
351
- fbo.texture,
352
- scene,
353
- defaultScene,
354
- background,
355
- frames,
356
- renderer,
357
- blur,
358
- backgroundBlurriness,
359
- backgroundIntensity,
360
- backgroundRotation,
361
- environmentIntensity,
362
- environmentRotation
363
- ]);
364
- let count = 1;
365
- useFrame$1(() => {
366
- if (frames === Infinity || count < frames) {
367
- const autoClear = renderer.autoClear;
368
- renderer.autoClear = true;
369
- camera.current.update(renderer, virtualScene);
370
- renderer.autoClear = autoClear;
371
- count++;
373
+ const observerNode = nodeObject(createOcclusionObserverNode(store, uniform));
374
+ material.colorNode = observerNode;
375
+ material.needsUpdate = true;
376
+ const mesh = new Mesh(geometry, material);
377
+ mesh.name = "__r3fOcclusionObserver";
378
+ mesh.scale.setScalar(1e-4);
379
+ mesh.frustumCulled = false;
380
+ mesh.__r3fInternal = true;
381
+ helperGroup.add(mesh);
382
+ set((state2) => ({
383
+ internal: {
384
+ ...state2.internal,
385
+ helperGroup,
386
+ occlusionObserver: mesh,
387
+ occlusionEnabled: true
372
388
  }
373
- });
374
- return /* @__PURE__ */ jsx(Fragment, { children: createPortal$1(
375
- /* @__PURE__ */ jsxs(Fragment, { children: [
376
- children,
377
- /* @__PURE__ */ jsx("cubeCamera", { ref: camera, args: [near, far, fbo] }),
378
- files || preset ? /* @__PURE__ */ jsx(EnvironmentCube, { background: true, files, preset, path, extensions }) : map ? /* @__PURE__ */ jsx(EnvironmentMap, { background: true, map, extensions }) : null
379
- ] }),
380
- virtualScene
381
- ) });
389
+ }));
390
+ occlusionSetupPromise = null;
382
391
  }
383
- function EnvironmentGround(props) {
384
- const textureDefault = useEnvironment(props);
385
- const texture = props.map || textureDefault;
386
- React.useMemo(() => extend$1({ GroundProjectedEnvImpl: GroundedSkybox }), []);
387
- React.useEffect(() => {
388
- return () => {
389
- textureDefault.dispose();
390
- };
391
- }, [textureDefault]);
392
- const height = props.ground?.height ?? 15;
393
- const radius = props.ground?.radius ?? 60;
394
- const scale = props.ground?.scale ?? 1e3;
395
- const args = React.useMemo(
396
- () => [texture, height, radius],
397
- [texture, height, radius]
398
- );
399
- return /* @__PURE__ */ jsxs(Fragment, { children: [
400
- /* @__PURE__ */ jsx(EnvironmentMap, { ...props, map: texture }),
401
- /* @__PURE__ */ jsx("groundProjectedEnvImpl", { args, scale })
402
- ] });
403
- }
404
- function EnvironmentColor({ color, scene }) {
405
- const defaultScene = useThree$1((state) => state.scene);
406
- React.useLayoutEffect(() => {
407
- if (color === void 0) return;
408
- const target = resolveScene(scene || defaultScene);
409
- const oldBg = target.background;
410
- target.background = new Color(color);
411
- return () => {
412
- target.background = oldBg;
413
- };
414
- });
415
- return null;
416
- }
417
- function EnvironmentDualSource(props) {
418
- const { backgroundFiles, ...envProps } = props;
419
- return /* @__PURE__ */ jsxs(Fragment, { children: [
420
- /* @__PURE__ */ jsx(EnvironmentCube, { ...envProps, background: false }),
421
- /* @__PURE__ */ jsx(EnvironmentCube, { ...props, files: backgroundFiles, background: "only" })
422
- ] });
423
- }
424
- function Environment(props) {
425
- if (props.color && !props.files && !props.preset && !props.map) {
426
- return /* @__PURE__ */ jsx(EnvironmentColor, { ...props });
392
+ function disableOcclusion(store) {
393
+ const { internal, set } = store.getState();
394
+ if (!internal.occlusionEnabled) return;
395
+ if (internal.occlusionObserver) {
396
+ internal.occlusionObserver.removeFromParent();
397
+ internal.occlusionObserver.geometry.dispose();
398
+ internal.occlusionObserver.material.dispose();
427
399
  }
428
- if (props.backgroundFiles && props.backgroundFiles !== props.files) {
429
- return /* @__PURE__ */ jsx(EnvironmentDualSource, { ...props });
400
+ internal.occlusionCache.clear();
401
+ set((state) => ({
402
+ internal: {
403
+ ...state.internal,
404
+ occlusionObserver: null,
405
+ occlusionEnabled: false
406
+ }
407
+ }));
408
+ }
409
+ function cleanupHelperGroup(store) {
410
+ const { internal, set } = store.getState();
411
+ disableOcclusion(store);
412
+ if (internal.helperGroup) {
413
+ internal.helperGroup.removeFromParent();
414
+ set((state) => ({
415
+ internal: {
416
+ ...state.internal,
417
+ helperGroup: null
418
+ }
419
+ }));
430
420
  }
431
- return props.ground ? /* @__PURE__ */ jsx(EnvironmentGround, { ...props }) : props.map ? /* @__PURE__ */ jsx(EnvironmentMap, { ...props }) : props.children ? /* @__PURE__ */ jsx(EnvironmentPortal, { ...props }) : /* @__PURE__ */ jsx(EnvironmentCube, { ...props });
432
421
  }
433
-
434
- var __defProp = Object.defineProperty;
435
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
436
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
437
- const act = React["act"];
438
- const useIsomorphicLayoutEffect = /* @__PURE__ */ (() => typeof window !== "undefined" && (window.document?.createElement || window.navigator?.product === "ReactNative"))() ? React.useLayoutEffect : React.useEffect;
439
- function useMutableCallback(fn) {
440
- const ref = React.useRef(fn);
441
- useIsomorphicLayoutEffect(() => void (ref.current = fn), [fn]);
442
- return ref;
422
+ function registerVisibility(store, object, handlers) {
423
+ const { internal } = store.getState();
424
+ const registry = internal.visibilityRegistry;
425
+ const entry = {
426
+ object,
427
+ handlers,
428
+ lastFramedState: null,
429
+ lastOccludedState: null,
430
+ lastVisibleState: null
431
+ };
432
+ registry.set(object.uuid, entry);
433
+ if (handlers.onOccluded || handlers.onVisible) {
434
+ object.occlusionTest = true;
435
+ if (!internal.occlusionEnabled) {
436
+ enableOcclusion(store);
437
+ }
438
+ }
443
439
  }
444
- function useBridge() {
445
- const fiber = useFiber();
446
- const ContextBridge = useContextBridge();
447
- return React.useMemo(
448
- () => ({ children }) => {
449
- const strict = !!traverseFiber(fiber, true, (node) => node.type === React.StrictMode);
450
- const Root = strict ? React.StrictMode : React.Fragment;
451
- return /* @__PURE__ */ jsx(Root, { children: /* @__PURE__ */ jsx(ContextBridge, { children }) });
452
- },
453
- [fiber, ContextBridge]
454
- );
440
+ function unregisterVisibility(store, object) {
441
+ const { internal } = store.getState();
442
+ internal.visibilityRegistry.delete(object.uuid);
443
+ internal.occlusionCache.delete(object);
455
444
  }
456
- function Block({ set }) {
457
- useIsomorphicLayoutEffect(() => {
458
- set(new Promise(() => null));
459
- return () => set(false);
460
- }, [set]);
461
- return null;
445
+ function updateVisibilityHandlers(store, object, handlers) {
446
+ const { internal } = store.getState();
447
+ const entry = internal.visibilityRegistry.get(object.uuid);
448
+ if (!entry) return false;
449
+ entry.handlers = handlers;
450
+ if ((handlers.onOccluded || handlers.onVisible) && !internal.occlusionEnabled) {
451
+ object.occlusionTest = true;
452
+ enableOcclusion(store);
453
+ }
454
+ return true;
462
455
  }
463
- const ErrorBoundary = /* @__PURE__ */ (() => {
464
- var _a;
465
- return _a = class extends React.Component {
466
- constructor() {
467
- super(...arguments);
468
- __publicField(this, "state", { error: false });
469
- }
470
- componentDidCatch(err) {
471
- this.props.set(err);
472
- }
473
- render() {
474
- return this.state.error ? null : this.props.children;
456
+ function checkVisibility(state) {
457
+ const { internal, camera } = state;
458
+ const registry = internal.visibilityRegistry;
459
+ if (registry.size === 0) return;
460
+ updateFrustum(camera, tempFrustum);
461
+ for (const entry of registry.values()) {
462
+ const { object, handlers, lastFramedState, lastOccludedState, lastVisibleState } = entry;
463
+ let inFrustum = null;
464
+ const computeFrustum = () => {
465
+ if (inFrustum === null) {
466
+ if (object.geometry?.boundingSphere === null) {
467
+ object.geometry?.computeBoundingSphere();
468
+ }
469
+ inFrustum = tempFrustum.intersectsObject(object);
470
+ }
471
+ return inFrustum;
472
+ };
473
+ if (handlers.onFramed) {
474
+ const currentInFrustum = computeFrustum();
475
+ if (currentInFrustum !== lastFramedState) {
476
+ entry.lastFramedState = currentInFrustum;
477
+ handlers.onFramed(currentInFrustum);
478
+ }
475
479
  }
476
- }, __publicField(_a, "getDerivedStateFromError", () => ({ error: true })), _a;
477
- })();
478
-
479
- const is = {
480
- obj: (a) => a === Object(a) && !is.arr(a) && typeof a !== "function",
481
- fun: (a) => typeof a === "function",
482
- str: (a) => typeof a === "string",
483
- num: (a) => typeof a === "number",
484
- boo: (a) => typeof a === "boolean",
485
- und: (a) => a === void 0,
486
- nul: (a) => a === null,
487
- arr: (a) => Array.isArray(a),
488
- equ(a, b, { arrays = "shallow", objects = "reference", strict = true } = {}) {
489
- if (typeof a !== typeof b || !!a !== !!b) return false;
490
- if (is.str(a) || is.num(a) || is.boo(a)) return a === b;
491
- const isObj = is.obj(a);
492
- if (isObj && objects === "reference") return a === b;
493
- const isArr = is.arr(a);
494
- if (isArr && arrays === "reference") return a === b;
495
- if ((isArr || isObj) && a === b) return true;
496
- let i;
497
- for (i in a) if (!(i in b)) return false;
498
- if (isObj && arrays === "shallow" && objects === "shallow") {
499
- for (i in strict ? b : a) if (!is.equ(a[i], b[i], { strict, objects: "reference" })) return false;
500
- } else {
501
- for (i in strict ? b : a) if (a[i] !== b[i]) return false;
480
+ let currentOcclusion = null;
481
+ if (handlers.onOccluded && internal.occlusionEnabled) {
482
+ currentOcclusion = internal.occlusionCache.get(object) ?? null;
483
+ if (currentOcclusion !== null && currentOcclusion !== lastOccludedState) {
484
+ entry.lastOccludedState = currentOcclusion;
485
+ handlers.onOccluded(currentOcclusion);
486
+ }
502
487
  }
503
- if (is.und(i)) {
504
- if (isArr && a.length === 0 && b.length === 0) return true;
505
- if (isObj && Object.keys(a).length === 0 && Object.keys(b).length === 0) return true;
506
- if (a !== b) return false;
488
+ if (handlers.onVisible) {
489
+ const currentInFrustum = computeFrustum();
490
+ if (!handlers.onFramed && currentInFrustum !== lastFramedState) {
491
+ entry.lastFramedState = currentInFrustum;
492
+ }
493
+ let isOccluded = currentOcclusion;
494
+ if (isOccluded === null && internal.occlusionEnabled) {
495
+ isOccluded = internal.occlusionCache.get(object) ?? null;
496
+ }
497
+ if (isOccluded === null) isOccluded = false;
498
+ const isVisible = currentInFrustum && !isOccluded && object.visible;
499
+ if (isVisible !== lastVisibleState) {
500
+ entry.lastVisibleState = isVisible;
501
+ handlers.onVisible(isVisible);
502
+ }
507
503
  }
508
- return true;
509
504
  }
510
- };
511
- const isOrthographicCamera = (def) => def && def.isOrthographicCamera;
512
- const isRef = (obj) => obj !== null && typeof obj === "object" && obj.hasOwnProperty("current");
513
- const isColorRepresentation = (value) => value != null && (typeof value === "string" || typeof value === "number" || value.isColor);
514
- const isObject3D = (object) => object?.isObject3D;
515
- const isTexture = (value) => !!value?.isTexture;
516
- const isVectorLike = (object) => object !== null && typeof object === "object" && "set" in object && typeof object.set === "function";
517
- const isCopyable = (object) => isVectorLike(object) && "copy" in object && typeof object.copy === "function";
518
- const hasConstructor = (object) => !!object?.constructor;
519
-
520
- function calculateDpr(dpr) {
521
- const target = typeof window !== "undefined" ? window.devicePixelRatio ?? 2 : 1;
522
- return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], target), dpr[1]) : dpr;
523
505
  }
524
- function getUuidPrefix(uuid) {
525
- return uuid.split("-")[0];
506
+ function hasVisibilityHandlers(handlers) {
507
+ if (!handlers) return false;
508
+ return !!(handlers.onFramed || handlers.onOccluded || handlers.onVisible);
526
509
  }
527
- function updateCamera(camera, size) {
528
- if (camera.manual) return;
529
- if (isOrthographicCamera(camera)) {
530
- camera.left = size.width / -2;
531
- camera.right = size.width / 2;
532
- camera.top = size.height / 2;
533
- camera.bottom = size.height / -2;
534
- } else {
535
- camera.aspect = size.width / size.height;
536
- }
537
- camera.updateProjectionMatrix();
510
+
511
+ const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
512
+ function fromRef(ref, transform) {
513
+ const marker = { [FROM_REF]: ref };
514
+ if (transform) marker.transform = transform;
515
+ return marker;
538
516
  }
539
- const frustumMatrix = new Matrix4();
540
- function updateFrustum(camera, frustum) {
541
- const target = frustum ?? new Frustum();
542
- frustumMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
543
- target.setFromProjectionMatrix(frustumMatrix);
544
- return target;
517
+ function isFromRef(value) {
518
+ return value !== null && typeof value === "object" && FROM_REF in value;
545
519
  }
546
520
 
547
- const REACT_INTERNAL_PROPS = ["children", "key", "ref"];
548
- function findInitialRoot(instance) {
549
- let root = instance.root;
550
- while (root.getState().previousRoot) root = root.getState().previousRoot;
551
- return root;
521
+ const ONCE = Symbol.for("@react-three/fiber.once");
522
+ function once(...args) {
523
+ return { [ONCE]: args.length ? args : true };
552
524
  }
553
- function getRootState(obj) {
554
- let state = obj.__r3f?.root.getState();
555
- if (!state) {
556
- obj.traverseAncestors((ancestor) => {
557
- const parentState = ancestor.__r3f?.root.getState();
558
- if (parentState) {
559
- state = parentState;
560
- return false;
561
- }
562
- });
563
- }
564
- return state;
525
+ function isOnce(value) {
526
+ return value !== null && typeof value === "object" && ONCE in value;
565
527
  }
566
- function buildGraph(object) {
567
- const data = { nodes: {}, materials: {}, meshes: {} };
568
- if (object) {
569
- object.traverse((obj) => {
570
- if (obj.name) data.nodes[obj.name] = obj;
571
- if (obj.material) {
572
- const material = Array.isArray(obj.material) ? obj.material[0] : obj.material;
573
- const nameAlreadyUsed = data.materials[material.name];
574
- let materialName = material.name;
575
- if (nameAlreadyUsed) {
576
- materialName = materialName + `-${getUuidPrefix(material.uuid)}`;
577
- material.userData.materialCacheName = materialName;
578
- }
579
- data.materials[materialName] = material;
580
- }
581
- if (obj.isMesh && !data.meshes[obj.name]) data.meshes[obj.name] = obj;
582
- });
528
+
529
+ const shownNotices = /* @__PURE__ */ new Set();
530
+ function notifyDepreciated({ heading, body, link }) {
531
+ if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_DEPRECATION_WARNINGS !== "true") {
532
+ return;
583
533
  }
584
- return data;
585
- }
586
- function dispose(obj) {
587
- if (obj.type !== "Scene") obj.dispose?.();
588
- for (const p in obj) {
589
- const prop = obj[p];
590
- if (prop?.type !== "Scene") prop?.dispose?.();
534
+ if (shownNotices.has(heading)) return;
535
+ shownNotices.add(heading);
536
+ const caller = getCallerFrame();
537
+ if (caller) {
538
+ console.log();
591
539
  }
592
- }
593
- function getInstanceProps(pendingProps) {
594
- const props = {};
595
- for (const key in pendingProps) {
596
- if (!REACT_INTERNAL_PROPS.includes(key)) props[key] = pendingProps[key];
540
+ const boxStyle = "background: #ff9800; color: #1a1a1a; padding: 8px 12px; border-radius: 4px; font-weight: 500;";
541
+ if (caller) {
542
+ console.log(`%c\u26A0\uFE0F ${heading}`, boxStyle);
543
+ }
544
+ if (body || link) {
545
+ let message = "";
546
+ if (body) message += body;
547
+ if (link) message += (body ? "\n\n" : "") + `More info: ${link}`;
548
+ console.warn(`%c${message}`, "font-weight: bold;");
597
549
  }
598
- return props;
599
550
  }
600
- function prepare(target, root, type, props) {
601
- const object = target;
602
- let instance = object?.__r3f;
603
- if (!instance) {
604
- instance = {
605
- root,
606
- type,
607
- parent: null,
608
- children: [],
609
- props: getInstanceProps(props),
610
- object,
611
- eventCount: 0,
612
- handlers: {},
613
- isHidden: false
614
- };
615
- if (object) object.__r3f = instance;
551
+ function getCallerFrame(depth = 3) {
552
+ const stack = new Error().stack;
553
+ if (!stack) return null;
554
+ const lines = stack.split("\n");
555
+ const frame = lines[depth];
556
+ if (!frame) return null;
557
+ let match = frame.match(/^\s*at (?:(.+?) )?\(?(.+?):(\d+):(\d+)\)?$/);
558
+ if (!match) {
559
+ match = frame.match(/^(?:(.+?)@)?(.+?):(\d+):(\d+)$/);
616
560
  }
617
- return instance;
561
+ if (!match) return null;
562
+ const [, fn, url, line] = match;
563
+ return {
564
+ functionName: fn ?? "<anonymous>",
565
+ location: formatLocation(url, Number(line))
566
+ };
618
567
  }
619
- function invalidateInstance(instance) {
620
- if (!instance.parent) return;
621
- instance.props.onUpdate?.(instance.object);
622
- const state = instance.root?.getState?.();
623
- if (state && state.internal.frames === 0) state.invalidate();
568
+ function formatLocation(url, line) {
569
+ const clean = url.split("?")[0];
570
+ const file = clean.split("/").pop() ?? clean;
571
+ return `${file}:${line}`;
624
572
  }
625
-
626
- const tempFrustum = new Frustum();
627
- let hasWarnedWebGL = false;
628
- let tslModule = null;
629
- async function loadTSL() {
630
- if (tslModule) return tslModule;
631
- try {
632
- const tsl = await import('three/tsl');
633
- tslModule = { uniform: tsl.uniform, nodeObject: tsl.nodeObject };
634
- return tslModule;
635
- } catch {
636
- return null;
573
+ function notifyAlpha({ message, link }) {
574
+ if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_ALPHA_WARNINGS !== "true") {
575
+ return;
576
+ }
577
+ if (shownNotices.has(message)) return;
578
+ shownNotices.add(message);
579
+ const boxStyle = "background: #6366f1; color: #ffffff; padding: 6px 10px; border-radius: 4px; font-weight: 500;";
580
+ console.log(`%c\u{1F52C} ${message}`, boxStyle);
581
+ {
582
+ console.log(`%cMore info: ${link}`, "color: #6366f1; font-weight: normal;");
637
583
  }
638
584
  }
639
- function createOcclusionObserverNode(store, uniform) {
640
- const node = new Node("float");
641
- node.updateType = NodeUpdateType.OBJECT;
642
- node.update = function(frame) {
643
- const { internal } = store.getState();
644
- const registry = internal.visibilityRegistry;
645
- const cache = internal.occlusionCache;
646
- for (const entry of registry.values()) {
647
- const { object, handlers } = entry;
648
- if (handlers.onOccluded || handlers.onVisible) {
649
- const isOccluded = frame.renderer.isOccluded(object);
650
- cache.set(object, isOccluded);
585
+
586
+ const RESERVED_PROPS = [
587
+ "children",
588
+ "key",
589
+ "ref",
590
+ // Instance props
591
+ "args",
592
+ "dispose",
593
+ "attach",
594
+ "object",
595
+ // Behavior flags
596
+ "dispose"
597
+ ];
598
+ const EVENT_REGEX = /^on(Pointer|Drag|Drop|Click|DoubleClick|ContextMenu|Wheel)/;
599
+ const VISIBILITY_EVENT_REGEX = /^on(Framed|Occluded|Visible)$/;
600
+ const INDEX_REGEX = /-\d+$/;
601
+ const MEMOIZED_PROTOTYPES = /* @__PURE__ */ new Map();
602
+ const colorMaps = ["map", "emissiveMap", "sheenColorMap", "specularColorMap", "envMap"];
603
+ function resolve(root, key) {
604
+ if (!key.includes("-")) return { root, key, target: root[key] };
605
+ if (key in root) return { root, key, target: root[key] };
606
+ const originalKey = key;
607
+ let target = root;
608
+ const parts = key.split("-");
609
+ for (const part of parts) {
610
+ if (typeof target !== "object" || target === null) {
611
+ if (target !== void 0) {
612
+ const remaining = parts.slice(parts.indexOf(part)).join("-");
613
+ return { root: target, key: remaining, target: void 0 };
651
614
  }
615
+ return { root, key: originalKey, target: void 0 };
652
616
  }
653
- };
654
- node.setup = function() {
655
- return uniform(0);
656
- };
657
- return node;
617
+ key = part;
618
+ root = target;
619
+ target = target[key];
620
+ }
621
+ return { root, key, target };
658
622
  }
659
- let occlusionSetupPromise = null;
660
- function enableOcclusion(store) {
661
- const state = store.getState();
662
- const { internal, renderer } = state;
663
- if (internal.occlusionEnabled || occlusionSetupPromise) return;
664
- const hasOcclusionSupport = typeof renderer?.isOccluded === "function";
665
- if (!hasOcclusionSupport) {
666
- if (!hasWarnedWebGL) {
667
- console.warn(
668
- "[R3F] Warning: onOccluded/onVisible occlusion queries require WebGPU renderer. Occlusion events will not fire on WebGL."
669
- );
670
- hasWarnedWebGL = true;
623
+ function attach(parent, child) {
624
+ if (is.str(child.props.attach)) {
625
+ if (INDEX_REGEX.test(child.props.attach)) {
626
+ const index = child.props.attach.replace(INDEX_REGEX, "");
627
+ const { root: root2, key: key2 } = resolve(parent.object, index);
628
+ if (!Array.isArray(root2[key2])) root2[key2] = [];
671
629
  }
672
- return;
630
+ const { root, key } = resolve(parent.object, child.props.attach);
631
+ child.previousAttach = root[key];
632
+ root[key] = child.object;
633
+ } else if (is.fun(child.props.attach)) {
634
+ child.previousAttach = child.props.attach(parent.object, child.object);
673
635
  }
674
- occlusionSetupPromise = setupOcclusion(store);
675
636
  }
676
- async function setupOcclusion(store) {
677
- const state = store.getState();
678
- const { internal, rootScene, set } = state;
679
- const tsl = await loadTSL();
680
- if (!tsl) {
681
- console.warn("[R3F] Warning: TSL module not available. Occlusion queries disabled.");
682
- occlusionSetupPromise = null;
683
- return;
684
- }
685
- const { uniform, nodeObject } = tsl;
686
- let helperGroup = internal.helperGroup;
687
- if (!helperGroup) {
688
- helperGroup = new Group();
689
- helperGroup.name = "__r3fInternal";
690
- helperGroup.__r3fInternal = true;
691
- rootScene.add(helperGroup);
637
+ function detach(parent, child) {
638
+ if (is.str(child.props.attach)) {
639
+ const { root, key } = resolve(parent.object, child.props.attach);
640
+ const previous = child.previousAttach;
641
+ if (previous === void 0) delete root[key];
642
+ else root[key] = previous;
643
+ } else {
644
+ child.previousAttach?.(parent.object, child.object);
692
645
  }
693
- const geometry = new BoxGeometry(1, 1, 1);
694
- const material = new MeshBasicNodeMaterial({
695
- transparent: true,
696
- opacity: 0
697
- });
698
- const observerNode = nodeObject(createOcclusionObserverNode(store, uniform));
699
- material.colorNode = observerNode;
700
- material.needsUpdate = true;
701
- const mesh = new Mesh(geometry, material);
702
- mesh.name = "__r3fOcclusionObserver";
703
- mesh.scale.setScalar(1e-4);
704
- mesh.frustumCulled = false;
705
- mesh.__r3fInternal = true;
706
- helperGroup.add(mesh);
707
- set((state2) => ({
708
- internal: {
709
- ...state2.internal,
710
- helperGroup,
711
- occlusionObserver: mesh,
712
- occlusionEnabled: true
646
+ delete child.previousAttach;
647
+ }
648
+ function getMemoizedPrototype(root) {
649
+ let ctor = MEMOIZED_PROTOTYPES.get(root.constructor);
650
+ try {
651
+ if (!ctor) {
652
+ ctor = new root.constructor();
653
+ MEMOIZED_PROTOTYPES.set(root.constructor, ctor);
713
654
  }
714
- }));
715
- occlusionSetupPromise = null;
716
- }
717
- function disableOcclusion(store) {
718
- const { internal, set } = store.getState();
719
- if (!internal.occlusionEnabled) return;
720
- if (internal.occlusionObserver) {
721
- internal.occlusionObserver.removeFromParent();
722
- internal.occlusionObserver.geometry.dispose();
723
- internal.occlusionObserver.material.dispose();
724
- }
725
- internal.occlusionCache.clear();
726
- set((state) => ({
727
- internal: {
728
- ...state.internal,
729
- occlusionObserver: null,
730
- occlusionEnabled: false
731
- }
732
- }));
733
- }
734
- function cleanupHelperGroup(store) {
735
- const { internal, set } = store.getState();
736
- disableOcclusion(store);
737
- if (internal.helperGroup) {
738
- internal.helperGroup.removeFromParent();
739
- set((state) => ({
740
- internal: {
741
- ...state.internal,
742
- helperGroup: null
743
- }
744
- }));
745
- }
746
- }
747
- function registerVisibility(store, object, handlers) {
748
- const { internal } = store.getState();
749
- const registry = internal.visibilityRegistry;
750
- const entry = {
751
- object,
752
- handlers,
753
- lastFramedState: null,
754
- lastOccludedState: null,
755
- lastVisibleState: null
756
- };
757
- registry.set(object.uuid, entry);
758
- if (handlers.onOccluded || handlers.onVisible) {
759
- object.occlusionTest = true;
760
- if (!internal.occlusionEnabled) {
761
- enableOcclusion(store);
762
- }
763
- }
764
- }
765
- function unregisterVisibility(store, object) {
766
- const { internal } = store.getState();
767
- internal.visibilityRegistry.delete(object.uuid);
768
- internal.occlusionCache.delete(object);
769
- }
770
- function updateVisibilityHandlers(store, object, handlers) {
771
- const { internal } = store.getState();
772
- const entry = internal.visibilityRegistry.get(object.uuid);
773
- if (!entry) return false;
774
- entry.handlers = handlers;
775
- if ((handlers.onOccluded || handlers.onVisible) && !internal.occlusionEnabled) {
776
- object.occlusionTest = true;
777
- enableOcclusion(store);
778
- }
779
- return true;
780
- }
781
- function checkVisibility(state) {
782
- const { internal, camera } = state;
783
- const registry = internal.visibilityRegistry;
784
- if (registry.size === 0) return;
785
- updateFrustum(camera, tempFrustum);
786
- for (const entry of registry.values()) {
787
- const { object, handlers, lastFramedState, lastOccludedState, lastVisibleState } = entry;
788
- let inFrustum = null;
789
- const computeFrustum = () => {
790
- if (inFrustum === null) {
791
- if (object.geometry?.boundingSphere === null) {
792
- object.geometry?.computeBoundingSphere();
793
- }
794
- inFrustum = tempFrustum.intersectsObject(object);
795
- }
796
- return inFrustum;
797
- };
798
- if (handlers.onFramed) {
799
- const currentInFrustum = computeFrustum();
800
- if (currentInFrustum !== lastFramedState) {
801
- entry.lastFramedState = currentInFrustum;
802
- handlers.onFramed(currentInFrustum);
803
- }
804
- }
805
- let currentOcclusion = null;
806
- if (handlers.onOccluded && internal.occlusionEnabled) {
807
- currentOcclusion = internal.occlusionCache.get(object) ?? null;
808
- if (currentOcclusion !== null && currentOcclusion !== lastOccludedState) {
809
- entry.lastOccludedState = currentOcclusion;
810
- handlers.onOccluded(currentOcclusion);
811
- }
812
- }
813
- if (handlers.onVisible) {
814
- const currentInFrustum = computeFrustum();
815
- if (!handlers.onFramed && currentInFrustum !== lastFramedState) {
816
- entry.lastFramedState = currentInFrustum;
817
- }
818
- let isOccluded = currentOcclusion;
819
- if (isOccluded === null && internal.occlusionEnabled) {
820
- isOccluded = internal.occlusionCache.get(object) ?? null;
821
- }
822
- if (isOccluded === null) isOccluded = false;
823
- const isVisible = currentInFrustum && !isOccluded && object.visible;
824
- if (isVisible !== lastVisibleState) {
825
- entry.lastVisibleState = isVisible;
826
- handlers.onVisible(isVisible);
827
- }
828
- }
829
- }
830
- }
831
- function hasVisibilityHandlers(handlers) {
832
- if (!handlers) return false;
833
- return !!(handlers.onFramed || handlers.onOccluded || handlers.onVisible);
834
- }
835
-
836
- const FROM_REF = Symbol.for("@react-three/fiber.fromRef");
837
- function fromRef(ref) {
838
- return { [FROM_REF]: ref };
839
- }
840
- function isFromRef(value) {
841
- return value !== null && typeof value === "object" && FROM_REF in value;
842
- }
843
-
844
- const ONCE = Symbol.for("@react-three/fiber.once");
845
- function once(...args) {
846
- return { [ONCE]: args.length ? args : true };
847
- }
848
- function isOnce(value) {
849
- return value !== null && typeof value === "object" && ONCE in value;
850
- }
851
-
852
- const RESERVED_PROPS = [
853
- "children",
854
- "key",
855
- "ref",
856
- // Instance props
857
- "args",
858
- "dispose",
859
- "attach",
860
- "object",
861
- "onUpdate",
862
- // Behavior flags
863
- "dispose"
864
- ];
865
- const EVENT_REGEX = /^on(Pointer|Drag|Drop|Click|DoubleClick|ContextMenu|Wheel)/;
866
- const VISIBILITY_EVENT_REGEX = /^on(Framed|Occluded|Visible)$/;
867
- const INDEX_REGEX = /-\d+$/;
868
- const MEMOIZED_PROTOTYPES = /* @__PURE__ */ new Map();
869
- const colorMaps = ["map", "emissiveMap", "sheenColorMap", "specularColorMap", "envMap"];
870
- function resolve(root, key) {
871
- if (!key.includes("-")) return { root, key, target: root[key] };
872
- if (key in root) return { root, key, target: root[key] };
873
- const originalKey = key;
874
- let target = root;
875
- const parts = key.split("-");
876
- for (const part of parts) {
877
- if (typeof target !== "object" || target === null) {
878
- if (target !== void 0) {
879
- const remaining = parts.slice(parts.indexOf(part)).join("-");
880
- return { root: target, key: remaining, target: void 0 };
881
- }
882
- return { root, key: originalKey, target: void 0 };
883
- }
884
- key = part;
885
- root = target;
886
- target = target[key];
887
- }
888
- return { root, key, target };
889
- }
890
- function attach(parent, child) {
891
- if (is.str(child.props.attach)) {
892
- if (INDEX_REGEX.test(child.props.attach)) {
893
- const index = child.props.attach.replace(INDEX_REGEX, "");
894
- const { root: root2, key: key2 } = resolve(parent.object, index);
895
- if (!Array.isArray(root2[key2])) root2[key2] = [];
896
- }
897
- const { root, key } = resolve(parent.object, child.props.attach);
898
- child.previousAttach = root[key];
899
- root[key] = child.object;
900
- } else if (is.fun(child.props.attach)) {
901
- child.previousAttach = child.props.attach(parent.object, child.object);
902
- }
903
- }
904
- function detach(parent, child) {
905
- if (is.str(child.props.attach)) {
906
- const { root, key } = resolve(parent.object, child.props.attach);
907
- const previous = child.previousAttach;
908
- if (previous === void 0) delete root[key];
909
- else root[key] = previous;
910
- } else {
911
- child.previousAttach?.(parent.object, child.object);
912
- }
913
- delete child.previousAttach;
914
- }
915
- function getMemoizedPrototype(root) {
916
- let ctor = MEMOIZED_PROTOTYPES.get(root.constructor);
917
- try {
918
- if (!ctor) {
919
- ctor = new root.constructor();
920
- MEMOIZED_PROTOTYPES.set(root.constructor, ctor);
921
- }
922
- } catch {
923
- }
924
- return ctor;
655
+ } catch {
656
+ }
657
+ return ctor;
925
658
  }
926
659
  function diffProps(instance, newProps) {
927
660
  const changedProps = {};
@@ -936,11 +669,9 @@ function diffProps(instance, newProps) {
936
669
  for (const prop in instance.props) {
937
670
  if (RESERVED_PROPS.includes(prop) || newProps.hasOwnProperty(prop)) continue;
938
671
  const { root, key } = resolve(instance.object, prop);
939
- if (root.constructor && root.constructor.length === 0) {
672
+ if (typeof root?.constructor === "function") {
940
673
  const ctor = getMemoizedPrototype(root);
941
- if (!is.und(ctor)) changedProps[key] = ctor[key];
942
- } else {
943
- changedProps[key] = 0;
674
+ if (!is.und(ctor)) changedProps[prop] = ctor[key];
944
675
  }
945
676
  }
946
677
  return changedProps;
@@ -952,6 +683,13 @@ function applyProps(object, props) {
952
683
  for (const prop in props) {
953
684
  const value = props[prop];
954
685
  if (RESERVED_PROPS.includes(prop)) continue;
686
+ if (prop === "onUpdate") {
687
+ notifyDepreciated({
688
+ heading: "onUpdate is no longer an R3F prop",
689
+ body: "v10 removed the onUpdate hook: R3F no longer calls it after prop updates. The value is assigned to the object by name. On a Texture that sets three's Texture.onUpdate, which the renderer calls after a GPU upload, not after prop changes. On a node it replaces the Node.onUpdate() method. On other objects it is never called.\n\nUse an effect keyed on the props that change, read the object in useFrame, or use a ref callback.",
690
+ link: "https://docs.pmnd.rs/react-three-fiber/migration/v10#onupdate-removed"
691
+ });
692
+ }
955
693
  if (instance && EVENT_REGEX.test(prop)) {
956
694
  if (typeof value === "function") instance.handlers[prop] = value;
957
695
  else delete instance.handlers[prop];
@@ -1057,613 +795,11 @@ function applyProps(object, props) {
1057
795
  return object;
1058
796
  }
1059
797
 
1060
- const DEFAULT_POINTER_ID = 0;
1061
- const XR_POINTER_ID_START = 1e3;
1062
- function getPointerState(internal, pointerId) {
1063
- let state = internal.pointerMap.get(pointerId);
1064
- if (!state) {
1065
- state = {
1066
- hovered: /* @__PURE__ */ new Map(),
1067
- captured: /* @__PURE__ */ new Map(),
1068
- initialClick: [0, 0],
1069
- initialHits: []
1070
- };
1071
- internal.pointerMap.set(pointerId, state);
1072
- }
1073
- return state;
1074
- }
1075
- function getPointerId(event) {
1076
- return "pointerId" in event ? event.pointerId : DEFAULT_POINTER_ID;
1077
- }
1078
- function makeId(event) {
1079
- return (event.eventObject || event.object).uuid + "/" + event.index + event.instanceId;
1080
- }
1081
- function releaseInternalPointerCapture(internal, obj, pointerId) {
1082
- const pointerState = internal.pointerMap.get(pointerId);
1083
- if (!pointerState) return;
1084
- const captureData = pointerState.captured.get(obj);
1085
- if (captureData) {
1086
- pointerState.captured.delete(obj);
1087
- captureData.target.releasePointerCapture(pointerId);
1088
- }
1089
- }
1090
- function removeInteractivity(store, object) {
1091
- const { internal } = store.getState();
1092
- internal.interaction = internal.interaction.filter((o) => o !== object);
1093
- for (const [pointerId, pointerState] of internal.pointerMap) {
1094
- pointerState.initialHits = pointerState.initialHits.filter((o) => o !== object);
1095
- pointerState.hovered.forEach((value, key) => {
1096
- if (value.eventObject === object || value.object === object) {
1097
- pointerState.hovered.delete(key);
1098
- }
1099
- });
1100
- if (pointerState.captured.has(object)) {
1101
- releaseInternalPointerCapture(internal, object, pointerId);
1102
- }
1103
- }
1104
- unregisterVisibility(store, object);
1105
- }
1106
- function createEvents(store) {
1107
- function calculateDistance(event, pointerId) {
1108
- const { internal } = store.getState();
1109
- const pointerState = internal.pointerMap.get(pointerId);
1110
- if (!pointerState) return 0;
1111
- const [initialX, initialY] = pointerState.initialClick;
1112
- const dx = event.offsetX - initialX;
1113
- const dy = event.offsetY - initialY;
1114
- return Math.round(Math.sqrt(dx * dx + dy * dy));
1115
- }
1116
- function filterPointerEvents(objects) {
1117
- return objects.filter(
1118
- (obj) => ["Move", "Over", "Enter", "Out", "Leave"].some(
1119
- (name) => obj.__r3f?.handlers["onPointer" + name]
1120
- ) || ["OverEnter", "OverLeave", "Over"].some(
1121
- (name) => obj.__r3f?.handlers["onDrag" + name]
1122
- ) || obj.__r3f?.handlers.onDrop
1123
- );
1124
- }
1125
- function intersect(event, filter) {
1126
- const state = store.getState();
1127
- const duplicates = /* @__PURE__ */ new Set();
1128
- const intersections = [];
1129
- const eventsObjects = filter ? filter(state.internal.interaction) : state.internal.interaction;
1130
- for (let i = 0; i < eventsObjects.length; i++) {
1131
- const state2 = getRootState(eventsObjects[i]);
1132
- if (state2) {
1133
- state2.raycaster.camera = void 0;
1134
- }
1135
- }
1136
- if (!state.previousRoot) {
1137
- state.events.compute?.(event, state);
1138
- }
1139
- function handleRaycast(obj) {
1140
- const state2 = getRootState(obj);
1141
- if (!state2 || !state2.events.enabled || state2.raycaster.camera === null) return [];
1142
- if (state2.raycaster.camera === void 0) {
1143
- state2.events.compute?.(event, state2, state2.previousRoot?.getState());
1144
- if (state2.raycaster.camera === void 0) state2.raycaster.camera = null;
1145
- }
1146
- return state2.raycaster.camera ? state2.raycaster.intersectObject(obj, true) : [];
1147
- }
1148
- let hits = eventsObjects.flatMap(handleRaycast).sort((a, b) => {
1149
- const aInteractivePriority = a.object.userData?.interactivePriority;
1150
- const bInteractivePriority = b.object.userData?.interactivePriority;
1151
- if (aInteractivePriority !== void 0 || bInteractivePriority !== void 0) {
1152
- if (aInteractivePriority !== void 0 && bInteractivePriority === void 0) return -1;
1153
- if (bInteractivePriority !== void 0 && aInteractivePriority === void 0) return 1;
1154
- if (aInteractivePriority !== bInteractivePriority) {
1155
- return (bInteractivePriority ?? 0) - (aInteractivePriority ?? 0);
1156
- }
1157
- }
1158
- const aState = getRootState(a.object);
1159
- const bState = getRootState(b.object);
1160
- const aPriority = aState?.events?.priority ?? 1;
1161
- const bPriority = bState?.events?.priority ?? 1;
1162
- return bPriority - aPriority || a.distance - b.distance;
1163
- }).filter((item) => {
1164
- const id = makeId(item);
1165
- if (duplicates.has(id)) return false;
1166
- duplicates.add(id);
1167
- return true;
1168
- });
1169
- if (state.events.filter) hits = state.events.filter(hits, state);
1170
- for (const hit of hits) {
1171
- let eventObject = hit.object;
1172
- while (eventObject) {
1173
- if (eventObject.__r3f?.eventCount) {
1174
- intersections.push({ ...hit, eventObject });
1175
- }
1176
- eventObject = eventObject.parent;
1177
- }
1178
- }
1179
- if ("pointerId" in event) {
1180
- const pointerId = event.pointerId;
1181
- const pointerState = state.internal.pointerMap.get(pointerId);
1182
- if (pointerState?.captured.size) {
1183
- for (const captureData of pointerState.captured.values()) {
1184
- if (!duplicates.has(makeId(captureData.intersection))) intersections.push(captureData.intersection);
1185
- }
1186
- }
1187
- }
1188
- return intersections;
1189
- }
1190
- function handleIntersects(intersections, event, delta, callback) {
1191
- if (intersections.length) {
1192
- const localState = { stopped: false };
1193
- for (const hit of intersections) {
1194
- const state = getRootState(hit.object);
1195
- if (state) {
1196
- const { raycaster, pointer, camera, internal } = state;
1197
- const unprojectedPoint = new Vector3(pointer.x, pointer.y, 0).unproject(camera);
1198
- const hasPointerCapture = (id) => {
1199
- const pointerState = internal.pointerMap.get(id);
1200
- return pointerState?.captured.has(hit.eventObject) ?? false;
1201
- };
1202
- const setPointerCapture = (id) => {
1203
- const captureData = { intersection: hit, target: event.target };
1204
- const pointerState = getPointerState(internal, id);
1205
- pointerState.captured.set(hit.eventObject, captureData);
1206
- event.target.setPointerCapture(id);
1207
- };
1208
- const releasePointerCapture = (id) => {
1209
- releaseInternalPointerCapture(internal, hit.eventObject, id);
1210
- };
1211
- const extractEventProps = {};
1212
- for (const prop in event) {
1213
- const property = event[prop];
1214
- if (typeof property !== "function") extractEventProps[prop] = property;
1215
- }
1216
- const eventPointerId = "pointerId" in event ? event.pointerId : void 0;
1217
- const raycastEvent = {
1218
- ...hit,
1219
- ...extractEventProps,
1220
- pointer,
1221
- intersections,
1222
- stopped: localState.stopped,
1223
- delta,
1224
- unprojectedPoint,
1225
- ray: raycaster.ray,
1226
- camera,
1227
- pointerId: eventPointerId,
1228
- // Hijack stopPropagation, which just sets a flag
1229
- stopPropagation() {
1230
- const pointerState = eventPointerId !== void 0 ? internal.pointerMap.get(eventPointerId) : void 0;
1231
- if (
1232
- // ...if this pointer hasn't been captured
1233
- !pointerState?.captured.size || // ... or if the hit object is capturing the pointer
1234
- pointerState.captured.has(hit.eventObject)
1235
- ) {
1236
- raycastEvent.stopped = localState.stopped = true;
1237
- if (pointerState?.hovered.size && Array.from(pointerState.hovered.values()).find((i) => i.eventObject === hit.eventObject)) {
1238
- const higher = intersections.slice(0, intersections.indexOf(hit));
1239
- cancelPointer([...higher, hit], eventPointerId);
1240
- }
1241
- }
1242
- },
1243
- // there should be a distinction between target and currentTarget
1244
- target: { hasPointerCapture, setPointerCapture, releasePointerCapture },
1245
- currentTarget: { hasPointerCapture, setPointerCapture, releasePointerCapture },
1246
- nativeEvent: event
1247
- };
1248
- callback(raycastEvent);
1249
- if (localState.stopped === true) break;
1250
- }
1251
- }
1252
- }
1253
- return intersections;
1254
- }
1255
- function cancelPointer(intersections, pointerId) {
1256
- const { internal } = store.getState();
1257
- const pid = pointerId ?? DEFAULT_POINTER_ID;
1258
- const pointerState = internal.pointerMap.get(pid);
1259
- if (!pointerState) return;
1260
- for (const [hoveredId, hoveredObj] of pointerState.hovered) {
1261
- if (!intersections.length || !intersections.find(
1262
- (hit) => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId
1263
- )) {
1264
- const eventObject = hoveredObj.eventObject;
1265
- const instance = eventObject.__r3f;
1266
- pointerState.hovered.delete(hoveredId);
1267
- if (instance?.eventCount) {
1268
- const handlers = instance.handlers;
1269
- const data = { ...hoveredObj, intersections };
1270
- handlers.onPointerOut?.(data);
1271
- handlers.onPointerLeave?.(data);
1272
- handlers.onDragOverLeave?.(data);
1273
- }
1274
- }
1275
- }
1276
- }
1277
- function pointerMissed(event, objects) {
1278
- for (let i = 0; i < objects.length; i++) {
1279
- const instance = objects[i].__r3f;
1280
- instance?.handlers.onPointerMissed?.(event);
1281
- }
1282
- }
1283
- function dragOverMissed(event, objects) {
1284
- for (let i = 0; i < objects.length; i++) {
1285
- const instance = objects[i].__r3f;
1286
- instance?.handlers.onDragOverMissed?.(event);
1287
- }
1288
- }
1289
- function dropMissed(event, objects) {
1290
- for (let i = 0; i < objects.length; i++) {
1291
- const instance = objects[i].__r3f;
1292
- instance?.handlers.onDropMissed?.(event);
1293
- }
1294
- }
1295
- function cleanupPointer(pointerId) {
1296
- const { internal } = store.getState();
1297
- const pointerState = internal.pointerMap.get(pointerId);
1298
- if (pointerState) {
1299
- for (const [, hoveredObj] of pointerState.hovered) {
1300
- const eventObject = hoveredObj.eventObject;
1301
- const instance = eventObject.__r3f;
1302
- if (instance?.eventCount) {
1303
- const handlers = instance.handlers;
1304
- const data = { ...hoveredObj, intersections: [] };
1305
- handlers.onPointerOut?.(data);
1306
- handlers.onPointerLeave?.(data);
1307
- }
1308
- }
1309
- internal.pointerMap.delete(pointerId);
1310
- }
1311
- internal.pointerDirty.delete(pointerId);
1312
- }
1313
- function processDeferredPointer(event, pointerId) {
1314
- const state = store.getState();
1315
- const { internal } = state;
1316
- if (!state.events.enabled) return;
1317
- const filter = filterPointerEvents;
1318
- const hits = intersect(event, filter);
1319
- cancelPointer(hits, pointerId);
1320
- function onIntersect(data) {
1321
- const eventObject = data.eventObject;
1322
- const instance = eventObject.__r3f;
1323
- if (!instance?.eventCount) return;
1324
- const handlers = instance.handlers;
1325
- if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
1326
- const id = makeId(data);
1327
- const pointerState = getPointerState(internal, pointerId);
1328
- const hoveredItem = pointerState.hovered.get(id);
1329
- if (!hoveredItem) {
1330
- pointerState.hovered.set(id, data);
1331
- handlers.onPointerOver?.(data);
1332
- handlers.onPointerEnter?.(data);
1333
- } else if (hoveredItem.stopped) {
1334
- data.stopPropagation();
1335
- }
1336
- }
1337
- handlers.onPointerMove?.(data);
1338
- }
1339
- handleIntersects(hits, event, 0, onIntersect);
1340
- }
1341
- function handlePointer(name) {
1342
- switch (name) {
1343
- case "onPointerLeave":
1344
- case "onDragLeave":
1345
- return () => cancelPointer([]);
1346
- // Global cancel of these events
1347
- case "onPointerCancel":
1348
- return (event) => {
1349
- const pointerId = getPointerId(event);
1350
- cleanupPointer(pointerId);
1351
- };
1352
- case "onLostPointerCapture":
1353
- return (event) => {
1354
- const { internal } = store.getState();
1355
- const pointerId = getPointerId(event);
1356
- const pointerState = internal.pointerMap.get(pointerId);
1357
- if (pointerState?.captured.size) {
1358
- requestAnimationFrame(() => {
1359
- const pointerState2 = internal.pointerMap.get(pointerId);
1360
- if (pointerState2?.captured.size) {
1361
- pointerState2.captured.clear();
1362
- }
1363
- cancelPointer([], pointerId);
1364
- });
1365
- }
1366
- };
1367
- }
1368
- return function handleEvent(event) {
1369
- const state = store.getState();
1370
- const { onPointerMissed, onDragOverMissed, onDropMissed, internal, events } = state;
1371
- const pointerId = getPointerId(event);
1372
- internal.lastEvent.current = event;
1373
- if (!events.enabled) return;
1374
- const isPointerMove = name === "onPointerMove";
1375
- const isDragOver = name === "onDragOver";
1376
- const isDrop = name === "onDrop";
1377
- const isClickEvent = name === "onClick" || name === "onContextMenu" || name === "onDoubleClick";
1378
- const isPointerDown = name === "onPointerDown";
1379
- const isPointerUp = name === "onPointerUp";
1380
- const isWheel = name === "onWheel";
1381
- const canDeferRaycasts = events.frameTimedRaycasts && state.frameloop === "always";
1382
- if (isPointerMove && canDeferRaycasts) {
1383
- events.compute?.(event, state);
1384
- internal.pointerDirty.set(pointerId, event);
1385
- return;
1386
- }
1387
- if (isWheel && canDeferRaycasts && !events.alwaysFireOnScroll) {
1388
- events.compute?.(event, state);
1389
- internal.pointerDirty.set(pointerId, event);
1390
- return;
1391
- }
1392
- if ((isClickEvent || isPointerDown || isPointerUp) && internal.pointerDirty.has(pointerId)) {
1393
- const deferredEvent = internal.pointerDirty.get(pointerId);
1394
- internal.pointerDirty.delete(pointerId);
1395
- processDeferredPointer(deferredEvent, pointerId);
1396
- }
1397
- const filter = isPointerMove || isDragOver || isDrop ? filterPointerEvents : void 0;
1398
- const hits = intersect(event, filter);
1399
- const delta = isClickEvent ? calculateDistance(event, pointerId) : 0;
1400
- if (isPointerDown) {
1401
- const pointerState2 = getPointerState(internal, pointerId);
1402
- pointerState2.initialClick = [event.offsetX, event.offsetY];
1403
- pointerState2.initialHits = hits.map((hit) => hit.eventObject);
1404
- }
1405
- const pointerState = internal.pointerMap.get(pointerId);
1406
- const initialHits = pointerState?.initialHits ?? [];
1407
- if (isClickEvent && !hits.length) {
1408
- if (delta <= 2) {
1409
- pointerMissed(event, internal.interaction);
1410
- if (onPointerMissed) onPointerMissed(event);
1411
- }
1412
- }
1413
- if (isDragOver && !hits.length) {
1414
- dragOverMissed(event, internal.interaction);
1415
- if (onDragOverMissed) onDragOverMissed(event);
1416
- }
1417
- if (isDrop && !hits.length) {
1418
- dropMissed(event, internal.interaction);
1419
- if (onDropMissed) onDropMissed(event);
1420
- }
1421
- if (isPointerMove || isDragOver) {
1422
- cancelPointer(hits, pointerId);
1423
- }
1424
- function onIntersect(data) {
1425
- const eventObject = data.eventObject;
1426
- const instance = eventObject.__r3f;
1427
- if (!instance?.eventCount) return;
1428
- const handlers = instance.handlers;
1429
- if (isPointerMove) {
1430
- if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
1431
- const id = makeId(data);
1432
- const pointerState2 = getPointerState(internal, pointerId);
1433
- const hoveredItem = pointerState2.hovered.get(id);
1434
- if (!hoveredItem) {
1435
- pointerState2.hovered.set(id, data);
1436
- handlers.onPointerOver?.(data);
1437
- handlers.onPointerEnter?.(data);
1438
- } else if (hoveredItem.stopped) {
1439
- data.stopPropagation();
1440
- }
1441
- }
1442
- handlers.onPointerMove?.(data);
1443
- } else if (isDragOver) {
1444
- const id = makeId(data);
1445
- const pointerState2 = getPointerState(internal, pointerId);
1446
- const hoveredItem = pointerState2.hovered.get(id);
1447
- if (!hoveredItem) {
1448
- pointerState2.hovered.set(id, data);
1449
- handlers.onDragOverEnter?.(data);
1450
- } else if (hoveredItem.stopped) {
1451
- data.stopPropagation();
1452
- }
1453
- handlers.onDragOver?.(data);
1454
- } else if (isDrop) {
1455
- handlers.onDrop?.(data);
1456
- } else {
1457
- const handler = handlers[name];
1458
- if (handler) {
1459
- if (!isClickEvent || initialHits.includes(eventObject)) {
1460
- pointerMissed(
1461
- event,
1462
- internal.interaction.filter((object) => !initialHits.includes(object))
1463
- );
1464
- handler(data);
1465
- }
1466
- } else {
1467
- if (isClickEvent && initialHits.includes(eventObject)) {
1468
- pointerMissed(
1469
- event,
1470
- internal.interaction.filter((object) => !initialHits.includes(object))
1471
- );
1472
- }
1473
- }
1474
- }
1475
- }
1476
- handleIntersects(hits, event, delta, onIntersect);
1477
- };
1478
- }
1479
- function flushDeferredPointers() {
1480
- const { internal, events } = store.getState();
1481
- if (!events.frameTimedRaycasts) return;
1482
- for (const [pointerId, event] of internal.pointerDirty) {
1483
- processDeferredPointer(event, pointerId);
1484
- }
1485
- internal.pointerDirty.clear();
1486
- }
1487
- return { handlePointer, flushDeferredPointers, processDeferredPointer };
1488
- }
1489
- const DOM_EVENTS = {
1490
- onClick: ["click", false],
1491
- onContextMenu: ["contextmenu", false],
1492
- onDoubleClick: ["dblclick", false],
1493
- onDragEnter: ["dragenter", false],
1494
- onDragLeave: ["dragleave", false],
1495
- onDragOver: ["dragover", false],
1496
- onDrop: ["drop", false],
1497
- onWheel: ["wheel", true],
1498
- onPointerDown: ["pointerdown", true],
1499
- onPointerUp: ["pointerup", true],
1500
- onPointerLeave: ["pointerleave", true],
1501
- onPointerMove: ["pointermove", true],
1502
- onPointerCancel: ["pointercancel", true],
1503
- onLostPointerCapture: ["lostpointercapture", true]
1504
- };
1505
- function createPointerEvents(store) {
1506
- const { handlePointer, flushDeferredPointers, processDeferredPointer } = createEvents(store);
1507
- let nextXRPointerId = XR_POINTER_ID_START;
1508
- const xrPointers = /* @__PURE__ */ new Map();
1509
- return {
1510
- priority: 1,
1511
- enabled: true,
1512
- frameTimedRaycasts: true,
1513
- alwaysFireOnScroll: true,
1514
- updateOnFrame: false,
1515
- compute(event, state) {
1516
- state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
1517
- state.raycaster.setFromCamera(state.pointer, state.camera);
1518
- },
1519
- connected: void 0,
1520
- handlers: Object.keys(DOM_EVENTS).reduce(
1521
- (acc, key) => ({ ...acc, [key]: handlePointer(key) }),
1522
- {}
1523
- ),
1524
- update: (pointerId) => {
1525
- const { events, internal } = store.getState();
1526
- if (!events.handlers) return;
1527
- if (pointerId !== void 0) {
1528
- const event = internal.pointerDirty.get(pointerId);
1529
- if (event) {
1530
- internal.pointerDirty.delete(pointerId);
1531
- processDeferredPointer(event, pointerId);
1532
- } else if (internal.lastEvent?.current) {
1533
- processDeferredPointer(internal.lastEvent.current, pointerId);
1534
- }
1535
- } else {
1536
- flushDeferredPointers();
1537
- if (internal.lastEvent?.current) {
1538
- events.handlers.onPointerMove(internal.lastEvent.current);
1539
- }
1540
- }
1541
- },
1542
- flush: () => {
1543
- const { events, internal } = store.getState();
1544
- flushDeferredPointers();
1545
- if (events.updateOnFrame && internal.lastEvent?.current && events.handlers) {
1546
- events.handlers.onPointerMove(internal.lastEvent.current);
1547
- }
1548
- },
1549
- connect: (target) => {
1550
- if (!target) return;
1551
- const { set, events } = store.getState();
1552
- events.disconnect?.();
1553
- set((state) => ({ events: { ...state.events, connected: target } }));
1554
- if (events.handlers) {
1555
- for (const name in events.handlers) {
1556
- const event = events.handlers[name];
1557
- const [eventName, passive] = DOM_EVENTS[name];
1558
- target.addEventListener(eventName, event, { passive });
1559
- }
1560
- }
1561
- },
1562
- disconnect: () => {
1563
- const { set, events } = store.getState();
1564
- if (events.connected) {
1565
- if (events.handlers) {
1566
- for (const name in events.handlers) {
1567
- const event = events.handlers[name];
1568
- const [eventName] = DOM_EVENTS[name];
1569
- events.connected.removeEventListener(eventName, event);
1570
- }
1571
- }
1572
- set((state) => ({ events: { ...state.events, connected: void 0 } }));
1573
- }
1574
- },
1575
- // PREVIEW (A8): the XR pointer registration API may change before stable.
1576
- registerPointer: (config) => {
1577
- const pointerId = nextXRPointerId++;
1578
- xrPointers.set(pointerId, config);
1579
- const { internal } = store.getState();
1580
- getPointerState(internal, pointerId);
1581
- return pointerId;
1582
- },
1583
- unregisterPointer: (pointerId) => {
1584
- xrPointers.delete(pointerId);
1585
- const { internal } = store.getState();
1586
- const pointerState = internal.pointerMap.get(pointerId);
1587
- if (pointerState) {
1588
- for (const [, hoveredObj] of pointerState.hovered) {
1589
- const eventObject = hoveredObj.eventObject;
1590
- const instance = eventObject.__r3f;
1591
- if (instance?.eventCount) {
1592
- const handlers = instance.handlers;
1593
- const data = { ...hoveredObj, intersections: [] };
1594
- handlers.onPointerOut?.(data);
1595
- handlers.onPointerLeave?.(data);
1596
- }
1597
- }
1598
- internal.pointerMap.delete(pointerId);
1599
- }
1600
- internal.pointerDirty.delete(pointerId);
1601
- }
1602
- };
1603
- }
1604
-
1605
- const shownNotices = /* @__PURE__ */ new Set();
1606
- function notifyDepreciated({ heading, body, link }) {
1607
- if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_DEPRECATION_WARNINGS !== "true") {
1608
- return;
1609
- }
1610
- if (shownNotices.has(heading)) return;
1611
- shownNotices.add(heading);
1612
- const caller = getCallerFrame();
1613
- if (caller) {
1614
- console.log();
1615
- }
1616
- const boxStyle = "background: #ff9800; color: #1a1a1a; padding: 8px 12px; border-radius: 4px; font-weight: 500;";
1617
- if (caller) {
1618
- console.log(`%c\u26A0\uFE0F ${heading}`, boxStyle);
1619
- }
1620
- if (body || link) {
1621
- let message = "";
1622
- if (body) message += body;
1623
- if (link) message += (body ? "\n\n" : "") + `More info: ${link}`;
1624
- console.warn(`%c${message}`, "font-weight: bold;");
1625
- }
1626
- }
1627
- function getCallerFrame(depth = 3) {
1628
- const stack = new Error().stack;
1629
- if (!stack) return null;
1630
- const lines = stack.split("\n");
1631
- const frame = lines[depth];
1632
- if (!frame) return null;
1633
- let match = frame.match(/^\s*at (?:(.+?) )?\(?(.+?):(\d+):(\d+)\)?$/);
1634
- if (!match) {
1635
- match = frame.match(/^(?:(.+?)@)?(.+?):(\d+):(\d+)$/);
1636
- }
1637
- if (!match) return null;
1638
- const [, fn, url, line] = match;
1639
- return {
1640
- functionName: fn ?? "<anonymous>",
1641
- location: formatLocation(url, Number(line))
1642
- };
1643
- }
1644
- function formatLocation(url, line) {
1645
- const clean = url.split("?")[0];
1646
- const file = clean.split("/").pop() ?? clean;
1647
- return `${file}:${line}`;
1648
- }
1649
- function notifyAlpha({ message, link }) {
1650
- if (typeof process !== "undefined" && (process.env.NODE_ENV === "test" || process.env.JEST_WORKER_ID !== void 0) && process.env.R3F_SHOW_ALPHA_WARNINGS !== "true") {
1651
- return;
1652
- }
1653
- if (shownNotices.has(message)) return;
1654
- shownNotices.add(message);
1655
- const boxStyle = "background: #6366f1; color: #ffffff; padding: 6px 10px; border-radius: 4px; font-weight: 500;";
1656
- console.log(`%c\u{1F52C} ${message}`, boxStyle);
1657
- {
1658
- console.log(`%cMore info: ${link}`, "color: #6366f1; font-weight: normal;");
1659
- }
1660
- }
1661
-
1662
- const INTERNAL_LIB_MARKERS = ["zustand", "setState", "Object.assign"];
1663
- function isInternalRendererAccess(stack, callerDepth = 2) {
1664
- if (!stack) return false;
1665
- const caller = stack.split("\n")[callerDepth] ?? "";
1666
- return INTERNAL_LIB_MARKERS.some((m) => caller.includes(m));
798
+ const INTERNAL_LIB_MARKERS = ["zustand", "setState", "Object.assign"];
799
+ function isInternalRendererAccess(stack, callerDepth = 2) {
800
+ if (!stack) return false;
801
+ const caller = stack.split("\n")[callerDepth] ?? "";
802
+ return INTERNAL_LIB_MARKERS.some((m) => caller.includes(m));
1667
803
  }
1668
804
 
1669
805
  const R3F_CONTEXT = Symbol.for("@react-three/fiber.context");
@@ -1775,7 +911,7 @@ const createStore = (invalidate, advance) => {
1775
911
  size: newSize,
1776
912
  viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, newSize) }
1777
913
  }));
1778
- getScheduler().invalidate();
914
+ get().invalidate();
1779
915
  }
1780
916
  }
1781
917
  return;
@@ -1790,15 +926,16 @@ const createStore = (invalidate, advance) => {
1790
926
  viewport: { ...s.viewport, ...getCurrentViewport(state2.camera, defaultTarget, size) },
1791
927
  _sizeImperative: true
1792
928
  }));
1793
- getScheduler().invalidate();
929
+ get().invalidate();
1794
930
  },
1795
931
  setDpr: (dpr) => set((state2) => {
1796
932
  const resolved = calculateDpr(dpr);
1797
933
  return { viewport: { ...state2.viewport, dpr: resolved, initialDpr: state2.viewport.initialDpr || resolved } };
1798
934
  }),
1799
935
  setFrameloop: (frameloop = "always") => {
936
+ const rootId = get().internal.rootId;
937
+ if (rootId) getScheduler().setRootFrameloop(rootId, frameloop);
1800
938
  set(() => ({ frameloop }));
1801
- getScheduler().frameloop = frameloop;
1802
939
  },
1803
940
  setError: (error) => set(() => ({ error })),
1804
941
  error: null,
@@ -1914,17 +1051,11 @@ const createStore = (invalidate, advance) => {
1914
1051
  oldSize = size;
1915
1052
  oldDpr = viewport.dpr;
1916
1053
  updateCamera(camera, size);
1917
- if (internal.isSecondary && canvasTarget) {
1918
- if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
1919
- canvasTarget.setSize(size.width, size.height, false);
1920
- } else {
1921
- if (viewport.dpr > 0) actualRenderer.setPixelRatio(viewport.dpr);
1922
- actualRenderer.setSize(size.width, size.height, false);
1923
- if (canvasTarget) {
1924
- if (viewport.dpr > 0) canvasTarget.setPixelRatio(viewport.dpr);
1925
- canvasTarget.setSize(size.width, size.height, false);
1926
- }
1927
- }
1054
+ const resizeTarget = canvasTarget ?? actualRenderer;
1055
+ if (viewport.dpr > 0) resizeTarget.setPixelRatio(viewport.dpr);
1056
+ resizeTarget.setSize(size.width, size.height, false);
1057
+ const activeTarget = actualRenderer.getCanvasTarget?.();
1058
+ if (!canvasTarget || activeTarget !== canvasTarget) internal.canvasTargetSizeDirty = true;
1928
1059
  }
1929
1060
  if (camera !== oldCamera) {
1930
1061
  oldCamera = camera;
@@ -1945,7 +1076,7 @@ const createStore = (invalidate, advance) => {
1945
1076
 
1946
1077
  const memoizedLoaders = /* @__PURE__ */ new WeakMap();
1947
1078
  const isConstructor$1 = (value) => typeof value === "function" && value?.prototype?.constructor === value;
1948
- function getLoader(Proto) {
1079
+ function getLoader$1(Proto) {
1949
1080
  if (isConstructor$1(Proto)) {
1950
1081
  let loader = memoizedLoaders.get(Proto);
1951
1082
  if (!loader) {
@@ -1958,7 +1089,7 @@ function getLoader(Proto) {
1958
1089
  }
1959
1090
  function loadingFn(extensions, onProgress) {
1960
1091
  return function(Proto, input) {
1961
- const loader = getLoader(Proto);
1092
+ const loader = getLoader$1(Proto);
1962
1093
  if (extensions) extensions(loader);
1963
1094
  if ("loadAsync" in loader && typeof loader.loadAsync === "function") {
1964
1095
  return loader.loadAsync(input, onProgress).then((data) => {
@@ -1986,7 +1117,11 @@ function useLoader(loader, input, extensions, onProgress, cacheKey) {
1986
1117
  const results = cacheKeys.map(
1987
1118
  (key, index) => suspend(() => fn(loader, inputs[index]), [loader, key], { equal: is.equ })
1988
1119
  );
1989
- return Array.isArray(input) ? results : results[0];
1120
+ const stableRef = useRef(null);
1121
+ const previous = stableRef.current;
1122
+ const stable = previous !== null && previous.length === results.length && previous.every((value, i) => value === results[i]) ? previous : results;
1123
+ stableRef.current = stable;
1124
+ return Array.isArray(input) ? stable : stable[0];
1990
1125
  }
1991
1126
  useLoader.preload = function(loader, input, extensions, onProgress, cacheKey) {
1992
1127
  const inputs = Array.isArray(input) ? input : [input];
@@ -1999,7 +1134,7 @@ useLoader.clear = function(loader, input, cacheKey) {
1999
1134
  const cacheKeys = Array.isArray(cacheKey ?? input) ? cacheKey ?? input : [cacheKey ?? input];
2000
1135
  cacheKeys.forEach((key) => clear([loader, key]));
2001
1136
  };
2002
- useLoader.loader = getLoader;
1137
+ useLoader.loader = getLoader$1;
2003
1138
 
2004
1139
  function useFrame(callback, priorityOrOptions) {
2005
1140
  const store = React.useContext(context);
@@ -2106,6 +1241,13 @@ function useFrame(callback, priorityOrOptions) {
2106
1241
  * Use for controlling the entire frame loop, adding phases, etc.
2107
1242
  */
2108
1243
  scheduler: scheduler2,
1244
+ /**
1245
+ * The root that currently owns this job. Resolve on access because ambient
1246
+ * jobs can be adopted by a Canvas after the controls object is created.
1247
+ */
1248
+ get rootId() {
1249
+ return getScheduler().getJobRootId(id);
1250
+ },
2109
1251
  /**
2110
1252
  * Manually step this job only.
2111
1253
  * Bypasses FPS limiting - always runs.
@@ -2122,6 +1264,14 @@ function useFrame(callback, priorityOrOptions) {
2122
1264
  stepAll: (timestamp) => {
2123
1265
  getScheduler().step(timestamp);
2124
1266
  },
1267
+ /**
1268
+ * Request frames for this job's owning root without waking sibling roots.
1269
+ */
1270
+ invalidate: (frames, stackFrames) => {
1271
+ const scheduler3 = getScheduler();
1272
+ const rootId = scheduler3.getJobRootId(id);
1273
+ if (rootId) scheduler3.invalidateRoot(rootId, frames, stackFrames);
1274
+ },
2125
1275
  /**
2126
1276
  * Pause this job (set enabled=false).
2127
1277
  * Job remains registered but won't run.
@@ -2151,6 +1301,11 @@ function getUrls(input) {
2151
1301
  if (Array.isArray(input)) return input;
2152
1302
  return Object.values(input);
2153
1303
  }
1304
+ function inputSignature(input) {
1305
+ if (typeof input === "string") return input;
1306
+ if (Array.isArray(input)) return input.join("\0");
1307
+ return Object.keys(input).sort().map((key) => `${key}\0${input[key]}`).join("");
1308
+ }
2154
1309
  function allUrlsCached(urls, textureCache) {
2155
1310
  return urls.every((url) => textureCache.has(url));
2156
1311
  }
@@ -2176,24 +1331,37 @@ function useTexture(input, optionsOrOnLoad) {
2176
1331
  const onLoadRef = useRef(onLoad);
2177
1332
  onLoadRef.current = onLoad;
2178
1333
  const onLoadCalledForRef = useRef(null);
2179
- const urls = useMemo(() => getUrls(input), [input]);
1334
+ const inputKey = useMemo(() => inputSignature(input), [input]);
1335
+ const stableInput = useMemo(() => input, [inputKey]);
1336
+ const urls = useMemo(() => getUrls(stableInput), [stableInput]);
2180
1337
  const cachedResult = useMemo(() => {
2181
1338
  if (!cache) return null;
2182
1339
  const textures = store.getState().textures;
2183
1340
  if (!allUrlsCached(urls, textures)) return null;
2184
- return buildFromCache(input, textures);
2185
- }, [cache, urls, input, store]);
1341
+ return buildFromCache(stableInput, textures);
1342
+ }, [cache, urls, stableInput, store]);
2186
1343
  const loadedTextures = useLoader(
2187
1344
  TextureLoader,
2188
- IsObject(input) ? Object.values(input) : input
1345
+ IsObject(stableInput) ? Object.values(stableInput) : stableInput
2189
1346
  );
2190
- const inputKey = urls.join("\0");
1347
+ const mappedTextures = useMemo(() => {
1348
+ if (cachedResult) return cachedResult;
1349
+ if (IsObject(stableInput)) {
1350
+ const keyed = {};
1351
+ const textureArray = loadedTextures;
1352
+ let i = 0;
1353
+ for (const key in stableInput) keyed[key] = textureArray[i++];
1354
+ return keyed;
1355
+ } else {
1356
+ return loadedTextures;
1357
+ }
1358
+ }, [stableInput, loadedTextures, cachedResult]);
2191
1359
  useLayoutEffect(() => {
2192
1360
  if (cachedResult) return;
2193
1361
  if (onLoadCalledForRef.current === inputKey) return;
2194
1362
  onLoadCalledForRef.current = inputKey;
2195
- onLoadRef.current?.(loadedTextures);
2196
- }, [cachedResult, loadedTextures, inputKey]);
1363
+ onLoadRef.current?.(mappedTextures);
1364
+ }, [cachedResult, mappedTextures, inputKey]);
2197
1365
  useEffect(() => {
2198
1366
  if (cachedResult) return;
2199
1367
  if ("initTexture" in renderer) {
@@ -2212,30 +1380,18 @@ function useTexture(input, optionsOrOnLoad) {
2212
1380
  });
2213
1381
  }
2214
1382
  }, [renderer, loadedTextures, cachedResult]);
2215
- const mappedTextures = useMemo(() => {
2216
- if (cachedResult) return cachedResult;
2217
- if (IsObject(input)) {
2218
- const keyed = {};
2219
- const textureArray = loadedTextures;
2220
- let i = 0;
2221
- for (const key in input) keyed[key] = textureArray[i++];
2222
- return keyed;
2223
- } else {
2224
- return loadedTextures;
2225
- }
2226
- }, [input, loadedTextures, cachedResult]);
2227
1383
  useEffect(() => {
2228
1384
  if (!cache) return;
2229
1385
  const urlTextureMap = [];
2230
- if (typeof input === "string") {
2231
- urlTextureMap.push([input, mappedTextures]);
2232
- } else if (Array.isArray(input)) {
1386
+ if (typeof stableInput === "string") {
1387
+ urlTextureMap.push([stableInput, mappedTextures]);
1388
+ } else if (Array.isArray(stableInput)) {
2233
1389
  const textureArray = mappedTextures;
2234
- input.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
2235
- } else if (IsObject(input)) {
1390
+ stableInput.forEach((url, i) => urlTextureMap.push([url, textureArray[i]]));
1391
+ } else if (IsObject(stableInput)) {
2236
1392
  const textureRecord = mappedTextures;
2237
- for (const key in input) {
2238
- const url = input[key];
1393
+ for (const key in stableInput) {
1394
+ const url = stableInput[key];
2239
1395
  urlTextureMap.push([url, textureRecord[key]]);
2240
1396
  }
2241
1397
  }
@@ -2264,7 +1420,7 @@ function useTexture(input, optionsOrOnLoad) {
2264
1420
  }
2265
1421
  return { _textureRefs: refs };
2266
1422
  });
2267
- }, [cache, input, mappedTextures, store]);
1423
+ }, [cache, stableInput, mappedTextures, store]);
2268
1424
  return mappedTextures;
2269
1425
  }
2270
1426
  useTexture.preload = (url) => useLoader.preload(TextureLoader, url);
@@ -2359,13 +1515,134 @@ function useRenderTarget(widthOrOptions, heightOrOptions, options) {
2359
1515
  height = widthOrOptions;
2360
1516
  }
2361
1517
  }
2362
- return useMemo(() => {
2363
- const w = width ?? size.width;
2364
- const h = height ?? size.height;
2365
- {
2366
- return isLegacy ? new WebGLRenderTarget(w, h, opts) : new RenderTarget(w, h, opts);
2367
- }
2368
- }, [width, height, size.width, size.height, opts, isLegacy]);
1518
+ return useMemo(() => {
1519
+ const w = width ?? size.width;
1520
+ const h = height ?? size.height;
1521
+ {
1522
+ return isLegacy ? new WebGLRenderTarget(w, h, opts) : new RenderTarget(w, h, opts);
1523
+ }
1524
+ }, [width, height, size.width, size.height, opts, isLegacy]);
1525
+ }
1526
+
1527
+ const presetsObj = {
1528
+ apartment: "lebombo_1k.hdr",
1529
+ city: "potsdamer_platz_1k.hdr",
1530
+ dawn: "kiara_1_dawn_1k.hdr",
1531
+ forest: "forest_slope_1k.hdr",
1532
+ lobby: "st_fagans_interior_1k.hdr",
1533
+ night: "dikhololo_night_1k.hdr",
1534
+ park: "rooitou_park_1k.hdr",
1535
+ studio: "studio_small_03_1k.hdr",
1536
+ sunset: "venice_sunset_1k.hdr",
1537
+ warehouse: "empty_warehouse_01_1k.hdr"
1538
+ };
1539
+
1540
+ const CUBEMAP_ROOT = "https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/";
1541
+ const isArray = (arr) => Array.isArray(arr);
1542
+ const defaultFiles = ["/px.png", "/nx.png", "/py.png", "/ny.png", "/pz.png", "/nz.png"];
1543
+ function useEnvironment({
1544
+ files = defaultFiles,
1545
+ path = "",
1546
+ preset = void 0,
1547
+ colorSpace = void 0,
1548
+ extensions
1549
+ } = {}) {
1550
+ if (preset) {
1551
+ validatePreset(preset);
1552
+ files = presetsObj[preset];
1553
+ path = CUBEMAP_ROOT;
1554
+ }
1555
+ const multiFile = isArray(files);
1556
+ const { extension, isCubemap } = getExtension(files);
1557
+ const loader = getLoader(extension);
1558
+ if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
1559
+ const renderer = useThree((state) => state.renderer);
1560
+ useLayoutEffect(() => {
1561
+ if (extension !== "webp" && extension !== "jpg" && extension !== "jpeg") return;
1562
+ function clearGainmapTexture() {
1563
+ useLoader.clear(loader, multiFile ? [files] : files);
1564
+ }
1565
+ renderer.domElement.addEventListener("webglcontextlost", clearGainmapTexture, { once: true });
1566
+ }, [extension, files, loader, multiFile, renderer.domElement]);
1567
+ const loaderResult = useLoader(
1568
+ loader,
1569
+ multiFile ? [files] : files,
1570
+ (loader2) => {
1571
+ if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
1572
+ loader2.setRenderer?.(renderer);
1573
+ }
1574
+ loader2.setPath?.(path);
1575
+ if (extensions) extensions(loader2);
1576
+ }
1577
+ );
1578
+ let texture = multiFile ? (
1579
+ // @ts-ignore
1580
+ loaderResult[0]
1581
+ ) : loaderResult;
1582
+ if (extension === "jpg" || extension === "jpeg" || extension === "webp") {
1583
+ texture = texture.renderTarget?.texture;
1584
+ }
1585
+ texture.mapping = isCubemap ? CubeReflectionMapping : EquirectangularReflectionMapping;
1586
+ texture.colorSpace = colorSpace ?? (isCubemap && extension !== "hdr-cube" ? "srgb" : "srgb-linear");
1587
+ return texture;
1588
+ }
1589
+ const preloadDefaultOptions = {
1590
+ files: defaultFiles,
1591
+ path: "",
1592
+ preset: void 0,
1593
+ extensions: void 0
1594
+ };
1595
+ useEnvironment.preload = (preloadOptions) => {
1596
+ const options = { ...preloadDefaultOptions, ...preloadOptions };
1597
+ let { files, path = "" } = options;
1598
+ const { preset, extensions } = options;
1599
+ if (preset) {
1600
+ validatePreset(preset);
1601
+ files = presetsObj[preset];
1602
+ path = CUBEMAP_ROOT;
1603
+ }
1604
+ const { extension } = getExtension(files);
1605
+ if (extension === "webp" || extension === "jpg" || extension === "jpeg") {
1606
+ throw new Error("useEnvironment: Preloading gainmaps is not supported");
1607
+ }
1608
+ const loader = getLoader(extension);
1609
+ if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
1610
+ useLoader.preload(loader, isArray(files) ? [files] : files, (loader2) => {
1611
+ loader2.setPath?.(path);
1612
+ if (extensions) extensions(loader2);
1613
+ });
1614
+ };
1615
+ const clearDefaultOptins = {
1616
+ files: defaultFiles,
1617
+ preset: void 0
1618
+ };
1619
+ useEnvironment.clear = (clearOptions) => {
1620
+ const options = { ...clearDefaultOptins, ...clearOptions };
1621
+ let { files } = options;
1622
+ const { preset } = options;
1623
+ if (preset) {
1624
+ validatePreset(preset);
1625
+ files = presetsObj[preset];
1626
+ }
1627
+ const { extension } = getExtension(files);
1628
+ const loader = getLoader(extension);
1629
+ if (!loader) throw new Error("useEnvironment: Unrecognized file extension: " + files);
1630
+ useLoader.clear(loader, isArray(files) ? [files] : files);
1631
+ };
1632
+ function validatePreset(preset) {
1633
+ if (!(preset in presetsObj)) throw new Error("Preset must be one of: " + Object.keys(presetsObj).join(", "));
1634
+ }
1635
+ function getExtension(files) {
1636
+ const isCubemap = isArray(files) && files.length === 6;
1637
+ const isGainmap = isArray(files) && files.length === 3 && files.some((file) => file.endsWith("json"));
1638
+ const firstEntry = isArray(files) ? files[0] : files;
1639
+ const firstExtension = firstEntry.split(".").pop()?.split("?")?.shift()?.toLowerCase();
1640
+ const extension = isCubemap ? firstExtension === "hdr" ? "hdr-cube" : "cube" : isGainmap ? "webp" : firstEntry.startsWith("data:application/exr") ? "exr" : firstEntry.startsWith("data:application/hdr") ? "hdr" : firstEntry.startsWith("data:image/jpeg") ? "jpg" : firstExtension;
1641
+ return { extension, isCubemap, isGainmap };
1642
+ }
1643
+ function getLoader(extension) {
1644
+ const loader = extension === "cube" ? CubeTextureLoader : extension === "hdr-cube" ? HDRCubeTextureLoader : extension === "hdr" ? HDRLoader : extension === "exr" ? EXRLoader : extension === "jpg" || extension === "jpeg" ? UltraHDRLoader : extension === "webp" ? GainMapLoader : null;
1645
+ return loader;
2369
1646
  }
2370
1647
 
2371
1648
  function useStore() {
@@ -2385,6 +1662,8 @@ function useGraph(object) {
2385
1662
  return useMemo(() => buildGraph(object), [object]);
2386
1663
  }
2387
1664
 
1665
+ const t = 1, o = 8, r = 32, e = 2, i$1 = 268435456;
1666
+
2388
1667
  let effectId = 0;
2389
1668
  function addEffect(callback) {
2390
1669
  notifyDepreciated({
@@ -2413,13 +1692,19 @@ function addTail(callback) {
2413
1692
  return getScheduler().onIdle(callback);
2414
1693
  }
2415
1694
  function invalidate(state, frames = 1, stackFrames = false) {
2416
- getScheduler().invalidate(frames, stackFrames);
1695
+ const rootId = state?.internal?.rootId;
1696
+ const scheduler = getScheduler();
1697
+ if (rootId) scheduler.invalidateRoot(rootId, frames, stackFrames);
1698
+ else scheduler.invalidate(frames, stackFrames);
2417
1699
  }
2418
- function advance(timestamp) {
2419
- getScheduler().step(timestamp);
1700
+ function advance(timestamp, runGlobalEffects, state) {
1701
+ const rootId = state?.internal?.rootId;
1702
+ const scheduler = getScheduler();
1703
+ if (rootId) scheduler.stepRoot(rootId, timestamp);
1704
+ else scheduler.step(timestamp);
2420
1705
  }
2421
1706
 
2422
- const version = "10.0.0-alpha.3";
1707
+ const version = "10.0.0-alpha.5";
2423
1708
  const packageData = {
2424
1709
  version: version};
2425
1710
 
@@ -13292,390 +12577,973 @@ Check the top-level render call using <` + i + ">.");
13292
12577
  var i = x.H;
13293
12578
  x.H = $o;
13294
12579
  try {
13295
- return Br(e, n, o);
13296
- } finally {
13297
- x.H = i;
12580
+ return Br(e, n, o);
12581
+ } finally {
12582
+ x.H = i;
12583
+ }
12584
+ }, useRef: function() {
12585
+ return z = "useRef", D(), N(), xe().memoizedState;
12586
+ }, useState: function() {
12587
+ z = "useState", D(), N();
12588
+ var e = x.H;
12589
+ x.H = $o;
12590
+ try {
12591
+ return Br(gr);
12592
+ } finally {
12593
+ x.H = e;
12594
+ }
12595
+ }, useDebugValue: function() {
12596
+ z = "useDebugValue", D(), N();
12597
+ }, useDeferredValue: function(e, n) {
12598
+ return z = "useDeferredValue", D(), N(), nc(e, n);
12599
+ }, useTransition: function() {
12600
+ return z = "useTransition", D(), N(), Qp();
12601
+ }, useSyncExternalStore: function(e, n, o) {
12602
+ return z = "useSyncExternalStore", D(), N(), ta(e, n, o);
12603
+ }, useId: function() {
12604
+ return z = "useId", D(), N(), xe().memoizedState;
12605
+ }, useFormState: function(e) {
12606
+ return z = "useFormState", D(), N(), hs(e);
12607
+ }, useActionState: function(e) {
12608
+ return z = "useActionState", D(), N(), hs(e);
12609
+ }, useOptimistic: function(e, n) {
12610
+ return z = "useOptimistic", D(), N(), rf(e, n);
12611
+ }, useMemoCache: function(e) {
12612
+ return D(), Oa(e);
12613
+ }, useHostTransitionStatus: ia, useCacheRefresh: function() {
12614
+ return z = "useCacheRefresh", N(), xe().memoizedState;
12615
+ }, useEffectEvent: function(e) {
12616
+ return z = "useEffectEvent", D(), N(), oa(e);
12617
+ } }, dm = { readContext: function(e) {
12618
+ return Ce(), Ee(e);
12619
+ }, use: function(e) {
12620
+ return D(), we(e);
12621
+ }, useCallback: function(e, n) {
12622
+ return z = "useCallback", D(), N(), Ma(e, n);
12623
+ }, useContext: function(e) {
12624
+ return z = "useContext", D(), N(), Ee(e);
12625
+ }, useEffect: function(e, n) {
12626
+ z = "useEffect", D(), N(), Qn(2048, Ut, e, n);
12627
+ }, useImperativeHandle: function(e, n, o) {
12628
+ return z = "useImperativeHandle", D(), N(), aa(e, n, o);
12629
+ }, useInsertionEffect: function(e, n) {
12630
+ return z = "useInsertionEffect", D(), N(), Qn(4, Wt, e, n);
12631
+ }, useLayoutEffect: function(e, n) {
12632
+ return z = "useLayoutEffect", D(), N(), Qn(4, Rr, e, n);
12633
+ }, useMemo: function(e, n) {
12634
+ z = "useMemo", D(), N();
12635
+ var o = x.H;
12636
+ x.H = $o;
12637
+ try {
12638
+ return Vi(e, n);
12639
+ } finally {
12640
+ x.H = o;
12641
+ }
12642
+ }, useReducer: function(e, n, o) {
12643
+ z = "useReducer", D(), N();
12644
+ var i = x.H;
12645
+ x.H = $o;
12646
+ try {
12647
+ return Qi(e, n, o);
12648
+ } finally {
12649
+ x.H = i;
12650
+ }
12651
+ }, useRef: function() {
12652
+ return z = "useRef", D(), N(), xe().memoizedState;
12653
+ }, useState: function() {
12654
+ z = "useState", D(), N();
12655
+ var e = x.H;
12656
+ x.H = $o;
12657
+ try {
12658
+ return Qi(gr);
12659
+ } finally {
12660
+ x.H = e;
12661
+ }
12662
+ }, useDebugValue: function() {
12663
+ z = "useDebugValue", D(), N();
12664
+ }, useDeferredValue: function(e, n) {
12665
+ return z = "useDeferredValue", D(), N(), sf(e, n);
12666
+ }, useTransition: function() {
12667
+ return z = "useTransition", D(), N(), Ro();
12668
+ }, useSyncExternalStore: function(e, n, o) {
12669
+ return z = "useSyncExternalStore", D(), N(), ta(e, n, o);
12670
+ }, useId: function() {
12671
+ return z = "useId", D(), N(), xe().memoizedState;
12672
+ }, useFormState: function(e) {
12673
+ return z = "useFormState", D(), N(), $t(e);
12674
+ }, useActionState: function(e) {
12675
+ return z = "useActionState", D(), N(), $t(e);
12676
+ }, useOptimistic: function(e, n) {
12677
+ return z = "useOptimistic", D(), N(), of(e, n);
12678
+ }, useMemoCache: function(e) {
12679
+ return D(), Oa(e);
12680
+ }, useHostTransitionStatus: ia, useCacheRefresh: function() {
12681
+ return z = "useCacheRefresh", N(), xe().memoizedState;
12682
+ }, useEffectEvent: function(e) {
12683
+ return z = "useEffectEvent", D(), N(), oa(e);
12684
+ } };
12685
+ var Fy = {}, Hy = /* @__PURE__ */ new Set(), Ay = /* @__PURE__ */ new Set(), jy = /* @__PURE__ */ new Set(), Dy = /* @__PURE__ */ new Set(), Wy = /* @__PURE__ */ new Set(), Uy = /* @__PURE__ */ new Set(), By = /* @__PURE__ */ new Set(), Oy = /* @__PURE__ */ new Set(), My = /* @__PURE__ */ new Set(), Qy = /* @__PURE__ */ new Set();
12686
+ Object.freeze(Fy);
12687
+ var zg = { enqueueSetState: function(e, n, o) {
12688
+ e = e._reactInternals;
12689
+ var i = Nt(e), s = zo(i);
12690
+ s.payload = n, o != null && (df(o), s.callback = o), n = Mt(e, s, i), n !== null && (ur(i, "this.setState()", e), We(n, e, i), Bi(n, e, i));
12691
+ }, enqueueReplaceState: function(e, n, o) {
12692
+ e = e._reactInternals;
12693
+ var i = Nt(e), s = zo(i);
12694
+ s.tag = Cy, s.payload = n, o != null && (df(o), s.callback = o), n = Mt(e, s, i), n !== null && (ur(i, "this.replaceState()", e), We(n, e, i), Bi(n, e, i));
12695
+ }, enqueueForceUpdate: function(e, n) {
12696
+ e = e._reactInternals;
12697
+ var o = Nt(e), i = zo(o);
12698
+ i.tag = Ty, n != null && (df(n), i.callback = n), n = Mt(e, i, o), n !== null && (ur(o, "this.forceUpdate()", e), We(n, e, o), Bi(n, e, o));
12699
+ } }, bd = null, Cg = null, Tg = Error("This is not a real error. It's an implementation detail of React's selective hydration feature. If this leaks into userspace, it's a bug in React. Please file an issue."), Cn = false, $y = {}, Vy = {}, qy = {}, Gy = {}, vd = false, Jy = {}, fm = {}, _g = { dehydrated: null, treeContext: null, retryLane: 0, hydrationErrors: null }, Zy = false, Yy = null;
12700
+ Yy = /* @__PURE__ */ new Set();
12701
+ var Si = false, Tn = false, Rg = false, Xy = typeof WeakSet == "function" ? WeakSet : Set, Gn = null, Sd = null, kd = null, _n = null, nr = false, Vo = null, Wn = false, wd = 8192, Vb = { getCacheForType: function(e) {
12702
+ var n = Ee(un), o = n.data.get(e);
12703
+ return o === void 0 && (o = e(), n.data.set(e, o)), o;
12704
+ }, cacheSignal: function() {
12705
+ return Ee(un).controller.signal;
12706
+ }, getOwner: function() {
12707
+ return di;
12708
+ } }, pm = 0, hm = 1, mm = 2, gm = 3, ym = 4;
12709
+ if (typeof Symbol == "function" && Symbol.for) {
12710
+ var bp = Symbol.for;
12711
+ pm = bp("selector.component"), hm = bp("selector.has_pseudo_class"), mm = bp("selector.role"), gm = bp("selector.test_id"), ym = bp("selector.text");
12712
+ }
12713
+ var bm = [], qb = typeof WeakMap == "function" ? WeakMap : Map, Jn = 0, Zn = 2, uo = 4, ki = 0, vp = 1, iu = 2, vm = 3, Tl = 4, Sm = 6, Ky = 5, ye = Jn, je = null, se = null, ae = 0, tr = 0, km = 1, lu = 2, Sp = 3, eb = 4, Eg = 5, kp = 6, wm = 7, Ig = 8, su = 9, Le = tr, Er = null, _l = false, Pd = false, Lg = false, Ta = 0, nn = ki, Rl = 0, El = 0, Ng = 0, rr = 0, uu = 0, wp = null, Bt = null, Pm = false, xm = 0, nb = 0, tb = 300, Pp = 1 / 0, Fg = 500, xp = null, gn = null, Il = null, zm = 0, Hg = 1, Ag = 2, rb = 3, Ll = 0, ob = 1, ab = 2, ib = 3, lb = 4, Cm = 5, Rn = 0, Nl = null, xd = null, qo = 0, jg = 0, Dg = -0, Wg = null, sb = null, ub = null, Go = zm, cb = null, Gb = 50, zp = 0, Ug = null, Bg = false, Tm = false, Jb = 50, cu = 0, Cp = null, zd = false, _m = null, db = false, fb = /* @__PURE__ */ new Set(), Zb = {}, co = null, Cd = null, pb = false;
12714
+ try {
12715
+ var o0 = Object.preventExtensions({});
12716
+ } catch {
12717
+ pb = true;
12718
+ }
12719
+ var hb = false, mb = {}, gb = null, yb = null, bb = null, vb = null, Sb = null, kb = null, wb = null, Pb = null, xb = null, zb = null;
12720
+ return gb = function(e, n, o, i) {
12721
+ n = Yn(e, n), n !== null && (o = _d(n.memoizedState, o, 0, i), n.memoizedState = o, n.baseState = o, e.memoizedProps = ze({}, e.memoizedProps), o = On(e, 2), o !== null && We(o, e, 2));
12722
+ }, yb = function(e, n, o) {
12723
+ n = Yn(e, n), n !== null && (o = du(n.memoizedState, o, 0), n.memoizedState = o, n.baseState = o, e.memoizedProps = ze({}, e.memoizedProps), o = On(e, 2), o !== null && We(o, e, 2));
12724
+ }, bb = function(e, n, o, i) {
12725
+ n = Yn(e, n), n !== null && (o = F(n.memoizedState, o, i), n.memoizedState = o, n.baseState = o, e.memoizedProps = ze({}, e.memoizedProps), o = On(e, 2), o !== null && We(o, e, 2));
12726
+ }, vb = function(e, n, o) {
12727
+ e.pendingProps = _d(e.memoizedProps, n, 0, o), e.alternate && (e.alternate.pendingProps = e.pendingProps), n = On(e, 2), n !== null && We(n, e, 2);
12728
+ }, Sb = function(e, n) {
12729
+ e.pendingProps = du(e.memoizedProps, n, 0), e.alternate && (e.alternate.pendingProps = e.pendingProps), n = On(e, 2), n !== null && We(n, e, 2);
12730
+ }, kb = function(e, n, o) {
12731
+ e.pendingProps = F(e.memoizedProps, n, o), e.alternate && (e.alternate.pendingProps = e.pendingProps), n = On(e, 2), n !== null && We(n, e, 2);
12732
+ }, wb = function(e) {
12733
+ var n = On(e, 2);
12734
+ n !== null && We(n, e, 2);
12735
+ }, Pb = function(e) {
12736
+ var n = ut(), o = On(e, n);
12737
+ o !== null && We(o, e, n);
12738
+ }, xb = function(e) {
12739
+ pu = e;
12740
+ }, zb = function(e) {
12741
+ fu = e;
12742
+ }, le.attemptContinuousHydration = function(e) {
12743
+ if (e.tag === 13 || e.tag === 31) {
12744
+ var n = On(e, 67108864);
12745
+ n !== null && We(n, e, 67108864), rl(e, 67108864);
12746
+ }
12747
+ }, le.attemptHydrationAtCurrentPriority = function(e) {
12748
+ if (e.tag === 13 || e.tag === 31) {
12749
+ var n = Nt(e);
12750
+ n = Xo(n);
12751
+ var o = On(e, n);
12752
+ o !== null && We(o, e, n), rl(e, n);
12753
+ }
12754
+ }, le.attemptSynchronousHydration = function(e) {
12755
+ switch (e.tag) {
12756
+ case 3:
12757
+ if (e = e.stateNode, e.current.memoizedState.isDehydrated) {
12758
+ var n = _t(e.pendingLanes);
12759
+ if (n !== 0) {
12760
+ for (e.pendingLanes |= 2, e.entangledLanes |= 2; n; ) {
12761
+ var o = 1 << 31 - vn(n);
12762
+ e.entanglements[1] |= o, n &= ~o;
12763
+ }
12764
+ Kn(e), (ye & (Zn | uo)) === Jn && (Pp = me() + Fg, Wa(0));
12765
+ }
12766
+ }
12767
+ break;
12768
+ case 31:
12769
+ case 13:
12770
+ n = On(e, 2), n !== null && We(n, e, 2), Ls(), rl(e, 2);
12771
+ }
12772
+ }, le.batchedUpdates = function(e, n) {
12773
+ return e(n);
12774
+ }, le.createComponentSelector = function(e) {
12775
+ return { $$typeof: pm, value: e };
12776
+ }, le.createContainer = function(e, n, o, i, s, u, f, p, g, S) {
12777
+ return Ka(e, n, false, null, o, i, u, null, f, p, g, S);
12778
+ }, le.createHasPseudoClassSelector = function(e) {
12779
+ return { $$typeof: hm, value: e };
12780
+ }, le.createHydrationContainer = function(e, n, o, i, s, u, f, p, g, S, T, _, I, O) {
12781
+ return e = Ka(o, i, true, e, s, u, p, O, g, S, T, _), e.context = Dh(null), o = e.current, i = Nt(o), i = Xo(i), s = zo(i), s.callback = n ?? null, Mt(o, s, i), ur(i, "hydrateRoot()", null), n = i, e.current.lanes = n, Ci(e, n), Kn(e), e;
12782
+ }, le.createPortal = function(e, n, o) {
12783
+ var i = 3 < arguments.length && arguments[3] !== void 0 ? arguments[3] : null;
12784
+ try {
12785
+ vt(i);
12786
+ var s = false;
12787
+ } catch {
12788
+ s = true;
13298
12789
  }
13299
- }, useRef: function() {
13300
- return z = "useRef", D(), N(), xe().memoizedState;
13301
- }, useState: function() {
13302
- z = "useState", D(), N();
13303
- var e = x.H;
13304
- x.H = $o;
12790
+ return s && (console.error("The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", typeof Symbol == "function" && Symbol.toStringTag && i[Symbol.toStringTag] || i.constructor.name || "Object"), vt(i)), { $$typeof: Ao, key: i == null ? null : "" + i, children: e, containerInfo: n, implementation: o };
12791
+ }, le.createRoleSelector = function(e) {
12792
+ return { $$typeof: mm, value: e };
12793
+ }, le.createTestNameSelector = function(e) {
12794
+ return { $$typeof: gm, value: e };
12795
+ }, le.createTextSelector = function(e) {
12796
+ return { $$typeof: ym, value: e };
12797
+ }, le.defaultOnCaughtError = function(e) {
12798
+ var n = bd ? "The above error occurred in the <" + bd + "> component." : "The above error occurred in one of your React components.", o = "React will try to recreate this component tree from scratch using the error boundary you provided, " + ((Cg || "Anonymous") + ".");
12799
+ typeof e == "object" && e !== null && typeof e.environmentName == "string" ? ri("error", [`%o
12800
+
12801
+ %s
12802
+
12803
+ %s
12804
+ `, e, n, o], e.environmentName)() : console.error(`%o
12805
+
12806
+ %s
12807
+
12808
+ %s
12809
+ `, e, n, o);
12810
+ }, le.defaultOnRecoverableError = function(e) {
12811
+ qg(e);
12812
+ }, le.defaultOnUncaughtError = function(e) {
12813
+ qg(e), console.warn(`%s
12814
+
12815
+ %s
12816
+ `, bd ? "An error occurred in the <" + bd + "> component." : "An error occurred in one of your React components.", `Consider adding an error boundary to your tree to customize error handling behavior.
12817
+ Visit https://react.dev/link/error-boundaries to learn more about error boundaries.`);
12818
+ }, le.deferredUpdates = function(e) {
12819
+ var n = x.T, o = wt();
13305
12820
  try {
13306
- return Br(gr);
12821
+ return an(32), x.T = null, e();
13307
12822
  } finally {
13308
- x.H = e;
12823
+ an(o), x.T = n;
13309
12824
  }
13310
- }, useDebugValue: function() {
13311
- z = "useDebugValue", D(), N();
13312
- }, useDeferredValue: function(e, n) {
13313
- return z = "useDeferredValue", D(), N(), nc(e, n);
13314
- }, useTransition: function() {
13315
- return z = "useTransition", D(), N(), Qp();
13316
- }, useSyncExternalStore: function(e, n, o) {
13317
- return z = "useSyncExternalStore", D(), N(), ta(e, n, o);
13318
- }, useId: function() {
13319
- return z = "useId", D(), N(), xe().memoizedState;
13320
- }, useFormState: function(e) {
13321
- return z = "useFormState", D(), N(), hs(e);
13322
- }, useActionState: function(e) {
13323
- return z = "useActionState", D(), N(), hs(e);
13324
- }, useOptimistic: function(e, n) {
13325
- return z = "useOptimistic", D(), N(), rf(e, n);
13326
- }, useMemoCache: function(e) {
13327
- return D(), Oa(e);
13328
- }, useHostTransitionStatus: ia, useCacheRefresh: function() {
13329
- return z = "useCacheRefresh", N(), xe().memoizedState;
13330
- }, useEffectEvent: function(e) {
13331
- return z = "useEffectEvent", D(), N(), oa(e);
13332
- } }, dm = { readContext: function(e) {
13333
- return Ce(), Ee(e);
13334
- }, use: function(e) {
13335
- return D(), we(e);
13336
- }, useCallback: function(e, n) {
13337
- return z = "useCallback", D(), N(), Ma(e, n);
13338
- }, useContext: function(e) {
13339
- return z = "useContext", D(), N(), Ee(e);
13340
- }, useEffect: function(e, n) {
13341
- z = "useEffect", D(), N(), Qn(2048, Ut, e, n);
13342
- }, useImperativeHandle: function(e, n, o) {
13343
- return z = "useImperativeHandle", D(), N(), aa(e, n, o);
13344
- }, useInsertionEffect: function(e, n) {
13345
- return z = "useInsertionEffect", D(), N(), Qn(4, Wt, e, n);
13346
- }, useLayoutEffect: function(e, n) {
13347
- return z = "useLayoutEffect", D(), N(), Qn(4, Rr, e, n);
13348
- }, useMemo: function(e, n) {
13349
- z = "useMemo", D(), N();
13350
- var o = x.H;
13351
- x.H = $o;
12825
+ }, le.discreteUpdates = function(e, n, o, i, s) {
12826
+ var u = x.T, f = wt();
13352
12827
  try {
13353
- return Vi(e, n);
12828
+ return an(2), x.T = null, e(n, o, i, s);
13354
12829
  } finally {
13355
- x.H = o;
12830
+ an(f), x.T = u, ye === Jn && (Pp = me() + Fg);
13356
12831
  }
13357
- }, useReducer: function(e, n, o) {
13358
- z = "useReducer", D(), N();
13359
- var i = x.H;
13360
- x.H = $o;
13361
- try {
13362
- return Qi(e, n, o);
13363
- } finally {
13364
- x.H = i;
12832
+ }, le.findAllNodes = kc, le.findBoundingRects = function(e, n) {
12833
+ if (!xr) throw Error("Test selector API is not supported by this renderer.");
12834
+ n = kc(e, n), e = [];
12835
+ for (var o = 0; o < n.length; o++) e.push(ma(n[o]));
12836
+ for (n = e.length - 1; 0 < n; n--) {
12837
+ o = e[n];
12838
+ for (var i = o.x, s = i + o.width, u = o.y, f = u + o.height, p = n - 1; 0 <= p; p--) if (n !== p) {
12839
+ var g = e[p], S = g.x, T = S + g.width, _ = g.y, I = _ + g.height;
12840
+ if (i >= S && u >= _ && s <= T && f <= I) {
12841
+ e.splice(n, 1);
12842
+ break;
12843
+ } else if (i !== S || o.width !== g.width || I < u || _ > f) {
12844
+ if (!(u !== _ || o.height !== g.height || T < i || S > s)) {
12845
+ S > i && (g.width += S - i, g.x = i), T < s && (g.width = s - S), e.splice(n, 1);
12846
+ break;
12847
+ }
12848
+ } else {
12849
+ _ > u && (g.height += _ - u, g.y = u), I < f && (g.height = f - _), e.splice(n, 1);
12850
+ break;
12851
+ }
12852
+ }
13365
12853
  }
13366
- }, useRef: function() {
13367
- return z = "useRef", D(), N(), xe().memoizedState;
13368
- }, useState: function() {
13369
- z = "useState", D(), N();
13370
- var e = x.H;
13371
- x.H = $o;
12854
+ return e;
12855
+ }, le.findHostInstance = function(e) {
12856
+ var n = e._reactInternals;
12857
+ if (n === void 0) throw typeof e.render == "function" ? Error("Unable to find node on an unmounted component.") : (e = Object.keys(e).join(","), Error("Argument appears to not be a ReactComponent. Keys: " + e));
12858
+ return e = mu(n), e === null ? null : ot(e.stateNode);
12859
+ }, le.findHostInstanceWithNoPortals = function(e) {
12860
+ return e = Ed(e), e = e !== null ? _p(e) : null, e === null ? null : ot(e.stateNode);
12861
+ }, le.findHostInstanceWithWarning = function(e, n) {
12862
+ var o = e._reactInternals;
12863
+ if (o === void 0) throw typeof e.render == "function" ? Error("Unable to find node on an unmounted component.") : (e = Object.keys(e).join(","), Error("Argument appears to not be a ReactComponent. Keys: " + e));
12864
+ if (e = mu(o), e === null) return null;
12865
+ if (e.mode & 8) {
12866
+ var i = G(o) || "Component";
12867
+ mb[i] || (mb[i] = true, B(e, function() {
12868
+ o.mode & 8 ? console.error("%s is deprecated in StrictMode. %s was passed an instance of %s which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://react.dev/link/strict-mode-find-node", n, n, i) : console.error("%s is deprecated in StrictMode. %s was passed an instance of %s which renders StrictMode children. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://react.dev/link/strict-mode-find-node", n, n, i);
12869
+ }));
12870
+ }
12871
+ return ot(e.stateNode);
12872
+ }, le.flushPassiveEffects = el, le.flushSyncFromReconciler = function(e) {
12873
+ var n = ye;
12874
+ ye |= 1;
12875
+ var o = x.T, i = wt();
13372
12876
  try {
13373
- return Qi(gr);
12877
+ if (an(2), x.T = null, e) return e();
13374
12878
  } finally {
13375
- x.H = e;
12879
+ an(i), x.T = o, ye = n, (ye & (Zn | uo)) === Jn && Wa(0);
12880
+ }
12881
+ }, le.flushSyncWork = Ls, le.focusWithin = function(e, n) {
12882
+ if (!xr) throw Error("Test selector API is not supported by this renderer.");
12883
+ for (e = Ef(e), n = hh(e, n), n = Array.from(n), e = 0; e < n.length; ) {
12884
+ var o = n[e++], i = o.tag;
12885
+ if (!Kr(o)) {
12886
+ if ((i === 5 || i === 26 || i === 27) && Ft(o.stateNode)) return true;
12887
+ for (o = o.child; o !== null; ) n.push(o), o = o.sibling;
12888
+ }
12889
+ }
12890
+ return false;
12891
+ }, le.getFindAllNodesFailureDescription = function(e, n) {
12892
+ if (!xr) throw Error("Test selector API is not supported by this renderer.");
12893
+ var o = 0, i = [];
12894
+ e = [Ef(e), 0];
12895
+ for (var s = 0; s < e.length; ) {
12896
+ var u = e[s++], f = u.tag, p = e[s++], g = n[p];
12897
+ if ((f !== 5 && f !== 26 && f !== 27 || !Kr(u)) && (If(u, g) && (i.push(Sc(g)), p++, p > o && (o = p)), p < n.length)) for (u = u.child; u !== null; ) e.push(u, p), u = u.sibling;
12898
+ }
12899
+ if (o < n.length) {
12900
+ for (e = []; o < n.length; o++) e.push(Sc(n[o]));
12901
+ return `findAllNodes was able to match part of the selector:
12902
+ ` + (i.join(" > ") + `
12903
+
12904
+ No matching component was found for:
12905
+ `) + e.join(" > ");
12906
+ }
12907
+ return null;
12908
+ }, le.getPublicRootInstance = function(e) {
12909
+ if (e = e.current, !e.child) return null;
12910
+ switch (e.child.tag) {
12911
+ case 27:
12912
+ case 5:
12913
+ return ot(e.child.stateNode);
12914
+ default:
12915
+ return e.child.stateNode;
12916
+ }
12917
+ }, le.injectIntoDevTools = function() {
12918
+ var e = { bundleType: 1, version: Jt, rendererPackageName: Zt, currentDispatcherRef: x, reconcilerVersion: "19.2.0" };
12919
+ return jo !== null && (e.rendererConfig = jo), e.overrideHookState = gb, e.overrideHookStateDeletePath = yb, e.overrideHookStateRenamePath = bb, e.overrideProps = vb, e.overridePropsDeletePath = Sb, e.overridePropsRenamePath = kb, e.scheduleUpdate = wb, e.scheduleRetry = Pb, e.setErrorHandler = xb, e.setSuspenseHandler = zb, e.scheduleRefresh = hu, e.scheduleRoot = Fl, e.setRefreshHandler = Ir, e.getCurrentFiber = Ic, Ep(e);
12920
+ }, le.isAlreadyRendering = Ns, le.observeVisibleRects = function(e, n, o, i) {
12921
+ function s() {
12922
+ var S = kc(e, n);
12923
+ u.forEach(function(T) {
12924
+ 0 > S.indexOf(T) && g(T);
12925
+ }), S.forEach(function(T) {
12926
+ 0 > u.indexOf(T) && p(T);
12927
+ });
12928
+ }
12929
+ if (!xr) throw Error("Test selector API is not supported by this renderer.");
12930
+ var u = kc(e, n);
12931
+ o = zr(u, o, i);
12932
+ var f = o.disconnect, p = o.observe, g = o.unobserve;
12933
+ return bm.push(s), { disconnect: function() {
12934
+ var S = bm.indexOf(s);
12935
+ 0 <= S && bm.splice(S, 1), f();
12936
+ } };
12937
+ }, le.shouldError = function(e) {
12938
+ return pu(e);
12939
+ }, le.shouldSuspend = function(e) {
12940
+ return fu(e);
12941
+ }, le.startHostTransition = function(e, n, o, i) {
12942
+ if (e.tag !== 5) throw Error("Expected the form instance to be a HostComponent. This is a bug in React.");
12943
+ var s = uf(e).queue;
12944
+ Hp(e), nt(e, s, n, Xt, o === null ? Em : function() {
12945
+ x.T === null && console.error("requestFormReset was called outside a transition or action. To fix, move to an action, or wrap with startTransition.");
12946
+ var u = uf(e);
12947
+ return u.next === null && (u = e.alternate.memoizedState), qi(e, u.next.queue, {}, Nt(e)), o(i);
12948
+ });
12949
+ }, le.updateContainer = function(e, n, o, i) {
12950
+ var s = n.current, u = Nt(s);
12951
+ return As(s, u, e, n, o, i), u;
12952
+ }, le.updateContainerSync = Wh, le;
12953
+ }, Tt.exports.default = Tt.exports, Object.defineProperty(Tt.exports, "__esModule", { value: true }));
12954
+ })(Mg)), Mg.exports;
12955
+ }
12956
+ var Eb;
12957
+ function n0() {
12958
+ return Eb || (Eb = 1, process.env.NODE_ENV === "production" ? Rm.exports = Kb() : Rm.exports = e0()), Rm.exports;
12959
+ }
12960
+ var t0 = n0();
12961
+ const r0 = Xb(t0);
12962
+
12963
+ const DEFAULT_POINTER_ID = 0;
12964
+ const XR_POINTER_ID_START = 1e3;
12965
+ function getPointerState(internal, pointerId) {
12966
+ let state = internal.pointerMap.get(pointerId);
12967
+ if (!state) {
12968
+ state = {
12969
+ hovered: /* @__PURE__ */ new Map(),
12970
+ captured: /* @__PURE__ */ new Map(),
12971
+ initialClick: [0, 0],
12972
+ initialHits: []
12973
+ };
12974
+ internal.pointerMap.set(pointerId, state);
12975
+ }
12976
+ return state;
12977
+ }
12978
+ function getPointerId(event) {
12979
+ return "pointerId" in event ? event.pointerId : DEFAULT_POINTER_ID;
12980
+ }
12981
+ function makeId(event) {
12982
+ return (event.eventObject || event.object).uuid + "/" + event.index + event.instanceId;
12983
+ }
12984
+ function releaseInternalPointerCapture(internal, obj, pointerId) {
12985
+ const pointerState = internal.pointerMap.get(pointerId);
12986
+ if (!pointerState) return;
12987
+ const captureData = pointerState.captured.get(obj);
12988
+ if (captureData) {
12989
+ pointerState.captured.delete(obj);
12990
+ try {
12991
+ captureData.target.releasePointerCapture?.(pointerId);
12992
+ } catch {
12993
+ }
12994
+ }
12995
+ }
12996
+ function swapInteractivity(store, object, newObject) {
12997
+ const { internal } = store.getState();
12998
+ for (let i = 0; i < internal.interaction.length; i++) {
12999
+ if (internal.interaction[i] === object) internal.interaction[i] = newObject;
13000
+ }
13001
+ for (const pointerState of internal.pointerMap.values()) {
13002
+ for (let i = 0; i < pointerState.initialHits.length; i++) {
13003
+ if (pointerState.initialHits[i] === object) pointerState.initialHits[i] = newObject;
13004
+ }
13005
+ pointerState.hovered.forEach((value, key) => {
13006
+ if (value.eventObject === object || value.object === object) {
13007
+ pointerState.hovered.delete(key);
13008
+ const next = {
13009
+ ...value,
13010
+ eventObject: value.eventObject === object ? newObject : value.eventObject,
13011
+ object: value.object === object ? newObject : value.object
13012
+ };
13013
+ pointerState.hovered.set(makeId(next), next);
13014
+ }
13015
+ });
13016
+ const captureData = pointerState.captured.get(object);
13017
+ if (captureData) {
13018
+ pointerState.captured.delete(object);
13019
+ pointerState.captured.set(newObject, {
13020
+ ...captureData,
13021
+ intersection: {
13022
+ ...captureData.intersection,
13023
+ object: captureData.intersection.object === object ? newObject : captureData.intersection.object,
13024
+ eventObject: captureData.intersection.eventObject === object ? newObject : captureData.intersection.eventObject
13376
13025
  }
13377
- }, useDebugValue: function() {
13378
- z = "useDebugValue", D(), N();
13379
- }, useDeferredValue: function(e, n) {
13380
- return z = "useDeferredValue", D(), N(), sf(e, n);
13381
- }, useTransition: function() {
13382
- return z = "useTransition", D(), N(), Ro();
13383
- }, useSyncExternalStore: function(e, n, o) {
13384
- return z = "useSyncExternalStore", D(), N(), ta(e, n, o);
13385
- }, useId: function() {
13386
- return z = "useId", D(), N(), xe().memoizedState;
13387
- }, useFormState: function(e) {
13388
- return z = "useFormState", D(), N(), $t(e);
13389
- }, useActionState: function(e) {
13390
- return z = "useActionState", D(), N(), $t(e);
13391
- }, useOptimistic: function(e, n) {
13392
- return z = "useOptimistic", D(), N(), of(e, n);
13393
- }, useMemoCache: function(e) {
13394
- return D(), Oa(e);
13395
- }, useHostTransitionStatus: ia, useCacheRefresh: function() {
13396
- return z = "useCacheRefresh", N(), xe().memoizedState;
13397
- }, useEffectEvent: function(e) {
13398
- return z = "useEffectEvent", D(), N(), oa(e);
13399
- } };
13400
- var Fy = {}, Hy = /* @__PURE__ */ new Set(), Ay = /* @__PURE__ */ new Set(), jy = /* @__PURE__ */ new Set(), Dy = /* @__PURE__ */ new Set(), Wy = /* @__PURE__ */ new Set(), Uy = /* @__PURE__ */ new Set(), By = /* @__PURE__ */ new Set(), Oy = /* @__PURE__ */ new Set(), My = /* @__PURE__ */ new Set(), Qy = /* @__PURE__ */ new Set();
13401
- Object.freeze(Fy);
13402
- var zg = { enqueueSetState: function(e, n, o) {
13403
- e = e._reactInternals;
13404
- var i = Nt(e), s = zo(i);
13405
- s.payload = n, o != null && (df(o), s.callback = o), n = Mt(e, s, i), n !== null && (ur(i, "this.setState()", e), We(n, e, i), Bi(n, e, i));
13406
- }, enqueueReplaceState: function(e, n, o) {
13407
- e = e._reactInternals;
13408
- var i = Nt(e), s = zo(i);
13409
- s.tag = Cy, s.payload = n, o != null && (df(o), s.callback = o), n = Mt(e, s, i), n !== null && (ur(i, "this.replaceState()", e), We(n, e, i), Bi(n, e, i));
13410
- }, enqueueForceUpdate: function(e, n) {
13411
- e = e._reactInternals;
13412
- var o = Nt(e), i = zo(o);
13413
- i.tag = Ty, n != null && (df(n), i.callback = n), n = Mt(e, i, o), n !== null && (ur(o, "this.forceUpdate()", e), We(n, e, o), Bi(n, e, o));
13414
- } }, bd = null, Cg = null, Tg = Error("This is not a real error. It's an implementation detail of React's selective hydration feature. If this leaks into userspace, it's a bug in React. Please file an issue."), Cn = false, $y = {}, Vy = {}, qy = {}, Gy = {}, vd = false, Jy = {}, fm = {}, _g = { dehydrated: null, treeContext: null, retryLane: 0, hydrationErrors: null }, Zy = false, Yy = null;
13415
- Yy = /* @__PURE__ */ new Set();
13416
- var Si = false, Tn = false, Rg = false, Xy = typeof WeakSet == "function" ? WeakSet : Set, Gn = null, Sd = null, kd = null, _n = null, nr = false, Vo = null, Wn = false, wd = 8192, Vb = { getCacheForType: function(e) {
13417
- var n = Ee(un), o = n.data.get(e);
13418
- return o === void 0 && (o = e(), n.data.set(e, o)), o;
13419
- }, cacheSignal: function() {
13420
- return Ee(un).controller.signal;
13421
- }, getOwner: function() {
13422
- return di;
13423
- } }, pm = 0, hm = 1, mm = 2, gm = 3, ym = 4;
13424
- if (typeof Symbol == "function" && Symbol.for) {
13425
- var bp = Symbol.for;
13426
- pm = bp("selector.component"), hm = bp("selector.has_pseudo_class"), mm = bp("selector.role"), gm = bp("selector.test_id"), ym = bp("selector.text");
13026
+ });
13027
+ }
13028
+ }
13029
+ unregisterVisibility(store, object);
13030
+ }
13031
+ function removeInteractivity(store, object) {
13032
+ const { internal } = store.getState();
13033
+ internal.interaction = internal.interaction.filter((o) => o !== object);
13034
+ for (const [pointerId, pointerState] of internal.pointerMap) {
13035
+ pointerState.initialHits = pointerState.initialHits.filter((o) => o !== object);
13036
+ pointerState.hovered.forEach((value, key) => {
13037
+ if (value.eventObject === object || value.object === object) {
13038
+ pointerState.hovered.delete(key);
13427
13039
  }
13428
- var bm = [], qb = typeof WeakMap == "function" ? WeakMap : Map, Jn = 0, Zn = 2, uo = 4, ki = 0, vp = 1, iu = 2, vm = 3, Tl = 4, Sm = 6, Ky = 5, ye = Jn, je = null, se = null, ae = 0, tr = 0, km = 1, lu = 2, Sp = 3, eb = 4, Eg = 5, kp = 6, wm = 7, Ig = 8, su = 9, Le = tr, Er = null, _l = false, Pd = false, Lg = false, Ta = 0, nn = ki, Rl = 0, El = 0, Ng = 0, rr = 0, uu = 0, wp = null, Bt = null, Pm = false, xm = 0, nb = 0, tb = 300, Pp = 1 / 0, Fg = 500, xp = null, gn = null, Il = null, zm = 0, Hg = 1, Ag = 2, rb = 3, Ll = 0, ob = 1, ab = 2, ib = 3, lb = 4, Cm = 5, Rn = 0, Nl = null, xd = null, qo = 0, jg = 0, Dg = -0, Wg = null, sb = null, ub = null, Go = zm, cb = null, Gb = 50, zp = 0, Ug = null, Bg = false, Tm = false, Jb = 50, cu = 0, Cp = null, zd = false, _m = null, db = false, fb = /* @__PURE__ */ new Set(), Zb = {}, co = null, Cd = null, pb = false;
13429
- try {
13430
- var o0 = Object.preventExtensions({});
13431
- } catch {
13432
- pb = true;
13040
+ });
13041
+ if (pointerState.captured.has(object)) {
13042
+ releaseInternalPointerCapture(internal, object, pointerId);
13043
+ }
13044
+ }
13045
+ unregisterVisibility(store, object);
13046
+ }
13047
+ function createEvents(store) {
13048
+ function calculateDistance(event, pointerId) {
13049
+ const { internal } = store.getState();
13050
+ const pointerState = internal.pointerMap.get(pointerId);
13051
+ if (!pointerState) return 0;
13052
+ const [initialX, initialY] = pointerState.initialClick;
13053
+ const dx = event.offsetX - initialX;
13054
+ const dy = event.offsetY - initialY;
13055
+ return Math.round(Math.sqrt(dx * dx + dy * dy));
13056
+ }
13057
+ function filterPointerEvents(objects) {
13058
+ return objects.filter(
13059
+ (obj) => ["Move", "Over", "Enter", "Out", "Leave"].some(
13060
+ (name) => obj.__r3f?.handlers["onPointer" + name]
13061
+ ) || ["OverEnter", "OverLeave", "Over"].some(
13062
+ (name) => obj.__r3f?.handlers["onDrag" + name]
13063
+ ) || obj.__r3f?.handlers.onDrop
13064
+ );
13065
+ }
13066
+ function intersect(event, filter) {
13067
+ const state = store.getState();
13068
+ const duplicates = /* @__PURE__ */ new Set();
13069
+ const intersections = [];
13070
+ const eventsObjects = filter ? filter(state.internal.interaction) : state.internal.interaction;
13071
+ for (let i = 0; i < eventsObjects.length; i++) {
13072
+ const state2 = getRootState(eventsObjects[i]);
13073
+ if (state2) {
13074
+ state2.raycaster.camera = void 0;
13433
13075
  }
13434
- var hb = false, mb = {}, gb = null, yb = null, bb = null, vb = null, Sb = null, kb = null, wb = null, Pb = null, xb = null, zb = null;
13435
- return gb = function(e, n, o, i) {
13436
- n = Yn(e, n), n !== null && (o = _d(n.memoizedState, o, 0, i), n.memoizedState = o, n.baseState = o, e.memoizedProps = ze({}, e.memoizedProps), o = On(e, 2), o !== null && We(o, e, 2));
13437
- }, yb = function(e, n, o) {
13438
- n = Yn(e, n), n !== null && (o = du(n.memoizedState, o, 0), n.memoizedState = o, n.baseState = o, e.memoizedProps = ze({}, e.memoizedProps), o = On(e, 2), o !== null && We(o, e, 2));
13439
- }, bb = function(e, n, o, i) {
13440
- n = Yn(e, n), n !== null && (o = F(n.memoizedState, o, i), n.memoizedState = o, n.baseState = o, e.memoizedProps = ze({}, e.memoizedProps), o = On(e, 2), o !== null && We(o, e, 2));
13441
- }, vb = function(e, n, o) {
13442
- e.pendingProps = _d(e.memoizedProps, n, 0, o), e.alternate && (e.alternate.pendingProps = e.pendingProps), n = On(e, 2), n !== null && We(n, e, 2);
13443
- }, Sb = function(e, n) {
13444
- e.pendingProps = du(e.memoizedProps, n, 0), e.alternate && (e.alternate.pendingProps = e.pendingProps), n = On(e, 2), n !== null && We(n, e, 2);
13445
- }, kb = function(e, n, o) {
13446
- e.pendingProps = F(e.memoizedProps, n, o), e.alternate && (e.alternate.pendingProps = e.pendingProps), n = On(e, 2), n !== null && We(n, e, 2);
13447
- }, wb = function(e) {
13448
- var n = On(e, 2);
13449
- n !== null && We(n, e, 2);
13450
- }, Pb = function(e) {
13451
- var n = ut(), o = On(e, n);
13452
- o !== null && We(o, e, n);
13453
- }, xb = function(e) {
13454
- pu = e;
13455
- }, zb = function(e) {
13456
- fu = e;
13457
- }, le.attemptContinuousHydration = function(e) {
13458
- if (e.tag === 13 || e.tag === 31) {
13459
- var n = On(e, 67108864);
13460
- n !== null && We(n, e, 67108864), rl(e, 67108864);
13076
+ }
13077
+ if (!state.previousRoot) {
13078
+ state.events.compute?.(event, state);
13079
+ }
13080
+ function handleRaycast(obj) {
13081
+ const state2 = getRootState(obj);
13082
+ if (!state2 || !state2.events.enabled || state2.raycaster.camera === null) return [];
13083
+ if (state2.raycaster.camera === void 0) {
13084
+ state2.events.compute?.(event, state2, state2.previousRoot?.getState());
13085
+ if (state2.raycaster.camera === void 0) state2.raycaster.camera = null;
13086
+ }
13087
+ if (!state2.raycaster.camera) return [];
13088
+ obj.updateWorldMatrix(true, true);
13089
+ return state2.raycaster.intersectObject(obj, true);
13090
+ }
13091
+ let hits = eventsObjects.flatMap(handleRaycast).sort((a, b) => {
13092
+ const aInteractivePriority = a.object.userData?.interactivePriority;
13093
+ const bInteractivePriority = b.object.userData?.interactivePriority;
13094
+ if (aInteractivePriority !== void 0 || bInteractivePriority !== void 0) {
13095
+ if (aInteractivePriority !== void 0 && bInteractivePriority === void 0) return -1;
13096
+ if (bInteractivePriority !== void 0 && aInteractivePriority === void 0) return 1;
13097
+ if (aInteractivePriority !== bInteractivePriority) {
13098
+ return (bInteractivePriority ?? 0) - (aInteractivePriority ?? 0);
13461
13099
  }
13462
- }, le.attemptHydrationAtCurrentPriority = function(e) {
13463
- if (e.tag === 13 || e.tag === 31) {
13464
- var n = Nt(e);
13465
- n = Xo(n);
13466
- var o = On(e, n);
13467
- o !== null && We(o, e, n), rl(e, n);
13100
+ }
13101
+ const aState = getRootState(a.object);
13102
+ const bState = getRootState(b.object);
13103
+ const aPriority = aState?.events?.priority ?? 1;
13104
+ const bPriority = bState?.events?.priority ?? 1;
13105
+ return bPriority - aPriority || a.distance - b.distance;
13106
+ }).filter((item) => {
13107
+ const id = makeId(item);
13108
+ if (duplicates.has(id)) return false;
13109
+ duplicates.add(id);
13110
+ return true;
13111
+ });
13112
+ if (state.events.filter) hits = state.events.filter(hits, state);
13113
+ for (const hit of hits) {
13114
+ let eventObject = hit.object;
13115
+ while (eventObject) {
13116
+ if (eventObject.__r3f?.eventCount) {
13117
+ intersections.push({ ...hit, eventObject });
13468
13118
  }
13469
- }, le.attemptSynchronousHydration = function(e) {
13470
- switch (e.tag) {
13471
- case 3:
13472
- if (e = e.stateNode, e.current.memoizedState.isDehydrated) {
13473
- var n = _t(e.pendingLanes);
13474
- if (n !== 0) {
13475
- for (e.pendingLanes |= 2, e.entangledLanes |= 2; n; ) {
13476
- var o = 1 << 31 - vn(n);
13477
- e.entanglements[1] |= o, n &= ~o;
13119
+ eventObject = eventObject.parent;
13120
+ }
13121
+ }
13122
+ if ("pointerId" in event) {
13123
+ const pointerId = event.pointerId;
13124
+ const pointerState = state.internal.pointerMap.get(pointerId);
13125
+ if (pointerState?.captured.size) {
13126
+ for (const captureData of pointerState.captured.values()) {
13127
+ if (!duplicates.has(makeId(captureData.intersection))) intersections.push(captureData.intersection);
13128
+ }
13129
+ }
13130
+ }
13131
+ return intersections;
13132
+ }
13133
+ function handleIntersects(intersections, event, delta, callback) {
13134
+ if (intersections.length) {
13135
+ const localState = { stopped: false };
13136
+ for (const hit of intersections) {
13137
+ const state = getRootState(hit.object);
13138
+ if (state) {
13139
+ const { raycaster, pointer, camera, internal } = state;
13140
+ const unprojectedPoint = new Vector3(pointer.x, pointer.y, 0).unproject(camera);
13141
+ const hasPointerCapture = (id) => {
13142
+ const pointerState = internal.pointerMap.get(id);
13143
+ return pointerState?.captured.has(hit.eventObject) ?? false;
13144
+ };
13145
+ const setPointerCapture = (id) => {
13146
+ const captureData = { intersection: hit, target: event.target };
13147
+ const pointerState = getPointerState(internal, id);
13148
+ pointerState.captured.set(hit.eventObject, captureData);
13149
+ event.target.setPointerCapture(id);
13150
+ };
13151
+ const releasePointerCapture = (id) => {
13152
+ releaseInternalPointerCapture(internal, hit.eventObject, id);
13153
+ };
13154
+ const extractEventProps = {};
13155
+ for (const prop in event) {
13156
+ const property = event[prop];
13157
+ if (typeof property !== "function") extractEventProps[prop] = property;
13158
+ }
13159
+ const eventPointerId = "pointerId" in event ? event.pointerId : void 0;
13160
+ const raycastEvent = {
13161
+ ...hit,
13162
+ ...extractEventProps,
13163
+ pointer,
13164
+ intersections,
13165
+ stopped: localState.stopped,
13166
+ delta,
13167
+ unprojectedPoint,
13168
+ ray: raycaster.ray,
13169
+ camera,
13170
+ pointerId: eventPointerId,
13171
+ // Hijack stopPropagation, which just sets a flag
13172
+ stopPropagation() {
13173
+ const pointerState = eventPointerId !== void 0 ? internal.pointerMap.get(eventPointerId) : void 0;
13174
+ if (
13175
+ // ...if this pointer hasn't been captured
13176
+ !pointerState?.captured.size || // ... or if the hit object is capturing the pointer
13177
+ pointerState.captured.has(hit.eventObject)
13178
+ ) {
13179
+ raycastEvent.stopped = localState.stopped = true;
13180
+ if (pointerState?.hovered.size && Array.from(pointerState.hovered.values()).find((i) => i.eventObject === hit.eventObject)) {
13181
+ const higher = intersections.slice(0, intersections.indexOf(hit));
13182
+ cancelPointer([...higher, hit], eventPointerId);
13478
13183
  }
13479
- Kn(e), (ye & (Zn | uo)) === Jn && (Pp = me() + Fg, Wa(0));
13480
13184
  }
13481
- }
13482
- break;
13483
- case 31:
13484
- case 13:
13485
- n = On(e, 2), n !== null && We(n, e, 2), Ls(), rl(e, 2);
13185
+ },
13186
+ // there should be a distinction between target and currentTarget
13187
+ target: { hasPointerCapture, setPointerCapture, releasePointerCapture },
13188
+ currentTarget: { hasPointerCapture, setPointerCapture, releasePointerCapture },
13189
+ nativeEvent: event
13190
+ };
13191
+ callback(raycastEvent);
13192
+ if (localState.stopped === true) break;
13486
13193
  }
13487
- }, le.batchedUpdates = function(e, n) {
13488
- return e(n);
13489
- }, le.createComponentSelector = function(e) {
13490
- return { $$typeof: pm, value: e };
13491
- }, le.createContainer = function(e, n, o, i, s, u, f, p, g, S) {
13492
- return Ka(e, n, false, null, o, i, u, null, f, p, g, S);
13493
- }, le.createHasPseudoClassSelector = function(e) {
13494
- return { $$typeof: hm, value: e };
13495
- }, le.createHydrationContainer = function(e, n, o, i, s, u, f, p, g, S, T, _, I, O) {
13496
- return e = Ka(o, i, true, e, s, u, p, O, g, S, T, _), e.context = Dh(null), o = e.current, i = Nt(o), i = Xo(i), s = zo(i), s.callback = n ?? null, Mt(o, s, i), ur(i, "hydrateRoot()", null), n = i, e.current.lanes = n, Ci(e, n), Kn(e), e;
13497
- }, le.createPortal = function(e, n, o) {
13498
- var i = 3 < arguments.length && arguments[3] !== void 0 ? arguments[3] : null;
13499
- try {
13500
- vt(i);
13501
- var s = false;
13502
- } catch {
13503
- s = true;
13194
+ }
13195
+ }
13196
+ return intersections;
13197
+ }
13198
+ function cancelPointer(intersections, pointerId) {
13199
+ const { internal } = store.getState();
13200
+ const pid = pointerId ?? DEFAULT_POINTER_ID;
13201
+ const pointerState = internal.pointerMap.get(pid);
13202
+ if (!pointerState) return;
13203
+ for (const [hoveredId, hoveredObj] of pointerState.hovered) {
13204
+ if (!intersections.length || !intersections.find(
13205
+ (hit) => hit.object === hoveredObj.object && hit.index === hoveredObj.index && hit.instanceId === hoveredObj.instanceId
13206
+ )) {
13207
+ const eventObject = hoveredObj.eventObject;
13208
+ const instance = eventObject.__r3f;
13209
+ pointerState.hovered.delete(hoveredId);
13210
+ if (instance?.eventCount) {
13211
+ const handlers = instance.handlers;
13212
+ const data = { ...hoveredObj, intersections };
13213
+ handlers.onPointerOut?.(data);
13214
+ handlers.onPointerLeave?.(data);
13215
+ handlers.onDragOverLeave?.(data);
13504
13216
  }
13505
- return s && (console.error("The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", typeof Symbol == "function" && Symbol.toStringTag && i[Symbol.toStringTag] || i.constructor.name || "Object"), vt(i)), { $$typeof: Ao, key: i == null ? null : "" + i, children: e, containerInfo: n, implementation: o };
13506
- }, le.createRoleSelector = function(e) {
13507
- return { $$typeof: mm, value: e };
13508
- }, le.createTestNameSelector = function(e) {
13509
- return { $$typeof: gm, value: e };
13510
- }, le.createTextSelector = function(e) {
13511
- return { $$typeof: ym, value: e };
13512
- }, le.defaultOnCaughtError = function(e) {
13513
- var n = bd ? "The above error occurred in the <" + bd + "> component." : "The above error occurred in one of your React components.", o = "React will try to recreate this component tree from scratch using the error boundary you provided, " + ((Cg || "Anonymous") + ".");
13514
- typeof e == "object" && e !== null && typeof e.environmentName == "string" ? ri("error", [`%o
13515
-
13516
- %s
13517
-
13518
- %s
13519
- `, e, n, o], e.environmentName)() : console.error(`%o
13520
-
13521
- %s
13522
-
13523
- %s
13524
- `, e, n, o);
13525
- }, le.defaultOnRecoverableError = function(e) {
13526
- qg(e);
13527
- }, le.defaultOnUncaughtError = function(e) {
13528
- qg(e), console.warn(`%s
13529
-
13530
- %s
13531
- `, bd ? "An error occurred in the <" + bd + "> component." : "An error occurred in one of your React components.", `Consider adding an error boundary to your tree to customize error handling behavior.
13532
- Visit https://react.dev/link/error-boundaries to learn more about error boundaries.`);
13533
- }, le.deferredUpdates = function(e) {
13534
- var n = x.T, o = wt();
13535
- try {
13536
- return an(32), x.T = null, e();
13537
- } finally {
13538
- an(o), x.T = n;
13217
+ }
13218
+ }
13219
+ }
13220
+ function pointerMissed(event, objects) {
13221
+ for (let i = 0; i < objects.length; i++) {
13222
+ const instance = objects[i].__r3f;
13223
+ instance?.handlers.onPointerMissed?.(event);
13224
+ }
13225
+ }
13226
+ function dragOverMissed(event, objects) {
13227
+ for (let i = 0; i < objects.length; i++) {
13228
+ const instance = objects[i].__r3f;
13229
+ instance?.handlers.onDragOverMissed?.(event);
13230
+ }
13231
+ }
13232
+ function dropMissed(event, objects) {
13233
+ for (let i = 0; i < objects.length; i++) {
13234
+ const instance = objects[i].__r3f;
13235
+ instance?.handlers.onDropMissed?.(event);
13236
+ }
13237
+ }
13238
+ function cleanupPointer(pointerId) {
13239
+ const { internal } = store.getState();
13240
+ const pointerState = internal.pointerMap.get(pointerId);
13241
+ if (pointerState) {
13242
+ for (const [, hoveredObj] of pointerState.hovered) {
13243
+ const eventObject = hoveredObj.eventObject;
13244
+ const instance = eventObject.__r3f;
13245
+ if (instance?.eventCount) {
13246
+ const handlers = instance.handlers;
13247
+ const data = { ...hoveredObj, intersections: [] };
13248
+ handlers.onPointerOut?.(data);
13249
+ handlers.onPointerLeave?.(data);
13539
13250
  }
13540
- }, le.discreteUpdates = function(e, n, o, i, s) {
13541
- var u = x.T, f = wt();
13542
- try {
13543
- return an(2), x.T = null, e(n, o, i, s);
13544
- } finally {
13545
- an(f), x.T = u, ye === Jn && (Pp = me() + Fg);
13251
+ }
13252
+ internal.pointerMap.delete(pointerId);
13253
+ }
13254
+ internal.pointerDirty.delete(pointerId);
13255
+ }
13256
+ function processDeferredPointer(event, pointerId) {
13257
+ const state = store.getState();
13258
+ const { internal } = state;
13259
+ if (!state.events.enabled) return;
13260
+ const filter = filterPointerEvents;
13261
+ const hits = intersect(event, filter);
13262
+ cancelPointer(hits, pointerId);
13263
+ function onIntersect(data) {
13264
+ const eventObject = data.eventObject;
13265
+ const instance = eventObject.__r3f;
13266
+ if (!instance?.eventCount) return;
13267
+ const handlers = instance.handlers;
13268
+ if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
13269
+ const id = makeId(data);
13270
+ const pointerState = getPointerState(internal, pointerId);
13271
+ const hoveredItem = pointerState.hovered.get(id);
13272
+ if (!hoveredItem) {
13273
+ pointerState.hovered.set(id, data);
13274
+ handlers.onPointerOver?.(data);
13275
+ handlers.onPointerEnter?.(data);
13276
+ } else if (hoveredItem.stopped) {
13277
+ data.stopPropagation();
13546
13278
  }
13547
- }, le.findAllNodes = kc, le.findBoundingRects = function(e, n) {
13548
- if (!xr) throw Error("Test selector API is not supported by this renderer.");
13549
- n = kc(e, n), e = [];
13550
- for (var o = 0; o < n.length; o++) e.push(ma(n[o]));
13551
- for (n = e.length - 1; 0 < n; n--) {
13552
- o = e[n];
13553
- for (var i = o.x, s = i + o.width, u = o.y, f = u + o.height, p = n - 1; 0 <= p; p--) if (n !== p) {
13554
- var g = e[p], S = g.x, T = S + g.width, _ = g.y, I = _ + g.height;
13555
- if (i >= S && u >= _ && s <= T && f <= I) {
13556
- e.splice(n, 1);
13557
- break;
13558
- } else if (i !== S || o.width !== g.width || I < u || _ > f) {
13559
- if (!(u !== _ || o.height !== g.height || T < i || S > s)) {
13560
- S > i && (g.width += S - i, g.x = i), T < s && (g.width = s - S), e.splice(n, 1);
13561
- break;
13279
+ }
13280
+ handlers.onPointerMove?.(data);
13281
+ }
13282
+ handleIntersects(hits, event, 0, onIntersect);
13283
+ }
13284
+ function handlePointer(name) {
13285
+ switch (name) {
13286
+ case "onPointerLeave":
13287
+ case "onDragLeave":
13288
+ return () => cancelPointer([]);
13289
+ // Global cancel of these events
13290
+ case "onPointerCancel":
13291
+ return (event) => {
13292
+ const pointerId = getPointerId(event);
13293
+ cleanupPointer(pointerId);
13294
+ };
13295
+ case "onLostPointerCapture":
13296
+ return (event) => {
13297
+ const { internal } = store.getState();
13298
+ const pointerId = getPointerId(event);
13299
+ const pointerState = internal.pointerMap.get(pointerId);
13300
+ if (pointerState?.captured.size) {
13301
+ requestAnimationFrame(() => {
13302
+ const pointerState2 = internal.pointerMap.get(pointerId);
13303
+ if (pointerState2?.captured.size) {
13304
+ pointerState2.captured.clear();
13562
13305
  }
13563
- } else {
13564
- _ > u && (g.height += _ - u, g.y = u), I < f && (g.height = f - _), e.splice(n, 1);
13565
- break;
13306
+ cancelPointer([], pointerId);
13307
+ });
13308
+ }
13309
+ };
13310
+ }
13311
+ return function handleEvent(event) {
13312
+ const state = store.getState();
13313
+ const { onPointerMissed, onDragOverMissed, onDropMissed, internal, events } = state;
13314
+ const pointerId = getPointerId(event);
13315
+ internal.lastEvent.current = event;
13316
+ if (!events.enabled) return;
13317
+ const isPointerMove = name === "onPointerMove";
13318
+ const isDragOver = name === "onDragOver";
13319
+ const isDrop = name === "onDrop";
13320
+ const isClickEvent = name === "onClick" || name === "onContextMenu" || name === "onDoubleClick";
13321
+ const isPointerDown = name === "onPointerDown";
13322
+ const isPointerUp = name === "onPointerUp";
13323
+ const isWheel = name === "onWheel";
13324
+ const canDeferRaycasts = events.frameTimedRaycasts && state.frameloop === "always";
13325
+ if (isPointerMove && canDeferRaycasts) {
13326
+ events.compute?.(event, state);
13327
+ internal.pointerDirty.set(pointerId, event);
13328
+ return;
13329
+ }
13330
+ if (isWheel && canDeferRaycasts && !events.alwaysFireOnScroll) {
13331
+ events.compute?.(event, state);
13332
+ internal.pointerDirty.set(pointerId, event);
13333
+ return;
13334
+ }
13335
+ if ((isClickEvent || isPointerDown || isPointerUp) && internal.pointerDirty.has(pointerId)) {
13336
+ const deferredEvent = internal.pointerDirty.get(pointerId);
13337
+ internal.pointerDirty.delete(pointerId);
13338
+ processDeferredPointer(deferredEvent, pointerId);
13339
+ }
13340
+ const filter = isPointerMove || isDragOver || isDrop ? filterPointerEvents : void 0;
13341
+ const hits = intersect(event, filter);
13342
+ const delta = isClickEvent ? calculateDistance(event, pointerId) : 0;
13343
+ if (isPointerDown) {
13344
+ const pointerState2 = getPointerState(internal, pointerId);
13345
+ pointerState2.initialClick = [event.offsetX, event.offsetY];
13346
+ pointerState2.initialHits = hits.map((hit) => hit.eventObject);
13347
+ }
13348
+ const pointerState = internal.pointerMap.get(pointerId);
13349
+ const initialHits = pointerState?.initialHits ?? [];
13350
+ if (isClickEvent && !hits.length) {
13351
+ if (delta <= 2) {
13352
+ pointerMissed(event, internal.interaction);
13353
+ if (onPointerMissed) onPointerMissed(event);
13354
+ }
13355
+ }
13356
+ if (isDragOver && !hits.length) {
13357
+ dragOverMissed(event, internal.interaction);
13358
+ if (onDragOverMissed) onDragOverMissed(event);
13359
+ }
13360
+ if (isDrop && !hits.length) {
13361
+ dropMissed(event, internal.interaction);
13362
+ if (onDropMissed) onDropMissed(event);
13363
+ }
13364
+ if (isPointerMove || isDragOver) {
13365
+ cancelPointer(hits, pointerId);
13366
+ }
13367
+ function onIntersect(data) {
13368
+ const eventObject = data.eventObject;
13369
+ const instance = eventObject.__r3f;
13370
+ if (!instance?.eventCount) return;
13371
+ const handlers = instance.handlers;
13372
+ if (isPointerMove) {
13373
+ if (handlers.onPointerOver || handlers.onPointerEnter || handlers.onPointerOut || handlers.onPointerLeave) {
13374
+ const id = makeId(data);
13375
+ const pointerState2 = getPointerState(internal, pointerId);
13376
+ const hoveredItem = pointerState2.hovered.get(id);
13377
+ if (!hoveredItem) {
13378
+ pointerState2.hovered.set(id, data);
13379
+ handlers.onPointerOver?.(data);
13380
+ handlers.onPointerEnter?.(data);
13381
+ } else if (hoveredItem.stopped) {
13382
+ data.stopPropagation();
13566
13383
  }
13567
13384
  }
13568
- }
13569
- return e;
13570
- }, le.findHostInstance = function(e) {
13571
- var n = e._reactInternals;
13572
- if (n === void 0) throw typeof e.render == "function" ? Error("Unable to find node on an unmounted component.") : (e = Object.keys(e).join(","), Error("Argument appears to not be a ReactComponent. Keys: " + e));
13573
- return e = mu(n), e === null ? null : ot(e.stateNode);
13574
- }, le.findHostInstanceWithNoPortals = function(e) {
13575
- return e = Ed(e), e = e !== null ? _p(e) : null, e === null ? null : ot(e.stateNode);
13576
- }, le.findHostInstanceWithWarning = function(e, n) {
13577
- var o = e._reactInternals;
13578
- if (o === void 0) throw typeof e.render == "function" ? Error("Unable to find node on an unmounted component.") : (e = Object.keys(e).join(","), Error("Argument appears to not be a ReactComponent. Keys: " + e));
13579
- if (e = mu(o), e === null) return null;
13580
- if (e.mode & 8) {
13581
- var i = G(o) || "Component";
13582
- mb[i] || (mb[i] = true, B(e, function() {
13583
- o.mode & 8 ? console.error("%s is deprecated in StrictMode. %s was passed an instance of %s which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://react.dev/link/strict-mode-find-node", n, n, i) : console.error("%s is deprecated in StrictMode. %s was passed an instance of %s which renders StrictMode children. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://react.dev/link/strict-mode-find-node", n, n, i);
13584
- }));
13585
- }
13586
- return ot(e.stateNode);
13587
- }, le.flushPassiveEffects = el, le.flushSyncFromReconciler = function(e) {
13588
- var n = ye;
13589
- ye |= 1;
13590
- var o = x.T, i = wt();
13591
- try {
13592
- if (an(2), x.T = null, e) return e();
13593
- } finally {
13594
- an(i), x.T = o, ye = n, (ye & (Zn | uo)) === Jn && Wa(0);
13595
- }
13596
- }, le.flushSyncWork = Ls, le.focusWithin = function(e, n) {
13597
- if (!xr) throw Error("Test selector API is not supported by this renderer.");
13598
- for (e = Ef(e), n = hh(e, n), n = Array.from(n), e = 0; e < n.length; ) {
13599
- var o = n[e++], i = o.tag;
13600
- if (!Kr(o)) {
13601
- if ((i === 5 || i === 26 || i === 27) && Ft(o.stateNode)) return true;
13602
- for (o = o.child; o !== null; ) n.push(o), o = o.sibling;
13385
+ handlers.onPointerMove?.(data);
13386
+ } else if (isDragOver) {
13387
+ const id = makeId(data);
13388
+ const pointerState2 = getPointerState(internal, pointerId);
13389
+ const hoveredItem = pointerState2.hovered.get(id);
13390
+ if (!hoveredItem) {
13391
+ pointerState2.hovered.set(id, data);
13392
+ handlers.onDragOverEnter?.(data);
13393
+ } else if (hoveredItem.stopped) {
13394
+ data.stopPropagation();
13395
+ }
13396
+ handlers.onDragOver?.(data);
13397
+ } else if (isDrop) {
13398
+ handlers.onDrop?.(data);
13399
+ } else {
13400
+ const handler = handlers[name];
13401
+ if (handler) {
13402
+ if (!isClickEvent || initialHits.includes(eventObject)) {
13403
+ pointerMissed(
13404
+ event,
13405
+ internal.interaction.filter((object) => !initialHits.includes(object))
13406
+ );
13407
+ handler(data);
13408
+ }
13409
+ } else {
13410
+ if (isClickEvent && initialHits.includes(eventObject)) {
13411
+ pointerMissed(
13412
+ event,
13413
+ internal.interaction.filter((object) => !initialHits.includes(object))
13414
+ );
13415
+ }
13603
13416
  }
13604
13417
  }
13605
- return false;
13606
- }, le.getFindAllNodesFailureDescription = function(e, n) {
13607
- if (!xr) throw Error("Test selector API is not supported by this renderer.");
13608
- var o = 0, i = [];
13609
- e = [Ef(e), 0];
13610
- for (var s = 0; s < e.length; ) {
13611
- var u = e[s++], f = u.tag, p = e[s++], g = n[p];
13612
- if ((f !== 5 && f !== 26 && f !== 27 || !Kr(u)) && (If(u, g) && (i.push(Sc(g)), p++, p > o && (o = p)), p < n.length)) for (u = u.child; u !== null; ) e.push(u, p), u = u.sibling;
13418
+ }
13419
+ handleIntersects(hits, event, delta, onIntersect);
13420
+ };
13421
+ }
13422
+ function flushDeferredPointers() {
13423
+ const { internal, events } = store.getState();
13424
+ if (!events.frameTimedRaycasts) return;
13425
+ for (const [pointerId, event] of internal.pointerDirty) {
13426
+ processDeferredPointer(event, pointerId);
13427
+ }
13428
+ internal.pointerDirty.clear();
13429
+ }
13430
+ return { handlePointer, flushDeferredPointers, processDeferredPointer };
13431
+ }
13432
+ const DOM_EVENTS = {
13433
+ onClick: ["click", false],
13434
+ onContextMenu: ["contextmenu", false],
13435
+ onDoubleClick: ["dblclick", false],
13436
+ onDragEnter: ["dragenter", false],
13437
+ onDragLeave: ["dragleave", false],
13438
+ onDragOver: ["dragover", false],
13439
+ onDrop: ["drop", false],
13440
+ onWheel: ["wheel", true],
13441
+ onPointerDown: ["pointerdown", true],
13442
+ onPointerUp: ["pointerup", true],
13443
+ onPointerLeave: ["pointerleave", true],
13444
+ onPointerMove: ["pointermove", true],
13445
+ onPointerCancel: ["pointercancel", true],
13446
+ onLostPointerCapture: ["lostpointercapture", true]
13447
+ };
13448
+ function createPointerEvents(store) {
13449
+ const { handlePointer, flushDeferredPointers, processDeferredPointer } = createEvents(store);
13450
+ let nextXRPointerId = XR_POINTER_ID_START;
13451
+ const xrPointers = /* @__PURE__ */ new Map();
13452
+ return {
13453
+ priority: 1,
13454
+ enabled: true,
13455
+ frameTimedRaycasts: true,
13456
+ alwaysFireOnScroll: true,
13457
+ updateOnFrame: false,
13458
+ compute(event, state) {
13459
+ state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
13460
+ state.raycaster.setFromCamera(state.pointer, state.camera);
13461
+ },
13462
+ connected: void 0,
13463
+ handlers: Object.keys(DOM_EVENTS).reduce(
13464
+ (acc, key) => ({ ...acc, [key]: handlePointer(key) }),
13465
+ {}
13466
+ ),
13467
+ update: (pointerId) => {
13468
+ const { events, internal } = store.getState();
13469
+ if (!events.handlers) return;
13470
+ if (pointerId !== void 0) {
13471
+ const event = internal.pointerDirty.get(pointerId);
13472
+ if (event) {
13473
+ internal.pointerDirty.delete(pointerId);
13474
+ processDeferredPointer(event, pointerId);
13475
+ } else if (internal.lastEvent?.current) {
13476
+ processDeferredPointer(internal.lastEvent.current, pointerId);
13613
13477
  }
13614
- if (o < n.length) {
13615
- for (e = []; o < n.length; o++) e.push(Sc(n[o]));
13616
- return `findAllNodes was able to match part of the selector:
13617
- ` + (i.join(" > ") + `
13618
-
13619
- No matching component was found for:
13620
- `) + e.join(" > ");
13478
+ } else {
13479
+ flushDeferredPointers();
13480
+ if (internal.lastEvent?.current) {
13481
+ events.handlers.onPointerMove(internal.lastEvent.current);
13621
13482
  }
13622
- return null;
13623
- }, le.getPublicRootInstance = function(e) {
13624
- if (e = e.current, !e.child) return null;
13625
- switch (e.child.tag) {
13626
- case 27:
13627
- case 5:
13628
- return ot(e.child.stateNode);
13629
- default:
13630
- return e.child.stateNode;
13483
+ }
13484
+ },
13485
+ flush: () => {
13486
+ const { events, internal } = store.getState();
13487
+ flushDeferredPointers();
13488
+ if (events.updateOnFrame && internal.lastEvent?.current && events.handlers) {
13489
+ events.handlers.onPointerMove(internal.lastEvent.current);
13490
+ }
13491
+ },
13492
+ connect: (target) => {
13493
+ if (!target) return;
13494
+ const { set, events } = store.getState();
13495
+ events.disconnect?.();
13496
+ set((state) => ({ events: { ...state.events, connected: target } }));
13497
+ if (events.handlers) {
13498
+ for (const name in events.handlers) {
13499
+ const event = events.handlers[name];
13500
+ const [eventName, passive] = DOM_EVENTS[name];
13501
+ target.addEventListener(eventName, event, { passive });
13631
13502
  }
13632
- }, le.injectIntoDevTools = function() {
13633
- var e = { bundleType: 1, version: Jt, rendererPackageName: Zt, currentDispatcherRef: x, reconcilerVersion: "19.2.0" };
13634
- return jo !== null && (e.rendererConfig = jo), e.overrideHookState = gb, e.overrideHookStateDeletePath = yb, e.overrideHookStateRenamePath = bb, e.overrideProps = vb, e.overridePropsDeletePath = Sb, e.overridePropsRenamePath = kb, e.scheduleUpdate = wb, e.scheduleRetry = Pb, e.setErrorHandler = xb, e.setSuspenseHandler = zb, e.scheduleRefresh = hu, e.scheduleRoot = Fl, e.setRefreshHandler = Ir, e.getCurrentFiber = Ic, Ep(e);
13635
- }, le.isAlreadyRendering = Ns, le.observeVisibleRects = function(e, n, o, i) {
13636
- function s() {
13637
- var S = kc(e, n);
13638
- u.forEach(function(T) {
13639
- 0 > S.indexOf(T) && g(T);
13640
- }), S.forEach(function(T) {
13641
- 0 > u.indexOf(T) && p(T);
13642
- });
13503
+ }
13504
+ },
13505
+ disconnect: () => {
13506
+ const { set, events } = store.getState();
13507
+ if (events.connected) {
13508
+ if (events.handlers) {
13509
+ for (const name in events.handlers) {
13510
+ const event = events.handlers[name];
13511
+ const [eventName] = DOM_EVENTS[name];
13512
+ events.connected.removeEventListener(eventName, event);
13513
+ }
13514
+ }
13515
+ set((state) => ({ events: { ...state.events, connected: void 0 } }));
13516
+ }
13517
+ },
13518
+ // PREVIEW (A8): the XR pointer registration API may change before stable.
13519
+ registerPointer: (config) => {
13520
+ const pointerId = nextXRPointerId++;
13521
+ xrPointers.set(pointerId, config);
13522
+ const { internal } = store.getState();
13523
+ getPointerState(internal, pointerId);
13524
+ return pointerId;
13525
+ },
13526
+ unregisterPointer: (pointerId) => {
13527
+ xrPointers.delete(pointerId);
13528
+ const { internal } = store.getState();
13529
+ const pointerState = internal.pointerMap.get(pointerId);
13530
+ if (pointerState) {
13531
+ for (const [, hoveredObj] of pointerState.hovered) {
13532
+ const eventObject = hoveredObj.eventObject;
13533
+ const instance = eventObject.__r3f;
13534
+ if (instance?.eventCount) {
13535
+ const handlers = instance.handlers;
13536
+ const data = { ...hoveredObj, intersections: [] };
13537
+ handlers.onPointerOut?.(data);
13538
+ handlers.onPointerLeave?.(data);
13539
+ }
13643
13540
  }
13644
- if (!xr) throw Error("Test selector API is not supported by this renderer.");
13645
- var u = kc(e, n);
13646
- o = zr(u, o, i);
13647
- var f = o.disconnect, p = o.observe, g = o.unobserve;
13648
- return bm.push(s), { disconnect: function() {
13649
- var S = bm.indexOf(s);
13650
- 0 <= S && bm.splice(S, 1), f();
13651
- } };
13652
- }, le.shouldError = function(e) {
13653
- return pu(e);
13654
- }, le.shouldSuspend = function(e) {
13655
- return fu(e);
13656
- }, le.startHostTransition = function(e, n, o, i) {
13657
- if (e.tag !== 5) throw Error("Expected the form instance to be a HostComponent. This is a bug in React.");
13658
- var s = uf(e).queue;
13659
- Hp(e), nt(e, s, n, Xt, o === null ? Em : function() {
13660
- x.T === null && console.error("requestFormReset was called outside a transition or action. To fix, move to an action, or wrap with startTransition.");
13661
- var u = uf(e);
13662
- return u.next === null && (u = e.alternate.memoizedState), qi(e, u.next.queue, {}, Nt(e)), o(i);
13663
- });
13664
- }, le.updateContainer = function(e, n, o, i) {
13665
- var s = n.current, u = Nt(s);
13666
- return As(s, u, e, n, o, i), u;
13667
- }, le.updateContainerSync = Wh, le;
13668
- }, Tt.exports.default = Tt.exports, Object.defineProperty(Tt.exports, "__esModule", { value: true }));
13669
- })(Mg)), Mg.exports;
13670
- }
13671
- var Eb;
13672
- function n0() {
13673
- return Eb || (Eb = 1, process.env.NODE_ENV === "production" ? Rm.exports = Kb() : Rm.exports = e0()), Rm.exports;
13541
+ internal.pointerMap.delete(pointerId);
13542
+ }
13543
+ internal.pointerDirty.delete(pointerId);
13544
+ }
13545
+ };
13674
13546
  }
13675
- var t0 = n0();
13676
- const r0 = Xb(t0);
13677
-
13678
- const t = 1, o = 8, r = 32, e = 2;
13679
13547
 
13680
13548
  function createReconciler(config) {
13681
13549
  const reconciler2 = r0(config);
@@ -13695,7 +13563,10 @@ function extend(objects) {
13695
13563
  catalogue[Component] = objects;
13696
13564
  return Component;
13697
13565
  } else {
13698
- Object.assign(catalogue, objects);
13566
+ for (const name in objects) {
13567
+ const object = objects[name];
13568
+ if (isConstructor(object)) catalogue[name] = object;
13569
+ }
13699
13570
  }
13700
13571
  }
13701
13572
  function validateInstance(type, props) {
@@ -13840,7 +13711,15 @@ function setFiberRef(fiber, publicInstance) {
13840
13711
  }
13841
13712
  }
13842
13713
  const reconstructed = [];
13843
- function swapInstances() {
13714
+ function flushReconstructedInstances() {
13715
+ if (reconstructed.length === 0) return;
13716
+ try {
13717
+ swapReconstructedInstances();
13718
+ } finally {
13719
+ reconstructed.length = 0;
13720
+ }
13721
+ }
13722
+ function swapReconstructedInstances() {
13844
13723
  for (const [instance] of reconstructed) {
13845
13724
  const parent = instance.parent;
13846
13725
  if (parent) {
@@ -13858,7 +13737,9 @@ function swapInstances() {
13858
13737
  }
13859
13738
  }
13860
13739
  if (instance.isHidden) unhideInstance(instance);
13861
- if (isObject3D(instance.object)) removeInteractivity(findInitialRoot(instance), instance.object);
13740
+ if (isObject3D(instance.object) && !instance.parent) {
13741
+ removeInteractivity(findInitialRoot(instance), instance.object);
13742
+ }
13862
13743
  if (instance.object.__r3f) delete instance.object.__r3f;
13863
13744
  if (instance.type !== "primitive") disposeOnIdle(instance.object);
13864
13745
  }
@@ -13867,9 +13748,13 @@ function swapInstances() {
13867
13748
  const parent = instance.parent;
13868
13749
  if (parent) {
13869
13750
  const target = catalogue[toPascalCase(instance.type)];
13751
+ const prevObject = instance.object;
13870
13752
  instance.object = instance.props.object ?? new target(...instance.props.args ?? []);
13871
13753
  instance.object.__r3f = instance;
13872
13754
  setFiberRef(fiber, instance.object);
13755
+ if (isObject3D(prevObject) && isObject3D(instance.object)) {
13756
+ swapInteractivity(findInitialRoot(instance), prevObject, instance.object);
13757
+ }
13873
13758
  delete instance.appliedOnce;
13874
13759
  instance.eventCount = 0;
13875
13760
  instance.handlers = {};
@@ -13889,14 +13774,114 @@ function swapInstances() {
13889
13774
  invalidateInstance(instance);
13890
13775
  }
13891
13776
  }
13892
- reconstructed.length = 0;
13893
13777
  }
13894
13778
  const handleTextInstance = () => {
13895
13779
  };
13896
13780
  const NO_CONTEXT = {};
13897
13781
  let currentUpdatePriority = NoEventPriority;
13898
- const NoFlags = 0;
13899
- const Update = 4;
13782
+ function getEventPriority(type) {
13783
+ switch (type) {
13784
+ case "beforetoggle":
13785
+ case "cancel":
13786
+ case "click":
13787
+ case "close":
13788
+ case "contextmenu":
13789
+ case "copy":
13790
+ case "cut":
13791
+ case "auxclick":
13792
+ case "dblclick":
13793
+ case "dragend":
13794
+ case "dragstart":
13795
+ case "drop":
13796
+ case "focusin":
13797
+ case "focusout":
13798
+ case "input":
13799
+ case "invalid":
13800
+ case "keydown":
13801
+ case "keypress":
13802
+ case "keyup":
13803
+ case "mousedown":
13804
+ case "mouseup":
13805
+ case "paste":
13806
+ case "pause":
13807
+ case "play":
13808
+ case "pointercancel":
13809
+ case "pointerdown":
13810
+ case "pointerup":
13811
+ case "ratechange":
13812
+ case "reset":
13813
+ case "resize":
13814
+ case "seeked":
13815
+ case "submit":
13816
+ case "touchcancel":
13817
+ case "touchend":
13818
+ case "touchstart":
13819
+ case "volumechange":
13820
+ case "change":
13821
+ case "selectionchange":
13822
+ case "compositionstart":
13823
+ case "compositionend":
13824
+ case "compositionupdate":
13825
+ case "beforeinput":
13826
+ case "blur":
13827
+ case "fullscreenchange":
13828
+ case "focus":
13829
+ case "hashchange":
13830
+ case "popstate":
13831
+ case "select":
13832
+ case "selectstart":
13833
+ return e;
13834
+ case "drag":
13835
+ case "dragenter":
13836
+ case "dragexit":
13837
+ case "dragleave":
13838
+ case "dragover":
13839
+ case "mousemove":
13840
+ case "mouseout":
13841
+ case "mouseover":
13842
+ case "pointermove":
13843
+ case "pointerout":
13844
+ case "pointerover":
13845
+ case "scroll":
13846
+ case "touchmove":
13847
+ case "wheel":
13848
+ case "mouseenter":
13849
+ case "mouseleave":
13850
+ case "pointerenter":
13851
+ case "pointerleave":
13852
+ return o;
13853
+ case "message": {
13854
+ switch (unstable_getCurrentPriorityLevel()) {
13855
+ case unstable_ImmediatePriority:
13856
+ return e;
13857
+ case unstable_UserBlockingPriority:
13858
+ return o;
13859
+ case unstable_NormalPriority:
13860
+ case unstable_LowPriority:
13861
+ return r;
13862
+ case unstable_IdlePriority:
13863
+ return i$1;
13864
+ default:
13865
+ return r;
13866
+ }
13867
+ }
13868
+ default:
13869
+ return r;
13870
+ }
13871
+ }
13872
+ function scheduleMicrotask(callback) {
13873
+ if (typeof queueMicrotask === "function") {
13874
+ queueMicrotask(callback);
13875
+ } else if (typeof Promise !== "undefined") {
13876
+ Promise.resolve().then(callback).catch((error) => {
13877
+ setTimeout(() => {
13878
+ throw error;
13879
+ });
13880
+ });
13881
+ } else {
13882
+ setTimeout(callback);
13883
+ }
13884
+ }
13900
13885
  const reconciler = /* @__PURE__ */ createReconciler({
13901
13886
  isPrimaryRenderer: false,
13902
13887
  warnsIfNotActing: false,
@@ -13929,22 +13914,21 @@ const reconciler = /* @__PURE__ */ createReconciler({
13929
13914
  getRootHostContext: () => NO_CONTEXT,
13930
13915
  getChildHostContext: () => NO_CONTEXT,
13931
13916
  commitUpdate(instance, type, oldProps, newProps, fiber) {
13932
- validateInstance(type, newProps);
13917
+ validateInstance(instance.type, newProps);
13933
13918
  let reconstruct = false;
13934
13919
  if (instance.type === "primitive" && oldProps.object !== newProps.object) reconstruct = true;
13935
13920
  else if (newProps.args?.length !== oldProps.args?.length) reconstruct = true;
13936
13921
  else if (newProps.args?.some((value, index) => value !== oldProps.args?.[index])) reconstruct = true;
13937
13922
  if (reconstruct) {
13938
- reconstructed.push([instance, { ...newProps }, fiber]);
13923
+ reconstructed.push([instance, getInstanceProps(newProps), fiber]);
13939
13924
  } else {
13940
13925
  const changedProps = diffProps(instance, newProps);
13941
- if (Object.keys(changedProps).length) {
13942
- Object.assign(instance.props, changedProps);
13943
- applyProps(instance.object, changedProps);
13944
- }
13926
+ const attach2 = instance.props.attach;
13927
+ instance.props = getInstanceProps(newProps);
13928
+ if (attach2 !== void 0) instance.props.attach = attach2;
13929
+ else delete instance.props.attach;
13930
+ if (Object.keys(changedProps).length) applyProps(instance.object, changedProps);
13945
13931
  }
13946
- const isTailSibling = fiber.sibling === null || (fiber.flags & Update) === NoFlags;
13947
- if (isTailSibling) swapInstances();
13948
13932
  },
13949
13933
  finalizeInitialChildren: (instance) => {
13950
13934
  for (const prop in instance.props) {
@@ -13957,8 +13941,8 @@ const reconciler = /* @__PURE__ */ createReconciler({
13957
13941
  for (const prop in instance.props) {
13958
13942
  const value = instance.props[prop];
13959
13943
  if (isFromRef(value)) {
13960
- const ref = value[FROM_REF];
13961
- if (ref.current != null) resolved[prop] = ref.current;
13944
+ const { [FROM_REF]: ref, transform } = value;
13945
+ if (ref.current != null) resolved[prop] = transform ? transform(ref.current) : ref.current;
13962
13946
  }
13963
13947
  }
13964
13948
  if (Object.keys(resolved).length) applyProps(instance.object, resolved);
@@ -13969,8 +13953,9 @@ const reconciler = /* @__PURE__ */ createReconciler({
13969
13953
  const target = container.getState().internal.container ?? container.getState().scene;
13970
13954
  return prepare(target, container, "", {});
13971
13955
  },
13972
- resetAfterCommit: () => {
13973
- },
13956
+ // Reconstructed instances are swapped once all mutations are committed,
13957
+ // before layout effects run so refs point to the new objects
13958
+ resetAfterCommit: flushReconstructedInstances,
13974
13959
  shouldSetTextContent: () => false,
13975
13960
  clearContainer: () => false,
13976
13961
  hideInstance,
@@ -13978,6 +13963,9 @@ const reconciler = /* @__PURE__ */ createReconciler({
13978
13963
  createTextInstance: handleTextInstance,
13979
13964
  hideTextInstance: handleTextInstance,
13980
13965
  unhideTextInstance: handleTextInstance,
13966
+ // Mirrors react-dom, which flushes discrete work in microtasks
13967
+ supportsMicrotasks: true,
13968
+ scheduleMicrotask,
13981
13969
  scheduleTimeout: typeof setTimeout === "function" ? setTimeout : void 0,
13982
13970
  cancelTimeout: typeof clearTimeout === "function" ? clearTimeout : void 0,
13983
13971
  noTimeout: -1,
@@ -14018,28 +14006,9 @@ const reconciler = /* @__PURE__ */ createReconciler({
14018
14006
  },
14019
14007
  resolveUpdatePriority() {
14020
14008
  if (currentUpdatePriority !== NoEventPriority) return currentUpdatePriority;
14021
- switch (typeof window !== "undefined" && window.event?.type) {
14022
- case "click":
14023
- case "contextmenu":
14024
- case "dblclick":
14025
- case "dragenter":
14026
- case "dragleave":
14027
- case "drop":
14028
- case "pointercancel":
14029
- case "pointerdown":
14030
- case "pointerup":
14031
- return e;
14032
- case "dragover":
14033
- case "pointermove":
14034
- case "pointerout":
14035
- case "pointerover":
14036
- case "pointerenter":
14037
- case "pointerleave":
14038
- case "wheel":
14039
- return o;
14040
- default:
14041
- return r;
14042
- }
14009
+ const eventType = typeof window !== "undefined" ? window.event?.type : void 0;
14010
+ if (eventType === void 0) return r;
14011
+ return getEventPriority(eventType);
14043
14012
  },
14044
14013
  resetFormInstance() {
14045
14014
  },
@@ -14272,9 +14241,8 @@ function createRoot(canvas) {
14272
14241
  if (!renderer.hasInitialized?.()) {
14273
14242
  const size2 = computeInitialSize(canvas, propsSize);
14274
14243
  if (size2.width > 0 && size2.height > 0) {
14275
- const pixelRatio = calculateDpr(dpr);
14276
- canvas.width = size2.width * pixelRatio;
14277
- canvas.height = size2.height * pixelRatio;
14244
+ renderer.setPixelRatio(calculateDpr(dpr));
14245
+ renderer.setSize(size2.width, size2.height, false);
14278
14246
  }
14279
14247
  await renderer.init();
14280
14248
  }
@@ -14283,7 +14251,7 @@ function createRoot(canvas) {
14283
14251
  state.internal.actualRenderer = renderer;
14284
14252
  state.set({ webGPUSupported: isWebGPUBackend, renderer, primaryStore: store });
14285
14253
  if (canvasId && !state.internal.isSecondary) {
14286
- const canvasTarget = new CanvasTarget(canvas);
14254
+ const canvasTarget = renderer.getCanvasTarget?.();
14287
14255
  const unregisterPrimary = registerPrimary(canvasId, renderer, store);
14288
14256
  state.set((prev) => ({
14289
14257
  internal: {
@@ -14397,7 +14365,7 @@ function createRoot(canvas) {
14397
14365
  const handleXRFrame = (timestamp, _frame) => {
14398
14366
  const state2 = store.getState();
14399
14367
  if (state2.frameloop === "never") return;
14400
- advance(timestamp);
14368
+ advance(timestamp, true, state2);
14401
14369
  };
14402
14370
  const actualRenderer = state.internal.actualRenderer;
14403
14371
  const handleSessionChange = () => {
@@ -14405,7 +14373,7 @@ function createRoot(canvas) {
14405
14373
  const renderer2 = state2.internal.actualRenderer;
14406
14374
  actualRenderer.xr.enabled = actualRenderer.xr.isPresenting;
14407
14375
  renderer2.xr.setAnimationLoop(renderer2.xr.isPresenting ? handleXRFrame : null);
14408
- if (!renderer2.xr.isPresenting) invalidate();
14376
+ if (!renderer2.xr.isPresenting) invalidate(state2);
14409
14377
  };
14410
14378
  const xr = {
14411
14379
  connect() {
@@ -14487,14 +14455,23 @@ function createRoot(canvas) {
14487
14455
  const newRootId = canvasId || scheduler.generateRootId();
14488
14456
  const unregisterRoot = scheduler.registerRoot(newRootId, {
14489
14457
  getState: () => store.getState(),
14490
- onError: (err) => store.getState().setError(err)
14458
+ onError: (err) => store.getState().setError(err),
14459
+ frameloop: store.getState().frameloop,
14460
+ before: schedulerConfig?.before,
14461
+ after: schedulerConfig?.after,
14462
+ order: schedulerConfig?.order
14491
14463
  });
14492
14464
  const unregisterCanvasTarget = scheduler.register(
14493
14465
  () => {
14494
14466
  const state2 = store.getState();
14495
- if (state2.internal.isMultiCanvas && state2.internal.canvasTarget) {
14467
+ const canvasTarget = state2.internal.canvasTarget;
14468
+ if (canvasTarget) {
14496
14469
  const renderer2 = state2.internal.actualRenderer;
14497
- renderer2.setCanvasTarget(state2.internal.canvasTarget);
14470
+ if (renderer2.getCanvasTarget() !== canvasTarget) renderer2.setCanvasTarget(canvasTarget);
14471
+ if (state2.internal.canvasTargetSizeDirty) {
14472
+ state2.internal.canvasTargetSizeDirty = false;
14473
+ renderer2.backend?.updateSize?.();
14474
+ }
14498
14475
  }
14499
14476
  },
14500
14477
  {
@@ -14563,8 +14540,7 @@ function createRoot(canvas) {
14563
14540
  phase: "render",
14564
14541
  system: true,
14565
14542
  // Internal flag: this is a system job, not user-controlled
14566
- // Apply scheduler config for render ordering and rate limiting
14567
- ...schedulerConfig?.after && { after: schedulerConfig.after },
14543
+ // FPS throttles only the default render job; Canvas ordering belongs to the root.
14568
14544
  ...schedulerConfig?.fps && { fps: schedulerConfig.fps }
14569
14545
  }
14570
14546
  );
@@ -14583,8 +14559,21 @@ function createRoot(canvas) {
14583
14559
  scheduler
14584
14560
  }
14585
14561
  }));
14562
+ } else {
14563
+ const constraintsChanged = !is.equ(schedulerConfig?.before, lastConfiguredProps.schedulerBefore, shallowLoose) || !is.equ(schedulerConfig?.after, lastConfiguredProps.schedulerAfter, shallowLoose);
14564
+ if (constraintsChanged) {
14565
+ scheduler.setRootConstraints(rootId, {
14566
+ before: schedulerConfig?.before,
14567
+ after: schedulerConfig?.after
14568
+ });
14569
+ }
14570
+ if (schedulerConfig?.order !== lastConfiguredProps.schedulerOrder) {
14571
+ scheduler.setRootOrder(rootId, schedulerConfig?.order ?? 0);
14572
+ }
14586
14573
  }
14587
- scheduler.frameloop = frameloop;
14574
+ lastConfiguredProps.schedulerBefore = schedulerConfig?.before;
14575
+ lastConfiguredProps.schedulerAfter = schedulerConfig?.after;
14576
+ lastConfiguredProps.schedulerOrder = schedulerConfig?.order;
14588
14577
  onCreated = onCreatedCallback;
14589
14578
  configured = true;
14590
14579
  resolve();
@@ -14626,18 +14615,23 @@ function unmountComponentAtNode(canvas, callback) {
14626
14615
  const fiber = root?.fiber;
14627
14616
  if (fiber) {
14628
14617
  const state = root?.store.getState();
14629
- if (state) state.internal.active = false;
14618
+ if (state) {
14619
+ state.internal.active = false;
14620
+ const unregisterRoot = state.internal.unregisterRoot;
14621
+ if (unregisterRoot) {
14622
+ unregisterRoot();
14623
+ state.internal.unregisterRoot = void 0;
14624
+ }
14625
+ }
14630
14626
  reconciler.updateContainer(null, fiber, null, () => {
14631
14627
  if (state) {
14632
14628
  setTimeout(() => {
14633
14629
  try {
14634
14630
  const renderer = state.internal.actualRenderer;
14635
- const unregisterRoot = state.internal.unregisterRoot;
14636
- if (unregisterRoot) unregisterRoot();
14637
14631
  const unregisterPrimary = state.internal.unregisterPrimary;
14638
14632
  if (unregisterPrimary) unregisterPrimary();
14639
14633
  const canvasTarget = state.internal.canvasTarget;
14640
- if (canvasTarget?.dispose) canvasTarget.dispose();
14634
+ if (state.internal.isSecondary && canvasTarget?.dispose) canvasTarget.dispose();
14641
14635
  state.events.disconnect?.();
14642
14636
  cleanupHelperGroup(root.store);
14643
14637
  if (state.isLegacy && renderer) {
@@ -14763,6 +14757,207 @@ function flushSync(fn) {
14763
14757
  return reconciler.flushSyncFromReconciler(fn);
14764
14758
  }
14765
14759
 
14760
+ const isRef = (obj) => obj.current && obj.current.isScene;
14761
+ const resolveScene = (scene) => isRef(scene) ? scene.current : scene;
14762
+ function setEnvProps(background, scene, defaultScene, texture, sceneProps = {}) {
14763
+ sceneProps = {
14764
+ backgroundBlurriness: 0,
14765
+ backgroundIntensity: 1,
14766
+ backgroundRotation: [0, 0, 0],
14767
+ environmentIntensity: 1,
14768
+ environmentRotation: [0, 0, 0],
14769
+ ...sceneProps
14770
+ };
14771
+ const target = resolveScene(scene || defaultScene);
14772
+ const oldbg = target.background;
14773
+ const oldenv = target.environment;
14774
+ const oldSceneProps = {
14775
+ backgroundBlurriness: target.backgroundBlurriness,
14776
+ backgroundIntensity: target.backgroundIntensity,
14777
+ backgroundRotation: target.backgroundRotation.clone(),
14778
+ environmentIntensity: target.environmentIntensity,
14779
+ environmentRotation: target.environmentRotation.clone()
14780
+ };
14781
+ if (background !== "only") target.environment = texture;
14782
+ if (background) target.background = texture;
14783
+ applyProps(target, sceneProps);
14784
+ return () => {
14785
+ if (background !== "only") target.environment = oldenv;
14786
+ if (background) target.background = oldbg;
14787
+ applyProps(target, oldSceneProps);
14788
+ };
14789
+ }
14790
+ function EnvironmentMap({ scene, background = false, map, ...config }) {
14791
+ const defaultScene = useThree((state) => state.scene);
14792
+ React.useLayoutEffect(() => {
14793
+ if (map) return setEnvProps(background, scene, defaultScene, map, config);
14794
+ });
14795
+ return null;
14796
+ }
14797
+ function EnvironmentCube({
14798
+ background = false,
14799
+ scene,
14800
+ blur,
14801
+ backgroundBlurriness,
14802
+ backgroundIntensity,
14803
+ backgroundRotation,
14804
+ environmentIntensity,
14805
+ environmentRotation,
14806
+ ...rest
14807
+ }) {
14808
+ const texture = useEnvironment(rest);
14809
+ const defaultScene = useThree((state) => state.scene);
14810
+ React.useLayoutEffect(() => {
14811
+ return setEnvProps(background, scene, defaultScene, texture, {
14812
+ backgroundBlurriness: blur ?? backgroundBlurriness,
14813
+ backgroundIntensity,
14814
+ backgroundRotation,
14815
+ environmentIntensity,
14816
+ environmentRotation
14817
+ });
14818
+ });
14819
+ React.useEffect(() => {
14820
+ return () => {
14821
+ texture.dispose();
14822
+ };
14823
+ }, [texture]);
14824
+ return null;
14825
+ }
14826
+ function EnvironmentPortal({
14827
+ children,
14828
+ near = 0.1,
14829
+ far = 1e3,
14830
+ resolution = 256,
14831
+ frames = 1,
14832
+ map,
14833
+ background = false,
14834
+ blur,
14835
+ backgroundBlurriness,
14836
+ backgroundIntensity,
14837
+ backgroundRotation,
14838
+ environmentIntensity,
14839
+ environmentRotation,
14840
+ scene,
14841
+ files,
14842
+ path,
14843
+ preset = void 0,
14844
+ extensions
14845
+ }) {
14846
+ const renderer = useThree((state) => state.renderer);
14847
+ const isLegacy = useThree((state) => state.isLegacy);
14848
+ const defaultScene = useThree((state) => state.scene);
14849
+ const camera = React.useRef(null);
14850
+ const [virtualScene] = React.useState(() => new Scene());
14851
+ const fbo = React.useMemo(() => {
14852
+ const fbo2 = isLegacy ? new WebGLCubeRenderTarget(resolution) : new CubeRenderTarget(resolution);
14853
+ fbo2.texture.type = HalfFloatType;
14854
+ return fbo2;
14855
+ }, [resolution, isLegacy]);
14856
+ React.useEffect(() => {
14857
+ return () => {
14858
+ fbo.dispose();
14859
+ };
14860
+ }, [fbo]);
14861
+ React.useLayoutEffect(() => {
14862
+ if (frames === 1) {
14863
+ const autoClear = renderer.autoClear;
14864
+ renderer.autoClear = true;
14865
+ camera.current.update(renderer, virtualScene);
14866
+ renderer.autoClear = autoClear;
14867
+ }
14868
+ return setEnvProps(background, scene, defaultScene, fbo.texture, {
14869
+ backgroundBlurriness: blur ?? backgroundBlurriness,
14870
+ backgroundIntensity,
14871
+ backgroundRotation,
14872
+ environmentIntensity,
14873
+ environmentRotation
14874
+ });
14875
+ }, [
14876
+ children,
14877
+ virtualScene,
14878
+ fbo.texture,
14879
+ scene,
14880
+ defaultScene,
14881
+ background,
14882
+ frames,
14883
+ renderer,
14884
+ blur,
14885
+ backgroundBlurriness,
14886
+ backgroundIntensity,
14887
+ backgroundRotation,
14888
+ environmentIntensity,
14889
+ environmentRotation
14890
+ ]);
14891
+ let count = 1;
14892
+ useFrame(() => {
14893
+ if (frames === Infinity || count < frames) {
14894
+ const autoClear = renderer.autoClear;
14895
+ renderer.autoClear = true;
14896
+ camera.current.update(renderer, virtualScene);
14897
+ renderer.autoClear = autoClear;
14898
+ count++;
14899
+ }
14900
+ });
14901
+ return /* @__PURE__ */ jsx(Fragment, { children: createPortal(
14902
+ /* @__PURE__ */ jsxs(Fragment, { children: [
14903
+ children,
14904
+ /* @__PURE__ */ jsx("cubeCamera", { ref: camera, args: [near, far, fbo] }),
14905
+ files || preset ? /* @__PURE__ */ jsx(EnvironmentCube, { background: true, files, preset, path, extensions }) : map ? /* @__PURE__ */ jsx(EnvironmentMap, { background: true, map, extensions }) : null
14906
+ ] }),
14907
+ virtualScene
14908
+ ) });
14909
+ }
14910
+ function EnvironmentGround(props) {
14911
+ const textureDefault = useEnvironment(props);
14912
+ const texture = props.map || textureDefault;
14913
+ React.useMemo(() => extend({ GroundProjectedEnvImpl: GroundedSkybox }), []);
14914
+ React.useEffect(() => {
14915
+ return () => {
14916
+ textureDefault.dispose();
14917
+ };
14918
+ }, [textureDefault]);
14919
+ const height = props.ground?.height ?? 15;
14920
+ const radius = props.ground?.radius ?? 60;
14921
+ const scale = props.ground?.scale ?? 1e3;
14922
+ const args = React.useMemo(
14923
+ () => [texture, height, radius],
14924
+ [texture, height, radius]
14925
+ );
14926
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
14927
+ /* @__PURE__ */ jsx(EnvironmentMap, { ...props, map: texture }),
14928
+ /* @__PURE__ */ jsx("groundProjectedEnvImpl", { args, scale })
14929
+ ] });
14930
+ }
14931
+ function EnvironmentColor({ color, scene }) {
14932
+ const defaultScene = useThree((state) => state.scene);
14933
+ React.useLayoutEffect(() => {
14934
+ if (color === void 0) return;
14935
+ const target = resolveScene(scene || defaultScene);
14936
+ const oldBg = target.background;
14937
+ target.background = new Color(color);
14938
+ return () => {
14939
+ target.background = oldBg;
14940
+ };
14941
+ });
14942
+ return null;
14943
+ }
14944
+ function EnvironmentDualSource(props) {
14945
+ const { backgroundFiles, ...envProps } = props;
14946
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
14947
+ /* @__PURE__ */ jsx(EnvironmentCube, { ...envProps, background: false }),
14948
+ /* @__PURE__ */ jsx(EnvironmentCube, { ...props, files: backgroundFiles, background: "only" })
14949
+ ] });
14950
+ }
14951
+ function Environment(props) {
14952
+ if (props.color && !props.files && !props.preset && !props.map) {
14953
+ return /* @__PURE__ */ jsx(EnvironmentColor, { ...props });
14954
+ }
14955
+ if (props.backgroundFiles && props.backgroundFiles !== props.files) {
14956
+ return /* @__PURE__ */ jsx(EnvironmentDualSource, { ...props });
14957
+ }
14958
+ return props.ground ? /* @__PURE__ */ jsx(EnvironmentGround, { ...props }) : props.map ? /* @__PURE__ */ jsx(EnvironmentMap, { ...props }) : props.children ? /* @__PURE__ */ jsx(EnvironmentPortal, { ...props }) : /* @__PURE__ */ jsx(EnvironmentCube, { ...props });
14959
+ }
14960
+
14766
14961
  function parseBackground(background) {
14767
14962
  if (!background) return null;
14768
14963
  if (typeof background === "object" && !background.isColor) {
@@ -14875,9 +15070,9 @@ function CanvasImpl({
14875
15070
  React.useMemo(() => extend(THREE), []);
14876
15071
  const Bridge = useBridge();
14877
15072
  const backgroundProps = React.useMemo(() => parseBackground(background), [background]);
14878
- const hasInitialSizeRef = React.useRef(false);
15073
+ const [hasInitialSize, setHasInitialSize] = React.useState(false);
14879
15074
  const measureConfig = React.useMemo(() => {
14880
- if (!hasInitialSizeRef.current) {
15075
+ if (!hasInitialSize) {
14881
15076
  return {
14882
15077
  ...resize,
14883
15078
  scroll: resize?.scroll ?? true,
@@ -14889,7 +15084,7 @@ function CanvasImpl({
14889
15084
  debounce: { scroll: 50, resize: 0 },
14890
15085
  ...resize
14891
15086
  };
14892
- }, [resize, hasInitialSizeRef.current]);
15087
+ }, [hasInitialSize, resize]);
14893
15088
  const [containerRef, containerRect] = useMeasure(measureConfig);
14894
15089
  const effectiveSize = React.useMemo(() => {
14895
15090
  let w = width ?? containerRect.width;
@@ -14905,9 +15100,7 @@ function CanvasImpl({
14905
15100
  left: containerRect.left
14906
15101
  };
14907
15102
  }, [width, height, containerRect, forceEven]);
14908
- if (!hasInitialSizeRef.current && effectiveSize.width > 0 && effectiveSize.height > 0) {
14909
- hasInitialSizeRef.current = true;
14910
- }
15103
+ if (!hasInitialSize && effectiveSize.width > 0 && effectiveSize.height > 0) setHasInitialSize(true);
14911
15104
  const canvasRef = React.useRef(null);
14912
15105
  const divRef = React.useRef(null);
14913
15106
  React.useImperativeHandle(ref, () => canvasRef.current);
@@ -14972,7 +15165,7 @@ function CanvasImpl({
14972
15165
  onDropMissed: (...args) => handleDropMissed.current?.(...args),
14973
15166
  onCreated: (state) => {
14974
15167
  state.events.connect?.(
14975
- eventSource ? isRef(eventSource) ? eventSource.current : eventSource : divRef.current
15168
+ eventSource ? isRef$1(eventSource) ? eventSource.current : eventSource : divRef.current
14976
15169
  );
14977
15170
  if (eventPrefix) {
14978
15171
  state.setEvents({
@@ -15021,6 +15214,7 @@ function CanvasImpl({
15021
15214
  const canvas = canvasRef.current;
15022
15215
  if (canvas) {
15023
15216
  return () => {
15217
+ if (canvas.isConnected) return;
15024
15218
  unmountComponentAtNode(canvas);
15025
15219
  root.current = null;
15026
15220
  };
@@ -15085,4 +15279,4 @@ function Canvas(props) {
15085
15279
 
15086
15280
  extend(THREE);
15087
15281
 
15088
- export { Block, Canvas, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, ErrorBoundary, FROM_REF, IsObject, ONCE, Portal, R3F_BUILD_LEGACY, R3F_BUILD_WEBGPU, REACT_INTERNAL_PROPS, RESERVED_PROPS, Texture, _roots, act, addAfterEffect, addEffect, addTail, advance, applyProps, attach, buildGraph, calculateDpr, context, createEvents, createPointerEvents, createPortal, createRoot, createStore, detach, diffProps, dispose, createPointerEvents as events, extend, findInitialRoot, flushSync, fromRef, getInstanceProps, getPrimary, getPrimaryIds, getRootState, getUuidPrefix, hasConstructor, hasPrimary, invalidate, invalidateInstance, is, isColorRepresentation, isCopyable, isFromRef, isObject3D, isOnce, isOrthographicCamera, isRef, isRenderer, isTexture, isVectorLike, once, prepare, presetsObj, reconciler, registerPrimary, removeInteractivity, resolve, unmountComponentAtNode, unregisterPrimary, updateCamera, updateFrustum, useBridge, useEnvironment, useFrame, useGraph, useInstanceHandle, useIsomorphicLayoutEffect, useLoader, useMutableCallback, useRenderTarget, useStore, useTexture, useTextures, useThree, waitForPrimary };
15282
+ export { Block, Canvas, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, ErrorBoundary, FROM_REF, IsObject, ONCE, Portal, R3F_BUILD_LEGACY, R3F_BUILD_WEBGPU, REACT_INTERNAL_PROPS, RESERVED_PROPS, Texture, _roots, addAfterEffect, addEffect, addTail, advance, applyProps, attach, buildGraph, calculateDpr, context, createEvents, createPointerEvents, createPortal, createRoot, createStore, detach, diffProps, dispose, createPointerEvents as events, extend, findInitialRoot, flushSync, fromRef, getInstanceProps, getPrimary, getPrimaryIds, getRootState, getUuidPrefix, hasConstructor, hasPrimary, invalidate, invalidateInstance, is, isColorRepresentation, isCopyable, isFromRef, isObject3D, isOnce, isOrthographicCamera, isRef$1 as isRef, isRenderer, isTexture, isVectorLike, once, prepare, presetsObj, reconciler, registerPrimary, removeInteractivity, resolve, swapInteractivity, unmountComponentAtNode, unregisterPrimary, updateCamera, updateFrustum, useBridge, useEnvironment, useFrame, useGraph, useInstanceHandle, useIsomorphicLayoutEffect, useLoader, useMutableCallback, useRenderTarget, useStore, useTexture, useTextures, useThree, waitForPrimary };