@needle-tools/three 0.169.20-experimental.0 → 0.183.2-canary.0

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.
Files changed (1051) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +5 -6
  3. package/build/three.cjs +54184 -56703
  4. package/build/three.core.js +59506 -0
  5. package/build/three.core.min.js +6 -0
  6. package/build/three.module.js +11645 -73000
  7. package/build/three.module.min.js +2 -2
  8. package/build/three.tsl.js +648 -0
  9. package/build/three.tsl.min.js +6 -0
  10. package/build/three.webgpu.js +53912 -51652
  11. package/build/three.webgpu.min.js +2 -2
  12. package/build/three.webgpu.nodes.js +53888 -51806
  13. package/build/three.webgpu.nodes.min.js +2 -2
  14. package/examples/fonts/MPLUSRounded1c/MPLUSRounded1c-Regular.typeface.json.zip +0 -0
  15. package/examples/fonts/MPLUSRounded1c/OFL.txt +91 -0
  16. package/examples/jsm/Addons.js +5 -15
  17. package/examples/jsm/animation/AnimationClipCreator.js +58 -6
  18. package/examples/jsm/animation/CCDIKSolver.js +152 -45
  19. package/examples/jsm/capabilities/WebGL.js +28 -29
  20. package/examples/jsm/capabilities/WebGPU.js +19 -17
  21. package/examples/jsm/controls/ArcballControls.js +474 -178
  22. package/examples/jsm/controls/DragControls.js +100 -58
  23. package/examples/jsm/controls/FirstPersonControls.js +116 -6
  24. package/examples/jsm/controls/FlyControls.js +50 -2
  25. package/examples/jsm/controls/MapControls.js +96 -8
  26. package/examples/jsm/controls/OrbitControls.js +496 -57
  27. package/examples/jsm/controls/PointerLockControls.js +115 -22
  28. package/examples/jsm/controls/TrackballControls.js +166 -14
  29. package/examples/jsm/controls/TransformControls.js +336 -26
  30. package/examples/jsm/csm/CSM.js +232 -18
  31. package/examples/jsm/csm/CSMFrustum.js +61 -4
  32. package/examples/jsm/csm/CSMHelper.js +50 -0
  33. package/examples/jsm/csm/CSMShader.js +13 -1
  34. package/examples/jsm/csm/CSMShadowNode.js +599 -0
  35. package/examples/jsm/curves/CurveExtras.js +303 -31
  36. package/examples/jsm/curves/NURBSCurve.js +91 -16
  37. package/examples/jsm/curves/NURBSSurface.js +52 -6
  38. package/examples/jsm/curves/NURBSUtils.js +102 -112
  39. package/examples/jsm/curves/NURBSVolume.js +24 -4
  40. package/examples/jsm/effects/AnaglyphEffect.js +134 -7
  41. package/examples/jsm/effects/AsciiEffect.js +69 -22
  42. package/examples/jsm/effects/OutlineEffect.js +61 -111
  43. package/examples/jsm/effects/ParallaxBarrierEffect.js +30 -0
  44. package/examples/jsm/effects/StereoEffect.js +31 -0
  45. package/examples/jsm/environments/ColorEnvironment.js +59 -0
  46. package/examples/jsm/environments/DebugEnvironment.js +50 -0
  47. package/examples/jsm/environments/RoomEnvironment.js +83 -42
  48. package/examples/jsm/exporters/DRACOExporter.js +56 -14
  49. package/examples/jsm/exporters/EXRExporter.js +40 -9
  50. package/examples/jsm/exporters/GLTFExporter.js +502 -169
  51. package/examples/jsm/exporters/OBJExporter.js +21 -1
  52. package/examples/jsm/exporters/PLYExporter.js +44 -12
  53. package/examples/jsm/exporters/STLExporter.js +27 -5
  54. package/examples/jsm/exporters/USDZExporter.js +781 -291
  55. package/examples/jsm/geometries/BoxLineGeometry.js +23 -0
  56. package/examples/jsm/geometries/ConvexGeometry.js +19 -0
  57. package/examples/jsm/geometries/DecalGeometry.js +91 -30
  58. package/examples/jsm/geometries/ParametricFunctions.js +100 -0
  59. package/examples/jsm/geometries/ParametricGeometry.js +38 -5
  60. package/examples/jsm/geometries/RoundedBoxGeometry.js +68 -7
  61. package/examples/jsm/geometries/TeapotGeometry.js +23 -38
  62. package/examples/jsm/geometries/TextGeometry.js +48 -29
  63. package/examples/jsm/gpgpu/BitonicSort.js +715 -0
  64. package/examples/jsm/helpers/AnimationPathHelper.js +302 -0
  65. package/examples/jsm/helpers/LightProbeHelper.js +36 -0
  66. package/examples/jsm/helpers/LightProbeHelperGPU.js +38 -1
  67. package/examples/jsm/helpers/OctreeHelper.js +36 -0
  68. package/examples/jsm/helpers/PositionalAudioHelper.js +60 -0
  69. package/examples/jsm/helpers/RapierHelper.js +59 -0
  70. package/examples/jsm/helpers/RectAreaLightHelper.js +36 -3
  71. package/examples/jsm/helpers/TextureHelper.js +28 -0
  72. package/examples/jsm/helpers/TextureHelperGPU.js +214 -0
  73. package/examples/jsm/helpers/VertexNormalsHelper.js +61 -2
  74. package/examples/jsm/helpers/VertexTangentsHelper.js +47 -2
  75. package/examples/jsm/helpers/ViewHelper.js +181 -9
  76. package/examples/jsm/inspector/Inspector.js +487 -0
  77. package/examples/jsm/inspector/RendererInspector.js +425 -0
  78. package/examples/jsm/inspector/tabs/Console.js +238 -0
  79. package/examples/jsm/inspector/tabs/Parameters.js +348 -0
  80. package/examples/jsm/inspector/tabs/Performance.js +268 -0
  81. package/examples/jsm/inspector/tabs/Viewer.js +166 -0
  82. package/examples/jsm/inspector/ui/Graph.js +95 -0
  83. package/examples/jsm/inspector/ui/Item.js +170 -0
  84. package/examples/jsm/inspector/ui/List.js +75 -0
  85. package/examples/jsm/inspector/ui/Profiler.js +1975 -0
  86. package/examples/jsm/inspector/ui/Style.js +1613 -0
  87. package/examples/jsm/inspector/ui/Tab.js +233 -0
  88. package/examples/jsm/inspector/ui/Values.js +439 -0
  89. package/examples/jsm/inspector/ui/utils.js +56 -0
  90. package/examples/jsm/interactive/HTMLMesh.js +43 -12
  91. package/examples/jsm/interactive/InteractiveGroup.js +170 -52
  92. package/examples/jsm/interactive/SelectionBox.js +106 -9
  93. package/examples/jsm/interactive/SelectionHelper.js +76 -30
  94. package/examples/jsm/libs/demuxer_mp4.js +109 -0
  95. package/examples/jsm/libs/meshopt_decoder.module.js +76 -58
  96. package/examples/jsm/libs/motion-controllers.module.js +1 -1
  97. package/examples/jsm/lighting/TiledLighting.js +42 -0
  98. package/examples/jsm/lights/LightProbeGenerator.js +44 -7
  99. package/examples/jsm/lights/RectAreaLightTexturesLib.js +50 -14
  100. package/examples/jsm/lights/RectAreaLightUniformsLib.js +16 -0
  101. package/examples/jsm/lines/Line2.js +41 -4
  102. package/examples/jsm/lines/LineGeometry.js +80 -2
  103. package/examples/jsm/lines/LineMaterial.js +105 -5
  104. package/examples/jsm/lines/LineSegments2.js +54 -4
  105. package/examples/jsm/lines/LineSegmentsGeometry.js +65 -8
  106. package/examples/jsm/lines/Wireframe.js +41 -4
  107. package/examples/jsm/lines/WireframeGeometry2.js +27 -2
  108. package/examples/jsm/lines/webgpu/Line2.js +28 -2
  109. package/examples/jsm/lines/webgpu/LineSegments2.js +59 -24
  110. package/examples/jsm/lines/webgpu/Wireframe.js +86 -0
  111. package/examples/jsm/loaders/3DMLoader.js +78 -6
  112. package/examples/jsm/loaders/3MFLoader.js +148 -7
  113. package/examples/jsm/loaders/AMFLoader.js +34 -14
  114. package/examples/jsm/loaders/BVHLoader.js +59 -12
  115. package/examples/jsm/loaders/ColladaLoader.js +61 -4027
  116. package/examples/jsm/loaders/DDSLoader.js +68 -1
  117. package/examples/jsm/loaders/DRACOLoader.js +146 -22
  118. package/examples/jsm/loaders/EXRLoader.js +255 -34
  119. package/examples/jsm/loaders/FBXLoader.js +80 -42
  120. package/examples/jsm/loaders/FontLoader.js +83 -6
  121. package/examples/jsm/loaders/GCodeLoader.js +71 -14
  122. package/examples/jsm/loaders/GLTFLoader.js +381 -263
  123. package/examples/jsm/loaders/HDRCubeTextureLoader.js +52 -3
  124. package/examples/jsm/loaders/HDRLoader.js +485 -0
  125. package/examples/jsm/loaders/IESLoader.js +42 -0
  126. package/examples/jsm/loaders/KMZLoader.js +39 -6
  127. package/examples/jsm/loaders/KTX2Loader.js +124 -48
  128. package/examples/jsm/loaders/KTXLoader.js +31 -10
  129. package/examples/jsm/loaders/LDrawLoader.js +192 -145
  130. package/examples/jsm/loaders/LUT3dlLoader.js +47 -10
  131. package/examples/jsm/loaders/LUTCubeLoader.js +46 -9
  132. package/examples/jsm/loaders/LUTImageLoader.js +79 -38
  133. package/examples/jsm/loaders/LWOLoader.js +54 -59
  134. package/examples/jsm/loaders/LottieLoader.js +54 -1
  135. package/examples/jsm/loaders/MD2Loader.js +37 -1
  136. package/examples/jsm/loaders/MDDLoader.js +57 -12
  137. package/examples/jsm/loaders/MTLLoader.js +60 -35
  138. package/examples/jsm/loaders/MaterialXLoader.js +268 -34
  139. package/examples/jsm/loaders/NRRDLoader.js +40 -8
  140. package/examples/jsm/loaders/OBJLoader.js +51 -2
  141. package/examples/jsm/loaders/PCDLoader.js +173 -21
  142. package/examples/jsm/loaders/PDBLoader.js +41 -2
  143. package/examples/jsm/loaders/PLYLoader.js +70 -39
  144. package/examples/jsm/loaders/PVRLoader.js +25 -6
  145. package/examples/jsm/loaders/RGBELoader.js +6 -438
  146. package/examples/jsm/loaders/STLLoader.js +48 -38
  147. package/examples/jsm/loaders/SVGLoader.js +119 -25
  148. package/examples/jsm/loaders/TDSLoader.js +92 -74
  149. package/examples/jsm/loaders/TGALoader.js +23 -2
  150. package/examples/jsm/loaders/TIFFLoader.js +23 -0
  151. package/examples/jsm/loaders/TTFLoader.js +50 -3
  152. package/examples/jsm/loaders/USDLoader.js +279 -0
  153. package/examples/jsm/loaders/USDZLoader.js +4 -858
  154. package/examples/jsm/loaders/UltraHDRLoader.js +338 -166
  155. package/examples/jsm/loaders/VOXLoader.js +688 -87
  156. package/examples/jsm/loaders/VRMLLoader.js +121 -12
  157. package/examples/jsm/loaders/VTKLoader.js +77 -25
  158. package/examples/jsm/loaders/XYZLoader.js +36 -0
  159. package/examples/jsm/loaders/collada/ColladaComposer.js +2950 -0
  160. package/examples/jsm/loaders/collada/ColladaParser.js +1962 -0
  161. package/examples/jsm/loaders/lwo/IFFParser.js +77 -77
  162. package/examples/jsm/loaders/usd/USDAParser.js +822 -0
  163. package/examples/jsm/loaders/usd/USDCParser.js +1852 -0
  164. package/examples/jsm/loaders/usd/USDComposer.js +4041 -0
  165. package/examples/jsm/materials/LDrawConditionalLineMaterial.js +183 -0
  166. package/examples/jsm/materials/LDrawConditionalLineNodeMaterial.js +154 -0
  167. package/examples/jsm/materials/WoodNodeMaterial.js +533 -0
  168. package/examples/jsm/math/Capsule.js +91 -14
  169. package/examples/jsm/math/ColorConverter.js +22 -0
  170. package/examples/jsm/math/ColorSpaces.js +74 -2
  171. package/examples/jsm/math/ConvexHull.js +517 -93
  172. package/examples/jsm/math/ImprovedNoise.js +32 -15
  173. package/examples/jsm/math/Lut.js +113 -0
  174. package/examples/jsm/math/MeshSurfaceSampler.js +78 -13
  175. package/examples/jsm/math/OBB.js +141 -29
  176. package/examples/jsm/math/Octree.js +283 -7
  177. package/examples/jsm/math/SimplexNoise.js +68 -42
  178. package/examples/jsm/misc/ConvexObjectBreaker.js +45 -25
  179. package/examples/jsm/misc/GPUComputationRenderer.js +96 -20
  180. package/examples/jsm/misc/Gyroscope.js +12 -0
  181. package/examples/jsm/misc/MD2Character.js +117 -2
  182. package/examples/jsm/misc/MD2CharacterComplex.js +175 -11
  183. package/examples/jsm/misc/MorphAnimMesh.js +44 -0
  184. package/examples/jsm/misc/MorphBlendMesh.js +103 -0
  185. package/examples/jsm/misc/ProgressiveLightMap.js +100 -54
  186. package/examples/jsm/misc/ProgressiveLightMapGPU.js +322 -0
  187. package/examples/jsm/misc/RollerCoaster.js +57 -0
  188. package/examples/jsm/misc/TubePainter.js +437 -40
  189. package/examples/jsm/misc/Volume.js +123 -76
  190. package/examples/jsm/misc/VolumeSlice.js +95 -49
  191. package/examples/jsm/modifiers/CurveModifier.js +66 -38
  192. package/examples/jsm/modifiers/CurveModifierGPU.js +42 -19
  193. package/examples/jsm/modifiers/EdgeSplitModifier.js +20 -0
  194. package/examples/jsm/modifiers/SimplifyModifier.js +24 -10
  195. package/examples/jsm/modifiers/TessellateModifier.js +35 -2
  196. package/examples/jsm/objects/GroundedSkybox.js +25 -6
  197. package/examples/jsm/objects/Lensflare.js +94 -2
  198. package/examples/jsm/objects/LensflareMesh.js +64 -10
  199. package/examples/jsm/objects/MarchingCubes.js +90 -5
  200. package/examples/jsm/objects/Reflector.js +76 -2
  201. package/examples/jsm/objects/ReflectorForSSRPass.js +41 -0
  202. package/examples/jsm/objects/Refractor.js +62 -0
  203. package/examples/jsm/objects/ShadowMesh.js +54 -4
  204. package/examples/jsm/objects/Sky.js +106 -16
  205. package/examples/jsm/objects/SkyMesh.js +211 -38
  206. package/examples/jsm/objects/Water.js +49 -8
  207. package/examples/jsm/objects/Water2.js +49 -7
  208. package/examples/jsm/objects/Water2Mesh.js +50 -9
  209. package/examples/jsm/objects/WaterMesh.js +136 -43
  210. package/examples/jsm/physics/AmmoPhysics.js +60 -7
  211. package/examples/jsm/physics/JoltPhysics.js +65 -12
  212. package/examples/jsm/physics/RapierPhysics.js +217 -21
  213. package/examples/jsm/postprocessing/AfterimagePass.js +110 -29
  214. package/examples/jsm/postprocessing/BloomPass.js +128 -26
  215. package/examples/jsm/postprocessing/BokehPass.js +99 -22
  216. package/examples/jsm/postprocessing/ClearPass.js +54 -3
  217. package/examples/jsm/postprocessing/CubeTexturePass.js +82 -21
  218. package/examples/jsm/postprocessing/DotScreenPass.js +59 -10
  219. package/examples/jsm/postprocessing/EffectComposer.js +140 -6
  220. package/examples/jsm/postprocessing/FXAAPass.js +40 -0
  221. package/examples/jsm/postprocessing/FilmPass.js +54 -5
  222. package/examples/jsm/postprocessing/GTAOPass.js +202 -57
  223. package/examples/jsm/postprocessing/GlitchPass.js +86 -34
  224. package/examples/jsm/postprocessing/HalftonePass.js +65 -10
  225. package/examples/jsm/postprocessing/LUTPass.js +38 -8
  226. package/examples/jsm/postprocessing/MaskPass.js +91 -0
  227. package/examples/jsm/postprocessing/OutlinePass.js +272 -135
  228. package/examples/jsm/postprocessing/OutputPass.js +65 -14
  229. package/examples/jsm/postprocessing/Pass.js +100 -4
  230. package/examples/jsm/postprocessing/RenderPass.js +94 -0
  231. package/examples/jsm/postprocessing/RenderPixelatedPass.js +124 -45
  232. package/examples/jsm/postprocessing/RenderTransitionPass.js +120 -21
  233. package/examples/jsm/postprocessing/SAOPass.js +128 -55
  234. package/examples/jsm/postprocessing/SMAAPass.js +106 -75
  235. package/examples/jsm/postprocessing/SSAARenderPass.js +118 -35
  236. package/examples/jsm/postprocessing/SSAOPass.js +173 -60
  237. package/examples/jsm/postprocessing/SSRPass.js +268 -53
  238. package/examples/jsm/postprocessing/SavePass.js +69 -16
  239. package/examples/jsm/postprocessing/ShaderPass.js +65 -7
  240. package/examples/jsm/postprocessing/TAARenderPass.js +79 -24
  241. package/examples/jsm/postprocessing/TexturePass.js +72 -8
  242. package/examples/jsm/postprocessing/UnrealBloomPass.js +168 -59
  243. package/examples/jsm/renderers/CSS2DRenderer.js +98 -5
  244. package/examples/jsm/renderers/CSS3DRenderer.js +111 -7
  245. package/examples/jsm/renderers/Projector.js +288 -32
  246. package/examples/jsm/renderers/SVGRenderer.js +323 -61
  247. package/examples/jsm/renderers/webgl-legacy/nodes/GLSL1NodeBuilder.js +3 -1
  248. package/examples/jsm/renderers/webgl-legacy/nodes/SlotNode.js +1 -1
  249. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodeBuilder.js +5 -1
  250. package/examples/jsm/shaders/ACESFilmicToneMappingShader.js +12 -5
  251. package/examples/jsm/shaders/AfterimageShader.js +8 -3
  252. package/examples/jsm/shaders/BasicShader.js +8 -1
  253. package/examples/jsm/shaders/BleachBypassShader.js +10 -3
  254. package/examples/jsm/shaders/BlendShader.js +8 -1
  255. package/examples/jsm/shaders/BokehShader.js +9 -3
  256. package/examples/jsm/shaders/BokehShader2.js +11 -4
  257. package/examples/jsm/shaders/BrightnessContrastShader.js +10 -4
  258. package/examples/jsm/shaders/ColorCorrectionShader.js +8 -1
  259. package/examples/jsm/shaders/ColorifyShader.js +8 -1
  260. package/examples/jsm/shaders/ConvolutionShader.js +9 -38
  261. package/examples/jsm/shaders/CopyShader.js +8 -1
  262. package/examples/jsm/shaders/DOFMipMapShader.js +10 -3
  263. package/examples/jsm/shaders/DepthLimitedBlurShader.js +10 -1
  264. package/examples/jsm/shaders/DigitalGlitch.js +10 -7
  265. package/examples/jsm/shaders/DotScreenShader.js +8 -3
  266. package/examples/jsm/shaders/ExposureShader.js +8 -1
  267. package/examples/jsm/shaders/FXAAShader.js +233 -221
  268. package/examples/jsm/shaders/FilmShader.js +13 -0
  269. package/examples/jsm/shaders/FocusShader.js +8 -3
  270. package/examples/jsm/shaders/FreiChenShader.js +10 -3
  271. package/examples/jsm/shaders/GTAOShader.js +55 -45
  272. package/examples/jsm/shaders/GammaCorrectionShader.js +11 -2
  273. package/examples/jsm/shaders/HalftoneShader.js +24 -4
  274. package/examples/jsm/shaders/HorizontalBlurShader.js +12 -3
  275. package/examples/jsm/shaders/HorizontalTiltShiftShader.js +9 -2
  276. package/examples/jsm/shaders/HueSaturationShader.js +10 -3
  277. package/examples/jsm/shaders/KaleidoShader.js +11 -4
  278. package/examples/jsm/shaders/LuminosityHighPassShader.js +8 -4
  279. package/examples/jsm/shaders/LuminosityShader.js +8 -2
  280. package/examples/jsm/shaders/MirrorShader.js +10 -4
  281. package/examples/jsm/shaders/NormalMapShader.js +7 -2
  282. package/examples/jsm/shaders/OutputShader.js +19 -1
  283. package/examples/jsm/shaders/PoissonDenoiseShader.js +30 -17
  284. package/examples/jsm/shaders/RGBShiftShader.js +8 -1
  285. package/examples/jsm/shaders/SAOShader.js +27 -5
  286. package/examples/jsm/shaders/SMAAShader.js +24 -1
  287. package/examples/jsm/shaders/SSAOShader.js +37 -6
  288. package/examples/jsm/shaders/SSRShader.js +32 -6
  289. package/examples/jsm/shaders/SepiaShader.js +8 -3
  290. package/examples/jsm/shaders/SobelOperatorShader.js +9 -3
  291. package/examples/jsm/shaders/SubsurfaceScatteringShader.js +13 -8
  292. package/examples/jsm/shaders/TechnicolorShader.js +10 -4
  293. package/examples/jsm/shaders/ToonShader.js +29 -6
  294. package/examples/jsm/shaders/TriangleBlurShader.js +9 -4
  295. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +19 -6
  296. package/examples/jsm/shaders/VelocityShader.js +8 -1
  297. package/examples/jsm/shaders/VerticalBlurShader.js +9 -2
  298. package/examples/jsm/shaders/VerticalTiltShiftShader.js +8 -1
  299. package/examples/jsm/shaders/VignetteShader.js +8 -3
  300. package/examples/jsm/shaders/VolumeShader.js +11 -2
  301. package/examples/jsm/shaders/WaterRefractionShader.js +11 -0
  302. package/examples/jsm/textures/FlakesTexture.js +14 -0
  303. package/examples/jsm/transpiler/AST.js +436 -31
  304. package/examples/jsm/transpiler/GLSLDecoder.js +380 -135
  305. package/examples/jsm/transpiler/Linker.js +327 -0
  306. package/examples/jsm/transpiler/ShaderToyDecoder.js +3 -1
  307. package/examples/jsm/transpiler/TSLEncoder.js +363 -97
  308. package/examples/jsm/transpiler/Transpiler.js +50 -1
  309. package/examples/jsm/transpiler/TranspilerUtils.js +29 -0
  310. package/examples/jsm/transpiler/WGSLEncoder.js +839 -0
  311. package/examples/jsm/tsl/display/AfterImageNode.js +244 -0
  312. package/examples/jsm/tsl/display/AnaglyphPassNode.js +549 -0
  313. package/examples/jsm/tsl/display/AnamorphicNode.js +282 -0
  314. package/examples/jsm/tsl/display/BilateralBlurNode.js +364 -0
  315. package/{src/nodes → examples/jsm/tsl}/display/BleachBypass.js +11 -4
  316. package/examples/jsm/tsl/display/BloomNode.js +534 -0
  317. package/examples/jsm/tsl/display/CRT.js +150 -0
  318. package/examples/jsm/tsl/display/ChromaticAberrationNode.js +207 -0
  319. package/examples/jsm/tsl/display/DenoiseNode.js +334 -0
  320. package/examples/jsm/tsl/display/DepthOfFieldNode.js +554 -0
  321. package/examples/jsm/tsl/display/DotScreenNode.js +104 -0
  322. package/examples/jsm/tsl/display/FXAANode.js +365 -0
  323. package/examples/jsm/tsl/display/FilmNode.js +101 -0
  324. package/examples/jsm/tsl/display/GTAONode.js +571 -0
  325. package/examples/jsm/tsl/display/GaussianBlurNode.js +389 -0
  326. package/examples/jsm/tsl/display/GodraysNode.js +624 -0
  327. package/examples/jsm/tsl/display/LensflareNode.js +279 -0
  328. package/examples/jsm/tsl/display/Lut3DNode.js +109 -0
  329. package/examples/jsm/tsl/display/MotionBlur.js +33 -0
  330. package/examples/jsm/tsl/display/OutlineNode.js +762 -0
  331. package/examples/jsm/tsl/display/ParallaxBarrierPassNode.js +89 -0
  332. package/examples/jsm/tsl/display/PixelationPassNode.js +335 -0
  333. package/examples/jsm/tsl/display/RGBShiftNode.js +96 -0
  334. package/examples/jsm/tsl/display/RetroPassNode.js +263 -0
  335. package/examples/jsm/tsl/display/SMAANode.js +768 -0
  336. package/{src/nodes → examples/jsm/tsl}/display/SSAAPassNode.js +120 -49
  337. package/examples/jsm/tsl/display/SSGINode.js +642 -0
  338. package/examples/jsm/tsl/display/SSRNode.js +656 -0
  339. package/examples/jsm/tsl/display/SSSNode.js +490 -0
  340. package/{src/nodes → examples/jsm/tsl}/display/Sepia.js +9 -2
  341. package/examples/jsm/tsl/display/Shape.js +29 -0
  342. package/{src/nodes → examples/jsm/tsl}/display/SobelOperatorNode.js +61 -19
  343. package/examples/jsm/tsl/display/StereoCompositePassNode.js +192 -0
  344. package/{src/nodes → examples/jsm/tsl}/display/StereoPassNode.js +48 -12
  345. package/examples/jsm/tsl/display/TRAANode.js +726 -0
  346. package/examples/jsm/tsl/display/TransitionNode.js +141 -0
  347. package/examples/jsm/tsl/display/boxBlur.js +65 -0
  348. package/examples/jsm/tsl/display/depthAwareBlend.js +80 -0
  349. package/examples/jsm/tsl/display/hashBlur.js +54 -0
  350. package/examples/jsm/tsl/display/radialBlur.js +68 -0
  351. package/examples/jsm/tsl/lighting/TiledLightsNode.js +442 -0
  352. package/examples/jsm/tsl/math/Bayer.js +73 -0
  353. package/examples/jsm/tsl/shadows/TileShadowNode.js +456 -0
  354. package/examples/jsm/tsl/shadows/TileShadowNodeHelper.js +212 -0
  355. package/examples/jsm/tsl/utils/Raymarching.js +70 -0
  356. package/examples/jsm/utils/BufferGeometryUtils.js +91 -29
  357. package/examples/jsm/utils/CameraUtils.js +15 -6
  358. package/examples/jsm/utils/GeometryCompressionUtils.js +23 -30
  359. package/examples/jsm/utils/GeometryUtils.js +32 -27
  360. package/examples/jsm/utils/LDrawUtils.js +14 -5
  361. package/examples/jsm/utils/SceneOptimizer.js +458 -0
  362. package/examples/jsm/utils/SceneUtils.js +53 -3
  363. package/examples/jsm/utils/ShadowMapViewer.js +72 -33
  364. package/examples/jsm/utils/ShadowMapViewerGPU.js +61 -29
  365. package/examples/jsm/utils/SkeletonUtils.js +48 -0
  366. package/examples/jsm/utils/SortUtils.js +17 -5
  367. package/examples/jsm/utils/UVsDebug.js +12 -4
  368. package/examples/jsm/utils/{TextureUtils.js → WebGLTextureUtils.js} +16 -0
  369. package/examples/jsm/utils/{TextureUtilsGPU.js → WebGPUTextureUtils.js} +20 -2
  370. package/examples/jsm/utils/WorkerPool.js +67 -2
  371. package/examples/jsm/webxr/ARButton.js +19 -0
  372. package/examples/jsm/webxr/OculusHandModel.js +84 -0
  373. package/examples/jsm/webxr/OculusHandPointerModel.js +148 -22
  374. package/examples/jsm/webxr/Text2D.js +20 -6
  375. package/examples/jsm/webxr/VRButton.js +31 -0
  376. package/examples/jsm/webxr/XRButton.js +23 -0
  377. package/examples/jsm/webxr/XRControllerModelFactory.js +94 -3
  378. package/examples/jsm/webxr/XREstimatedLight.js +35 -4
  379. package/examples/jsm/webxr/XRHandMeshModel.js +37 -0
  380. package/examples/jsm/webxr/XRHandModelFactory.js +96 -6
  381. package/examples/jsm/webxr/XRHandPrimitiveModel.js +44 -0
  382. package/examples/jsm/webxr/XRPlanes.js +18 -0
  383. package/package.json +29 -37
  384. package/src/Three.Core.js +198 -0
  385. package/src/Three.Legacy.js +0 -21
  386. package/src/Three.TSL.js +641 -0
  387. package/src/Three.WebGPU.Nodes.js +14 -186
  388. package/src/Three.WebGPU.js +16 -186
  389. package/src/Three.js +2 -197
  390. package/src/animation/AnimationAction.js +263 -31
  391. package/src/animation/AnimationClip.js +162 -7
  392. package/src/animation/AnimationMixer.js +105 -15
  393. package/src/animation/AnimationObjectGroup.js +45 -21
  394. package/src/animation/AnimationUtils.js +163 -24
  395. package/src/animation/KeyframeTrack.js +191 -17
  396. package/src/animation/PropertyBinding.js +91 -16
  397. package/src/animation/PropertyMixer.js +72 -5
  398. package/src/animation/tracks/BooleanKeyframeTrack.js +33 -6
  399. package/src/animation/tracks/ColorKeyframeTrack.js +26 -5
  400. package/src/animation/tracks/NumberKeyframeTrack.js +26 -2
  401. package/src/animation/tracks/QuaternionKeyframeTrack.js +30 -1
  402. package/src/animation/tracks/StringKeyframeTrack.js +33 -2
  403. package/src/animation/tracks/VectorKeyframeTrack.js +26 -2
  404. package/src/audio/Audio.js +386 -8
  405. package/src/audio/AudioAnalyser.js +58 -1
  406. package/src/audio/AudioContext.js +15 -0
  407. package/src/audio/AudioListener.js +94 -13
  408. package/src/audio/PositionalAudio.js +107 -0
  409. package/src/cameras/ArrayCamera.js +37 -0
  410. package/src/cameras/Camera.js +61 -0
  411. package/src/cameras/CubeCamera.js +86 -0
  412. package/src/cameras/OrthographicCamera.js +110 -1
  413. package/src/cameras/PerspectiveCamera.js +174 -35
  414. package/src/cameras/StereoCamera.js +48 -2
  415. package/src/constants.js +1546 -11
  416. package/src/core/BufferAttribute.js +417 -3
  417. package/src/core/BufferGeometry.js +407 -22
  418. package/src/core/Clock.js +69 -8
  419. package/src/core/EventDispatcher.js +52 -8
  420. package/src/core/GLBufferAttribute.js +113 -2
  421. package/src/core/InstancedBufferAttribute.js +29 -0
  422. package/src/core/InstancedBufferGeometry.js +20 -0
  423. package/src/core/InstancedInterleavedBuffer.js +26 -0
  424. package/src/core/InterleavedBuffer.js +141 -7
  425. package/src/core/InterleavedBufferAttribute.js +200 -2
  426. package/src/core/Layers.js +71 -10
  427. package/src/core/Object3D.js +673 -26
  428. package/src/core/Raycaster.js +136 -2
  429. package/src/core/RenderTarget.js +256 -27
  430. package/src/core/RenderTarget3D.js +48 -0
  431. package/src/core/Timer.js +184 -0
  432. package/src/core/Uniform.js +29 -0
  433. package/src/core/UniformsGroup.js +84 -2
  434. package/src/extras/Controls.js +89 -1
  435. package/src/extras/DataUtils.js +50 -9
  436. package/src/extras/Earcut.js +18 -779
  437. package/src/extras/ImageUtils.js +22 -14
  438. package/src/extras/PMREMGenerator.js +316 -67
  439. package/src/extras/ShapeUtils.js +24 -2
  440. package/src/extras/TextureUtils.js +101 -15
  441. package/src/extras/core/Curve.js +156 -55
  442. package/src/extras/core/CurvePath.js +63 -22
  443. package/src/extras/core/Interpolations.js +34 -2
  444. package/src/extras/core/Path.js +134 -1
  445. package/src/extras/core/Shape.js +66 -3
  446. package/src/extras/core/ShapePath.js +80 -4
  447. package/src/extras/curves/ArcCurve.js +22 -0
  448. package/src/extras/curves/CatmullRomCurve3.js +89 -18
  449. package/src/extras/curves/CubicBezierCurve.js +67 -0
  450. package/src/extras/curves/CubicBezierCurve3.js +50 -0
  451. package/src/extras/curves/EllipseCurve.js +102 -0
  452. package/src/extras/curves/LineCurve.js +36 -0
  453. package/src/extras/curves/LineCurve3.js +36 -0
  454. package/src/extras/curves/QuadraticBezierCurve.js +59 -0
  455. package/src/extras/curves/QuadraticBezierCurve3.js +43 -0
  456. package/src/extras/curves/SplineCurve.js +48 -0
  457. package/src/extras/lib/earcut.js +685 -0
  458. package/src/geometries/BoxGeometry.js +39 -0
  459. package/src/geometries/CapsuleGeometry.js +196 -11
  460. package/src/geometries/CircleGeometry.js +41 -0
  461. package/src/geometries/ConeGeometry.js +39 -0
  462. package/src/geometries/CylinderGeometry.js +42 -2
  463. package/src/geometries/DodecahedronGeometry.js +33 -0
  464. package/src/geometries/EdgesGeometry.js +30 -2
  465. package/src/geometries/ExtrudeGeometry.js +148 -52
  466. package/src/geometries/IcosahedronGeometry.js +33 -0
  467. package/src/geometries/LatheGeometry.js +44 -3
  468. package/src/geometries/OctahedronGeometry.js +33 -0
  469. package/src/geometries/PlaneGeometry.js +35 -0
  470. package/src/geometries/PolyhedronGeometry.js +30 -1
  471. package/src/geometries/RingGeometry.js +37 -0
  472. package/src/geometries/ShapeGeometry.js +38 -0
  473. package/src/geometries/SphereGeometry.js +38 -0
  474. package/src/geometries/TetrahedronGeometry.js +33 -0
  475. package/src/geometries/TorusGeometry.js +44 -3
  476. package/src/geometries/TorusKnotGeometry.js +39 -0
  477. package/src/geometries/TubeGeometry.js +50 -0
  478. package/src/geometries/WireframeGeometry.js +32 -0
  479. package/src/helpers/ArrowHelper.js +62 -5
  480. package/src/helpers/AxesHelper.js +28 -0
  481. package/src/helpers/Box3Helper.js +28 -0
  482. package/src/helpers/BoxHelper.js +43 -7
  483. package/src/helpers/CameraHelper.js +103 -27
  484. package/src/helpers/DirectionalLightHelper.js +55 -0
  485. package/src/helpers/GridHelper.js +26 -0
  486. package/src/helpers/HemisphereLightHelper.js +42 -0
  487. package/src/helpers/PlaneHelper.js +33 -0
  488. package/src/helpers/PointLightHelper.js +43 -24
  489. package/src/helpers/PolarGridHelper.js +30 -0
  490. package/src/helpers/SkeletonHelper.js +73 -7
  491. package/src/helpers/SpotLightHelper.js +43 -0
  492. package/src/lights/AmbientLight.js +25 -0
  493. package/src/lights/DirectionalLight.js +70 -0
  494. package/src/lights/DirectionalLightShadow.js +15 -0
  495. package/src/lights/HemisphereLight.js +42 -0
  496. package/src/lights/Light.js +37 -11
  497. package/src/lights/LightProbe.js +37 -9
  498. package/src/lights/LightShadow.js +202 -7
  499. package/src/lights/PointLight.js +74 -0
  500. package/src/lights/PointLightShadow.js +15 -80
  501. package/src/lights/RectAreaLight.js +59 -0
  502. package/src/lights/SpotLight.js +124 -1
  503. package/src/lights/SpotLightShadow.js +33 -3
  504. package/src/lights/webgpu/IESSpotLight.js +22 -0
  505. package/src/lights/webgpu/ProjectorLight.js +46 -0
  506. package/src/loaders/AnimationLoader.js +34 -2
  507. package/src/loaders/AudioLoader.js +34 -2
  508. package/src/loaders/BufferGeometryLoader.js +38 -13
  509. package/src/loaders/Cache.js +75 -2
  510. package/src/loaders/CompressedTextureLoader.js +36 -3
  511. package/src/loaders/CubeTextureLoader.js +45 -0
  512. package/src/loaders/DataTextureLoader.js +45 -4
  513. package/src/loaders/FileLoader.js +85 -5
  514. package/src/loaders/ImageBitmapLoader.js +113 -11
  515. package/src/loaders/ImageLoader.js +85 -8
  516. package/src/loaders/Loader.js +150 -0
  517. package/src/loaders/LoaderUtils.js +18 -36
  518. package/src/loaders/LoadingManager.js +187 -0
  519. package/src/loaders/MaterialLoader.js +62 -3
  520. package/src/loaders/ObjectLoader.js +131 -31
  521. package/src/loaders/TextureLoader.js +33 -0
  522. package/src/loaders/nodes/NodeLoader.js +68 -4
  523. package/src/loaders/nodes/NodeMaterialLoader.js +45 -0
  524. package/src/loaders/nodes/NodeObjectLoader.js +61 -0
  525. package/src/materials/LineBasicMaterial.js +74 -1
  526. package/src/materials/LineDashedMaterial.js +52 -1
  527. package/src/materials/Material.js +502 -8
  528. package/src/materials/MeshBasicMaterial.js +168 -2
  529. package/src/materials/MeshDepthMaterial.js +94 -0
  530. package/src/materials/MeshDistanceMaterial.js +76 -0
  531. package/src/materials/MeshLambertMaterial.js +283 -0
  532. package/src/materials/MeshMatcapMaterial.js +164 -0
  533. package/src/materials/MeshNormalMaterial.js +114 -0
  534. package/src/materials/MeshPhongMaterial.js +298 -0
  535. package/src/materials/MeshPhysicalMaterial.js +296 -4
  536. package/src/materials/MeshStandardMaterial.js +300 -2
  537. package/src/materials/MeshToonMaterial.js +219 -0
  538. package/src/materials/PointsMaterial.js +89 -0
  539. package/src/materials/RawShaderMaterial.js +25 -0
  540. package/src/materials/ShaderMaterial.js +234 -6
  541. package/src/materials/ShadowMaterial.js +54 -0
  542. package/src/materials/SpriteMaterial.js +82 -0
  543. package/src/materials/nodes/Line2NodeMaterial.js +158 -53
  544. package/src/materials/nodes/LineBasicNodeMaterial.js +17 -2
  545. package/src/materials/nodes/LineDashedNodeMaterial.js +81 -6
  546. package/src/materials/nodes/MeshBasicNodeMaterial.js +59 -2
  547. package/src/materials/nodes/MeshLambertNodeMaterial.js +35 -0
  548. package/src/materials/nodes/MeshMatcapNodeMaterial.js +23 -3
  549. package/src/materials/nodes/MeshNormalNodeMaterial.js +27 -4
  550. package/src/materials/nodes/MeshPhongNodeMaterial.js +64 -1
  551. package/src/materials/nodes/MeshPhysicalNodeMaterial.js +276 -3
  552. package/src/materials/nodes/MeshSSSNodeMaterial.js +98 -10
  553. package/src/materials/nodes/MeshStandardNodeMaterial.js +83 -4
  554. package/src/materials/nodes/MeshToonNodeMaterial.js +28 -0
  555. package/src/materials/nodes/NodeMaterial.js +789 -74
  556. package/src/materials/nodes/NodeMaterials.js +0 -1
  557. package/src/materials/nodes/PointsNodeMaterial.js +180 -11
  558. package/src/materials/nodes/ShadowNodeMaterial.js +38 -0
  559. package/src/materials/nodes/SpriteNodeMaterial.js +86 -23
  560. package/src/materials/nodes/VolumeNodeMaterial.js +57 -84
  561. package/src/materials/nodes/manager/NodeMaterialObserver.js +329 -12
  562. package/src/math/Box2.js +177 -0
  563. package/src/math/Box3.js +271 -0
  564. package/src/math/Color.js +355 -11
  565. package/src/math/ColorManagement.js +158 -92
  566. package/src/math/Cylindrical.js +65 -6
  567. package/src/math/Euler.js +139 -5
  568. package/src/math/Frustum.js +108 -9
  569. package/src/math/FrustumArray.js +258 -0
  570. package/src/math/Interpolant.js +87 -8
  571. package/src/math/Line3.js +221 -2
  572. package/src/math/MathUtils.js +408 -20
  573. package/src/math/Matrix2.js +70 -0
  574. package/src/math/Matrix3.js +229 -4
  575. package/src/math/Matrix4.js +489 -94
  576. package/src/math/Plane.js +164 -2
  577. package/src/math/Quaternion.js +322 -90
  578. package/src/math/Ray.js +162 -0
  579. package/src/math/Sphere.js +175 -0
  580. package/src/math/Spherical.js +73 -11
  581. package/src/math/SphericalHarmonics3.js +112 -14
  582. package/src/math/Triangle.js +206 -2
  583. package/src/math/Vector2.js +396 -10
  584. package/src/math/Vector3.js +550 -15
  585. package/src/math/Vector4.js +415 -9
  586. package/src/math/interpolants/BezierInterpolant.js +108 -0
  587. package/src/math/interpolants/CubicInterpolant.js +10 -1
  588. package/src/math/interpolants/DiscreteInterpolant.js +10 -2
  589. package/src/math/interpolants/LinearInterpolant.js +13 -0
  590. package/src/math/interpolants/QuaternionLinearInterpolant.js +10 -1
  591. package/src/nodes/Nodes.js +91 -88
  592. package/src/nodes/TSL.js +32 -38
  593. package/src/nodes/accessors/AccessorsUtils.js +37 -9
  594. package/src/nodes/accessors/Arrays.js +68 -0
  595. package/src/nodes/accessors/BatchNode.js +49 -14
  596. package/src/nodes/accessors/Bitangent.js +82 -13
  597. package/src/nodes/accessors/BufferAttributeNode.js +269 -8
  598. package/src/nodes/accessors/BufferNode.js +91 -2
  599. package/src/nodes/accessors/BuiltinNode.js +63 -0
  600. package/src/nodes/accessors/Camera.js +400 -10
  601. package/src/nodes/accessors/ClippingNode.js +149 -45
  602. package/src/nodes/accessors/CubeTextureNode.js +137 -7
  603. package/src/nodes/accessors/InstanceNode.js +245 -40
  604. package/src/nodes/accessors/InstancedMeshNode.js +50 -0
  605. package/src/nodes/accessors/Lights.js +88 -0
  606. package/src/nodes/accessors/MaterialNode.js +355 -13
  607. package/src/nodes/accessors/MaterialProperties.js +57 -1
  608. package/src/nodes/accessors/MaterialReferenceNode.js +52 -14
  609. package/src/nodes/accessors/ModelNode.js +117 -5
  610. package/src/nodes/accessors/ModelViewProjectionNode.js +10 -39
  611. package/src/nodes/accessors/MorphNode.js +73 -26
  612. package/src/nodes/accessors/Normal.js +174 -19
  613. package/src/nodes/accessors/Object3DNode.js +146 -12
  614. package/src/nodes/accessors/PointUVNode.js +25 -0
  615. package/src/nodes/accessors/Position.js +119 -7
  616. package/src/nodes/accessors/ReferenceBaseNode.js +190 -4
  617. package/src/nodes/accessors/ReferenceNode.js +223 -8
  618. package/src/nodes/accessors/ReflectVector.js +29 -3
  619. package/src/nodes/accessors/RendererReferenceNode.js +45 -2
  620. package/src/nodes/accessors/SceneProperties.js +53 -0
  621. package/src/nodes/accessors/SkinningNode.js +180 -43
  622. package/src/nodes/accessors/StorageBufferNode.js +278 -26
  623. package/src/nodes/accessors/StorageTextureNode.js +205 -12
  624. package/src/nodes/accessors/Tangent.js +48 -10
  625. package/src/nodes/accessors/TangentUtils.js +46 -0
  626. package/src/nodes/accessors/Texture3DNode.js +104 -11
  627. package/src/nodes/accessors/TextureBicubic.js +31 -4
  628. package/src/nodes/accessors/TextureNode.js +564 -52
  629. package/src/nodes/accessors/TextureSizeNode.js +42 -1
  630. package/src/nodes/accessors/UV.js +9 -1
  631. package/src/nodes/accessors/UniformArrayNode.js +226 -34
  632. package/src/nodes/accessors/UserDataNode.js +46 -2
  633. package/src/nodes/accessors/VelocityNode.js +93 -3
  634. package/src/nodes/accessors/VertexColorNode.js +39 -4
  635. package/src/nodes/code/CodeNode.js +101 -8
  636. package/src/nodes/code/ExpressionNode.js +29 -2
  637. package/src/nodes/code/FunctionCallNode.js +98 -10
  638. package/src/nodes/code/FunctionNode.js +69 -2
  639. package/src/nodes/core/ArrayNode.js +174 -0
  640. package/src/nodes/core/AssignNode.js +80 -9
  641. package/src/nodes/core/AttributeNode.js +47 -4
  642. package/src/nodes/core/BypassNode.js +47 -3
  643. package/src/nodes/core/ConstNode.js +32 -0
  644. package/src/nodes/core/ContextNode.js +220 -14
  645. package/src/nodes/core/IndexNode.js +72 -7
  646. package/src/nodes/core/InputNode.js +50 -1
  647. package/src/nodes/core/InspectorNode.js +128 -0
  648. package/src/nodes/core/IsolateNode.js +133 -0
  649. package/src/nodes/core/LightingModel.js +65 -5
  650. package/src/nodes/core/MRTNode.js +113 -2
  651. package/src/nodes/core/Node.js +595 -36
  652. package/src/nodes/core/NodeAttribute.js +38 -0
  653. package/src/nodes/core/NodeBuilder.js +1840 -121
  654. package/src/nodes/core/NodeCache.js +41 -2
  655. package/src/nodes/core/NodeCode.js +31 -0
  656. package/src/nodes/core/NodeError.js +28 -0
  657. package/src/nodes/core/NodeFrame.js +153 -24
  658. package/src/nodes/core/NodeFunction.js +48 -1
  659. package/src/nodes/core/NodeFunctionInput.js +44 -0
  660. package/src/nodes/core/NodeParser.js +13 -1
  661. package/src/nodes/core/NodeUniform.js +53 -1
  662. package/src/nodes/core/NodeUtils.js +201 -51
  663. package/src/nodes/core/NodeVar.js +47 -1
  664. package/src/nodes/core/NodeVarying.js +47 -1
  665. package/src/nodes/core/OutputStructNode.js +54 -12
  666. package/src/nodes/core/ParameterNode.js +60 -2
  667. package/src/nodes/core/PropertyNode.js +286 -7
  668. package/src/nodes/core/StackNode.js +337 -20
  669. package/src/nodes/core/StackTrace.js +139 -0
  670. package/src/nodes/core/StructNode.js +134 -0
  671. package/src/nodes/core/StructType.js +13 -0
  672. package/src/nodes/core/StructTypeNode.js +126 -6
  673. package/src/nodes/core/SubBuildNode.js +89 -0
  674. package/src/nodes/core/TempNode.js +31 -5
  675. package/src/nodes/core/UniformGroupNode.js +85 -7
  676. package/src/nodes/core/UniformNode.js +163 -16
  677. package/src/nodes/core/VarNode.js +317 -10
  678. package/src/nodes/core/VaryingNode.js +115 -13
  679. package/src/nodes/core/constants.js +40 -0
  680. package/src/nodes/display/BlendModes.js +171 -0
  681. package/src/nodes/display/BumpMapNode.js +38 -2
  682. package/src/nodes/display/ColorAdjustment.js +118 -6
  683. package/src/nodes/display/ColorSpaceFunctions.js +22 -6
  684. package/src/nodes/display/ColorSpaceNode.js +97 -47
  685. package/src/nodes/display/FrontFacingNode.js +64 -7
  686. package/src/nodes/display/NormalMapNode.js +101 -54
  687. package/src/nodes/display/PassNode.js +690 -33
  688. package/src/nodes/display/RenderOutputNode.js +94 -4
  689. package/src/nodes/display/ScreenNode.js +138 -27
  690. package/src/nodes/display/ToneMappingFunctions.js +62 -10
  691. package/src/nodes/display/ToneMappingNode.js +88 -8
  692. package/src/nodes/display/ToonOutlinePassNode.js +84 -4
  693. package/src/nodes/display/ViewportDepthNode.js +227 -10
  694. package/src/nodes/display/ViewportDepthTextureNode.js +39 -5
  695. package/src/nodes/display/ViewportSharedTextureNode.js +35 -1
  696. package/src/nodes/display/ViewportTextureNode.js +171 -7
  697. package/src/nodes/fog/Fog.js +97 -0
  698. package/src/nodes/functions/BSDF/BRDF_GGX.js +2 -6
  699. package/src/nodes/functions/BSDF/BRDF_GGX_Multiscatter.js +52 -0
  700. package/src/nodes/functions/BSDF/BRDF_Sheen.js +4 -4
  701. package/src/nodes/functions/BSDF/DFGLUT.js +56 -0
  702. package/src/nodes/functions/BSDF/EnvironmentBRDF.js +2 -2
  703. package/src/nodes/functions/BSDF/LTC.js +45 -1
  704. package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +1 -1
  705. package/src/nodes/functions/BasicLightingModel.js +28 -6
  706. package/src/nodes/functions/PhongLightingModel.js +36 -6
  707. package/src/nodes/functions/PhysicalLightingModel.js +336 -91
  708. package/src/nodes/functions/ShadowMaskModel.js +30 -3
  709. package/src/nodes/functions/ToonLightingModel.js +21 -2
  710. package/src/nodes/functions/VolumetricLightingModel.js +183 -0
  711. package/src/nodes/functions/material/getAlphaHashThreshold.js +68 -0
  712. package/src/nodes/functions/material/getGeometryRoughness.js +10 -4
  713. package/src/nodes/functions/material/getParallaxCorrectNormal.js +37 -0
  714. package/src/nodes/geometry/RangeNode.js +97 -8
  715. package/src/nodes/gpgpu/AtomicFunctionNode.js +198 -23
  716. package/src/nodes/gpgpu/BarrierNode.js +52 -3
  717. package/src/nodes/gpgpu/ComputeBuiltinNode.js +135 -6
  718. package/src/nodes/gpgpu/ComputeNode.js +212 -16
  719. package/src/nodes/gpgpu/SubgroupFunctionNode.js +455 -0
  720. package/src/nodes/gpgpu/WorkgroupInfoNode.js +143 -9
  721. package/src/nodes/lighting/AONode.js +18 -0
  722. package/src/nodes/lighting/AmbientLightNode.js +10 -0
  723. package/src/nodes/lighting/AnalyticLightNode.js +186 -399
  724. package/src/nodes/lighting/BasicEnvironmentNode.js +19 -0
  725. package/src/nodes/lighting/BasicLightMapNode.js +17 -0
  726. package/src/nodes/lighting/DirectionalLightNode.js +12 -11
  727. package/src/nodes/lighting/EnvironmentNode.js +59 -19
  728. package/src/nodes/lighting/HemisphereLightNode.js +33 -2
  729. package/src/nodes/lighting/IESSpotLightNode.js +13 -1
  730. package/src/nodes/lighting/IrradianceNode.js +17 -0
  731. package/src/nodes/lighting/LightProbeNode.js +20 -0
  732. package/src/nodes/lighting/LightUtils.js +11 -3
  733. package/src/nodes/lighting/LightingContextNode.js +52 -4
  734. package/src/nodes/lighting/LightingNode.js +15 -6
  735. package/src/nodes/lighting/LightsNode.js +238 -35
  736. package/src/nodes/lighting/PointLightNode.js +60 -25
  737. package/src/nodes/lighting/PointShadowNode.js +325 -0
  738. package/src/nodes/lighting/ProjectorLightNode.js +91 -0
  739. package/src/nodes/lighting/RectAreaLightNode.js +50 -14
  740. package/src/nodes/lighting/ShadowBaseNode.js +81 -0
  741. package/src/nodes/lighting/ShadowFilterNode.js +264 -0
  742. package/src/nodes/lighting/ShadowNode.js +867 -0
  743. package/src/nodes/lighting/SpotLightNode.js +99 -18
  744. package/src/nodes/materialx/MaterialXNodes.js +131 -2
  745. package/src/nodes/materialx/lib/mx_noise.js +166 -2
  746. package/src/nodes/math/BitcastNode.js +156 -0
  747. package/src/nodes/math/BitcountNode.js +433 -0
  748. package/src/nodes/math/ConditionalNode.js +110 -21
  749. package/src/nodes/math/Hash.js +8 -0
  750. package/src/nodes/math/MathNode.js +820 -97
  751. package/src/nodes/math/MathUtils.js +47 -1
  752. package/src/nodes/math/OperatorNode.js +517 -84
  753. package/src/nodes/math/PackFloatNode.js +98 -0
  754. package/src/nodes/math/TriNoise3D.js +17 -7
  755. package/src/nodes/math/UnpackFloatNode.js +96 -0
  756. package/src/nodes/parsers/GLSLNodeFunction.js +16 -0
  757. package/src/nodes/parsers/GLSLNodeParser.js +11 -0
  758. package/src/nodes/pmrem/PMREMNode.js +180 -23
  759. package/src/nodes/pmrem/PMREMUtils.js +114 -5
  760. package/src/nodes/procedural/Checker.js +8 -0
  761. package/src/nodes/shapes/Shapes.js +33 -0
  762. package/src/nodes/tsl/TSLBase.js +10 -4
  763. package/src/nodes/tsl/TSLCore.js +732 -160
  764. package/src/nodes/utils/ArrayElementNode.js +55 -4
  765. package/src/nodes/utils/ConvertNode.js +31 -0
  766. package/src/nodes/utils/CubeMapNode.js +79 -2
  767. package/src/nodes/utils/DebugNode.js +83 -0
  768. package/src/nodes/utils/Discard.js +18 -2
  769. package/src/nodes/utils/EquirectUV.js +27 -0
  770. package/src/nodes/utils/EventNode.js +118 -0
  771. package/src/nodes/utils/FlipNode.js +38 -0
  772. package/src/nodes/utils/FunctionOverloadingNode.js +91 -22
  773. package/src/nodes/utils/JoinNode.js +57 -4
  774. package/src/nodes/utils/LoopNode.js +193 -55
  775. package/src/nodes/utils/MatcapUV.js +22 -0
  776. package/src/nodes/utils/MaxMipLevelNode.js +49 -1
  777. package/src/nodes/utils/MemberNode.js +120 -0
  778. package/src/nodes/utils/Oscillators.js +41 -0
  779. package/src/nodes/utils/Packing.js +30 -1
  780. package/src/nodes/utils/PostProcessingUtils.js +154 -0
  781. package/src/nodes/utils/RTTNode.js +165 -9
  782. package/src/nodes/utils/ReflectorNode.js +407 -21
  783. package/src/nodes/utils/RemapNode.js +81 -2
  784. package/src/nodes/utils/RotateNode.js +41 -1
  785. package/src/nodes/utils/SampleNode.js +91 -0
  786. package/src/nodes/utils/SetNode.js +44 -1
  787. package/src/nodes/utils/SplitNode.js +66 -3
  788. package/src/nodes/utils/SpriteSheetUV.js +35 -0
  789. package/src/nodes/utils/SpriteUtils.js +16 -0
  790. package/src/nodes/utils/StorageArrayElementNode.js +56 -3
  791. package/src/nodes/utils/Timer.js +26 -0
  792. package/src/nodes/utils/TriplanarTextures.js +65 -0
  793. package/src/nodes/utils/UVUtils.js +48 -0
  794. package/src/nodes/utils/ViewportUtils.js +12 -0
  795. package/src/objects/BatchedMesh.js +798 -309
  796. package/src/objects/Bone.js +24 -0
  797. package/src/objects/ClippingGroup.js +68 -0
  798. package/src/objects/Group.js +24 -0
  799. package/src/objects/InstancedMesh.js +131 -2
  800. package/src/objects/LOD.js +99 -5
  801. package/src/objects/Line.js +90 -7
  802. package/src/objects/LineLoop.js +20 -0
  803. package/src/objects/LineSegments.js +20 -1
  804. package/src/objects/Mesh.js +84 -0
  805. package/src/objects/Points.js +60 -0
  806. package/src/objects/Skeleton.js +120 -5
  807. package/src/objects/SkinnedMesh.js +102 -6
  808. package/src/objects/Sprite.js +65 -1
  809. package/src/renderers/WebGL3DRenderTarget.js +26 -0
  810. package/src/renderers/WebGLArrayRenderTarget.js +26 -0
  811. package/src/renderers/WebGLCubeRenderTarget.js +41 -5
  812. package/src/renderers/WebGLRenderTarget.js +19 -0
  813. package/src/renderers/WebGLRenderer.js +1016 -278
  814. package/src/renderers/common/Animation.js +123 -14
  815. package/src/renderers/common/Attributes.js +41 -1
  816. package/src/renderers/common/Backend.js +623 -44
  817. package/src/renderers/common/Background.js +99 -16
  818. package/src/renderers/common/BindGroup.js +37 -2
  819. package/src/renderers/common/Binding.js +46 -0
  820. package/src/renderers/common/Bindings.js +211 -20
  821. package/src/renderers/common/BlendMode.js +143 -0
  822. package/src/renderers/common/Buffer.js +89 -0
  823. package/src/renderers/common/BufferUtils.js +25 -0
  824. package/src/renderers/common/BundleGroup.js +57 -0
  825. package/src/renderers/common/CanvasTarget.js +341 -0
  826. package/src/renderers/common/ChainMap.js +73 -10
  827. package/src/renderers/common/ClippingContext.js +172 -87
  828. package/src/renderers/common/Color4.js +40 -0
  829. package/src/renderers/common/ComputePipeline.js +24 -0
  830. package/src/renderers/common/Constants.js +2 -1
  831. package/src/renderers/common/CubeRenderTarget.js +77 -7
  832. package/src/renderers/common/DataMap.js +37 -1
  833. package/src/renderers/common/Geometries.js +163 -14
  834. package/src/renderers/common/IndirectStorageBufferAttribute.js +38 -0
  835. package/src/renderers/common/Info.js +81 -36
  836. package/src/renderers/common/InspectorBase.js +146 -0
  837. package/src/renderers/common/Lighting.js +57 -0
  838. package/src/renderers/common/Pipeline.js +22 -0
  839. package/src/renderers/common/Pipelines.js +150 -7
  840. package/src/renderers/common/PostProcessing.js +22 -84
  841. package/src/renderers/common/ProgrammableStage.js +60 -2
  842. package/src/renderers/common/QuadMesh.js +63 -6
  843. package/src/renderers/common/RenderBundle.js +14 -8
  844. package/src/renderers/common/RenderBundles.js +40 -10
  845. package/src/renderers/common/RenderContext.js +219 -4
  846. package/src/renderers/common/RenderContexts.js +54 -17
  847. package/src/renderers/common/RenderList.js +233 -24
  848. package/src/renderers/common/RenderLists.js +46 -6
  849. package/src/renderers/common/RenderObject.js +548 -46
  850. package/src/renderers/common/RenderObjectPipeline.js +40 -0
  851. package/src/renderers/common/RenderObjects.js +133 -15
  852. package/src/renderers/common/RenderPipeline.js +216 -6
  853. package/src/renderers/common/Renderer.js +2155 -332
  854. package/src/renderers/common/RendererUtils.js +200 -0
  855. package/src/renderers/common/SampledTexture.js +99 -39
  856. package/src/renderers/common/Sampler.js +148 -1
  857. package/src/renderers/common/Storage3DTexture.js +100 -0
  858. package/src/renderers/common/StorageArrayTexture.js +84 -0
  859. package/src/renderers/common/StorageBuffer.js +38 -2
  860. package/src/renderers/common/StorageBufferAttribute.js +31 -2
  861. package/src/renderers/common/StorageInstancedBufferAttribute.js +31 -2
  862. package/src/renderers/common/StorageTexture.js +65 -0
  863. package/src/renderers/common/Textures.js +273 -57
  864. package/src/renderers/common/TimestampQueryPool.js +163 -0
  865. package/src/renderers/common/Uniform.js +233 -3
  866. package/src/renderers/common/UniformBuffer.js +19 -0
  867. package/src/renderers/common/UniformsGroup.js +235 -26
  868. package/src/renderers/common/XRManager.js +1677 -0
  869. package/src/renderers/common/XRRenderTarget.js +91 -0
  870. package/src/renderers/common/extras/PMREMGenerator.js +371 -108
  871. package/src/renderers/common/nodes/NodeBuilderState.js +100 -6
  872. package/src/renderers/common/nodes/NodeLibrary.js +95 -17
  873. package/src/renderers/common/nodes/NodeManager.js +852 -0
  874. package/src/renderers/common/nodes/NodeSampledTexture.js +84 -8
  875. package/src/renderers/common/nodes/NodeSampler.js +41 -1
  876. package/src/renderers/common/nodes/NodeStorageBuffer.js +48 -3
  877. package/src/renderers/common/nodes/NodeUniform.js +285 -2
  878. package/src/renderers/common/nodes/NodeUniformBuffer.js +81 -0
  879. package/src/renderers/common/nodes/NodeUniformsGroup.js +31 -18
  880. package/src/renderers/shaders/DFGLUTData.js +49 -0
  881. package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +2 -2
  882. package/src/renderers/shaders/ShaderChunk/color_fragment.glsl.js +1 -5
  883. package/src/renderers/shaders/ShaderChunk/color_pars_fragment.glsl.js +1 -5
  884. package/src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl.js +1 -5
  885. package/src/renderers/shaders/ShaderChunk/color_vertex.glsl.js +8 -10
  886. package/src/renderers/shaders/ShaderChunk/colorspace_pars_fragment.glsl.js +4 -24
  887. package/src/renderers/shaders/ShaderChunk/common.glsl.js +0 -12
  888. package/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl.js +8 -0
  889. package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +1 -1
  890. package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +7 -11
  891. package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +1 -1
  892. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +5 -2
  893. package/src/renderers/shaders/ShaderChunk/lights_fragment_end.glsl.js +6 -0
  894. package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +6 -2
  895. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +8 -4
  896. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +154 -59
  897. package/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl.js +1 -1
  898. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl.js +1 -1
  899. package/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl.js +1 -1
  900. package/src/renderers/shaders/ShaderChunk/logdepthbuf_vertex.glsl.js +1 -1
  901. package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +2 -2
  902. package/src/renderers/shaders/ShaderChunk/packing.glsl.js +20 -4
  903. package/src/renderers/shaders/ShaderChunk/premultiplied_alpha_fragment.glsl.js +1 -1
  904. package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +230 -181
  905. package/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl.js +1 -1
  906. package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
  907. package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +7 -7
  908. package/src/renderers/shaders/ShaderChunk.js +3 -3
  909. package/src/renderers/shaders/ShaderLib/background.glsl.js +1 -1
  910. package/src/renderers/shaders/ShaderLib/depth.glsl.js +14 -2
  911. package/src/renderers/shaders/ShaderLib/{distanceRGBA.glsl.js → distance.glsl.js} +1 -2
  912. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +2 -1
  913. package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +1 -2
  914. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +2 -1
  915. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -9
  916. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +0 -1
  917. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +1 -1
  918. package/src/renderers/shaders/ShaderLib/vsm.glsl.js +4 -6
  919. package/src/renderers/shaders/ShaderLib.js +7 -5
  920. package/src/renderers/shaders/UniformsLib.js +2 -7
  921. package/src/renderers/shaders/UniformsUtils.js +21 -2
  922. package/src/renderers/webgl/WebGLAttributes.js +4 -0
  923. package/src/renderers/webgl/WebGLBackground.js +30 -5
  924. package/src/renderers/webgl/WebGLBindingStates.js +99 -27
  925. package/src/renderers/webgl/WebGLBufferRenderer.js +2 -6
  926. package/src/renderers/webgl/WebGLCapabilities.js +7 -14
  927. package/src/renderers/webgl/WebGLEnvironments.js +228 -0
  928. package/src/renderers/webgl/WebGLExtensions.js +2 -25
  929. package/src/renderers/webgl/WebGLGeometries.js +10 -35
  930. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +2 -6
  931. package/src/renderers/webgl/WebGLInfo.js +3 -1
  932. package/src/renderers/webgl/WebGLLights.js +18 -1
  933. package/src/renderers/webgl/WebGLMaterials.js +12 -0
  934. package/src/renderers/webgl/WebGLObjects.js +3 -1
  935. package/src/renderers/webgl/WebGLOutput.js +267 -0
  936. package/src/renderers/webgl/WebGLProgram.js +87 -148
  937. package/src/renderers/webgl/WebGLPrograms.js +53 -51
  938. package/src/renderers/webgl/WebGLRenderLists.js +15 -0
  939. package/src/renderers/webgl/WebGLShadowMap.js +204 -28
  940. package/src/renderers/webgl/WebGLState.js +88 -56
  941. package/src/renderers/webgl/WebGLTextures.js +293 -59
  942. package/src/renderers/webgl/WebGLUniforms.js +40 -3
  943. package/src/renderers/webgl/WebGLUniformsGroups.js +5 -3
  944. package/src/renderers/webgl/WebGLUtils.js +7 -5
  945. package/src/renderers/webgl-fallback/WebGLBackend.js +1416 -293
  946. package/src/renderers/webgl-fallback/WebGLBufferRenderer.js +5 -10
  947. package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +785 -92
  948. package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +62 -1
  949. package/src/renderers/webgl-fallback/utils/WebGLCapabilities.js +28 -0
  950. package/src/renderers/webgl-fallback/utils/WebGLConstants.js +3 -3
  951. package/src/renderers/webgl-fallback/utils/WebGLExtensions.js +45 -0
  952. package/src/renderers/webgl-fallback/utils/WebGLState.js +584 -20
  953. package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +468 -80
  954. package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +396 -0
  955. package/src/renderers/webgl-fallback/utils/WebGLUtils.js +72 -24
  956. package/src/renderers/webgpu/WebGPUBackend.js +1517 -428
  957. package/src/renderers/webgpu/WebGPURenderer.Nodes.js +31 -4
  958. package/src/renderers/webgpu/WebGPURenderer.js +55 -4
  959. package/src/renderers/webgpu/nodes/BasicNodeLibrary.js +23 -16
  960. package/src/renderers/webgpu/nodes/StandardNodeLibrary.js +37 -42
  961. package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +1335 -241
  962. package/src/renderers/webgpu/nodes/WGSLNodeFunction.js +32 -4
  963. package/src/renderers/webgpu/nodes/WGSLNodeParser.js +11 -0
  964. package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +144 -20
  965. package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +460 -116
  966. package/src/renderers/webgpu/utils/WebGPUConstants.js +17 -4
  967. package/src/renderers/webgpu/utils/WebGPUPipelineUtils.js +283 -69
  968. package/src/renderers/webgpu/utils/WebGPUTexturePassUtils.js +225 -178
  969. package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +583 -191
  970. package/src/renderers/webgpu/utils/WebGPUTimestampQueryPool.js +310 -0
  971. package/src/renderers/webgpu/utils/WebGPUUtils.js +150 -28
  972. package/src/renderers/webxr/WebXRController.js +87 -2
  973. package/src/renderers/webxr/WebXRDepthSensing.js +52 -7
  974. package/src/renderers/webxr/WebXRManager.js +275 -15
  975. package/src/scenes/Fog.js +60 -0
  976. package/src/scenes/FogExp2.js +51 -0
  977. package/src/scenes/Scene.js +88 -0
  978. package/src/textures/CanvasTexture.js +28 -0
  979. package/src/textures/CompressedArrayTexture.js +57 -0
  980. package/src/textures/CompressedCubeTexture.js +29 -0
  981. package/src/textures/CompressedTexture.js +64 -6
  982. package/src/textures/CubeDepthTexture.js +76 -0
  983. package/src/textures/CubeTexture.js +52 -4
  984. package/src/textures/Data3DTexture.js +79 -2
  985. package/src/textures/DataArrayTexture.js +93 -0
  986. package/src/textures/DataTexture.js +65 -0
  987. package/src/textures/DepthTexture.js +59 -11
  988. package/src/textures/ExternalTexture.js +56 -0
  989. package/src/textures/FramebufferTexture.js +62 -0
  990. package/src/textures/Source.js +106 -4
  991. package/src/textures/Texture.js +488 -6
  992. package/src/textures/VideoFrameTexture.js +72 -0
  993. package/src/textures/VideoTexture.js +78 -6
  994. package/src/utils.js +322 -3
  995. package/examples/jsm/animation/MMDAnimationHelper.js +0 -1207
  996. package/examples/jsm/animation/MMDPhysics.js +0 -1406
  997. package/examples/jsm/cameras/CinematicCamera.js +0 -208
  998. package/examples/jsm/effects/PeppersGhostEffect.js +0 -153
  999. package/examples/jsm/exporters/MMDExporter.js +0 -217
  1000. package/examples/jsm/geometries/InstancedPointsGeometry.js +0 -174
  1001. package/examples/jsm/geometries/ParametricGeometries.js +0 -254
  1002. package/examples/jsm/libs/mmdparser.module.js +0 -11530
  1003. package/examples/jsm/loaders/GLTFLoaderAnimationPointer.js +0 -729
  1004. package/examples/jsm/loaders/MMDLoader.js +0 -2295
  1005. package/examples/jsm/loaders/RGBMLoader.js +0 -1081
  1006. package/examples/jsm/materials/MeshGouraudMaterial.js +0 -432
  1007. package/examples/jsm/materials/MeshPostProcessingMaterial.js +0 -144
  1008. package/examples/jsm/misc/Timer.js +0 -128
  1009. package/examples/jsm/objects/InstancedPoints.js +0 -21
  1010. package/examples/jsm/shaders/GodRaysShader.js +0 -321
  1011. package/examples/jsm/shaders/MMDToonShader.js +0 -134
  1012. package/src/materials/nodes/InstancedPointsNodeMaterial.js +0 -156
  1013. package/src/nodes/accessors/InstancedPointsMaterialNode.js +0 -24
  1014. package/src/nodes/accessors/SceneNode.js +0 -55
  1015. package/src/nodes/code/ScriptableNode.js +0 -505
  1016. package/src/nodes/code/ScriptableValueNode.js +0 -170
  1017. package/src/nodes/core/CacheNode.js +0 -50
  1018. package/src/nodes/core/UniformGroup.js +0 -13
  1019. package/src/nodes/display/AfterImageNode.js +0 -158
  1020. package/src/nodes/display/AnaglyphPassNode.js +0 -67
  1021. package/src/nodes/display/AnamorphicNode.js +0 -151
  1022. package/src/nodes/display/BlendMode.js +0 -54
  1023. package/src/nodes/display/BloomNode.js +0 -341
  1024. package/src/nodes/display/DenoiseNode.js +0 -204
  1025. package/src/nodes/display/DepthOfFieldNode.js +0 -124
  1026. package/src/nodes/display/DotScreenNode.js +0 -66
  1027. package/src/nodes/display/FXAANode.js +0 -332
  1028. package/src/nodes/display/FilmNode.js +0 -56
  1029. package/src/nodes/display/GTAONode.js +0 -331
  1030. package/src/nodes/display/GaussianBlurNode.js +0 -213
  1031. package/src/nodes/display/Lut3DNode.js +0 -57
  1032. package/src/nodes/display/MotionBlur.js +0 -25
  1033. package/src/nodes/display/ParallaxBarrierPassNode.js +0 -58
  1034. package/src/nodes/display/PixelationPassNode.js +0 -213
  1035. package/src/nodes/display/PosterizeNode.js +0 -33
  1036. package/src/nodes/display/RGBShiftNode.js +0 -53
  1037. package/src/nodes/display/StereoCompositePassNode.js +0 -110
  1038. package/src/nodes/display/TransitionNode.js +0 -80
  1039. package/src/nodes/fog/FogExp2Node.js +0 -35
  1040. package/src/nodes/fog/FogNode.js +0 -50
  1041. package/src/nodes/fog/FogRangeNode.js +0 -36
  1042. package/src/nodes/functions/BSDF/DFGApprox.js +0 -30
  1043. package/src/nodes/utils/EquirectUVNode.js +0 -36
  1044. package/src/nodes/utils/MatcapUVNode.js +0 -33
  1045. package/src/nodes/utils/OscNode.js +0 -85
  1046. package/src/nodes/utils/SpriteSheetUVNode.js +0 -45
  1047. package/src/nodes/utils/TimerNode.js +0 -97
  1048. package/src/nodes/utils/TriplanarTexturesNode.js +0 -64
  1049. package/src/renderers/common/nodes/Nodes.js +0 -534
  1050. package/src/renderers/webgl/WebGLCubeMaps.js +0 -99
  1051. package/src/renderers/webgl/WebGLCubeUVMaps.js +0 -136
