UNPKG

@needle-tools/engine

Version:

Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.

1,363 lines (1,352 loc) • 1.85 MB
import { Vector2 as Z, Vector3 as _, Vector4 as ye, Quaternion as V, Box3 as Ut, ShadowMaterial as Ov, Euler as dt, PlaneGeometry as kn, WebGLRenderer as zr, PerspectiveCamera as de, OrthographicCamera as vu, Scene as Ei, Mesh as H, Texture as xe, Uniform$1 as Qi, Color as re, ShaderMaterial as Qn, MeshStandardMaterial as gt, Box3Helper as mS, GridHelper as Mv, Object3D as M, Material as be, Matrix3 as Rv, Matrix4 as ee, Layers as Po, PropertyBinding as za, AnimationClip as Mi, KeyframeTrack as gS, FileLoader as Ev, BufferGeometry as Ki, TextureLoader as Mr, MeshBasicMaterial as Se, DoubleSide as Ti, Group as ks, CylinderGeometry as Tv, SphereGeometry as wu, BoxGeometry as Ua, SpriteMaterial as yS, Sprite as _S, Shape as bS, ExtrudeGeometry as vS, Ray as Is, CubeUVReflectionMapping as Ls, LinearSRGBColorSpace as Ds, ShaderChunk as ei, Sphere as xu, DataTexture as rg, RGBAFormat as Su, EquirectangularReflectionMapping as Os, SRGBColorSpace as js, Clock as wS, NeutralToneMapping as Na, AgXToneMapping as Cu, ACESFilmicToneMapping as Pu, NoToneMapping as zd, PCFSoftShadowMap$1 as xS, BasicNodeLibrary as SS, WebGLRenderTarget as Yn, DepthTexture as Av, NearestFilter as Ud, AxesHelper as Ri, MathUtils as Ms, Fog as Iv, DirectionalLight as Qp, PointLight as ag, EdgesGeometry as CS, LineSegments as Yp, LineBasicMaterial as Nd, Line as $a, BufferAttribute as tt, Raycaster as ku, ArrayCamera as PS, Plane as Rr, SkinnedMesh as vo, InterleavedBufferAttribute as Lv, Skeleton as kS, Bone as OS, WebGLCubeRenderTarget as MS, CubeCamera as RS, LoopRepeat as ES, LoopOnce as Kp, AnimationMixer as lg, CompressedTexture as TS, FrontSide as ko, Camera as AS, Frustum as qy, AudioListener as IS, PositionalAudio as LS, AudioLoader as Zp, VectorKeyframeTrack as DS, QuaternionKeyframeTrack as jS, Audio as BS, BackSide as Ou, PMREMGenerator$1 as FS, EquirectangularRefractionMapping as Dv, CubeTexture as jv, CompressedCubeTexture as zS, EventDispatcher as cg, MeshDepthMaterial as US, CustomBlending as NS, MaxEquation as $S, AlwaysStencilFunc as WS, GreaterEqualStencilFunc as VS, NotEqualStencilFunc as HS, GreaterStencilFunc as GS, LessEqualStencilFunc as qS, EqualStencilFunc as XS, LessStencilFunc as QS, NeverStencilFunc as Xy, InvertStencilOp as YS, DecrementWrapStencilOp as KS, IncrementWrapStencilOp as ZS, DecrementStencilOp as JS, IncrementStencilOp as eC, ReplaceStencilOp as tC, ZeroStencilOp as iC, KeepStencilOp as nC, AmbientLight as sC, HemisphereLight as oC, Loader as rC, GLSL3 as aC, AlwaysDepth as lC, GreaterEqualDepth as cC, GreaterDepth as hC, LessEqualDepth as dC, LessDepth as uC, NotEqualDepth as fC, EqualDepth as pC, RawShaderMaterial as Bv, BatchedMesh as Qy, LinearFilter as $d, UnsignedByteType as mC, MeshPhysicalMaterial as Yy, RingGeometry as gC, Line3 as yC, AdditiveBlending as Fv, BoxHelper as _C, SpotLight as bC, DirectionalLightHelper as vC, CameraHelper as wC, LOD as xC, Triangle as SC, NormalBlending as CC, ReinhardToneMapping as hg, LinearToneMapping as dg, HalfFloatType as Bf, Source as PC, VideoTexture as kC, CatmullRomCurve3 as OC, MirroredRepeatWrapping as Ky, ShaderLib as Wd, UniformsUtils as zv, MeshNormalMaterial as MC, AudioContext as RC } from "./three.js"; import { createLoaders as ug, LODsManager as Jo, NEEDLE_progressive as Ve, getRaycastMesh as Uv, setKTX2TranscoderLocation as EC, setDracoDecoderLocation as TC, addDracoAndKTX2Loaders as AC, configureLoader as IC } from "./gltf-progressive-Cl167Vjx.js"; import { GroundedSkybox as Wa, Font as LC, TextGeometry as DC, FontLoader as jC, GLTFLoader as Bs, EXRLoader as fg, RGBELoader as Nv, Stats as BC, nodeFrame as Zy, TransformControlsGizmo as Jy, OrbitControls as FC, PositionalAudioHelper as zC, HorizontalBlurShader as UC, VerticalBlurShader as NC, GLTFExporter as $v, strToU8 as Wv, zipSync as $C, XRControllerModelFactory as WC, XRHandMeshModel as VC, Line2 as HC, LineGeometry as GC, LineMaterial as qC, TransformControls as XC, InteractiveGroup as QC, HTMLMesh as YC, VertexNormalsHelper as KC, OBJLoader as pg, FBXLoader as Vv, mergeVertices as ZC } from "./three-examples.js"; import { _md5 as e_, md5 as JC, v5 as t_, ByteBuffer as e1, fetchProfile as t1, MotionController as i1, SIZE_PREFIX_LENGTH as Hv, Builder as mg, createNoise4D as n1, Matrix4 as Ff, BatchedParticleRenderer as s1, ParticleSystem as o1, RenderMode as ms, ConstantColor as r1, Vector4 as a1, ConstantValue as l1, TrailParticle as i_, WorkerBase as c1, MeshBVH as h1 } from "./vendor-vHLk8sXu.js"; import { __webpack_exports__default as ke, __webpack_exports__Text as Gv, __webpack_exports__update as d1, __webpack_exports__Block as qv, SimpleStateBehavior as u1, __webpack_exports__Inline as zf, __webpack_exports__FontLibrary as n_, ThreeMeshUI as s_ } from "./three-mesh-ui-B-lqrZWj.js"; import { EffectAttribute as f1 } from "./postprocessing-WDc9WwI3.js"; const o_ = typeof window !== void 0 ? window.location.search.includes("debugcontext") : !1; var ue = /* @__PURE__ */ ((s) => (s.ContextRegistered = "ContextRegistered", s.ContextCreationStart = "ContextCreationStart", s.ContextCreated = "ContextCreated", s.ContextFirstFrameRendered = "ContextFirstFrameRendered", s.ContextDestroying = "ContextDestroying", s.ContextDestroyed = "ContextDestroyed", s.MissingCamera = "MissingCamera", s.ContextClearing = "ContextClearing", s.ContextCleared = "ContextCleared", s))(ue || {}); class pe { /** The currently active (rendering) Needle Engine context */ static get Current() { return globalThis["NeedleEngine.Context.Current"]; } /** @internal */ static set Current(e) { globalThis["NeedleEngine.Context.Current"] = e; } /** Returns the array of all registered Needle Engine contexts. Do not modify */ static get All() { return this.Registered; } /** All currently registered Needle Engine contexts. Do not modify */ static Registered = []; /** @internal Internal use only */ static register(e) { this.Registered.indexOf(e) === -1 && (o_ && console.warn("Registering context"), this.Registered.push(e), this.dispatchCallback("ContextRegistered", e)); } /** @internal Internal use only */ static unregister(e) { const t = this.Registered.indexOf(e); t !== -1 && (o_ && console.warn("Unregistering context"), this.Registered.splice(t, 1)); } static _callbacks = {}; /** * Register a callback to be called when the given event occurs */ static registerCallback(e, t) { this._callbacks[e] || (this._callbacks[e] = []), this._callbacks[e].push(t); } /** Unregister a callback */ static unregisterCallback(e, t) { if (!this._callbacks[e]) return; const i = this._callbacks[e].indexOf(t); i !== -1 && this._callbacks[e].splice(i, 1); } /** @internal */ static dispatchCallback(e, t, i) { if (!this._callbacks[e]) return !0; const n = { event: e, context: t }; if (i) for (const r in i) n[r] = i[r]; const o = new Array(); return this._callbacks[e].forEach((r) => { const a = r(n); a instanceof Promise && o.push(a); }), Promise.all(o); } /** * Register a callback to be called when a context is created */ static addContextCreatedCallback(e) { this.registerCallback("ContextCreated", e); } /** * Register a callback to be called when a context is registered */ static addContextDestroyedCallback(e) { this.registerCallback("ContextDestroyed", e); } } const Uf = /* @__PURE__ */ new Map(); function Zi(s = globalThis.location?.hostname) { if (Uf.has(s)) return Uf.get(s); const e = /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|localhost/.test(s); return Uf.set(s, e), e === !0; } function p1() { return window.location.hostname.includes("glitch.me"); } const m1 = () => (s) => s; function RD(s) { return m1()(s); } function ED() { return !!x("debug"); } class Ji { _factory; _cache = []; _maxSize; _index = 0; constructor(e, t) { this._factory = e, this._maxSize = t; } get() { const e = this._index % this._maxSize; return this._index++, this._cache.length <= e && (this._cache[e] = this._factory()), this._cache[e]; } } let ur = !1; const Jp = new Array(); typeof window < "u" && setTimeout(() => { if (ur) { const s = {}, e = new URL(window.location.href), t = new URL(e); t.searchParams.append("console", ""); const i = t.toString().replace(/=$|=(?=&)/g, ""); for (const o of Jp) { const r = new URL(e); r.searchParams.append(o, ""), s[o] = r.toString().replace(/=$|=(?=&)/g, ""); } console.log( `🌵 ?help: Debug Options for Needle Engine. Append any of these parameters to the URL to enable specific debug options. Example: ${i} will show an onscreen console window.` ); const n = ur === !0 ? "" : ` (containing "${ur}")`; console.group("Available URL parameters:" + n); for (const o of Object.keys(s).sort()) typeof ur == "string" && !o.toLowerCase().includes(ur.toLowerCase()) || (console.groupCollapsed(o), console.log("Reload with this flag enabled:"), console.log(s[o]), console.groupEnd()); console.groupEnd(); } }, 100); function Mu() { return new URLSearchParams(globalThis.location?.search); } function x(s) { ur && !Jp.includes(s) && Jp.push(s); const e = Mu(); if (e.has(s)) { const t = e.get(s); if (t) { const i = Number(t); return isNaN(i) ? t : i; } else return !0; } return !1; } ur = x("help"); function TD(s, e) { const t = Mu(); t.has(s) ? t.set(s, e) : t.append(s, e), document.location.search = t.toString(); } function Vd(s, e, t = !0) { const i = Mu(); i.has(s) ? e === null ? i.delete(s) : i.set(s, e) : e !== null && i.append(s, e), t ? g1(s, i) : Xv(s, i); } function r_(s, e, t) { s.has(e) ? s.set(e, t.toString()) : s.append(e, t.toString()); } function g1(s, e, t) { window.history.pushState(t, s, "?" + e.toString()); } function Xv(s, e, t) { window.history.replaceState(t, s, "?" + e.toString()); } function AD(s) { for (var e = "", t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", i = t.length, n = 0; n < s; n++) e += t.charAt(Math.floor(Math.random() * i)); return e; } function ID(s, e) { return Math.floor(Math.random() * (e - s + 1)) + s; } const a_ = ["smol", "tiny", "giant", "interesting", "smart", "bright", "dull", "extreme", "beautiful", "pretty", "dark", "epic", "salty", "silly", "funny", "lame", "lazy", "loud", "lucky", "mad", "mean", "mighty", "mysterious", "nasty", "odd", "old", "powerful", "quiet", "rapid", "scary", "shiny", "shy", "silly", "smooth", "sour", "spicy", "stupid", "sweet", "tasty", "terrible", "ugly", "unusual", "vast", "wet", "wild", "witty", "wrong", "zany", "zealous", "zippy", "zombie", "zorro"], l_ = ["cat", "dog", "mouse", "pig", "cow", "horse", "sheep", "chicken", "duck", "goat", "panda", "tiger", "lion", "elephant", "monkey", "bird", "fish", "snake", "frog", "turtle", "hamster", "penguin", "kangaroo", "whale", "dolphin", "crocodile", "snail", "ant", "bee", "beetle", "butterfly", "dragon", "eagle", "fish", "giraffe", "lizard", "panda", "penguin", "rabbit", "snake", "spider", "tiger", "zebra"]; function y1() { const s = a_[Math.floor(Math.random() * a_.length)], e = l_[Math.floor(Math.random() * l_.length)]; return s + "_" + e; } function _1(s) { return s = s.replace(/[^a-z0-9áéíóúñü \.,_-]/gim, ""), s.trim(); } function Ac(s, e, t = !0, i = !1) { if (e == null) return null; if (e.userData && e.userData.guid === s) return e; if (e.guid == s) return e; if (i && e.userData?.components) { for (const n of e.userData.components) if (n.guid === s) return n; } if (t) { if (e.scenes) for (const n in e.scenes) { const o = e.scenes[n], r = Ac(s, o, t, i); if (r) return r; } if (e.children) for (const n in e.children) { const o = e.children[n], r = Ac(s, o, t, i); if (r) return r; } } } function Ru(s, e) { if (s != null && typeof s == "object") { let t; Array.isArray(s) ? t = [] : (t = Object.create(s), Object.assign(t, s)); for (const i of Object.keys(s)) { const n = s[i]; e && !e(s, i, n) ? t[i] = n : n?.clone !== void 0 && typeof n.clone == "function" ? t[i] = n.clone() : t[i] = Ru(n, e); } return t; } return s; } function Oo(s) { return new Promise((e, t) => { setTimeout(e, s); }); } function Eu(s, e) { if (s <= 0) return Promise.resolve(); if (e || (e = pe.Current), !e) return Promise.reject("No context"); const t = e.time.frameCount + s; return new Promise((i, n) => { if (!e) return n("No context"); const o = () => { e.time.frameCount >= t && (e.pre_update_callbacks.splice(e.pre_update_callbacks.indexOf(o), 1), i()); }; e.pre_update_callbacks.push(o); }); } const Th = x("debugresolveurl"), b1 = "rel:"; function LD(s, e) { return Eo(s, e); } function Eo(s, e) { if (e === void 0) return Th && console.warn("getPath: uri is undefined, returning uri", e), e; if (e.startsWith("./")) return e; if (e.startsWith("http")) return Th && console.warn("getPath: uri is absolute, returning uri", e), e; if (s === void 0) return Th && console.warn("getPath: source is undefined, returning uri", e), e; e.startsWith(b1) && (e = e.substring(4)); const t = s.lastIndexOf("/"); if (t >= 0) { const i = s.substring(0, t + 1); for (; i.endsWith("/") && e.startsWith("/"); ) e = e.substring(1); const n = i + e; return Th && console.log("source:", s, `changed uri from`, e, ` to `, n, ` basePath: ` + i), n; } return e; } function v1(s) { if (s) return s = s.trim(), s = s.split("?")[0]?.split("#")[0], s; } class w1 { subscribeWrite(e) { this.writeCallbacks.push(e); } unsubscribeWrite(e) { const t = this.writeCallbacks.indexOf(e); t !== -1 && this.writeCallbacks.splice(t, 1); } writeCallbacks = []; constructor(e, t) { this._object = e, this._prop = t, this._wrapperProp = /* @__PURE__ */ Symbol("$" + t), this.apply(); } _applied = !1; _object; _prop; _wrapperProp; apply() { if (this._applied || !this._object) return; const e = this._object, t = this._prop; if (e[t] === void 0) return; this._applied = !0, e[this._wrapperProp] !== void 0 && console.warn("Watcher is being applied to an object that already has a wrapper property. This is not (yet) supported"); const i = e[t]; e[this._wrapperProp] = i, Object.defineProperty(e, t, { get: () => e[this._wrapperProp], set: (r) => { e[this._wrapperProp] = r; for (const a of this.writeCallbacks) a(r, this._prop); } }); } revoke() { if (!this._applied || !this._object) return; this._applied = !1; const e = this._object, t = this._prop; Reflect.deleteProperty(e, t); const i = e[this._wrapperProp]; e[t] = i, Reflect.deleteProperty(e, this._wrapperProp); } dispose() { this.revoke(), this.writeCallbacks.length = 0, this._object = null; } } class wo { _watches = []; constructor(e, t) { if (Array.isArray(t)) for (const i of t) this._watches.push(new wo(e, i)); else this._watches.push(new w1(e, t)); } subscribeWrite(e) { for (const t of this._watches) t.subscribeWrite(e); } unsubscribeWrite(e) { for (const t of this._watches) t.unsubscribeWrite(e); } apply() { for (const e of this._watches) e.apply(); } revoke() { for (const e of this._watches) e.revoke(); } dispose() { for (const e of this._watches) e.dispose(); this._watches.length = 0; } } const ua = /* @__PURE__ */ Symbol("needle:watches"); function gg(s, e) { if (!s[ua]) if (s instanceof Z) s[ua] = new wo(s, ["x", "y"]); else if (s instanceof _) s[ua] = new wo(s, ["x", "y", "z"]); else if (s instanceof ye || s instanceof V) s[ua] = new wo(s, ["x", "y", "z", "w"]); else return !1; return s[ua].subscribeWrite(e), !0; } function Qv(s, e) { if (!s) return; const t = s[ua]; t && t.unsubscribeWrite(e); } var D; ((s) => { let e; function t() { if (e !== void 0) return e; const J = window.navigator.userAgent, Oe = /Windows|MacOS|Mac OS/.test(J), ai = /Windows NT/.test(J) && /Edg/.test(J) && !/Win64/.test(J); return e = Oe && !ai && !T(); } s.isDesktop = t; let i; function n() { return i !== void 0 ? i : typeof window.orientation < "u" || navigator.userAgent.indexOf("IEMobile") !== -1 ? i = !0 : i = /iPhone|iPad|iPod|Android|IEMobile/i.test(navigator.userAgent); } s.isMobileDevice = n; function o() { return a(); } s.isIPad = o; let r; function a() { if (r !== void 0) return r; const J = navigator.userAgent.toLowerCase(); return r = /iPad/.test(navigator.userAgent) || J.includes("macintosh") && "ontouchend" in document; } s.isiPad = a; let l; function c() { return l !== void 0 ? l : l = /Android/.test(navigator.userAgent); } s.isAndroidDevice = c; let h; function d() { return h !== void 0 ? h : h = /WebXRViewer\//i.test(navigator.userAgent); } s.isMozillaXR = d; let f; function p() { return f !== void 0 ? f : f = /NeedleAppClip\//i.test(navigator.userAgent); } s.isNeedleAppClip = p; let g; function y() { if (g !== void 0) return g; if (T() || a()) return g = !1; const J = navigator.userAgent.toLowerCase(); return navigator.userAgentData ? g = navigator.userAgentData.platform === "macOS" : g = J.includes("mac os x") || J.includes("macintosh"); } s.isMacOS = y; let m; function v() { return m !== void 0 ? m : m = a() && "xr" in navigator && G(); } s.isVisionOS = v; let b; const w = ["iPad Simulator", "iPhone Simulator", "iPod Simulator", "iPad", "iPhone", "iPod"]; function T() { return b !== void 0 ? b : b = w.includes(navigator.platform) || navigator.userAgent.includes("Mac") && "ontouchend" in document; } s.isiOS = T; let k; function R() { return k !== void 0 || (k = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)), k; } s.isSafari = R; let I; function j() { return I !== void 0 ? I : I = navigator.userAgent.includes("OculusBrowser"); } s.isQuest = j; let B; function G() { return B !== void 0 || (B = document.createElement("a").relList.supports("ar")), B; } s.supportsQuickLookAR = G; async function X() { try { return (await navigator.permissions.query({ name: "microphone" })).state !== "denied"; } catch (J) { return console.error("Error querying `microphone` permissions.", J), !1; } } s.microphonePermissionsGranted = X; let O; function W() { if (O !== void 0) return O; const J = navigator.userAgent.match(/iPhone OS (\d+_\d+)/); if (J && (O = J[1].replace("_", ".")), !O) { const Oe = navigator.userAgent.match(/(?:\(Macintosh;|iPhone;|iPad;).*Version\/(\d+\.\d+)/); Oe && (O = Oe[1]); } return O || (O = null), O; } s.getiOSVersion = W; let q; function se() { if (q !== void 0) return q; const J = navigator.userAgent.match(/(?:CriOS|Chrome)\/(\d+\.\d+\.\d+\.\d+)/); return J ? q = J[1].replace("_", ".") : q = null, q; } s.getChromeVersion = se; let oe; function fe() { if (oe !== void 0) return oe; const J = navigator.userAgent.match(/Version\/(\d+\.\d+)/); return J && R() ? oe = J[1] : oe = null, oe; } s.getSafariVersion = fe; })(D || (D = {})); function DD() { return D.isDesktop(); } function jD() { return D.isMobileDevice(); } function BD() { return D.isiPad(); } function FD() { return D.isiPad(); } function zD() { return D.isAndroidDevice(); } function UD() { return D.isMozillaXR(); } function ND() { return D.isMacOS(); } function $D() { return D.isiOS(); } function WD() { return D.isSafari(); } function VD() { return D.isQuest(); } async function HD() { return D.microphonePermissionsGranted(); } const go = /* @__PURE__ */ new WeakMap(); function Yv(s, e, t) { if (!go.get(s)) { const n = new MutationObserver((o) => { x1(s, o); }); go.set(s, { observer: n, attributeChangedListeners: /* @__PURE__ */ new Map() }), n.observe(s, { attributes: !0 }); } const i = go.get(s).attributeChangedListeners; return i.has(e) || i.set(e, []), i.get(e).push(t), () => { Kv(s, e, t); }; } function Kv(s, e, t) { if (!go.get(s)) return; const i = go.get(s).attributeChangedListeners; if (!i.has(e)) return; const n = i.get(e), o = n.indexOf(t); o !== -1 && (n.splice(o, 1), n.length <= 0 && (i.delete(e), go.get(s)?.observer.disconnect(), go.delete(s))); } function x1(s, e) { const t = go.get(s).attributeChangedListeners; for (const i of e) if (i.type === "attributes") { const n = i.attributeName, o = s.getAttribute(n); if (t.has(n)) for (const r of t.get(n)) r(o); } } class c_ { reason; constructor(e) { this.reason = e; } } async function Zv(s) { const e = await Promise.allSettled(s).catch((n) => [ new c_(n.message) ]); let t = !1; const i = e.map((n) => "value" in n ? n.value : (t = !0, new c_(n.reason))); return { anyFailed: t, results: i }; } const S1 = x("debugdebug"); let yg = !1; (x("noerrors") || x("nooverlaymessages")) && (yg = !0); const Nf = "needle_engine_global_error_container"; var Yi = /* @__PURE__ */ ((s) => (s[s.Log = 0] = "Log", s[s.Warn = 1] = "Warn", s[s.Error = 2] = "Error", s))(Yi || {}); function Jv() { return t0; } const em = new Array(); function C1(s) { em.push(s); } let $f = !1; function P1(...s) { if (!$f) { $f = !0; try { for (let e = 0; e < em.length; e++) em[e](...s); } catch (e) { console.error(e); } $f = !1; } } const e0 = console.error, k1 = function(...s) { e0.apply(console, s), R1(s), gr(2, s, {}), M1(...s); }; function O1(s) { yg = !s, s ? console.error = k1 : console.error = e0; } function GD(s) { return O1(s); } let t0 = 0; function M1(...s) { t0 += 1, P1(...s); } function R1(s) { if (Array.isArray(s)) for (let e = 0; e < s.length; e++) { const t = s[e]; typeof t == "string" && t.startsWith("THREE.PropertyBinding: Trying to update node for track:") && (s[e] = "Some animated objects couldn't be found: see console for details"); } } const h_ = /* @__PURE__ */ new Set(); function gr(s, e, t = {}, i, n) { if (yg) return; if (t.once === !0) { let a = ""; if (Array.isArray(e)) for (let l = 0; l < e.length; l++) { let c = e[l]; c instanceof Error && (c = c.message), typeof c != "object" && (l > 0 && (a += " "), a += c); } else typeof e == "string" && (a = e); if (h_.has(a)) return; h_.add(a); } const o = pe.Current; let r = o?.domElement ?? document.querySelector("needle-engine"); if (o?.isInAR && (r = o.arOverlayElement), !!r) { if (Array.isArray(e)) { let a = ""; for (let l = 0; l < e.length; l++) { let c = e[l]; c instanceof Error && (c = c.message), typeof c != "object" && (l > 0 && (a += " "), a += c); } e = a; } !e || e.length <= 0 || E1(s, r, e, t); } } const wa = /* @__PURE__ */ new Map(), d_ = 0.2; function E1(s, e, t, i = {}) { if (t == null) return; const n = A1(e); if (n.childElementCount >= 20) { const c = n.lastElementChild; u_(c); } t.length > 400 && (t = t.substring(0, 400) + "..."); const o = i.key ?? t; if (wa.has(o)) { wa.get(o)?.update(t, i); return; } const r = I1(s, t); n.prepend(r); const a = () => { wa.delete(o), u_(r); }; let l = setTimeout(a, Math.max(d_, i.duration ?? 10) * 1e3); wa.set(o, { update: (c, h) => { c.length > 400 && (c = c.substring(0, 400) + "..."), r.innerHTML = c, h.duration && (clearTimeout(l), l = setTimeout(a, Math.max(d_, h.duration) * 1e3)); }, removeFunction: a }); } function qD() { S1 && console.log("Clearing messages"); for (const s of wa.values()) s?.removeFunction.call(s); wa.clear(); } const T1 = ` @import url('https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,wght@8..144,100..1000&display=swap'); div[data-needle_engine_debug_overlay] { font-family: 'Roboto Flex', sans-serif; font-weight: 400; font-size: 16px; } div[data-needle_engine_debug_overlay] strong { font-weight: 700; } div[data-needle_engine_debug_overlay] a { color: white; text-decoration: none; border-bottom: 1px solid rgba(255, 255, 255, 0.3); } div[data-needle_engine_debug_overlay] a:hover { text-decoration: none; border: none; } div[data-needle_engine_debug_overlay] .log strong { color: rgba(200,200,200,.9); } div[data-needle_engine_debug_overlay] .warn strong { color: rgba(255,255,230, 1); } div[data-needle_engine_debug_overlay] .error strong { color: rgba(255,100,120, 1); } `; function A1(s) { globalThis[Nf] || (globalThis[Nf] = /* @__PURE__ */ new Map()); const e = globalThis[Nf]; if (e.has(s)) return e.get(s); { const t = document.createElement("div"); e.set(s, t), t.setAttribute("data-needle_engine_debug_overlay", ""), t.classList.add("debug-container"), t.style.cssText = ` position: absolute; top: 0; right: 5px; padding-top: env(safe-area-inset-top, 0px); max-width: 70%; max-height: calc(100% - 105px); z-index: 100000; pointer-events: scroll; display: flex; align-items: end; flex-direction: column; color: white; overflow: auto; word-break: break-word; `, D.isNeedleAppClip() && (t.style.left = "5px", t.style.right = "unset"); const i = document.querySelector('meta[name="viewport"]'); i && !i.getAttribute("content")?.includes("viewport-fit=") && i.setAttribute("content", i.getAttribute("content") + ",viewport-fit=cover"), s.shadowRoot ? s.shadowRoot.appendChild(t) : s.appendChild(t); const n = document.createElement("style"); return n.innerHTML = T1, t.appendChild(n), t; } } const i0 = /* @__PURE__ */ Symbol("logtype"), Hd = /* @__PURE__ */ new Map(); function u_(s) { s.remove(); const e = s[i0], t = Hd.get(e) ?? []; t.push(s), Hd.set(e, t); } function I1(s, e) { if (Hd.has(s)) { const i = Hd.get(s); if (i.length > 0) { const n = i.pop(); return n.innerHTML = e, n; } } const t = document.createElement("div"); switch (t.setAttribute("data-id", "__needle_engine_debug_overlay"), t.style.marginRight = "5px", t.style.padding = ".5em", t.style.backgroundColor = "rgba(0,0,0,.9)", t.style.marginTop = "5px", t.style.marginBottom = "3px", t.style.borderRadius = "8px", t.style.pointerEvents = "all", t.style.userSelect = "text", t.style.maxWidth = "250px", t.style.whiteSpace = "pre-wrap", t.style["backdrop-filter"] = "blur(10px)", t.style["-webkit-backdrop-filter"] = "blur(10px)", t.style.backgroundColor = "rgba(20,20,20,.8)", t.style.boxShadow = "inset 0 0 80px rgba(0,0,0,.2), 0 0 5px rgba(0,0,0,.2)", t.style.border = "1px solid rgba(160,160,160,.2)", t[i0] = s, s) { case 0: t.classList.add("log"), t.style.color = "rgba(200,200,200,.7)", t.style.backgroundColor = "rgba(40,40,40,.7)"; break; case 1: t.classList.add("warn"), t.style.color = "rgb(255, 255, 150)", t.style.backgroundColor = "rgba(50,50,20,.8)"; break; case 2: t.classList.add("error"), t.style.color = "rgb(255, 50, 50", t.style.backgroundColor = "rgba(50,20,20,.8)"; break; } return t.title = "Open the browser console (F12) for more information", t.innerHTML = e, t; } const L1 = x("nodevlogs"); let tm, Wf; function L() { if (L1) return !1; if (tm !== void 0) return tm; if (Wf !== void 0) return Wf; let s = Zi(); return s || (s = window.location.hostname.endsWith(".local-credentialless.webcontainer.io")), Wf = s, s; } function XD(s) { tm = s; } class D1 { random(e, t) { return Array.isArray(e) ? e.length <= 0 ? null : e[Math.floor(Math.random() * e.length)] : e !== void 0 && t !== void 0 ? Math.random() * (t - e) + e : Math.random(); } /** * Fills a Vector3 with random values. * @param target Vector3 to fill with random values * @param min Minimum value for each component * @param max Maximum value for each component */ randomVector3(e, t = 0, i = 1) { e.x = this.random(t, i), e.y = this.random(t, i), e.z = this.random(t, i); } /** * Clamps a value between min and max. * @param value Value to clamp * @param min Minimum bound * @param max Maximum bound * @returns Clamped value */ clamp(e, t, i) { return e < t ? t : e > i ? i : e; } /** * Clamps a value between 0 and 1. * @param value Value to clamp * @returns Value clamped to [0, 1] */ clamp01(e) { return this.clamp(e, 0, 1); } /** * Linearly interpolates between two values. * @param value1 Start value (returned when t=0) * @param value2 End value (returned when t=1) * @param t Interpolation factor, clamped to [0, 1] * @returns Interpolated value */ lerp(e, t, i) { return i = i < 0 ? 0 : i, i = i > 1 ? 1 : i, e + (t - e) * i; } /** * Calculates the linear interpolation parameter that produces the given value. * Inverse of lerp: if `lerp(a, b, t) = v`, then `inverseLerp(a, b, v) = t` * @param value1 Start value * @param value2 End value * @param t The value to find the parameter for * @returns The interpolation parameter (may be outside [0,1] if t is outside [value1, value2]) */ inverseLerp(e, t, i) { return (i - e) / (t - e); } /** * Remaps a value from one range to another. * @param value The value to remap. * @param min1 The minimum value of the current range. * @param max1 The maximum value of the current range. * @param min2 The minimum value of the target range. * @param max2 The maximum value of the target range. */ remap(e, t, i, n, o) { return n + (o - n) * (e - t) / (i - t); } /** * Moves a value towards a target by a maximum step amount. * Useful for smooth following or gradual value changes. * @param value1 Current value * @param value2 Target value * @param amount Maximum step to move (positive moves toward target) * @returns New value moved toward target, never overshooting */ moveTowards(e, t, i) { return e += i, (i < 0 && e < t || i > 0 && e > t) && (e = t), e; } Rad2Deg = 180 / Math.PI; Deg2Rad = Math.PI / 180; Epsilon = 1e-5; /** * Converts radians to degrees */ toDegrees(e) { return e * 180 / Math.PI; } /** * Converts degrees to radians */ toRadians(e) { return e * Math.PI / 180; } tan(e) { return Math.tan(e); } gammaToLinear(e) { return Math.pow(e, 2.2); } linearToGamma(e) { return Math.pow(e, 1 / 2.2); } /** * Checks if two vectors are approximately equal within epsilon tolerance. * Works with Vector2, Vector3, Vector4, and Quaternion. * @param v1 First vector * @param v2 Second vector * @param epsilon Tolerance for comparison (default: Number.EPSILON) * @returns True if all components are within epsilon of each other */ approximately(e, t, i = Number.EPSILON) { for (const n of j1) { const o = e[n], r = t[n]; if (o === void 0 || r === void 0) break; if (Math.abs(o - r) > i) return !1; } return !0; } /** * Easing function: slow start, fast middle, slow end (cubic). * @param x Input value from 0 to 1 * @returns Eased value from 0 to 1 */ easeInOutCubic(e) { return e < 0.5 ? 4 * e * e * e : 1 - Math.pow(-2 * e + 2, 3) / 2; } } const j1 = ["x", "y", "z", "w"], F = new D1(); class f_ { y; s; alpha = 0; constructor(e) { this.setAlpha(e), this.y = null, this.s = null; } setAlpha(e) { if (e <= 0 || e > 1) throw new Error(); this.alpha = e; } filter(e, t) { t && this.setAlpha(t); let i; return this.y ? i = this.alpha * e + (1 - this.alpha) * this.s : i = e, this.y = e, this.s = i, i; } lastValue() { return this.y; } reset(e) { this.y = e, this.s = e; } } class Vf { /** * An estimate of the frequency in Hz of the signal (> 0), if timestamps are not available. */ freq; /** * Min cutoff frequency in Hz (> 0). Lower values allow to remove more jitter. */ minCutOff; /** * Parameter to reduce latency (> 0). Higher values make the filter react faster to changes. */ beta; /** * Used to filter the derivates. 1 Hz by default. Change this parameter if you know what you are doing. */ dCutOff; /** * The low-pass filter for the signal. */ x; /** * The low-pass filter for the derivates. */ dx; /** * The last time the filter was called. */ lasttime; /** Create a new OneEuroFilter * @param freq - An estimate of the frequency in Hz of the signal (> 0), if timestamps are not available. * @param minCutOff - Min cutoff frequency in Hz (> 0). Lower values allow to remove more jitter. * @param beta - Parameter to reduce latency (> 0). Higher values make the filter react faster to changes. * @param dCutOff - Used to filter the derivates. 1 Hz by default. Change this parameter if you know what you are doing. */ constructor(e, t = 1, i = 0, n = 1) { if (e <= 0 || t <= 0 || n <= 0) throw new Error(); this.freq = e, this.minCutOff = t, this.beta = i, this.dCutOff = n, this.x = new f_(this.alpha(this.minCutOff)), this.dx = new f_(this.alpha(this.dCutOff)), this.lasttime = null; } alpha(e) { const t = 1 / this.freq; return 1 / (1 + 1 / (2 * Math.PI * e) / t); } /** Filter your value: call with your value and the current timestamp (e.g. from this.context.time.time) */ filter(e, t = null) { this.lasttime && t && (this.freq = 1 / (t - this.lasttime)), this.lasttime = t; const i = this.x.lastValue(), n = i ? (e - i) * this.freq : 0, o = this.dx.filter(n, this.alpha(this.dCutOff)), r = this.minCutOff + this.beta * Math.abs(o); return this.x.filter(e, this.alpha(r)); } reset(e) { e != null && this.x.reset(e), this.x.alpha = this.alpha(this.minCutOff), this.dx.alpha = this.alpha(this.dCutOff), this.lasttime = null; } } class n0 { x; y; z; /** Create a new OneEuroFilter * @param freq - An estimate of the frequency in Hz of the signal (> 0), if timestamps are not available. * @param minCutOff - Min cutoff frequency in Hz (> 0). Lower values allow to remove more jitter. * @param beta - Parameter to reduce latency (> 0). Higher values make the filter react faster to changes. * @param dCutOff - Used to filter the derivates. 1 Hz by default. Change this parameter if you know what you are doing. */ constructor(e, t = 1, i = 0, n = 1) { this.x = new Vf(e, t, i, n), this.y = new Vf(e, t, i, n), this.z = new Vf(e, t, i, n); } filter(e, t, i = null) { t.x = this.x.filter(e.x, i), t.y = this.y.filter(e.y, i), t.z = this.z.filter(e.z, i); } reset(e) { this.x.reset(e?.x), this.y.reset(e?.y), this.z.reset(e?.z); } } const gd = "needle:cameraController"; function B1(s) { return s[gd]; } function p_(s, e, t) { t ? s[gd] = e : s[gd] === e && (s[gd] = null); } const im = "needle:autofit"; function F1(s) { return s[im] === void 0 ? !0 : s[im] !== !1; } function nm(s, e) { s[im] = e; } let cn; const z1 = { x: 0, y: 0, width: 0, height: 0 }, U1 = x("debugfocusrect"); function N1(s, e, t, i, n) { s instanceof Element && (U1 && s instanceof HTMLElement && (s.style.outline = "2px dashed rgba(255, 150, 0, .8)"), s = s.getBoundingClientRect()), cn = n.domElement.getBoundingClientRect(); const o = z1; o.x = s.x, o.y = s.y, o.width = s.width, o.height = s.height, o.x -= cn.x, o.y -= cn.y; const r = cn.width, a = cn.height, l = i.view, c = e.zoom; let h = l?.offsetX || 0, d = l?.offsetY || 0, f = cn.width, p = cn.height; f /= c, p /= c, h = f * (c - 1) * 0.5, d = p * (c - 1) * 0.5; const g = o.x + o.width * 0.5, y = o.y + o.height * 0.5, m = cn.width * 0.5, v = cn.height * 0.5, b = g - m, w = y - v; h -= b / c, d -= w / c, e.offsetX !== void 0 && (h += e.offsetX * (cn.width * 0.5)), e.offsetY !== void 0 && (d -= e.offsetY * (cn.height * 0.5)); const T = l?.offsetX || h, k = l?.offsetY || d; h = F.lerp(T, h, t), d = F.lerp(k, d, t); const R = l?.width || r, I = l?.height || a; f = F.lerp(R, f, t), p = F.lerp(I, p, t), i.setViewOffset(r, a, h, d, f, p), i.updateProjectionMatrix(), e.damping > 0 && (e.damping *= 1 - t, e.damping < 0.01 && (e.damping = 0), e.damping = Math.max(0, e.damping)); } function $1(s, e, t) { const i = s.length(), n = e.length(), o = F.lerp(i, n, t); return s.lerp(e, t).normalize().multiplyScalar(o); } const Hf = new V(), s0 = new V().setFromAxisAngle(new _(0, 1, 0), Math.PI); function QD(s, e) { s.lookAt(e), s.quaternion.multiply(s0); } function Tu(s, e, t = !0, i = !1) { if (s === e) return; Hf.copy(s.quaternion); const n = te(e), o = te(s); if (i) { if (Kn(s, ve(e)), t) { const r = o.y, a = o.sub(K1(s)); a.y = r, s.lookAt(a), s.quaternion.multiply(s0); } Number.isNaN(s.quaternion.x) && s.quaternion.copy(Hf); return; } t && (n.y = o.y), s.lookAt(n), Number.isNaN(s.quaternion.x) && s.quaternion.copy(Hf); } function YD(s, e, t, i = 1) { if (t) { const n = U(0, 0, 0), o = e.x / window.innerWidth * 2 - 1, r = -(e.y / window.innerHeight) * 2 + 1; n.set( o, r, 0 ), n.unproject(t); const a = t.worldPosition, l = s.worldPosition.distanceTo(a), c = n.sub(a); c.multiplyScalar(i * 3.6 * l); const h = t.worldPosition.add(c); return s.lookAt(h), h; } return null; } const W1 = new Ji(() => new _(), 100); function U(s, e, t) { const i = W1.get(); return i.set(0, 0, 0), s instanceof _ ? i.copy(s) : Array.isArray(s) ? i.set(s[0], s[1], s[2]) : s instanceof DOMPointReadOnly ? i.set(s.x, s.y, s.z) : typeof s == "number" ? (i.x = s, i.y = e !== void 0 ? e : i.x, i.z = t !== void 0 ? t : i.x) : typeof s == "object" && (i.x = s.x, i.y = s.y, i.z = s.z), i; } const V1 = new Ji(() => new re(), 30); function H1(s) { const e = V1.get(); return s ? e.copy(s) : e.set(0, 0, 0), e; } const G1 = new Ji(() => new V(), 100); function wi(s, e, t, i) { const n = G1.get(); return n.identity(), s instanceof V ? n.copy(s) : s instanceof DOMPointReadOnly ? n.set(s.x, s.y, s.z, s.w) : typeof s == "number" && e !== void 0 && t !== void 0 && i !== void 0 ? n.set(s, e, t, i) : typeof s == "object" && "x" in s && "y" in s && "z" in s && "w" in s && n.set(s.x, s.y, s.z, s.w), n; } const _g = new Ji(() => new _(), 100), m_ = /* @__PURE__ */ Symbol("lastMatrixWorldUpdateKey"); function te(s, e = null, t = !0) { const i = e ?? _g.get(); return s ? s.parent ? (t && s.updateWorldMatrix(!0, !1), s.matrixWorldNeedsUpdate && s[m_] !== Date.now() && (s[m_] = Date.now(), s.updateMatrixWorld()), i.setFromMatrixPosition(s.matrixWorld), i) : i.copy(s.position) : i.set(0, 0, 0); } function At(s, e) { if (!s) return s; const t = _g.get(); return e !== t && t.copy(e), s.parent !== null && s.parent.worldToLocal(t), s.position.set(t.x, t.y, t.z), s; } function Va(s, e, t, i) { const n = _g.get(); return n.set(e, t, i), At(s, n), s; } const Gd = new Ji(() => new V(), 100), vr = new V(), Gf = new V(); function ve(s, e = null) { if (!s) return Gd.get().identity(); const t = e ?? Gd.get(); return s.parent ? (s.getWorldQuaternion(t), t) : t.copy(s.quaternion); } function Kn(s, e) { if (!s) return; e !== vr && vr.copy(e); const t = vr; s?.parent?.getWorldQuaternion(Gf), Gf.invert(); const n = Gf.multiply(t); s.quaternion.set(n.x, n.y, n.z, n.w); } function o0(s, e, t, i, n) { vr.set(e, t, i, n), Kn(s, vr); } const q1 = new Ji(() => new _(), 100), X1 = new _(); function Qe(s, e = null) { return e || (e = q1.get()), s ? s.parent ? (s.getWorldScale(e), e) : e.copy(s.scale) : e.set(0, 0, 0); } function Ic(s, e) { if (!s) return; if (!s.parent) { s.scale.copy(e); return; } const t = X1; s.parent.getWorldScale(t), s.scale.copy(e), s.scale.divide(t); } const Q1 = new _(), g_ = new V(); function KD(s) { return ve(s, g_), Q1.set(0, 0, 1).applyQuaternion(g_); } const Y1 = new Ji(() => new _(), 100), y_ = new V(); function K1(s, e) { return e || (e = Y1.get().set(0, 0, 1)), ve(s, y_), e.applyQuaternion(y_); } const __ = new dt(), b_ = new dt(), Z1 = new _(); function r0(s) { const e = Gd.get(); return s.getWorldQuaternion(e), b_.setFromQuaternion(e), b_; } function a0(s, e) { const t = Gd.get(); Kn(s, t.setFromEuler(e)); } function bg(s) { const e = r0(s), t = Z1; return t.set(e.x, e.y, e.z), t.x = F.toDegrees(t.x), t.y = F.toDegrees(t.y), t.z = F.toDegrees(t.z), t; } function J1(s, e) { Au(s, e.x, e.y, e.z, !0); } function Au(s, e, t, i, n = !0) { n && (e = F.toRadians(e), t = F.toRadians(t), i = F.toRadians(i)), __.set(e, t, i), vr.setFromEuler(__), Kn(s, vr); } function sm(s, e = !0) { s && (e ? (function t(i) { console.groupCollapsed((i.name ? i.name : "(no name : " + i.type + ")") + " %o", i), i.children.forEach(t), console.groupEnd(); })(s) : s.traverse(function(t) { for (var i = "|___", n = t; n.parent !== null; ) i = " " + i, n = n.parent; console.log(i + t.name + " <" + t.type + ">"); })); } function ZD(s) { let e = s?.name || ""; if (!s) return e; let t = s.parent; for (; t; ) e = t.name + "/" + e, t = t.parent; return e; } function eP(s) { if (s) { const e = s; return e.blendMode !== void 0 && e.clampWhenFinished !== void 0 && e.enabled !== void 0 && e.fadeIn !== void 0 && e.getClip !== void 0; } return !1; } class qd extends Qn { static vertex = ` varying vec2 vUv; void main(){ vUv = uv; gl_Position = vec4(position.xy, 0., 1.0); }`; constructor() { super({ vertexShader: qd.vertex, uniforms: { map: new Qi(null), flipY: new Qi(!0), writeDepth: new Qi(!1), depthTexture: new Qi(null) }, fragmentShader: ` uniform sampler2D map; uniform bool flipY; uniform bool writeDepth; uniform sampler2D depthTexture; varying vec2 vUv; void main(){ vec2 uv = vUv; if (flipY) uv.y = 1.0 - uv.y; gl_FragColor = texture2D(map, uv); if (writeDepth) { float depth = texture2D(depthTexture, uv).r; gl_FragDepth = depth; // float linearDepth = (depth - 0.99) * 100.0; // Enhance near 1.0 values // gl_FragColor = vec4(linearDepth, linearDepth, linearDepth, 1.0); } }` }); } reset() { this.uniforms.map.value = null, this.uniforms.flipY.value = !0, this.uniforms.writeDepth.value = !1, this.uniforms.depthTexture.value = null, this.needsUpdate = !0, this.uniformsNeedUpdate = !0; } } class Er { static planeGeometry = new kn(2, 2, 1, 1); static renderer = new zr({ antialias: !1, alpha: !0 }); static perspectiveCam = new de(); static orthographicCam = new vu(); static scene = new Ei(); static blitMaterial = new qd(); static mesh = new H(Er.planeGeometry, Er.blitMaterial); /** * Copy a texture to a new texture * @param texture the texture to copy * @param blitMaterial the material to use for copying (optional) * @returns the newly created, copied texture */ static copyTexture(e, t) { t || (t = this.blitMaterial), this.blitMaterial.reset(); const i = t || this.blitMaterial; i.uniforms.map.value = e, i.needsUpdate = !0, i.uniformsNeedUpdate = !0; const n = i.vertexShader; i.vertexShader = qd.vertex; const o = this.mesh; o.material = i, o.frustumCulled = !1, this.scene.children.length = 0, this.scene.add(o), this.renderer.setSize(e.image.width, e.image.height), this.renderer.clear(), this.renderer.render(this.scene, this.perspectiveCam); const r = new xe(this.renderer.domElement); return r.name = "Copy", r.needsUpdate = !0, i.vertexShader = n, r; } static blit(e, t, i) { const { renderer: n = this.renderer, blitMaterial: o = this.blitMaterial, flipY: r = !1, depthTexture: a = null, depthTest: l = !0, depthWrite: c = !0 } = i || {}; this.blitMaterial.reset(), o.uniforms.map && (o.uniforms.map.value = e), o.uniforms.flipY && (o.uniforms.flipY.value = r), a ? (o.uniforms.writeDepth = new Qi(!0), o.uniforms.depthTexture.value = a) : (o.uniforms.writeDepth = new Qi(!1), o.uniforms.depthTexture.value = null), o.needsUpdate = !0, o.uniformsNeedUpdate = !0; const h = this.mesh; h.material = o, h.frustumCulled = !1, this.scene.children.length = 0, this.scene.add(h); const d = n.getRenderTarget(), f = n.getContext(); l ? f.enable(f.DEPTH_TEST) : f.disable(f.DEPTH_TEST), n.state.buffers.depth.setMask(c), n.setClearColor(new re(0, 0, 0), 0), n.setRenderTarget(t), n.clear(), n.render(this.scene, this.perspectiveCam), n.setRenderTarget(d), f.enable(f.DEPTH_TEST), n.state.buffers.depth.setMask(!0); } /** * Copy a texture to a HTMLCanvasElement * @param texture the texture convert * @param force if true the texture will be copied to a new texture before converting * @returns the HTMLCanvasElement with the texture or null if the texture could not be copied */ static textureToCanvas(e, t = !1) { if (!e) return null; (t === !0 || e.isCompressedTexture === !0) && (e = tP(e)); const i = e.image; if (iP(i)) { const n = document.createElement("canvas"); n.width = i.width, n.height = i.height; const o = n.getContext("2d"); return o ? (o.drawImage(i, 0, 0, i.width, i.height, 0, 0, n.width, n.height), n) : (console.error("Failed getting canvas 2d context"), null); } return null; } } function tP(s) { return Er.copyTexture(s); } function JD(s, e = !1) { return Er.textureToCanvas(s, e); } function iP(s) { return typeof HTMLImageElement < "u" && s instanceof HTMLImageElement || typeof HTMLCanvasElement < "u" && s instanceof HTMLCanvasElement || typeof OffscreenCanvas < "u" && s instanceof OffscreenCanvas || typeof ImageBitmap < "u" && s instanceof ImageBitmap; } function nP(s) { const e = s.type; return e === "Mesh" || e === "SkinnedMesh"; } function l0(s, e) { e ? s["needle:rendercustomshadow"] = !0 : s["needle:rendercustomshadow"] = !1; } function sP(s) { if (s) { if (s["needle:rendercustomshadow"] === !0) return !0; if (s["needle:rendercustomshadow"] == null) return !0; } return !1; } function Ai(s, e = void 0, t = void 0, i = void 0) { const n = i || new Ut(); n.makeEmpty(); const o = []; function r(l) { let c = !0; if (l.visible && F1(l) !== !1 && !(l.type === "TransformControlsGizmo" || l.type === "TransformControlsPlane")) { if (l instanceof mS && (c = !1), l instanceof Mv && (c = !1), l instanceof Wa && (c = !1), l.isGizmo === !0 && (c = !1), l.material instanceof Ov && (c = !1), nP(l) || (c = !1), t && l.layers.test(t) === !1 && (c = !1), c) { if (e && Array.isArray(e) && e?.includes(l)) return; if (typeof e == "function" && e(l) === !0) return; } if (l.isUI !== !0) { if (c) { const h = l.children; l.children = o; const d = l.position, f = l.scale; if (Number.isNaN(d.x) || Number.isNaN(d.y) || Number.isNaN(d.z)) { console.warn(`Object "${l.name}" has NaN values in position or scale.... will ignore it`, d, f); return; } l.geometry === null && (l.geometry = void 0), n.expandByObject(l, !0), l.children = h; } for (const h of l.children) r(h); } } } let a = !1; Array.isArray(s) || (s = [s]); for (const l of s) l && (a = !0, l.updateMatrixWorld(), r(l)); return a || console.warn("No objects to fit camera to..."), n; } function oP(s, e, t) { const i = Ai([s], t?.ignore), n = new _(); i.getSize(n); const o = new _(); i.getCenter(o); const r = new _(); e.getSize(r); const a = new _(); e.getCenter(a); const l = new _(); l.set(r.x / n.x, r.y / n.y, r.z / n.z); const c = Math.min(l.x, l.y, l.z), h = t?.scale !== !1; if (h && Ic(s, Qe(s).multiplyScalar(c)), t?.position !== !1) { const d = new _(); i.getCenter(d), d.y = i.min.y; const f = new _(); e.getCenter(f), f.y = e.min.y; const p = f.clone().sub(d); h && p.multiplyScalar(c), At(s, te(s).add(p)); } return { boundsBefore: i, scale: l }; } function rP(s, e) { const t = Ai([s]), i = new _(); t.getCenter(i), i.y = t.min.y; const n = e.clone().sub(i), o = te(s); return At(s, o.add(n)), { offset: n, bounds: t }; } function c0(s, e, t, i) { if (Array.isArray(e)) { let r = !0; for (let a = 0; a < e.length; a++) c0(s, e[a], a, e) || (r = !1); return r; } if (e.type === "MeshStandardMaterial" || e.type === "MeshBasicMaterial") return !1; if (e["material:fbx"] != null) return !0; const n = new gt(); n["material:fbx"] = e; const o = e; return o && (o.map ? n.color.set(1, 1, 1) : n.color.copyLinearToSRGB(o.color), n.emissive.copyLinearToSRGB(o.emissive), n.emissiveIntensity = o.emissiveIntensity, n.opacity = o.opacity, n.displacementScale = o.displacementScale, n.transparent = o.transparent, n.bumpMap = o.bumpMap, n.aoMap = o.aoMap, n.map = o.map, n.displacementMap = o.displacementMap, n.emissiveMap = o.emissiveMap, n.normalMap = o.normalMap, n.envMap = o.envMap, n.alphaMap = o.alphaMap, n.metalness = o.reflectivity, n.vertexColors = o.vertexColors, o.shininess && (n.roughness = 1 - Math.sqrt(o.shininess) / 10), n.needsUpdate = !0), t === void 0 ? s.material = n : i[t] = n, !0; } let Ah = !1; C1((...s) => { L() && pe.Current?.isInXR && (uc(!0), h0("error", ...s)); }); function uc(s)