@@ -0,0 +1,1975 @@
1
+ import { Style } from './Style.js';
2
+
3
+ export class Profiler {
4
+
5
+ constructor() {
6
+
7
+ this.tabs = {};
8
+ this.activeTabId = null;
9
+ this.isResizing = false;
10
+ this.lastHeightBottom = 350; // Height for bottom position
11
+ this.lastWidthRight = 450; // Width for right position
12
+ this.position = 'bottom'; // 'bottom' or 'right'
13
+ this.detachedWindows = []; // Array to store detached tab windows
14
+ this.isMobile = this.detectMobile();
15
+ this.maxZIndex = 1002; // Track the highest z-index for detached windows (starts at base z-index from CSS)
16
+ this.nextTabOriginalIndex = 0; // Track the original order of tabs as they are added
17
+
18
+ Style.init();
19
+
20
+ this.setupShell();
21
+ this.setupResizing();
22
+
23
+ // Setup orientation change listener for mobile devices
24
+ if ( this.isMobile ) {
25
+
26
+ this.setupOrientationListener();
27
+
28
+ }
29
+
30
+ // Setup window resize listener to constrain detached windows
31
+ this.setupWindowResizeListener();
32
+
33
+ }
34
+
35
+ detectMobile() {
36
+
37
+ // Check for mobile devices
38
+ const userAgent = navigator.userAgent || navigator.vendor || window.opera;
39
+ const isMobileUA = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test( userAgent );
40
+ const isTouchDevice = ( 'ontouchstart' in window ) || ( navigator.maxTouchPoints > 0 );
41
+ const isSmallScreen = window.innerWidth <= 768;
42
+
43
+ return isMobileUA || ( isTouchDevice && isSmallScreen );
44
+
45
+ }
46
+
47
+ setupOrientationListener() {
48
+
49
+ const handleOrientationChange = () => {
50
+
51
+ // Check if device is in landscape or portrait mode
52
+ const isLandscape = window.innerWidth > window.innerHeight;
53
+
54
+ // In landscape mode, use right position (vertical panel)
55
+ // In portrait mode, use bottom position (horizontal panel)
56
+ const targetPosition = isLandscape ? 'right' : 'bottom';
57
+
58
+ if ( this.position !== targetPosition ) {
59
+
60
+ this.setPosition( targetPosition );
61
+
62
+ }
63
+
64
+ };
65
+
66
+ // Initial check
67
+ handleOrientationChange();
68
+
69
+ // Listen for orientation changes
70
+ window.addEventListener( 'orientationchange', handleOrientationChange );
71
+ window.addEventListener( 'resize', handleOrientationChange );
72
+
73
+ }
74
+
75
+ setupWindowResizeListener() {
76
+
77
+ const constrainDetachedWindows = () => {
78
+
79
+ this.detachedWindows.forEach( detachedWindow => {
80
+
81
+ this.constrainWindowToBounds( detachedWindow.panel );
82
+
83
+ } );
84
+
85
+ };
86
+
87
+ const constrainMainPanel = () => {
88
+
89
+ // Skip if panel is maximized (it should always fill the screen)
90
+ if ( this.panel.classList.contains( 'maximized' ) ) return;
91
+
92
+ const windowWidth = window.innerWidth;
93
+ const windowHeight = window.innerHeight;
94
+
95
+ if ( this.position === 'bottom' ) {
96
+
97
+ const currentHeight = this.panel.offsetHeight;
98
+ const maxHeight = windowHeight - 50; // Leave 50px margin
99
+
100
+ if ( currentHeight > maxHeight ) {
101
+
102
+ this.panel.style.height = `${ maxHeight }px`;
103
+ this.lastHeightBottom = maxHeight;
104
+
105
+ }
106
+
107
+ } else if ( this.position === 'right' ) {
108
+
109
+ const currentWidth = this.panel.offsetWidth;
110
+ const maxWidth = windowWidth - 50; // Leave 50px margin
111
+
112
+ if ( currentWidth > maxWidth ) {
113
+
114
+ this.panel.style.width = `${ maxWidth }px`;
115
+ this.lastWidthRight = maxWidth;
116
+
117
+ }
118
+
119
+ }
120
+
121
+ };
122
+
123
+ // Listen for window resize events
124
+ window.addEventListener( 'resize', () => {
125
+
126
+ constrainDetachedWindows();
127
+ constrainMainPanel();
128
+
129
+ } );
130
+
131
+ }
132
+
133
+ constrainWindowToBounds( windowPanel ) {
134
+
135
+ const windowWidth = window.innerWidth;
136
+ const windowHeight = window.innerHeight;
137
+
138
+ const panelWidth = windowPanel.offsetWidth;
139
+ const panelHeight = windowPanel.offsetHeight;
140
+
141
+ let left = parseFloat( windowPanel.style.left ) || windowPanel.offsetLeft || 0;
142
+ let top = parseFloat( windowPanel.style.top ) || windowPanel.offsetTop || 0;
143
+
144
+ // Allow window to extend half its width/height outside the screen
145
+ const halfWidth = panelWidth / 2;
146
+ const halfHeight = panelHeight / 2;
147
+
148
+ // Constrain horizontal position (allow half width to extend beyond right edge)
149
+ if ( left + panelWidth > windowWidth + halfWidth ) {
150
+
151
+ left = windowWidth + halfWidth - panelWidth;
152
+
153
+ }
154
+
155
+ // Constrain horizontal position (allow half width to extend beyond left edge)
156
+ if ( left < - halfWidth ) {
157
+
158
+ left = - halfWidth;
159
+
160
+ }
161
+
162
+ // Constrain vertical position (allow half height to extend beyond bottom edge)
163
+ if ( top + panelHeight > windowHeight + halfHeight ) {
164
+
165
+ top = windowHeight + halfHeight - panelHeight;
166
+
167
+ }
168
+
169
+ // Constrain vertical position (allow half height to extend beyond top edge)
170
+ if ( top < - halfHeight ) {
171
+
172
+ top = - halfHeight;
173
+
174
+ }
175
+
176
+ // Apply constrained position
177
+ windowPanel.style.left = `${ left }px`;
178
+ windowPanel.style.top = `${ top }px`;
179
+
180
+ }
181
+
182
+ setupShell() {
183
+
184
+ this.domElement = document.createElement( 'div' );
185
+ this.domElement.id = 'profiler-shell';
186
+
187
+ this.toggleButton = document.createElement( 'button' );
188
+ this.toggleButton.id = 'profiler-toggle';
189
+ this.toggleButton.innerHTML = `
190
+ <span id="builtin-tabs-container"></span>
191
+ <span id="toggle-text">
192
+ <span id="fps-counter">-</span>
193
+ <span class="fps-label">FPS</span>
194
+ </span>
195
+ <span id="toggle-icon">
196
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-device-ipad-horizontal-search"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M11.5 20h-6.5a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v5.5" /><path d="M9 17h2" /><path d="M18 18m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0" /><path d="M20.2 20.2l1.8 1.8" /></svg>
197
+ </span>
198
+ `;
199
+ this.toggleButton.onclick = () => this.togglePanel();
200
+
201
+ this.builtinTabsContainer = this.toggleButton.querySelector( '#builtin-tabs-container' );
202
+
203
+ // Create mini-panel for builtin tabs (shown when panel is hidden)
204
+ this.miniPanel = document.createElement( 'div' );
205
+ this.miniPanel.id = 'profiler-mini-panel';
206
+ this.miniPanel.className = 'profiler-mini-panel';
207
+
208
+ this.panel = document.createElement( 'div' );
209
+ this.panel.id = 'profiler-panel';
210
+
211
+ const header = document.createElement( 'div' );
212
+ header.className = 'profiler-header';
213
+ this.tabsContainer = document.createElement( 'div' );
214
+ this.tabsContainer.className = 'profiler-tabs';
215
+
216
+ const controls = document.createElement( 'div' );
217
+ controls.className = 'profiler-controls';
218
+
219
+ this.floatingBtn = document.createElement( 'button' );
220
+ this.floatingBtn.id = 'floating-btn';
221
+ this.floatingBtn.title = 'Switch to Right Side';
222
+ this.floatingBtn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="15" y1="3" x2="15" y2="21"></line></svg>';
223
+ this.floatingBtn.onclick = () => this.togglePosition();
224
+
225
+ // Hide position toggle button on mobile devices
226
+ if ( this.isMobile ) {
227
+
228
+ this.floatingBtn.style.display = 'none';
229
+ this.panel.classList.add( 'hide-position-toggle' );
230
+
231
+ }
232
+
233
+ this.maximizeBtn = document.createElement( 'button' );
234
+ this.maximizeBtn.id = 'maximize-btn';
235
+ this.maximizeBtn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/></svg>';
236
+ this.maximizeBtn.onclick = () => this.toggleMaximize();
237
+
238
+ const hideBtn = document.createElement( 'button' );
239
+ hideBtn.id = 'hide-panel-btn';
240
+ hideBtn.textContent = '-';
241
+ hideBtn.onclick = () => this.togglePanel();
242
+
243
+ controls.append( this.floatingBtn, this.maximizeBtn, hideBtn );
244
+ header.append( this.tabsContainer, controls );
245
+
246
+ this.contentWrapper = document.createElement( 'div' );
247
+ this.contentWrapper.className = 'profiler-content-wrapper';
248
+
249
+ const resizer = document.createElement( 'div' );
250
+ resizer.className = 'panel-resizer';
251
+
252
+ this.panel.append( resizer, header, this.contentWrapper );
253
+
254
+ this.domElement.append( this.toggleButton, this.miniPanel, this.panel );
255
+
256
+ // Set initial position class
257
+ this.panel.classList.add( `position-${this.position}` );
258
+
259
+ }
260
+
261
+ setupResizing() {
262
+
263
+ const resizer = this.panel.querySelector( '.panel-resizer' );
264
+
265
+ const onStart = ( e ) => {
266
+
267
+ this.isResizing = true;
268
+ this.panel.classList.add( 'resizing' );
269
+ resizer.setPointerCapture( e.pointerId );
270
+ const startX = e.clientX;
271
+ const startY = e.clientY;
272
+ const startHeight = this.panel.offsetHeight;
273
+ const startWidth = this.panel.offsetWidth;
274
+
275
+ const onMove = ( moveEvent ) => {
276
+
277
+ if ( ! this.isResizing ) return;
278
+ moveEvent.preventDefault();
279
+ const currentX = moveEvent.clientX;
280
+ const currentY = moveEvent.clientY;
281
+
282
+ if ( this.position === 'bottom' ) {
283
+
284
+ // Vertical resize for bottom position
285
+ const newHeight = startHeight - ( currentY - startY );
286
+
287
+ if ( newHeight > 100 && newHeight < window.innerHeight - 50 ) {
288
+
289
+ this.panel.style.height = `${ newHeight }px`;
290
+
291
+ }
292
+
293
+ } else if ( this.position === 'right' ) {
294
+
295
+ // Horizontal resize for right position
296
+ const newWidth = startWidth - ( currentX - startX );
297
+
298
+ if ( newWidth > 200 && newWidth < window.innerWidth - 50 ) {
299
+
300
+ this.panel.style.width = `${ newWidth }px`;
301
+
302
+ }
303
+
304
+ }
305
+
306
+ };
307
+
308
+ const onEnd = () => {
309
+
310
+ this.isResizing = false;
311
+ this.panel.classList.remove( 'resizing' );
312
+ resizer.removeEventListener( 'pointermove', onMove );
313
+ resizer.removeEventListener( 'pointerup', onEnd );
314
+ resizer.removeEventListener( 'pointercancel', onEnd );
315
+ if ( ! this.panel.classList.contains( 'maximized' ) ) {
316
+
317
+ // Save dimensions based on current position
318
+ if ( this.position === 'bottom' ) {
319
+
320
+ this.lastHeightBottom = this.panel.offsetHeight;
321
+
322
+ } else if ( this.position === 'right' ) {
323
+
324
+ this.lastWidthRight = this.panel.offsetWidth;
325
+
326
+ }
327
+
328
+ // Save layout after resize
329
+ this.saveLayout();
330
+
331
+ }
332
+
333
+ };
334
+
335
+ resizer.addEventListener( 'pointermove', onMove );
336
+ resizer.addEventListener( 'pointerup', onEnd );
337
+ resizer.addEventListener( 'pointercancel', onEnd );
338
+
339
+ };
340
+
341
+ resizer.addEventListener( 'pointerdown', onStart );
342
+
343
+ }
344
+
345
+ toggleMaximize() {
346
+
347
+ if ( this.panel.classList.contains( 'maximized' ) ) {
348
+
349
+ this.panel.classList.remove( 'maximized' );
350
+
351
+ // Restore size based on current position
352
+ if ( this.position === 'bottom' ) {
353
+
354
+ this.panel.style.height = `${ this.lastHeightBottom }px`;
355
+ this.panel.style.width = '100%';
356
+
357
+ } else if ( this.position === 'right' ) {
358
+
359
+ this.panel.style.height = '100%';
360
+ this.panel.style.width = `${ this.lastWidthRight }px`;
361
+
362
+ }
363
+
364
+ this.maximizeBtn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/></svg>';
365
+
366
+ } else {
367
+
368
+ // Save current size before maximizing
369
+ if ( this.position === 'bottom' ) {
370
+
371
+ this.lastHeightBottom = this.panel.offsetHeight;
372
+
373
+ } else if ( this.position === 'right' ) {
374
+
375
+ this.lastWidthRight = this.panel.offsetWidth;
376
+
377
+ }
378
+
379
+ this.panel.classList.add( 'maximized' );
380
+
381
+ // Maximize based on current position
382
+ if ( this.position === 'bottom' ) {
383
+
384
+ this.panel.style.height = '100vh';
385
+ this.panel.style.width = '100%';
386
+
387
+ } else if ( this.position === 'right' ) {
388
+
389
+ this.panel.style.height = '100%';
390
+ this.panel.style.width = '100vw';
391
+
392
+ }
393
+
394
+ this.maximizeBtn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="8" y="8" width="12" height="12" rx="2" ry="2"></rect><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"></path></svg>';
395
+
396
+ }
397
+
398
+ }
399
+
400
+ addTab( tab ) {
401
+
402
+ this.tabs[ tab.id ] = tab;
403
+
404
+ // Assign a permanent original index to this tab
405
+ tab.originalIndex = this.nextTabOriginalIndex ++;
406
+
407
+ // Add visual indicator for tabs that cannot be detached
408
+ if ( tab.allowDetach === false ) {
409
+
410
+ tab.button.classList.add( 'no-detach' );
411
+
412
+ }
413
+
414
+ // Set visibility change callback
415
+ tab.onVisibilityChange = () => this.updatePanelSize();
416
+
417
+ this.setupTabDragAndDrop( tab );
418
+
419
+ this.tabsContainer.appendChild( tab.button );
420
+ this.contentWrapper.appendChild( tab.content );
421
+
422
+ // Apply the current visibility state to the DOM elements
423
+ if ( ! tab.isVisible ) {
424
+
425
+ tab.button.style.display = 'none';
426
+ tab.content.style.display = 'none';
427
+
428
+ }
429
+
430
+ // If tab is builtin, add it to the profiler-toggle button
431
+ if ( tab.builtin ) {
432
+
433
+ this.addBuiltinTab( tab );
434
+
435
+ }
436
+
437
+ // Update panel size when tabs change
438
+ this.updatePanelSize();
439
+
440
+ }
441
+
442
+ addBuiltinTab( tab ) {
443
+
444
+ // Create a button for the builtin tab in the profiler-toggle
445
+ const builtinButton = document.createElement( 'button' );
446
+ builtinButton.className = 'builtin-tab-btn';
447
+
448
+ // Use icon if provided, otherwise use first letter
449
+ if ( tab.icon ) {
450
+
451
+ builtinButton.innerHTML = tab.icon;
452
+
453
+ } else {
454
+
455
+ builtinButton.textContent = tab.button.textContent.charAt( 0 ).toUpperCase();
456
+
457
+ }
458
+
459
+ builtinButton.title = tab.button.textContent;
460
+
461
+ // Create mini-panel content container for this tab
462
+ const miniContent = document.createElement( 'div' );
463
+ miniContent.className = 'mini-panel-content';
464
+ miniContent.style.display = 'none';
465
+
466
+ // Store references in the tab object
467
+ tab.builtinButton = builtinButton;
468
+ tab.miniContent = miniContent;
469
+
470
+ this.miniPanel.appendChild( miniContent );
471
+
472
+ builtinButton.onclick = ( e ) => {
473
+
474
+ e.stopPropagation(); // Prevent toggle panel from triggering
475
+
476
+ const isPanelVisible = this.panel.classList.contains( 'visible' );
477
+
478
+ if ( isPanelVisible ) {
479
+
480
+ // Panel is visible - navigate to tab
481
+ if ( ! tab.isVisible ) {
482
+
483
+ tab.show();
484
+
485
+ }
486
+
487
+ if ( tab.isDetached ) {
488
+
489
+ // If tab is detached, just bring its window to front
490
+ if ( tab.detachedWindow ) {
491
+
492
+ this.bringWindowToFront( tab.detachedWindow.panel );
493
+
494
+ }
495
+
496
+ } else {
497
+
498
+ // Activate the tab
499
+ this.setActiveTab( tab.id );
500
+
501
+ }
502
+
503
+ } else {
504
+
505
+ // Panel is hidden - toggle mini-panel for this tab
506
+ const isCurrentlyActive = miniContent.style.display !== 'none' && miniContent.children.length > 0;
507
+
508
+ // Hide all other mini-panel contents
509
+ this.miniPanel.querySelectorAll( '.mini-panel-content' ).forEach( content => {
510
+
511
+ content.style.display = 'none';
512
+
513
+ } );
514
+
515
+ // Remove active state from all builtin buttons
516
+ this.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ).forEach( btn => {
517
+
518
+ btn.classList.remove( 'active' );
519
+
520
+ } );
521
+
522
+ if ( isCurrentlyActive ) {
523
+
524
+ // Toggle off - hide mini-panel and move content back
525
+ this.miniPanel.classList.remove( 'visible' );
526
+ miniContent.style.display = 'none';
527
+
528
+ // Move content back to main panel
529
+ if ( miniContent.firstChild ) {
530
+
531
+ tab.content.appendChild( miniContent.firstChild );
532
+
533
+ }
534
+
535
+ } else {
536
+
537
+ // Toggle on - show mini-panel with this tab's content
538
+ builtinButton.classList.add( 'active' );
539
+
540
+ // Move actual content to mini-panel (not clone) if not already there
541
+ if ( ! miniContent.firstChild ) {
542
+
543
+ const actualContent = tab.content.querySelector( '.list-scroll-wrapper' ) || tab.content.firstElementChild;
544
+
545
+ if ( actualContent ) {
546
+
547
+ miniContent.appendChild( actualContent );
548
+
549
+ }
550
+
551
+ }
552
+
553
+ // Show after content is moved
554
+ miniContent.style.display = 'block';
555
+ this.miniPanel.classList.add( 'visible' );
556
+
557
+ }
558
+
559
+ }
560
+
561
+ };
562
+
563
+ this.builtinTabsContainer.appendChild( builtinButton );
564
+
565
+ // Store references
566
+ tab.builtinButton = builtinButton;
567
+ tab.miniContent = miniContent;
568
+ tab.profiler = this;
569
+
570
+ // If the tab was hidden before being added, hide the builtin button
571
+ if ( ! tab.isVisible ) {
572
+
573
+ builtinButton.style.display = 'none';
574
+ miniContent.style.display = 'none';
575
+
576
+ // Hide the builtin-tabs-container if all builtin buttons are hidden
577
+ const hasVisibleBuiltinButtons = Array.from( this.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ) )
578
+ .some( btn => btn.style.display !== 'none' );
579
+
580
+ if ( ! hasVisibleBuiltinButtons ) {
581
+
582
+ this.builtinTabsContainer.style.display = 'none';
583
+
584
+ }
585
+
586
+ }
587
+
588
+ }
589
+
590
+ updatePanelSize() {
591
+
592
+ // Check if there are any visible tabs in the panel
593
+ const hasVisibleTabs = Object.values( this.tabs ).some( tab => ! tab.isDetached && tab.isVisible );
594
+
595
+ // Add or remove CSS class to indicate no tabs state
596
+ if ( ! hasVisibleTabs ) {
597
+
598
+ this.panel.classList.add( 'no-tabs' );
599
+
600
+ // If maximized and no tabs, restore to normal size
601
+ if ( this.panel.classList.contains( 'maximized' ) ) {
602
+
603
+ this.panel.classList.remove( 'maximized' );
604
+ this.maximizeBtn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/></svg>';
605
+
606
+ }
607
+
608
+ // No tabs visible - set to minimum size
609
+ if ( this.position === 'bottom' ) {
610
+
611
+ this.panel.style.height = '38px';
612
+
613
+ } else if ( this.position === 'right' ) {
614
+
615
+ // 45px = width of one button column
616
+ this.panel.style.width = '45px';
617
+
618
+ }
619
+
620
+ } else {
621
+
622
+ this.panel.classList.remove( 'no-tabs' );
623
+
624
+ if ( Object.keys( this.tabs ).length > 0 ) {
625
+
626
+ // Has tabs - restore to saved size only if we had set it to minimum before
627
+ if ( this.position === 'bottom' ) {
628
+
629
+ const currentHeight = parseInt( this.panel.style.height );
630
+ if ( currentHeight === 38 ) {
631
+
632
+ this.panel.style.height = `${ this.lastHeightBottom }px`;
633
+
634
+ }
635
+
636
+ } else if ( this.position === 'right' ) {
637
+
638
+ const currentWidth = parseInt( this.panel.style.width );
639
+ if ( currentWidth === 45 ) {
640
+
641
+ this.panel.style.width = `${ this.lastWidthRight }px`;
642
+
643
+ }
644
+
645
+ }
646
+
647
+ }
648
+
649
+ }
650
+
651
+ }
652
+
653
+ setupTabDragAndDrop( tab ) {
654
+
655
+ // Disable drag and drop on mobile devices
656
+ if ( this.isMobile ) {
657
+
658
+ tab.button.addEventListener( 'click', () => {
659
+
660
+ this.setActiveTab( tab.id );
661
+
662
+ } );
663
+
664
+ return;
665
+
666
+ }
667
+
668
+ // Disable drag and drop if tab doesn't allow detach
669
+ if ( tab.allowDetach === false ) {
670
+
671
+ tab.button.addEventListener( 'click', () => {
672
+
673
+ this.setActiveTab( tab.id );
674
+
675
+ } );
676
+
677
+ tab.button.style.cursor = 'default';
678
+
679
+ return;
680
+
681
+ }
682
+
683
+ let isDragging = false;
684
+ let startX, startY;
685
+ let hasMoved = false;
686
+ let previewWindow = null;
687
+ const dragThreshold = 10; // pixels to move before starting drag
688
+
689
+ const onDragStart = ( e ) => {
690
+
691
+ startX = e.clientX;
692
+ startY = e.clientY;
693
+ isDragging = false;
694
+ hasMoved = false;
695
+ tab.button.setPointerCapture( e.pointerId );
696
+
697
+ };
698
+
699
+ const onDragMove = ( e ) => {
700
+
701
+ const currentX = e.clientX;
702
+ const currentY = e.clientY;
703
+
704
+ const deltaX = Math.abs( currentX - startX );
705
+ const deltaY = Math.abs( currentY - startY );
706
+
707
+ if ( ! isDragging && ( deltaX > dragThreshold || deltaY > dragThreshold ) ) {
708
+
709
+ isDragging = true;
710
+ tab.button.style.cursor = 'grabbing';
711
+ tab.button.style.opacity = '0.5';
712
+ tab.button.style.transform = 'scale(1.05)';
713
+
714
+ previewWindow = this.createPreviewWindow( tab, currentX, currentY );
715
+ previewWindow.style.opacity = '0.8';
716
+
717
+ }
718
+
719
+ if ( isDragging && previewWindow ) {
720
+
721
+ hasMoved = true;
722
+ e.preventDefault();
723
+
724
+ previewWindow.style.left = `${ currentX - 200 }px`;
725
+ previewWindow.style.top = `${ currentY - 20 }px`;
726
+
727
+ }
728
+
729
+ };
730
+
731
+ const onDragEnd = () => {
732
+
733
+ if ( isDragging && hasMoved && previewWindow ) {
734
+
735
+ if ( previewWindow.parentNode ) {
736
+
737
+ previewWindow.parentNode.removeChild( previewWindow );
738
+
739
+ }
740
+
741
+ const finalX = parseInt( previewWindow.style.left ) + 200;
742
+ const finalY = parseInt( previewWindow.style.top ) + 20;
743
+
744
+ this.detachTab( tab, finalX, finalY );
745
+
746
+ } else if ( ! hasMoved ) {
747
+
748
+ this.setActiveTab( tab.id );
749
+
750
+ if ( previewWindow && previewWindow.parentNode ) {
751
+
752
+ previewWindow.parentNode.removeChild( previewWindow );
753
+
754
+ }
755
+
756
+ } else if ( previewWindow ) {
757
+
758
+ if ( previewWindow.parentNode ) {
759
+
760
+ previewWindow.parentNode.removeChild( previewWindow );
761
+
762
+ }
763
+
764
+ }
765
+
766
+ tab.button.style.opacity = '';
767
+ tab.button.style.transform = '';
768
+ tab.button.style.cursor = '';
769
+ isDragging = false;
770
+ hasMoved = false;
771
+ previewWindow = null;
772
+
773
+ tab.button.removeEventListener( 'pointermove', onDragMove );
774
+ tab.button.removeEventListener( 'pointerup', onDragEnd );
775
+ tab.button.removeEventListener( 'pointercancel', onDragEnd );
776
+
777
+ };
778
+
779
+ tab.button.addEventListener( 'pointerdown', ( e ) => {
780
+
781
+ onDragStart( e );
782
+ tab.button.addEventListener( 'pointermove', onDragMove );
783
+ tab.button.addEventListener( 'pointerup', onDragEnd );
784
+ tab.button.addEventListener( 'pointercancel', onDragEnd );
785
+
786
+ } );
787
+
788
+ // Set cursor to grab for tabs that can be detached
789
+ tab.button.style.cursor = 'grab';
790
+
791
+ }
792
+
793
+ createPreviewWindow( tab, x, y ) {
794
+
795
+ const windowPanel = document.createElement( 'div' );
796
+ windowPanel.className = 'detached-tab-panel';
797
+ windowPanel.style.left = `${ x - 200 }px`;
798
+ windowPanel.style.top = `${ y - 20 }px`;
799
+ windowPanel.style.pointerEvents = 'none'; // Preview only
800
+
801
+ // Set z-index for preview window to be on top
802
+ this.maxZIndex ++;
803
+ windowPanel.style.setProperty( 'z-index', this.maxZIndex, 'important' );
804
+
805
+ const windowHeader = document.createElement( 'div' );
806
+ windowHeader.className = 'detached-tab-header';
807
+
808
+ const title = document.createElement( 'span' );
809
+ title.textContent = tab.button.textContent.replace( '⇱', '' ).trim();
810
+ windowHeader.appendChild( title );
811
+
812
+ const headerControls = document.createElement( 'div' );
813
+ headerControls.className = 'detached-header-controls';
814
+
815
+ const reattachBtn = document.createElement( 'button' );
816
+ reattachBtn.className = 'detached-reattach-btn';
817
+ reattachBtn.innerHTML = '↩';
818
+ headerControls.appendChild( reattachBtn );
819
+ windowHeader.appendChild( headerControls );
820
+
821
+ const windowContent = document.createElement( 'div' );
822
+ windowContent.className = 'detached-tab-content';
823
+
824
+ const resizer = document.createElement( 'div' );
825
+ resizer.className = 'detached-tab-resizer';
826
+
827
+ windowPanel.appendChild( resizer );
828
+ windowPanel.appendChild( windowHeader );
829
+ windowPanel.appendChild( windowContent );
830
+
831
+ document.body.appendChild( windowPanel );
832
+
833
+ return windowPanel;
834
+
835
+ }
836
+
837
+ detachTab( tab, x, y ) {
838
+
839
+ if ( tab.isDetached ) return;
840
+
841
+ // Check if tab allows detachment
842
+ if ( tab.allowDetach === false ) return;
843
+
844
+ const allButtons = Array.from( this.tabsContainer.children );
845
+
846
+ const tabIdsInOrder = allButtons.map( btn => {
847
+
848
+ return Object.keys( this.tabs ).find( id => this.tabs[ id ].button === btn );
849
+
850
+ } ).filter( id => id !== undefined );
851
+
852
+ const currentIndex = tabIdsInOrder.indexOf( tab.id );
853
+
854
+ let newActiveTab = null;
855
+
856
+ if ( this.activeTabId === tab.id ) {
857
+
858
+ tab.setActive( false );
859
+
860
+ const remainingTabs = tabIdsInOrder.filter( id =>
861
+ id !== tab.id &&
862
+ ! this.tabs[ id ].isDetached &&
863
+ this.tabs[ id ].isVisible
864
+ );
865
+
866
+ if ( remainingTabs.length > 0 ) {
867
+
868
+ for ( let i = currentIndex - 1; i >= 0; i -- ) {
869
+
870
+ if ( remainingTabs.includes( tabIdsInOrder[ i ] ) ) {
871
+
872
+ newActiveTab = tabIdsInOrder[ i ];
873
+ break;
874
+
875
+ }
876
+
877
+ }
878
+
879
+ if ( ! newActiveTab ) {
880
+
881
+ for ( let i = currentIndex + 1; i < tabIdsInOrder.length; i ++ ) {
882
+
883
+ if ( remainingTabs.includes( tabIdsInOrder[ i ] ) ) {
884
+
885
+ newActiveTab = tabIdsInOrder[ i ];
886
+ break;
887
+
888
+ }
889
+
890
+ }
891
+
892
+ }
893
+
894
+ if ( ! newActiveTab ) {
895
+
896
+ newActiveTab = remainingTabs[ 0 ];
897
+
898
+ }
899
+
900
+ }
901
+
902
+ }
903
+
904
+ if ( tab.button.parentNode ) {
905
+
906
+ tab.button.parentNode.removeChild( tab.button );
907
+
908
+ }
909
+
910
+ if ( tab.content.parentNode ) {
911
+
912
+ tab.content.parentNode.removeChild( tab.content );
913
+
914
+ }
915
+
916
+ const detachedWindow = this.createDetachedWindow( tab, x, y );
917
+ this.detachedWindows.push( detachedWindow );
918
+
919
+ tab.isDetached = true;
920
+ tab.detachedWindow = detachedWindow;
921
+
922
+ if ( newActiveTab ) {
923
+
924
+ this.setActiveTab( newActiveTab );
925
+
926
+ } else if ( this.activeTabId === tab.id ) {
927
+
928
+ this.activeTabId = null;
929
+
930
+ }
931
+
932
+ // Update panel size after detaching
933
+ this.updatePanelSize();
934
+
935
+ this.saveLayout();
936
+
937
+ }
938
+
939
+ createDetachedWindow( tab, x, y ) {
940
+
941
+ // Constrain initial position to window bounds
942
+ const windowWidth = window.innerWidth;
943
+ const windowHeight = window.innerHeight;
944
+ const estimatedWidth = 400; // Default detached window width
945
+ const estimatedHeight = 300; // Default detached window height
946
+
947
+ let constrainedX = x - 200;
948
+ let constrainedY = y - 20;
949
+
950
+ if ( constrainedX + estimatedWidth > windowWidth ) {
951
+
952
+ constrainedX = windowWidth - estimatedWidth;
953
+
954
+ }
955
+
956
+ if ( constrainedX < 0 ) {
957
+
958
+ constrainedX = 0;
959
+
960
+ }
961
+
962
+ if ( constrainedY + estimatedHeight > windowHeight ) {
963
+
964
+ constrainedY = windowHeight - estimatedHeight;
965
+
966
+ }
967
+
968
+ if ( constrainedY < 0 ) {
969
+
970
+ constrainedY = 0;
971
+
972
+ }
973
+
974
+ const windowPanel = document.createElement( 'div' );
975
+ windowPanel.className = 'detached-tab-panel';
976
+ windowPanel.style.left = `${ constrainedX }px`;
977
+ windowPanel.style.top = `${ constrainedY }px`;
978
+
979
+ if ( ! this.panel.classList.contains( 'visible' ) ) {
980
+
981
+ windowPanel.style.opacity = '0';
982
+ windowPanel.style.visibility = 'hidden';
983
+ windowPanel.style.pointerEvents = 'none';
984
+
985
+ }
986
+
987
+ // Hide detached window if tab is not visible
988
+ if ( ! tab.isVisible ) {
989
+
990
+ windowPanel.style.display = 'none';
991
+
992
+ }
993
+
994
+ const windowHeader = document.createElement( 'div' );
995
+ windowHeader.className = 'detached-tab-header';
996
+
997
+ const title = document.createElement( 'span' );
998
+ title.textContent = tab.button.textContent.replace( '⇱', '' ).trim();
999
+ windowHeader.appendChild( title );
1000
+
1001
+ const headerControls = document.createElement( 'div' );
1002
+ headerControls.className = 'detached-header-controls';
1003
+
1004
+ const reattachBtn = document.createElement( 'button' );
1005
+ reattachBtn.className = 'detached-reattach-btn';
1006
+ reattachBtn.innerHTML = '↩';
1007
+ reattachBtn.title = 'Reattach to main panel';
1008
+ reattachBtn.onclick = () => this.reattachTab( tab );
1009
+
1010
+ headerControls.appendChild( reattachBtn );
1011
+ windowHeader.appendChild( headerControls );
1012
+
1013
+ const windowContent = document.createElement( 'div' );
1014
+ windowContent.className = 'detached-tab-content';
1015
+ windowContent.appendChild( tab.content );
1016
+
1017
+ // Make sure content is visible
1018
+ tab.content.style.display = 'block';
1019
+ tab.content.classList.add( 'active' );
1020
+
1021
+ // Create resize handles for all edges
1022
+ const resizerTop = document.createElement( 'div' );
1023
+ resizerTop.className = 'detached-tab-resizer-top';
1024
+
1025
+ const resizerRight = document.createElement( 'div' );
1026
+ resizerRight.className = 'detached-tab-resizer-right';
1027
+
1028
+ const resizerBottom = document.createElement( 'div' );
1029
+ resizerBottom.className = 'detached-tab-resizer-bottom';
1030
+
1031
+ const resizerLeft = document.createElement( 'div' );
1032
+ resizerLeft.className = 'detached-tab-resizer-left';
1033
+
1034
+ const resizerCorner = document.createElement( 'div' );
1035
+ resizerCorner.className = 'detached-tab-resizer';
1036
+
1037
+ windowPanel.appendChild( resizerTop );
1038
+ windowPanel.appendChild( resizerRight );
1039
+ windowPanel.appendChild( resizerBottom );
1040
+ windowPanel.appendChild( resizerLeft );
1041
+ windowPanel.appendChild( resizerCorner );
1042
+ windowPanel.appendChild( windowHeader );
1043
+ windowPanel.appendChild( windowContent );
1044
+
1045
+ document.body.appendChild( windowPanel );
1046
+
1047
+ // Setup window dragging
1048
+ this.setupDetachedWindowDrag( windowPanel, windowHeader, tab );
1049
+
1050
+ // Setup window resizing
1051
+ this.setupDetachedWindowResize( windowPanel, resizerTop, resizerRight, resizerBottom, resizerLeft, resizerCorner );
1052
+
1053
+ // Use the same z-index that was set on the preview window
1054
+ windowPanel.style.setProperty( 'z-index', this.maxZIndex, 'important' );
1055
+
1056
+ return { panel: windowPanel, tab: tab };
1057
+
1058
+ }
1059
+
1060
+ bringWindowToFront( windowPanel ) {
1061
+
1062
+ // Increment the max z-index and apply it to the clicked window
1063
+ this.maxZIndex ++;
1064
+ windowPanel.style.setProperty( 'z-index', this.maxZIndex, 'important' );
1065
+
1066
+ }
1067
+
1068
+ setupDetachedWindowDrag( windowPanel, header, tab ) {
1069
+
1070
+ let isDragging = false;
1071
+ let startX, startY, startLeft, startTop;
1072
+
1073
+ // Bring window to front when clicking anywhere on it
1074
+ windowPanel.addEventListener( 'pointerdown', () => {
1075
+
1076
+ this.bringWindowToFront( windowPanel );
1077
+
1078
+ } );
1079
+
1080
+ const onDragStart = ( e ) => {
1081
+
1082
+ if ( e.target.classList.contains( 'detached-reattach-btn' ) ) {
1083
+
1084
+ return;
1085
+
1086
+ }
1087
+
1088
+ // Bring window to front when starting to drag
1089
+ this.bringWindowToFront( windowPanel );
1090
+
1091
+ isDragging = true;
1092
+ header.style.cursor = 'grabbing';
1093
+ header.setPointerCapture( e.pointerId );
1094
+
1095
+ startX = e.clientX;
1096
+ startY = e.clientY;
1097
+
1098
+ const rect = windowPanel.getBoundingClientRect();
1099
+ startLeft = rect.left;
1100
+ startTop = rect.top;
1101
+
1102
+ };
1103
+
1104
+ const onDragMove = ( e ) => {
1105
+
1106
+ if ( ! isDragging ) return;
1107
+
1108
+ e.preventDefault();
1109
+
1110
+ const currentX = e.clientX;
1111
+ const currentY = e.clientY;
1112
+
1113
+ const deltaX = currentX - startX;
1114
+ const deltaY = currentY - startY;
1115
+
1116
+ let newLeft = startLeft + deltaX;
1117
+ let newTop = startTop + deltaY;
1118
+
1119
+ // Constrain to window bounds (allow half width/height to extend outside)
1120
+ const windowWidth = window.innerWidth;
1121
+ const windowHeight = window.innerHeight;
1122
+ const panelWidth = windowPanel.offsetWidth;
1123
+ const panelHeight = windowPanel.offsetHeight;
1124
+ const halfWidth = panelWidth / 2;
1125
+ const halfHeight = panelHeight / 2;
1126
+
1127
+ // Allow window to extend half its width beyond right edge
1128
+ if ( newLeft + panelWidth > windowWidth + halfWidth ) {
1129
+
1130
+ newLeft = windowWidth + halfWidth - panelWidth;
1131
+
1132
+ }
1133
+
1134
+ // Allow window to extend half its width beyond left edge
1135
+ if ( newLeft < - halfWidth ) {
1136
+
1137
+ newLeft = - halfWidth;
1138
+
1139
+ }
1140
+
1141
+ // Allow window to extend half its height beyond bottom edge
1142
+ if ( newTop + panelHeight > windowHeight + halfHeight ) {
1143
+
1144
+ newTop = windowHeight + halfHeight - panelHeight;
1145
+
1146
+ }
1147
+
1148
+ // Allow window to extend half its height beyond top edge
1149
+ if ( newTop < - halfHeight ) {
1150
+
1151
+ newTop = - halfHeight;
1152
+
1153
+ }
1154
+
1155
+ windowPanel.style.left = `${ newLeft }px`;
1156
+ windowPanel.style.top = `${ newTop }px`;
1157
+
1158
+ // Check if cursor is over the inspector panel
1159
+ const panelRect = this.panel.getBoundingClientRect();
1160
+ const isOverPanel = currentX >= panelRect.left && currentX <= panelRect.right &&
1161
+ currentY >= panelRect.top && currentY <= panelRect.bottom;
1162
+
1163
+ if ( isOverPanel ) {
1164
+
1165
+ windowPanel.style.opacity = '0.5';
1166
+ this.panel.style.outline = '2px solid var(--accent-color)';
1167
+
1168
+ } else {
1169
+
1170
+ windowPanel.style.opacity = '';
1171
+ this.panel.style.outline = '';
1172
+
1173
+ }
1174
+
1175
+ };
1176
+
1177
+ const onDragEnd = ( e ) => {
1178
+
1179
+ if ( ! isDragging ) return;
1180
+
1181
+ isDragging = false;
1182
+ header.style.cursor = '';
1183
+ windowPanel.style.opacity = '';
1184
+ this.panel.style.outline = '';
1185
+
1186
+ // Check if dropped over the inspector panel
1187
+ const currentX = e.clientX;
1188
+ const currentY = e.clientY;
1189
+
1190
+ if ( currentX !== undefined && currentY !== undefined ) {
1191
+
1192
+ const panelRect = this.panel.getBoundingClientRect();
1193
+ const isOverPanel = currentX >= panelRect.left && currentX <= panelRect.right &&
1194
+ currentY >= panelRect.top && currentY <= panelRect.bottom;
1195
+
1196
+ if ( isOverPanel && tab ) {
1197
+
1198
+ // Reattach the tab
1199
+ this.reattachTab( tab );
1200
+
1201
+ } else {
1202
+
1203
+ // Save layout after moving detached window
1204
+ this.saveLayout();
1205
+
1206
+ }
1207
+
1208
+ }
1209
+
1210
+ header.removeEventListener( 'pointermove', onDragMove );
1211
+ header.removeEventListener( 'pointerup', onDragEnd );
1212
+ header.removeEventListener( 'pointercancel', onDragEnd );
1213
+
1214
+ };
1215
+
1216
+ header.addEventListener( 'pointerdown', ( e ) => {
1217
+
1218
+ onDragStart( e );
1219
+ header.addEventListener( 'pointermove', onDragMove );
1220
+ header.addEventListener( 'pointerup', onDragEnd );
1221
+ header.addEventListener( 'pointercancel', onDragEnd );
1222
+
1223
+ } );
1224
+
1225
+ header.style.cursor = 'grab';
1226
+
1227
+ }
1228
+
1229
+ setupDetachedWindowResize( windowPanel, resizerTop, resizerRight, resizerBottom, resizerLeft, resizerCorner ) {
1230
+
1231
+ const minWidth = 250;
1232
+ const minHeight = 150;
1233
+
1234
+ const setupResizer = ( resizer, direction ) => {
1235
+
1236
+ let isResizing = false;
1237
+ let startX, startY, startWidth, startHeight, startLeft, startTop;
1238
+
1239
+ const onResizeStart = ( e ) => {
1240
+
1241
+ e.preventDefault();
1242
+ e.stopPropagation();
1243
+ isResizing = true;
1244
+
1245
+ // Bring window to front when resizing
1246
+ this.bringWindowToFront( windowPanel );
1247
+
1248
+ resizer.setPointerCapture( e.pointerId );
1249
+
1250
+ startX = e.clientX;
1251
+ startY = e.clientY;
1252
+ startWidth = windowPanel.offsetWidth;
1253
+ startHeight = windowPanel.offsetHeight;
1254
+ startLeft = windowPanel.offsetLeft;
1255
+ startTop = windowPanel.offsetTop;
1256
+
1257
+ };
1258
+
1259
+ const onResizeMove = ( e ) => {
1260
+
1261
+ if ( ! isResizing ) return;
1262
+
1263
+ e.preventDefault();
1264
+
1265
+ const currentX = e.clientX;
1266
+ const currentY = e.clientY;
1267
+
1268
+ const deltaX = currentX - startX;
1269
+ const deltaY = currentY - startY;
1270
+
1271
+ const windowWidth = window.innerWidth;
1272
+ const windowHeight = window.innerHeight;
1273
+
1274
+ if ( direction === 'right' || direction === 'corner' ) {
1275
+
1276
+ const newWidth = startWidth + deltaX;
1277
+ const maxWidth = windowWidth - startLeft;
1278
+
1279
+ if ( newWidth >= minWidth && newWidth <= maxWidth ) {
1280
+
1281
+ windowPanel.style.width = `${ newWidth }px`;
1282
+
1283
+ }
1284
+
1285
+ }
1286
+
1287
+ if ( direction === 'bottom' || direction === 'corner' ) {
1288
+
1289
+ const newHeight = startHeight + deltaY;
1290
+ const maxHeight = windowHeight - startTop;
1291
+
1292
+ if ( newHeight >= minHeight && newHeight <= maxHeight ) {
1293
+
1294
+ windowPanel.style.height = `${ newHeight }px`;
1295
+
1296
+ }
1297
+
1298
+ }
1299
+
1300
+ if ( direction === 'left' ) {
1301
+
1302
+ const newWidth = startWidth - deltaX;
1303
+ const maxLeft = startLeft + startWidth - minWidth;
1304
+
1305
+ if ( newWidth >= minWidth ) {
1306
+
1307
+ const newLeft = startLeft + deltaX;
1308
+
1309
+ if ( newLeft >= 0 && newLeft <= maxLeft ) {
1310
+
1311
+ windowPanel.style.width = `${ newWidth }px`;
1312
+ windowPanel.style.left = `${ newLeft }px`;
1313
+
1314
+ }
1315
+
1316
+ }
1317
+
1318
+ }
1319
+
1320
+ if ( direction === 'top' ) {
1321
+
1322
+ const newHeight = startHeight - deltaY;
1323
+ const maxTop = startTop + startHeight - minHeight;
1324
+
1325
+ if ( newHeight >= minHeight ) {
1326
+
1327
+ const newTop = startTop + deltaY;
1328
+
1329
+ if ( newTop >= 0 && newTop <= maxTop ) {
1330
+
1331
+ windowPanel.style.height = `${ newHeight }px`;
1332
+ windowPanel.style.top = `${ newTop }px`;
1333
+
1334
+ }
1335
+
1336
+ }
1337
+
1338
+ }
1339
+
1340
+ };
1341
+
1342
+ const onResizeEnd = () => {
1343
+
1344
+ isResizing = false;
1345
+
1346
+ resizer.removeEventListener( 'pointermove', onResizeMove );
1347
+ resizer.removeEventListener( 'pointerup', onResizeEnd );
1348
+ resizer.removeEventListener( 'pointercancel', onResizeEnd );
1349
+
1350
+ // Save layout after resizing detached window
1351
+ this.saveLayout();
1352
+
1353
+ };
1354
+
1355
+ resizer.addEventListener( 'pointerdown', ( e ) => {
1356
+
1357
+ onResizeStart( e );
1358
+ resizer.addEventListener( 'pointermove', onResizeMove );
1359
+ resizer.addEventListener( 'pointerup', onResizeEnd );
1360
+ resizer.addEventListener( 'pointercancel', onResizeEnd );
1361
+
1362
+ } );
1363
+
1364
+ };
1365
+
1366
+ // Setup all resizers
1367
+ setupResizer( resizerTop, 'top' );
1368
+ setupResizer( resizerRight, 'right' );
1369
+ setupResizer( resizerBottom, 'bottom' );
1370
+ setupResizer( resizerLeft, 'left' );
1371
+ setupResizer( resizerCorner, 'corner' );
1372
+
1373
+ }
1374
+
1375
+ reattachTab( tab ) {
1376
+
1377
+ if ( ! tab.isDetached ) return;
1378
+
1379
+ if ( tab.detachedWindow ) {
1380
+
1381
+ const index = this.detachedWindows.indexOf( tab.detachedWindow );
1382
+
1383
+ if ( index > - 1 ) {
1384
+
1385
+ this.detachedWindows.splice( index, 1 );
1386
+
1387
+ }
1388
+
1389
+ if ( tab.detachedWindow.panel.parentNode ) {
1390
+
1391
+ tab.detachedWindow.panel.parentNode.removeChild( tab.detachedWindow.panel );
1392
+
1393
+ }
1394
+
1395
+ tab.detachedWindow = null;
1396
+
1397
+ }
1398
+
1399
+ tab.isDetached = false;
1400
+
1401
+ // Get all tabs and sort by their original index to determine the correct order
1402
+ const allTabs = Object.values( this.tabs );
1403
+ const allTabsSorted = allTabs
1404
+ .filter( t => t.originalIndex !== undefined && t.isVisible )
1405
+ .sort( ( a, b ) => a.originalIndex - b.originalIndex );
1406
+
1407
+ // Get currently attached tab buttons
1408
+ const currentButtons = Array.from( this.tabsContainer.children );
1409
+
1410
+ // Find the correct position for this tab
1411
+ let insertIndex = 0;
1412
+ for ( const t of allTabsSorted ) {
1413
+
1414
+ if ( t.id === tab.id ) {
1415
+
1416
+ break;
1417
+
1418
+ }
1419
+
1420
+ // Count only non-detached tabs that come before this one
1421
+ if ( ! t.isDetached ) {
1422
+
1423
+ insertIndex ++;
1424
+
1425
+ }
1426
+
1427
+ }
1428
+
1429
+ // Insert the button at the correct position
1430
+ if ( insertIndex >= currentButtons.length || currentButtons.length === 0 ) {
1431
+
1432
+ // If insert index is beyond current buttons, or no buttons exist, append at the end
1433
+ this.tabsContainer.appendChild( tab.button );
1434
+
1435
+ } else {
1436
+
1437
+ // Insert before the button at the insert index
1438
+ this.tabsContainer.insertBefore( tab.button, currentButtons[ insertIndex ] );
1439
+
1440
+ }
1441
+
1442
+ this.contentWrapper.appendChild( tab.content );
1443
+
1444
+ this.setActiveTab( tab.id );
1445
+
1446
+ // Update panel size after reattaching
1447
+ this.updatePanelSize();
1448
+
1449
+ this.saveLayout();
1450
+
1451
+ }
1452
+
1453
+ setActiveTab( id ) {
1454
+
1455
+ if ( this.activeTabId && this.tabs[ this.activeTabId ] && ! this.tabs[ this.activeTabId ].isDetached ) {
1456
+
1457
+ this.tabs[ this.activeTabId ].setActive( false );
1458
+
1459
+ }
1460
+
1461
+ this.activeTabId = id;
1462
+
1463
+ if ( this.tabs[ id ] ) {
1464
+
1465
+ this.tabs[ id ].setActive( true );
1466
+
1467
+ }
1468
+
1469
+ }
1470
+
1471
+ togglePanel() {
1472
+
1473
+ this.panel.classList.toggle( 'visible' );
1474
+ this.toggleButton.classList.toggle( 'hidden' );
1475
+
1476
+ const isVisible = this.panel.classList.contains( 'visible' );
1477
+
1478
+ if ( isVisible ) {
1479
+
1480
+ // Save mini-panel state before hiding
1481
+ this.savedMiniPanelState = {
1482
+ isVisible: this.miniPanel.classList.contains( 'visible' ),
1483
+ activeTabId: null,
1484
+ contentMap: {}
1485
+ };
1486
+
1487
+ // Find which tab was active in mini-panel
1488
+ this.miniPanel.querySelectorAll( '.mini-panel-content' ).forEach( content => {
1489
+
1490
+ if ( content.style.display !== 'none' && content.firstChild ) {
1491
+
1492
+ // Find the tab that owns this content
1493
+ Object.values( this.tabs ).forEach( tab => {
1494
+
1495
+ if ( tab.miniContent === content ) {
1496
+
1497
+ this.savedMiniPanelState.activeTabId = tab.id;
1498
+ // Move content back to main panel
1499
+ tab.content.appendChild( content.firstChild );
1500
+
1501
+ }
1502
+
1503
+ } );
1504
+
1505
+ }
1506
+
1507
+ } );
1508
+
1509
+ // Hide mini-panel temporarily
1510
+ this.miniPanel.classList.remove( 'visible' );
1511
+
1512
+ // Hide all mini-panel contents
1513
+ this.miniPanel.querySelectorAll( '.mini-panel-content' ).forEach( content => {
1514
+
1515
+ content.style.display = 'none';
1516
+
1517
+ } );
1518
+
1519
+ // Remove active state from builtin buttons
1520
+ this.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ).forEach( btn => {
1521
+
1522
+ btn.classList.remove( 'active' );
1523
+
1524
+ } );
1525
+
1526
+ } else {
1527
+
1528
+ // Restore mini-panel state when minimizing
1529
+ if ( this.savedMiniPanelState && this.savedMiniPanelState.isVisible && this.savedMiniPanelState.activeTabId ) {
1530
+
1531
+ const tab = this.tabs[ this.savedMiniPanelState.activeTabId ];
1532
+
1533
+ if ( tab && tab.miniContent && tab.builtinButton ) {
1534
+
1535
+ // Restore mini-panel visibility
1536
+ this.miniPanel.classList.add( 'visible' );
1537
+ tab.miniContent.style.display = 'block';
1538
+ tab.builtinButton.classList.add( 'active' );
1539
+
1540
+ // Move content back to mini-panel
1541
+ const actualContent = tab.content.querySelector( '.list-scroll-wrapper, .profiler-content > *' );
1542
+
1543
+ if ( actualContent ) {
1544
+
1545
+ tab.miniContent.appendChild( actualContent );
1546
+
1547
+ }
1548
+
1549
+ }
1550
+
1551
+ }
1552
+
1553
+ }
1554
+
1555
+ this.detachedWindows.forEach( detachedWindow => {
1556
+
1557
+ if ( isVisible ) {
1558
+
1559
+ detachedWindow.panel.style.opacity = '';
1560
+ detachedWindow.panel.style.visibility = '';
1561
+ detachedWindow.panel.style.pointerEvents = '';
1562
+
1563
+ } else {
1564
+
1565
+ detachedWindow.panel.style.opacity = '0';
1566
+ detachedWindow.panel.style.visibility = 'hidden';
1567
+ detachedWindow.panel.style.pointerEvents = 'none';
1568
+
1569
+ }
1570
+
1571
+ } );
1572
+
1573
+ }
1574
+
1575
+ togglePosition() {
1576
+
1577
+ const newPosition = this.position === 'bottom' ? 'right' : 'bottom';
1578
+ this.setPosition( newPosition );
1579
+
1580
+ }
1581
+
1582
+ setPosition( targetPosition ) {
1583
+
1584
+ if ( this.position === targetPosition ) return;
1585
+
1586
+ this.panel.style.transition = 'none';
1587
+
1588
+ // Check if panel is currently maximized
1589
+ const isMaximized = this.panel.classList.contains( 'maximized' );
1590
+
1591
+ if ( targetPosition === 'right' ) {
1592
+
1593
+ this.position = 'right';
1594
+ this.floatingBtn.classList.add( 'active' );
1595
+ this.floatingBtn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><path d="M3 15h18"></path></svg>';
1596
+ this.floatingBtn.title = 'Switch to Bottom';
1597
+
1598
+ // Apply right position styles
1599
+ this.panel.classList.remove( 'position-bottom' );
1600
+ this.panel.classList.add( 'position-right' );
1601
+ this.panel.style.bottom = '';
1602
+ this.panel.style.top = '0';
1603
+ this.panel.style.right = '0';
1604
+ this.panel.style.left = '';
1605
+
1606
+ // Apply size based on maximized state
1607
+ if ( isMaximized ) {
1608
+
1609
+ this.panel.style.width = '100vw';
1610
+ this.panel.style.height = '100%';
1611
+
1612
+ } else {
1613
+
1614
+ this.panel.style.width = `${ this.lastWidthRight }px`;
1615
+ this.panel.style.height = '100%';
1616
+
1617
+ }
1618
+
1619
+ } else {
1620
+
1621
+ this.position = 'bottom';
1622
+ this.floatingBtn.classList.remove( 'active' );
1623
+ this.floatingBtn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="15" y1="3" x2="15" y2="21"></line></svg>';
1624
+ this.floatingBtn.title = 'Switch to Right Side';
1625
+
1626
+ // Apply bottom position styles
1627
+ this.panel.classList.remove( 'position-right' );
1628
+ this.panel.classList.add( 'position-bottom' );
1629
+ this.panel.style.top = '';
1630
+ this.panel.style.right = '';
1631
+ this.panel.style.bottom = '0';
1632
+ this.panel.style.left = '0';
1633
+
1634
+ // Apply size based on maximized state
1635
+ if ( isMaximized ) {
1636
+
1637
+ this.panel.style.width = '100%';
1638
+ this.panel.style.height = '100vh';
1639
+
1640
+ } else {
1641
+
1642
+ this.panel.style.width = '100%';
1643
+ this.panel.style.height = `${ this.lastHeightBottom }px`;
1644
+
1645
+ }
1646
+
1647
+ }
1648
+
1649
+ // Re-enable transition after a brief delay
1650
+ setTimeout( () => {
1651
+
1652
+ this.panel.style.transition = '';
1653
+
1654
+ }, 50 );
1655
+
1656
+ // Update panel size based on visible tabs
1657
+ this.updatePanelSize();
1658
+
1659
+ // Save layout after position change
1660
+ this.saveLayout();
1661
+
1662
+ }
1663
+
1664
+ saveLayout() {
1665
+
1666
+ const layout = {
1667
+ position: this.position,
1668
+ lastHeightBottom: this.lastHeightBottom,
1669
+ lastWidthRight: this.lastWidthRight,
1670
+ activeTabId: this.activeTabId,
1671
+ detachedTabs: []
1672
+ };
1673
+
1674
+ // Save detached windows state
1675
+ this.detachedWindows.forEach( detachedWindow => {
1676
+
1677
+ const tab = detachedWindow.tab;
1678
+ const panel = detachedWindow.panel;
1679
+
1680
+ // Get position values, ensuring they're valid numbers
1681
+ const left = parseFloat( panel.style.left ) || panel.offsetLeft || 0;
1682
+ const top = parseFloat( panel.style.top ) || panel.offsetTop || 0;
1683
+ const width = panel.offsetWidth;
1684
+ const height = panel.offsetHeight;
1685
+
1686
+ layout.detachedTabs.push( {
1687
+ tabId: tab.id,
1688
+ originalIndex: tab.originalIndex !== undefined ? tab.originalIndex : 0,
1689
+ left: left,
1690
+ top: top,
1691
+ width: width,
1692
+ height: height
1693
+ } );
1694
+
1695
+ } );
1696
+
1697
+ try {
1698
+
1699
+ localStorage.setItem( 'profiler-layout', JSON.stringify( layout ) );
1700
+
1701
+ } catch ( e ) {
1702
+
1703
+ console.warn( 'Failed to save profiler layout:', e );
1704
+
1705
+ }
1706
+
1707
+ }
1708
+
1709
+ loadLayout() {
1710
+
1711
+ try {
1712
+
1713
+ const savedLayout = localStorage.getItem( 'profiler-layout' );
1714
+
1715
+ if ( ! savedLayout ) return;
1716
+
1717
+ const layout = JSON.parse( savedLayout );
1718
+
1719
+ // Constrain detached tabs positions to current screen bounds
1720
+ if ( layout.detachedTabs && layout.detachedTabs.length > 0 ) {
1721
+
1722
+ const windowWidth = window.innerWidth;
1723
+ const windowHeight = window.innerHeight;
1724
+
1725
+ layout.detachedTabs = layout.detachedTabs.map( detachedTabData => {
1726
+
1727
+ let { left, top, width, height } = detachedTabData;
1728
+
1729
+ // Ensure width and height are within bounds
1730
+ if ( width > windowWidth ) {
1731
+
1732
+ width = windowWidth - 100; // Leave some margin
1733
+
1734
+ }
1735
+
1736
+ if ( height > windowHeight ) {
1737
+
1738
+ height = windowHeight - 100; // Leave some margin
1739
+
1740
+ }
1741
+
1742
+ // Allow window to extend half its width/height outside the screen
1743
+ const halfWidth = width / 2;
1744
+ const halfHeight = height / 2;
1745
+
1746
+ // Constrain horizontal position (allow half width to extend beyond right edge)
1747
+ if ( left + width > windowWidth + halfWidth ) {
1748
+
1749
+ left = windowWidth + halfWidth - width;
1750
+
1751
+ }
1752
+
1753
+ // Constrain horizontal position (allow half width to extend beyond left edge)
1754
+ if ( left < - halfWidth ) {
1755
+
1756
+ left = - halfWidth;
1757
+
1758
+ }
1759
+
1760
+ // Constrain vertical position (allow half height to extend beyond bottom edge)
1761
+ if ( top + height > windowHeight + halfHeight ) {
1762
+
1763
+ top = windowHeight + halfHeight - height;
1764
+
1765
+ }
1766
+
1767
+ // Constrain vertical position (allow half height to extend beyond top edge)
1768
+ if ( top < - halfHeight ) {
1769
+
1770
+ top = - halfHeight;
1771
+
1772
+ }
1773
+
1774
+ return {
1775
+ ...detachedTabData,
1776
+ left,
1777
+ top,
1778
+ width,
1779
+ height
1780
+ };
1781
+
1782
+ } );
1783
+
1784
+ }
1785
+
1786
+ // Restore position and dimensions
1787
+ if ( layout.position ) {
1788
+
1789
+ this.position = layout.position;
1790
+
1791
+ }
1792
+
1793
+ if ( layout.lastHeightBottom ) {
1794
+
1795
+ this.lastHeightBottom = layout.lastHeightBottom;
1796
+
1797
+ }
1798
+
1799
+ if ( layout.lastWidthRight ) {
1800
+
1801
+ this.lastWidthRight = layout.lastWidthRight;
1802
+
1803
+ }
1804
+
1805
+ // Constrain saved dimensions to current screen bounds
1806
+ const windowWidth = window.innerWidth;
1807
+ const windowHeight = window.innerHeight;
1808
+
1809
+ if ( this.lastHeightBottom > windowHeight - 50 ) {
1810
+
1811
+ this.lastHeightBottom = windowHeight - 50;
1812
+
1813
+ }
1814
+
1815
+ if ( this.lastWidthRight > windowWidth - 50 ) {
1816
+
1817
+ this.lastWidthRight = windowWidth - 50;
1818
+
1819
+ }
1820
+
1821
+ // Apply the saved position after shell is set up
1822
+ if ( this.position === 'right' ) {
1823
+
1824
+ this.floatingBtn.classList.add( 'active' );
1825
+ this.floatingBtn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><path d="M3 15h18"></path></svg>';
1826
+ this.floatingBtn.title = 'Switch to Bottom';
1827
+
1828
+ this.panel.classList.remove( 'position-bottom' );
1829
+ this.panel.classList.add( 'position-right' );
1830
+ this.panel.style.bottom = '';
1831
+ this.panel.style.top = '0';
1832
+ this.panel.style.right = '0';
1833
+ this.panel.style.left = '';
1834
+ this.panel.style.width = `${ this.lastWidthRight }px`;
1835
+ this.panel.style.height = '100%';
1836
+
1837
+ } else {
1838
+
1839
+ this.panel.style.height = `${ this.lastHeightBottom }px`;
1840
+
1841
+ }
1842
+
1843
+ if ( layout.activeTabId ) {
1844
+
1845
+ const willBeDetached = layout.detachedTabs &&
1846
+ layout.detachedTabs.some( dt => dt.tabId === layout.activeTabId );
1847
+
1848
+ if ( willBeDetached ) {
1849
+
1850
+ this.setActiveTab( layout.activeTabId );
1851
+
1852
+ }
1853
+
1854
+ }
1855
+
1856
+ if ( layout.detachedTabs && layout.detachedTabs.length > 0 ) {
1857
+
1858
+ this.pendingDetachedTabs = layout.detachedTabs;
1859
+ this.restoreDetachedTabs();
1860
+
1861
+ }
1862
+
1863
+ // Update panel size after loading layout
1864
+ this.updatePanelSize();
1865
+
1866
+ } catch ( e ) {
1867
+
1868
+ console.warn( 'Failed to load profiler layout:', e );
1869
+
1870
+ }
1871
+
1872
+ }
1873
+
1874
+ restoreDetachedTabs() {
1875
+
1876
+ if ( ! this.pendingDetachedTabs || this.pendingDetachedTabs.length === 0 ) return;
1877
+
1878
+ this.pendingDetachedTabs.forEach( detachedTabData => {
1879
+
1880
+ const tab = this.tabs[ detachedTabData.tabId ];
1881
+
1882
+ if ( ! tab || tab.isDetached ) return;
1883
+
1884
+ // Restore originalIndex if saved
1885
+ if ( detachedTabData.originalIndex !== undefined ) {
1886
+
1887
+ tab.originalIndex = detachedTabData.originalIndex;
1888
+
1889
+ }
1890
+
1891
+ if ( tab.button.parentNode ) {
1892
+
1893
+ tab.button.parentNode.removeChild( tab.button );
1894
+
1895
+ }
1896
+
1897
+ if ( tab.content.parentNode ) {
1898
+
1899
+ tab.content.parentNode.removeChild( tab.content );
1900
+
1901
+ }
1902
+
1903
+ const detachedWindow = this.createDetachedWindow( tab, 0, 0 );
1904
+
1905
+ detachedWindow.panel.style.left = `${ detachedTabData.left }px`;
1906
+ detachedWindow.panel.style.top = `${ detachedTabData.top }px`;
1907
+ detachedWindow.panel.style.width = `${ detachedTabData.width }px`;
1908
+ detachedWindow.panel.style.height = `${ detachedTabData.height }px`;
1909
+
1910
+ // Constrain window to bounds after restoring position and size
1911
+ this.constrainWindowToBounds( detachedWindow.panel );
1912
+
1913
+ this.detachedWindows.push( detachedWindow );
1914
+
1915
+ tab.isDetached = true;
1916
+ tab.detachedWindow = detachedWindow;
1917
+
1918
+ } );
1919
+
1920
+ this.pendingDetachedTabs = null;
1921
+
1922
+ // Update maxZIndex to be higher than all existing windows
1923
+ this.detachedWindows.forEach( detachedWindow => {
1924
+
1925
+ const currentZIndex = parseInt( getComputedStyle( detachedWindow.panel ).zIndex ) || 0;
1926
+ if ( currentZIndex > this.maxZIndex ) {
1927
+
1928
+ this.maxZIndex = currentZIndex;
1929
+
1930
+ }
1931
+
1932
+ } );
1933
+
1934
+ const needsNewActiveTab = ! this.activeTabId ||
1935
+ ! this.tabs[ this.activeTabId ] ||
1936
+ this.tabs[ this.activeTabId ].isDetached ||
1937
+ ! this.tabs[ this.activeTabId ].isVisible;
1938
+
1939
+ if ( needsNewActiveTab ) {
1940
+
1941
+ const tabIds = Object.keys( this.tabs );
1942
+ const availableTabs = tabIds.filter( id =>
1943
+ ! this.tabs[ id ].isDetached &&
1944
+ this.tabs[ id ].isVisible
1945
+ );
1946
+
1947
+ if ( availableTabs.length > 0 ) {
1948
+
1949
+ const buttons = Array.from( this.tabsContainer.children );
1950
+ const orderedTabIds = buttons.map( btn => {
1951
+
1952
+ return Object.keys( this.tabs ).find( id => this.tabs[ id ].button === btn );
1953
+
1954
+ } ).filter( id =>
1955
+ id !== undefined &&
1956
+ ! this.tabs[ id ].isDetached &&
1957
+ this.tabs[ id ].isVisible
1958
+ );
1959
+
1960
+ this.setActiveTab( orderedTabIds[ 0 ] || availableTabs[ 0 ] );
1961
+
1962
+ } else {
1963
+
1964
+ this.activeTabId = null;
1965
+
1966
+ }
1967
+
1968
+ }
1969
+
1970
+ // Update panel size after restoring detached tabs
1971
+ this.updatePanelSize();
1972
+
1973
+ }
1974
+
1975
+ }